From 9b93d12f82772926aa95922ce904b2ee4d55955d Mon Sep 17 00:00:00 2001 From: Toni500git Date: Sun, 21 Jun 2026 17:19:06 +0200 Subject: [PATCH 01/40] libs: updated fmt, toml++, spdlog, imgui, stb --- include/libs/fmt/args.h | 2 +- include/libs/fmt/base.h | 26 +- include/libs/fmt/chrono.h | 8 +- include/libs/fmt/color.h | 44 ++- include/libs/fmt/compile.h | 2 +- include/libs/fmt/core.h | 7 + include/libs/fmt/format-inl.h | 30 +- include/libs/fmt/format.h | 7 +- include/libs/fmt/os.h | 2 +- include/libs/fmt/ostream.h | 2 +- include/libs/fmt/ranges.h | 46 ++- include/libs/fmt/xchar.h | 2 +- include/libs/imgui/imconfig.h | 8 +- include/libs/imgui/imgui.h | 106 ++++-- include/libs/imgui/imgui_impl_metal.h | 2 - include/libs/imgui/imgui_internal.h | 203 ++++++----- include/libs/spdlog/async.h | 10 +- include/libs/spdlog/async_logger-inl.h | 20 +- include/libs/spdlog/async_logger.h | 4 +- include/libs/spdlog/cfg/argv.h | 4 +- include/libs/spdlog/cfg/env.h | 6 +- include/libs/spdlog/cfg/helpers-inl.h | 4 +- include/libs/spdlog/cfg/helpers.h | 4 +- include/libs/spdlog/common-inl.h | 10 +- include/libs/spdlog/common.h | 26 +- include/libs/spdlog/details/backtracer-inl.h | 4 +- include/libs/spdlog/details/backtracer.h | 4 +- include/libs/spdlog/details/circular_q.h | 4 +- include/libs/spdlog/details/console_globals.h | 4 +- include/libs/spdlog/details/file_helper-inl.h | 4 +- include/libs/spdlog/details/file_helper.h | 4 +- include/libs/spdlog/details/fmt_helper.h | 6 +- include/libs/spdlog/details/log_msg-inl.h | 22 +- include/libs/spdlog/details/log_msg.h | 4 +- .../libs/spdlog/details/log_msg_buffer-inl.h | 4 +- include/libs/spdlog/details/log_msg_buffer.h | 4 +- include/libs/spdlog/details/mpmc_blocking_q.h | 6 +- include/libs/spdlog/details/null_mutex.h | 6 +- include/libs/spdlog/details/os-inl.h | 6 +- include/libs/spdlog/details/os.h | 6 +- .../libs/spdlog/details/periodic_worker-inl.h | 4 +- include/libs/spdlog/details/periodic_worker.h | 4 +- include/libs/spdlog/details/registry-inl.h | 6 +- include/libs/spdlog/details/registry.h | 6 +- .../libs/spdlog/details/synchronous_factory.h | 8 +- .../libs/spdlog/details/tcp_client-windows.h | 13 +- include/libs/spdlog/details/tcp_client.h | 4 +- include/libs/spdlog/details/thread_pool-inl.h | 6 +- include/libs/spdlog/details/thread_pool.h | 6 +- .../libs/spdlog/details/udp_client-windows.h | 4 +- include/libs/spdlog/details/udp_client.h | 4 +- include/libs/spdlog/fmt/bin_to_hex.h | 10 +- include/libs/spdlog/formatter.h | 4 +- include/libs/spdlog/fwd.h | 6 +- include/libs/spdlog/logger-inl.h | 8 +- include/libs/spdlog/logger.h | 10 +- include/libs/spdlog/mdc.h | 4 +- include/libs/spdlog/namespace.h | 27 ++ include/libs/spdlog/pattern_formatter-inl.h | 4 +- include/libs/spdlog/pattern_formatter.h | 8 +- include/libs/spdlog/sinks/android_sink.h | 22 +- .../libs/spdlog/sinks/ansicolor_sink-inl.h | 10 +- include/libs/spdlog/sinks/ansicolor_sink.h | 8 +- include/libs/spdlog/sinks/base_sink-inl.h | 26 +- include/libs/spdlog/sinks/base_sink.h | 12 +- .../libs/spdlog/sinks/basic_file_sink-inl.h | 4 +- include/libs/spdlog/sinks/basic_file_sink.h | 8 +- include/libs/spdlog/sinks/callback_sink.h | 8 +- include/libs/spdlog/sinks/daily_file_sink.h | 14 +- include/libs/spdlog/sinks/dist_sink.h | 8 +- include/libs/spdlog/sinks/dup_filter_sink.h | 11 +- include/libs/spdlog/sinks/hourly_file_sink.h | 10 +- include/libs/spdlog/sinks/kafka_sink.h | 26 +- include/libs/spdlog/sinks/loki_sink.h | 149 ++++++++ include/libs/spdlog/sinks/mongo_sink.h | 12 +- include/libs/spdlog/sinks/msvc_sink.h | 4 +- include/libs/spdlog/sinks/null_sink.h | 8 +- include/libs/spdlog/sinks/ostream_sink.h | 4 +- include/libs/spdlog/sinks/qt_sinks.h | 20 +- include/libs/spdlog/sinks/ringbuffer_sink.h | 4 +- .../spdlog/sinks/rotating_file_sink-inl.h | 4 +- .../libs/spdlog/sinks/rotating_file_sink.h | 8 +- include/libs/spdlog/sinks/sink-inl.h | 12 +- include/libs/spdlog/sinks/sink.h | 6 +- .../spdlog/sinks/stdout_color_sinks-inl.h | 4 +- .../libs/spdlog/sinks/stdout_color_sinks.h | 12 +- include/libs/spdlog/sinks/stdout_sinks-inl.h | 12 +- include/libs/spdlog/sinks/stdout_sinks.h | 16 +- include/libs/spdlog/sinks/syslog_sink.h | 8 +- .../spdlog/sinks/systemd_namespace_sink.h | 159 ++++++++ include/libs/spdlog/sinks/systemd_sink.h | 8 +- include/libs/spdlog/sinks/tcp_sink.h | 14 +- include/libs/spdlog/sinks/udp_sink.h | 20 +- include/libs/spdlog/sinks/win_eventlog_sink.h | 4 +- include/libs/spdlog/sinks/wincolor_sink-inl.h | 10 +- include/libs/spdlog/sinks/wincolor_sink.h | 8 +- include/libs/spdlog/spdlog-inl.h | 14 +- include/libs/spdlog/spdlog.h | 42 +-- include/libs/spdlog/stopwatch.h | 11 +- include/libs/spdlog/tweakme.h | 7 +- include/libs/stb_image_resize2.h | 110 +++--- include/libs/toml++/toml.hpp | 115 +++--- src/libs/fmt/format.cc | 2 +- src/libs/fmt/os.cc | 5 +- src/libs/imgui/imgui.cpp | 196 ++++++---- src/libs/imgui/imgui_draw.cpp | 343 +++++++++++------- src/libs/imgui/imgui_impl_metal.mm | 33 +- src/libs/imgui/imgui_tables.cpp | 246 ++++++++----- src/libs/imgui/imgui_widgets.cpp | 111 ++++-- 109 files changed, 1745 insertions(+), 982 deletions(-) create mode 100644 include/libs/spdlog/namespace.h create mode 100644 include/libs/spdlog/sinks/loki_sink.h create mode 100644 include/libs/spdlog/sinks/systemd_namespace_sink.h diff --git a/include/libs/fmt/args.h b/include/libs/fmt/args.h index 7b04ef0..3283e6f 100644 --- a/include/libs/fmt/args.h +++ b/include/libs/fmt/args.h @@ -1,6 +1,6 @@ // Formatting library for C++ - dynamic argument lists // -// Copyright (c) 2012 - present, Victor Zverovich +// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors // All rights reserved. // // For the license information refer to format.h. diff --git a/include/libs/fmt/base.h b/include/libs/fmt/base.h index be7a40d..5d0241c 100644 --- a/include/libs/fmt/base.h +++ b/include/libs/fmt/base.h @@ -1,6 +1,6 @@ // Formatting library for C++ - the base API for char/UTF-8 // -// Copyright (c) 2012 - present, Victor Zverovich +// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors // All rights reserved. // // For the license information refer to format.h. @@ -21,7 +21,7 @@ #endif // The fmt library version in the form major * 10000 + minor * 100 + patch. -#define FMT_VERSION 120101 +#define FMT_VERSION 120200 // Detect compiler versions. #if defined(__clang__) && !defined(__ibmxl__) @@ -224,9 +224,14 @@ # define FMT_PRAGMA_CLANG(x) #endif +#ifndef FMT_USE_OPTIMIZE_PRAGMA +# define FMT_USE_OPTIMIZE_PRAGMA 1 +#endif + // Enable minimal optimizations for more compact code in debug mode. FMT_PRAGMA_GCC(push_options) -#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE) +#if FMT_USE_OPTIMIZE_PRAGMA && !defined(__OPTIMIZE__) && \ + !defined(__CUDACC__) && !defined(FMT_MODULE) FMT_PRAGMA_GCC(optimize("Og")) #endif @@ -484,6 +489,14 @@ inline FMT_CONSTEXPR auto get_container(OutputIt it) -> }; return *accessor(it).container; } + +template +struct is_contiguous : std::false_type {}; +template +struct is_contiguous().data()), + decltype(std::declval().size()), + decltype(std::declval()[size_t()])>> + : std::true_type {}; } // namespace detail // Parsing-related public API and forward declarations. @@ -587,9 +600,6 @@ using string_view = basic_string_view; template class basic_appender; using appender = basic_appender; -// Checks whether T is a container with contiguous storage. -template struct is_contiguous : std::false_type {}; - class context; template class generic_context; template class parse_context; @@ -608,6 +618,8 @@ using buffered_context = conditional_t::value, context, generic_context, Char>>; +template struct is_contiguous : detail::is_contiguous {}; + template class basic_format_arg; template class basic_format_args; @@ -2581,7 +2593,7 @@ template class basic_format_args { FMT_CONSTEXPR auto get(int id) const -> format_arg { auto arg = format_arg(); if (!is_packed()) { - if (id < max_size()) arg = args_[id]; + if (unsigned(id) < unsigned(max_size())) arg = args_[id]; return arg; } if (unsigned(id) >= detail::max_packed_args) return arg; diff --git a/include/libs/fmt/chrono.h b/include/libs/fmt/chrono.h index 752b969..4659007 100644 --- a/include/libs/fmt/chrono.h +++ b/include/libs/fmt/chrono.h @@ -1,6 +1,6 @@ // Formatting library for C++ - chrono support // -// Copyright (c) 2012 - present, Victor Zverovich +// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors // All rights reserved. // // For the license information refer to format.h. @@ -934,10 +934,9 @@ inline auto to_nonnegative_int(T value, Int upper) -> Int { } template ::value)> inline auto to_nonnegative_int(T value, Int upper) -> Int { - auto int_value = static_cast(value); - if (int_value < 0 || value > static_cast(upper)) + if (value < 0 || value >= static_cast(upper) + 1) FMT_THROW(format_error("invalid value")); - return int_value; + return static_cast(value); } constexpr auto pow10(std::uint32_t n) -> long long { @@ -1192,6 +1191,7 @@ class tm_writer { template ::value)> void format_tz_name(const T& tm) { + if (!tm.tm_zone) FMT_THROW(format_error("no timezone")); out_ = write_tm_str(out_, tm.tm_zone, loc_); } template ::value)> diff --git a/include/libs/fmt/color.h b/include/libs/fmt/color.h index 153784f..bf0c32d 100644 --- a/include/libs/fmt/color.h +++ b/include/libs/fmt/color.h @@ -1,6 +1,6 @@ // Formatting library for C++ - color support // -// Copyright (c) 2018 - present, Victor Zverovich and fmt contributors +// Copyright (c) 2018 - present, Victor Zverovich and {fmt} contributors // All rights reserved. // // For the license information refer to format.h. @@ -471,7 +471,7 @@ template inline void reset_color(buffer& buffer) { template struct styled_arg : view { const T& value; text_style style; - styled_arg(const T& v, text_style s) : value(v), style(s) {} + FMT_CONSTEXPR styled_arg(const T& v, text_style s) : value(v), style(s) {} }; template @@ -528,6 +528,42 @@ void print(text_style ts, format_string fmt, T&&... args) { return print(stdout, ts, fmt, std::forward(args)...); } +inline void vprintln(FILE* f, text_style ts, string_view fmt, + format_args args) { + auto buf = memory_buffer(); + detail::vformat_to(buf, ts, fmt, args); + buf.push_back('\n'); + print(f, FMT_STRING("{}"), string_view(buf.begin(), buf.size())); +} + +/** + * Formats a string and prints it to the specified file stream followed by a + * newline, using ANSI escape sequences to specify text formatting. + * + * **Example**: + * + * fmt::println(fmt::emphasis::bold | fg(fmt::color::red), + * "Elapsed time: {0:.2f} seconds", 1.23); + */ +template +void println(FILE* f, text_style ts, format_string fmt, T&&... args) { + vprintln(f, ts, fmt.str, vargs{{args...}}); +} + +/** + * Formats a string and prints it to stdout followed by a newline, using ANSI + * escape sequences to specify text formatting. + * + * **Example**: + * + * fmt::println(fmt::emphasis::bold | fg(fmt::color::red), + * "Elapsed time: {0:.2f} seconds", 1.23); + */ +template +void println(text_style ts, format_string fmt, T&&... args) { + return println(stdout, ts, fmt, std::forward(args)...); +} + inline auto vformat(text_style ts, string_view fmt, format_args args) -> std::string { auto buf = memory_buffer(); @@ -583,8 +619,8 @@ inline auto format_to(OutputIt out, text_style ts, format_string fmt, template struct formatter, Char> : formatter { template - auto format(const detail::styled_arg& arg, FormatContext& ctx) const - -> decltype(ctx.out()) { + FMT_CONSTEXPR auto format(const detail::styled_arg& arg, + FormatContext& ctx) const -> decltype(ctx.out()) { const auto& ts = arg.style; auto out = ctx.out(); diff --git a/include/libs/fmt/compile.h b/include/libs/fmt/compile.h index 5c6820f..1a987cb 100644 --- a/include/libs/fmt/compile.h +++ b/include/libs/fmt/compile.h @@ -1,6 +1,6 @@ // Formatting library for C++ - experimental format string compilation // -// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors +// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors // All rights reserved. // // For the license information refer to format.h. diff --git a/include/libs/fmt/core.h b/include/libs/fmt/core.h index f1490a9..eff2ae8 100644 --- a/include/libs/fmt/core.h +++ b/include/libs/fmt/core.h @@ -1,3 +1,10 @@ +// Formatting library for C++ - core API +// +// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors +// All rights reserved. +// +// For the license information refer to format.h. + #include "base.h" // Using fmt::format via fmt/core.h has been deprecated since version 11 diff --git a/include/libs/fmt/format-inl.h b/include/libs/fmt/format-inl.h index 539b1fd..ecd3ffe 100644 --- a/include/libs/fmt/format-inl.h +++ b/include/libs/fmt/format-inl.h @@ -1,6 +1,6 @@ // Formatting library for C++ - implementation // -// Copyright (c) 2012 - 2016, Victor Zverovich +// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors // All rights reserved. // // For the license information refer to format.h. @@ -8,15 +8,17 @@ #ifndef FMT_FORMAT_INL_H_ #define FMT_FORMAT_INL_H_ +#ifdef __SANITIZE_THREAD__ +extern "C" void __tsan_acquire(void*); +extern "C" void __tsan_release(void*); +#endif + #ifndef FMT_MODULE # include // ptrdiff_t # include # include // errno -# include -# include -# include -# include // std::bad_alloc +# include // std::bad_alloc #endif #if defined(_WIN32) && !defined(FMT_USE_WRITE_CONSOLE) @@ -1524,7 +1526,10 @@ template class file_base { FMT_THROW(system_error(errno, FMT_STRING("ungetc failed"))); } - void flush() { fflush(this->file_); } + void flush() { + if (fflush(this->file_) != 0) + FMT_THROW(system_error(errno, FMT_STRING("fflush failed"))); + } }; // A FILE wrapper for glibc. @@ -1570,7 +1575,10 @@ template class glibc_file : public file_base { return memchr(end, '\n', static_cast(size)); } - void flush() { fflush_unlocked(this->file_); } + void flush() { + if (fflush_unlocked(this->file_) != 0) + FMT_THROW(system_error(errno, FMT_STRING("fflush failed"))); + } }; // A FILE wrapper for Apple's libc. @@ -1696,6 +1704,9 @@ class file_print_buffer::value>> public: explicit file_print_buffer(F* f) : buffer(grow, size_t()), file_(f) { flockfile(f); +#ifdef __SANITIZE_THREAD__ + __tsan_acquire(f); +#endif file_.init_buffer(); auto buf = file_.get_write_buffer(); set(buf.data, buf.size); @@ -1703,7 +1714,10 @@ class file_print_buffer::value>> ~file_print_buffer() { file_.advance_write_buffer(size()); bool flush = file_.needs_flush(); - F* f = file_; // Make funlockfile depend on the template parameter F + F* f = file_; // Make funlockfile depend on the template parameter F. +#ifdef __SANITIZE_THREAD__ + __tsan_release(f); +#endif funlockfile(f); // for the system API detection to work. if (flush) fflush(file_); } diff --git a/include/libs/fmt/format.h b/include/libs/fmt/format.h index 256a99a..5706279 100644 --- a/include/libs/fmt/format.h +++ b/include/libs/fmt/format.h @@ -1,7 +1,7 @@ /* Formatting library for C++ - Copyright (c) 2012 - present, Victor Zverovich + Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -326,6 +326,9 @@ class uint128 { -> uint128 { return {lhs.hi_ & rhs.hi_, lhs.lo_ & rhs.lo_}; } + friend constexpr auto operator~(const uint128& n) -> uint128 { + return {~n.hi_, ~n.lo_}; + } friend FMT_CONSTEXPR auto operator+(const uint128& lhs, const uint128& rhs) -> uint128 { auto result = uint128(lhs); @@ -3888,7 +3891,7 @@ template class generic_context { constexpr auto out() const -> iterator { return out_; } - void advance_to(iterator it) { + FMT_CONSTEXPR void advance_to(iterator it) { if (!detail::is_back_insert_iterator()) out_ = it; } diff --git a/include/libs/fmt/os.h b/include/libs/fmt/os.h index 3fbd690..a3ee58f 100644 --- a/include/libs/fmt/os.h +++ b/include/libs/fmt/os.h @@ -1,6 +1,6 @@ // Formatting library for C++ - optional OS-specific functionality // -// Copyright (c) 2012 - present, Victor Zverovich +// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors // All rights reserved. // // For the license information refer to format.h. diff --git a/include/libs/fmt/ostream.h b/include/libs/fmt/ostream.h index a139e82..da9c65e 100644 --- a/include/libs/fmt/ostream.h +++ b/include/libs/fmt/ostream.h @@ -1,6 +1,6 @@ // Formatting library for C++ - std::ostream support // -// Copyright (c) 2012 - present, Victor Zverovich +// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors // All rights reserved. // // For the license information refer to format.h. diff --git a/include/libs/fmt/ranges.h b/include/libs/fmt/ranges.h index d7dbc16..99bef84 100644 --- a/include/libs/fmt/ranges.h +++ b/include/libs/fmt/ranges.h @@ -69,11 +69,12 @@ struct has_member_fn_begin_end_t().begin()), // Member function overloads. template -auto range_begin(T&& rng) -> decltype(static_cast(rng).begin()) { +FMT_CONSTEXPR auto range_begin(T&& rng) + -> decltype(static_cast(rng).begin()) { return static_cast(rng).begin(); } template -auto range_end(T&& rng) -> decltype(static_cast(rng).end()) { +FMT_CONSTEXPR auto range_end(T&& rng) -> decltype(static_cast(rng).end()) { return static_cast(rng).end(); } @@ -129,6 +130,13 @@ template class is_tuple_like_ { !std::is_void(nullptr))>::value; }; +template +struct is_optional_like_ : std::false_type {}; +template +struct is_optional_like_().has_value()), + decltype(std::declval().value())>> + : std::true_type {}; + // Check for integer_sequence #if defined(__cpp_lib_integer_sequence) || FMT_MSC_VERSION >= 1900 template @@ -343,8 +351,9 @@ struct formatter struct is_range { - static constexpr bool value = - detail::is_range_::value && !detail::has_to_string_view::value; + static constexpr bool value = detail::is_range_::value && + !detail::is_optional_like_::value && + !detail::has_to_string_view::value; }; namespace detail { @@ -460,7 +469,8 @@ struct range_formatter< } template - auto format(R&& range, FormatContext& ctx) const -> decltype(ctx.out()) { + FMT_CONSTEXPR auto format(R&& range, FormatContext& ctx) const + -> decltype(ctx.out()) { auto out = ctx.out(); auto it = detail::range_begin(range); auto end = detail::range_end(range); @@ -516,7 +526,7 @@ struct formatter< } template - auto format(range_type& range, FormatContext& ctx) const + FMT_CONSTEXPR auto format(range_type& range, FormatContext& ctx) const -> decltype(ctx.out()) { return range_formatter_.format(range, ctx); } @@ -625,7 +635,7 @@ struct join_view : detail::view { Sentinel end; basic_string_view sep; - join_view(It b, Sentinel e, basic_string_view s) + FMT_CONSTEXPR join_view(It b, Sentinel e, basic_string_view s) : begin(std::move(b)), end(e), sep(s) {} }; @@ -652,7 +662,8 @@ struct formatter, Char> { } template - auto format(view& value, FormatContext& ctx) const -> decltype(ctx.out()) { + FMT_CONSTEXPR auto format(view& value, FormatContext& ctx) const + -> decltype(ctx.out()) { using iter = conditional_t::value, It, It&>; iter it = value.begin; @@ -675,7 +686,7 @@ template struct tuple_join_view : detail::view { const Tuple& tuple; basic_string_view sep; - tuple_join_view(const Tuple& t, basic_string_view s) + FMT_CONSTEXPR tuple_join_view(const Tuple& t, basic_string_view s) : tuple(t), sep{s} {} }; @@ -694,8 +705,9 @@ struct formatter, Char, } template - auto format(const tuple_join_view& value, - FormatContext& ctx) const -> typename FormatContext::iterator { + FMT_CONSTEXPR auto format(const tuple_join_view& value, + FormatContext& ctx) const -> + typename FormatContext::iterator { return do_format(value, ctx, std::tuple_size()); } @@ -726,15 +738,17 @@ struct formatter, Char, } template - auto do_format(const tuple_join_view&, FormatContext& ctx, - std::integral_constant) const -> + FMT_CONSTEXPR auto do_format(const tuple_join_view&, + FormatContext& ctx, + std::integral_constant) const -> typename FormatContext::iterator { return ctx.out(); } template - auto do_format(const tuple_join_view& value, FormatContext& ctx, - std::integral_constant) const -> + FMT_CONSTEXPR auto do_format(const tuple_join_view& value, + FormatContext& ctx, + std::integral_constant) const -> typename FormatContext::iterator { using std::get; auto out = @@ -813,7 +827,7 @@ auto join(It begin, Sentinel end, string_view sep) -> join_view { * // Output: 01, 02, 03 */ template ::value)> -auto join(Range&& r, string_view sep) +FMT_CONSTEXPR auto join(Range&& r, string_view sep) -> join_view { return {detail::range_begin(r), detail::range_end(r), sep}; diff --git a/include/libs/fmt/xchar.h b/include/libs/fmt/xchar.h index 6d95a73..9631372 100644 --- a/include/libs/fmt/xchar.h +++ b/include/libs/fmt/xchar.h @@ -1,6 +1,6 @@ // Formatting library for C++ - optional wchar_t and exotic character support // -// Copyright (c) 2012 - present, Victor Zverovich +// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors // All rights reserved. // // For the license information refer to format.h. diff --git a/include/libs/imgui/imconfig.h b/include/libs/imgui/imconfig.h index 6b11ed8..8db72ba 100644 --- a/include/libs/imgui/imconfig.h +++ b/include/libs/imgui/imconfig.h @@ -1,3 +1,5 @@ +// https://github.com/ocornut/imgui/commit/d15966ff6cb48adacaae2f6d40230b4194d8ea70 + //----------------------------------------------------------------------------- // DEAR IMGUI COMPILE-TIME OPTIONS // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. @@ -49,11 +51,13 @@ //#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies) //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). -//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded fonts (ProggyClean/ProggyForever), remove ~9 KB + ~14 KB from output binary. AddFontDefaultXXX() functions will assert. +//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded fonts (ProggyClean + ProggyForever). Remove ~9 KB + ~14 KB from output binary. AddFontDefaultXXX() functions will assert. +//#define IMGUI_DISABLE_DEFAULT_FONT_BITMAP // Disable default embedded bitmap font (ProggyClean). Remove ~9 KB from output binary. AddFontDefaultBitmap() will assert. +//#define IMGUI_DISABLE_DEFAULT_FONT_VECTOR // Disable default embedded vector font (ProggyForever), Remove ~14 KB from output binary. AddFontDefaultVector() will assert. //#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available //---- Enable Test Engine / Automation features. -//#define IMGUI_ENABLE_TEST_ENGINE // Enable imgui_test_engine hooks. Generally set automatically by include "imgui_te_config.h", see Test Engine for details. +//#define IMGUI_ENABLE_TEST_ENGINE // Enable imgui_test_engine hooks. Generally set automatically by include "imgui_te_imconfig.h", see Test Engine for details. //---- Include imgui_user.h at the end of imgui.h as a convenience // May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included. diff --git a/include/libs/imgui/imgui.h b/include/libs/imgui/imgui.h index 41a93de..720e3c8 100644 --- a/include/libs/imgui/imgui.h +++ b/include/libs/imgui/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.92.8 WIP +// dear imgui, v1.92.9 WIP // (headers) // Help: @@ -29,8 +29,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.92.8 WIP" -#define IMGUI_VERSION_NUM 19275 +#define IMGUI_VERSION "1.92.9 WIP" +#define IMGUI_VERSION_NUM 19284 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 @@ -613,7 +613,8 @@ namespace ImGui IMGUI_API ImGuiID GetID(int int_id); // Widgets: Text - IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // raw text without formatting. Roughly equivalent to Text("%s", text) but: A) doesn't require null terminated string if 'text_end' is specified, B) it's faster, no memory copy is done, no buffer size limits, recommended for long chunks of text. + // - Note that all functions taking format strings in the API may be passed ("%s", text) or ("%.*s", text_len, text): which will automatically bypass the formatter. + IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // raw text without formatting. Practically equivalent to 'Text("%s", text)' but doesn't require null terminated string if 'text_end' is specified. IMGUI_API void Text(const char* fmt, ...) IM_FMTARGS(1); // formatted text IMGUI_API void TextV(const char* fmt, va_list args) IM_FMTLIST(1); IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...) IM_FMTARGS(2); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor(); @@ -648,7 +649,7 @@ namespace ImGui // Widgets: Images // - Read about ImTextureID/ImTextureRef here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples // - 'uv0' and 'uv1' are texture coordinates. Read about them from the same link above. - // - Image() pads adds style.ImageBorderSize on each side, ImageButton() adds style.FramePadding on each side. + // - Image() adds style.ImageBorderSize on each side, ImageButton() adds style.FramePadding on each side. // - ImageButton() draws a background based on regular Button() color + optionally an inner background if specified. // - An obsolete version of Image(), before 1.91.9 (March 2025), had a 'tint_col' parameter which is now supported by the ImageWithBg() function. IMGUI_API void Image(ImTextureRef tex_ref, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1)); @@ -808,7 +809,7 @@ namespace ImGui // - Use BeginMenuBar() on a window ImGuiWindowFlags_MenuBar to append to its menu bar. // - Use BeginMainMenuBar() to create a menu bar at the top of the screen and append to it. // - Use BeginMenu() to create a menu. You can call BeginMenu() multiple time with the same identifier to append more items to it. - // - Not that MenuItem() keyboardshortcuts are displayed as a convenience but _not processed_ by Dear ImGui at the moment. + // - Note that MenuItem() keyboard shortcuts are displayed as a convenience but _not processed_ by Dear ImGui at the moment. IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window). IMGUI_API void EndMenuBar(); // only call EndMenuBar() if BeginMenuBar() returns true! IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar. @@ -837,7 +838,7 @@ namespace ImGui // Popups, Modals // - They block normal mouse hovering detection (and therefore most mouse interactions) behind them. - // - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE. + // - If not modal: they can be closed by clicking anywhere outside them, or by pressing Escape (call 'Shortcut(ImGuiKey_Escape)' to claim a higher-priority shortcut). // - Their visibility state (~bool) is held internally instead of being held by the programmer as we are used to with regular Begin*() calls. // - The 3 properties above are related: we need to retain popup visibility state in the library because popups may be closed as any time. // - You can bypass the hovering restriction by using ImGuiHoveredFlags_AllowWhenBlockedByPopup when calling IsItemHovered() or IsWindowHovered(). @@ -908,14 +909,15 @@ namespace ImGui IMGUI_API bool TableSetColumnIndex(int column_n); // append into the specified column. Return true when column is visible. // Tables: Headers & Columns declaration - // - Use TableSetupColumn() to specify label, resizing policy, default width/weight, id, various other flags etc. + // - Use TableSetupColumn() to specify label, resizing policy, default width/weight, various other flags etc. + // (the trailing 'ImGuiID user_data', which used to be referred to as 'ImGuiID user_id', is merely user data that is blindly copied in ImGuiTableColumnSortSpecs). // - Use TableHeadersRow() to create a header row and automatically submit a TableHeader() for each column. // Headers are required to perform: reordering, sorting, and opening the context menu. // The context menu can also be made available in columns body using ImGuiTableFlags_ContextMenuInBody. // - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in // some advanced use cases (e.g. adding custom widgets in header row). // - Use TableSetupScrollFreeze() to lock columns/rows so they stay visible when scrolled. When freezing columns you would usually also use ImGuiTableColumnFlags_NoHide on them. - IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImGuiID user_id = 0); + IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImGuiID user_data = 0); IMGUI_API void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled. IMGUI_API void TableHeader(const char* label); // submit one header cell manually (rarely used) IMGUI_API void TableHeadersRow(); // submit a row with headers cells based on data provided to TableSetupColumn() + submit context menu @@ -1092,10 +1094,11 @@ namespace ImGui // Inputs Utilities: Key/Input Ownership [BETA] // - One common use case would be to allow your items to disable standard inputs behaviors such // as Tab or Alt key handling, Mouse Wheel scrolling, etc. - // e.g. Button(...); SetItemKeyOwner(ImGuiKey_MouseWheelY); to make hovering/activating a button disable wheel for scrolling. + // e.g. `Button(...); if (SetItemKeyOwner(ImGuiKey_MouseWheelY)) { ... }` to make hovering/activating a button disable wheel for scrolling. // - Reminder ImGuiKey enum include access to mouse buttons and gamepad, so key ownership can apply to them. + // - The return value of SetItemKeyOwner() says if ownership has been requested for the item, which is a shortcut to calling yet non-public TestKeyOwner() function. // - Many related features are still in imgui_internal.h. For instance, most IsKeyXXX()/IsMouseXXX() functions have an owner-id-aware version. - IMGUI_API void SetItemKeyOwner(ImGuiKey key); // Set key owner to last item ID if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'. + IMGUI_API bool SetItemKeyOwner(ImGuiKey key); // Set key owner to last item ID if it is hovered or active. Return true when ownership has been set. Roughly equivalent to 'if (TestKeyOwner(key, GetItemID()) && (IsItemHovered() || IsItemActive())) { SetKeyOwner(key, GetItemID());'. // Inputs Utilities: Mouse // - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right. @@ -1329,7 +1332,7 @@ enum ImGuiTreeNodeFlags_ #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS ImGuiTreeNodeFlags_NavLeftJumpsBackHere = ImGuiTreeNodeFlags_NavLeftJumpsToParent, // Renamed in 1.92.0 - ImGuiTreeNodeFlags_SpanTextWidth = ImGuiTreeNodeFlags_SpanLabelWidth, // Renamed in 1.90.7 + //ImGuiTreeNodeFlags_SpanTextWidth = ImGuiTreeNodeFlags_SpanLabelWidth, // Renamed in 1.90.7 //ImGuiTreeNodeFlags_AllowItemOverlap = ImGuiTreeNodeFlags_AllowOverlap, // Renamed in 1.89.7 #endif }; @@ -1755,6 +1758,7 @@ enum ImGuiCol_ ImGuiCol_ScrollbarGrabHovered, ImGuiCol_ScrollbarGrabActive, ImGuiCol_CheckMark, // Checkbox tick and RadioButton circle + ImGuiCol_CheckboxSelectedBg, // Checkbox background when Selected, otherwise use FrameBg ImGuiCol_SliderGrab, ImGuiCol_SliderGrabActive, ImGuiCol_Button, @@ -1852,6 +1856,7 @@ enum ImGuiStyleVar_ ImGuiStyleVar_TableAngledHeadersTextAlign,// ImVec2 TableAngledHeadersTextAlign ImGuiStyleVar_TreeLinesSize, // float TreeLinesSize ImGuiStyleVar_TreeLinesRounding, // float TreeLinesRounding + ImGuiStyleVar_DragDropTargetRounding, // float DragDropTargetRounding ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign ImGuiStyleVar_SeparatorSize, // float SeparatorSize @@ -2155,7 +2160,7 @@ struct ImGuiTableSortSpecs // Sorting specification for one column of a table (sizeof == 12 bytes) struct ImGuiTableColumnSortSpecs { - ImGuiID ColumnUserID; // User id of the column (if specified by a TableSetupColumn() call) + ImGuiID ColumnUserID; // User data for the column (if specified by a TableSetupColumn() call in the 'ImGuiID user_data' field). FIXME: Should be called 'UserData'.. ImS16 ColumnIndex; // Index of the column ImS16 SortOrder; // Index within parent ImGuiTableSortSpecs (always stored in order starting from 0, tables sorted on a single criteria will always have a 0 here) ImGuiSortDirection SortDirection; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending @@ -2328,13 +2333,14 @@ struct ImGuiStyle ImGuiTreeNodeFlags TreeLinesFlags; // Default way to draw lines connecting TreeNode hierarchy. ImGuiTreeNodeFlags_DrawLinesNone or ImGuiTreeNodeFlags_DrawLinesFull or ImGuiTreeNodeFlags_DrawLinesToNodes. float TreeLinesSize; // Thickness of outlines when using ImGuiTreeNodeFlags_DrawLines. float TreeLinesRounding; // Radius of lines connecting child nodes to the vertical line. - float DragDropTargetRounding; // Radius of the drag and drop target frame. + float DragDropTargetRounding; // Radius of the drag and drop target frame. When <0.0f: use FrameRounding. float DragDropTargetBorderSize; // Thickness of the drag and drop target border. float DragDropTargetPadding; // Size to expand the drag and drop target from actual target item size. float ColorMarkerSize; // Size of R/G/B/A color markers for ColorEdit4() and for Drags/Sliders when using ImGuiSliderFlags_ColorMarkers. ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered). ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. + float InputTextCursorSize; // Thickness of cursor/caret in InputText(). float SeparatorSize; // Thickness of border in Separator(). Must be >= 1.0f. float SeparatorTextBorderSize; // Thickness of border in SeparatorText() ImVec2 SeparatorTextAlign; // Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center). @@ -2609,7 +2615,7 @@ struct ImGuiIO //void* ImeWindowHandle; // [Obsoleted in 1.87] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning. #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - float FontGlobalScale; // Moved io.FontGlobalScale to style.FontScaleMain in 1.92 (June 2025) + float FontGlobalScale; // Moved io.FontGlobalScale to style.FontScaleMain in 1.92.0 (June 2025) // Legacy: before 1.91.1, clipboard functions were stored in ImGuiIO instead of ImGuiPlatformIO. // As this is will affect all users of custom engines/backends, we are providing proper legacy redirection (will obsolete). @@ -3239,23 +3245,30 @@ struct ImDrawListSplitter }; // Flags for ImDrawList functions -// (Legacy: bit 0 must always correspond to ImDrawFlags_Closed to be backward compatible with old API using a bool. Bits 1..3 must be unused) enum ImDrawFlags_ { ImDrawFlags_None = 0, - ImDrawFlags_Closed = 1 << 0, // PathStroke(), AddPolyline(): specify that shape should be closed (Important: this is always == 1 for legacy reason) - ImDrawFlags_RoundCornersTopLeft = 1 << 4, // AddRect(), AddRectFilled(), PathRect(): enable rounding top-left corner only (when rounding > 0.0f, we default to all corners). Was 0x01. - ImDrawFlags_RoundCornersTopRight = 1 << 5, // AddRect(), AddRectFilled(), PathRect(): enable rounding top-right corner only (when rounding > 0.0f, we default to all corners). Was 0x02. - ImDrawFlags_RoundCornersBottomLeft = 1 << 6, // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-left corner only (when rounding > 0.0f, we default to all corners). Was 0x04. - ImDrawFlags_RoundCornersBottomRight = 1 << 7, // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-right corner only (when rounding > 0.0f, we default to all corners). Wax 0x08. - ImDrawFlags_RoundCornersNone = 1 << 8, // AddRect(), AddRectFilled(), PathRect(): disable rounding on all corners (when rounding > 0.0f). This is NOT zero, NOT an implicit flag! + + // Rounding for AddRect(), AddRectFilled(), PathRect() + // - When not specified, we defaults to ImDrawFlags_RoundCornersAll! So you only need to use those flags if you want another configuration. + ImDrawFlags_RoundCornersTopLeft = 1 << 4, // Round top-left corner only (when rounding > 0.0f, we default to all corners). + ImDrawFlags_RoundCornersTopRight = 1 << 5, // Round top-right corner only (when rounding > 0.0f, we default to all corners). + ImDrawFlags_RoundCornersBottomLeft = 1 << 6, // Round bottom-left corner only (when rounding > 0.0f, we default to all corners). + ImDrawFlags_RoundCornersBottomRight = 1 << 7, // Round bottom-right corner only (when rounding > 0.0f, we default to all corners). + ImDrawFlags_RoundCornersNone = 1 << 8, // Disable rounding even if `float rounding > 0.0f`. This is NOT zero, NOT an implicit flag! + ImDrawFlags_RoundCornersAll = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, // (Default!!) + ImDrawFlags_RoundCornersDefault_ = ImDrawFlags_RoundCornersAll, // Default to ALL corners if none of the _RoundCornersXX flags are specified! ImDrawFlags_RoundCornersTop = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight, ImDrawFlags_RoundCornersBottom = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, ImDrawFlags_RoundCornersLeft = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersTopLeft, ImDrawFlags_RoundCornersRight = ImDrawFlags_RoundCornersBottomRight | ImDrawFlags_RoundCornersTopRight, - ImDrawFlags_RoundCornersAll = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, - ImDrawFlags_RoundCornersDefault_ = ImDrawFlags_RoundCornersAll, // Default to ALL corners if none of the _RoundCornersXX flags are specified. ImDrawFlags_RoundCornersMask_ = ImDrawFlags_RoundCornersAll | ImDrawFlags_RoundCornersNone, + + // Stroke options + ImDrawFlags_Closed = 1 << 9, // PathStroke(), AddPolyline(): specify that shape should be closed. + //ImDrawFlags_Closed = 1 << 0, // Prior to 1.92.8 (May 2026), ImDrawFlags_Closed was guaranteed to be == 1<<0 == 1 for legacy compatibility reason. Hardcoded use of 1 or true should be replaced. + + ImDrawFlags_InvalidMask_ = ~0x7FFFFFF0, // == 0x8000000F, }; // Flags for ImDrawList instance. Those are set automatically by ImGui:: functions from ImGuiIO settings, and generally not manipulated directly. @@ -3267,6 +3280,7 @@ enum ImDrawListFlags_ ImDrawListFlags_AntiAliasedLinesUseTex = 1 << 1, // Enable anti-aliased lines/borders using textures when possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). ImDrawListFlags_AntiAliasedFill = 1 << 2, // Enable anti-aliased edge around filled shapes (rounded rectangles, circles). ImDrawListFlags_AllowVtxOffset = 1 << 3, // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled. + ImDrawListFlags_TextNoPixelSnap = 1 << 4, // Disable automatically snapping AddText() calls to pixel boundaries. }; // Draw command list @@ -3321,7 +3335,9 @@ struct ImDrawList // In future versions we will use textures to provide cheaper and higher-quality circles. // Use AddNgon() and AddNgonFilled() functions if you need to guarantee a specific number of sides. IMGUI_API void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f); - IMGUI_API void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0, float thickness = 1.0f); // a: upper-left, b: lower-right (== upper-left + size) + IMGUI_API void AddLineH(float min_x, float max_x, float y, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddLineV(float x, float min_y, float max_y, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, float thickness = 1.0f, ImDrawFlags flags = 0); // a: upper-left, b: lower-right (== upper-left + size) IMGUI_API void AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0); // a: upper-left, b: lower-right (== upper-left + size) IMGUI_API void AddRectFilledMultiColor(const ImVec2& p_min, const ImVec2& p_max, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left); IMGUI_API void AddQuad(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness = 1.0f); @@ -3342,7 +3358,7 @@ struct ImDrawList // General polygon // - Only simple polygons are supported by filling functions (no self-intersections, no holes). // - Concave polygon fill is more expensive than convex one: it has O(N^2) complexity. Provided as a convenience for the user but not used by the main library. - IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness); + IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, float thickness, ImDrawFlags flags = 0); IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); IMGUI_API void AddConcavePolyFilled(const ImVec2* points, int num_points, ImU32 col); @@ -3362,7 +3378,7 @@ struct ImDrawList inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path.Data[_Path.Size - 1], &pos, 8) != 0) _Path.push_back(pos); } inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; } inline void PathFillConcave(ImU32 col) { AddConcavePolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; } - inline void PathStroke(ImU32 col, ImDrawFlags flags = 0, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, flags, thickness); _Path.Size = 0; } + inline void PathStroke(ImU32 col, float thickness = 1.0f, ImDrawFlags flags = 0) { AddPolyline(_Path.Data, _Path.Size, col, thickness, flags); _Path.Size = 0; } IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 0); IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle IMGUI_API void PathEllipticalArcTo(const ImVec2& center, const ImVec2& radius, float rot, float a_min, float a_max, int num_segments = 0); // Ellipse @@ -3410,8 +3426,15 @@ struct ImDrawList // Obsolete names #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + inline void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags, float thickness) { AddRect(p_min, p_max, col, rounding, thickness, flags); } // OBSOLETED in 1.92.8: NEW FUNCTION SIGNATURE HAS 'thickness' AND 'flags' SWAPPED. + inline void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness) { AddPolyline(points, num_points, col, thickness, flags); } // OBSOLETED in 1.92.8: NEW FUNCTION SIGNATURE HAS 'thickness' AND 'flags' SWAPPED. + inline void PathStroke(ImU32 col, ImDrawFlags flags, float thickness) { PathStroke(col, thickness, flags); } // OBSOLETED in 1.92.8: NEW FUNCTION SIGNATURE HAS 'thickness' AND 'flags' SWAPPED. inline void PushTextureID(ImTextureRef tex_ref) { PushTexture(tex_ref); } // RENAMED in 1.92.0 inline void PopTextureID() { PopTexture(); } // RENAMED in 1.92.0 +#else + void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding /*= 0.0f*/, ImDrawFlags flags /*= 0*/, float thickness /*= 1.0f*/) = delete; + void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness) = delete; + inline void PathStroke(ImU32 col, ImDrawFlags flags /*= 0*/, float thickness /*= 1.0f*/) = delete; #endif //inline void AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f) { AddEllipse(center, ImVec2(radius_x, radius_y), col, rot, num_segments, thickness); } // OBSOLETED in 1.90.5 (Mar 2024) //inline void AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0) { AddEllipseFilled(center, ImVec2(radius_x, radius_y), col, rot, num_segments); } // OBSOLETED in 1.90.5 (Mar 2024) @@ -3491,7 +3514,7 @@ enum ImTextureStatus // You may use ImTextureData::Updates[] for the list, or ImTextureData::UpdateBox for a single bounding box. struct ImTextureRect { - unsigned short x, y; // Upper-left coordinates of rectangle to update + unsigned short x, y; // Upper-left coordinates of rectangle to update, within the parent Pixels[] array. unsigned short w, h; // Size of rectangle to update (in pixels) }; @@ -3513,7 +3536,7 @@ struct ImTextureData int Width; // w r // Texture width int Height; // w r // Texture height int BytesPerPixel; // w r // 4 or 1 - unsigned char* Pixels; // w r // Pointer to buffer holding 'Width*Height' pixels and 'Width*Height*BytesPerPixels' bytes. + unsigned char* Pixels; // w r // Pointer to whole texture buffer holding 'Width*Height' pixels and 'Width*Height*BytesPerPixels' bytes. ImTextureRect UsedRect; // w r // Bounding box encompassing all past and queued Updates[]. ImTextureRect UpdateRect; // w r // Bounding box encompassing all queued Updates[]. ImVector Updates; // w r // Array of individual updates. @@ -3523,6 +3546,7 @@ struct ImTextureData bool WantDestroyNextFrame; // rw - // [Internal] Queued to set ImTextureStatus_WantDestroy next frame. May still be used in the current frame. // Functions + // - If GetPixels() functions asserts while being called by your render loop, it could be caused by calling ImFontAtlas::Clear()/ClearFonts()? ImTextureData() { memset((void*)this, 0, sizeof(*this)); Status = ImTextureStatus_Destroyed; TexID = ImTextureID_Invalid; } ~ImTextureData() { DestroyPixels(); } IMGUI_API void Create(ImTextureFormat format, int w, int h); @@ -3676,15 +3700,17 @@ struct ImFontAtlas IMGUI_API ImFont* AddFontFromMemoryTTF(void* font_data, int font_data_size, float size_pixels = 0.0f, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // Note: Transfer ownership of 'ttf_data' to ImFontAtlas! Will be deleted after destruction of the atlas. Set font_cfg->FontDataOwnedByAtlas=false to keep ownership of your data and it won't be freed. IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_data_size, float size_pixels = 0.0f, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp. IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels = 0.0f, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter. - IMGUI_API void RemoveFont(ImFont* font); - - IMGUI_API void Clear(); // Clear everything (input fonts, output glyphs/textures). - IMGUI_API void CompactCache(); // Compact cached glyphs and texture. + IMGUI_API void RemoveFont(ImFont* font); // Remove a font + IMGUI_API void CompactCache(); // Compact cached glyphs and texture. IMGUI_API void SetFontLoader(const ImFontLoader* font_loader); // Change font loader at runtime. - // As we are transitioning toward a new font system, we expect to obsolete those soon: + // Clearing the atlas/fonts has little use nowadays, unless you want to batch remove all fonts. + // - Since 1.92, you can call ClearFonts() mid-frame, if you load new fonts afterwards. + // - As we are transitioning toward our new font system the semantic for those functions gets increasingly misleading and are often a source of issues. + // TL;DR; most likely, don't use any of those functions. We expect to obsolete/rework them. + IMGUI_API void Clear(); // Clear everything (fonts + textures). Don't call mid-frame! + IMGUI_API void ClearFonts(); // Clear input+output font data/glyphs. New fonts and textures will be recreated afterwards. IMGUI_API void ClearInputData(); // [OBSOLETE] Clear input data (all ImFontConfig structures including sizes, TTF data, glyph ranges, etc.) = all the data used to build the texture and fonts. - IMGUI_API void ClearFonts(); // [OBSOLETE] Clear input+output font data (same as ClearInputData() + glyphs storage, UV coordinates). IMGUI_API void ClearTexData(); // [OBSOLETE] Clear CPU-side copy of the texture data. Saves RAM once the texture has been copied to graphics memory. #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS @@ -3902,7 +3928,7 @@ struct ImFont IMGUI_API void RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c, const ImVec4* cpu_fine_clip = NULL); IMGUI_API void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, ImDrawTextFlags flags = 0); #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - inline const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) { return CalcWordWrapPosition(LegacySize * scale, text, text_end, wrap_width); } + inline const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) { return CalcWordWrapPosition(LegacySize * scale, text, text_end, wrap_width); } // Obsoleted old name in 1.92.0. Note how `scale` was to `size`. #endif // [Internal] Don't use! @@ -4017,11 +4043,11 @@ struct ImGuiPlatformIO // Written by some backends during ImGui_ImplXXXX_RenderDrawData() call to point backend_specific ImGui_ImplXXXX_RenderState* structure. void* Renderer_RenderState; - // Standard draw callbacks + // Standard draw callbacks provided by renderer backend. ImDrawCallback DrawCallback_ResetRenderState; // Request to reset the graphics/render state. - ImDrawCallback DrawCallback_SetSamplerLinear; // Request to set current texture sampling to Linear - ImDrawCallback DrawCallback_SetSamplerNearest; // Request to set current texture sampling to Nearest/Point - //ImDrawCallback DrawCallback_SetSamplerCustom; // Request to set current texture sampling using Backend Specific data. + ImDrawCallback DrawCallback_SetSamplerLinear; // Request backend to set texture sampling to Linear. + ImDrawCallback DrawCallback_SetSamplerNearest; // Request backend to set texture sampling to Nearest/Point. + //ImDrawCallback DrawCallback_SetSamplerCustom; // Request backend to set texture sampling using Backend Specific data. //------------------------------------------------------------------ // Output diff --git a/include/libs/imgui/imgui_impl_metal.h b/include/libs/imgui/imgui_impl_metal.h index 879fadc..8af2c8b 100644 --- a/include/libs/imgui/imgui_impl_metal.h +++ b/include/libs/imgui/imgui_impl_metal.h @@ -5,8 +5,6 @@ // [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef! // [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset). // [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures). -// Missing features or Issues: -// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. diff --git a/include/libs/imgui/imgui_internal.h b/include/libs/imgui/imgui_internal.h index e1b27f2..ffd9d76 100644 --- a/include/libs/imgui/imgui_internal.h +++ b/include/libs/imgui/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.92.8 WIP +// dear imgui, v1.92.9 WIP // (internal structures/api) // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. @@ -35,7 +35,7 @@ Index of this file: // [SECTION] ImGuiContext (main imgui context) // [SECTION] ImGuiWindowTempData, ImGuiWindow // [SECTION] Tab bar, Tab item support -// [SECTION] Table support +// [SECTION] Table support + internal API // [SECTION] ImGui internal API // [SECTION] ImFontLoader // [SECTION] ImFontAtlas internal API @@ -247,6 +247,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer #define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) #define IMGUI_DEBUG_LOG_NAV(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventNav) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) #define IMGUI_DEBUG_LOG_SELECTION(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventSelection) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) +#define IMGUI_DEBUG_LOG_TABLE(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventTable) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) #define IMGUI_DEBUG_LOG_CLIPPER(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventClipper) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) #define IMGUI_DEBUG_LOG_IO(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventIO) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) #define IMGUI_DEBUG_LOG_FONT(...) do { ImGuiContext* g2 = GImGui; if (g2 && g2->DebugLogFlags & ImGuiDebugLogFlags_EventFont) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) // Called from ImFontAtlas function which may operate without a context. @@ -321,6 +322,8 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer #define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xde01") #elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__) #define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xe7f001f0") +#elif defined(__GNUC__) && defined(__aarch64__) +#define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xd4200000") // GDB needs 'set $pc=($pc+4)' to skip this :( #else #define IM_DEBUG_BREAK() IM_ASSERT(0) // It is expected that you define IM_DEBUG_BREAK() into something that will break nicely in a debugger! #endif @@ -531,6 +534,7 @@ inline float ImFloor(float f) { return inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2(ImFloor(v.x), ImFloor(v.y)); } inline float ImTrunc64(float f) { return (float)(ImS64)(f); } inline float ImRound64(float f) { return (float)(ImS64)(f + 0.5f); } // FIXME: Positive values only. +inline float ImCeilFast(float f) { int i = (int)f; return (float)(i + (f > (float)i)); } // Consider using the the bit-hack version (search for "0x1p120f"). inline int ImModPositive(int a, int b) { return (a + b) % b; } inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } @@ -688,6 +692,8 @@ struct ImSpan inline void set(T* data, int size) { Data = data; DataEnd = data + size; } inline void set(T* data, T* data_end) { Data = data; DataEnd = data_end; } + inline void clear() { Data = DataEnd = NULL; } + inline bool empty() const { return Data == DataEnd; } inline int size() const { return (int)(ptrdiff_t)(DataEnd - Data); } inline int size_in_bytes() const { return (int)(ptrdiff_t)(DataEnd - Data) * (int)sizeof(T); } inline T& operator[](int i) { T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; } @@ -872,7 +878,7 @@ struct IMGUI_API ImDrawListSharedData float FontSize; // Current font size (used for for simplified AddText overload) float FontScale; // Current font scale (== FontSize / Font->FontSize) float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() - float CircleSegmentMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc + float CircleTessellationMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc float InitialFringeScale; // Initial scale to apply to AA fringe ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards) ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen() @@ -1211,6 +1217,7 @@ struct IMGUI_API ImGuiMenuColumns }; // Internal temporary state for deactivating InputText() instances. +// Store as part of ImGuiDeactivatedItemData? struct IMGUI_API ImGuiInputTextDeactivatedState { ImGuiID ID; // widget id owning the text state (which just got deactivated) @@ -1456,6 +1463,7 @@ struct ImGuiPtrOrIndex }; // Data used by IsItemDeactivated()/IsItemDeactivatedAfterEdit() functions +// Also see ImGuiInputTextDeactivatedState which is an extension for this for InputText() struct ImGuiDeactivatedItemData { ImGuiID ID; @@ -1700,6 +1708,7 @@ enum ImGuiActivateFlags_ }; // Early work-in-progress API for ScrollToItem() +// FIXME: Missing flags to request making both edges visible when possible. enum ImGuiScrollFlags_ { ImGuiScrollFlags_None = 0, @@ -2043,7 +2052,10 @@ enum ImGuiLocKey : int ImGuiLocKey_TableSizeOne, ImGuiLocKey_TableSizeAllFit, ImGuiLocKey_TableSizeAllDefault, + ImGuiLocKey_TableReset, + //ImGuiLocKey_TableResetAll, ImGuiLocKey_TableResetOrder, + ImGuiLocKey_TableResetVisibility, ImGuiLocKey_WindowingMainMenuBar, ImGuiLocKey_WindowingPopup, ImGuiLocKey_WindowingUntitled, @@ -2097,8 +2109,9 @@ enum ImGuiDebugLogFlags_ ImGuiDebugLogFlags_EventInputRouting = 1 << 9, ImGuiDebugLogFlags_EventDocking = 1 << 10, // Unused in this branch ImGuiDebugLogFlags_EventViewport = 1 << 11, // Unused in this branch + ImGuiDebugLogFlags_EventTable = 1 << 12, - ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventError | ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventIO | ImGuiDebugLogFlags_EventFont | ImGuiDebugLogFlags_EventInputRouting | ImGuiDebugLogFlags_EventDocking | ImGuiDebugLogFlags_EventViewport, + ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventError | ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventTable | ImGuiDebugLogFlags_EventIO | ImGuiDebugLogFlags_EventFont | ImGuiDebugLogFlags_EventInputRouting | ImGuiDebugLogFlags_EventDocking | ImGuiDebugLogFlags_EventViewport, ImGuiDebugLogFlags_OutputToTTY = 1 << 20, // Also send output to TTY ImGuiDebugLogFlags_OutputToDebugger = 1 << 21, // Also send output to Debugger Console [Windows only] ImGuiDebugLogFlags_OutputToTestEngine = 1 << 22, // Also send output to Dear ImGui Test Engine @@ -2874,7 +2887,7 @@ struct IMGUI_API ImGuiTabBar }; //----------------------------------------------------------------------------- -// [SECTION] Table support +// [SECTION] Table support + internal API //----------------------------------------------------------------------------- #define IM_COL32_DISABLE IM_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color. @@ -2896,7 +2909,8 @@ struct ImGuiTableColumn float StretchWeight; // Master width weight when (Flags & _WidthStretch). Often around ~1.0f initially. float InitStretchWeightOrWidth; // Value passed to TableSetupColumn(). For Width it is a content width (_without padding_). ImRect ClipRect; // Clipping rectangle for the column - ImGuiID UserID; // Optional, value passed to TableSetupColumn() + ImGuiID ID; // Hash of column name (ignoring top of ID stack), used for .ini persistence when available. + ImGuiID UserData; // (Optional) User data value passed to TableSetupColumn() float WorkMinX; // Contents region min ~(MinX + CellPaddingX + CellSpacingX1) == cursor start position when entering column float WorkMaxX; // Contents region max ~(MaxX - CellPaddingX - CellSpacingX2) float ItemWidth; // Current item width for the column, preserved across rows @@ -2922,8 +2936,8 @@ struct ImGuiTableColumn bool IsSkipItems; // Do we want item submissions to this column to be completely ignored (no layout will happen). bool IsPreserveWidthAuto; ImS8 NavLayerCurrent; // ImGuiNavLayer in 1 byte - ImU8 AutoFitQueue; // Queue of 8 values for the next 8 frames to request auto-fit - ImU8 CannotSkipItemsQueue; // Queue of 8 values for the next 8 frames to disable Clipped/SkipItem + ImU8 AutoFitQueue : 4; // Queue of 4 values for the next 4 frames to request auto-fit + ImU8 CannotSkipItemsQueue : 4; // Queue of 4 values for the next 4 frames to disable Clipped/SkipItem ImU8 SortDirection : 2; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending ImU8 SortDirectionsAvailCount : 2; // Number of available sort directions (0 to 3) ImU8 SortDirectionsAvailMask : 4; // Mask of available sort directions (1-bit each) @@ -3082,8 +3096,10 @@ struct IMGUI_API ImGuiTable bool IsSettingsRequestLoad; bool IsSettingsDirty; // Set when table settings have changed and needs to be reported into ImGuiTableSettings data. bool IsDefaultDisplayOrder; // Set when display order is unchanged from default (DisplayOrder contains 0...Count-1) - bool IsResetAllRequest; + bool IsDefaultVisibility; // Set when enabled/visibility is unchanged from default + bool IsResetAllRequest; // Set to queue a call to TableResetSettings() in BeginTable() bool IsResetDisplayOrderRequest; + bool IsResetVisibilityRequest; bool IsUnfrozenRows; // Set when we got past the frozen row. bool IsDefaultSizingPolicy; // Set if user didn't explicitly set a sizing policy in BeginTable() bool IsActiveIdAliveBeforeTable; @@ -3108,7 +3124,7 @@ struct IMGUI_API ImGuiTableTempData int TableIndex; // Index in g.Tables.Buf[] pool float LastTimeActive; // Last timestamp this structure was used float AngledHeadersExtraWidth; // Used in EndTable() - ImVector AngledHeadersRequests; // Used in TableAngledHeadersRow() + ImVector AngledHeadersRequests; // Used in TableAngledHeadersRow() // FIXME: Single instance is enough? ImVec2 UserOuterSize; // outer_size.x passed to BeginTable() ImDrawListSplitter DrawSplitter; @@ -3129,18 +3145,18 @@ struct IMGUI_API ImGuiTableTempData struct ImGuiTableColumnSettings { float WidthOrWeight; - ImGuiID UserID; + ImGuiID ID; ImGuiTableColumnIdx Index; ImGuiTableColumnIdx DisplayOrder; ImGuiTableColumnIdx SortOrder; ImU8 SortDirection : 2; - ImS8 IsEnabled : 2; // "Visible" in ini file + ImS8 IsEnabled : 2; // "Visible" in .ini file ImU8 IsStretch : 1; ImGuiTableColumnSettings() { WidthOrWeight = 0.0f; - UserID = 0; + ID = 0; Index = -1; DisplayOrder = SortOrder = -1; SortDirection = ImGuiSortDirection_None; @@ -3163,6 +3179,83 @@ struct ImGuiTableSettings ImGuiTableColumnSettings* GetColumnSettings() { return (ImGuiTableColumnSettings*)(this + 1); } }; +namespace ImGui +{ + // Tables: Candidates for public API + IMGUI_API void TableOpenContextMenu(int column_n = -1); + IMGUI_API void TableSetColumnWidth(int column_n, float width); + IMGUI_API void TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs); + IMGUI_API int TableGetHoveredRow(); // Retrieve *PREVIOUS FRAME* hovered row. This difference with TableGetHoveredColumn() is the reason why this is not public yet. + IMGUI_API float TableGetHeaderRowHeight(); + IMGUI_API float TableGetHeaderAngledMaxLabelWidth(); + IMGUI_API void TablePushBackgroundChannel(); + IMGUI_API void TablePopBackgroundChannel(); + IMGUI_API void TablePushColumnChannel(int column_n); + IMGUI_API void TablePopColumnChannel(); + IMGUI_API void TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label_width, const ImGuiTableHeaderData* data, int data_count); + + // Tables: Internals + inline ImGuiTable* GetCurrentTable() { ImGuiContext& g = *GImGui; return g.CurrentTable; } + IMGUI_API ImGuiTable* TableFindByID(ImGuiID id); + IMGUI_API bool BeginTableEx(const char* name, ImGuiID id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0, 0), float inner_width = 0.0f); + IMGUI_API void TableBeginInitMemory(ImGuiTable* table, int columns_count); + IMGUI_API void TableApplyQueuedRequests(ImGuiTable* table); + IMGUI_API void TableSetupDrawChannels(ImGuiTable* table); + IMGUI_API void TableUpdateLayout(ImGuiTable* table); + IMGUI_API void TableUpdateBorders(ImGuiTable* table); + IMGUI_API void TableUpdateColumnsWeightFromWidth(ImGuiTable* table); + IMGUI_API void TableApplyExternalUnclipRect(ImGuiTable* table, ImRect& rect); + IMGUI_API void TableDrawBorders(ImGuiTable* table); + IMGUI_API void TableDrawDefaultContextMenu(ImGuiTable* table, ImGuiTableFlags flags_for_section_to_display); + IMGUI_API bool TableBeginContextMenuPopup(ImGuiTable* table); + IMGUI_API void TableMergeDrawChannels(ImGuiTable* table); + inline ImGuiTableInstanceData* TableGetInstanceData(ImGuiTable* table, int instance_no) { if (instance_no == 0) return &table->InstanceDataFirst; return &table->InstanceDataExtra[instance_no - 1]; } + inline ImGuiID TableGetInstanceID(ImGuiTable* table, int instance_no) { return TableGetInstanceData(table, instance_no)->TableInstanceID; } + IMGUI_API void TableFixDisplayOrder(ImGuiTable* table); + IMGUI_API void TableSortSpecsSanitize(ImGuiTable* table); + IMGUI_API void TableSortSpecsBuild(ImGuiTable* table); + IMGUI_API ImGuiSortDirection TableGetColumnNextSortDirection(ImGuiTableColumn* column); + IMGUI_API void TableFixColumnSortDirection(ImGuiTable* table, ImGuiTableColumn* column); + IMGUI_API float TableGetColumnWidthAuto(ImGuiTable* table, ImGuiTableColumn* column); + IMGUI_API void TableBeginRow(ImGuiTable* table); + IMGUI_API void TableEndRow(ImGuiTable* table); + IMGUI_API void TableBeginCell(ImGuiTable* table, int column_n); + IMGUI_API void TableEndCell(ImGuiTable* table); + IMGUI_API ImRect TableGetCellBgRect(const ImGuiTable* table, int column_n); + IMGUI_API const char* TableGetColumnName(const ImGuiTable* table, int column_n); + IMGUI_API ImGuiID TableGetColumnResizeID(ImGuiTable* table, int column_n, int instance_no = 0); + IMGUI_API float TableCalcMaxColumnWidth(const ImGuiTable* table, int column_n); + IMGUI_API void TableSetColumnWidthAutoSingle(ImGuiTable* table, int column_n); + IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table); + IMGUI_API void TableSetColumnDisplayOrder(ImGuiTable* table, int column_n, int dst_order); + IMGUI_API void TableQueueSetColumnDisplayOrder(ImGuiTable* table, int column_n, int dst_order); + IMGUI_API void TableRemove(ImGuiTable* table); + IMGUI_API void TableGcCompactTransientBuffers(ImGuiTable* table); + IMGUI_API void TableGcCompactTransientBuffers(ImGuiTableTempData* table); + IMGUI_API void TableGcCompactSettings(); + + // Tables: Settings + IMGUI_API void TableLoadSettings(ImGuiTable* table); + IMGUI_API void TableSaveSettings(ImGuiTable* table); + IMGUI_API void TableResetSettings(ImGuiTable* table); + IMGUI_API ImGuiTableSettings* TableGetBoundSettings(ImGuiTable* table); + IMGUI_API void TableSettingsAddSettingsHandler(); + IMGUI_API ImGuiTableSettings* TableSettingsCreate(ImGuiID id, int columns_count); + IMGUI_API ImGuiTableSettings* TableSettingsFindByID(ImGuiID id); + + // Legacy Columns API (this is not exposed because we will encourage transitioning to the Tables API) + IMGUI_API void SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect); + IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiOldColumnFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). + IMGUI_API void EndColumns(); // close columns + IMGUI_API void PushColumnClipRect(int column_index); + IMGUI_API void PushColumnsBackground(); + IMGUI_API void PopColumnsBackground(); + IMGUI_API ImGuiID GetColumnsID(const char* str_id, int count); + IMGUI_API ImGuiOldColumns* FindOrCreateColumns(ImGuiWindow* window, ImGuiID id); + IMGUI_API float GetColumnOffsetFromNorm(const ImGuiOldColumns* columns, float offset_norm); + IMGUI_API float GetColumnNormFromOffset(const ImGuiOldColumns* columns, float offset); +} + //----------------------------------------------------------------------------- // [SECTION] ImGui internal API // No guarantee of forward compatibility here! @@ -3215,7 +3308,7 @@ namespace ImGui IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags); // Fonts, drawing - IMGUI_API void RegisterUserTexture(ImTextureData* tex); // Register external texture. EXPERIMENTAL: DO NOT USE YET. + IMGUI_API void RegisterUserTexture(ImTextureData* tex); // Register external texture. EXPERIMENTAL. IMGUI_API void UnregisterUserTexture(ImTextureData* tex); IMGUI_API void RegisterFontAtlas(ImFontAtlas* atlas); IMGUI_API void UnregisterFontAtlas(ImFontAtlas* atlas); @@ -3436,7 +3529,7 @@ namespace ImGui IMGUI_API ImGuiID GetKeyOwner(ImGuiKey key); IMGUI_API void SetKeyOwner(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0); IMGUI_API void SetKeyOwnersForKeyChord(ImGuiKeyChord key, ImGuiID owner_id, ImGuiInputFlags flags = 0); - IMGUI_API void SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags); // Set key owner to last item if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'. + IMGUI_API bool SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags); IMGUI_API bool TestKeyOwner(ImGuiKey key, ImGuiID owner_id); // Test that key is either not owned, either owned by 'owner_id' inline ImGuiKeyOwnerData* GetKeyOwnerData(ImGuiContext* ctx, ImGuiKey key) { if (key & ImGuiMod_Mask_) key = ConvertSingleModFlagToKey(key); IM_ASSERT(IsNamedKey(key)); return &ctx->KeysOwnerData[key - ImGuiKey_NamedKey_BEGIN]; } @@ -3494,7 +3587,7 @@ namespace ImGui IMGUI_API void ClearDragDrop(); IMGUI_API bool IsDragDropPayloadBeingAccepted(); IMGUI_API void RenderDragDropTargetRectForItem(const ImRect& bb); - IMGUI_API void RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb); + IMGUI_API void RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb, float rounding); // Typing-Select API // (provide Windows Explorer style "select items by typing partial name" + "cycle through items by typing same letter" feature) @@ -3516,80 +3609,6 @@ namespace ImGui inline ImGuiBoxSelectState* GetBoxSelectState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.BoxSelectState.ID == id && g.BoxSelectState.IsActive) ? &g.BoxSelectState : NULL; } inline ImGuiMultiSelectState* GetMultiSelectState(ImGuiID id) { ImGuiContext& g = *GImGui; return g.MultiSelectStorage.GetByKey(id); } - // Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API) - IMGUI_API void SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect); - IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiOldColumnFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). - IMGUI_API void EndColumns(); // close columns - IMGUI_API void PushColumnClipRect(int column_index); - IMGUI_API void PushColumnsBackground(); - IMGUI_API void PopColumnsBackground(); - IMGUI_API ImGuiID GetColumnsID(const char* str_id, int count); - IMGUI_API ImGuiOldColumns* FindOrCreateColumns(ImGuiWindow* window, ImGuiID id); - IMGUI_API float GetColumnOffsetFromNorm(const ImGuiOldColumns* columns, float offset_norm); - IMGUI_API float GetColumnNormFromOffset(const ImGuiOldColumns* columns, float offset); - - // Tables: Candidates for public API - IMGUI_API void TableOpenContextMenu(int column_n = -1); - IMGUI_API void TableSetColumnWidth(int column_n, float width); - IMGUI_API void TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs); - IMGUI_API int TableGetHoveredRow(); // Retrieve *PREVIOUS FRAME* hovered row. This difference with TableGetHoveredColumn() is the reason why this is not public yet. - IMGUI_API float TableGetHeaderRowHeight(); - IMGUI_API float TableGetHeaderAngledMaxLabelWidth(); - IMGUI_API void TablePushBackgroundChannel(); - IMGUI_API void TablePopBackgroundChannel(); - IMGUI_API void TablePushColumnChannel(int column_n); - IMGUI_API void TablePopColumnChannel(); - IMGUI_API void TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label_width, const ImGuiTableHeaderData* data, int data_count); - - // Tables: Internals - inline ImGuiTable* GetCurrentTable() { ImGuiContext& g = *GImGui; return g.CurrentTable; } - IMGUI_API ImGuiTable* TableFindByID(ImGuiID id); - IMGUI_API bool BeginTableEx(const char* name, ImGuiID id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0, 0), float inner_width = 0.0f); - IMGUI_API void TableBeginInitMemory(ImGuiTable* table, int columns_count); - IMGUI_API void TableBeginApplyRequests(ImGuiTable* table); - IMGUI_API void TableSetupDrawChannels(ImGuiTable* table); - IMGUI_API void TableUpdateLayout(ImGuiTable* table); - IMGUI_API void TableUpdateBorders(ImGuiTable* table); - IMGUI_API void TableUpdateColumnsWeightFromWidth(ImGuiTable* table); - IMGUI_API void TableApplyExternalUnclipRect(ImGuiTable* table, ImRect& rect); - IMGUI_API void TableDrawBorders(ImGuiTable* table); - IMGUI_API void TableDrawDefaultContextMenu(ImGuiTable* table, ImGuiTableFlags flags_for_section_to_display); - IMGUI_API bool TableBeginContextMenuPopup(ImGuiTable* table); - IMGUI_API void TableMergeDrawChannels(ImGuiTable* table); - inline ImGuiTableInstanceData* TableGetInstanceData(ImGuiTable* table, int instance_no) { if (instance_no == 0) return &table->InstanceDataFirst; return &table->InstanceDataExtra[instance_no - 1]; } - inline ImGuiID TableGetInstanceID(ImGuiTable* table, int instance_no) { return TableGetInstanceData(table, instance_no)->TableInstanceID; } - IMGUI_API void TableFixDisplayOrder(ImGuiTable* table); - IMGUI_API void TableSortSpecsSanitize(ImGuiTable* table); - IMGUI_API void TableSortSpecsBuild(ImGuiTable* table); - IMGUI_API ImGuiSortDirection TableGetColumnNextSortDirection(ImGuiTableColumn* column); - IMGUI_API void TableFixColumnSortDirection(ImGuiTable* table, ImGuiTableColumn* column); - IMGUI_API float TableGetColumnWidthAuto(ImGuiTable* table, ImGuiTableColumn* column); - IMGUI_API void TableBeginRow(ImGuiTable* table); - IMGUI_API void TableEndRow(ImGuiTable* table); - IMGUI_API void TableBeginCell(ImGuiTable* table, int column_n); - IMGUI_API void TableEndCell(ImGuiTable* table); - IMGUI_API ImRect TableGetCellBgRect(const ImGuiTable* table, int column_n); - IMGUI_API const char* TableGetColumnName(const ImGuiTable* table, int column_n); - IMGUI_API ImGuiID TableGetColumnResizeID(ImGuiTable* table, int column_n, int instance_no = 0); - IMGUI_API float TableCalcMaxColumnWidth(const ImGuiTable* table, int column_n); - IMGUI_API void TableSetColumnWidthAutoSingle(ImGuiTable* table, int column_n); - IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table); - IMGUI_API void TableSetColumnDisplayOrder(ImGuiTable* table, int column_n, int dst_order); - IMGUI_API void TableQueueSetColumnDisplayOrder(ImGuiTable* table, int column_n, int dst_order); - IMGUI_API void TableRemove(ImGuiTable* table); - IMGUI_API void TableGcCompactTransientBuffers(ImGuiTable* table); - IMGUI_API void TableGcCompactTransientBuffers(ImGuiTableTempData* table); - IMGUI_API void TableGcCompactSettings(); - - // Tables: Settings - IMGUI_API void TableLoadSettings(ImGuiTable* table); - IMGUI_API void TableSaveSettings(ImGuiTable* table); - IMGUI_API void TableResetSettings(ImGuiTable* table); - IMGUI_API ImGuiTableSettings* TableGetBoundSettings(ImGuiTable* table); - IMGUI_API void TableSettingsAddSettingsHandler(); - IMGUI_API ImGuiTableSettings* TableSettingsCreate(ImGuiID id, int columns_count); - IMGUI_API ImGuiTableSettings* TableSettingsFindByID(ImGuiID id); - // Tab Bars inline ImGuiTabBar* GetCurrentTabBar() { ImGuiContext& g = *GImGui; return g.CurrentTabBar; } IMGUI_API ImGuiTabBar* TabBarFindByID(ImGuiID id); @@ -3767,7 +3786,7 @@ namespace ImGui IMGUI_API void DebugNodeStorage(ImGuiStorage* storage, const char* label); IMGUI_API void DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label); IMGUI_API void DebugNodeTable(ImGuiTable* table); - IMGUI_API void DebugNodeTableSettings(ImGuiTableSettings* settings); + IMGUI_API void DebugNodeTableSettings(ImGuiTableSettings* settings, ImGuiTable* table); IMGUI_API void DebugNodeInputTextState(ImGuiInputTextState* state); IMGUI_API void DebugNodeTypingSelectState(ImGuiTypingSelectState* state); IMGUI_API void DebugNodeMultiSelectState(ImGuiMultiSelectState* state); @@ -3977,6 +3996,8 @@ IMGUI_API void ImFontAtlasTextureBlockFill(ImTextureData* dst_tex, IMGUI_API void ImFontAtlasTextureBlockCopy(ImTextureData* src_tex, int src_x, int src_y, ImTextureData* dst_tex, int dst_x, int dst_y, int w, int h); IMGUI_API void ImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas, ImTextureData* tex, int x, int y, int w, int h); +IMGUI_API bool ImTextureDataUpdateNewFrame(ImTextureData* tex); +IMGUI_API void ImTextureDataQueueUpload(ImTextureData* tex, int x, int y, int w, int h); IMGUI_API int ImTextureDataGetFormatBytesPerPixel(ImTextureFormat format); IMGUI_API const char* ImTextureDataGetStatusName(ImTextureStatus status); IMGUI_API const char* ImTextureDataGetFormatName(ImTextureFormat format); diff --git a/include/libs/spdlog/async.h b/include/libs/spdlog/async.h index 92fcd9a..f4e14df 100644 --- a/include/libs/spdlog/async.h +++ b/include/libs/spdlog/async.h @@ -22,7 +22,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { static const size_t default_async_q_size = 8192; @@ -59,14 +59,14 @@ using async_factory = async_factory_impl; using async_factory_nonblock = async_factory_impl; template -inline std::shared_ptr create_async(std::string logger_name, +inline std::shared_ptr create_async(std::string logger_name, SinkArgs &&...sink_args) { return async_factory::create(std::move(logger_name), std::forward(sink_args)...); } template -inline std::shared_ptr create_async_nb(std::string logger_name, +inline std::shared_ptr create_async_nb(std::string logger_name, SinkArgs &&...sink_args) { return async_factory_nonblock::create(std::move(logger_name), std::forward(sink_args)...); @@ -93,7 +93,7 @@ inline void init_thread_pool(size_t q_size, size_t thread_count) { } // get the global thread pool. -inline std::shared_ptr thread_pool() { +inline std::shared_ptr thread_pool() { return details::registry::instance().get_tp(); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/async_logger-inl.h b/include/libs/spdlog/async_logger-inl.h index 382ef07..2ffe94b 100644 --- a/include/libs/spdlog/async_logger-inl.h +++ b/include/libs/spdlog/async_logger-inl.h @@ -13,7 +13,9 @@ #include #include -SPDLOG_INLINE spdlog::async_logger::async_logger(std::string logger_name, +SPDLOG_NAMESPACE_BEGIN + +SPDLOG_INLINE async_logger::async_logger(std::string logger_name, sinks_init_list sinks_list, std::weak_ptr tp, async_overflow_policy overflow_policy) @@ -23,7 +25,7 @@ SPDLOG_INLINE spdlog::async_logger::async_logger(std::string logger_name, std::move(tp), overflow_policy) {} -SPDLOG_INLINE spdlog::async_logger::async_logger(std::string logger_name, +SPDLOG_INLINE async_logger::async_logger(std::string logger_name, sink_ptr single_sink, std::weak_ptr tp, async_overflow_policy overflow_policy) @@ -31,7 +33,7 @@ SPDLOG_INLINE spdlog::async_logger::async_logger(std::string logger_name, std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy) {} // send the log message to the thread pool -SPDLOG_INLINE void spdlog::async_logger::sink_it_(const details::log_msg &msg){ +SPDLOG_INLINE void async_logger::sink_it_(const details::log_msg &msg){ SPDLOG_TRY{if (auto pool_ptr = thread_pool_.lock()){ pool_ptr -> post_log(shared_from_this(), msg, overflow_policy_); } @@ -43,7 +45,7 @@ SPDLOG_LOGGER_CATCH(msg.source) } // send flush request to the thread pool -SPDLOG_INLINE void spdlog::async_logger::flush_(){ +SPDLOG_INLINE void async_logger::flush_(){ SPDLOG_TRY{if (auto pool_ptr = thread_pool_.lock()){ pool_ptr -> post_flush(shared_from_this(), overflow_policy_); } @@ -57,7 +59,7 @@ SPDLOG_LOGGER_CATCH(source_loc()) // // backend functions - called from the thread pool to do the actual job // -SPDLOG_INLINE void spdlog::async_logger::backend_sink_it_(const details::log_msg &incoming_log_msg) { +SPDLOG_INLINE void async_logger::backend_sink_it_(const details::log_msg &incoming_log_msg) { for (auto &sink : sinks_) { if (sink->should_log(incoming_log_msg.level)) { SPDLOG_TRY { sink->log(incoming_log_msg); } @@ -70,15 +72,17 @@ SPDLOG_INLINE void spdlog::async_logger::backend_sink_it_(const details::log_msg } } -SPDLOG_INLINE void spdlog::async_logger::backend_flush_() { +SPDLOG_INLINE void async_logger::backend_flush_() { for (auto &sink : sinks_) { SPDLOG_TRY { sink->flush(); } SPDLOG_LOGGER_CATCH(source_loc()) } } -SPDLOG_INLINE std::shared_ptr spdlog::async_logger::clone(std::string new_name) { - auto cloned = std::make_shared(*this); +SPDLOG_INLINE std::shared_ptr async_logger::clone(std::string new_name) { + auto cloned = std::make_shared(*this); cloned->name_ = std::move(new_name); return cloned; } + +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/async_logger.h b/include/libs/spdlog/async_logger.h index be36153..3534f08 100644 --- a/include/libs/spdlog/async_logger.h +++ b/include/libs/spdlog/async_logger.h @@ -16,7 +16,7 @@ #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN // Async overflow policy - block by default. enum class async_overflow_policy { @@ -67,7 +67,7 @@ class SPDLOG_API async_logger final : public std::enable_shared_from_this thread_pool_; async_overflow_policy overflow_policy_; }; -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "async_logger-inl.h" diff --git a/include/libs/spdlog/cfg/argv.h b/include/libs/spdlog/cfg/argv.h index 64cf389..852803b 100644 --- a/include/libs/spdlog/cfg/argv.h +++ b/include/libs/spdlog/cfg/argv.h @@ -17,7 +17,7 @@ // turn off all logging except for logger1 and logger2: // example.exe "SPDLOG_LEVEL=off,logger1=debug,logger2=info" -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace cfg { // search for SPDLOG_LEVEL= in the args and use it to init the levels @@ -37,4 +37,4 @@ inline void load_argv_levels(int argc, char **argv) { } } // namespace cfg -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/cfg/env.h b/include/libs/spdlog/cfg/env.h index cb153e0..e9d5199 100644 --- a/include/libs/spdlog/cfg/env.h +++ b/include/libs/spdlog/cfg/env.h @@ -17,13 +17,13 @@ // export SPDLOG_LEVEL=debug // // turn off all logging except for logger1: -// export SPDLOG_LEVEL="*=off,logger1=debug" +// export SPDLOG_LEVEL="off,logger1=debug" // // turn off all logging except for logger1 and logger2: // export SPDLOG_LEVEL="off,logger1=debug,logger2=info" -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace cfg { inline void load_env_levels(const char* var = "SPDLOG_LEVEL") { const auto levels_spec = details::os::getenv(var); @@ -33,4 +33,4 @@ inline void load_env_levels(const char* var = "SPDLOG_LEVEL") { } } // namespace cfg -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/cfg/helpers-inl.h b/include/libs/spdlog/cfg/helpers-inl.h index 0105036..294cb61 100644 --- a/include/libs/spdlog/cfg/helpers-inl.h +++ b/include/libs/spdlog/cfg/helpers-inl.h @@ -15,7 +15,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace cfg { namespace helpers { @@ -103,4 +103,4 @@ SPDLOG_INLINE void load_levels(const std::string &levels_spec) { } // namespace helpers } // namespace cfg -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/cfg/helpers.h b/include/libs/spdlog/cfg/helpers.h index 25590e4..1842a43 100644 --- a/include/libs/spdlog/cfg/helpers.h +++ b/include/libs/spdlog/cfg/helpers.h @@ -6,7 +6,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace cfg { namespace helpers { // @@ -22,7 +22,7 @@ SPDLOG_API void load_levels(const std::string &levels_spec); } // namespace helpers } // namespace cfg -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "helpers-inl.h" diff --git a/include/libs/spdlog/common-inl.h b/include/libs/spdlog/common-inl.h index 4ce5e91..60b3198 100644 --- a/include/libs/spdlog/common-inl.h +++ b/include/libs/spdlog/common-inl.h @@ -11,7 +11,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace level { #if __cplusplus >= 201703L @@ -21,15 +21,15 @@ constexpr static const char *short_level_names[] SPDLOG_SHORT_LEVEL_NAMES; -SPDLOG_INLINE const string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT { +SPDLOG_INLINE const string_view_t &to_string_view(level::level_enum l) SPDLOG_NOEXCEPT { return level_string_views[l]; } -SPDLOG_INLINE const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT { +SPDLOG_INLINE const char *to_short_c_str(level::level_enum l) SPDLOG_NOEXCEPT { return short_level_names[l]; } -SPDLOG_INLINE spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT { +SPDLOG_INLINE level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT { auto it = std::find_if(std::begin(level_string_views), std::end(level_string_views), [&name](const string_view_t &level_name) { return level_name.size() == name.size() && @@ -82,4 +82,4 @@ SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno) { SPDLOG_INLINE void throw_spdlog_ex(std::string msg) { SPDLOG_THROW(spdlog_ex(std::move(msg))); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/common.h b/include/libs/spdlog/common.h index 8ff3166..3d1f3f2 100644 --- a/include/libs/spdlog/common.h +++ b/include/libs/spdlog/common.h @@ -120,7 +120,9 @@ } #endif -namespace spdlog { +#include "./namespace.h" + +SPDLOG_NAMESPACE_BEGIN class formatter; @@ -253,13 +255,13 @@ enum level_enum : int { n_levels }; -#define SPDLOG_LEVEL_NAME_TRACE spdlog::string_view_t("trace", 5) -#define SPDLOG_LEVEL_NAME_DEBUG spdlog::string_view_t("debug", 5) -#define SPDLOG_LEVEL_NAME_INFO spdlog::string_view_t("info", 4) -#define SPDLOG_LEVEL_NAME_WARNING spdlog::string_view_t("warning", 7) -#define SPDLOG_LEVEL_NAME_ERROR spdlog::string_view_t("error", 5) -#define SPDLOG_LEVEL_NAME_CRITICAL spdlog::string_view_t("critical", 8) -#define SPDLOG_LEVEL_NAME_OFF spdlog::string_view_t("off", 3) +#define SPDLOG_LEVEL_NAME_TRACE SPDLOG_NAMESPACE::string_view_t("trace", 5) +#define SPDLOG_LEVEL_NAME_DEBUG SPDLOG_NAMESPACE::string_view_t("debug", 5) +#define SPDLOG_LEVEL_NAME_INFO SPDLOG_NAMESPACE::string_view_t("info", 4) +#define SPDLOG_LEVEL_NAME_WARNING SPDLOG_NAMESPACE::string_view_t("warning", 7) +#define SPDLOG_LEVEL_NAME_ERROR SPDLOG_NAMESPACE::string_view_t("error", 5) +#define SPDLOG_LEVEL_NAME_CRITICAL SPDLOG_NAMESPACE::string_view_t("critical", 8) +#define SPDLOG_LEVEL_NAME_OFF SPDLOG_NAMESPACE::string_view_t("off", 3) #if !defined(SPDLOG_LEVEL_NAMES) #define SPDLOG_LEVEL_NAMES \ @@ -276,9 +278,9 @@ enum level_enum : int { { "T", "D", "I", "W", "E", "C", "O" } #endif -SPDLOG_API const string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT; -SPDLOG_API const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT; -SPDLOG_API spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT; +SPDLOG_API const string_view_t &to_string_view(level::level_enum l) SPDLOG_NOEXCEPT; +SPDLOG_API const char *to_short_c_str(level::level_enum l) SPDLOG_NOEXCEPT; +SPDLOG_API level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT; } // namespace level @@ -367,7 +369,7 @@ constexpr T conditional_static_cast(U value) { } } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "common-inl.h" diff --git a/include/libs/spdlog/details/backtracer-inl.h b/include/libs/spdlog/details/backtracer-inl.h index baa06b6..fa3b795 100644 --- a/include/libs/spdlog/details/backtracer-inl.h +++ b/include/libs/spdlog/details/backtracer-inl.h @@ -6,7 +6,7 @@ #ifndef SPDLOG_HEADER_ONLY #include #endif -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { SPDLOG_INLINE backtracer::backtracer(const backtracer &other) { std::lock_guard lock(other.mutex_); @@ -60,4 +60,4 @@ SPDLOG_INLINE void backtracer::foreach_pop(std::function class circular_q { @@ -112,4 +112,4 @@ class circular_q { } }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/console_globals.h b/include/libs/spdlog/details/console_globals.h index 9c55210..f405163 100644 --- a/include/libs/spdlog/details/console_globals.h +++ b/include/libs/spdlog/details/console_globals.h @@ -6,7 +6,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { struct console_mutex { @@ -25,4 +25,4 @@ struct console_nullmutex { } }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/file_helper-inl.h b/include/libs/spdlog/details/file_helper-inl.h index c7260ec..6f57a4b 100644 --- a/include/libs/spdlog/details/file_helper-inl.h +++ b/include/libs/spdlog/details/file_helper-inl.h @@ -15,7 +15,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { SPDLOG_INLINE file_helper::file_helper(const file_event_handlers &event_handlers) @@ -148,4 +148,4 @@ SPDLOG_INLINE std::tuple file_helper::split_by_extension } } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/file_helper.h b/include/libs/spdlog/details/file_helper.h index aba0be4..a7c0d0f 100644 --- a/include/libs/spdlog/details/file_helper.h +++ b/include/libs/spdlog/details/file_helper.h @@ -6,7 +6,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { // Helper class for file sinks. @@ -54,7 +54,7 @@ class SPDLOG_API file_helper { file_event_handlers event_handlers_; }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "file_helper-inl.h" diff --git a/include/libs/spdlog/details/fmt_helper.h b/include/libs/spdlog/details/fmt_helper.h index b629b89..e2102df 100644 --- a/include/libs/spdlog/details/fmt_helper.h +++ b/include/libs/spdlog/details/fmt_helper.h @@ -14,11 +14,11 @@ #endif // Some fmt helpers to efficiently format and pad ints and strings -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { namespace fmt_helper { -inline void append_string_view(spdlog::string_view_t view, memory_buf_t &dest) { +inline void append_string_view(string_view_t view, memory_buf_t &dest) { auto *buf_ptr = view.data(); dest.append(buf_ptr, buf_ptr + view.size()); } @@ -138,4 +138,4 @@ inline ToDuration time_fraction(log_clock::time_point tp) { } // namespace fmt_helper } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/log_msg-inl.h b/include/libs/spdlog/details/log_msg-inl.h index 3a23dcf..de6b23b 100644 --- a/include/libs/spdlog/details/log_msg-inl.h +++ b/include/libs/spdlog/details/log_msg-inl.h @@ -9,14 +9,14 @@ #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { -SPDLOG_INLINE log_msg::log_msg(spdlog::log_clock::time_point log_time, - spdlog::source_loc loc, +SPDLOG_INLINE log_msg::log_msg(log_clock::time_point log_time, + source_loc loc, string_view_t a_logger_name, - spdlog::level::level_enum lvl, - spdlog::string_view_t msg) + level::level_enum lvl, + string_view_t msg) : logger_name(a_logger_name), level(lvl), time(log_time) @@ -29,16 +29,16 @@ SPDLOG_INLINE log_msg::log_msg(spdlog::log_clock::time_point log_time, payload(msg) { } -SPDLOG_INLINE log_msg::log_msg(spdlog::source_loc loc, +SPDLOG_INLINE log_msg::log_msg(source_loc loc, string_view_t a_logger_name, - spdlog::level::level_enum lvl, - spdlog::string_view_t msg) + level::level_enum lvl, + string_view_t msg) : log_msg(os::now(), loc, a_logger_name, lvl, msg) {} SPDLOG_INLINE log_msg::log_msg(string_view_t a_logger_name, - spdlog::level::level_enum lvl, - spdlog::string_view_t msg) + level::level_enum lvl, + string_view_t msg) : log_msg(os::now(), source_loc{}, a_logger_name, lvl, msg) {} } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/log_msg.h b/include/libs/spdlog/details/log_msg.h index 64b4bf6..8f3dead 100644 --- a/include/libs/spdlog/details/log_msg.h +++ b/include/libs/spdlog/details/log_msg.h @@ -6,7 +6,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { struct SPDLOG_API log_msg { log_msg() = default; @@ -33,7 +33,7 @@ struct SPDLOG_API log_msg { string_view_t payload; }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "log_msg-inl.h" diff --git a/include/libs/spdlog/details/log_msg_buffer-inl.h b/include/libs/spdlog/details/log_msg_buffer-inl.h index 45c3383..4102b59 100644 --- a/include/libs/spdlog/details/log_msg_buffer-inl.h +++ b/include/libs/spdlog/details/log_msg_buffer-inl.h @@ -7,7 +7,7 @@ #include #endif -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { SPDLOG_INLINE log_msg_buffer::log_msg_buffer(const log_msg &orig_msg) @@ -51,4 +51,4 @@ SPDLOG_INLINE void log_msg_buffer::update_string_views() { } } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/log_msg_buffer.h b/include/libs/spdlog/details/log_msg_buffer.h index c926cfa..9cfc1a5 100644 --- a/include/libs/spdlog/details/log_msg_buffer.h +++ b/include/libs/spdlog/details/log_msg_buffer.h @@ -5,7 +5,7 @@ #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { // Extend log_msg with internal buffer to store its payload. @@ -25,7 +25,7 @@ class SPDLOG_API log_msg_buffer : public log_msg { }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "log_msg_buffer-inl.h" diff --git a/include/libs/spdlog/details/mpmc_blocking_q.h b/include/libs/spdlog/details/mpmc_blocking_q.h index f153f6c..1fc2d49 100644 --- a/include/libs/spdlog/details/mpmc_blocking_q.h +++ b/include/libs/spdlog/details/mpmc_blocking_q.h @@ -16,7 +16,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { template @@ -170,8 +170,8 @@ class mpmc_blocking_queue { std::mutex queue_mutex_; std::condition_variable push_cv_; std::condition_variable pop_cv_; - spdlog::details::circular_q q_; + circular_q q_; std::atomic discard_counter_{0}; }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/null_mutex.h b/include/libs/spdlog/details/null_mutex.h index 7b391c3..3cfcf91 100644 --- a/include/libs/spdlog/details/null_mutex.h +++ b/include/libs/spdlog/details/null_mutex.h @@ -3,11 +3,13 @@ #pragma once +#include + #include #include // null, no cost dummy "mutex" and dummy "atomic" int -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { struct null_mutex { void lock() const {} @@ -32,4 +34,4 @@ struct null_atomic_int { }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/os-inl.h b/include/libs/spdlog/details/os-inl.h index 92dfe12..bdc5a91 100644 --- a/include/libs/spdlog/details/os-inl.h +++ b/include/libs/spdlog/details/os-inl.h @@ -68,11 +68,11 @@ #define __has_feature(x) 0 // Compatibility with non-clang compilers. #endif -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { namespace os { -SPDLOG_INLINE spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT { +SPDLOG_INLINE log_clock::time_point now() SPDLOG_NOEXCEPT { #if defined __linux__ && defined SPDLOG_CLOCK_COARSE timespec ts; ::clock_gettime(CLOCK_REALTIME_COARSE, &ts); @@ -567,4 +567,4 @@ SPDLOG_INLINE bool fwrite_bytes(const void *ptr, const size_t n_bytes, FILE *fp) } // namespace os } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/os.h b/include/libs/spdlog/details/os.h index 8bb8d14..922959f 100644 --- a/include/libs/spdlog/details/os.h +++ b/include/libs/spdlog/details/os.h @@ -6,11 +6,11 @@ #include // std::time_t #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { namespace os { -SPDLOG_API spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT; +SPDLOG_API log_clock::time_point now() SPDLOG_NOEXCEPT; SPDLOG_API std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT; @@ -120,7 +120,7 @@ SPDLOG_API bool fwrite_bytes(const void *ptr, const size_t n_bytes, FILE *fp); } // namespace os } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "os-inl.h" diff --git a/include/libs/spdlog/details/periodic_worker-inl.h b/include/libs/spdlog/details/periodic_worker-inl.h index c12e9e1..40b97ee 100644 --- a/include/libs/spdlog/details/periodic_worker-inl.h +++ b/include/libs/spdlog/details/periodic_worker-inl.h @@ -7,7 +7,7 @@ #include #endif -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { // stop the worker thread and join it @@ -23,4 +23,4 @@ SPDLOG_INLINE periodic_worker::~periodic_worker() { } } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/periodic_worker.h b/include/libs/spdlog/details/periodic_worker.h index 2f59bb3..ce27fad 100644 --- a/include/libs/spdlog/details/periodic_worker.h +++ b/include/libs/spdlog/details/periodic_worker.h @@ -15,7 +15,7 @@ #include #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { class SPDLOG_API periodic_worker { @@ -51,7 +51,7 @@ class SPDLOG_API periodic_worker { std::condition_variable cv_; }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "periodic_worker-inl.h" diff --git a/include/libs/spdlog/details/registry-inl.h b/include/libs/spdlog/details/registry-inl.h index c1af924..d8c08b7 100644 --- a/include/libs/spdlog/details/registry-inl.h +++ b/include/libs/spdlog/details/registry-inl.h @@ -27,7 +27,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { SPDLOG_INLINE registry::registry() @@ -41,7 +41,7 @@ SPDLOG_INLINE registry::registry() #endif const char *default_logger_name = ""; - default_logger_ = std::make_shared(default_logger_name, std::move(color_sink)); + default_logger_ = std::make_shared(default_logger_name, std::move(color_sink)); loggers_[default_logger_name] = default_logger_; #endif // SPDLOG_DISABLE_DEFAULT_LOGGER @@ -267,4 +267,4 @@ SPDLOG_INLINE void registry::register_or_replace_(std::shared_ptr new_lo } } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/registry.h b/include/libs/spdlog/details/registry.h index 576803e..9b4eb60 100644 --- a/include/libs/spdlog/details/registry.h +++ b/include/libs/spdlog/details/registry.h @@ -18,7 +18,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN class logger; namespace details { @@ -113,7 +113,7 @@ class SPDLOG_API registry { std::unordered_map> loggers_; log_levels log_levels_; std::unique_ptr formatter_; - spdlog::level::level_enum global_log_level_ = level::info; + level::level_enum global_log_level_ = level::info; level::level_enum flush_level_ = level::off; err_handler err_handler_; std::shared_ptr tp_; @@ -124,7 +124,7 @@ class SPDLOG_API registry { }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "registry-inl.h" diff --git a/include/libs/spdlog/details/synchronous_factory.h b/include/libs/spdlog/details/synchronous_factory.h index 4bd5a51..33219b7 100644 --- a/include/libs/spdlog/details/synchronous_factory.h +++ b/include/libs/spdlog/details/synchronous_factory.h @@ -5,18 +5,18 @@ #include "registry.h" -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN // Default logger factory- creates synchronous loggers class logger; struct synchronous_factory { template - static std::shared_ptr create(std::string logger_name, SinkArgs &&...args) { + static std::shared_ptr create(std::string logger_name, SinkArgs &&...args) { auto sink = std::make_shared(std::forward(args)...); - auto new_logger = std::make_shared(std::move(logger_name), std::move(sink)); + auto new_logger = std::make_shared(std::move(logger_name), std::move(sink)); details::registry::instance().initialize_logger(new_logger); return new_logger; } }; -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/tcp_client-windows.h b/include/libs/spdlog/details/tcp_client-windows.h index 956f9f9..b80c6bd 100644 --- a/include/libs/spdlog/details/tcp_client-windows.h +++ b/include/libs/spdlog/details/tcp_client-windows.h @@ -19,7 +19,7 @@ #pragma comment(lib, "Mswsock.lib") #pragma comment(lib, "AdvApi32.lib") -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { class tcp_client { SOCKET socket_ = INVALID_SOCKET; @@ -52,8 +52,10 @@ class tcp_client { bool is_connected() const { return socket_ != INVALID_SOCKET; } void close() { - ::closesocket(socket_); - socket_ = INVALID_SOCKET; + if (socket_ != INVALID_SOCKET) { + ::closesocket(socket_); + socket_ = INVALID_SOCKET; + } } SOCKET fd() const { return socket_; } @@ -154,7 +156,6 @@ class tcp_client { int last_error = 0; if (rv != 0) { last_error = ::WSAGetLastError(); - WSACleanup(); throw_winsock_error_("getaddrinfo failed", last_error); } @@ -163,7 +164,6 @@ class tcp_client { socket_ = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (socket_ == INVALID_SOCKET) { last_error = ::WSAGetLastError(); - WSACleanup(); continue; } if (connect_socket_with_timeout(socket_, rp->ai_addr, (int)rp->ai_addrlen, tv) == 0) { @@ -176,7 +176,6 @@ class tcp_client { } ::freeaddrinfo(addrinfo_result); if (socket_ == INVALID_SOCKET) { - WSACleanup(); throw_winsock_error_("connect failed", last_error); } if (timeout_ms > 0) { @@ -214,4 +213,4 @@ class tcp_client { } }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/tcp_client.h b/include/libs/spdlog/details/tcp_client.h index a6f9b80..2395a66 100644 --- a/include/libs/spdlog/details/tcp_client.h +++ b/include/libs/spdlog/details/tcp_client.h @@ -21,7 +21,7 @@ #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { class tcp_client { int socket_ = -1; @@ -200,4 +200,4 @@ class tcp_client { } }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/thread_pool-inl.h b/include/libs/spdlog/details/thread_pool-inl.h index 3fefc67..e2d23f0 100644 --- a/include/libs/spdlog/details/thread_pool-inl.h +++ b/include/libs/spdlog/details/thread_pool-inl.h @@ -10,7 +10,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, @@ -20,7 +20,7 @@ SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, : q_(q_max_items) { if (threads_n == 0 || threads_n > 1000) { throw_spdlog_ex( - "spdlog::thread_pool(): invalid threads_n param (valid " + "thread_pool(): invalid threads_n param (valid " "range is 1-1000)"); } for (size_t i = 0; i < threads_n; i++) { @@ -122,4 +122,4 @@ bool SPDLOG_INLINE thread_pool::process_next_msg_() { } } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/thread_pool.h b/include/libs/spdlog/details/thread_pool.h index b9303cf..826b3e1 100644 --- a/include/libs/spdlog/details/thread_pool.h +++ b/include/libs/spdlog/details/thread_pool.h @@ -13,12 +13,12 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN class async_logger; namespace details { -using async_logger_ptr = std::shared_ptr; +using async_logger_ptr = std::shared_ptr; enum class async_msg_type { log, flush, terminate }; @@ -110,7 +110,7 @@ class SPDLOG_API thread_pool { }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "thread_pool-inl.h" diff --git a/include/libs/spdlog/details/udp_client-windows.h b/include/libs/spdlog/details/udp_client-windows.h index fd60f28..e16f27b 100644 --- a/include/libs/spdlog/details/udp_client-windows.h +++ b/include/libs/spdlog/details/udp_client-windows.h @@ -21,7 +21,7 @@ #pragma comment(lib, "AdvApi32.lib") #endif -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { class udp_client { static constexpr int TX_BUFFER_SIZE = 1024 * 10; @@ -95,4 +95,4 @@ class udp_client { } }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/details/udp_client.h b/include/libs/spdlog/details/udp_client.h index 9825fdb..dc39ff8 100644 --- a/include/libs/spdlog/details/udp_client.h +++ b/include/libs/spdlog/details/udp_client.h @@ -22,7 +22,7 @@ #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { class udp_client { @@ -77,4 +77,4 @@ class udp_client { } }; } // namespace details -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/fmt/bin_to_hex.h b/include/libs/spdlog/fmt/bin_to_hex.h index 57ef302..10fb8f9 100644 --- a/include/libs/spdlog/fmt/bin_to_hex.h +++ b/include/libs/spdlog/fmt/bin_to_hex.h @@ -36,7 +36,7 @@ // logger->info("Some buffer {:X}", spdlog::to_hex(std::begin(buf), std::end(buf))); // logger->info("Some buffer {:X}", spdlog::to_hex(std::begin(buf), std::end(buf), 16)); -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { template @@ -90,7 +90,7 @@ inline details::dump_info to_hex(const It range_begin, return details::dump_info(range_begin, range_end, size_per_line); } -} // namespace spdlog +SPDLOG_NAMESPACE_END namespace #ifdef SPDLOG_USE_STD_FORMAT @@ -101,7 +101,7 @@ namespace { template -struct formatter, char> { +struct formatter, char> { char delimiter = ' '; bool put_newlines = true; bool put_delimiters = true; @@ -142,7 +142,7 @@ struct formatter, char> { // format the given bytes range as hex template - auto format(const spdlog::details::dump_info &the_range, + auto format(const SPDLOG_NAMESPACE::details::dump_info &the_range, FormatContext &ctx) const -> decltype(ctx.out()) { SPDLOG_CONSTEXPR const char *hex_upper = "0123456789ABCDEF"; SPDLOG_CONSTEXPR const char *hex_lower = "0123456789abcdef"; @@ -217,7 +217,7 @@ struct formatter, char> { *inserter++ = '\n'; if (put_positions) { - spdlog::fmt_lib::format_to(inserter, SPDLOG_FMT_STRING("{:04X}: "), pos); + SPDLOG_NAMESPACE::fmt_lib::format_to(inserter, SPDLOG_FMT_STRING("{:04X}: "), pos); } } }; diff --git a/include/libs/spdlog/formatter.h b/include/libs/spdlog/formatter.h index 4d482f8..0a200ef 100644 --- a/include/libs/spdlog/formatter.h +++ b/include/libs/spdlog/formatter.h @@ -6,7 +6,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN class formatter { public: @@ -14,4 +14,4 @@ class formatter { virtual void format(const details::log_msg &msg, memory_buf_t &dest) = 0; virtual std::unique_ptr clone() const = 0; }; -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/fwd.h b/include/libs/spdlog/fwd.h index 647b16b..b5429ec 100644 --- a/include/libs/spdlog/fwd.h +++ b/include/libs/spdlog/fwd.h @@ -3,7 +3,9 @@ #pragma once -namespace spdlog { +#include "spdlog/namespace.h" + +SPDLOG_NAMESPACE_BEGIN class logger; class formatter; @@ -15,4 +17,4 @@ namespace level { enum level_enum : int; } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/logger-inl.h b/include/libs/spdlog/logger-inl.h index 381f11c..cb54141 100644 --- a/include/libs/spdlog/logger-inl.h +++ b/include/libs/spdlog/logger-inl.h @@ -13,7 +13,7 @@ #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN // public methods SPDLOG_INLINE logger::logger(const logger &other) @@ -39,7 +39,7 @@ SPDLOG_INLINE logger &logger::operator=(logger other) SPDLOG_NOEXCEPT { return *this; } -SPDLOG_INLINE void logger::swap(spdlog::logger &other) SPDLOG_NOEXCEPT { +SPDLOG_INLINE void logger::swap(logger &other) SPDLOG_NOEXCEPT { name_.swap(other.name_); sinks_.swap(other.sinks_); @@ -121,7 +121,7 @@ SPDLOG_INLINE std::shared_ptr logger::clone(std::string logger_name) { } // protected methods -SPDLOG_INLINE void logger::log_it_(const spdlog::details::log_msg &log_msg, +SPDLOG_INLINE void logger::log_it_(const details::log_msg &log_msg, bool log_enabled, bool traceback_enabled) { if (log_enabled) { @@ -194,4 +194,4 @@ SPDLOG_INLINE void logger::err_handler_(const std::string &msg) const { #endif } } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/logger.h b/include/libs/spdlog/logger.h index aeb52c5..b2a0a48 100644 --- a/include/libs/spdlog/logger.h +++ b/include/libs/spdlog/logger.h @@ -45,7 +45,7 @@ #define SPDLOG_LOGGER_CATCH(location) #endif -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN class SPDLOG_API logger { public: @@ -73,7 +73,7 @@ class SPDLOG_API logger { logger(const logger &other); logger(logger &&other) SPDLOG_NOEXCEPT; logger &operator=(logger other) SPDLOG_NOEXCEPT; - void swap(spdlog::logger &other) SPDLOG_NOEXCEPT; + void swap(logger &other) SPDLOG_NOEXCEPT; template void log(source_loc loc, level::level_enum lvl, format_string_t fmt, Args &&...args) { @@ -315,8 +315,8 @@ class SPDLOG_API logger { protected: std::string name_; std::vector sinks_; - spdlog::level_t level_{level::info}; - spdlog::level_t flush_level_{level::off}; + level_t level_{level::info}; + level_t flush_level_{level::off}; err_handler custom_err_handler_{nullptr}; details::backtracer tracer_; @@ -380,7 +380,7 @@ class SPDLOG_API logger { void swap(logger &a, logger &b) noexcept; -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "logger-inl.h" diff --git a/include/libs/spdlog/mdc.h b/include/libs/spdlog/mdc.h index 2f2665a..fd95614 100644 --- a/include/libs/spdlog/mdc.h +++ b/include/libs/spdlog/mdc.h @@ -21,7 +21,7 @@ // spdlog::info("Hello, {}", "World!"); // => [2024-04-26 02:08:05.040] [info] // [mdc_key_1:mdc_value_1] Hello, World! -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN class SPDLOG_API mdc { public: using mdc_map_t = std::map; @@ -49,4 +49,4 @@ class SPDLOG_API mdc { } }; -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/namespace.h b/include/libs/spdlog/namespace.h new file mode 100644 index 0000000..a397a7f --- /dev/null +++ b/include/libs/spdlog/namespace.h @@ -0,0 +1,27 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +// SPDLOG_NAMESPACE is the outermost namespace token used to qualify spdlog names +// in contexts outside a SPDLOG_NAMESPACE_BEGIN block (e.g. logging macros). +// Override it to rename the outer namespace. +#ifndef SPDLOG_NAMESPACE + #define SPDLOG_NAMESPACE spdlog +#endif +// SPDLOG_NAMESPACE_BEGIN / SPDLOG_NAMESPACE_END delimit every spdlog +// declaration, defaulting to "namespace SPDLOG_NAMESPACE { ... }". +// Override both to use a more complex namespace expression, e.g. to wrap +// symbols in an inline sub-namespace (keeps "spdlog::" accessible). +// In C++11/17: +// #define SPDLOG_NAMESPACE_BEGIN namespace spdlog { inline namespace my_copy { +// #define SPDLOG_NAMESPACE_END } } +// In C++20, the nested inline-namespace syntax may be used instead: +// #define SPDLOG_NAMESPACE_BEGIN namespace spdlog::inline my_copy { +// #define SPDLOG_NAMESPACE_END } +#ifndef SPDLOG_NAMESPACE_BEGIN + #define SPDLOG_NAMESPACE_BEGIN namespace SPDLOG_NAMESPACE { +#endif +#ifndef SPDLOG_NAMESPACE_END + #define SPDLOG_NAMESPACE_END } +#endif diff --git a/include/libs/spdlog/pattern_formatter-inl.h b/include/libs/spdlog/pattern_formatter-inl.h index f650627..41b5d6f 100644 --- a/include/libs/spdlog/pattern_formatter-inl.h +++ b/include/libs/spdlog/pattern_formatter-inl.h @@ -32,7 +32,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { /////////////////////////////////////////////////////////////////////// @@ -1347,4 +1347,4 @@ SPDLOG_INLINE void pattern_formatter::compile_pattern_(const std::string &patter formatters_.push_back(std::move(user_chars)); } } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/pattern_formatter.h b/include/libs/spdlog/pattern_formatter.h index 42a7509..ad6c0cf 100644 --- a/include/libs/spdlog/pattern_formatter.h +++ b/include/libs/spdlog/pattern_formatter.h @@ -16,7 +16,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace details { // padding information. @@ -68,12 +68,12 @@ class SPDLOG_API pattern_formatter final : public formatter { explicit pattern_formatter(std::string pattern, pattern_time_type time_type = pattern_time_type::local, - std::string eol = spdlog::details::os::default_eol, + std::string eol = details::os::default_eol, custom_flags custom_user_flags = custom_flags()); // use default pattern is not given explicit pattern_formatter(pattern_time_type time_type = pattern_time_type::local, - std::string eol = spdlog::details::os::default_eol); + std::string eol = details::os::default_eol); pattern_formatter(const pattern_formatter &other) = delete; pattern_formatter &operator=(const pattern_formatter &other) = delete; @@ -111,7 +111,7 @@ class SPDLOG_API pattern_formatter final : public formatter { void compile_pattern_(const std::string &pattern); }; -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "pattern_formatter-inl.h" diff --git a/include/libs/spdlog/sinks/android_sink.h b/include/libs/spdlog/sinks/android_sink.h index c9e1d27..2a1e61d 100644 --- a/include/libs/spdlog/sinks/android_sink.h +++ b/include/libs/spdlog/sinks/android_sink.h @@ -22,7 +22,7 @@ #define SPDLOG_ANDROID_RETRIES 2 #endif -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { /* @@ -85,19 +85,19 @@ class android_sink final : public base_sink { return __android_log_buf_write(ID, prio, tag, text); } - static android_LogPriority convert_to_android_(spdlog::level::level_enum level) { + static android_LogPriority convert_to_android_(level::level_enum level) { switch (level) { - case spdlog::level::trace: + case level::trace: return ANDROID_LOG_VERBOSE; - case spdlog::level::debug: + case level::debug: return ANDROID_LOG_DEBUG; - case spdlog::level::info: + case level::info: return ANDROID_LOG_INFO; - case spdlog::level::warn: + case level::warn: return ANDROID_LOG_WARN; - case spdlog::level::err: + case level::err: return ANDROID_LOG_ERROR; - case spdlog::level::critical: + case level::critical: return ANDROID_LOG_FATAL; default: return ANDROID_LOG_DEFAULT; @@ -120,18 +120,18 @@ using android_sink_buf_st = android_sink; // Create and register android syslog logger -template +template inline std::shared_ptr android_logger_mt(const std::string &logger_name, const std::string &tag = "spdlog") { return Factory::template create(logger_name, tag); } -template +template inline std::shared_ptr android_logger_st(const std::string &logger_name, const std::string &tag = "spdlog") { return Factory::template create(logger_name, tag); } -} // namespace spdlog +SPDLOG_NAMESPACE_END #endif // __ANDROID__ diff --git a/include/libs/spdlog/sinks/ansicolor_sink-inl.h b/include/libs/spdlog/sinks/ansicolor_sink-inl.h index 1d2c544..2673d2d 100644 --- a/include/libs/spdlog/sinks/ansicolor_sink-inl.h +++ b/include/libs/spdlog/sinks/ansicolor_sink-inl.h @@ -10,14 +10,14 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { template SPDLOG_INLINE ansicolor_sink::ansicolor_sink(FILE *target_file, color_mode mode) : target_file_(target_file), mutex_(ConsoleMutex::mutex()), - formatter_(details::make_unique()) + formatter_(details::make_unique()) { set_color_mode_(mode); @@ -71,12 +71,12 @@ SPDLOG_INLINE void ansicolor_sink::flush() { template SPDLOG_INLINE void ansicolor_sink::set_pattern(const std::string &pattern) { std::lock_guard lock(mutex_); - formatter_ = std::unique_ptr(new pattern_formatter(pattern)); + formatter_ = std::unique_ptr(new pattern_formatter(pattern)); } template SPDLOG_INLINE void ansicolor_sink::set_formatter( - std::unique_ptr sink_formatter) { + std::unique_ptr sink_formatter) { std::lock_guard lock(mutex_); formatter_ = std::move(sink_formatter); } @@ -139,4 +139,4 @@ SPDLOG_INLINE ansicolor_stderr_sink::ansicolor_stderr_sink(color_m : ansicolor_sink(stderr, mode) {} } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/ansicolor_sink.h b/include/libs/spdlog/sinks/ansicolor_sink.h index 542888f..052e467 100644 --- a/include/libs/spdlog/sinks/ansicolor_sink.h +++ b/include/libs/spdlog/sinks/ansicolor_sink.h @@ -11,7 +11,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { /** @@ -41,7 +41,7 @@ class ansicolor_sink : public sink { void log(const details::log_msg &msg) override; void flush() override; void set_pattern(const std::string &pattern) override; - void set_formatter(std::unique_ptr sink_formatter) override; + void set_formatter(std::unique_ptr sink_formatter) override; // Formatting codes const string_view_t reset = "\033[m"; @@ -84,7 +84,7 @@ class ansicolor_sink : public sink { private: mutex_t &mutex_; bool should_do_colors_; - std::unique_ptr formatter_; + std::unique_ptr formatter_; std::array colors_; void set_color_mode_(color_mode mode); void print_ccode_(const string_view_t &color_code) const; @@ -111,7 +111,7 @@ using ansicolor_stderr_sink_mt = ansicolor_stderr_sink; using ansicolor_stderr_sink_st = ansicolor_stderr_sink; } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "ansicolor_sink-inl.h" diff --git a/include/libs/spdlog/sinks/base_sink-inl.h b/include/libs/spdlog/sinks/base_sink-inl.h index 4c3625e..4d10dd6 100644 --- a/include/libs/spdlog/sinks/base_sink-inl.h +++ b/include/libs/spdlog/sinks/base_sink-inl.h @@ -13,47 +13,51 @@ #include #include +SPDLOG_NAMESPACE_BEGIN + template -SPDLOG_INLINE spdlog::sinks::base_sink::base_sink() - : formatter_{details::make_unique()} {} +SPDLOG_INLINE sinks::base_sink::base_sink() + : formatter_{details::make_unique()} {} template -SPDLOG_INLINE spdlog::sinks::base_sink::base_sink( - std::unique_ptr formatter) +SPDLOG_INLINE sinks::base_sink::base_sink( + std::unique_ptr formatter) : formatter_{std::move(formatter)} {} template -void SPDLOG_INLINE spdlog::sinks::base_sink::log(const details::log_msg &msg) { +void SPDLOG_INLINE sinks::base_sink::log(const details::log_msg &msg) { std::lock_guard lock(mutex_); sink_it_(msg); } template -void SPDLOG_INLINE spdlog::sinks::base_sink::flush() { +void SPDLOG_INLINE sinks::base_sink::flush() { std::lock_guard lock(mutex_); flush_(); } template -void SPDLOG_INLINE spdlog::sinks::base_sink::set_pattern(const std::string &pattern) { +void SPDLOG_INLINE sinks::base_sink::set_pattern(const std::string &pattern) { std::lock_guard lock(mutex_); set_pattern_(pattern); } template void SPDLOG_INLINE -spdlog::sinks::base_sink::set_formatter(std::unique_ptr sink_formatter) { +sinks::base_sink::set_formatter(std::unique_ptr sink_formatter) { std::lock_guard lock(mutex_); set_formatter_(std::move(sink_formatter)); } template -void SPDLOG_INLINE spdlog::sinks::base_sink::set_pattern_(const std::string &pattern) { - set_formatter_(details::make_unique(pattern)); +void SPDLOG_INLINE sinks::base_sink::set_pattern_(const std::string &pattern) { + set_formatter_(details::make_unique(pattern)); } template void SPDLOG_INLINE -spdlog::sinks::base_sink::set_formatter_(std::unique_ptr sink_formatter) { +sinks::base_sink::set_formatter_(std::unique_ptr sink_formatter) { formatter_ = std::move(sink_formatter); } + +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/base_sink.h b/include/libs/spdlog/sinks/base_sink.h index c4fb4fc..6712783 100644 --- a/include/libs/spdlog/sinks/base_sink.h +++ b/include/libs/spdlog/sinks/base_sink.h @@ -13,13 +13,13 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { template class SPDLOG_API base_sink : public sink { public: base_sink(); - explicit base_sink(std::unique_ptr formatter); + explicit base_sink(std::unique_ptr formatter); ~base_sink() override = default; base_sink(const base_sink &) = delete; @@ -31,20 +31,20 @@ class SPDLOG_API base_sink : public sink { void log(const details::log_msg &msg) final override; void flush() final override; void set_pattern(const std::string &pattern) final override; - void set_formatter(std::unique_ptr sink_formatter) final override; + void set_formatter(std::unique_ptr sink_formatter) final override; protected: // sink formatter - std::unique_ptr formatter_; + std::unique_ptr formatter_; Mutex mutex_; virtual void sink_it_(const details::log_msg &msg) = 0; virtual void flush_() = 0; virtual void set_pattern_(const std::string &pattern); - virtual void set_formatter_(std::unique_ptr sink_formatter); + virtual void set_formatter_(std::unique_ptr sink_formatter); }; } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "base_sink-inl.h" diff --git a/include/libs/spdlog/sinks/basic_file_sink-inl.h b/include/libs/spdlog/sinks/basic_file_sink-inl.h index 8aec33c..b2adea0 100644 --- a/include/libs/spdlog/sinks/basic_file_sink-inl.h +++ b/include/libs/spdlog/sinks/basic_file_sink-inl.h @@ -10,7 +10,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { template @@ -45,4 +45,4 @@ SPDLOG_INLINE void basic_file_sink::flush_() { } } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/basic_file_sink.h b/include/libs/spdlog/sinks/basic_file_sink.h index 23ac6c1..46b6af7 100644 --- a/include/libs/spdlog/sinks/basic_file_sink.h +++ b/include/libs/spdlog/sinks/basic_file_sink.h @@ -11,7 +11,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { /* * Trivial file sink with single file as target @@ -41,7 +41,7 @@ using basic_file_sink_st = basic_file_sink; // // factory functions // -template +template inline std::shared_ptr basic_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate = false, @@ -50,7 +50,7 @@ inline std::shared_ptr basic_logger_mt(const std::string &logger_name, event_handlers); } -template +template inline std::shared_ptr basic_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate = false, @@ -59,7 +59,7 @@ inline std::shared_ptr basic_logger_st(const std::string &logger_name, event_handlers); } -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "basic_file_sink-inl.h" diff --git a/include/libs/spdlog/sinks/callback_sink.h b/include/libs/spdlog/sinks/callback_sink.h index 8f0c8d4..75b6f5b 100644 --- a/include/libs/spdlog/sinks/callback_sink.h +++ b/include/libs/spdlog/sinks/callback_sink.h @@ -10,7 +10,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN // callbacks type typedef std::function custom_log_callback; @@ -41,16 +41,16 @@ using callback_sink_st = callback_sink; // // factory functions // -template +template inline std::shared_ptr callback_logger_mt(const std::string &logger_name, const custom_log_callback &callback) { return Factory::template create(logger_name, callback); } -template +template inline std::shared_ptr callback_logger_st(const std::string &logger_name, const custom_log_callback &callback) { return Factory::template create(logger_name, callback); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/daily_file_sink.h b/include/libs/spdlog/sinks/daily_file_sink.h index fa2582d..63cf5e9 100644 --- a/include/libs/spdlog/sinks/daily_file_sink.h +++ b/include/libs/spdlog/sinks/daily_file_sink.h @@ -20,7 +20,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { /* @@ -145,7 +145,7 @@ class daily_file_sink final : public base_sink { tm now_tm(log_clock::time_point tp) { time_t tnow = log_clock::to_time_t(tp); - return spdlog::details::os::localtime(tnow); + return details::os::localtime(tnow); } log_clock::time_point next_rotation_tp_() { @@ -202,7 +202,7 @@ using daily_file_format_sink_st = // // factory functions // -template +template inline std::shared_ptr daily_logger_mt(const std::string &logger_name, const filename_t &filename, int hour = 0, @@ -214,7 +214,7 @@ inline std::shared_ptr daily_logger_mt(const std::string &logger_name, truncate, max_files, event_handlers); } -template +template inline std::shared_ptr daily_logger_format_mt( const std::string &logger_name, const filename_t &filename, @@ -227,7 +227,7 @@ inline std::shared_ptr daily_logger_format_mt( logger_name, filename, hour, minute, truncate, max_files, event_handlers); } -template +template inline std::shared_ptr daily_logger_st(const std::string &logger_name, const filename_t &filename, int hour = 0, @@ -239,7 +239,7 @@ inline std::shared_ptr daily_logger_st(const std::string &logger_name, truncate, max_files, event_handlers); } -template +template inline std::shared_ptr daily_logger_format_st( const std::string &logger_name, const filename_t &filename, @@ -251,4 +251,4 @@ inline std::shared_ptr daily_logger_format_st( return Factory::template create( logger_name, filename, hour, minute, truncate, max_files, event_handlers); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/dist_sink.h b/include/libs/spdlog/sinks/dist_sink.h index b143e58..26b37f0 100644 --- a/include/libs/spdlog/sinks/dist_sink.h +++ b/include/libs/spdlog/sinks/dist_sink.h @@ -16,7 +16,7 @@ // Distribution sink (mux). Stores a vector of sinks which get called when log // is called -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { template @@ -62,10 +62,10 @@ class dist_sink : public base_sink { } void set_pattern_(const std::string &pattern) override { - set_formatter_(details::make_unique(pattern)); + set_formatter_(details::make_unique(pattern)); } - void set_formatter_(std::unique_ptr sink_formatter) override { + void set_formatter_(std::unique_ptr sink_formatter) override { base_sink::formatter_ = std::move(sink_formatter); for (auto &sub_sink : sinks_) { sub_sink->set_formatter(base_sink::formatter_->clone()); @@ -78,4 +78,4 @@ using dist_sink_mt = dist_sink; using dist_sink_st = dist_sink; } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/dup_filter_sink.h b/include/libs/spdlog/sinks/dup_filter_sink.h index 1071e98..eb38333 100644 --- a/include/libs/spdlog/sinks/dup_filter_sink.h +++ b/include/libs/spdlog/sinks/dup_filter_sink.h @@ -34,7 +34,7 @@ // [2019-06-25 17:50:56.512] [logger] [info] Skipped 3 duplicate messages.. // [2019-06-25 17:50:56.512] [logger] [info] Different Hello -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { template class dup_filter_sink : public dist_sink { @@ -43,12 +43,17 @@ class dup_filter_sink : public dist_sink { explicit dup_filter_sink(std::chrono::duration max_skip_duration) : max_skip_duration_{max_skip_duration} {} + template + explicit dup_filter_sink(std::chrono::duration max_skip_duration, std::vector> sinks) + : max_skip_duration_{max_skip_duration} + , dist_sink(std::move(sinks)) {} + protected: std::chrono::microseconds max_skip_duration_; log_clock::time_point last_msg_time_; std::string last_msg_payload_; size_t skip_counter_ = 0; - level::level_enum skipped_msg_log_level_ = spdlog::level::level_enum::off; + level::level_enum skipped_msg_log_level_ = level::level_enum::off; void sink_it_(const details::log_msg &msg) override { bool filtered = filter_(msg); @@ -88,4 +93,4 @@ using dup_filter_sink_mt = dup_filter_sink; using dup_filter_sink_st = dup_filter_sink; } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/hourly_file_sink.h b/include/libs/spdlog/sinks/hourly_file_sink.h index 3e61872..1a5dfea 100644 --- a/include/libs/spdlog/sinks/hourly_file_sink.h +++ b/include/libs/spdlog/sinks/hourly_file_sink.h @@ -18,7 +18,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { /* @@ -119,7 +119,7 @@ class hourly_file_sink final : public base_sink { tm now_tm(log_clock::time_point tp) { time_t tnow = log_clock::to_time_t(tp); - return spdlog::details::os::localtime(tnow); + return details::os::localtime(tnow); } log_clock::time_point next_rotation_tp_() { @@ -171,7 +171,7 @@ using hourly_file_sink_st = hourly_file_sink; // // factory functions // -template +template inline std::shared_ptr hourly_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate = false, @@ -181,7 +181,7 @@ inline std::shared_ptr hourly_logger_mt(const std::string &logger_name, max_files, event_handlers); } -template +template inline std::shared_ptr hourly_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate = false, @@ -190,4 +190,4 @@ inline std::shared_ptr hourly_logger_st(const std::string &logger_name, return Factory::template create(logger_name, filename, truncate, max_files, event_handlers); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/kafka_sink.h b/include/libs/spdlog/sinks/kafka_sink.h index 91e9878..1abbd02 100644 --- a/include/libs/spdlog/sinks/kafka_sink.h +++ b/include/libs/spdlog/sinks/kafka_sink.h @@ -21,7 +21,7 @@ // kafka header #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { struct kafka_sink_config { @@ -88,32 +88,32 @@ class kafka_sink : public base_sink { }; using kafka_sink_mt = kafka_sink; -using kafka_sink_st = kafka_sink; +using kafka_sink_st = kafka_sink; } // namespace sinks -template +template inline std::shared_ptr kafka_logger_mt(const std::string &logger_name, - spdlog::sinks::kafka_sink_config config) { + sinks::kafka_sink_config config) { return Factory::template create(logger_name, config); } -template +template inline std::shared_ptr kafka_logger_st(const std::string &logger_name, - spdlog::sinks::kafka_sink_config config) { + sinks::kafka_sink_config config) { return Factory::template create(logger_name, config); } -template -inline std::shared_ptr kafka_logger_async_mt( - std::string logger_name, spdlog::sinks::kafka_sink_config config) { +template +inline std::shared_ptr kafka_logger_async_mt( + std::string logger_name, sinks::kafka_sink_config config) { return Factory::template create(logger_name, config); } -template -inline std::shared_ptr kafka_logger_async_st( - std::string logger_name, spdlog::sinks::kafka_sink_config config) { +template +inline std::shared_ptr kafka_logger_async_st( + std::string logger_name, sinks::kafka_sink_config config) { return Factory::template create(logger_name, config); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/loki_sink.h b/include/libs/spdlog/sinks/loki_sink.h new file mode 100644 index 0000000..ae7517e --- /dev/null +++ b/include/libs/spdlog/sinks/loki_sink.h @@ -0,0 +1,149 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +// Grafana Loki sink - sends log messages to Loki via the HTTP push API. +// Requires nlohmann/json (https://github.com/nlohmann/json) and +// cpp-httplib (https://github.com/yhirose/cpp-httplib). +// Docs: https://grafana.com/docs/loki/latest/reference/loki-http-api/#ingest-logs +// +// The default pattern is "%v" (message text only) because Loki stores the timestamp separately and +// (by default) the log level is sent as a "level" stream label. Override with set_pattern() to include +// additional context in the log line (e.g. "%t %v" to prepend the thread id). +// +// For production use, prefer loki_logger_async_mt: sink_it_() makes a blocking +// HTTP call and should not run on the caller's thread. +// +// Limitations: +// - Sends one log entry per HTTP request (no batching). +// - No TLS/auth header support (e.g. Grafana Cloud / auth-protected setups). + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +SPDLOG_NAMESPACE_BEGIN +namespace sinks { + +struct loki_sink_config { + std::string server_host; + int server_port; + std::unordered_map labels; + bool add_level_label = true; + // 0 = use cpp-httplib defaults (300s connect, 300s read/write). Set explicitly + // when using the synchronous factory to bound blocking time in sink_it_(). + int timeout_seconds = 0; + + loki_sink_config(std::string host, int port) + : server_host{std::move(host)}, + server_port{port} {} +}; + +template +class loki_sink : public base_sink { +public: + explicit loki_sink(loki_sink_config config) + : config_{std::move(config)}, + client_(config_.server_host, config_.server_port), + labels_json_(config_.labels) { + // Timestamp and level go into Loki structured fields, so default to message text only. + // Users can call set_pattern() to include additional context (e.g. thread id). + base_sink::set_formatter_( + details::make_unique("%v", pattern_time_type::local, "")); + client_.set_keep_alive(true); + if (config_.timeout_seconds > 0) { + client_.set_connection_timeout(config_.timeout_seconds); + client_.set_read_timeout(config_.timeout_seconds); + client_.set_write_timeout(config_.timeout_seconds); + } + } + + ~loki_sink() override = default; + loki_sink(const loki_sink &) = delete; + loki_sink &operator=(const loki_sink &) = delete; + +protected: + void sink_it_(const details::log_msg &msg) override { + memory_buf_t formatted; + base_sink::formatter_->format(msg, formatted); + auto body = build_json_(msg, std::string(formatted.data(), formatted.size())); + auto res = client_.Post("/loki/api/v1/push", body, "application/json"); + if (!res) + throw_spdlog_ex("loki_sink: connection failed"); + if (res->status != 204) + throw_spdlog_ex("loki_sink: HTTP " + std::to_string(res->status) + " " + res->reason + + (res->body.empty() ? "" : ": " + res->body)); + } + + void flush_() override {} + + void set_pattern_(const std::string &pattern) override { + this->set_formatter_(details::make_unique(pattern, pattern_time_type::local, "")); + } + +private: + std::string build_json_(const details::log_msg &msg, const std::string &line) const { + auto ns = std::chrono::duration_cast( + msg.time.time_since_epoch()) + .count(); + if (ns < 0) ns = 0; + + nlohmann::json labels = labels_json_; + if (config_.add_level_label && !labels.contains("level")) { + auto sv = level::to_string_view(msg.level); + labels["level"] = std::string(sv.data(), sv.size()); + } + + return nlohmann::json{{"streams", {{ + {"stream", labels}, + {"values", nlohmann::json::array({nlohmann::json::array({std::to_string(ns), line})})} + }}}}.dump(); + } + + loki_sink_config config_; + httplib::Client client_; + nlohmann::json labels_json_; +}; + +using loki_sink_mt = loki_sink; +using loki_sink_st = loki_sink; + +} // namespace sinks + +template +inline std::shared_ptr loki_logger_mt(const std::string &logger_name, + sinks::loki_sink_config config) { + return Factory::template create(logger_name, std::move(config)); +} + +template +inline std::shared_ptr loki_logger_st(const std::string &logger_name, + sinks::loki_sink_config config) { + return Factory::template create(logger_name, std::move(config)); +} + +template +inline std::shared_ptr loki_logger_async_mt(const std::string &logger_name, + sinks::loki_sink_config config) { + return Factory::template create(logger_name, std::move(config)); +} + +template +inline std::shared_ptr loki_logger_async_st(const std::string &logger_name, + sinks::loki_sink_config config) { + return Factory::template create(logger_name, std::move(config)); +} + +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/mongo_sink.h b/include/libs/spdlog/sinks/mongo_sink.h index c5b38ab..f289463 100644 --- a/include/libs/spdlog/sinks/mongo_sink.h +++ b/include/libs/spdlog/sinks/mongo_sink.h @@ -23,7 +23,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { template class mongo_sink : public base_sink { @@ -44,7 +44,7 @@ class mongo_sink : public base_sink { db_name_(db_name), coll_name_(collection_name) { try { - client_ = spdlog::details::make_unique(mongocxx::uri{uri}); + client_ = details::make_unique(mongocxx::uri{uri}); } catch (const std::exception &e) { throw_spdlog_ex(fmt_lib::format("Error opening database: {}", e.what())); } @@ -81,11 +81,11 @@ class mongo_sink : public base_sink { #include "spdlog/details/null_mutex.h" #include using mongo_sink_mt = mongo_sink; -using mongo_sink_st = mongo_sink; +using mongo_sink_st = mongo_sink; } // namespace sinks -template +template inline std::shared_ptr mongo_logger_mt( const std::string &logger_name, const std::string &db_name, @@ -95,7 +95,7 @@ inline std::shared_ptr mongo_logger_mt( uri); } -template +template inline std::shared_ptr mongo_logger_st( const std::string &logger_name, const std::string &db_name, @@ -105,4 +105,4 @@ inline std::shared_ptr mongo_logger_st( uri); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/msvc_sink.h b/include/libs/spdlog/sinks/msvc_sink.h index 1fe9892..7b907db 100644 --- a/include/libs/spdlog/sinks/msvc_sink.h +++ b/include/libs/spdlog/sinks/msvc_sink.h @@ -22,7 +22,7 @@ extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char *l #endif extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { /* * MSVC sink (logging using OutputDebugStringA) @@ -63,6 +63,6 @@ using windebug_sink_mt = msvc_sink_mt; using windebug_sink_st = msvc_sink_st; } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END #endif diff --git a/include/libs/spdlog/sinks/null_sink.h b/include/libs/spdlog/sinks/null_sink.h index 74530b5..3114d55 100644 --- a/include/libs/spdlog/sinks/null_sink.h +++ b/include/libs/spdlog/sinks/null_sink.h @@ -9,7 +9,7 @@ #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { template @@ -24,18 +24,18 @@ using null_sink_st = null_sink; } // namespace sinks -template +template inline std::shared_ptr null_logger_mt(const std::string &logger_name) { auto null_logger = Factory::template create(logger_name); null_logger->set_level(level::off); return null_logger; } -template +template inline std::shared_ptr null_logger_st(const std::string &logger_name) { auto null_logger = Factory::template create(logger_name); null_logger->set_level(level::off); return null_logger; } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/ostream_sink.h b/include/libs/spdlog/sinks/ostream_sink.h index 6af9dd0..95d46c0 100644 --- a/include/libs/spdlog/sinks/ostream_sink.h +++ b/include/libs/spdlog/sinks/ostream_sink.h @@ -9,7 +9,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { template class ostream_sink final : public base_sink { @@ -40,4 +40,4 @@ using ostream_sink_mt = ostream_sink; using ostream_sink_st = ostream_sink; } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/qt_sinks.h b/include/libs/spdlog/sinks/qt_sinks.h index ce74f88..2f577b5 100644 --- a/include/libs/spdlog/sinks/qt_sinks.h +++ b/include/libs/spdlog/sinks/qt_sinks.h @@ -24,7 +24,7 @@ // // qt_sink class // -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { template class qt_sink : public base_sink { @@ -243,14 +243,14 @@ using qt_color_sink_st = qt_color_sink; // // log to QTextEdit -template +template inline std::shared_ptr qt_logger_mt(const std::string &logger_name, QTextEdit *qt_object, const std::string &meta_method = "append") { return Factory::template create(logger_name, qt_object, meta_method); } -template +template inline std::shared_ptr qt_logger_st(const std::string &logger_name, QTextEdit *qt_object, const std::string &meta_method = "append") { @@ -258,28 +258,28 @@ inline std::shared_ptr qt_logger_st(const std::string &logger_name, } // log to QPlainTextEdit -template +template inline std::shared_ptr qt_logger_mt(const std::string &logger_name, QPlainTextEdit *qt_object, const std::string &meta_method = "appendPlainText") { return Factory::template create(logger_name, qt_object, meta_method); } -template +template inline std::shared_ptr qt_logger_st(const std::string &logger_name, QPlainTextEdit *qt_object, const std::string &meta_method = "appendPlainText") { return Factory::template create(logger_name, qt_object, meta_method); } // log to QObject -template +template inline std::shared_ptr qt_logger_mt(const std::string &logger_name, QObject *qt_object, const std::string &meta_method) { return Factory::template create(logger_name, qt_object, meta_method); } -template +template inline std::shared_ptr qt_logger_st(const std::string &logger_name, QObject *qt_object, const std::string &meta_method) { @@ -287,7 +287,7 @@ inline std::shared_ptr qt_logger_st(const std::string &logger_name, } // log to QTextEdit with colorized output -template +template inline std::shared_ptr qt_color_logger_mt(const std::string &logger_name, QTextEdit *qt_text_edit, int max_lines, @@ -296,7 +296,7 @@ inline std::shared_ptr qt_color_logger_mt(const std::string &logger_name false, is_utf8); } -template +template inline std::shared_ptr qt_color_logger_st(const std::string &logger_name, QTextEdit *qt_text_edit, int max_lines, @@ -305,4 +305,4 @@ inline std::shared_ptr qt_color_logger_st(const std::string &logger_name false, is_utf8); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/ringbuffer_sink.h b/include/libs/spdlog/sinks/ringbuffer_sink.h index bcdf0ff..ebef6f0 100644 --- a/include/libs/spdlog/sinks/ringbuffer_sink.h +++ b/include/libs/spdlog/sinks/ringbuffer_sink.h @@ -12,7 +12,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { /* * Ring buffer sink @@ -68,4 +68,4 @@ using ringbuffer_sink_st = ringbuffer_sink; } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/rotating_file_sink-inl.h b/include/libs/spdlog/sinks/rotating_file_sink-inl.h index 370fa7c..847be34 100644 --- a/include/libs/spdlog/sinks/rotating_file_sink-inl.h +++ b/include/libs/spdlog/sinks/rotating_file_sink-inl.h @@ -19,7 +19,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { template @@ -176,4 +176,4 @@ SPDLOG_INLINE bool rotating_file_sink::rename_file_(const filename_t &src } } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/rotating_file_sink.h b/include/libs/spdlog/sinks/rotating_file_sink.h index 522dab6..998c881 100644 --- a/include/libs/spdlog/sinks/rotating_file_sink.h +++ b/include/libs/spdlog/sinks/rotating_file_sink.h @@ -11,7 +11,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { // @@ -65,7 +65,7 @@ using rotating_file_sink_st = rotating_file_sink; // // factory functions // -template +template std::shared_ptr rotating_logger_mt(const std::string &logger_name, const filename_t &filename, size_t max_file_size, @@ -76,7 +76,7 @@ std::shared_ptr rotating_logger_mt(const std::string &logger_name, logger_name, filename, max_file_size, max_files, rotate_on_open, event_handlers); } -template +template std::shared_ptr rotating_logger_st(const std::string &logger_name, const filename_t &filename, size_t max_file_size, @@ -86,7 +86,7 @@ std::shared_ptr rotating_logger_st(const std::string &logger_name, return Factory::template create( logger_name, filename, max_file_size, max_files, rotate_on_open, event_handlers); } -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "rotating_file_sink-inl.h" diff --git a/include/libs/spdlog/sinks/sink-inl.h b/include/libs/spdlog/sinks/sink-inl.h index 7ffb33e..705c63f 100644 --- a/include/libs/spdlog/sinks/sink-inl.h +++ b/include/libs/spdlog/sinks/sink-inl.h @@ -9,14 +9,18 @@ #include -SPDLOG_INLINE bool spdlog::sinks::sink::should_log(spdlog::level::level_enum msg_level) const { +SPDLOG_NAMESPACE_BEGIN + +SPDLOG_INLINE bool sinks::sink::should_log(level::level_enum msg_level) const { return msg_level >= level_.load(std::memory_order_relaxed); } -SPDLOG_INLINE void spdlog::sinks::sink::set_level(level::level_enum log_level) { +SPDLOG_INLINE void sinks::sink::set_level(level::level_enum log_level) { level_.store(log_level, std::memory_order_relaxed); } -SPDLOG_INLINE spdlog::level::level_enum spdlog::sinks::sink::level() const { - return static_cast(level_.load(std::memory_order_relaxed)); +SPDLOG_INLINE level::level_enum sinks::sink::level() const { + return static_cast(level_.load(std::memory_order_relaxed)); } + +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/sink.h b/include/libs/spdlog/sinks/sink.h index 9c39522..00837cc 100644 --- a/include/libs/spdlog/sinks/sink.h +++ b/include/libs/spdlog/sinks/sink.h @@ -6,7 +6,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { class SPDLOG_API sink { @@ -15,7 +15,7 @@ class SPDLOG_API sink { virtual void log(const details::log_msg &msg) = 0; virtual void flush() = 0; virtual void set_pattern(const std::string &pattern) = 0; - virtual void set_formatter(std::unique_ptr sink_formatter) = 0; + virtual void set_formatter(std::unique_ptr sink_formatter) = 0; void set_level(level::level_enum log_level); level::level_enum level() const; @@ -27,7 +27,7 @@ class SPDLOG_API sink { }; } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "sink-inl.h" diff --git a/include/libs/spdlog/sinks/stdout_color_sinks-inl.h b/include/libs/spdlog/sinks/stdout_color_sinks-inl.h index 74c8113..cde0703 100644 --- a/include/libs/spdlog/sinks/stdout_color_sinks-inl.h +++ b/include/libs/spdlog/sinks/stdout_color_sinks-inl.h @@ -10,7 +10,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN template SPDLOG_INLINE std::shared_ptr stdout_color_mt(const std::string &logger_name, @@ -35,4 +35,4 @@ SPDLOG_INLINE std::shared_ptr stderr_color_st(const std::string &logger_ color_mode mode) { return Factory::template create(logger_name, mode); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/stdout_color_sinks.h b/include/libs/spdlog/sinks/stdout_color_sinks.h index 9ce2672..eff751b 100644 --- a/include/libs/spdlog/sinks/stdout_color_sinks.h +++ b/include/libs/spdlog/sinks/stdout_color_sinks.h @@ -11,7 +11,7 @@ #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { #ifdef _WIN32 using stdout_color_sink_mt = wincolor_stdout_sink_mt; @@ -26,23 +26,23 @@ using stderr_color_sink_st = ansicolor_stderr_sink_st; #endif } // namespace sinks -template +template std::shared_ptr stdout_color_mt(const std::string &logger_name, color_mode mode = color_mode::automatic); -template +template std::shared_ptr stdout_color_st(const std::string &logger_name, color_mode mode = color_mode::automatic); -template +template std::shared_ptr stderr_color_mt(const std::string &logger_name, color_mode mode = color_mode::automatic); -template +template std::shared_ptr stderr_color_st(const std::string &logger_name, color_mode mode = color_mode::automatic); -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "stdout_color_sinks-inl.h" diff --git a/include/libs/spdlog/sinks/stdout_sinks-inl.h b/include/libs/spdlog/sinks/stdout_sinks-inl.h index 74ec141..349fe09 100644 --- a/include/libs/spdlog/sinks/stdout_sinks-inl.h +++ b/include/libs/spdlog/sinks/stdout_sinks-inl.h @@ -25,7 +25,7 @@ #include // _fileno(..) #endif // _WIN32 -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { @@ -33,7 +33,7 @@ template SPDLOG_INLINE stdout_sink_base::stdout_sink_base(FILE *file) : mutex_(ConsoleMutex::mutex()), file_(file), - formatter_(details::make_unique()) { + formatter_(details::make_unique()) { #ifdef _WIN32 // get windows handle from the FILE* object @@ -43,7 +43,7 @@ SPDLOG_INLINE stdout_sink_base::stdout_sink_base(FILE *file) // and let the log method to do nothing if (handle_ == INVALID_HANDLE_VALUE). // throw only if non stdout/stderr target is requested (probably regular file and not console). if (handle_ == INVALID_HANDLE_VALUE && file != stdout && file != stderr) { - throw_spdlog_ex("spdlog::stdout_sink_base: _get_osfhandle() failed", errno); + throw_spdlog_ex("stdout_sink_base: _get_osfhandle() failed", errno); } #endif // _WIN32 } @@ -82,12 +82,12 @@ SPDLOG_INLINE void stdout_sink_base::flush() { template SPDLOG_INLINE void stdout_sink_base::set_pattern(const std::string &pattern) { std::lock_guard lock(mutex_); - formatter_ = std::unique_ptr(new pattern_formatter(pattern)); + formatter_ = std::unique_ptr(new pattern_formatter(pattern)); } template SPDLOG_INLINE void stdout_sink_base::set_formatter( - std::unique_ptr sink_formatter) { + std::unique_ptr sink_formatter) { std::lock_guard lock(mutex_); formatter_ = std::move(sink_formatter); } @@ -124,4 +124,4 @@ template SPDLOG_INLINE std::shared_ptr stderr_logger_st(const std::string &logger_name) { return Factory::template create(logger_name); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/stdout_sinks.h b/include/libs/spdlog/sinks/stdout_sinks.h index 0b36c16..11483f4 100644 --- a/include/libs/spdlog/sinks/stdout_sinks.h +++ b/include/libs/spdlog/sinks/stdout_sinks.h @@ -12,7 +12,7 @@ #include #endif -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { @@ -33,12 +33,12 @@ class stdout_sink_base : public sink { void flush() override; void set_pattern(const std::string &pattern) override; - void set_formatter(std::unique_ptr sink_formatter) override; + void set_formatter(std::unique_ptr sink_formatter) override; protected: mutex_t &mutex_; FILE *file_; - std::unique_ptr formatter_; + std::unique_ptr formatter_; #ifdef _WIN32 HANDLE handle_; #endif // WIN32 @@ -65,19 +65,19 @@ using stderr_sink_st = stderr_sink; } // namespace sinks // factory methods -template +template std::shared_ptr stdout_logger_mt(const std::string &logger_name); -template +template std::shared_ptr stdout_logger_st(const std::string &logger_name); -template +template std::shared_ptr stderr_logger_mt(const std::string &logger_name); -template +template std::shared_ptr stderr_logger_st(const std::string &logger_name); -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "stdout_sinks-inl.h" diff --git a/include/libs/spdlog/sinks/syslog_sink.h b/include/libs/spdlog/sinks/syslog_sink.h index 913d41b..044dcdb 100644 --- a/include/libs/spdlog/sinks/syslog_sink.h +++ b/include/libs/spdlog/sinks/syslog_sink.h @@ -11,7 +11,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { /** * Sink that write to syslog using the `syscall()` library call. @@ -82,7 +82,7 @@ using syslog_sink_st = syslog_sink; } // namespace sinks // Create and register a syslog logger -template +template inline std::shared_ptr syslog_logger_mt(const std::string &logger_name, const std::string &syslog_ident = "", int syslog_option = 0, @@ -92,7 +92,7 @@ inline std::shared_ptr syslog_logger_mt(const std::string &logger_name, syslog_facility, enable_formatting); } -template +template inline std::shared_ptr syslog_logger_st(const std::string &logger_name, const std::string &syslog_ident = "", int syslog_option = 0, @@ -101,4 +101,4 @@ inline std::shared_ptr syslog_logger_st(const std::string &logger_name, return Factory::template create(logger_name, syslog_ident, syslog_option, syslog_facility, enable_formatting); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/systemd_namespace_sink.h b/include/libs/spdlog/sinks/systemd_namespace_sink.h new file mode 100644 index 0000000..374db24 --- /dev/null +++ b/include/libs/spdlog/sinks/systemd_namespace_sink.h @@ -0,0 +1,159 @@ +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include + +SPDLOG_NAMESPACE_BEGIN +namespace sinks { + +/** + * Sink that opens a stream to a specific systemd journal namespace using + * sd_journal_stream_fd_with_namespace(). This sink cannot utilize extra fields like TID, CODE_LINE, + * or CODE_FUNC since sd_journal_send() does not have a namespace-specific counterpart. Journal does + * interpret kernel-style log level prefixes though, so PRIORITY field is populated correctly. + */ +template +class systemd_namespace_sink : public base_sink { +public: + explicit systemd_namespace_sink(std::string ident, + std::string name_space, + bool enable_formatting) + : enable_formatting_{enable_formatting} { + int stream_fd = -1; + if (name_space.empty()) { + stream_fd = ::sd_journal_stream_fd(ident.c_str(), LOG_INFO, 1); + } else { + stream_fd = ::sd_journal_stream_fd_with_namespace(name_space.c_str(), ident.c_str(), + LOG_INFO, 1); + } + if (stream_fd < 0) { + throw_spdlog_ex( + "Failed opening systemd journal stream to namespace '" + name_space + "'", + -stream_fd); + } + journal_ = ::fdopen(stream_fd, "w"); + if (journal_ == nullptr) { + // Capture errno from the failed fdopen() instead of close() (in case that fails too) + const int saved_errno = errno; + ::close(stream_fd); + throw_spdlog_ex( + "Failed opening systemd journal stream to namespace '" + name_space + "'", + saved_errno); + } + // Use line buffering which matches with journald's line-oriented protocol + if (::setvbuf(journal_, nullptr, _IOLBF, 0) != 0) { + // Capture errno from the failed setvbuf() instead of close() (in case that fails too) + const int saved_errno = errno; + ::close(stream_fd); + throw_spdlog_ex( + "Failed setting line buffering mode for systemd journal stream to namespace '" + + name_space + "'", + saved_errno); + } + } + + ~systemd_namespace_sink() override { + if (journal_ != nullptr) { + ::fclose(journal_); + journal_ = nullptr; + } + } + + systemd_namespace_sink(const systemd_namespace_sink &) = delete; + systemd_namespace_sink &operator=(const systemd_namespace_sink &) = delete; + +protected: + FILE *journal_ = nullptr; + bool enable_formatting_ = false; + using level_prefix_array = std::array; + static constexpr level_prefix_array level_prefixes_ = { + {/* spdlog::level::trace */ SD_DEBUG, + /* spdlog::level::debug */ SD_DEBUG, + /* spdlog::level::info */ SD_INFO, + /* spdlog::level::warn */ SD_WARNING, + /* spdlog::level::err */ SD_ERR, + /* spdlog::level::critical */ SD_CRIT, + /* spdlog::level::off */ SD_INFO}}; + + void sink_it_(const details::log_msg &msg) override { + string_view_t payload; + memory_buf_t formatted; + if (enable_formatting_) { + base_sink::formatter_->format(msg, formatted); + payload = string_view_t(formatted.data(), formatted.size()); + } else { + payload = msg.payload; + } + + // Journal stream is line-oriented; if there's newlines in the payload, send each + // newline-delimited piece separately as its own message. + size_t pos = 0; + while (pos < payload.size()) { + size_t nl_pos = payload.find('\n', pos); + size_t end = (nl_pos == string_view_t::npos) ? payload.size() : nl_pos + 1; + string_view_t one_message = payload.substr(pos, end - pos); + + // Write log level prefix + const auto &prefix = + level_prefixes_.at(static_cast(msg.level)); + write_or_throw_(prefix.data(), prefix.size()); + // Write the message + write_or_throw_(one_message.data(), one_message.size()); + // Append newline if the message didn't have one + if (nl_pos == string_view_t::npos) { + write_or_throw_("\n", 1); + } + + pos = end; + } + } + + void flush_() override { + if (journal_ != nullptr) { + if (::fflush(journal_) != 0) { + throw_spdlog_ex("Failed flush to systemd journal", errno); + } + } + } + +private: + void write_or_throw_(const void *data, size_t n) { + if (journal_ != nullptr) { + if (!details::os::fwrite_bytes(data, n, journal_)) { + throw_spdlog_ex("Failed writing to systemd journal", errno); + } + } + } +}; + +using systemd_namespace_sink_mt = systemd_namespace_sink; +using systemd_namespace_sink_st = systemd_namespace_sink; +} // namespace sinks + +template +inline std::shared_ptr systemd_namespace_logger_mt(const std::string &logger_name, + const std::string &ident, + const std::string &name_space, + bool enable_formatting) { + return Factory::template create( + logger_name, ident, name_space, enable_formatting); +} + +template +inline std::shared_ptr systemd_namespace_logger_st(const std::string &logger_name, + const std::string &ident, + const std::string &name_space, + bool enable_formatting) { + return Factory::template create( + logger_name, ident, name_space, enable_formatting); +} +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/systemd_sink.h b/include/libs/spdlog/sinks/systemd_sink.h index 1ad32ce..114c452 100644 --- a/include/libs/spdlog/sinks/systemd_sink.h +++ b/include/libs/spdlog/sinks/systemd_sink.h @@ -14,7 +14,7 @@ #endif #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { /** @@ -105,17 +105,17 @@ using systemd_sink_st = systemd_sink; } // namespace sinks // Create and register a syslog logger -template +template inline std::shared_ptr systemd_logger_mt(const std::string &logger_name, const std::string &ident = "", bool enable_formatting = false) { return Factory::template create(logger_name, ident, enable_formatting); } -template +template inline std::shared_ptr systemd_logger_st(const std::string &logger_name, const std::string &ident = "", bool enable_formatting = false) { return Factory::template create(logger_name, ident, enable_formatting); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/tcp_sink.h b/include/libs/spdlog/sinks/tcp_sink.h index cffd433..e89547c 100644 --- a/include/libs/spdlog/sinks/tcp_sink.h +++ b/include/libs/spdlog/sinks/tcp_sink.h @@ -25,7 +25,7 @@ // If more complicated behaviour is needed (i.e get responses), you can inherit it and override the // sink_it_ method. -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { struct tcp_sink_config { @@ -41,7 +41,7 @@ struct tcp_sink_config { }; template -class tcp_sink : public spdlog::sinks::base_sink { +class tcp_sink : public sinks::base_sink { public: // connect to tcp host/port or throw if failed // host can be hostname or ip address @@ -68,9 +68,9 @@ class tcp_sink : public spdlog::sinks::base_sink { ~tcp_sink() override = default; protected: - void sink_it_(const spdlog::details::log_msg &msg) override { - spdlog::memory_buf_t formatted; - spdlog::sinks::base_sink::formatter_->format(msg, formatted); + void sink_it_(const details::log_msg &msg) override { + memory_buf_t formatted; + sinks::base_sink::formatter_->format(msg, formatted); if (!client_.is_connected()) { client_.connect(config_.server_host, config_.server_port, config_.timeout_ms); } @@ -83,7 +83,7 @@ class tcp_sink : public spdlog::sinks::base_sink { }; using tcp_sink_mt = tcp_sink; -using tcp_sink_st = tcp_sink; +using tcp_sink_st = tcp_sink; } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/udp_sink.h b/include/libs/spdlog/sinks/udp_sink.h index 9980ef7..e02c36a 100644 --- a/include/libs/spdlog/sinks/udp_sink.h +++ b/include/libs/spdlog/sinks/udp_sink.h @@ -20,7 +20,7 @@ // Simple udp client sink // Sends formatted log via udp -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { struct udp_sink_config { @@ -33,7 +33,7 @@ struct udp_sink_config { }; template -class udp_sink : public spdlog::sinks::base_sink { +class udp_sink : public sinks::base_sink { public: // host can be hostname or ip address explicit udp_sink(const udp_sink_config& sink_config) @@ -42,9 +42,9 @@ class udp_sink : public spdlog::sinks::base_sink { ~udp_sink() override = default; protected: - void sink_it_(const spdlog::details::log_msg &msg) override { - spdlog::memory_buf_t formatted; - spdlog::sinks::base_sink::formatter_->format(msg, formatted); + void sink_it_(const details::log_msg &msg) override { + memory_buf_t formatted; + sinks::base_sink::formatter_->format(msg, formatted); client_.send(formatted.data(), formatted.size()); } @@ -53,17 +53,17 @@ class udp_sink : public spdlog::sinks::base_sink { }; using udp_sink_mt = udp_sink; -using udp_sink_st = udp_sink; +using udp_sink_st = udp_sink; } // namespace sinks // // factory functions // -template +template inline std::shared_ptr udp_logger_mt(const std::string &logger_name, - sinks::udp_sink_config skin_config) { - return Factory::template create(logger_name, skin_config); + sinks::udp_sink_config sink_config) { + return Factory::template create(logger_name, sink_config); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/win_eventlog_sink.h b/include/libs/spdlog/sinks/win_eventlog_sink.h index 2c9b582..d30bd54 100644 --- a/include/libs/spdlog/sinks/win_eventlog_sink.h +++ b/include/libs/spdlog/sinks/win_eventlog_sink.h @@ -43,7 +43,7 @@ Windows Registry Editor Version 5.00 #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { namespace win_eventlog { @@ -257,4 +257,4 @@ using win_eventlog_sink_mt = win_eventlog::win_eventlog_sink; using win_eventlog_sink_st = win_eventlog::win_eventlog_sink; } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/wincolor_sink-inl.h b/include/libs/spdlog/sinks/wincolor_sink-inl.h index 910115c..b037cbd 100644 --- a/include/libs/spdlog/sinks/wincolor_sink-inl.h +++ b/include/libs/spdlog/sinks/wincolor_sink-inl.h @@ -13,13 +13,13 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { template SPDLOG_INLINE wincolor_sink::wincolor_sink(void *out_handle, color_mode mode) : out_handle_(out_handle), mutex_(ConsoleMutex::mutex()), - formatter_(details::make_unique()) { + formatter_(details::make_unique()) { set_color_mode_impl(mode); // set level colors colors_[level::trace] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; // white @@ -82,12 +82,12 @@ void SPDLOG_INLINE wincolor_sink::flush() { template void SPDLOG_INLINE wincolor_sink::set_pattern(const std::string &pattern) { std::lock_guard lock(mutex_); - formatter_ = std::unique_ptr(new pattern_formatter(pattern)); + formatter_ = std::unique_ptr(new pattern_formatter(pattern)); } template void SPDLOG_INLINE -wincolor_sink::set_formatter(std::unique_ptr sink_formatter) { +wincolor_sink::set_formatter(std::unique_ptr sink_formatter) { std::lock_guard lock(mutex_); formatter_ = std::move(sink_formatter); } @@ -169,4 +169,4 @@ template SPDLOG_INLINE wincolor_stderr_sink::wincolor_stderr_sink(color_mode mode) : wincolor_sink(::GetStdHandle(STD_ERROR_HANDLE), mode) {} } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/sinks/wincolor_sink.h b/include/libs/spdlog/sinks/wincolor_sink.h index 743241c..b1501ae 100644 --- a/include/libs/spdlog/sinks/wincolor_sink.h +++ b/include/libs/spdlog/sinks/wincolor_sink.h @@ -14,7 +14,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN namespace sinks { /* * Windows color console sink. Uses WriteConsoleA to write to the console with @@ -34,7 +34,7 @@ class wincolor_sink : public sink { void log(const details::log_msg &msg) override; void flush() override; void set_pattern(const std::string &pattern) override; - void set_formatter(std::unique_ptr sink_formatter) override; + void set_formatter(std::unique_ptr sink_formatter) override; void set_color_mode(color_mode mode); protected: @@ -42,7 +42,7 @@ class wincolor_sink : public sink { void *out_handle_; mutex_t &mutex_; bool should_do_colors_; - std::unique_ptr formatter_; + std::unique_ptr formatter_; std::array colors_; // set foreground color and return the orig console attributes (for resetting later) @@ -75,7 +75,7 @@ using wincolor_stdout_sink_st = wincolor_stdout_sink using wincolor_stderr_sink_mt = wincolor_stderr_sink; using wincolor_stderr_sink_st = wincolor_stderr_sink; } // namespace sinks -} // namespace spdlog +SPDLOG_NAMESPACE_END #ifdef SPDLOG_HEADER_ONLY #include "wincolor_sink-inl.h" diff --git a/include/libs/spdlog/spdlog-inl.h b/include/libs/spdlog/spdlog-inl.h index 56f1916..cc22477 100644 --- a/include/libs/spdlog/spdlog-inl.h +++ b/include/libs/spdlog/spdlog-inl.h @@ -10,7 +10,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN SPDLOG_INLINE void initialize_logger(std::shared_ptr logger) { details::registry::instance().initialize_logger(std::move(logger)); @@ -20,13 +20,13 @@ SPDLOG_INLINE std::shared_ptr get(const std::string &name) { return details::registry::instance().get(name); } -SPDLOG_INLINE void set_formatter(std::unique_ptr formatter) { +SPDLOG_INLINE void set_formatter(std::unique_ptr formatter) { details::registry::instance().set_formatter(std::move(formatter)); } SPDLOG_INLINE void set_pattern(std::string pattern, pattern_time_type time_type) { set_formatter( - std::unique_ptr(new pattern_formatter(std::move(pattern), time_type))); + std::unique_ptr(new pattern_formatter(std::move(pattern), time_type))); } SPDLOG_INLINE void enable_backtrace(size_t n_messages) { @@ -77,15 +77,15 @@ SPDLOG_INLINE void set_automatic_registration(bool automatic_registration) { details::registry::instance().set_automatic_registration(automatic_registration); } -SPDLOG_INLINE std::shared_ptr default_logger() { +SPDLOG_INLINE std::shared_ptr default_logger() { return details::registry::instance().default_logger(); } -SPDLOG_INLINE spdlog::logger *default_logger_raw() { +SPDLOG_INLINE logger *default_logger_raw() { return details::registry::instance().get_default_raw(); } -SPDLOG_INLINE void set_default_logger(std::shared_ptr default_logger) { +SPDLOG_INLINE void set_default_logger(std::shared_ptr default_logger) { details::registry::instance().set_default_logger(std::move(default_logger)); } @@ -93,4 +93,4 @@ SPDLOG_INLINE void apply_logger_env_levels(std::shared_ptr logger) { details::registry::instance().apply_logger_env_levels(std::move(logger)); } -} // namespace spdlog +SPDLOG_NAMESPACE_END diff --git a/include/libs/spdlog/spdlog.h b/include/libs/spdlog/spdlog.h index 649318b..8d18cff 100644 --- a/include/libs/spdlog/spdlog.h +++ b/include/libs/spdlog/spdlog.h @@ -20,7 +20,7 @@ #include #include -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN using default_factory = synchronous_factory; @@ -31,7 +31,7 @@ using default_factory = synchronous_factory; // Example: // spdlog::create("logger_name", "dailylog_filename", 11, 59); template -inline std::shared_ptr create(std::string logger_name, SinkArgs &&...sink_args) { +inline std::shared_ptr create(std::string logger_name, SinkArgs &&...sink_args) { return default_factory::create(std::move(logger_name), std::forward(sink_args)...); } @@ -52,7 +52,7 @@ SPDLOG_API void initialize_logger(std::shared_ptr logger); SPDLOG_API std::shared_ptr get(const std::string &name); // Set global formatter. Each sink in each logger will get a clone of this object -SPDLOG_API void set_formatter(std::unique_ptr formatter); +SPDLOG_API void set_formatter(std::unique_ptr formatter); // Set global format string. // example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v"); @@ -130,11 +130,11 @@ SPDLOG_API void set_automatic_registration(bool automatic_registration); // set_default_logger() *should not* be used concurrently with the default API. // e.g., do not call set_default_logger() from one thread while calling spdlog::info() from another. -SPDLOG_API std::shared_ptr default_logger(); +SPDLOG_API std::shared_ptr default_logger(); -SPDLOG_API spdlog::logger *default_logger_raw(); +SPDLOG_API logger *default_logger_raw(); -SPDLOG_API void set_default_logger(std::shared_ptr default_logger); +SPDLOG_API void set_default_logger(std::shared_ptr default_logger); // Initialize logger level based on environment configs. // @@ -273,7 +273,7 @@ inline void critical(const T &msg) { default_logger_raw()->critical(msg); } -} // namespace spdlog +SPDLOG_NAMESPACE_END // // enable/disable log calls at compile time according to global level. @@ -290,16 +290,16 @@ inline void critical(const T &msg) { #ifndef SPDLOG_NO_SOURCE_LOC #define SPDLOG_LOGGER_CALL(logger, level, ...) \ - (logger)->log(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__) + (logger)->log(SPDLOG_NAMESPACE::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__) #else #define SPDLOG_LOGGER_CALL(logger, level, ...) \ - (logger)->log(spdlog::source_loc{}, level, __VA_ARGS__) + (logger)->log(SPDLOG_NAMESPACE::source_loc{}, level, __VA_ARGS__) #endif #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE #define SPDLOG_LOGGER_TRACE(logger, ...) \ - SPDLOG_LOGGER_CALL(logger, spdlog::level::trace, __VA_ARGS__) -#define SPDLOG_TRACE(...) SPDLOG_LOGGER_TRACE(spdlog::default_logger_raw(), __VA_ARGS__) + SPDLOG_LOGGER_CALL(logger, SPDLOG_NAMESPACE::level::trace, __VA_ARGS__) +#define SPDLOG_TRACE(...) SPDLOG_LOGGER_TRACE(SPDLOG_NAMESPACE::default_logger_raw(), __VA_ARGS__) #else #define SPDLOG_LOGGER_TRACE(logger, ...) (void)0 #define SPDLOG_TRACE(...) (void)0 @@ -307,32 +307,32 @@ inline void critical(const T &msg) { #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_DEBUG #define SPDLOG_LOGGER_DEBUG(logger, ...) \ - SPDLOG_LOGGER_CALL(logger, spdlog::level::debug, __VA_ARGS__) -#define SPDLOG_DEBUG(...) SPDLOG_LOGGER_DEBUG(spdlog::default_logger_raw(), __VA_ARGS__) + SPDLOG_LOGGER_CALL(logger, SPDLOG_NAMESPACE::level::debug, __VA_ARGS__) +#define SPDLOG_DEBUG(...) SPDLOG_LOGGER_DEBUG(SPDLOG_NAMESPACE::default_logger_raw(), __VA_ARGS__) #else #define SPDLOG_LOGGER_DEBUG(logger, ...) (void)0 #define SPDLOG_DEBUG(...) (void)0 #endif #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_INFO -#define SPDLOG_LOGGER_INFO(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::info, __VA_ARGS__) -#define SPDLOG_INFO(...) SPDLOG_LOGGER_INFO(spdlog::default_logger_raw(), __VA_ARGS__) +#define SPDLOG_LOGGER_INFO(logger, ...) SPDLOG_LOGGER_CALL(logger, SPDLOG_NAMESPACE::level::info, __VA_ARGS__) +#define SPDLOG_INFO(...) SPDLOG_LOGGER_INFO(SPDLOG_NAMESPACE::default_logger_raw(), __VA_ARGS__) #else #define SPDLOG_LOGGER_INFO(logger, ...) (void)0 #define SPDLOG_INFO(...) (void)0 #endif #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_WARN -#define SPDLOG_LOGGER_WARN(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::warn, __VA_ARGS__) -#define SPDLOG_WARN(...) SPDLOG_LOGGER_WARN(spdlog::default_logger_raw(), __VA_ARGS__) +#define SPDLOG_LOGGER_WARN(logger, ...) SPDLOG_LOGGER_CALL(logger, SPDLOG_NAMESPACE::level::warn, __VA_ARGS__) +#define SPDLOG_WARN(...) SPDLOG_LOGGER_WARN(SPDLOG_NAMESPACE::default_logger_raw(), __VA_ARGS__) #else #define SPDLOG_LOGGER_WARN(logger, ...) (void)0 #define SPDLOG_WARN(...) (void)0 #endif #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_ERROR -#define SPDLOG_LOGGER_ERROR(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::err, __VA_ARGS__) -#define SPDLOG_ERROR(...) SPDLOG_LOGGER_ERROR(spdlog::default_logger_raw(), __VA_ARGS__) +#define SPDLOG_LOGGER_ERROR(logger, ...) SPDLOG_LOGGER_CALL(logger, SPDLOG_NAMESPACE::level::err, __VA_ARGS__) +#define SPDLOG_ERROR(...) SPDLOG_LOGGER_ERROR(SPDLOG_NAMESPACE::default_logger_raw(), __VA_ARGS__) #else #define SPDLOG_LOGGER_ERROR(logger, ...) (void)0 #define SPDLOG_ERROR(...) (void)0 @@ -340,8 +340,8 @@ inline void critical(const T &msg) { #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_CRITICAL #define SPDLOG_LOGGER_CRITICAL(logger, ...) \ - SPDLOG_LOGGER_CALL(logger, spdlog::level::critical, __VA_ARGS__) -#define SPDLOG_CRITICAL(...) SPDLOG_LOGGER_CRITICAL(spdlog::default_logger_raw(), __VA_ARGS__) + SPDLOG_LOGGER_CALL(logger, SPDLOG_NAMESPACE::level::critical, __VA_ARGS__) +#define SPDLOG_CRITICAL(...) SPDLOG_LOGGER_CRITICAL(SPDLOG_NAMESPACE::default_logger_raw(), __VA_ARGS__) #else #define SPDLOG_LOGGER_CRITICAL(logger, ...) (void)0 #define SPDLOG_CRITICAL(...) (void)0 diff --git a/include/libs/spdlog/stopwatch.h b/include/libs/spdlog/stopwatch.h index 54ab3d3..85c13b5 100644 --- a/include/libs/spdlog/stopwatch.h +++ b/include/libs/spdlog/stopwatch.h @@ -5,6 +5,7 @@ #include #include +#include // Stopwatch support for spdlog (using std::chrono::steady_clock). // Displays elapsed seconds since construction as double. @@ -17,7 +18,7 @@ // spdlog::info("Elapsed: {:.6} seconds", sw); => "Elapsed 0.005163 seconds" // // -// If other units are needed (e.g. millis instead of double), include "fmt/chrono.h" and use +// If other units are needed (e.g. millis instead of seconds), include "fmt/chrono.h" and use // "duration_cast<..>(sw.elapsed())": // // #include @@ -26,7 +27,7 @@ // using std::chrono::milliseconds; // spdlog::info("Elapsed {}", duration_cast(sw.elapsed())); => "Elapsed 5ms" -namespace spdlog { +SPDLOG_NAMESPACE_BEGIN class stopwatch { using clock = std::chrono::steady_clock; std::chrono::time_point start_tp_; @@ -45,7 +46,7 @@ class stopwatch { void reset() { start_tp_ = clock::now(); } }; -} // namespace spdlog +SPDLOG_NAMESPACE_END // Support for fmt formatting (e.g. "{:012.9}" or just "{}") namespace @@ -57,9 +58,9 @@ namespace { template <> -struct formatter : formatter { +struct formatter : formatter { template - auto format(const spdlog::stopwatch &sw, FormatContext &ctx) const -> decltype(ctx.out()) { + auto format(const SPDLOG_NAMESPACE::stopwatch &sw, FormatContext &ctx) const -> decltype(ctx.out()) { return formatter::format(sw.elapsed().count(), ctx); } }; diff --git a/include/libs/spdlog/tweakme.h b/include/libs/spdlog/tweakme.h index e624e5e..d609298 100644 --- a/include/libs/spdlog/tweakme.h +++ b/include/libs/spdlog/tweakme.h @@ -78,7 +78,7 @@ // In this case spdlog will try to include so set your -I flag // accordingly. // -#define SPDLOG_FMT_EXTERNAL +// #define SPDLOG_FMT_EXTERNAL /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -102,8 +102,9 @@ /////////////////////////////////////////////////////////////////////////////// // Uncomment to customize level names (e.g. "MY TRACE") // -#define SPDLOG_LEVEL_NAMES { "TRACE", "DEBUG", "INFO", "WARNING", "ERROR", "FATAL", "OFF" } - +// #define SPDLOG_LEVEL_NAMES { "MY TRACE", "MY DEBUG", "MY INFO", "MY WARNING", "MY ERROR", "MY +// CRITICAL", "OFF" } +// // For C++17 use string_view_literals: // // #include diff --git a/include/libs/stb_image_resize2.h b/include/libs/stb_image_resize2.h index 6146ab7..0798976 100644 --- a/include/libs/stb_image_resize2.h +++ b/include/libs/stb_image_resize2.h @@ -1,4 +1,4 @@ -/* stb_image_resize2 - v2.17 - public domain image resizing +/* stb_image_resize2 - v2.18 - public domain image resizing by Jeff Roberts (v2) and Jorge L Rodriguez http://github.com/nothings/stb @@ -141,13 +141,13 @@ COLOR+ALPHA buffer types tell the resizer to do. When you use the pixel layouts STBIR_RGBA, STBIR_BGRA, STBIR_ARGB, - STBIR_ABGR, STBIR_RX, or STBIR_XR you are telling us that the pixels are + STBIR_ABGR, STBIR_RA, or STBIR_AR you are telling us that the pixels are non-premultiplied. In these cases, the resizer will alpha weight the colors (effectively creating the premultiplied image), do the filtering, and then convert back to non-premult on exit. - When you use the pixel layouts STBIR_RGBA_PM, STBIR_RGBA_PM, STBIR_RGBA_PM, - STBIR_RGBA_PM, STBIR_RX_PM or STBIR_XR_PM, you are telling that the pixels + When you use the pixel layouts STBIR_RGBA_PM, STBIR_BGRA_PM, STBIR_ARGB_PM, + STBIR_ABGR_PM, STBIR_RA_PM or STBIR_AR_PM, you are telling that the pixels ARE premultiplied. In this case, the resizer doesn't have to do the premultipling - it can filter directly on the input. This about twice as fast as the non-premultiplied case, so it's the right option if your data is @@ -329,6 +329,10 @@ Nathan Reed: warning fixes for 1.0 REVISIONS + 2.18 (2026-03-25) fixed coefficient calculation when skipping a coefficient off + the left side of the window, added non-aligned access safe + memcpy mode for scalar path, fixed various typos, and fixed + define error in the float clamp output mode. 2.17 (2025-10-25) silly format bug in easy-to-use APIs. 2.16 (2025-10-21) fixed the easy-to-use APIs to allow inverted bitmaps (negative strides), fix vertical filter kernel callback, fix threaded @@ -1197,7 +1201,7 @@ static stbir__inline stbir_uint8 stbir__linear_to_srgb_uchar(float in) #define STBIR_AVX2 #endif #if defined( _MSC_VER ) && !defined(__clang__) - #ifndef STBIR_FP16C // FP16C instructions are on all AVX2 cpus, so we can autoselect it here on microsoft - clang needs -m16c + #ifndef STBIR_FP16C // FP16C instructions are on all AVX2 cpus, so we can autoselect it here on microsoft - clang needs -mf16c #define STBIR_FP16C #endif #endif @@ -2568,7 +2572,7 @@ static const STBIR__SIMDF_CONST(STBIR_simd_point5, 0.5f); static const STBIR__SIMDF_CONST(STBIR_ones, 1.0f); static const STBIR__SIMDI_CONST(STBIR_almost_zero, (127 - 13) << 23); static const STBIR__SIMDI_CONST(STBIR_almost_one, 0x3f7fffff); -static const STBIR__SIMDI_CONST(STBIR_mastissa_mask, 0xff); +static const STBIR__SIMDI_CONST(STBIR_mantissa_mask, 0xff); static const STBIR__SIMDI_CONST(STBIR_topscale, 0x02000000); // Basically, in simd mode, we unroll the proper amount, and we don't want @@ -2839,16 +2843,34 @@ static void stbir_overlapping_memcpy( void * dest, void const * src, size_t byte char STBIR_SIMD_STREAMOUT_PTR( * ) s_end = ((char*) src) + bytes; ptrdiff_t ofs_to_dest = (char*)dest - (char*)src; - if ( ofs_to_dest >= 8 ) // is the overlap more than 8 away? + if ( ofs_to_dest >= 8 ) // is the overlap more than 8 away { char STBIR_SIMD_STREAMOUT_PTR( * ) s_end8 = ((char*) src) + (bytes&~7); - STBIR_NO_UNROLL_LOOP_START - do + + if ( ( ( ((ptrdiff_t)dest)|((ptrdiff_t)src) ) & 7 ) == 0 ) // is it 8byte aligned? { - STBIR_NO_UNROLL(sd); - *(stbir_uint64*)( sd + ofs_to_dest ) = *(stbir_uint64*) sd; - sd += 8; - } while ( sd < s_end8 ); + STBIR_NO_UNROLL_LOOP_START + do + { + STBIR_NO_UNROLL(sd); + *(stbir_uint64*)( sd + ofs_to_dest ) = *(stbir_uint64*) sd; + sd += 8; + } while ( sd < s_end8 ); + } + else + { + STBIR_NO_UNROLL_LOOP_START + do + { + int a,b; + STBIR_NO_UNROLL(sd); + a = ((int*)sd)[0]; + b = ((int*)sd)[1]; + ((int*)( sd + ofs_to_dest ))[0] = a; + ((int*)( sd + ofs_to_dest ))[1] = b; + sd += 8; + } while ( sd < s_end8 ); + } if ( sd == s_end ) return; @@ -3241,7 +3263,7 @@ static void stbir__get_extents( stbir__sampler * samp, stbir__extents * scanline newspan->n1 = ( max_left - min_left ) - left_margin; scanline_extents->edge_sizes[0] = 0; // don't need to copy the left margin, since we are directly decoding into the margin } - // if we can't merge the min_left range, add it as a second range + // if we can't merge the min_right range, add it as a second range else if ( ( right_margin ) && ( min_right != 0x7fffffff ) ) { @@ -3357,23 +3379,29 @@ static void stbir__calculate_coefficients_for_gather_upsample( float out_filter_ static void stbir__insert_coeff( stbir__contributors * contribs, float * coeffs, int new_pixel, float new_coeff, int max_width ) { - if ( new_pixel <= contribs->n1 ) // before the end + if ( contribs->n1 < contribs->n0 ) // this first clause should never happen, but handle in case + { + contribs->n0 = contribs->n1 = new_pixel; + coeffs[0] = new_coeff; + } + else if ( new_pixel <= contribs->n1 ) // before the end { if ( new_pixel < contribs->n0 ) // before the front? { if ( ( contribs->n1 - new_pixel + 1 ) <= max_width ) { int j, o = contribs->n0 - new_pixel; - for ( j = contribs->n1 - contribs->n0 ; j <= 0 ; j-- ) + for ( j = contribs->n1 - contribs->n0 ; j >= 0 ; j-- ) coeffs[ j + o ] = coeffs[ j ]; - for ( j = 1 ; j < o ; j-- ) - coeffs[ j ] = coeffs[ 0 ]; + for ( j = 1 ; j < o ; j++ ) + coeffs[ j ] = 0; coeffs[ 0 ] = new_coeff; contribs->n0 = new_pixel; } } else { + // add new weight to existing coeff if already there coeffs[ new_pixel - contribs->n0 ] += new_coeff; } } @@ -3820,7 +3848,7 @@ static int stbir__pack_coefficients( int num_contributors, stbir__contributors* } } - // some horizontal routines read one float off the end (which is then masked off), so put in a sentinal so we don't read an snan or denormal + // some horizontal routines read one float off the end (which is then masked off), so put in a sentinel so we don't read an snan or denormal coefficents[ widest * num_contributors ] = 8888.0f; // the minimum we might read for unrolled filters widths is 12. So, we need to @@ -6872,45 +6900,45 @@ static float stbir__compute_weights[5][STBIR_RESIZE_CLASSIFICATIONS][4]= // 5 = { 0.56250f, 0.59375f, 0.00000f, 0.96875f }, { 1.00000f, 0.06250f, 0.00000f, 1.00000f }, { 0.00000f, 0.09375f, 1.00000f, 1.00000f }, - { 1.00000f, 1.00000f, 1.00000f, 1.00000f }, + { 1.00000f, 1.00000f, 0.31250f, 1.00000f }, { 0.03125f, 0.12500f, 1.00000f, 1.00000f }, - { 0.06250f, 0.12500f, 0.00000f, 1.00000f }, + { 1.00000f, 1.00000f, 0.06250f, 1.00000f }, { 0.00000f, 1.00000f, 0.00000f, 0.03125f }, }, { { 0.00000f, 0.84375f, 0.00000f, 0.03125f }, { 0.09375f, 0.93750f, 0.00000f, 0.78125f }, { 0.87500f, 0.21875f, 0.00000f, 0.96875f }, { 0.09375f, 0.09375f, 1.00000f, 1.00000f }, - { 1.00000f, 1.00000f, 1.00000f, 1.00000f }, + { 0.00000f, 0.84375f, 0.00000f, 0.03125f }, { 0.03125f, 0.12500f, 1.00000f, 1.00000f }, - { 0.06250f, 0.12500f, 0.00000f, 1.00000f }, + { 1.00000f, 1.00000f, 0.06250f, 1.00000f }, { 0.00000f, 1.00000f, 0.00000f, 0.53125f }, }, { { 0.00000f, 0.53125f, 0.00000f, 0.03125f }, { 0.06250f, 0.96875f, 0.00000f, 0.53125f }, { 0.87500f, 0.18750f, 0.00000f, 0.93750f }, { 0.00000f, 0.09375f, 1.00000f, 1.00000f }, - { 1.00000f, 1.00000f, 1.00000f, 1.00000f }, + { 0.00000f, 0.53125f, 0.00000f, 0.03125f }, { 0.03125f, 0.12500f, 1.00000f, 1.00000f }, - { 0.06250f, 0.12500f, 0.00000f, 1.00000f }, + { 1.00000f, 1.00000f, 0.06250f, 1.00000f }, { 0.00000f, 1.00000f, 0.00000f, 0.56250f }, }, { { 0.00000f, 0.50000f, 0.00000f, 0.71875f }, { 0.06250f, 0.84375f, 0.00000f, 0.87500f }, { 1.00000f, 0.50000f, 0.50000f, 0.96875f }, { 1.00000f, 0.09375f, 0.31250f, 0.50000f }, - { 1.00000f, 1.00000f, 1.00000f, 1.00000f }, + { 0.00000f, 0.50000f, 0.00000f, 0.71875f }, { 1.00000f, 0.03125f, 0.03125f, 0.53125f }, - { 0.18750f, 0.12500f, 0.00000f, 1.00000f }, + { 1.00000f, 1.00000f, 0.06250f, 1.00000f }, { 0.00000f, 1.00000f, 0.03125f, 0.18750f }, }, { { 0.00000f, 0.59375f, 0.00000f, 0.96875f }, { 0.06250f, 0.81250f, 0.06250f, 0.59375f }, { 0.75000f, 0.43750f, 0.12500f, 0.96875f }, { 0.87500f, 0.06250f, 0.18750f, 0.43750f }, - { 1.00000f, 1.00000f, 1.00000f, 1.00000f }, + { 0.00000f, 0.59375f, 0.00000f, 0.96875f }, { 0.15625f, 0.12500f, 1.00000f, 1.00000f }, - { 0.06250f, 0.12500f, 0.00000f, 1.00000f }, + { 1.00000f, 1.00000f, 0.06250f, 1.00000f }, { 0.00000f, 1.00000f, 0.03125f, 0.34375f }, } }; @@ -6964,16 +6992,16 @@ static int stbir__should_do_vertical_first( float weights_table[STBIR_RESIZE_CLA // categorize the resize into buckets if ( ( vertical_output_size <= 4 ) || ( horizontal_output_size <= 4 ) ) v_classification = ( vertical_output_size < horizontal_output_size ) ? 6 : 7; + else if ( ( !is_gather ) && ( ( vertical_output_size <= 16 ) || ( horizontal_output_size <= 16 ) ) ) + v_classification = 4; else if ( vertical_scale <= 1.0f ) v_classification = ( is_gather ) ? 1 : 0; else if ( vertical_scale <= 2.0f) v_classification = 2; else if ( vertical_scale <= 3.0f) v_classification = 3; - else if ( vertical_scale <= 4.0f) - v_classification = 5; - else - v_classification = 6; + else + v_classification = 5; // everything bigger than 3x // use the right weights weights = weights_table[ v_classification ]; @@ -7597,7 +7625,7 @@ static int stbir__double_to_rational(double f, stbir_uint32 limit, stbir_uint32 numer_estimate = temp; } - // we didn't fine anything good enough for float, use a full range estimate + // we didn't find anything good enough for float, use a full range estimate if ( limit_denom ) { numer_estimate= (stbir_uint64)( f * (double)limit + 0.5 ); @@ -7918,7 +7946,7 @@ static int stbir__perform_build( STBIR_RESIZE * resize, int splits ) return 0; } -void stbir_free_samplers( STBIR_RESIZE * resize ) +STBIRDEF void stbir_free_samplers( STBIR_RESIZE * resize ) { if ( resize->samplers ) { @@ -8132,7 +8160,7 @@ STBIRDEF void * stbir_resize( const void *input_pixels , int input_w , int input STBIRDEF void stbir_resize_build_profile_info( STBIR_PROFILE_INFO * info, STBIR_RESIZE const * resize ) { - static char const * bdescriptions[6] = { "Building", "Allocating", "Horizontal sampler", "Vertical sampler", "Coefficient cleanup", "Coefficient piovot" } ; + static char const * bdescriptions[6] = { "Building", "Allocating", "Horizontal sampler", "Vertical sampler", "Coefficient cleanup", "Coefficient pivot" } ; stbir__info* samp = resize->samplers; int i; @@ -8183,7 +8211,7 @@ STBIRDEF void stbir_resize_split_profile_info( STBIR_PROFILE_INFO * info, STBIR_ info->clocks[i] = sum; } - info->total_clocks = split_info->profile.named.total; + info->total_clocks = split_info->profile.named.total; info->descriptions = descriptions; info->count = STBIR__ARRAY_SIZE( descriptions ); } @@ -8731,7 +8759,7 @@ static float * STBIR__CODER_NAME(stbir__decode_uint8_srgb)( float * decodep, int { \ stbir__simdi temp; \ stbir__simdi_32shr( temp, stbir_simdi_castf( f ), 12 ) ; \ - stbir__simdi_and( temp, temp, STBIR__CONSTI(STBIR_mastissa_mask) ); \ + stbir__simdi_and( temp, temp, STBIR__CONSTI(STBIR_mantissa_mask) ); \ stbir__simdi_or( temp, temp, STBIR__CONSTI(STBIR_topscale) ); \ stbir__simdi_16madd( i, i, temp ); \ stbir__simdi_32shr( i, i, 16 ); \ @@ -8972,7 +9000,7 @@ static float * STBIR__CODER_NAME(stbir__decode_uint8_srgb2_linearalpha)( float * decode -= 4; if( decode < decode_end ) { - decode[0] = stbir__srgb_uchar_to_linear_float[ stbir__decode_order0 ]; + decode[0] = stbir__srgb_uchar_to_linear_float[ input[stbir__decode_order0] ]; decode[1] = ( (float) input[stbir__decode_order1] ) * stbir__max_uint8_as_float_inverted; } return decode_end; @@ -9708,7 +9736,7 @@ static float * STBIR__CODER_NAME(stbir__decode_float_linear)( float * decodep, i static void STBIR__CODER_NAME( stbir__encode_float_linear )( void * outputp, int width_times_channels, float const * encode ) { - #if !defined( STBIR_FLOAT_HIGH_CLAMP ) && !defined(STBIR_FLOAT_LO_CLAMP) && !defined(stbir__decode_swizzle) + #if !defined( STBIR_FLOAT_HIGH_CLAMP ) && !defined(STBIR_FLOAT_LOW_CLAMP) && !defined(stbir__decode_swizzle) if ( (void*)outputp != (void*) encode ) STBIR_MEMCPY( outputp, encode, width_times_channels * sizeof( float ) ); @@ -9763,7 +9791,7 @@ static void STBIR__CODER_NAME( stbir__encode_float_linear )( void * outputp, int stbir__simdfX_store( output+stbir__simdfX_float_count, e1 ); encode += stbir__simdfX_float_count * 2; output += stbir__simdfX_float_count * 2; - if ( output < end_output ) + if ( output <= end_output ) continue; if ( output == ( end_output + ( stbir__simdfX_float_count * 2 ) ) ) break; diff --git a/include/libs/toml++/toml.hpp b/include/libs/toml++/toml.hpp index c01a208..caf87c4 100644 --- a/include/libs/toml++/toml.hpp +++ b/include/libs/toml++/toml.hpp @@ -773,7 +773,6 @@ __pragma(warning(disable : 4710)) /* function not inlined */ \ __pragma(warning(disable : 4711)) /* function selected for automatic expansion */ \ __pragma(warning(disable : 4820)) /* N bytes padding added */ \ - __pragma(warning(disable : 4946)) /* reinterpret_cast used between related classes */ \ __pragma(warning(disable : 5026)) /* move constructor was implicitly defined as deleted */ \ __pragma(warning(disable : 5027)) /* move assignment operator was implicitly defined as deleted */ \ __pragma(warning(disable : 5039)) /* potentially throwing function passed to 'extern "C"' function */ \ @@ -1086,9 +1085,11 @@ #endif #ifndef TOML_MAX_NESTED_VALUES -#define TOML_MAX_NESTED_VALUES 256 +#define TOML_MAX_NESTED_VALUES 128 // this refers to the depth of nested values, e.g. inline tables and arrays. -// 256 is crazy high! if you're hitting this limit with real input, TOML is probably the wrong tool for the job... +// 128 is very generous; real TOML files rarely exceed single-digit nesting. +// keep this value low enough to avoid stack overflows in sanitizer-instrumented builds +// where each recursion cycle may consume ~3KB of stack. #endif #ifndef TOML_MAX_DOTTED_KEYS_DEPTH @@ -3809,7 +3810,7 @@ TOML_NAMESPACE_START { using out_ref = ref_cast_type; using out_type = std::remove_reference_t; - return static_cast(*reinterpret_cast(this)); + return static_cast(*static_cast(this)); } template @@ -3818,7 +3819,7 @@ TOML_NAMESPACE_START { using out_ref = ref_cast_type; using out_type = std::remove_reference_t; - return static_cast(*reinterpret_cast(this)); + return static_cast(*static_cast(this)); } template @@ -3827,7 +3828,7 @@ TOML_NAMESPACE_START { using out_ref = ref_cast_type; using out_type = std::remove_reference_t; - return static_cast(*reinterpret_cast(this)); + return static_cast(*static_cast(this)); } template @@ -3836,7 +3837,7 @@ TOML_NAMESPACE_START { using out_ref = ref_cast_type; using out_type = std::remove_reference_t; - return static_cast(*reinterpret_cast(this)); + return static_cast(*static_cast(this)); } public: @@ -12051,7 +12052,7 @@ TOML_NAMESPACE_START auto type = child.elems_[i]->type(); if (type == node_type::array) { - array& arr = *reinterpret_cast(child.elems_[i].get()); + array& arr = *static_cast(child.elems_[i].get()); if (!arr.empty()) flatten_child(std::move(arr), dest_index); } @@ -12165,7 +12166,7 @@ TOML_NAMESPACE_START const bool equal = lhs.elems_[i]->visit( [&](const auto& lhs_) noexcept - { return lhs_ == *reinterpret_cast*>(&rhs_); }); + { return lhs_ == *static_cast*>(&rhs_); }); if (!equal) return false; } @@ -12487,7 +12488,7 @@ TOML_NAMESPACE_START const bool equal = l->second->visit( [&](const auto& lhs_) noexcept - { return lhs_ == *reinterpret_cast*>(&rhs_); }); + { return lhs_ == *static_cast*>(&rhs_); }); if (!equal) return false; } @@ -14270,6 +14271,9 @@ TOML_IMPL_NAMESPACE_START TOML_ASSERT_ASSUME(is_string_delimiter(*cp)); push_parse_scope("string"sv); + // snapshot length so the recording buffer can be rewound alongside go_back(2u) below + const auto recording_buffer_rollback_size = recording_buffer.length(); + // get the first three characters to determine the string type const auto first = cp->value; advance_and_return_if_error_or_eof({}); @@ -14300,6 +14304,8 @@ TOML_IMPL_NAMESPACE_START // step back two characters so that the current // character is the string delimiter go_back(2u); + if (recording) + recording_buffer.resize(recording_buffer_rollback_size); return { first == U'\'' ? parse_literal_string(false) : parse_basic_string(false), false }; } @@ -15740,6 +15746,11 @@ TOML_IMPL_NAMESPACE_START if (*cp == U']') set_error_and_return_default("tables with blank bare keys are explicitly prohibited"sv); + if (!is_bare_key_character(*cp) && !is_string_delimiter(*cp)) + set_error_and_return_default("expected bare key starting character or string delimiter, saw '"sv, + to_sv(*cp), + "'"sv); + // get the actual key start_recording(); parse_key(); @@ -16979,13 +16990,13 @@ TOML_IMPL_NAMESPACE_START TOML_ASSUME(type > node_type::array); switch (type) { - case node_type::string: print(*reinterpret_cast*>(&val_node)); break; - case node_type::integer: print(*reinterpret_cast*>(&val_node)); break; - case node_type::floating_point: print(*reinterpret_cast*>(&val_node)); break; - case node_type::boolean: print(*reinterpret_cast*>(&val_node)); break; - case node_type::date: print(*reinterpret_cast*>(&val_node)); break; - case node_type::time: print(*reinterpret_cast*>(&val_node)); break; - case node_type::date_time: print(*reinterpret_cast*>(&val_node)); break; + case node_type::string: print(*static_cast*>(&val_node)); break; + case node_type::integer: print(*static_cast*>(&val_node)); break; + case node_type::floating_point: print(*static_cast*>(&val_node)); break; + case node_type::boolean: print(*static_cast*>(&val_node)); break; + case node_type::date: print(*static_cast*>(&val_node)); break; + case node_type::time: print(*static_cast*>(&val_node)); break; + case node_type::date_time: print(*static_cast*>(&val_node)); break; default: TOML_UNREACHABLE; } } @@ -17053,7 +17064,7 @@ TOML_ANON_NAMESPACE_START { case node_type::table: { - auto& tbl = *reinterpret_cast(&node); + auto& tbl = *static_cast(&node); if (tbl.empty()) return 2u; // "{}" size_t weight = 3u; // "{ }" @@ -17068,7 +17079,7 @@ TOML_ANON_NAMESPACE_START case node_type::array: { - auto& arr = *reinterpret_cast(&node); + auto& arr = *static_cast(&node); if (arr.empty()) return 2u; // "[]" size_t weight = 3u; // "[ ]" @@ -17085,13 +17096,13 @@ TOML_ANON_NAMESPACE_START { // todo: proper utf8 decoding? // todo: tab awareness? - auto& str = (*reinterpret_cast*>(&node)).get(); + auto& str = (*static_cast*>(&node)).get(); return str.length() + 2u; // + "" } case node_type::integer: { - auto val = (*reinterpret_cast*>(&node)).get(); + auto val = (*static_cast*>(&node)).get(); if (!val) return 1u; size_t weight = {}; @@ -17105,7 +17116,7 @@ TOML_ANON_NAMESPACE_START case node_type::floating_point: { - auto val = (*reinterpret_cast*>(&node)).get(); + auto val = (*static_cast*>(&node)).get(); if (val == 0.0) return 3u; // "0.0" size_t weight = 2u; // ".0" @@ -17183,8 +17194,8 @@ TOML_NAMESPACE_START TOML_ASSUME(type != node_type::none); switch (type) { - case node_type::table: print_inline(*reinterpret_cast(&v)); break; - case node_type::array: print(*reinterpret_cast(&v)); break; + case node_type::table: print_inline(*static_cast(&v)); break; + case node_type::array: print(*static_cast(&v)); break; default: print_value(v, type); } } @@ -17240,8 +17251,8 @@ TOML_NAMESPACE_START TOML_ASSUME(type != node_type::none); switch (type) { - case node_type::table: print_inline(*reinterpret_cast(&v)); break; - case node_type::array: print(*reinterpret_cast(&v)); break; + case node_type::table: print_inline(*static_cast(&v)); break; + case node_type::array: print(*static_cast(&v)); break; default: print_value(v, type); } } @@ -17266,14 +17277,14 @@ TOML_NAMESPACE_START if (!arr || !arr->is_array_of_tables()) return false; - return !reinterpret_cast(&(*arr)[0])->is_inline(); + return !static_cast(&(*arr)[0])->is_inline(); }; // values, arrays, and inline tables/table arrays for (auto&& [k, v] : tbl) { const auto type = v.type(); - if ((type == node_type::table && !reinterpret_cast(&v)->is_inline()) + if ((type == node_type::table && !static_cast(&v)->is_inline()) || (type == node_type::array && is_non_inline_array_of_tables(v))) continue; @@ -17288,8 +17299,8 @@ TOML_NAMESPACE_START TOML_ASSUME(type != node_type::none); switch (type) { - case node_type::table: print_inline(*reinterpret_cast(&v)); break; - case node_type::array: print(*reinterpret_cast(&v)); break; + case node_type::table: print_inline(*static_cast(&v)); break; + case node_type::array: print(*static_cast(&v)); break; default: print_value(v, type); } } @@ -17309,9 +17320,9 @@ TOML_NAMESPACE_START for (auto&& [k, v] : tbl) { const auto type = v.type(); - if (type != node_type::table || reinterpret_cast(&v)->is_inline()) + if (type != node_type::table || static_cast(&v)->is_inline()) continue; - auto& child_tbl = *reinterpret_cast(&v); + auto& child_tbl = *static_cast(&v); // we can skip indenting and emitting the headers for tables that only contain other tables // (so we don't over-nest) @@ -17326,7 +17337,7 @@ TOML_NAMESPACE_START switch (child_type) { case node_type::table: - if (reinterpret_cast(&child_v)->is_inline()) + if (static_cast(&child_v)->is_inline()) child_value_count++; else child_table_count++; @@ -17372,7 +17383,7 @@ TOML_NAMESPACE_START { if (!is_non_inline_array_of_tables(v)) continue; - auto& arr = *reinterpret_cast(&v); + auto& arr = *static_cast(&v); if (indent_sub_tables()) increase_indent(); @@ -17386,7 +17397,7 @@ TOML_NAMESPACE_START print_key_path(); print_unformatted("]]"sv); pending_table_separator_ = true; - print(*reinterpret_cast(&arr[i])); + print(*static_cast(&arr[i])); } key_path_.pop_back(); @@ -17405,7 +17416,7 @@ TOML_NAMESPACE_START { case node_type::table: { - auto& tbl = *reinterpret_cast(&source()); + auto& tbl = *static_cast(&source()); if (tbl.is_inline()) print_inline(tbl); else @@ -17416,7 +17427,7 @@ TOML_NAMESPACE_START break; } - case node_type::array: print(*reinterpret_cast(&source())); break; + case node_type::array: print(*static_cast(&source())); break; default: print_value(source(), source_type); } @@ -17484,8 +17495,8 @@ TOML_NAMESPACE_START TOML_ASSUME(type != node_type::none); switch (type) { - case node_type::table: print(*reinterpret_cast(&v)); break; - case node_type::array: print(*reinterpret_cast(&v)); break; + case node_type::table: print(*static_cast(&v)); break; + case node_type::array: print(*static_cast(&v)); break; default: print_value(v, type); } } @@ -17521,8 +17532,8 @@ TOML_NAMESPACE_START TOML_ASSUME(type != node_type::none); switch (type) { - case node_type::table: print(*reinterpret_cast(&v)); break; - case node_type::array: print(*reinterpret_cast(&v)); break; + case node_type::table: print(*static_cast(&v)); break; + case node_type::array: print(*static_cast(&v)); break; default: print_value(v, type); } } @@ -17541,8 +17552,8 @@ TOML_NAMESPACE_START switch (auto source_type = source().type()) { - case node_type::table: print(*reinterpret_cast(&source())); break; - case node_type::array: print(*reinterpret_cast(&source())); break; + case node_type::table: print(*static_cast(&source())); break; + case node_type::array: print(*static_cast(&source())); break; default: print_value(source(), source_type); } } @@ -17649,9 +17660,9 @@ TOML_NAMESPACE_START TOML_ASSUME(type != node_type::none); switch (type) { - case node_type::table: print(*reinterpret_cast(&v)); break; - case node_type::array: print(*reinterpret_cast(&v)); break; - case node_type::string: print_yaml_string(*reinterpret_cast*>(&v)); break; + case node_type::table: print(*static_cast(&v)); break; + case node_type::array: print(*static_cast(&v)); break; + case node_type::string: print_yaml_string(*static_cast*>(&v)); break; default: print_value(v, type); } } @@ -17685,9 +17696,9 @@ TOML_NAMESPACE_START TOML_ASSUME(type != node_type::none); switch (type) { - case node_type::table: print(*reinterpret_cast(&v), true); break; - case node_type::array: print(*reinterpret_cast(&v), true); break; - case node_type::string: print_yaml_string(*reinterpret_cast*>(&v)); break; + case node_type::table: print(*static_cast(&v), true); break; + case node_type::array: print(*static_cast(&v), true); break; + case node_type::string: print_yaml_string(*static_cast*>(&v)); break; default: print_value(v, type); } } @@ -17705,12 +17716,12 @@ TOML_NAMESPACE_START { case node_type::table: decrease_indent(); // so root kvps and tables have the same indent - print(*reinterpret_cast(&source())); + print(*static_cast(&source())); break; - case node_type::array: print(*reinterpret_cast(&source())); break; + case node_type::array: print(*static_cast(&source())); break; - case node_type::string: print_yaml_string(*reinterpret_cast*>(&source())); break; + case node_type::string: print_yaml_string(*static_cast*>(&source())); break; default: print_value(source(), source_type); } diff --git a/src/libs/fmt/format.cc b/src/libs/fmt/format.cc index 526082e..298c5b4 100644 --- a/src/libs/fmt/format.cc +++ b/src/libs/fmt/format.cc @@ -1,6 +1,6 @@ // Formatting library for C++ // -// Copyright (c) 2012 - 2016, Victor Zverovich +// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors // All rights reserved. // // For the license information refer to format.h. diff --git a/src/libs/fmt/os.cc b/src/libs/fmt/os.cc index 409863a..4840a65 100644 --- a/src/libs/fmt/os.cc +++ b/src/libs/fmt/os.cc @@ -1,6 +1,6 @@ // Formatting library for C++ - optional OS-specific functionality // -// Copyright (c) 2012 - 2016, Victor Zverovich +// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors // All rights reserved. // // For the license information refer to format.h. @@ -13,7 +13,6 @@ #include "fmt/os.h" #ifndef FMT_MODULE -# include # if FMT_USE_FCNTL # include @@ -35,6 +34,8 @@ # ifdef _WIN32 # include + +# include // CHAR_BIT # endif #endif diff --git a/src/libs/imgui/imgui.cpp b/src/libs/imgui/imgui.cpp index 1829d4f..e56165a 100644 --- a/src/libs/imgui/imgui.cpp +++ b/src/libs/imgui/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.8 WIP +// dear imgui, v1.92.9 WIP // (main code and documentation) // Help: @@ -395,7 +395,31 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures: When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2026/04/23 (1.92.8) - Obsoleted `ImDrawCallback_ResetRenderState` in favor of using `ImGui::GetPlatformIO().DrawCallback_ResetRenderState`, which is part of our new standard draw callbacks. (#9378) + - 2026/06/02 (1.92.9) - TreeNode: commented out legacy name ImGuiTreeNodeFlags_SpanTextWidth which was obsoleted in 1.90.7 (May 2024). Use ImGuiTreeNodeFlags_SpanLabelWidth instead. + - 2026/05/07 (1.92.8) - DrawList: swapped the last two arguments of AddRect(), AddPolyline(), PathStroke(). + - Before: void ImDrawList::AddRect(ImVec2 p_min, ImVec2 p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0, float thickness = 1.0f); + - After: void ImDrawList::AddRect(ImVec2 p_min, ImVec2 p_max, ImU32 col, float rounding = 0.0f, float thickness = 1.0f, ImDrawFlags flags = 0); + - Before: void ImDrawList::AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness); + - After: void ImDrawList::AddPolyline(const ImVec2* points, int num_points, ImU32 col, float thickness, ImDrawFlags flags = 0); + - Before: void ImDrawList::PathStroke(ImU32 col, ImDrawFlags flags = 0, float thickness = 1.0f); + - After: void ImDrawList::PathStroke(ImU32 col, float thickness = 1.0f, ImDrawFlags flags = 0); + Added inline redirection functions when IMGUI_DISABLE_OBSOLETE_FUNCTIONS is off. + Marked the old functions are =delete when IMGUI_DISABLE_OBSOLETE_FUNCTIONS is on, to allow for better type-checking. + Effectively the typical call site is changing from: + - Before: window->DrawList->AddRect(p_min, p_max, color, rounding, ImDrawFlags_None, border_size); + - After: window->DrawList->AddRect(p_min, p_max, color, rounding, border_size); + Notes: + - Users of C++ and other languages with type-checking will be notified at compile-time of any mistakes. + - Users of high-level bindings or languages with no type-checking will be notified at runtime via an assert for invalid flags value. + If you are a binding maintainer consider doing something to facilitate transition or error detection. + - This is perhaps the worst breaking change in our history :( but it makes ImDrawList function signatures consistent. + As we are aiming to add flags and features to variety of ImDrawList functions, that consistency becomes more important. + The new order is also more convenient as `flags` are less frequently used than `thickness` in real code. + - As a general policy in Dear ImGui, all our flags default to 0 so ImDrawFlags_None was likely written 0 in some call sites. + - Consider adding `#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS` in your imconfig.h, even temporarily, to clean up legacy code. + - 2026/05/07 (1.92.8) - DrawList: changed value of `ImDrawFlags_Closed`. It was previously advertised as "always == 1" when introduced in 1.82 (2021/02), in order to facilitate backward compatibility with the legacy `bool closed` flag. + This guarantee has been removed. The bit is reserved and `AddPolyline()`, `PathStroke()` will assert when it is used. + - 2026/04/23 (1.92.8) - DrawList: obsoleted `ImDrawCallback_ResetRenderState` in favor of using `ImGui::GetPlatformIO().DrawCallback_ResetRenderState`, which is part of our new standard draw callbacks. (#9378) - 2026/04/22 (1.92.8) - Backends: Vulkan: redesigned to use separate ImageView + Sampler instead of Combined Image Sampler. - When registering custom textures: changed ImGui_ImplVulkan_AddTexture() signature to remove Sampler. - When creating your own descriptor pool (instead of letting backend creates its own): need at least IMGUI_IMPL_VULKAN_MINIMUM_SAMPLED_IMAGE_POOL_SIZE descriptors of type VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE + IMGUI_IMPL_VULKAN_MINIMUM_SAMPLER_POOL_SIZE descriptors of type VK_DESCRIPTOR_TYPE_SAMPLER. @@ -1516,6 +1540,7 @@ ImGuiStyle::ImGuiStyle() ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text. SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. + InputTextCursorSize = 1.0f; // Thickness of cursor/caret in InputText(). SeparatorSize = 1.0f; // Thickness of border in Separator(). SeparatorTextBorderSize = 3.0f; // Thickness of border in SeparatorText(). SeparatorTextAlign = ImVec2(0.0f,0.5f);// Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center). @@ -1591,6 +1616,7 @@ void ImGuiStyle::ScaleAllSizes(float scale_factor) DragDropTargetBorderSize = ImTrunc(DragDropTargetBorderSize * scale_factor); DragDropTargetPadding = ImTrunc(DragDropTargetPadding * scale_factor); ColorMarkerSize = ImTrunc(ColorMarkerSize * scale_factor); + InputTextCursorSize = ImTrunc(InputTextCursorSize * scale_factor); SeparatorSize = ImTrunc(SeparatorSize * scale_factor); SeparatorTextBorderSize = ImTrunc(SeparatorTextBorderSize * scale_factor); SeparatorTextPadding = ImTrunc(SeparatorTextPadding * scale_factor); @@ -3659,6 +3685,7 @@ static const ImGuiStyleVarInfo GStyleVarsInfo[] = { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersTextAlign)},// ImGuiStyleVar_TableAngledHeadersTextAlign { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesSize)}, // ImGuiStyleVar_TreeLinesSize { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesRounding)}, // ImGuiStyleVar_TreeLinesRounding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, DragDropTargetRounding)}, // ImGuiStyleVar_DragDropTargetRounding { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorSize)}, // ImGuiStyleVar_SeparatorSize @@ -3759,6 +3786,7 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx) case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered"; case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive"; case ImGuiCol_CheckMark: return "CheckMark"; + case ImGuiCol_CheckboxSelectedBg: return "CheckboxSelectedBg"; case ImGuiCol_SliderGrab: return "SliderGrab"; case ImGuiCol_SliderGrabActive: return "SliderGrabActive"; case ImGuiCol_Button: return "Button"; @@ -3926,8 +3954,8 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con text_end_full = FindRenderedTextEnd(text); const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_end_full, false, 0.0f); - //draw_list->AddLine(ImVec2(pos_max.x, pos_min.y - 4), ImVec2(pos_max.x, pos_max.y + 6), IM_COL32(0, 0, 255, 255)); - //draw_list->AddLine(ImVec2(ellipsis_max_x, pos_min.y - 2), ImVec2(ellipsis_max_x, pos_max.y + 3), IM_COL32(0, 255, 0, 255)); + //draw_list->AddLineV(pos_max.x, pos_min.y - 4, pos_max.y + 6, IM_COL32(0, 0, 255, 255)); + //draw_list->AddLineV(ellipsis_max_x, pos_min.y - 2, pos_max.y + 3, IM_COL32(0, 255, 0, 255)); // FIXME: We could technically remove (last_glyph->AdvanceX - last_glyph->X1) from text_size.x here and save a few pixels. if (text_size.x > pos_max.x - pos_min.x) @@ -3972,8 +4000,8 @@ void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool borders const float border_size = g.Style.FrameBorderSize; if (borders && border_size > 0.0f) { - window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, 0, border_size); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, 0, border_size); + window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, border_size); } } @@ -3984,8 +4012,8 @@ void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding) const float border_size = g.Style.FrameBorderSize; if (border_size > 0.0f) { - window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, 0, border_size); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, 0, border_size); + window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, border_size); } } @@ -4020,7 +4048,7 @@ void ImGui::RenderNavCursor(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFl const float thickness = 2.0f; if (flags & ImGuiNavRenderCursorFlags_Compact) { - window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavCursor), rounding, 0, thickness); + window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavCursor), rounding, thickness); } else { @@ -4029,7 +4057,7 @@ void ImGui::RenderNavCursor(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFl bool fully_visible = window->ClipRect.Contains(display_rect); if (!fully_visible) window->DrawList->PushClipRect(display_rect.Min, display_rect.Max); - window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavCursor), rounding, 0, thickness); + window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavCursor), rounding, thickness); if (!fully_visible) window->DrawList->PopClipRect(); } @@ -4063,7 +4091,7 @@ void ImGui::RenderMouseCursor(ImVec2 base_pos, float base_scale, ImGuiMouseCurso float a_min = ImFmod((float)g.Time * 5.0f, 2.0f * IM_PI); float a_max = a_min + IM_PI * 1.65f; draw_list->PathArcTo(pos + ImVec2(14, -1) * scale, 6.0f * scale, a_min, a_max); - draw_list->PathStroke(col_fill, ImDrawFlags_None, 3.0f * scale); + draw_list->PathStroke(col_fill, 3.0f * scale); } draw_list->PopTexture(); } @@ -4133,7 +4161,10 @@ static const ImGuiLocEntry GLocalizationEntriesEnUS[] = { ImGuiLocKey_TableSizeOne, "Size column to fit###SizeOne" }, { ImGuiLocKey_TableSizeAllFit, "Size all columns to fit###SizeAll" }, { ImGuiLocKey_TableSizeAllDefault, "Size all columns to default###SizeAll" }, + { ImGuiLocKey_TableReset, "Reset" }, + //{ ImGuiLocKey_TableResetAll, "Reset to default###ResetAll" }, { ImGuiLocKey_TableResetOrder, "Reset order###ResetOrder" }, + { ImGuiLocKey_TableResetVisibility, "Reset visibility###ResetVisibility" }, { ImGuiLocKey_WindowingMainMenuBar, "(Main menu bar)" }, { ImGuiLocKey_WindowingPopup, "(Popup)" }, { ImGuiLocKey_WindowingUntitled, "(Untitled)" }, @@ -4448,7 +4479,7 @@ void ImGui::Shutdown() for (ImFontAtlas* atlas : g.FontAtlases) { UnregisterFontAtlas(atlas); - if (atlas->RefCount == 0) + if (atlas->RefCount == 0 && atlas->OwnerContext == &g) { atlas->Locked = false; IM_DELETE(atlas); @@ -4697,7 +4728,8 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) g.ActiveIdIsJustActivated = (g.ActiveId != id); if (g.ActiveIdIsJustActivated) { - IMGUI_DEBUG_LOG_ACTIVEID("SetActiveID() old:0x%08X (window \"%s\") -> new:0x%08X (window \"%s\")\n", g.ActiveId, g.ActiveIdWindow ? g.ActiveIdWindow->Name : "", id, window ? window->Name : ""); + IMGUI_DEBUG_LOG_ACTIVEID("SetActiveID() 0x%08X in \"%s\"%*s(previously 0x%08X in \"%s\")\n", id, window ? window->Name : "", + ImMax(0, 20 - (int)(window ? strlen(window->Name) : 0)), "", g.ActiveId, g.ActiveIdWindow ? g.ActiveIdWindow->Name : ""); g.ActiveIdTimer = 0.0f; g.ActiveIdHasBeenPressedBefore = false; g.ActiveIdHasBeenEditedBefore = false; @@ -4936,7 +4968,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag { g.HoveredIdPreviousFrameItemCount++; if (g.DebugDrawIdConflictsId == id) - window->DrawList->AddRect(bb.Min - ImVec2(1,1), bb.Max + ImVec2(1,1), IM_COL32(255, 0, 0, 255), 0.0f, ImDrawFlags_None, 2.0f); + window->DrawList->AddRect(bb.Min - ImVec2(1,1), bb.Max + ImVec2(1,1), IM_COL32(255, 0, 0, 255), 0.0f, 2.0f); } #endif @@ -5333,14 +5365,15 @@ void ImGui::UpdateMouseMovingWindowEndFrame() // Click on empty space to focus window and start moving // (after we're done with all our widgets) - if (g.IO.MouseClicked[0]) + if (IsMouseClicked(0, ImGuiInputFlags_None, ImGuiKeyOwner_NoOwner)) { // Handle the edge case of a popup being closed while clicking in its empty space. // If we try to focus it, FocusWindow() > ClosePopupsOverWindow() will accidentally close any parent popups because they are not linked together any more. ImGuiWindow* hovered_root = hovered_window ? hovered_window->RootWindow : NULL; const bool is_closed_popup = hovered_root && (hovered_root->Flags & ImGuiWindowFlags_Popup) && !IsPopupOpen(hovered_root->PopupId, ImGuiPopupFlags_AnyPopupLevel); + const bool is_queued_focus_request = g.NavMoveSubmitted && (g.NavMoveFlags & ImGuiNavMoveFlags_FocusApi); - if (hovered_window != NULL && !is_closed_popup) + if (hovered_window != NULL && !is_closed_popup && !is_queued_focus_request) { StartMouseMovingWindow(hovered_window); //-V595 @@ -5371,7 +5404,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame() // With right mouse button we close popups without changing focus based on where the mouse is aimed // Instead, focus will be restored to the window under the bottom-most closed popup. // (The left mouse button path calls FocusWindow on the hovered window, which will lead NewFrame->ClosePopupsOverWindow to trigger) - if (g.IO.MouseClicked[1] && g.HoveredId == 0) + if (g.HoveredId == 0 && IsMouseClicked(1, ImGuiInputFlags_None, ImGuiKeyOwner_NoOwner)) { // Find the top-most window between HoveredWindow and the top-most Modal Window. // This is where we can trim the popup stack. @@ -5733,7 +5766,7 @@ void ImGui::NewFrame() g.CurrentWindowStack.resize(0); g.BeginPopupStack.resize(0); g.ItemFlagsStack.resize(0); - g.ItemFlagsStack.push_back(ImGuiItemFlags_AutoClosePopups); // Default flags + g.ItemFlagsStack.push_back(ImGuiItemFlags_Default_); // Default flags g.CurrentItemFlags = g.ItemFlagsStack.back(); g.GroupStack.resize(0); @@ -5968,7 +6001,7 @@ static void ImGui::RenderDimmedBackgrounds() if (window->DrawList->CmdBuffer.Size == 0) window->DrawList->AddDrawCmd(); window->DrawList->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size); - window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), window->WindowRounding, 0, 3.0f); // FIXME-DPI + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), window->WindowRounding, 3.0f); // FIXME-DPI window->DrawList->PopClipRect(); } } @@ -6170,11 +6203,9 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL); // Round - // FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out. - // FIXME: Investigate using ceilf or e.g. - // - https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c - // - https://embarkstudios.github.io/rust-gpu/api/src/libm/math/ceilf.rs.html - text_size.x = IM_TRUNC(text_size.x + 0.99999f); + // (see 7b0bf230, 4622fa4b6, #791 for details about this.) + // FIXME: Add a way to disable this. + text_size.x = ImCeilFast(text_size.x); return text_size; } @@ -6293,11 +6324,12 @@ bool ImGui::IsItemToggledOpen() return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_ToggledOpen) ? true : false; } -// Call after a Selectable() or TreeNode() involved in multi-selection. -// Useful if you need the per-item information before reaching EndMultiSelect(), e.g. for rendering purpose. -// This is only meant to be called inside a BeginMultiSelect()/EndMultiSelect() block. -// (Outside of multi-select, it would be misleading/ambiguous to report this signal, as widgets -// return e.g. a pressed event and user code is in charge of altering selection in ways we cannot predict.) +// Call after a Selectable() or TreeNode() items inside a BeginMultiSelect()/EndMultiSelect() scope. +// - Useful if you need the per-item information before reaching EndMultiSelect(), e.g. for rendering purpose. +// Outside of a multi-select block: +// - It would be misleading/ambiguous to report this signal, as widgets return e.g. a pressed event, +// and user code is in charge of altering selection in ways we cannot predict. +// Prefer using 'if (IsItemClicked() && !IsItemToggledOpen())' for a manual reimplementation of selection. bool ImGui::IsItemToggledSelection() { ImGuiContext& g = *GImGui; @@ -7128,7 +7160,7 @@ static void RenderWindowOuterSingleBorder(ImGuiWindow* window, int border_n, ImU const ImRect border_r = GetResizeBorderRect(window, border_n, rounding, 0.0f); window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN1) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle - IM_PI * 0.25f, def.OuterAngle); window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN2) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle, def.OuterAngle + IM_PI * 0.25f); - window->DrawList->PathStroke(border_col, ImDrawFlags_None, border_size); + window->DrawList->PathStroke(border_col, border_size); } static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window) @@ -7137,7 +7169,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window) const float border_size = window->WindowBorderSize; const ImU32 border_col = GetColorU32(ImGuiCol_Border); if (border_size > 0.0f && (window->Flags & ImGuiWindowFlags_NoBackground) == 0) - window->DrawList->AddRect(window->Pos, window->Pos + window->Size, border_col, window->WindowRounding, 0, window->WindowBorderSize); + window->DrawList->AddRect(window->Pos, window->Pos + window->Size, border_col, window->WindowRounding, window->WindowBorderSize); else if (border_size > 0.0f) { if (window->ChildFlags & ImGuiChildFlags_ResizeX) // Similar code as 'resize_border_mask' computation in UpdateWindowManualResize() but we specifically only always draw explicit child resize border. @@ -7154,7 +7186,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window) if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar)) { float y = window->Pos.y + window->TitleBarHeight - 1; - window->DrawList->AddLine(ImVec2(window->Pos.x + border_size * 0.5f, y), ImVec2(window->Pos.x + window->Size.x - border_size * 0.5f, y), border_col, g.Style.FrameBorderSize); + window->DrawList->AddLineH(window->Pos.x + border_size * 0.5f, window->Pos.x + window->Size.x - border_size * 0.5f, y, border_col, g.Style.FrameBorderSize); } } @@ -7202,7 +7234,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar if (bg_col & IM_COL32_A_MASK) { ImRect bg_rect(window->Pos + ImVec2(0, window->TitleBarHeight), window->Pos + window->Size); - ImDrawFlags bg_rounding_flags = (flags & ImGuiWindowFlags_NoTitleBar) ? 0 : ImDrawFlags_RoundCornersBottom; + ImDrawFlags bg_rounding_flags = (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawFlags_RoundCornersAll : ImDrawFlags_RoundCornersBottom; ImDrawList* bg_draw_list = window->DrawList; bg_draw_list->AddRectFilled(bg_rect.Min, bg_rect.Max, bg_col, window_rounding, bg_rounding_flags); } @@ -7222,7 +7254,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them. window->DrawList->AddRectFilled(menu_bar_rect.Min, menu_bar_rect.Max, GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawFlags_RoundCornersTop); if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y) - window->DrawList->AddLine(menu_bar_rect.GetBL() + ImVec2(window_border_size * 0.5f, 0.0f), menu_bar_rect.GetBR() - ImVec2(window_border_size * 0.5f, 0.0f), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); + window->DrawList->AddLineH(menu_bar_rect.Min.x + window_border_size * 0.5f, menu_bar_rect.Max.x - window_border_size * 0.5f, menu_bar_rect.Max.y, GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } // Scrollbars @@ -7682,7 +7714,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) ImRect title_bar_rect = window->TitleBarRect(); if (g.HoveredWindow == window && g.HoveredId == 0 && g.HoveredIdPreviousFrame == 0 && g.ActiveId == 0 && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max)) if (g.IO.MouseClickedCount[0] == 2 && GetKeyOwner(ImGuiKey_MouseLeft) == ImGuiKeyOwner_NoOwner) + { window->WantCollapseToggle = true; + SetKeyOwner(ImGuiKey_MouseLeft, window->MoveId); // Claim input the same way ButtonBehavior() does. Prevent a same-frame move from triggering other items. (#9439) + } if (window->WantCollapseToggle) { window->Collapsed = !window->Collapsed; @@ -8951,6 +8986,8 @@ static void ImGui::UpdateTexturesNewFrame() IM_ASSERT(atlas->RendererHasTextures == has_textures); } } + for (ImTextureData* tex : g.UserTextures) + ImTextureDataUpdateNewFrame(tex); } // Build a single texture list @@ -9012,7 +9049,7 @@ ImFont* ImGui::GetDefaultFont() return g.IO.FontDefault ? g.IO.FontDefault : atlas->Fonts[0]; } -// EXPERIMENTAL: DO NOT USE YET. +// EXPERIMENTAL. Use ImTextureDataQueueUpload() to queue updates. Textures logic will be automatically be updated in NewFrame(). void ImGui::RegisterUserTexture(ImTextureData* tex) { ImGuiContext& g = *GImGui; @@ -10342,15 +10379,21 @@ void ImGui::UpdateMouseWheel() LockWheelingWindow(NULL, 0.0f); } - ImVec2 wheel; - wheel.x = TestKeyOwner(ImGuiKey_MouseWheelX, ImGuiKeyOwner_NoOwner) ? g.IO.MouseWheelH : 0.0f; - wheel.y = TestKeyOwner(ImGuiKey_MouseWheelY, ImGuiKeyOwner_NoOwner) ? g.IO.MouseWheel : 0.0f; - - //IMGUI_DEBUG_LOG("MouseWheel X:%.3f Y:%.3f\n", wheel_x, wheel_y); ImGuiWindow* mouse_window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow; if (!mouse_window || mouse_window->Collapsed) return; + ImGuiID owner_id = mouse_window->ID; + ImVec2 wheel; + wheel.x = TestKeyOwner(ImGuiKey_MouseWheelX, owner_id) ? g.IO.MouseWheelH : 0.0f; + wheel.y = TestKeyOwner(ImGuiKey_MouseWheelY, owner_id) ? g.IO.MouseWheel : 0.0f; + //IMGUI_DEBUG_LOG("MouseWheel X:%.3f Y:%.3f\n", wheel_x, wheel_y); + if (g.WheelingWindow != NULL) + { + SetKeyOwner(ImGuiKey_MouseWheelX, owner_id); + SetKeyOwner(ImGuiKey_MouseWheelY, owner_id); + } + // Zoom / Scale window // FIXME-OBSOLETE: This is an old feature, it still works but pretty much nobody is using it and may be best redesigned. if (wheel.y != 0.0f && g.IO.KeyCtrl && g.IO.FontAllowUserScaling) @@ -10654,6 +10697,7 @@ bool ImGui::TestKeyOwner(ImGuiKey key, ImGuiID owner_id) // - SetKeyOwner(..., None) : clears owner // - SetKeyOwner(..., Any, !Lock) : illegal (assert) // - SetKeyOwner(..., Any or None, Lock) : set lock +// Ownership is automatically released on the frame after a release, see code in UpdateKeyboardInputs(). void ImGui::SetKeyOwner(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags) { ImGuiContext& g = *GImGui; @@ -10680,30 +10724,34 @@ void ImGui::SetKeyOwnersForKeyChord(ImGuiKeyChord key_chord, ImGuiID owner_id, I if (key_chord & ~ImGuiMod_Mask_) { SetKeyOwner((ImGuiKey)(key_chord & ~ImGuiMod_Mask_), owner_id, flags); } } -// This is more or less equivalent to: +// This is more or less equivalent to a fancier version of: // if (IsItemHovered() || IsItemActive()) // SetKeyOwner(key, GetItemID()); // Extensive uses of that (e.g. many calls for a single item) may want to manually perform the tests once and then call SetKeyOwner() multiple times. // More advanced usage scenarios may want to call SetKeyOwner() manually based on different condition. // Worth noting is that only one item can be hovered and only one item can be active, therefore this usage pattern doesn't need to bother with routing and priority. -void ImGui::SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags) +bool ImGui::SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags) { ImGuiContext& g = *GImGui; ImGuiID id = g.LastItemData.ID; if (id == 0 || (g.HoveredId != id && g.ActiveId != id)) - return; + return false; if ((flags & ImGuiInputFlags_CondMask_) == 0) flags |= ImGuiInputFlags_CondDefault_; if ((g.HoveredId == id && (flags & ImGuiInputFlags_CondHovered)) || (g.ActiveId == id && (flags & ImGuiInputFlags_CondActive))) { IM_ASSERT((flags & ~ImGuiInputFlags_SupportedBySetItemKeyOwner) == 0); // Passing flags not supported by this function! + if (!TestKeyOwner(key, id)) + return false; SetKeyOwner(key, id, flags & ~ImGuiInputFlags_CondMask_); + return true; } + return false; } -void ImGui::SetItemKeyOwner(ImGuiKey key) +bool ImGui::SetItemKeyOwner(ImGuiKey key) { - SetItemKeyOwner(key, ImGuiInputFlags_None); + return SetItemKeyOwner(key, ImGuiInputFlags_None); } // This is the only public API until we expose owner_id versions of the API as replacements. @@ -12454,6 +12502,17 @@ bool ImGui::BeginPopupMenuEx(ImGuiID id, const char* label, ImGuiWindowFlags ext return false; } + // As we bypass BeginChild(), set ImGuiChildFlags_AlwaysAutoResize as it is checked independently from ImGuiWindowFlags_AlwaysAutoResize for now (see #9355) + // Ideally we should remove setting ImGuiWindowFlags_AlwaysAutoResize in BeginChild(). + if ((extra_window_flags & ImGuiWindowFlags_ChildWindow) && (extra_window_flags & ImGuiWindowFlags_AlwaysAutoResize)) + { + if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags) + g.NextWindowData.ChildFlags |= ImGuiChildFlags_AlwaysAutoResize; + else + g.NextWindowData.ChildFlags = ImGuiChildFlags_AlwaysAutoResize; + g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasChildFlags; + } + char name[128]; IM_ASSERT(extra_window_flags & ImGuiWindowFlags_ChildMenu); ImFormatString(name, IM_COUNTOF(name), "%s###Menu_%02d", label, g.BeginMenuDepth); // Recycle windows based on depth @@ -13751,13 +13810,13 @@ static void ImGui::NavUpdate() // FIXME-NAV: Now that keys are separated maybe we can get rid of NavInputSource? const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; const ImGuiKey nav_gamepad_keys_to_change_source[] = { ImGuiKey_GamepadFaceRight, ImGuiKey_GamepadFaceLeft, ImGuiKey_GamepadFaceUp, ImGuiKey_GamepadFaceDown, ImGuiKey_GamepadDpadRight, ImGuiKey_GamepadDpadLeft, ImGuiKey_GamepadDpadUp, ImGuiKey_GamepadDpadDown }; - if (nav_gamepad_active) + if (nav_gamepad_active && g.NavInputSource != ImGuiInputSource_Gamepad) for (ImGuiKey key : nav_gamepad_keys_to_change_source) if (IsKeyDown(key)) g.NavInputSource = ImGuiInputSource_Gamepad; const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; const ImGuiKey nav_keyboard_keys_to_change_source[] = { ImGuiKey_Space, ImGuiKey_Enter, ImGuiKey_Escape, ImGuiKey_RightArrow, ImGuiKey_LeftArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow }; - if (nav_keyboard_active) + if (nav_keyboard_active && g.NavInputSource != ImGuiInputSource_Keyboard) for (ImGuiKey key : nav_keyboard_keys_to_change_source) if (IsKeyDown(key)) g.NavInputSource = ImGuiInputSource_Keyboard; @@ -15118,7 +15177,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop { ImRect bb = g.DragDropTargetRect; bb.Expand(-3.5f); - RenderDragDropTargetRectEx(GetForegroundDrawList(), bb); + RenderDragDropTargetRectEx(GetForegroundDrawList(), bb, g.Style.DragDropTargetRounding); } else if (draw_target_rect) { @@ -15149,16 +15208,16 @@ void ImGui::RenderDragDropTargetRectForItem(const ImRect& bb) bool push_clip_rect = !window->ClipRect.Contains(bb_display); if (push_clip_rect) window->DrawList->PushClipRectFullScreen(); - RenderDragDropTargetRectEx(window->DrawList, bb_display); + RenderDragDropTargetRectEx(window->DrawList, bb_display, g.Style.DragDropTargetRounding); if (push_clip_rect) window->DrawList->PopClipRect(); } -void ImGui::RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb) +void ImGui::RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb, float rounding) { ImGuiContext& g = *GImGui; - draw_list->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTargetBg), g.Style.DragDropTargetRounding, 0); - draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTarget), g.Style.DragDropTargetRounding, 0, g.Style.DragDropTargetBorderSize); + draw_list->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTargetBg), rounding, 0); + draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTarget), rounding, g.Style.DragDropTargetBorderSize); } const ImGuiPayload* ImGui::GetDragDropPayload() @@ -16260,7 +16319,7 @@ void ImGui::DebugRenderKeyboardPreview(ImDrawList* draw_list) draw_list->AddRect(key_min, key_max, IM_COL32(24, 24, 24, 255), key_rounding); ImVec2 face_min = ImVec2(key_min.x + key_face_pos.x, key_min.y + key_face_pos.y); ImVec2 face_max = ImVec2(face_min.x + key_face_size.x, face_min.y + key_face_size.y); - draw_list->AddRect(face_min, face_max, IM_COL32(193, 193, 193, 255), key_face_rounding, ImDrawFlags_None, 2.0f); + draw_list->AddRect(face_min, face_max, IM_COL32(193, 193, 193, 255), key_face_rounding, 2.0f); draw_list->AddRectFilled(face_min, face_max, IM_COL32(252, 252, 252, 255), key_face_rounding); ImVec2 label_min = ImVec2(key_min.x + key_label_pos.x, key_min.y + key_label_pos.y); draw_list->AddText(label_min, IM_COL32(64, 64, 64, 255), key_data->Label); @@ -16683,7 +16742,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) BulletText("Table 0x%08X (%d columns, in '%s')", table->ID, table->ColumnsCount, table->OuterWindow->Name); if (IsItemHovered()) - GetForegroundDrawList(table->OuterWindow)->AddRect(table->OuterRect.Min - ImVec2(1, 1), table->OuterRect.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 0, 2.0f); + GetForegroundDrawList(table->OuterWindow)->AddRect(table->OuterRect.Min - ImVec2(1, 1), table->OuterRect.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 2.0f); Indent(); char buf[128]; for (int rect_n = 0; rect_n < TRT_Count; rect_n++) @@ -16698,7 +16757,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImFormatString(buf, IM_COUNTOF(buf), "(%6.1f,%6.1f) (%6.1f,%6.1f) Size (%6.1f,%6.1f) Col %d %s", r.Min.x, r.Min.y, r.Max.x, r.Max.y, r.GetWidth(), r.GetHeight(), column_n, trt_rects_names[rect_n]); Selectable(buf); if (IsItemHovered()) - GetForegroundDrawList(table->OuterWindow)->AddRect(r.Min - ImVec2(1, 1), r.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 0, 2.0f); + GetForegroundDrawList(table->OuterWindow)->AddRect(r.Min - ImVec2(1, 1), r.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 2.0f); } } else @@ -16707,7 +16766,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImFormatString(buf, IM_COUNTOF(buf), "(%6.1f,%6.1f) (%6.1f,%6.1f) Size (%6.1f,%6.1f) %s", r.Min.x, r.Min.y, r.Max.x, r.Max.y, r.GetWidth(), r.GetHeight(), trt_rects_names[rect_n]); Selectable(buf); if (IsItemHovered()) - GetForegroundDrawList(table->OuterWindow)->AddRect(r.Min - ImVec2(1, 1), r.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 0, 2.0f); + GetForegroundDrawList(table->OuterWindow)->AddRect(r.Min - ImVec2(1, 1), r.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 2.0f); } } Unindent(); @@ -16900,7 +16959,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) if (TreeNode("SettingsTables", "Settings packed data: Tables: %d bytes", g.SettingsTables.size())) { for (ImGuiTableSettings* settings = g.SettingsTables.begin(); settings != NULL; settings = g.SettingsTables.next_chunk(settings)) - DebugNodeTableSettings(settings); + DebugNodeTableSettings(settings, NULL); TreePop(); } @@ -17115,7 +17174,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImRect r = Funcs::GetTableRect(table, cfg->ShowTablesRectsType, column_n); ImU32 col = (table->HoveredColumnBody == column_n) ? IM_COL32(255, 255, 128, 255) : IM_COL32(255, 0, 128, 255); float thickness = (table->HoveredColumnBody == column_n) ? 3.0f : 1.0f; - draw_list->AddRect(r.Min, r.Max, col, 0.0f, 0, thickness); + draw_list->AddRect(r.Min, r.Max, col, 0.0f, thickness); } } else @@ -17292,7 +17351,7 @@ void ImGui::DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, con { ImDrawListFlags backup_flags = fg_draw_list->Flags; fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles. - fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), ImDrawFlags_Closed, 1.0f); + fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), 1.0f, ImDrawFlags_Closed); fg_draw_list->Flags = backup_flags; } } @@ -17320,7 +17379,7 @@ void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, co for (int n = 0; n < 3; n++, idx_n++) vtxs_rect.Add((triangle[n] = vtx_buffer[idx_buffer ? idx_buffer[idx_n] : idx_n].pos)); if (show_mesh) - out_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), ImDrawFlags_Closed, 1.0f); // In yellow: mesh triangles + out_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), 1.0f, ImDrawFlags_Closed); // In yellow: mesh triangles } // Draw bounding boxes if (show_aabb) @@ -17601,8 +17660,8 @@ void ImGui::DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label) { ImDrawList* draw_list = GetForegroundDrawList(tab_bar->Window); draw_list->AddRect(tab_bar->BarRect.Min, tab_bar->BarRect.Max, IM_COL32(255, 255, 0, 255)); - draw_list->AddLine(ImVec2(tab_bar->ScrollingRectMinX, tab_bar->BarRect.Min.y), ImVec2(tab_bar->ScrollingRectMinX, tab_bar->BarRect.Max.y), IM_COL32(0, 255, 0, 255)); - draw_list->AddLine(ImVec2(tab_bar->ScrollingRectMaxX, tab_bar->BarRect.Min.y), ImVec2(tab_bar->ScrollingRectMaxX, tab_bar->BarRect.Max.y), IM_COL32(0, 255, 0, 255)); + draw_list->AddLineV(tab_bar->ScrollingRectMinX, tab_bar->BarRect.Min.y, tab_bar->BarRect.Max.y, IM_COL32(0, 255, 0, 255)); + draw_list->AddLineV(tab_bar->ScrollingRectMaxX, tab_bar->BarRect.Min.y, tab_bar->BarRect.Max.y, IM_COL32(0, 255, 0, 255)); } if (open) { @@ -17853,6 +17912,7 @@ void ImGui::ShowDebugLogWindow(bool* p_open) ShowDebugLogFlag("Nav", ImGuiDebugLogFlags_EventNav); ShowDebugLogFlag("Popup", ImGuiDebugLogFlags_EventPopup); ShowDebugLogFlag("Selection", ImGuiDebugLogFlags_EventSelection); + ShowDebugLogFlag("Table", ImGuiDebugLogFlags_EventTable); ShowDebugLogFlag("InputRouting", ImGuiDebugLogFlags_EventInputRouting); if (SmallButton("Clear")) @@ -17931,8 +17991,8 @@ void ImGui::DebugDrawCursorPos(ImU32 col) ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; ImVec2 pos = window->DC.CursorPos; - window->DrawList->AddLine(ImVec2(pos.x, pos.y - 3.0f), ImVec2(pos.x, pos.y + 4.0f), col, 1.0f); - window->DrawList->AddLine(ImVec2(pos.x - 3.0f, pos.y), ImVec2(pos.x + 4.0f, pos.y), col, 1.0f); + window->DrawList->AddLineV(pos.x, pos.y - 3.0f, pos.y + 4.0f, col, 1.0f); + window->DrawList->AddLineH(pos.x - 3.0f, pos.x + 4.0f, pos.y, col, 1.0f); } // Draw a 10px wide rectangle around CurposPos.x using Line Y1/Y2 in current window's DrawList @@ -17943,9 +18003,9 @@ void ImGui::DebugDrawLineExtents(ImU32 col) float curr_x = window->DC.CursorPos.x; float line_y1 = (window->DC.IsSameLine ? window->DC.CursorPosPrevLine.y : window->DC.CursorPos.y); float line_y2 = line_y1 + (window->DC.IsSameLine ? window->DC.PrevLineSize.y : window->DC.CurrLineSize.y); - window->DrawList->AddLine(ImVec2(curr_x - 5.0f, line_y1), ImVec2(curr_x + 5.0f, line_y1), col, 1.0f); - window->DrawList->AddLine(ImVec2(curr_x - 0.5f, line_y1), ImVec2(curr_x - 0.5f, line_y2), col, 1.0f); - window->DrawList->AddLine(ImVec2(curr_x - 5.0f, line_y2), ImVec2(curr_x + 5.0f, line_y2), col, 1.0f); + window->DrawList->AddLineH(curr_x - 5.0f, curr_x + 5.0f, line_y1, col, 1.0f); + window->DrawList->AddLineV(curr_x - 0.5f, line_y1, line_y2, col, 1.0f); + window->DrawList->AddLineH(curr_x - 5.0f, curr_x + 5.0f, line_y2, col, 1.0f); } // Draw last item rect in ForegroundDrawList (so it is always visible) @@ -18315,7 +18375,7 @@ void ImGui::ShowFontSelector(const char* label) "- Load additional fonts with io.Fonts->AddFontXXX() functions.\n" "- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n" "- Read FAQ and docs/FONTS.md for more details.\n" - "- If you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame()."); + "- Legacy backend: if you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame()."); } #endif // #if !defined(IMGUI_DISABLE_DEMO_WINDOWS) || !defined(IMGUI_DISABLE_DEBUG_TOOLS) diff --git a/src/libs/imgui/imgui_draw.cpp b/src/libs/imgui/imgui_draw.cpp index dc814a4..4a68ff4 100644 --- a/src/libs/imgui/imgui_draw.cpp +++ b/src/libs/imgui/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.8 WIP +// dear imgui, v1.92.9 WIP // (drawing and font code) /* @@ -208,6 +208,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f); colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_CheckboxSelectedBg] = ImLerp(colors[ImGuiCol_FrameBg], colors[ImGuiCol_FrameBgHovered], 0.65f); colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f); colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); @@ -275,6 +276,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst) colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.41f, 0.39f, 0.80f, 0.60f); colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); + colors[ImGuiCol_CheckboxSelectedBg] = ImLerp(colors[ImGuiCol_FrameBg], colors[ImGuiCol_FrameBgActive], 0.65f); colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); colors[ImGuiCol_SliderGrabActive] = ImVec4(0.41f, 0.39f, 0.80f, 0.60f); colors[ImGuiCol_Button] = ImVec4(0.35f, 0.40f, 0.61f, 0.62f); @@ -343,6 +345,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.49f, 0.49f, 0.49f, 0.80f); colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f); colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_CheckboxSelectedBg] = ImVec4(0.95f, 0.97f, 1.00f, 1.00f); colors[ImGuiCol_SliderGrab] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f); colors[ImGuiCol_SliderGrabActive] = ImVec4(0.46f, 0.54f, 0.80f, 0.60f); colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); @@ -399,7 +402,6 @@ ImDrawListSharedData::ImDrawListSharedData() const float a = ((float)i * 2 * IM_PI) / (float)IM_COUNTOF(ArcFastVtx); ArcFastVtx[i] = ImVec2(ImCos(a), ImSin(a)); } - ArcFastRadiusCutoff = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(IM_DRAWLIST_ARCFAST_SAMPLE_MAX, CircleSegmentMaxError); } ImDrawListSharedData::~ImDrawListSharedData() @@ -409,17 +411,17 @@ ImDrawListSharedData::~ImDrawListSharedData() void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error) { - if (CircleSegmentMaxError == max_error) + if (CircleTessellationMaxError == max_error) return; IM_ASSERT(max_error > 0.0f); - CircleSegmentMaxError = max_error; + CircleTessellationMaxError = max_error; for (int i = 0; i < IM_COUNTOF(CircleSegmentCounts); i++) { const float radius = (float)i; - CircleSegmentCounts[i] = (ImU8)((i > 0) ? IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError) : IM_DRAWLIST_ARCFAST_SAMPLE_MAX); + CircleSegmentCounts[i] = (ImU8)((i > 0) ? IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleTessellationMaxError) : IM_DRAWLIST_ARCFAST_SAMPLE_MAX); } - ArcFastRadiusCutoff = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(IM_DRAWLIST_ARCFAST_SAMPLE_MAX, CircleSegmentMaxError); + ArcFastRadiusCutoff = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(IM_DRAWLIST_ARCFAST_SAMPLE_MAX, CircleTessellationMaxError); } ImDrawList::ImDrawList(ImDrawListSharedData* shared_data) @@ -653,11 +655,11 @@ void ImDrawList::_OnChangedVtxOffset() int ImDrawList::_CalcCircleAutoSegmentCount(float radius) const { // Automatic segment count - const int radius_idx = (int)(radius + 0.999999f); // ceil to never reduce accuracy + const int radius_idx = (int)(radius + 0.999f); // ceil to never reduce accuracy if (radius_idx >= 0 && radius_idx < IM_COUNTOF(_Data->CircleSegmentCounts)) return _Data->CircleSegmentCounts[radius_idx]; // Use cached value else - return IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError); + return IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleTessellationMaxError); } // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) @@ -811,7 +813,7 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c // TODO: Thickness anti-aliased lines cap are missing their AA fringe. // We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds. -void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, ImDrawFlags flags, float thickness) +void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, float thickness, ImDrawFlags flags) { if (points_count < 2 || (col & IM_COL32_A_MASK) == 0) return; @@ -821,6 +823,12 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw const bool thick_line = (thickness > _FringeScale); + // If this assert triggers on legacy code: + // - 1.92.8 (2025/05): swapped two last parameters order: flags, thickness --> thickness, flags. This should normally be caught by compile-time type-checking. + // - 1.92.8 (2025/05): changed value of ImDrawList_Closed which was previously guaranteed to be == 1. Hardcoded use of 1 or true should be replaced. + // Read more details near AddRect() + see "API BREAKING CHANGES" section for 1.82, 1.90 and 1.92.8. + IM_ASSERT_USER_ERROR_RET((flags & ImDrawFlags_InvalidMask_) == 0, "Incorrect parameter. Did you swap 'thickness' and 'flags'?"); + if (Flags & ImDrawListFlags_AntiAliasedLines) { // Anti-aliased stroke @@ -1441,14 +1449,6 @@ void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDr { if (rounding >= 0.5f) { - // If this assert triggers on legacy code, please update your code replacing hardcoded values with ImDrawFlags_RoundCorners* values. - // - See details in 1.82 Changelog as well as 2021/03/12 and 2023/09/08 entries in "API BREAKING CHANGES" section. - // - Note that ImDrawFlags_Closed (== 0x01) is an invalid flag for AddRect(), AddRectFilled(), PathRect() etc. anyway. - // - Marked obsolete in 1.82 and completely removed in 1.90: - // - Hard coded support for ~0 == ImDrawFlags_RoundCornersAll. - // - Hard coded support for values 0x01 to 0x0F (matching 15 out of 16 old flags combinations) --> see FixRectCornerFlags() in <1.90 code. - // - Hard coded 0x00 with 'float rounding > 0.0f' --> replace with ImDrawFlags_RoundCornersNone or use 'float rounding = 0.0f' - IM_ASSERT((flags & 0x0F) == 0 && "Misuse of legacy hardcoded ImDrawCornerFlags values!"); if ((flags & ImDrawFlags_RoundCornersMask_) == 0) flags |= ImDrawFlags_RoundCornersAll; @@ -1479,22 +1479,48 @@ void ImDrawList::AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float th { if ((col & IM_COL32_A_MASK) == 0) return; - PathLineTo(p1 + ImVec2(0.5f, 0.5f)); - PathLineTo(p2 + ImVec2(0.5f, 0.5f)); - PathStroke(col, 0, thickness); + const ImVec2 points[2] = { ImVec2(p1.x + 0.5f, p1.y + 0.5f), ImVec2(p2.x + 0.5f, p2.y + 0.5f) }; + AddPolyline(points, 2, col, thickness); +} + +void ImDrawList::AddLineH(float min_x, float max_x, float y, ImU32 col, float thickness) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + const ImVec2 points[2] = { ImVec2(min_x + 0.5f, y + 0.5f), ImVec2(max_x + 0.5f, y + 0.5f) }; // Same as AddLine() above. + AddPolyline(points, 2, col, thickness); +} + +void ImDrawList::AddLineV(float x, float min_y, float max_y, ImU32 col, float thickness) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + const ImVec2 points[2] = { ImVec2(x + 0.5f, min_y + 0.5f), ImVec2(x + 0.5f, max_y + 0.5f) }; // Same as AddLine() above. + AddPolyline(points, 2, col, thickness); } // p_min = upper-left, p_max = lower-right // Note we don't render 1 pixels sized rectangles properly. -void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags, float thickness) -{ +void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, float thickness, ImDrawFlags flags) +{ + // If this assert triggers on legacy code: + // - 1.92.8 (2025/05): swapped two last parameters order: flags, thickness --> thickness, flags. This should normally be caught by compile-time type-checking. + // - 1.92.8 (2025/05): changed value of ImDrawList_Closed which was previously guaranteed to be == 1. Hardcoded use of 1 or true should be replaced. + // - 1.82.0 (2021/03): changed ImDrawCornerFlags to ImDrawFlags_RoundCornersXXX values. + // If you used hard-coded 1 to 15 or ~0 in flags to configure corner rounding use the new flags! + // - Hard coded support for ~0 == ImDrawFlags_RoundCornersAll. + // - Hard coded support for values 0x01 to 0x0F (matching 15 out of 16 old flags combinations) --> see FixRectCornerFlags() in <1.90 code. + // - Hard coded 0x00 with 'float rounding > 0.0f' --> replace with ImDrawFlags_RoundCornersNone or use 'float rounding = 0.0f'. + // See "API BREAKING CHANGES" section for 1.82, 1.90 and 1.92.8. + IM_ASSERT_USER_ERROR_RET((flags & ImDrawFlags_InvalidMask_) == 0, "Incorrect parameter. Did you swap 'thickness' and 'flags'?"); // Or misuse of legacy hard-coded ImDrawCornerFlags values + if ((col & IM_COL32_A_MASK) == 0) return; if (Flags & ImDrawListFlags_AntiAliasedLines) PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.50f, 0.50f), rounding, flags); else PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.49f, 0.49f), rounding, flags); // Better looking lower-right corner and rounded non-AA shapes. - PathStroke(col, ImDrawFlags_Closed, thickness); + PathStroke(col, thickness, ImDrawFlags_Closed); } void ImDrawList::AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags) @@ -1538,7 +1564,7 @@ void ImDrawList::AddQuad(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, c PathLineTo(p2); PathLineTo(p3); PathLineTo(p4); - PathStroke(col, ImDrawFlags_Closed, thickness); + PathStroke(col, thickness, ImDrawFlags_Closed); } void ImDrawList::AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col) @@ -1561,7 +1587,7 @@ void ImDrawList::AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p PathLineTo(p1); PathLineTo(p2); PathLineTo(p3); - PathStroke(col, ImDrawFlags_Closed, thickness); + PathStroke(col, thickness, ImDrawFlags_Closed); } void ImDrawList::AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col) @@ -1596,7 +1622,7 @@ void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int nu PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1); } - PathStroke(col, ImDrawFlags_Closed, thickness); + PathStroke(col, thickness, ImDrawFlags_Closed); } void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments) @@ -1632,7 +1658,7 @@ void ImDrawList::AddNgon(const ImVec2& center, float radius, ImU32 col, int num_ // Because we are filling a closed shape we remove 1 from the count of segments/points const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments; PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1); - PathStroke(col, ImDrawFlags_Closed, thickness); + PathStroke(col, thickness, ImDrawFlags_Closed); } // Guaranteed to honor 'num_segments' @@ -1659,7 +1685,7 @@ void ImDrawList::AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 co // Because we are filling a closed shape we remove 1 from the count of segments/points const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments; PathEllipticalArcTo(center, radius, rot, 0.0f, a_max, num_segments - 1); - PathStroke(col, true, thickness); + PathStroke(col, thickness, ImDrawFlags_Closed); } void ImDrawList::AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot, int num_segments) @@ -1684,7 +1710,7 @@ void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2 PathLineTo(p1); PathBezierCubicCurveTo(p2, p3, p4, num_segments); - PathStroke(col, 0, thickness); + PathStroke(col, thickness); } // Quadratic Bezier takes 3 controls points @@ -1695,7 +1721,7 @@ void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const Im PathLineTo(p1); PathBezierQuadraticCurveTo(p2, p3, num_segments); - PathStroke(col, 0, thickness); + PathStroke(col, thickness); } void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect) @@ -2495,10 +2521,11 @@ void ImTextureData::DestroyPixels() // - Default texture data encoded in ASCII // - ImFontAtlas() // - ImFontAtlas::Clear() -// - ImFontAtlas::CompactCache() +// - ImFontAtlas::ClearFonts() // - ImFontAtlas::ClearInputData() // - ImFontAtlas::ClearTexData() -// - ImFontAtlas::ClearFonts() +// - ImFontAtlas::CompactCache() +// - ImFontAtlas::SetFontLoader() //----------------------------------------------------------------------------- // - ImFontAtlasUpdateNewFrame() // - ImFontAtlasTextureBlockConvert() @@ -2535,8 +2562,6 @@ void ImTextureData::DestroyPixels() // - ImFontAtlasBuildPreloadAllGlyphRanges() // - ImFontAtlasBuildUpdatePointers() // - ImFontAtlasBuildRenderBitmapFromString() -// - ImFontAtlasBuildUpdateBasicTexData() -// - ImFontAtlasBuildUpdateLinesTexData() // - ImFontAtlasBuildAddFont() // - ImFontAtlasBuildSetupFontBakedEllipsis() // - ImFontAtlasBuildSetupFontBakedBlanks() @@ -2553,13 +2578,14 @@ void ImTextureData::DestroyPixels() // - ImFontAtlasUpdateDrawListsSharedData() //----------------------------------------------------------------------------- // - ImFontAtlasBuildSetTexture() -// - ImFontAtlasBuildAddTexture() -// - ImFontAtlasBuildMakeSpace() -// - ImFontAtlasBuildRepackTexture() -// - ImFontAtlasBuildGrowTexture() -// - ImFontAtlasBuildRepackOrGrowTexture() -// - ImFontAtlasBuildGetTextureSizeEstimate() -// - ImFontAtlasBuildCompactTexture() +// - ImFontAtlasBuildUpdateTexData() +// - ImFontAtlasTextureAdd() +// - ImFontAtlasTextureRepack() +// - ImFontAtlasTextureGrow() +// - ImFontAtlasTextureMakeSpace() +// - ImFontAtlasTextureGetSizeEstimate() +// - ImFontAtlasBuildClear() +// - ImFontAtlasTextureCompact() // - ImFontAtlasBuildInit() // - ImFontAtlasBuildDestroy() //----------------------------------------------------------------------------- @@ -2659,9 +2685,12 @@ ImFontAtlas::~ImFontAtlas() TexData = NULL; } -// If you call this mid-frame, you would need to add new font and bind them! +// You probably should not call this directly. It is not well specified. +// If you want to replace all your fonts mid-frame, most likely you should instead call ClearFonts() then load the new fonts. +// Calling this mid-frame will discard the CPU-side copy of the texture data which is generally unreliable as you may have textures queued for creation or updates. void ImFontAtlas::Clear() { + IMGUI_DEBUG_LOG_FONT("[font] ImFontAtlas::Clear()\n"); bool backup_renderer_has_textures = RendererHasTextures; RendererHasTextures = false; // Full Clear() is supported, but ClearTexData() only isn't. ClearFonts(); @@ -2669,20 +2698,28 @@ void ImFontAtlas::Clear() RendererHasTextures = backup_renderer_has_textures; } -void ImFontAtlas::CompactCache() -{ - ImFontAtlasTextureCompact(this); -} - -void ImFontAtlas::SetFontLoader(const ImFontLoader* font_loader) +void ImFontAtlas::ClearFonts() { - ImFontAtlasBuildSetupFontLoader(this, font_loader); + // FIXME-NEWATLAS: Illegal to remove currently bound font. + IMGUI_DEBUG_LOG_FONT("[font] ImFontAtlas::ClearFonts()\n"); + IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!"); + for (ImFont* font : Fonts) + ImFontAtlasBuildNotifySetFont(this, font, NULL); + ImFontAtlasBuildDestroy(this); + ClearInputData(); + Fonts.clear_delete(); + TexIsBuilt = false; + for (ImDrawListSharedData* shared_data : DrawListSharedDatas) + if (shared_data->FontAtlas == this) + { + shared_data->Font = NULL; + shared_data->FontScale = shared_data->FontSize = 0.0f; + } } void ImFontAtlas::ClearInputData() { IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!"); - for (ImFont* font : Fonts) ImFontAtlasFontDestroyOutput(this, font); for (ImFontConfig& font_cfg : Sources) @@ -2706,22 +2743,14 @@ void ImFontAtlas::ClearTexData() //Locked = true; // Hoped to be able to lock this down but some reload patterns may not be happy with it. } -void ImFontAtlas::ClearFonts() +void ImFontAtlas::CompactCache() { - // FIXME-NEWATLAS: Illegal to remove currently bound font. - IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!"); - for (ImFont* font : Fonts) - ImFontAtlasBuildNotifySetFont(this, font, NULL); - ImFontAtlasBuildDestroy(this); - ClearInputData(); - Fonts.clear_delete(); - TexIsBuilt = false; - for (ImDrawListSharedData* shared_data : DrawListSharedDatas) - if (shared_data->FontAtlas == this) - { - shared_data->Font = NULL; - shared_data->FontScale = shared_data->FontSize = 0.0f; - } + ImFontAtlasTextureCompact(this); +} + +void ImFontAtlas::SetFontLoader(const ImFontLoader* font_loader) +{ + ImFontAtlasBuildSetupFontLoader(this, font_loader); } static void ImFontAtlasBuildUpdateRendererHasTexturesFromContext(ImFontAtlas* atlas) @@ -2748,6 +2777,28 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere IM_ASSERT(atlas->Builder == NULL || atlas->Builder->FrameCount < frame_count); // Protection against being called twice. atlas->RendererHasTextures = renderer_has_textures; + // Update texture status and discard old textures. + // (we do this first thing to handle an edge case: if user mistakenly calls ClearFonts()+SetStatus(OK) during + // rendering, it would ImFontAtlasBuildMain() rebuilding before tex->Updates[] gets a chance to be cleared) + // (if somehow we need to move this back lower in the function, we could manually call the code to clear Updates[]). + for (int tex_n = 0; tex_n < atlas->TexList.Size; tex_n++) + { + // Update and remove if requested + ImTextureData* tex = atlas->TexList[tex_n]; + if (tex->Status == ImTextureStatus_WantCreate && atlas->RendererHasTextures) + IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture's TexID/BackendUserData but did not update Status to OK."); + + bool remove_from_list = ImTextureDataUpdateNewFrame(tex); + if (remove_from_list) + { + IM_ASSERT(atlas->TexData != tex); + tex->DestroyPixels(); + IM_DELETE(tex); + atlas->TexList.erase(atlas->TexList.begin() + tex_n); + tex_n--; + } + } + // Check that font atlas was built or backend support texture reload in which case we can build now if (atlas->RendererHasTextures) { @@ -2787,61 +2838,49 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere builder->BakedPool.Size -= builder->BakedDiscardedCount; builder->BakedDiscardedCount = 0; } +} - // Update texture status - for (int tex_n = 0; tex_n < atlas->TexList.Size; tex_n++) +bool ImTextureDataUpdateNewFrame(ImTextureData* tex) +{ + bool remove_from_list = false; + if (tex->Status == ImTextureStatus_OK) { - ImTextureData* tex = atlas->TexList[tex_n]; - bool remove_from_list = false; - if (tex->Status == ImTextureStatus_OK) - { - tex->Updates.resize(0); - tex->UpdateRect.x = tex->UpdateRect.y = (unsigned short)~0; - tex->UpdateRect.w = tex->UpdateRect.h = 0; - } - if (tex->Status == ImTextureStatus_WantCreate && atlas->RendererHasTextures) - IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture's TexID/BackendUserData but did not update Status to OK."); + tex->Updates.resize(0); + tex->UpdateRect.x = tex->UpdateRect.y = (unsigned short)~0; + tex->UpdateRect.w = tex->UpdateRect.h = 0; + } - // Request destroy - // - Keep bool to true in order to differentiate a planned destroy vs a destroy decided by the backend. - // - We don't destroy pixels right away, as backend may have an in-flight copy from RAM. - if (tex->WantDestroyNextFrame && tex->Status != ImTextureStatus_Destroyed && tex->Status != ImTextureStatus_WantDestroy) - { - IM_ASSERT(tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates); - tex->Status = ImTextureStatus_WantDestroy; - } + // Request destroy + // - Keep bool to true in order to differentiate a planned destroy vs a destroy decided by the backend. + // - We don't destroy pixels right away, as backend may have an in-flight copy from RAM. + if (tex->WantDestroyNextFrame && tex->Status != ImTextureStatus_Destroyed && tex->Status != ImTextureStatus_WantDestroy) + { + IM_ASSERT(tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates); + tex->Status = ImTextureStatus_WantDestroy; + } - // If a texture has never reached the backend, they don't need to know about it. - // (note: backends between 1.92.0 and 1.92.4 could set an already destroyed texture to ImTextureStatus_WantDestroy - // when invalidating graphics objects twice, which would previously remove it from the list and crash.) - if (tex->Status == ImTextureStatus_WantDestroy && tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL) - tex->Status = ImTextureStatus_Destroyed; + // If a texture has never reached the backend, they don't need to know about it. + // (note: backends between 1.92.0 and 1.92.4 could set an already destroyed texture to ImTextureStatus_WantDestroy + // when invalidating graphics objects twice, which would previously remove it from the list and crash.) + if (tex->Status == ImTextureStatus_WantDestroy && tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL) + tex->Status = ImTextureStatus_Destroyed; - // Process texture being destroyed - if (tex->Status == ImTextureStatus_Destroyed) - { - IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture Status to Destroyed but did not clear TexID/BackendUserData!"); - if (tex->WantDestroyNextFrame) - remove_from_list = true; // Destroy was scheduled by us - else - tex->Status = ImTextureStatus_WantCreate; // Destroy was done was backend: recreate it (e.g. freed resources mid-run) - } + // Process texture being destroyed + if (tex->Status == ImTextureStatus_Destroyed) + { + IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture Status to Destroyed but did not clear TexID/BackendUserData!"); + if (tex->WantDestroyNextFrame) + remove_from_list = true; // Destroy was scheduled by us + else + tex->Status = ImTextureStatus_WantCreate; // Destroy was done was backend: recreate it (e.g. freed resources mid-run) + } - // The backend may need defer destroying by a few frames, to handle texture used by previous in-flight rendering. - // We allow the texture staying in _WantDestroy state and increment a counter which the backend can use to take its decision. - if (tex->Status == ImTextureStatus_WantDestroy) - tex->UnusedFrames++; + // The backend may need defer destroying by a few frames, to handle texture used by previous in-flight rendering. + // We allow the texture staying in _WantDestroy state and increment a counter which the backend can use to take its decision. + if (tex->Status == ImTextureStatus_WantDestroy) + tex->UnusedFrames++; - // Destroy and remove - if (remove_from_list) - { - IM_ASSERT(atlas->TexData != tex); - tex->DestroyPixels(); - IM_DELETE(tex); - atlas->TexList.erase(atlas->TexList.begin() + tex_n); - tex_n--; - } - } + return remove_from_list; } void ImFontAtlasTextureBlockConvert(const unsigned char* src_pixels, ImTextureFormat src_fmt, int src_pitch, unsigned char* dst_pixels, ImTextureFormat dst_fmt, int dst_pitch, int w, int h) @@ -2955,12 +2994,17 @@ void ImFontAtlasTextureBlockCopy(ImTextureData* src_tex, int src_x, int src_y, I memcpy(dst_tex->GetPixelsAt(dst_x, dst_y + y), src_tex->GetPixelsAt(src_x, src_y + y), w * dst_tex->BytesPerPixel); } -// Queue texture block update for renderer backend void ImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas, ImTextureData* tex, int x, int y, int w, int h) +{ + ImTextureDataQueueUpload(tex, x, y, w, h); + atlas->TexIsBuilt = false; +} + +// Queue texture block update for renderer backend +void ImTextureDataQueueUpload(ImTextureData* tex, int x, int y, int w, int h) { IM_ASSERT(tex->Status != ImTextureStatus_WantDestroy && tex->Status != ImTextureStatus_Destroyed); IM_ASSERT(x >= 0 && x <= 0xFFFF && y >= 0 && y <= 0xFFFF && w >= 0 && x + w <= 0x10000 && h >= 0 && y + h <= 0x10000); - IM_UNUSED(atlas); ImTextureRect req = { (unsigned short)x, (unsigned short)y, (unsigned short)w, (unsigned short)h }; int new_x1 = ImMax(tex->UpdateRect.w == 0 ? 0 : tex->UpdateRect.x + tex->UpdateRect.w, req.x + req.w); @@ -2973,7 +3017,6 @@ void ImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas, ImTextureData* tex, tex->UsedRect.y = ImMin(tex->UsedRect.y, req.y); tex->UsedRect.w = (unsigned short)(ImMax(tex->UsedRect.x + tex->UsedRect.w, req.x + req.w) - tex->UsedRect.x); tex->UsedRect.h = (unsigned short)(ImMax(tex->UsedRect.y + tex->UsedRect.h, req.y + req.h) - tex->UsedRect.y); - atlas->TexIsBuilt = false; // No need to queue if status is == ImTextureStatus_WantCreate if (tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantUpdates) @@ -3113,8 +3156,10 @@ static void Decode85(const unsigned char* src, unsigned char* dst) dst += 4; } } -#ifndef IMGUI_DISABLE_DEFAULT_FONT +#if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_BITMAP) static const char* GetDefaultCompressedFontDataProggyClean(int* out_size); +#endif +#if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_VECTOR) static const char* GetDefaultCompressedFontDataProggyForever(int* out_size); #endif @@ -3139,7 +3184,7 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg) // If you want a similar font which may be better scaled, consider using AddFontDefaultVector(). ImFont* ImFontAtlas::AddFontDefaultBitmap(const ImFontConfig* font_cfg_template) { -#ifndef IMGUI_DISABLE_DEFAULT_FONT +#if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_BITMAP) ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); if (!font_cfg_template) font_cfg.PixelSnapH = true; // Prevents sub-integer scaling factors at lower-level layers. @@ -3160,14 +3205,14 @@ ImFont* ImFontAtlas::AddFontDefaultBitmap(const ImFontConfig* font_cfg_template) IM_ASSERT(0 && "Function is disabled in this build."); IM_UNUSED(font_cfg_template); return NULL; -#endif // #ifndef IMGUI_DISABLE_DEFAULT_FONT +#endif } // Load a minimal version of ProggyForever, designed to match our good old ProggyClean, but nicely scalable. // (See build script in https://github.com/ocornut/proggyforever for details) ImFont* ImFontAtlas::AddFontDefaultVector(const ImFontConfig* font_cfg_template) { -#ifndef IMGUI_DISABLE_DEFAULT_FONT +#if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_VECTOR) ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); if (!font_cfg_template) font_cfg.PixelSnapH = true; // Precisely match ProggyClean, but prevents sub-integer scaling factors at lower-level layers. @@ -3188,7 +3233,7 @@ ImFont* ImFontAtlas::AddFontDefaultVector(const ImFontConfig* font_cfg_template) IM_ASSERT(0 && "Function is disabled in this build."); IM_UNUSED(font_cfg_template); return NULL; -#endif // #ifndef IMGUI_DISABLE_DEFAULT_FONT +#endif } ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) @@ -3544,7 +3589,7 @@ void ImFontAtlasBuildRenderBitmapFromString(ImFontAtlas* atlas, int x, int y, in } } -static void ImFontAtlasBuildUpdateBasicTexData(ImFontAtlas* atlas) +static void ImFontAtlasBuildUpdateTexDataBasic(ImFontAtlas* atlas) { // Pack and store identifier so we can refresh UV coordinates on texture resize. // FIXME-NEWATLAS: User/custom rects where user code wants to store UV coordinates will need to do the same thing. @@ -3578,7 +3623,7 @@ static void ImFontAtlasBuildUpdateBasicTexData(ImFontAtlas* atlas) atlas->TexUvWhitePixel = ImVec2((r.x + 0.5f) * atlas->TexUvScale.x, (r.y + 0.5f) * atlas->TexUvScale.y); } -static void ImFontAtlasBuildUpdateLinesTexData(ImFontAtlas* atlas) +static void ImFontAtlasBuildUpdateTexDataLines(ImFontAtlas* atlas) { if (atlas->Flags & ImFontAtlasFlags_NoBakedLines) return; @@ -4027,6 +4072,12 @@ static void ImFontAtlasBuildSetTexture(ImFontAtlas* atlas, ImTextureData* tex) ImFontAtlasUpdateDrawListsTextures(atlas, old_tex_ref, atlas->TexRef); } +static void ImFontAtlasBuildUpdateTexData(ImFontAtlas* atlas) +{ + ImFontAtlasBuildUpdateTexDataBasic(atlas); + ImFontAtlasBuildUpdateTexDataLines(atlas); +} + // Create a new texture, discard previous one ImTextureData* ImFontAtlasTextureAdd(ImFontAtlas* atlas, int w, int h) { @@ -4141,8 +4192,7 @@ void ImFontAtlasTextureRepack(ImFontAtlas* atlas, int w, int h) } // Update other cached UV - ImFontAtlasBuildUpdateLinesTexData(atlas); - ImFontAtlasBuildUpdateBasicTexData(atlas); + ImFontAtlasBuildUpdateTexData(atlas); builder->LockDisableResize = false; ImFontAtlasUpdateDrawListsSharedData(atlas); @@ -4291,8 +4341,7 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas) ImFontAtlasPackInit(atlas); // Add required texture data - ImFontAtlasBuildUpdateLinesTexData(atlas); - ImFontAtlasBuildUpdateBasicTexData(atlas); + ImFontAtlasBuildUpdateTexData(atlas); // Register fonts ImFontAtlasBuildUpdatePointers(atlas); @@ -4321,6 +4370,8 @@ void ImFontAtlasBuildDestroy(ImFontAtlas* atlas) atlas->Builder = NULL; } +//----------------------------------------------------------------------------- + void ImFontAtlasPackInit(ImFontAtlas * atlas) { ImTextureData* tex = atlas->TexData; @@ -5717,8 +5768,13 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im if (glyph->Colored) col |= ~IM_COL32_A_MASK; float scale = (size >= 0.0f) ? (size / baked->Size) : 1.0f; - float x = IM_TRUNC(pos.x); - float y = IM_TRUNC(pos.y); + float x = pos.x; + float y = pos.y; + if ((draw_list->Flags & ImDrawListFlags_TextNoPixelSnap) == 0) + { + x = IM_TRUNC(x); + y = IM_TRUNC(y); + } float x1 = x + glyph->X0 * scale; float x2 = x + glyph->X1 * scale; @@ -5750,12 +5806,17 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im // DO NOT CALL DIRECTLY THIS WILL CHANGE WILDLY IN 2026. Use ImDrawList::AddText(). void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, ImDrawTextFlags flags) { - // Align to be pixel perfect begin: - float x = IM_TRUNC(pos.x); - float y = IM_TRUNC(pos.y); + // Align to be pixel perfect + float x = pos.x; + float y = pos.y; if (y > clip_rect.w) return; + if ((draw_list->Flags & ImDrawListFlags_TextNoPixelSnap) == 0) + { + x = IM_TRUNC(x); + y = IM_TRUNC(y); + } if (!text_end) text_end = text_begin + ImStrlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls. @@ -6019,7 +6080,7 @@ void ImGui::RenderCheckMark(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float draw_list->PathLineTo(ImVec2(bx - third, by - third)); draw_list->PathLineTo(ImVec2(bx, by)); draw_list->PathLineTo(ImVec2(bx + third * 2.0f, by - third * 2.0f)); - draw_list->PathStroke(col, 0, thickness); + draw_list->PathStroke(col, thickness); } // Render an arrow. 'pos' is position of the arrow tip. half_sz.x is length from base to tip. half_sz.y is length on each side. @@ -6141,8 +6202,8 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p flags = ImDrawFlags_RoundCornersDefault_; if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF) { - ImU32 col_bg1 = GetColorU32(ImAlphaBlendColors(IM_COL32(204, 204, 204, 255), col)); - ImU32 col_bg2 = GetColorU32(ImAlphaBlendColors(IM_COL32(128, 128, 128, 255), col)); + ImU32 col_bg1 = GetColorU32(ImAlphaBlendColors(IM_COL32(128, 128, 128, 255), col)); + ImU32 col_bg2 = GetColorU32(ImAlphaBlendColors(IM_COL32(204, 204, 204, 255), col)); draw_list->AddRectFilled(p_min, p_max, col_bg1, rounding, flags); int yi = 0; @@ -6151,12 +6212,12 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p float y1 = ImClamp(y, p_min.y, p_max.y), y2 = ImMin(y + grid_step, p_max.y); if (y2 <= y1) continue; - for (float x = p_min.x + grid_off.x + (yi & 1) * grid_step; x < p_max.x; x += grid_step * 2.0f) + for (float x = p_min.x + grid_off.x + ((yi ^ 1) & 1) * grid_step; x < p_max.x; x += grid_step * 2.0f) { float x1 = ImClamp(x, p_min.x, p_max.x), x2 = ImMin(x + grid_step, p_max.x); if (x2 <= x1) continue; - ImDrawFlags cell_flags = ImDrawFlags_RoundCornersNone; + ImDrawFlags cell_flags = ImDrawFlags_RoundCornersNone; // FIXME: Could use CalcRoundingFlagsForRectInRect() if (y1 <= p_min.y) { if (x1 <= p_min.x) cell_flags |= ImDrawFlags_RoundCornersTopLeft; if (x2 >= p_max.x) cell_flags |= ImDrawFlags_RoundCornersTopRight; } if (y2 >= p_max.y) { if (x1 <= p_min.x) cell_flags |= ImDrawFlags_RoundCornersBottomLeft; if (x2 >= p_max.x) cell_flags |= ImDrawFlags_RoundCornersBottomRight; } @@ -6298,7 +6359,7 @@ static unsigned int stb_decompress(unsigned char *output, const unsigned char *i // Download and more information at https://github.com/bluescan/proggyfonts //----------------------------------------------------------------------------- -#ifndef IMGUI_DISABLE_DEFAULT_FONT +#if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_BITMAP) // File: 'ProggyClean.ttf' (41208 bytes) // Exported using binary_to_compressed_c.exe -u8 "ProggyClean.ttf" proggy_clean_ttf @@ -6478,6 +6539,7 @@ static const char* GetDefaultCompressedFontDataProggyClean(int* out_size) *out_size = proggy_clean_ttf_compressed_size; return (const char*)proggy_clean_ttf_compressed_data; } +#endif // #if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_BITMAP) //----------------------------------------------------------------------------- // [SECTION] Default font data (ProggyForever-Regular-minimal.ttf) @@ -6486,6 +6548,8 @@ static const char* GetDefaultCompressedFontDataProggyClean(int* out_size) // MIT license / Copyright (c) 2026 Disco Hello, Copyright (c) 2019,2023 Tristan Grimmer //----------------------------------------------------------------------------- +#if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_VECTOR) + // File: 'output/ProggyForever-Regular-minimal.ttf' (18556 bytes) // Exported using binary_to_compressed_c.exe -u8 "output/ProggyForever-Regular-minimal.ttf" proggy_forever_minimal_ttf static const unsigned int proggy_forever_minimal_ttf_compressed_size = 14562; @@ -6740,7 +6804,6 @@ static const char* GetDefaultCompressedFontDataProggyForever(int* out_size) *out_size = proggy_forever_minimal_ttf_compressed_size; return (const char*)proggy_forever_minimal_ttf_compressed_data; } - -#endif // #ifndef IMGUI_DISABLE_DEFAULT_FONT +#endif // #if !defined(IMGUI_DISABLE_DEFAULT_FONT) && !defined(IMGUI_DISABLE_DEFAULT_FONT_VECTOR) #endif // #ifndef IMGUI_DISABLE diff --git a/src/libs/imgui/imgui_impl_metal.mm b/src/libs/imgui/imgui_impl_metal.mm index db2fcd3..652668c 100644 --- a/src/libs/imgui/imgui_impl_metal.mm +++ b/src/libs/imgui/imgui_impl_metal.mm @@ -5,8 +5,6 @@ // [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef! // [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset). // [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures). -// Missing features or Issues: -// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. @@ -18,6 +16,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2026-04-28: Added support for standard draw callbacks (in platform_io): DrawCallback_SetSamplerLinear and DrawCallback_SetSamplerNearest. (#9378, #9381) // 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState (others are not yet supported). (#9378) // 2026-04-14: Metal: use a dedicated bufferCacheLock to avoid crashing when bufferCache is replaced by a new object while being used for @synchronize(). (#9367) // 2026-04-03: Metal: avoid redundant vertex buffer bind in SetupRenderState. (#9343) @@ -79,6 +78,8 @@ - (instancetype)initWithTexture:(id)metalTexture; @interface MetalContext : NSObject @property (nonatomic, strong) id device; @property (nonatomic, strong) id depthStencilState; +@property (nonatomic, strong) id samplerStateLinear; +@property (nonatomic, strong) id samplerStateNearest; @property (nonatomic, strong) FramebufferDescriptor* framebufferDescriptor; // framebuffer descriptor for current frame; transient @property (nonatomic, strong) NSMutableDictionary* renderPipelineStateCache; // pipeline cache; keyed on framebuffer descriptors @property (nonatomic, strong) NSMutableArray* bufferCache; @@ -91,6 +92,7 @@ - (MetalBuffer*)dequeueReusableBufferOfLength:(NSUInteger)length device:(id RenderCommandEncoder; ImGui_ImplMetal_Data() { memset((void*)this, 0, sizeof(*this)); } }; @@ -185,12 +187,15 @@ static void ImGui_ImplMetal_SetupRenderState(ImDrawData* draw_data, idSharedMetalContext.samplerStateLinear atIndex:0]; [commandEncoder setVertexBuffer:vertexBuffer.buffer offset:vertexBufferOffset atIndex:0]; } // Draw callbacks -static void ImGui_ImplMetal_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way. +static void ImGui_ImplMetal_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way. +static void ImGui_ImplMetal_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData(); [bd->RenderCommandEncoder setFragmentSamplerState:bd->SharedMetalContext.samplerStateLinear atIndex:0]; } +static void ImGui_ImplMetal_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData(); [bd->RenderCommandEncoder setFragmentSamplerState:bd->SharedMetalContext.samplerStateNearest atIndex:0]; } // Metal Render function. void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id commandBuffer, id commandEncoder) @@ -228,6 +233,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id MetalBuffer* vertexBuffer = [ctx dequeueReusableBufferOfLength:vertexBufferLength device:commandBuffer.device]; MetalBuffer* indexBuffer = [ctx dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device]; + bd->RenderCommandEncoder = commandEncoder; ImGui_ImplMetal_SetupRenderState(draw_data, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, 0); // Will project scissor/clipping rectangles into framebuffer space @@ -306,6 +312,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id [sharedMetalContext.bufferCache addObject:indexBuffer]; } }]; + bd->RenderCommandEncoder = nil; } static void ImGui_ImplMetal_DestroyTexture(ImTextureData* tex) @@ -382,7 +389,17 @@ bool ImGui_ImplMetal_CreateDeviceObjects(id device) depthStencilDescriptor.depthWriteEnabled = NO; depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionAlways; bd->SharedMetalContext.depthStencilState = [device newDepthStencilStateWithDescriptor:depthStencilDescriptor]; + MTLSamplerDescriptor* samplerDescriptor = [[MTLSamplerDescriptor alloc] init]; + samplerDescriptor.minFilter = MTLSamplerMinMagFilterLinear; + samplerDescriptor.magFilter = MTLSamplerMinMagFilterLinear; + samplerDescriptor.mipFilter = MTLSamplerMipFilterLinear; + bd->SharedMetalContext.samplerStateLinear = [device newSamplerStateWithDescriptor:samplerDescriptor]; + samplerDescriptor.minFilter = MTLSamplerMinMagFilterNearest; + samplerDescriptor.magFilter = MTLSamplerMinMagFilterNearest; + samplerDescriptor.mipFilter = MTLSamplerMipFilterNearest; + bd->SharedMetalContext.samplerStateNearest = [device newSamplerStateWithDescriptor:samplerDescriptor]; #ifdef IMGUI_IMPL_METAL_CPP + [samplerDescriptor release]; [depthStencilDescriptor release]; #endif @@ -399,6 +416,8 @@ void ImGui_ImplMetal_DestroyDeviceObjects() ImGui_ImplMetal_DestroyTexture(tex); [bd->SharedMetalContext.renderPipelineStateCache removeAllObjects]; + bd->SharedMetalContext.samplerStateLinear = nil; + bd->SharedMetalContext.samplerStateNearest = nil; } bool ImGui_ImplMetal_Init(id device) @@ -415,6 +434,8 @@ bool ImGui_ImplMetal_Init(id device) ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); platform_io.DrawCallback_ResetRenderState = ImGui_ImplMetal_DrawCallback_ResetRenderState; + platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplMetal_DrawCallback_SetSamplerLinear; + platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplMetal_DrawCallback_SetSamplerNearest; bd->SharedMetalContext = [[MetalContext alloc] init]; bd->SharedMetalContext.device = device; @@ -599,9 +620,9 @@ - (MetalBuffer*)dequeueReusableBufferOfLength:(NSUInteger)length device:(id texture [[texture(0)]]) {\n" - " constexpr sampler linearSampler(coord::normalized, min_filter::linear, mag_filter::linear, mip_filter::linear);\n" - " half4 texColor = texture.sample(linearSampler, in.texCoords);\n" + " texture2d texture [[texture(0)]],\n" + " sampler textureSampler [[sampler(0)]]) {\n" + " half4 texColor = texture.sample(textureSampler, in.texCoords);\n" " return half4(in.color) * texColor;\n" "}\n"; diff --git a/src/libs/imgui/imgui_tables.cpp b/src/libs/imgui/imgui_tables.cpp index cc910b9..a028e3b 100644 --- a/src/libs/imgui/imgui_tables.cpp +++ b/src/libs/imgui/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.8 WIP +// dear imgui, v1.92.9 WIP // (tables and columns code) /* @@ -40,13 +40,15 @@ Index of this file: // | TableBeginInitMemory() - first time table is used // | TableResetSettings() - on settings reset // | TableLoadSettings() - on settings load -// | TableBeginApplyRequests() - apply queued resizing/reordering/hiding requests -// | - TableSetColumnWidth() - apply resizing width (for mouse resize, often requested by previous frame) -// | - TableUpdateColumnsWeightFromWidth()- recompute columns weights (of stretch columns) from their respective width +//----------------------------------------------------------------------------- // - TableSetupColumn() user submit columns details (optional) // - TableSetupScrollFreeze() user submit scroll freeze information (optional) //----------------------------------------------------------------------------- // - TableUpdateLayout() [Internal] followup to BeginTable(): setup everything: widths, columns positions, clipping rectangles. Automatically called by the FIRST call to TableNextRow() or TableHeadersRow(). +// | TableApplyQueuedRequests() - apply queued resizing/reordering/hiding requests +// | - TableSetColumnWidth() - apply resizing width (for mouse resize, often requested by previous frame) +// | - TableUpdateColumnsWeightFromWidth()- recompute columns weights (of stretch columns) from their respective width +// | - TableSetColumnDisplayOrder() - apply reordering a column // | TableSetupDrawChannels() - setup ImDrawList channels // | TableUpdateBorders() - detect hovering columns for resize, ahead of contents submission // | TableBeginContextMenuPopup() @@ -252,7 +254,7 @@ Index of this file: // - BeginTable() // - BeginTableEx() [Internal] // - TableBeginInitMemory() [Internal] -// - TableBeginApplyRequests() [Internal] +// - TableApplyQueuedRequests() [Internal] // - TableSetupColumnFlags() [Internal] // - TableUpdateLayout() [Internal] // - TableUpdateBorders() [Internal] @@ -567,6 +569,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG if (old_columns_count != 0 && old_columns_count != columns_count) { // Attempt to preserve width and other settings on column count/specs change (#4046) + IMGUI_DEBUG_LOG_TABLE("[table] Table 0x%08X column count %d -> %d, recreating storage.\n", table->ID, old_columns_count, columns_count); old_columns_to_preserve = table->Columns.Data; old_columns_raw_data = table->RawData; // Free at end of function table->RawData = NULL; @@ -615,21 +618,6 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG if (table->IsSettingsRequestLoad) TableLoadSettings(table); - // Handle DPI/font resize - // This is designed to facilitate DPI changes with the assumption that e.g. style.CellPadding has been scaled as well. - // It will also react to changing fonts with mixed results. It doesn't need to be perfect but merely provide a decent transition. - // FIXME-DPI: Provide consistent standards for reference size. Perhaps using g.CurrentDpiScale would be more self explanatory. - // This is will lead us to non-rounded WidthRequest in columns, which should work but is a poorly tested path. - const float new_ref_scale_unit = g.FontSize; // g.Font->GetCharAdvance('A') ? - if (table->RefScale != 0.0f && table->RefScale != new_ref_scale_unit) - { - const float scale_factor = new_ref_scale_unit / table->RefScale; - //IMGUI_DEBUG_PRINT("[table] %08X RefScaleUnit %.3f -> %.3f, scaling width by %.3f\n", table->ID, table->RefScaleUnit, new_ref_scale_unit, scale_factor); - for (int n = 0; n < columns_count; n++) - table->Columns[n].WidthRequest = table->Columns[n].WidthRequest * scale_factor; - } - table->RefScale = new_ref_scale_unit; - // Disable output until user calls TableNextRow() or TableNextColumn() leading to the TableUpdateLayout() call.. // This is not strictly necessary but will reduce cases were "out of table" output will be misleading to the user. // Because we cannot safely assert in EndTable() when no rows have been created, this seems like our best option. @@ -639,10 +627,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG // At this point the ->NameOffset field of each column will be invalid until TableUpdateLayout() or the first call to TableSetupColumn() if (table->ColumnsNames.Buf.Size > 0) table->ColumnsNames.Buf.resize(0); - - // Apply queued resizing/reordering/hiding requests - TableBeginApplyRequests(table); - + return true; } @@ -677,7 +662,7 @@ void ImGui::TableBeginInitMemory(ImGuiTable* table, int columns_count) } // Apply queued resizing/reordering/hiding requests -void ImGui::TableBeginApplyRequests(ImGuiTable* table) +void ImGui::TableApplyQueuedRequests(ImGuiTable* table) { // Handle resizing request // (We process this in the TableBegin() of the first instance of each table) @@ -719,7 +704,7 @@ void ImGui::TableBeginApplyRequests(ImGuiTable* table) // table->ReorderColumn = -1; } - // Handle display order reset request + // Handle display order / visibility reset requests if (table->IsResetDisplayOrderRequest) { for (int n = 0; n < table->ColumnsCount; n++) @@ -727,6 +712,13 @@ void ImGui::TableBeginApplyRequests(ImGuiTable* table) table->IsResetDisplayOrderRequest = false; table->IsSettingsDirty = true; } + if (table->IsResetVisibilityRequest) + { + for (ImGuiTableColumn& column : table->Columns) + column.IsUserEnabled = column.IsUserEnabledNextFrame = (column.Flags & ImGuiTableColumnFlags_DefaultHide) ? 0 : 1; + table->IsResetVisibilityRequest = false; + table->IsSettingsDirty = true; + } } // Apply immediately. See TableQueueSetColumnDisplayOrder() for additional checks/constraints. @@ -782,8 +774,9 @@ void ImGui::TableQueueSetColumnDisplayOrder(ImGuiTable* table, int column_n, int table->ReorderColumn = (ImGuiTableColumnIdx)column_n; table->ReorderColumnDstOrder = (ImGuiTableColumnIdx)-1; dst_order = TableGetMaxDisplayOrderAllowed(table, src_order, dst_order); - if (dst_order != src_order) - table->ReorderColumnDstOrder = (ImGuiTableColumnIdx)dst_order; + if (table->IsLayoutLocked && dst_order == src_order) // We allow calling the function before layout w/ reconcile so don't early out. + return; + table->ReorderColumnDstOrder = (ImGuiTableColumnIdx)dst_order; } // Adjust flags: default width mode + stretch columns are not allowed when auto extending @@ -851,11 +844,30 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) ImGuiContext& g = *GImGui; IM_ASSERT(table->IsLayoutLocked == false); + // Apply queued resizing/reordering/hiding requests + TableApplyQueuedRequests(table); + + // Handle DPI/font resize + // This is designed to facilitate DPI changes with the assumption that e.g. style.CellPadding has been scaled as well. + // It will also react to changing fonts with mixed results. It doesn't need to be perfect but merely provide a decent transition. + // FIXME-DPI: Provide consistent standards for reference size. Perhaps using g.CurrentDpiScale would be more self explanatory. + // This is will lead us to non-rounded WidthRequest in columns, which should work but is a poorly tested path. + const float new_ref_scale_unit = g.FontSize; // g.Font->GetCharAdvance('A') ? + const int columns_count = table->ColumnsCount; + if (table->RefScale != 0.0f && table->RefScale != new_ref_scale_unit) + { + const float scale_factor = new_ref_scale_unit / table->RefScale; + IMGUI_DEBUG_LOG_TABLE("[table] 0x%08X RefScale %.3f -> %.3f, scaling width by %.3f\n", table->ID, table->RefScale, new_ref_scale_unit, scale_factor); + for (int n = 0; n < columns_count; n++) + table->Columns[n].WidthRequest = table->Columns[n].WidthRequest * scale_factor; + } + table->RefScale = new_ref_scale_unit; + const ImGuiTableFlags table_sizing_policy = (table->Flags & ImGuiTableFlags_SizingMask_); - table->IsDefaultDisplayOrder = true; + table->IsDefaultDisplayOrder = table->IsDefaultVisibility = true; table->ColumnsEnabledCount = 0; - ImBitArrayClearAllBits(table->EnabledMaskByIndex, table->ColumnsCount); - ImBitArrayClearAllBits(table->EnabledMaskByDisplayOrder, table->ColumnsCount); + ImBitArrayClearAllBits(table->EnabledMaskByIndex, columns_count); + ImBitArrayClearAllBits(table->EnabledMaskByDisplayOrder, columns_count); table->LeftMostEnabledColumn = -1; table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE @@ -868,11 +880,9 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) bool has_resizable = false; float stretch_sum_width_auto = 0.0f; float fixed_max_width_auto = 0.0f; - for (int order_n = 0; order_n < table->ColumnsCount; order_n++) + for (int order_n = 0; order_n < columns_count; order_n++) { const int column_n = table->DisplayOrderToIndex[order_n]; - if (column_n != order_n) - table->IsDefaultDisplayOrder = false; ImGuiTableColumn* column = &table->Columns[column_n]; // Clear column setup if not submitted by user. Currently we make it mandatory to call TableSetupColumn() every frame. @@ -882,7 +892,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) { TableSetupColumnFlags(table, column, ImGuiTableColumnFlags_None); column->NameOffset = -1; - column->UserID = 0; + column->UserData = 0; column->InitStretchWeightOrWidth = -1.0f; } @@ -896,6 +906,11 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) } column->IsEnabled = column->IsUserEnabled && (column->Flags & ImGuiTableColumnFlags_Disabled) == 0; + if (column->IsEnabled != ((column->Flags & ImGuiTableColumnFlags_DefaultHide) ? 0 : 1)) + table->IsDefaultVisibility = false; + if (column_n != order_n) + table->IsDefaultDisplayOrder = false; + if (column->SortOrder != -1 && !column->IsEnabled) table->IsSortSpecsDirty = true; if (column->SortOrder > 0 && !(table->Flags & ImGuiTableFlags_SortMulti)) @@ -967,7 +982,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) float sum_width_requests = 0.0f; // Sum of all width for fixed and auto-resize columns, excluding width contributed by Stretch columns but including spacing/padding. float stretch_sum_weights = 0.0f; // Sum of all weights for stretch columns. table->LeftMostStretchedColumn = table->RightMostStretchedColumn = -1; - for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + for (int column_n = 0; column_n < columns_count; column_n++) { if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByIndex, column_n)) continue; @@ -1031,7 +1046,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests; float width_remaining_for_stretched_columns = width_avail_for_stretched_columns; table->ColumnsGivenWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount; - for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + for (int column_n = 0; column_n < columns_count; column_n++) { if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByIndex, column_n)) continue; @@ -1058,7 +1073,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) // [Part 5] Redistribute stretch remainder width due to rounding (remainder width is < 1.0f * number of Stretch column). // Using right-to-left distribution (more likely to match resizing cursor). if (width_remaining_for_stretched_columns >= 1.0f && !(table->Flags & ImGuiTableFlags_PreciseWidths)) - for (int order_n = table->ColumnsCount - 1; stretch_sum_weights > 0.0f && width_remaining_for_stretched_columns >= 1.0f && order_n >= 0; order_n--) + for (int order_n = columns_count - 1; stretch_sum_weights > 0.0f && width_remaining_for_stretched_columns >= 1.0f && order_n >= 0; order_n--) { if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n)) continue; @@ -1098,8 +1113,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) float offset_x = ((table->FreezeColumnsCount > 0) ? table->OuterRect.Min.x : work_rect.Min.x) + table->OuterPaddingX - table->CellSpacingX1; ImRect host_clip_rect = table->InnerClipRect; //host_clip_rect.Max.x += table->CellPaddingX + table->CellSpacingX2; - ImBitArrayClearAllBits(table->VisibleMaskByIndex, table->ColumnsCount); - for (int order_n = 0; order_n < table->ColumnsCount; order_n++) + ImBitArrayClearAllBits(table->VisibleMaskByIndex, columns_count); + for (int order_n = 0; order_n < columns_count; order_n++) { const int column_n = table->DisplayOrderToIndex[order_n]; ImGuiTableColumn* column = &table->Columns[column_n]; @@ -1247,7 +1262,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) const float unused_x1 = ImMax(table->WorkRect.Min.x, table->Columns[table->RightMostEnabledColumn].ClipRect.Max.x); if (is_hovering_table && table->HoveredColumnBody == -1) if (mouse_skewed_x >= unused_x1) - table->HoveredColumnBody = (ImGuiTableColumnIdx)table->ColumnsCount; + table->HoveredColumnBody = (ImGuiTableColumnIdx)columns_count; if (has_resizable == false && (table->Flags & ImGuiTableFlags_Resizable)) table->Flags &= ~ImGuiTableFlags_Resizable; @@ -1289,7 +1304,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) table->HighlightColumnHeader = -1; if (table->IsContextPopupOpen && table->ContextPopupColumn != -1 && table->InstanceInteracted == table->InstanceCurrent) table->HighlightColumnHeader = table->ContextPopupColumn; - else if ((table->Flags & ImGuiTableFlags_HighlightHoveredColumn) && table->HoveredColumnBody != -1 && table->HoveredColumnBody != table->ColumnsCount && table->HoveredColumnBorder == -1) + else if ((table->Flags & ImGuiTableFlags_HighlightHoveredColumn) && table->HoveredColumnBody != -1 && table->HoveredColumnBody != columns_count && table->HoveredColumnBorder == -1) if (g.ActiveId == 0 || (table->IsActiveIdInTable || g.DragDropActive)) table->HighlightColumnHeader = table->HoveredColumnBody; @@ -1656,17 +1671,9 @@ static void TableInitColumnDefaults(ImGuiTable* table, ImGuiTableColumn* column, // See "COLUMNS SIZING POLICIES" comments at the top of this file // If (init_width_or_weight <= 0.0f) it is ignored -void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id) +static void TableSetupColumnApply(ImGuiTable* table, int idx, ImGuiID id, ImS16 name_offset, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_data) { - ImGuiContext& g = *GImGui; - ImGuiTable* table = g.CurrentTable; - IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!"); - IM_ASSERT_USER_ERROR_RET(table->DeclColumnsCount < table->ColumnsCount, "TableSetupColumn(): called too many times!"); - IM_ASSERT_USER_ERROR_RET(table->IsLayoutLocked == false, "TableSetupColumn(): need to call before first row!"); // Table layout is locked when submitting a row or when calling BeginMultiSelect() with box-select. - IM_ASSERT((flags & ImGuiTableColumnFlags_StatusMask_) == 0 && "Illegal to pass StatusMask values to TableSetupColumn()"); - - ImGuiTableColumn* column = &table->Columns[table->DeclColumnsCount]; - table->DeclColumnsCount++; + ImGuiTableColumn* column = &table->Columns[idx]; // Assert when passing a width or weight if policy is entirely left to default, to avoid storing width into weight and vice-versa. // Give a grace to users of ImGuiTableFlags_ScrollX. @@ -1685,7 +1692,9 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo } TableSetupColumnFlags(table, column, flags); - column->UserID = user_id; + column->ID = id; + column->UserData = user_data; + column->NameOffset = name_offset; flags = column->Flags; // Initialize defaults @@ -1697,15 +1706,29 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo init_flags |= ImGuiTableFlags_Resizable; TableInitColumnDefaults(table, column, init_flags); } +} + +void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_data_for_sort_specs) +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + IM_ASSERT_USER_ERROR_RET(table != NULL, "Call should only be done while in BeginTable() scope!"); + IM_ASSERT_USER_ERROR_RET(table->DeclColumnsCount < table->ColumnsCount, "TableSetupColumn(): called too many times!"); + IM_ASSERT_USER_ERROR_RET(table->IsLayoutLocked == false, "TableSetupColumn(): need to call before first row!"); // Table layout is locked when submitting a row or when calling BeginMultiSelect() with box-select. + IM_ASSERT((flags & ImGuiTableColumnFlags_StatusMask_) == 0 && "Illegal to pass StatusMask values to TableSetupColumn()"); // Store name (append with zero-terminator in contiguous buffer) // FIXME: If we recorded the number of \n in names we could compute header row height - column->NameOffset = -1; + ImS16 name_offset = -1; if (label != NULL && label[0] != 0) { - column->NameOffset = (ImS16)table->ColumnsNames.size(); + name_offset = (ImS16)table->ColumnsNames.size(); table->ColumnsNames.append(label, label + ImStrlen(label) + 1); } + + const ImGuiID column_id = (label != NULL && label[0] != 0) ? ImHashStr(label) : 0; + TableSetupColumnApply(table, table->DeclColumnsCount, column_id, name_offset, flags, init_width_or_weight, user_data_for_sort_specs); + table->DeclColumnsCount++; } // [Public] @@ -2074,11 +2097,11 @@ void ImGui::TableEndRow(ImGuiTable* table) // Draw top border if (top_border_col && bg_y1 >= table->BgClipRect.Min.y && bg_y1 < table->BgClipRect.Max.y) - window->DrawList->AddLine(ImVec2(table->BorderX1, bg_y1), ImVec2(table->BorderX2, bg_y1), top_border_col, border_size); + window->DrawList->AddLineH(table->BorderX1, table->BorderX2, bg_y1, top_border_col, border_size); // Draw bottom border at the row unfreezing mark (always strong) if (draw_strong_bottom_border && bg_y2 >= table->BgClipRect.Min.y && bg_y2 < table->BgClipRect.Max.y) - window->DrawList->AddLine(ImVec2(table->BorderX1, bg_y2), ImVec2(table->BorderX2, bg_y2), table->BorderColorStrong, border_size); + window->DrawList->AddLineH(table->BorderX1, table->BorderX2, bg_y2, table->BorderColorStrong, border_size); } // End frozen rows (when we are past the last frozen row line, teleport cursor and alter clipping rectangle) @@ -2855,7 +2878,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table) else if ((table->Flags & (ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_NoBordersInBody)) == 0) draw_y2 = draw_y2_body; if (draw_y2 > draw_y1) - inner_drawlist->AddLine(ImVec2(column->MaxX, draw_y1), ImVec2(column->MaxX, draw_y2), TableGetColumnBorderCol(table, order_n, column_n), border_size); + inner_drawlist->AddLineV(column->MaxX, draw_y1, draw_y2, TableGetColumnBorderCol(table, order_n, column_n), border_size); } } @@ -2872,17 +2895,17 @@ void ImGui::TableDrawBorders(ImGuiTable* table) const ImU32 outer_col = table->BorderColorStrong; if ((table->Flags & ImGuiTableFlags_BordersOuter) == ImGuiTableFlags_BordersOuter) { - inner_drawlist->AddRect(outer_border.Min, outer_border.Max, outer_col, 0.0f, 0, border_size); + inner_drawlist->AddRect(outer_border.Min, outer_border.Max, outer_col, 0.0f, border_size); } else if (table->Flags & ImGuiTableFlags_BordersOuterV) { - inner_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Min.x, outer_border.Max.y), outer_col, border_size); - inner_drawlist->AddLine(ImVec2(outer_border.Max.x, outer_border.Min.y), outer_border.Max, outer_col, border_size); + inner_drawlist->AddLineV(outer_border.Min.x, outer_border.Min.y, outer_border.Max.y, outer_col, border_size); + inner_drawlist->AddLineV(outer_border.Max.x, outer_border.Min.y, outer_border.Max.y, outer_col, border_size); } else if (table->Flags & ImGuiTableFlags_BordersOuterH) { - inner_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Max.x, outer_border.Min.y), outer_col, border_size); - inner_drawlist->AddLine(ImVec2(outer_border.Min.x, outer_border.Max.y), outer_border.Max, outer_col, border_size); + inner_drawlist->AddLineH(outer_border.Min.x, outer_border.Max.x, outer_border.Min.y, outer_col, border_size); + inner_drawlist->AddLineH(outer_border.Min.x, outer_border.Max.x, outer_border.Max.y, outer_col, border_size); } } if ((table->Flags & ImGuiTableFlags_BordersInnerH) && table->RowPosY2 < table->OuterRect.Max.y) @@ -2890,7 +2913,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table) // Draw bottom-most row border between it is above outer border. const float border_y = table->RowPosY2; if (border_y >= table->BgClipRect.Min.y && border_y < table->BgClipRect.Max.y) - inner_drawlist->AddLine(ImVec2(table->BorderX1, border_y), ImVec2(table->BorderX2, border_y), table->BorderColorLight, border_size); + inner_drawlist->AddLineH(table->BorderX1, table->BorderX2, border_y, table->BorderColorLight, border_size); } inner_drawlist->PopClipRect(); @@ -3081,7 +3104,7 @@ void ImGui::TableSortSpecsBuild(ImGuiTable* table) continue; IM_ASSERT(column->SortOrder < table->SortSpecsCount); ImGuiTableColumnSortSpecs* sort_spec = &sort_specs[column->SortOrder]; - sort_spec->ColumnUserID = column->UserID; + sort_spec->ColumnUserID = column->UserData; sort_spec->ColumnIndex = (ImGuiTableColumnIdx)column_n; sort_spec->SortOrder = (ImGuiTableColumnIdx)column->SortOrder; sort_spec->SortDirection = (ImGuiSortDirection)column->SortDirection; @@ -3277,7 +3300,9 @@ void ImGui::TableHeader(const char* label) } // Sort order arrow - const float ellipsis_max = ImMax(cell_r.Max.x - w_arrow - w_sort_text, label_pos.x); + // - Only clip label for a visible arrow. Auto-fit still accounts for a possible arrow, but when + // manually sized smaller we don't clip the label for the sake of an arrow that isn't displayed. + const float ellipsis_max = ImMax(cell_r.Max.x - (sort_arrow ? w_arrow + w_sort_text : 0.0f), label_pos.x); if ((table->Flags & ImGuiTableFlags_Sortable) && !(column->Flags & ImGuiTableColumnFlags_NoSort)) { if (column->SortOrder != -1) @@ -3597,17 +3622,20 @@ void ImGui::TableDrawDefaultContextMenu(ImGuiTable* table, ImGuiTableFlags flags want_separator = true; } - // Ordering - if (flags_for_section_to_display & ImGuiTableFlags_Reorderable) - { - if (MenuItem(LocalizeGetMsg(ImGuiLocKey_TableResetOrder), NULL, false, !table->IsDefaultDisplayOrder)) - table->IsResetDisplayOrderRequest = true; - want_separator = true; - } - - // Reset all (should work but seems unnecessary/noisy to expose?) - //if (MenuItem("Reset all")) - // table->IsResetAllRequest = true; + // Reset Order/Visibility etc. + if (flags_for_section_to_display & (ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) + if (BeginMenu(LocalizeGetMsg(ImGuiLocKey_TableReset))) + { + //if (MenuItem(LocalizeGetMsg(ImGuiLocKey_TableResetAll))) // FIXME: Hiding because altering Sort Order + requesting auto-fit simultaneously has a tendency to exhibit a sizing glitch. + // table->IsResetAllRequest = true; + if (flags_for_section_to_display & ImGuiTableFlags_Reorderable) + if (MenuItem(LocalizeGetMsg(ImGuiLocKey_TableResetOrder), NULL, false, !table->IsDefaultDisplayOrder)) // PS: cannot be hidden because it would mess with drag reordering. + table->IsResetDisplayOrderRequest = true; + if (flags_for_section_to_display & ImGuiTableFlags_Hideable) + if (MenuItem(LocalizeGetMsg(ImGuiLocKey_TableResetVisibility), NULL, false, !table->IsDefaultVisibility)) + table->IsResetVisibilityRequest = true; + EndMenu(); + } // Sorting // (modify TableOpenContextMenu() to add _Sortable flag if enabling this) @@ -3793,6 +3821,7 @@ void ImGui::TableSaveSettings(ImGuiTable* table) for (int n = 0; n < table->ColumnsCount; n++, column++, column_settings++) { const float width_or_weight = (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? column->StretchWeight : column->WidthRequest; + column_settings->ID = column->ID; column_settings->WidthOrWeight = width_or_weight; column_settings->Index = (ImGuiTableColumnIdx)n; column_settings->DisplayOrder = column->DisplayOrder; @@ -3975,12 +4004,13 @@ static void TableSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, char c = 0; ImGuiTableColumnSettings* column = settings->GetColumnSettings() + column_n; column->Index = (ImGuiTableColumnIdx)column_n; - if (sscanf(line, "UserID=0x%08X%n", (ImU32*)&n, &r)==1) { line = ImStrSkipBlank(line + r); column->UserID = (ImGuiID)n; } + if (sscanf(line, "UserID=0x%08X%n", (ImU32*)&n, &r)==1) { line = ImStrSkipBlank(line + r); } // FIXME-LEGACY: Removed 2025/11/12, was never properly set. if (sscanf(line, "Width=%d%n", &n, &r) == 1) { line = ImStrSkipBlank(line + r); column->WidthOrWeight = (float)n; column->IsStretch = 0; settings->SaveFlags |= ImGuiTableFlags_Resizable; } if (sscanf(line, "Weight=%f%n", &f, &r) == 1) { line = ImStrSkipBlank(line + r); column->WidthOrWeight = f; column->IsStretch = 1; settings->SaveFlags |= ImGuiTableFlags_Resizable; } if (sscanf(line, "Visible=%d%n", &n, &r) == 1) { line = ImStrSkipBlank(line + r); column->IsEnabled = (ImU8)n; settings->SaveFlags |= ImGuiTableFlags_Hideable; } if (sscanf(line, "Order=%d%n", &n, &r) == 1) { line = ImStrSkipBlank(line + r); column->DisplayOrder = (ImGuiTableColumnIdx)n; settings->SaveFlags |= ImGuiTableFlags_Reorderable; } if (sscanf(line, "Sort=%d%c%n", &n, &c, &r) == 2) { line = ImStrSkipBlank(line + r); column->SortOrder = (ImGuiTableColumnIdx)n; column->SortDirection = (c == '^') ? ImGuiSortDirection_Descending : ImGuiSortDirection_Ascending; settings->SaveFlags |= ImGuiTableFlags_Sortable; } + if (sscanf(line, "ID=0x%08X%n", (ImU32*)&n, &r) == 1) { line = ImStrSkipBlank(line + r); column->ID = (ImGuiID)n; } } } @@ -4008,16 +4038,16 @@ static void TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandle for (int column_n = 0; column_n < settings->ColumnsCount; column_n++, column++) { // "Column 0 UserID=0x42AD2D21 Width=100 Visible=1 Order=0 Sort=0v" - bool save_column = column->UserID != 0 || save_size || save_visible || save_order || (save_sort && column->SortOrder != -1); + bool save_column = save_size || save_visible || save_order || (save_sort && column->SortOrder != -1); if (!save_column) continue; buf->appendf("Column %-2d", column_n); - if (column->UserID != 0) { buf->appendf(" UserID=%08X", column->UserID); } if (save_size && column->IsStretch) { buf->appendf(" Weight=%.4f", column->WidthOrWeight); } if (save_size && !column->IsStretch) { buf->appendf(" Width=%d", (int)column->WidthOrWeight); } if (save_visible) { buf->appendf(" Visible=%d", column->IsEnabled); } if (save_order) { buf->appendf(" Order=%d", column->DisplayOrder); } if (save_sort && column->SortOrder != -1) { buf->appendf(" Sort=%d%c", column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? 'v' : '^'); } + if (column->ID != 0) { buf->appendf(" ID=0x%08X", column->ID); } buf->append("\n"); } buf->append("\n"); @@ -4075,11 +4105,12 @@ void ImGui::TableGcCompactTransientBuffers(ImGuiTable* table) void ImGui::TableGcCompactTransientBuffers(ImGuiTableTempData* temp_data) { + temp_data->AngledHeadersRequests.clear(); temp_data->DrawSplitter.ClearFreeMemory(); temp_data->LastTimeActive = -1.0f; } -// Compact and remove unused settings data (currently only used by TestEngine) +// Compact and remove unused or resize settings data (only TestEngine mark unused, but resizing table down can lead to compaction) void ImGui::TableGcCompactSettings() { ImGuiContext& g = *GImGui; @@ -4095,6 +4126,9 @@ void ImGui::TableGcCompactSettings() if (settings->ID != 0) memcpy(new_chunk_stream.alloc_chunk(TableSettingsCalcChunkSize(settings->ColumnsCount)), settings, TableSettingsCalcChunkSize(settings->ColumnsCount)); g.SettingsTables.swap(new_chunk_stream); + for (int table_n = 0; table_n < g.Tables.GetMapSize(); table_n++) + if (ImGuiTable* table = g.Tables.TryGetMapData(table_n)) + table->SettingsOffset = -1; } @@ -4102,6 +4136,7 @@ void ImGui::TableGcCompactSettings() // [SECTION] Tables: Debugging //------------------------------------------------------------------------- // - DebugNodeTable() [Internal] +// - DebugNodeTableSettings() [Internal] //------------------------------------------------------------------------- #ifndef IMGUI_DISABLE_DEBUG_TOOLS @@ -4165,13 +4200,13 @@ void ImGui::DebugNodeTable(ImGuiTable* table) "WidthGiven: %.1f, Request/Auto: %.1f/%.1f, StretchWeight: %.3f (%.1f%%)\n" "MinX: %.1f, MaxX: %.1f (%+.1f), ClipRect: %.1f to %.1f (+%.1f)\n" "ContentWidth: %.1f,%.1f, HeadersUsed/Ideal %.1f/%.1f\n" - "Sort: %d%s, UserID: 0x%08X, Flags: 0x%04X: %s%s%s..", + "Sort: %d%s, UserData: 0x%08X, Flags: 0x%04X: %s%s%s..", n, column->DisplayOrder, name, column->MinX - table->WorkRect.Min.x, column->MaxX - table->WorkRect.Min.x, (n < table->FreezeColumnsRequest) ? " (Frozen)" : "", column->IsEnabled, column->IsVisibleX, column->IsVisibleY, column->IsRequestOutput, column->IsSkipItems, column->DrawChannelFrozen, column->DrawChannelUnfrozen, column->WidthGiven, column->WidthRequest, column->WidthAuto, column->StretchWeight, column->StretchWeight > 0.0f ? (column->StretchWeight / sum_weights) * 100.0f : 0.0f, column->MinX, column->MaxX, column->MaxX - column->MinX, column->ClipRect.Min.x, column->ClipRect.Max.x, column->ClipRect.Max.x - column->ClipRect.Min.x, column->ContentMaxXFrozen - column->WorkMinX, column->ContentMaxXUnfrozen - column->WorkMinX, column->ContentMaxXHeadersUsed - column->WorkMinX, column->ContentMaxXHeadersIdeal - column->WorkMinX, - column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? " (Asc)" : (column->SortDirection == ImGuiSortDirection_Descending) ? " (Des)" : "", column->UserID, column->Flags, + column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? " (Asc)" : (column->SortDirection == ImGuiSortDirection_Descending) ? " (Des)" : "", column->UserData, column->Flags, (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? "WidthStretch " : "", (column->Flags & ImGuiTableColumnFlags_WidthFixed) ? "WidthFixed " : "", (column->Flags & ImGuiTableColumnFlags_NoResize) ? "NoResize " : ""); @@ -4184,34 +4219,45 @@ void ImGui::DebugNodeTable(ImGuiTable* table) } } if (ImGuiTableSettings* settings = TableGetBoundSettings(table)) - DebugNodeTableSettings(settings); + DebugNodeTableSettings(settings, table); if (clear_settings) - table->IsResetAllRequest = true; + table->IsResetAllRequest = true; // Queue a call to TableResetSettings() TreePop(); } -void ImGui::DebugNodeTableSettings(ImGuiTableSettings* settings) +void ImGui::DebugNodeTableSettings(ImGuiTableSettings* settings, ImGuiTable* table) { - if (!TreeNode((void*)(intptr_t)settings->ID, "Settings 0x%08X (%d columns)", settings->ID, settings->ColumnsCount)) - return; - BulletText("SaveFlags: 0x%08X", settings->SaveFlags); - BulletText("ColumnsCount: %d (max %d)", settings->ColumnsCount, settings->ColumnsCountMax); - for (int n = 0; n < settings->ColumnsCount; n++) + if (settings->ID == 0) + PushID(settings); + const bool open = TreeNode((void*)(intptr_t)settings->ID, "Settings 0x%08X (%d columns)", settings->ID, settings->ColumnsCount); + const bool hovered = IsItemHovered(); + if (hovered && table == NULL && settings->ID != 0) + table = TableFindByID(settings->ID); + if (hovered && table != NULL) + GetForegroundDrawList(table->OuterWindow)->AddRect(table->OuterRect.Min, table->OuterRect.Max, IM_COL32(255, 255, 0, 255)); + if (open) { - ImGuiTableColumnSettings* column_settings = &settings->GetColumnSettings()[n]; - ImGuiSortDirection sort_dir = (column_settings->SortOrder != -1) ? (ImGuiSortDirection)column_settings->SortDirection : ImGuiSortDirection_None; - BulletText("Column %d Order %d SortOrder %d %s Vis %d %s %7.3f UserID 0x%08X", - n, column_settings->DisplayOrder, column_settings->SortOrder, - (sort_dir == ImGuiSortDirection_Ascending) ? "Asc" : (sort_dir == ImGuiSortDirection_Descending) ? "Des" : "---", - column_settings->IsEnabled, column_settings->IsStretch ? "Weight" : "Width ", column_settings->WidthOrWeight, column_settings->UserID); + BulletText("SaveFlags: 0x%08X", settings->SaveFlags); + BulletText("ColumnsCount: %d (max %d)", settings->ColumnsCount, settings->ColumnsCountMax); + for (int n = 0; n < settings->ColumnsCount; n++) + { + ImGuiTableColumnSettings* column_settings = &settings->GetColumnSettings()[n]; + ImGuiSortDirection sort_dir = (column_settings->SortOrder != -1) ? (ImGuiSortDirection)column_settings->SortDirection : ImGuiSortDirection_None; + BulletText("Column %d Order %d SortOrder %2d %s Vis %d %s %7.3f ID 0x%08X", + n, column_settings->DisplayOrder, column_settings->SortOrder, + (sort_dir == ImGuiSortDirection_Ascending) ? "Asc" : (sort_dir == ImGuiSortDirection_Descending) ? "Des" : "---", + column_settings->IsEnabled, column_settings->IsStretch ? "Weight" : "Width ", column_settings->WidthOrWeight, column_settings->ID); + } + TreePop(); } - TreePop(); + if (settings->ID == 0) + PopID(); } #else // #ifndef IMGUI_DISABLE_DEBUG_TOOLS void ImGui::DebugNodeTable(ImGuiTable*) {} -void ImGui::DebugNodeTableSettings(ImGuiTableSettings*) {} +void ImGui::DebugNodeTableSettings(ImGuiTableSettings*, ImGuiTable*) {} #endif @@ -4618,7 +4664,7 @@ void ImGui::EndColumns() // Draw column const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); const float xi = IM_TRUNC(x); - window->DrawList->AddLine(ImVec2(xi, y1 + 1.0f), ImVec2(xi, y2), col); + window->DrawList->AddLineV(xi, y1 + 1.0f, y2, col); } // Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame. diff --git a/src/libs/imgui/imgui_widgets.cpp b/src/libs/imgui/imgui_widgets.cpp index 59d0ceb..7b8c4e9 100644 --- a/src/libs/imgui/imgui_widgets.cpp +++ b/src/libs/imgui/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.8 WIP +// dear imgui, v1.92.9 WIP // (widgets code) /* @@ -266,6 +266,8 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags) } } +// Note that all functions taking format strings in the API may be passed ("%s", text) or ("%.*s", text_len, text), +// which will automatically bypass the formatter. void ImGui::TextUnformatted(const char* text, const char* text_end) { TextEx(text, text_end, ImGuiTextFlags_NoWidthForLargeClippedText); @@ -1151,7 +1153,7 @@ void ImGui::ImageWithBg(ImTextureRef tex_ref, const ImVec2& image_size, const Im else window->DrawList->AddImage(tex_ref, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col)); if (g.Style.ImageBorderSize > 0.0f) - window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border), rounding, ImDrawFlags_None, g.Style.ImageBorderSize); + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border), rounding, g.Style.ImageBorderSize); } void ImGui::Image(ImTextureRef tex_ref, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1) @@ -1288,8 +1290,9 @@ bool ImGui::Checkbox(const char* label, bool* v) if (is_visible) { RenderNavCursor(total_bb, id); - RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); + ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : (mixed_value || checked) ? ImGuiCol_CheckboxSelectedBg : ImGuiCol_FrameBg); ImU32 check_col = GetColorU32(ImGuiCol_CheckMark); + RenderFrame(check_bb.Min, check_bb.Max, bg_col, true, style.FrameRounding); if (mixed_value) { // Undocumented tristate/mixed/indeterminate checkbox (#2644) @@ -1556,7 +1559,7 @@ bool ImGui::TextLink(const char* label) } float line_y = bb.Max.y + ImFloor(g.FontBaked->Descent * g.FontBakedScale * 0.20f); - window->DrawList->AddLine(ImVec2(bb.Min.x, line_y), ImVec2(bb.Max.x, line_y), GetColorU32(line_colf), 1.0f * (float)(int)g.Style._MainScale); // FIXME-TEXT: Underline mode // FIXME-DPI + window->DrawList->AddLineH(bb.Min.x, bb.Max.x, line_y, GetColorU32(line_colf), 1.0f * (float)(int)g.Style._MainScale); // FIXME-TEXT: Underline mode // FIXME-DPI PushStyleColor(ImGuiCol_Text, GetColorU32(text_colf)); RenderText(bb.Min, label, label_end, false); @@ -1574,7 +1577,7 @@ bool ImGui::TextLinkOpenURL(const char* label, const char* url) bool pressed = TextLink(label); if (pressed && g.PlatformIO.Platform_OpenInShellFn != NULL) g.PlatformIO.Platform_OpenInShellFn(&g, url); - SetItemTooltip(LocalizeGetMsg(ImGuiLocKey_OpenLink_s), url); // It is more reassuring for user to _always_ display URL when we same as label + SetItemTooltip(LocalizeGetMsg(ImGuiLocKey_OpenLink_s), url); // It is more reassuring for user to _always_ display URL when it is the same as the label. if (BeginPopupContextItem()) { if (MenuItem(LocalizeGetMsg(ImGuiLocKey_CopyLink))) @@ -1745,14 +1748,14 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end const float separator_thickness = style.SeparatorTextBorderSize; const ImVec2 min_size(label_size.x + extra_w + padding.x * 2.0f, ImMax(label_size.y + padding.y * 2.0f, separator_thickness)); const ImRect bb(pos, ImVec2(window->WorkRect.Max.x, pos.y + min_size.y)); - const float text_baseline_y = ImTrunc((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.99999f); //ImMax(padding.y, ImTrunc((style.SeparatorTextSize - label_size.y) * 0.5f)); + const float text_baseline_y = ImTrunc((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.999f); //ImMax(padding.y, ImTrunc((style.SeparatorTextSize - label_size.y) * 0.5f)); ItemSize(min_size, text_baseline_y); if (!ItemAdd(bb, id)) return; const float sep1_x1 = pos.x; const float sep2_x2 = bb.Max.x; - const float seps_y = ImTrunc((bb.Min.y + bb.Max.y) * 0.5f + 0.99999f); + const float seps_y = ImTrunc((bb.Min.y + bb.Max.y) * 0.5f + 0.999f); const float label_avail_w = ImMax(0.0f, sep2_x2 - sep1_x1 - padding.x * 2.0f); const ImVec2 label_pos(pos.x + padding.x + ImMax(0.0f, (label_avail_w - label_size.x - extra_w) * style.SeparatorTextAlign.x), pos.y + text_baseline_y); // FIXME-ALIGN @@ -1766,9 +1769,9 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end const float sep1_x2 = label_pos.x - style.ItemSpacing.x; const float sep2_x1 = label_pos.x + label_size.x + extra_w + style.ItemSpacing.x; if (sep1_x2 > sep1_x1 && separator_thickness > 0.0f) - window->DrawList->AddLine(ImVec2(sep1_x1, seps_y), ImVec2(sep1_x2, seps_y), separator_col, separator_thickness); + window->DrawList->AddLineH(sep1_x1, sep1_x2, seps_y, separator_col, separator_thickness); if (sep2_x2 > sep2_x1 && separator_thickness > 0.0f) - window->DrawList->AddLine(ImVec2(sep2_x1, seps_y), ImVec2(sep2_x2, seps_y), separator_col, separator_thickness); + window->DrawList->AddLineH(sep2_x1, sep2_x2, seps_y, separator_col, separator_thickness); if (g.LogEnabled) LogSetNextTextDecoration("---", NULL); RenderTextEllipsis(window->DrawList, label_pos, ImVec2(bb.Max.x, bb.Max.y + style.ItemSpacing.y), bb.Max.x, label, label_end, &label_size); @@ -1778,7 +1781,7 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end if (g.LogEnabled) LogText("---"); if (separator_thickness > 0.0f) - window->DrawList->AddLine(ImVec2(sep1_x1, seps_y), ImVec2(sep2_x2, seps_y), separator_col, separator_thickness); + window->DrawList->AddLineH(sep1_x1, sep2_x2, seps_y, separator_col, separator_thickness); } } @@ -2375,12 +2378,17 @@ bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void // Sanitize format // - For float/double we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in, so force them into %f and %lf - // - In theory could treat empty format as using default, but this would only cover rare/bizarre case of using InputScalar() + integer + format string without %. char format_sanitized[32]; if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) + { format = type_info->ScanFmt; + } else + { format = ImParseFormatSanitizeForScanning(format, format_sanitized, IM_COUNTOF(format_sanitized)); + if (format[0] == '\0') + format = type_info->ScanFmt; // Format doesn't want us to show the number currently, but we still need to parse the resulting input + } // Small types need a 32-bit buffer to receive the result from scanf() int v32 = 0; @@ -3566,7 +3574,8 @@ bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, // - ImParseFormatSanitizeForPrinting() [Internal] // - ImParseFormatSanitizeForScanning() [Internal] // - ImParseFormatPrecision() [Internal] -// - TempInputTextScalar() [Internal] +// - TempInputText() [Internal] +// - TempInputScalar() [Internal] // - InputScalar() // - InputScalarN() // - InputFloat() @@ -4577,6 +4586,7 @@ void ImGui::InputTextDeactivateHook(ImGuiID id) ImGuiInputTextState* state = &g.InputTextState; if (id == 0 || state->ID != id) return; + //IMGUI_DEBUG_LOG_ACTIVEID("InputTextDeactivateHook() id = 0x%08X\n", id); g.InputTextDeactivatedState.ID = state->ID; if (state->Flags & ImGuiInputTextFlags_ReadOnly) { @@ -4892,7 +4902,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ } const bool is_osx = io.ConfigMacOSXBehaviors; - if (g.ActiveId != id && init_make_active) + if (init_make_active && g.ActiveId != id) { IM_ASSERT(state && state->ID == id); SetActiveID(id, window); @@ -5633,7 +5643,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ ImVec2 cursor_screen_pos = ImTrunc(draw_pos + cursor_offset - draw_scroll); ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f); if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect)) - draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_InputTextCursor), 1.0f * (float)(int)style._MainScale); // FIXME-DPI: Cursor thickness (#7031) + draw_window->DrawList->AddLineV(cursor_screen_rect.Min.x, cursor_screen_rect.Min.y, cursor_screen_rect.Max.y, GetColorU32(ImGuiCol_InputTextCursor), style.InputTextCursorSize); // Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.) // This is required for some backends (SDL3) to start emitting character/text inputs. @@ -6347,7 +6357,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl const float a1 = (n+1.0f)/6.0f * 2.0f * IM_PI + aeps; const int vert_start_idx = draw_list->VtxBuffer.Size; draw_list->PathArcTo(wheel_center, (wheel_r_inner + wheel_r_outer)*0.5f, a0, a1, segment_per_arc); - draw_list->PathStroke(col_white, 0, wheel_thickness); + draw_list->PathStroke(col_white, wheel_thickness); const int vert_end_idx = draw_list->VtxBuffer.Size; // Paint colors over existing vertices @@ -6491,7 +6501,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl if (g.Style.FrameBorderSize > 0.0f) RenderFrameBorder(bb.Min, bb.Max, rounding); else - window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding, 0, 1.0f * (float)(int)g.Style._MainScale); // Color buttons are often in need of some sort of border // FIXME-DPI + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding, 1.0f * (float)(int)g.Style._MainScale); // Color buttons are often in need of some sort of border // FIXME-DPI } // Drag and Drop Source @@ -7164,11 +7174,11 @@ void ImGui::TreeNodeDrawLineToChildNode(const ImVec2& target_pos) window->DrawList->PathArcToFast(ImVec2(x1, y - rounding), rounding, 6, 3); if (x1 < x2) window->DrawList->PathLineTo(ImVec2(x2, y)); - window->DrawList->PathStroke(GetColorU32(ImGuiCol_TreeLines), ImDrawFlags_None, g.Style.TreeLinesSize); + window->DrawList->PathStroke(GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize); } else { - window->DrawList->AddLine(ImVec2(x1, y), ImVec2(x2, y), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize); + window->DrawList->AddLineH(x1, x2, y, GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize); } } @@ -7194,7 +7204,7 @@ void ImGui::TreeNodeDrawLineToTreePop(const ImGuiTreeNodeStackData* data) float x = ImTrunc(data->DrawLinesX1); if (data->DrawLinesTableColumn != -1) TablePushColumnChannel(data->DrawLinesTableColumn); - window->DrawList->AddLine(ImVec2(x, y1), ImVec2(x, y2), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize); + window->DrawList->AddLineV(x, y1, y2, GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize); if (data->DrawLinesTableColumn != -1) TablePopColumnChannel(); } @@ -8367,11 +8377,23 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) if (ImGuiTable* table = g.CurrentTable) if (table->CurrentColumn != -1) { - // FIXME: We cannot use current ClipRect as it includes HostClipRect. - // A more generic version would be nice, but window->WorkRect.Min/Max exclude CellPadding. (#7994) + // FIXME: We cannot solely use current ClipRect as it includes HostClipRect. + // However we account for ClipRect being larger than current column (e.g. when using SpanAllColumns) + // A more generic version would be nice, but window->WorkRect.Min/Max exclude CellPadding. (#7994, #9383) ImGuiTableColumn* column = &table->Columns[table->CurrentColumn]; - item_rect.Min.x = ImMax(item_rect.Min.x, column->MinX); - item_rect.Max.x = ImMin(item_rect.Max.x, column->MaxX); + float clip_min_x = (g.LastItemData.ItemFlags & ImGuiItemStatusFlags_HasClipRect) ? g.LastItemData.ClipRect.Min.x : window->ClipRect.Min.x; + float clip_max_x = (g.LastItemData.ItemFlags & ImGuiItemStatusFlags_HasClipRect) ? g.LastItemData.ClipRect.Max.x : window->ClipRect.Max.x; + if (clip_min_x != clip_max_x) // When zero sized we expect that bounds have been clamped and thus are unreliable + { + item_rect.Min.x = ImMax(item_rect.Min.x, ImMin(column->MinX, clip_min_x)); + item_rect.Max.x = ImMin(item_rect.Max.x, ImMax(column->MaxX, clip_max_x)); + } + else + { + item_rect.Min.x = ImMax(item_rect.Min.x, column->MinX); + item_rect.Max.x = ImMin(item_rect.Max.x, column->MaxX); + } + //GetForegroundDrawList()->AddRect(item_rect.Min, item_rect.Max, IM_COL32(255, 0, 255, 255)); } const bool rect_overlap_curr = bs->BoxSelectRectCurr.Overlaps(item_rect); const bool rect_overlap_prev = bs->BoxSelectRectPrev.Overlaps(item_rect); @@ -8930,7 +8952,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_get // Tooltip on hover if (hovered && inner_bb.Contains(g.IO.MousePos)) { - const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.9999f); + const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.999f); const int v_idx = (int)(t * item_count); IM_ASSERT(v_idx >= 0 && v_idx < values_count); @@ -9373,8 +9395,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) bool pressed; - // We use ImGuiSelectableFlags_NoSetKeyOwner to allow down on one menu item, move, up on another. - const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_NoSetKeyOwner | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_NoAutoClosePopups; + const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoAutoClosePopups | (ImGuiSelectableFlags)ImGuiSelectableFlags_SelectOnClick; ImGuiMenuColumns* offsets = &window->DC.MenuColumns; if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { @@ -9412,6 +9433,14 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) if (!enabled) EndDisabled(); + // Once dragged, release ActiveId + key ownership. This is to allow the idiom of mouse down a menu, dragging elsewhere, up on some other MenuItem(). (#8233, #9394) + // Could move logic into lower-level ImGuiButtonFlags_AutoReleaseActiveId + ImGuiButtonFlags_AutoReleaseKeyOwner? Easier once we get rid of the Selectable() middle-man here. + if (g.ActiveId == id && g.HoveredId != id && g.ActiveIdSource == ImGuiInputSource_Mouse && IsMouseDragging(0)) + { + ClearActiveID(); + SetKeyOwner(ImGuiKey_MouseLeft, ImGuiKeyOwner_NoOwner); + } + const bool hovered = (g.HoveredId == id) && enabled && !g.NavHighlightItemUnderNav; if (menuset_is_open) PopItemFlag(); @@ -9492,6 +9521,9 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0)); PopID(); + if (g.ActiveId == id && want_open) + g.ActiveIdNoClearOnFocusLoss = true; + if (want_open && !menu_is_open && g.OpenPopupStack.Size > g.BeginPopupStack.Size) { // Don't reopen/recycle same menu level in the same frame if it is a different menu ID, first close the other menu and yield for a frame. @@ -9584,7 +9616,7 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut BeginDisabled(); // We use ImGuiSelectableFlags_NoSetKeyOwner to allow down on one menu item, move, up on another. - const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_NoSetKeyOwner | ImGuiSelectableFlags_SetNavIdOnHover; + const ImGuiSelectableFlags selectable_flags = (ImGuiSelectableFlags)ImGuiSelectableFlags_SelectOnRelease | (ImGuiSelectableFlags)ImGuiSelectableFlags_SetNavIdOnHover; ImGuiMenuColumns* offsets = &window->DC.MenuColumns; if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { @@ -9606,7 +9638,7 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut // Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.) float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f; float shortcut_w = (shortcut && shortcut[0]) ? CalcTextSize(shortcut, NULL).x : 0.0f; - float checkmark_w = IM_TRUNC(g.FontSize * 1.20f); + float checkmark_w = IM_TRUNC(g.FontSize * 1.20f); // FIXME: Always accounted for, even in a menu with none, because 'selected' has no neutral setting. float min_w = offsets->DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); ImVec2 text_pos(pos.x, pos.y + window->DC.CurrLineTextBaseOffset); @@ -9627,6 +9659,17 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut RenderCheckMark(window->DrawList, text_pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f); } } + + // Once dragged, release ActiveId + key ownership. This is to allow the idiom of mouse down a menu, dragging elsewhere, up on some other MenuItem(). (#8233, #9394) + // Could move logic into lower-level ImGuiButtonFlags_AutoReleaseActiveId + ImGuiButtonFlags_AutoReleaseKeyOwner? Easier once we get rid of the Selectable() middle-man here. + const ImGuiID id = g.LastItemData.ID; + if (g.ActiveId == id && g.HoveredId != id && g.ActiveIdSource == ImGuiInputSource_Mouse && IsMouseDragging(0)) + { + ClearActiveID(); + SetKeyOwner(ImGuiKey_MouseLeft, ImGuiKeyOwner_NoOwner); + } + + IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0)); if (!enabled) EndDisabled(); @@ -10739,7 +10782,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, float rounding = style.TabRounding; display_draw_list->PathArcToFast(tl + ImVec2(+rounding, +rounding), rounding, 7, 9); display_draw_list->PathArcToFast(tr + ImVec2(-rounding, +rounding), rounding, 9, 11); - display_draw_list->PathStroke(overline_col, 0, style.TabBarOverlineSize); + display_draw_list->PathStroke(overline_col, style.TabBarOverlineSize); } else { @@ -10830,20 +10873,16 @@ void ImGui::TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabI IM_UNUSED(flags); IM_ASSERT(width > 0.0f); const float rounding = ImMax(0.0f, ImMin((flags & ImGuiTabItemFlags_Button) ? g.Style.FrameRounding : g.Style.TabRounding, width * 0.5f - 1.0f)); - const float y1 = bb.Min.y + 1.0f; + const float y1 = bb.Min.y + 1.0f; // Leave a bit of room in title bars. const float y2 = bb.Max.y - g.Style.TabBarBorderSize; - draw_list->PathLineTo(ImVec2(bb.Min.x, y2)); - draw_list->PathArcToFast(ImVec2(bb.Min.x + rounding, y1 + rounding), rounding, 6, 9); - draw_list->PathArcToFast(ImVec2(bb.Max.x - rounding, y1 + rounding), rounding, 9, 12); - draw_list->PathLineTo(ImVec2(bb.Max.x, y2)); - draw_list->PathFillConvex(col); + draw_list->AddRectFilled(bb.Min, ImVec2(bb.Max.x, y2), col, rounding, ImDrawFlags_RoundCornersTop); if (g.Style.TabBorderSize > 0.0f) { draw_list->PathLineTo(ImVec2(bb.Min.x + 0.5f, y2)); draw_list->PathArcToFast(ImVec2(bb.Min.x + rounding + 0.5f, y1 + rounding + 0.5f), rounding, 6, 9); draw_list->PathArcToFast(ImVec2(bb.Max.x - rounding - 0.5f, y1 + rounding + 0.5f), rounding, 9, 12); draw_list->PathLineTo(ImVec2(bb.Max.x - 0.5f, y2)); - draw_list->PathStroke(GetColorU32(ImGuiCol_Border), 0, g.Style.TabBorderSize); + draw_list->PathStroke(GetColorU32(ImGuiCol_Border), g.Style.TabBorderSize); } } From a937f8050e6008ee8db57b04663ba99916118a8e Mon Sep 17 00:00:00 2001 From: Toni500git Date: Tue, 23 Jun 2026 22:08:41 +0200 Subject: [PATCH 02/40] misc: fix compilation from obselete functions --- src/screenshot_tool.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 64fcbce..65f250e 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -869,8 +869,8 @@ void ScreenshotTool::HandleColorPickerInput() ImVec2(loupe_origin.x + k_loupe_px, loupe_origin.y + k_loupe_px), IM_COL32(80, 80, 80, 220), 2.0f, - 0, - 1.5f); + 1.5f, + ImDrawFlags_None); ImGui::Spacing(); ImGui::ColorButton("##loupe_swatch", c.to_imvec4(), ImGuiColorEditFlags_NoPicker, ImVec2(32, 32)); @@ -1066,7 +1066,7 @@ void ScreenshotTool::DrawSelectionBorder() // Draw selection border draw_list->AddRect( - ImVec2(sel_x, sel_y), ImVec2(sel_x + sel_w, sel_y + sel_h), IM_COL32(0, 150, 255, 255), 0.0f, 0, 1.0f); + ImVec2(sel_x, sel_y), ImVec2(sel_x + sel_w, sel_y + sel_h), IM_COL32(0, 150, 255, 255), 0.0f, 1.0f, ImDrawFlags_None); if (!g_config->Runtime.enable_handles) return; @@ -1082,7 +1082,7 @@ void ScreenshotTool::DrawSelectionBorder() color = IM_COL32(255, 255, 0, 255); // Yellow draw_list->AddRectFilled(min, max, color); - draw_list->AddRect(min, max, IM_COL32(255, 255, 255, 255), 0.0f, 0, 2.0f); + draw_list->AddRect(min, max, IM_COL32(255, 255, 255, 255), 0.0f, 2.0f, ImDrawFlags_None); }; // Corner handles @@ -2393,7 +2393,7 @@ void ScreenshotTool::DrawAnnotations() ImVec2 min(std::min(p1.x, p2.x), std::min(p1.y, p2.y)); ImVec2 max(std::max(p1.x, p2.x), std::max(p1.y, p2.y)); filled ? draw_list->AddRectFilled(min, max, ann.color.to_abgr(), 0.0f, 0) - : draw_list->AddRect(min, max, ann.color.to_abgr(), 0.0f, 0, t); + : draw_list->AddRect(min, max, ann.color.to_abgr(), t, 0.0f, 0); }; auto draw_circle_or_filled = @@ -2433,8 +2433,8 @@ void ScreenshotTool::DrawAnnotations() draw_list->AddPolyline(reinterpret_cast(ann.points.data()), int(ann.points.size()), ann.color.to_abgr(), - ImDrawFlags_None, - t); + t, + ImDrawFlags_None); } }; From 6d0dd60f7d4805f88cbcf9e2ffdc5a9d8e6f0e29 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Tue, 23 Jun 2026 22:31:48 +0200 Subject: [PATCH 03/40] make: refactor src/libs/*/Makefile's to use common.mk --- Makefile | 22 +- mk/common.mk | 123 +++++ src/libs/clip/Makefile | 40 +- src/libs/fmt/CMakeLists.txt | 637 ++++++++++++++----------- src/libs/fmt/Makefile | 33 +- src/libs/getopt_port/Makefile | 15 +- src/libs/imgui/Makefile | 33 +- src/libs/nvdialog/Makefile | 59 +-- src/libs/tiny-process-library/Makefile | 40 +- src/libs/tinyfiledialogs/Makefile | 20 +- src/libs/toml++/Makefile | 19 +- src/libs/tray/Makefile | 38 +- 12 files changed, 571 insertions(+), 508 deletions(-) create mode 100644 mk/common.mk diff --git a/Makefile b/Makefile index e224653..7bb7c0b 100644 --- a/Makefile +++ b/Makefile @@ -68,10 +68,10 @@ SRC = $(wildcard src/*.cpp) OBJ = $(patsubst src/%.cpp,$(BUILDDIR)/%.o,$(SRC)) LDFLAGS += -L$(BUILDDIR) $(LTO_FLAGS) LDLIBS += $(LIBS) `pkg-config --static --libs glfw3 tesseract zbar` -CXXFLAGS += $(LTO_FLAGS) -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libs -std=$(CXXSTD) $(VARS) -DVERSION=\"$(VERSION)\" -DIMGUI_DISABLE_OBSOLETE_FUNCTIONS +CXXFLAGS += $(LTO_FLAGS) -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libs -std=$(CXXSTD) $(VARS) -DVERSION=\"$(VERSION)\" LIBS := \ - $(BUILDDIR)/libimgui.a \ + $(BUILDDIR)/liboshot_imgui.so \ $(BUILDDIR)/libfmt.a \ $(BUILDDIR)/libclip.a \ $(BUILDDIR)/libtray.a \ @@ -92,31 +92,31 @@ $(BUILDDIR)/%.o: src/%.cpp @mkdir -p $(dir $@) $(CXX) $(CXXFLAGS) -c $< -o $@ -$(BUILDDIR)/libimgui.a: | $(BUILDDIR) +$(BUILDDIR)/liboshot_imgui.so: | $(BUILDDIR) $(MAKE) -C src/libs/imgui BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) $(BUILDDIR)/libfmt.a: | $(BUILDDIR) $(MAKE) -C src/libs/fmt BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) -$(BUILDDIR)/toml.o: +$(BUILDDIR)/toml.o: | $(BUILDDIR) $(MAKE) -C src/libs/toml++ BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) -$(BUILDDIR)/libclip.a: +$(BUILDDIR)/libclip.a: | $(BUILDDIR) $(MAKE) -C src/libs/clip BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) -$(BUILDDIR)/libtray.a: +$(BUILDDIR)/libtray.a: | $(BUILDDIR) $(MAKE) -C src/libs/tray BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) -$(BUILDDIR)/libnvdialog.a: +$(BUILDDIR)/libnvdialog.a: | $(BUILDDIR) $(MAKE) -C src/libs/nvdialog BUILDDIR=$(BUILDDIR) DEBUG=$(DEBUG) -$(BUILDDIR)/tinyfiledialogs.o: +$(BUILDDIR)/tinyfiledialogs.o: | $(BUILDDIR) $(MAKE) -C src/libs/tinyfiledialogs BUILDDIR=$(BUILDDIR) -$(BUILDDIR)/libtiny-process-library.a: +$(BUILDDIR)/libtiny-process-library.a: | $(BUILDDIR) $(MAKE) -C src/libs/tiny-process-library BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) -$(BUILDDIR)/getopt.o: +$(BUILDDIR)/getopt.o: | $(BUILDDIR) $(MAKE) -C src/libs/getopt_port BUILDDIR=$(BUILDDIR) genver: @@ -140,4 +140,4 @@ distclean: updatever: sed -i "s#$(OLDVERSION)#$(VERSION)#g" $(wildcard .github/workflows/*.yml scripts/*) CMakeLists.txt compile_flags.txt -.PHONY: $(TARGET) updatever distclean clean imgui fmt tpl toml getopt-port clip tray dist all +.PHONY: $(TARGET) updatever distclean clean dist all diff --git a/mk/common.mk b/mk/common.mk new file mode 100644 index 0000000..213daab --- /dev/null +++ b/mk/common.mk @@ -0,0 +1,123 @@ +# Shared build logic for src/libs/*/Makefile. +# +# Each lib's Makefile sets a handful of variables and then does: +# include ../../../mk/common.mk +# +# Required variables (set by the including Makefile): +# LIBKIND - object | static | shared +# SRC - source files, e.g. SRC = toml.cpp, or SRC := $(wildcard *.cpp) +# +# Variables required for LIBKIND = static or shared, ignored for object: +# LIBNAME - output name without the shared extension, e.g. liboshot_imgui +# (the .a/.so/.dylib/.dll suffix is added here) +# +# Variables required for LIBKIND = object only: +# TARGET - single output object file, e.g. toml.o +# +# Optional variables: +# CXX, CC, CXXSTD - default to g++/cc/c++20 +# CXXFLAGS, CFLAGS - extra per-lib flags, appended after the common ones +# EXTRA_LIBS - extra -L/-l flags for the link step (LIBKIND = shared only) +# LTO_FLAGS, DEBUG_CXXFLAGS, DEBUG, BUILDDIR - passed down from the top-level Makefile + +CXX ?= g++ +CC ?= cc +CXXSTD ?= c++20 + +# Override VISIBILITY := default in the including Makefile for libs that need +# to export symbols (toml++, cimgui currently do; most static/internal libs don't). +VISIBILITY ?= hidden + +# No default -I path here: every lib states its own include dirs explicitly +# before the include line (some use the bare include/libs/ dir, some use +# their own include/libs// subdir - it varies per lib, so it's not +# safe to assume one or the other generically). +CSTD ?= c11 + +CXXFLAGS += -std=$(CXXSTD) $(LTO_FLAGS) -fvisibility=$(VISIBILITY) -fvisibility-inlines-hidden -fPIC +CFLAGS += -std=$(CSTD) $(LTO_FLAGS) -fvisibility=$(VISIBILITY) -fPIC + +ifeq ($(DEBUG),1) + CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter \ + -DDEBUG=1 -fno-omit-frame-pointer $(DEBUG_CXXFLAGS) $(CXXFLAGS) +else + CXXFLAGS += -O3 -DNDEBUG +endif + +UNAME_S := $(shell uname -s) + +ifeq ($(UNAME_S),Darwin) + SHAREDEXT = dylib + SHAREDFLAGS = -dynamiclib -install_name @rpath/$(LIBNAME).$(SHAREDEXT) +else ifeq ($(findstring MINGW64_NT,$(UNAME_S)),MINGW64_NT) + SHAREDEXT = dll + SHAREDFLAGS = -shared + CXXFLAGS += -D_CRT_SECURE_NO_WARNINGS +else + CXXFLAGS += -Wall -Wextra + SHAREDEXT = so + SHAREDFLAGS = -shared -Wl,-soname,$(LIBNAME).$(SHAREDEXT) +endif + +OBJ := $(addsuffix .o,$(basename $(SRC))) + +# Output name for static/shared kinds; unused for object (TARGET is used instead there). +OUT_static = $(LIBNAME).a +OUT_shared = $(LIBNAME).$(SHAREDEXT) +OUT = $(OUT_$(LIBKIND)) + +all: $(if $(filter object,$(LIBKIND)),$(TARGET),$(OUT)) + +# --- object: compile a single source file straight to ../../../$(BUILDDIR)/$(TARGET) --- +# Picks CC/CFLAGS for a .c source, CXX/CXXFLAGS otherwise. +ifeq ($(LIBKIND),object) +ifeq ($(suffix $(SRC)),.c) +$(TARGET): + $(CC) $(SRC) $(CFLAGS) -c -o ../../../$(BUILDDIR)/$@ +else +$(TARGET): + $(CXX) $(SRC) $(CXXFLAGS) -c -o ../../../$(BUILDDIR)/$@ +endif +endif + +# --- static: archive OBJ into $(LIBNAME).a --- +ifeq ($(LIBKIND),static) +$(OUT): $(OBJ) + ar rcs $@ $^ + ranlib $@ + mv -f $@ ../../../$(BUILDDIR)/$@ +endif + +# --- shared: link OBJ into a platform shared library --- +ifeq ($(LIBKIND),shared) +$(OUT): $(OBJ) + $(CXX) $(CXXFLAGS) $(SHAREDFLAGS) -o $@ $^ $(EXTRA_LIBS) + mv -f $@ ../../../$(BUILDDIR)/$@ +endif + +%.o: %.cpp + $(CXX) $(CXX_DEFINES) $(CXXFLAGS) -c -o $@ $< + +%.o: %.cc + $(CXX) $(CXX_DEFINES) $(CXXFLAGS) -c -o $@ $< + +%.o: %.mm + $(CXX) $(CXX_DEFINES) $(CXXFLAGS) -c -o $@ $< + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.o: %.m + $(CC) $(CFLAGS) -c -o $@ $< + +# Where `clean` looks for the installed artifact. Mirrors exactly what the +# build rules above write to, so clean never points at a path `all` doesn't +# actually produce (the previous per-lib Makefiles had drifted on this). +CLEANTARGET_object = ../../../$(BUILDDIR)/$(TARGET) +CLEANTARGET_static = ../../../$(BUILDDIR)/$(OUT) +CLEANTARGET_shared = ../../../$(BUILDDIR)/$(OUT) + +clean: + rm -f $(OBJ) $(TARGET) $(OUT) $(CLEANTARGET_$(LIBKIND)) + +.PHONY: all clean diff --git a/src/libs/clip/Makefile b/src/libs/clip/Makefile index 67c6467..a13f8f8 100644 --- a/src/libs/clip/Makefile +++ b/src/libs/clip/Makefile @@ -1,42 +1,20 @@ -CXX ?= g++ -CXXSTD ?= c++20 -CXXFLAGS = -I../../../include/libs/clip -std=$(CXXSTD) $(LTO_FLAGS) -fvisibility=default -fvisibility-inlines-hidden -fPIC -DCLIP_ENABLE_IMAGE=1 +LIBKIND := static +LIBNAME := libclip +VISIBILITY := default -ifeq ($(DEBUG),1) - CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter \ - -DDEBUG=1 -fno-omit-frame-pointer $(DEBUG_CXXFLAGS) $(CXXFLAGS) -else - CXXFLAGS += -O3 -DNDEBUG -endif +CXXFLAGS += -I../../../include/libs/clip -DCLIP_ENABLE_IMAGE=1 UNAME_S := $(shell uname -s) - ifeq ($(findstring NT,$(UNAME_S)),NT) - CXXFLAGS += -D_CRT_SECURE_NO_WARNINGS - SRC += $(wildcard clip_win*.cpp) + CXXFLAGS += -D_CRT_SECURE_NO_WARNINGS + SRC += $(wildcard clip_win*.cpp) # Check if we're in MSYS environment ifneq (,$(findstring MSYS,$(shell uname -o))) CXXFLAGS += -DMSYS_PROCESS_USE_SH endif else - CXXFLAGS += -Wall -Wextra - SRC += clip_none.cpp + SRC += clip_none.cpp endif +SRC += clip.cpp image.cpp -LIBNAME = libclip.a -SRC += clip.cpp image.cpp -OBJ = $(SRC:.cpp=.o) - -all: $(LIBNAME) - -$(LIBNAME): $(OBJ) - ar rcs $@ $^ - mv -f $(LIBNAME) ../../../$(BUILDDIR)/$(LIBNAME) - -%.o: %.cpp - $(CXX) $(CXXFLAGS) -c -o $@ $< - -clean: - rm -f $(OBJ) $(LIBNAME) - -.PHONY: all clean +include ../../../mk/common.mk diff --git a/src/libs/fmt/CMakeLists.txt b/src/libs/fmt/CMakeLists.txt index 1606e88..ee568ce 100644 --- a/src/libs/fmt/CMakeLists.txt +++ b/src/libs/fmt/CMakeLists.txt @@ -1,188 +1,112 @@ cmake_minimum_required(VERSION 3.8...3.28) +include_guard(GLOBAL) # Fallback for using newer policies on CMake <3.12. if (${CMAKE_VERSION} VERSION_LESS 3.12) cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) endif () -# Determine if fmt is built as a subproject (using add_subdirectory) -# or if it is the master project. +# Determine if fmt is built as a subproject (using add_subdirectory) or if it is +# the master project. if (NOT DEFINED FMT_MASTER_PROJECT) set(FMT_MASTER_PROJECT OFF) - if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + # Checking project name is more reliable than checking source directories. + if (NOT DEFINED PROJECT_NAME) set(FMT_MASTER_PROJECT ON) message(STATUS "CMake version: ${CMAKE_VERSION}") endif () endif () # Joins arguments and places the results in ${result_var}. -function(join result_var) +function (join result_var) set(result "") foreach (arg ${ARGN}) set(result "${result}${arg}") endforeach () - set(${result_var} "${result}" PARENT_SCOPE) -endfunction() - -# DEPRECATED! Should be merged into add_module_library. -function(enable_module target) - if (MSVC) - set(BMI ${CMAKE_CURRENT_BINARY_DIR}/${target}.ifc) - target_compile_options(${target} - PRIVATE /interface /ifcOutput ${BMI} - INTERFACE /reference fmt=${BMI}) - set_target_properties(${target} PROPERTIES ADDITIONAL_CLEAN_FILES ${BMI}) - set_source_files_properties(${BMI} PROPERTIES GENERATED ON) - endif () -endfunction() - -set(FMT_USE_CMAKE_MODULES FALSE) -if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.28 AND - CMAKE_GENERATOR STREQUAL "Ninja") - set(FMT_USE_CMAKE_MODULES TRUE) -endif () - -# Adds a library compiled with C++20 module support. -# `enabled` is a CMake variables that specifies if modules are enabled. -# If modules are disabled `add_module_library` falls back to creating a -# non-modular library. -# -# Usage: -# add_module_library( [sources...] FALLBACK [sources...] [IF enabled]) -function(add_module_library name) - cmake_parse_arguments(AML "" "IF" "FALLBACK" ${ARGN}) - set(sources ${AML_UNPARSED_ARGUMENTS}) - - add_library(${name}) - set_target_properties(${name} PROPERTIES LINKER_LANGUAGE CXX) - - if (NOT ${${AML_IF}}) - # Create a non-modular library. - target_sources(${name} PRIVATE ${AML_FALLBACK}) - set_target_properties(${name} PROPERTIES CXX_SCAN_FOR_MODULES OFF) - return() - endif () - - # Modules require C++20. - target_compile_features(${name} PUBLIC cxx_std_20) - if (CMAKE_COMPILER_IS_GNUCXX) - target_compile_options(${name} PUBLIC -fmodules-ts) - endif () - - target_compile_definitions(${name} PRIVATE FMT_MODULE) - - if (FMT_USE_CMAKE_MODULES) - target_sources(${name} PUBLIC FILE_SET fmt TYPE CXX_MODULES - FILES ${sources}) - else() - # `std` is affected by CMake options and may be higher than C++20. - get_target_property(std ${name} CXX_STANDARD) - - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(pcms) - foreach (src ${sources}) - get_filename_component(pcm ${src} NAME_WE) - set(pcm ${pcm}.pcm) - - # Propagate -fmodule-file=*.pcm to targets that link with this library. - target_compile_options( - ${name} PUBLIC -fmodule-file=${CMAKE_CURRENT_BINARY_DIR}/${pcm}) - - # Use an absolute path to prevent target_link_libraries prepending -l - # to it. - set(pcms ${pcms} ${CMAKE_CURRENT_BINARY_DIR}/${pcm}) - add_custom_command( - OUTPUT ${pcm} - COMMAND ${CMAKE_CXX_COMPILER} - -std=c++${std} -x c++-module --precompile -c - -o ${pcm} ${CMAKE_CURRENT_SOURCE_DIR}/${src} - "-I$,;-I>" - # Required by the -I generator expression above. - COMMAND_EXPAND_LISTS - DEPENDS ${src}) - endforeach () - - # Add .pcm files as sources to make sure they are built before the library. - set(sources) - foreach (pcm ${pcms}) - get_filename_component(pcm_we ${pcm} NAME_WE) - set(obj ${pcm_we}.o) - # Use an absolute path to prevent target_link_libraries prepending -l. - set(sources ${sources} ${pcm} ${CMAKE_CURRENT_BINARY_DIR}/${obj}) - add_custom_command( - OUTPUT ${obj} - COMMAND ${CMAKE_CXX_COMPILER} $ - -c -o ${obj} ${pcm} - DEPENDS ${pcm}) - endforeach () - endif () - target_sources(${name} PRIVATE ${sources}) - endif() -endfunction() - -include(CMakeParseArguments) + set(${result_var} + "${result}" + PARENT_SCOPE) +endfunction () # Sets a cache variable with a docstring joined from multiple arguments: -# set( ... CACHE ...) +# set_verbose( CACHE ...) # This allows splitting a long docstring for readability. -function(set_verbose) - # cmake_parse_arguments is broken in CMake 3.4 (cannot parse CACHE) so use - # list instead. - list(GET ARGN 0 var) - list(REMOVE_AT ARGN 0) - list(GET ARGN 0 val) - list(REMOVE_AT ARGN 0) - list(REMOVE_AT ARGN 0) - list(GET ARGN 0 type) - list(REMOVE_AT ARGN 0) +function (set_verbose variable value _cache type) join(doc ${ARGN}) - set(${var} ${val} CACHE ${type} ${doc}) -endfunction() + set(${variable} + ${value} + CACHE ${type} ${doc}) +endfunction () # Set the default CMAKE_BUILD_TYPE to Release. # This should be done before the project command since the latter can set # CMAKE_BUILD_TYPE itself (it does so for nmake). if (FMT_MASTER_PROJECT AND NOT CMAKE_BUILD_TYPE) - set_verbose(CMAKE_BUILD_TYPE Release CACHE STRING - "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or " - "CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.") + set_verbose( + CMAKE_BUILD_TYPE Release CACHE STRING + "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or " + "CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.") endif () project(FMT CXX) -include(GNUInstallDirs) -set_verbose(FMT_INC_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE STRING - "Installation directory for include files, a relative path that " - "will be joined with ${CMAKE_INSTALL_PREFIX} or an absolute path.") -option(FMT_PEDANTIC "Enable extra warnings and expensive tests." OFF) -option(FMT_WERROR "Halt the compilation with an error on compiler warnings." - OFF) +# Determine support for the C++ module scanning and CXX_MODULE File_Sets +# Requires C++20, CMake >= 3.28 and +# Generators(Ninja >= 1.11 OR Visual Studio >= 17.4). +# Compilers GCC>=14, Clang>=16 or MSVC >= 17.4 +# Source: https://cmake.org/cmake/help/latest/manual/cmake-cxxmodules.7.html +set(FMT_USE_CMAKE_MODULES FALSE) +if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.28 AND CMAKE_CXX_STANDARD + GREATER_EQUAL 20) + if (CMAKE_GENERATOR STREQUAL "Ninja") + execute_process(COMMAND "${CMAKE_MAKE_PROGRAM}" "--version" + OUTPUT_VARIABLE NINJA_VERSION) + if (NINJA_VERSION VERSION_GREATER_EQUAL 1.11) + if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION + GREATER_EQUAL 15) + OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" + AND CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 16) + OR (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND MSVC_VERSION + GREATER_EQUAL 1934)) + set(FMT_USE_CMAKE_MODULES TRUE) + endif () + endif () + elseif (CMAKE_GENERATOR MATCHES "^Visual Studio" AND MSVC_VERSION + GREATER_EQUAL 1934) + set(FMT_USE_CMAKE_MODULES TRUE) + endif () +endif () -# Options that control generation of various targets. option(FMT_DOC "Generate the doc target." ${FMT_MASTER_PROJECT}) -option(FMT_INSTALL "Generate the install target." ON) +option(FMT_INSTALL "Generate the install target." ${FMT_MASTER_PROJECT}) option(FMT_TEST "Generate the test target." ${FMT_MASTER_PROJECT}) option(FMT_FUZZ "Generate the fuzz target." OFF) option(FMT_CUDA_TEST "Generate the cuda-test target." OFF) option(FMT_OS "Include OS-specific APIs." ON) -option(FMT_MODULE "Build a module instead of a traditional library." OFF) +option(FMT_MODULE "Build a module library." ${FMT_USE_CMAKE_MODULES}) option(FMT_SYSTEM_HEADERS "Expose headers with marking them as system." OFF) option(FMT_UNICODE "Enable Unicode support." ON) +option(FMT_PEDANTIC "Enable extra warnings and expensive tests." OFF) +option(FMT_WERROR "Halt the compilation with an error on compiler warnings." + OFF) -if (FMT_TEST AND FMT_MODULE) - # The tests require {fmt} to be compiled as traditional library - message(STATUS "Testing is incompatible with build mode 'module'.") -endif () set(FMT_SYSTEM_HEADERS_ATTRIBUTE "") if (FMT_SYSTEM_HEADERS) set(FMT_SYSTEM_HEADERS_ATTRIBUTE SYSTEM) endif () -if (CMAKE_SYSTEM_NAME STREQUAL "MSDOS") - set(FMT_TEST OFF) - message(STATUS "MSDOS is incompatible with gtest") -endif () -# Get version from base.h +include(GNUInstallDirs) # CMAKE_INSTALL_INCLUDEDIR + +set_verbose( + FMT_INC_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE STRING + "Installation directory for include files, a relative path that " + "will be joined with ${CMAKE_INSTALL_PREFIX} or an absolute path.") + +set(FMT_DEBUG_POSTFIX + d + CACHE STRING "Debug library postfix.") + +# Get version from base.h. file(READ include/fmt/base.h base_h) if (NOT base_h MATCHES "FMT_VERSION ([0-9]+)([0-9][0-9])([0-9][0-9])") message(FATAL_ERROR "Cannot get FMT_VERSION from base.h.") @@ -192,7 +116,7 @@ math(EXPR CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1}) math(EXPR CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2}) math(EXPR CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3}) join(FMT_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}. - ${CPACK_PACKAGE_VERSION_PATCH}) + ${CPACK_PACKAGE_VERSION_PATCH}) message(STATUS "{fmt} version: ${FMT_VERSION}") message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") @@ -201,64 +125,90 @@ if (NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) endif () -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} - "${CMAKE_CURRENT_SOURCE_DIR}/support/cmake") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/support/cmake") include(CheckCXXCompilerFlag) include(JoinPaths) if (FMT_MASTER_PROJECT AND NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET) set_verbose(CMAKE_CXX_VISIBILITY_PRESET hidden CACHE STRING - "Preset for the export of private symbols") - set_property(CACHE CMAKE_CXX_VISIBILITY_PRESET PROPERTY STRINGS - hidden default) + "Preset for the export of private symbols.") + set_property(CACHE CMAKE_CXX_VISIBILITY_PRESET PROPERTY STRINGS hidden + default) endif () if (FMT_MASTER_PROJECT AND NOT DEFINED CMAKE_VISIBILITY_INLINES_HIDDEN) - set_verbose(CMAKE_VISIBILITY_INLINES_HIDDEN ON CACHE BOOL - "Whether to add a compile flag to hide symbols of inline functions") + set_verbose( + CMAKE_VISIBILITY_INLINES_HIDDEN ON CACHE BOOL + "Whether to add a compile flag to hide symbols of inline " "functions.") endif () if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") - set(PEDANTIC_COMPILE_FLAGS -pedantic-errors -Wall -Wextra -pedantic - -Wold-style-cast -Wundef - -Wredundant-decls -Wwrite-strings -Wpointer-arith - -Wcast-qual -Wformat=2 -Wmissing-include-dirs + set(PEDANTIC_COMPILE_FLAGS + -pedantic-errors + -Wall + -Wextra + -pedantic + -Wold-style-cast + -Wundef + -Wredundant-decls + -Wwrite-strings + -Wpointer-arith + -Wcast-qual + -Wformat=2 + -Wmissing-include-dirs -Wcast-align - -Wctor-dtor-privacy -Wdisabled-optimization - -Winvalid-pch -Woverloaded-virtual - -Wconversion -Wundef - -Wno-ctor-dtor-privacy -Wno-format-nonliteral) + -Wctor-dtor-privacy + -Wdisabled-optimization + -Winvalid-pch + -Woverloaded-virtual + -Wconversion + -Wundef + -Wno-ctor-dtor-privacy + -Wno-format-nonliteral) if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) - set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} - -Wno-dangling-else -Wno-unused-local-typedefs) + set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wno-dangling-else + -Wno-unused-local-typedefs) endif () if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) - set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wdouble-promotion - -Wtrampolines -Wzero-as-null-pointer-constant -Wuseless-cast - -Wvector-operation-performance -Wsized-deallocation -Wshadow) + set(PEDANTIC_COMPILE_FLAGS + ${PEDANTIC_COMPILE_FLAGS} + -Wdouble-promotion + -Wtrampolines + -Wzero-as-null-pointer-constant + -Wuseless-cast + -Wvector-operation-performance + -Wsized-deallocation + -Wshadow) endif () if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) - set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wshift-overflow=2 - -Wduplicated-cond) - # Workaround for GCC regression - # [12/13/14/15 regression] New (since gcc 12) false positive null-dereference in vector.resize - # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108860 - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0) - set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnull-dereference) - endif () + set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wshift-overflow=2 + -Wduplicated-cond) + # Workaround for GCC 12-15 regression: + # a false positive null-dereference in vector.resize + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108860. + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0) + set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnull-dereference) + endif () endif () set(WERROR_FLAG -Werror) endif () if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -pedantic -Wconversion -Wundef - -Wdeprecated -Wweak-vtables -Wshadow + set(PEDANTIC_COMPILE_FLAGS + -Wall + -Wextra + -pedantic + -Wconversion + -Wundef + -Wdeprecated + -Wweak-vtables + -Wshadow -Wno-gnu-zero-variadic-macro-arguments) check_cxx_compiler_flag(-Wzero-as-null-pointer-constant HAS_NULLPTR_WARNING) if (HAS_NULLPTR_WARNING) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} - -Wzero-as-null-pointer-constant) + -Wzero-as-null-pointer-constant) endif () set(WERROR_FLAG -Werror) endif () @@ -281,34 +231,66 @@ if (FMT_MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio") join(netfxpath "C:\\Program Files\\Reference Assemblies\\Microsoft\\Framework\\" ".NETFramework\\v4.0") - file(WRITE run-msbuild.bat " - ${MSBUILD_SETUP} + file(WRITE run-msbuild.bat "${MSBUILD_SETUP} ${CMAKE_MAKE_PROGRAM} -p:FrameworkPathOverride=\"${netfxpath}\" %*") endif () -function(add_headers VAR) - set(headers ${${VAR}}) - foreach (header ${ARGN}) - set(headers ${headers} include/fmt/${header}) - endforeach() - set(${VAR} ${headers} PARENT_SCOPE) -endfunction() - -# Define the fmt library, its includes and the needed defines. -add_headers(FMT_HEADERS args.h base.h chrono.h color.h compile.h core.h format.h - format-inl.h os.h ostream.h printf.h ranges.h std.h - xchar.h) -set(FMT_SOURCES src/format.cc) - -add_module_library(fmt src/fmt.cc FALLBACK - ${FMT_SOURCES} ${FMT_HEADERS} README.md ChangeLog.md - IF FMT_MODULE) -add_library(fmt::fmt ALIAS fmt) -if (FMT_MODULE) - enable_module(fmt) -elseif (FMT_OS) +# Sets up a top-level fmt target. Targets that depend on other top-level targets +# should call this because they'll automatically get the required properties. +function (setup_target target kind) + add_library(fmt::${target} ALIAS ${target}) + + target_include_directories( + ${target} ${FMT_SYSTEM_HEADERS_ATTRIBUTE} BEFORE ${kind} + $ + $) + + if (NOT MSVC) + # Unicode is always supported on compilers other than MSVC. + elseif (FMT_UNICODE) + # Unicode support requires compiling with /utf-8. + target_compile_options( + ${target} ${kind} + $<$,$>:/utf-8>) + else () + target_compile_definitions(${target} ${kind} FMT_UNICODE=0) + endif () + + set_target_properties( + ${target} + PROPERTIES VERSION ${FMT_VERSION} + SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR} + DEBUG_POSTFIX "${FMT_DEBUG_POSTFIX}") +endfunction () + +set(FMT_HEADERS) +foreach ( + header + args.h + base.h + chrono.h + color.h + compile.h + core.h + format.h + format-inl.h + os.h + ostream.h + printf.h + ranges.h + std.h + xchar.h) + set(FMT_HEADERS ${FMT_HEADERS} include/fmt/${header}) +endforeach () + +# Add the main fmt library. +add_library(fmt src/format.cc ${FMT_HEADERS} README.md ChangeLog.md) +setup_target(fmt PUBLIC) +set_target_properties(fmt PROPERTIES PUBLIC_HEADER "${FMT_HEADERS}") + +if (FMT_OS) target_sources(fmt PRIVATE src/os.cc) -else() +else () target_compile_definitions(fmt PRIVATE FMT_OS=0) endif () @@ -325,25 +307,6 @@ else () message(WARNING "Feature cxx_std_11 is unknown for the CXX compiler") endif () -target_include_directories(fmt ${FMT_SYSTEM_HEADERS_ATTRIBUTE} BEFORE PUBLIC - $ - $) - -set(FMT_DEBUG_POSTFIX d CACHE STRING "Debug library postfix.") - -set_target_properties(fmt PROPERTIES - VERSION ${FMT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR} - PUBLIC_HEADER "${FMT_HEADERS}" - DEBUG_POSTFIX "${FMT_DEBUG_POSTFIX}" - - # Workaround for Visual Studio 2017: - # Ensure the .pdb is created with the same name and in the same directory - # as the .lib. Newer VS versions already do this by default, but there is no - # harm in setting it for those too. Ignored by other generators. - COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" - COMPILE_PDB_NAME "fmt" - COMPILE_PDB_NAME_DEBUG "fmt${FMT_DEBUG_POSTFIX}") - # Set FMT_LIB_NAME for pkg-config fmt.pc. We cannot use the OUTPUT_NAME target # property because it's not set by default. set(FMT_LIB_NAME fmt) @@ -352,53 +315,147 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug") endif () if (BUILD_SHARED_LIBS) - target_compile_definitions(fmt PRIVATE FMT_LIB_EXPORT INTERFACE FMT_SHARED) + target_compile_definitions( + fmt + PRIVATE FMT_LIB_EXPORT + INTERFACE FMT_SHARED) endif () if (FMT_SAFE_DURATION_CAST) target_compile_definitions(fmt PUBLIC FMT_SAFE_DURATION_CAST) endif () -add_library(fmt-header-only INTERFACE) -add_library(fmt::fmt-header-only ALIAS fmt-header-only) - -if (NOT MSVC) - # Unicode is always supported on compilers other than MSVC. -elseif (FMT_UNICODE) - # Unicode support requires compiling with /utf-8. - target_compile_options(fmt PUBLIC $<$,$>:/utf-8>) - target_compile_options(fmt-header-only INTERFACE $<$,$>:/utf-8>) -else () - target_compile_definitions(fmt PUBLIC FMT_UNICODE=0) +# Adds a library compiled with C++20 module support. +# +# Usage: +# add_module_library( [sources...] [USE_CMAKE_MODULES TRUE]) +function (add_module_library name) + cmake_parse_arguments(AML "" "USE_CMAKE_MODULES" "" ${ARGN}) + set(sources ${AML_UNPARSED_ARGUMENTS}) + + add_library(${name}) + set_target_properties(${name} PROPERTIES LINKER_LANGUAGE CXX) + + # Modules require C++20. + target_compile_features(${name} PUBLIC cxx_std_20) + + if (MSVC) + if (NOT CMAKE_GENERATOR STREQUAL "Ninja") + set(BMI_DIR "${CMAKE_CURRENT_BINARY_DIR}") + file(TO_NATIVE_PATH "${BMI_DIR}/${name}.ifc" BMI) + target_compile_options( + ${name} + PRIVATE /interface /ifcOutput ${BMI} + INTERFACE /reference fmt=${BMI}) + set_target_properties(${name} PROPERTIES ADDITIONAL_CLEAN_FILES ${BMI}) + set_source_files_properties(${BMI} PROPERTIES GENERATED ON) + endif () + endif () + + if (${AML_USE_CMAKE_MODULES}) + target_sources(${name} PUBLIC FILE_SET fmt TYPE CXX_MODULES FILES + ${sources}) + return() + endif () + + if (CMAKE_COMPILER_IS_GNUCXX) + target_compile_options(${name} PUBLIC -fmodules-ts) + endif () + + # `std` is affected by CMake options and may be higher than C++20. + get_target_property(std ${name} CXX_STANDARD) + + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(pcms) + foreach (src ${sources}) + get_filename_component(pcm ${src} NAME_WE) + set(pcm ${pcm}.pcm) + + # Propagate -fmodule-file=*.pcm to targets that link with this library. + target_compile_options( + ${name} PUBLIC -fmodule-file=${CMAKE_CURRENT_BINARY_DIR}/${pcm}) + + # Use an absolute path to prevent target_link_libraries prepending -l + # to it. + set(pcms ${pcms} ${CMAKE_CURRENT_BINARY_DIR}/${pcm}) + add_custom_command( + OUTPUT ${pcm} + COMMAND + ${CMAKE_CXX_COMPILER} -std=c++${std} -x c++-module --precompile -c -o + ${pcm} ${CMAKE_CURRENT_SOURCE_DIR}/${src} + "-I$,;-I>" + # Required by the -I generator expression above. + COMMAND_EXPAND_LISTS + DEPENDS ${src}) + endforeach () + + # Add .pcm files as sources to make sure they are built before the library. + set(sources) + foreach (pcm ${pcms}) + get_filename_component(pcm_we ${pcm} NAME_WE) + set(obj ${pcm_we}.o) + # Use an absolute path to prevent target_link_libraries prepending -l. + set(sources ${sources} ${pcm} ${CMAKE_CURRENT_BINARY_DIR}/${obj}) + add_custom_command( + OUTPUT ${obj} + COMMAND ${CMAKE_CXX_COMPILER} $ + -c -o ${obj} ${pcm} + DEPENDS ${pcm}) + endforeach () + endif () + target_sources(${name} PRIVATE ${sources}) +endfunction () + +if (FMT_MODULE) + add_module_library(fmt-module src/fmt.cc USE_CMAKE_MODULES + ${FMT_USE_CMAKE_MODULES}) + setup_target(fmt-module PUBLIC) endif () +add_library(fmt-header-only INTERFACE) + target_compile_definitions(fmt-header-only INTERFACE FMT_HEADER_ONLY=1) target_compile_features(fmt-header-only INTERFACE cxx_std_11) +setup_target(fmt-header-only INTERFACE) -target_include_directories(fmt-header-only - ${FMT_SYSTEM_HEADERS_ATTRIBUTE} BEFORE INTERFACE - $ - $) +add_library(fmt-c STATIC src/fmt-c.cc) +target_compile_features(fmt-c INTERFACE c_std_11) +if (MSVC) + target_compile_options(fmt-c PUBLIC /Zc:preprocessor) +endif () +target_link_libraries(fmt-c PUBLIC fmt::fmt) +add_library(fmt::fmt-c ALIAS fmt-c) + +set_target_properties(fmt-c PROPERTIES PUBLIC_HEADER include/fmt/fmt-c.h) # Install targets. if (FMT_INSTALL) include(CMakePackageConfigHelpers) - set_verbose(FMT_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/fmt CACHE STRING - "Installation directory for cmake files, a relative path that " - "will be joined with ${CMAKE_INSTALL_PREFIX} or an absolute " - "path.") + set_verbose( + FMT_CMAKE_DIR + ${CMAKE_INSTALL_LIBDIR}/cmake/fmt + CACHE + STRING + "Installation directory for cmake files, a relative path that " + "will be joined with ${CMAKE_INSTALL_PREFIX} or an absolute " + "path.") set(version_config ${PROJECT_BINARY_DIR}/fmt-config-version.cmake) set(project_config ${PROJECT_BINARY_DIR}/fmt-config.cmake) set(pkgconfig ${PROJECT_BINARY_DIR}/fmt.pc) set(targets_export_name fmt-targets) - set_verbose(FMT_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING - "Installation directory for libraries, a relative path that " - "will be joined to ${CMAKE_INSTALL_PREFIX} or an absolute path.") + set_verbose( + FMT_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING + "Installation directory for libraries, a relative path that " + "will be joined to ${CMAKE_INSTALL_PREFIX} or an absolute path.") - set_verbose(FMT_PKGCONFIG_DIR ${CMAKE_INSTALL_LIBDIR}/pkgconfig CACHE STRING - "Installation directory for pkgconfig (.pc) files, a relative " - "path that will be joined with ${CMAKE_INSTALL_PREFIX} or an " - "absolute path.") + set_verbose( + FMT_PKGCONFIG_DIR + ${CMAKE_INSTALL_LIBDIR}/pkgconfig + CACHE + STRING + "Installation directory for pkgconfig (.pc) files, a relative " + "path that will be joined with ${CMAKE_INSTALL_PREFIX} or an " + "absolute path.") # Generate the version, config and target files into the build directory. write_basic_package_version_file( @@ -409,80 +466,90 @@ if (FMT_INSTALL) join_paths(libdir_for_pc_file "\${exec_prefix}" "${FMT_LIB_DIR}") join_paths(includedir_for_pc_file "\${prefix}" "${FMT_INC_DIR}") - configure_file( - "${PROJECT_SOURCE_DIR}/support/cmake/fmt.pc.in" - "${pkgconfig}" - @ONLY) + configure_file("${PROJECT_SOURCE_DIR}/support/cmake/fmt.pc.in" "${pkgconfig}" + @ONLY) configure_package_config_file( - ${PROJECT_SOURCE_DIR}/support/cmake/fmt-config.cmake.in - ${project_config} + ${PROJECT_SOURCE_DIR}/support/cmake/fmt-config.cmake.in ${project_config} INSTALL_DESTINATION ${FMT_CMAKE_DIR}) - set(INSTALL_TARGETS fmt fmt-header-only) + set(INSTALL_TARGETS fmt fmt-header-only fmt-c) - set(INSTALL_FILE_SET) - if (FMT_USE_CMAKE_MODULES) - set(INSTALL_FILE_SET FILE_SET fmt DESTINATION "${FMT_INC_DIR}/fmt") - endif() + if (FMT_MODULE) + list(APPEND INSTALL_TARGETS fmt-module) + if (FMT_USE_CMAKE_MODULES) + set(INSTALL_FILE_SET FILE_SET fmt DESTINATION ${FMT_INC_DIR}/fmt) + endif () + endif () # Install the library and headers. - install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name} - LIBRARY DESTINATION ${FMT_LIB_DIR} - ARCHIVE DESTINATION ${FMT_LIB_DIR} - PUBLIC_HEADER DESTINATION "${FMT_INC_DIR}/fmt" - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - ${INSTALL_FILE_SET}) + install( + TARGETS ${INSTALL_TARGETS} + COMPONENT fmt_core + EXPORT ${targets_export_name} + LIBRARY DESTINATION ${FMT_LIB_DIR} + ARCHIVE DESTINATION ${FMT_LIB_DIR} + PUBLIC_HEADER DESTINATION ${FMT_INC_DIR}/fmt + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ${INSTALL_FILE_SET}) # Use a namespace because CMake provides better diagnostics for namespaced # imported targets. - export(TARGETS ${INSTALL_TARGETS} NAMESPACE fmt:: - FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake) + export( + TARGETS ${INSTALL_TARGETS} + NAMESPACE fmt:: + FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake) # Install version, config and target files. install( FILES ${project_config} ${version_config} - DESTINATION ${FMT_CMAKE_DIR}) - install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR} - NAMESPACE fmt::) + DESTINATION ${FMT_CMAKE_DIR} + COMPONENT fmt_core) + install( + EXPORT ${targets_export_name} + DESTINATION ${FMT_CMAKE_DIR} + NAMESPACE fmt:: + COMPONENT fmt_core) - install(FILES "${pkgconfig}" DESTINATION "${FMT_PKGCONFIG_DIR}") + install( + FILES "${pkgconfig}" + DESTINATION "${FMT_PKGCONFIG_DIR}" + COMPONENT fmt_core) endif () -function(add_doc_target) - find_program(DOXYGEN doxygen - PATHS "$ENV{ProgramFiles}/doxygen/bin" - "$ENV{ProgramFiles\(x86\)}/doxygen/bin") +function (add_doc_target) + find_program(DOXYGEN doxygen PATHS "$ENV{ProgramFiles}/doxygen/bin" + "$ENV{ProgramFiles\(x86\)}/doxygen/bin") if (NOT DOXYGEN) message(STATUS "Target 'doc' disabled because doxygen not found") - return () + return() endif () find_program(MKDOCS mkdocs) if (NOT MKDOCS) message(STATUS "Target 'doc' disabled because mkdocs not found") - return () + return() endif () - set(sources ) + set(sources) foreach (source api.md index.md syntax.md get-started.md fmt.css fmt.js) set(sources ${sources} doc/${source}) - endforeach() + endforeach () add_custom_target( doc COMMAND - ${CMAKE_COMMAND} - -E env PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR}/support/python - ${MKDOCS} build -f ${CMAKE_CURRENT_SOURCE_DIR}/support/mkdocs.yml - # MkDocs requires the site dir to be outside of the doc dir. - --site-dir ${CMAKE_CURRENT_BINARY_DIR}/doc-html - --no-directory-urls + ${CMAKE_COMMAND} -E env + PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR}/support/python ${MKDOCS} build -f + ${CMAKE_CURRENT_SOURCE_DIR}/support/mkdocs.yml + # MkDocs requires the site dir to be outside of the doc dir. + --site-dir ${CMAKE_CURRENT_BINARY_DIR}/doc-html --no-directory-urls SOURCES ${sources}) - include(GNUInstallDirs) - install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc-html/ - DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/doc/fmt OPTIONAL) -endfunction() + install( + DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc-html/ + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/doc/fmt + COMPONENT fmt_doc + OPTIONAL) +endfunction () if (FMT_DOC) add_doc_target() @@ -508,14 +575,16 @@ endif () set(gitignore ${PROJECT_SOURCE_DIR}/.gitignore) if (FMT_MASTER_PROJECT AND EXISTS ${gitignore}) # Get the list of ignored files from .gitignore. - file (STRINGS ${gitignore} lines) + file(STRINGS ${gitignore} lines) list(REMOVE_ITEM lines /doc/html) foreach (line ${lines}) string(REPLACE "." "[.]" line "${line}") string(REPLACE "*" ".*" line "${line}") set(ignored_files ${ignored_files} "${line}$" "${line}/") endforeach () - set(ignored_files ${ignored_files} /.git /build/doxyxml .vagrant) + # Exclude the whole build tree: the .gitignore-derived `build/` pattern does + # not actually prune the directory or its contents from the source package. + set(ignored_files ${ignored_files} /.git "/build($|/)" .vagrant) set(CPACK_SOURCE_GENERATOR ZIP) set(CPACK_SOURCE_IGNORE_FILES ${ignored_files}) diff --git a/src/libs/fmt/Makefile b/src/libs/fmt/Makefile index c93aca2..282a9c7 100644 --- a/src/libs/fmt/Makefile +++ b/src/libs/fmt/Makefile @@ -2,32 +2,11 @@ # I don't wanna use cmake # cmd: cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -CXX ?= g++ -CXXSTD ?= c++20 -# CXX_DEFINES = -DFMT_LIB_EXPORT -Dfmt_EXPORTS -CXXFLAGS = -I../../../include/libs -std=$(CXXSTD) $(LTO_FLAGS) -fvisibility=hidden -fvisibility-inlines-hidden -fPIC +LIBKIND := static +LIBNAME := libfmt +SRC = format.cc os.cc +# CXX_DEFINES = -DFMT_LIB_EXPORT -Dfmt_EXPORTS -OBJ = format.cc.o os.cc.o +CXXFLAGS += -I../../../include/libs -ifeq ($(DEBUG),1) - CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter \ - -DDEBUG=1 -fno-omit-frame-pointer $(DEBUG_CXXFLAGS) $(CXXFLAGS) -else - CXXFLAGS += -O3 -DNDEBUG -endif - -all: fmt - -fmt: $(OBJ) - ar qc libfmt.a $(OBJ) - ranlib libfmt.a - mkdir -p ../../../$(BUILDDIR) - mv -f libfmt.a ../../../$(BUILDDIR)/libfmt.a - -%.cc.o: %.cc - $(CXX) $(CXX_DEFINES) $(CXXFLAGS) -c $< -o $@ - -clean: - rm -f *.o *.so *.a ../../../$(BUILDDIR)/fmt/.*a - -.PHONY: clean all fmt +include ../../../mk/common.mk diff --git a/src/libs/getopt_port/Makefile b/src/libs/getopt_port/Makefile index d369ff9..8a81c92 100644 --- a/src/libs/getopt_port/Makefile +++ b/src/libs/getopt_port/Makefile @@ -1,14 +1,5 @@ -CC ?= cc -SRC = getopt.c +LIBKIND := object +SRC = getopt.c TARGET = getopt.o -CFLAGS = -I../../../include/libs $(LTO_FLAGS) -fvisibility=hidden -fPIC -all: $(TARGET) - -$(TARGET): - $(CC) $(SRC) $(CFLAGS) -c -o ../../../$(BUILDDIR)/$@ - -clean: - rm -rf ../../../$(BUILDDIR)/getopt_port/$(TARGET) - -.PHONY: $(TARGET) clean all +include ../../../mk/common.mk diff --git a/src/libs/imgui/Makefile b/src/libs/imgui/Makefile index 85e21b3..4d1adef 100644 --- a/src/libs/imgui/Makefile +++ b/src/libs/imgui/Makefile @@ -1,29 +1,8 @@ -CXX ?= g++ -CXXSTD ?= c++20 -CXXFLAGS = -std=$(CXXSTD) $(LTO_FLAGS) -I../../../include/libs/imgui -fvisibility=hidden -fvisibility-inlines-hidden -fPIC -DIMGUI_DISABLE_OBSOLETE_FUNCTIONS +LIBKIND := shared +LIBNAME := liboshot_imgui +SRC := $(wildcard *.cpp) +VISIBILITY := default -SRC := $(wildcard *.cpp) -OBJ := $(SRC:.cpp=.o) -LIBNAME := libimgui.a +CXXFLAGS += -I../../../include/libs/imgui -DIMGUI_DISABLE_OBSOLETE_FUNCTIONS -ifeq ($(DEBUG),1) - CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter \ - -DDEBUG=1 -fno-omit-frame-pointer $(DEBUG_CXXFLAGS) $(CXXFLAGS) -else - CXXFLAGS += -O3 -DNDEBUG -endif - -all: $(LIBNAME) - -$(LIBNAME): $(OBJ) - ar rcs $@ $^ - ranlib $(LIBNAME) - mv -f $(LIBNAME) ../../../$(BUILDDIR)/$(LIBNAME) - -%.o: %.cpp - $(CXX) $(CXXFLAGS) -c -o $@ $< - -clean: - rm -f $(OBJ) $(LIBNAME) - -.PHONY: all clean +include ../../../mk/common.mk diff --git a/src/libs/nvdialog/Makefile b/src/libs/nvdialog/Makefile index d879158..49af77d 100644 --- a/src/libs/nvdialog/Makefile +++ b/src/libs/nvdialog/Makefile @@ -1,32 +1,33 @@ -CC ?= gcc -PKGCONF ?= pkg-config - -CFLAGS := -std=c11 -Wall -Wextra -Wconversion -Winline -Werror=format -Werror=format-security -Werror=write-strings -Wno-sign-conversion -CFLAGS += -I../../../include/libs/nvdialog $(LTO_FLAGS) -Iimpl -Ibackend -O3 -fvisibility=default -DNVDIALOG_MAXBUF=4096 -DNVD_EXPORT_SYMBOLS -DNVD_STATIC_LINKAGE=1 -CFLAGS += `$(PKGCONF) --cflags gtk+-3.0 dbus-1` -LDFLAGS := `$(PKGCONF) --libs gtk+-3.0 dbus-1` - -LIBNAME := libnvdialog.a -COMMON_SRC := $(wildcard src/*.c) -SRC := $(wildcard *.c backend/gtk/*.c) -OBJ := $(SRC:%.c=%.o) -OBJ := $(OBJ:%.c=%.o) - -LIBNAME := libnvdialog.a +LIBKIND := static +LIBNAME := libnvdialog +VISIBILITY := default -all: $(LIBNAME) +CFLAGS += -I../../../include/libs/nvdialog -Iimpl -Ibackend -O3 \ + -Wall -Wextra -Wconversion -Winline -Wno-sign-conversion \ + -Werror=format -Werror=format-security -Werror=write-strings \ + -DNVDIALOG_MAXBUF=4096 -DNVD_EXPORT_SYMBOLS -DNVD_STATIC_LINKAGE=1 -$(LIBNAME): $(OBJ) - ar rcs $@ $^ - ranlib $@ - mv -f $@ ../../../$(BUILDDIR)/$@ - -# universal compile rule -$(OBJDIR)/%.o: src/%.c - mkdir -p $(dir $@) - $(CC) $(CFLAGS) -c $< -o $@ - -clean: - rm -rf $(OBJ) $(LIBNAME) +PKGCONF ?= pkg-config -.PHONY: all clean +# Sources common to every platform. +SRC := $(wildcard *.c) $(wildcard src/*.c) + +UNAME_S := $(shell uname -s) + +ifeq ($(UNAME_S),Darwin) + SRC += $(wildcard backend/cocoa/*.m) + CFLAGS += -DNVD_USE_COCOA=1 -fno-objc-arc + # Whatever links libnvdialog.a must additionally add: + # -framework AppKit -framework Cocoa -framework Foundation -framework UserNotifications +else ifeq ($(findstring NT,$(UNAME_S)),NT) + SRC += $(wildcard backend/win32/*.c) + # Whatever links libnvdialog.a must additionally add: + # -lcomdlg32 -lshell32 -luser32 -lgdi32 -lole32 +else + SRC += $(wildcard backend/gtk/*.c) + CFLAGS += `$(PKGCONF) --cflags gtk+-3.0 dbus-1` + # Whatever links libnvdialog.a must additionally add: + # `pkg-config --libs gtk+-3.0 dbus-1` +endif + +include ../../../mk/common.mk diff --git a/src/libs/tiny-process-library/Makefile b/src/libs/tiny-process-library/Makefile index 58fc491..31d14b8 100644 --- a/src/libs/tiny-process-library/Makefile +++ b/src/libs/tiny-process-library/Makefile @@ -1,42 +1,20 @@ -CXX ?= g++ -CXXSTD ?= c++20 -CXXFLAGS = -I../../../include/libs/tiny-process-library -std=$(CXXSTD) $(LTO_FLAGS) -fvisibility=default -fvisibility-inlines-hidden -fPIC +LIBKIND := static +LIBNAME := libtiny-process-library +VISIBILITY := default -ifeq ($(DEBUG),1) - CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter \ - -DDEBUG=1 -fno-omit-frame-pointer $(DEBUG_CXXFLAGS) $(CXXFLAGS) -else - CXXFLAGS += -O3 -DNDEBUG -endif +CXXFLAGS += -I../../../include/libs/tiny-process-library UNAME_S := $(shell uname -s) - ifeq ($(findstring MINGW64_NT,$(UNAME_S)),MINGW64_NT) - CXXFLAGS += -D_CRT_SECURE_NO_WARNINGS - SRC += process_win.cpp + CXXFLAGS += -D_CRT_SECURE_NO_WARNINGS + SRC += process_win.cpp # Check if we're in MSYS environment ifneq (,$(findstring MSYS,$(shell uname -o))) CXXFLAGS += -DMSYS_PROCESS_USE_SH endif else - CXXFLAGS += -Wall -Wextra - SRC += process_unix.cpp + SRC += process_unix.cpp endif +SRC += process.cpp -LIBNAME = libtiny-process-library.a -SRC += process.cpp -OBJ = $(SRC:.cpp=.o) - -all: $(LIBNAME) - -$(LIBNAME): $(OBJ) - ar rcs $@ $^ - mv -f $(LIBNAME) ../../../$(BUILDDIR)/$(LIBNAME) - -%.o: %.cpp - $(CXX) $(CXXFLAGS) -c -o $@ $< - -clean: - rm -f $(OBJ) $(LIBNAME) - -.PHONY: all clean +include ../../../mk/common.mk diff --git a/src/libs/tinyfiledialogs/Makefile b/src/libs/tinyfiledialogs/Makefile index 793c7db..4e45d76 100644 --- a/src/libs/tinyfiledialogs/Makefile +++ b/src/libs/tinyfiledialogs/Makefile @@ -1,15 +1,9 @@ -CC ?= gcc -CSTD ?= c11 -SRC = tinyfiledialogs.c -TARGET = tinyfiledialogs.o -CFLAGS = -I../../../include/libs $(LTO_FLAGS) -O3 -fvisibility=default -fPIC -std=$(CSTD) +LIBKIND := object +SRC = tinyfiledialogs.c +TARGET = tinyfiledialogs.o +VISIBILITY := default +CSTD ?= c11 -all: $(TARGET) +CFLAGS += -I../../../include/libs -O3 -$(TARGET): - $(CC) $(SRC) $(CFLAGS) -c -o ../../../$(BUILDDIR)/$@ - -clean: - rm -rf ../../../$(BUILDDIR)/$(TARGET) - -.PHONY: $(TARGET) clean all +include ../../../mk/common.mk diff --git a/src/libs/toml++/Makefile b/src/libs/toml++/Makefile index 811bdc3..7c2e602 100644 --- a/src/libs/toml++/Makefile +++ b/src/libs/toml++/Makefile @@ -1,15 +1,8 @@ -CXX ?= g++ -CXXSTD ?= c++20 -SRC = toml.cpp -TARGET = toml.o -CXXFLAGS = -I../../../include/libs $(LTO_FLAGS) -fvisibility-inlines-hidden -fvisibility=default -fPIC -std=$(CXXSTD) +LIBKIND := object +SRC = toml.cpp +TARGET = toml.o +VISIBILITY := default -all: $(TARGET) +CXXFLAGS += -I../../../include/libs -$(TARGET): - $(CXX) $(SRC) $(CXXFLAGS) -c -o ../../../$(BUILDDIR)/$@ - -clean: - rm -rf ../../../$(BUILDDIR)/toml++/$(TARGET) - -.PHONY: $(TARGET) clean all +include ../../../mk/common.mk diff --git a/src/libs/tray/Makefile b/src/libs/tray/Makefile index 51d73e0..2bd0b7d 100644 --- a/src/libs/tray/Makefile +++ b/src/libs/tray/Makefile @@ -1,35 +1,13 @@ -PKG_FLAGS := `pkg-config --cflags appindicator3-0.1` +LIBKIND := static +LIBNAME := libtray +PKG_FLAGS := `pkg-config --cflags appindicator3-0.1` -CXX ?= g++ -CXXSTD ?= c++20 -CXXFLAGS = $(PKG_FLAGS) -std=$(CXXSTD) $(LTO_FLAGS) -I../../../include/libs/ -fvisibility=hidden -fvisibility-inlines-hidden -fPIC - -SRC := $(wildcard ./*.cpp) -OBJ := $(SRC:.cpp=.o) -LIBNAME := libtray.a - -ifeq ($(DEBUG),1) - CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter \ - -DDEBUG=1 -fno-omit-frame-pointer $(DEBUG_CXXFLAGS) $(CXXFLAGS) -else - CXXFLAGS += -O3 -DNDEBUG -endif +CXXFLAGS += $(PKG_FLAGS) -I../../../include/libs ifeq ($(shell uname -s),Darwin) - SRC := tray_darwin.mm + SRC := tray_darwin.mm +else + SRC := $(wildcard ./*.cpp) endif -all: $(LIBNAME) - -$(LIBNAME): $(OBJ) - ar rcs $@ $^ - ranlib $(LIBNAME) - mv -f $(LIBNAME) ../../../$(BUILDDIR)/$(LIBNAME) - -%.o: %.cpp - $(CXX) $(CXXFLAGS) -c -o $@ $< - -clean: - rm -f $(OBJ) $(LIBNAME) - -.PHONY: all clean +include ../../../mk/common.mk From 57426281fd2ac575d41ab0a647edeaed27d566aa Mon Sep 17 00:00:00 2001 From: Toni500git Date: Tue, 23 Jun 2026 22:32:11 +0200 Subject: [PATCH 04/40] libs: added cimgui - C-ABI wrapper for imgui --- CMakeLists.txt | 15 +- Makefile | 4 + include/libs/cimgui/cimgui.h | 5230 ++++++++++++++++++++++++++++ src/libs/cimgui/Makefile | 9 + src/libs/cimgui/cimgui.cpp | 6215 ++++++++++++++++++++++++++++++++++ 5 files changed, 11470 insertions(+), 3 deletions(-) create mode 100644 include/libs/cimgui/cimgui.h create mode 100644 src/libs/cimgui/Makefile create mode 100644 src/libs/cimgui/cimgui.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a79eef5..ea2dfd9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -171,7 +171,6 @@ elseif(APPLE) # Add Metal render loop source target_sources(${PROJECT_NAME} PRIVATE src/main_tool_metal.mm) - target_link_options( ${PROJECT_NAME} PRIVATE $<$:-stdlib=libc++> @@ -225,19 +224,29 @@ target_link_libraries(${PROJECT_NAME} PRIVATE fmt) file(GLOB IMGUI_SOURCES src/libs/imgui/*.cpp) if(APPLE) - list(APPEND IMGUI_SOURCES src/libs/imgui/imgui_impl_metal.mm) + file(GLOB IMGUI_APPLE_SOURCE src/libs/imgui/*.mm) + list(APPEND IMGUI_SOURCES IMGUI_APPLE_SOURCE) endif() -add_library(imgui STATIC ${IMGUI_SOURCES}) +add_library(imgui SHARED ${IMGUI_SOURCES}) enable_lto(imgui) target_include_directories(imgui PUBLIC include/libs/imgui) target_compile_definitions(imgui PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLAD) target_link_libraries(imgui PUBLIC ${GLFW_TARGET}) +set_target_properties(imgui PROPERTIES VERSION 1.92.9 SOVERSION 1) target_link_libraries(${PROJECT_NAME} PRIVATE imgui) +# ----------------------------- +# cimgui library (C-ABI plugins only) +# ----------------------------- + +add_library(cimgui SHARED src/libs/cimgui/cimgui.cpp) +target_link_libraries(cimgui PUBLIC imgui) +set_target_properties(cimgui PROPERTIES VERSION 1 SOVERSION 1) + # ----------------------------- # Tray library (integrated from its own CMakeLists.txt) # ----------------------------- diff --git a/Makefile b/Makefile index 7bb7c0b..834c2a9 100644 --- a/Makefile +++ b/Makefile @@ -72,6 +72,7 @@ CXXFLAGS += $(LTO_FLAGS) -fvisibility-inlines-hidden -fvisibility=hidden -Iin LIBS := \ $(BUILDDIR)/liboshot_imgui.so \ + $(BUILDDIR)/liboshot_cimgui.so \ $(BUILDDIR)/libfmt.a \ $(BUILDDIR)/libclip.a \ $(BUILDDIR)/libtray.a \ @@ -98,6 +99,9 @@ $(BUILDDIR)/liboshot_imgui.so: | $(BUILDDIR) $(BUILDDIR)/libfmt.a: | $(BUILDDIR) $(MAKE) -C src/libs/fmt BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) +$(BUILDDIR)/liboshot_cimgui.so: $(BUILDDIR)/liboshot_imgui.so | $(BUILDDIR) + $(MAKE) -C src/libs/cimgui BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) + $(BUILDDIR)/toml.o: | $(BUILDDIR) $(MAKE) -C src/libs/toml++ BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) diff --git a/include/libs/cimgui/cimgui.h b/include/libs/cimgui/cimgui.h new file mode 100644 index 0000000..6741441 --- /dev/null +++ b/include/libs/cimgui/cimgui.h @@ -0,0 +1,5230 @@ +//This file is automatically generated by generator.lua from https://github.com/cimgui/cimgui +//based on imgui.h file version "1.92.9 WIP" 19284 from Dear ImGui https://github.com/ocornut/imgui +//with imgui_internal.h api +//with imgui_freetype.h api +#ifndef CIMGUI_INCLUDED +#define CIMGUI_INCLUDED +#include +#include +#if defined _WIN32 || defined __CYGWIN__ + #ifdef CIMGUI_NO_EXPORT + #define API + #else + #define API __declspec(dllexport) + #endif +#else + #ifdef __GNUC__ + #define API __attribute__((__visibility__("default"))) + #else + #define API + #endif +#endif + +#if defined __cplusplus + #define EXTERN extern "C" +#else + #include + #include + #define EXTERN extern +#endif + +#define CIMGUI_API EXTERN API +#define CONST const + + +#ifdef _MSC_VER +typedef unsigned __int64 ImU64; +#else +//typedef unsigned long long ImU64; +#endif + +#ifndef CIMGUI_DEFINE_ENUMS_AND_STRUCTS +#ifdef IMGUI_ENABLE_FREETYPE +#include "./imgui/misc/freetype/imgui_freetype.h" +#endif +#endif + + +#ifdef CIMGUI_DEFINE_ENUMS_AND_STRUCTS + +typedef struct ImDrawChannel ImDrawChannel; +typedef struct ImDrawCmd ImDrawCmd; +typedef struct ImDrawData ImDrawData; +typedef struct ImDrawList ImDrawList; +typedef struct ImDrawListSharedData ImDrawListSharedData; +typedef struct ImDrawListSplitter ImDrawListSplitter; +typedef struct ImDrawVert ImDrawVert; +typedef struct ImFont ImFont; +typedef struct ImFontAtlas ImFontAtlas; +typedef struct ImFontAtlasBuilder ImFontAtlasBuilder; +typedef struct ImFontAtlasRect ImFontAtlasRect; +typedef struct ImFontBaked ImFontBaked; +typedef struct ImFontConfig ImFontConfig; +typedef struct ImFontGlyph ImFontGlyph; +typedef struct ImFontGlyphRangesBuilder ImFontGlyphRangesBuilder; +typedef struct ImFontLoader ImFontLoader; +typedef struct ImTextureData ImTextureData; +typedef struct ImTextureRect ImTextureRect; +typedef struct ImColor_c ImColor_c; +typedef struct ImGuiContext ImGuiContext; +typedef struct ImGuiIO ImGuiIO; +typedef struct ImGuiInputTextCallbackData ImGuiInputTextCallbackData; +typedef struct ImGuiKeyData ImGuiKeyData; +typedef struct ImGuiListClipper ImGuiListClipper; +typedef struct ImGuiMultiSelectIO ImGuiMultiSelectIO; +typedef struct ImGuiOnceUponAFrame ImGuiOnceUponAFrame; +typedef struct ImGuiPayload ImGuiPayload; +typedef struct ImGuiPlatformIO ImGuiPlatformIO; +typedef struct ImGuiPlatformImeData ImGuiPlatformImeData; +typedef struct ImGuiSelectionBasicStorage ImGuiSelectionBasicStorage; +typedef struct ImGuiSelectionExternalStorage ImGuiSelectionExternalStorage; +typedef struct ImGuiSelectionRequest ImGuiSelectionRequest; +typedef struct ImGuiSizeCallbackData ImGuiSizeCallbackData; +typedef struct ImGuiStorage ImGuiStorage; +typedef struct ImGuiStoragePair ImGuiStoragePair; +typedef struct ImGuiStyle ImGuiStyle; +typedef struct ImGuiTableSortSpecs ImGuiTableSortSpecs; +typedef struct ImGuiTableColumnSortSpecs ImGuiTableColumnSortSpecs; +typedef struct ImGuiTextBuffer ImGuiTextBuffer; +typedef struct ImGuiTextFilter ImGuiTextFilter; +typedef struct ImGuiViewport ImGuiViewport; +typedef struct ImBitVector ImBitVector; +typedef struct ImRect_c ImRect_c; +typedef struct ImGuiTextIndex ImGuiTextIndex; +typedef struct ImDrawDataBuilder ImDrawDataBuilder; +typedef struct ImFontAtlasPostProcessData ImFontAtlasPostProcessData; +typedef struct ImFontAtlasRectEntry ImFontAtlasRectEntry; +typedef struct ImGuiBoxSelectState ImGuiBoxSelectState; +typedef struct ImGuiColorMod ImGuiColorMod; +typedef struct ImGuiContextHook ImGuiContextHook; +typedef struct ImGuiDataTypeInfo ImGuiDataTypeInfo; +typedef struct ImGuiDeactivatedItemData ImGuiDeactivatedItemData; +typedef struct ImGuiErrorRecoveryState ImGuiErrorRecoveryState; +typedef struct ImGuiGroupData ImGuiGroupData; +typedef struct ImGuiInputTextState ImGuiInputTextState; +typedef struct ImGuiInputTextDeactivateData ImGuiInputTextDeactivateData; +typedef struct ImGuiLastItemData ImGuiLastItemData; +typedef struct ImGuiLocEntry ImGuiLocEntry; +typedef struct ImGuiMenuColumns ImGuiMenuColumns; +typedef struct ImGuiMultiSelectState ImGuiMultiSelectState; +typedef struct ImGuiMultiSelectTempData ImGuiMultiSelectTempData; +typedef struct ImGuiNavItemData ImGuiNavItemData; +typedef struct ImGuiMetricsConfig ImGuiMetricsConfig; +typedef struct ImGuiNextWindowData ImGuiNextWindowData; +typedef struct ImGuiNextItemData ImGuiNextItemData; +typedef struct ImGuiOldColumnData ImGuiOldColumnData; +typedef struct ImGuiOldColumns ImGuiOldColumns; +typedef struct ImGuiPopupData ImGuiPopupData; +typedef struct ImGuiSettingsHandler ImGuiSettingsHandler; +typedef struct ImGuiStyleMod ImGuiStyleMod; +typedef struct ImGuiStyleVarInfo ImGuiStyleVarInfo; +typedef struct ImGuiTabBar ImGuiTabBar; +typedef struct ImGuiTabItem ImGuiTabItem; +typedef struct ImGuiTable ImGuiTable; +typedef struct ImGuiTableHeaderData ImGuiTableHeaderData; +typedef struct ImGuiTableColumn ImGuiTableColumn; +typedef struct ImGuiTableInstanceData ImGuiTableInstanceData; +typedef struct ImGuiTableTempData ImGuiTableTempData; +typedef struct ImGuiTableSettings ImGuiTableSettings; +typedef struct ImGuiTableColumnsSettings ImGuiTableColumnsSettings; +typedef struct ImGuiTreeNodeStackData ImGuiTreeNodeStackData; +typedef struct ImGuiTypingSelectState ImGuiTypingSelectState; +typedef struct ImGuiTypingSelectRequest ImGuiTypingSelectRequest; +typedef struct ImGuiWindow ImGuiWindow; +typedef struct ImGuiWindowTempData ImGuiWindowTempData; +typedef struct ImGuiWindowSettings ImGuiWindowSettings; +typedef struct STB_TexteditState STB_TexteditState; +typedef struct stbrp_node stbrp_node; +typedef unsigned int ImGuiID; +typedef signed char ImS8; +typedef unsigned char ImU8; +typedef signed short ImS16; +typedef unsigned short ImU16; +typedef signed int ImS32; +typedef unsigned int ImU32; +typedef signed long long ImS64; +typedef unsigned long long ImU64; +struct ImDrawChannel; +struct ImDrawCmd; +struct ImDrawData; +struct ImDrawList; +struct ImDrawListSharedData; +struct ImDrawListSplitter; +struct ImDrawVert; +struct ImFont; +struct ImFontAtlas; +struct ImFontAtlasBuilder; +struct ImFontAtlasRect; +struct ImFontBaked; +struct ImFontConfig; +struct ImFontGlyph; +struct ImFontGlyphRangesBuilder; +struct ImFontLoader; +struct ImTextureData; +struct ImTextureRect; +struct ImColor_c; +struct ImGuiContext; +struct ImGuiIO; +struct ImGuiInputTextCallbackData; +struct ImGuiKeyData; +struct ImGuiListClipper; +struct ImGuiMultiSelectIO; +struct ImGuiOnceUponAFrame; +struct ImGuiPayload; +struct ImGuiPlatformIO; +struct ImGuiPlatformImeData; +struct ImGuiSelectionBasicStorage; +struct ImGuiSelectionExternalStorage; +struct ImGuiSelectionRequest; +struct ImGuiSizeCallbackData; +struct ImGuiStorage; +struct ImGuiStoragePair; +struct ImGuiStyle; +struct ImGuiTableSortSpecs; +struct ImGuiTableColumnSortSpecs; +struct ImGuiTextBuffer; +struct ImGuiTextFilter; +struct ImGuiViewport; +typedef int ImGuiCol; +typedef int ImGuiCond; +typedef int ImGuiDataType; +typedef int ImGuiMouseButton; +typedef int ImGuiMouseCursor; +typedef int ImGuiStyleVar; +typedef int ImGuiTableBgTarget; +typedef int ImDrawFlags; +typedef int ImDrawListFlags; +typedef int ImDrawTextFlags; +typedef int ImFontFlags; +typedef int ImFontAtlasFlags; +typedef int ImGuiBackendFlags; +typedef int ImGuiButtonFlags; +typedef int ImGuiChildFlags; +typedef int ImGuiColorEditFlags; +typedef int ImGuiConfigFlags; +typedef int ImGuiComboFlags; +typedef int ImGuiDragDropFlags; +typedef int ImGuiFocusedFlags; +typedef int ImGuiHoveredFlags; +typedef int ImGuiInputFlags; +typedef int ImGuiInputTextFlags; +typedef int ImGuiItemFlags; +typedef int ImGuiKeyChord; +typedef int ImGuiListClipperFlags; +typedef int ImGuiPopupFlags; +typedef int ImGuiMultiSelectFlags; +typedef int ImGuiSelectableFlags; +typedef int ImGuiSliderFlags; +typedef int ImGuiTabBarFlags; +typedef int ImGuiTabItemFlags; +typedef int ImGuiTableFlags; +typedef int ImGuiTableColumnFlags; +typedef int ImGuiTableRowFlags; +typedef int ImGuiTreeNodeFlags; +typedef int ImGuiViewportFlags; +typedef int ImGuiWindowFlags; +typedef unsigned int ImWchar32; +typedef unsigned short ImWchar16; + +#ifdef IMGUI_USE_WCHAR32 +typedef ImWchar32 ImWchar; +#else +typedef ImWchar16 ImWchar; +#endif +#ifdef IMGUI_USE_WCHAR32 +#define IM_UNICODE_CODEPOINT_MAX 0x10FFFF +#else +#define IM_UNICODE_CODEPOINT_MAX 0xFFFF +#endif + +typedef ImS64 ImGuiSelectionUserData; +typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData* data); +typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); +typedef void* (*ImGuiMemAllocFunc)(size_t sz, void* user_data); +typedef void (*ImGuiMemFreeFunc)(void* ptr, void* user_data); +typedef struct ImVec2_c ImVec2_c; +struct ImVec2_c +{ + float x, y; +}; +typedef struct ImVec4_c ImVec4_c; +struct ImVec4_c +{ + float x, y, z, w; +}; +typedef ImU64 ImTextureID; +typedef struct ImTextureRef_c ImTextureRef_c; +struct ImTextureRef_c +{ + ImTextureData* _TexData; + ImTextureID _TexID; +}; +typedef enum { + ImGuiWindowFlags_None = 0, + ImGuiWindowFlags_NoTitleBar = 1 << 0, + ImGuiWindowFlags_NoResize = 1 << 1, + ImGuiWindowFlags_NoMove = 1 << 2, + ImGuiWindowFlags_NoScrollbar = 1 << 3, + ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, + ImGuiWindowFlags_NoCollapse = 1 << 5, + ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, + ImGuiWindowFlags_NoBackground = 1 << 7, + ImGuiWindowFlags_NoSavedSettings = 1 << 8, + ImGuiWindowFlags_NoMouseInputs = 1 << 9, + ImGuiWindowFlags_MenuBar = 1 << 10, + ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, + ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12, + ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, + ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, + ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, + ImGuiWindowFlags_NoNavInputs = 1 << 16, + ImGuiWindowFlags_NoNavFocus = 1 << 17, + ImGuiWindowFlags_UnsavedDocument = 1 << 18, + ImGuiWindowFlags_NoNav = ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus, + ImGuiWindowFlags_NoDecoration = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse, + ImGuiWindowFlags_NoInputs = ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus, + ImGuiWindowFlags_ChildWindow = 1 << 24, + ImGuiWindowFlags_Tooltip = 1 << 25, + ImGuiWindowFlags_Popup = 1 << 26, + ImGuiWindowFlags_Modal = 1 << 27, + ImGuiWindowFlags_ChildMenu = 1 << 28, +}ImGuiWindowFlags_; +typedef enum { + ImGuiChildFlags_None = 0, + ImGuiChildFlags_Borders = 1 << 0, + ImGuiChildFlags_AlwaysUseWindowPadding = 1 << 1, + ImGuiChildFlags_ResizeX = 1 << 2, + ImGuiChildFlags_ResizeY = 1 << 3, + ImGuiChildFlags_AutoResizeX = 1 << 4, + ImGuiChildFlags_AutoResizeY = 1 << 5, + ImGuiChildFlags_AlwaysAutoResize = 1 << 6, + ImGuiChildFlags_FrameStyle = 1 << 7, + ImGuiChildFlags_NavFlattened = 1 << 8, +}ImGuiChildFlags_; +typedef enum { + ImGuiItemFlags_None = 0, + ImGuiItemFlags_NoTabStop = 1 << 0, + ImGuiItemFlags_NoNav = 1 << 1, + ImGuiItemFlags_NoNavDefaultFocus = 1 << 2, + ImGuiItemFlags_ButtonRepeat = 1 << 3, + ImGuiItemFlags_AutoClosePopups = 1 << 4, + ImGuiItemFlags_AllowDuplicateId = 1 << 5, + ImGuiItemFlags_Disabled = 1 << 6, +}ImGuiItemFlags_; +typedef enum { + ImGuiInputTextFlags_None = 0, + ImGuiInputTextFlags_CharsDecimal = 1 << 0, + ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, + ImGuiInputTextFlags_CharsScientific = 1 << 2, + ImGuiInputTextFlags_CharsUppercase = 1 << 3, + ImGuiInputTextFlags_CharsNoBlank = 1 << 4, + ImGuiInputTextFlags_AllowTabInput = 1 << 5, + ImGuiInputTextFlags_EnterReturnsTrue = 1 << 6, + ImGuiInputTextFlags_EscapeClearsAll = 1 << 7, + ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 8, + ImGuiInputTextFlags_ReadOnly = 1 << 9, + ImGuiInputTextFlags_Password = 1 << 10, + ImGuiInputTextFlags_AlwaysOverwrite = 1 << 11, + ImGuiInputTextFlags_AutoSelectAll = 1 << 12, + ImGuiInputTextFlags_ParseEmptyRefVal = 1 << 13, + ImGuiInputTextFlags_DisplayEmptyRefVal = 1 << 14, + ImGuiInputTextFlags_NoHorizontalScroll = 1 << 15, + ImGuiInputTextFlags_NoUndoRedo = 1 << 16, + ImGuiInputTextFlags_ElideLeft = 1 << 17, + ImGuiInputTextFlags_CallbackCompletion = 1 << 18, + ImGuiInputTextFlags_CallbackHistory = 1 << 19, + ImGuiInputTextFlags_CallbackAlways = 1 << 20, + ImGuiInputTextFlags_CallbackCharFilter = 1 << 21, + ImGuiInputTextFlags_CallbackResize = 1 << 22, + ImGuiInputTextFlags_CallbackEdit = 1 << 23, + ImGuiInputTextFlags_WordWrap = 1 << 24, +}ImGuiInputTextFlags_; +typedef enum { + ImGuiTreeNodeFlags_None = 0, + ImGuiTreeNodeFlags_Selected = 1 << 0, + ImGuiTreeNodeFlags_Framed = 1 << 1, + ImGuiTreeNodeFlags_AllowOverlap = 1 << 2, + ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, + ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, + ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, + ImGuiTreeNodeFlags_OpenOnDoubleClick = 1 << 6, + ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, + ImGuiTreeNodeFlags_Leaf = 1 << 8, + ImGuiTreeNodeFlags_Bullet = 1 << 9, + ImGuiTreeNodeFlags_FramePadding = 1 << 10, + ImGuiTreeNodeFlags_SpanAvailWidth = 1 << 11, + ImGuiTreeNodeFlags_SpanFullWidth = 1 << 12, + ImGuiTreeNodeFlags_SpanLabelWidth = 1 << 13, + ImGuiTreeNodeFlags_SpanAllColumns = 1 << 14, + ImGuiTreeNodeFlags_LabelSpanAllColumns = 1 << 15, + ImGuiTreeNodeFlags_NavLeftJumpsToParent = 1 << 17, + ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog, + ImGuiTreeNodeFlags_DrawLinesNone = 1 << 18, + ImGuiTreeNodeFlags_DrawLinesFull = 1 << 19, + ImGuiTreeNodeFlags_DrawLinesToNodes = 1 << 20, +}ImGuiTreeNodeFlags_; +typedef enum { + ImGuiPopupFlags_None = 0, + ImGuiPopupFlags_MouseButtonLeft = 1 << 2, + ImGuiPopupFlags_MouseButtonRight = 2 << 2, + ImGuiPopupFlags_MouseButtonMiddle = 3 << 2, + ImGuiPopupFlags_NoReopen = 1 << 5, + ImGuiPopupFlags_NoOpenOverExistingPopup = 1 << 7, + ImGuiPopupFlags_NoOpenOverItems = 1 << 8, + ImGuiPopupFlags_AnyPopupId = 1 << 10, + ImGuiPopupFlags_AnyPopupLevel = 1 << 11, + ImGuiPopupFlags_AnyPopup = ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel, + ImGuiPopupFlags_MouseButtonShift_ = 2, + ImGuiPopupFlags_MouseButtonMask_ = 0x0C, + ImGuiPopupFlags_InvalidMask_ = 0x03, +}ImGuiPopupFlags_; +typedef enum { + ImGuiSelectableFlags_None = 0, + ImGuiSelectableFlags_NoAutoClosePopups = 1 << 0, + ImGuiSelectableFlags_SpanAllColumns = 1 << 1, + ImGuiSelectableFlags_AllowDoubleClick = 1 << 2, + ImGuiSelectableFlags_Disabled = 1 << 3, + ImGuiSelectableFlags_AllowOverlap = 1 << 4, + ImGuiSelectableFlags_Highlight = 1 << 5, + ImGuiSelectableFlags_SelectOnNav = 1 << 6, +}ImGuiSelectableFlags_; +typedef enum { + ImGuiComboFlags_None = 0, + ImGuiComboFlags_PopupAlignLeft = 1 << 0, + ImGuiComboFlags_HeightSmall = 1 << 1, + ImGuiComboFlags_HeightRegular = 1 << 2, + ImGuiComboFlags_HeightLarge = 1 << 3, + ImGuiComboFlags_HeightLargest = 1 << 4, + ImGuiComboFlags_NoArrowButton = 1 << 5, + ImGuiComboFlags_NoPreview = 1 << 6, + ImGuiComboFlags_WidthFitPreview = 1 << 7, + ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest, +}ImGuiComboFlags_; +typedef enum { + ImGuiTabBarFlags_None = 0, + ImGuiTabBarFlags_Reorderable = 1 << 0, + ImGuiTabBarFlags_AutoSelectNewTabs = 1 << 1, + ImGuiTabBarFlags_TabListPopupButton = 1 << 2, + ImGuiTabBarFlags_NoCloseWithMiddleMouseButton = 1 << 3, + ImGuiTabBarFlags_NoTabListScrollingButtons = 1 << 4, + ImGuiTabBarFlags_NoTooltip = 1 << 5, + ImGuiTabBarFlags_DrawSelectedOverline = 1 << 6, + ImGuiTabBarFlags_FittingPolicyMixed = 1 << 7, + ImGuiTabBarFlags_FittingPolicyShrink = 1 << 8, + ImGuiTabBarFlags_FittingPolicyScroll = 1 << 9, + ImGuiTabBarFlags_FittingPolicyMask_ = ImGuiTabBarFlags_FittingPolicyMixed | ImGuiTabBarFlags_FittingPolicyShrink | ImGuiTabBarFlags_FittingPolicyScroll, + ImGuiTabBarFlags_FittingPolicyDefault_ = ImGuiTabBarFlags_FittingPolicyMixed, +}ImGuiTabBarFlags_; +typedef enum { + ImGuiTabItemFlags_None = 0, + ImGuiTabItemFlags_UnsavedDocument = 1 << 0, + ImGuiTabItemFlags_SetSelected = 1 << 1, + ImGuiTabItemFlags_NoCloseWithMiddleMouseButton = 1 << 2, + ImGuiTabItemFlags_NoPushId = 1 << 3, + ImGuiTabItemFlags_NoTooltip = 1 << 4, + ImGuiTabItemFlags_NoReorder = 1 << 5, + ImGuiTabItemFlags_Leading = 1 << 6, + ImGuiTabItemFlags_Trailing = 1 << 7, + ImGuiTabItemFlags_NoAssumedClosure = 1 << 8, +}ImGuiTabItemFlags_; +typedef enum { + ImGuiFocusedFlags_None = 0, + ImGuiFocusedFlags_ChildWindows = 1 << 0, + ImGuiFocusedFlags_RootWindow = 1 << 1, + ImGuiFocusedFlags_AnyWindow = 1 << 2, + ImGuiFocusedFlags_NoPopupHierarchy = 1 << 3, + ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows, +}ImGuiFocusedFlags_; +typedef enum { + ImGuiHoveredFlags_None = 0, + ImGuiHoveredFlags_ChildWindows = 1 << 0, + ImGuiHoveredFlags_RootWindow = 1 << 1, + ImGuiHoveredFlags_AnyWindow = 1 << 2, + ImGuiHoveredFlags_NoPopupHierarchy = 1 << 3, + ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 5, + ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 7, + ImGuiHoveredFlags_AllowWhenOverlappedByItem = 1 << 8, + ImGuiHoveredFlags_AllowWhenOverlappedByWindow = 1 << 9, + ImGuiHoveredFlags_AllowWhenDisabled = 1 << 10, + ImGuiHoveredFlags_NoNavOverride = 1 << 11, + ImGuiHoveredFlags_AllowWhenOverlapped = ImGuiHoveredFlags_AllowWhenOverlappedByItem | ImGuiHoveredFlags_AllowWhenOverlappedByWindow, + ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped, + ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows, + ImGuiHoveredFlags_ForTooltip = 1 << 12, + ImGuiHoveredFlags_Stationary = 1 << 13, + ImGuiHoveredFlags_DelayNone = 1 << 14, + ImGuiHoveredFlags_DelayShort = 1 << 15, + ImGuiHoveredFlags_DelayNormal = 1 << 16, + ImGuiHoveredFlags_NoSharedDelay = 1 << 17, +}ImGuiHoveredFlags_; +typedef enum { + ImGuiDragDropFlags_None = 0, + ImGuiDragDropFlags_SourceNoPreviewTooltip = 1 << 0, + ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, + ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, + ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, + ImGuiDragDropFlags_SourceExtern = 1 << 4, + ImGuiDragDropFlags_PayloadAutoExpire = 1 << 5, + ImGuiDragDropFlags_PayloadNoCrossContext = 1 << 6, + ImGuiDragDropFlags_PayloadNoCrossProcess = 1 << 7, + ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, + ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, + ImGuiDragDropFlags_AcceptNoPreviewTooltip = 1 << 12, + ImGuiDragDropFlags_AcceptDrawAsHovered = 1 << 13, + ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect, +}ImGuiDragDropFlags_; +typedef enum { + ImGuiDataType_S8, + ImGuiDataType_U8, + ImGuiDataType_S16, + ImGuiDataType_U16, + ImGuiDataType_S32, + ImGuiDataType_U32, + ImGuiDataType_S64, + ImGuiDataType_U64, + ImGuiDataType_Float, + ImGuiDataType_Double, + ImGuiDataType_Bool, + ImGuiDataType_String, + ImGuiDataType_COUNT +}ImGuiDataType_; +typedef enum { +ImGuiDir_None=-1, +ImGuiDir_Left=0, +ImGuiDir_Right=1, +ImGuiDir_Up=2, +ImGuiDir_Down=3, +ImGuiDir_COUNT=4, +}ImGuiDir; +typedef enum { +ImGuiSortDirection_None=0, +ImGuiSortDirection_Ascending=1, +ImGuiSortDirection_Descending=2, +}ImGuiSortDirection; +typedef enum { +ImGuiKey_None=0, +ImGuiKey_NamedKey_BEGIN=512, +ImGuiKey_Tab=512, +ImGuiKey_LeftArrow=513, +ImGuiKey_RightArrow=514, +ImGuiKey_UpArrow=515, +ImGuiKey_DownArrow=516, +ImGuiKey_PageUp=517, +ImGuiKey_PageDown=518, +ImGuiKey_Home=519, +ImGuiKey_End=520, +ImGuiKey_Insert=521, +ImGuiKey_Delete=522, +ImGuiKey_Backspace=523, +ImGuiKey_Space=524, +ImGuiKey_Enter=525, +ImGuiKey_Escape=526, +ImGuiKey_LeftCtrl=527, +ImGuiKey_LeftShift=528, +ImGuiKey_LeftAlt=529, +ImGuiKey_LeftSuper=530, +ImGuiKey_RightCtrl=531, +ImGuiKey_RightShift=532, +ImGuiKey_RightAlt=533, +ImGuiKey_RightSuper=534, +ImGuiKey_Menu=535, +ImGuiKey_0=536, +ImGuiKey_1=537, +ImGuiKey_2=538, +ImGuiKey_3=539, +ImGuiKey_4=540, +ImGuiKey_5=541, +ImGuiKey_6=542, +ImGuiKey_7=543, +ImGuiKey_8=544, +ImGuiKey_9=545, +ImGuiKey_A=546, +ImGuiKey_B=547, +ImGuiKey_C=548, +ImGuiKey_D=549, +ImGuiKey_E=550, +ImGuiKey_F=551, +ImGuiKey_G=552, +ImGuiKey_H=553, +ImGuiKey_I=554, +ImGuiKey_J=555, +ImGuiKey_K=556, +ImGuiKey_L=557, +ImGuiKey_M=558, +ImGuiKey_N=559, +ImGuiKey_O=560, +ImGuiKey_P=561, +ImGuiKey_Q=562, +ImGuiKey_R=563, +ImGuiKey_S=564, +ImGuiKey_T=565, +ImGuiKey_U=566, +ImGuiKey_V=567, +ImGuiKey_W=568, +ImGuiKey_X=569, +ImGuiKey_Y=570, +ImGuiKey_Z=571, +ImGuiKey_F1=572, +ImGuiKey_F2=573, +ImGuiKey_F3=574, +ImGuiKey_F4=575, +ImGuiKey_F5=576, +ImGuiKey_F6=577, +ImGuiKey_F7=578, +ImGuiKey_F8=579, +ImGuiKey_F9=580, +ImGuiKey_F10=581, +ImGuiKey_F11=582, +ImGuiKey_F12=583, +ImGuiKey_F13=584, +ImGuiKey_F14=585, +ImGuiKey_F15=586, +ImGuiKey_F16=587, +ImGuiKey_F17=588, +ImGuiKey_F18=589, +ImGuiKey_F19=590, +ImGuiKey_F20=591, +ImGuiKey_F21=592, +ImGuiKey_F22=593, +ImGuiKey_F23=594, +ImGuiKey_F24=595, +ImGuiKey_Apostrophe=596, +ImGuiKey_Comma=597, +ImGuiKey_Minus=598, +ImGuiKey_Period=599, +ImGuiKey_Slash=600, +ImGuiKey_Semicolon=601, +ImGuiKey_Equal=602, +ImGuiKey_LeftBracket=603, +ImGuiKey_Backslash=604, +ImGuiKey_RightBracket=605, +ImGuiKey_GraveAccent=606, +ImGuiKey_CapsLock=607, +ImGuiKey_ScrollLock=608, +ImGuiKey_NumLock=609, +ImGuiKey_PrintScreen=610, +ImGuiKey_Pause=611, +ImGuiKey_Keypad0=612, +ImGuiKey_Keypad1=613, +ImGuiKey_Keypad2=614, +ImGuiKey_Keypad3=615, +ImGuiKey_Keypad4=616, +ImGuiKey_Keypad5=617, +ImGuiKey_Keypad6=618, +ImGuiKey_Keypad7=619, +ImGuiKey_Keypad8=620, +ImGuiKey_Keypad9=621, +ImGuiKey_KeypadDecimal=622, +ImGuiKey_KeypadDivide=623, +ImGuiKey_KeypadMultiply=624, +ImGuiKey_KeypadSubtract=625, +ImGuiKey_KeypadAdd=626, +ImGuiKey_KeypadEnter=627, +ImGuiKey_KeypadEqual=628, +ImGuiKey_AppBack=629, +ImGuiKey_AppForward=630, +ImGuiKey_Oem102=631, +ImGuiKey_GamepadStart=632, +ImGuiKey_GamepadBack=633, +ImGuiKey_GamepadFaceLeft=634, +ImGuiKey_GamepadFaceRight=635, +ImGuiKey_GamepadFaceUp=636, +ImGuiKey_GamepadFaceDown=637, +ImGuiKey_GamepadDpadLeft=638, +ImGuiKey_GamepadDpadRight=639, +ImGuiKey_GamepadDpadUp=640, +ImGuiKey_GamepadDpadDown=641, +ImGuiKey_GamepadL1=642, +ImGuiKey_GamepadR1=643, +ImGuiKey_GamepadL2=644, +ImGuiKey_GamepadR2=645, +ImGuiKey_GamepadL3=646, +ImGuiKey_GamepadR3=647, +ImGuiKey_GamepadLStickLeft=648, +ImGuiKey_GamepadLStickRight=649, +ImGuiKey_GamepadLStickUp=650, +ImGuiKey_GamepadLStickDown=651, +ImGuiKey_GamepadRStickLeft=652, +ImGuiKey_GamepadRStickRight=653, +ImGuiKey_GamepadRStickUp=654, +ImGuiKey_GamepadRStickDown=655, +ImGuiKey_MouseLeft=656, +ImGuiKey_MouseRight=657, +ImGuiKey_MouseMiddle=658, +ImGuiKey_MouseX1=659, +ImGuiKey_MouseX2=660, +ImGuiKey_MouseWheelX=661, +ImGuiKey_MouseWheelY=662, +ImGuiKey_ReservedForModCtrl=663, +ImGuiKey_ReservedForModShift=664, +ImGuiKey_ReservedForModAlt=665, +ImGuiKey_ReservedForModSuper=666, +ImGuiKey_NamedKey_END=667, +ImGuiKey_NamedKey_COUNT=ImGuiKey_NamedKey_END - ImGuiKey_NamedKey_BEGIN, +ImGuiMod_None=0, +ImGuiMod_Ctrl=1 << 12, +ImGuiMod_Shift=1 << 13, +ImGuiMod_Alt=1 << 14, +ImGuiMod_Super=1 << 15, +ImGuiMod_Mask_=0xF000, +}ImGuiKey; +typedef enum { + ImGuiInputFlags_None = 0, + ImGuiInputFlags_Repeat = 1 << 0, + ImGuiInputFlags_RouteActive = 1 << 10, + ImGuiInputFlags_RouteFocused = 1 << 11, + ImGuiInputFlags_RouteGlobal = 1 << 12, + ImGuiInputFlags_RouteAlways = 1 << 13, + ImGuiInputFlags_RouteOverFocused = 1 << 14, + ImGuiInputFlags_RouteOverActive = 1 << 15, + ImGuiInputFlags_RouteUnlessBgFocused = 1 << 16, + ImGuiInputFlags_RouteFromRootWindow = 1 << 17, + ImGuiInputFlags_Tooltip = 1 << 18, +}ImGuiInputFlags_; +typedef enum { + ImGuiConfigFlags_None = 0, + ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, + ImGuiConfigFlags_NavEnableGamepad = 1 << 1, + ImGuiConfigFlags_NoMouse = 1 << 4, + ImGuiConfigFlags_NoMouseCursorChange = 1 << 5, + ImGuiConfigFlags_NoKeyboard = 1 << 6, + ImGuiConfigFlags_IsSRGB = 1 << 20, + ImGuiConfigFlags_IsTouchScreen = 1 << 21, +}ImGuiConfigFlags_; +typedef enum { + ImGuiBackendFlags_None = 0, + ImGuiBackendFlags_HasGamepad = 1 << 0, + ImGuiBackendFlags_HasMouseCursors = 1 << 1, + ImGuiBackendFlags_HasSetMousePos = 1 << 2, + ImGuiBackendFlags_RendererHasVtxOffset = 1 << 3, + ImGuiBackendFlags_RendererHasTextures = 1 << 4, +}ImGuiBackendFlags_; +typedef enum { + ImGuiCol_Text, + ImGuiCol_TextDisabled, + ImGuiCol_WindowBg, + ImGuiCol_ChildBg, + ImGuiCol_PopupBg, + ImGuiCol_Border, + ImGuiCol_BorderShadow, + ImGuiCol_FrameBg, + ImGuiCol_FrameBgHovered, + ImGuiCol_FrameBgActive, + ImGuiCol_TitleBg, + ImGuiCol_TitleBgActive, + ImGuiCol_TitleBgCollapsed, + ImGuiCol_MenuBarBg, + ImGuiCol_ScrollbarBg, + ImGuiCol_ScrollbarGrab, + ImGuiCol_ScrollbarGrabHovered, + ImGuiCol_ScrollbarGrabActive, + ImGuiCol_CheckMark, + ImGuiCol_CheckboxSelectedBg, + ImGuiCol_SliderGrab, + ImGuiCol_SliderGrabActive, + ImGuiCol_Button, + ImGuiCol_ButtonHovered, + ImGuiCol_ButtonActive, + ImGuiCol_Header, + ImGuiCol_HeaderHovered, + ImGuiCol_HeaderActive, + ImGuiCol_Separator, + ImGuiCol_SeparatorHovered, + ImGuiCol_SeparatorActive, + ImGuiCol_ResizeGrip, + ImGuiCol_ResizeGripHovered, + ImGuiCol_ResizeGripActive, + ImGuiCol_InputTextCursor, + ImGuiCol_TabHovered, + ImGuiCol_Tab, + ImGuiCol_TabSelected, + ImGuiCol_TabSelectedOverline, + ImGuiCol_TabDimmed, + ImGuiCol_TabDimmedSelected, + ImGuiCol_TabDimmedSelectedOverline, + ImGuiCol_PlotLines, + ImGuiCol_PlotLinesHovered, + ImGuiCol_PlotHistogram, + ImGuiCol_PlotHistogramHovered, + ImGuiCol_TableHeaderBg, + ImGuiCol_TableBorderStrong, + ImGuiCol_TableBorderLight, + ImGuiCol_TableRowBg, + ImGuiCol_TableRowBgAlt, + ImGuiCol_TextLink, + ImGuiCol_TextSelectedBg, + ImGuiCol_TreeLines, + ImGuiCol_DragDropTarget, + ImGuiCol_DragDropTargetBg, + ImGuiCol_UnsavedMarker, + ImGuiCol_NavCursor, + ImGuiCol_NavWindowingHighlight, + ImGuiCol_NavWindowingDimBg, + ImGuiCol_ModalWindowDimBg, + ImGuiCol_COUNT, +}ImGuiCol_; +typedef enum { + ImGuiStyleVar_Alpha, + ImGuiStyleVar_DisabledAlpha, + ImGuiStyleVar_WindowPadding, + ImGuiStyleVar_WindowRounding, + ImGuiStyleVar_WindowBorderSize, + ImGuiStyleVar_WindowMinSize, + ImGuiStyleVar_WindowTitleAlign, + ImGuiStyleVar_ChildRounding, + ImGuiStyleVar_ChildBorderSize, + ImGuiStyleVar_PopupRounding, + ImGuiStyleVar_PopupBorderSize, + ImGuiStyleVar_FramePadding, + ImGuiStyleVar_FrameRounding, + ImGuiStyleVar_FrameBorderSize, + ImGuiStyleVar_ItemSpacing, + ImGuiStyleVar_ItemInnerSpacing, + ImGuiStyleVar_IndentSpacing, + ImGuiStyleVar_CellPadding, + ImGuiStyleVar_ScrollbarSize, + ImGuiStyleVar_ScrollbarRounding, + ImGuiStyleVar_ScrollbarPadding, + ImGuiStyleVar_GrabMinSize, + ImGuiStyleVar_GrabRounding, + ImGuiStyleVar_ImageRounding, + ImGuiStyleVar_ImageBorderSize, + ImGuiStyleVar_TabRounding, + ImGuiStyleVar_TabBorderSize, + ImGuiStyleVar_TabMinWidthBase, + ImGuiStyleVar_TabMinWidthShrink, + ImGuiStyleVar_TabBarBorderSize, + ImGuiStyleVar_TabBarOverlineSize, + ImGuiStyleVar_TableAngledHeadersAngle, + ImGuiStyleVar_TableAngledHeadersTextAlign, + ImGuiStyleVar_TreeLinesSize, + ImGuiStyleVar_TreeLinesRounding, + ImGuiStyleVar_DragDropTargetRounding, + ImGuiStyleVar_ButtonTextAlign, + ImGuiStyleVar_SelectableTextAlign, + ImGuiStyleVar_SeparatorSize, + ImGuiStyleVar_SeparatorTextBorderSize, + ImGuiStyleVar_SeparatorTextAlign, + ImGuiStyleVar_SeparatorTextPadding, + ImGuiStyleVar_COUNT +}ImGuiStyleVar_; +typedef enum { + ImGuiButtonFlags_None = 0, + ImGuiButtonFlags_MouseButtonLeft = 1 << 0, + ImGuiButtonFlags_MouseButtonRight = 1 << 1, + ImGuiButtonFlags_MouseButtonMiddle = 1 << 2, + ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle, + ImGuiButtonFlags_EnableNav = 1 << 3, + ImGuiButtonFlags_AllowOverlap = 1 << 12, +}ImGuiButtonFlags_; +typedef enum { + ImGuiColorEditFlags_None = 0, + ImGuiColorEditFlags_NoAlpha = 1 << 1, + ImGuiColorEditFlags_NoPicker = 1 << 2, + ImGuiColorEditFlags_NoOptions = 1 << 3, + ImGuiColorEditFlags_NoSmallPreview = 1 << 4, + ImGuiColorEditFlags_NoInputs = 1 << 5, + ImGuiColorEditFlags_NoTooltip = 1 << 6, + ImGuiColorEditFlags_NoLabel = 1 << 7, + ImGuiColorEditFlags_NoSidePreview = 1 << 8, + ImGuiColorEditFlags_NoDragDrop = 1 << 9, + ImGuiColorEditFlags_NoBorder = 1 << 10, + ImGuiColorEditFlags_NoColorMarkers = 1 << 11, + ImGuiColorEditFlags_AlphaOpaque = 1 << 12, + ImGuiColorEditFlags_AlphaNoBg = 1 << 13, + ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 14, + ImGuiColorEditFlags_AlphaBar = 1 << 18, + ImGuiColorEditFlags_HDR = 1 << 19, + ImGuiColorEditFlags_DisplayRGB = 1 << 20, + ImGuiColorEditFlags_DisplayHSV = 1 << 21, + ImGuiColorEditFlags_DisplayHex = 1 << 22, + ImGuiColorEditFlags_Uint8 = 1 << 23, + ImGuiColorEditFlags_Float = 1 << 24, + ImGuiColorEditFlags_PickerHueBar = 1 << 25, + ImGuiColorEditFlags_PickerHueWheel = 1 << 26, + ImGuiColorEditFlags_InputRGB = 1 << 27, + ImGuiColorEditFlags_InputHSV = 1 << 28, + ImGuiColorEditFlags_DefaultOptions_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_PickerHueBar, + ImGuiColorEditFlags_AlphaMask_ = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaOpaque | ImGuiColorEditFlags_AlphaNoBg | ImGuiColorEditFlags_AlphaPreviewHalf, + ImGuiColorEditFlags_DisplayMask_ = ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex, + ImGuiColorEditFlags_DataTypeMask_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_Float, + ImGuiColorEditFlags_PickerMask_ = ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_PickerHueBar, + ImGuiColorEditFlags_InputMask_ = ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_InputHSV, +}ImGuiColorEditFlags_; +typedef enum { + ImGuiSliderFlags_None = 0, + ImGuiSliderFlags_Logarithmic = 1 << 5, + ImGuiSliderFlags_NoRoundToFormat = 1 << 6, + ImGuiSliderFlags_NoInput = 1 << 7, + ImGuiSliderFlags_WrapAround = 1 << 8, + ImGuiSliderFlags_ClampOnInput = 1 << 9, + ImGuiSliderFlags_ClampZeroRange = 1 << 10, + ImGuiSliderFlags_NoSpeedTweaks = 1 << 11, + ImGuiSliderFlags_ColorMarkers = 1 << 12, + ImGuiSliderFlags_AlwaysClamp = ImGuiSliderFlags_ClampOnInput | ImGuiSliderFlags_ClampZeroRange, + ImGuiSliderFlags_InvalidMask_ = 0x7000000F, +}ImGuiSliderFlags_; +typedef enum { + ImGuiMouseButton_Left = 0, + ImGuiMouseButton_Right = 1, + ImGuiMouseButton_Middle = 2, + ImGuiMouseButton_COUNT = 5 +}ImGuiMouseButton_; +typedef enum { + ImGuiMouseCursor_None = -1, + ImGuiMouseCursor_Arrow = 0, + ImGuiMouseCursor_TextInput, + ImGuiMouseCursor_ResizeAll, + ImGuiMouseCursor_ResizeNS, + ImGuiMouseCursor_ResizeEW, + ImGuiMouseCursor_ResizeNESW, + ImGuiMouseCursor_ResizeNWSE, + ImGuiMouseCursor_Hand, + ImGuiMouseCursor_Wait, + ImGuiMouseCursor_Progress, + ImGuiMouseCursor_NotAllowed, + ImGuiMouseCursor_COUNT +}ImGuiMouseCursor_; +typedef enum { +ImGuiMouseSource_Mouse=0, +ImGuiMouseSource_TouchScreen=1, +ImGuiMouseSource_Pen=2, +ImGuiMouseSource_COUNT=3, +}ImGuiMouseSource; +typedef enum { + ImGuiCond_None = 0, + ImGuiCond_Always = 1 << 0, + ImGuiCond_Once = 1 << 1, + ImGuiCond_FirstUseEver = 1 << 2, + ImGuiCond_Appearing = 1 << 3, +}ImGuiCond_; +typedef enum { + ImGuiTableFlags_None = 0, + ImGuiTableFlags_Resizable = 1 << 0, + ImGuiTableFlags_Reorderable = 1 << 1, + ImGuiTableFlags_Hideable = 1 << 2, + ImGuiTableFlags_Sortable = 1 << 3, + ImGuiTableFlags_NoSavedSettings = 1 << 4, + ImGuiTableFlags_ContextMenuInBody = 1 << 5, + ImGuiTableFlags_RowBg = 1 << 6, + ImGuiTableFlags_BordersInnerH = 1 << 7, + ImGuiTableFlags_BordersOuterH = 1 << 8, + ImGuiTableFlags_BordersInnerV = 1 << 9, + ImGuiTableFlags_BordersOuterV = 1 << 10, + ImGuiTableFlags_BordersH = ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH, + ImGuiTableFlags_BordersV = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuterV, + ImGuiTableFlags_BordersInner = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersInnerH, + ImGuiTableFlags_BordersOuter = ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_BordersOuterH, + ImGuiTableFlags_Borders = ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter, + ImGuiTableFlags_NoBordersInBody = 1 << 11, + ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 12, + ImGuiTableFlags_SizingFixedFit = 1 << 13, + ImGuiTableFlags_SizingFixedSame = 2 << 13, + ImGuiTableFlags_SizingStretchProp = 3 << 13, + ImGuiTableFlags_SizingStretchSame = 4 << 13, + ImGuiTableFlags_NoHostExtendX = 1 << 16, + ImGuiTableFlags_NoHostExtendY = 1 << 17, + ImGuiTableFlags_NoKeepColumnsVisible = 1 << 18, + ImGuiTableFlags_PreciseWidths = 1 << 19, + ImGuiTableFlags_NoClip = 1 << 20, + ImGuiTableFlags_PadOuterX = 1 << 21, + ImGuiTableFlags_NoPadOuterX = 1 << 22, + ImGuiTableFlags_NoPadInnerX = 1 << 23, + ImGuiTableFlags_ScrollX = 1 << 24, + ImGuiTableFlags_ScrollY = 1 << 25, + ImGuiTableFlags_SortMulti = 1 << 26, + ImGuiTableFlags_SortTristate = 1 << 27, + ImGuiTableFlags_HighlightHoveredColumn = 1 << 28, + ImGuiTableFlags_SizingMask_ = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_SizingFixedSame | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_SizingStretchSame, +}ImGuiTableFlags_; +typedef enum { + ImGuiTableColumnFlags_None = 0, + ImGuiTableColumnFlags_Disabled = 1 << 0, + ImGuiTableColumnFlags_DefaultHide = 1 << 1, + ImGuiTableColumnFlags_DefaultSort = 1 << 2, + ImGuiTableColumnFlags_WidthStretch = 1 << 3, + ImGuiTableColumnFlags_WidthFixed = 1 << 4, + ImGuiTableColumnFlags_NoResize = 1 << 5, + ImGuiTableColumnFlags_NoReorder = 1 << 6, + ImGuiTableColumnFlags_NoHide = 1 << 7, + ImGuiTableColumnFlags_NoClip = 1 << 8, + ImGuiTableColumnFlags_NoSort = 1 << 9, + ImGuiTableColumnFlags_NoSortAscending = 1 << 10, + ImGuiTableColumnFlags_NoSortDescending = 1 << 11, + ImGuiTableColumnFlags_NoHeaderLabel = 1 << 12, + ImGuiTableColumnFlags_NoHeaderWidth = 1 << 13, + ImGuiTableColumnFlags_PreferSortAscending = 1 << 14, + ImGuiTableColumnFlags_PreferSortDescending = 1 << 15, + ImGuiTableColumnFlags_IndentEnable = 1 << 16, + ImGuiTableColumnFlags_IndentDisable = 1 << 17, + ImGuiTableColumnFlags_AngledHeader = 1 << 18, + ImGuiTableColumnFlags_IsEnabled = 1 << 24, + ImGuiTableColumnFlags_IsVisible = 1 << 25, + ImGuiTableColumnFlags_IsSorted = 1 << 26, + ImGuiTableColumnFlags_IsHovered = 1 << 27, + ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthFixed, + ImGuiTableColumnFlags_IndentMask_ = ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_IndentDisable, + ImGuiTableColumnFlags_StatusMask_ = ImGuiTableColumnFlags_IsEnabled | ImGuiTableColumnFlags_IsVisible | ImGuiTableColumnFlags_IsSorted | ImGuiTableColumnFlags_IsHovered, + ImGuiTableColumnFlags_NoDirectResize_ = 1 << 30, +}ImGuiTableColumnFlags_; +typedef enum { + ImGuiTableRowFlags_None = 0, + ImGuiTableRowFlags_Headers = 1 << 0, +}ImGuiTableRowFlags_; +typedef enum { + ImGuiTableBgTarget_None = 0, + ImGuiTableBgTarget_RowBg0 = 1, + ImGuiTableBgTarget_RowBg1 = 2, + ImGuiTableBgTarget_CellBg = 3, +}ImGuiTableBgTarget_; +struct ImGuiTableSortSpecs +{ + const ImGuiTableColumnSortSpecs* Specs; + int SpecsCount; + bool SpecsDirty; +}; +struct ImGuiTableColumnSortSpecs +{ + ImGuiID ColumnUserID; + ImS16 ColumnIndex; + ImS16 SortOrder; + ImGuiSortDirection SortDirection; +}; +struct ImGuiStyle +{ + float FontSizeBase; + float FontScaleMain; + float FontScaleDpi; + float Alpha; + float DisabledAlpha; + ImVec2_c WindowPadding; + float WindowRounding; + float WindowBorderSize; + float WindowBorderHoverPadding; + ImVec2_c WindowMinSize; + ImVec2_c WindowTitleAlign; + ImGuiDir WindowMenuButtonPosition; + float ChildRounding; + float ChildBorderSize; + float PopupRounding; + float PopupBorderSize; + ImVec2_c FramePadding; + float FrameRounding; + float FrameBorderSize; + ImVec2_c ItemSpacing; + ImVec2_c ItemInnerSpacing; + ImVec2_c CellPadding; + ImVec2_c TouchExtraPadding; + float IndentSpacing; + float ColumnsMinSpacing; + float ScrollbarSize; + float ScrollbarRounding; + float ScrollbarPadding; + float GrabMinSize; + float GrabRounding; + float LogSliderDeadzone; + float ImageRounding; + float ImageBorderSize; + float TabRounding; + float TabBorderSize; + float TabMinWidthBase; + float TabMinWidthShrink; + float TabCloseButtonMinWidthSelected; + float TabCloseButtonMinWidthUnselected; + float TabBarBorderSize; + float TabBarOverlineSize; + float TableAngledHeadersAngle; + ImVec2_c TableAngledHeadersTextAlign; + ImGuiTreeNodeFlags TreeLinesFlags; + float TreeLinesSize; + float TreeLinesRounding; + float DragDropTargetRounding; + float DragDropTargetBorderSize; + float DragDropTargetPadding; + float ColorMarkerSize; + ImGuiDir ColorButtonPosition; + ImVec2_c ButtonTextAlign; + ImVec2_c SelectableTextAlign; + float InputTextCursorSize; + float SeparatorSize; + float SeparatorTextBorderSize; + ImVec2_c SeparatorTextAlign; + ImVec2_c SeparatorTextPadding; + ImVec2_c DisplayWindowPadding; + ImVec2_c DisplaySafeAreaPadding; + float MouseCursorScale; + bool AntiAliasedLines; + bool AntiAliasedLinesUseTex; + bool AntiAliasedFill; + float CurveTessellationTol; + float CircleTessellationMaxError; + ImVec4_c Colors[ImGuiCol_COUNT]; + float HoverStationaryDelay; + float HoverDelayShort; + float HoverDelayNormal; + ImGuiHoveredFlags HoverFlagsForTooltipMouse; + ImGuiHoveredFlags HoverFlagsForTooltipNav; + float _MainScale; + float _NextFrameFontSizeBase; +}; +struct ImGuiKeyData +{ + bool Down; + float DownDuration; + float DownDurationPrev; + float AnalogValue; +}; +typedef struct ImVector_ImWchar {int Size;int Capacity;ImWchar* Data;} ImVector_ImWchar; + +struct ImGuiIO +{ + ImGuiConfigFlags ConfigFlags; + ImGuiBackendFlags BackendFlags; + ImVec2_c DisplaySize; + ImVec2_c DisplayFramebufferScale; + float DeltaTime; + float IniSavingRate; + const char* IniFilename; + const char* LogFilename; + void* UserData; + ImFontAtlas*Fonts; + ImFont* FontDefault; + bool FontAllowUserScaling; + bool ConfigNavSwapGamepadButtons; + bool ConfigNavMoveSetMousePos; + bool ConfigNavCaptureKeyboard; + bool ConfigNavEscapeClearFocusItem; + bool ConfigNavEscapeClearFocusWindow; + bool ConfigNavCursorVisibleAuto; + bool ConfigNavCursorVisibleAlways; + bool MouseDrawCursor; + bool ConfigMacOSXBehaviors; + bool ConfigInputTrickleEventQueue; + bool ConfigInputTextCursorBlink; + bool ConfigInputTextEnterKeepActive; + bool ConfigDragClickToInputText; + bool ConfigWindowsResizeFromEdges; + bool ConfigWindowsMoveFromTitleBarOnly; + bool ConfigWindowsCopyContentsWithCtrlC; + bool ConfigScrollbarScrollByPage; + float ConfigMemoryCompactTimer; + float MouseDoubleClickTime; + float MouseDoubleClickMaxDist; + float MouseDragThreshold; + float KeyRepeatDelay; + float KeyRepeatRate; + bool ConfigErrorRecovery; + bool ConfigErrorRecoveryEnableAssert; + bool ConfigErrorRecoveryEnableDebugLog; + bool ConfigErrorRecoveryEnableTooltip; + bool ConfigDebugIsDebuggerPresent; + bool ConfigDebugHighlightIdConflicts; + bool ConfigDebugHighlightIdConflictsShowItemPicker; + bool ConfigDebugBeginReturnValueOnce; + bool ConfigDebugBeginReturnValueLoop; + bool ConfigDebugIgnoreFocusLoss; + bool ConfigDebugIniSettings; + const char* BackendPlatformName; + const char* BackendRendererName; + void* BackendPlatformUserData; + void* BackendRendererUserData; + void* BackendLanguageUserData; + bool WantCaptureMouse; + bool WantCaptureKeyboard; + bool WantTextInput; + bool WantSetMousePos; + bool WantSaveIniSettings; + bool NavActive; + bool NavVisible; + float Framerate; + int MetricsRenderVertices; + int MetricsRenderIndices; + int MetricsRenderWindows; + int MetricsActiveWindows; + ImVec2_c MouseDelta; + ImGuiContext* Ctx; + ImVec2_c MousePos; + bool MouseDown[5]; + float MouseWheel; + float MouseWheelH; + ImGuiMouseSource MouseSource; + bool KeyCtrl; + bool KeyShift; + bool KeyAlt; + bool KeySuper; + ImGuiKeyChord KeyMods; + ImGuiKeyData KeysData[ImGuiKey_NamedKey_COUNT]; + bool WantCaptureMouseUnlessPopupClose; + ImVec2_c MousePosPrev; + ImVec2_c MouseClickedPos[5]; + double MouseClickedTime[5]; + bool MouseClicked[5]; + bool MouseDoubleClicked[5]; + ImU16 MouseClickedCount[5]; + ImU16 MouseClickedLastCount[5]; + bool MouseReleased[5]; + double MouseReleasedTime[5]; + bool MouseDownOwned[5]; + bool MouseDownOwnedUnlessPopupClose[5]; + bool MouseWheelRequestAxisSwap; + bool MouseCtrlLeftAsRightClick; + float MouseDownDuration[5]; + float MouseDownDurationPrev[5]; + float MouseDragMaxDistanceSqr[5]; + float PenPressure; + bool AppFocusLost; + bool AppAcceptingEvents; + ImWchar16 InputQueueSurrogate; + ImVector_ImWchar InputQueueCharacters; +}; +struct ImGuiInputTextCallbackData +{ + ImGuiContext* Ctx; + ImGuiInputTextFlags EventFlag; + ImGuiInputTextFlags Flags; + void* UserData; + ImGuiID ID; + ImGuiKey EventKey; + ImWchar EventChar; + bool EventActivated; + bool BufDirty; + char* Buf; + int BufTextLen; + int BufSize; + int CursorPos; + int SelectionStart; + int SelectionEnd; +}; +struct ImGuiSizeCallbackData +{ + void* UserData; + ImVec2_c Pos; + ImVec2_c CurrentSize; + ImVec2_c DesiredSize; +}; +struct ImGuiPayload +{ + void* Data; + int DataSize; + ImGuiID SourceId; + ImGuiID SourceParentId; + int DataFrameCount; + char DataType[32 + 1]; + bool Preview; + bool Delivery; +}; +struct ImGuiOnceUponAFrame +{ + int RefFrame; +}; +struct ImGuiTextRange +{ + const char* b; + const char* e; +}; +typedef struct ImGuiTextRange ImGuiTextRange; + +typedef struct ImVector_ImGuiTextRange {int Size;int Capacity;ImGuiTextRange* Data;} ImVector_ImGuiTextRange; + +struct ImGuiTextFilter +{ + char InputBuf[256]; + ImVector_ImGuiTextRange Filters; + int CountGrep; +}; +typedef struct ImGuiTextRange ImGuiTextRange; +typedef struct ImVector_char {int Size;int Capacity;char* Data;} ImVector_char; + +struct ImGuiTextBuffer +{ + ImVector_char Buf; +}; +struct ImGuiStoragePair +{ + ImGuiID key; + union { int val_i; float val_f; void* val_p; }; +}; +typedef struct ImVector_ImGuiStoragePair {int Size;int Capacity;ImGuiStoragePair* Data;} ImVector_ImGuiStoragePair; + +struct ImGuiStorage +{ + ImVector_ImGuiStoragePair Data; +}; +typedef enum { + ImGuiListClipperFlags_None = 0, + ImGuiListClipperFlags_NoSetTableRowCounters = 1 << 0, +}ImGuiListClipperFlags_; +struct ImGuiListClipper +{ + int DisplayStart; + int DisplayEnd; + int UserIndex; + int ItemsCount; + float ItemsHeight; + ImGuiListClipperFlags Flags; + double StartPosY; + double StartSeekOffsetY; + ImGuiContext* Ctx; + void* TempData; +}; +struct ImColor_c +{ + ImVec4_c Value; +}; +typedef enum { + ImGuiMultiSelectFlags_None = 0, + ImGuiMultiSelectFlags_SingleSelect = 1 << 0, + ImGuiMultiSelectFlags_NoSelectAll = 1 << 1, + ImGuiMultiSelectFlags_NoRangeSelect = 1 << 2, + ImGuiMultiSelectFlags_NoAutoSelect = 1 << 3, + ImGuiMultiSelectFlags_NoAutoClear = 1 << 4, + ImGuiMultiSelectFlags_NoAutoClearOnReselect = 1 << 5, + ImGuiMultiSelectFlags_BoxSelect1d = 1 << 6, + ImGuiMultiSelectFlags_BoxSelect2d = 1 << 7, + ImGuiMultiSelectFlags_BoxSelectNoScroll = 1 << 8, + ImGuiMultiSelectFlags_ClearOnEscape = 1 << 9, + ImGuiMultiSelectFlags_ClearOnClickVoid = 1 << 10, + ImGuiMultiSelectFlags_ScopeWindow = 1 << 11, + ImGuiMultiSelectFlags_ScopeRect = 1 << 12, + ImGuiMultiSelectFlags_SelectOnAuto = 1 << 13, + ImGuiMultiSelectFlags_SelectOnClickAlways = 1 << 14, + ImGuiMultiSelectFlags_SelectOnClickRelease = 1 << 15, + ImGuiMultiSelectFlags_NavWrapX = 1 << 16, + ImGuiMultiSelectFlags_NoSelectOnRightClick = 1 << 17, + ImGuiMultiSelectFlags_SelectOnMask_ = ImGuiMultiSelectFlags_SelectOnAuto | ImGuiMultiSelectFlags_SelectOnClickAlways | ImGuiMultiSelectFlags_SelectOnClickRelease, +}ImGuiMultiSelectFlags_; +typedef struct ImVector_ImGuiSelectionRequest {int Size;int Capacity;ImGuiSelectionRequest* Data;} ImVector_ImGuiSelectionRequest; + +struct ImGuiMultiSelectIO +{ + ImVector_ImGuiSelectionRequest Requests; + ImGuiSelectionUserData RangeSrcItem; + ImGuiSelectionUserData NavIdItem; + bool NavIdSelected; + bool RangeSrcReset; + int ItemsCount; +}; +typedef enum { + ImGuiSelectionRequestType_None = 0, + ImGuiSelectionRequestType_SetAll, + ImGuiSelectionRequestType_SetRange, +}ImGuiSelectionRequestType; +struct ImGuiSelectionRequest +{ + ImGuiSelectionRequestType Type; + bool Selected; + ImS8 RangeDirection; + ImGuiSelectionUserData RangeFirstItem; + ImGuiSelectionUserData RangeLastItem; +}; +struct ImGuiSelectionBasicStorage +{ + int Size; + bool PreserveOrder; + void* UserData; + ImGuiID (*AdapterIndexToStorageId)(ImGuiSelectionBasicStorage* self, int idx); + int _SelectionOrder; + ImGuiStorage _Storage; +}; +struct ImGuiSelectionExternalStorage +{ + void* UserData; + void (*AdapterSetItemSelected)(ImGuiSelectionExternalStorage* self, int idx, bool selected); +}; +typedef unsigned short ImDrawIdx; +typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* cmd); +struct ImDrawCmd +{ + ImVec4_c ClipRect; + ImTextureRef_c TexRef; + unsigned int VtxOffset; + unsigned int IdxOffset; + unsigned int ElemCount; + ImDrawCallback UserCallback; + void* UserCallbackData; + int UserCallbackDataSize; + int UserCallbackDataOffset; +}; +struct ImDrawVert +{ + ImVec2_c pos; + ImVec2_c uv; + ImU32 col; +}; +typedef struct ImDrawCmdHeader ImDrawCmdHeader; +struct ImDrawCmdHeader +{ + ImVec4_c ClipRect; + ImTextureRef_c TexRef; + unsigned int VtxOffset; +}; +typedef struct ImVector_ImDrawCmd {int Size;int Capacity;ImDrawCmd* Data;} ImVector_ImDrawCmd; + +typedef struct ImVector_ImDrawIdx {int Size;int Capacity;ImDrawIdx* Data;} ImVector_ImDrawIdx; + +struct ImDrawChannel +{ + ImVector_ImDrawCmd _CmdBuffer; + ImVector_ImDrawIdx _IdxBuffer; +}; +typedef struct ImVector_ImDrawChannel {int Size;int Capacity;ImDrawChannel* Data;} ImVector_ImDrawChannel; + +struct ImDrawListSplitter +{ + int _Current; + int _Count; + ImVector_ImDrawChannel _Channels; +}; +typedef enum { + ImDrawFlags_None = 0, + ImDrawFlags_RoundCornersTopLeft = 1 << 4, + ImDrawFlags_RoundCornersTopRight = 1 << 5, + ImDrawFlags_RoundCornersBottomLeft = 1 << 6, + ImDrawFlags_RoundCornersBottomRight = 1 << 7, + ImDrawFlags_RoundCornersNone = 1 << 8, + ImDrawFlags_RoundCornersAll = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, + ImDrawFlags_RoundCornersDefault_ = ImDrawFlags_RoundCornersAll, + ImDrawFlags_RoundCornersTop = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight, + ImDrawFlags_RoundCornersBottom = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, + ImDrawFlags_RoundCornersLeft = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersTopLeft, + ImDrawFlags_RoundCornersRight = ImDrawFlags_RoundCornersBottomRight | ImDrawFlags_RoundCornersTopRight, + ImDrawFlags_RoundCornersMask_ = ImDrawFlags_RoundCornersAll | ImDrawFlags_RoundCornersNone, + ImDrawFlags_Closed = 1 << 9, + ImDrawFlags_InvalidMask_ = ~0x7FFFFFF0, +}ImDrawFlags_; +typedef enum { + ImDrawListFlags_None = 0, + ImDrawListFlags_AntiAliasedLines = 1 << 0, + ImDrawListFlags_AntiAliasedLinesUseTex = 1 << 1, + ImDrawListFlags_AntiAliasedFill = 1 << 2, + ImDrawListFlags_AllowVtxOffset = 1 << 3, + ImDrawListFlags_TextNoPixelSnap = 1 << 4, +}ImDrawListFlags_; +typedef struct ImVector_ImDrawVert {int Size;int Capacity;ImDrawVert* Data;} ImVector_ImDrawVert; + +typedef struct ImVector_ImVec2 {int Size;int Capacity;ImVec2_c* Data;} ImVector_ImVec2; + +typedef struct ImVector_ImVec4 {int Size;int Capacity;ImVec4_c* Data;} ImVector_ImVec4; + +typedef struct ImVector_ImTextureRef {int Size;int Capacity;ImTextureRef_c* Data;} ImVector_ImTextureRef; + +typedef struct ImVector_ImU8 {int Size;int Capacity;ImU8* Data;} ImVector_ImU8; + +struct ImDrawList +{ + ImVector_ImDrawCmd CmdBuffer; + ImVector_ImDrawIdx IdxBuffer; + ImVector_ImDrawVert VtxBuffer; + ImDrawListFlags Flags; + unsigned int _VtxCurrentIdx; + ImDrawListSharedData* _Data; + ImDrawVert* _VtxWritePtr; + ImDrawIdx* _IdxWritePtr; + ImVector_ImVec2 _Path; + ImDrawCmdHeader _CmdHeader; + ImDrawListSplitter _Splitter; + ImVector_ImVec4 _ClipRectStack; + ImVector_ImTextureRef _TextureStack; + ImVector_ImU8 _CallbacksDataBuf; + float _FringeScale; + const char* _OwnerName; +}; +typedef struct ImVector_ImDrawListPtr {int Size;int Capacity;ImDrawList** Data;} ImVector_ImDrawListPtr; + +typedef struct ImVector_ImTextureDataPtr {int Size;int Capacity;ImTextureData** Data;} ImVector_ImTextureDataPtr; + +struct ImDrawData +{ + bool Valid; + int CmdListsCount; + int TotalIdxCount; + int TotalVtxCount; + ImVector_ImDrawListPtr CmdLists; + ImVec2_c DisplayPos; + ImVec2_c DisplaySize; + ImVec2_c FramebufferScale; + ImGuiViewport* OwnerViewport; + ImVector_ImTextureDataPtr* Textures; +}; +typedef enum { + ImTextureFormat_RGBA32, + ImTextureFormat_Alpha8, +}ImTextureFormat; +typedef enum { + ImTextureStatus_OK, + ImTextureStatus_Destroyed, + ImTextureStatus_WantCreate, + ImTextureStatus_WantUpdates, + ImTextureStatus_WantDestroy, +}ImTextureStatus; +struct ImTextureRect +{ + unsigned short x, y; + unsigned short w, h; +}; +typedef struct ImVector_ImTextureRect {int Size;int Capacity;ImTextureRect* Data;} ImVector_ImTextureRect; + +struct ImTextureData +{ + int UniqueID; + ImTextureStatus Status; + void* BackendUserData; + ImTextureID TexID; + ImTextureFormat Format; + int Width; + int Height; + int BytesPerPixel; + unsigned char* Pixels; + ImTextureRect UsedRect; + ImTextureRect UpdateRect; + ImVector_ImTextureRect Updates; + int UnusedFrames; + unsigned short RefCount; + bool UseColors; + bool WantDestroyNextFrame; +}; +struct ImFontConfig +{ + char Name[40]; + void* FontData; + int FontDataSize; + bool FontDataOwnedByAtlas; + bool MergeMode; + bool PixelSnapH; + ImS8 OversampleH; + ImS8 OversampleV; + ImWchar EllipsisChar; + float SizePixels; + const ImWchar* GlyphRanges; + const ImWchar* GlyphExcludeRanges; + ImVec2_c GlyphOffset; + float GlyphMinAdvanceX; + float GlyphMaxAdvanceX; + float GlyphExtraAdvanceX; + ImU32 FontNo; + unsigned int FontLoaderFlags; + float RasterizerMultiply; + float RasterizerDensity; + float ExtraSizeScale; + ImFontFlags Flags; + ImFont* DstFont; + const ImFontLoader* FontLoader; + void* FontLoaderData; +}; +struct ImFontGlyph +{ + unsigned int Colored : 1; + unsigned int Visible : 1; + unsigned int SourceIdx : 4; + unsigned int Codepoint : 26; + float AdvanceX; + float X0, Y0, X1, Y1; + float U0, V0, U1, V1; + int PackId; +}; +typedef struct ImVector_ImU32 {int Size;int Capacity;ImU32* Data;} ImVector_ImU32; + +struct ImFontGlyphRangesBuilder +{ + ImVector_ImU32 UsedChars; +}; +typedef int ImFontAtlasRectId; +struct ImFontAtlasRect +{ + unsigned short x, y; + unsigned short w, h; + ImVec2_c uv0, uv1; +}; +typedef enum { + ImFontAtlasFlags_None = 0, + ImFontAtlasFlags_NoPowerOfTwoHeight = 1 << 0, + ImFontAtlasFlags_NoMouseCursors = 1 << 1, + ImFontAtlasFlags_NoBakedLines = 1 << 2, +}ImFontAtlasFlags_; +typedef struct ImVector_ImFontPtr {int Size;int Capacity;ImFont** Data;} ImVector_ImFontPtr; + +typedef struct ImVector_ImFontConfig {int Size;int Capacity;ImFontConfig* Data;} ImVector_ImFontConfig; + +typedef struct ImVector_ImDrawListSharedDataPtr {int Size;int Capacity;ImDrawListSharedData** Data;} ImVector_ImDrawListSharedDataPtr; + +struct ImFontAtlas +{ + ImFontAtlasFlags Flags; + ImTextureFormat TexDesiredFormat; + int TexGlyphPadding; + int TexMinWidth; + int TexMinHeight; + int TexMaxWidth; + int TexMaxHeight; + void* UserData; + ImTextureRef_c TexRef; + ImTextureData* TexData; + ImVector_ImTextureDataPtr TexList; + bool Locked; + bool RendererHasTextures; + bool TexIsBuilt; + bool TexPixelsUseColors; + ImVec2_c TexUvScale; + ImVec2_c TexUvWhitePixel; + ImVector_ImFontPtr Fonts; + ImVector_ImFontConfig Sources; + ImVec4_c TexUvLines[(32) + 1]; + int TexNextUniqueID; + int FontNextUniqueID; + ImVector_ImDrawListSharedDataPtr DrawListSharedDatas; + ImFontAtlasBuilder* Builder; + const ImFontLoader* FontLoader; + const char* FontLoaderName; + void* FontLoaderData; + unsigned int FontLoaderFlags; + int RefCount; + ImGuiContext* OwnerContext; +}; +typedef struct ImVector_float {int Size;int Capacity;float* Data;} ImVector_float; + +typedef struct ImVector_ImU16 {int Size;int Capacity;ImU16* Data;} ImVector_ImU16; + +typedef struct ImVector_ImFontGlyph {int Size;int Capacity;ImFontGlyph* Data;} ImVector_ImFontGlyph; + +struct ImFontBaked +{ + ImVector_float IndexAdvanceX; + float FallbackAdvanceX; + float Size; + float RasterizerDensity; + ImVector_ImU16 IndexLookup; + ImVector_ImFontGlyph Glyphs; + int FallbackGlyphIndex; + float Ascent, Descent; + unsigned int MetricsTotalSurface:26; + unsigned int WantDestroy:1; + unsigned int LoadNoFallback:1; + unsigned int LoadNoRenderOnLayout:1; + int LastUsedFrame; + ImGuiID BakedId; + ImFont* OwnerFont; + void* FontLoaderDatas; +}; +typedef enum { + ImFontFlags_None = 0, + ImFontFlags_NoLoadError = 1 << 1, + ImFontFlags_NoLoadGlyphs = 1 << 2, + ImFontFlags_LockBakedSizes = 1 << 3, + ImFontFlags_ImplicitRefSize = 1 << 4, +}ImFontFlags_; +typedef struct ImVector_ImFontConfigPtr {int Size;int Capacity;ImFontConfig** Data;} ImVector_ImFontConfigPtr; + +struct ImFont +{ + ImFontBaked* LastBaked; + ImFontAtlas* OwnerAtlas; + ImFontFlags Flags; + float CurrentRasterizerDensity; + ImGuiID FontId; + float LegacySize; + ImVector_ImFontConfigPtr Sources; + ImWchar EllipsisChar; + ImWchar FallbackChar; + ImU8 Used8kPagesMap[(IM_UNICODE_CODEPOINT_MAX +1)/8192/8]; + bool EllipsisAutoBake; + ImGuiStorage RemapPairs; +}; +typedef enum { + ImGuiViewportFlags_None = 0, + ImGuiViewportFlags_IsPlatformWindow = 1 << 0, + ImGuiViewportFlags_IsPlatformMonitor = 1 << 1, + ImGuiViewportFlags_OwnedByApp = 1 << 2, +}ImGuiViewportFlags_; +struct ImGuiViewport +{ + ImGuiID ID; + ImGuiViewportFlags Flags; + ImVec2_c Pos; + ImVec2_c Size; + ImVec2_c FramebufferScale; + ImVec2_c WorkPos; + ImVec2_c WorkSize; + void* PlatformHandle; + void* PlatformHandleRaw; +}; +struct ImGuiPlatformIO +{ + const char* (*Platform_GetClipboardTextFn)(ImGuiContext* ctx); + void (*Platform_SetClipboardTextFn)(ImGuiContext* ctx, const char* text); + void* Platform_ClipboardUserData; + bool (*Platform_OpenInShellFn)(ImGuiContext* ctx, const char* path); + void* Platform_OpenInShellUserData; + void (*Platform_SetImeDataFn)(ImGuiContext* ctx, ImGuiViewport* viewport, ImGuiPlatformImeData* data); + void* Platform_ImeUserData; + ImWchar Platform_LocaleDecimalPoint; + int Renderer_TextureMaxWidth; + int Renderer_TextureMaxHeight; + void* Renderer_RenderState; + ImDrawCallback DrawCallback_ResetRenderState; + ImDrawCallback DrawCallback_SetSamplerLinear; + ImDrawCallback DrawCallback_SetSamplerNearest; + ImVector_ImTextureDataPtr Textures; +}; +struct ImGuiPlatformImeData +{ + bool WantVisible; + bool WantTextInput; + ImVec2_c InputPos; + float InputLineHeight; + ImGuiID ViewportId; +}; +struct ImBitVector; +struct ImRect_c; +struct ImGuiTextIndex; +struct ImDrawDataBuilder; +struct ImDrawListSharedData; +struct ImFontAtlasBuilder; +struct ImFontAtlasPostProcessData; +struct ImFontAtlasRectEntry; +struct ImGuiBoxSelectState; +struct ImGuiColorMod; +struct ImGuiContext; +struct ImGuiContextHook; +struct ImGuiDataTypeInfo; +struct ImGuiDeactivatedItemData; +struct ImGuiErrorRecoveryState; +struct ImGuiGroupData; +struct ImGuiInputTextState; +struct ImGuiInputTextDeactivateData; +struct ImGuiLastItemData; +struct ImGuiLocEntry; +struct ImGuiMenuColumns; +struct ImGuiMultiSelectState; +struct ImGuiMultiSelectTempData; +struct ImGuiNavItemData; +struct ImGuiMetricsConfig; +struct ImGuiNextWindowData; +struct ImGuiNextItemData; +struct ImGuiOldColumnData; +struct ImGuiOldColumns; +struct ImGuiPopupData; +struct ImGuiSettingsHandler; +struct ImGuiStyleMod; +struct ImGuiStyleVarInfo; +struct ImGuiTabBar; +struct ImGuiTabItem; +struct ImGuiTable; +struct ImGuiTableHeaderData; +struct ImGuiTableColumn; +struct ImGuiTableInstanceData; +struct ImGuiTableTempData; +struct ImGuiTableSettings; +struct ImGuiTableColumnsSettings; +struct ImGuiTreeNodeStackData; +struct ImGuiTypingSelectState; +struct ImGuiTypingSelectRequest; +struct ImGuiWindow; +struct ImGuiWindowTempData; +struct ImGuiWindowSettings; +typedef int ImGuiLayoutType; +typedef int ImDrawTextFlags; +typedef int ImGuiActivateFlags; +typedef int ImGuiDebugLogFlags; +typedef int ImGuiFocusRequestFlags; +typedef int ImGuiItemStatusFlags; +typedef int ImGuiOldColumnFlags; +typedef int ImGuiLogFlags; +typedef int ImGuiNavRenderCursorFlags; +typedef int ImGuiNavMoveFlags; +typedef int ImGuiNextItemDataFlags; +typedef int ImGuiNextWindowDataFlags; +typedef int ImGuiScrollFlags; +typedef int ImGuiSeparatorFlags; +typedef int ImGuiTextFlags; +typedef int ImGuiTooltipFlags; +typedef int ImGuiTypingSelectFlags; +typedef int ImGuiWindowBgClickFlags; +typedef int ImGuiWindowRefreshFlags; +typedef ImS16 ImGuiTableColumnIdx; +typedef ImU16 ImGuiTableDrawChannelIdx; +typedef enum { + ImDrawTextFlags_None = 0, + ImDrawTextFlags_CpuFineClip = 1 << 0, + ImDrawTextFlags_WrapKeepBlanks = 1 << 1, + ImDrawTextFlags_StopOnNewLine = 1 << 2, +}ImDrawTextFlags_; +typedef enum { + ImWcharClass_Blank, ImWcharClass_Punct, ImWcharClass_Other +}ImWcharClass; +typedef FILE* ImFileHandle; +typedef struct ImVec1 ImVec1; +struct ImVec1 +{ + float x; +}; +typedef struct ImVec2i_c ImVec2i_c; +struct ImVec2i_c +{ + int x, y; +}; +typedef struct ImVec2ih ImVec2ih; +struct ImVec2ih +{ + short x, y; +}; +struct ImRect_c +{ + ImVec2_c Min; + ImVec2_c Max; +}; +typedef ImU32* ImBitArrayPtr; +struct ImBitVector +{ + ImVector_ImU32 Storage; +}; +typedef int ImPoolIdx; +typedef struct ImVector_int {int Size;int Capacity;int* Data;} ImVector_int; + +struct ImGuiTextIndex +{ + ImVector_int Offsets; + int EndOffset; +}; +struct ImDrawListSharedData +{ + ImVec2_c TexUvWhitePixel; + const ImVec4_c* TexUvLines; + ImFontAtlas* FontAtlas; + ImFont* Font; + float FontSize; + float FontScale; + float CurveTessellationTol; + float CircleTessellationMaxError; + float InitialFringeScale; + ImDrawListFlags InitialFlags; + ImVec4_c ClipRectFullscreen; + ImVector_ImVec2 TempBuffer; + ImVector_ImDrawListPtr DrawLists; + ImGuiContext* Context; + ImVec2_c ArcFastVtx[48]; + float ArcFastRadiusCutoff; + ImU8 CircleSegmentCounts[64]; +}; +struct ImDrawDataBuilder +{ + ImVector_ImDrawListPtr* Layers[2]; + ImVector_ImDrawListPtr LayerData1; +}; +typedef struct ImFontStackData ImFontStackData; +struct ImFontStackData +{ + ImFont* Font; + float FontSizeBeforeScaling; + float FontSizeAfterScaling; +}; +struct ImGuiStyleVarInfo +{ + ImU32 Count : 8; + ImGuiDataType DataType : 8; + ImU32 Offset : 16; +}; +struct ImGuiColorMod +{ + ImGuiCol Col; + ImVec4_c BackupValue; +}; +struct ImGuiStyleMod +{ + ImGuiStyleVar VarIdx; + union { int BackupInt[2]; float BackupFloat[2]; }; +}; +typedef struct ImGuiDataTypeStorage ImGuiDataTypeStorage; +struct ImGuiDataTypeStorage +{ + ImU8 Data[8]; +}; +struct ImGuiDataTypeInfo +{ + size_t Size; + const char* Name; + const char* PrintFmt; + const char* ScanFmt; +}; +typedef enum { + ImGuiDataType_Pointer = ImGuiDataType_COUNT, + ImGuiDataType_ID, +}ImGuiDataTypePrivate_; +typedef enum { + ImGuiItemFlags_ReadOnly = 1 << 11, + ImGuiItemFlags_MixedValue = 1 << 12, + ImGuiItemFlags_NoWindowHoverableCheck = 1 << 13, + ImGuiItemFlags_AllowOverlap = 1 << 14, + ImGuiItemFlags_NoNavDisableMouseHover = 1 << 15, + ImGuiItemFlags_NoMarkEdited = 1 << 16, + ImGuiItemFlags_NoFocus = 1 << 17, + ImGuiItemFlags_Inputable = 1 << 20, + ImGuiItemFlags_HasSelectionUserData = 1 << 21, + ImGuiItemFlags_IsMultiSelect = 1 << 22, + ImGuiItemFlags_Default_ = ImGuiItemFlags_AutoClosePopups, +}ImGuiItemFlagsPrivate_; +typedef enum { + ImGuiItemStatusFlags_None = 0, + ImGuiItemStatusFlags_HoveredRect = 1 << 0, + ImGuiItemStatusFlags_HasDisplayRect = 1 << 1, + ImGuiItemStatusFlags_Edited = 1 << 2, + ImGuiItemStatusFlags_ToggledSelection = 1 << 3, + ImGuiItemStatusFlags_ToggledOpen = 1 << 4, + ImGuiItemStatusFlags_HasDeactivated = 1 << 5, + ImGuiItemStatusFlags_Deactivated = 1 << 6, + ImGuiItemStatusFlags_HoveredWindow = 1 << 7, + ImGuiItemStatusFlags_Visible = 1 << 8, + ImGuiItemStatusFlags_HasClipRect = 1 << 9, + ImGuiItemStatusFlags_HasShortcut = 1 << 10, + ImGuiItemStatusFlags_EditedInternal = 1 << 11, +}ImGuiItemStatusFlags_; +typedef enum { + ImGuiHoveredFlags_DelayMask_ = ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay, + ImGuiHoveredFlags_AllowedMaskForIsWindowHovered = ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_NoPopupHierarchy | ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_Stationary, + ImGuiHoveredFlags_AllowedMaskForIsItemHovered = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped | ImGuiHoveredFlags_AllowWhenDisabled | ImGuiHoveredFlags_NoNavOverride | ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayMask_, +}ImGuiHoveredFlagsPrivate_; +typedef enum { + ImGuiInputTextFlags_Multiline = 1 << 26, + ImGuiInputTextFlags_TempInput = 1 << 27, + ImGuiInputTextFlags_LocalizeDecimalPoint= 1 << 28, +}ImGuiInputTextFlagsPrivate_; +typedef enum { + ImGuiButtonFlags_PressedOnClick = 1 << 4, + ImGuiButtonFlags_PressedOnClickRelease = 1 << 5, + ImGuiButtonFlags_PressedOnClickReleaseAnywhere = 1 << 6, + ImGuiButtonFlags_PressedOnRelease = 1 << 7, + ImGuiButtonFlags_PressedOnDoubleClick = 1 << 8, + ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, + ImGuiButtonFlags_FlattenChildren = 1 << 11, + ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, + ImGuiButtonFlags_NoKeyModsAllowed = 1 << 16, + ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, + ImGuiButtonFlags_NoNavFocus = 1 << 18, + ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, + ImGuiButtonFlags_NoSetKeyOwner = 1 << 20, + ImGuiButtonFlags_NoTestKeyOwner = 1 << 21, + ImGuiButtonFlags_NoFocus = 1 << 22, + ImGuiButtonFlags_PressedOnMask_ = ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_PressedOnDragDropHold, + ImGuiButtonFlags_PressedOnDefault_ = ImGuiButtonFlags_PressedOnClickRelease, +}ImGuiButtonFlagsPrivate_; +typedef enum { + ImGuiComboFlags_CustomPreview = 1 << 20, +}ImGuiComboFlagsPrivate_; +typedef enum { + ImGuiSliderFlags_Vertical = 1 << 20, + ImGuiSliderFlags_ReadOnly = 1 << 21, +}ImGuiSliderFlagsPrivate_; +typedef enum { + ImGuiSelectableFlags_NoHoldingActiveID = 1 << 20, + ImGuiSelectableFlags_SelectOnClick = 1 << 22, + ImGuiSelectableFlags_SelectOnRelease = 1 << 23, + ImGuiSelectableFlags_SpanAvailWidth = 1 << 24, + ImGuiSelectableFlags_SetNavIdOnHover = 1 << 25, + ImGuiSelectableFlags_NoPadWithHalfSpacing = 1 << 26, + ImGuiSelectableFlags_NoSetKeyOwner = 1 << 27, +}ImGuiSelectableFlagsPrivate_; +typedef enum { + ImGuiTreeNodeFlags_NoNavFocus = 1 << 27, + ImGuiTreeNodeFlags_ClipLabelForTrailingButton = 1 << 28, + ImGuiTreeNodeFlags_UpsideDownArrow = 1 << 29, + ImGuiTreeNodeFlags_OpenOnMask_ = ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_OpenOnArrow, + ImGuiTreeNodeFlags_DrawLinesMask_ = ImGuiTreeNodeFlags_DrawLinesNone | ImGuiTreeNodeFlags_DrawLinesFull | ImGuiTreeNodeFlags_DrawLinesToNodes, +}ImGuiTreeNodeFlagsPrivate_; +typedef enum { + ImGuiSeparatorFlags_None = 0, + ImGuiSeparatorFlags_Horizontal = 1 << 0, + ImGuiSeparatorFlags_Vertical = 1 << 1, + ImGuiSeparatorFlags_SpanAllColumns = 1 << 2, +}ImGuiSeparatorFlags_; +typedef enum { + ImGuiFocusRequestFlags_None = 0, + ImGuiFocusRequestFlags_RestoreFocusedChild = 1 << 0, + ImGuiFocusRequestFlags_UnlessBelowModal = 1 << 1, +}ImGuiFocusRequestFlags_; +typedef enum { + ImGuiTextFlags_None = 0, + ImGuiTextFlags_NoWidthForLargeClippedText = 1 << 0, +}ImGuiTextFlags_; +typedef enum { + ImGuiTooltipFlags_None = 0, + ImGuiTooltipFlags_OverridePrevious = 1 << 1, +}ImGuiTooltipFlags_; +typedef enum { + ImGuiLayoutType_Horizontal = 0, + ImGuiLayoutType_Vertical = 1 +}ImGuiLayoutType_; +typedef enum { + ImGuiLogFlags_None = 0, + ImGuiLogFlags_OutputTTY = 1 << 0, + ImGuiLogFlags_OutputFile = 1 << 1, + ImGuiLogFlags_OutputBuffer = 1 << 2, + ImGuiLogFlags_OutputClipboard = 1 << 3, + ImGuiLogFlags_OutputMask_ = ImGuiLogFlags_OutputTTY | ImGuiLogFlags_OutputFile | ImGuiLogFlags_OutputBuffer | ImGuiLogFlags_OutputClipboard, +}ImGuiLogFlags_; +typedef enum { + ImGuiAxis_None = -1, + ImGuiAxis_X = 0, + ImGuiAxis_Y = 1 +}ImGuiAxis; +typedef enum { + ImGuiPlotType_Lines, + ImGuiPlotType_Histogram, +}ImGuiPlotType; +typedef struct ImGuiComboPreviewData ImGuiComboPreviewData; +struct ImGuiComboPreviewData +{ + ImRect_c PreviewRect; + ImVec2_c BackupCursorPos; + ImVec2_c BackupCursorMaxPos; + ImVec2_c BackupCursorPosPrevLine; + float BackupPrevLineTextBaseOffset; + ImGuiLayoutType BackupLayout; +}; +struct ImGuiGroupData +{ + ImGuiID WindowID; + ImVec2_c BackupCursorPos; + ImVec2_c BackupCursorMaxPos; + ImVec2_c BackupCursorPosPrevLine; + ImVec1 BackupIndent; + ImVec1 BackupGroupOffset; + ImVec2_c BackupCurrLineSize; + float BackupCurrLineTextBaseOffset; + ImGuiID BackupActiveIdIsAlive; + bool BackupActiveIdHasBeenEditedThisFrame; + bool BackupDeactivatedIdIsAlive; + bool BackupHoveredIdIsAlive; + bool BackupIsSameLine; + bool EmitItem; +}; +struct ImGuiMenuColumns +{ + ImU32 TotalWidth; + ImU32 NextTotalWidth; + ImU16 Spacing; + ImU16 OffsetIcon; + ImU16 OffsetLabel; + ImU16 OffsetShortcut; + ImU16 OffsetMark; + ImU16 Widths[4]; +}; +typedef struct ImGuiInputTextDeactivatedState ImGuiInputTextDeactivatedState; +struct ImGuiInputTextDeactivatedState +{ + ImGuiID ID; + ImVector_char TextA; +}; struct STB_TexteditState; +typedef STB_TexteditState ImStbTexteditState; +struct ImGuiInputTextState +{ + ImGuiContext* Ctx; + ImStbTexteditState* Stb; + ImGuiInputTextFlags Flags; + ImGuiID ID; + int TextLen; + const char* TextSrc; + ImVector_char TextA; + ImVector_char TextToRevertTo; + ImVector_char CallbackTextBackup; + int BufCapacity; + ImVec2_c Scroll; + int LineCount; + float WrapWidth; + float CursorAnim; + bool CursorFollow; + bool CursorCenterY; + bool SelectedAllMouseLock; + bool EditedBefore; + bool EditedThisFrame; + bool WantReloadUserBuf; + ImS8 LastMoveDirectionLR; + int ReloadSelectionStart; + int ReloadSelectionEnd; +}; +typedef enum { + ImGuiWindowRefreshFlags_None = 0, + ImGuiWindowRefreshFlags_TryToAvoidRefresh = 1 << 0, + ImGuiWindowRefreshFlags_RefreshOnHover = 1 << 1, + ImGuiWindowRefreshFlags_RefreshOnFocus = 1 << 2, +}ImGuiWindowRefreshFlags_; +typedef enum { + ImGuiWindowBgClickFlags_None = 0, + ImGuiWindowBgClickFlags_Move = 1 << 0, +}ImGuiWindowBgClickFlags_; +typedef enum { + ImGuiNextWindowDataFlags_None = 0, + ImGuiNextWindowDataFlags_HasPos = 1 << 0, + ImGuiNextWindowDataFlags_HasSize = 1 << 1, + ImGuiNextWindowDataFlags_HasContentSize = 1 << 2, + ImGuiNextWindowDataFlags_HasCollapsed = 1 << 3, + ImGuiNextWindowDataFlags_HasSizeConstraint = 1 << 4, + ImGuiNextWindowDataFlags_HasFocus = 1 << 5, + ImGuiNextWindowDataFlags_HasBgAlpha = 1 << 6, + ImGuiNextWindowDataFlags_HasScroll = 1 << 7, + ImGuiNextWindowDataFlags_HasWindowFlags = 1 << 8, + ImGuiNextWindowDataFlags_HasChildFlags = 1 << 9, + ImGuiNextWindowDataFlags_HasRefreshPolicy = 1 << 10, +}ImGuiNextWindowDataFlags_; +struct ImGuiNextWindowData +{ + ImGuiNextWindowDataFlags HasFlags; + ImGuiCond PosCond; + ImGuiCond SizeCond; + ImGuiCond CollapsedCond; + ImVec2_c PosVal; + ImVec2_c PosPivotVal; + ImVec2_c SizeVal; + ImVec2_c ContentSizeVal; + ImVec2_c ScrollVal; + ImGuiWindowFlags WindowFlags; + ImGuiChildFlags ChildFlags; + bool CollapsedVal; + ImRect_c SizeConstraintRect; + ImGuiSizeCallback SizeCallback; + void* SizeCallbackUserData; + float BgAlphaVal; + ImVec2_c MenuBarOffsetMinVal; + ImGuiWindowRefreshFlags RefreshFlagsVal; +}; +typedef enum { + ImGuiNextItemDataFlags_None = 0, + ImGuiNextItemDataFlags_HasWidth = 1 << 0, + ImGuiNextItemDataFlags_HasOpen = 1 << 1, + ImGuiNextItemDataFlags_HasShortcut = 1 << 2, + ImGuiNextItemDataFlags_HasRefVal = 1 << 3, + ImGuiNextItemDataFlags_HasStorageID = 1 << 4, + ImGuiNextItemDataFlags_HasColorMarker = 1 << 5, +}ImGuiNextItemDataFlags_; +struct ImGuiNextItemData +{ + ImGuiNextItemDataFlags HasFlags; + ImGuiItemFlags ItemFlags; + ImGuiID FocusScopeId; + ImGuiSelectionUserData SelectionUserData; + float Width; + ImGuiKeyChord Shortcut; + ImGuiInputFlags ShortcutFlags; + bool OpenVal; + ImU8 OpenCond; + ImGuiDataTypeStorage RefVal; + ImGuiID StorageId; + ImU32 ColorMarker; +}; +struct ImGuiLastItemData +{ + ImGuiID ID; + ImGuiItemFlags ItemFlags; + ImGuiItemStatusFlags StatusFlags; + ImRect_c Rect; + ImRect_c NavRect; + ImRect_c DisplayRect; + ImRect_c ClipRect; + ImGuiKeyChord Shortcut; +}; +struct ImGuiTreeNodeStackData +{ + ImGuiID ID; + ImGuiTreeNodeFlags TreeFlags; + ImGuiItemFlags ItemFlags; + ImRect_c NavRect; + float DrawLinesX1; + float DrawLinesToNodesY2; + ImGuiTableColumnIdx DrawLinesTableColumn; +}; +struct ImGuiErrorRecoveryState +{ + short SizeOfWindowStack; + short SizeOfIDStack; + short SizeOfTreeStack; + short SizeOfColorStack; + short SizeOfStyleVarStack; + short SizeOfFontStack; + short SizeOfFocusScopeStack; + short SizeOfGroupStack; + short SizeOfItemFlagsStack; + short SizeOfBeginPopupStack; + short SizeOfDisabledStack; +}; +typedef struct ImGuiWindowStackData ImGuiWindowStackData; +struct ImGuiWindowStackData +{ + ImGuiWindow* Window; + ImGuiLastItemData ParentLastItemDataBackup; + ImGuiErrorRecoveryState StackSizesInBegin; + bool DisabledOverrideReenable; + float DisabledOverrideReenableAlphaBackup; +}; +typedef struct ImGuiShrinkWidthItem ImGuiShrinkWidthItem; +struct ImGuiShrinkWidthItem +{ + int Index; + float Width; + float InitialWidth; +}; +typedef struct ImGuiPtrOrIndex ImGuiPtrOrIndex; +struct ImGuiPtrOrIndex +{ + void* Ptr; + int Index; +}; +struct ImGuiDeactivatedItemData +{ + ImGuiID ID; + int ElapseFrame; + bool HasBeenEditedBefore; + bool IsAlive; +}; +typedef enum { + ImGuiPopupPositionPolicy_Default, + ImGuiPopupPositionPolicy_ComboBox, + ImGuiPopupPositionPolicy_Tooltip, +}ImGuiPopupPositionPolicy; +struct ImGuiPopupData +{ + ImGuiID PopupId; + ImGuiWindow* Window; + ImGuiWindow* RestoreNavWindow; + int ParentNavLayer; + int OpenFrameCount; + ImGuiID OpenParentId; + ImVec2_c OpenPopupPos; + ImVec2_c OpenMousePos; +}; +typedef struct ImBitArray_ImGuiKey_NamedKey_COUNT__lessImGuiKey_NamedKey_BEGIN {ImU32 Data[(ImGuiKey_NamedKey_COUNT+31)>>5];} ImBitArray_ImGuiKey_NamedKey_COUNT__lessImGuiKey_NamedKey_BEGIN; + +typedef ImBitArray_ImGuiKey_NamedKey_COUNT__lessImGuiKey_NamedKey_BEGIN ImBitArrayForNamedKeys; +typedef enum { + ImGuiInputEventType_None = 0, + ImGuiInputEventType_MousePos, + ImGuiInputEventType_MouseWheel, + ImGuiInputEventType_MouseButton, + ImGuiInputEventType_Key, + ImGuiInputEventType_Text, + ImGuiInputEventType_Focus, + ImGuiInputEventType_COUNT +}ImGuiInputEventType; +typedef enum { +ImGuiInputSource_None=0, +ImGuiInputSource_Mouse=1, +ImGuiInputSource_Keyboard=2, +ImGuiInputSource_Gamepad=3, +ImGuiInputSource_COUNT=4, +}ImGuiInputSource; +typedef struct ImGuiInputEventMousePos ImGuiInputEventMousePos; +struct ImGuiInputEventMousePos +{ float PosX, PosY; ImGuiMouseSource MouseSource; +}; +typedef struct ImGuiInputEventMouseWheel ImGuiInputEventMouseWheel; +struct ImGuiInputEventMouseWheel +{ float WheelX, WheelY; ImGuiMouseSource MouseSource; +}; +typedef struct ImGuiInputEventMouseButton ImGuiInputEventMouseButton; +struct ImGuiInputEventMouseButton +{ int Button; bool Down; ImGuiMouseSource MouseSource; +}; +typedef struct ImGuiInputEventKey ImGuiInputEventKey; +struct ImGuiInputEventKey +{ ImGuiKey Key; bool Down; float AnalogValue; +}; +typedef struct ImGuiInputEventText ImGuiInputEventText; +struct ImGuiInputEventText +{ unsigned int Char; +}; +typedef struct ImGuiInputEventAppFocused ImGuiInputEventAppFocused; +struct ImGuiInputEventAppFocused +{ bool Focused; +}; +typedef struct ImGuiInputEvent ImGuiInputEvent; +struct ImGuiInputEvent +{ + ImGuiInputEventType Type; + ImGuiInputSource Source; + ImU32 EventId; + union + { + ImGuiInputEventMousePos MousePos; + ImGuiInputEventMouseWheel MouseWheel; + ImGuiInputEventMouseButton MouseButton; + ImGuiInputEventKey Key; + ImGuiInputEventText Text; + ImGuiInputEventAppFocused AppFocused; + }; + bool AddedByTestEngine; +}; +typedef ImS16 ImGuiKeyRoutingIndex; +typedef struct ImGuiKeyRoutingData ImGuiKeyRoutingData; +struct ImGuiKeyRoutingData +{ + ImGuiKeyRoutingIndex NextEntryIndex; + ImU16 Mods; + ImU16 RoutingCurrScore; + ImU16 RoutingNextScore; + ImGuiID RoutingCurr; + ImGuiID RoutingNext; +}; +typedef struct ImGuiKeyRoutingTable ImGuiKeyRoutingTable; +typedef struct ImVector_ImGuiKeyRoutingData {int Size;int Capacity;ImGuiKeyRoutingData* Data;} ImVector_ImGuiKeyRoutingData; + +struct ImGuiKeyRoutingTable +{ + ImGuiKeyRoutingIndex Index[ImGuiKey_NamedKey_COUNT]; + ImVector_ImGuiKeyRoutingData Entries; + ImVector_ImGuiKeyRoutingData EntriesNext; +}; +typedef struct ImGuiKeyOwnerData ImGuiKeyOwnerData; +struct ImGuiKeyOwnerData +{ + ImGuiID OwnerCurr; + ImGuiID OwnerNext; + bool LockThisFrame; + bool LockUntilRelease; +}; +typedef enum { + ImGuiInputFlags_RepeatRateDefault = 1 << 1, + ImGuiInputFlags_RepeatRateNavMove = 1 << 2, + ImGuiInputFlags_RepeatRateNavTweak = 1 << 3, + ImGuiInputFlags_RepeatUntilRelease = 1 << 4, + ImGuiInputFlags_RepeatUntilKeyModsChange = 1 << 5, + ImGuiInputFlags_RepeatUntilKeyModsChangeFromNone = 1 << 6, + ImGuiInputFlags_RepeatUntilOtherKeyPress = 1 << 7, + ImGuiInputFlags_LockThisFrame = 1 << 20, + ImGuiInputFlags_LockUntilRelease = 1 << 21, + ImGuiInputFlags_CondHovered = 1 << 22, + ImGuiInputFlags_CondActive = 1 << 23, + ImGuiInputFlags_CondDefault_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive, + ImGuiInputFlags_RepeatRateMask_ = ImGuiInputFlags_RepeatRateDefault | ImGuiInputFlags_RepeatRateNavMove | ImGuiInputFlags_RepeatRateNavTweak, + ImGuiInputFlags_RepeatUntilMask_ = ImGuiInputFlags_RepeatUntilRelease | ImGuiInputFlags_RepeatUntilKeyModsChange | ImGuiInputFlags_RepeatUntilKeyModsChangeFromNone | ImGuiInputFlags_RepeatUntilOtherKeyPress, + ImGuiInputFlags_RepeatMask_ = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RepeatUntilMask_, + ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive, + ImGuiInputFlags_RouteTypeMask_ = ImGuiInputFlags_RouteActive | ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteAlways, + ImGuiInputFlags_RouteOptionsMask_ = ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive | ImGuiInputFlags_RouteUnlessBgFocused | ImGuiInputFlags_RouteFromRootWindow, + ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_RepeatMask_, + ImGuiInputFlags_SupportedByIsMouseClicked = ImGuiInputFlags_Repeat, + ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteTypeMask_ | ImGuiInputFlags_RouteOptionsMask_, + ImGuiInputFlags_SupportedBySetNextItemShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteTypeMask_ | ImGuiInputFlags_RouteOptionsMask_ | ImGuiInputFlags_Tooltip, + ImGuiInputFlags_SupportedBySetKeyOwner = ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease, + ImGuiInputFlags_SupportedBySetItemKeyOwner = ImGuiInputFlags_SupportedBySetKeyOwner | ImGuiInputFlags_CondMask_, +}ImGuiInputFlagsPrivate_; +typedef struct ImGuiListClipperRange ImGuiListClipperRange; +struct ImGuiListClipperRange +{ + int Min; + int Max; + bool PosToIndexConvert; + ImS8 PosToIndexOffsetMin; + ImS8 PosToIndexOffsetMax; +}; +typedef struct ImGuiListClipperData ImGuiListClipperData; +typedef struct ImVector_ImGuiListClipperRange {int Size;int Capacity;ImGuiListClipperRange* Data;} ImVector_ImGuiListClipperRange; + +struct ImGuiListClipperData +{ + ImGuiListClipper* ListClipper; + float LossynessOffset; + int StepNo; + int ItemsFrozen; + ImVector_ImGuiListClipperRange Ranges; +}; +typedef enum { + ImGuiActivateFlags_None = 0, + ImGuiActivateFlags_PreferInput = 1 << 0, + ImGuiActivateFlags_PreferTweak = 1 << 1, + ImGuiActivateFlags_TryToPreserveState = 1 << 2, + ImGuiActivateFlags_FromTabbing = 1 << 3, + ImGuiActivateFlags_FromShortcut = 1 << 4, + ImGuiActivateFlags_FromFocusApi = 1 << 5, +}ImGuiActivateFlags_; +typedef enum { + ImGuiScrollFlags_None = 0, + ImGuiScrollFlags_KeepVisibleEdgeX = 1 << 0, + ImGuiScrollFlags_KeepVisibleEdgeY = 1 << 1, + ImGuiScrollFlags_KeepVisibleCenterX = 1 << 2, + ImGuiScrollFlags_KeepVisibleCenterY = 1 << 3, + ImGuiScrollFlags_AlwaysCenterX = 1 << 4, + ImGuiScrollFlags_AlwaysCenterY = 1 << 5, + ImGuiScrollFlags_NoScrollParent = 1 << 6, + ImGuiScrollFlags_MaskX_ = ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleCenterX | ImGuiScrollFlags_AlwaysCenterX, + ImGuiScrollFlags_MaskY_ = ImGuiScrollFlags_KeepVisibleEdgeY | ImGuiScrollFlags_KeepVisibleCenterY | ImGuiScrollFlags_AlwaysCenterY, +}ImGuiScrollFlags_; +typedef enum { + ImGuiNavRenderCursorFlags_None = 0, + ImGuiNavRenderCursorFlags_Compact = 1 << 1, + ImGuiNavRenderCursorFlags_AlwaysDraw = 1 << 2, + ImGuiNavRenderCursorFlags_NoRounding = 1 << 3, +}ImGuiNavRenderCursorFlags_; +typedef enum { + ImGuiNavMoveFlags_None = 0, + ImGuiNavMoveFlags_LoopX = 1 << 0, + ImGuiNavMoveFlags_LoopY = 1 << 1, + ImGuiNavMoveFlags_WrapX = 1 << 2, + ImGuiNavMoveFlags_WrapY = 1 << 3, + ImGuiNavMoveFlags_WrapMask_ = ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_LoopY | ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_WrapY, + ImGuiNavMoveFlags_AllowCurrentNavId = 1 << 4, + ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, + ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, + ImGuiNavMoveFlags_Forwarded = 1 << 7, + ImGuiNavMoveFlags_DebugNoResult = 1 << 8, + ImGuiNavMoveFlags_FocusApi = 1 << 9, + ImGuiNavMoveFlags_IsTabbing = 1 << 10, + ImGuiNavMoveFlags_IsPageMove = 1 << 11, + ImGuiNavMoveFlags_Activate = 1 << 12, + ImGuiNavMoveFlags_NoSelect = 1 << 13, + ImGuiNavMoveFlags_NoSetNavCursorVisible = 1 << 14, + ImGuiNavMoveFlags_NoClearActiveId = 1 << 15, +}ImGuiNavMoveFlags_; +typedef enum { + ImGuiNavLayer_Main = 0, + ImGuiNavLayer_Menu = 1, + ImGuiNavLayer_COUNT +}ImGuiNavLayer; +struct ImGuiNavItemData +{ + ImGuiWindow* Window; + ImGuiID ID; + ImGuiID FocusScopeId; + ImRect_c RectRel; + ImGuiItemFlags ItemFlags; + float DistBox; + float DistCenter; + float DistAxial; + ImGuiSelectionUserData SelectionUserData; +}; +typedef struct ImGuiFocusScopeData ImGuiFocusScopeData; +struct ImGuiFocusScopeData +{ + ImGuiID ID; + ImGuiID WindowID; +}; +typedef enum { + ImGuiTypingSelectFlags_None = 0, + ImGuiTypingSelectFlags_AllowBackspace = 1 << 0, + ImGuiTypingSelectFlags_AllowSingleCharMode = 1 << 1, +}ImGuiTypingSelectFlags_; +struct ImGuiTypingSelectRequest +{ + ImGuiTypingSelectFlags Flags; + int SearchBufferLen; + const char* SearchBuffer; + bool SelectRequest; + bool SingleCharMode; + ImS8 SingleCharSize; +}; +struct ImGuiTypingSelectState +{ + ImGuiTypingSelectRequest Request; + char SearchBuffer[64]; + ImGuiID FocusScope; + int LastRequestFrame; + float LastRequestTime; + bool SingleCharModeLock; +}; +typedef enum { + ImGuiOldColumnFlags_None = 0, + ImGuiOldColumnFlags_NoBorder = 1 << 0, + ImGuiOldColumnFlags_NoResize = 1 << 1, + ImGuiOldColumnFlags_NoPreserveWidths = 1 << 2, + ImGuiOldColumnFlags_NoForceWithinWindow = 1 << 3, + ImGuiOldColumnFlags_GrowParentContentsSize = 1 << 4, +}ImGuiOldColumnFlags_; +struct ImGuiOldColumnData +{ + float OffsetNorm; + float OffsetNormBeforeResize; + ImGuiOldColumnFlags Flags; + ImRect_c ClipRect; +}; +typedef struct ImVector_ImGuiOldColumnData {int Size;int Capacity;ImGuiOldColumnData* Data;} ImVector_ImGuiOldColumnData; + +struct ImGuiOldColumns +{ + ImGuiID ID; + ImGuiOldColumnFlags Flags; + bool IsFirstFrame; + bool IsBeingResized; + int Current; + int Count; + float OffMinX, OffMaxX; + float LineMinY, LineMaxY; + float HostCursorPosY; + float HostCursorMaxPosX; + ImRect_c HostInitialClipRect; + ImRect_c HostBackupClipRect; + ImRect_c HostBackupParentWorkRect; + ImVector_ImGuiOldColumnData Columns; + ImDrawListSplitter Splitter; +}; +struct ImGuiBoxSelectState +{ + ImGuiID ID; + bool IsActive; + bool IsStarting; + bool IsStartedFromVoid; + bool IsStartedSetNavIdOnce; + bool RequestClear; + ImGuiKeyChord KeyMods : 16; + ImVec2_c StartPosRel; + ImVec2_c EndPosRel; + ImVec2_c ScrollAccum; + ImGuiWindow* Window; + bool UnclipMode; + ImRect_c UnclipRect; + ImRect_c UnclipRects[2]; + ImRect_c BoxSelectRectPrev; + ImRect_c BoxSelectRectCurr; +}; +struct ImGuiMultiSelectTempData +{ + ImGuiMultiSelectIO IO; + ImGuiMultiSelectState* Storage; + ImGuiID FocusScopeId; + ImGuiMultiSelectFlags Flags; + ImVec2_c ScopeRectMin; + ImVec2_c BackupCursorMaxPos; + ImGuiID BoxSelectId; + ImGuiKeyChord KeyMods; + ImS8 LoopRequestSetAll; + bool IsEndIO; + bool IsFocused; + bool IsKeyboardSetRange; + bool NavIdPassedBy; + bool RangeSrcPassedBy; + bool RangeDstPassedBy; +}; +struct ImGuiMultiSelectState +{ + ImGuiWindow* Window; + ImGuiID ID; + int LastFrameActive; + int LastSelectionSize; + ImS8 RangeSelected; + ImS8 NavIdSelected; + ImGuiSelectionUserData RangeSrcItem; + ImGuiSelectionUserData NavIdItem; +}; +typedef struct ImGuiViewportP ImGuiViewportP; +struct ImGuiViewportP +{ + ImGuiViewport _ImGuiViewport; + float BgFgDrawListsLastTimeActive[2]; + ImDrawList* BgFgDrawLists[2]; + ImDrawData DrawDataP; + ImDrawDataBuilder DrawDataBuilder; + ImVec2_c WorkInsetMin; + ImVec2_c WorkInsetMax; + ImVec2_c BuildWorkInsetMin; + ImVec2_c BuildWorkInsetMax; +}; +struct ImGuiWindowSettings +{ + ImGuiID ID; + ImVec2ih Pos; + ImVec2ih Size; + bool Collapsed; + bool IsChild; + bool WantApply; + bool WantDelete; +}; +struct ImGuiSettingsHandler +{ + const char* TypeName; + ImGuiID TypeHash; + void (*ClearAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler); + void (*ReadInitFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler); + void* (*ReadOpenFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name); + void (*ReadLineFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line); + void (*ApplyAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler); + void (*WriteAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf); + void* UserData; +}; +typedef enum { +ImGuiLocKey_VersionStr=0, +ImGuiLocKey_TableSizeOne=1, +ImGuiLocKey_TableSizeAllFit=2, +ImGuiLocKey_TableSizeAllDefault=3, +ImGuiLocKey_TableReset=4, +ImGuiLocKey_TableResetOrder=5, +ImGuiLocKey_TableResetVisibility=6, +ImGuiLocKey_WindowingMainMenuBar=7, +ImGuiLocKey_WindowingPopup=8, +ImGuiLocKey_WindowingUntitled=9, +ImGuiLocKey_OpenLink_s=10, +ImGuiLocKey_CopyLink=11, +ImGuiLocKey_COUNT=12, +}ImGuiLocKey; +struct ImGuiLocEntry +{ + ImGuiLocKey Key; + const char* Text; +}; +typedef void (*ImGuiErrorCallback)(ImGuiContext* ctx, void* user_data, const char* msg); +typedef enum { + ImGuiDebugLogFlags_None = 0, + ImGuiDebugLogFlags_EventError = 1 << 0, + ImGuiDebugLogFlags_EventActiveId = 1 << 1, + ImGuiDebugLogFlags_EventFocus = 1 << 2, + ImGuiDebugLogFlags_EventPopup = 1 << 3, + ImGuiDebugLogFlags_EventNav = 1 << 4, + ImGuiDebugLogFlags_EventClipper = 1 << 5, + ImGuiDebugLogFlags_EventSelection = 1 << 6, + ImGuiDebugLogFlags_EventIO = 1 << 7, + ImGuiDebugLogFlags_EventFont = 1 << 8, + ImGuiDebugLogFlags_EventInputRouting = 1 << 9, + ImGuiDebugLogFlags_EventDocking = 1 << 10, + ImGuiDebugLogFlags_EventViewport = 1 << 11, + ImGuiDebugLogFlags_EventTable = 1 << 12, + ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventError | ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventTable | ImGuiDebugLogFlags_EventIO | ImGuiDebugLogFlags_EventFont | ImGuiDebugLogFlags_EventInputRouting | ImGuiDebugLogFlags_EventDocking | ImGuiDebugLogFlags_EventViewport, + ImGuiDebugLogFlags_OutputToTTY = 1 << 20, + ImGuiDebugLogFlags_OutputToDebugger = 1 << 21, + ImGuiDebugLogFlags_OutputToTestEngine = 1 << 22, +}ImGuiDebugLogFlags_; +typedef struct ImGuiDebugAllocEntry ImGuiDebugAllocEntry; +struct ImGuiDebugAllocEntry +{ + int FrameCount; + ImS16 AllocCount; + ImS16 FreeCount; +}; +typedef struct ImGuiDebugAllocInfo ImGuiDebugAllocInfo; +struct ImGuiDebugAllocInfo +{ + int TotalAllocCount; + int TotalFreeCount; + ImS16 LastEntriesIdx; + ImGuiDebugAllocEntry LastEntriesBuf[6]; +}; +struct ImGuiMetricsConfig +{ + bool ShowDebugLog; + bool ShowIDStackTool; + bool ShowWindowsRects; + bool ShowWindowsBeginOrder; + bool ShowTablesRects; + bool ShowDrawCmdMesh; + bool ShowDrawCmdBoundingBoxes; + bool ShowTextEncodingViewer; + bool ShowTextureUsedRect; + int ShowWindowsRectsType; + int ShowTablesRectsType; + int HighlightMonitorIdx; + ImGuiID HighlightViewportID; + bool ShowFontPreview; +}; +typedef struct ImGuiStackLevelInfo ImGuiStackLevelInfo; +struct ImGuiStackLevelInfo +{ + ImGuiID ID; + ImS8 QueryFrameCount; + bool QuerySuccess; + ImS8 DataType; + int DescOffset; +}; +typedef struct ImGuiDebugItemPathQuery ImGuiDebugItemPathQuery; +typedef struct ImVector_ImGuiStackLevelInfo {int Size;int Capacity;ImGuiStackLevelInfo* Data;} ImVector_ImGuiStackLevelInfo; + +struct ImGuiDebugItemPathQuery +{ + ImGuiID MainID; + bool Active; + bool Complete; + ImS8 Step; + ImVector_ImGuiStackLevelInfo Results; + ImGuiTextBuffer ResultsDescBuf; + ImGuiTextBuffer ResultPathBuf; +}; +typedef struct ImGuiIDStackTool ImGuiIDStackTool; +struct ImGuiIDStackTool +{ + bool OptHexEncodeNonAsciiChars; + bool OptCopyToClipboardOnCtrlC; + int LastActiveFrame; + float CopyToClipboardLastTime; +}; +typedef void (*ImGuiContextHookCallback)(ImGuiContext* ctx, ImGuiContextHook* hook); +typedef enum { ImGuiContextHookType_NewFramePre, ImGuiContextHookType_NewFramePost, ImGuiContextHookType_EndFramePre, ImGuiContextHookType_EndFramePost, ImGuiContextHookType_RenderPre, ImGuiContextHookType_RenderPost, ImGuiContextHookType_Shutdown, ImGuiContextHookType_PendingRemoval_ }ImGuiContextHookType; +struct ImGuiContextHook +{ + ImGuiID HookId; + ImGuiContextHookType Type; + ImGuiID Owner; + ImGuiContextHookCallback Callback; + void* UserData; +}; +typedef void (*ImGuiDemoMarkerCallback)(const char* file, int line, const char* section); +typedef struct ImVector_ImFontAtlasPtr {int Size;int Capacity;ImFontAtlas** Data;} ImVector_ImFontAtlasPtr; + +typedef struct ImVector_ImGuiInputEvent {int Size;int Capacity;ImGuiInputEvent* Data;} ImVector_ImGuiInputEvent; + +typedef struct ImVector_ImGuiWindowPtr {int Size;int Capacity;ImGuiWindow** Data;} ImVector_ImGuiWindowPtr; + +typedef struct ImVector_ImGuiWindowStackData {int Size;int Capacity;ImGuiWindowStackData* Data;} ImVector_ImGuiWindowStackData; + +typedef struct ImVector_ImGuiColorMod {int Size;int Capacity;ImGuiColorMod* Data;} ImVector_ImGuiColorMod; + +typedef struct ImVector_ImGuiStyleMod {int Size;int Capacity;ImGuiStyleMod* Data;} ImVector_ImGuiStyleMod; + +typedef struct ImVector_ImFontStackData {int Size;int Capacity;ImFontStackData* Data;} ImVector_ImFontStackData; + +typedef struct ImVector_ImGuiFocusScopeData {int Size;int Capacity;ImGuiFocusScopeData* Data;} ImVector_ImGuiFocusScopeData; + +typedef struct ImVector_ImGuiItemFlags {int Size;int Capacity;ImGuiItemFlags* Data;} ImVector_ImGuiItemFlags; + +typedef struct ImVector_ImGuiGroupData {int Size;int Capacity;ImGuiGroupData* Data;} ImVector_ImGuiGroupData; + +typedef struct ImVector_ImGuiPopupData {int Size;int Capacity;ImGuiPopupData* Data;} ImVector_ImGuiPopupData; + +typedef struct ImVector_ImGuiTreeNodeStackData {int Size;int Capacity;ImGuiTreeNodeStackData* Data;} ImVector_ImGuiTreeNodeStackData; + +typedef struct ImVector_ImGuiViewportPPtr {int Size;int Capacity;ImGuiViewportP** Data;} ImVector_ImGuiViewportPPtr; + +typedef struct ImVector_unsigned_char {int Size;int Capacity;unsigned char* Data;} ImVector_unsigned_char; + +typedef struct ImVector_ImGuiListClipperData {int Size;int Capacity;ImGuiListClipperData* Data;} ImVector_ImGuiListClipperData; + +typedef struct ImVector_ImGuiTableTempData {int Size;int Capacity;ImGuiTableTempData* Data;} ImVector_ImGuiTableTempData; + +typedef struct ImVector_ImGuiTable {int Size;int Capacity;ImGuiTable* Data;} ImVector_ImGuiTable; + +typedef struct ImPool_ImGuiTable {ImVector_ImGuiTable Buf;ImGuiStorage Map;ImPoolIdx FreeIdx;ImPoolIdx AliveCount;} ImPool_ImGuiTable; + +typedef struct ImVector_ImGuiTabBar {int Size;int Capacity;ImGuiTabBar* Data;} ImVector_ImGuiTabBar; + +typedef struct ImPool_ImGuiTabBar {ImVector_ImGuiTabBar Buf;ImGuiStorage Map;ImPoolIdx FreeIdx;ImPoolIdx AliveCount;} ImPool_ImGuiTabBar; + +typedef struct ImVector_ImGuiPtrOrIndex {int Size;int Capacity;ImGuiPtrOrIndex* Data;} ImVector_ImGuiPtrOrIndex; + +typedef struct ImVector_ImGuiShrinkWidthItem {int Size;int Capacity;ImGuiShrinkWidthItem* Data;} ImVector_ImGuiShrinkWidthItem; + +typedef struct ImVector_ImGuiMultiSelectTempData {int Size;int Capacity;ImGuiMultiSelectTempData* Data;} ImVector_ImGuiMultiSelectTempData; + +typedef struct ImVector_ImGuiMultiSelectState {int Size;int Capacity;ImGuiMultiSelectState* Data;} ImVector_ImGuiMultiSelectState; + +typedef struct ImPool_ImGuiMultiSelectState {ImVector_ImGuiMultiSelectState Buf;ImGuiStorage Map;ImPoolIdx FreeIdx;ImPoolIdx AliveCount;} ImPool_ImGuiMultiSelectState; + +typedef struct ImVector_ImGuiID {int Size;int Capacity;ImGuiID* Data;} ImVector_ImGuiID; + +typedef struct ImVector_ImGuiSettingsHandler {int Size;int Capacity;ImGuiSettingsHandler* Data;} ImVector_ImGuiSettingsHandler; + +typedef struct ImChunkStream_ImGuiWindowSettings {ImVector_char Buf;} ImChunkStream_ImGuiWindowSettings; + +typedef struct ImChunkStream_ImGuiTableSettings {ImVector_char Buf;} ImChunkStream_ImGuiTableSettings; + +typedef struct ImVector_ImGuiContextHook {int Size;int Capacity;ImGuiContextHook* Data;} ImVector_ImGuiContextHook; + +struct ImGuiContext +{ + bool Initialized; + bool WithinFrameScope; + bool WithinFrameScopeWithImplicitWindow; + bool TestEngineHookItems; + int FrameCount; + int FrameCountEnded; + int FrameCountRendered; + double Time; + char ContextName[16]; + ImGuiIO IO; + ImGuiPlatformIO PlatformIO; + ImGuiStyle Style; + ImVector_ImFontAtlasPtr FontAtlases; + ImFont* Font; + ImFontBaked* FontBaked; + float FontSize; + float FontSizeBase; + float FontBakedScale; + float FontRasterizerDensity; + float CurrentDpiScale; + ImDrawListSharedData DrawListSharedData; + ImGuiID WithinEndChildID; + ImGuiID WithinEndPopupID; + void* TestEngine; + ImVector_ImGuiInputEvent InputEventsQueue; + ImVector_ImGuiInputEvent InputEventsTrail; + ImGuiMouseSource InputEventsNextMouseSource; + ImU32 InputEventsNextEventId; + ImVector_ImGuiWindowPtr Windows; + ImVector_ImGuiWindowPtr WindowsFocusOrder; + ImVector_ImGuiWindowPtr WindowsTempSortBuffer; + ImVector_ImGuiWindowStackData CurrentWindowStack; + ImGuiStorage WindowsById; + int WindowsActiveCount; + float WindowsBorderHoverPadding; + ImGuiID DebugBreakInWindow; + ImGuiWindow* CurrentWindow; + ImGuiWindow* HoveredWindow; + ImGuiWindow* HoveredWindowUnderMovingWindow; + ImGuiWindow* HoveredWindowBeforeClear; + ImGuiWindow* MovingWindow; + ImGuiWindow* WheelingWindow; + ImVec2_c WheelingWindowRefMousePos; + int WheelingWindowStartFrame; + int WheelingWindowScrolledFrame; + float WheelingWindowReleaseTimer; + ImVec2_c WheelingWindowWheelRemainder; + ImVec2_c WheelingAxisAvg; + ImGuiID DebugDrawIdConflictsId; + ImGuiID DebugHookIdInfoId; + ImGuiID HoveredId; + ImGuiID HoveredIdPreviousFrame; + int HoveredIdPreviousFrameItemCount; + float HoveredIdTimer; + float HoveredIdNotActiveTimer; + bool HoveredIdAllowOverlap; + bool HoveredIdIsDisabled; + bool ItemUnclipByLog; + ImGuiID ActiveId; + ImGuiID ActiveIdIsAlive; + float ActiveIdTimer; + bool ActiveIdIsJustActivated; + bool ActiveIdAllowOverlap; + bool ActiveIdNoClearOnFocusLoss; + bool ActiveIdHasBeenPressedBefore; + bool ActiveIdHasBeenEditedBefore; + bool ActiveIdHasBeenEditedThisFrame; + bool ActiveIdFromShortcut; + ImS8 ActiveIdMouseButton; + ImGuiID ActiveIdDisabledId; + ImVec2_c ActiveIdClickOffset; + ImGuiInputSource ActiveIdSource; + ImGuiWindow* ActiveIdWindow; + ImGuiID ActiveIdPreviousFrame; + ImGuiDeactivatedItemData DeactivatedItemData; + ImGuiDataTypeStorage ActiveIdValueOnActivation; + ImGuiID LastActiveId; + float LastActiveIdTimer; + double LastKeyModsChangeTime; + double LastKeyModsChangeFromNoneTime; + double LastKeyboardKeyPressTime; + ImBitArrayForNamedKeys KeysMayBeCharInput; + ImGuiKeyOwnerData KeysOwnerData[ImGuiKey_NamedKey_COUNT]; + ImGuiKeyRoutingTable KeysRoutingTable; + ImU32 ActiveIdUsingNavDirMask; + bool ActiveIdUsingAllKeyboardKeys; + ImGuiKeyChord DebugBreakInShortcutRouting; + ImGuiID CurrentFocusScopeId; + ImGuiItemFlags CurrentItemFlags; + ImGuiID DebugLocateId; + ImGuiNextItemData NextItemData; + ImGuiLastItemData LastItemData; + ImGuiNextWindowData NextWindowData; + bool DebugShowGroupRects; + bool GcCompactAll; + ImGuiCol DebugFlashStyleColorIdx; + ImVector_ImGuiColorMod ColorStack; + ImVector_ImGuiStyleMod StyleVarStack; + ImVector_ImFontStackData FontStack; + ImVector_ImGuiFocusScopeData FocusScopeStack; + ImVector_ImGuiItemFlags ItemFlagsStack; + ImVector_ImGuiGroupData GroupStack; + ImVector_ImGuiPopupData OpenPopupStack; + ImVector_ImGuiPopupData BeginPopupStack; + ImVector_ImGuiTreeNodeStackData TreeNodeStack; + ImVector_ImGuiViewportPPtr Viewports; + bool NavCursorVisible; + bool NavHighlightItemUnderNav; + bool NavMousePosDirty; + bool NavIdIsAlive; + ImGuiID NavId; + ImGuiWindow* NavWindow; + ImGuiID NavFocusScopeId; + ImGuiNavLayer NavLayer; + ImGuiItemFlags NavIdItemFlags; + ImGuiID NavActivateId; + ImGuiID NavActivateDownId; + ImGuiID NavActivatePressedId; + ImGuiActivateFlags NavActivateFlags; + ImVector_ImGuiFocusScopeData NavFocusRoute; + ImGuiID NavHighlightActivatedId; + float NavHighlightActivatedTimer; + ImGuiID NavOpenContextMenuItemId; + ImGuiID NavOpenContextMenuWindowId; + ImGuiID NavNextActivateId; + ImGuiActivateFlags NavNextActivateFlags; + ImGuiInputSource NavInputSource; + ImGuiSelectionUserData NavLastValidSelectionUserData; + ImS8 NavCursorHideFrames; + bool NavAnyRequest; + bool NavInitRequest; + bool NavInitRequestFromMove; + ImGuiNavItemData NavInitResult; + bool NavMoveSubmitted; + bool NavMoveScoringItems; + bool NavMoveForwardToNextFrame; + ImGuiNavMoveFlags NavMoveFlags; + ImGuiScrollFlags NavMoveScrollFlags; + ImGuiKeyChord NavMoveKeyMods; + ImGuiDir NavMoveDir; + ImGuiDir NavMoveDirForDebug; + ImGuiDir NavMoveClipDir; + ImRect_c NavScoringRect; + ImRect_c NavScoringNoClipRect; + int NavScoringDebugCount; + int NavTabbingDir; + int NavTabbingCounter; + ImGuiNavItemData NavMoveResultLocal; + ImGuiNavItemData NavMoveResultLocalVisible; + ImGuiNavItemData NavMoveResultOther; + ImGuiNavItemData NavTabbingResultFirst; + ImGuiID NavJustMovedFromFocusScopeId; + ImGuiID NavJustMovedToId; + ImGuiID NavJustMovedToFocusScopeId; + ImGuiKeyChord NavJustMovedToKeyMods; + bool NavJustMovedToIsTabbing; + bool NavJustMovedToHasSelectionData; + bool ConfigNavEnableTabbing; + bool ConfigNavWindowingWithGamepad; + ImGuiKeyChord ConfigNavWindowingKeyNext; + ImGuiKeyChord ConfigNavWindowingKeyPrev; + ImGuiWindow* NavWindowingTarget; + ImGuiWindow* NavWindowingTargetAnim; + ImGuiWindow* NavWindowingListWindow; + float NavWindowingTimer; + float NavWindowingHighlightAlpha; + ImGuiInputSource NavWindowingInputSource; + bool NavWindowingToggleLayer; + ImGuiKey NavWindowingToggleKey; + ImVec2_c NavWindowingAccumDeltaPos; + ImVec2_c NavWindowingAccumDeltaSize; + float DimBgRatio; + bool DragDropActive; + bool DragDropWithinSource; + bool DragDropWithinTarget; + ImGuiDragDropFlags DragDropSourceFlags; + int DragDropSourceFrameCount; + int DragDropMouseButton; + ImGuiPayload DragDropPayload; + ImRect_c DragDropTargetRect; + ImRect_c DragDropTargetClipRect; + ImGuiID DragDropTargetId; + ImGuiID DragDropTargetFullViewport; + ImGuiDragDropFlags DragDropAcceptFlagsCurr; + ImGuiDragDropFlags DragDropAcceptFlagsPrev; + float DragDropAcceptIdCurrRectSurface; + ImGuiID DragDropAcceptIdCurr; + ImGuiID DragDropAcceptIdPrev; + int DragDropAcceptFrameCount; + ImGuiID DragDropHoldJustPressedId; + ImVector_unsigned_char DragDropPayloadBufHeap; + unsigned char DragDropPayloadBufLocal[16]; + int ClipperTempDataStacked; + ImVector_ImGuiListClipperData ClipperTempData; + ImGuiTable* CurrentTable; + ImGuiID DebugBreakInTable; + int TablesTempDataStacked; + ImVector_ImGuiTableTempData TablesTempData; + ImPool_ImGuiTable Tables; + ImVector_float TablesLastTimeActive; + ImVector_ImDrawChannel DrawChannelsTempMergeBuffer; + ImGuiTabBar* CurrentTabBar; + ImPool_ImGuiTabBar TabBars; + ImVector_ImGuiPtrOrIndex CurrentTabBarStack; + ImVector_ImGuiShrinkWidthItem ShrinkWidthBuffer; + ImGuiBoxSelectState BoxSelectState; + ImGuiMultiSelectTempData* CurrentMultiSelect; + int MultiSelectTempDataStacked; + ImVector_ImGuiMultiSelectTempData MultiSelectTempData; + ImPool_ImGuiMultiSelectState MultiSelectStorage; + ImGuiID HoverItemDelayId; + ImGuiID HoverItemDelayIdPreviousFrame; + float HoverItemDelayTimer; + float HoverItemDelayClearTimer; + ImGuiID HoverItemUnlockedStationaryId; + ImGuiID HoverWindowUnlockedStationaryId; + ImGuiMouseCursor MouseCursor; + float MouseStationaryTimer; + ImVec2_c MouseLastValidPos; + ImGuiInputTextState InputTextState; + ImGuiTextIndex InputTextLineIndex; + ImGuiInputTextDeactivatedState InputTextDeactivatedState; + ImFontBaked InputTextPasswordFontBackupBaked; + ImFontFlags InputTextPasswordFontBackupFlags; + ImGuiID InputTextReactivateId; + ImGuiID TempInputId; + ImGuiDataTypeStorage DataTypeZeroValue; + int BeginMenuDepth; + int BeginComboDepth; + ImGuiColorEditFlags ColorEditOptions; + ImGuiID ColorEditCurrentID; + ImGuiID ColorEditSavedID; + float ColorEditSavedHue; + float ColorEditSavedSat; + ImU32 ColorEditSavedColor; + ImVec4_c ColorPickerRef; + ImGuiComboPreviewData ComboPreviewData; + ImRect_c WindowResizeBorderExpectedRect; + bool WindowResizeRelativeMode; + short ScrollbarSeekMode; + float ScrollbarClickDeltaToGrabCenter; + float SliderGrabClickOffset; + float SliderCurrentAccum; + bool SliderCurrentAccumDirty; + bool DragCurrentAccumDirty; + float DragCurrentAccum; + float DragSpeedDefaultRatio; + float DisabledAlphaBackup; + short DisabledStackSize; + short TooltipOverrideCount; + ImGuiWindow* TooltipPreviousWindow; + ImVector_char ClipboardHandlerData; + ImVector_ImGuiID MenusIdSubmittedThisFrame; + ImGuiTypingSelectState TypingSelectState; + ImGuiPlatformImeData PlatformImeData; + ImGuiPlatformImeData PlatformImeDataPrev; + ImVector_ImTextureDataPtr UserTextures; + bool SettingsLoaded; + float SettingsDirtyTimer; + ImGuiTextBuffer SettingsIniData; + ImVector_ImGuiSettingsHandler SettingsHandlers; + ImChunkStream_ImGuiWindowSettings SettingsWindows; + ImChunkStream_ImGuiTableSettings SettingsTables; + ImVector_ImGuiContextHook Hooks; + ImGuiID HookIdNext; + ImGuiDemoMarkerCallback DemoMarkerCallback; + const char* LocalizationTable[ImGuiLocKey_COUNT]; + bool LogEnabled; + bool LogLineFirstItem; + ImGuiLogFlags LogFlags; + ImGuiWindow* LogWindow; + ImFileHandle LogFile; + ImGuiTextBuffer LogBuffer; + const char* LogNextPrefix; + const char* LogNextSuffix; + float LogLinePosY; + int LogDepthRef; + int LogDepthToExpand; + int LogDepthToExpandDefault; + ImGuiErrorCallback ErrorCallback; + void* ErrorCallbackUserData; + ImVec2_c ErrorTooltipLockedPos; + bool ErrorFirst; + int ErrorCountCurrentFrame; + ImGuiErrorRecoveryState StackSizesInNewFrame; + ImGuiErrorRecoveryState*StackSizesInBeginForCurrentWindow; + int DebugDrawIdConflictsCount; + ImGuiDebugLogFlags DebugLogFlags; + ImGuiTextBuffer DebugLogBuf; + ImGuiTextIndex DebugLogIndex; + int DebugLogSkippedErrors; + ImGuiDebugLogFlags DebugLogAutoDisableFlags; + ImU8 DebugLogAutoDisableFrames; + ImU8 DebugLocateFrames; + bool DebugBreakInLocateId; + ImGuiKeyChord DebugBreakKeyChord; + ImS8 DebugBeginReturnValueCullDepth; + bool DebugItemPickerActive; + ImU8 DebugItemPickerMouseButton; + ImGuiID DebugItemPickerBreakId; + float DebugFlashStyleColorTime; + ImVec4_c DebugFlashStyleColorBackup; + ImGuiMetricsConfig DebugMetricsConfig; + ImGuiDebugItemPathQuery DebugItemPathQuery; + ImGuiIDStackTool DebugIDStackTool; + ImGuiDebugAllocInfo DebugAllocInfo; + float FramerateSecPerFrame[60]; + int FramerateSecPerFrameIdx; + int FramerateSecPerFrameCount; + float FramerateSecPerFrameAccum; + int WantCaptureMouseNextFrame; + int WantCaptureKeyboardNextFrame; + int WantTextInputNextFrame; + ImVector_char TempBuffer; + char TempKeychordName[64]; +}; +struct ImGuiWindowTempData +{ + ImVec2_c CursorPos; + ImVec2_c CursorPosPrevLine; + ImVec2_c CursorStartPos; + ImVec2_c CursorMaxPos; + ImVec2_c IdealMaxPos; + ImVec2_c CurrLineSize; + ImVec2_c PrevLineSize; + float CurrLineTextBaseOffset; + float PrevLineTextBaseOffset; + bool IsSameLine; + bool IsSetPos; + ImVec1 Indent; + ImVec1 ColumnsOffset; + ImVec1 GroupOffset; + ImVec2_c CursorStartPosLossyness; + ImGuiNavLayer NavLayerCurrent; + short NavLayersActiveMask; + short NavLayersActiveMaskNext; + bool NavIsScrollPushableX; + bool NavHideHighlightOneFrame; + bool NavWindowHasScrollY; + bool MenuBarAppending; + ImVec2_c MenuBarOffset; + ImGuiMenuColumns MenuColumns; + int TreeDepth; + ImU32 TreeHasStackDataDepthMask; + ImU32 TreeRecordsClippedNodesY2Mask; + ImVector_ImGuiWindowPtr ChildWindows; + ImGuiStorage* StateStorage; + ImGuiOldColumns* CurrentColumns; + int CurrentTableIdx; + ImGuiLayoutType LayoutType; + ImGuiLayoutType ParentLayoutType; + ImU32 ModalDimBgColor; + ImGuiItemStatusFlags WindowItemStatusFlags; + ImGuiItemStatusFlags ChildItemStatusFlags; + float ItemWidth; + float ItemWidthDefault; + float TextWrapPos; + ImVector_float ItemWidthStack; + ImVector_float TextWrapPosStack; +}; +typedef struct ImVector_ImGuiOldColumns {int Size;int Capacity;ImGuiOldColumns* Data;} ImVector_ImGuiOldColumns; + +struct ImGuiWindow +{ + ImGuiContext* Ctx; + char* Name; + ImGuiID ID; + ImGuiWindowFlags Flags; + ImGuiChildFlags ChildFlags; + ImGuiViewportP* Viewport; + ImVec2_c Pos; + ImVec2_c Size; + ImVec2_c SizeFull; + ImVec2_c ContentSize; + ImVec2_c ContentSizeIdeal; + ImVec2_c ContentSizeExplicit; + ImVec2_c WindowPadding; + float WindowRounding; + float WindowBorderSize; + float TitleBarHeight, MenuBarHeight; + float DecoOuterSizeX1, DecoOuterSizeY1; + float DecoOuterSizeX2, DecoOuterSizeY2; + float DecoInnerSizeX1, DecoInnerSizeY1; + int NameBufLen; + ImGuiID MoveId; + ImGuiID ChildId; + ImGuiID PopupId; + ImVec2_c Scroll; + ImVec2_c ScrollMax; + ImVec2_c ScrollTarget; + ImVec2_c ScrollTargetCenterRatio; + ImVec2_c ScrollTargetEdgeSnapDist; + ImVec2_c ScrollbarSizes; + bool ScrollbarX, ScrollbarY; + bool ScrollbarXStabilizeEnabled; + ImU8 ScrollbarXStabilizeToggledHistory; + bool Active; + bool WasActive; + bool WriteAccessed; + bool Collapsed; + bool WantCollapseToggle; + bool SkipItems; + bool SkipRefresh; + bool Appearing; + bool Hidden; + bool IsFallbackWindow; + bool IsExplicitChild; + bool HasCloseButton; + signed char ResizeBorderHovered; + signed char ResizeBorderHeld; + short BeginCount; + short BeginCountPreviousFrame; + short BeginOrderWithinParent; + short BeginOrderWithinContext; + short FocusOrder; + ImGuiDir AutoPosLastDirection; + ImS8 AutoFitFramesX, AutoFitFramesY; + bool AutoFitOnlyGrows; + ImS8 HiddenFramesCanSkipItems; + ImS8 HiddenFramesCannotSkipItems; + ImS8 HiddenFramesForRenderOnly; + ImS8 DisableInputsFrames; + ImGuiWindowBgClickFlags BgClickFlags : 8; + ImGuiCond SetWindowPosAllowFlags : 8; + ImGuiCond SetWindowSizeAllowFlags : 8; + ImGuiCond SetWindowCollapsedAllowFlags : 8; + ImVec2_c SetWindowPosVal; + ImVec2_c SetWindowPosPivot; + ImVector_ImGuiID IDStack; + ImGuiWindowTempData DC; + ImRect_c OuterRectClipped; + ImRect_c InnerRect; + ImRect_c InnerClipRect; + ImRect_c WorkRect; + ImRect_c ParentWorkRect; + ImRect_c ClipRect; + ImRect_c ContentRegionRect; + ImVec2ih HitTestHoleSize; + ImVec2ih HitTestHoleOffset; + int LastFrameActive; + float LastTimeActive; + ImGuiStorage StateStorage; + ImVector_ImGuiOldColumns ColumnsStorage; + float FontWindowScale; + float FontWindowScaleParents; + float FontRefSize; + int SettingsOffset; + ImDrawList* DrawList; + ImDrawList DrawListInst; + ImGuiWindow* ParentWindow; + ImGuiWindow* ParentWindowInBeginStack; + ImGuiWindow* RootWindow; + ImGuiWindow* RootWindowPopupTree; + ImGuiWindow* RootWindowForTitleBarHighlight; + ImGuiWindow* RootWindowForNav; + ImGuiWindow* ParentWindowForFocusRoute; + ImGuiWindow* NavLastChildNavWindow; + ImGuiID NavLastIds[ImGuiNavLayer_COUNT]; + ImRect_c NavRectRel[ImGuiNavLayer_COUNT]; + ImVec2_c NavPreferredScoringPosRel[ImGuiNavLayer_COUNT]; + ImGuiID NavRootFocusScopeId; + int MemoryDrawListIdxCapacity; + int MemoryDrawListVtxCapacity; + bool MemoryCompacted; +}; +typedef enum { + ImGuiTabBarFlags_DockNode = 1 << 20, + ImGuiTabBarFlags_IsFocused = 1 << 21, + ImGuiTabBarFlags_SaveSettings = 1 << 22, +}ImGuiTabBarFlagsPrivate_; +typedef enum { + ImGuiTabItemFlags_SectionMask_ = ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing, + ImGuiTabItemFlags_NoCloseButton = 1 << 20, + ImGuiTabItemFlags_Button = 1 << 21, + ImGuiTabItemFlags_Invisible = 1 << 22, +}ImGuiTabItemFlagsPrivate_; +struct ImGuiTabItem +{ + ImGuiID ID; + ImGuiTabItemFlags Flags; + int LastFrameVisible; + int LastFrameSelected; + float Offset; + float Width; + float ContentWidth; + float RequestedWidth; + ImS32 NameOffset; + ImS16 BeginOrder; + ImS16 IndexDuringLayout; + bool WantClose; +}; +typedef struct ImVector_ImGuiTabItem {int Size;int Capacity;ImGuiTabItem* Data;} ImVector_ImGuiTabItem; + +struct ImGuiTabBar +{ + ImGuiWindow* Window; + ImVector_ImGuiTabItem Tabs; + ImGuiTabBarFlags Flags; + ImGuiID ID; + ImGuiID SelectedTabId; + ImGuiID NextSelectedTabId; + ImGuiID NextScrollToTabId; + ImGuiID VisibleTabId; + int CurrFrameVisible; + int PrevFrameVisible; + ImRect_c BarRect; + float BarRectPrevWidth; + float CurrTabsContentsHeight; + float PrevTabsContentsHeight; + float WidthAllTabs; + float WidthAllTabsIdeal; + float ScrollingAnim; + float ScrollingTarget; + float ScrollingTargetDistToVisibility; + float ScrollingSpeed; + float ScrollingRectMinX; + float ScrollingRectMaxX; + float SeparatorMinX; + float SeparatorMaxX; + ImGuiID ReorderRequestTabId; + ImS16 ReorderRequestOffset; + ImS8 BeginCount; + bool WantLayout; + bool VisibleTabWasSubmitted; + bool TabsAddedNew; + bool ScrollButtonEnabled; + ImS16 TabsActiveCount; + ImS16 LastTabItemIdx; + float ItemSpacingY; + ImVec2_c FramePadding; + ImVec2_c BackupCursorPos; + ImGuiTextBuffer TabsNames; +}; +struct ImGuiTableColumn +{ + ImGuiTableColumnFlags Flags; + float WidthGiven; + float MinX; + float MaxX; + float WidthRequest; + float WidthAuto; + float WidthMax; + float StretchWeight; + float InitStretchWeightOrWidth; + ImRect_c ClipRect; + ImGuiID ID; + ImGuiID UserData; + float WorkMinX; + float WorkMaxX; + float ItemWidth; + float ContentMaxXFrozen; + float ContentMaxXUnfrozen; + float ContentMaxXHeadersUsed; + float ContentMaxXHeadersIdeal; + ImS16 NameOffset; + ImGuiTableColumnIdx DisplayOrder; + ImGuiTableColumnIdx IndexWithinEnabledSet; + ImGuiTableColumnIdx PrevEnabledColumn; + ImGuiTableColumnIdx NextEnabledColumn; + ImGuiTableColumnIdx SortOrder; + ImGuiTableDrawChannelIdx DrawChannelCurrent; + ImGuiTableDrawChannelIdx DrawChannelFrozen; + ImGuiTableDrawChannelIdx DrawChannelUnfrozen; + bool IsEnabled; + bool IsUserEnabled; + bool IsUserEnabledNextFrame; + bool IsVisibleX; + bool IsVisibleY; + bool IsRequestOutput; + bool IsSkipItems; + bool IsPreserveWidthAuto; + ImS8 NavLayerCurrent; + ImU8 AutoFitQueue : 4; + ImU8 CannotSkipItemsQueue : 4; + ImU8 SortDirection : 2; + ImU8 SortDirectionsAvailCount : 2; + ImU8 SortDirectionsAvailMask : 4; + ImU8 SortDirectionsAvailList; +}; +typedef struct ImGuiTableCellData ImGuiTableCellData; +struct ImGuiTableCellData +{ + ImU32 BgColor; + ImGuiTableColumnIdx Column; +}; +struct ImGuiTableHeaderData +{ + ImGuiTableColumnIdx Index; + ImU32 TextColor; + ImU32 BgColor0; + ImU32 BgColor1; +}; +struct ImGuiTableInstanceData +{ + ImGuiID TableInstanceID; + float LastOuterHeight; + float LastTopHeadersRowHeight; + float LastFrozenHeight; + int HoveredRowLast; + int HoveredRowNext; +}; +typedef struct ImSpan_ImGuiTableColumn {ImGuiTableColumn* Data;ImGuiTableColumn* DataEnd;} ImSpan_ImGuiTableColumn; + +typedef struct ImSpan_ImGuiTableColumnIdx {ImGuiTableColumnIdx* Data;ImGuiTableColumnIdx* DataEnd;} ImSpan_ImGuiTableColumnIdx; + +typedef struct ImSpan_ImGuiTableCellData {ImGuiTableCellData* Data;ImGuiTableCellData* DataEnd;} ImSpan_ImGuiTableCellData; + +typedef struct ImVector_ImGuiTableInstanceData {int Size;int Capacity;ImGuiTableInstanceData* Data;} ImVector_ImGuiTableInstanceData; + +typedef struct ImVector_ImGuiTableColumnSortSpecs {int Size;int Capacity;ImGuiTableColumnSortSpecs* Data;} ImVector_ImGuiTableColumnSortSpecs; + +struct ImGuiTable +{ + ImGuiID ID; + ImGuiTableFlags Flags; + void* RawData; + ImGuiTableTempData* TempData; + ImSpan_ImGuiTableColumn Columns; + ImSpan_ImGuiTableColumnIdx DisplayOrderToIndex; + ImSpan_ImGuiTableCellData RowCellData; + ImBitArrayPtr EnabledMaskByDisplayOrder; + ImBitArrayPtr EnabledMaskByIndex; + ImBitArrayPtr VisibleMaskByIndex; + ImGuiTableFlags SettingsLoadedFlags; + int SettingsOffset; + int LastFrameActive; + int ColumnsCount; + int CurrentRow; + int CurrentColumn; + ImS16 InstanceCurrent; + ImS16 InstanceInteracted; + float RowPosY1; + float RowPosY2; + float RowMinHeight; + float RowCellPaddingY; + float RowTextBaseline; + float RowIndentOffsetX; + ImGuiTableRowFlags RowFlags : 16; + ImGuiTableRowFlags LastRowFlags : 16; + int RowBgColorCounter; + ImU32 RowBgColor[2]; + ImU32 BorderColorStrong; + ImU32 BorderColorLight; + float BorderX1; + float BorderX2; + float HostIndentX; + float MinColumnWidth; + float OuterPaddingX; + float CellPaddingX; + float CellSpacingX1; + float CellSpacingX2; + float InnerWidth; + float ColumnsGivenWidth; + float ColumnsAutoFitWidth; + float ColumnsStretchSumWeights; + float ResizedColumnNextWidth; + float ResizeLockMinContentsX2; + float RefScale; + float AngledHeadersHeight; + float AngledHeadersSlope; + ImRect_c OuterRect; + ImRect_c InnerRect; + ImRect_c WorkRect; + ImRect_c InnerClipRect; + ImRect_c BgClipRect; + ImRect_c Bg0ClipRectForDrawCmd; + ImRect_c Bg2ClipRectForDrawCmd; + ImRect_c HostClipRect; + ImRect_c HostBackupInnerClipRect; + ImGuiWindow* OuterWindow; + ImGuiWindow* InnerWindow; + ImGuiTextBuffer ColumnsNames; + ImDrawListSplitter* DrawSplitter; + ImGuiTableInstanceData InstanceDataFirst; + ImVector_ImGuiTableInstanceData InstanceDataExtra; + ImGuiTableColumnSortSpecs SortSpecsSingle; + ImVector_ImGuiTableColumnSortSpecs SortSpecsMulti; + ImGuiTableSortSpecs SortSpecs; + ImGuiTableColumnIdx SortSpecsCount; + ImGuiTableColumnIdx ColumnsEnabledCount; + ImGuiTableColumnIdx ColumnsEnabledFixedCount; + ImGuiTableColumnIdx DeclColumnsCount; + ImGuiTableColumnIdx AngledHeadersCount; + ImGuiTableColumnIdx HoveredColumnBody; + ImGuiTableColumnIdx HoveredColumnBorder; + ImGuiTableColumnIdx HighlightColumnHeader; + ImGuiTableColumnIdx AutoFitSingleColumn; + ImGuiTableColumnIdx ResizedColumn; + ImGuiTableColumnIdx LastResizedColumn; + ImGuiTableColumnIdx HeldHeaderColumn; + ImGuiTableColumnIdx LastHeldHeaderColumn; + ImGuiTableColumnIdx ReorderColumn; + ImGuiTableColumnIdx ReorderColumnDstOrder; + ImGuiTableColumnIdx LeftMostEnabledColumn; + ImGuiTableColumnIdx RightMostEnabledColumn; + ImGuiTableColumnIdx LeftMostStretchedColumn; + ImGuiTableColumnIdx RightMostStretchedColumn; + ImGuiTableColumnIdx ContextPopupColumn; + ImGuiTableColumnIdx FreezeRowsRequest; + ImGuiTableColumnIdx FreezeRowsCount; + ImGuiTableColumnIdx FreezeColumnsRequest; + ImGuiTableColumnIdx FreezeColumnsCount; + ImGuiTableColumnIdx RowCellDataCurrent; + ImGuiTableDrawChannelIdx DummyDrawChannel; + ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent; + ImGuiTableDrawChannelIdx Bg2DrawChannelUnfrozen; + ImS8 NavLayer; + bool IsLayoutLocked; + bool IsInsideRow; + bool IsInitializing; + bool IsSortSpecsDirty; + bool IsUsingHeaders; + bool IsContextPopupOpen; + bool DisableDefaultContextMenu; + bool IsSettingsRequestLoad; + bool IsSettingsDirty; + bool IsDefaultDisplayOrder; + bool IsDefaultVisibility; + bool IsResetAllRequest; + bool IsResetDisplayOrderRequest; + bool IsResetVisibilityRequest; + bool IsUnfrozenRows; + bool IsDefaultSizingPolicy; + bool IsActiveIdAliveBeforeTable; + bool IsActiveIdInTable; + bool HasScrollbarYCurr; + bool HasScrollbarYPrev; + bool MemoryCompacted; + bool HostSkipItems; +}; +typedef struct ImVector_ImGuiTableHeaderData {int Size;int Capacity;ImGuiTableHeaderData* Data;} ImVector_ImGuiTableHeaderData; + +struct ImGuiTableTempData +{ + ImGuiID WindowID; + int TableIndex; + float LastTimeActive; + float AngledHeadersExtraWidth; + ImVector_ImGuiTableHeaderData AngledHeadersRequests; + ImVec2_c UserOuterSize; + ImDrawListSplitter DrawSplitter; + ImRect_c HostBackupWorkRect; + ImRect_c HostBackupParentWorkRect; + ImVec2_c HostBackupPrevLineSize; + ImVec2_c HostBackupCurrLineSize; + ImVec2_c HostBackupCursorMaxPos; + ImVec1 HostBackupColumnsOffset; + float HostBackupItemWidth; + int HostBackupItemWidthStackSize; +}; +typedef struct ImGuiTableColumnSettings ImGuiTableColumnSettings; +struct ImGuiTableColumnSettings +{ + float WidthOrWeight; + ImGuiID ID; + ImGuiTableColumnIdx Index; + ImGuiTableColumnIdx DisplayOrder; + ImGuiTableColumnIdx SortOrder; + ImU8 SortDirection : 2; + ImS8 IsEnabled : 2; + ImU8 IsStretch : 1; +}; +struct ImGuiTableSettings +{ + ImGuiID ID; + ImGuiTableFlags SaveFlags; + float RefScale; + ImGuiTableColumnIdx ColumnsCount; + ImGuiTableColumnIdx ColumnsCountMax; + bool WantApply; +}; +struct ImFontLoader +{ + const char* Name; + bool (*LoaderInit)(ImFontAtlas* atlas); + void (*LoaderShutdown)(ImFontAtlas* atlas); + bool (*FontSrcInit)(ImFontAtlas* atlas, ImFontConfig* src); + void (*FontSrcDestroy)(ImFontAtlas* atlas, ImFontConfig* src); + bool (*FontSrcContainsGlyph)(ImFontAtlas* atlas, ImFontConfig* src, ImWchar codepoint); + bool (*FontBakedInit)(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src); + void (*FontBakedDestroy)(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src); + bool (*FontBakedLoadGlyph)(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src, ImWchar codepoint, ImFontGlyph* out_glyph, float* out_advance_x); + size_t FontBakedSrcLoaderDataSize; +}; +struct ImFontAtlasRectEntry +{ + int TargetIndex : 20; + unsigned int Generation : 10; + unsigned int IsUsed : 1; +}; +struct ImFontAtlasPostProcessData +{ + ImFontAtlas* FontAtlas; + ImFont* Font; + ImFontConfig* FontSrc; + ImFontBaked* FontBaked; + ImFontGlyph* Glyph; + void* Pixels; + ImTextureFormat Format; + int Pitch; + int Width; + int Height; +}; +struct stbrp_node; +typedef stbrp_node stbrp_node_im; +typedef struct stbrp_context_opaque stbrp_context_opaque; +struct stbrp_context_opaque +{ char data[80]; +}; +typedef struct ImVector_stbrp_node_im {int Size;int Capacity;stbrp_node_im* Data;} ImVector_stbrp_node_im; + +typedef struct ImVector_ImFontAtlasRectEntry {int Size;int Capacity;ImFontAtlasRectEntry* Data;} ImVector_ImFontAtlasRectEntry; + +typedef struct ImVector_ImFontBakedPtr {int Size;int Capacity;ImFontBaked** Data;} ImVector_ImFontBakedPtr; + +typedef struct ImStableVector_ImFontBaked__32 {int Size;int Capacity;ImVector_ImFontBakedPtr Blocks;} ImStableVector_ImFontBaked__32; + +struct ImFontAtlasBuilder +{ + stbrp_context_opaque PackContext; + ImVector_stbrp_node_im PackNodes; + ImVector_ImTextureRect Rects; + ImVector_ImFontAtlasRectEntry RectsIndex; + ImVector_unsigned_char TempBuffer; + int RectsIndexFreeListStart; + int RectsPackedCount; + int RectsPackedSurface; + int RectsDiscardedCount; + int RectsDiscardedSurface; + int FrameCount; + ImVec2i_c MaxRectSize; + ImVec2i_c MaxRectBounds; + bool LockDisableResize; + bool PreloadedAllGlyphsRanges; + ImStableVector_ImFontBaked__32 BakedPool; + ImGuiStorage BakedMap; + int BakedDiscardedCount; + ImFontAtlasRectId PackIdMouseCursors; + ImFontAtlasRectId PackIdLinesTexData; +}; +#ifdef IMGUI_ENABLE_FREETYPE +struct ImFontAtlas; +struct ImFontLoader; +typedef unsigned int ImGuiFreeTypeLoaderFlags; +typedef enum { + ImGuiFreeTypeLoaderFlags_NoHinting = 1 << 0, + ImGuiFreeTypeLoaderFlags_NoAutoHint = 1 << 1, + ImGuiFreeTypeLoaderFlags_ForceAutoHint = 1 << 2, + ImGuiFreeTypeLoaderFlags_LightHinting = 1 << 3, + ImGuiFreeTypeLoaderFlags_MonoHinting = 1 << 4, + ImGuiFreeTypeLoaderFlags_Bold = 1 << 5, + ImGuiFreeTypeLoaderFlags_Oblique = 1 << 6, + ImGuiFreeTypeLoaderFlags_Monochrome = 1 << 7, + ImGuiFreeTypeLoaderFlags_LoadColor = 1 << 8, + ImGuiFreeTypeLoaderFlags_Bitmap = 1 << 9, +}ImGuiFreeTypeLoaderFlags_; +#endif +#define ImTextureID_Invalid ((ImTextureID)0) + +#else +struct GLFWwindow; +struct SDL_Window; +typedef union SDL_Event SDL_Event; +#endif // CIMGUI_DEFINE_ENUMS_AND_STRUCTS + +#ifdef CIMGUI_DEFINE_ENUMS_AND_STRUCTS +typedef struct ImTextureRef_c ImTextureRef; +typedef struct ImVec2_c ImVec2; +typedef struct ImVec2i_c ImVec2i; +typedef struct ImVec4_c ImVec4; +typedef struct ImColor_c ImColor; +typedef struct ImRect_c ImRect; +#endif +#ifndef CIMGUI_DEFINE_ENUMS_AND_STRUCTS +typedef struct ImTextureRef_c ImTextureRef_c; +struct ImTextureRef_c { + ImTextureData* _TexData; + ImTextureID _TexID; +}; +typedef struct ImVec2_c ImVec2_c; +struct ImVec2_c { + float x; + float y; +}; +typedef struct ImVec2i_c ImVec2i_c; +struct ImVec2i_c { + int x; + int y; +}; +typedef struct ImVec4_c ImVec4_c; +struct ImVec4_c { + float x; + float y; + float z; + float w; +}; +typedef struct ImColor_c ImColor_c; +struct ImColor_c { + ImVec4_c Value; +}; +typedef struct ImRect_c ImRect_c; +struct ImRect_c { + ImVec2_c Min; + ImVec2_c Max; +}; +#endif + + +#ifndef CIMGUI_DEFINE_ENUMS_AND_STRUCTS +typedef struct ImGuiTextFilter::ImGuiTextRange ImGuiTextRange; +typedef ImStb::STB_TexteditState STB_TexteditState; +typedef ImChunkStream ImChunkStream_ImGuiTableSettings; +typedef ImChunkStream ImChunkStream_ImGuiWindowSettings; +typedef ImPool ImPool_ImGuiMultiSelectState; +typedef ImPool ImPool_ImGuiTabBar; +typedef ImPool ImPool_ImGuiTable; +typedef ImSpan ImSpan_ImGuiTableCellData; +typedef ImSpan ImSpan_ImGuiTableColumn; +typedef ImSpan ImSpan_ImGuiTableColumnIdx; +typedef ImStableVector ImStableVector_ImFontBaked__32; +typedef ImVector ImVector_ImDrawChannel; +typedef ImVector ImVector_ImDrawCmd; +typedef ImVector ImVector_ImDrawIdx; +typedef ImVector ImVector_ImDrawListPtr; +typedef ImVector ImVector_ImDrawListSharedDataPtr; +typedef ImVector ImVector_ImDrawVert; +typedef ImVector ImVector_ImFontPtr; +typedef ImVector ImVector_ImFontAtlasPtr; +typedef ImVector ImVector_ImFontAtlasRectEntry; +typedef ImVector ImVector_ImFontConfig; +typedef ImVector ImVector_ImFontConfigPtr; +typedef ImVector ImVector_ImFontGlyph; +typedef ImVector ImVector_ImFontStackData; +typedef ImVector ImVector_ImGuiColorMod; +typedef ImVector ImVector_ImGuiContextHook; +typedef ImVector ImVector_ImGuiFocusScopeData; +typedef ImVector ImVector_ImGuiGroupData; +typedef ImVector ImVector_ImGuiID; +typedef ImVector ImVector_ImGuiInputEvent; +typedef ImVector ImVector_ImGuiItemFlags; +typedef ImVector ImVector_ImGuiKeyRoutingData; +typedef ImVector ImVector_ImGuiListClipperData; +typedef ImVector ImVector_ImGuiListClipperRange; +typedef ImVector ImVector_ImGuiMultiSelectTempData; +typedef ImVector ImVector_ImGuiOldColumnData; +typedef ImVector ImVector_ImGuiOldColumns; +typedef ImVector ImVector_ImGuiPopupData; +typedef ImVector ImVector_ImGuiPtrOrIndex; +typedef ImVector ImVector_ImGuiSelectionRequest; +typedef ImVector ImVector_ImGuiSettingsHandler; +typedef ImVector ImVector_ImGuiShrinkWidthItem; +typedef ImVector ImVector_ImGuiStackLevelInfo; +typedef ImVector ImVector_ImGuiStoragePair; +typedef ImVector ImVector_ImGuiStyleMod; +typedef ImVector ImVector_ImGuiTabItem; +typedef ImVector ImVector_ImGuiTableColumnSortSpecs; +typedef ImVector ImVector_ImGuiTableHeaderData; +typedef ImVector ImVector_ImGuiTableInstanceData; +typedef ImVector ImVector_ImGuiTableTempData; +typedef ImVector ImVector_ImGuiTextRange; +typedef ImVector ImVector_ImGuiTreeNodeStackData; +typedef ImVector ImVector_ImGuiViewportPPtr; +typedef ImVector ImVector_ImGuiWindowPtr; +typedef ImVector ImVector_ImGuiWindowStackData; +typedef ImVector ImVector_ImTextureDataPtr; +typedef ImVector ImVector_ImTextureRect; +typedef ImVector ImVector_ImTextureRef; +typedef ImVector ImVector_ImU16; +typedef ImVector ImVector_ImU32; +typedef ImVector ImVector_ImU8; +typedef ImVector ImVector_ImVec2; +typedef ImVector ImVector_ImVec4; +typedef ImVector ImVector_ImWchar; +typedef ImVector ImVector_char; +typedef ImVector ImVector_float; +typedef ImVector ImVector_int; +typedef ImVector ImVector_stbrp_node_im; +typedef ImVector ImVector_unsigned_char; +#endif //CIMGUI_DEFINE_ENUMS_AND_STRUCTS +CIMGUI_API ImVec2* ImVec2_ImVec2_Nil(void); +CIMGUI_API void ImVec2_destroy(ImVec2* self); +CIMGUI_API ImVec2* ImVec2_ImVec2_Float(float _x,float _y); +CIMGUI_API ImVec4* ImVec4_ImVec4_Nil(void); +CIMGUI_API void ImVec4_destroy(ImVec4* self); +CIMGUI_API ImVec4* ImVec4_ImVec4_Float(float _x,float _y,float _z,float _w); +CIMGUI_API ImTextureRef* ImTextureRef_ImTextureRef_Nil(void); +CIMGUI_API void ImTextureRef_destroy(ImTextureRef* self); +CIMGUI_API ImTextureRef* ImTextureRef_ImTextureRef_TextureID(ImTextureID tex_id); +CIMGUI_API ImTextureID ImTextureRef_GetTexID(ImTextureRef* self); +CIMGUI_API ImGuiContext* igCreateContext(ImFontAtlas* shared_font_atlas); +CIMGUI_API void igDestroyContext(ImGuiContext* ctx); +CIMGUI_API ImGuiContext* igGetCurrentContext(void); +CIMGUI_API void igSetCurrentContext(ImGuiContext* ctx); +CIMGUI_API ImGuiIO* igGetIO_Nil(void); +CIMGUI_API ImGuiPlatformIO* igGetPlatformIO_Nil(void); +CIMGUI_API ImGuiStyle* igGetStyle(void); +CIMGUI_API void igNewFrame(void); +CIMGUI_API void igEndFrame(void); +CIMGUI_API void igRender(void); +CIMGUI_API ImDrawData* igGetDrawData(void); +CIMGUI_API void igShowMetricsWindow(bool* p_open); +CIMGUI_API void igShowIDStackToolWindow(bool* p_open); +CIMGUI_API const char* igGetVersion(void); +CIMGUI_API void igStyleColorsDark(ImGuiStyle* dst); +CIMGUI_API void igStyleColorsLight(ImGuiStyle* dst); +CIMGUI_API void igStyleColorsClassic(ImGuiStyle* dst); +CIMGUI_API bool igBegin(const char* name,bool* p_open,ImGuiWindowFlags flags); +CIMGUI_API void igEnd(void); +CIMGUI_API bool igBeginChild_Str(const char* str_id,const ImVec2_c size,ImGuiChildFlags child_flags,ImGuiWindowFlags window_flags); +CIMGUI_API bool igBeginChild_ID(ImGuiID id,const ImVec2_c size,ImGuiChildFlags child_flags,ImGuiWindowFlags window_flags); +CIMGUI_API void igEndChild(void); +CIMGUI_API bool igIsWindowAppearing(void); +CIMGUI_API bool igIsWindowCollapsed(void); +CIMGUI_API bool igIsWindowFocused(ImGuiFocusedFlags flags); +CIMGUI_API bool igIsWindowHovered(ImGuiHoveredFlags flags); +CIMGUI_API ImDrawList* igGetWindowDrawList(void); +CIMGUI_API ImVec2_c igGetWindowPos(void); +CIMGUI_API ImVec2_c igGetWindowSize(void); +CIMGUI_API float igGetWindowWidth(void); +CIMGUI_API float igGetWindowHeight(void); +CIMGUI_API void igSetNextWindowPos(const ImVec2_c pos,ImGuiCond cond,const ImVec2_c pivot); +CIMGUI_API void igSetNextWindowSize(const ImVec2_c size,ImGuiCond cond); +CIMGUI_API void igSetNextWindowSizeConstraints(const ImVec2_c size_min,const ImVec2_c size_max,ImGuiSizeCallback custom_callback,void* custom_callback_data); +CIMGUI_API void igSetNextWindowContentSize(const ImVec2_c size); +CIMGUI_API void igSetNextWindowCollapsed(bool collapsed,ImGuiCond cond); +CIMGUI_API void igSetNextWindowFocus(void); +CIMGUI_API void igSetNextWindowScroll(const ImVec2_c scroll); +CIMGUI_API void igSetNextWindowBgAlpha(float alpha); +CIMGUI_API void igSetWindowPos_Vec2(const ImVec2_c pos,ImGuiCond cond); +CIMGUI_API void igSetWindowSize_Vec2(const ImVec2_c size,ImGuiCond cond); +CIMGUI_API void igSetWindowCollapsed_Bool(bool collapsed,ImGuiCond cond); +CIMGUI_API void igSetWindowFocus_Nil(void); +CIMGUI_API void igSetWindowPos_Str(const char* name,const ImVec2_c pos,ImGuiCond cond); +CIMGUI_API void igSetWindowSize_Str(const char* name,const ImVec2_c size,ImGuiCond cond); +CIMGUI_API void igSetWindowCollapsed_Str(const char* name,bool collapsed,ImGuiCond cond); +CIMGUI_API void igSetWindowFocus_Str(const char* name); +CIMGUI_API float igGetScrollX(void); +CIMGUI_API float igGetScrollY(void); +CIMGUI_API void igSetScrollX_Float(float scroll_x); +CIMGUI_API void igSetScrollY_Float(float scroll_y); +CIMGUI_API float igGetScrollMaxX(void); +CIMGUI_API float igGetScrollMaxY(void); +CIMGUI_API void igSetScrollHereX(float center_x_ratio); +CIMGUI_API void igSetScrollHereY(float center_y_ratio); +CIMGUI_API void igSetScrollFromPosX_Float(float local_x,float center_x_ratio); +CIMGUI_API void igSetScrollFromPosY_Float(float local_y,float center_y_ratio); +CIMGUI_API void igPushFont(ImFont* font,float font_size_base_unscaled); +CIMGUI_API void igPopFont(void); +CIMGUI_API ImFont* igGetFont(void); +CIMGUI_API float igGetFontSize(void); +CIMGUI_API ImFontBaked* igGetFontBaked(void); +CIMGUI_API void igPushStyleColor_U32(ImGuiCol idx,ImU32 col); +CIMGUI_API void igPushStyleColor_Vec4(ImGuiCol idx,const ImVec4_c col); +CIMGUI_API void igPopStyleColor(int count); +CIMGUI_API void igPushStyleVar_Float(ImGuiStyleVar idx,float val); +CIMGUI_API void igPushStyleVar_Vec2(ImGuiStyleVar idx,const ImVec2_c val); +CIMGUI_API void igPushStyleVarX(ImGuiStyleVar idx,float val_x); +CIMGUI_API void igPushStyleVarY(ImGuiStyleVar idx,float val_y); +CIMGUI_API void igPopStyleVar(int count); +CIMGUI_API void igPushItemFlag(ImGuiItemFlags option,bool enabled); +CIMGUI_API void igPopItemFlag(void); +CIMGUI_API void igPushItemWidth(float item_width); +CIMGUI_API void igPopItemWidth(void); +CIMGUI_API void igSetNextItemWidth(float item_width); +CIMGUI_API float igCalcItemWidth(void); +CIMGUI_API void igPushTextWrapPos(float wrap_local_pos_x); +CIMGUI_API void igPopTextWrapPos(void); +CIMGUI_API ImVec2_c igGetFontTexUvWhitePixel(void); +CIMGUI_API ImU32 igGetColorU32_Col(ImGuiCol idx,float alpha_mul); +CIMGUI_API ImU32 igGetColorU32_Vec4(const ImVec4_c col); +CIMGUI_API ImU32 igGetColorU32_U32(ImU32 col,float alpha_mul); +CIMGUI_API const ImVec4_c* igGetStyleColorVec4(ImGuiCol idx); +CIMGUI_API ImVec2_c igGetCursorScreenPos(void); +CIMGUI_API void igSetCursorScreenPos(const ImVec2_c pos); +CIMGUI_API ImVec2_c igGetContentRegionAvail(void); +CIMGUI_API ImVec2_c igGetCursorPos(void); +CIMGUI_API float igGetCursorPosX(void); +CIMGUI_API float igGetCursorPosY(void); +CIMGUI_API void igSetCursorPos(const ImVec2_c local_pos); +CIMGUI_API void igSetCursorPosX(float local_x); +CIMGUI_API void igSetCursorPosY(float local_y); +CIMGUI_API ImVec2_c igGetCursorStartPos(void); +CIMGUI_API void igSeparator(void); +CIMGUI_API void igSameLine(float offset_from_start_x,float spacing); +CIMGUI_API void igNewLine(void); +CIMGUI_API void igSpacing(void); +CIMGUI_API void igDummy(const ImVec2_c size); +CIMGUI_API void igIndent(float indent_w); +CIMGUI_API void igUnindent(float indent_w); +CIMGUI_API void igBeginGroup(void); +CIMGUI_API void igEndGroup(void); +CIMGUI_API void igAlignTextToFramePadding(void); +CIMGUI_API float igGetTextLineHeight(void); +CIMGUI_API float igGetTextLineHeightWithSpacing(void); +CIMGUI_API float igGetFrameHeight(void); +CIMGUI_API float igGetFrameHeightWithSpacing(void); +CIMGUI_API void igPushID_Str(const char* str_id); +CIMGUI_API void igPushID_StrStr(const char* str_id_begin,const char* str_id_end); +CIMGUI_API void igPushID_Ptr(const void* ptr_id); +CIMGUI_API void igPushID_Int(int int_id); +CIMGUI_API void igPopID(void); +CIMGUI_API ImGuiID igGetID_Str(const char* str_id); +CIMGUI_API ImGuiID igGetID_StrStr(const char* str_id_begin,const char* str_id_end); +CIMGUI_API ImGuiID igGetID_Ptr(const void* ptr_id); +CIMGUI_API ImGuiID igGetID_Int(int int_id); +CIMGUI_API void igTextUnformatted(const char* text,const char* text_end); +CIMGUI_API void igText(const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igText0(const char* fmt); +#endif +CIMGUI_API void igTextV(const char* fmt,va_list args); +CIMGUI_API void igTextColored(const ImVec4_c col,const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igTextColored0(const ImVec4_c col,const char* fmt); +#endif +CIMGUI_API void igTextColoredV(const ImVec4_c col,const char* fmt,va_list args); +CIMGUI_API void igTextDisabled(const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igTextDisabled0(const char* fmt); +#endif +CIMGUI_API void igTextDisabledV(const char* fmt,va_list args); +CIMGUI_API void igTextWrapped(const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igTextWrapped0(const char* fmt); +#endif +CIMGUI_API void igTextWrappedV(const char* fmt,va_list args); +CIMGUI_API void igLabelText(const char* label,const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igLabelText0(const char* label,const char* fmt); +#endif +CIMGUI_API void igLabelTextV(const char* label,const char* fmt,va_list args); +CIMGUI_API void igBulletText(const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igBulletText0(const char* fmt); +#endif +CIMGUI_API void igBulletTextV(const char* fmt,va_list args); +CIMGUI_API void igSeparatorText(const char* label); +CIMGUI_API bool igButton(const char* label,const ImVec2_c size); +CIMGUI_API bool igSmallButton(const char* label); +CIMGUI_API bool igInvisibleButton(const char* str_id,const ImVec2_c size,ImGuiButtonFlags flags); +CIMGUI_API bool igArrowButton(const char* str_id,ImGuiDir dir); +CIMGUI_API bool igCheckbox(const char* label,bool* v); +CIMGUI_API bool igCheckboxFlags_IntPtr(const char* label,int* flags,int flags_value); +CIMGUI_API bool igCheckboxFlags_UintPtr(const char* label,unsigned int* flags,unsigned int flags_value); +CIMGUI_API bool igRadioButton_Bool(const char* label,bool active); +CIMGUI_API bool igRadioButton_IntPtr(const char* label,int* v,int v_button); +CIMGUI_API void igProgressBar(float fraction,const ImVec2_c size_arg,const char* overlay); +CIMGUI_API void igBullet(void); +CIMGUI_API bool igTextLink(const char* label); +CIMGUI_API bool igTextLinkOpenURL(const char* label,const char* url); +CIMGUI_API void igImage(ImTextureRef_c tex_ref,const ImVec2_c image_size,const ImVec2_c uv0,const ImVec2_c uv1); +CIMGUI_API void igImageWithBg(ImTextureRef_c tex_ref,const ImVec2_c image_size,const ImVec2_c uv0,const ImVec2_c uv1,const ImVec4_c bg_col,const ImVec4_c tint_col); +CIMGUI_API bool igImageButton(const char* str_id,ImTextureRef_c tex_ref,const ImVec2_c image_size,const ImVec2_c uv0,const ImVec2_c uv1,const ImVec4_c bg_col,const ImVec4_c tint_col); +CIMGUI_API bool igBeginCombo(const char* label,const char* preview_value,ImGuiComboFlags flags); +CIMGUI_API void igEndCombo(void); +CIMGUI_API bool igCombo_Str_arr(const char* label,int* current_item,const char* const items[],int items_count,int popup_max_height_in_items); +CIMGUI_API bool igCombo_Str(const char* label,int* current_item,const char* items_separated_by_zeros,int popup_max_height_in_items); +CIMGUI_API bool igCombo_FnStrPtr(const char* label,int* current_item,const char*(*getter)(void* user_data,int idx),void* user_data,int items_count,int popup_max_height_in_items); +CIMGUI_API bool igDragFloat(const char* label,float* v,float v_speed,float v_min,float v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igDragFloat2(const char* label,float v[2],float v_speed,float v_min,float v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igDragFloat3(const char* label,float v[3],float v_speed,float v_min,float v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igDragFloat4(const char* label,float v[4],float v_speed,float v_min,float v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igDragFloatRange2(const char* label,float* v_current_min,float* v_current_max,float v_speed,float v_min,float v_max,const char* format,const char* format_max,ImGuiSliderFlags flags); +CIMGUI_API bool igDragInt(const char* label,int* v,float v_speed,int v_min,int v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igDragInt2(const char* label,int v[2],float v_speed,int v_min,int v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igDragInt3(const char* label,int v[3],float v_speed,int v_min,int v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igDragInt4(const char* label,int v[4],float v_speed,int v_min,int v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igDragIntRange2(const char* label,int* v_current_min,int* v_current_max,float v_speed,int v_min,int v_max,const char* format,const char* format_max,ImGuiSliderFlags flags); +CIMGUI_API bool igDragScalar(const char* label,ImGuiDataType data_type,void* p_data,float v_speed,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igDragScalarN(const char* label,ImGuiDataType data_type,void* p_data,int components,float v_speed,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igSliderFloat(const char* label,float* v,float v_min,float v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igSliderFloat2(const char* label,float v[2],float v_min,float v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igSliderFloat3(const char* label,float v[3],float v_min,float v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igSliderFloat4(const char* label,float v[4],float v_min,float v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igSliderAngle(const char* label,float* v_rad,float v_degrees_min,float v_degrees_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igSliderInt(const char* label,int* v,int v_min,int v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igSliderInt2(const char* label,int v[2],int v_min,int v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igSliderInt3(const char* label,int v[3],int v_min,int v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igSliderInt4(const char* label,int v[4],int v_min,int v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igSliderScalar(const char* label,ImGuiDataType data_type,void* p_data,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igSliderScalarN(const char* label,ImGuiDataType data_type,void* p_data,int components,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igVSliderFloat(const char* label,const ImVec2_c size,float* v,float v_min,float v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igVSliderInt(const char* label,const ImVec2_c size,int* v,int v_min,int v_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igVSliderScalar(const char* label,const ImVec2_c size,ImGuiDataType data_type,void* p_data,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igInputText(const char* label,char* buf,size_t buf_size,ImGuiInputTextFlags flags,ImGuiInputTextCallback callback,void* user_data); +CIMGUI_API bool igInputTextMultiline(const char* label,char* buf,size_t buf_size,const ImVec2_c size,ImGuiInputTextFlags flags,ImGuiInputTextCallback callback,void* user_data); +CIMGUI_API bool igInputTextWithHint(const char* label,const char* hint,char* buf,size_t buf_size,ImGuiInputTextFlags flags,ImGuiInputTextCallback callback,void* user_data); +CIMGUI_API bool igInputFloat(const char* label,float* v,float step,float step_fast,const char* format,ImGuiInputTextFlags flags); +CIMGUI_API bool igInputFloat2(const char* label,float v[2],const char* format,ImGuiInputTextFlags flags); +CIMGUI_API bool igInputFloat3(const char* label,float v[3],const char* format,ImGuiInputTextFlags flags); +CIMGUI_API bool igInputFloat4(const char* label,float v[4],const char* format,ImGuiInputTextFlags flags); +CIMGUI_API bool igInputInt(const char* label,int* v,int step,int step_fast,ImGuiInputTextFlags flags); +CIMGUI_API bool igInputInt2(const char* label,int v[2],ImGuiInputTextFlags flags); +CIMGUI_API bool igInputInt3(const char* label,int v[3],ImGuiInputTextFlags flags); +CIMGUI_API bool igInputInt4(const char* label,int v[4],ImGuiInputTextFlags flags); +CIMGUI_API bool igInputDouble(const char* label,double* v,double step,double step_fast,const char* format,ImGuiInputTextFlags flags); +CIMGUI_API bool igInputScalar(const char* label,ImGuiDataType data_type,void* p_data,const void* p_step,const void* p_step_fast,const char* format,ImGuiInputTextFlags flags); +CIMGUI_API bool igInputScalarN(const char* label,ImGuiDataType data_type,void* p_data,int components,const void* p_step,const void* p_step_fast,const char* format,ImGuiInputTextFlags flags); +CIMGUI_API bool igColorEdit3(const char* label,float col[3],ImGuiColorEditFlags flags); +CIMGUI_API bool igColorEdit4(const char* label,float col[4],ImGuiColorEditFlags flags); +CIMGUI_API bool igColorPicker3(const char* label,float col[3],ImGuiColorEditFlags flags); +CIMGUI_API bool igColorPicker4(const char* label,float col[4],ImGuiColorEditFlags flags,const float* ref_col); +CIMGUI_API bool igColorButton(const char* desc_id,const ImVec4_c col,ImGuiColorEditFlags flags,const ImVec2_c size); +CIMGUI_API void igSetColorEditOptions(ImGuiColorEditFlags flags); +CIMGUI_API bool igTreeNode_Str(const char* label); +CIMGUI_API bool igTreeNode_StrStr(const char* str_id,const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API bool igTreeNode_StrStr0(const char* str_id,const char* fmt); +#endif +CIMGUI_API bool igTreeNode_Ptr(const void* ptr_id,const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API bool igTreeNode_Ptr0(const void* ptr_id,const char* fmt); +#endif +CIMGUI_API bool igTreeNodeV_Str(const char* str_id,const char* fmt,va_list args); +CIMGUI_API bool igTreeNodeV_Ptr(const void* ptr_id,const char* fmt,va_list args); +CIMGUI_API bool igTreeNodeEx_Str(const char* label,ImGuiTreeNodeFlags flags); +CIMGUI_API bool igTreeNodeEx_StrStr(const char* str_id,ImGuiTreeNodeFlags flags,const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API bool igTreeNodeEx_StrStr0(const char* str_id,ImGuiTreeNodeFlags flags,const char* fmt); +#endif +CIMGUI_API bool igTreeNodeEx_Ptr(const void* ptr_id,ImGuiTreeNodeFlags flags,const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API bool igTreeNodeEx_Ptr0(const void* ptr_id,ImGuiTreeNodeFlags flags,const char* fmt); +#endif +CIMGUI_API bool igTreeNodeExV_Str(const char* str_id,ImGuiTreeNodeFlags flags,const char* fmt,va_list args); +CIMGUI_API bool igTreeNodeExV_Ptr(const void* ptr_id,ImGuiTreeNodeFlags flags,const char* fmt,va_list args); +CIMGUI_API void igTreePush_Str(const char* str_id); +CIMGUI_API void igTreePush_Ptr(const void* ptr_id); +CIMGUI_API void igTreePop(void); +CIMGUI_API float igGetTreeNodeToLabelSpacing(void); +CIMGUI_API bool igCollapsingHeader_TreeNodeFlags(const char* label,ImGuiTreeNodeFlags flags); +CIMGUI_API bool igCollapsingHeader_BoolPtr(const char* label,bool* p_visible,ImGuiTreeNodeFlags flags); +CIMGUI_API void igSetNextItemOpen(bool is_open,ImGuiCond cond); +CIMGUI_API void igSetNextItemStorageID(ImGuiID storage_id); +CIMGUI_API bool igTreeNodeGetOpen(ImGuiID storage_id); +CIMGUI_API bool igSelectable_Bool(const char* label,bool selected,ImGuiSelectableFlags flags,const ImVec2_c size); +CIMGUI_API bool igSelectable_BoolPtr(const char* label,bool* p_selected,ImGuiSelectableFlags flags,const ImVec2_c size); +CIMGUI_API ImGuiMultiSelectIO* igBeginMultiSelect(ImGuiMultiSelectFlags flags,int selection_size,int items_count); +CIMGUI_API ImGuiMultiSelectIO* igEndMultiSelect(void); +CIMGUI_API void igSetNextItemSelectionUserData(ImGuiSelectionUserData selection_user_data); +CIMGUI_API bool igIsItemToggledSelection(void); +CIMGUI_API bool igBeginListBox(const char* label,const ImVec2_c size); +CIMGUI_API void igEndListBox(void); +CIMGUI_API bool igListBox_Str_arr(const char* label,int* current_item,const char* const items[],int items_count,int height_in_items); +CIMGUI_API bool igListBox_FnStrPtr(const char* label,int* current_item,const char*(*getter)(void* user_data,int idx),void* user_data,int items_count,int height_in_items); +CIMGUI_API void igPlotLines_FloatPtr(const char* label,const float* values,int values_count,int values_offset,const char* overlay_text,float scale_min,float scale_max,ImVec2_c graph_size,int stride); +CIMGUI_API void igPlotLines_FnFloatPtr(const char* label,float(*values_getter)(void* data,int idx),void* data,int values_count,int values_offset,const char* overlay_text,float scale_min,float scale_max,ImVec2_c graph_size); +CIMGUI_API void igPlotHistogram_FloatPtr(const char* label,const float* values,int values_count,int values_offset,const char* overlay_text,float scale_min,float scale_max,ImVec2_c graph_size,int stride); +CIMGUI_API void igPlotHistogram_FnFloatPtr(const char* label,float(*values_getter)(void* data,int idx),void* data,int values_count,int values_offset,const char* overlay_text,float scale_min,float scale_max,ImVec2_c graph_size); +CIMGUI_API void igValue_Bool(const char* prefix,bool b); +CIMGUI_API void igValue_Int(const char* prefix,int v); +CIMGUI_API void igValue_Uint(const char* prefix,unsigned int v); +CIMGUI_API void igValue_Float(const char* prefix,float v,const char* float_format); +CIMGUI_API bool igBeginMenuBar(void); +CIMGUI_API void igEndMenuBar(void); +CIMGUI_API bool igBeginMainMenuBar(void); +CIMGUI_API void igEndMainMenuBar(void); +CIMGUI_API bool igBeginMenu(const char* label,bool enabled); +CIMGUI_API void igEndMenu(void); +CIMGUI_API bool igMenuItem_Bool(const char* label,const char* shortcut,bool selected,bool enabled); +CIMGUI_API bool igMenuItem_BoolPtr(const char* label,const char* shortcut,bool* p_selected,bool enabled); +CIMGUI_API bool igBeginTooltip(void); +CIMGUI_API void igEndTooltip(void); +CIMGUI_API void igSetTooltip(const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igSetTooltip0(const char* fmt); +#endif +CIMGUI_API void igSetTooltipV(const char* fmt,va_list args); +CIMGUI_API bool igBeginItemTooltip(void); +CIMGUI_API void igSetItemTooltip(const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igSetItemTooltip0(const char* fmt); +#endif +CIMGUI_API void igSetItemTooltipV(const char* fmt,va_list args); +CIMGUI_API bool igBeginPopup(const char* str_id,ImGuiWindowFlags flags); +CIMGUI_API bool igBeginPopupModal(const char* name,bool* p_open,ImGuiWindowFlags flags); +CIMGUI_API void igEndPopup(void); +CIMGUI_API void igOpenPopup_Str(const char* str_id,ImGuiPopupFlags popup_flags); +CIMGUI_API void igOpenPopup_ID(ImGuiID id,ImGuiPopupFlags popup_flags); +CIMGUI_API void igOpenPopupOnItemClick(const char* str_id,ImGuiPopupFlags popup_flags); +CIMGUI_API void igCloseCurrentPopup(void); +CIMGUI_API bool igBeginPopupContextItem(const char* str_id,ImGuiPopupFlags popup_flags); +CIMGUI_API bool igBeginPopupContextWindow(const char* str_id,ImGuiPopupFlags popup_flags); +CIMGUI_API bool igBeginPopupContextVoid(const char* str_id,ImGuiPopupFlags popup_flags); +CIMGUI_API bool igIsPopupOpen_Str(const char* str_id,ImGuiPopupFlags flags); +CIMGUI_API bool igBeginTable(const char* str_id,int columns,ImGuiTableFlags flags,const ImVec2_c outer_size,float inner_width); +CIMGUI_API void igEndTable(void); +CIMGUI_API void igTableNextRow(ImGuiTableRowFlags row_flags,float min_row_height); +CIMGUI_API bool igTableNextColumn(void); +CIMGUI_API bool igTableSetColumnIndex(int column_n); +CIMGUI_API void igTableSetupColumn(const char* label,ImGuiTableColumnFlags flags,float init_width_or_weight,ImGuiID user_data); +CIMGUI_API void igTableSetupScrollFreeze(int cols,int rows); +CIMGUI_API void igTableHeader(const char* label); +CIMGUI_API void igTableHeadersRow(void); +CIMGUI_API void igTableAngledHeadersRow(void); +CIMGUI_API ImGuiTableSortSpecs* igTableGetSortSpecs(void); +CIMGUI_API int igTableGetColumnCount(void); +CIMGUI_API int igTableGetColumnIndex(void); +CIMGUI_API int igTableGetRowIndex(void); +CIMGUI_API const char* igTableGetColumnName_Int(int column_n); +CIMGUI_API ImGuiTableColumnFlags igTableGetColumnFlags(int column_n); +CIMGUI_API void igTableSetColumnEnabled(int column_n,bool v); +CIMGUI_API int igTableGetHoveredColumn(void); +CIMGUI_API void igTableSetBgColor(ImGuiTableBgTarget target,ImU32 color,int column_n); +CIMGUI_API void igColumns(int count,const char* id,bool borders); +CIMGUI_API void igNextColumn(void); +CIMGUI_API int igGetColumnIndex(void); +CIMGUI_API float igGetColumnWidth(int column_index); +CIMGUI_API void igSetColumnWidth(int column_index,float width); +CIMGUI_API float igGetColumnOffset(int column_index); +CIMGUI_API void igSetColumnOffset(int column_index,float offset_x); +CIMGUI_API int igGetColumnsCount(void); +CIMGUI_API bool igBeginTabBar(const char* str_id,ImGuiTabBarFlags flags); +CIMGUI_API void igEndTabBar(void); +CIMGUI_API bool igBeginTabItem(const char* label,bool* p_open,ImGuiTabItemFlags flags); +CIMGUI_API void igEndTabItem(void); +CIMGUI_API bool igTabItemButton(const char* label,ImGuiTabItemFlags flags); +CIMGUI_API void igSetTabItemClosed(const char* tab_or_docked_window_label); +CIMGUI_API void igLogToTTY(int auto_open_depth); +CIMGUI_API void igLogToFile(int auto_open_depth,const char* filename); +CIMGUI_API void igLogToClipboard(int auto_open_depth); +CIMGUI_API void igLogFinish(void); +CIMGUI_API void igLogButtons(void); +CIMGUI_API void igLogText(const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igLogText0(const char* fmt); +#endif +CIMGUI_API void igLogTextV(const char* fmt,va_list args); +CIMGUI_API bool igBeginDragDropSource(ImGuiDragDropFlags flags); +CIMGUI_API bool igSetDragDropPayload(const char* type,const void* data,size_t sz,ImGuiCond cond); +CIMGUI_API void igEndDragDropSource(void); +CIMGUI_API bool igBeginDragDropTarget(void); +CIMGUI_API const ImGuiPayload* igAcceptDragDropPayload(const char* type,ImGuiDragDropFlags flags); +CIMGUI_API void igEndDragDropTarget(void); +CIMGUI_API const ImGuiPayload* igGetDragDropPayload(void); +CIMGUI_API void igBeginDisabled(bool disabled); +CIMGUI_API void igEndDisabled(void); +CIMGUI_API void igPushClipRect(const ImVec2_c clip_rect_min,const ImVec2_c clip_rect_max,bool intersect_with_current_clip_rect); +CIMGUI_API void igPopClipRect(void); +CIMGUI_API void igSetItemDefaultFocus(void); +CIMGUI_API void igSetKeyboardFocusHere(int offset); +CIMGUI_API void igSetNavCursorVisible(bool visible); +CIMGUI_API void igSetNextItemAllowOverlap(void); +CIMGUI_API bool igIsItemHovered(ImGuiHoveredFlags flags); +CIMGUI_API bool igIsItemActive(void); +CIMGUI_API bool igIsItemFocused(void); +CIMGUI_API bool igIsItemClicked(ImGuiMouseButton mouse_button); +CIMGUI_API bool igIsItemVisible(void); +CIMGUI_API bool igIsItemEdited(void); +CIMGUI_API bool igIsItemActivated(void); +CIMGUI_API bool igIsItemDeactivated(void); +CIMGUI_API bool igIsItemDeactivatedAfterEdit(void); +CIMGUI_API bool igIsItemToggledOpen(void); +CIMGUI_API bool igIsAnyItemHovered(void); +CIMGUI_API bool igIsAnyItemActive(void); +CIMGUI_API bool igIsAnyItemFocused(void); +CIMGUI_API ImGuiID igGetItemID(void); +CIMGUI_API ImVec2_c igGetItemRectMin(void); +CIMGUI_API ImVec2_c igGetItemRectMax(void); +CIMGUI_API ImVec2_c igGetItemRectSize(void); +CIMGUI_API ImGuiItemFlags igGetItemFlags(void); +CIMGUI_API ImGuiViewport* igGetMainViewport(void); +CIMGUI_API ImDrawList* igGetBackgroundDrawList_Nil(void); +CIMGUI_API ImDrawList* igGetForegroundDrawList_Nil(void); +CIMGUI_API bool igIsRectVisible_Nil(const ImVec2_c size); +CIMGUI_API bool igIsRectVisible_Vec2(const ImVec2_c rect_min,const ImVec2_c rect_max); +CIMGUI_API double igGetTime(void); +CIMGUI_API int igGetFrameCount(void); +CIMGUI_API ImDrawListSharedData* igGetDrawListSharedData(void); +CIMGUI_API const char* igGetStyleColorName(ImGuiCol idx); +CIMGUI_API void igSetStateStorage(ImGuiStorage* storage); +CIMGUI_API ImGuiStorage* igGetStateStorage(void); +CIMGUI_API ImVec2_c igCalcTextSize(const char* text,const char* text_end,bool hide_text_after_double_hash,float wrap_width); +CIMGUI_API ImVec4_c igColorConvertU32ToFloat4(ImU32 in); +CIMGUI_API ImU32 igColorConvertFloat4ToU32(const ImVec4_c in); +CIMGUI_API void igColorConvertRGBtoHSV(float r,float g,float b,float* out_h,float* out_s,float* out_v); +CIMGUI_API void igColorConvertHSVtoRGB(float h,float s,float v,float* out_r,float* out_g,float* out_b); +CIMGUI_API bool igIsKeyDown_Nil(ImGuiKey key); +CIMGUI_API bool igIsKeyPressed_Bool(ImGuiKey key,bool repeat); +CIMGUI_API bool igIsKeyReleased_Nil(ImGuiKey key); +CIMGUI_API bool igIsKeyChordPressed_Nil(ImGuiKeyChord key_chord); +CIMGUI_API int igGetKeyPressedAmount(ImGuiKey key,float repeat_delay,float rate); +CIMGUI_API const char* igGetKeyName(ImGuiKey key); +CIMGUI_API void igSetNextFrameWantCaptureKeyboard(bool want_capture_keyboard); +CIMGUI_API bool igShortcut_Nil(ImGuiKeyChord key_chord,ImGuiInputFlags flags); +CIMGUI_API void igSetNextItemShortcut(ImGuiKeyChord key_chord,ImGuiInputFlags flags); +CIMGUI_API bool igSetItemKeyOwner_Nil(ImGuiKey key); +CIMGUI_API bool igIsMouseDown_Nil(ImGuiMouseButton button); +CIMGUI_API bool igIsMouseClicked_Bool(ImGuiMouseButton button,bool repeat); +CIMGUI_API bool igIsMouseReleased_Nil(ImGuiMouseButton button); +CIMGUI_API bool igIsMouseDoubleClicked_Nil(ImGuiMouseButton button); +CIMGUI_API bool igIsMouseReleasedWithDelay(ImGuiMouseButton button,float delay); +CIMGUI_API int igGetMouseClickedCount(ImGuiMouseButton button); +CIMGUI_API bool igIsMouseHoveringRect(const ImVec2_c r_min,const ImVec2_c r_max,bool clip); +CIMGUI_API bool igIsMousePosValid(const ImVec2_c* mouse_pos); +CIMGUI_API bool igIsAnyMouseDown(void); +CIMGUI_API ImVec2_c igGetMousePos(void); +CIMGUI_API ImVec2_c igGetMousePosOnOpeningCurrentPopup(void); +CIMGUI_API bool igIsMouseDragging(ImGuiMouseButton button,float lock_threshold); +CIMGUI_API ImVec2_c igGetMouseDragDelta(ImGuiMouseButton button,float lock_threshold); +CIMGUI_API void igResetMouseDragDelta(ImGuiMouseButton button); +CIMGUI_API ImGuiMouseCursor igGetMouseCursor(void); +CIMGUI_API void igSetMouseCursor(ImGuiMouseCursor cursor_type); +CIMGUI_API void igSetNextFrameWantCaptureMouse(bool want_capture_mouse); +CIMGUI_API const char* igGetClipboardText(void); +CIMGUI_API void igSetClipboardText(const char* text); +CIMGUI_API void igLoadIniSettingsFromDisk(const char* ini_filename); +CIMGUI_API void igLoadIniSettingsFromMemory(const char* ini_data,size_t ini_size); +CIMGUI_API void igSaveIniSettingsToDisk(const char* ini_filename); +CIMGUI_API const char* igSaveIniSettingsToMemory(size_t* out_ini_size); +CIMGUI_API void igDebugStartItemPicker(void); +CIMGUI_API bool igDebugCheckVersionAndDataLayout(const char* version_str,size_t sz_io,size_t sz_style,size_t sz_vec2,size_t sz_vec4,size_t sz_drawvert,size_t sz_drawidx); +CIMGUI_API void igSetAllocatorFunctions(ImGuiMemAllocFunc alloc_func,ImGuiMemFreeFunc free_func,void* user_data); +CIMGUI_API void igGetAllocatorFunctions(ImGuiMemAllocFunc* p_alloc_func,ImGuiMemFreeFunc* p_free_func,void** p_user_data); +CIMGUI_API void* igMemAlloc(size_t size); +CIMGUI_API void igMemFree(void* ptr); +CIMGUI_API ImGuiTableSortSpecs* ImGuiTableSortSpecs_ImGuiTableSortSpecs(void); +CIMGUI_API void ImGuiTableSortSpecs_destroy(ImGuiTableSortSpecs* self); +CIMGUI_API ImGuiTableColumnSortSpecs* ImGuiTableColumnSortSpecs_ImGuiTableColumnSortSpecs(void); +CIMGUI_API void ImGuiTableColumnSortSpecs_destroy(ImGuiTableColumnSortSpecs* self); +CIMGUI_API ImGuiStyle* ImGuiStyle_ImGuiStyle(void); +CIMGUI_API void ImGuiStyle_destroy(ImGuiStyle* self); +CIMGUI_API void ImGuiStyle_ScaleAllSizes(ImGuiStyle* self,float scale_factor); +CIMGUI_API void ImGuiIO_AddKeyEvent(ImGuiIO* self,ImGuiKey key,bool down); +CIMGUI_API void ImGuiIO_AddKeyAnalogEvent(ImGuiIO* self,ImGuiKey key,bool down,float v); +CIMGUI_API void ImGuiIO_AddMousePosEvent(ImGuiIO* self,float x,float y); +CIMGUI_API void ImGuiIO_AddMouseButtonEvent(ImGuiIO* self,int button,bool down); +CIMGUI_API void ImGuiIO_AddMouseWheelEvent(ImGuiIO* self,float wheel_x,float wheel_y); +CIMGUI_API void ImGuiIO_AddMouseSourceEvent(ImGuiIO* self,ImGuiMouseSource source); +CIMGUI_API void ImGuiIO_AddFocusEvent(ImGuiIO* self,bool focused); +CIMGUI_API void ImGuiIO_AddInputCharacter(ImGuiIO* self,unsigned int c); +CIMGUI_API void ImGuiIO_AddInputCharacterUTF16(ImGuiIO* self,ImWchar16 c); +CIMGUI_API void ImGuiIO_AddInputCharactersUTF8(ImGuiIO* self,const char* str); +CIMGUI_API void ImGuiIO_SetKeyEventNativeData(ImGuiIO* self,ImGuiKey key,int native_keycode,int native_scancode,int native_legacy_index); +CIMGUI_API void ImGuiIO_SetAppAcceptingEvents(ImGuiIO* self,bool accepting_events); +CIMGUI_API void ImGuiIO_ClearEventsQueue(ImGuiIO* self); +CIMGUI_API void ImGuiIO_ClearInputKeys(ImGuiIO* self); +CIMGUI_API void ImGuiIO_ClearInputMouse(ImGuiIO* self); +CIMGUI_API ImGuiIO* ImGuiIO_ImGuiIO(void); +CIMGUI_API void ImGuiIO_destroy(ImGuiIO* self); +CIMGUI_API ImGuiInputTextCallbackData* ImGuiInputTextCallbackData_ImGuiInputTextCallbackData(void); +CIMGUI_API void ImGuiInputTextCallbackData_destroy(ImGuiInputTextCallbackData* self); +CIMGUI_API void ImGuiInputTextCallbackData_DeleteChars(ImGuiInputTextCallbackData* self,int pos,int bytes_count); +CIMGUI_API void ImGuiInputTextCallbackData_InsertChars(ImGuiInputTextCallbackData* self,int pos,const char* text,const char* text_end); +CIMGUI_API void ImGuiInputTextCallbackData_SelectAll(ImGuiInputTextCallbackData* self); +CIMGUI_API void ImGuiInputTextCallbackData_SetSelection(ImGuiInputTextCallbackData* self,int s,int e); +CIMGUI_API void ImGuiInputTextCallbackData_ClearSelection(ImGuiInputTextCallbackData* self); +CIMGUI_API bool ImGuiInputTextCallbackData_HasSelection(ImGuiInputTextCallbackData* self); +CIMGUI_API ImGuiPayload* ImGuiPayload_ImGuiPayload(void); +CIMGUI_API void ImGuiPayload_destroy(ImGuiPayload* self); +CIMGUI_API void ImGuiPayload_Clear(ImGuiPayload* self); +CIMGUI_API bool ImGuiPayload_IsDataType(ImGuiPayload* self,const char* type); +CIMGUI_API bool ImGuiPayload_IsPreview(ImGuiPayload* self); +CIMGUI_API bool ImGuiPayload_IsDelivery(ImGuiPayload* self); +CIMGUI_API ImGuiOnceUponAFrame* ImGuiOnceUponAFrame_ImGuiOnceUponAFrame(void); +CIMGUI_API void ImGuiOnceUponAFrame_destroy(ImGuiOnceUponAFrame* self); +CIMGUI_API ImGuiTextFilter* ImGuiTextFilter_ImGuiTextFilter(const char* default_filter); +CIMGUI_API void ImGuiTextFilter_destroy(ImGuiTextFilter* self); +CIMGUI_API bool ImGuiTextFilter_Draw(ImGuiTextFilter* self,const char* label,float width); +CIMGUI_API bool ImGuiTextFilter_PassFilter(ImGuiTextFilter* self,const char* text,const char* text_end); +CIMGUI_API void ImGuiTextFilter_Build(ImGuiTextFilter* self); +CIMGUI_API void ImGuiTextFilter_Clear(ImGuiTextFilter* self); +CIMGUI_API bool ImGuiTextFilter_IsActive(ImGuiTextFilter* self); +CIMGUI_API ImGuiTextRange* ImGuiTextRange_ImGuiTextRange_Nil(void); +CIMGUI_API void ImGuiTextRange_destroy(ImGuiTextRange* self); +CIMGUI_API ImGuiTextRange* ImGuiTextRange_ImGuiTextRange_Str(const char* _b,const char* _e); +CIMGUI_API bool ImGuiTextRange_empty(ImGuiTextRange* self); +CIMGUI_API void ImGuiTextRange_split(ImGuiTextRange* self,char separator,ImVector_ImGuiTextRange* out); +CIMGUI_API ImGuiTextBuffer* ImGuiTextBuffer_ImGuiTextBuffer(void); +CIMGUI_API void ImGuiTextBuffer_destroy(ImGuiTextBuffer* self); +CIMGUI_API const char* ImGuiTextBuffer_begin(ImGuiTextBuffer* self); +CIMGUI_API const char* ImGuiTextBuffer_end(ImGuiTextBuffer* self); +CIMGUI_API int ImGuiTextBuffer_size(ImGuiTextBuffer* self); +CIMGUI_API bool ImGuiTextBuffer_empty(ImGuiTextBuffer* self); +CIMGUI_API void ImGuiTextBuffer_clear(ImGuiTextBuffer* self); +CIMGUI_API void ImGuiTextBuffer_resize(ImGuiTextBuffer* self,int size); +CIMGUI_API void ImGuiTextBuffer_reserve(ImGuiTextBuffer* self,int capacity); +CIMGUI_API const char* ImGuiTextBuffer_c_str(ImGuiTextBuffer* self); +CIMGUI_API void ImGuiTextBuffer_append(ImGuiTextBuffer* self,const char* str,const char* str_end); +CIMGUI_API void ImGuiTextBuffer_appendfv(ImGuiTextBuffer* self,const char* fmt,va_list args); +CIMGUI_API ImGuiStoragePair* ImGuiStoragePair_ImGuiStoragePair_Int(ImGuiID _key,int _val); +CIMGUI_API void ImGuiStoragePair_destroy(ImGuiStoragePair* self); +CIMGUI_API ImGuiStoragePair* ImGuiStoragePair_ImGuiStoragePair_Float(ImGuiID _key,float _val); +CIMGUI_API ImGuiStoragePair* ImGuiStoragePair_ImGuiStoragePair_Ptr(ImGuiID _key,void* _val); +CIMGUI_API void ImGuiStorage_Clear(ImGuiStorage* self); +CIMGUI_API int ImGuiStorage_GetInt(ImGuiStorage* self,ImGuiID key,int default_val); +CIMGUI_API void ImGuiStorage_SetInt(ImGuiStorage* self,ImGuiID key,int val); +CIMGUI_API bool ImGuiStorage_GetBool(ImGuiStorage* self,ImGuiID key,bool default_val); +CIMGUI_API void ImGuiStorage_SetBool(ImGuiStorage* self,ImGuiID key,bool val); +CIMGUI_API float ImGuiStorage_GetFloat(ImGuiStorage* self,ImGuiID key,float default_val); +CIMGUI_API void ImGuiStorage_SetFloat(ImGuiStorage* self,ImGuiID key,float val); +CIMGUI_API void* ImGuiStorage_GetVoidPtr(ImGuiStorage* self,ImGuiID key); +CIMGUI_API void ImGuiStorage_SetVoidPtr(ImGuiStorage* self,ImGuiID key,void* val); +CIMGUI_API int* ImGuiStorage_GetIntRef(ImGuiStorage* self,ImGuiID key,int default_val); +CIMGUI_API bool* ImGuiStorage_GetBoolRef(ImGuiStorage* self,ImGuiID key,bool default_val); +CIMGUI_API float* ImGuiStorage_GetFloatRef(ImGuiStorage* self,ImGuiID key,float default_val); +CIMGUI_API void** ImGuiStorage_GetVoidPtrRef(ImGuiStorage* self,ImGuiID key,void* default_val); +CIMGUI_API void ImGuiStorage_BuildSortByKey(ImGuiStorage* self); +CIMGUI_API void ImGuiStorage_SetAllInt(ImGuiStorage* self,int val); +CIMGUI_API ImGuiListClipper* ImGuiListClipper_ImGuiListClipper(void); +CIMGUI_API void ImGuiListClipper_destroy(ImGuiListClipper* self); +CIMGUI_API void ImGuiListClipper_Begin(ImGuiListClipper* self,int items_count,float items_height); +CIMGUI_API void ImGuiListClipper_End(ImGuiListClipper* self); +CIMGUI_API bool ImGuiListClipper_Step(ImGuiListClipper* self); +CIMGUI_API void ImGuiListClipper_IncludeItemByIndex(ImGuiListClipper* self,int item_index); +CIMGUI_API void ImGuiListClipper_IncludeItemsByIndex(ImGuiListClipper* self,int item_begin,int item_end); +CIMGUI_API void ImGuiListClipper_SeekCursorForItem(ImGuiListClipper* self,int item_index); +CIMGUI_API ImColor* ImColor_ImColor_Nil(void); +CIMGUI_API void ImColor_destroy(ImColor* self); +CIMGUI_API ImColor* ImColor_ImColor_Float(float r,float g,float b,float a); +CIMGUI_API ImColor* ImColor_ImColor_Vec4(const ImVec4_c col); +CIMGUI_API ImColor* ImColor_ImColor_Int(int r,int g,int b,int a); +CIMGUI_API ImColor* ImColor_ImColor_U32(ImU32 rgba); +CIMGUI_API void ImColor_SetHSV(ImColor* self,float h,float s,float v,float a); +CIMGUI_API ImColor_c ImColor_HSV(float h,float s,float v,float a); +CIMGUI_API ImGuiSelectionBasicStorage* ImGuiSelectionBasicStorage_ImGuiSelectionBasicStorage(void); +CIMGUI_API void ImGuiSelectionBasicStorage_destroy(ImGuiSelectionBasicStorage* self); +CIMGUI_API void ImGuiSelectionBasicStorage_ApplyRequests(ImGuiSelectionBasicStorage* self,ImGuiMultiSelectIO* ms_io); +CIMGUI_API bool ImGuiSelectionBasicStorage_Contains(ImGuiSelectionBasicStorage* self,ImGuiID id); +CIMGUI_API void ImGuiSelectionBasicStorage_Clear(ImGuiSelectionBasicStorage* self); +CIMGUI_API void ImGuiSelectionBasicStorage_Swap(ImGuiSelectionBasicStorage* self,ImGuiSelectionBasicStorage* r); +CIMGUI_API void ImGuiSelectionBasicStorage_SetItemSelected(ImGuiSelectionBasicStorage* self,ImGuiID id,bool selected); +CIMGUI_API bool ImGuiSelectionBasicStorage_GetNextSelectedItem(ImGuiSelectionBasicStorage* self,void** opaque_it,ImGuiID* out_id); +CIMGUI_API ImGuiID ImGuiSelectionBasicStorage_GetStorageIdFromIndex(ImGuiSelectionBasicStorage* self,int idx); +CIMGUI_API ImGuiSelectionExternalStorage* ImGuiSelectionExternalStorage_ImGuiSelectionExternalStorage(void); +CIMGUI_API void ImGuiSelectionExternalStorage_destroy(ImGuiSelectionExternalStorage* self); +CIMGUI_API void ImGuiSelectionExternalStorage_ApplyRequests(ImGuiSelectionExternalStorage* self,ImGuiMultiSelectIO* ms_io); +CIMGUI_API ImDrawCmd* ImDrawCmd_ImDrawCmd(void); +CIMGUI_API void ImDrawCmd_destroy(ImDrawCmd* self); +CIMGUI_API ImTextureID ImDrawCmd_GetTexID(ImDrawCmd* self); +CIMGUI_API ImDrawListSplitter* ImDrawListSplitter_ImDrawListSplitter(void); +CIMGUI_API void ImDrawListSplitter_destroy(ImDrawListSplitter* self); +CIMGUI_API void ImDrawListSplitter_Clear(ImDrawListSplitter* self); +CIMGUI_API void ImDrawListSplitter_ClearFreeMemory(ImDrawListSplitter* self); +CIMGUI_API void ImDrawListSplitter_Split(ImDrawListSplitter* self,ImDrawList* draw_list,int count); +CIMGUI_API void ImDrawListSplitter_Merge(ImDrawListSplitter* self,ImDrawList* draw_list); +CIMGUI_API void ImDrawListSplitter_SetCurrentChannel(ImDrawListSplitter* self,ImDrawList* draw_list,int channel_idx); +CIMGUI_API ImDrawList* ImDrawList_ImDrawList(ImDrawListSharedData* shared_data); +CIMGUI_API void ImDrawList_destroy(ImDrawList* self); +CIMGUI_API void ImDrawList_PushClipRect(ImDrawList* self,const ImVec2_c clip_rect_min,const ImVec2_c clip_rect_max,bool intersect_with_current_clip_rect); +CIMGUI_API void ImDrawList_PushClipRectFullScreen(ImDrawList* self); +CIMGUI_API void ImDrawList_PopClipRect(ImDrawList* self); +CIMGUI_API void ImDrawList_PushTexture(ImDrawList* self,ImTextureRef_c tex_ref); +CIMGUI_API void ImDrawList_PopTexture(ImDrawList* self); +CIMGUI_API ImVec2_c ImDrawList_GetClipRectMin(ImDrawList* self); +CIMGUI_API ImVec2_c ImDrawList_GetClipRectMax(ImDrawList* self); +CIMGUI_API void ImDrawList_AddLine(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,ImU32 col,float thickness); +CIMGUI_API void ImDrawList_AddLineH(ImDrawList* self,float min_x,float max_x,float y,ImU32 col,float thickness); +CIMGUI_API void ImDrawList_AddLineV(ImDrawList* self,float x,float min_y,float max_y,ImU32 col,float thickness); +CIMGUI_API void ImDrawList_AddRect(ImDrawList* self,const ImVec2_c p_min,const ImVec2_c p_max,ImU32 col,float rounding,float thickness,ImDrawFlags flags); +CIMGUI_API void ImDrawList_AddRectFilled(ImDrawList* self,const ImVec2_c p_min,const ImVec2_c p_max,ImU32 col,float rounding,ImDrawFlags flags); +CIMGUI_API void ImDrawList_AddRectFilledMultiColor(ImDrawList* self,const ImVec2_c p_min,const ImVec2_c p_max,ImU32 col_upr_left,ImU32 col_upr_right,ImU32 col_bot_right,ImU32 col_bot_left); +CIMGUI_API void ImDrawList_AddQuad(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,ImU32 col,float thickness); +CIMGUI_API void ImDrawList_AddQuadFilled(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,ImU32 col); +CIMGUI_API void ImDrawList_AddTriangle(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,ImU32 col,float thickness); +CIMGUI_API void ImDrawList_AddTriangleFilled(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,ImU32 col); +CIMGUI_API void ImDrawList_AddCircle(ImDrawList* self,const ImVec2_c center,float radius,ImU32 col,int num_segments,float thickness); +CIMGUI_API void ImDrawList_AddCircleFilled(ImDrawList* self,const ImVec2_c center,float radius,ImU32 col,int num_segments); +CIMGUI_API void ImDrawList_AddNgon(ImDrawList* self,const ImVec2_c center,float radius,ImU32 col,int num_segments,float thickness); +CIMGUI_API void ImDrawList_AddNgonFilled(ImDrawList* self,const ImVec2_c center,float radius,ImU32 col,int num_segments); +CIMGUI_API void ImDrawList_AddEllipse(ImDrawList* self,const ImVec2_c center,const ImVec2_c radius,ImU32 col,float rot,int num_segments,float thickness); +CIMGUI_API void ImDrawList_AddEllipseFilled(ImDrawList* self,const ImVec2_c center,const ImVec2_c radius,ImU32 col,float rot,int num_segments); +CIMGUI_API void ImDrawList_AddText_Vec2(ImDrawList* self,const ImVec2_c pos,ImU32 col,const char* text_begin,const char* text_end); +CIMGUI_API void ImDrawList_AddText_FontPtr(ImDrawList* self,ImFont* font,float font_size,const ImVec2_c pos,ImU32 col,const char* text_begin,const char* text_end,float wrap_width,const ImVec4* cpu_fine_clip_rect); +CIMGUI_API void ImDrawList_AddBezierCubic(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,ImU32 col,float thickness,int num_segments); +CIMGUI_API void ImDrawList_AddBezierQuadratic(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,ImU32 col,float thickness,int num_segments); +CIMGUI_API void ImDrawList_AddPolyline(ImDrawList* self,const ImVec2_c* points,int num_points,ImU32 col,float thickness,ImDrawFlags flags); +CIMGUI_API void ImDrawList_AddConvexPolyFilled(ImDrawList* self,const ImVec2_c* points,int num_points,ImU32 col); +CIMGUI_API void ImDrawList_AddConcavePolyFilled(ImDrawList* self,const ImVec2_c* points,int num_points,ImU32 col); +CIMGUI_API void ImDrawList_AddImage(ImDrawList* self,ImTextureRef_c tex_ref,const ImVec2_c p_min,const ImVec2_c p_max,const ImVec2_c uv_min,const ImVec2_c uv_max,ImU32 col); +CIMGUI_API void ImDrawList_AddImageQuad(ImDrawList* self,ImTextureRef_c tex_ref,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,const ImVec2_c uv1,const ImVec2_c uv2,const ImVec2_c uv3,const ImVec2_c uv4,ImU32 col); +CIMGUI_API void ImDrawList_AddImageRounded(ImDrawList* self,ImTextureRef_c tex_ref,const ImVec2_c p_min,const ImVec2_c p_max,const ImVec2_c uv_min,const ImVec2_c uv_max,ImU32 col,float rounding,ImDrawFlags flags); +CIMGUI_API void ImDrawList_PathClear(ImDrawList* self); +CIMGUI_API void ImDrawList_PathLineTo(ImDrawList* self,const ImVec2_c pos); +CIMGUI_API void ImDrawList_PathLineToMergeDuplicate(ImDrawList* self,const ImVec2_c pos); +CIMGUI_API void ImDrawList_PathFillConvex(ImDrawList* self,ImU32 col); +CIMGUI_API void ImDrawList_PathFillConcave(ImDrawList* self,ImU32 col); +CIMGUI_API void ImDrawList_PathStroke(ImDrawList* self,ImU32 col,float thickness,ImDrawFlags flags); +CIMGUI_API void ImDrawList_PathArcTo(ImDrawList* self,const ImVec2_c center,float radius,float a_min,float a_max,int num_segments); +CIMGUI_API void ImDrawList_PathArcToFast(ImDrawList* self,const ImVec2_c center,float radius,int a_min_of_12,int a_max_of_12); +CIMGUI_API void ImDrawList_PathEllipticalArcTo(ImDrawList* self,const ImVec2_c center,const ImVec2_c radius,float rot,float a_min,float a_max,int num_segments); +CIMGUI_API void ImDrawList_PathBezierCubicCurveTo(ImDrawList* self,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,int num_segments); +CIMGUI_API void ImDrawList_PathBezierQuadraticCurveTo(ImDrawList* self,const ImVec2_c p2,const ImVec2_c p3,int num_segments); +CIMGUI_API void ImDrawList_PathRect(ImDrawList* self,const ImVec2_c rect_min,const ImVec2_c rect_max,float rounding,ImDrawFlags flags); +CIMGUI_API void ImDrawList_AddCallback(ImDrawList* self,ImDrawCallback callback,void* userdata,size_t userdata_size); +CIMGUI_API void ImDrawList_AddDrawCmd(ImDrawList* self); +CIMGUI_API ImDrawList* ImDrawList_CloneOutput(ImDrawList* self); +CIMGUI_API void ImDrawList_ChannelsSplit(ImDrawList* self,int count); +CIMGUI_API void ImDrawList_ChannelsMerge(ImDrawList* self); +CIMGUI_API void ImDrawList_ChannelsSetCurrent(ImDrawList* self,int n); +CIMGUI_API void ImDrawList_PrimReserve(ImDrawList* self,int idx_count,int vtx_count); +CIMGUI_API void ImDrawList_PrimUnreserve(ImDrawList* self,int idx_count,int vtx_count); +CIMGUI_API void ImDrawList_PrimRect(ImDrawList* self,const ImVec2_c a,const ImVec2_c b,ImU32 col); +CIMGUI_API void ImDrawList_PrimRectUV(ImDrawList* self,const ImVec2_c a,const ImVec2_c b,const ImVec2_c uv_a,const ImVec2_c uv_b,ImU32 col); +CIMGUI_API void ImDrawList_PrimQuadUV(ImDrawList* self,const ImVec2_c a,const ImVec2_c b,const ImVec2_c c,const ImVec2_c d,const ImVec2_c uv_a,const ImVec2_c uv_b,const ImVec2_c uv_c,const ImVec2_c uv_d,ImU32 col); +CIMGUI_API void ImDrawList_PrimWriteVtx(ImDrawList* self,const ImVec2_c pos,const ImVec2_c uv,ImU32 col); +CIMGUI_API void ImDrawList_PrimWriteIdx(ImDrawList* self,ImDrawIdx idx); +CIMGUI_API void ImDrawList_PrimVtx(ImDrawList* self,const ImVec2_c pos,const ImVec2_c uv,ImU32 col); +CIMGUI_API void ImDrawList__SetDrawListSharedData(ImDrawList* self,ImDrawListSharedData* data); +CIMGUI_API void ImDrawList__ResetForNewFrame(ImDrawList* self); +CIMGUI_API void ImDrawList__ClearFreeMemory(ImDrawList* self); +CIMGUI_API void ImDrawList__PopUnusedDrawCmd(ImDrawList* self); +CIMGUI_API void ImDrawList__TryMergeDrawCmds(ImDrawList* self); +CIMGUI_API void ImDrawList__OnChangedClipRect(ImDrawList* self); +CIMGUI_API void ImDrawList__OnChangedTexture(ImDrawList* self); +CIMGUI_API void ImDrawList__OnChangedVtxOffset(ImDrawList* self); +CIMGUI_API void ImDrawList__SetTexture(ImDrawList* self,ImTextureRef_c tex_ref); +CIMGUI_API int ImDrawList__CalcCircleAutoSegmentCount(ImDrawList* self,float radius); +CIMGUI_API void ImDrawList__PathArcToFastEx(ImDrawList* self,const ImVec2_c center,float radius,int a_min_sample,int a_max_sample,int a_step); +CIMGUI_API void ImDrawList__PathArcToN(ImDrawList* self,const ImVec2_c center,float radius,float a_min,float a_max,int num_segments); +CIMGUI_API ImDrawData* ImDrawData_ImDrawData(void); +CIMGUI_API void ImDrawData_destroy(ImDrawData* self); +CIMGUI_API void ImDrawData_Clear(ImDrawData* self); +CIMGUI_API void ImDrawData_AddDrawList(ImDrawData* self,ImDrawList* draw_list); +CIMGUI_API void ImDrawData_DeIndexAllBuffers(ImDrawData* self); +CIMGUI_API void ImDrawData_ScaleClipRects(ImDrawData* self,const ImVec2_c fb_scale); +CIMGUI_API ImTextureData* ImTextureData_ImTextureData(void); +CIMGUI_API void ImTextureData_destroy(ImTextureData* self); +CIMGUI_API void ImTextureData_Create(ImTextureData* self,ImTextureFormat format,int w,int h); +CIMGUI_API void ImTextureData_DestroyPixels(ImTextureData* self); +CIMGUI_API void* ImTextureData_GetPixels(ImTextureData* self); +CIMGUI_API void* ImTextureData_GetPixelsAt(ImTextureData* self,int x,int y); +CIMGUI_API int ImTextureData_GetSizeInBytes(ImTextureData* self); +CIMGUI_API int ImTextureData_GetPitch(ImTextureData* self); +CIMGUI_API ImTextureRef_c ImTextureData_GetTexRef(ImTextureData* self); +CIMGUI_API ImTextureID ImTextureData_GetTexID(ImTextureData* self); +CIMGUI_API void ImTextureData_SetTexID(ImTextureData* self,ImTextureID tex_id); +CIMGUI_API void ImTextureData_SetStatus(ImTextureData* self,ImTextureStatus status); +CIMGUI_API ImFontConfig* ImFontConfig_ImFontConfig(void); +CIMGUI_API void ImFontConfig_destroy(ImFontConfig* self); +CIMGUI_API ImFontGlyph* ImFontGlyph_ImFontGlyph(void); +CIMGUI_API void ImFontGlyph_destroy(ImFontGlyph* self); +CIMGUI_API ImFontGlyphRangesBuilder* ImFontGlyphRangesBuilder_ImFontGlyphRangesBuilder(void); +CIMGUI_API void ImFontGlyphRangesBuilder_destroy(ImFontGlyphRangesBuilder* self); +CIMGUI_API void ImFontGlyphRangesBuilder_Clear(ImFontGlyphRangesBuilder* self); +CIMGUI_API bool ImFontGlyphRangesBuilder_GetBit(ImFontGlyphRangesBuilder* self,size_t n); +CIMGUI_API void ImFontGlyphRangesBuilder_SetBit(ImFontGlyphRangesBuilder* self,size_t n); +CIMGUI_API void ImFontGlyphRangesBuilder_AddChar(ImFontGlyphRangesBuilder* self,ImWchar c); +CIMGUI_API void ImFontGlyphRangesBuilder_AddText(ImFontGlyphRangesBuilder* self,const char* text,const char* text_end); +CIMGUI_API void ImFontGlyphRangesBuilder_AddRanges(ImFontGlyphRangesBuilder* self,const ImWchar* ranges); +CIMGUI_API void ImFontGlyphRangesBuilder_BuildRanges(ImFontGlyphRangesBuilder* self,ImVector_ImWchar* out_ranges); +CIMGUI_API ImFontAtlasRect* ImFontAtlasRect_ImFontAtlasRect(void); +CIMGUI_API void ImFontAtlasRect_destroy(ImFontAtlasRect* self); +CIMGUI_API ImFontAtlas* ImFontAtlas_ImFontAtlas(void); +CIMGUI_API void ImFontAtlas_destroy(ImFontAtlas* self); +CIMGUI_API ImFont* ImFontAtlas_AddFont(ImFontAtlas* self,const ImFontConfig* font_cfg); +CIMGUI_API ImFont* ImFontAtlas_AddFontDefault(ImFontAtlas* self,const ImFontConfig* font_cfg); +CIMGUI_API ImFont* ImFontAtlas_AddFontDefaultVector(ImFontAtlas* self,const ImFontConfig* font_cfg); +CIMGUI_API ImFont* ImFontAtlas_AddFontDefaultBitmap(ImFontAtlas* self,const ImFontConfig* font_cfg); +CIMGUI_API ImFont* ImFontAtlas_AddFontFromFileTTF(ImFontAtlas* self,const char* filename,float size_pixels,const ImFontConfig* font_cfg,const ImWchar* glyph_ranges); +CIMGUI_API ImFont* ImFontAtlas_AddFontFromMemoryTTF(ImFontAtlas* self,void* font_data,int font_data_size,float size_pixels,const ImFontConfig* font_cfg,const ImWchar* glyph_ranges); +CIMGUI_API ImFont* ImFontAtlas_AddFontFromMemoryCompressedTTF(ImFontAtlas* self,const void* compressed_font_data,int compressed_font_data_size,float size_pixels,const ImFontConfig* font_cfg,const ImWchar* glyph_ranges); +CIMGUI_API ImFont* ImFontAtlas_AddFontFromMemoryCompressedBase85TTF(ImFontAtlas* self,const char* compressed_font_data_base85,float size_pixels,const ImFontConfig* font_cfg,const ImWchar* glyph_ranges); +CIMGUI_API void ImFontAtlas_RemoveFont(ImFontAtlas* self,ImFont* font); +CIMGUI_API void ImFontAtlas_CompactCache(ImFontAtlas* self); +CIMGUI_API void ImFontAtlas_SetFontLoader(ImFontAtlas* self,const ImFontLoader* font_loader); +CIMGUI_API void ImFontAtlas_Clear(ImFontAtlas* self); +CIMGUI_API void ImFontAtlas_ClearFonts(ImFontAtlas* self); +CIMGUI_API void ImFontAtlas_ClearInputData(ImFontAtlas* self); +CIMGUI_API void ImFontAtlas_ClearTexData(ImFontAtlas* self); +CIMGUI_API const ImWchar* ImFontAtlas_GetGlyphRangesDefault(ImFontAtlas* self); +CIMGUI_API ImFontAtlasRectId ImFontAtlas_AddCustomRect(ImFontAtlas* self,int width,int height,ImFontAtlasRect* out_r); +CIMGUI_API void ImFontAtlas_RemoveCustomRect(ImFontAtlas* self,ImFontAtlasRectId id); +CIMGUI_API bool ImFontAtlas_GetCustomRect(ImFontAtlas* self,ImFontAtlasRectId id,ImFontAtlasRect* out_r); +CIMGUI_API ImFontBaked* ImFontBaked_ImFontBaked(void); +CIMGUI_API void ImFontBaked_destroy(ImFontBaked* self); +CIMGUI_API void ImFontBaked_ClearOutputData(ImFontBaked* self); +CIMGUI_API ImFontGlyph* ImFontBaked_FindGlyph(ImFontBaked* self,ImWchar c); +CIMGUI_API ImFontGlyph* ImFontBaked_FindGlyphNoFallback(ImFontBaked* self,ImWchar c); +CIMGUI_API float ImFontBaked_GetCharAdvance(ImFontBaked* self,ImWchar c); +CIMGUI_API bool ImFontBaked_IsGlyphLoaded(ImFontBaked* self,ImWchar c); +CIMGUI_API ImFont* ImFont_ImFont(void); +CIMGUI_API void ImFont_destroy(ImFont* self); +CIMGUI_API bool ImFont_IsGlyphInFont(ImFont* self,ImWchar c); +CIMGUI_API bool ImFont_IsLoaded(ImFont* self); +CIMGUI_API const char* ImFont_GetDebugName(ImFont* self); +CIMGUI_API ImFontBaked* ImFont_GetFontBaked(ImFont* self,float font_size,float density); +CIMGUI_API ImVec2_c ImFont_CalcTextSizeA(ImFont* self,float size,float max_width,float wrap_width,const char* text_begin,const char* text_end,const char** out_remaining); +CIMGUI_API const char* ImFont_CalcWordWrapPosition(ImFont* self,float size,const char* text,const char* text_end,float wrap_width); +CIMGUI_API void ImFont_RenderChar(ImFont* self,ImDrawList* draw_list,float size,const ImVec2_c pos,ImU32 col,ImWchar c,const ImVec4* cpu_fine_clip); +CIMGUI_API void ImFont_RenderText(ImFont* self,ImDrawList* draw_list,float size,const ImVec2_c pos,ImU32 col,const ImVec4_c clip_rect,const char* text_begin,const char* text_end,float wrap_width,ImDrawTextFlags flags); +CIMGUI_API void ImFont_ClearOutputData(ImFont* self); +CIMGUI_API void ImFont_AddRemapChar(ImFont* self,ImWchar from_codepoint,ImWchar to_codepoint); +CIMGUI_API bool ImFont_IsGlyphRangeUnused(ImFont* self,unsigned int c_begin,unsigned int c_last); +CIMGUI_API ImGuiViewport* ImGuiViewport_ImGuiViewport(void); +CIMGUI_API void ImGuiViewport_destroy(ImGuiViewport* self); +CIMGUI_API ImVec2_c ImGuiViewport_GetCenter(ImGuiViewport* self); +CIMGUI_API ImVec2_c ImGuiViewport_GetWorkCenter(ImGuiViewport* self); +CIMGUI_API ImGuiPlatformIO* ImGuiPlatformIO_ImGuiPlatformIO(void); +CIMGUI_API void ImGuiPlatformIO_destroy(ImGuiPlatformIO* self); +CIMGUI_API void ImGuiPlatformIO_ClearPlatformHandlers(ImGuiPlatformIO* self); +CIMGUI_API void ImGuiPlatformIO_ClearRendererHandlers(ImGuiPlatformIO* self); +CIMGUI_API ImGuiPlatformImeData* ImGuiPlatformImeData_ImGuiPlatformImeData(void); +CIMGUI_API void ImGuiPlatformImeData_destroy(ImGuiPlatformImeData* self); +CIMGUI_API ImGuiID igImHashData(const void* data,size_t data_size,ImGuiID seed); +CIMGUI_API ImGuiID igImHashStr(const char* data,size_t data_size,ImGuiID seed); +CIMGUI_API const char* igImHashSkipUncontributingPrefix(const char* label); +CIMGUI_API void igImQsort(void* base,size_t count,size_t size_of_element,int(*compare_func)(void const*,void const*)); +CIMGUI_API ImU32 igImAlphaBlendColors(ImU32 col_a,ImU32 col_b); +CIMGUI_API bool igImIsPowerOfTwo_Int(int v); +CIMGUI_API bool igImIsPowerOfTwo_U64(ImU64 v); +CIMGUI_API int igImUpperPowerOfTwo(int v); +CIMGUI_API unsigned int igImCountSetBits(unsigned int v); +CIMGUI_API int igImStricmp(const char* str1,const char* str2); +CIMGUI_API int igImStrnicmp(const char* str1,const char* str2,size_t count); +CIMGUI_API void igImStrncpy(char* dst,const char* src,size_t count); +CIMGUI_API char* igImStrdup(const char* str); +CIMGUI_API void* igImMemdup(const void* src,size_t size); +CIMGUI_API char* igImStrdupcpy(char* dst,size_t* p_dst_size,const char* str); +CIMGUI_API const char* igImStrchrRange(const char* str_begin,const char* str_end,char c); +CIMGUI_API const char* igImStreolRange(const char* str,const char* str_end); +CIMGUI_API const char* igImStristr(const char* haystack,const char* haystack_end,const char* needle,const char* needle_end); +CIMGUI_API void igImStrTrimBlanks(char* str); +CIMGUI_API const char* igImStrSkipBlank(const char* str); +CIMGUI_API int igImStrlenW(const ImWchar* str); +CIMGUI_API const char* igImStrbol(const char* buf_mid_line,const char* buf_begin); +CIMGUI_API char igImToUpper(char c); +CIMGUI_API bool igImCharIsBlankA(char c); +CIMGUI_API bool igImCharIsBlankW(unsigned int c); +CIMGUI_API bool igImCharIsXdigitA(char c); +CIMGUI_API int igImFormatString(char* buf,size_t buf_size,const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API int igImFormatString0(char* buf,size_t buf_size,const char* fmt); +#endif +CIMGUI_API int igImFormatStringV(char* buf,size_t buf_size,const char* fmt,va_list args); +CIMGUI_API void igImFormatStringToTempBuffer(const char** out_buf,const char** out_buf_end,const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igImFormatStringToTempBuffer0(const char** out_buf,const char** out_buf_end,const char* fmt); +#endif +CIMGUI_API void igImFormatStringToTempBufferV(const char** out_buf,const char** out_buf_end,const char* fmt,va_list args); +CIMGUI_API const char* igImParseFormatFindStart(const char* format); +CIMGUI_API const char* igImParseFormatFindEnd(const char* format); +CIMGUI_API const char* igImParseFormatTrimDecorations(const char* format,char* buf,size_t buf_size); +CIMGUI_API void igImParseFormatSanitizeForPrinting(const char* fmt_in,char* fmt_out,size_t fmt_out_size); +CIMGUI_API const char* igImParseFormatSanitizeForScanning(const char* fmt_in,char* fmt_out,size_t fmt_out_size); +CIMGUI_API int igImParseFormatPrecision(const char* format,int default_value); +CIMGUI_API int igImTextCharToUtf8(char out_buf[5],unsigned int c); +CIMGUI_API int igImTextStrToUtf8(char* out_buf,int out_buf_size,const ImWchar* in_text,const ImWchar* in_text_end); +CIMGUI_API int igImTextCharFromUtf8(unsigned int* out_char,const char* in_text,const char* in_text_end); +CIMGUI_API int igImTextStrFromUtf8(ImWchar* out_buf,int out_buf_size,const char* in_text,const char* in_text_end,const char** in_remaining); +CIMGUI_API int igImTextCountCharsFromUtf8(const char* in_text,const char* in_text_end); +CIMGUI_API int igImTextCountUtf8BytesFromChar(const char* in_text,const char* in_text_end); +CIMGUI_API int igImTextCountUtf8BytesFromStr(const ImWchar* in_text,const ImWchar* in_text_end); +CIMGUI_API const char* igImTextFindPreviousUtf8Codepoint(const char* in_text_start,const char* in_p); +CIMGUI_API const char* igImTextFindValidUtf8CodepointEnd(const char* in_text_start,const char* in_text_end,const char* in_p); +CIMGUI_API int igImTextCountLines(const char* in_text,const char* in_text_end); +CIMGUI_API ImVec2_c igImFontCalcTextSizeEx(ImFont* font,float size,float max_width,float wrap_width,const char* text_begin,const char* text_end_display,const char* text_end,const char** out_remaining,ImVec2_c* out_offset,ImDrawTextFlags flags); +CIMGUI_API const char* igImFontCalcWordWrapPositionEx(ImFont* font,float size,const char* text,const char* text_end,float wrap_width,ImDrawTextFlags flags); +CIMGUI_API const char* igImTextCalcWordWrapNextLineStart(const char* text,const char* text_end,ImDrawTextFlags flags); +CIMGUI_API void igImTextInitClassifiers(void); +CIMGUI_API void igImTextClassifierClear(ImU32* bits,unsigned int codepoint_min,unsigned int codepoint_end,ImWcharClass char_class); +CIMGUI_API void igImTextClassifierSetCharClass(ImU32* bits,unsigned int codepoint_min,unsigned int codepoint_end,ImWcharClass char_class,unsigned int c); +CIMGUI_API void igImTextClassifierSetCharClassFromStr(ImU32* bits,unsigned int codepoint_min,unsigned int codepoint_end,ImWcharClass char_class,const char* s); +CIMGUI_API ImFileHandle igImFileOpen(const char* filename,const char* mode); +CIMGUI_API bool igImFileClose(ImFileHandle file); +CIMGUI_API ImU64 igImFileGetSize(ImFileHandle file); +CIMGUI_API ImU64 igImFileRead(void* data,ImU64 size,ImU64 count,ImFileHandle file); +CIMGUI_API ImU64 igImFileWrite(const void* data,ImU64 size,ImU64 count,ImFileHandle file); +CIMGUI_API void* igImFileLoadToMemory(const char* filename,const char* mode,size_t* out_file_size,int padding_bytes); +CIMGUI_API float igImPow_Float(float x,float y); +CIMGUI_API double igImPow_double(double x,double y); +CIMGUI_API float igImLog_Float(float x); +CIMGUI_API double igImLog_double(double x); +CIMGUI_API int igImAbs_Int(int x); +CIMGUI_API float igImAbs_Float(float x); +CIMGUI_API double igImAbs_double(double x); +CIMGUI_API float igImSign_Float(float x); +CIMGUI_API double igImSign_double(double x); +CIMGUI_API float igImRsqrt_Float(float x); +CIMGUI_API double igImRsqrt_double(double x); +CIMGUI_API ImVec2_c igImMin(const ImVec2_c lhs,const ImVec2_c rhs); +CIMGUI_API ImVec2_c igImMax(const ImVec2_c lhs,const ImVec2_c rhs); +CIMGUI_API ImVec2_c igImClamp(const ImVec2_c v,const ImVec2_c mn,const ImVec2_c mx); +CIMGUI_API ImVec2_c igImLerp_Vec2Float(const ImVec2_c a,const ImVec2_c b,float t); +CIMGUI_API ImVec2_c igImLerp_Vec2Vec2(const ImVec2_c a,const ImVec2_c b,const ImVec2_c t); +CIMGUI_API ImVec4_c igImLerp_Vec4(const ImVec4_c a,const ImVec4_c b,float t); +CIMGUI_API float igImSaturate(float f); +CIMGUI_API float igImLengthSqr_Vec2(const ImVec2_c lhs); +CIMGUI_API float igImLengthSqr_Vec4(const ImVec4_c lhs); +CIMGUI_API float igImInvLength(const ImVec2_c lhs,float fail_value); +CIMGUI_API float igImTrunc_Float(float f); +CIMGUI_API ImVec2_c igImTrunc_Vec2(const ImVec2_c v); +CIMGUI_API float igImFloor_Float(float f); +CIMGUI_API ImVec2_c igImFloor_Vec2(const ImVec2_c v); +CIMGUI_API float igImTrunc64(float f); +CIMGUI_API float igImRound64(float f); +CIMGUI_API float igImCeilFast(float f); +CIMGUI_API int igImModPositive(int a,int b); +CIMGUI_API float igImDot(const ImVec2_c a,const ImVec2_c b); +CIMGUI_API ImVec2_c igImRotate(const ImVec2_c v,float cos_a,float sin_a); +CIMGUI_API float igImLinearSweep(float current,float target,float speed); +CIMGUI_API float igImLinearRemapClamp(float s0,float s1,float d0,float d1,float x); +CIMGUI_API ImVec2_c igImMul(const ImVec2_c lhs,const ImVec2_c rhs); +CIMGUI_API bool igImIsFloatAboveGuaranteedIntegerPrecision(float f); +CIMGUI_API float igImExponentialMovingAverage(float avg,float sample,int n); +CIMGUI_API ImVec2_c igImBezierCubicCalc(const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,float t); +CIMGUI_API ImVec2_c igImBezierCubicClosestPoint(const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,const ImVec2_c p,int num_segments); +CIMGUI_API ImVec2_c igImBezierCubicClosestPointCasteljau(const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,const ImVec2_c p,float tess_tol); +CIMGUI_API ImVec2_c igImBezierQuadraticCalc(const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,float t); +CIMGUI_API ImVec2_c igImLineClosestPoint(const ImVec2_c a,const ImVec2_c b,const ImVec2_c p); +CIMGUI_API bool igImTriangleContainsPoint(const ImVec2_c a,const ImVec2_c b,const ImVec2_c c,const ImVec2_c p); +CIMGUI_API ImVec2_c igImTriangleClosestPoint(const ImVec2_c a,const ImVec2_c b,const ImVec2_c c,const ImVec2_c p); +CIMGUI_API void igImTriangleBarycentricCoords(const ImVec2_c a,const ImVec2_c b,const ImVec2_c c,const ImVec2_c p,float* out_u,float* out_v,float* out_w); +CIMGUI_API float igImTriangleArea(const ImVec2_c a,const ImVec2_c b,const ImVec2_c c); +CIMGUI_API bool igImTriangleIsClockwise(const ImVec2_c a,const ImVec2_c b,const ImVec2_c c); +CIMGUI_API ImVec1* ImVec1_ImVec1_Nil(void); +CIMGUI_API void ImVec1_destroy(ImVec1* self); +CIMGUI_API ImVec1* ImVec1_ImVec1_Float(float _x); +CIMGUI_API ImVec2i* ImVec2i_ImVec2i_Nil(void); +CIMGUI_API void ImVec2i_destroy(ImVec2i* self); +CIMGUI_API ImVec2i* ImVec2i_ImVec2i_Int(int _x,int _y); +CIMGUI_API ImVec2ih* ImVec2ih_ImVec2ih_Nil(void); +CIMGUI_API void ImVec2ih_destroy(ImVec2ih* self); +CIMGUI_API ImVec2ih* ImVec2ih_ImVec2ih_short(short _x,short _y); +CIMGUI_API ImVec2ih* ImVec2ih_ImVec2ih_Vec2(const ImVec2_c rhs); +CIMGUI_API ImRect* ImRect_ImRect_Nil(void); +CIMGUI_API void ImRect_destroy(ImRect* self); +CIMGUI_API ImRect* ImRect_ImRect_Vec2(const ImVec2_c min,const ImVec2_c max); +CIMGUI_API ImRect* ImRect_ImRect_Vec4(const ImVec4_c v); +CIMGUI_API ImRect* ImRect_ImRect_Float(float x1,float y1,float x2,float y2); +CIMGUI_API ImVec2_c ImRect_GetCenter(ImRect* self); +CIMGUI_API ImVec2_c ImRect_GetSize(ImRect* self); +CIMGUI_API float ImRect_GetWidth(ImRect* self); +CIMGUI_API float ImRect_GetHeight(ImRect* self); +CIMGUI_API float ImRect_GetArea(ImRect* self); +CIMGUI_API ImVec2_c ImRect_GetTL(ImRect* self); +CIMGUI_API ImVec2_c ImRect_GetTR(ImRect* self); +CIMGUI_API ImVec2_c ImRect_GetBL(ImRect* self); +CIMGUI_API ImVec2_c ImRect_GetBR(ImRect* self); +CIMGUI_API bool ImRect_Contains_Vec2(ImRect* self,const ImVec2_c p); +CIMGUI_API bool ImRect_Contains_Rect(ImRect* self,const ImRect_c r); +CIMGUI_API bool ImRect_ContainsWithPad(ImRect* self,const ImVec2_c p,const ImVec2_c pad); +CIMGUI_API bool ImRect_Overlaps(ImRect* self,const ImRect_c r); +CIMGUI_API void ImRect_Add_Vec2(ImRect* self,const ImVec2_c p); +CIMGUI_API void ImRect_Add_Rect(ImRect* self,const ImRect_c r); +CIMGUI_API void ImRect_AddX(ImRect* self,float x); +CIMGUI_API void ImRect_AddY(ImRect* self,float y); +CIMGUI_API void ImRect_Expand_Float(ImRect* self,const float amount); +CIMGUI_API void ImRect_Expand_Vec2(ImRect* self,const ImVec2_c amount); +CIMGUI_API void ImRect_Translate(ImRect* self,const ImVec2_c d); +CIMGUI_API void ImRect_TranslateX(ImRect* self,float dx); +CIMGUI_API void ImRect_TranslateY(ImRect* self,float dy); +CIMGUI_API void ImRect_ClipWith(ImRect* self,const ImRect_c r); +CIMGUI_API void ImRect_ClipWithFull(ImRect* self,const ImRect_c r); +CIMGUI_API bool ImRect_IsInverted(ImRect* self); +CIMGUI_API ImVec4_c ImRect_ToVec4(ImRect* self); +CIMGUI_API const ImVec4_c* ImRect_AsVec4(ImRect* self); +CIMGUI_API size_t igImBitArrayGetStorageSizeInBytes(int bitcount); +CIMGUI_API void igImBitArrayClearAllBits(ImU32* arr,int bitcount); +CIMGUI_API bool igImBitArrayTestBit(const ImU32* arr,int n); +CIMGUI_API void igImBitArrayClearBit(ImU32* arr,int n); +CIMGUI_API void igImBitArraySetBit(ImU32* arr,int n); +CIMGUI_API void igImBitArraySetBitRange(ImU32* arr,int n,int n2); +CIMGUI_API void ImBitVector_Create(ImBitVector* self,int sz); +CIMGUI_API void ImBitVector_Clear(ImBitVector* self); +CIMGUI_API bool ImBitVector_TestBit(ImBitVector* self,int n); +CIMGUI_API void ImBitVector_SetBit(ImBitVector* self,int n); +CIMGUI_API void ImBitVector_ClearBit(ImBitVector* self,int n); +CIMGUI_API void ImGuiTextIndex_clear(ImGuiTextIndex* self); +CIMGUI_API int ImGuiTextIndex_size(ImGuiTextIndex* self); +CIMGUI_API const char* ImGuiTextIndex_get_line_begin(ImGuiTextIndex* self,const char* base,int n); +CIMGUI_API const char* ImGuiTextIndex_get_line_end(ImGuiTextIndex* self,const char* base,int n); +CIMGUI_API void ImGuiTextIndex_append(ImGuiTextIndex* self,const char* base,int old_size,int new_size); +CIMGUI_API ImGuiStoragePair* igImLowerBound(ImGuiStoragePair* in_begin,ImGuiStoragePair* in_end,ImGuiID key); +CIMGUI_API ImDrawListSharedData* ImDrawListSharedData_ImDrawListSharedData(void); +CIMGUI_API void ImDrawListSharedData_destroy(ImDrawListSharedData* self); +CIMGUI_API void ImDrawListSharedData_SetCircleTessellationMaxError(ImDrawListSharedData* self,float max_error); +CIMGUI_API ImDrawDataBuilder* ImDrawDataBuilder_ImDrawDataBuilder(void); +CIMGUI_API void ImDrawDataBuilder_destroy(ImDrawDataBuilder* self); +CIMGUI_API void* ImGuiStyleVarInfo_GetVarPtr(ImGuiStyleVarInfo* self,void* parent); +CIMGUI_API ImGuiStyleMod* ImGuiStyleMod_ImGuiStyleMod_Int(ImGuiStyleVar idx,int v); +CIMGUI_API void ImGuiStyleMod_destroy(ImGuiStyleMod* self); +CIMGUI_API ImGuiStyleMod* ImGuiStyleMod_ImGuiStyleMod_Float(ImGuiStyleVar idx,float v); +CIMGUI_API ImGuiStyleMod* ImGuiStyleMod_ImGuiStyleMod_Vec2(ImGuiStyleVar idx,ImVec2_c v); +CIMGUI_API ImGuiComboPreviewData* ImGuiComboPreviewData_ImGuiComboPreviewData(void); +CIMGUI_API void ImGuiComboPreviewData_destroy(ImGuiComboPreviewData* self); +CIMGUI_API ImGuiMenuColumns* ImGuiMenuColumns_ImGuiMenuColumns(void); +CIMGUI_API void ImGuiMenuColumns_destroy(ImGuiMenuColumns* self); +CIMGUI_API void ImGuiMenuColumns_Update(ImGuiMenuColumns* self,float spacing,bool window_reappearing); +CIMGUI_API float ImGuiMenuColumns_DeclColumns(ImGuiMenuColumns* self,float w_icon,float w_label,float w_shortcut,float w_mark); +CIMGUI_API void ImGuiMenuColumns_CalcNextTotalWidth(ImGuiMenuColumns* self,bool update_offsets); +CIMGUI_API ImGuiInputTextDeactivatedState* ImGuiInputTextDeactivatedState_ImGuiInputTextDeactivatedState(void); +CIMGUI_API void ImGuiInputTextDeactivatedState_destroy(ImGuiInputTextDeactivatedState* self); +CIMGUI_API void ImGuiInputTextDeactivatedState_ClearFreeMemory(ImGuiInputTextDeactivatedState* self); +CIMGUI_API ImGuiInputTextState* ImGuiInputTextState_ImGuiInputTextState(void); +CIMGUI_API void ImGuiInputTextState_destroy(ImGuiInputTextState* self); +CIMGUI_API void ImGuiInputTextState_ClearText(ImGuiInputTextState* self); +CIMGUI_API void ImGuiInputTextState_ClearFreeMemory(ImGuiInputTextState* self); +CIMGUI_API void ImGuiInputTextState_OnKeyPressed(ImGuiInputTextState* self,int key); +CIMGUI_API void ImGuiInputTextState_OnCharPressed(ImGuiInputTextState* self,unsigned int c); +CIMGUI_API float ImGuiInputTextState_GetPreferredOffsetX(ImGuiInputTextState* self); +CIMGUI_API const char* ImGuiInputTextState_GetText(ImGuiInputTextState* self); +CIMGUI_API void ImGuiInputTextState_CursorAnimReset(ImGuiInputTextState* self); +CIMGUI_API void ImGuiInputTextState_CursorClamp(ImGuiInputTextState* self); +CIMGUI_API bool ImGuiInputTextState_HasSelection(ImGuiInputTextState* self); +CIMGUI_API void ImGuiInputTextState_ClearSelection(ImGuiInputTextState* self); +CIMGUI_API int ImGuiInputTextState_GetCursorPos(ImGuiInputTextState* self); +CIMGUI_API int ImGuiInputTextState_GetSelectionStart(ImGuiInputTextState* self); +CIMGUI_API int ImGuiInputTextState_GetSelectionEnd(ImGuiInputTextState* self); +CIMGUI_API void ImGuiInputTextState_SetSelection(ImGuiInputTextState* self,int start,int end); +CIMGUI_API void ImGuiInputTextState_SelectAll(ImGuiInputTextState* self); +CIMGUI_API void ImGuiInputTextState_ReloadUserBufAndSelectAll(ImGuiInputTextState* self); +CIMGUI_API void ImGuiInputTextState_ReloadUserBufAndKeepSelection(ImGuiInputTextState* self); +CIMGUI_API void ImGuiInputTextState_ReloadUserBufAndMoveToEnd(ImGuiInputTextState* self); +CIMGUI_API ImGuiNextWindowData* ImGuiNextWindowData_ImGuiNextWindowData(void); +CIMGUI_API void ImGuiNextWindowData_destroy(ImGuiNextWindowData* self); +CIMGUI_API void ImGuiNextWindowData_ClearFlags(ImGuiNextWindowData* self); +CIMGUI_API ImGuiNextItemData* ImGuiNextItemData_ImGuiNextItemData(void); +CIMGUI_API void ImGuiNextItemData_destroy(ImGuiNextItemData* self); +CIMGUI_API void ImGuiNextItemData_ClearFlags(ImGuiNextItemData* self); +CIMGUI_API ImGuiLastItemData* ImGuiLastItemData_ImGuiLastItemData(void); +CIMGUI_API void ImGuiLastItemData_destroy(ImGuiLastItemData* self); +CIMGUI_API ImGuiErrorRecoveryState* ImGuiErrorRecoveryState_ImGuiErrorRecoveryState(void); +CIMGUI_API void ImGuiErrorRecoveryState_destroy(ImGuiErrorRecoveryState* self); +CIMGUI_API ImGuiPtrOrIndex* ImGuiPtrOrIndex_ImGuiPtrOrIndex_Ptr(void* ptr); +CIMGUI_API void ImGuiPtrOrIndex_destroy(ImGuiPtrOrIndex* self); +CIMGUI_API ImGuiPtrOrIndex* ImGuiPtrOrIndex_ImGuiPtrOrIndex_Int(int index); +CIMGUI_API ImGuiPopupData* ImGuiPopupData_ImGuiPopupData(void); +CIMGUI_API void ImGuiPopupData_destroy(ImGuiPopupData* self); +CIMGUI_API ImGuiInputEvent* ImGuiInputEvent_ImGuiInputEvent(void); +CIMGUI_API void ImGuiInputEvent_destroy(ImGuiInputEvent* self); +CIMGUI_API ImGuiKeyRoutingData* ImGuiKeyRoutingData_ImGuiKeyRoutingData(void); +CIMGUI_API void ImGuiKeyRoutingData_destroy(ImGuiKeyRoutingData* self); +CIMGUI_API ImGuiKeyRoutingTable* ImGuiKeyRoutingTable_ImGuiKeyRoutingTable(void); +CIMGUI_API void ImGuiKeyRoutingTable_destroy(ImGuiKeyRoutingTable* self); +CIMGUI_API void ImGuiKeyRoutingTable_Clear(ImGuiKeyRoutingTable* self); +CIMGUI_API ImGuiKeyOwnerData* ImGuiKeyOwnerData_ImGuiKeyOwnerData(void); +CIMGUI_API void ImGuiKeyOwnerData_destroy(ImGuiKeyOwnerData* self); +CIMGUI_API ImGuiListClipperRange ImGuiListClipperRange_FromIndices(int min,int max); +CIMGUI_API ImGuiListClipperRange ImGuiListClipperRange_FromPositions(float y1,float y2,int off_min,int off_max); +CIMGUI_API ImGuiListClipperData* ImGuiListClipperData_ImGuiListClipperData(void); +CIMGUI_API void ImGuiListClipperData_destroy(ImGuiListClipperData* self); +CIMGUI_API void ImGuiListClipperData_Reset(ImGuiListClipperData* self,ImGuiListClipper* clipper); +CIMGUI_API ImGuiNavItemData* ImGuiNavItemData_ImGuiNavItemData(void); +CIMGUI_API void ImGuiNavItemData_destroy(ImGuiNavItemData* self); +CIMGUI_API void ImGuiNavItemData_Clear(ImGuiNavItemData* self); +CIMGUI_API ImGuiTypingSelectState* ImGuiTypingSelectState_ImGuiTypingSelectState(void); +CIMGUI_API void ImGuiTypingSelectState_destroy(ImGuiTypingSelectState* self); +CIMGUI_API void ImGuiTypingSelectState_Clear(ImGuiTypingSelectState* self); +CIMGUI_API ImGuiOldColumnData* ImGuiOldColumnData_ImGuiOldColumnData(void); +CIMGUI_API void ImGuiOldColumnData_destroy(ImGuiOldColumnData* self); +CIMGUI_API ImGuiOldColumns* ImGuiOldColumns_ImGuiOldColumns(void); +CIMGUI_API void ImGuiOldColumns_destroy(ImGuiOldColumns* self); +CIMGUI_API ImGuiBoxSelectState* ImGuiBoxSelectState_ImGuiBoxSelectState(void); +CIMGUI_API void ImGuiBoxSelectState_destroy(ImGuiBoxSelectState* self); +CIMGUI_API ImGuiMultiSelectTempData* ImGuiMultiSelectTempData_ImGuiMultiSelectTempData(void); +CIMGUI_API void ImGuiMultiSelectTempData_destroy(ImGuiMultiSelectTempData* self); +CIMGUI_API void ImGuiMultiSelectTempData_Clear(ImGuiMultiSelectTempData* self); +CIMGUI_API void ImGuiMultiSelectTempData_ClearIO(ImGuiMultiSelectTempData* self); +CIMGUI_API ImGuiMultiSelectState* ImGuiMultiSelectState_ImGuiMultiSelectState(void); +CIMGUI_API void ImGuiMultiSelectState_destroy(ImGuiMultiSelectState* self); +CIMGUI_API ImGuiViewportP* ImGuiViewportP_ImGuiViewportP(void); +CIMGUI_API void ImGuiViewportP_destroy(ImGuiViewportP* self); +CIMGUI_API ImVec2_c ImGuiViewportP_CalcWorkRectPos(ImGuiViewportP* self,const ImVec2_c inset_min); +CIMGUI_API ImVec2_c ImGuiViewportP_CalcWorkRectSize(ImGuiViewportP* self,const ImVec2_c inset_min,const ImVec2_c inset_max); +CIMGUI_API void ImGuiViewportP_UpdateWorkRect(ImGuiViewportP* self); +CIMGUI_API ImRect_c ImGuiViewportP_GetMainRect(ImGuiViewportP* self); +CIMGUI_API ImRect_c ImGuiViewportP_GetWorkRect(ImGuiViewportP* self); +CIMGUI_API ImRect_c ImGuiViewportP_GetBuildWorkRect(ImGuiViewportP* self); +CIMGUI_API ImGuiWindowSettings* ImGuiWindowSettings_ImGuiWindowSettings(void); +CIMGUI_API void ImGuiWindowSettings_destroy(ImGuiWindowSettings* self); +CIMGUI_API char* ImGuiWindowSettings_GetName(ImGuiWindowSettings* self); +CIMGUI_API ImGuiSettingsHandler* ImGuiSettingsHandler_ImGuiSettingsHandler(void); +CIMGUI_API void ImGuiSettingsHandler_destroy(ImGuiSettingsHandler* self); +CIMGUI_API ImGuiDebugAllocInfo* ImGuiDebugAllocInfo_ImGuiDebugAllocInfo(void); +CIMGUI_API void ImGuiDebugAllocInfo_destroy(ImGuiDebugAllocInfo* self); +CIMGUI_API ImGuiStackLevelInfo* ImGuiStackLevelInfo_ImGuiStackLevelInfo(void); +CIMGUI_API void ImGuiStackLevelInfo_destroy(ImGuiStackLevelInfo* self); +CIMGUI_API ImGuiDebugItemPathQuery* ImGuiDebugItemPathQuery_ImGuiDebugItemPathQuery(void); +CIMGUI_API void ImGuiDebugItemPathQuery_destroy(ImGuiDebugItemPathQuery* self); +CIMGUI_API ImGuiIDStackTool* ImGuiIDStackTool_ImGuiIDStackTool(void); +CIMGUI_API void ImGuiIDStackTool_destroy(ImGuiIDStackTool* self); +CIMGUI_API ImGuiContextHook* ImGuiContextHook_ImGuiContextHook(void); +CIMGUI_API void ImGuiContextHook_destroy(ImGuiContextHook* self); +CIMGUI_API ImGuiContext* ImGuiContext_ImGuiContext(ImFontAtlas* shared_font_atlas); +CIMGUI_API void ImGuiContext_destroy(ImGuiContext* self); +CIMGUI_API ImGuiWindow* ImGuiWindow_ImGuiWindow(ImGuiContext* context,const char* name); +CIMGUI_API void ImGuiWindow_destroy(ImGuiWindow* self); +CIMGUI_API ImGuiID ImGuiWindow_GetID_Str(ImGuiWindow* self,const char* str,const char* str_end); +CIMGUI_API ImGuiID ImGuiWindow_GetID_Ptr(ImGuiWindow* self,const void* ptr); +CIMGUI_API ImGuiID ImGuiWindow_GetID_Int(ImGuiWindow* self,int n); +CIMGUI_API ImGuiID ImGuiWindow_GetIDFromPos(ImGuiWindow* self,const ImVec2_c p_abs); +CIMGUI_API ImGuiID ImGuiWindow_GetIDFromRectangle(ImGuiWindow* self,const ImRect_c r_abs); +CIMGUI_API ImRect_c ImGuiWindow_Rect(ImGuiWindow* self); +CIMGUI_API ImRect_c ImGuiWindow_TitleBarRect(ImGuiWindow* self); +CIMGUI_API ImRect_c ImGuiWindow_MenuBarRect(ImGuiWindow* self); +CIMGUI_API ImGuiTabItem* ImGuiTabItem_ImGuiTabItem(void); +CIMGUI_API void ImGuiTabItem_destroy(ImGuiTabItem* self); +CIMGUI_API ImGuiTabBar* ImGuiTabBar_ImGuiTabBar(void); +CIMGUI_API void ImGuiTabBar_destroy(ImGuiTabBar* self); +CIMGUI_API ImGuiTableColumn* ImGuiTableColumn_ImGuiTableColumn(void); +CIMGUI_API void ImGuiTableColumn_destroy(ImGuiTableColumn* self); +CIMGUI_API ImGuiTableInstanceData* ImGuiTableInstanceData_ImGuiTableInstanceData(void); +CIMGUI_API void ImGuiTableInstanceData_destroy(ImGuiTableInstanceData* self); +CIMGUI_API ImGuiTable* ImGuiTable_ImGuiTable(void); +CIMGUI_API void ImGuiTable_destroy(ImGuiTable* self); +CIMGUI_API ImGuiTableTempData* ImGuiTableTempData_ImGuiTableTempData(void); +CIMGUI_API void ImGuiTableTempData_destroy(ImGuiTableTempData* self); +CIMGUI_API ImGuiTableColumnSettings* ImGuiTableColumnSettings_ImGuiTableColumnSettings(void); +CIMGUI_API void ImGuiTableColumnSettings_destroy(ImGuiTableColumnSettings* self); +CIMGUI_API ImGuiTableSettings* ImGuiTableSettings_ImGuiTableSettings(void); +CIMGUI_API void ImGuiTableSettings_destroy(ImGuiTableSettings* self); +CIMGUI_API ImGuiTableColumnSettings* ImGuiTableSettings_GetColumnSettings(ImGuiTableSettings* self); +CIMGUI_API void igTableOpenContextMenu(int column_n); +CIMGUI_API void igTableSetColumnWidth(int column_n,float width); +CIMGUI_API void igTableSetColumnSortDirection(int column_n,ImGuiSortDirection sort_direction,bool append_to_sort_specs); +CIMGUI_API int igTableGetHoveredRow(void); +CIMGUI_API float igTableGetHeaderRowHeight(void); +CIMGUI_API float igTableGetHeaderAngledMaxLabelWidth(void); +CIMGUI_API void igTablePushBackgroundChannel(void); +CIMGUI_API void igTablePopBackgroundChannel(void); +CIMGUI_API void igTablePushColumnChannel(int column_n); +CIMGUI_API void igTablePopColumnChannel(void); +CIMGUI_API void igTableAngledHeadersRowEx(ImGuiID row_id,float angle,float max_label_width,const ImGuiTableHeaderData* data,int data_count); +CIMGUI_API ImGuiTable* igGetCurrentTable(void); +CIMGUI_API ImGuiTable* igTableFindByID(ImGuiID id); +CIMGUI_API bool igBeginTableEx(const char* name,ImGuiID id,int columns_count,ImGuiTableFlags flags,const ImVec2_c outer_size,float inner_width); +CIMGUI_API void igTableBeginInitMemory(ImGuiTable* table,int columns_count); +CIMGUI_API void igTableApplyQueuedRequests(ImGuiTable* table); +CIMGUI_API void igTableSetupDrawChannels(ImGuiTable* table); +CIMGUI_API void igTableUpdateLayout(ImGuiTable* table); +CIMGUI_API void igTableUpdateBorders(ImGuiTable* table); +CIMGUI_API void igTableUpdateColumnsWeightFromWidth(ImGuiTable* table); +CIMGUI_API void igTableApplyExternalUnclipRect(ImGuiTable* table,ImRect* rect); +CIMGUI_API void igTableDrawBorders(ImGuiTable* table); +CIMGUI_API void igTableDrawDefaultContextMenu(ImGuiTable* table,ImGuiTableFlags flags_for_section_to_display); +CIMGUI_API bool igTableBeginContextMenuPopup(ImGuiTable* table); +CIMGUI_API void igTableMergeDrawChannels(ImGuiTable* table); +CIMGUI_API ImGuiTableInstanceData* igTableGetInstanceData(ImGuiTable* table,int instance_no); +CIMGUI_API ImGuiID igTableGetInstanceID(ImGuiTable* table,int instance_no); +CIMGUI_API void igTableFixDisplayOrder(ImGuiTable* table); +CIMGUI_API void igTableSortSpecsSanitize(ImGuiTable* table); +CIMGUI_API void igTableSortSpecsBuild(ImGuiTable* table); +CIMGUI_API ImGuiSortDirection igTableGetColumnNextSortDirection(ImGuiTableColumn* column); +CIMGUI_API void igTableFixColumnSortDirection(ImGuiTable* table,ImGuiTableColumn* column); +CIMGUI_API float igTableGetColumnWidthAuto(ImGuiTable* table,ImGuiTableColumn* column); +CIMGUI_API void igTableBeginRow(ImGuiTable* table); +CIMGUI_API void igTableEndRow(ImGuiTable* table); +CIMGUI_API void igTableBeginCell(ImGuiTable* table,int column_n); +CIMGUI_API void igTableEndCell(ImGuiTable* table); +CIMGUI_API ImRect_c igTableGetCellBgRect(const ImGuiTable* table,int column_n); +CIMGUI_API const char* igTableGetColumnName_TablePtr(const ImGuiTable* table,int column_n); +CIMGUI_API ImGuiID igTableGetColumnResizeID(ImGuiTable* table,int column_n,int instance_no); +CIMGUI_API float igTableCalcMaxColumnWidth(const ImGuiTable* table,int column_n); +CIMGUI_API void igTableSetColumnWidthAutoSingle(ImGuiTable* table,int column_n); +CIMGUI_API void igTableSetColumnWidthAutoAll(ImGuiTable* table); +CIMGUI_API void igTableSetColumnDisplayOrder(ImGuiTable* table,int column_n,int dst_order); +CIMGUI_API void igTableQueueSetColumnDisplayOrder(ImGuiTable* table,int column_n,int dst_order); +CIMGUI_API void igTableRemove(ImGuiTable* table); +CIMGUI_API void igTableGcCompactTransientBuffers_TablePtr(ImGuiTable* table); +CIMGUI_API void igTableGcCompactTransientBuffers_TableTempDataPtr(ImGuiTableTempData* table); +CIMGUI_API void igTableGcCompactSettings(void); +CIMGUI_API void igTableLoadSettings(ImGuiTable* table); +CIMGUI_API void igTableSaveSettings(ImGuiTable* table); +CIMGUI_API void igTableResetSettings(ImGuiTable* table); +CIMGUI_API ImGuiTableSettings* igTableGetBoundSettings(ImGuiTable* table); +CIMGUI_API void igTableSettingsAddSettingsHandler(void); +CIMGUI_API ImGuiTableSettings* igTableSettingsCreate(ImGuiID id,int columns_count); +CIMGUI_API ImGuiTableSettings* igTableSettingsFindByID(ImGuiID id); +CIMGUI_API void igSetWindowClipRectBeforeSetChannel(ImGuiWindow* window,const ImRect_c clip_rect); +CIMGUI_API void igBeginColumns(const char* str_id,int count,ImGuiOldColumnFlags flags); +CIMGUI_API void igEndColumns(void); +CIMGUI_API void igPushColumnClipRect(int column_index); +CIMGUI_API void igPushColumnsBackground(void); +CIMGUI_API void igPopColumnsBackground(void); +CIMGUI_API ImGuiID igGetColumnsID(const char* str_id,int count); +CIMGUI_API ImGuiOldColumns* igFindOrCreateColumns(ImGuiWindow* window,ImGuiID id); +CIMGUI_API float igGetColumnOffsetFromNorm(const ImGuiOldColumns* columns,float offset_norm); +CIMGUI_API float igGetColumnNormFromOffset(const ImGuiOldColumns* columns,float offset); +CIMGUI_API ImGuiIO* igGetIO_ContextPtr(ImGuiContext* ctx); +CIMGUI_API ImGuiPlatformIO* igGetPlatformIO_ContextPtr(ImGuiContext* ctx); +CIMGUI_API float igGetScale(void); +CIMGUI_API ImGuiWindow* igGetCurrentWindowRead(void); +CIMGUI_API ImGuiWindow* igGetCurrentWindow(void); +CIMGUI_API ImGuiWindow* igFindWindowByID(ImGuiID id); +CIMGUI_API ImGuiWindow* igFindWindowByName(const char* name); +CIMGUI_API void igUpdateWindowParentAndRootLinks(ImGuiWindow* window,ImGuiWindowFlags flags,ImGuiWindow* parent_window); +CIMGUI_API void igUpdateWindowSkipRefresh(ImGuiWindow* window); +CIMGUI_API ImVec2_c igCalcWindowNextAutoFitSize(ImGuiWindow* window); +CIMGUI_API bool igIsWindowChildOf(ImGuiWindow* window,ImGuiWindow* potential_parent,bool popup_hierarchy); +CIMGUI_API bool igIsWindowInBeginStack(ImGuiWindow* window); +CIMGUI_API bool igIsWindowWithinBeginStackOf(ImGuiWindow* window,ImGuiWindow* potential_parent); +CIMGUI_API bool igIsWindowAbove(ImGuiWindow* potential_above,ImGuiWindow* potential_below); +CIMGUI_API bool igIsWindowNavFocusable(ImGuiWindow* window); +CIMGUI_API void igSetWindowPos_WindowPtr(ImGuiWindow* window,const ImVec2_c pos,ImGuiCond cond); +CIMGUI_API void igSetWindowSize_WindowPtr(ImGuiWindow* window,const ImVec2_c size,ImGuiCond cond); +CIMGUI_API void igSetWindowCollapsed_WindowPtr(ImGuiWindow* window,bool collapsed,ImGuiCond cond); +CIMGUI_API void igSetWindowHitTestHole(ImGuiWindow* window,const ImVec2_c pos,const ImVec2_c size); +CIMGUI_API void igSetWindowHiddenAndSkipItemsForCurrentFrame(ImGuiWindow* window); +CIMGUI_API void igSetWindowParentWindowForFocusRoute(ImGuiWindow* window,ImGuiWindow* parent_window); +CIMGUI_API ImRect_c igWindowRectAbsToRel(ImGuiWindow* window,const ImRect_c r); +CIMGUI_API ImRect_c igWindowRectRelToAbs(ImGuiWindow* window,const ImRect_c r); +CIMGUI_API ImVec2_c igWindowPosAbsToRel(ImGuiWindow* window,const ImVec2_c p); +CIMGUI_API ImVec2_c igWindowPosRelToAbs(ImGuiWindow* window,const ImVec2_c p); +CIMGUI_API void igFocusWindow(ImGuiWindow* window,ImGuiFocusRequestFlags flags); +CIMGUI_API void igFocusTopMostWindowUnderOne(ImGuiWindow* under_this_window,ImGuiWindow* ignore_window,ImGuiViewport* filter_viewport,ImGuiFocusRequestFlags flags); +CIMGUI_API void igBringWindowToFocusFront(ImGuiWindow* window); +CIMGUI_API void igBringWindowToDisplayFront(ImGuiWindow* window); +CIMGUI_API void igBringWindowToDisplayBack(ImGuiWindow* window); +CIMGUI_API void igBringWindowToDisplayBehind(ImGuiWindow* window,ImGuiWindow* above_window); +CIMGUI_API int igFindWindowDisplayIndex(ImGuiWindow* window); +CIMGUI_API ImGuiWindow* igFindBottomMostVisibleWindowWithinBeginStack(ImGuiWindow* window); +CIMGUI_API void igSetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags); +CIMGUI_API void igRegisterUserTexture(ImTextureData* tex); +CIMGUI_API void igUnregisterUserTexture(ImTextureData* tex); +CIMGUI_API void igRegisterFontAtlas(ImFontAtlas* atlas); +CIMGUI_API void igUnregisterFontAtlas(ImFontAtlas* atlas); +CIMGUI_API void igSetCurrentFont(ImFont* font,float font_size_before_scaling,float font_size_after_scaling); +CIMGUI_API void igUpdateCurrentFontSize(float restore_font_size_after_scaling); +CIMGUI_API void igSetFontRasterizerDensity(float rasterizer_density); +CIMGUI_API float igGetFontRasterizerDensity(void); +CIMGUI_API float igGetRoundedFontSize(float size); +CIMGUI_API ImFont* igGetDefaultFont(void); +CIMGUI_API void igPushPasswordFont(void); +CIMGUI_API void igPopPasswordFont(void); +CIMGUI_API ImDrawList* igGetForegroundDrawList_WindowPtr(ImGuiWindow* window); +CIMGUI_API ImDrawList* igGetBackgroundDrawList_ViewportPtr(ImGuiViewport* viewport); +CIMGUI_API ImDrawList* igGetForegroundDrawList_ViewportPtr(ImGuiViewport* viewport); +CIMGUI_API void igAddDrawListToDrawDataEx(ImDrawData* draw_data,ImVector_ImDrawListPtr* out_list,ImDrawList* draw_list); +CIMGUI_API void igInitialize(void); +CIMGUI_API void igShutdown(void); +CIMGUI_API void igSetContextName(ImGuiContext* ctx,const char* name); +CIMGUI_API ImGuiID igAddContextHook(ImGuiContext* ctx,const ImGuiContextHook* hook); +CIMGUI_API void igRemoveContextHook(ImGuiContext* ctx,ImGuiID hook_to_remove); +CIMGUI_API void igCallContextHooks(ImGuiContext* ctx,ImGuiContextHookType type); +CIMGUI_API void igUpdateInputEvents(bool trickle_fast_inputs); +CIMGUI_API void igUpdateHoveredWindowAndCaptureFlags(const ImVec2_c mouse_pos); +CIMGUI_API void igFindHoveredWindowEx(const ImVec2_c pos,bool find_first_and_in_any_viewport,ImGuiWindow** out_hovered_window,ImGuiWindow** out_hovered_window_under_moving_window); +CIMGUI_API void igStartMouseMovingWindow(ImGuiWindow* window); +CIMGUI_API void igStopMouseMovingWindow(void); +CIMGUI_API void igUpdateMouseMovingWindowNewFrame(void); +CIMGUI_API void igUpdateMouseMovingWindowEndFrame(void); +CIMGUI_API ImGuiViewport* igGetWindowViewport(void); +CIMGUI_API void igScaleWindowsInViewport(ImGuiViewportP* viewport,float scale); +CIMGUI_API void igSetWindowViewport(ImGuiWindow* window,ImGuiViewportP* viewport); +CIMGUI_API void igMarkIniSettingsDirty_Nil(void); +CIMGUI_API void igMarkIniSettingsDirty_WindowPtr(ImGuiWindow* window); +CIMGUI_API void igClearIniSettings(void); +CIMGUI_API void igAddSettingsHandler(const ImGuiSettingsHandler* handler); +CIMGUI_API void igRemoveSettingsHandler(const char* type_name); +CIMGUI_API ImGuiSettingsHandler* igFindSettingsHandler(const char* type_name); +CIMGUI_API ImGuiWindowSettings* igCreateNewWindowSettings(const char* name); +CIMGUI_API ImGuiWindowSettings* igFindWindowSettingsByID(ImGuiID id); +CIMGUI_API ImGuiWindowSettings* igFindWindowSettingsByWindow(ImGuiWindow* window); +CIMGUI_API void igClearWindowSettings(const char* name); +CIMGUI_API void igLocalizeRegisterEntries(const ImGuiLocEntry* entries,int count); +CIMGUI_API const char* igLocalizeGetMsg(ImGuiLocKey key); +CIMGUI_API void igSetScrollX_WindowPtr(ImGuiWindow* window,float scroll_x); +CIMGUI_API void igSetScrollY_WindowPtr(ImGuiWindow* window,float scroll_y); +CIMGUI_API void igSetScrollFromPosX_WindowPtr(ImGuiWindow* window,float local_x,float center_x_ratio); +CIMGUI_API void igSetScrollFromPosY_WindowPtr(ImGuiWindow* window,float local_y,float center_y_ratio); +CIMGUI_API void igScrollToItem(ImGuiScrollFlags flags); +CIMGUI_API void igScrollToRect(ImGuiWindow* window,const ImRect_c rect,ImGuiScrollFlags flags); +CIMGUI_API ImVec2_c igScrollToRectEx(ImGuiWindow* window,const ImRect_c rect,ImGuiScrollFlags flags); +CIMGUI_API void igScrollToBringRectIntoView(ImGuiWindow* window,const ImRect_c rect); +CIMGUI_API ImGuiItemStatusFlags igGetItemStatusFlags(void); +CIMGUI_API ImGuiID igGetActiveID(void); +CIMGUI_API ImGuiID igGetFocusID(void); +CIMGUI_API void igSetActiveID(ImGuiID id,ImGuiWindow* window); +CIMGUI_API void igSetFocusID(ImGuiID id,ImGuiWindow* window); +CIMGUI_API void igClearActiveID(void); +CIMGUI_API ImGuiID igGetHoveredID(void); +CIMGUI_API void igSetHoveredID(ImGuiID id); +CIMGUI_API void igKeepAliveID(ImGuiID id); +CIMGUI_API void igMarkItemEdited(ImGuiID id); +CIMGUI_API void igPushOverrideID(ImGuiID id); +CIMGUI_API ImGuiID igGetIDWithSeed_Str(const char* str_id_begin,const char* str_id_end,ImGuiID seed); +CIMGUI_API ImGuiID igGetIDWithSeed_Int(int n,ImGuiID seed); +CIMGUI_API void igItemSize_Vec2(const ImVec2_c size,float text_baseline_y); +CIMGUI_API void igItemSize_Rect(const ImRect_c bb,float text_baseline_y); +CIMGUI_API bool igItemAdd(const ImRect_c bb,ImGuiID id,const ImRect* nav_bb,ImGuiItemFlags extra_flags); +CIMGUI_API bool igItemHoverable(const ImRect_c bb,ImGuiID id,ImGuiItemFlags item_flags); +CIMGUI_API bool igIsWindowContentHoverable(ImGuiWindow* window,ImGuiHoveredFlags flags); +CIMGUI_API bool igIsClippedEx(const ImRect_c bb,ImGuiID id); +CIMGUI_API void igSetLastItemData(ImGuiID item_id,ImGuiItemFlags item_flags,ImGuiItemStatusFlags status_flags,const ImRect_c item_rect); +CIMGUI_API ImVec2_c igCalcItemSize(ImVec2_c size,float default_w,float default_h); +CIMGUI_API float igCalcWrapWidthForPos(const ImVec2_c pos,float wrap_pos_x); +CIMGUI_API void igPushMultiItemsWidths(int components,float width_full); +CIMGUI_API void igShrinkWidths(ImGuiShrinkWidthItem* items,int count,float width_excess,float width_min); +CIMGUI_API void igCalcClipRectVisibleItemsY(const ImRect_c clip_rect,const ImVec2_c pos,float items_height,int* out_visible_start,int* out_visible_end); +CIMGUI_API const ImGuiStyleVarInfo* igGetStyleVarInfo(ImGuiStyleVar idx); +CIMGUI_API void igBeginDisabledOverrideReenable(void); +CIMGUI_API void igEndDisabledOverrideReenable(void); +CIMGUI_API void igLogBegin(ImGuiLogFlags flags,int auto_open_depth); +CIMGUI_API void igLogToBuffer(int auto_open_depth); +CIMGUI_API void igLogRenderedText(const ImVec2_c* ref_pos,const char* text,const char* text_end); +CIMGUI_API void igLogSetNextTextDecoration(const char* prefix,const char* suffix); +CIMGUI_API bool igBeginChildEx(const char* name,ImGuiID id,const ImVec2_c size_arg,ImGuiChildFlags child_flags,ImGuiWindowFlags window_flags); +CIMGUI_API ImGuiWindow* igFindFrontMostVisibleChildWindow(ImGuiWindow* window); +CIMGUI_API bool igBeginPopupEx(ImGuiID id,ImGuiWindowFlags extra_window_flags); +CIMGUI_API bool igBeginPopupMenuEx(ImGuiID id,const char* label,ImGuiWindowFlags extra_window_flags); +CIMGUI_API void igOpenPopupEx(ImGuiID id,ImGuiPopupFlags popup_flags); +CIMGUI_API void igClosePopupToLevel(int remaining,bool restore_focus_to_window_under_popup); +CIMGUI_API void igClosePopupsOverWindow(ImGuiWindow* ref_window,bool restore_focus_to_window_under_popup); +CIMGUI_API void igClosePopupsExceptModals(void); +CIMGUI_API bool igIsPopupOpen_ID(ImGuiID id,ImGuiPopupFlags popup_flags); +CIMGUI_API ImRect_c igGetPopupAllowedExtentRect(ImGuiWindow* window); +CIMGUI_API ImGuiWindow* igGetTopMostPopupModal(void); +CIMGUI_API ImGuiWindow* igGetTopMostAndVisiblePopupModal(void); +CIMGUI_API ImGuiWindow* igFindBlockingModal(ImGuiWindow* window); +CIMGUI_API ImVec2_c igFindBestWindowPosForPopup(ImGuiWindow* window); +CIMGUI_API ImVec2_c igFindBestWindowPosForPopupEx(const ImVec2_c ref_pos,const ImVec2_c size,ImGuiDir* last_dir,const ImRect_c r_outer,const ImRect_c r_avoid,ImGuiPopupPositionPolicy policy); +CIMGUI_API ImGuiMouseButton igGetMouseButtonFromPopupFlags(ImGuiPopupFlags flags); +CIMGUI_API bool igIsPopupOpenRequestForItem(ImGuiPopupFlags flags,ImGuiID id); +CIMGUI_API bool igIsPopupOpenRequestForWindow(ImGuiPopupFlags flags); +CIMGUI_API bool igBeginTooltipEx(ImGuiTooltipFlags tooltip_flags,ImGuiWindowFlags extra_window_flags); +CIMGUI_API bool igBeginTooltipHidden(void); +CIMGUI_API bool igBeginViewportSideBar(const char* name,ImGuiViewport* viewport,ImGuiDir dir,float size,ImGuiWindowFlags window_flags); +CIMGUI_API bool igBeginMenuEx(const char* label,const char* icon,bool enabled); +CIMGUI_API bool igMenuItemEx(const char* label,const char* icon,const char* shortcut,bool selected,bool enabled); +CIMGUI_API bool igBeginComboPopup(ImGuiID popup_id,const ImRect_c bb,ImGuiComboFlags flags); +CIMGUI_API bool igBeginComboPreview(void); +CIMGUI_API void igEndComboPreview(void); +CIMGUI_API void igNavInitWindow(ImGuiWindow* window,bool force_reinit); +CIMGUI_API void igNavInitRequestApplyResult(void); +CIMGUI_API bool igNavMoveRequestButNoResultYet(void); +CIMGUI_API void igNavMoveRequestSubmit(ImGuiDir move_dir,ImGuiDir clip_dir,ImGuiNavMoveFlags move_flags,ImGuiScrollFlags scroll_flags); +CIMGUI_API void igNavMoveRequestForward(ImGuiDir move_dir,ImGuiDir clip_dir,ImGuiNavMoveFlags move_flags,ImGuiScrollFlags scroll_flags); +CIMGUI_API void igNavMoveRequestResolveWithLastItem(ImGuiNavItemData* result); +CIMGUI_API void igNavMoveRequestResolveWithPastTreeNode(ImGuiNavItemData* result,const ImGuiTreeNodeStackData* tree_node_data); +CIMGUI_API void igNavMoveRequestCancel(void); +CIMGUI_API void igNavMoveRequestApplyResult(void); +CIMGUI_API void igNavMoveRequestTryWrapping(ImGuiWindow* window,ImGuiNavMoveFlags move_flags); +CIMGUI_API void igNavHighlightActivated(ImGuiID id); +CIMGUI_API void igNavClearPreferredPosForAxis(ImGuiAxis axis); +CIMGUI_API void igSetNavCursorVisibleAfterMove(void); +CIMGUI_API void igNavUpdateCurrentWindowIsScrollPushableX(void); +CIMGUI_API void igSetNavWindow(ImGuiWindow* window); +CIMGUI_API void igSetNavID(ImGuiID id,ImGuiNavLayer nav_layer,ImGuiID focus_scope_id,const ImRect_c rect_rel); +CIMGUI_API void igSetNavFocusScope(ImGuiID focus_scope_id); +CIMGUI_API void igFocusItem(void); +CIMGUI_API void igActivateItemByID(ImGuiID id); +CIMGUI_API bool igIsNamedKey(ImGuiKey key); +CIMGUI_API bool igIsNamedKeyOrMod(ImGuiKey key); +CIMGUI_API bool igIsLegacyKey(ImGuiKey key); +CIMGUI_API bool igIsKeyboardKey(ImGuiKey key); +CIMGUI_API bool igIsGamepadKey(ImGuiKey key); +CIMGUI_API bool igIsMouseKey(ImGuiKey key); +CIMGUI_API bool igIsAliasKey(ImGuiKey key); +CIMGUI_API bool igIsLRModKey(ImGuiKey key); +CIMGUI_API ImGuiKeyChord igFixupKeyChord(ImGuiKeyChord key_chord); +CIMGUI_API ImGuiKey igConvertSingleModFlagToKey(ImGuiKey key); +CIMGUI_API ImGuiKeyData* igGetKeyData_ContextPtr(ImGuiContext* ctx,ImGuiKey key); +CIMGUI_API ImGuiKeyData* igGetKeyData_Key(ImGuiKey key); +CIMGUI_API const char* igGetKeyChordName(ImGuiKeyChord key_chord); +CIMGUI_API ImGuiKey igMouseButtonToKey(ImGuiMouseButton button); +CIMGUI_API bool igIsMouseDragPastThreshold(ImGuiMouseButton button,float lock_threshold); +CIMGUI_API ImVec2_c igGetKeyMagnitude2d(ImGuiKey key_left,ImGuiKey key_right,ImGuiKey key_up,ImGuiKey key_down); +CIMGUI_API float igGetNavTweakPressedAmount(ImGuiAxis axis); +CIMGUI_API int igCalcTypematicRepeatAmount(float t0,float t1,float repeat_delay,float repeat_rate); +CIMGUI_API void igGetTypematicRepeatRate(ImGuiInputFlags flags,float* repeat_delay,float* repeat_rate); +CIMGUI_API void igTeleportMousePos(const ImVec2_c pos); +CIMGUI_API void igSetActiveIdUsingAllKeyboardKeys(void); +CIMGUI_API bool igIsActiveIdUsingNavDir(ImGuiDir dir); +CIMGUI_API ImGuiID igGetKeyOwner(ImGuiKey key); +CIMGUI_API void igSetKeyOwner(ImGuiKey key,ImGuiID owner_id,ImGuiInputFlags flags); +CIMGUI_API void igSetKeyOwnersForKeyChord(ImGuiKeyChord key,ImGuiID owner_id,ImGuiInputFlags flags); +CIMGUI_API bool igSetItemKeyOwner_InputFlags(ImGuiKey key,ImGuiInputFlags flags); +CIMGUI_API bool igTestKeyOwner(ImGuiKey key,ImGuiID owner_id); +CIMGUI_API ImGuiKeyOwnerData* igGetKeyOwnerData(ImGuiContext* ctx,ImGuiKey key); +CIMGUI_API bool igIsKeyDown_ID(ImGuiKey key,ImGuiID owner_id); +CIMGUI_API bool igIsKeyPressed_InputFlags(ImGuiKey key,ImGuiInputFlags flags,ImGuiID owner_id); +CIMGUI_API bool igIsKeyReleased_ID(ImGuiKey key,ImGuiID owner_id); +CIMGUI_API bool igIsKeyChordPressed_InputFlags(ImGuiKeyChord key_chord,ImGuiInputFlags flags,ImGuiID owner_id); +CIMGUI_API bool igIsMouseDown_ID(ImGuiMouseButton button,ImGuiID owner_id); +CIMGUI_API bool igIsMouseClicked_InputFlags(ImGuiMouseButton button,ImGuiInputFlags flags,ImGuiID owner_id); +CIMGUI_API bool igIsMouseReleased_ID(ImGuiMouseButton button,ImGuiID owner_id); +CIMGUI_API bool igIsMouseDoubleClicked_ID(ImGuiMouseButton button,ImGuiID owner_id); +CIMGUI_API bool igShortcut_ID(ImGuiKeyChord key_chord,ImGuiInputFlags flags,ImGuiID owner_id); +CIMGUI_API bool igSetShortcutRouting(ImGuiKeyChord key_chord,ImGuiInputFlags flags,ImGuiID owner_id); +CIMGUI_API bool igTestShortcutRouting(ImGuiKeyChord key_chord,ImGuiID owner_id); +CIMGUI_API ImGuiKeyRoutingData* igGetShortcutRoutingData(ImGuiKeyChord key_chord); +CIMGUI_API void igPushFocusScope(ImGuiID id); +CIMGUI_API void igPopFocusScope(void); +CIMGUI_API bool igIsInNavFocusRoute(ImGuiID focus_scope_id); +CIMGUI_API ImGuiID igGetCurrentFocusScope(void); +CIMGUI_API bool igIsDragDropActive(void); +CIMGUI_API bool igBeginDragDropTargetCustom(const ImRect_c bb,ImGuiID id); +CIMGUI_API bool igBeginDragDropTargetViewport(ImGuiViewport* viewport,const ImRect* p_bb); +CIMGUI_API void igClearDragDrop(void); +CIMGUI_API bool igIsDragDropPayloadBeingAccepted(void); +CIMGUI_API void igRenderDragDropTargetRectForItem(const ImRect_c bb); +CIMGUI_API void igRenderDragDropTargetRectEx(ImDrawList* draw_list,const ImRect_c bb,float rounding); +CIMGUI_API ImGuiTypingSelectRequest* igGetTypingSelectRequest(ImGuiTypingSelectFlags flags); +CIMGUI_API int igTypingSelectFindMatch(ImGuiTypingSelectRequest* req,int items_count,const char*(*get_item_name_func)(void*,int),void* user_data,int nav_item_idx); +CIMGUI_API int igTypingSelectFindNextSingleCharMatch(ImGuiTypingSelectRequest* req,int items_count,const char*(*get_item_name_func)(void*,int),void* user_data,int nav_item_idx); +CIMGUI_API int igTypingSelectFindBestLeadingMatch(ImGuiTypingSelectRequest* req,int items_count,const char*(*get_item_name_func)(void*,int),void* user_data); +CIMGUI_API bool igBeginBoxSelect(const ImRect_c scope_rect,ImGuiWindow* window,ImGuiID box_select_id,ImGuiMultiSelectFlags ms_flags); +CIMGUI_API void igEndBoxSelect(const ImRect_c scope_rect,ImGuiMultiSelectFlags ms_flags); +CIMGUI_API void igMultiSelectItemHeader(ImGuiID id,bool* p_selected,ImGuiButtonFlags* p_button_flags); +CIMGUI_API void igMultiSelectItemFooter(ImGuiID id,bool* p_selected,bool* p_pressed); +CIMGUI_API void igMultiSelectAddSetAll(ImGuiMultiSelectTempData* ms,bool selected); +CIMGUI_API void igMultiSelectAddSetRange(ImGuiMultiSelectTempData* ms,bool selected,int range_dir,ImGuiSelectionUserData first_item,ImGuiSelectionUserData last_item); +CIMGUI_API ImGuiBoxSelectState* igGetBoxSelectState(ImGuiID id); +CIMGUI_API ImGuiMultiSelectState* igGetMultiSelectState(ImGuiID id); +CIMGUI_API ImGuiTabBar* igGetCurrentTabBar(void); +CIMGUI_API ImGuiTabBar* igTabBarFindByID(ImGuiID id); +CIMGUI_API void igTabBarRemove(ImGuiTabBar* tab_bar); +CIMGUI_API bool igBeginTabBarEx(ImGuiTabBar* tab_bar,const ImRect_c bb,ImGuiTabBarFlags flags); +CIMGUI_API ImGuiTabItem* igTabBarFindTabByID(ImGuiTabBar* tab_bar,ImGuiID tab_id); +CIMGUI_API ImGuiTabItem* igTabBarFindTabByOrder(ImGuiTabBar* tab_bar,int order); +CIMGUI_API ImGuiTabItem* igTabBarGetCurrentTab(ImGuiTabBar* tab_bar); +CIMGUI_API int igTabBarGetTabOrder(ImGuiTabBar* tab_bar,ImGuiTabItem* tab); +CIMGUI_API const char* igTabBarGetTabName(ImGuiTabBar* tab_bar,ImGuiTabItem* tab); +CIMGUI_API void igTabBarRemoveTab(ImGuiTabBar* tab_bar,ImGuiID tab_id); +CIMGUI_API void igTabBarCloseTab(ImGuiTabBar* tab_bar,ImGuiTabItem* tab); +CIMGUI_API void igTabBarQueueFocus_TabItemPtr(ImGuiTabBar* tab_bar,ImGuiTabItem* tab); +CIMGUI_API void igTabBarQueueFocus_Str(ImGuiTabBar* tab_bar,const char* tab_name); +CIMGUI_API void igTabBarQueueReorder(ImGuiTabBar* tab_bar,ImGuiTabItem* tab,int offset); +CIMGUI_API void igTabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar,ImGuiTabItem* tab,ImVec2_c mouse_pos); +CIMGUI_API bool igTabBarProcessReorder(ImGuiTabBar* tab_bar); +CIMGUI_API bool igTabItemEx(ImGuiTabBar* tab_bar,const char* label,bool* p_open,ImGuiTabItemFlags flags,ImGuiWindow* docked_window); +CIMGUI_API void igTabItemSpacing(const char* str_id,ImGuiTabItemFlags flags,float width); +CIMGUI_API ImVec2_c igTabItemCalcSize_Str(const char* label,bool has_close_button_or_unsaved_marker); +CIMGUI_API ImVec2_c igTabItemCalcSize_WindowPtr(ImGuiWindow* window); +CIMGUI_API void igTabItemBackground(ImDrawList* draw_list,const ImRect_c bb,ImGuiTabItemFlags flags,ImU32 col); +CIMGUI_API void igTabItemLabelAndCloseButton(ImDrawList* draw_list,const ImRect_c bb,ImGuiTabItemFlags flags,ImVec2_c frame_padding,const char* label,ImGuiID tab_id,ImGuiID close_button_id,bool is_contents_visible,bool* out_just_closed,bool* out_text_clipped); +CIMGUI_API void igRenderText(ImVec2_c pos,const char* text,const char* text_end,bool hide_text_after_hash); +CIMGUI_API void igRenderTextWrapped(ImVec2_c pos,const char* text,const char* text_end,float wrap_width); +CIMGUI_API void igRenderTextClipped(const ImVec2_c pos_min,const ImVec2_c pos_max,const char* text,const char* text_end,const ImVec2_c* text_size_if_known,const ImVec2_c align,const ImRect* clip_rect); +CIMGUI_API void igRenderTextClippedEx(ImDrawList* draw_list,const ImVec2_c pos_min,const ImVec2_c pos_max,const char* text,const char* text_end,const ImVec2_c* text_size_if_known,const ImVec2_c align,const ImRect* clip_rect); +CIMGUI_API void igRenderTextEllipsis(ImDrawList* draw_list,const ImVec2_c pos_min,const ImVec2_c pos_max,float ellipsis_max_x,const char* text,const char* text_end,const ImVec2_c* text_size_if_known); +CIMGUI_API void igRenderFrame(ImVec2_c p_min,ImVec2_c p_max,ImU32 fill_col,bool borders,float rounding); +CIMGUI_API void igRenderFrameBorder(ImVec2_c p_min,ImVec2_c p_max,float rounding); +CIMGUI_API void igRenderColorComponentMarker(const ImRect_c bb,ImU32 col,float rounding); +CIMGUI_API void igRenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list,ImVec2_c p_min,ImVec2_c p_max,ImU32 fill_col,float grid_step,ImVec2_c grid_off,float rounding,ImDrawFlags flags); +CIMGUI_API void igRenderNavCursor(const ImRect_c bb,ImGuiID id,ImGuiNavRenderCursorFlags flags); +CIMGUI_API const char* igFindRenderedTextEnd(const char* text,const char* text_end); +CIMGUI_API void igRenderMouseCursor(ImVec2_c pos,float scale,ImGuiMouseCursor mouse_cursor,ImU32 col_fill,ImU32 col_border,ImU32 col_shadow); +CIMGUI_API void igRenderArrow(ImDrawList* draw_list,ImVec2_c pos,ImU32 col,ImGuiDir dir,float scale); +CIMGUI_API void igRenderBullet(ImDrawList* draw_list,ImVec2_c pos,ImU32 col); +CIMGUI_API void igRenderCheckMark(ImDrawList* draw_list,ImVec2_c pos,ImU32 col,float sz); +CIMGUI_API void igRenderArrowPointingAt(ImDrawList* draw_list,ImVec2_c pos,ImVec2_c half_sz,ImGuiDir direction,ImU32 col); +CIMGUI_API void igRenderRectFilledInRangeH(ImDrawList* draw_list,const ImRect_c rect,ImU32 col,float fill_x0,float fill_x1,float rounding); +CIMGUI_API void igRenderRectFilledWithHole(ImDrawList* draw_list,const ImRect_c outer,const ImRect_c inner,ImU32 col,float rounding); +CIMGUI_API ImDrawFlags igCalcRoundingFlagsForRectInRect(const ImRect_c r_in,const ImRect_c r_outer,float threshold); +CIMGUI_API void igTextEx(const char* text,const char* text_end,ImGuiTextFlags flags); +CIMGUI_API void igTextAligned(float align_x,float size_x,const char* fmt,...); +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igTextAligned0(float align_x,float size_x,const char* fmt); +#endif +CIMGUI_API void igTextAlignedV(float align_x,float size_x,const char* fmt,va_list args); +CIMGUI_API bool igButtonEx(const char* label,const ImVec2_c size_arg,ImGuiButtonFlags flags); +CIMGUI_API bool igArrowButtonEx(const char* str_id,ImGuiDir dir,ImVec2_c size_arg,ImGuiButtonFlags flags); +CIMGUI_API bool igImageButtonEx(ImGuiID id,ImTextureRef_c tex_ref,const ImVec2_c image_size,const ImVec2_c uv0,const ImVec2_c uv1,const ImVec4_c bg_col,const ImVec4_c tint_col,ImGuiButtonFlags flags); +CIMGUI_API void igSeparatorEx(ImGuiSeparatorFlags flags,float thickness); +CIMGUI_API void igSeparatorTextEx(ImGuiID id,const char* label,const char* label_end,float extra_width); +CIMGUI_API bool igCheckboxFlags_S64Ptr(const char* label,ImS64* flags,ImS64 flags_value); +CIMGUI_API bool igCheckboxFlags_U64Ptr(const char* label,ImU64* flags,ImU64 flags_value); +CIMGUI_API bool igCloseButton(ImGuiID id,const ImVec2_c pos); +CIMGUI_API bool igCollapseButton(ImGuiID id,const ImVec2_c pos); +CIMGUI_API void igScrollbar(ImGuiAxis axis); +CIMGUI_API bool igScrollbarEx(const ImRect_c bb,ImGuiID id,ImGuiAxis axis,ImS64* p_scroll_v,ImS64 avail_v,ImS64 contents_v,ImDrawFlags draw_rounding_flags); +CIMGUI_API ImRect_c igGetWindowScrollbarRect(ImGuiWindow* window,ImGuiAxis axis); +CIMGUI_API ImGuiID igGetWindowScrollbarID(ImGuiWindow* window,ImGuiAxis axis); +CIMGUI_API ImGuiID igGetWindowResizeCornerID(ImGuiWindow* window,int n); +CIMGUI_API ImGuiID igGetWindowResizeBorderID(ImGuiWindow* window,ImGuiDir dir); +CIMGUI_API void igExtendHitBoxWhenNearViewportEdge(ImGuiWindow* window,ImRect* bb,float threshold,ImGuiAxis axis); +CIMGUI_API bool igButtonBehavior(const ImRect_c bb,ImGuiID id,bool* out_hovered,bool* out_held,ImGuiButtonFlags flags); +CIMGUI_API bool igDragBehavior(ImGuiID id,ImGuiDataType data_type,void* p_v,float v_speed,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags); +CIMGUI_API bool igSliderBehavior(const ImRect_c bb,ImGuiID id,ImGuiDataType data_type,void* p_v,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags,ImRect* out_grab_bb); +CIMGUI_API bool igSplitterBehavior(const ImRect_c bb,ImGuiID id,ImGuiAxis axis,float* size1,float* size2,float min_size1,float min_size2,float hover_extend,float hover_visibility_delay,ImU32 bg_col); +CIMGUI_API bool igTreeNodeBehavior(ImGuiID id,ImGuiTreeNodeFlags flags,const char* label,const char* label_end); +CIMGUI_API void igTreeNodeDrawLineToChildNode(const ImVec2_c target_pos); +CIMGUI_API void igTreeNodeDrawLineToTreePop(const ImGuiTreeNodeStackData* data); +CIMGUI_API void igTreePushOverrideID(ImGuiID id); +CIMGUI_API void igTreeNodeSetOpen(ImGuiID storage_id,bool open); +CIMGUI_API bool igTreeNodeUpdateNextOpen(ImGuiID storage_id,ImGuiTreeNodeFlags flags); +CIMGUI_API const ImGuiDataTypeInfo* igDataTypeGetInfo(ImGuiDataType data_type); +CIMGUI_API int igDataTypeFormatString(char* buf,int buf_size,ImGuiDataType data_type,const void* p_data,const char* format); +CIMGUI_API void igDataTypeApplyOp(ImGuiDataType data_type,int op,void* output,const void* arg_1,const void* arg_2); +CIMGUI_API bool igDataTypeApplyFromText(const char* buf,ImGuiDataType data_type,void* p_data,const char* format,void* p_data_when_empty); +CIMGUI_API int igDataTypeCompare(ImGuiDataType data_type,const void* arg_1,const void* arg_2); +CIMGUI_API bool igDataTypeClamp(ImGuiDataType data_type,void* p_data,const void* p_min,const void* p_max); +CIMGUI_API bool igDataTypeIsZero(ImGuiDataType data_type,const void* p_data); +CIMGUI_API bool igInputTextEx(const char* label,const char* hint,char* buf,int buf_size,const ImVec2_c size_arg,ImGuiInputTextFlags flags,ImGuiInputTextCallback callback,void* user_data); +CIMGUI_API void igInputTextDeactivateHook(ImGuiID id); +CIMGUI_API bool igTempInputText(const ImRect_c bb,ImGuiID id,const char* label,char* buf,size_t buf_size,ImGuiInputTextFlags flags,ImGuiInputTextCallback callback,void* user_data); +CIMGUI_API bool igTempInputScalar(const ImRect_c bb,ImGuiID id,const char* label,ImGuiDataType data_type,void* p_data,const char* format,const void* p_clamp_min,const void* p_clamp_max); +CIMGUI_API bool igTempInputIsActive(ImGuiID id); +CIMGUI_API ImGuiInputTextState* igGetInputTextState(ImGuiID id); +CIMGUI_API void igSetNextItemRefVal(ImGuiDataType data_type,void* p_data); +CIMGUI_API bool igIsItemActiveAsInputText(void); +CIMGUI_API void igColorTooltip(const char* text,const float* col,ImGuiColorEditFlags flags); +CIMGUI_API void igColorEditOptionsPopup(const float* col,ImGuiColorEditFlags flags); +CIMGUI_API void igColorPickerOptionsPopup(const float* ref_col,ImGuiColorEditFlags flags); +CIMGUI_API void igSetNextItemColorMarker(ImU32 col); +CIMGUI_API int igPlotEx(ImGuiPlotType plot_type,const char* label,float(*values_getter)(void* data,int idx),void* data,int values_count,int values_offset,const char* overlay_text,float scale_min,float scale_max,const ImVec2_c size_arg); +CIMGUI_API void igShadeVertsLinearColorGradientKeepAlpha(ImDrawList* draw_list,int vert_start_idx,int vert_end_idx,ImVec2_c gradient_p0,ImVec2_c gradient_p1,ImU32 col0,ImU32 col1); +CIMGUI_API void igShadeVertsLinearUV(ImDrawList* draw_list,int vert_start_idx,int vert_end_idx,const ImVec2_c a,const ImVec2_c b,const ImVec2_c uv_a,const ImVec2_c uv_b,bool clamp); +CIMGUI_API void igShadeVertsTransformPos(ImDrawList* draw_list,int vert_start_idx,int vert_end_idx,const ImVec2_c pivot_in,float cos_a,float sin_a,const ImVec2_c pivot_out); +CIMGUI_API void igGcCompactTransientMiscBuffers(void); +CIMGUI_API void igGcCompactTransientWindowBuffers(ImGuiWindow* window); +CIMGUI_API void igGcAwakeTransientWindowBuffers(ImGuiWindow* window); +CIMGUI_API bool igErrorLog(const char* msg); +CIMGUI_API void igErrorRecoveryStoreState(ImGuiErrorRecoveryState* state_out); +CIMGUI_API void igErrorRecoveryTryToRecoverState(const ImGuiErrorRecoveryState* state_in); +CIMGUI_API void igErrorRecoveryTryToRecoverWindowState(const ImGuiErrorRecoveryState* state_in); +CIMGUI_API void igErrorCheckUsingSetCursorPosToExtendParentBoundaries(void); +CIMGUI_API void igErrorCheckEndFrameFinalizeErrorTooltip(void); +CIMGUI_API bool igBeginErrorTooltip(void); +CIMGUI_API void igEndErrorTooltip(void); +CIMGUI_API void igDemoMarker(const char* file,int line,const char* section); +CIMGUI_API void igDebugAllocHook(ImGuiDebugAllocInfo* info,int frame_count,void* ptr,size_t size); +CIMGUI_API void igShowFontAtlas(ImFontAtlas* atlas); +CIMGUI_API void igDebugHookIdInfo(ImGuiID id,ImGuiDataType data_type,const void* data_id,const void* data_id_end); +CIMGUI_API void igDebugNodeColumns(ImGuiOldColumns* columns); +CIMGUI_API void igDebugNodeDrawList(ImGuiWindow* window,ImGuiViewportP* viewport,const ImDrawList* draw_list,const char* label); +CIMGUI_API void igDebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list,const ImDrawList* draw_list,const ImDrawCmd* draw_cmd,bool show_mesh,bool show_aabb); +CIMGUI_API void igDebugNodeFont(ImFont* font); +CIMGUI_API void igDebugNodeFontGlyphsForSrcMask(ImFont* font,ImFontBaked* baked,int src_mask); +CIMGUI_API void igDebugNodeStorage(ImGuiStorage* storage,const char* label); +CIMGUI_API void igDebugNodeTabBar(ImGuiTabBar* tab_bar,const char* label); +CIMGUI_API void igDebugNodeTable(ImGuiTable* table); +CIMGUI_API void igDebugNodeTableSettings(ImGuiTableSettings* settings,ImGuiTable* table); +CIMGUI_API void igDebugNodeInputTextState(ImGuiInputTextState* state); +CIMGUI_API void igDebugNodeTypingSelectState(ImGuiTypingSelectState* state); +CIMGUI_API void igDebugNodeMultiSelectState(ImGuiMultiSelectState* state); +CIMGUI_API void igDebugNodeWindow(ImGuiWindow* window,const char* label); +CIMGUI_API void igDebugNodeWindowSettings(ImGuiWindowSettings* settings); +CIMGUI_API void igDebugNodeWindowsList(ImVector_ImGuiWindowPtr* windows,const char* label); +CIMGUI_API void igDebugNodeViewport(ImGuiViewportP* viewport); +CIMGUI_API ImFontLoader* ImFontLoader_ImFontLoader(void); +CIMGUI_API void ImFontLoader_destroy(ImFontLoader* self); +CIMGUI_API const ImFontLoader* igImFontAtlasGetFontLoaderForStbTruetype(void); +CIMGUI_API int igImFontAtlasRectId_GetIndex(ImFontAtlasRectId id); +CIMGUI_API unsigned int igImFontAtlasRectId_GetGeneration(ImFontAtlasRectId id); +CIMGUI_API ImFontAtlasRectId igImFontAtlasRectId_Make(int index_idx,int gen_idx); +CIMGUI_API ImFontAtlasBuilder* ImFontAtlasBuilder_ImFontAtlasBuilder(void); +CIMGUI_API void ImFontAtlasBuilder_destroy(ImFontAtlasBuilder* self); +CIMGUI_API void igImFontAtlasBuildInit(ImFontAtlas* atlas); +CIMGUI_API void igImFontAtlasBuildDestroy(ImFontAtlas* atlas); +CIMGUI_API void igImFontAtlasBuildMain(ImFontAtlas* atlas); +CIMGUI_API void igImFontAtlasBuildSetupFontLoader(ImFontAtlas* atlas,const ImFontLoader* font_loader); +CIMGUI_API void igImFontAtlasBuildNotifySetFont(ImFontAtlas* atlas,ImFont* old_font,ImFont* new_font); +CIMGUI_API void igImFontAtlasBuildUpdatePointers(ImFontAtlas* atlas); +CIMGUI_API void igImFontAtlasBuildRenderBitmapFromString(ImFontAtlas* atlas,int x,int y,int w,int h,const char* in_str,char in_marker_char); +CIMGUI_API void igImFontAtlasBuildClear(ImFontAtlas* atlas); +CIMGUI_API ImTextureData* igImFontAtlasTextureAdd(ImFontAtlas* atlas,int w,int h); +CIMGUI_API void igImFontAtlasTextureMakeSpace(ImFontAtlas* atlas); +CIMGUI_API void igImFontAtlasTextureRepack(ImFontAtlas* atlas,int w,int h); +CIMGUI_API void igImFontAtlasTextureGrow(ImFontAtlas* atlas,int old_w,int old_h); +CIMGUI_API void igImFontAtlasTextureCompact(ImFontAtlas* atlas); +CIMGUI_API ImVec2i_c igImFontAtlasTextureGetSizeEstimate(ImFontAtlas* atlas); +CIMGUI_API void igImFontAtlasBuildSetupFontSpecialGlyphs(ImFontAtlas* atlas,ImFont* font,ImFontConfig* src); +CIMGUI_API void igImFontAtlasBuildLegacyPreloadAllGlyphRanges(ImFontAtlas* atlas); +CIMGUI_API void igImFontAtlasBuildGetOversampleFactors(ImFontConfig* src,ImFontBaked* baked,int* out_oversample_h,int* out_oversample_v); +CIMGUI_API void igImFontAtlasBuildDiscardBakes(ImFontAtlas* atlas,int unused_frames); +CIMGUI_API bool igImFontAtlasFontSourceInit(ImFontAtlas* atlas,ImFontConfig* src); +CIMGUI_API void igImFontAtlasFontSourceAddToFont(ImFontAtlas* atlas,ImFont* font,ImFontConfig* src); +CIMGUI_API void igImFontAtlasFontDestroySourceData(ImFontAtlas* atlas,ImFontConfig* src); +CIMGUI_API bool igImFontAtlasFontInitOutput(ImFontAtlas* atlas,ImFont* font); +CIMGUI_API void igImFontAtlasFontDestroyOutput(ImFontAtlas* atlas,ImFont* font); +CIMGUI_API void igImFontAtlasFontRebuildOutput(ImFontAtlas* atlas,ImFont* font); +CIMGUI_API void igImFontAtlasFontDiscardBakes(ImFontAtlas* atlas,ImFont* font,int unused_frames); +CIMGUI_API ImGuiID igImFontAtlasBakedGetId(ImGuiID font_id,float baked_size,float rasterizer_density); +CIMGUI_API ImFontBaked* igImFontAtlasBakedGetOrAdd(ImFontAtlas* atlas,ImFont* font,float font_size,float font_rasterizer_density); +CIMGUI_API ImFontBaked* igImFontAtlasBakedGetClosestMatch(ImFontAtlas* atlas,ImFont* font,float font_size,float font_rasterizer_density); +CIMGUI_API ImFontBaked* igImFontAtlasBakedAdd(ImFontAtlas* atlas,ImFont* font,float font_size,float font_rasterizer_density,ImGuiID baked_id); +CIMGUI_API void igImFontAtlasBakedDiscard(ImFontAtlas* atlas,ImFont* font,ImFontBaked* baked); +CIMGUI_API ImFontGlyph* igImFontAtlasBakedAddFontGlyph(ImFontAtlas* atlas,ImFontBaked* baked,ImFontConfig* src,const ImFontGlyph* in_glyph); +CIMGUI_API void igImFontAtlasBakedAddFontGlyphAdvancedX(ImFontAtlas* atlas,ImFontBaked* baked,ImFontConfig* src,ImWchar codepoint,float advance_x); +CIMGUI_API void igImFontAtlasBakedDiscardFontGlyph(ImFontAtlas* atlas,ImFont* font,ImFontBaked* baked,ImFontGlyph* glyph); +CIMGUI_API void igImFontAtlasBakedSetFontGlyphBitmap(ImFontAtlas* atlas,ImFontBaked* baked,ImFontConfig* src,ImFontGlyph* glyph,ImTextureRect* r,const unsigned char* src_pixels,ImTextureFormat src_fmt,int src_pitch); +CIMGUI_API void igImFontAtlasPackInit(ImFontAtlas* atlas); +CIMGUI_API ImFontAtlasRectId igImFontAtlasPackAddRect(ImFontAtlas* atlas,int w,int h,ImFontAtlasRectEntry* overwrite_entry); +CIMGUI_API ImTextureRect* igImFontAtlasPackGetRect(ImFontAtlas* atlas,ImFontAtlasRectId id); +CIMGUI_API ImTextureRect* igImFontAtlasPackGetRectSafe(ImFontAtlas* atlas,ImFontAtlasRectId id); +CIMGUI_API void igImFontAtlasPackDiscardRect(ImFontAtlas* atlas,ImFontAtlasRectId id); +CIMGUI_API void igImFontAtlasUpdateNewFrame(ImFontAtlas* atlas,int frame_count,bool renderer_has_textures); +CIMGUI_API void igImFontAtlasAddDrawListSharedData(ImFontAtlas* atlas,ImDrawListSharedData* data); +CIMGUI_API void igImFontAtlasRemoveDrawListSharedData(ImFontAtlas* atlas,ImDrawListSharedData* data); +CIMGUI_API void igImFontAtlasUpdateDrawListsTextures(ImFontAtlas* atlas,ImTextureRef_c old_tex,ImTextureRef_c new_tex); +CIMGUI_API void igImFontAtlasUpdateDrawListsSharedData(ImFontAtlas* atlas); +CIMGUI_API void igImFontAtlasTextureBlockConvert(const unsigned char* src_pixels,ImTextureFormat src_fmt,int src_pitch,unsigned char* dst_pixels,ImTextureFormat dst_fmt,int dst_pitch,int w,int h); +CIMGUI_API void igImFontAtlasTextureBlockPostProcess(ImFontAtlasPostProcessData* data); +CIMGUI_API void igImFontAtlasTextureBlockPostProcessMultiply(ImFontAtlasPostProcessData* data,float multiply_factor); +CIMGUI_API void igImFontAtlasTextureBlockFill(ImTextureData* dst_tex,int dst_x,int dst_y,int w,int h,ImU32 col); +CIMGUI_API void igImFontAtlasTextureBlockCopy(ImTextureData* src_tex,int src_x,int src_y,ImTextureData* dst_tex,int dst_x,int dst_y,int w,int h); +CIMGUI_API void igImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas,ImTextureData* tex,int x,int y,int w,int h); +CIMGUI_API bool igImTextureDataUpdateNewFrame(ImTextureData* tex); +CIMGUI_API void igImTextureDataQueueUpload(ImTextureData* tex,int x,int y,int w,int h); +CIMGUI_API int igImTextureDataGetFormatBytesPerPixel(ImTextureFormat format); +CIMGUI_API const char* igImTextureDataGetStatusName(ImTextureStatus status); +CIMGUI_API const char* igImTextureDataGetFormatName(ImTextureFormat format); +CIMGUI_API bool igImFontAtlasGetMouseCursorTexData(ImFontAtlas* atlas,ImGuiMouseCursor cursor_type,ImVec2_c* out_offset,ImVec2_c* out_size,ImVec2 out_uv_border[2],ImVec2 out_uv_fill[2]); +#ifdef IMGUI_ENABLE_FREETYPE +CIMGUI_API const ImFontLoader* ImGuiFreeType_GetFontLoader(void); +CIMGUI_API void ImGuiFreeType_SetAllocatorFunctions(void*(*alloc_func)(size_t sz,void* user_data),void(*free_func)(void* ptr,void* user_data),void* user_data); +CIMGUI_API bool ImGuiFreeType_DebugEditFontLoaderFlags(ImGuiFreeTypeLoaderFlags* p_font_loader_flags); +#endif + + +/////////////////////////hand written functions +//no appendfV +CIMGUI_API void ImGuiTextBuffer_appendf(ImGuiTextBuffer *self, const char *fmt, ...); +//for getting FLT_MAX in bindings +CIMGUI_API float igGET_FLT_MAX(void); +//for getting FLT_MIN in bindings +CIMGUI_API float igGET_FLT_MIN(void); + + +CIMGUI_API ImVector_ImWchar* ImVector_ImWchar_create(void); +CIMGUI_API void ImVector_ImWchar_destroy(ImVector_ImWchar* self); +CIMGUI_API void ImVector_ImWchar_Init(ImVector_ImWchar* p); +CIMGUI_API void ImVector_ImWchar_UnInit(ImVector_ImWchar* p); + +#ifdef IMGUI_HAS_DOCK +CIMGUI_API void ImGuiPlatformIO_Set_Platform_GetWindowPos(ImGuiPlatformIO* platform_io, void(*user_callback)(ImGuiViewport* vp, ImVec2* out_pos)); +CIMGUI_API void ImGuiPlatformIO_Set_Platform_GetWindowSize(ImGuiPlatformIO* platform_io, void(*user_callback)(ImGuiViewport* vp, ImVec2* out_size)); +#endif + +#endif //CIMGUI_INCLUDED + + + + diff --git a/src/libs/cimgui/Makefile b/src/libs/cimgui/Makefile new file mode 100644 index 0000000..b599dae --- /dev/null +++ b/src/libs/cimgui/Makefile @@ -0,0 +1,9 @@ +LIBKIND := shared +LIBNAME := liboshot_cimgui +SRC += cimgui.cpp +VISIBILITY := default + +CXXFLAGS += -I../../../include/libs/cimgui -I../../../include/libs/ +EXTRA_LIBS = -L../../../$(BUILDDIR) -loshot_imgui + +include ../../../mk/common.mk diff --git a/src/libs/cimgui/cimgui.cpp b/src/libs/cimgui/cimgui.cpp new file mode 100644 index 0000000..64bc479 --- /dev/null +++ b/src/libs/cimgui/cimgui.cpp @@ -0,0 +1,6215 @@ +//This file is automatically generated by generator.lua from https://github.com/cimgui/cimgui +//based on imgui.h file version "1.92.9 WIP" 19284 from Dear ImGui https://github.com/ocornut/imgui +//with imgui_internal.h api +//with imgui_freetype.h api + +#include "./imgui/imgui.h" +#include "./imgui/imgui_internal.h" +#include "cimgui.h" + + + +static inline ImColor ConvertToCPP_ImColor(const ImColor_c& src) +{ + ImColor dest; + dest.Value.x = src.Value.x; + dest.Value.y = src.Value.y; + dest.Value.z = src.Value.z; + dest.Value.w = src.Value.w; + return dest; +} +static inline ImColor_c ConvertFromCPP_ImColor(const ImColor& src) +{ + ImColor_c dest; + dest.Value.x = src.Value.x; + dest.Value.y = src.Value.y; + dest.Value.z = src.Value.z; + dest.Value.w = src.Value.w; + return dest; +} +static inline ImRect ConvertToCPP_ImRect(const ImRect_c& src) +{ + ImRect dest; + dest.Min.x = src.Min.x; + dest.Min.y = src.Min.y; + dest.Max.x = src.Max.x; + dest.Max.y = src.Max.y; + return dest; +} +static inline ImRect_c ConvertFromCPP_ImRect(const ImRect& src) +{ + ImRect_c dest; + dest.Min.x = src.Min.x; + dest.Min.y = src.Min.y; + dest.Max.x = src.Max.x; + dest.Max.y = src.Max.y; + return dest; +} +static inline ImTextureRef ConvertToCPP_ImTextureRef(const ImTextureRef_c& src) +{ + ImTextureRef dest; + dest._TexData = src._TexData; + dest._TexID = src._TexID; + return dest; +} +static inline ImTextureRef_c ConvertFromCPP_ImTextureRef(const ImTextureRef& src) +{ + ImTextureRef_c dest; + dest._TexData = src._TexData; + dest._TexID = src._TexID; + return dest; +} +static inline ImVec2 ConvertToCPP_ImVec2(const ImVec2_c& src) +{ + ImVec2 dest; + dest.x = src.x; + dest.y = src.y; + return dest; +} +static inline ImVec2_c ConvertFromCPP_ImVec2(const ImVec2& src) +{ + ImVec2_c dest; + dest.x = src.x; + dest.y = src.y; + return dest; +} +static inline ImVec2i ConvertToCPP_ImVec2i(const ImVec2i_c& src) +{ + ImVec2i dest; + dest.x = src.x; + dest.y = src.y; + return dest; +} +static inline ImVec2i_c ConvertFromCPP_ImVec2i(const ImVec2i& src) +{ + ImVec2i_c dest; + dest.x = src.x; + dest.y = src.y; + return dest; +} +static inline ImVec4 ConvertToCPP_ImVec4(const ImVec4_c& src) +{ + ImVec4 dest; + dest.x = src.x; + dest.y = src.y; + dest.z = src.z; + dest.w = src.w; + return dest; +} +static inline ImVec4_c ConvertFromCPP_ImVec4(const ImVec4& src) +{ + ImVec4_c dest; + dest.x = src.x; + dest.y = src.y; + dest.z = src.z; + dest.w = src.w; + return dest; +}CIMGUI_API ImVec2* ImVec2_ImVec2_Nil(void) +{ + return IM_NEW(ImVec2)(); +} +CIMGUI_API void ImVec2_destroy(ImVec2* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImVec2* ImVec2_ImVec2_Float(float _x,float _y) +{ + return IM_NEW(ImVec2)(_x,_y); +} +CIMGUI_API ImVec4* ImVec4_ImVec4_Nil(void) +{ + return IM_NEW(ImVec4)(); +} +CIMGUI_API void ImVec4_destroy(ImVec4* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImVec4* ImVec4_ImVec4_Float(float _x,float _y,float _z,float _w) +{ + return IM_NEW(ImVec4)(_x,_y,_z,_w); +} +CIMGUI_API ImTextureRef* ImTextureRef_ImTextureRef_Nil(void) +{ + return IM_NEW(ImTextureRef)(); +} +CIMGUI_API void ImTextureRef_destroy(ImTextureRef* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImTextureRef* ImTextureRef_ImTextureRef_TextureID(ImTextureID tex_id) +{ + return IM_NEW(ImTextureRef)(tex_id); +} +CIMGUI_API ImTextureID ImTextureRef_GetTexID(ImTextureRef* self) +{ + return self->GetTexID(); +} +CIMGUI_API ImGuiContext* igCreateContext(ImFontAtlas* shared_font_atlas) +{ + return ImGui::CreateContext(shared_font_atlas); +} +CIMGUI_API void igDestroyContext(ImGuiContext* ctx) +{ + return ImGui::DestroyContext(ctx); +} +CIMGUI_API ImGuiContext* igGetCurrentContext() +{ + return ImGui::GetCurrentContext(); +} +CIMGUI_API void igSetCurrentContext(ImGuiContext* ctx) +{ + return ImGui::SetCurrentContext(ctx); +} +CIMGUI_API ImGuiIO* igGetIO_Nil() +{ + return &ImGui::GetIO(); +} +CIMGUI_API ImGuiPlatformIO* igGetPlatformIO_Nil() +{ + return &ImGui::GetPlatformIO(); +} +CIMGUI_API ImGuiStyle* igGetStyle() +{ + return &ImGui::GetStyle(); +} +CIMGUI_API void igNewFrame() +{ + return ImGui::NewFrame(); +} +CIMGUI_API void igEndFrame() +{ + return ImGui::EndFrame(); +} +CIMGUI_API void igRender() +{ + return ImGui::Render(); +} +CIMGUI_API ImDrawData* igGetDrawData() +{ + return ImGui::GetDrawData(); +} +CIMGUI_API void igShowMetricsWindow(bool* p_open) +{ + return ImGui::ShowMetricsWindow(p_open); +} +CIMGUI_API void igShowDebugLogWindow(bool* p_open) +{ + return ImGui::ShowDebugLogWindow(p_open); +} +CIMGUI_API void igShowIDStackToolWindow(bool* p_open) +{ + return ImGui::ShowIDStackToolWindow(p_open); +} +CIMGUI_API const char* igGetVersion() +{ + return ImGui::GetVersion(); +} +CIMGUI_API void igStyleColorsDark(ImGuiStyle* dst) +{ + return ImGui::StyleColorsDark(dst); +} +CIMGUI_API void igStyleColorsLight(ImGuiStyle* dst) +{ + return ImGui::StyleColorsLight(dst); +} +CIMGUI_API void igStyleColorsClassic(ImGuiStyle* dst) +{ + return ImGui::StyleColorsClassic(dst); +} +CIMGUI_API bool igBegin(const char* name,bool* p_open,ImGuiWindowFlags flags) +{ + return ImGui::Begin(name,p_open,flags); +} +CIMGUI_API void igEnd() +{ + return ImGui::End(); +} +CIMGUI_API bool igBeginChild_Str(const char* str_id,const ImVec2_c size,ImGuiChildFlags child_flags,ImGuiWindowFlags window_flags) +{ + return ImGui::BeginChild(str_id,ConvertToCPP_ImVec2(size),child_flags,window_flags); +} +CIMGUI_API bool igBeginChild_ID(ImGuiID id,const ImVec2_c size,ImGuiChildFlags child_flags,ImGuiWindowFlags window_flags) +{ + return ImGui::BeginChild(id,ConvertToCPP_ImVec2(size),child_flags,window_flags); +} +CIMGUI_API void igEndChild() +{ + return ImGui::EndChild(); +} +CIMGUI_API bool igIsWindowAppearing() +{ + return ImGui::IsWindowAppearing(); +} +CIMGUI_API bool igIsWindowCollapsed() +{ + return ImGui::IsWindowCollapsed(); +} +CIMGUI_API bool igIsWindowFocused(ImGuiFocusedFlags flags) +{ + return ImGui::IsWindowFocused(flags); +} +CIMGUI_API bool igIsWindowHovered(ImGuiHoveredFlags flags) +{ + return ImGui::IsWindowHovered(flags); +} +CIMGUI_API ImDrawList* igGetWindowDrawList() +{ + return ImGui::GetWindowDrawList(); +} +CIMGUI_API ImVec2_c igGetWindowPos() +{ + return ConvertFromCPP_ImVec2(ImGui::GetWindowPos()); +} +CIMGUI_API ImVec2_c igGetWindowSize() +{ + return ConvertFromCPP_ImVec2(ImGui::GetWindowSize()); +} +CIMGUI_API float igGetWindowWidth() +{ + return ImGui::GetWindowWidth(); +} +CIMGUI_API float igGetWindowHeight() +{ + return ImGui::GetWindowHeight(); +} +CIMGUI_API void igSetNextWindowPos(const ImVec2_c pos,ImGuiCond cond,const ImVec2_c pivot) +{ + return ImGui::SetNextWindowPos(ConvertToCPP_ImVec2(pos),cond,ConvertToCPP_ImVec2(pivot)); +} +CIMGUI_API void igSetNextWindowSize(const ImVec2_c size,ImGuiCond cond) +{ + return ImGui::SetNextWindowSize(ConvertToCPP_ImVec2(size),cond); +} +CIMGUI_API void igSetNextWindowSizeConstraints(const ImVec2_c size_min,const ImVec2_c size_max,ImGuiSizeCallback custom_callback,void* custom_callback_data) +{ + return ImGui::SetNextWindowSizeConstraints(ConvertToCPP_ImVec2(size_min),ConvertToCPP_ImVec2(size_max),custom_callback,custom_callback_data); +} +CIMGUI_API void igSetNextWindowContentSize(const ImVec2_c size) +{ + return ImGui::SetNextWindowContentSize(ConvertToCPP_ImVec2(size)); +} +CIMGUI_API void igSetNextWindowCollapsed(bool collapsed,ImGuiCond cond) +{ + return ImGui::SetNextWindowCollapsed(collapsed,cond); +} +CIMGUI_API void igSetNextWindowFocus() +{ + return ImGui::SetNextWindowFocus(); +} +CIMGUI_API void igSetNextWindowScroll(const ImVec2_c scroll) +{ + return ImGui::SetNextWindowScroll(ConvertToCPP_ImVec2(scroll)); +} +CIMGUI_API void igSetNextWindowBgAlpha(float alpha) +{ + return ImGui::SetNextWindowBgAlpha(alpha); +} +CIMGUI_API void igSetWindowPos_Vec2(const ImVec2_c pos,ImGuiCond cond) +{ + return ImGui::SetWindowPos(ConvertToCPP_ImVec2(pos),cond); +} +CIMGUI_API void igSetWindowSize_Vec2(const ImVec2_c size,ImGuiCond cond) +{ + return ImGui::SetWindowSize(ConvertToCPP_ImVec2(size),cond); +} +CIMGUI_API void igSetWindowCollapsed_Bool(bool collapsed,ImGuiCond cond) +{ + return ImGui::SetWindowCollapsed(collapsed,cond); +} +CIMGUI_API void igSetWindowFocus_Nil() +{ + return ImGui::SetWindowFocus(); +} +CIMGUI_API void igSetWindowPos_Str(const char* name,const ImVec2_c pos,ImGuiCond cond) +{ + return ImGui::SetWindowPos(name,ConvertToCPP_ImVec2(pos),cond); +} +CIMGUI_API void igSetWindowSize_Str(const char* name,const ImVec2_c size,ImGuiCond cond) +{ + return ImGui::SetWindowSize(name,ConvertToCPP_ImVec2(size),cond); +} +CIMGUI_API void igSetWindowCollapsed_Str(const char* name,bool collapsed,ImGuiCond cond) +{ + return ImGui::SetWindowCollapsed(name,collapsed,cond); +} +CIMGUI_API void igSetWindowFocus_Str(const char* name) +{ + return ImGui::SetWindowFocus(name); +} +CIMGUI_API float igGetScrollX() +{ + return ImGui::GetScrollX(); +} +CIMGUI_API float igGetScrollY() +{ + return ImGui::GetScrollY(); +} +CIMGUI_API void igSetScrollX_Float(float scroll_x) +{ + return ImGui::SetScrollX(scroll_x); +} +CIMGUI_API void igSetScrollY_Float(float scroll_y) +{ + return ImGui::SetScrollY(scroll_y); +} +CIMGUI_API float igGetScrollMaxX() +{ + return ImGui::GetScrollMaxX(); +} +CIMGUI_API float igGetScrollMaxY() +{ + return ImGui::GetScrollMaxY(); +} +CIMGUI_API void igSetScrollHereX(float center_x_ratio) +{ + return ImGui::SetScrollHereX(center_x_ratio); +} +CIMGUI_API void igSetScrollHereY(float center_y_ratio) +{ + return ImGui::SetScrollHereY(center_y_ratio); +} +CIMGUI_API void igSetScrollFromPosX_Float(float local_x,float center_x_ratio) +{ + return ImGui::SetScrollFromPosX(local_x,center_x_ratio); +} +CIMGUI_API void igSetScrollFromPosY_Float(float local_y,float center_y_ratio) +{ + return ImGui::SetScrollFromPosY(local_y,center_y_ratio); +} +CIMGUI_API void igPushFont(ImFont* font,float font_size_base_unscaled) +{ + return ImGui::PushFont(font,font_size_base_unscaled); +} +CIMGUI_API void igPopFont() +{ + return ImGui::PopFont(); +} +CIMGUI_API ImFont* igGetFont() +{ + return ImGui::GetFont(); +} +CIMGUI_API float igGetFontSize() +{ + return ImGui::GetFontSize(); +} +CIMGUI_API ImFontBaked* igGetFontBaked() +{ + return ImGui::GetFontBaked(); +} +CIMGUI_API void igPushStyleColor_U32(ImGuiCol idx,ImU32 col) +{ + return ImGui::PushStyleColor(idx,col); +} +CIMGUI_API void igPushStyleColor_Vec4(ImGuiCol idx,const ImVec4_c col) +{ + return ImGui::PushStyleColor(idx,ConvertToCPP_ImVec4(col)); +} +CIMGUI_API void igPopStyleColor(int count) +{ + return ImGui::PopStyleColor(count); +} +CIMGUI_API void igPushStyleVar_Float(ImGuiStyleVar idx,float val) +{ + return ImGui::PushStyleVar(idx,val); +} +CIMGUI_API void igPushStyleVar_Vec2(ImGuiStyleVar idx,const ImVec2_c val) +{ + return ImGui::PushStyleVar(idx,ConvertToCPP_ImVec2(val)); +} +CIMGUI_API void igPushStyleVarX(ImGuiStyleVar idx,float val_x) +{ + return ImGui::PushStyleVarX(idx,val_x); +} +CIMGUI_API void igPushStyleVarY(ImGuiStyleVar idx,float val_y) +{ + return ImGui::PushStyleVarY(idx,val_y); +} +CIMGUI_API void igPopStyleVar(int count) +{ + return ImGui::PopStyleVar(count); +} +CIMGUI_API void igPushItemFlag(ImGuiItemFlags option,bool enabled) +{ + return ImGui::PushItemFlag(option,enabled); +} +CIMGUI_API void igPopItemFlag() +{ + return ImGui::PopItemFlag(); +} +CIMGUI_API void igPushItemWidth(float item_width) +{ + return ImGui::PushItemWidth(item_width); +} +CIMGUI_API void igPopItemWidth() +{ + return ImGui::PopItemWidth(); +} +CIMGUI_API void igSetNextItemWidth(float item_width) +{ + return ImGui::SetNextItemWidth(item_width); +} +CIMGUI_API float igCalcItemWidth() +{ + return ImGui::CalcItemWidth(); +} +CIMGUI_API void igPushTextWrapPos(float wrap_local_pos_x) +{ + return ImGui::PushTextWrapPos(wrap_local_pos_x); +} +CIMGUI_API void igPopTextWrapPos() +{ + return ImGui::PopTextWrapPos(); +} +CIMGUI_API ImVec2_c igGetFontTexUvWhitePixel() +{ + return ConvertFromCPP_ImVec2(ImGui::GetFontTexUvWhitePixel()); +} +CIMGUI_API ImU32 igGetColorU32_Col(ImGuiCol idx,float alpha_mul) +{ + return ImGui::GetColorU32(idx,alpha_mul); +} +CIMGUI_API ImU32 igGetColorU32_Vec4(const ImVec4_c col) +{ + return ImGui::GetColorU32(ConvertToCPP_ImVec4(col)); +} +CIMGUI_API ImU32 igGetColorU32_U32(ImU32 col,float alpha_mul) +{ + return ImGui::GetColorU32(col,alpha_mul); +} +CIMGUI_API const ImVec4_c* igGetStyleColorVec4(ImGuiCol idx) +{ + return reinterpret_cast(&ImGui::GetStyleColorVec4(idx)); +} +CIMGUI_API ImVec2_c igGetCursorScreenPos() +{ + return ConvertFromCPP_ImVec2(ImGui::GetCursorScreenPos()); +} +CIMGUI_API void igSetCursorScreenPos(const ImVec2_c pos) +{ + return ImGui::SetCursorScreenPos(ConvertToCPP_ImVec2(pos)); +} +CIMGUI_API ImVec2_c igGetContentRegionAvail() +{ + return ConvertFromCPP_ImVec2(ImGui::GetContentRegionAvail()); +} +CIMGUI_API ImVec2_c igGetCursorPos() +{ + return ConvertFromCPP_ImVec2(ImGui::GetCursorPos()); +} +CIMGUI_API float igGetCursorPosX() +{ + return ImGui::GetCursorPosX(); +} +CIMGUI_API float igGetCursorPosY() +{ + return ImGui::GetCursorPosY(); +} +CIMGUI_API void igSetCursorPos(const ImVec2_c local_pos) +{ + return ImGui::SetCursorPos(ConvertToCPP_ImVec2(local_pos)); +} +CIMGUI_API void igSetCursorPosX(float local_x) +{ + return ImGui::SetCursorPosX(local_x); +} +CIMGUI_API void igSetCursorPosY(float local_y) +{ + return ImGui::SetCursorPosY(local_y); +} +CIMGUI_API ImVec2_c igGetCursorStartPos() +{ + return ConvertFromCPP_ImVec2(ImGui::GetCursorStartPos()); +} +CIMGUI_API void igSeparator() +{ + return ImGui::Separator(); +} +CIMGUI_API void igSameLine(float offset_from_start_x,float spacing) +{ + return ImGui::SameLine(offset_from_start_x,spacing); +} +CIMGUI_API void igNewLine() +{ + return ImGui::NewLine(); +} +CIMGUI_API void igSpacing() +{ + return ImGui::Spacing(); +} +CIMGUI_API void igDummy(const ImVec2_c size) +{ + return ImGui::Dummy(ConvertToCPP_ImVec2(size)); +} +CIMGUI_API void igIndent(float indent_w) +{ + return ImGui::Indent(indent_w); +} +CIMGUI_API void igUnindent(float indent_w) +{ + return ImGui::Unindent(indent_w); +} +CIMGUI_API void igBeginGroup() +{ + return ImGui::BeginGroup(); +} +CIMGUI_API void igEndGroup() +{ + return ImGui::EndGroup(); +} +CIMGUI_API void igAlignTextToFramePadding() +{ + return ImGui::AlignTextToFramePadding(); +} +CIMGUI_API float igGetTextLineHeight() +{ + return ImGui::GetTextLineHeight(); +} +CIMGUI_API float igGetTextLineHeightWithSpacing() +{ + return ImGui::GetTextLineHeightWithSpacing(); +} +CIMGUI_API float igGetFrameHeight() +{ + return ImGui::GetFrameHeight(); +} +CIMGUI_API float igGetFrameHeightWithSpacing() +{ + return ImGui::GetFrameHeightWithSpacing(); +} +CIMGUI_API void igPushID_Str(const char* str_id) +{ + return ImGui::PushID(str_id); +} +CIMGUI_API void igPushID_StrStr(const char* str_id_begin,const char* str_id_end) +{ + return ImGui::PushID(str_id_begin,str_id_end); +} +CIMGUI_API void igPushID_Ptr(const void* ptr_id) +{ + return ImGui::PushID(ptr_id); +} +CIMGUI_API void igPushID_Int(int int_id) +{ + return ImGui::PushID(int_id); +} +CIMGUI_API void igPopID() +{ + return ImGui::PopID(); +} +CIMGUI_API ImGuiID igGetID_Str(const char* str_id) +{ + return ImGui::GetID(str_id); +} +CIMGUI_API ImGuiID igGetID_StrStr(const char* str_id_begin,const char* str_id_end) +{ + return ImGui::GetID(str_id_begin,str_id_end); +} +CIMGUI_API ImGuiID igGetID_Ptr(const void* ptr_id) +{ + return ImGui::GetID(ptr_id); +} +CIMGUI_API ImGuiID igGetID_Int(int int_id) +{ + return ImGui::GetID(int_id); +} +CIMGUI_API void igTextUnformatted(const char* text,const char* text_end) +{ + return ImGui::TextUnformatted(text,text_end); +} +CIMGUI_API void igText(const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + ImGui::TextV(fmt,args); + va_end(args); +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igText0(const char* fmt) +{ + return igText(fmt); +} +#endif +CIMGUI_API void igTextV(const char* fmt,va_list args) +{ + return ImGui::TextV(fmt,args); +} +CIMGUI_API void igTextColored(const ImVec4_c col,const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + ImGui::TextColoredV(ConvertToCPP_ImVec4(col),fmt,args); + va_end(args); +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igTextColored0(const ImVec4_c col,const char* fmt) +{ + return igTextColored(col,fmt); +} +#endif +CIMGUI_API void igTextColoredV(const ImVec4_c col,const char* fmt,va_list args) +{ + return ImGui::TextColoredV(ConvertToCPP_ImVec4(col),fmt,args); +} +CIMGUI_API void igTextDisabled(const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + ImGui::TextDisabledV(fmt,args); + va_end(args); +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igTextDisabled0(const char* fmt) +{ + return igTextDisabled(fmt); +} +#endif +CIMGUI_API void igTextDisabledV(const char* fmt,va_list args) +{ + return ImGui::TextDisabledV(fmt,args); +} +CIMGUI_API void igTextWrapped(const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + ImGui::TextWrappedV(fmt,args); + va_end(args); +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igTextWrapped0(const char* fmt) +{ + return igTextWrapped(fmt); +} +#endif +CIMGUI_API void igTextWrappedV(const char* fmt,va_list args) +{ + return ImGui::TextWrappedV(fmt,args); +} +CIMGUI_API void igLabelText(const char* label,const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + ImGui::LabelTextV(label,fmt,args); + va_end(args); +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igLabelText0(const char* label,const char* fmt) +{ + return igLabelText(label,fmt); +} +#endif +CIMGUI_API void igLabelTextV(const char* label,const char* fmt,va_list args) +{ + return ImGui::LabelTextV(label,fmt,args); +} +CIMGUI_API void igBulletText(const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + ImGui::BulletTextV(fmt,args); + va_end(args); +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igBulletText0(const char* fmt) +{ + return igBulletText(fmt); +} +#endif +CIMGUI_API void igBulletTextV(const char* fmt,va_list args) +{ + return ImGui::BulletTextV(fmt,args); +} +CIMGUI_API void igSeparatorText(const char* label) +{ + return ImGui::SeparatorText(label); +} +CIMGUI_API bool igButton(const char* label,const ImVec2_c size) +{ + return ImGui::Button(label,ConvertToCPP_ImVec2(size)); +} +CIMGUI_API bool igSmallButton(const char* label) +{ + return ImGui::SmallButton(label); +} +CIMGUI_API bool igInvisibleButton(const char* str_id,const ImVec2_c size,ImGuiButtonFlags flags) +{ + return ImGui::InvisibleButton(str_id,ConvertToCPP_ImVec2(size),flags); +} +CIMGUI_API bool igArrowButton(const char* str_id,ImGuiDir dir) +{ + return ImGui::ArrowButton(str_id,dir); +} +CIMGUI_API bool igCheckbox(const char* label,bool* v) +{ + return ImGui::Checkbox(label,v); +} +CIMGUI_API bool igCheckboxFlags_IntPtr(const char* label,int* flags,int flags_value) +{ + return ImGui::CheckboxFlags(label,flags,flags_value); +} +CIMGUI_API bool igCheckboxFlags_UintPtr(const char* label,unsigned int* flags,unsigned int flags_value) +{ + return ImGui::CheckboxFlags(label,flags,flags_value); +} +CIMGUI_API bool igRadioButton_Bool(const char* label,bool active) +{ + return ImGui::RadioButton(label,active); +} +CIMGUI_API bool igRadioButton_IntPtr(const char* label,int* v,int v_button) +{ + return ImGui::RadioButton(label,v,v_button); +} +CIMGUI_API void igProgressBar(float fraction,const ImVec2_c size_arg,const char* overlay) +{ + return ImGui::ProgressBar(fraction,ConvertToCPP_ImVec2(size_arg),overlay); +} +CIMGUI_API void igBullet() +{ + return ImGui::Bullet(); +} +CIMGUI_API bool igTextLink(const char* label) +{ + return ImGui::TextLink(label); +} +CIMGUI_API bool igTextLinkOpenURL(const char* label,const char* url) +{ + return ImGui::TextLinkOpenURL(label,url); +} +CIMGUI_API void igImage(ImTextureRef_c tex_ref,const ImVec2_c image_size,const ImVec2_c uv0,const ImVec2_c uv1) +{ + return ImGui::Image(ConvertToCPP_ImTextureRef(tex_ref),ConvertToCPP_ImVec2(image_size),ConvertToCPP_ImVec2(uv0),ConvertToCPP_ImVec2(uv1)); +} +CIMGUI_API void igImageWithBg(ImTextureRef_c tex_ref,const ImVec2_c image_size,const ImVec2_c uv0,const ImVec2_c uv1,const ImVec4_c bg_col,const ImVec4_c tint_col) +{ + return ImGui::ImageWithBg(ConvertToCPP_ImTextureRef(tex_ref),ConvertToCPP_ImVec2(image_size),ConvertToCPP_ImVec2(uv0),ConvertToCPP_ImVec2(uv1),ConvertToCPP_ImVec4(bg_col),ConvertToCPP_ImVec4(tint_col)); +} +CIMGUI_API bool igImageButton(const char* str_id,ImTextureRef_c tex_ref,const ImVec2_c image_size,const ImVec2_c uv0,const ImVec2_c uv1,const ImVec4_c bg_col,const ImVec4_c tint_col) +{ + return ImGui::ImageButton(str_id,ConvertToCPP_ImTextureRef(tex_ref),ConvertToCPP_ImVec2(image_size),ConvertToCPP_ImVec2(uv0),ConvertToCPP_ImVec2(uv1),ConvertToCPP_ImVec4(bg_col),ConvertToCPP_ImVec4(tint_col)); +} +CIMGUI_API bool igBeginCombo(const char* label,const char* preview_value,ImGuiComboFlags flags) +{ + return ImGui::BeginCombo(label,preview_value,flags); +} +CIMGUI_API void igEndCombo() +{ + return ImGui::EndCombo(); +} +CIMGUI_API bool igCombo_Str_arr(const char* label,int* current_item,const char* const items[],int items_count,int popup_max_height_in_items) +{ + return ImGui::Combo(label,current_item,items,items_count,popup_max_height_in_items); +} +CIMGUI_API bool igCombo_Str(const char* label,int* current_item,const char* items_separated_by_zeros,int popup_max_height_in_items) +{ + return ImGui::Combo(label,current_item,items_separated_by_zeros,popup_max_height_in_items); +} +CIMGUI_API bool igCombo_FnStrPtr(const char* label,int* current_item,const char*(*getter)(void* user_data,int idx),void* user_data,int items_count,int popup_max_height_in_items) +{ + return ImGui::Combo(label,current_item,getter,user_data,items_count,popup_max_height_in_items); +} +CIMGUI_API bool igDragFloat(const char* label,float* v,float v_speed,float v_min,float v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::DragFloat(label,v,v_speed,v_min,v_max,format,flags); +} +CIMGUI_API bool igDragFloat2(const char* label,float v[2],float v_speed,float v_min,float v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::DragFloat2(label,v,v_speed,v_min,v_max,format,flags); +} +CIMGUI_API bool igDragFloat3(const char* label,float v[3],float v_speed,float v_min,float v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::DragFloat3(label,v,v_speed,v_min,v_max,format,flags); +} +CIMGUI_API bool igDragFloat4(const char* label,float v[4],float v_speed,float v_min,float v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::DragFloat4(label,v,v_speed,v_min,v_max,format,flags); +} +CIMGUI_API bool igDragFloatRange2(const char* label,float* v_current_min,float* v_current_max,float v_speed,float v_min,float v_max,const char* format,const char* format_max,ImGuiSliderFlags flags) +{ + return ImGui::DragFloatRange2(label,v_current_min,v_current_max,v_speed,v_min,v_max,format,format_max,flags); +} +CIMGUI_API bool igDragInt(const char* label,int* v,float v_speed,int v_min,int v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::DragInt(label,v,v_speed,v_min,v_max,format,flags); +} +CIMGUI_API bool igDragInt2(const char* label,int v[2],float v_speed,int v_min,int v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::DragInt2(label,v,v_speed,v_min,v_max,format,flags); +} +CIMGUI_API bool igDragInt3(const char* label,int v[3],float v_speed,int v_min,int v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::DragInt3(label,v,v_speed,v_min,v_max,format,flags); +} +CIMGUI_API bool igDragInt4(const char* label,int v[4],float v_speed,int v_min,int v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::DragInt4(label,v,v_speed,v_min,v_max,format,flags); +} +CIMGUI_API bool igDragIntRange2(const char* label,int* v_current_min,int* v_current_max,float v_speed,int v_min,int v_max,const char* format,const char* format_max,ImGuiSliderFlags flags) +{ + return ImGui::DragIntRange2(label,v_current_min,v_current_max,v_speed,v_min,v_max,format,format_max,flags); +} +CIMGUI_API bool igDragScalar(const char* label,ImGuiDataType data_type,void* p_data,float v_speed,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::DragScalar(label,data_type,p_data,v_speed,p_min,p_max,format,flags); +} +CIMGUI_API bool igDragScalarN(const char* label,ImGuiDataType data_type,void* p_data,int components,float v_speed,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::DragScalarN(label,data_type,p_data,components,v_speed,p_min,p_max,format,flags); +} +CIMGUI_API bool igSliderFloat(const char* label,float* v,float v_min,float v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::SliderFloat(label,v,v_min,v_max,format,flags); +} +CIMGUI_API bool igSliderFloat2(const char* label,float v[2],float v_min,float v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::SliderFloat2(label,v,v_min,v_max,format,flags); +} +CIMGUI_API bool igSliderFloat3(const char* label,float v[3],float v_min,float v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::SliderFloat3(label,v,v_min,v_max,format,flags); +} +CIMGUI_API bool igSliderFloat4(const char* label,float v[4],float v_min,float v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::SliderFloat4(label,v,v_min,v_max,format,flags); +} +CIMGUI_API bool igSliderAngle(const char* label,float* v_rad,float v_degrees_min,float v_degrees_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::SliderAngle(label,v_rad,v_degrees_min,v_degrees_max,format,flags); +} +CIMGUI_API bool igSliderInt(const char* label,int* v,int v_min,int v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::SliderInt(label,v,v_min,v_max,format,flags); +} +CIMGUI_API bool igSliderInt2(const char* label,int v[2],int v_min,int v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::SliderInt2(label,v,v_min,v_max,format,flags); +} +CIMGUI_API bool igSliderInt3(const char* label,int v[3],int v_min,int v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::SliderInt3(label,v,v_min,v_max,format,flags); +} +CIMGUI_API bool igSliderInt4(const char* label,int v[4],int v_min,int v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::SliderInt4(label,v,v_min,v_max,format,flags); +} +CIMGUI_API bool igSliderScalar(const char* label,ImGuiDataType data_type,void* p_data,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::SliderScalar(label,data_type,p_data,p_min,p_max,format,flags); +} +CIMGUI_API bool igSliderScalarN(const char* label,ImGuiDataType data_type,void* p_data,int components,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::SliderScalarN(label,data_type,p_data,components,p_min,p_max,format,flags); +} +CIMGUI_API bool igVSliderFloat(const char* label,const ImVec2_c size,float* v,float v_min,float v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::VSliderFloat(label,ConvertToCPP_ImVec2(size),v,v_min,v_max,format,flags); +} +CIMGUI_API bool igVSliderInt(const char* label,const ImVec2_c size,int* v,int v_min,int v_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::VSliderInt(label,ConvertToCPP_ImVec2(size),v,v_min,v_max,format,flags); +} +CIMGUI_API bool igVSliderScalar(const char* label,const ImVec2_c size,ImGuiDataType data_type,void* p_data,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::VSliderScalar(label,ConvertToCPP_ImVec2(size),data_type,p_data,p_min,p_max,format,flags); +} +CIMGUI_API bool igInputText(const char* label,char* buf,size_t buf_size,ImGuiInputTextFlags flags,ImGuiInputTextCallback callback,void* user_data) +{ + return ImGui::InputText(label,buf,buf_size,flags,callback,user_data); +} +CIMGUI_API bool igInputTextMultiline(const char* label,char* buf,size_t buf_size,const ImVec2_c size,ImGuiInputTextFlags flags,ImGuiInputTextCallback callback,void* user_data) +{ + return ImGui::InputTextMultiline(label,buf,buf_size,ConvertToCPP_ImVec2(size),flags,callback,user_data); +} +CIMGUI_API bool igInputTextWithHint(const char* label,const char* hint,char* buf,size_t buf_size,ImGuiInputTextFlags flags,ImGuiInputTextCallback callback,void* user_data) +{ + return ImGui::InputTextWithHint(label,hint,buf,buf_size,flags,callback,user_data); +} +CIMGUI_API bool igInputFloat(const char* label,float* v,float step,float step_fast,const char* format,ImGuiInputTextFlags flags) +{ + return ImGui::InputFloat(label,v,step,step_fast,format,flags); +} +CIMGUI_API bool igInputFloat2(const char* label,float v[2],const char* format,ImGuiInputTextFlags flags) +{ + return ImGui::InputFloat2(label,v,format,flags); +} +CIMGUI_API bool igInputFloat3(const char* label,float v[3],const char* format,ImGuiInputTextFlags flags) +{ + return ImGui::InputFloat3(label,v,format,flags); +} +CIMGUI_API bool igInputFloat4(const char* label,float v[4],const char* format,ImGuiInputTextFlags flags) +{ + return ImGui::InputFloat4(label,v,format,flags); +} +CIMGUI_API bool igInputInt(const char* label,int* v,int step,int step_fast,ImGuiInputTextFlags flags) +{ + return ImGui::InputInt(label,v,step,step_fast,flags); +} +CIMGUI_API bool igInputInt2(const char* label,int v[2],ImGuiInputTextFlags flags) +{ + return ImGui::InputInt2(label,v,flags); +} +CIMGUI_API bool igInputInt3(const char* label,int v[3],ImGuiInputTextFlags flags) +{ + return ImGui::InputInt3(label,v,flags); +} +CIMGUI_API bool igInputInt4(const char* label,int v[4],ImGuiInputTextFlags flags) +{ + return ImGui::InputInt4(label,v,flags); +} +CIMGUI_API bool igInputDouble(const char* label,double* v,double step,double step_fast,const char* format,ImGuiInputTextFlags flags) +{ + return ImGui::InputDouble(label,v,step,step_fast,format,flags); +} +CIMGUI_API bool igInputScalar(const char* label,ImGuiDataType data_type,void* p_data,const void* p_step,const void* p_step_fast,const char* format,ImGuiInputTextFlags flags) +{ + return ImGui::InputScalar(label,data_type,p_data,p_step,p_step_fast,format,flags); +} +CIMGUI_API bool igInputScalarN(const char* label,ImGuiDataType data_type,void* p_data,int components,const void* p_step,const void* p_step_fast,const char* format,ImGuiInputTextFlags flags) +{ + return ImGui::InputScalarN(label,data_type,p_data,components,p_step,p_step_fast,format,flags); +} +CIMGUI_API bool igColorEdit3(const char* label,float col[3],ImGuiColorEditFlags flags) +{ + return ImGui::ColorEdit3(label,col,flags); +} +CIMGUI_API bool igColorEdit4(const char* label,float col[4],ImGuiColorEditFlags flags) +{ + return ImGui::ColorEdit4(label,col,flags); +} +CIMGUI_API bool igColorPicker3(const char* label,float col[3],ImGuiColorEditFlags flags) +{ + return ImGui::ColorPicker3(label,col,flags); +} +CIMGUI_API bool igColorPicker4(const char* label,float col[4],ImGuiColorEditFlags flags,const float* ref_col) +{ + return ImGui::ColorPicker4(label,col,flags,ref_col); +} +CIMGUI_API bool igColorButton(const char* desc_id,const ImVec4_c col,ImGuiColorEditFlags flags,const ImVec2_c size) +{ + return ImGui::ColorButton(desc_id,ConvertToCPP_ImVec4(col),flags,ConvertToCPP_ImVec2(size)); +} +CIMGUI_API void igSetColorEditOptions(ImGuiColorEditFlags flags) +{ + return ImGui::SetColorEditOptions(flags); +} +CIMGUI_API bool igTreeNode_Str(const char* label) +{ + return ImGui::TreeNode(label); +} +CIMGUI_API bool igTreeNode_StrStr(const char* str_id,const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + bool ret = ImGui::TreeNodeV(str_id,fmt,args); + va_end(args); + return ret; +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API bool igTreeNode_StrStr0(const char* str_id,const char* fmt) +{ + return igTreeNode_StrStr(str_id,fmt); +} +#endif +CIMGUI_API bool igTreeNode_Ptr(const void* ptr_id,const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + bool ret = ImGui::TreeNodeV(ptr_id,fmt,args); + va_end(args); + return ret; +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API bool igTreeNode_Ptr0(const void* ptr_id,const char* fmt) +{ + return igTreeNode_Ptr(ptr_id,fmt); +} +#endif +CIMGUI_API bool igTreeNodeV_Str(const char* str_id,const char* fmt,va_list args) +{ + return ImGui::TreeNodeV(str_id,fmt,args); +} +CIMGUI_API bool igTreeNodeV_Ptr(const void* ptr_id,const char* fmt,va_list args) +{ + return ImGui::TreeNodeV(ptr_id,fmt,args); +} +CIMGUI_API bool igTreeNodeEx_Str(const char* label,ImGuiTreeNodeFlags flags) +{ + return ImGui::TreeNodeEx(label,flags); +} +CIMGUI_API bool igTreeNodeEx_StrStr(const char* str_id,ImGuiTreeNodeFlags flags,const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + bool ret = ImGui::TreeNodeExV(str_id,flags,fmt,args); + va_end(args); + return ret; +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API bool igTreeNodeEx_StrStr0(const char* str_id,ImGuiTreeNodeFlags flags,const char* fmt) +{ + return igTreeNodeEx_StrStr(str_id,flags,fmt); +} +#endif +CIMGUI_API bool igTreeNodeEx_Ptr(const void* ptr_id,ImGuiTreeNodeFlags flags,const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + bool ret = ImGui::TreeNodeExV(ptr_id,flags,fmt,args); + va_end(args); + return ret; +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API bool igTreeNodeEx_Ptr0(const void* ptr_id,ImGuiTreeNodeFlags flags,const char* fmt) +{ + return igTreeNodeEx_Ptr(ptr_id,flags,fmt); +} +#endif +CIMGUI_API bool igTreeNodeExV_Str(const char* str_id,ImGuiTreeNodeFlags flags,const char* fmt,va_list args) +{ + return ImGui::TreeNodeExV(str_id,flags,fmt,args); +} +CIMGUI_API bool igTreeNodeExV_Ptr(const void* ptr_id,ImGuiTreeNodeFlags flags,const char* fmt,va_list args) +{ + return ImGui::TreeNodeExV(ptr_id,flags,fmt,args); +} +CIMGUI_API void igTreePush_Str(const char* str_id) +{ + return ImGui::TreePush(str_id); +} +CIMGUI_API void igTreePush_Ptr(const void* ptr_id) +{ + return ImGui::TreePush(ptr_id); +} +CIMGUI_API void igTreePop() +{ + return ImGui::TreePop(); +} +CIMGUI_API float igGetTreeNodeToLabelSpacing() +{ + return ImGui::GetTreeNodeToLabelSpacing(); +} +CIMGUI_API bool igCollapsingHeader_TreeNodeFlags(const char* label,ImGuiTreeNodeFlags flags) +{ + return ImGui::CollapsingHeader(label,flags); +} +CIMGUI_API bool igCollapsingHeader_BoolPtr(const char* label,bool* p_visible,ImGuiTreeNodeFlags flags) +{ + return ImGui::CollapsingHeader(label,p_visible,flags); +} +CIMGUI_API void igSetNextItemOpen(bool is_open,ImGuiCond cond) +{ + return ImGui::SetNextItemOpen(is_open,cond); +} +CIMGUI_API void igSetNextItemStorageID(ImGuiID storage_id) +{ + return ImGui::SetNextItemStorageID(storage_id); +} +CIMGUI_API bool igTreeNodeGetOpen(ImGuiID storage_id) +{ + return ImGui::TreeNodeGetOpen(storage_id); +} +CIMGUI_API bool igSelectable_Bool(const char* label,bool selected,ImGuiSelectableFlags flags,const ImVec2_c size) +{ + return ImGui::Selectable(label,selected,flags,ConvertToCPP_ImVec2(size)); +} +CIMGUI_API bool igSelectable_BoolPtr(const char* label,bool* p_selected,ImGuiSelectableFlags flags,const ImVec2_c size) +{ + return ImGui::Selectable(label,p_selected,flags,ConvertToCPP_ImVec2(size)); +} +CIMGUI_API ImGuiMultiSelectIO* igBeginMultiSelect(ImGuiMultiSelectFlags flags,int selection_size,int items_count) +{ + return ImGui::BeginMultiSelect(flags,selection_size,items_count); +} +CIMGUI_API ImGuiMultiSelectIO* igEndMultiSelect() +{ + return ImGui::EndMultiSelect(); +} +CIMGUI_API void igSetNextItemSelectionUserData(ImGuiSelectionUserData selection_user_data) +{ + return ImGui::SetNextItemSelectionUserData(selection_user_data); +} +CIMGUI_API bool igIsItemToggledSelection() +{ + return ImGui::IsItemToggledSelection(); +} +CIMGUI_API bool igBeginListBox(const char* label,const ImVec2_c size) +{ + return ImGui::BeginListBox(label,ConvertToCPP_ImVec2(size)); +} +CIMGUI_API void igEndListBox() +{ + return ImGui::EndListBox(); +} +CIMGUI_API bool igListBox_Str_arr(const char* label,int* current_item,const char* const items[],int items_count,int height_in_items) +{ + return ImGui::ListBox(label,current_item,items,items_count,height_in_items); +} +CIMGUI_API bool igListBox_FnStrPtr(const char* label,int* current_item,const char*(*getter)(void* user_data,int idx),void* user_data,int items_count,int height_in_items) +{ + return ImGui::ListBox(label,current_item,getter,user_data,items_count,height_in_items); +} +CIMGUI_API void igPlotLines_FloatPtr(const char* label,const float* values,int values_count,int values_offset,const char* overlay_text,float scale_min,float scale_max,ImVec2_c graph_size,int stride) +{ + return ImGui::PlotLines(label,values,values_count,values_offset,overlay_text,scale_min,scale_max,ConvertToCPP_ImVec2(graph_size),stride); +} +CIMGUI_API void igPlotLines_FnFloatPtr(const char* label,float(*values_getter)(void* data,int idx),void* data,int values_count,int values_offset,const char* overlay_text,float scale_min,float scale_max,ImVec2_c graph_size) +{ + return ImGui::PlotLines(label,values_getter,data,values_count,values_offset,overlay_text,scale_min,scale_max,ConvertToCPP_ImVec2(graph_size)); +} +CIMGUI_API void igPlotHistogram_FloatPtr(const char* label,const float* values,int values_count,int values_offset,const char* overlay_text,float scale_min,float scale_max,ImVec2_c graph_size,int stride) +{ + return ImGui::PlotHistogram(label,values,values_count,values_offset,overlay_text,scale_min,scale_max,ConvertToCPP_ImVec2(graph_size),stride); +} +CIMGUI_API void igPlotHistogram_FnFloatPtr(const char* label,float(*values_getter)(void* data,int idx),void* data,int values_count,int values_offset,const char* overlay_text,float scale_min,float scale_max,ImVec2_c graph_size) +{ + return ImGui::PlotHistogram(label,values_getter,data,values_count,values_offset,overlay_text,scale_min,scale_max,ConvertToCPP_ImVec2(graph_size)); +} +CIMGUI_API void igValue_Bool(const char* prefix,bool b) +{ + return ImGui::Value(prefix,b); +} +CIMGUI_API void igValue_Int(const char* prefix,int v) +{ + return ImGui::Value(prefix,v); +} +CIMGUI_API void igValue_Uint(const char* prefix,unsigned int v) +{ + return ImGui::Value(prefix,v); +} +CIMGUI_API void igValue_Float(const char* prefix,float v,const char* float_format) +{ + return ImGui::Value(prefix,v,float_format); +} +CIMGUI_API bool igBeginMenuBar() +{ + return ImGui::BeginMenuBar(); +} +CIMGUI_API void igEndMenuBar() +{ + return ImGui::EndMenuBar(); +} +CIMGUI_API bool igBeginMainMenuBar() +{ + return ImGui::BeginMainMenuBar(); +} +CIMGUI_API void igEndMainMenuBar() +{ + return ImGui::EndMainMenuBar(); +} +CIMGUI_API bool igBeginMenu(const char* label,bool enabled) +{ + return ImGui::BeginMenu(label,enabled); +} +CIMGUI_API void igEndMenu() +{ + return ImGui::EndMenu(); +} +CIMGUI_API bool igMenuItem_Bool(const char* label,const char* shortcut,bool selected,bool enabled) +{ + return ImGui::MenuItem(label,shortcut,selected,enabled); +} +CIMGUI_API bool igMenuItem_BoolPtr(const char* label,const char* shortcut,bool* p_selected,bool enabled) +{ + return ImGui::MenuItem(label,shortcut,p_selected,enabled); +} +CIMGUI_API bool igBeginTooltip() +{ + return ImGui::BeginTooltip(); +} +CIMGUI_API void igEndTooltip() +{ + return ImGui::EndTooltip(); +} +CIMGUI_API void igSetTooltip(const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + ImGui::SetTooltipV(fmt,args); + va_end(args); +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igSetTooltip0(const char* fmt) +{ + return igSetTooltip(fmt); +} +#endif +CIMGUI_API void igSetTooltipV(const char* fmt,va_list args) +{ + return ImGui::SetTooltipV(fmt,args); +} +CIMGUI_API bool igBeginItemTooltip() +{ + return ImGui::BeginItemTooltip(); +} +CIMGUI_API void igSetItemTooltip(const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + ImGui::SetItemTooltipV(fmt,args); + va_end(args); +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igSetItemTooltip0(const char* fmt) +{ + return igSetItemTooltip(fmt); +} +#endif +CIMGUI_API void igSetItemTooltipV(const char* fmt,va_list args) +{ + return ImGui::SetItemTooltipV(fmt,args); +} +CIMGUI_API bool igBeginPopup(const char* str_id,ImGuiWindowFlags flags) +{ + return ImGui::BeginPopup(str_id,flags); +} +CIMGUI_API bool igBeginPopupModal(const char* name,bool* p_open,ImGuiWindowFlags flags) +{ + return ImGui::BeginPopupModal(name,p_open,flags); +} +CIMGUI_API void igEndPopup() +{ + return ImGui::EndPopup(); +} +CIMGUI_API void igOpenPopup_Str(const char* str_id,ImGuiPopupFlags popup_flags) +{ + return ImGui::OpenPopup(str_id,popup_flags); +} +CIMGUI_API void igOpenPopup_ID(ImGuiID id,ImGuiPopupFlags popup_flags) +{ + return ImGui::OpenPopup(id,popup_flags); +} +CIMGUI_API void igOpenPopupOnItemClick(const char* str_id,ImGuiPopupFlags popup_flags) +{ + return ImGui::OpenPopupOnItemClick(str_id,popup_flags); +} +CIMGUI_API void igCloseCurrentPopup() +{ + return ImGui::CloseCurrentPopup(); +} +CIMGUI_API bool igBeginPopupContextItem(const char* str_id,ImGuiPopupFlags popup_flags) +{ + return ImGui::BeginPopupContextItem(str_id,popup_flags); +} +CIMGUI_API bool igBeginPopupContextWindow(const char* str_id,ImGuiPopupFlags popup_flags) +{ + return ImGui::BeginPopupContextWindow(str_id,popup_flags); +} +CIMGUI_API bool igBeginPopupContextVoid(const char* str_id,ImGuiPopupFlags popup_flags) +{ + return ImGui::BeginPopupContextVoid(str_id,popup_flags); +} +CIMGUI_API bool igIsPopupOpen_Str(const char* str_id,ImGuiPopupFlags flags) +{ + return ImGui::IsPopupOpen(str_id,flags); +} +CIMGUI_API bool igBeginTable(const char* str_id,int columns,ImGuiTableFlags flags,const ImVec2_c outer_size,float inner_width) +{ + return ImGui::BeginTable(str_id,columns,flags,ConvertToCPP_ImVec2(outer_size),inner_width); +} +CIMGUI_API void igEndTable() +{ + return ImGui::EndTable(); +} +CIMGUI_API void igTableNextRow(ImGuiTableRowFlags row_flags,float min_row_height) +{ + return ImGui::TableNextRow(row_flags,min_row_height); +} +CIMGUI_API bool igTableNextColumn() +{ + return ImGui::TableNextColumn(); +} +CIMGUI_API bool igTableSetColumnIndex(int column_n) +{ + return ImGui::TableSetColumnIndex(column_n); +} +CIMGUI_API void igTableSetupColumn(const char* label,ImGuiTableColumnFlags flags,float init_width_or_weight,ImGuiID user_data) +{ + return ImGui::TableSetupColumn(label,flags,init_width_or_weight,user_data); +} +CIMGUI_API void igTableSetupScrollFreeze(int cols,int rows) +{ + return ImGui::TableSetupScrollFreeze(cols,rows); +} +CIMGUI_API void igTableHeader(const char* label) +{ + return ImGui::TableHeader(label); +} +CIMGUI_API void igTableHeadersRow() +{ + return ImGui::TableHeadersRow(); +} +CIMGUI_API void igTableAngledHeadersRow() +{ + return ImGui::TableAngledHeadersRow(); +} +CIMGUI_API ImGuiTableSortSpecs* igTableGetSortSpecs() +{ + return ImGui::TableGetSortSpecs(); +} +CIMGUI_API int igTableGetColumnCount() +{ + return ImGui::TableGetColumnCount(); +} +CIMGUI_API int igTableGetColumnIndex() +{ + return ImGui::TableGetColumnIndex(); +} +CIMGUI_API int igTableGetRowIndex() +{ + return ImGui::TableGetRowIndex(); +} +CIMGUI_API const char* igTableGetColumnName_Int(int column_n) +{ + return ImGui::TableGetColumnName(column_n); +} +CIMGUI_API ImGuiTableColumnFlags igTableGetColumnFlags(int column_n) +{ + return ImGui::TableGetColumnFlags(column_n); +} +CIMGUI_API void igTableSetColumnEnabled(int column_n,bool v) +{ + return ImGui::TableSetColumnEnabled(column_n,v); +} +CIMGUI_API int igTableGetHoveredColumn() +{ + return ImGui::TableGetHoveredColumn(); +} +CIMGUI_API void igTableSetBgColor(ImGuiTableBgTarget target,ImU32 color,int column_n) +{ + return ImGui::TableSetBgColor(target,color,column_n); +} +CIMGUI_API void igColumns(int count,const char* id,bool borders) +{ + return ImGui::Columns(count,id,borders); +} +CIMGUI_API void igNextColumn() +{ + return ImGui::NextColumn(); +} +CIMGUI_API int igGetColumnIndex() +{ + return ImGui::GetColumnIndex(); +} +CIMGUI_API float igGetColumnWidth(int column_index) +{ + return ImGui::GetColumnWidth(column_index); +} +CIMGUI_API void igSetColumnWidth(int column_index,float width) +{ + return ImGui::SetColumnWidth(column_index,width); +} +CIMGUI_API float igGetColumnOffset(int column_index) +{ + return ImGui::GetColumnOffset(column_index); +} +CIMGUI_API void igSetColumnOffset(int column_index,float offset_x) +{ + return ImGui::SetColumnOffset(column_index,offset_x); +} +CIMGUI_API int igGetColumnsCount() +{ + return ImGui::GetColumnsCount(); +} +CIMGUI_API bool igBeginTabBar(const char* str_id,ImGuiTabBarFlags flags) +{ + return ImGui::BeginTabBar(str_id,flags); +} +CIMGUI_API void igEndTabBar() +{ + return ImGui::EndTabBar(); +} +CIMGUI_API bool igBeginTabItem(const char* label,bool* p_open,ImGuiTabItemFlags flags) +{ + return ImGui::BeginTabItem(label,p_open,flags); +} +CIMGUI_API void igEndTabItem() +{ + return ImGui::EndTabItem(); +} +CIMGUI_API bool igTabItemButton(const char* label,ImGuiTabItemFlags flags) +{ + return ImGui::TabItemButton(label,flags); +} +CIMGUI_API void igSetTabItemClosed(const char* tab_or_docked_window_label) +{ + return ImGui::SetTabItemClosed(tab_or_docked_window_label); +} +CIMGUI_API void igLogToTTY(int auto_open_depth) +{ + return ImGui::LogToTTY(auto_open_depth); +} +CIMGUI_API void igLogToFile(int auto_open_depth,const char* filename) +{ + return ImGui::LogToFile(auto_open_depth,filename); +} +CIMGUI_API void igLogToClipboard(int auto_open_depth) +{ + return ImGui::LogToClipboard(auto_open_depth); +} +CIMGUI_API void igLogFinish() +{ + return ImGui::LogFinish(); +} +CIMGUI_API void igLogButtons() +{ + return ImGui::LogButtons(); +} +CIMGUI_API void igLogText(const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + ImGui::LogTextV(fmt,args); + va_end(args); +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igLogText0(const char* fmt) +{ + return igLogText(fmt); +} +#endif +CIMGUI_API void igLogTextV(const char* fmt,va_list args) +{ + return ImGui::LogTextV(fmt,args); +} +CIMGUI_API bool igBeginDragDropSource(ImGuiDragDropFlags flags) +{ + return ImGui::BeginDragDropSource(flags); +} +CIMGUI_API bool igSetDragDropPayload(const char* type,const void* data,size_t sz,ImGuiCond cond) +{ + return ImGui::SetDragDropPayload(type,data,sz,cond); +} +CIMGUI_API void igEndDragDropSource() +{ + return ImGui::EndDragDropSource(); +} +CIMGUI_API bool igBeginDragDropTarget() +{ + return ImGui::BeginDragDropTarget(); +} +CIMGUI_API const ImGuiPayload* igAcceptDragDropPayload(const char* type,ImGuiDragDropFlags flags) +{ + return ImGui::AcceptDragDropPayload(type,flags); +} +CIMGUI_API void igEndDragDropTarget() +{ + return ImGui::EndDragDropTarget(); +} +CIMGUI_API const ImGuiPayload* igGetDragDropPayload() +{ + return ImGui::GetDragDropPayload(); +} +CIMGUI_API void igBeginDisabled(bool disabled) +{ + return ImGui::BeginDisabled(disabled); +} +CIMGUI_API void igEndDisabled() +{ + return ImGui::EndDisabled(); +} +CIMGUI_API void igPushClipRect(const ImVec2_c clip_rect_min,const ImVec2_c clip_rect_max,bool intersect_with_current_clip_rect) +{ + return ImGui::PushClipRect(ConvertToCPP_ImVec2(clip_rect_min),ConvertToCPP_ImVec2(clip_rect_max),intersect_with_current_clip_rect); +} +CIMGUI_API void igPopClipRect() +{ + return ImGui::PopClipRect(); +} +CIMGUI_API void igSetItemDefaultFocus() +{ + return ImGui::SetItemDefaultFocus(); +} +CIMGUI_API void igSetKeyboardFocusHere(int offset) +{ + return ImGui::SetKeyboardFocusHere(offset); +} +CIMGUI_API void igSetNavCursorVisible(bool visible) +{ + return ImGui::SetNavCursorVisible(visible); +} +CIMGUI_API void igSetNextItemAllowOverlap() +{ + return ImGui::SetNextItemAllowOverlap(); +} +CIMGUI_API bool igIsItemHovered(ImGuiHoveredFlags flags) +{ + return ImGui::IsItemHovered(flags); +} +CIMGUI_API bool igIsItemActive() +{ + return ImGui::IsItemActive(); +} +CIMGUI_API bool igIsItemFocused() +{ + return ImGui::IsItemFocused(); +} +CIMGUI_API bool igIsItemClicked(ImGuiMouseButton mouse_button) +{ + return ImGui::IsItemClicked(mouse_button); +} +CIMGUI_API bool igIsItemVisible() +{ + return ImGui::IsItemVisible(); +} +CIMGUI_API bool igIsItemEdited() +{ + return ImGui::IsItemEdited(); +} +CIMGUI_API bool igIsItemActivated() +{ + return ImGui::IsItemActivated(); +} +CIMGUI_API bool igIsItemDeactivated() +{ + return ImGui::IsItemDeactivated(); +} +CIMGUI_API bool igIsItemDeactivatedAfterEdit() +{ + return ImGui::IsItemDeactivatedAfterEdit(); +} +CIMGUI_API bool igIsItemToggledOpen() +{ + return ImGui::IsItemToggledOpen(); +} +CIMGUI_API bool igIsAnyItemHovered() +{ + return ImGui::IsAnyItemHovered(); +} +CIMGUI_API bool igIsAnyItemActive() +{ + return ImGui::IsAnyItemActive(); +} +CIMGUI_API bool igIsAnyItemFocused() +{ + return ImGui::IsAnyItemFocused(); +} +CIMGUI_API ImGuiID igGetItemID() +{ + return ImGui::GetItemID(); +} +CIMGUI_API ImVec2_c igGetItemRectMin() +{ + return ConvertFromCPP_ImVec2(ImGui::GetItemRectMin()); +} +CIMGUI_API ImVec2_c igGetItemRectMax() +{ + return ConvertFromCPP_ImVec2(ImGui::GetItemRectMax()); +} +CIMGUI_API ImVec2_c igGetItemRectSize() +{ + return ConvertFromCPP_ImVec2(ImGui::GetItemRectSize()); +} +CIMGUI_API ImGuiItemFlags igGetItemFlags() +{ + return ImGui::GetItemFlags(); +} +CIMGUI_API ImGuiViewport* igGetMainViewport() +{ + return ImGui::GetMainViewport(); +} +CIMGUI_API ImDrawList* igGetBackgroundDrawList_Nil() +{ + return ImGui::GetBackgroundDrawList(); +} +CIMGUI_API ImDrawList* igGetForegroundDrawList_Nil() +{ + return ImGui::GetForegroundDrawList(); +} +CIMGUI_API bool igIsRectVisible_Nil(const ImVec2_c size) +{ + return ImGui::IsRectVisible(ConvertToCPP_ImVec2(size)); +} +CIMGUI_API bool igIsRectVisible_Vec2(const ImVec2_c rect_min,const ImVec2_c rect_max) +{ + return ImGui::IsRectVisible(ConvertToCPP_ImVec2(rect_min),ConvertToCPP_ImVec2(rect_max)); +} +CIMGUI_API double igGetTime() +{ + return ImGui::GetTime(); +} +CIMGUI_API int igGetFrameCount() +{ + return ImGui::GetFrameCount(); +} +CIMGUI_API ImDrawListSharedData* igGetDrawListSharedData() +{ + return ImGui::GetDrawListSharedData(); +} +CIMGUI_API const char* igGetStyleColorName(ImGuiCol idx) +{ + return ImGui::GetStyleColorName(idx); +} +CIMGUI_API void igSetStateStorage(ImGuiStorage* storage) +{ + return ImGui::SetStateStorage(storage); +} +CIMGUI_API ImGuiStorage* igGetStateStorage() +{ + return ImGui::GetStateStorage(); +} +CIMGUI_API ImVec2_c igCalcTextSize(const char* text,const char* text_end,bool hide_text_after_double_hash,float wrap_width) +{ + return ConvertFromCPP_ImVec2(ImGui::CalcTextSize(text,text_end,hide_text_after_double_hash,wrap_width)); +} +CIMGUI_API ImVec4_c igColorConvertU32ToFloat4(ImU32 in) +{ + return ConvertFromCPP_ImVec4(ImGui::ColorConvertU32ToFloat4(in)); +} +CIMGUI_API ImU32 igColorConvertFloat4ToU32(const ImVec4_c in) +{ + return ImGui::ColorConvertFloat4ToU32(ConvertToCPP_ImVec4(in)); +} +CIMGUI_API void igColorConvertRGBtoHSV(float r,float g,float b,float* out_h,float* out_s,float* out_v) +{ + return ImGui::ColorConvertRGBtoHSV(r,g,b,*out_h,*out_s,*out_v); +} +CIMGUI_API void igColorConvertHSVtoRGB(float h,float s,float v,float* out_r,float* out_g,float* out_b) +{ + return ImGui::ColorConvertHSVtoRGB(h,s,v,*out_r,*out_g,*out_b); +} +CIMGUI_API bool igIsKeyDown_Nil(ImGuiKey key) +{ + return ImGui::IsKeyDown(key); +} +CIMGUI_API bool igIsKeyPressed_Bool(ImGuiKey key,bool repeat) +{ + return ImGui::IsKeyPressed(key,repeat); +} +CIMGUI_API bool igIsKeyReleased_Nil(ImGuiKey key) +{ + return ImGui::IsKeyReleased(key); +} +CIMGUI_API bool igIsKeyChordPressed_Nil(ImGuiKeyChord key_chord) +{ + return ImGui::IsKeyChordPressed(key_chord); +} +CIMGUI_API int igGetKeyPressedAmount(ImGuiKey key,float repeat_delay,float rate) +{ + return ImGui::GetKeyPressedAmount(key,repeat_delay,rate); +} +CIMGUI_API const char* igGetKeyName(ImGuiKey key) +{ + return ImGui::GetKeyName(key); +} +CIMGUI_API void igSetNextFrameWantCaptureKeyboard(bool want_capture_keyboard) +{ + return ImGui::SetNextFrameWantCaptureKeyboard(want_capture_keyboard); +} +CIMGUI_API bool igShortcut_Nil(ImGuiKeyChord key_chord,ImGuiInputFlags flags) +{ + return ImGui::Shortcut(key_chord,flags); +} +CIMGUI_API void igSetNextItemShortcut(ImGuiKeyChord key_chord,ImGuiInputFlags flags) +{ + return ImGui::SetNextItemShortcut(key_chord,flags); +} +CIMGUI_API bool igSetItemKeyOwner_Nil(ImGuiKey key) +{ + return ImGui::SetItemKeyOwner(key); +} +CIMGUI_API bool igIsMouseDown_Nil(ImGuiMouseButton button) +{ + return ImGui::IsMouseDown(button); +} +CIMGUI_API bool igIsMouseClicked_Bool(ImGuiMouseButton button,bool repeat) +{ + return ImGui::IsMouseClicked(button,repeat); +} +CIMGUI_API bool igIsMouseReleased_Nil(ImGuiMouseButton button) +{ + return ImGui::IsMouseReleased(button); +} +CIMGUI_API bool igIsMouseDoubleClicked_Nil(ImGuiMouseButton button) +{ + return ImGui::IsMouseDoubleClicked(button); +} +CIMGUI_API bool igIsMouseReleasedWithDelay(ImGuiMouseButton button,float delay) +{ + return ImGui::IsMouseReleasedWithDelay(button,delay); +} +CIMGUI_API int igGetMouseClickedCount(ImGuiMouseButton button) +{ + return ImGui::GetMouseClickedCount(button); +} +CIMGUI_API bool igIsMouseHoveringRect(const ImVec2_c r_min,const ImVec2_c r_max,bool clip) +{ + return ImGui::IsMouseHoveringRect(ConvertToCPP_ImVec2(r_min),ConvertToCPP_ImVec2(r_max),clip); +} +CIMGUI_API bool igIsMousePosValid(const ImVec2_c* mouse_pos) +{ + return ImGui::IsMousePosValid(reinterpret_cast(mouse_pos)); +} +CIMGUI_API bool igIsAnyMouseDown() +{ + return ImGui::IsAnyMouseDown(); +} +CIMGUI_API ImVec2_c igGetMousePos() +{ + return ConvertFromCPP_ImVec2(ImGui::GetMousePos()); +} +CIMGUI_API ImVec2_c igGetMousePosOnOpeningCurrentPopup() +{ + return ConvertFromCPP_ImVec2(ImGui::GetMousePosOnOpeningCurrentPopup()); +} +CIMGUI_API bool igIsMouseDragging(ImGuiMouseButton button,float lock_threshold) +{ + return ImGui::IsMouseDragging(button,lock_threshold); +} +CIMGUI_API ImVec2_c igGetMouseDragDelta(ImGuiMouseButton button,float lock_threshold) +{ + return ConvertFromCPP_ImVec2(ImGui::GetMouseDragDelta(button,lock_threshold)); +} +CIMGUI_API void igResetMouseDragDelta(ImGuiMouseButton button) +{ + return ImGui::ResetMouseDragDelta(button); +} +CIMGUI_API ImGuiMouseCursor igGetMouseCursor() +{ + return ImGui::GetMouseCursor(); +} +CIMGUI_API void igSetMouseCursor(ImGuiMouseCursor cursor_type) +{ + return ImGui::SetMouseCursor(cursor_type); +} +CIMGUI_API void igSetNextFrameWantCaptureMouse(bool want_capture_mouse) +{ + return ImGui::SetNextFrameWantCaptureMouse(want_capture_mouse); +} +CIMGUI_API const char* igGetClipboardText() +{ + return ImGui::GetClipboardText(); +} +CIMGUI_API void igSetClipboardText(const char* text) +{ + return ImGui::SetClipboardText(text); +} +CIMGUI_API void igLoadIniSettingsFromDisk(const char* ini_filename) +{ + return ImGui::LoadIniSettingsFromDisk(ini_filename); +} +CIMGUI_API void igLoadIniSettingsFromMemory(const char* ini_data,size_t ini_size) +{ + return ImGui::LoadIniSettingsFromMemory(ini_data,ini_size); +} +CIMGUI_API void igSaveIniSettingsToDisk(const char* ini_filename) +{ + return ImGui::SaveIniSettingsToDisk(ini_filename); +} +CIMGUI_API const char* igSaveIniSettingsToMemory(size_t* out_ini_size) +{ + return ImGui::SaveIniSettingsToMemory(out_ini_size); +} +CIMGUI_API void igDebugStartItemPicker() +{ + return ImGui::DebugStartItemPicker(); +} +CIMGUI_API bool igDebugCheckVersionAndDataLayout(const char* version_str,size_t sz_io,size_t sz_style,size_t sz_vec2,size_t sz_vec4,size_t sz_drawvert,size_t sz_drawidx) +{ + return ImGui::DebugCheckVersionAndDataLayout(version_str,sz_io,sz_style,sz_vec2,sz_vec4,sz_drawvert,sz_drawidx); +} +CIMGUI_API void igSetAllocatorFunctions(ImGuiMemAllocFunc alloc_func,ImGuiMemFreeFunc free_func,void* user_data) +{ + return ImGui::SetAllocatorFunctions(alloc_func,free_func,user_data); +} +CIMGUI_API void igGetAllocatorFunctions(ImGuiMemAllocFunc* p_alloc_func,ImGuiMemFreeFunc* p_free_func,void** p_user_data) +{ + return ImGui::GetAllocatorFunctions(p_alloc_func,p_free_func,p_user_data); +} +CIMGUI_API void* igMemAlloc(size_t size) +{ + return ImGui::MemAlloc(size); +} +CIMGUI_API void igMemFree(void* ptr) +{ + return ImGui::MemFree(ptr); +} +CIMGUI_API ImGuiTableSortSpecs* ImGuiTableSortSpecs_ImGuiTableSortSpecs(void) +{ + return IM_NEW(ImGuiTableSortSpecs)(); +} +CIMGUI_API void ImGuiTableSortSpecs_destroy(ImGuiTableSortSpecs* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiTableColumnSortSpecs* ImGuiTableColumnSortSpecs_ImGuiTableColumnSortSpecs(void) +{ + return IM_NEW(ImGuiTableColumnSortSpecs)(); +} +CIMGUI_API void ImGuiTableColumnSortSpecs_destroy(ImGuiTableColumnSortSpecs* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiStyle* ImGuiStyle_ImGuiStyle(void) +{ + return IM_NEW(ImGuiStyle)(); +} +CIMGUI_API void ImGuiStyle_destroy(ImGuiStyle* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiStyle_ScaleAllSizes(ImGuiStyle* self,float scale_factor) +{ + return self->ScaleAllSizes(scale_factor); +} +CIMGUI_API void ImGuiIO_AddKeyEvent(ImGuiIO* self,ImGuiKey key,bool down) +{ + return self->AddKeyEvent(key,down); +} +CIMGUI_API void ImGuiIO_AddKeyAnalogEvent(ImGuiIO* self,ImGuiKey key,bool down,float v) +{ + return self->AddKeyAnalogEvent(key,down,v); +} +CIMGUI_API void ImGuiIO_AddMousePosEvent(ImGuiIO* self,float x,float y) +{ + return self->AddMousePosEvent(x,y); +} +CIMGUI_API void ImGuiIO_AddMouseButtonEvent(ImGuiIO* self,int button,bool down) +{ + return self->AddMouseButtonEvent(button,down); +} +CIMGUI_API void ImGuiIO_AddMouseWheelEvent(ImGuiIO* self,float wheel_x,float wheel_y) +{ + return self->AddMouseWheelEvent(wheel_x,wheel_y); +} +CIMGUI_API void ImGuiIO_AddMouseSourceEvent(ImGuiIO* self,ImGuiMouseSource source) +{ + return self->AddMouseSourceEvent(source); +} +CIMGUI_API void ImGuiIO_AddFocusEvent(ImGuiIO* self,bool focused) +{ + return self->AddFocusEvent(focused); +} +CIMGUI_API void ImGuiIO_AddInputCharacter(ImGuiIO* self,unsigned int c) +{ + return self->AddInputCharacter(c); +} +CIMGUI_API void ImGuiIO_AddInputCharacterUTF16(ImGuiIO* self,ImWchar16 c) +{ + return self->AddInputCharacterUTF16(c); +} +CIMGUI_API void ImGuiIO_AddInputCharactersUTF8(ImGuiIO* self,const char* str) +{ + return self->AddInputCharactersUTF8(str); +} +CIMGUI_API void ImGuiIO_SetKeyEventNativeData(ImGuiIO* self,ImGuiKey key,int native_keycode,int native_scancode,int native_legacy_index) +{ + return self->SetKeyEventNativeData(key,native_keycode,native_scancode,native_legacy_index); +} +CIMGUI_API void ImGuiIO_SetAppAcceptingEvents(ImGuiIO* self,bool accepting_events) +{ + return self->SetAppAcceptingEvents(accepting_events); +} +CIMGUI_API void ImGuiIO_ClearEventsQueue(ImGuiIO* self) +{ + return self->ClearEventsQueue(); +} +CIMGUI_API void ImGuiIO_ClearInputKeys(ImGuiIO* self) +{ + return self->ClearInputKeys(); +} +CIMGUI_API void ImGuiIO_ClearInputMouse(ImGuiIO* self) +{ + return self->ClearInputMouse(); +} +CIMGUI_API ImGuiIO* ImGuiIO_ImGuiIO(void) +{ + return IM_NEW(ImGuiIO)(); +} +CIMGUI_API void ImGuiIO_destroy(ImGuiIO* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiInputTextCallbackData* ImGuiInputTextCallbackData_ImGuiInputTextCallbackData(void) +{ + return IM_NEW(ImGuiInputTextCallbackData)(); +} +CIMGUI_API void ImGuiInputTextCallbackData_destroy(ImGuiInputTextCallbackData* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiInputTextCallbackData_DeleteChars(ImGuiInputTextCallbackData* self,int pos,int bytes_count) +{ + return self->DeleteChars(pos,bytes_count); +} +CIMGUI_API void ImGuiInputTextCallbackData_InsertChars(ImGuiInputTextCallbackData* self,int pos,const char* text,const char* text_end) +{ + return self->InsertChars(pos,text,text_end); +} +CIMGUI_API void ImGuiInputTextCallbackData_SelectAll(ImGuiInputTextCallbackData* self) +{ + return self->SelectAll(); +} +CIMGUI_API void ImGuiInputTextCallbackData_SetSelection(ImGuiInputTextCallbackData* self,int s,int e) +{ + return self->SetSelection(s,e); +} +CIMGUI_API void ImGuiInputTextCallbackData_ClearSelection(ImGuiInputTextCallbackData* self) +{ + return self->ClearSelection(); +} +CIMGUI_API bool ImGuiInputTextCallbackData_HasSelection(ImGuiInputTextCallbackData* self) +{ + return self->HasSelection(); +} +CIMGUI_API ImGuiPayload* ImGuiPayload_ImGuiPayload(void) +{ + return IM_NEW(ImGuiPayload)(); +} +CIMGUI_API void ImGuiPayload_destroy(ImGuiPayload* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiPayload_Clear(ImGuiPayload* self) +{ + return self->Clear(); +} +CIMGUI_API bool ImGuiPayload_IsDataType(ImGuiPayload* self,const char* type) +{ + return self->IsDataType(type); +} +CIMGUI_API bool ImGuiPayload_IsPreview(ImGuiPayload* self) +{ + return self->IsPreview(); +} +CIMGUI_API bool ImGuiPayload_IsDelivery(ImGuiPayload* self) +{ + return self->IsDelivery(); +} +CIMGUI_API ImGuiOnceUponAFrame* ImGuiOnceUponAFrame_ImGuiOnceUponAFrame(void) +{ + return IM_NEW(ImGuiOnceUponAFrame)(); +} +CIMGUI_API void ImGuiOnceUponAFrame_destroy(ImGuiOnceUponAFrame* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiTextFilter* ImGuiTextFilter_ImGuiTextFilter(const char* default_filter) +{ + return IM_NEW(ImGuiTextFilter)(default_filter); +} +CIMGUI_API void ImGuiTextFilter_destroy(ImGuiTextFilter* self) +{ + IM_DELETE(self); +} +CIMGUI_API bool ImGuiTextFilter_Draw(ImGuiTextFilter* self,const char* label,float width) +{ + return self->Draw(label,width); +} +CIMGUI_API bool ImGuiTextFilter_PassFilter(ImGuiTextFilter* self,const char* text,const char* text_end) +{ + return self->PassFilter(text,text_end); +} +CIMGUI_API void ImGuiTextFilter_Build(ImGuiTextFilter* self) +{ + return self->Build(); +} +CIMGUI_API void ImGuiTextFilter_Clear(ImGuiTextFilter* self) +{ + return self->Clear(); +} +CIMGUI_API bool ImGuiTextFilter_IsActive(ImGuiTextFilter* self) +{ + return self->IsActive(); +} +CIMGUI_API ImGuiTextRange* ImGuiTextRange_ImGuiTextRange_Nil(void) +{ + return IM_NEW(ImGuiTextRange)(); +} +CIMGUI_API void ImGuiTextRange_destroy(ImGuiTextRange* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiTextRange* ImGuiTextRange_ImGuiTextRange_Str(const char* _b,const char* _e) +{ + return IM_NEW(ImGuiTextRange)(_b,_e); +} +CIMGUI_API bool ImGuiTextRange_empty(ImGuiTextRange* self) +{ + return self->empty(); +} +CIMGUI_API void ImGuiTextRange_split(ImGuiTextRange* self,char separator,ImVector_ImGuiTextRange* out) +{ + return self->split(separator,out); +} +CIMGUI_API ImGuiTextBuffer* ImGuiTextBuffer_ImGuiTextBuffer(void) +{ + return IM_NEW(ImGuiTextBuffer)(); +} +CIMGUI_API void ImGuiTextBuffer_destroy(ImGuiTextBuffer* self) +{ + IM_DELETE(self); +} +CIMGUI_API const char* ImGuiTextBuffer_begin(ImGuiTextBuffer* self) +{ + return self->begin(); +} +CIMGUI_API const char* ImGuiTextBuffer_end(ImGuiTextBuffer* self) +{ + return self->end(); +} +CIMGUI_API int ImGuiTextBuffer_size(ImGuiTextBuffer* self) +{ + return self->size(); +} +CIMGUI_API bool ImGuiTextBuffer_empty(ImGuiTextBuffer* self) +{ + return self->empty(); +} +CIMGUI_API void ImGuiTextBuffer_clear(ImGuiTextBuffer* self) +{ + return self->clear(); +} +CIMGUI_API void ImGuiTextBuffer_resize(ImGuiTextBuffer* self,int size) +{ + return self->resize(size); +} +CIMGUI_API void ImGuiTextBuffer_reserve(ImGuiTextBuffer* self,int capacity) +{ + return self->reserve(capacity); +} +CIMGUI_API const char* ImGuiTextBuffer_c_str(ImGuiTextBuffer* self) +{ + return self->c_str(); +} +CIMGUI_API void ImGuiTextBuffer_append(ImGuiTextBuffer* self,const char* str,const char* str_end) +{ + return self->append(str,str_end); +} +CIMGUI_API void ImGuiTextBuffer_appendfv(ImGuiTextBuffer* self,const char* fmt,va_list args) +{ + return self->appendfv(fmt,args); +} +CIMGUI_API ImGuiStoragePair* ImGuiStoragePair_ImGuiStoragePair_Int(ImGuiID _key,int _val) +{ + return IM_NEW(ImGuiStoragePair)(_key,_val); +} +CIMGUI_API void ImGuiStoragePair_destroy(ImGuiStoragePair* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiStoragePair* ImGuiStoragePair_ImGuiStoragePair_Float(ImGuiID _key,float _val) +{ + return IM_NEW(ImGuiStoragePair)(_key,_val); +} +CIMGUI_API ImGuiStoragePair* ImGuiStoragePair_ImGuiStoragePair_Ptr(ImGuiID _key,void* _val) +{ + return IM_NEW(ImGuiStoragePair)(_key,_val); +} +CIMGUI_API void ImGuiStorage_Clear(ImGuiStorage* self) +{ + return self->Clear(); +} +CIMGUI_API int ImGuiStorage_GetInt(ImGuiStorage* self,ImGuiID key,int default_val) +{ + return self->GetInt(key,default_val); +} +CIMGUI_API void ImGuiStorage_SetInt(ImGuiStorage* self,ImGuiID key,int val) +{ + return self->SetInt(key,val); +} +CIMGUI_API bool ImGuiStorage_GetBool(ImGuiStorage* self,ImGuiID key,bool default_val) +{ + return self->GetBool(key,default_val); +} +CIMGUI_API void ImGuiStorage_SetBool(ImGuiStorage* self,ImGuiID key,bool val) +{ + return self->SetBool(key,val); +} +CIMGUI_API float ImGuiStorage_GetFloat(ImGuiStorage* self,ImGuiID key,float default_val) +{ + return self->GetFloat(key,default_val); +} +CIMGUI_API void ImGuiStorage_SetFloat(ImGuiStorage* self,ImGuiID key,float val) +{ + return self->SetFloat(key,val); +} +CIMGUI_API void* ImGuiStorage_GetVoidPtr(ImGuiStorage* self,ImGuiID key) +{ + return self->GetVoidPtr(key); +} +CIMGUI_API void ImGuiStorage_SetVoidPtr(ImGuiStorage* self,ImGuiID key,void* val) +{ + return self->SetVoidPtr(key,val); +} +CIMGUI_API int* ImGuiStorage_GetIntRef(ImGuiStorage* self,ImGuiID key,int default_val) +{ + return self->GetIntRef(key,default_val); +} +CIMGUI_API bool* ImGuiStorage_GetBoolRef(ImGuiStorage* self,ImGuiID key,bool default_val) +{ + return self->GetBoolRef(key,default_val); +} +CIMGUI_API float* ImGuiStorage_GetFloatRef(ImGuiStorage* self,ImGuiID key,float default_val) +{ + return self->GetFloatRef(key,default_val); +} +CIMGUI_API void** ImGuiStorage_GetVoidPtrRef(ImGuiStorage* self,ImGuiID key,void* default_val) +{ + return self->GetVoidPtrRef(key,default_val); +} +CIMGUI_API void ImGuiStorage_BuildSortByKey(ImGuiStorage* self) +{ + return self->BuildSortByKey(); +} +CIMGUI_API void ImGuiStorage_SetAllInt(ImGuiStorage* self,int val) +{ + return self->SetAllInt(val); +} +CIMGUI_API ImGuiListClipper* ImGuiListClipper_ImGuiListClipper(void) +{ + return IM_NEW(ImGuiListClipper)(); +} +CIMGUI_API void ImGuiListClipper_destroy(ImGuiListClipper* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiListClipper_Begin(ImGuiListClipper* self,int items_count,float items_height) +{ + return self->Begin(items_count,items_height); +} +CIMGUI_API void ImGuiListClipper_End(ImGuiListClipper* self) +{ + return self->End(); +} +CIMGUI_API bool ImGuiListClipper_Step(ImGuiListClipper* self) +{ + return self->Step(); +} +CIMGUI_API void ImGuiListClipper_IncludeItemByIndex(ImGuiListClipper* self,int item_index) +{ + return self->IncludeItemByIndex(item_index); +} +CIMGUI_API void ImGuiListClipper_IncludeItemsByIndex(ImGuiListClipper* self,int item_begin,int item_end) +{ + return self->IncludeItemsByIndex(item_begin,item_end); +} +CIMGUI_API void ImGuiListClipper_SeekCursorForItem(ImGuiListClipper* self,int item_index) +{ + return self->SeekCursorForItem(item_index); +} +CIMGUI_API ImColor* ImColor_ImColor_Nil(void) +{ + return IM_NEW(ImColor)(); +} +CIMGUI_API void ImColor_destroy(ImColor* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImColor* ImColor_ImColor_Float(float r,float g,float b,float a) +{ + return IM_NEW(ImColor)(r,g,b,a); +} +CIMGUI_API ImColor* ImColor_ImColor_Vec4(const ImVec4_c col) +{ + return IM_NEW(ImColor)(ConvertToCPP_ImVec4(col)); +} +CIMGUI_API ImColor* ImColor_ImColor_Int(int r,int g,int b,int a) +{ + return IM_NEW(ImColor)(r,g,b,a); +} +CIMGUI_API ImColor* ImColor_ImColor_U32(ImU32 rgba) +{ + return IM_NEW(ImColor)(rgba); +} +CIMGUI_API void ImColor_SetHSV(ImColor* self,float h,float s,float v,float a) +{ + return self->SetHSV(h,s,v,a); +} +CIMGUI_API ImColor_c ImColor_HSV(float h,float s,float v,float a) +{ + return ConvertFromCPP_ImColor(ImColor::HSV(h,s,v,a)); +} +CIMGUI_API ImGuiSelectionBasicStorage* ImGuiSelectionBasicStorage_ImGuiSelectionBasicStorage(void) +{ + return IM_NEW(ImGuiSelectionBasicStorage)(); +} +CIMGUI_API void ImGuiSelectionBasicStorage_destroy(ImGuiSelectionBasicStorage* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiSelectionBasicStorage_ApplyRequests(ImGuiSelectionBasicStorage* self,ImGuiMultiSelectIO* ms_io) +{ + return self->ApplyRequests(ms_io); +} +CIMGUI_API bool ImGuiSelectionBasicStorage_Contains(ImGuiSelectionBasicStorage* self,ImGuiID id) +{ + return self->Contains(id); +} +CIMGUI_API void ImGuiSelectionBasicStorage_Clear(ImGuiSelectionBasicStorage* self) +{ + return self->Clear(); +} +CIMGUI_API void ImGuiSelectionBasicStorage_Swap(ImGuiSelectionBasicStorage* self,ImGuiSelectionBasicStorage* r) +{ + return self->Swap(*r); +} +CIMGUI_API void ImGuiSelectionBasicStorage_SetItemSelected(ImGuiSelectionBasicStorage* self,ImGuiID id,bool selected) +{ + return self->SetItemSelected(id,selected); +} +CIMGUI_API bool ImGuiSelectionBasicStorage_GetNextSelectedItem(ImGuiSelectionBasicStorage* self,void** opaque_it,ImGuiID* out_id) +{ + return self->GetNextSelectedItem(opaque_it,out_id); +} +CIMGUI_API ImGuiID ImGuiSelectionBasicStorage_GetStorageIdFromIndex(ImGuiSelectionBasicStorage* self,int idx) +{ + return self->GetStorageIdFromIndex(idx); +} +CIMGUI_API ImGuiSelectionExternalStorage* ImGuiSelectionExternalStorage_ImGuiSelectionExternalStorage(void) +{ + return IM_NEW(ImGuiSelectionExternalStorage)(); +} +CIMGUI_API void ImGuiSelectionExternalStorage_destroy(ImGuiSelectionExternalStorage* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiSelectionExternalStorage_ApplyRequests(ImGuiSelectionExternalStorage* self,ImGuiMultiSelectIO* ms_io) +{ + return self->ApplyRequests(ms_io); +} +CIMGUI_API ImDrawCmd* ImDrawCmd_ImDrawCmd(void) +{ + return IM_NEW(ImDrawCmd)(); +} +CIMGUI_API void ImDrawCmd_destroy(ImDrawCmd* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImTextureID ImDrawCmd_GetTexID(ImDrawCmd* self) +{ + return self->GetTexID(); +} +CIMGUI_API ImDrawListSplitter* ImDrawListSplitter_ImDrawListSplitter(void) +{ + return IM_NEW(ImDrawListSplitter)(); +} +CIMGUI_API void ImDrawListSplitter_destroy(ImDrawListSplitter* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImDrawListSplitter_Clear(ImDrawListSplitter* self) +{ + return self->Clear(); +} +CIMGUI_API void ImDrawListSplitter_ClearFreeMemory(ImDrawListSplitter* self) +{ + return self->ClearFreeMemory(); +} +CIMGUI_API void ImDrawListSplitter_Split(ImDrawListSplitter* self,ImDrawList* draw_list,int count) +{ + return self->Split(draw_list,count); +} +CIMGUI_API void ImDrawListSplitter_Merge(ImDrawListSplitter* self,ImDrawList* draw_list) +{ + return self->Merge(draw_list); +} +CIMGUI_API void ImDrawListSplitter_SetCurrentChannel(ImDrawListSplitter* self,ImDrawList* draw_list,int channel_idx) +{ + return self->SetCurrentChannel(draw_list,channel_idx); +} +CIMGUI_API ImDrawList* ImDrawList_ImDrawList(ImDrawListSharedData* shared_data) +{ + return IM_NEW(ImDrawList)(shared_data); +} +CIMGUI_API void ImDrawList_destroy(ImDrawList* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImDrawList_PushClipRect(ImDrawList* self,const ImVec2_c clip_rect_min,const ImVec2_c clip_rect_max,bool intersect_with_current_clip_rect) +{ + return self->PushClipRect(ConvertToCPP_ImVec2(clip_rect_min),ConvertToCPP_ImVec2(clip_rect_max),intersect_with_current_clip_rect); +} +CIMGUI_API void ImDrawList_PushClipRectFullScreen(ImDrawList* self) +{ + return self->PushClipRectFullScreen(); +} +CIMGUI_API void ImDrawList_PopClipRect(ImDrawList* self) +{ + return self->PopClipRect(); +} +CIMGUI_API void ImDrawList_PushTexture(ImDrawList* self,ImTextureRef_c tex_ref) +{ + return self->PushTexture(ConvertToCPP_ImTextureRef(tex_ref)); +} +CIMGUI_API void ImDrawList_PopTexture(ImDrawList* self) +{ + return self->PopTexture(); +} +CIMGUI_API ImVec2_c ImDrawList_GetClipRectMin(ImDrawList* self) +{ + return ConvertFromCPP_ImVec2(self->GetClipRectMin()); +} +CIMGUI_API ImVec2_c ImDrawList_GetClipRectMax(ImDrawList* self) +{ + return ConvertFromCPP_ImVec2(self->GetClipRectMax()); +} +CIMGUI_API void ImDrawList_AddLine(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,ImU32 col,float thickness) +{ + return self->AddLine(ConvertToCPP_ImVec2(p1),ConvertToCPP_ImVec2(p2),col,thickness); +} +CIMGUI_API void ImDrawList_AddLineH(ImDrawList* self,float min_x,float max_x,float y,ImU32 col,float thickness) +{ + return self->AddLineH(min_x,max_x,y,col,thickness); +} +CIMGUI_API void ImDrawList_AddLineV(ImDrawList* self,float x,float min_y,float max_y,ImU32 col,float thickness) +{ + return self->AddLineV(x,min_y,max_y,col,thickness); +} +CIMGUI_API void ImDrawList_AddRect(ImDrawList* self,const ImVec2_c p_min,const ImVec2_c p_max,ImU32 col,float rounding,float thickness,ImDrawFlags flags) +{ + return self->AddRect(ConvertToCPP_ImVec2(p_min),ConvertToCPP_ImVec2(p_max),col,rounding,thickness,flags); +} +CIMGUI_API void ImDrawList_AddRectFilled(ImDrawList* self,const ImVec2_c p_min,const ImVec2_c p_max,ImU32 col,float rounding,ImDrawFlags flags) +{ + return self->AddRectFilled(ConvertToCPP_ImVec2(p_min),ConvertToCPP_ImVec2(p_max),col,rounding,flags); +} +CIMGUI_API void ImDrawList_AddRectFilledMultiColor(ImDrawList* self,const ImVec2_c p_min,const ImVec2_c p_max,ImU32 col_upr_left,ImU32 col_upr_right,ImU32 col_bot_right,ImU32 col_bot_left) +{ + return self->AddRectFilledMultiColor(ConvertToCPP_ImVec2(p_min),ConvertToCPP_ImVec2(p_max),col_upr_left,col_upr_right,col_bot_right,col_bot_left); +} +CIMGUI_API void ImDrawList_AddQuad(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,ImU32 col,float thickness) +{ + return self->AddQuad(ConvertToCPP_ImVec2(p1),ConvertToCPP_ImVec2(p2),ConvertToCPP_ImVec2(p3),ConvertToCPP_ImVec2(p4),col,thickness); +} +CIMGUI_API void ImDrawList_AddQuadFilled(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,ImU32 col) +{ + return self->AddQuadFilled(ConvertToCPP_ImVec2(p1),ConvertToCPP_ImVec2(p2),ConvertToCPP_ImVec2(p3),ConvertToCPP_ImVec2(p4),col); +} +CIMGUI_API void ImDrawList_AddTriangle(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,ImU32 col,float thickness) +{ + return self->AddTriangle(ConvertToCPP_ImVec2(p1),ConvertToCPP_ImVec2(p2),ConvertToCPP_ImVec2(p3),col,thickness); +} +CIMGUI_API void ImDrawList_AddTriangleFilled(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,ImU32 col) +{ + return self->AddTriangleFilled(ConvertToCPP_ImVec2(p1),ConvertToCPP_ImVec2(p2),ConvertToCPP_ImVec2(p3),col); +} +CIMGUI_API void ImDrawList_AddCircle(ImDrawList* self,const ImVec2_c center,float radius,ImU32 col,int num_segments,float thickness) +{ + return self->AddCircle(ConvertToCPP_ImVec2(center),radius,col,num_segments,thickness); +} +CIMGUI_API void ImDrawList_AddCircleFilled(ImDrawList* self,const ImVec2_c center,float radius,ImU32 col,int num_segments) +{ + return self->AddCircleFilled(ConvertToCPP_ImVec2(center),radius,col,num_segments); +} +CIMGUI_API void ImDrawList_AddNgon(ImDrawList* self,const ImVec2_c center,float radius,ImU32 col,int num_segments,float thickness) +{ + return self->AddNgon(ConvertToCPP_ImVec2(center),radius,col,num_segments,thickness); +} +CIMGUI_API void ImDrawList_AddNgonFilled(ImDrawList* self,const ImVec2_c center,float radius,ImU32 col,int num_segments) +{ + return self->AddNgonFilled(ConvertToCPP_ImVec2(center),radius,col,num_segments); +} +CIMGUI_API void ImDrawList_AddEllipse(ImDrawList* self,const ImVec2_c center,const ImVec2_c radius,ImU32 col,float rot,int num_segments,float thickness) +{ + return self->AddEllipse(ConvertToCPP_ImVec2(center),ConvertToCPP_ImVec2(radius),col,rot,num_segments,thickness); +} +CIMGUI_API void ImDrawList_AddEllipseFilled(ImDrawList* self,const ImVec2_c center,const ImVec2_c radius,ImU32 col,float rot,int num_segments) +{ + return self->AddEllipseFilled(ConvertToCPP_ImVec2(center),ConvertToCPP_ImVec2(radius),col,rot,num_segments); +} +CIMGUI_API void ImDrawList_AddText_Vec2(ImDrawList* self,const ImVec2_c pos,ImU32 col,const char* text_begin,const char* text_end) +{ + return self->AddText(ConvertToCPP_ImVec2(pos),col,text_begin,text_end); +} +CIMGUI_API void ImDrawList_AddText_FontPtr(ImDrawList* self,ImFont* font,float font_size,const ImVec2_c pos,ImU32 col,const char* text_begin,const char* text_end,float wrap_width,const ImVec4* cpu_fine_clip_rect) +{ + return self->AddText(font,font_size,ConvertToCPP_ImVec2(pos),col,text_begin,text_end,wrap_width,cpu_fine_clip_rect); +} +CIMGUI_API void ImDrawList_AddBezierCubic(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,ImU32 col,float thickness,int num_segments) +{ + return self->AddBezierCubic(ConvertToCPP_ImVec2(p1),ConvertToCPP_ImVec2(p2),ConvertToCPP_ImVec2(p3),ConvertToCPP_ImVec2(p4),col,thickness,num_segments); +} +CIMGUI_API void ImDrawList_AddBezierQuadratic(ImDrawList* self,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,ImU32 col,float thickness,int num_segments) +{ + return self->AddBezierQuadratic(ConvertToCPP_ImVec2(p1),ConvertToCPP_ImVec2(p2),ConvertToCPP_ImVec2(p3),col,thickness,num_segments); +} +CIMGUI_API void ImDrawList_AddPolyline(ImDrawList* self,const ImVec2_c* points,int num_points,ImU32 col,float thickness,ImDrawFlags flags) +{ + return self->AddPolyline(reinterpret_cast(points),num_points,col,thickness,flags); +} +CIMGUI_API void ImDrawList_AddConvexPolyFilled(ImDrawList* self,const ImVec2_c* points,int num_points,ImU32 col) +{ + return self->AddConvexPolyFilled(reinterpret_cast(points),num_points,col); +} +CIMGUI_API void ImDrawList_AddConcavePolyFilled(ImDrawList* self,const ImVec2_c* points,int num_points,ImU32 col) +{ + return self->AddConcavePolyFilled(reinterpret_cast(points),num_points,col); +} +CIMGUI_API void ImDrawList_AddImage(ImDrawList* self,ImTextureRef_c tex_ref,const ImVec2_c p_min,const ImVec2_c p_max,const ImVec2_c uv_min,const ImVec2_c uv_max,ImU32 col) +{ + return self->AddImage(ConvertToCPP_ImTextureRef(tex_ref),ConvertToCPP_ImVec2(p_min),ConvertToCPP_ImVec2(p_max),ConvertToCPP_ImVec2(uv_min),ConvertToCPP_ImVec2(uv_max),col); +} +CIMGUI_API void ImDrawList_AddImageQuad(ImDrawList* self,ImTextureRef_c tex_ref,const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,const ImVec2_c uv1,const ImVec2_c uv2,const ImVec2_c uv3,const ImVec2_c uv4,ImU32 col) +{ + return self->AddImageQuad(ConvertToCPP_ImTextureRef(tex_ref),ConvertToCPP_ImVec2(p1),ConvertToCPP_ImVec2(p2),ConvertToCPP_ImVec2(p3),ConvertToCPP_ImVec2(p4),ConvertToCPP_ImVec2(uv1),ConvertToCPP_ImVec2(uv2),ConvertToCPP_ImVec2(uv3),ConvertToCPP_ImVec2(uv4),col); +} +CIMGUI_API void ImDrawList_AddImageRounded(ImDrawList* self,ImTextureRef_c tex_ref,const ImVec2_c p_min,const ImVec2_c p_max,const ImVec2_c uv_min,const ImVec2_c uv_max,ImU32 col,float rounding,ImDrawFlags flags) +{ + return self->AddImageRounded(ConvertToCPP_ImTextureRef(tex_ref),ConvertToCPP_ImVec2(p_min),ConvertToCPP_ImVec2(p_max),ConvertToCPP_ImVec2(uv_min),ConvertToCPP_ImVec2(uv_max),col,rounding,flags); +} +CIMGUI_API void ImDrawList_PathClear(ImDrawList* self) +{ + return self->PathClear(); +} +CIMGUI_API void ImDrawList_PathLineTo(ImDrawList* self,const ImVec2_c pos) +{ + return self->PathLineTo(ConvertToCPP_ImVec2(pos)); +} +CIMGUI_API void ImDrawList_PathLineToMergeDuplicate(ImDrawList* self,const ImVec2_c pos) +{ + return self->PathLineToMergeDuplicate(ConvertToCPP_ImVec2(pos)); +} +CIMGUI_API void ImDrawList_PathFillConvex(ImDrawList* self,ImU32 col) +{ + return self->PathFillConvex(col); +} +CIMGUI_API void ImDrawList_PathFillConcave(ImDrawList* self,ImU32 col) +{ + return self->PathFillConcave(col); +} +CIMGUI_API void ImDrawList_PathStroke(ImDrawList* self,ImU32 col,float thickness,ImDrawFlags flags) +{ + return self->PathStroke(col,thickness,flags); +} +CIMGUI_API void ImDrawList_PathArcTo(ImDrawList* self,const ImVec2_c center,float radius,float a_min,float a_max,int num_segments) +{ + return self->PathArcTo(ConvertToCPP_ImVec2(center),radius,a_min,a_max,num_segments); +} +CIMGUI_API void ImDrawList_PathArcToFast(ImDrawList* self,const ImVec2_c center,float radius,int a_min_of_12,int a_max_of_12) +{ + return self->PathArcToFast(ConvertToCPP_ImVec2(center),radius,a_min_of_12,a_max_of_12); +} +CIMGUI_API void ImDrawList_PathEllipticalArcTo(ImDrawList* self,const ImVec2_c center,const ImVec2_c radius,float rot,float a_min,float a_max,int num_segments) +{ + return self->PathEllipticalArcTo(ConvertToCPP_ImVec2(center),ConvertToCPP_ImVec2(radius),rot,a_min,a_max,num_segments); +} +CIMGUI_API void ImDrawList_PathBezierCubicCurveTo(ImDrawList* self,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,int num_segments) +{ + return self->PathBezierCubicCurveTo(ConvertToCPP_ImVec2(p2),ConvertToCPP_ImVec2(p3),ConvertToCPP_ImVec2(p4),num_segments); +} +CIMGUI_API void ImDrawList_PathBezierQuadraticCurveTo(ImDrawList* self,const ImVec2_c p2,const ImVec2_c p3,int num_segments) +{ + return self->PathBezierQuadraticCurveTo(ConvertToCPP_ImVec2(p2),ConvertToCPP_ImVec2(p3),num_segments); +} +CIMGUI_API void ImDrawList_PathRect(ImDrawList* self,const ImVec2_c rect_min,const ImVec2_c rect_max,float rounding,ImDrawFlags flags) +{ + return self->PathRect(ConvertToCPP_ImVec2(rect_min),ConvertToCPP_ImVec2(rect_max),rounding,flags); +} +CIMGUI_API void ImDrawList_AddCallback(ImDrawList* self,ImDrawCallback callback,void* userdata,size_t userdata_size) +{ + return self->AddCallback(callback,userdata,userdata_size); +} +CIMGUI_API void ImDrawList_AddDrawCmd(ImDrawList* self) +{ + return self->AddDrawCmd(); +} +CIMGUI_API ImDrawList* ImDrawList_CloneOutput(ImDrawList* self) +{ + return self->CloneOutput(); +} +CIMGUI_API void ImDrawList_ChannelsSplit(ImDrawList* self,int count) +{ + return self->ChannelsSplit(count); +} +CIMGUI_API void ImDrawList_ChannelsMerge(ImDrawList* self) +{ + return self->ChannelsMerge(); +} +CIMGUI_API void ImDrawList_ChannelsSetCurrent(ImDrawList* self,int n) +{ + return self->ChannelsSetCurrent(n); +} +CIMGUI_API void ImDrawList_PrimReserve(ImDrawList* self,int idx_count,int vtx_count) +{ + return self->PrimReserve(idx_count,vtx_count); +} +CIMGUI_API void ImDrawList_PrimUnreserve(ImDrawList* self,int idx_count,int vtx_count) +{ + return self->PrimUnreserve(idx_count,vtx_count); +} +CIMGUI_API void ImDrawList_PrimRect(ImDrawList* self,const ImVec2_c a,const ImVec2_c b,ImU32 col) +{ + return self->PrimRect(ConvertToCPP_ImVec2(a),ConvertToCPP_ImVec2(b),col); +} +CIMGUI_API void ImDrawList_PrimRectUV(ImDrawList* self,const ImVec2_c a,const ImVec2_c b,const ImVec2_c uv_a,const ImVec2_c uv_b,ImU32 col) +{ + return self->PrimRectUV(ConvertToCPP_ImVec2(a),ConvertToCPP_ImVec2(b),ConvertToCPP_ImVec2(uv_a),ConvertToCPP_ImVec2(uv_b),col); +} +CIMGUI_API void ImDrawList_PrimQuadUV(ImDrawList* self,const ImVec2_c a,const ImVec2_c b,const ImVec2_c c,const ImVec2_c d,const ImVec2_c uv_a,const ImVec2_c uv_b,const ImVec2_c uv_c,const ImVec2_c uv_d,ImU32 col) +{ + return self->PrimQuadUV(ConvertToCPP_ImVec2(a),ConvertToCPP_ImVec2(b),ConvertToCPP_ImVec2(c),ConvertToCPP_ImVec2(d),ConvertToCPP_ImVec2(uv_a),ConvertToCPP_ImVec2(uv_b),ConvertToCPP_ImVec2(uv_c),ConvertToCPP_ImVec2(uv_d),col); +} +CIMGUI_API void ImDrawList_PrimWriteVtx(ImDrawList* self,const ImVec2_c pos,const ImVec2_c uv,ImU32 col) +{ + return self->PrimWriteVtx(ConvertToCPP_ImVec2(pos),ConvertToCPP_ImVec2(uv),col); +} +CIMGUI_API void ImDrawList_PrimWriteIdx(ImDrawList* self,ImDrawIdx idx) +{ + return self->PrimWriteIdx(idx); +} +CIMGUI_API void ImDrawList_PrimVtx(ImDrawList* self,const ImVec2_c pos,const ImVec2_c uv,ImU32 col) +{ + return self->PrimVtx(ConvertToCPP_ImVec2(pos),ConvertToCPP_ImVec2(uv),col); +} +CIMGUI_API void ImDrawList__SetDrawListSharedData(ImDrawList* self,ImDrawListSharedData* data) +{ + return self->_SetDrawListSharedData(data); +} +CIMGUI_API void ImDrawList__ResetForNewFrame(ImDrawList* self) +{ + return self->_ResetForNewFrame(); +} +CIMGUI_API void ImDrawList__ClearFreeMemory(ImDrawList* self) +{ + return self->_ClearFreeMemory(); +} +CIMGUI_API void ImDrawList__PopUnusedDrawCmd(ImDrawList* self) +{ + return self->_PopUnusedDrawCmd(); +} +CIMGUI_API void ImDrawList__TryMergeDrawCmds(ImDrawList* self) +{ + return self->_TryMergeDrawCmds(); +} +CIMGUI_API void ImDrawList__OnChangedClipRect(ImDrawList* self) +{ + return self->_OnChangedClipRect(); +} +CIMGUI_API void ImDrawList__OnChangedTexture(ImDrawList* self) +{ + return self->_OnChangedTexture(); +} +CIMGUI_API void ImDrawList__OnChangedVtxOffset(ImDrawList* self) +{ + return self->_OnChangedVtxOffset(); +} +CIMGUI_API void ImDrawList__SetTexture(ImDrawList* self,ImTextureRef_c tex_ref) +{ + return self->_SetTexture(ConvertToCPP_ImTextureRef(tex_ref)); +} +CIMGUI_API int ImDrawList__CalcCircleAutoSegmentCount(ImDrawList* self,float radius) +{ + return self->_CalcCircleAutoSegmentCount(radius); +} +CIMGUI_API void ImDrawList__PathArcToFastEx(ImDrawList* self,const ImVec2_c center,float radius,int a_min_sample,int a_max_sample,int a_step) +{ + return self->_PathArcToFastEx(ConvertToCPP_ImVec2(center),radius,a_min_sample,a_max_sample,a_step); +} +CIMGUI_API void ImDrawList__PathArcToN(ImDrawList* self,const ImVec2_c center,float radius,float a_min,float a_max,int num_segments) +{ + return self->_PathArcToN(ConvertToCPP_ImVec2(center),radius,a_min,a_max,num_segments); +} +CIMGUI_API ImDrawData* ImDrawData_ImDrawData(void) +{ + return IM_NEW(ImDrawData)(); +} +CIMGUI_API void ImDrawData_destroy(ImDrawData* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImDrawData_Clear(ImDrawData* self) +{ + return self->Clear(); +} +CIMGUI_API void ImDrawData_AddDrawList(ImDrawData* self,ImDrawList* draw_list) +{ + return self->AddDrawList(draw_list); +} +CIMGUI_API void ImDrawData_DeIndexAllBuffers(ImDrawData* self) +{ + return self->DeIndexAllBuffers(); +} +CIMGUI_API void ImDrawData_ScaleClipRects(ImDrawData* self,const ImVec2_c fb_scale) +{ + return self->ScaleClipRects(ConvertToCPP_ImVec2(fb_scale)); +} +CIMGUI_API ImTextureData* ImTextureData_ImTextureData(void) +{ + return IM_NEW(ImTextureData)(); +} +CIMGUI_API void ImTextureData_destroy(ImTextureData* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImTextureData_Create(ImTextureData* self,ImTextureFormat format,int w,int h) +{ + return self->Create(format,w,h); +} +CIMGUI_API void ImTextureData_DestroyPixels(ImTextureData* self) +{ + return self->DestroyPixels(); +} +CIMGUI_API void* ImTextureData_GetPixels(ImTextureData* self) +{ + return self->GetPixels(); +} +CIMGUI_API void* ImTextureData_GetPixelsAt(ImTextureData* self,int x,int y) +{ + return self->GetPixelsAt(x,y); +} +CIMGUI_API int ImTextureData_GetSizeInBytes(ImTextureData* self) +{ + return self->GetSizeInBytes(); +} +CIMGUI_API int ImTextureData_GetPitch(ImTextureData* self) +{ + return self->GetPitch(); +} +CIMGUI_API ImTextureRef_c ImTextureData_GetTexRef(ImTextureData* self) +{ + return ConvertFromCPP_ImTextureRef(self->GetTexRef()); +} +CIMGUI_API ImTextureID ImTextureData_GetTexID(ImTextureData* self) +{ + return self->GetTexID(); +} +CIMGUI_API void ImTextureData_SetTexID(ImTextureData* self,ImTextureID tex_id) +{ + return self->SetTexID(tex_id); +} +CIMGUI_API void ImTextureData_SetStatus(ImTextureData* self,ImTextureStatus status) +{ + return self->SetStatus(status); +} +CIMGUI_API ImFontConfig* ImFontConfig_ImFontConfig(void) +{ + return IM_NEW(ImFontConfig)(); +} +CIMGUI_API void ImFontConfig_destroy(ImFontConfig* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImFontGlyph* ImFontGlyph_ImFontGlyph(void) +{ + return IM_NEW(ImFontGlyph)(); +} +CIMGUI_API void ImFontGlyph_destroy(ImFontGlyph* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImFontGlyphRangesBuilder* ImFontGlyphRangesBuilder_ImFontGlyphRangesBuilder(void) +{ + return IM_NEW(ImFontGlyphRangesBuilder)(); +} +CIMGUI_API void ImFontGlyphRangesBuilder_destroy(ImFontGlyphRangesBuilder* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImFontGlyphRangesBuilder_Clear(ImFontGlyphRangesBuilder* self) +{ + return self->Clear(); +} +CIMGUI_API bool ImFontGlyphRangesBuilder_GetBit(ImFontGlyphRangesBuilder* self,size_t n) +{ + return self->GetBit(n); +} +CIMGUI_API void ImFontGlyphRangesBuilder_SetBit(ImFontGlyphRangesBuilder* self,size_t n) +{ + return self->SetBit(n); +} +CIMGUI_API void ImFontGlyphRangesBuilder_AddChar(ImFontGlyphRangesBuilder* self,ImWchar c) +{ + return self->AddChar(c); +} +CIMGUI_API void ImFontGlyphRangesBuilder_AddText(ImFontGlyphRangesBuilder* self,const char* text,const char* text_end) +{ + return self->AddText(text,text_end); +} +CIMGUI_API void ImFontGlyphRangesBuilder_AddRanges(ImFontGlyphRangesBuilder* self,const ImWchar* ranges) +{ + return self->AddRanges(ranges); +} +CIMGUI_API void ImFontGlyphRangesBuilder_BuildRanges(ImFontGlyphRangesBuilder* self,ImVector_ImWchar* out_ranges) +{ + return self->BuildRanges(out_ranges); +} +CIMGUI_API ImFontAtlasRect* ImFontAtlasRect_ImFontAtlasRect(void) +{ + return IM_NEW(ImFontAtlasRect)(); +} +CIMGUI_API void ImFontAtlasRect_destroy(ImFontAtlasRect* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImFontAtlas* ImFontAtlas_ImFontAtlas(void) +{ + return IM_NEW(ImFontAtlas)(); +} +CIMGUI_API void ImFontAtlas_destroy(ImFontAtlas* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImFont* ImFontAtlas_AddFont(ImFontAtlas* self,const ImFontConfig* font_cfg) +{ + return self->AddFont(font_cfg); +} +CIMGUI_API ImFont* ImFontAtlas_AddFontDefault(ImFontAtlas* self,const ImFontConfig* font_cfg) +{ + return self->AddFontDefault(font_cfg); +} +CIMGUI_API ImFont* ImFontAtlas_AddFontDefaultVector(ImFontAtlas* self,const ImFontConfig* font_cfg) +{ + return self->AddFontDefaultVector(font_cfg); +} +CIMGUI_API ImFont* ImFontAtlas_AddFontDefaultBitmap(ImFontAtlas* self,const ImFontConfig* font_cfg) +{ + return self->AddFontDefaultBitmap(font_cfg); +} +CIMGUI_API ImFont* ImFontAtlas_AddFontFromFileTTF(ImFontAtlas* self,const char* filename,float size_pixels,const ImFontConfig* font_cfg,const ImWchar* glyph_ranges) +{ + return self->AddFontFromFileTTF(filename,size_pixels,font_cfg,glyph_ranges); +} +CIMGUI_API ImFont* ImFontAtlas_AddFontFromMemoryTTF(ImFontAtlas* self,void* font_data,int font_data_size,float size_pixels,const ImFontConfig* font_cfg,const ImWchar* glyph_ranges) +{ + return self->AddFontFromMemoryTTF(font_data,font_data_size,size_pixels,font_cfg,glyph_ranges); +} +CIMGUI_API ImFont* ImFontAtlas_AddFontFromMemoryCompressedTTF(ImFontAtlas* self,const void* compressed_font_data,int compressed_font_data_size,float size_pixels,const ImFontConfig* font_cfg,const ImWchar* glyph_ranges) +{ + return self->AddFontFromMemoryCompressedTTF(compressed_font_data,compressed_font_data_size,size_pixels,font_cfg,glyph_ranges); +} +CIMGUI_API ImFont* ImFontAtlas_AddFontFromMemoryCompressedBase85TTF(ImFontAtlas* self,const char* compressed_font_data_base85,float size_pixels,const ImFontConfig* font_cfg,const ImWchar* glyph_ranges) +{ + return self->AddFontFromMemoryCompressedBase85TTF(compressed_font_data_base85,size_pixels,font_cfg,glyph_ranges); +} +CIMGUI_API void ImFontAtlas_RemoveFont(ImFontAtlas* self,ImFont* font) +{ + return self->RemoveFont(font); +} +CIMGUI_API void ImFontAtlas_CompactCache(ImFontAtlas* self) +{ + return self->CompactCache(); +} +CIMGUI_API void ImFontAtlas_SetFontLoader(ImFontAtlas* self,const ImFontLoader* font_loader) +{ + return self->SetFontLoader(font_loader); +} +CIMGUI_API void ImFontAtlas_Clear(ImFontAtlas* self) +{ + return self->Clear(); +} +CIMGUI_API void ImFontAtlas_ClearFonts(ImFontAtlas* self) +{ + return self->ClearFonts(); +} +CIMGUI_API void ImFontAtlas_ClearInputData(ImFontAtlas* self) +{ + return self->ClearInputData(); +} +CIMGUI_API void ImFontAtlas_ClearTexData(ImFontAtlas* self) +{ + return self->ClearTexData(); +} +CIMGUI_API const ImWchar* ImFontAtlas_GetGlyphRangesDefault(ImFontAtlas* self) +{ + return self->GetGlyphRangesDefault(); +} +CIMGUI_API ImFontAtlasRectId ImFontAtlas_AddCustomRect(ImFontAtlas* self,int width,int height,ImFontAtlasRect* out_r) +{ + return self->AddCustomRect(width,height,out_r); +} +CIMGUI_API void ImFontAtlas_RemoveCustomRect(ImFontAtlas* self,ImFontAtlasRectId id) +{ + return self->RemoveCustomRect(id); +} +CIMGUI_API bool ImFontAtlas_GetCustomRect(ImFontAtlas* self,ImFontAtlasRectId id,ImFontAtlasRect* out_r) +{ + return self->GetCustomRect(id,out_r); +} +CIMGUI_API ImFontBaked* ImFontBaked_ImFontBaked(void) +{ + return IM_NEW(ImFontBaked)(); +} +CIMGUI_API void ImFontBaked_destroy(ImFontBaked* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImFontBaked_ClearOutputData(ImFontBaked* self) +{ + return self->ClearOutputData(); +} +CIMGUI_API ImFontGlyph* ImFontBaked_FindGlyph(ImFontBaked* self,ImWchar c) +{ + return self->FindGlyph(c); +} +CIMGUI_API ImFontGlyph* ImFontBaked_FindGlyphNoFallback(ImFontBaked* self,ImWchar c) +{ + return self->FindGlyphNoFallback(c); +} +CIMGUI_API float ImFontBaked_GetCharAdvance(ImFontBaked* self,ImWchar c) +{ + return self->GetCharAdvance(c); +} +CIMGUI_API bool ImFontBaked_IsGlyphLoaded(ImFontBaked* self,ImWchar c) +{ + return self->IsGlyphLoaded(c); +} +CIMGUI_API ImFont* ImFont_ImFont(void) +{ + return IM_NEW(ImFont)(); +} +CIMGUI_API void ImFont_destroy(ImFont* self) +{ + IM_DELETE(self); +} +CIMGUI_API bool ImFont_IsGlyphInFont(ImFont* self,ImWchar c) +{ + return self->IsGlyphInFont(c); +} +CIMGUI_API bool ImFont_IsLoaded(ImFont* self) +{ + return self->IsLoaded(); +} +CIMGUI_API const char* ImFont_GetDebugName(ImFont* self) +{ + return self->GetDebugName(); +} +CIMGUI_API ImFontBaked* ImFont_GetFontBaked(ImFont* self,float font_size,float density) +{ + return self->GetFontBaked(font_size,density); +} +CIMGUI_API ImVec2_c ImFont_CalcTextSizeA(ImFont* self,float size,float max_width,float wrap_width,const char* text_begin,const char* text_end,const char** out_remaining) +{ + return ConvertFromCPP_ImVec2(self->CalcTextSizeA(size,max_width,wrap_width,text_begin,text_end,out_remaining)); +} +CIMGUI_API const char* ImFont_CalcWordWrapPosition(ImFont* self,float size,const char* text,const char* text_end,float wrap_width) +{ + return self->CalcWordWrapPosition(size,text,text_end,wrap_width); +} +CIMGUI_API void ImFont_RenderChar(ImFont* self,ImDrawList* draw_list,float size,const ImVec2_c pos,ImU32 col,ImWchar c,const ImVec4* cpu_fine_clip) +{ + return self->RenderChar(draw_list,size,ConvertToCPP_ImVec2(pos),col,c,cpu_fine_clip); +} +CIMGUI_API void ImFont_RenderText(ImFont* self,ImDrawList* draw_list,float size,const ImVec2_c pos,ImU32 col,const ImVec4_c clip_rect,const char* text_begin,const char* text_end,float wrap_width,ImDrawTextFlags flags) +{ + return self->RenderText(draw_list,size,ConvertToCPP_ImVec2(pos),col,ConvertToCPP_ImVec4(clip_rect),text_begin,text_end,wrap_width,flags); +} +CIMGUI_API void ImFont_ClearOutputData(ImFont* self) +{ + return self->ClearOutputData(); +} +CIMGUI_API void ImFont_AddRemapChar(ImFont* self,ImWchar from_codepoint,ImWchar to_codepoint) +{ + return self->AddRemapChar(from_codepoint,to_codepoint); +} +CIMGUI_API bool ImFont_IsGlyphRangeUnused(ImFont* self,unsigned int c_begin,unsigned int c_last) +{ + return self->IsGlyphRangeUnused(c_begin,c_last); +} +CIMGUI_API ImGuiViewport* ImGuiViewport_ImGuiViewport(void) +{ + return IM_NEW(ImGuiViewport)(); +} +CIMGUI_API void ImGuiViewport_destroy(ImGuiViewport* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImVec2_c ImGuiViewport_GetCenter(ImGuiViewport* self) +{ + return ConvertFromCPP_ImVec2(self->GetCenter()); +} +CIMGUI_API ImVec2_c ImGuiViewport_GetWorkCenter(ImGuiViewport* self) +{ + return ConvertFromCPP_ImVec2(self->GetWorkCenter()); +} +CIMGUI_API ImGuiPlatformIO* ImGuiPlatformIO_ImGuiPlatformIO(void) +{ + return IM_NEW(ImGuiPlatformIO)(); +} +CIMGUI_API void ImGuiPlatformIO_destroy(ImGuiPlatformIO* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiPlatformIO_ClearPlatformHandlers(ImGuiPlatformIO* self) +{ + return self->ClearPlatformHandlers(); +} +CIMGUI_API void ImGuiPlatformIO_ClearRendererHandlers(ImGuiPlatformIO* self) +{ + return self->ClearRendererHandlers(); +} +CIMGUI_API ImGuiPlatformImeData* ImGuiPlatformImeData_ImGuiPlatformImeData(void) +{ + return IM_NEW(ImGuiPlatformImeData)(); +} +CIMGUI_API void ImGuiPlatformImeData_destroy(ImGuiPlatformImeData* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiID igImHashData(const void* data,size_t data_size,ImGuiID seed) +{ + return ImHashData(data,data_size,seed); +} +CIMGUI_API ImGuiID igImHashStr(const char* data,size_t data_size,ImGuiID seed) +{ + return ImHashStr(data,data_size,seed); +} +CIMGUI_API const char* igImHashSkipUncontributingPrefix(const char* label) +{ + return ImHashSkipUncontributingPrefix(label); +} +CIMGUI_API void igImQsort(void* base,size_t count,size_t size_of_element,int(*compare_func)(void const*,void const*)) +{ + return ImQsort(base,count,size_of_element,compare_func); +} +CIMGUI_API ImU32 igImAlphaBlendColors(ImU32 col_a,ImU32 col_b) +{ + return ImAlphaBlendColors(col_a,col_b); +} +CIMGUI_API bool igImIsPowerOfTwo_Int(int v) +{ + return ImIsPowerOfTwo(v); +} +CIMGUI_API bool igImIsPowerOfTwo_U64(ImU64 v) +{ + return ImIsPowerOfTwo(v); +} +CIMGUI_API int igImUpperPowerOfTwo(int v) +{ + return ImUpperPowerOfTwo(v); +} +CIMGUI_API unsigned int igImCountSetBits(unsigned int v) +{ + return ImCountSetBits(v); +} +CIMGUI_API int igImStricmp(const char* str1,const char* str2) +{ + return ImStricmp(str1,str2); +} +CIMGUI_API int igImStrnicmp(const char* str1,const char* str2,size_t count) +{ + return ImStrnicmp(str1,str2,count); +} +CIMGUI_API void igImStrncpy(char* dst,const char* src,size_t count) +{ + return ImStrncpy(dst,src,count); +} +CIMGUI_API char* igImStrdup(const char* str) +{ + return ImStrdup(str); +} +CIMGUI_API void* igImMemdup(const void* src,size_t size) +{ + return ImMemdup(src,size); +} +CIMGUI_API char* igImStrdupcpy(char* dst,size_t* p_dst_size,const char* str) +{ + return ImStrdupcpy(dst,p_dst_size,str); +} +CIMGUI_API const char* igImStrchrRange(const char* str_begin,const char* str_end,char c) +{ + return ImStrchrRange(str_begin,str_end,c); +} +CIMGUI_API const char* igImStreolRange(const char* str,const char* str_end) +{ + return ImStreolRange(str,str_end); +} +CIMGUI_API const char* igImStristr(const char* haystack,const char* haystack_end,const char* needle,const char* needle_end) +{ + return ImStristr(haystack,haystack_end,needle,needle_end); +} +CIMGUI_API void igImStrTrimBlanks(char* str) +{ + return ImStrTrimBlanks(str); +} +CIMGUI_API const char* igImStrSkipBlank(const char* str) +{ + return ImStrSkipBlank(str); +} +CIMGUI_API int igImStrlenW(const ImWchar* str) +{ + return ImStrlenW(str); +} +CIMGUI_API const char* igImStrbol(const char* buf_mid_line,const char* buf_begin) +{ + return ImStrbol(buf_mid_line,buf_begin); +} +CIMGUI_API char igImToUpper(char c) +{ + return ImToUpper(c); +} +CIMGUI_API bool igImCharIsBlankA(char c) +{ + return ImCharIsBlankA(c); +} +CIMGUI_API bool igImCharIsBlankW(unsigned int c) +{ + return ImCharIsBlankW(c); +} +CIMGUI_API bool igImCharIsXdigitA(char c) +{ + return ImCharIsXdigitA(c); +} +CIMGUI_API int igImFormatString(char* buf,size_t buf_size,const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + int ret = ImFormatStringV(buf,buf_size,fmt,args); + va_end(args); + return ret; +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API int igImFormatString0(char* buf,size_t buf_size,const char* fmt) +{ + return igImFormatString(buf,buf_size,fmt); +} +#endif +CIMGUI_API int igImFormatStringV(char* buf,size_t buf_size,const char* fmt,va_list args) +{ + return ImFormatStringV(buf,buf_size,fmt,args); +} +CIMGUI_API void igImFormatStringToTempBuffer(const char** out_buf,const char** out_buf_end,const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + ImFormatStringToTempBufferV(out_buf,out_buf_end,fmt,args); + va_end(args); +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igImFormatStringToTempBuffer0(const char** out_buf,const char** out_buf_end,const char* fmt) +{ + return igImFormatStringToTempBuffer(out_buf,out_buf_end,fmt); +} +#endif +CIMGUI_API void igImFormatStringToTempBufferV(const char** out_buf,const char** out_buf_end,const char* fmt,va_list args) +{ + return ImFormatStringToTempBufferV(out_buf,out_buf_end,fmt,args); +} +CIMGUI_API const char* igImParseFormatFindStart(const char* format) +{ + return ImParseFormatFindStart(format); +} +CIMGUI_API const char* igImParseFormatFindEnd(const char* format) +{ + return ImParseFormatFindEnd(format); +} +CIMGUI_API const char* igImParseFormatTrimDecorations(const char* format,char* buf,size_t buf_size) +{ + return ImParseFormatTrimDecorations(format,buf,buf_size); +} +CIMGUI_API void igImParseFormatSanitizeForPrinting(const char* fmt_in,char* fmt_out,size_t fmt_out_size) +{ + return ImParseFormatSanitizeForPrinting(fmt_in,fmt_out,fmt_out_size); +} +CIMGUI_API const char* igImParseFormatSanitizeForScanning(const char* fmt_in,char* fmt_out,size_t fmt_out_size) +{ + return ImParseFormatSanitizeForScanning(fmt_in,fmt_out,fmt_out_size); +} +CIMGUI_API int igImParseFormatPrecision(const char* format,int default_value) +{ + return ImParseFormatPrecision(format,default_value); +} +CIMGUI_API int igImTextCharToUtf8(char out_buf[5],unsigned int c) +{ + return ImTextCharToUtf8(out_buf,c); +} +CIMGUI_API int igImTextStrToUtf8(char* out_buf,int out_buf_size,const ImWchar* in_text,const ImWchar* in_text_end) +{ + return ImTextStrToUtf8(out_buf,out_buf_size,in_text,in_text_end); +} +CIMGUI_API int igImTextCharFromUtf8(unsigned int* out_char,const char* in_text,const char* in_text_end) +{ + return ImTextCharFromUtf8(out_char,in_text,in_text_end); +} +CIMGUI_API int igImTextStrFromUtf8(ImWchar* out_buf,int out_buf_size,const char* in_text,const char* in_text_end,const char** in_remaining) +{ + return ImTextStrFromUtf8(out_buf,out_buf_size,in_text,in_text_end,in_remaining); +} +CIMGUI_API int igImTextCountCharsFromUtf8(const char* in_text,const char* in_text_end) +{ + return ImTextCountCharsFromUtf8(in_text,in_text_end); +} +CIMGUI_API int igImTextCountUtf8BytesFromChar(const char* in_text,const char* in_text_end) +{ + return ImTextCountUtf8BytesFromChar(in_text,in_text_end); +} +CIMGUI_API int igImTextCountUtf8BytesFromStr(const ImWchar* in_text,const ImWchar* in_text_end) +{ + return ImTextCountUtf8BytesFromStr(in_text,in_text_end); +} +CIMGUI_API const char* igImTextFindPreviousUtf8Codepoint(const char* in_text_start,const char* in_p) +{ + return ImTextFindPreviousUtf8Codepoint(in_text_start,in_p); +} +CIMGUI_API const char* igImTextFindValidUtf8CodepointEnd(const char* in_text_start,const char* in_text_end,const char* in_p) +{ + return ImTextFindValidUtf8CodepointEnd(in_text_start,in_text_end,in_p); +} +CIMGUI_API int igImTextCountLines(const char* in_text,const char* in_text_end) +{ + return ImTextCountLines(in_text,in_text_end); +} +CIMGUI_API ImVec2_c igImFontCalcTextSizeEx(ImFont* font,float size,float max_width,float wrap_width,const char* text_begin,const char* text_end_display,const char* text_end,const char** out_remaining,ImVec2_c* out_offset,ImDrawTextFlags flags) +{ + return ConvertFromCPP_ImVec2(ImFontCalcTextSizeEx(font,size,max_width,wrap_width,text_begin,text_end_display,text_end,out_remaining,reinterpret_cast(out_offset),flags)); +} +CIMGUI_API const char* igImFontCalcWordWrapPositionEx(ImFont* font,float size,const char* text,const char* text_end,float wrap_width,ImDrawTextFlags flags) +{ + return ImFontCalcWordWrapPositionEx(font,size,text,text_end,wrap_width,flags); +} +CIMGUI_API const char* igImTextCalcWordWrapNextLineStart(const char* text,const char* text_end,ImDrawTextFlags flags) +{ + return ImTextCalcWordWrapNextLineStart(text,text_end,flags); +} +CIMGUI_API void igImTextInitClassifiers() +{ + return ImTextInitClassifiers(); +} +CIMGUI_API void igImTextClassifierClear(ImU32* bits,unsigned int codepoint_min,unsigned int codepoint_end,ImWcharClass char_class) +{ + return ImTextClassifierClear(bits,codepoint_min,codepoint_end,char_class); +} +CIMGUI_API void igImTextClassifierSetCharClass(ImU32* bits,unsigned int codepoint_min,unsigned int codepoint_end,ImWcharClass char_class,unsigned int c) +{ + return ImTextClassifierSetCharClass(bits,codepoint_min,codepoint_end,char_class,c); +} +CIMGUI_API void igImTextClassifierSetCharClassFromStr(ImU32* bits,unsigned int codepoint_min,unsigned int codepoint_end,ImWcharClass char_class,const char* s) +{ + return ImTextClassifierSetCharClassFromStr(bits,codepoint_min,codepoint_end,char_class,s); +} +CIMGUI_API ImFileHandle igImFileOpen(const char* filename,const char* mode) +{ + return ImFileOpen(filename,mode); +} +CIMGUI_API bool igImFileClose(ImFileHandle file) +{ + return ImFileClose(file); +} +CIMGUI_API ImU64 igImFileGetSize(ImFileHandle file) +{ + return ImFileGetSize(file); +} +CIMGUI_API ImU64 igImFileRead(void* data,ImU64 size,ImU64 count,ImFileHandle file) +{ + return ImFileRead(data,size,count,file); +} +CIMGUI_API ImU64 igImFileWrite(const void* data,ImU64 size,ImU64 count,ImFileHandle file) +{ + return ImFileWrite(data,size,count,file); +} +CIMGUI_API void* igImFileLoadToMemory(const char* filename,const char* mode,size_t* out_file_size,int padding_bytes) +{ + return ImFileLoadToMemory(filename,mode,out_file_size,padding_bytes); +} +CIMGUI_API float igImPow_Float(float x,float y) +{ + return ImPow(x,y); +} +CIMGUI_API double igImPow_double(double x,double y) +{ + return ImPow(x,y); +} +CIMGUI_API float igImLog_Float(float x) +{ + return ImLog(x); +} +CIMGUI_API double igImLog_double(double x) +{ + return ImLog(x); +} +CIMGUI_API int igImAbs_Int(int x) +{ + return ImAbs(x); +} +CIMGUI_API float igImAbs_Float(float x) +{ + return ImAbs(x); +} +CIMGUI_API double igImAbs_double(double x) +{ + return ImAbs(x); +} +CIMGUI_API float igImSign_Float(float x) +{ + return ImSign(x); +} +CIMGUI_API double igImSign_double(double x) +{ + return ImSign(x); +} +CIMGUI_API float igImRsqrt_Float(float x) +{ + return ImRsqrt(x); +} +CIMGUI_API double igImRsqrt_double(double x) +{ + return ImRsqrt(x); +} +CIMGUI_API ImVec2_c igImMin(const ImVec2_c lhs,const ImVec2_c rhs) +{ + return ConvertFromCPP_ImVec2(ImMin(ConvertToCPP_ImVec2(lhs),ConvertToCPP_ImVec2(rhs))); +} +CIMGUI_API ImVec2_c igImMax(const ImVec2_c lhs,const ImVec2_c rhs) +{ + return ConvertFromCPP_ImVec2(ImMax(ConvertToCPP_ImVec2(lhs),ConvertToCPP_ImVec2(rhs))); +} +CIMGUI_API ImVec2_c igImClamp(const ImVec2_c v,const ImVec2_c mn,const ImVec2_c mx) +{ + return ConvertFromCPP_ImVec2(ImClamp(ConvertToCPP_ImVec2(v),ConvertToCPP_ImVec2(mn),ConvertToCPP_ImVec2(mx))); +} +CIMGUI_API ImVec2_c igImLerp_Vec2Float(const ImVec2_c a,const ImVec2_c b,float t) +{ + return ConvertFromCPP_ImVec2(ImLerp(ConvertToCPP_ImVec2(a),ConvertToCPP_ImVec2(b),t)); +} +CIMGUI_API ImVec2_c igImLerp_Vec2Vec2(const ImVec2_c a,const ImVec2_c b,const ImVec2_c t) +{ + return ConvertFromCPP_ImVec2(ImLerp(ConvertToCPP_ImVec2(a),ConvertToCPP_ImVec2(b),ConvertToCPP_ImVec2(t))); +} +CIMGUI_API ImVec4_c igImLerp_Vec4(const ImVec4_c a,const ImVec4_c b,float t) +{ + return ConvertFromCPP_ImVec4(ImLerp(ConvertToCPP_ImVec4(a),ConvertToCPP_ImVec4(b),t)); +} +CIMGUI_API float igImSaturate(float f) +{ + return ImSaturate(f); +} +CIMGUI_API float igImLengthSqr_Vec2(const ImVec2_c lhs) +{ + return ImLengthSqr(ConvertToCPP_ImVec2(lhs)); +} +CIMGUI_API float igImLengthSqr_Vec4(const ImVec4_c lhs) +{ + return ImLengthSqr(ConvertToCPP_ImVec4(lhs)); +} +CIMGUI_API float igImInvLength(const ImVec2_c lhs,float fail_value) +{ + return ImInvLength(ConvertToCPP_ImVec2(lhs),fail_value); +} +CIMGUI_API float igImTrunc_Float(float f) +{ + return ImTrunc(f); +} +CIMGUI_API ImVec2_c igImTrunc_Vec2(const ImVec2_c v) +{ + return ConvertFromCPP_ImVec2(ImTrunc(ConvertToCPP_ImVec2(v))); +} +CIMGUI_API float igImFloor_Float(float f) +{ + return ImFloor(f); +} +CIMGUI_API ImVec2_c igImFloor_Vec2(const ImVec2_c v) +{ + return ConvertFromCPP_ImVec2(ImFloor(ConvertToCPP_ImVec2(v))); +} +CIMGUI_API float igImTrunc64(float f) +{ + return ImTrunc64(f); +} +CIMGUI_API float igImRound64(float f) +{ + return ImRound64(f); +} +CIMGUI_API float igImCeilFast(float f) +{ + return ImCeilFast(f); +} +CIMGUI_API int igImModPositive(int a,int b) +{ + return ImModPositive(a,b); +} +CIMGUI_API float igImDot(const ImVec2_c a,const ImVec2_c b) +{ + return ImDot(ConvertToCPP_ImVec2(a),ConvertToCPP_ImVec2(b)); +} +CIMGUI_API ImVec2_c igImRotate(const ImVec2_c v,float cos_a,float sin_a) +{ + return ConvertFromCPP_ImVec2(ImRotate(ConvertToCPP_ImVec2(v),cos_a,sin_a)); +} +CIMGUI_API float igImLinearSweep(float current,float target,float speed) +{ + return ImLinearSweep(current,target,speed); +} +CIMGUI_API float igImLinearRemapClamp(float s0,float s1,float d0,float d1,float x) +{ + return ImLinearRemapClamp(s0,s1,d0,d1,x); +} +CIMGUI_API ImVec2_c igImMul(const ImVec2_c lhs,const ImVec2_c rhs) +{ + return ConvertFromCPP_ImVec2(ImMul(ConvertToCPP_ImVec2(lhs),ConvertToCPP_ImVec2(rhs))); +} +CIMGUI_API bool igImIsFloatAboveGuaranteedIntegerPrecision(float f) +{ + return ImIsFloatAboveGuaranteedIntegerPrecision(f); +} +CIMGUI_API float igImExponentialMovingAverage(float avg,float sample,int n) +{ + return ImExponentialMovingAverage(avg,sample,n); +} +CIMGUI_API ImVec2_c igImBezierCubicCalc(const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,float t) +{ + return ConvertFromCPP_ImVec2(ImBezierCubicCalc(ConvertToCPP_ImVec2(p1),ConvertToCPP_ImVec2(p2),ConvertToCPP_ImVec2(p3),ConvertToCPP_ImVec2(p4),t)); +} +CIMGUI_API ImVec2_c igImBezierCubicClosestPoint(const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,const ImVec2_c p,int num_segments) +{ + return ConvertFromCPP_ImVec2(ImBezierCubicClosestPoint(ConvertToCPP_ImVec2(p1),ConvertToCPP_ImVec2(p2),ConvertToCPP_ImVec2(p3),ConvertToCPP_ImVec2(p4),ConvertToCPP_ImVec2(p),num_segments)); +} +CIMGUI_API ImVec2_c igImBezierCubicClosestPointCasteljau(const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,const ImVec2_c p4,const ImVec2_c p,float tess_tol) +{ + return ConvertFromCPP_ImVec2(ImBezierCubicClosestPointCasteljau(ConvertToCPP_ImVec2(p1),ConvertToCPP_ImVec2(p2),ConvertToCPP_ImVec2(p3),ConvertToCPP_ImVec2(p4),ConvertToCPP_ImVec2(p),tess_tol)); +} +CIMGUI_API ImVec2_c igImBezierQuadraticCalc(const ImVec2_c p1,const ImVec2_c p2,const ImVec2_c p3,float t) +{ + return ConvertFromCPP_ImVec2(ImBezierQuadraticCalc(ConvertToCPP_ImVec2(p1),ConvertToCPP_ImVec2(p2),ConvertToCPP_ImVec2(p3),t)); +} +CIMGUI_API ImVec2_c igImLineClosestPoint(const ImVec2_c a,const ImVec2_c b,const ImVec2_c p) +{ + return ConvertFromCPP_ImVec2(ImLineClosestPoint(ConvertToCPP_ImVec2(a),ConvertToCPP_ImVec2(b),ConvertToCPP_ImVec2(p))); +} +CIMGUI_API bool igImTriangleContainsPoint(const ImVec2_c a,const ImVec2_c b,const ImVec2_c c,const ImVec2_c p) +{ + return ImTriangleContainsPoint(ConvertToCPP_ImVec2(a),ConvertToCPP_ImVec2(b),ConvertToCPP_ImVec2(c),ConvertToCPP_ImVec2(p)); +} +CIMGUI_API ImVec2_c igImTriangleClosestPoint(const ImVec2_c a,const ImVec2_c b,const ImVec2_c c,const ImVec2_c p) +{ + return ConvertFromCPP_ImVec2(ImTriangleClosestPoint(ConvertToCPP_ImVec2(a),ConvertToCPP_ImVec2(b),ConvertToCPP_ImVec2(c),ConvertToCPP_ImVec2(p))); +} +CIMGUI_API void igImTriangleBarycentricCoords(const ImVec2_c a,const ImVec2_c b,const ImVec2_c c,const ImVec2_c p,float* out_u,float* out_v,float* out_w) +{ + return ImTriangleBarycentricCoords(ConvertToCPP_ImVec2(a),ConvertToCPP_ImVec2(b),ConvertToCPP_ImVec2(c),ConvertToCPP_ImVec2(p),*out_u,*out_v,*out_w); +} +CIMGUI_API float igImTriangleArea(const ImVec2_c a,const ImVec2_c b,const ImVec2_c c) +{ + return ImTriangleArea(ConvertToCPP_ImVec2(a),ConvertToCPP_ImVec2(b),ConvertToCPP_ImVec2(c)); +} +CIMGUI_API bool igImTriangleIsClockwise(const ImVec2_c a,const ImVec2_c b,const ImVec2_c c) +{ + return ImTriangleIsClockwise(ConvertToCPP_ImVec2(a),ConvertToCPP_ImVec2(b),ConvertToCPP_ImVec2(c)); +} +CIMGUI_API ImVec1* ImVec1_ImVec1_Nil(void) +{ + return IM_NEW(ImVec1)(); +} +CIMGUI_API void ImVec1_destroy(ImVec1* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImVec1* ImVec1_ImVec1_Float(float _x) +{ + return IM_NEW(ImVec1)(_x); +} +CIMGUI_API ImVec2i* ImVec2i_ImVec2i_Nil(void) +{ + return IM_NEW(ImVec2i)(); +} +CIMGUI_API void ImVec2i_destroy(ImVec2i* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImVec2i* ImVec2i_ImVec2i_Int(int _x,int _y) +{ + return IM_NEW(ImVec2i)(_x,_y); +} +CIMGUI_API ImVec2ih* ImVec2ih_ImVec2ih_Nil(void) +{ + return IM_NEW(ImVec2ih)(); +} +CIMGUI_API void ImVec2ih_destroy(ImVec2ih* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImVec2ih* ImVec2ih_ImVec2ih_short(short _x,short _y) +{ + return IM_NEW(ImVec2ih)(_x,_y); +} +CIMGUI_API ImVec2ih* ImVec2ih_ImVec2ih_Vec2(const ImVec2_c rhs) +{ + return IM_NEW(ImVec2ih)(ConvertToCPP_ImVec2(rhs)); +} +CIMGUI_API ImRect* ImRect_ImRect_Nil(void) +{ + return IM_NEW(ImRect)(); +} +CIMGUI_API void ImRect_destroy(ImRect* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImRect* ImRect_ImRect_Vec2(const ImVec2_c min,const ImVec2_c max) +{ + return IM_NEW(ImRect)(ConvertToCPP_ImVec2(min),ConvertToCPP_ImVec2(max)); +} +CIMGUI_API ImRect* ImRect_ImRect_Vec4(const ImVec4_c v) +{ + return IM_NEW(ImRect)(ConvertToCPP_ImVec4(v)); +} +CIMGUI_API ImRect* ImRect_ImRect_Float(float x1,float y1,float x2,float y2) +{ + return IM_NEW(ImRect)(x1,y1,x2,y2); +} +CIMGUI_API ImVec2_c ImRect_GetCenter(ImRect* self) +{ + return ConvertFromCPP_ImVec2(self->GetCenter()); +} +CIMGUI_API ImVec2_c ImRect_GetSize(ImRect* self) +{ + return ConvertFromCPP_ImVec2(self->GetSize()); +} +CIMGUI_API float ImRect_GetWidth(ImRect* self) +{ + return self->GetWidth(); +} +CIMGUI_API float ImRect_GetHeight(ImRect* self) +{ + return self->GetHeight(); +} +CIMGUI_API float ImRect_GetArea(ImRect* self) +{ + return self->GetArea(); +} +CIMGUI_API ImVec2_c ImRect_GetTL(ImRect* self) +{ + return ConvertFromCPP_ImVec2(self->GetTL()); +} +CIMGUI_API ImVec2_c ImRect_GetTR(ImRect* self) +{ + return ConvertFromCPP_ImVec2(self->GetTR()); +} +CIMGUI_API ImVec2_c ImRect_GetBL(ImRect* self) +{ + return ConvertFromCPP_ImVec2(self->GetBL()); +} +CIMGUI_API ImVec2_c ImRect_GetBR(ImRect* self) +{ + return ConvertFromCPP_ImVec2(self->GetBR()); +} +CIMGUI_API bool ImRect_Contains_Vec2(ImRect* self,const ImVec2_c p) +{ + return self->Contains(ConvertToCPP_ImVec2(p)); +} +CIMGUI_API bool ImRect_Contains_Rect(ImRect* self,const ImRect_c r) +{ + return self->Contains(ConvertToCPP_ImRect(r)); +} +CIMGUI_API bool ImRect_ContainsWithPad(ImRect* self,const ImVec2_c p,const ImVec2_c pad) +{ + return self->ContainsWithPad(ConvertToCPP_ImVec2(p),ConvertToCPP_ImVec2(pad)); +} +CIMGUI_API bool ImRect_Overlaps(ImRect* self,const ImRect_c r) +{ + return self->Overlaps(ConvertToCPP_ImRect(r)); +} +CIMGUI_API void ImRect_Add_Vec2(ImRect* self,const ImVec2_c p) +{ + return self->Add(ConvertToCPP_ImVec2(p)); +} +CIMGUI_API void ImRect_Add_Rect(ImRect* self,const ImRect_c r) +{ + return self->Add(ConvertToCPP_ImRect(r)); +} +CIMGUI_API void ImRect_AddX(ImRect* self,float x) +{ + return self->AddX(x); +} +CIMGUI_API void ImRect_AddY(ImRect* self,float y) +{ + return self->AddY(y); +} +CIMGUI_API void ImRect_Expand_Float(ImRect* self,const float amount) +{ + return self->Expand(amount); +} +CIMGUI_API void ImRect_Expand_Vec2(ImRect* self,const ImVec2_c amount) +{ + return self->Expand(ConvertToCPP_ImVec2(amount)); +} +CIMGUI_API void ImRect_Translate(ImRect* self,const ImVec2_c d) +{ + return self->Translate(ConvertToCPP_ImVec2(d)); +} +CIMGUI_API void ImRect_TranslateX(ImRect* self,float dx) +{ + return self->TranslateX(dx); +} +CIMGUI_API void ImRect_TranslateY(ImRect* self,float dy) +{ + return self->TranslateY(dy); +} +CIMGUI_API void ImRect_ClipWith(ImRect* self,const ImRect_c r) +{ + return self->ClipWith(ConvertToCPP_ImRect(r)); +} +CIMGUI_API void ImRect_ClipWithFull(ImRect* self,const ImRect_c r) +{ + return self->ClipWithFull(ConvertToCPP_ImRect(r)); +} +CIMGUI_API bool ImRect_IsInverted(ImRect* self) +{ + return self->IsInverted(); +} +CIMGUI_API ImVec4_c ImRect_ToVec4(ImRect* self) +{ + return ConvertFromCPP_ImVec4(self->ToVec4()); +} +CIMGUI_API const ImVec4_c* ImRect_AsVec4(ImRect* self) +{ + return reinterpret_cast(&self->AsVec4()); +} +CIMGUI_API size_t igImBitArrayGetStorageSizeInBytes(int bitcount) +{ + return ImBitArrayGetStorageSizeInBytes(bitcount); +} +CIMGUI_API void igImBitArrayClearAllBits(ImU32* arr,int bitcount) +{ + return ImBitArrayClearAllBits(arr,bitcount); +} +CIMGUI_API bool igImBitArrayTestBit(const ImU32* arr,int n) +{ + return ImBitArrayTestBit(arr,n); +} +CIMGUI_API void igImBitArrayClearBit(ImU32* arr,int n) +{ + return ImBitArrayClearBit(arr,n); +} +CIMGUI_API void igImBitArraySetBit(ImU32* arr,int n) +{ + return ImBitArraySetBit(arr,n); +} +CIMGUI_API void igImBitArraySetBitRange(ImU32* arr,int n,int n2) +{ + return ImBitArraySetBitRange(arr,n,n2); +} +CIMGUI_API void ImBitVector_Create(ImBitVector* self,int sz) +{ + return self->Create(sz); +} +CIMGUI_API void ImBitVector_Clear(ImBitVector* self) +{ + return self->Clear(); +} +CIMGUI_API bool ImBitVector_TestBit(ImBitVector* self,int n) +{ + return self->TestBit(n); +} +CIMGUI_API void ImBitVector_SetBit(ImBitVector* self,int n) +{ + return self->SetBit(n); +} +CIMGUI_API void ImBitVector_ClearBit(ImBitVector* self,int n) +{ + return self->ClearBit(n); +} +CIMGUI_API void ImGuiTextIndex_clear(ImGuiTextIndex* self) +{ + return self->clear(); +} +CIMGUI_API int ImGuiTextIndex_size(ImGuiTextIndex* self) +{ + return self->size(); +} +CIMGUI_API const char* ImGuiTextIndex_get_line_begin(ImGuiTextIndex* self,const char* base,int n) +{ + return self->get_line_begin(base,n); +} +CIMGUI_API const char* ImGuiTextIndex_get_line_end(ImGuiTextIndex* self,const char* base,int n) +{ + return self->get_line_end(base,n); +} +CIMGUI_API void ImGuiTextIndex_append(ImGuiTextIndex* self,const char* base,int old_size,int new_size) +{ + return self->append(base,old_size,new_size); +} +CIMGUI_API ImGuiStoragePair* igImLowerBound(ImGuiStoragePair* in_begin,ImGuiStoragePair* in_end,ImGuiID key) +{ + return ImLowerBound(in_begin,in_end,key); +} +CIMGUI_API ImDrawListSharedData* ImDrawListSharedData_ImDrawListSharedData(void) +{ + return IM_NEW(ImDrawListSharedData)(); +} +CIMGUI_API void ImDrawListSharedData_destroy(ImDrawListSharedData* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImDrawListSharedData_SetCircleTessellationMaxError(ImDrawListSharedData* self,float max_error) +{ + return self->SetCircleTessellationMaxError(max_error); +} +CIMGUI_API ImDrawDataBuilder* ImDrawDataBuilder_ImDrawDataBuilder(void) +{ + return IM_NEW(ImDrawDataBuilder)(); +} +CIMGUI_API void ImDrawDataBuilder_destroy(ImDrawDataBuilder* self) +{ + IM_DELETE(self); +} +CIMGUI_API void* ImGuiStyleVarInfo_GetVarPtr(ImGuiStyleVarInfo* self,void* parent) +{ + return self->GetVarPtr(parent); +} +CIMGUI_API ImGuiStyleMod* ImGuiStyleMod_ImGuiStyleMod_Int(ImGuiStyleVar idx,int v) +{ + return IM_NEW(ImGuiStyleMod)(idx,v); +} +CIMGUI_API void ImGuiStyleMod_destroy(ImGuiStyleMod* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiStyleMod* ImGuiStyleMod_ImGuiStyleMod_Float(ImGuiStyleVar idx,float v) +{ + return IM_NEW(ImGuiStyleMod)(idx,v); +} +CIMGUI_API ImGuiStyleMod* ImGuiStyleMod_ImGuiStyleMod_Vec2(ImGuiStyleVar idx,ImVec2_c v) +{ + return IM_NEW(ImGuiStyleMod)(idx,ConvertToCPP_ImVec2(v)); +} +CIMGUI_API ImGuiComboPreviewData* ImGuiComboPreviewData_ImGuiComboPreviewData(void) +{ + return IM_NEW(ImGuiComboPreviewData)(); +} +CIMGUI_API void ImGuiComboPreviewData_destroy(ImGuiComboPreviewData* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiMenuColumns* ImGuiMenuColumns_ImGuiMenuColumns(void) +{ + return IM_NEW(ImGuiMenuColumns)(); +} +CIMGUI_API void ImGuiMenuColumns_destroy(ImGuiMenuColumns* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiMenuColumns_Update(ImGuiMenuColumns* self,float spacing,bool window_reappearing) +{ + return self->Update(spacing,window_reappearing); +} +CIMGUI_API float ImGuiMenuColumns_DeclColumns(ImGuiMenuColumns* self,float w_icon,float w_label,float w_shortcut,float w_mark) +{ + return self->DeclColumns(w_icon,w_label,w_shortcut,w_mark); +} +CIMGUI_API void ImGuiMenuColumns_CalcNextTotalWidth(ImGuiMenuColumns* self,bool update_offsets) +{ + return self->CalcNextTotalWidth(update_offsets); +} +CIMGUI_API ImGuiInputTextDeactivatedState* ImGuiInputTextDeactivatedState_ImGuiInputTextDeactivatedState(void) +{ + return IM_NEW(ImGuiInputTextDeactivatedState)(); +} +CIMGUI_API void ImGuiInputTextDeactivatedState_destroy(ImGuiInputTextDeactivatedState* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiInputTextDeactivatedState_ClearFreeMemory(ImGuiInputTextDeactivatedState* self) +{ + return self->ClearFreeMemory(); +} +CIMGUI_API ImGuiInputTextState* ImGuiInputTextState_ImGuiInputTextState(void) +{ + return IM_NEW(ImGuiInputTextState)(); +} +CIMGUI_API void ImGuiInputTextState_destroy(ImGuiInputTextState* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiInputTextState_ClearText(ImGuiInputTextState* self) +{ + return self->ClearText(); +} +CIMGUI_API void ImGuiInputTextState_ClearFreeMemory(ImGuiInputTextState* self) +{ + return self->ClearFreeMemory(); +} +CIMGUI_API void ImGuiInputTextState_OnKeyPressed(ImGuiInputTextState* self,int key) +{ + return self->OnKeyPressed(key); +} +CIMGUI_API void ImGuiInputTextState_OnCharPressed(ImGuiInputTextState* self,unsigned int c) +{ + return self->OnCharPressed(c); +} +CIMGUI_API float ImGuiInputTextState_GetPreferredOffsetX(ImGuiInputTextState* self) +{ + return self->GetPreferredOffsetX(); +} +CIMGUI_API const char* ImGuiInputTextState_GetText(ImGuiInputTextState* self) +{ + return self->GetText(); +} +CIMGUI_API void ImGuiInputTextState_CursorAnimReset(ImGuiInputTextState* self) +{ + return self->CursorAnimReset(); +} +CIMGUI_API void ImGuiInputTextState_CursorClamp(ImGuiInputTextState* self) +{ + return self->CursorClamp(); +} +CIMGUI_API bool ImGuiInputTextState_HasSelection(ImGuiInputTextState* self) +{ + return self->HasSelection(); +} +CIMGUI_API void ImGuiInputTextState_ClearSelection(ImGuiInputTextState* self) +{ + return self->ClearSelection(); +} +CIMGUI_API int ImGuiInputTextState_GetCursorPos(ImGuiInputTextState* self) +{ + return self->GetCursorPos(); +} +CIMGUI_API int ImGuiInputTextState_GetSelectionStart(ImGuiInputTextState* self) +{ + return self->GetSelectionStart(); +} +CIMGUI_API int ImGuiInputTextState_GetSelectionEnd(ImGuiInputTextState* self) +{ + return self->GetSelectionEnd(); +} +CIMGUI_API void ImGuiInputTextState_SetSelection(ImGuiInputTextState* self,int start,int end) +{ + return self->SetSelection(start,end); +} +CIMGUI_API void ImGuiInputTextState_SelectAll(ImGuiInputTextState* self) +{ + return self->SelectAll(); +} +CIMGUI_API void ImGuiInputTextState_ReloadUserBufAndSelectAll(ImGuiInputTextState* self) +{ + return self->ReloadUserBufAndSelectAll(); +} +CIMGUI_API void ImGuiInputTextState_ReloadUserBufAndKeepSelection(ImGuiInputTextState* self) +{ + return self->ReloadUserBufAndKeepSelection(); +} +CIMGUI_API void ImGuiInputTextState_ReloadUserBufAndMoveToEnd(ImGuiInputTextState* self) +{ + return self->ReloadUserBufAndMoveToEnd(); +} +CIMGUI_API ImGuiNextWindowData* ImGuiNextWindowData_ImGuiNextWindowData(void) +{ + return IM_NEW(ImGuiNextWindowData)(); +} +CIMGUI_API void ImGuiNextWindowData_destroy(ImGuiNextWindowData* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiNextWindowData_ClearFlags(ImGuiNextWindowData* self) +{ + return self->ClearFlags(); +} +CIMGUI_API ImGuiNextItemData* ImGuiNextItemData_ImGuiNextItemData(void) +{ + return IM_NEW(ImGuiNextItemData)(); +} +CIMGUI_API void ImGuiNextItemData_destroy(ImGuiNextItemData* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiNextItemData_ClearFlags(ImGuiNextItemData* self) +{ + return self->ClearFlags(); +} +CIMGUI_API ImGuiLastItemData* ImGuiLastItemData_ImGuiLastItemData(void) +{ + return IM_NEW(ImGuiLastItemData)(); +} +CIMGUI_API void ImGuiLastItemData_destroy(ImGuiLastItemData* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiErrorRecoveryState* ImGuiErrorRecoveryState_ImGuiErrorRecoveryState(void) +{ + return IM_NEW(ImGuiErrorRecoveryState)(); +} +CIMGUI_API void ImGuiErrorRecoveryState_destroy(ImGuiErrorRecoveryState* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiPtrOrIndex* ImGuiPtrOrIndex_ImGuiPtrOrIndex_Ptr(void* ptr) +{ + return IM_NEW(ImGuiPtrOrIndex)(ptr); +} +CIMGUI_API void ImGuiPtrOrIndex_destroy(ImGuiPtrOrIndex* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiPtrOrIndex* ImGuiPtrOrIndex_ImGuiPtrOrIndex_Int(int index) +{ + return IM_NEW(ImGuiPtrOrIndex)(index); +} +CIMGUI_API ImGuiPopupData* ImGuiPopupData_ImGuiPopupData(void) +{ + return IM_NEW(ImGuiPopupData)(); +} +CIMGUI_API void ImGuiPopupData_destroy(ImGuiPopupData* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiInputEvent* ImGuiInputEvent_ImGuiInputEvent(void) +{ + return IM_NEW(ImGuiInputEvent)(); +} +CIMGUI_API void ImGuiInputEvent_destroy(ImGuiInputEvent* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiKeyRoutingData* ImGuiKeyRoutingData_ImGuiKeyRoutingData(void) +{ + return IM_NEW(ImGuiKeyRoutingData)(); +} +CIMGUI_API void ImGuiKeyRoutingData_destroy(ImGuiKeyRoutingData* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiKeyRoutingTable* ImGuiKeyRoutingTable_ImGuiKeyRoutingTable(void) +{ + return IM_NEW(ImGuiKeyRoutingTable)(); +} +CIMGUI_API void ImGuiKeyRoutingTable_destroy(ImGuiKeyRoutingTable* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiKeyRoutingTable_Clear(ImGuiKeyRoutingTable* self) +{ + return self->Clear(); +} +CIMGUI_API ImGuiKeyOwnerData* ImGuiKeyOwnerData_ImGuiKeyOwnerData(void) +{ + return IM_NEW(ImGuiKeyOwnerData)(); +} +CIMGUI_API void ImGuiKeyOwnerData_destroy(ImGuiKeyOwnerData* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiListClipperRange ImGuiListClipperRange_FromIndices(int min,int max) +{ + return ImGuiListClipperRange::FromIndices(min,max); +} +CIMGUI_API ImGuiListClipperRange ImGuiListClipperRange_FromPositions(float y1,float y2,int off_min,int off_max) +{ + return ImGuiListClipperRange::FromPositions(y1,y2,off_min,off_max); +} +CIMGUI_API ImGuiListClipperData* ImGuiListClipperData_ImGuiListClipperData(void) +{ + return IM_NEW(ImGuiListClipperData)(); +} +CIMGUI_API void ImGuiListClipperData_destroy(ImGuiListClipperData* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiListClipperData_Reset(ImGuiListClipperData* self,ImGuiListClipper* clipper) +{ + return self->Reset(clipper); +} +CIMGUI_API ImGuiNavItemData* ImGuiNavItemData_ImGuiNavItemData(void) +{ + return IM_NEW(ImGuiNavItemData)(); +} +CIMGUI_API void ImGuiNavItemData_destroy(ImGuiNavItemData* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiNavItemData_Clear(ImGuiNavItemData* self) +{ + return self->Clear(); +} +CIMGUI_API ImGuiTypingSelectState* ImGuiTypingSelectState_ImGuiTypingSelectState(void) +{ + return IM_NEW(ImGuiTypingSelectState)(); +} +CIMGUI_API void ImGuiTypingSelectState_destroy(ImGuiTypingSelectState* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiTypingSelectState_Clear(ImGuiTypingSelectState* self) +{ + return self->Clear(); +} +CIMGUI_API ImGuiOldColumnData* ImGuiOldColumnData_ImGuiOldColumnData(void) +{ + return IM_NEW(ImGuiOldColumnData)(); +} +CIMGUI_API void ImGuiOldColumnData_destroy(ImGuiOldColumnData* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiOldColumns* ImGuiOldColumns_ImGuiOldColumns(void) +{ + return IM_NEW(ImGuiOldColumns)(); +} +CIMGUI_API void ImGuiOldColumns_destroy(ImGuiOldColumns* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiBoxSelectState* ImGuiBoxSelectState_ImGuiBoxSelectState(void) +{ + return IM_NEW(ImGuiBoxSelectState)(); +} +CIMGUI_API void ImGuiBoxSelectState_destroy(ImGuiBoxSelectState* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiMultiSelectTempData* ImGuiMultiSelectTempData_ImGuiMultiSelectTempData(void) +{ + return IM_NEW(ImGuiMultiSelectTempData)(); +} +CIMGUI_API void ImGuiMultiSelectTempData_destroy(ImGuiMultiSelectTempData* self) +{ + IM_DELETE(self); +} +CIMGUI_API void ImGuiMultiSelectTempData_Clear(ImGuiMultiSelectTempData* self) +{ + return self->Clear(); +} +CIMGUI_API void ImGuiMultiSelectTempData_ClearIO(ImGuiMultiSelectTempData* self) +{ + return self->ClearIO(); +} +CIMGUI_API ImGuiMultiSelectState* ImGuiMultiSelectState_ImGuiMultiSelectState(void) +{ + return IM_NEW(ImGuiMultiSelectState)(); +} +CIMGUI_API void ImGuiMultiSelectState_destroy(ImGuiMultiSelectState* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiViewportP* ImGuiViewportP_ImGuiViewportP(void) +{ + return IM_NEW(ImGuiViewportP)(); +} +CIMGUI_API void ImGuiViewportP_destroy(ImGuiViewportP* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImVec2_c ImGuiViewportP_CalcWorkRectPos(ImGuiViewportP* self,const ImVec2_c inset_min) +{ + return ConvertFromCPP_ImVec2(self->CalcWorkRectPos(ConvertToCPP_ImVec2(inset_min))); +} +CIMGUI_API ImVec2_c ImGuiViewportP_CalcWorkRectSize(ImGuiViewportP* self,const ImVec2_c inset_min,const ImVec2_c inset_max) +{ + return ConvertFromCPP_ImVec2(self->CalcWorkRectSize(ConvertToCPP_ImVec2(inset_min),ConvertToCPP_ImVec2(inset_max))); +} +CIMGUI_API void ImGuiViewportP_UpdateWorkRect(ImGuiViewportP* self) +{ + return self->UpdateWorkRect(); +} +CIMGUI_API ImRect_c ImGuiViewportP_GetMainRect(ImGuiViewportP* self) +{ + return ConvertFromCPP_ImRect(self->GetMainRect()); +} +CIMGUI_API ImRect_c ImGuiViewportP_GetWorkRect(ImGuiViewportP* self) +{ + return ConvertFromCPP_ImRect(self->GetWorkRect()); +} +CIMGUI_API ImRect_c ImGuiViewportP_GetBuildWorkRect(ImGuiViewportP* self) +{ + return ConvertFromCPP_ImRect(self->GetBuildWorkRect()); +} +CIMGUI_API ImGuiWindowSettings* ImGuiWindowSettings_ImGuiWindowSettings(void) +{ + return IM_NEW(ImGuiWindowSettings)(); +} +CIMGUI_API void ImGuiWindowSettings_destroy(ImGuiWindowSettings* self) +{ + IM_DELETE(self); +} +CIMGUI_API char* ImGuiWindowSettings_GetName(ImGuiWindowSettings* self) +{ + return self->GetName(); +} +CIMGUI_API ImGuiSettingsHandler* ImGuiSettingsHandler_ImGuiSettingsHandler(void) +{ + return IM_NEW(ImGuiSettingsHandler)(); +} +CIMGUI_API void ImGuiSettingsHandler_destroy(ImGuiSettingsHandler* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiDebugAllocInfo* ImGuiDebugAllocInfo_ImGuiDebugAllocInfo(void) +{ + return IM_NEW(ImGuiDebugAllocInfo)(); +} +CIMGUI_API void ImGuiDebugAllocInfo_destroy(ImGuiDebugAllocInfo* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiStackLevelInfo* ImGuiStackLevelInfo_ImGuiStackLevelInfo(void) +{ + return IM_NEW(ImGuiStackLevelInfo)(); +} +CIMGUI_API void ImGuiStackLevelInfo_destroy(ImGuiStackLevelInfo* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiDebugItemPathQuery* ImGuiDebugItemPathQuery_ImGuiDebugItemPathQuery(void) +{ + return IM_NEW(ImGuiDebugItemPathQuery)(); +} +CIMGUI_API void ImGuiDebugItemPathQuery_destroy(ImGuiDebugItemPathQuery* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiIDStackTool* ImGuiIDStackTool_ImGuiIDStackTool(void) +{ + return IM_NEW(ImGuiIDStackTool)(); +} +CIMGUI_API void ImGuiIDStackTool_destroy(ImGuiIDStackTool* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiContextHook* ImGuiContextHook_ImGuiContextHook(void) +{ + return IM_NEW(ImGuiContextHook)(); +} +CIMGUI_API void ImGuiContextHook_destroy(ImGuiContextHook* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiContext* ImGuiContext_ImGuiContext(ImFontAtlas* shared_font_atlas) +{ + return IM_NEW(ImGuiContext)(shared_font_atlas); +} +CIMGUI_API void ImGuiContext_destroy(ImGuiContext* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiWindow* ImGuiWindow_ImGuiWindow(ImGuiContext* context,const char* name) +{ + return IM_NEW(ImGuiWindow)(context,name); +} +CIMGUI_API void ImGuiWindow_destroy(ImGuiWindow* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiID ImGuiWindow_GetID_Str(ImGuiWindow* self,const char* str,const char* str_end) +{ + return self->GetID(str,str_end); +} +CIMGUI_API ImGuiID ImGuiWindow_GetID_Ptr(ImGuiWindow* self,const void* ptr) +{ + return self->GetID(ptr); +} +CIMGUI_API ImGuiID ImGuiWindow_GetID_Int(ImGuiWindow* self,int n) +{ + return self->GetID(n); +} +CIMGUI_API ImGuiID ImGuiWindow_GetIDFromPos(ImGuiWindow* self,const ImVec2_c p_abs) +{ + return self->GetIDFromPos(ConvertToCPP_ImVec2(p_abs)); +} +CIMGUI_API ImGuiID ImGuiWindow_GetIDFromRectangle(ImGuiWindow* self,const ImRect_c r_abs) +{ + return self->GetIDFromRectangle(ConvertToCPP_ImRect(r_abs)); +} +CIMGUI_API ImRect_c ImGuiWindow_Rect(ImGuiWindow* self) +{ + return ConvertFromCPP_ImRect(self->Rect()); +} +CIMGUI_API ImRect_c ImGuiWindow_TitleBarRect(ImGuiWindow* self) +{ + return ConvertFromCPP_ImRect(self->TitleBarRect()); +} +CIMGUI_API ImRect_c ImGuiWindow_MenuBarRect(ImGuiWindow* self) +{ + return ConvertFromCPP_ImRect(self->MenuBarRect()); +} +CIMGUI_API ImGuiTabItem* ImGuiTabItem_ImGuiTabItem(void) +{ + return IM_NEW(ImGuiTabItem)(); +} +CIMGUI_API void ImGuiTabItem_destroy(ImGuiTabItem* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiTabBar* ImGuiTabBar_ImGuiTabBar(void) +{ + return IM_NEW(ImGuiTabBar)(); +} +CIMGUI_API void ImGuiTabBar_destroy(ImGuiTabBar* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiTableColumn* ImGuiTableColumn_ImGuiTableColumn(void) +{ + return IM_NEW(ImGuiTableColumn)(); +} +CIMGUI_API void ImGuiTableColumn_destroy(ImGuiTableColumn* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiTableInstanceData* ImGuiTableInstanceData_ImGuiTableInstanceData(void) +{ + return IM_NEW(ImGuiTableInstanceData)(); +} +CIMGUI_API void ImGuiTableInstanceData_destroy(ImGuiTableInstanceData* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiTable* ImGuiTable_ImGuiTable(void) +{ + return IM_NEW(ImGuiTable)(); +} +CIMGUI_API void ImGuiTable_destroy(ImGuiTable* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiTableTempData* ImGuiTableTempData_ImGuiTableTempData(void) +{ + return IM_NEW(ImGuiTableTempData)(); +} +CIMGUI_API void ImGuiTableTempData_destroy(ImGuiTableTempData* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiTableColumnSettings* ImGuiTableColumnSettings_ImGuiTableColumnSettings(void) +{ + return IM_NEW(ImGuiTableColumnSettings)(); +} +CIMGUI_API void ImGuiTableColumnSettings_destroy(ImGuiTableColumnSettings* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiTableSettings* ImGuiTableSettings_ImGuiTableSettings(void) +{ + return IM_NEW(ImGuiTableSettings)(); +} +CIMGUI_API void ImGuiTableSettings_destroy(ImGuiTableSettings* self) +{ + IM_DELETE(self); +} +CIMGUI_API ImGuiTableColumnSettings* ImGuiTableSettings_GetColumnSettings(ImGuiTableSettings* self) +{ + return self->GetColumnSettings(); +} +CIMGUI_API void igTableOpenContextMenu(int column_n) +{ + return ImGui::TableOpenContextMenu(column_n); +} +CIMGUI_API void igTableSetColumnWidth(int column_n,float width) +{ + return ImGui::TableSetColumnWidth(column_n,width); +} +CIMGUI_API void igTableSetColumnSortDirection(int column_n,ImGuiSortDirection sort_direction,bool append_to_sort_specs) +{ + return ImGui::TableSetColumnSortDirection(column_n,sort_direction,append_to_sort_specs); +} +CIMGUI_API int igTableGetHoveredRow() +{ + return ImGui::TableGetHoveredRow(); +} +CIMGUI_API float igTableGetHeaderRowHeight() +{ + return ImGui::TableGetHeaderRowHeight(); +} +CIMGUI_API float igTableGetHeaderAngledMaxLabelWidth() +{ + return ImGui::TableGetHeaderAngledMaxLabelWidth(); +} +CIMGUI_API void igTablePushBackgroundChannel() +{ + return ImGui::TablePushBackgroundChannel(); +} +CIMGUI_API void igTablePopBackgroundChannel() +{ + return ImGui::TablePopBackgroundChannel(); +} +CIMGUI_API void igTablePushColumnChannel(int column_n) +{ + return ImGui::TablePushColumnChannel(column_n); +} +CIMGUI_API void igTablePopColumnChannel() +{ + return ImGui::TablePopColumnChannel(); +} +CIMGUI_API void igTableAngledHeadersRowEx(ImGuiID row_id,float angle,float max_label_width,const ImGuiTableHeaderData* data,int data_count) +{ + return ImGui::TableAngledHeadersRowEx(row_id,angle,max_label_width,data,data_count); +} +CIMGUI_API ImGuiTable* igGetCurrentTable() +{ + return ImGui::GetCurrentTable(); +} +CIMGUI_API ImGuiTable* igTableFindByID(ImGuiID id) +{ + return ImGui::TableFindByID(id); +} +CIMGUI_API bool igBeginTableEx(const char* name,ImGuiID id,int columns_count,ImGuiTableFlags flags,const ImVec2_c outer_size,float inner_width) +{ + return ImGui::BeginTableEx(name,id,columns_count,flags,ConvertToCPP_ImVec2(outer_size),inner_width); +} +CIMGUI_API void igTableBeginInitMemory(ImGuiTable* table,int columns_count) +{ + return ImGui::TableBeginInitMemory(table,columns_count); +} +CIMGUI_API void igTableApplyQueuedRequests(ImGuiTable* table) +{ + return ImGui::TableApplyQueuedRequests(table); +} +CIMGUI_API void igTableSetupDrawChannels(ImGuiTable* table) +{ + return ImGui::TableSetupDrawChannels(table); +} +CIMGUI_API void igTableUpdateLayout(ImGuiTable* table) +{ + return ImGui::TableUpdateLayout(table); +} +CIMGUI_API void igTableUpdateBorders(ImGuiTable* table) +{ + return ImGui::TableUpdateBorders(table); +} +CIMGUI_API void igTableUpdateColumnsWeightFromWidth(ImGuiTable* table) +{ + return ImGui::TableUpdateColumnsWeightFromWidth(table); +} +CIMGUI_API void igTableApplyExternalUnclipRect(ImGuiTable* table,ImRect* rect) +{ + return ImGui::TableApplyExternalUnclipRect(table,*rect); +} +CIMGUI_API void igTableDrawBorders(ImGuiTable* table) +{ + return ImGui::TableDrawBorders(table); +} +CIMGUI_API void igTableDrawDefaultContextMenu(ImGuiTable* table,ImGuiTableFlags flags_for_section_to_display) +{ + return ImGui::TableDrawDefaultContextMenu(table,flags_for_section_to_display); +} +CIMGUI_API bool igTableBeginContextMenuPopup(ImGuiTable* table) +{ + return ImGui::TableBeginContextMenuPopup(table); +} +CIMGUI_API void igTableMergeDrawChannels(ImGuiTable* table) +{ + return ImGui::TableMergeDrawChannels(table); +} +CIMGUI_API ImGuiTableInstanceData* igTableGetInstanceData(ImGuiTable* table,int instance_no) +{ + return ImGui::TableGetInstanceData(table,instance_no); +} +CIMGUI_API ImGuiID igTableGetInstanceID(ImGuiTable* table,int instance_no) +{ + return ImGui::TableGetInstanceID(table,instance_no); +} +CIMGUI_API void igTableFixDisplayOrder(ImGuiTable* table) +{ + return ImGui::TableFixDisplayOrder(table); +} +CIMGUI_API void igTableSortSpecsSanitize(ImGuiTable* table) +{ + return ImGui::TableSortSpecsSanitize(table); +} +CIMGUI_API void igTableSortSpecsBuild(ImGuiTable* table) +{ + return ImGui::TableSortSpecsBuild(table); +} +CIMGUI_API ImGuiSortDirection igTableGetColumnNextSortDirection(ImGuiTableColumn* column) +{ + return ImGui::TableGetColumnNextSortDirection(column); +} +CIMGUI_API void igTableFixColumnSortDirection(ImGuiTable* table,ImGuiTableColumn* column) +{ + return ImGui::TableFixColumnSortDirection(table,column); +} +CIMGUI_API float igTableGetColumnWidthAuto(ImGuiTable* table,ImGuiTableColumn* column) +{ + return ImGui::TableGetColumnWidthAuto(table,column); +} +CIMGUI_API void igTableBeginRow(ImGuiTable* table) +{ + return ImGui::TableBeginRow(table); +} +CIMGUI_API void igTableEndRow(ImGuiTable* table) +{ + return ImGui::TableEndRow(table); +} +CIMGUI_API void igTableBeginCell(ImGuiTable* table,int column_n) +{ + return ImGui::TableBeginCell(table,column_n); +} +CIMGUI_API void igTableEndCell(ImGuiTable* table) +{ + return ImGui::TableEndCell(table); +} +CIMGUI_API ImRect_c igTableGetCellBgRect(const ImGuiTable* table,int column_n) +{ + return ConvertFromCPP_ImRect(ImGui::TableGetCellBgRect(table,column_n)); +} +CIMGUI_API const char* igTableGetColumnName_TablePtr(const ImGuiTable* table,int column_n) +{ + return ImGui::TableGetColumnName(table,column_n); +} +CIMGUI_API ImGuiID igTableGetColumnResizeID(ImGuiTable* table,int column_n,int instance_no) +{ + return ImGui::TableGetColumnResizeID(table,column_n,instance_no); +} +CIMGUI_API float igTableCalcMaxColumnWidth(const ImGuiTable* table,int column_n) +{ + return ImGui::TableCalcMaxColumnWidth(table,column_n); +} +CIMGUI_API void igTableSetColumnWidthAutoSingle(ImGuiTable* table,int column_n) +{ + return ImGui::TableSetColumnWidthAutoSingle(table,column_n); +} +CIMGUI_API void igTableSetColumnWidthAutoAll(ImGuiTable* table) +{ + return ImGui::TableSetColumnWidthAutoAll(table); +} +CIMGUI_API void igTableSetColumnDisplayOrder(ImGuiTable* table,int column_n,int dst_order) +{ + return ImGui::TableSetColumnDisplayOrder(table,column_n,dst_order); +} +CIMGUI_API void igTableQueueSetColumnDisplayOrder(ImGuiTable* table,int column_n,int dst_order) +{ + return ImGui::TableQueueSetColumnDisplayOrder(table,column_n,dst_order); +} +CIMGUI_API void igTableRemove(ImGuiTable* table) +{ + return ImGui::TableRemove(table); +} +CIMGUI_API void igTableGcCompactTransientBuffers_TablePtr(ImGuiTable* table) +{ + return ImGui::TableGcCompactTransientBuffers(table); +} +CIMGUI_API void igTableGcCompactTransientBuffers_TableTempDataPtr(ImGuiTableTempData* table) +{ + return ImGui::TableGcCompactTransientBuffers(table); +} +CIMGUI_API void igTableGcCompactSettings() +{ + return ImGui::TableGcCompactSettings(); +} +CIMGUI_API void igTableLoadSettings(ImGuiTable* table) +{ + return ImGui::TableLoadSettings(table); +} +CIMGUI_API void igTableSaveSettings(ImGuiTable* table) +{ + return ImGui::TableSaveSettings(table); +} +CIMGUI_API void igTableResetSettings(ImGuiTable* table) +{ + return ImGui::TableResetSettings(table); +} +CIMGUI_API ImGuiTableSettings* igTableGetBoundSettings(ImGuiTable* table) +{ + return ImGui::TableGetBoundSettings(table); +} +CIMGUI_API void igTableSettingsAddSettingsHandler() +{ + return ImGui::TableSettingsAddSettingsHandler(); +} +CIMGUI_API ImGuiTableSettings* igTableSettingsCreate(ImGuiID id,int columns_count) +{ + return ImGui::TableSettingsCreate(id,columns_count); +} +CIMGUI_API ImGuiTableSettings* igTableSettingsFindByID(ImGuiID id) +{ + return ImGui::TableSettingsFindByID(id); +} +CIMGUI_API void igSetWindowClipRectBeforeSetChannel(ImGuiWindow* window,const ImRect_c clip_rect) +{ + return ImGui::SetWindowClipRectBeforeSetChannel(window,ConvertToCPP_ImRect(clip_rect)); +} +CIMGUI_API void igBeginColumns(const char* str_id,int count,ImGuiOldColumnFlags flags) +{ + return ImGui::BeginColumns(str_id,count,flags); +} +CIMGUI_API void igEndColumns() +{ + return ImGui::EndColumns(); +} +CIMGUI_API void igPushColumnClipRect(int column_index) +{ + return ImGui::PushColumnClipRect(column_index); +} +CIMGUI_API void igPushColumnsBackground() +{ + return ImGui::PushColumnsBackground(); +} +CIMGUI_API void igPopColumnsBackground() +{ + return ImGui::PopColumnsBackground(); +} +CIMGUI_API ImGuiID igGetColumnsID(const char* str_id,int count) +{ + return ImGui::GetColumnsID(str_id,count); +} +CIMGUI_API ImGuiOldColumns* igFindOrCreateColumns(ImGuiWindow* window,ImGuiID id) +{ + return ImGui::FindOrCreateColumns(window,id); +} +CIMGUI_API float igGetColumnOffsetFromNorm(const ImGuiOldColumns* columns,float offset_norm) +{ + return ImGui::GetColumnOffsetFromNorm(columns,offset_norm); +} +CIMGUI_API float igGetColumnNormFromOffset(const ImGuiOldColumns* columns,float offset) +{ + return ImGui::GetColumnNormFromOffset(columns,offset); +} +CIMGUI_API ImGuiIO* igGetIO_ContextPtr(ImGuiContext* ctx) +{ + return &ImGui::GetIO(ctx); +} +CIMGUI_API ImGuiPlatformIO* igGetPlatformIO_ContextPtr(ImGuiContext* ctx) +{ + return &ImGui::GetPlatformIO(ctx); +} +CIMGUI_API float igGetScale() +{ + return ImGui::GetScale(); +} +CIMGUI_API ImGuiWindow* igGetCurrentWindowRead() +{ + return ImGui::GetCurrentWindowRead(); +} +CIMGUI_API ImGuiWindow* igGetCurrentWindow() +{ + return ImGui::GetCurrentWindow(); +} +CIMGUI_API ImGuiWindow* igFindWindowByID(ImGuiID id) +{ + return ImGui::FindWindowByID(id); +} +CIMGUI_API ImGuiWindow* igFindWindowByName(const char* name) +{ + return ImGui::FindWindowByName(name); +} +CIMGUI_API void igUpdateWindowParentAndRootLinks(ImGuiWindow* window,ImGuiWindowFlags flags,ImGuiWindow* parent_window) +{ + return ImGui::UpdateWindowParentAndRootLinks(window,flags,parent_window); +} +CIMGUI_API void igUpdateWindowSkipRefresh(ImGuiWindow* window) +{ + return ImGui::UpdateWindowSkipRefresh(window); +} +CIMGUI_API ImVec2_c igCalcWindowNextAutoFitSize(ImGuiWindow* window) +{ + return ConvertFromCPP_ImVec2(ImGui::CalcWindowNextAutoFitSize(window)); +} +CIMGUI_API bool igIsWindowChildOf(ImGuiWindow* window,ImGuiWindow* potential_parent,bool popup_hierarchy) +{ + return ImGui::IsWindowChildOf(window,potential_parent,popup_hierarchy); +} +CIMGUI_API bool igIsWindowInBeginStack(ImGuiWindow* window) +{ + return ImGui::IsWindowInBeginStack(window); +} +CIMGUI_API bool igIsWindowWithinBeginStackOf(ImGuiWindow* window,ImGuiWindow* potential_parent) +{ + return ImGui::IsWindowWithinBeginStackOf(window,potential_parent); +} +CIMGUI_API bool igIsWindowAbove(ImGuiWindow* potential_above,ImGuiWindow* potential_below) +{ + return ImGui::IsWindowAbove(potential_above,potential_below); +} +CIMGUI_API bool igIsWindowNavFocusable(ImGuiWindow* window) +{ + return ImGui::IsWindowNavFocusable(window); +} +CIMGUI_API void igSetWindowPos_WindowPtr(ImGuiWindow* window,const ImVec2_c pos,ImGuiCond cond) +{ + return ImGui::SetWindowPos(window,ConvertToCPP_ImVec2(pos),cond); +} +CIMGUI_API void igSetWindowSize_WindowPtr(ImGuiWindow* window,const ImVec2_c size,ImGuiCond cond) +{ + return ImGui::SetWindowSize(window,ConvertToCPP_ImVec2(size),cond); +} +CIMGUI_API void igSetWindowCollapsed_WindowPtr(ImGuiWindow* window,bool collapsed,ImGuiCond cond) +{ + return ImGui::SetWindowCollapsed(window,collapsed,cond); +} +CIMGUI_API void igSetWindowHitTestHole(ImGuiWindow* window,const ImVec2_c pos,const ImVec2_c size) +{ + return ImGui::SetWindowHitTestHole(window,ConvertToCPP_ImVec2(pos),ConvertToCPP_ImVec2(size)); +} +CIMGUI_API void igSetWindowHiddenAndSkipItemsForCurrentFrame(ImGuiWindow* window) +{ + return ImGui::SetWindowHiddenAndSkipItemsForCurrentFrame(window); +} +CIMGUI_API void igSetWindowParentWindowForFocusRoute(ImGuiWindow* window,ImGuiWindow* parent_window) +{ + return ImGui::SetWindowParentWindowForFocusRoute(window,parent_window); +} +CIMGUI_API ImRect_c igWindowRectAbsToRel(ImGuiWindow* window,const ImRect_c r) +{ + return ConvertFromCPP_ImRect(ImGui::WindowRectAbsToRel(window,ConvertToCPP_ImRect(r))); +} +CIMGUI_API ImRect_c igWindowRectRelToAbs(ImGuiWindow* window,const ImRect_c r) +{ + return ConvertFromCPP_ImRect(ImGui::WindowRectRelToAbs(window,ConvertToCPP_ImRect(r))); +} +CIMGUI_API ImVec2_c igWindowPosAbsToRel(ImGuiWindow* window,const ImVec2_c p) +{ + return ConvertFromCPP_ImVec2(ImGui::WindowPosAbsToRel(window,ConvertToCPP_ImVec2(p))); +} +CIMGUI_API ImVec2_c igWindowPosRelToAbs(ImGuiWindow* window,const ImVec2_c p) +{ + return ConvertFromCPP_ImVec2(ImGui::WindowPosRelToAbs(window,ConvertToCPP_ImVec2(p))); +} +CIMGUI_API void igFocusWindow(ImGuiWindow* window,ImGuiFocusRequestFlags flags) +{ + return ImGui::FocusWindow(window,flags); +} +CIMGUI_API void igFocusTopMostWindowUnderOne(ImGuiWindow* under_this_window,ImGuiWindow* ignore_window,ImGuiViewport* filter_viewport,ImGuiFocusRequestFlags flags) +{ + return ImGui::FocusTopMostWindowUnderOne(under_this_window,ignore_window,filter_viewport,flags); +} +CIMGUI_API void igBringWindowToFocusFront(ImGuiWindow* window) +{ + return ImGui::BringWindowToFocusFront(window); +} +CIMGUI_API void igBringWindowToDisplayFront(ImGuiWindow* window) +{ + return ImGui::BringWindowToDisplayFront(window); +} +CIMGUI_API void igBringWindowToDisplayBack(ImGuiWindow* window) +{ + return ImGui::BringWindowToDisplayBack(window); +} +CIMGUI_API void igBringWindowToDisplayBehind(ImGuiWindow* window,ImGuiWindow* above_window) +{ + return ImGui::BringWindowToDisplayBehind(window,above_window); +} +CIMGUI_API int igFindWindowDisplayIndex(ImGuiWindow* window) +{ + return ImGui::FindWindowDisplayIndex(window); +} +CIMGUI_API ImGuiWindow* igFindBottomMostVisibleWindowWithinBeginStack(ImGuiWindow* window) +{ + return ImGui::FindBottomMostVisibleWindowWithinBeginStack(window); +} +CIMGUI_API void igSetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags) +{ + return ImGui::SetNextWindowRefreshPolicy(flags); +} +CIMGUI_API void igRegisterUserTexture(ImTextureData* tex) +{ + return ImGui::RegisterUserTexture(tex); +} +CIMGUI_API void igUnregisterUserTexture(ImTextureData* tex) +{ + return ImGui::UnregisterUserTexture(tex); +} +CIMGUI_API void igRegisterFontAtlas(ImFontAtlas* atlas) +{ + return ImGui::RegisterFontAtlas(atlas); +} +CIMGUI_API void igUnregisterFontAtlas(ImFontAtlas* atlas) +{ + return ImGui::UnregisterFontAtlas(atlas); +} +CIMGUI_API void igSetCurrentFont(ImFont* font,float font_size_before_scaling,float font_size_after_scaling) +{ + return ImGui::SetCurrentFont(font,font_size_before_scaling,font_size_after_scaling); +} +CIMGUI_API void igUpdateCurrentFontSize(float restore_font_size_after_scaling) +{ + return ImGui::UpdateCurrentFontSize(restore_font_size_after_scaling); +} +CIMGUI_API void igSetFontRasterizerDensity(float rasterizer_density) +{ + return ImGui::SetFontRasterizerDensity(rasterizer_density); +} +CIMGUI_API float igGetFontRasterizerDensity() +{ + return ImGui::GetFontRasterizerDensity(); +} +CIMGUI_API float igGetRoundedFontSize(float size) +{ + return ImGui::GetRoundedFontSize(size); +} +CIMGUI_API ImFont* igGetDefaultFont() +{ + return ImGui::GetDefaultFont(); +} +CIMGUI_API void igPushPasswordFont() +{ + return ImGui::PushPasswordFont(); +} +CIMGUI_API void igPopPasswordFont() +{ + return ImGui::PopPasswordFont(); +} +CIMGUI_API ImDrawList* igGetForegroundDrawList_WindowPtr(ImGuiWindow* window) +{ + return ImGui::GetForegroundDrawList(window); +} +CIMGUI_API ImDrawList* igGetBackgroundDrawList_ViewportPtr(ImGuiViewport* viewport) +{ + return ImGui::GetBackgroundDrawList(viewport); +} +CIMGUI_API ImDrawList* igGetForegroundDrawList_ViewportPtr(ImGuiViewport* viewport) +{ + return ImGui::GetForegroundDrawList(viewport); +} +CIMGUI_API void igAddDrawListToDrawDataEx(ImDrawData* draw_data,ImVector_ImDrawListPtr* out_list,ImDrawList* draw_list) +{ + return ImGui::AddDrawListToDrawDataEx(draw_data,out_list,draw_list); +} +CIMGUI_API void igInitialize() +{ + return ImGui::Initialize(); +} +CIMGUI_API void igShutdown() +{ + return ImGui::Shutdown(); +} +CIMGUI_API void igSetContextName(ImGuiContext* ctx,const char* name) +{ + return ImGui::SetContextName(ctx,name); +} +CIMGUI_API ImGuiID igAddContextHook(ImGuiContext* ctx,const ImGuiContextHook* hook) +{ + return ImGui::AddContextHook(ctx,hook); +} +CIMGUI_API void igRemoveContextHook(ImGuiContext* ctx,ImGuiID hook_to_remove) +{ + return ImGui::RemoveContextHook(ctx,hook_to_remove); +} +CIMGUI_API void igCallContextHooks(ImGuiContext* ctx,ImGuiContextHookType type) +{ + return ImGui::CallContextHooks(ctx,type); +} +CIMGUI_API void igUpdateInputEvents(bool trickle_fast_inputs) +{ + return ImGui::UpdateInputEvents(trickle_fast_inputs); +} +CIMGUI_API void igUpdateHoveredWindowAndCaptureFlags(const ImVec2_c mouse_pos) +{ + return ImGui::UpdateHoveredWindowAndCaptureFlags(ConvertToCPP_ImVec2(mouse_pos)); +} +CIMGUI_API void igFindHoveredWindowEx(const ImVec2_c pos,bool find_first_and_in_any_viewport,ImGuiWindow** out_hovered_window,ImGuiWindow** out_hovered_window_under_moving_window) +{ + return ImGui::FindHoveredWindowEx(ConvertToCPP_ImVec2(pos),find_first_and_in_any_viewport,out_hovered_window,out_hovered_window_under_moving_window); +} +CIMGUI_API void igStartMouseMovingWindow(ImGuiWindow* window) +{ + return ImGui::StartMouseMovingWindow(window); +} +CIMGUI_API void igStopMouseMovingWindow() +{ + return ImGui::StopMouseMovingWindow(); +} +CIMGUI_API void igUpdateMouseMovingWindowNewFrame() +{ + return ImGui::UpdateMouseMovingWindowNewFrame(); +} +CIMGUI_API void igUpdateMouseMovingWindowEndFrame() +{ + return ImGui::UpdateMouseMovingWindowEndFrame(); +} +CIMGUI_API ImGuiViewport* igGetWindowViewport() +{ + return ImGui::GetWindowViewport(); +} +CIMGUI_API void igScaleWindowsInViewport(ImGuiViewportP* viewport,float scale) +{ + return ImGui::ScaleWindowsInViewport(viewport,scale); +} +CIMGUI_API void igSetWindowViewport(ImGuiWindow* window,ImGuiViewportP* viewport) +{ + return ImGui::SetWindowViewport(window,viewport); +} +CIMGUI_API void igMarkIniSettingsDirty_Nil() +{ + return ImGui::MarkIniSettingsDirty(); +} +CIMGUI_API void igMarkIniSettingsDirty_WindowPtr(ImGuiWindow* window) +{ + return ImGui::MarkIniSettingsDirty(window); +} +CIMGUI_API void igClearIniSettings() +{ + return ImGui::ClearIniSettings(); +} +CIMGUI_API void igAddSettingsHandler(const ImGuiSettingsHandler* handler) +{ + return ImGui::AddSettingsHandler(handler); +} +CIMGUI_API void igRemoveSettingsHandler(const char* type_name) +{ + return ImGui::RemoveSettingsHandler(type_name); +} +CIMGUI_API ImGuiSettingsHandler* igFindSettingsHandler(const char* type_name) +{ + return ImGui::FindSettingsHandler(type_name); +} +CIMGUI_API ImGuiWindowSettings* igCreateNewWindowSettings(const char* name) +{ + return ImGui::CreateNewWindowSettings(name); +} +CIMGUI_API ImGuiWindowSettings* igFindWindowSettingsByID(ImGuiID id) +{ + return ImGui::FindWindowSettingsByID(id); +} +CIMGUI_API ImGuiWindowSettings* igFindWindowSettingsByWindow(ImGuiWindow* window) +{ + return ImGui::FindWindowSettingsByWindow(window); +} +CIMGUI_API void igClearWindowSettings(const char* name) +{ + return ImGui::ClearWindowSettings(name); +} +CIMGUI_API void igLocalizeRegisterEntries(const ImGuiLocEntry* entries,int count) +{ + return ImGui::LocalizeRegisterEntries(entries,count); +} +CIMGUI_API const char* igLocalizeGetMsg(ImGuiLocKey key) +{ + return ImGui::LocalizeGetMsg(key); +} +CIMGUI_API void igSetScrollX_WindowPtr(ImGuiWindow* window,float scroll_x) +{ + return ImGui::SetScrollX(window,scroll_x); +} +CIMGUI_API void igSetScrollY_WindowPtr(ImGuiWindow* window,float scroll_y) +{ + return ImGui::SetScrollY(window,scroll_y); +} +CIMGUI_API void igSetScrollFromPosX_WindowPtr(ImGuiWindow* window,float local_x,float center_x_ratio) +{ + return ImGui::SetScrollFromPosX(window,local_x,center_x_ratio); +} +CIMGUI_API void igSetScrollFromPosY_WindowPtr(ImGuiWindow* window,float local_y,float center_y_ratio) +{ + return ImGui::SetScrollFromPosY(window,local_y,center_y_ratio); +} +CIMGUI_API void igScrollToItem(ImGuiScrollFlags flags) +{ + return ImGui::ScrollToItem(flags); +} +CIMGUI_API void igScrollToRect(ImGuiWindow* window,const ImRect_c rect,ImGuiScrollFlags flags) +{ + return ImGui::ScrollToRect(window,ConvertToCPP_ImRect(rect),flags); +} +CIMGUI_API ImVec2_c igScrollToRectEx(ImGuiWindow* window,const ImRect_c rect,ImGuiScrollFlags flags) +{ + return ConvertFromCPP_ImVec2(ImGui::ScrollToRectEx(window,ConvertToCPP_ImRect(rect),flags)); +} +CIMGUI_API void igScrollToBringRectIntoView(ImGuiWindow* window,const ImRect_c rect) +{ + return ImGui::ScrollToBringRectIntoView(window,ConvertToCPP_ImRect(rect)); +} +CIMGUI_API ImGuiItemStatusFlags igGetItemStatusFlags() +{ + return ImGui::GetItemStatusFlags(); +} +CIMGUI_API ImGuiID igGetActiveID() +{ + return ImGui::GetActiveID(); +} +CIMGUI_API ImGuiID igGetFocusID() +{ + return ImGui::GetFocusID(); +} +CIMGUI_API void igSetActiveID(ImGuiID id,ImGuiWindow* window) +{ + return ImGui::SetActiveID(id,window); +} +CIMGUI_API void igSetFocusID(ImGuiID id,ImGuiWindow* window) +{ + return ImGui::SetFocusID(id,window); +} +CIMGUI_API void igClearActiveID() +{ + return ImGui::ClearActiveID(); +} +CIMGUI_API ImGuiID igGetHoveredID() +{ + return ImGui::GetHoveredID(); +} +CIMGUI_API void igSetHoveredID(ImGuiID id) +{ + return ImGui::SetHoveredID(id); +} +CIMGUI_API void igKeepAliveID(ImGuiID id) +{ + return ImGui::KeepAliveID(id); +} +CIMGUI_API void igMarkItemEdited(ImGuiID id) +{ + return ImGui::MarkItemEdited(id); +} +CIMGUI_API void igPushOverrideID(ImGuiID id) +{ + return ImGui::PushOverrideID(id); +} +CIMGUI_API ImGuiID igGetIDWithSeed_Str(const char* str_id_begin,const char* str_id_end,ImGuiID seed) +{ + return ImGui::GetIDWithSeed(str_id_begin,str_id_end,seed); +} +CIMGUI_API ImGuiID igGetIDWithSeed_Int(int n,ImGuiID seed) +{ + return ImGui::GetIDWithSeed(n,seed); +} +CIMGUI_API void igItemSize_Vec2(const ImVec2_c size,float text_baseline_y) +{ + return ImGui::ItemSize(ConvertToCPP_ImVec2(size),text_baseline_y); +} +CIMGUI_API void igItemSize_Rect(const ImRect_c bb,float text_baseline_y) +{ + return ImGui::ItemSize(ConvertToCPP_ImRect(bb),text_baseline_y); +} +CIMGUI_API bool igItemAdd(const ImRect_c bb,ImGuiID id,const ImRect* nav_bb,ImGuiItemFlags extra_flags) +{ + return ImGui::ItemAdd(ConvertToCPP_ImRect(bb),id,nav_bb,extra_flags); +} +CIMGUI_API bool igItemHoverable(const ImRect_c bb,ImGuiID id,ImGuiItemFlags item_flags) +{ + return ImGui::ItemHoverable(ConvertToCPP_ImRect(bb),id,item_flags); +} +CIMGUI_API bool igIsWindowContentHoverable(ImGuiWindow* window,ImGuiHoveredFlags flags) +{ + return ImGui::IsWindowContentHoverable(window,flags); +} +CIMGUI_API bool igIsClippedEx(const ImRect_c bb,ImGuiID id) +{ + return ImGui::IsClippedEx(ConvertToCPP_ImRect(bb),id); +} +CIMGUI_API void igSetLastItemData(ImGuiID item_id,ImGuiItemFlags item_flags,ImGuiItemStatusFlags status_flags,const ImRect_c item_rect) +{ + return ImGui::SetLastItemData(item_id,item_flags,status_flags,ConvertToCPP_ImRect(item_rect)); +} +CIMGUI_API ImVec2_c igCalcItemSize(ImVec2_c size,float default_w,float default_h) +{ + return ConvertFromCPP_ImVec2(ImGui::CalcItemSize(ConvertToCPP_ImVec2(size),default_w,default_h)); +} +CIMGUI_API float igCalcWrapWidthForPos(const ImVec2_c pos,float wrap_pos_x) +{ + return ImGui::CalcWrapWidthForPos(ConvertToCPP_ImVec2(pos),wrap_pos_x); +} +CIMGUI_API void igPushMultiItemsWidths(int components,float width_full) +{ + return ImGui::PushMultiItemsWidths(components,width_full); +} +CIMGUI_API void igShrinkWidths(ImGuiShrinkWidthItem* items,int count,float width_excess,float width_min) +{ + return ImGui::ShrinkWidths(items,count,width_excess,width_min); +} +CIMGUI_API void igCalcClipRectVisibleItemsY(const ImRect_c clip_rect,const ImVec2_c pos,float items_height,int* out_visible_start,int* out_visible_end) +{ + return ImGui::CalcClipRectVisibleItemsY(ConvertToCPP_ImRect(clip_rect),ConvertToCPP_ImVec2(pos),items_height,out_visible_start,out_visible_end); +} +CIMGUI_API const ImGuiStyleVarInfo* igGetStyleVarInfo(ImGuiStyleVar idx) +{ + return ImGui::GetStyleVarInfo(idx); +} +CIMGUI_API void igBeginDisabledOverrideReenable() +{ + return ImGui::BeginDisabledOverrideReenable(); +} +CIMGUI_API void igEndDisabledOverrideReenable() +{ + return ImGui::EndDisabledOverrideReenable(); +} +CIMGUI_API void igLogBegin(ImGuiLogFlags flags,int auto_open_depth) +{ + return ImGui::LogBegin(flags,auto_open_depth); +} +CIMGUI_API void igLogToBuffer(int auto_open_depth) +{ + return ImGui::LogToBuffer(auto_open_depth); +} +CIMGUI_API void igLogRenderedText(const ImVec2_c* ref_pos,const char* text,const char* text_end) +{ + return ImGui::LogRenderedText(reinterpret_cast(ref_pos),text,text_end); +} +CIMGUI_API void igLogSetNextTextDecoration(const char* prefix,const char* suffix) +{ + return ImGui::LogSetNextTextDecoration(prefix,suffix); +} +CIMGUI_API bool igBeginChildEx(const char* name,ImGuiID id,const ImVec2_c size_arg,ImGuiChildFlags child_flags,ImGuiWindowFlags window_flags) +{ + return ImGui::BeginChildEx(name,id,ConvertToCPP_ImVec2(size_arg),child_flags,window_flags); +} +CIMGUI_API ImGuiWindow* igFindFrontMostVisibleChildWindow(ImGuiWindow* window) +{ + return ImGui::FindFrontMostVisibleChildWindow(window); +} +CIMGUI_API bool igBeginPopupEx(ImGuiID id,ImGuiWindowFlags extra_window_flags) +{ + return ImGui::BeginPopupEx(id,extra_window_flags); +} +CIMGUI_API bool igBeginPopupMenuEx(ImGuiID id,const char* label,ImGuiWindowFlags extra_window_flags) +{ + return ImGui::BeginPopupMenuEx(id,label,extra_window_flags); +} +CIMGUI_API void igOpenPopupEx(ImGuiID id,ImGuiPopupFlags popup_flags) +{ + return ImGui::OpenPopupEx(id,popup_flags); +} +CIMGUI_API void igClosePopupToLevel(int remaining,bool restore_focus_to_window_under_popup) +{ + return ImGui::ClosePopupToLevel(remaining,restore_focus_to_window_under_popup); +} +CIMGUI_API void igClosePopupsOverWindow(ImGuiWindow* ref_window,bool restore_focus_to_window_under_popup) +{ + return ImGui::ClosePopupsOverWindow(ref_window,restore_focus_to_window_under_popup); +} +CIMGUI_API void igClosePopupsExceptModals() +{ + return ImGui::ClosePopupsExceptModals(); +} +CIMGUI_API bool igIsPopupOpen_ID(ImGuiID id,ImGuiPopupFlags popup_flags) +{ + return ImGui::IsPopupOpen(id,popup_flags); +} +CIMGUI_API ImRect_c igGetPopupAllowedExtentRect(ImGuiWindow* window) +{ + return ConvertFromCPP_ImRect(ImGui::GetPopupAllowedExtentRect(window)); +} +CIMGUI_API ImGuiWindow* igGetTopMostPopupModal() +{ + return ImGui::GetTopMostPopupModal(); +} +CIMGUI_API ImGuiWindow* igGetTopMostAndVisiblePopupModal() +{ + return ImGui::GetTopMostAndVisiblePopupModal(); +} +CIMGUI_API ImGuiWindow* igFindBlockingModal(ImGuiWindow* window) +{ + return ImGui::FindBlockingModal(window); +} +CIMGUI_API ImVec2_c igFindBestWindowPosForPopup(ImGuiWindow* window) +{ + return ConvertFromCPP_ImVec2(ImGui::FindBestWindowPosForPopup(window)); +} +CIMGUI_API ImVec2_c igFindBestWindowPosForPopupEx(const ImVec2_c ref_pos,const ImVec2_c size,ImGuiDir* last_dir,const ImRect_c r_outer,const ImRect_c r_avoid,ImGuiPopupPositionPolicy policy) +{ + return ConvertFromCPP_ImVec2(ImGui::FindBestWindowPosForPopupEx(ConvertToCPP_ImVec2(ref_pos),ConvertToCPP_ImVec2(size),last_dir,ConvertToCPP_ImRect(r_outer),ConvertToCPP_ImRect(r_avoid),policy)); +} +CIMGUI_API ImGuiMouseButton igGetMouseButtonFromPopupFlags(ImGuiPopupFlags flags) +{ + return ImGui::GetMouseButtonFromPopupFlags(flags); +} +CIMGUI_API bool igIsPopupOpenRequestForItem(ImGuiPopupFlags flags,ImGuiID id) +{ + return ImGui::IsPopupOpenRequestForItem(flags,id); +} +CIMGUI_API bool igIsPopupOpenRequestForWindow(ImGuiPopupFlags flags) +{ + return ImGui::IsPopupOpenRequestForWindow(flags); +} +CIMGUI_API bool igBeginTooltipEx(ImGuiTooltipFlags tooltip_flags,ImGuiWindowFlags extra_window_flags) +{ + return ImGui::BeginTooltipEx(tooltip_flags,extra_window_flags); +} +CIMGUI_API bool igBeginTooltipHidden() +{ + return ImGui::BeginTooltipHidden(); +} +CIMGUI_API bool igBeginViewportSideBar(const char* name,ImGuiViewport* viewport,ImGuiDir dir,float size,ImGuiWindowFlags window_flags) +{ + return ImGui::BeginViewportSideBar(name,viewport,dir,size,window_flags); +} +CIMGUI_API bool igBeginMenuEx(const char* label,const char* icon,bool enabled) +{ + return ImGui::BeginMenuEx(label,icon,enabled); +} +CIMGUI_API bool igMenuItemEx(const char* label,const char* icon,const char* shortcut,bool selected,bool enabled) +{ + return ImGui::MenuItemEx(label,icon,shortcut,selected,enabled); +} +CIMGUI_API bool igBeginComboPopup(ImGuiID popup_id,const ImRect_c bb,ImGuiComboFlags flags) +{ + return ImGui::BeginComboPopup(popup_id,ConvertToCPP_ImRect(bb),flags); +} +CIMGUI_API bool igBeginComboPreview() +{ + return ImGui::BeginComboPreview(); +} +CIMGUI_API void igEndComboPreview() +{ + return ImGui::EndComboPreview(); +} +CIMGUI_API void igNavInitWindow(ImGuiWindow* window,bool force_reinit) +{ + return ImGui::NavInitWindow(window,force_reinit); +} +CIMGUI_API void igNavInitRequestApplyResult() +{ + return ImGui::NavInitRequestApplyResult(); +} +CIMGUI_API bool igNavMoveRequestButNoResultYet() +{ + return ImGui::NavMoveRequestButNoResultYet(); +} +CIMGUI_API void igNavMoveRequestSubmit(ImGuiDir move_dir,ImGuiDir clip_dir,ImGuiNavMoveFlags move_flags,ImGuiScrollFlags scroll_flags) +{ + return ImGui::NavMoveRequestSubmit(move_dir,clip_dir,move_flags,scroll_flags); +} +CIMGUI_API void igNavMoveRequestForward(ImGuiDir move_dir,ImGuiDir clip_dir,ImGuiNavMoveFlags move_flags,ImGuiScrollFlags scroll_flags) +{ + return ImGui::NavMoveRequestForward(move_dir,clip_dir,move_flags,scroll_flags); +} +CIMGUI_API void igNavMoveRequestResolveWithLastItem(ImGuiNavItemData* result) +{ + return ImGui::NavMoveRequestResolveWithLastItem(result); +} +CIMGUI_API void igNavMoveRequestResolveWithPastTreeNode(ImGuiNavItemData* result,const ImGuiTreeNodeStackData* tree_node_data) +{ + return ImGui::NavMoveRequestResolveWithPastTreeNode(result,tree_node_data); +} +CIMGUI_API void igNavMoveRequestCancel() +{ + return ImGui::NavMoveRequestCancel(); +} +CIMGUI_API void igNavMoveRequestApplyResult() +{ + return ImGui::NavMoveRequestApplyResult(); +} +CIMGUI_API void igNavMoveRequestTryWrapping(ImGuiWindow* window,ImGuiNavMoveFlags move_flags) +{ + return ImGui::NavMoveRequestTryWrapping(window,move_flags); +} +CIMGUI_API void igNavHighlightActivated(ImGuiID id) +{ + return ImGui::NavHighlightActivated(id); +} +CIMGUI_API void igNavClearPreferredPosForAxis(ImGuiAxis axis) +{ + return ImGui::NavClearPreferredPosForAxis(axis); +} +CIMGUI_API void igSetNavCursorVisibleAfterMove() +{ + return ImGui::SetNavCursorVisibleAfterMove(); +} +CIMGUI_API void igNavUpdateCurrentWindowIsScrollPushableX() +{ + return ImGui::NavUpdateCurrentWindowIsScrollPushableX(); +} +CIMGUI_API void igSetNavWindow(ImGuiWindow* window) +{ + return ImGui::SetNavWindow(window); +} +CIMGUI_API void igSetNavID(ImGuiID id,ImGuiNavLayer nav_layer,ImGuiID focus_scope_id,const ImRect_c rect_rel) +{ + return ImGui::SetNavID(id,nav_layer,focus_scope_id,ConvertToCPP_ImRect(rect_rel)); +} +CIMGUI_API void igSetNavFocusScope(ImGuiID focus_scope_id) +{ + return ImGui::SetNavFocusScope(focus_scope_id); +} +CIMGUI_API void igFocusItem() +{ + return ImGui::FocusItem(); +} +CIMGUI_API void igActivateItemByID(ImGuiID id) +{ + return ImGui::ActivateItemByID(id); +} +CIMGUI_API bool igIsNamedKey(ImGuiKey key) +{ + return ImGui::IsNamedKey(key); +} +CIMGUI_API bool igIsNamedKeyOrMod(ImGuiKey key) +{ + return ImGui::IsNamedKeyOrMod(key); +} +CIMGUI_API bool igIsLegacyKey(ImGuiKey key) +{ + return ImGui::IsLegacyKey(key); +} +CIMGUI_API bool igIsKeyboardKey(ImGuiKey key) +{ + return ImGui::IsKeyboardKey(key); +} +CIMGUI_API bool igIsGamepadKey(ImGuiKey key) +{ + return ImGui::IsGamepadKey(key); +} +CIMGUI_API bool igIsMouseKey(ImGuiKey key) +{ + return ImGui::IsMouseKey(key); +} +CIMGUI_API bool igIsAliasKey(ImGuiKey key) +{ + return ImGui::IsAliasKey(key); +} +CIMGUI_API bool igIsLRModKey(ImGuiKey key) +{ + return ImGui::IsLRModKey(key); +} +CIMGUI_API ImGuiKeyChord igFixupKeyChord(ImGuiKeyChord key_chord) +{ + return ImGui::FixupKeyChord(key_chord); +} +CIMGUI_API ImGuiKey igConvertSingleModFlagToKey(ImGuiKey key) +{ + return ImGui::ConvertSingleModFlagToKey(key); +} +CIMGUI_API ImGuiKeyData* igGetKeyData_ContextPtr(ImGuiContext* ctx,ImGuiKey key) +{ + return ImGui::GetKeyData(ctx,key); +} +CIMGUI_API ImGuiKeyData* igGetKeyData_Key(ImGuiKey key) +{ + return ImGui::GetKeyData(key); +} +CIMGUI_API const char* igGetKeyChordName(ImGuiKeyChord key_chord) +{ + return ImGui::GetKeyChordName(key_chord); +} +CIMGUI_API ImGuiKey igMouseButtonToKey(ImGuiMouseButton button) +{ + return ImGui::MouseButtonToKey(button); +} +CIMGUI_API bool igIsMouseDragPastThreshold(ImGuiMouseButton button,float lock_threshold) +{ + return ImGui::IsMouseDragPastThreshold(button,lock_threshold); +} +CIMGUI_API ImVec2_c igGetKeyMagnitude2d(ImGuiKey key_left,ImGuiKey key_right,ImGuiKey key_up,ImGuiKey key_down) +{ + return ConvertFromCPP_ImVec2(ImGui::GetKeyMagnitude2d(key_left,key_right,key_up,key_down)); +} +CIMGUI_API float igGetNavTweakPressedAmount(ImGuiAxis axis) +{ + return ImGui::GetNavTweakPressedAmount(axis); +} +CIMGUI_API int igCalcTypematicRepeatAmount(float t0,float t1,float repeat_delay,float repeat_rate) +{ + return ImGui::CalcTypematicRepeatAmount(t0,t1,repeat_delay,repeat_rate); +} +CIMGUI_API void igGetTypematicRepeatRate(ImGuiInputFlags flags,float* repeat_delay,float* repeat_rate) +{ + return ImGui::GetTypematicRepeatRate(flags,repeat_delay,repeat_rate); +} +CIMGUI_API void igTeleportMousePos(const ImVec2_c pos) +{ + return ImGui::TeleportMousePos(ConvertToCPP_ImVec2(pos)); +} +CIMGUI_API void igSetActiveIdUsingAllKeyboardKeys() +{ + return ImGui::SetActiveIdUsingAllKeyboardKeys(); +} +CIMGUI_API bool igIsActiveIdUsingNavDir(ImGuiDir dir) +{ + return ImGui::IsActiveIdUsingNavDir(dir); +} +CIMGUI_API ImGuiID igGetKeyOwner(ImGuiKey key) +{ + return ImGui::GetKeyOwner(key); +} +CIMGUI_API void igSetKeyOwner(ImGuiKey key,ImGuiID owner_id,ImGuiInputFlags flags) +{ + return ImGui::SetKeyOwner(key,owner_id,flags); +} +CIMGUI_API void igSetKeyOwnersForKeyChord(ImGuiKeyChord key,ImGuiID owner_id,ImGuiInputFlags flags) +{ + return ImGui::SetKeyOwnersForKeyChord(key,owner_id,flags); +} +CIMGUI_API bool igSetItemKeyOwner_InputFlags(ImGuiKey key,ImGuiInputFlags flags) +{ + return ImGui::SetItemKeyOwner(key,flags); +} +CIMGUI_API bool igTestKeyOwner(ImGuiKey key,ImGuiID owner_id) +{ + return ImGui::TestKeyOwner(key,owner_id); +} +CIMGUI_API ImGuiKeyOwnerData* igGetKeyOwnerData(ImGuiContext* ctx,ImGuiKey key) +{ + return ImGui::GetKeyOwnerData(ctx,key); +} +CIMGUI_API bool igIsKeyDown_ID(ImGuiKey key,ImGuiID owner_id) +{ + return ImGui::IsKeyDown(key,owner_id); +} +CIMGUI_API bool igIsKeyPressed_InputFlags(ImGuiKey key,ImGuiInputFlags flags,ImGuiID owner_id) +{ + return ImGui::IsKeyPressed(key,flags,owner_id); +} +CIMGUI_API bool igIsKeyReleased_ID(ImGuiKey key,ImGuiID owner_id) +{ + return ImGui::IsKeyReleased(key,owner_id); +} +CIMGUI_API bool igIsKeyChordPressed_InputFlags(ImGuiKeyChord key_chord,ImGuiInputFlags flags,ImGuiID owner_id) +{ + return ImGui::IsKeyChordPressed(key_chord,flags,owner_id); +} +CIMGUI_API bool igIsMouseDown_ID(ImGuiMouseButton button,ImGuiID owner_id) +{ + return ImGui::IsMouseDown(button,owner_id); +} +CIMGUI_API bool igIsMouseClicked_InputFlags(ImGuiMouseButton button,ImGuiInputFlags flags,ImGuiID owner_id) +{ + return ImGui::IsMouseClicked(button,flags,owner_id); +} +CIMGUI_API bool igIsMouseReleased_ID(ImGuiMouseButton button,ImGuiID owner_id) +{ + return ImGui::IsMouseReleased(button,owner_id); +} +CIMGUI_API bool igIsMouseDoubleClicked_ID(ImGuiMouseButton button,ImGuiID owner_id) +{ + return ImGui::IsMouseDoubleClicked(button,owner_id); +} +CIMGUI_API bool igShortcut_ID(ImGuiKeyChord key_chord,ImGuiInputFlags flags,ImGuiID owner_id) +{ + return ImGui::Shortcut(key_chord,flags,owner_id); +} +CIMGUI_API bool igSetShortcutRouting(ImGuiKeyChord key_chord,ImGuiInputFlags flags,ImGuiID owner_id) +{ + return ImGui::SetShortcutRouting(key_chord,flags,owner_id); +} +CIMGUI_API bool igTestShortcutRouting(ImGuiKeyChord key_chord,ImGuiID owner_id) +{ + return ImGui::TestShortcutRouting(key_chord,owner_id); +} +CIMGUI_API ImGuiKeyRoutingData* igGetShortcutRoutingData(ImGuiKeyChord key_chord) +{ + return ImGui::GetShortcutRoutingData(key_chord); +} +CIMGUI_API void igPushFocusScope(ImGuiID id) +{ + return ImGui::PushFocusScope(id); +} +CIMGUI_API void igPopFocusScope() +{ + return ImGui::PopFocusScope(); +} +CIMGUI_API bool igIsInNavFocusRoute(ImGuiID focus_scope_id) +{ + return ImGui::IsInNavFocusRoute(focus_scope_id); +} +CIMGUI_API ImGuiID igGetCurrentFocusScope() +{ + return ImGui::GetCurrentFocusScope(); +} +CIMGUI_API bool igIsDragDropActive() +{ + return ImGui::IsDragDropActive(); +} +CIMGUI_API bool igBeginDragDropTargetCustom(const ImRect_c bb,ImGuiID id) +{ + return ImGui::BeginDragDropTargetCustom(ConvertToCPP_ImRect(bb),id); +} +CIMGUI_API bool igBeginDragDropTargetViewport(ImGuiViewport* viewport,const ImRect* p_bb) +{ + return ImGui::BeginDragDropTargetViewport(viewport,p_bb); +} +CIMGUI_API void igClearDragDrop() +{ + return ImGui::ClearDragDrop(); +} +CIMGUI_API bool igIsDragDropPayloadBeingAccepted() +{ + return ImGui::IsDragDropPayloadBeingAccepted(); +} +CIMGUI_API void igRenderDragDropTargetRectForItem(const ImRect_c bb) +{ + return ImGui::RenderDragDropTargetRectForItem(ConvertToCPP_ImRect(bb)); +} +CIMGUI_API void igRenderDragDropTargetRectEx(ImDrawList* draw_list,const ImRect_c bb,float rounding) +{ + return ImGui::RenderDragDropTargetRectEx(draw_list,ConvertToCPP_ImRect(bb),rounding); +} +CIMGUI_API ImGuiTypingSelectRequest* igGetTypingSelectRequest(ImGuiTypingSelectFlags flags) +{ + return ImGui::GetTypingSelectRequest(flags); +} +CIMGUI_API int igTypingSelectFindMatch(ImGuiTypingSelectRequest* req,int items_count,const char*(*get_item_name_func)(void*,int),void* user_data,int nav_item_idx) +{ + return ImGui::TypingSelectFindMatch(req,items_count,get_item_name_func,user_data,nav_item_idx); +} +CIMGUI_API int igTypingSelectFindNextSingleCharMatch(ImGuiTypingSelectRequest* req,int items_count,const char*(*get_item_name_func)(void*,int),void* user_data,int nav_item_idx) +{ + return ImGui::TypingSelectFindNextSingleCharMatch(req,items_count,get_item_name_func,user_data,nav_item_idx); +} +CIMGUI_API int igTypingSelectFindBestLeadingMatch(ImGuiTypingSelectRequest* req,int items_count,const char*(*get_item_name_func)(void*,int),void* user_data) +{ + return ImGui::TypingSelectFindBestLeadingMatch(req,items_count,get_item_name_func,user_data); +} +CIMGUI_API bool igBeginBoxSelect(const ImRect_c scope_rect,ImGuiWindow* window,ImGuiID box_select_id,ImGuiMultiSelectFlags ms_flags) +{ + return ImGui::BeginBoxSelect(ConvertToCPP_ImRect(scope_rect),window,box_select_id,ms_flags); +} +CIMGUI_API void igEndBoxSelect(const ImRect_c scope_rect,ImGuiMultiSelectFlags ms_flags) +{ + return ImGui::EndBoxSelect(ConvertToCPP_ImRect(scope_rect),ms_flags); +} +CIMGUI_API void igMultiSelectItemHeader(ImGuiID id,bool* p_selected,ImGuiButtonFlags* p_button_flags) +{ + return ImGui::MultiSelectItemHeader(id,p_selected,p_button_flags); +} +CIMGUI_API void igMultiSelectItemFooter(ImGuiID id,bool* p_selected,bool* p_pressed) +{ + return ImGui::MultiSelectItemFooter(id,p_selected,p_pressed); +} +CIMGUI_API void igMultiSelectAddSetAll(ImGuiMultiSelectTempData* ms,bool selected) +{ + return ImGui::MultiSelectAddSetAll(ms,selected); +} +CIMGUI_API void igMultiSelectAddSetRange(ImGuiMultiSelectTempData* ms,bool selected,int range_dir,ImGuiSelectionUserData first_item,ImGuiSelectionUserData last_item) +{ + return ImGui::MultiSelectAddSetRange(ms,selected,range_dir,first_item,last_item); +} +CIMGUI_API ImGuiBoxSelectState* igGetBoxSelectState(ImGuiID id) +{ + return ImGui::GetBoxSelectState(id); +} +CIMGUI_API ImGuiMultiSelectState* igGetMultiSelectState(ImGuiID id) +{ + return ImGui::GetMultiSelectState(id); +} +CIMGUI_API ImGuiTabBar* igGetCurrentTabBar() +{ + return ImGui::GetCurrentTabBar(); +} +CIMGUI_API ImGuiTabBar* igTabBarFindByID(ImGuiID id) +{ + return ImGui::TabBarFindByID(id); +} +CIMGUI_API void igTabBarRemove(ImGuiTabBar* tab_bar) +{ + return ImGui::TabBarRemove(tab_bar); +} +CIMGUI_API bool igBeginTabBarEx(ImGuiTabBar* tab_bar,const ImRect_c bb,ImGuiTabBarFlags flags) +{ + return ImGui::BeginTabBarEx(tab_bar,ConvertToCPP_ImRect(bb),flags); +} +CIMGUI_API ImGuiTabItem* igTabBarFindTabByID(ImGuiTabBar* tab_bar,ImGuiID tab_id) +{ + return ImGui::TabBarFindTabByID(tab_bar,tab_id); +} +CIMGUI_API ImGuiTabItem* igTabBarFindTabByOrder(ImGuiTabBar* tab_bar,int order) +{ + return ImGui::TabBarFindTabByOrder(tab_bar,order); +} +CIMGUI_API ImGuiTabItem* igTabBarGetCurrentTab(ImGuiTabBar* tab_bar) +{ + return ImGui::TabBarGetCurrentTab(tab_bar); +} +CIMGUI_API int igTabBarGetTabOrder(ImGuiTabBar* tab_bar,ImGuiTabItem* tab) +{ + return ImGui::TabBarGetTabOrder(tab_bar,tab); +} +CIMGUI_API const char* igTabBarGetTabName(ImGuiTabBar* tab_bar,ImGuiTabItem* tab) +{ + return ImGui::TabBarGetTabName(tab_bar,tab); +} +CIMGUI_API void igTabBarRemoveTab(ImGuiTabBar* tab_bar,ImGuiID tab_id) +{ + return ImGui::TabBarRemoveTab(tab_bar,tab_id); +} +CIMGUI_API void igTabBarCloseTab(ImGuiTabBar* tab_bar,ImGuiTabItem* tab) +{ + return ImGui::TabBarCloseTab(tab_bar,tab); +} +CIMGUI_API void igTabBarQueueFocus_TabItemPtr(ImGuiTabBar* tab_bar,ImGuiTabItem* tab) +{ + return ImGui::TabBarQueueFocus(tab_bar,tab); +} +CIMGUI_API void igTabBarQueueFocus_Str(ImGuiTabBar* tab_bar,const char* tab_name) +{ + return ImGui::TabBarQueueFocus(tab_bar,tab_name); +} +CIMGUI_API void igTabBarQueueReorder(ImGuiTabBar* tab_bar,ImGuiTabItem* tab,int offset) +{ + return ImGui::TabBarQueueReorder(tab_bar,tab,offset); +} +CIMGUI_API void igTabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar,ImGuiTabItem* tab,ImVec2_c mouse_pos) +{ + return ImGui::TabBarQueueReorderFromMousePos(tab_bar,tab,ConvertToCPP_ImVec2(mouse_pos)); +} +CIMGUI_API bool igTabBarProcessReorder(ImGuiTabBar* tab_bar) +{ + return ImGui::TabBarProcessReorder(tab_bar); +} +CIMGUI_API bool igTabItemEx(ImGuiTabBar* tab_bar,const char* label,bool* p_open,ImGuiTabItemFlags flags,ImGuiWindow* docked_window) +{ + return ImGui::TabItemEx(tab_bar,label,p_open,flags,docked_window); +} +CIMGUI_API void igTabItemSpacing(const char* str_id,ImGuiTabItemFlags flags,float width) +{ + return ImGui::TabItemSpacing(str_id,flags,width); +} +CIMGUI_API ImVec2_c igTabItemCalcSize_Str(const char* label,bool has_close_button_or_unsaved_marker) +{ + return ConvertFromCPP_ImVec2(ImGui::TabItemCalcSize(label,has_close_button_or_unsaved_marker)); +} +CIMGUI_API ImVec2_c igTabItemCalcSize_WindowPtr(ImGuiWindow* window) +{ + return ConvertFromCPP_ImVec2(ImGui::TabItemCalcSize(window)); +} +CIMGUI_API void igTabItemBackground(ImDrawList* draw_list,const ImRect_c bb,ImGuiTabItemFlags flags,ImU32 col) +{ + return ImGui::TabItemBackground(draw_list,ConvertToCPP_ImRect(bb),flags,col); +} +CIMGUI_API void igTabItemLabelAndCloseButton(ImDrawList* draw_list,const ImRect_c bb,ImGuiTabItemFlags flags,ImVec2_c frame_padding,const char* label,ImGuiID tab_id,ImGuiID close_button_id,bool is_contents_visible,bool* out_just_closed,bool* out_text_clipped) +{ + return ImGui::TabItemLabelAndCloseButton(draw_list,ConvertToCPP_ImRect(bb),flags,ConvertToCPP_ImVec2(frame_padding),label,tab_id,close_button_id,is_contents_visible,out_just_closed,out_text_clipped); +} +CIMGUI_API void igRenderText(ImVec2_c pos,const char* text,const char* text_end,bool hide_text_after_hash) +{ + return ImGui::RenderText(ConvertToCPP_ImVec2(pos),text,text_end,hide_text_after_hash); +} +CIMGUI_API void igRenderTextWrapped(ImVec2_c pos,const char* text,const char* text_end,float wrap_width) +{ + return ImGui::RenderTextWrapped(ConvertToCPP_ImVec2(pos),text,text_end,wrap_width); +} +CIMGUI_API void igRenderTextClipped(const ImVec2_c pos_min,const ImVec2_c pos_max,const char* text,const char* text_end,const ImVec2_c* text_size_if_known,const ImVec2_c align,const ImRect* clip_rect) +{ + return ImGui::RenderTextClipped(ConvertToCPP_ImVec2(pos_min),ConvertToCPP_ImVec2(pos_max),text,text_end,reinterpret_cast(text_size_if_known),ConvertToCPP_ImVec2(align),clip_rect); +} +CIMGUI_API void igRenderTextClippedEx(ImDrawList* draw_list,const ImVec2_c pos_min,const ImVec2_c pos_max,const char* text,const char* text_end,const ImVec2_c* text_size_if_known,const ImVec2_c align,const ImRect* clip_rect) +{ + return ImGui::RenderTextClippedEx(draw_list,ConvertToCPP_ImVec2(pos_min),ConvertToCPP_ImVec2(pos_max),text,text_end,reinterpret_cast(text_size_if_known),ConvertToCPP_ImVec2(align),clip_rect); +} +CIMGUI_API void igRenderTextEllipsis(ImDrawList* draw_list,const ImVec2_c pos_min,const ImVec2_c pos_max,float ellipsis_max_x,const char* text,const char* text_end,const ImVec2_c* text_size_if_known) +{ + return ImGui::RenderTextEllipsis(draw_list,ConvertToCPP_ImVec2(pos_min),ConvertToCPP_ImVec2(pos_max),ellipsis_max_x,text,text_end,reinterpret_cast(text_size_if_known)); +} +CIMGUI_API void igRenderFrame(ImVec2_c p_min,ImVec2_c p_max,ImU32 fill_col,bool borders,float rounding) +{ + return ImGui::RenderFrame(ConvertToCPP_ImVec2(p_min),ConvertToCPP_ImVec2(p_max),fill_col,borders,rounding); +} +CIMGUI_API void igRenderFrameBorder(ImVec2_c p_min,ImVec2_c p_max,float rounding) +{ + return ImGui::RenderFrameBorder(ConvertToCPP_ImVec2(p_min),ConvertToCPP_ImVec2(p_max),rounding); +} +CIMGUI_API void igRenderColorComponentMarker(const ImRect_c bb,ImU32 col,float rounding) +{ + return ImGui::RenderColorComponentMarker(ConvertToCPP_ImRect(bb),col,rounding); +} +CIMGUI_API void igRenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list,ImVec2_c p_min,ImVec2_c p_max,ImU32 fill_col,float grid_step,ImVec2_c grid_off,float rounding,ImDrawFlags flags) +{ + return ImGui::RenderColorRectWithAlphaCheckerboard(draw_list,ConvertToCPP_ImVec2(p_min),ConvertToCPP_ImVec2(p_max),fill_col,grid_step,ConvertToCPP_ImVec2(grid_off),rounding,flags); +} +CIMGUI_API void igRenderNavCursor(const ImRect_c bb,ImGuiID id,ImGuiNavRenderCursorFlags flags) +{ + return ImGui::RenderNavCursor(ConvertToCPP_ImRect(bb),id,flags); +} +CIMGUI_API const char* igFindRenderedTextEnd(const char* text,const char* text_end) +{ + return ImGui::FindRenderedTextEnd(text,text_end); +} +CIMGUI_API void igRenderMouseCursor(ImVec2_c pos,float scale,ImGuiMouseCursor mouse_cursor,ImU32 col_fill,ImU32 col_border,ImU32 col_shadow) +{ + return ImGui::RenderMouseCursor(ConvertToCPP_ImVec2(pos),scale,mouse_cursor,col_fill,col_border,col_shadow); +} +CIMGUI_API void igRenderArrow(ImDrawList* draw_list,ImVec2_c pos,ImU32 col,ImGuiDir dir,float scale) +{ + return ImGui::RenderArrow(draw_list,ConvertToCPP_ImVec2(pos),col,dir,scale); +} +CIMGUI_API void igRenderBullet(ImDrawList* draw_list,ImVec2_c pos,ImU32 col) +{ + return ImGui::RenderBullet(draw_list,ConvertToCPP_ImVec2(pos),col); +} +CIMGUI_API void igRenderCheckMark(ImDrawList* draw_list,ImVec2_c pos,ImU32 col,float sz) +{ + return ImGui::RenderCheckMark(draw_list,ConvertToCPP_ImVec2(pos),col,sz); +} +CIMGUI_API void igRenderArrowPointingAt(ImDrawList* draw_list,ImVec2_c pos,ImVec2_c half_sz,ImGuiDir direction,ImU32 col) +{ + return ImGui::RenderArrowPointingAt(draw_list,ConvertToCPP_ImVec2(pos),ConvertToCPP_ImVec2(half_sz),direction,col); +} +CIMGUI_API void igRenderRectFilledInRangeH(ImDrawList* draw_list,const ImRect_c rect,ImU32 col,float fill_x0,float fill_x1,float rounding) +{ + return ImGui::RenderRectFilledInRangeH(draw_list,ConvertToCPP_ImRect(rect),col,fill_x0,fill_x1,rounding); +} +CIMGUI_API void igRenderRectFilledWithHole(ImDrawList* draw_list,const ImRect_c outer,const ImRect_c inner,ImU32 col,float rounding) +{ + return ImGui::RenderRectFilledWithHole(draw_list,ConvertToCPP_ImRect(outer),ConvertToCPP_ImRect(inner),col,rounding); +} +CIMGUI_API ImDrawFlags igCalcRoundingFlagsForRectInRect(const ImRect_c r_in,const ImRect_c r_outer,float threshold) +{ + return ImGui::CalcRoundingFlagsForRectInRect(ConvertToCPP_ImRect(r_in),ConvertToCPP_ImRect(r_outer),threshold); +} +CIMGUI_API void igTextEx(const char* text,const char* text_end,ImGuiTextFlags flags) +{ + return ImGui::TextEx(text,text_end,flags); +} +CIMGUI_API void igTextAligned(float align_x,float size_x,const char* fmt,...) +{ + va_list args; + va_start(args, fmt); + ImGui::TextAlignedV(align_x,size_x,fmt,args); + va_end(args); +} +#ifdef CIMGUI_VARGS0 +CIMGUI_API void igTextAligned0(float align_x,float size_x,const char* fmt) +{ + return igTextAligned(align_x,size_x,fmt); +} +#endif +CIMGUI_API void igTextAlignedV(float align_x,float size_x,const char* fmt,va_list args) +{ + return ImGui::TextAlignedV(align_x,size_x,fmt,args); +} +CIMGUI_API bool igButtonEx(const char* label,const ImVec2_c size_arg,ImGuiButtonFlags flags) +{ + return ImGui::ButtonEx(label,ConvertToCPP_ImVec2(size_arg),flags); +} +CIMGUI_API bool igArrowButtonEx(const char* str_id,ImGuiDir dir,ImVec2_c size_arg,ImGuiButtonFlags flags) +{ + return ImGui::ArrowButtonEx(str_id,dir,ConvertToCPP_ImVec2(size_arg),flags); +} +CIMGUI_API bool igImageButtonEx(ImGuiID id,ImTextureRef_c tex_ref,const ImVec2_c image_size,const ImVec2_c uv0,const ImVec2_c uv1,const ImVec4_c bg_col,const ImVec4_c tint_col,ImGuiButtonFlags flags) +{ + return ImGui::ImageButtonEx(id,ConvertToCPP_ImTextureRef(tex_ref),ConvertToCPP_ImVec2(image_size),ConvertToCPP_ImVec2(uv0),ConvertToCPP_ImVec2(uv1),ConvertToCPP_ImVec4(bg_col),ConvertToCPP_ImVec4(tint_col),flags); +} +CIMGUI_API void igSeparatorEx(ImGuiSeparatorFlags flags,float thickness) +{ + return ImGui::SeparatorEx(flags,thickness); +} +CIMGUI_API void igSeparatorTextEx(ImGuiID id,const char* label,const char* label_end,float extra_width) +{ + return ImGui::SeparatorTextEx(id,label,label_end,extra_width); +} +CIMGUI_API bool igCheckboxFlags_S64Ptr(const char* label,ImS64* flags,ImS64 flags_value) +{ + return ImGui::CheckboxFlags(label,flags,flags_value); +} +CIMGUI_API bool igCheckboxFlags_U64Ptr(const char* label,ImU64* flags,ImU64 flags_value) +{ + return ImGui::CheckboxFlags(label,flags,flags_value); +} +CIMGUI_API bool igCloseButton(ImGuiID id,const ImVec2_c pos) +{ + return ImGui::CloseButton(id,ConvertToCPP_ImVec2(pos)); +} +CIMGUI_API bool igCollapseButton(ImGuiID id,const ImVec2_c pos) +{ + return ImGui::CollapseButton(id,ConvertToCPP_ImVec2(pos)); +} +CIMGUI_API void igScrollbar(ImGuiAxis axis) +{ + return ImGui::Scrollbar(axis); +} +CIMGUI_API bool igScrollbarEx(const ImRect_c bb,ImGuiID id,ImGuiAxis axis,ImS64* p_scroll_v,ImS64 avail_v,ImS64 contents_v,ImDrawFlags draw_rounding_flags) +{ + return ImGui::ScrollbarEx(ConvertToCPP_ImRect(bb),id,axis,p_scroll_v,avail_v,contents_v,draw_rounding_flags); +} +CIMGUI_API ImRect_c igGetWindowScrollbarRect(ImGuiWindow* window,ImGuiAxis axis) +{ + return ConvertFromCPP_ImRect(ImGui::GetWindowScrollbarRect(window,axis)); +} +CIMGUI_API ImGuiID igGetWindowScrollbarID(ImGuiWindow* window,ImGuiAxis axis) +{ + return ImGui::GetWindowScrollbarID(window,axis); +} +CIMGUI_API ImGuiID igGetWindowResizeCornerID(ImGuiWindow* window,int n) +{ + return ImGui::GetWindowResizeCornerID(window,n); +} +CIMGUI_API ImGuiID igGetWindowResizeBorderID(ImGuiWindow* window,ImGuiDir dir) +{ + return ImGui::GetWindowResizeBorderID(window,dir); +} +CIMGUI_API void igExtendHitBoxWhenNearViewportEdge(ImGuiWindow* window,ImRect* bb,float threshold,ImGuiAxis axis) +{ + return ImGui::ExtendHitBoxWhenNearViewportEdge(window,bb,threshold,axis); +} +CIMGUI_API bool igButtonBehavior(const ImRect_c bb,ImGuiID id,bool* out_hovered,bool* out_held,ImGuiButtonFlags flags) +{ + return ImGui::ButtonBehavior(ConvertToCPP_ImRect(bb),id,out_hovered,out_held,flags); +} +CIMGUI_API bool igDragBehavior(ImGuiID id,ImGuiDataType data_type,void* p_v,float v_speed,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags) +{ + return ImGui::DragBehavior(id,data_type,p_v,v_speed,p_min,p_max,format,flags); +} +CIMGUI_API bool igSliderBehavior(const ImRect_c bb,ImGuiID id,ImGuiDataType data_type,void* p_v,const void* p_min,const void* p_max,const char* format,ImGuiSliderFlags flags,ImRect* out_grab_bb) +{ + return ImGui::SliderBehavior(ConvertToCPP_ImRect(bb),id,data_type,p_v,p_min,p_max,format,flags,out_grab_bb); +} +CIMGUI_API bool igSplitterBehavior(const ImRect_c bb,ImGuiID id,ImGuiAxis axis,float* size1,float* size2,float min_size1,float min_size2,float hover_extend,float hover_visibility_delay,ImU32 bg_col) +{ + return ImGui::SplitterBehavior(ConvertToCPP_ImRect(bb),id,axis,size1,size2,min_size1,min_size2,hover_extend,hover_visibility_delay,bg_col); +} +CIMGUI_API bool igTreeNodeBehavior(ImGuiID id,ImGuiTreeNodeFlags flags,const char* label,const char* label_end) +{ + return ImGui::TreeNodeBehavior(id,flags,label,label_end); +} +CIMGUI_API void igTreeNodeDrawLineToChildNode(const ImVec2_c target_pos) +{ + return ImGui::TreeNodeDrawLineToChildNode(ConvertToCPP_ImVec2(target_pos)); +} +CIMGUI_API void igTreeNodeDrawLineToTreePop(const ImGuiTreeNodeStackData* data) +{ + return ImGui::TreeNodeDrawLineToTreePop(data); +} +CIMGUI_API void igTreePushOverrideID(ImGuiID id) +{ + return ImGui::TreePushOverrideID(id); +} +CIMGUI_API void igTreeNodeSetOpen(ImGuiID storage_id,bool open) +{ + return ImGui::TreeNodeSetOpen(storage_id,open); +} +CIMGUI_API bool igTreeNodeUpdateNextOpen(ImGuiID storage_id,ImGuiTreeNodeFlags flags) +{ + return ImGui::TreeNodeUpdateNextOpen(storage_id,flags); +} +CIMGUI_API const ImGuiDataTypeInfo* igDataTypeGetInfo(ImGuiDataType data_type) +{ + return ImGui::DataTypeGetInfo(data_type); +} +CIMGUI_API int igDataTypeFormatString(char* buf,int buf_size,ImGuiDataType data_type,const void* p_data,const char* format) +{ + return ImGui::DataTypeFormatString(buf,buf_size,data_type,p_data,format); +} +CIMGUI_API void igDataTypeApplyOp(ImGuiDataType data_type,int op,void* output,const void* arg_1,const void* arg_2) +{ + return ImGui::DataTypeApplyOp(data_type,op,output,arg_1,arg_2); +} +CIMGUI_API bool igDataTypeApplyFromText(const char* buf,ImGuiDataType data_type,void* p_data,const char* format,void* p_data_when_empty) +{ + return ImGui::DataTypeApplyFromText(buf,data_type,p_data,format,p_data_when_empty); +} +CIMGUI_API int igDataTypeCompare(ImGuiDataType data_type,const void* arg_1,const void* arg_2) +{ + return ImGui::DataTypeCompare(data_type,arg_1,arg_2); +} +CIMGUI_API bool igDataTypeClamp(ImGuiDataType data_type,void* p_data,const void* p_min,const void* p_max) +{ + return ImGui::DataTypeClamp(data_type,p_data,p_min,p_max); +} +CIMGUI_API bool igDataTypeIsZero(ImGuiDataType data_type,const void* p_data) +{ + return ImGui::DataTypeIsZero(data_type,p_data); +} +CIMGUI_API bool igInputTextEx(const char* label,const char* hint,char* buf,int buf_size,const ImVec2_c size_arg,ImGuiInputTextFlags flags,ImGuiInputTextCallback callback,void* user_data) +{ + return ImGui::InputTextEx(label,hint,buf,buf_size,ConvertToCPP_ImVec2(size_arg),flags,callback,user_data); +} +CIMGUI_API void igInputTextDeactivateHook(ImGuiID id) +{ + return ImGui::InputTextDeactivateHook(id); +} +CIMGUI_API bool igTempInputText(const ImRect_c bb,ImGuiID id,const char* label,char* buf,size_t buf_size,ImGuiInputTextFlags flags,ImGuiInputTextCallback callback,void* user_data) +{ + return ImGui::TempInputText(ConvertToCPP_ImRect(bb),id,label,buf,buf_size,flags,callback,user_data); +} +CIMGUI_API bool igTempInputScalar(const ImRect_c bb,ImGuiID id,const char* label,ImGuiDataType data_type,void* p_data,const char* format,const void* p_clamp_min,const void* p_clamp_max) +{ + return ImGui::TempInputScalar(ConvertToCPP_ImRect(bb),id,label,data_type,p_data,format,p_clamp_min,p_clamp_max); +} +CIMGUI_API bool igTempInputIsActive(ImGuiID id) +{ + return ImGui::TempInputIsActive(id); +} +CIMGUI_API ImGuiInputTextState* igGetInputTextState(ImGuiID id) +{ + return ImGui::GetInputTextState(id); +} +CIMGUI_API void igSetNextItemRefVal(ImGuiDataType data_type,void* p_data) +{ + return ImGui::SetNextItemRefVal(data_type,p_data); +} +CIMGUI_API bool igIsItemActiveAsInputText() +{ + return ImGui::IsItemActiveAsInputText(); +} +CIMGUI_API void igColorTooltip(const char* text,const float* col,ImGuiColorEditFlags flags) +{ + return ImGui::ColorTooltip(text,col,flags); +} +CIMGUI_API void igColorEditOptionsPopup(const float* col,ImGuiColorEditFlags flags) +{ + return ImGui::ColorEditOptionsPopup(col,flags); +} +CIMGUI_API void igColorPickerOptionsPopup(const float* ref_col,ImGuiColorEditFlags flags) +{ + return ImGui::ColorPickerOptionsPopup(ref_col,flags); +} +CIMGUI_API void igSetNextItemColorMarker(ImU32 col) +{ + return ImGui::SetNextItemColorMarker(col); +} +CIMGUI_API int igPlotEx(ImGuiPlotType plot_type,const char* label,float(*values_getter)(void* data,int idx),void* data,int values_count,int values_offset,const char* overlay_text,float scale_min,float scale_max,const ImVec2_c size_arg) +{ + return ImGui::PlotEx(plot_type,label,values_getter,data,values_count,values_offset,overlay_text,scale_min,scale_max,ConvertToCPP_ImVec2(size_arg)); +} +CIMGUI_API void igShadeVertsLinearColorGradientKeepAlpha(ImDrawList* draw_list,int vert_start_idx,int vert_end_idx,ImVec2_c gradient_p0,ImVec2_c gradient_p1,ImU32 col0,ImU32 col1) +{ + return ImGui::ShadeVertsLinearColorGradientKeepAlpha(draw_list,vert_start_idx,vert_end_idx,ConvertToCPP_ImVec2(gradient_p0),ConvertToCPP_ImVec2(gradient_p1),col0,col1); +} +CIMGUI_API void igShadeVertsLinearUV(ImDrawList* draw_list,int vert_start_idx,int vert_end_idx,const ImVec2_c a,const ImVec2_c b,const ImVec2_c uv_a,const ImVec2_c uv_b,bool clamp) +{ + return ImGui::ShadeVertsLinearUV(draw_list,vert_start_idx,vert_end_idx,ConvertToCPP_ImVec2(a),ConvertToCPP_ImVec2(b),ConvertToCPP_ImVec2(uv_a),ConvertToCPP_ImVec2(uv_b),clamp); +} +CIMGUI_API void igShadeVertsTransformPos(ImDrawList* draw_list,int vert_start_idx,int vert_end_idx,const ImVec2_c pivot_in,float cos_a,float sin_a,const ImVec2_c pivot_out) +{ + return ImGui::ShadeVertsTransformPos(draw_list,vert_start_idx,vert_end_idx,ConvertToCPP_ImVec2(pivot_in),cos_a,sin_a,ConvertToCPP_ImVec2(pivot_out)); +} +CIMGUI_API void igGcCompactTransientMiscBuffers() +{ + return ImGui::GcCompactTransientMiscBuffers(); +} +CIMGUI_API void igGcCompactTransientWindowBuffers(ImGuiWindow* window) +{ + return ImGui::GcCompactTransientWindowBuffers(window); +} +CIMGUI_API void igGcAwakeTransientWindowBuffers(ImGuiWindow* window) +{ + return ImGui::GcAwakeTransientWindowBuffers(window); +} +CIMGUI_API bool igErrorLog(const char* msg) +{ + return ImGui::ErrorLog(msg); +} +CIMGUI_API void igErrorRecoveryStoreState(ImGuiErrorRecoveryState* state_out) +{ + return ImGui::ErrorRecoveryStoreState(state_out); +} +CIMGUI_API void igErrorRecoveryTryToRecoverState(const ImGuiErrorRecoveryState* state_in) +{ + return ImGui::ErrorRecoveryTryToRecoverState(state_in); +} +CIMGUI_API void igErrorRecoveryTryToRecoverWindowState(const ImGuiErrorRecoveryState* state_in) +{ + return ImGui::ErrorRecoveryTryToRecoverWindowState(state_in); +} +CIMGUI_API void igErrorCheckUsingSetCursorPosToExtendParentBoundaries() +{ + return ImGui::ErrorCheckUsingSetCursorPosToExtendParentBoundaries(); +} +CIMGUI_API void igErrorCheckEndFrameFinalizeErrorTooltip() +{ + return ImGui::ErrorCheckEndFrameFinalizeErrorTooltip(); +} +CIMGUI_API bool igBeginErrorTooltip() +{ + return ImGui::BeginErrorTooltip(); +} +CIMGUI_API void igEndErrorTooltip() +{ + return ImGui::EndErrorTooltip(); +} +CIMGUI_API void igDemoMarker(const char* file,int line,const char* section) +{ + return ImGui::DemoMarker(file,line,section); +} +CIMGUI_API void igDebugAllocHook(ImGuiDebugAllocInfo* info,int frame_count,void* ptr,size_t size) +{ + return ImGui::DebugAllocHook(info,frame_count,ptr,size); +} +CIMGUI_API void igShowFontAtlas(ImFontAtlas* atlas) +{ + return ImGui::ShowFontAtlas(atlas); +} +CIMGUI_API void igDebugHookIdInfo(ImGuiID id,ImGuiDataType data_type,const void* data_id,const void* data_id_end) +{ + return ImGui::DebugHookIdInfo(id,data_type,data_id,data_id_end); +} +CIMGUI_API void igDebugNodeColumns(ImGuiOldColumns* columns) +{ + return ImGui::DebugNodeColumns(columns); +} +CIMGUI_API void igDebugNodeDrawList(ImGuiWindow* window,ImGuiViewportP* viewport,const ImDrawList* draw_list,const char* label) +{ + return ImGui::DebugNodeDrawList(window,viewport,draw_list,label); +} +CIMGUI_API void igDebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list,const ImDrawList* draw_list,const ImDrawCmd* draw_cmd,bool show_mesh,bool show_aabb) +{ + return ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(out_draw_list,draw_list,draw_cmd,show_mesh,show_aabb); +} +CIMGUI_API void igDebugNodeFont(ImFont* font) +{ + return ImGui::DebugNodeFont(font); +} +CIMGUI_API void igDebugNodeFontGlyphsForSrcMask(ImFont* font,ImFontBaked* baked,int src_mask) +{ + return ImGui::DebugNodeFontGlyphsForSrcMask(font,baked,src_mask); +} +CIMGUI_API void igDebugNodeStorage(ImGuiStorage* storage,const char* label) +{ + return ImGui::DebugNodeStorage(storage,label); +} +CIMGUI_API void igDebugNodeTabBar(ImGuiTabBar* tab_bar,const char* label) +{ + return ImGui::DebugNodeTabBar(tab_bar,label); +} +CIMGUI_API void igDebugNodeTable(ImGuiTable* table) +{ + return ImGui::DebugNodeTable(table); +} +CIMGUI_API void igDebugNodeTableSettings(ImGuiTableSettings* settings,ImGuiTable* table) +{ + return ImGui::DebugNodeTableSettings(settings,table); +} +CIMGUI_API void igDebugNodeInputTextState(ImGuiInputTextState* state) +{ + return ImGui::DebugNodeInputTextState(state); +} +CIMGUI_API void igDebugNodeTypingSelectState(ImGuiTypingSelectState* state) +{ + return ImGui::DebugNodeTypingSelectState(state); +} +CIMGUI_API void igDebugNodeMultiSelectState(ImGuiMultiSelectState* state) +{ + return ImGui::DebugNodeMultiSelectState(state); +} +CIMGUI_API void igDebugNodeWindow(ImGuiWindow* window,const char* label) +{ + return ImGui::DebugNodeWindow(window,label); +} +CIMGUI_API void igDebugNodeWindowSettings(ImGuiWindowSettings* settings) +{ + return ImGui::DebugNodeWindowSettings(settings); +} +CIMGUI_API void igDebugNodeWindowsList(ImVector_ImGuiWindowPtr* windows,const char* label) +{ + return ImGui::DebugNodeWindowsList(windows,label); +} +CIMGUI_API void igDebugNodeViewport(ImGuiViewportP* viewport) +{ + return ImGui::DebugNodeViewport(viewport); +} +CIMGUI_API ImFontLoader* ImFontLoader_ImFontLoader(void) +{ + return IM_NEW(ImFontLoader)(); +} +CIMGUI_API void ImFontLoader_destroy(ImFontLoader* self) +{ + IM_DELETE(self); +} +CIMGUI_API const ImFontLoader* igImFontAtlasGetFontLoaderForStbTruetype() +{ + return ImFontAtlasGetFontLoaderForStbTruetype(); +} +CIMGUI_API int igImFontAtlasRectId_GetIndex(ImFontAtlasRectId id) +{ + return ImFontAtlasRectId_GetIndex(id); +} +CIMGUI_API unsigned int igImFontAtlasRectId_GetGeneration(ImFontAtlasRectId id) +{ + return ImFontAtlasRectId_GetGeneration(id); +} +CIMGUI_API ImFontAtlasRectId igImFontAtlasRectId_Make(int index_idx,int gen_idx) +{ + return ImFontAtlasRectId_Make(index_idx,gen_idx); +} +CIMGUI_API ImFontAtlasBuilder* ImFontAtlasBuilder_ImFontAtlasBuilder(void) +{ + return IM_NEW(ImFontAtlasBuilder)(); +} +CIMGUI_API void ImFontAtlasBuilder_destroy(ImFontAtlasBuilder* self) +{ + IM_DELETE(self); +} +CIMGUI_API void igImFontAtlasBuildInit(ImFontAtlas* atlas) +{ + return ImFontAtlasBuildInit(atlas); +} +CIMGUI_API void igImFontAtlasBuildDestroy(ImFontAtlas* atlas) +{ + return ImFontAtlasBuildDestroy(atlas); +} +CIMGUI_API void igImFontAtlasBuildMain(ImFontAtlas* atlas) +{ + return ImFontAtlasBuildMain(atlas); +} +CIMGUI_API void igImFontAtlasBuildSetupFontLoader(ImFontAtlas* atlas,const ImFontLoader* font_loader) +{ + return ImFontAtlasBuildSetupFontLoader(atlas,font_loader); +} +CIMGUI_API void igImFontAtlasBuildNotifySetFont(ImFontAtlas* atlas,ImFont* old_font,ImFont* new_font) +{ + return ImFontAtlasBuildNotifySetFont(atlas,old_font,new_font); +} +CIMGUI_API void igImFontAtlasBuildUpdatePointers(ImFontAtlas* atlas) +{ + return ImFontAtlasBuildUpdatePointers(atlas); +} +CIMGUI_API void igImFontAtlasBuildRenderBitmapFromString(ImFontAtlas* atlas,int x,int y,int w,int h,const char* in_str,char in_marker_char) +{ + return ImFontAtlasBuildRenderBitmapFromString(atlas,x,y,w,h,in_str,in_marker_char); +} +CIMGUI_API void igImFontAtlasBuildClear(ImFontAtlas* atlas) +{ + return ImFontAtlasBuildClear(atlas); +} +CIMGUI_API ImTextureData* igImFontAtlasTextureAdd(ImFontAtlas* atlas,int w,int h) +{ + return ImFontAtlasTextureAdd(atlas,w,h); +} +CIMGUI_API void igImFontAtlasTextureMakeSpace(ImFontAtlas* atlas) +{ + return ImFontAtlasTextureMakeSpace(atlas); +} +CIMGUI_API void igImFontAtlasTextureRepack(ImFontAtlas* atlas,int w,int h) +{ + return ImFontAtlasTextureRepack(atlas,w,h); +} +CIMGUI_API void igImFontAtlasTextureGrow(ImFontAtlas* atlas,int old_w,int old_h) +{ + return ImFontAtlasTextureGrow(atlas,old_w,old_h); +} +CIMGUI_API void igImFontAtlasTextureCompact(ImFontAtlas* atlas) +{ + return ImFontAtlasTextureCompact(atlas); +} +CIMGUI_API ImVec2i_c igImFontAtlasTextureGetSizeEstimate(ImFontAtlas* atlas) +{ + return ConvertFromCPP_ImVec2i(ImFontAtlasTextureGetSizeEstimate(atlas)); +} +CIMGUI_API void igImFontAtlasBuildSetupFontSpecialGlyphs(ImFontAtlas* atlas,ImFont* font,ImFontConfig* src) +{ + return ImFontAtlasBuildSetupFontSpecialGlyphs(atlas,font,src); +} +CIMGUI_API void igImFontAtlasBuildLegacyPreloadAllGlyphRanges(ImFontAtlas* atlas) +{ + return ImFontAtlasBuildLegacyPreloadAllGlyphRanges(atlas); +} +CIMGUI_API void igImFontAtlasBuildGetOversampleFactors(ImFontConfig* src,ImFontBaked* baked,int* out_oversample_h,int* out_oversample_v) +{ + return ImFontAtlasBuildGetOversampleFactors(src,baked,out_oversample_h,out_oversample_v); +} +CIMGUI_API void igImFontAtlasBuildDiscardBakes(ImFontAtlas* atlas,int unused_frames) +{ + return ImFontAtlasBuildDiscardBakes(atlas,unused_frames); +} +CIMGUI_API bool igImFontAtlasFontSourceInit(ImFontAtlas* atlas,ImFontConfig* src) +{ + return ImFontAtlasFontSourceInit(atlas,src); +} +CIMGUI_API void igImFontAtlasFontSourceAddToFont(ImFontAtlas* atlas,ImFont* font,ImFontConfig* src) +{ + return ImFontAtlasFontSourceAddToFont(atlas,font,src); +} +CIMGUI_API void igImFontAtlasFontDestroySourceData(ImFontAtlas* atlas,ImFontConfig* src) +{ + return ImFontAtlasFontDestroySourceData(atlas,src); +} +CIMGUI_API bool igImFontAtlasFontInitOutput(ImFontAtlas* atlas,ImFont* font) +{ + return ImFontAtlasFontInitOutput(atlas,font); +} +CIMGUI_API void igImFontAtlasFontDestroyOutput(ImFontAtlas* atlas,ImFont* font) +{ + return ImFontAtlasFontDestroyOutput(atlas,font); +} +CIMGUI_API void igImFontAtlasFontRebuildOutput(ImFontAtlas* atlas,ImFont* font) +{ + return ImFontAtlasFontRebuildOutput(atlas,font); +} +CIMGUI_API void igImFontAtlasFontDiscardBakes(ImFontAtlas* atlas,ImFont* font,int unused_frames) +{ + return ImFontAtlasFontDiscardBakes(atlas,font,unused_frames); +} +CIMGUI_API ImGuiID igImFontAtlasBakedGetId(ImGuiID font_id,float baked_size,float rasterizer_density) +{ + return ImFontAtlasBakedGetId(font_id,baked_size,rasterizer_density); +} +CIMGUI_API ImFontBaked* igImFontAtlasBakedGetOrAdd(ImFontAtlas* atlas,ImFont* font,float font_size,float font_rasterizer_density) +{ + return ImFontAtlasBakedGetOrAdd(atlas,font,font_size,font_rasterizer_density); +} +CIMGUI_API ImFontBaked* igImFontAtlasBakedGetClosestMatch(ImFontAtlas* atlas,ImFont* font,float font_size,float font_rasterizer_density) +{ + return ImFontAtlasBakedGetClosestMatch(atlas,font,font_size,font_rasterizer_density); +} +CIMGUI_API ImFontBaked* igImFontAtlasBakedAdd(ImFontAtlas* atlas,ImFont* font,float font_size,float font_rasterizer_density,ImGuiID baked_id) +{ + return ImFontAtlasBakedAdd(atlas,font,font_size,font_rasterizer_density,baked_id); +} +CIMGUI_API void igImFontAtlasBakedDiscard(ImFontAtlas* atlas,ImFont* font,ImFontBaked* baked) +{ + return ImFontAtlasBakedDiscard(atlas,font,baked); +} +CIMGUI_API ImFontGlyph* igImFontAtlasBakedAddFontGlyph(ImFontAtlas* atlas,ImFontBaked* baked,ImFontConfig* src,const ImFontGlyph* in_glyph) +{ + return ImFontAtlasBakedAddFontGlyph(atlas,baked,src,in_glyph); +} +CIMGUI_API void igImFontAtlasBakedAddFontGlyphAdvancedX(ImFontAtlas* atlas,ImFontBaked* baked,ImFontConfig* src,ImWchar codepoint,float advance_x) +{ + return ImFontAtlasBakedAddFontGlyphAdvancedX(atlas,baked,src,codepoint,advance_x); +} +CIMGUI_API void igImFontAtlasBakedDiscardFontGlyph(ImFontAtlas* atlas,ImFont* font,ImFontBaked* baked,ImFontGlyph* glyph) +{ + return ImFontAtlasBakedDiscardFontGlyph(atlas,font,baked,glyph); +} +CIMGUI_API void igImFontAtlasBakedSetFontGlyphBitmap(ImFontAtlas* atlas,ImFontBaked* baked,ImFontConfig* src,ImFontGlyph* glyph,ImTextureRect* r,const unsigned char* src_pixels,ImTextureFormat src_fmt,int src_pitch) +{ + return ImFontAtlasBakedSetFontGlyphBitmap(atlas,baked,src,glyph,r,src_pixels,src_fmt,src_pitch); +} +CIMGUI_API void igImFontAtlasPackInit(ImFontAtlas* atlas) +{ + return ImFontAtlasPackInit(atlas); +} +CIMGUI_API ImFontAtlasRectId igImFontAtlasPackAddRect(ImFontAtlas* atlas,int w,int h,ImFontAtlasRectEntry* overwrite_entry) +{ + return ImFontAtlasPackAddRect(atlas,w,h,overwrite_entry); +} +CIMGUI_API ImTextureRect* igImFontAtlasPackGetRect(ImFontAtlas* atlas,ImFontAtlasRectId id) +{ + return ImFontAtlasPackGetRect(atlas,id); +} +CIMGUI_API ImTextureRect* igImFontAtlasPackGetRectSafe(ImFontAtlas* atlas,ImFontAtlasRectId id) +{ + return ImFontAtlasPackGetRectSafe(atlas,id); +} +CIMGUI_API void igImFontAtlasPackDiscardRect(ImFontAtlas* atlas,ImFontAtlasRectId id) +{ + return ImFontAtlasPackDiscardRect(atlas,id); +} +CIMGUI_API void igImFontAtlasUpdateNewFrame(ImFontAtlas* atlas,int frame_count,bool renderer_has_textures) +{ + return ImFontAtlasUpdateNewFrame(atlas,frame_count,renderer_has_textures); +} +CIMGUI_API void igImFontAtlasAddDrawListSharedData(ImFontAtlas* atlas,ImDrawListSharedData* data) +{ + return ImFontAtlasAddDrawListSharedData(atlas,data); +} +CIMGUI_API void igImFontAtlasRemoveDrawListSharedData(ImFontAtlas* atlas,ImDrawListSharedData* data) +{ + return ImFontAtlasRemoveDrawListSharedData(atlas,data); +} +CIMGUI_API void igImFontAtlasUpdateDrawListsTextures(ImFontAtlas* atlas,ImTextureRef_c old_tex,ImTextureRef_c new_tex) +{ + return ImFontAtlasUpdateDrawListsTextures(atlas,ConvertToCPP_ImTextureRef(old_tex),ConvertToCPP_ImTextureRef(new_tex)); +} +CIMGUI_API void igImFontAtlasUpdateDrawListsSharedData(ImFontAtlas* atlas) +{ + return ImFontAtlasUpdateDrawListsSharedData(atlas); +} +CIMGUI_API void igImFontAtlasTextureBlockConvert(const unsigned char* src_pixels,ImTextureFormat src_fmt,int src_pitch,unsigned char* dst_pixels,ImTextureFormat dst_fmt,int dst_pitch,int w,int h) +{ + return ImFontAtlasTextureBlockConvert(src_pixels,src_fmt,src_pitch,dst_pixels,dst_fmt,dst_pitch,w,h); +} +CIMGUI_API void igImFontAtlasTextureBlockPostProcess(ImFontAtlasPostProcessData* data) +{ + return ImFontAtlasTextureBlockPostProcess(data); +} +CIMGUI_API void igImFontAtlasTextureBlockPostProcessMultiply(ImFontAtlasPostProcessData* data,float multiply_factor) +{ + return ImFontAtlasTextureBlockPostProcessMultiply(data,multiply_factor); +} +CIMGUI_API void igImFontAtlasTextureBlockFill(ImTextureData* dst_tex,int dst_x,int dst_y,int w,int h,ImU32 col) +{ + return ImFontAtlasTextureBlockFill(dst_tex,dst_x,dst_y,w,h,col); +} +CIMGUI_API void igImFontAtlasTextureBlockCopy(ImTextureData* src_tex,int src_x,int src_y,ImTextureData* dst_tex,int dst_x,int dst_y,int w,int h) +{ + return ImFontAtlasTextureBlockCopy(src_tex,src_x,src_y,dst_tex,dst_x,dst_y,w,h); +} +CIMGUI_API void igImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas,ImTextureData* tex,int x,int y,int w,int h) +{ + return ImFontAtlasTextureBlockQueueUpload(atlas,tex,x,y,w,h); +} +CIMGUI_API bool igImTextureDataUpdateNewFrame(ImTextureData* tex) +{ + return ImTextureDataUpdateNewFrame(tex); +} +CIMGUI_API void igImTextureDataQueueUpload(ImTextureData* tex,int x,int y,int w,int h) +{ + return ImTextureDataQueueUpload(tex,x,y,w,h); +} +CIMGUI_API int igImTextureDataGetFormatBytesPerPixel(ImTextureFormat format) +{ + return ImTextureDataGetFormatBytesPerPixel(format); +} +CIMGUI_API const char* igImTextureDataGetStatusName(ImTextureStatus status) +{ + return ImTextureDataGetStatusName(status); +} +CIMGUI_API const char* igImTextureDataGetFormatName(ImTextureFormat format) +{ + return ImTextureDataGetFormatName(format); +} +CIMGUI_API bool igImFontAtlasGetMouseCursorTexData(ImFontAtlas* atlas,ImGuiMouseCursor cursor_type,ImVec2_c* out_offset,ImVec2_c* out_size,ImVec2 out_uv_border[2],ImVec2 out_uv_fill[2]) +{ + return ImFontAtlasGetMouseCursorTexData(atlas,cursor_type,reinterpret_cast(out_offset),reinterpret_cast(out_size),out_uv_border,out_uv_fill); +} +#ifdef IMGUI_ENABLE_FREETYPE +CIMGUI_API const ImFontLoader* ImGuiFreeType_GetFontLoader() +{ + return ImGuiFreeType::GetFontLoader(); +} + +CIMGUI_API void ImGuiFreeType_SetAllocatorFunctions(void*(*alloc_func)(size_t sz,void* user_data),void(*free_func)(void* ptr,void* user_data),void* user_data) +{ + return ImGuiFreeType::SetAllocatorFunctions(alloc_func,free_func,user_data); +} + +CIMGUI_API bool ImGuiFreeType_DebugEditFontLoaderFlags(ImGuiFreeTypeLoaderFlags* p_font_loader_flags) +{ + return ImGuiFreeType::DebugEditFontLoaderFlags(p_font_loader_flags); +} + +#endif + + + +/////////////////////////////manual written functions + +CIMGUI_API void ImGuiTextBuffer_appendf(ImGuiTextBuffer *self, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + self->appendfv(fmt, args); + va_end(args); +} + +CIMGUI_API float igGET_FLT_MAX() +{ + return FLT_MAX; +} + +CIMGUI_API float igGET_FLT_MIN() +{ + return FLT_MIN; +} + + +CIMGUI_API ImVector_ImWchar* ImVector_ImWchar_create() +{ + return IM_NEW(ImVector) (); +} + +CIMGUI_API void ImVector_ImWchar_destroy(ImVector_ImWchar* self) +{ + IM_DELETE(self); +} + +CIMGUI_API void ImVector_ImWchar_Init(ImVector_ImWchar* p) +{ + IM_PLACEMENT_NEW(p) ImVector(); +} +CIMGUI_API void ImVector_ImWchar_UnInit(ImVector_ImWchar* p) +{ + p->~ImVector(); +} + + +#ifdef IMGUI_HAS_DOCK + +// NOTE: Some function pointers in the ImGuiPlatformIO structure are not C-compatible because of their +// use of a complex return type. To work around this, we store a custom CimguiStorage object inside +// ImGuiIO::BackendLanguageUserData, which contains C-compatible function pointer variants for these +// functions. When a user function pointer is provided, we hook up the underlying ImGuiPlatformIO +// function pointer to a thunk which accesses the user function pointer through CimguiStorage. + +struct CimguiStorage +{ + void(*Platform_GetWindowPos)(ImGuiViewport* vp, ImVec2* out_pos); + void(*Platform_GetWindowSize)(ImGuiViewport* vp, ImVec2* out_pos); +}; + +// Gets a reference to the CimguiStorage object stored in the current ImGui context's BackendLanguageUserData. +CimguiStorage& GetCimguiStorage() +{ + ImGuiIO& io = ImGui::GetIO(); + if (io.BackendLanguageUserData == NULL) + { + io.BackendLanguageUserData = IM_NEW(CimguiStorage)(); + } + + return *(CimguiStorage*)io.BackendLanguageUserData; +} + +// Thunk satisfying the signature of ImGuiPlatformIO::Platform_GetWindowPos. +ImVec2 Platform_GetWindowPos_hook(ImGuiViewport* vp) +{ + ImVec2 pos; + GetCimguiStorage().Platform_GetWindowPos(vp, &pos); + return pos; +}; + +// Fully C-compatible function pointer setter for ImGuiPlatformIO::Platform_GetWindowPos. +CIMGUI_API void ImGuiPlatformIO_Set_Platform_GetWindowPos(ImGuiPlatformIO* platform_io, void(*user_callback)(ImGuiViewport* vp, ImVec2* out_pos)) +{ + CimguiStorage& storage = GetCimguiStorage(); + storage.Platform_GetWindowPos = user_callback; + platform_io->Platform_GetWindowPos = &Platform_GetWindowPos_hook; +} + +// Thunk satisfying the signature of ImGuiPlatformIO::Platform_GetWindowSize. +ImVec2 Platform_GetWindowSize_hook(ImGuiViewport* vp) +{ + ImVec2 size; + GetCimguiStorage().Platform_GetWindowSize(vp, &size); + return size; +}; + +// Fully C-compatible function pointer setter for ImGuiPlatformIO::Platform_GetWindowSize. +CIMGUI_API void ImGuiPlatformIO_Set_Platform_GetWindowSize(ImGuiPlatformIO* platform_io, void(*user_callback)(ImGuiViewport* vp, ImVec2* out_size)) +{ + CimguiStorage& storage = GetCimguiStorage(); + storage.Platform_GetWindowSize = user_callback; + platform_io->Platform_GetWindowSize = &Platform_GetWindowSize_hook; +} + +#endif From 6ffb826bc3e028b30366fdedd3a6c8b2bb33ce21 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Tue, 23 Jun 2026 22:55:37 +0200 Subject: [PATCH 05/40] cmake: fix build --- CMakeLists.txt | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ea2dfd9..9233807 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -204,6 +204,13 @@ elseif(UNIX) ) endif() +set_target_properties( + ${PROJECT_NAME} + PROPERTIES + BUILD_RPATH "$ORIGIN/../lib;${CMAKE_BINARY_DIR}" + INSTALL_RPATH "$ORIGIN/../lib" +) + # ----------------------------- # fmt library # ----------------------------- @@ -224,8 +231,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE fmt) file(GLOB IMGUI_SOURCES src/libs/imgui/*.cpp) if(APPLE) - file(GLOB IMGUI_APPLE_SOURCE src/libs/imgui/*.mm) - list(APPEND IMGUI_SOURCES IMGUI_APPLE_SOURCE) + list(APPEND IMGUI_SOURCES src/libs/imgui/imgui_impl_metal.mm) endif() add_library(imgui SHARED ${IMGUI_SOURCES}) @@ -235,7 +241,15 @@ enable_lto(imgui) target_include_directories(imgui PUBLIC include/libs/imgui) target_compile_definitions(imgui PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLAD) target_link_libraries(imgui PUBLIC ${GLFW_TARGET}) -set_target_properties(imgui PROPERTIES VERSION 1.92.9 SOVERSION 1) + +set_target_properties( + imgui + PROPERTIES + CXX_VISIBILITY_PRESET default + VISIBILITY_INLINES_HIDDEN OFF + VERSION 1.92.9 + SOVERSION 1 +) target_link_libraries(${PROJECT_NAME} PRIVATE imgui) @@ -244,8 +258,17 @@ target_link_libraries(${PROJECT_NAME} PRIVATE imgui) # ----------------------------- add_library(cimgui SHARED src/libs/cimgui/cimgui.cpp) + +target_include_directories(imgui PUBLIC include/libs include/libs/cimgui) target_link_libraries(cimgui PUBLIC imgui) -set_target_properties(cimgui PROPERTIES VERSION 1 SOVERSION 1) +set_target_properties( + cimgui + PROPERTIES + CXX_VISIBILITY_PRESET default + VISIBILITY_INLINES_HIDDEN OFF + VERSION 1 + SOVERSION 1 +) # ----------------------------- # Tray library (integrated from its own CMakeLists.txt) @@ -352,6 +375,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE clip) # ----------------------------- # nvdialog (integrated from its own CMakeLists.txt) # ----------------------------- + file(GLOB NVD_COMMON_SOURCES src/libs/nvdialog/*.c) if(WIN32) @@ -470,7 +494,13 @@ target_link_libraries(${PROJECT_NAME} PRIVATE tiny-process-library) # Install # ----------------------------- -install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin COMPONENT runtime) +add_dependencies(${PROJECT_NAME} cimgui imgui) + +install( + TARGETS ${PROJECT_NAME} imgui cimgui + RUNTIME DESTINATION bin COMPONENT runtime + LIBRARY DESTINATION lib COMPONENT runtime +) install( FILES LICENSE From 1b99995bb18a3d0decfc7b6cf47e613ccffd190b Mon Sep 17 00:00:00 2001 From: Toni500git Date: Wed, 24 Jun 2026 21:09:07 +0200 Subject: [PATCH 06/40] fix this fucking cmake --- CMakeLists.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9233807..4c9b413 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,6 +242,17 @@ target_include_directories(imgui PUBLIC include/libs/imgui) target_compile_definitions(imgui PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLAD) target_link_libraries(imgui PUBLIC ${GLFW_TARGET}) +if(APPLE) + find_library(METAL_FRAMEWORK Metal REQUIRED) + find_library(FOUNDATION_FRAMEWORK Foundation REQUIRED) + find_library(QUARTZCORE_FRAMEWORK QuartzCore REQUIRED) + target_link_libraries(imgui PUBLIC + ${METAL_FRAMEWORK} + ${FOUNDATION_FRAMEWORK} + ${QUARTZCORE_FRAMEWORK} + ) +endif() + set_target_properties( imgui PROPERTIES @@ -259,7 +270,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE imgui) add_library(cimgui SHARED src/libs/cimgui/cimgui.cpp) -target_include_directories(imgui PUBLIC include/libs include/libs/cimgui) +target_include_directories(cimgui PUBLIC include/libs include/libs/cimgui) target_link_libraries(cimgui PUBLIC imgui) set_target_properties( cimgui From 7d98b014432366523810359a7b7bd7ad8552f614 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Wed, 24 Jun 2026 21:33:04 +0200 Subject: [PATCH 07/40] macos: fix spam of libimgui.1.dylib not being found when bundling the app --- CMakeLists.txt | 10 ++++++++-- scripts/create_app_bundle.sh | 7 +++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c9b413..4c24f3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -204,11 +204,17 @@ elseif(UNIX) ) endif() +if(APPLE) + set(_rpath_origin "@loader_path") +else() + set(_rpath_origin "$ORIGIN") +endif() + set_target_properties( ${PROJECT_NAME} PROPERTIES - BUILD_RPATH "$ORIGIN/../lib;${CMAKE_BINARY_DIR}" - INSTALL_RPATH "$ORIGIN/../lib" + BUILD_RPATH "${_rpath_origin}/../lib;$" + INSTALL_RPATH "${_rpath_origin}/../lib" ) # ----------------------------- diff --git a/scripts/create_app_bundle.sh b/scripts/create_app_bundle.sh index f1dee14..04a9b04 100755 --- a/scripts/create_app_bundle.sh +++ b/scripts/create_app_bundle.sh @@ -26,7 +26,7 @@ install_dylibbundler() { main() { if [ -z "$1" ]; then - echo "Usage: $0 [output_name]" + echo "Usage: $0 [output_name] [lib_search_dir]" exit 1 fi @@ -38,6 +38,8 @@ main() { check_file "$1" check_file oshot.png + LIB_SEARCH_DIR="${3:-$(dirname "$1")}" + APP_NAME="oshot" APP_DIR="${APP_NAME}.app" CONTENTS="${APP_DIR}/Contents" @@ -56,7 +58,8 @@ main() { dylibbundler -od -b \ -x "${MACOS}/${APP_NAME}" \ -d "${FRAMEWORKS}/" \ - -p @executable_path/../Frameworks/ + -p @executable_path/../Frameworks/ \ + -s "$LIB_SEARCH_DIR" # Convert oshot.png -> oshot.icns for the Dock icon if command -v sips &>/dev/null 2>&1 && command -v iconutil &>/dev/null 2>&1; then From 5ef104765f3ecc1985bbf0f21a39801167481d9f Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 26 Jun 2026 19:36:03 +0200 Subject: [PATCH 08/40] plugins: add first code of the plugins API --- .clangd | 14 +++++++ include/screenshot_tool.hpp | 25 +++--------- src/main.cpp | 1 + src/main_tool_metal.mm | 51 ++++++++++++------------- src/main_tool_opengl3.cpp | 13 +++---- src/plugins/oshot_plugin.h | 75 ++++++++++++++++++++++++++++++++++++ src/plugins/plugins.cpp | 76 +++++++++++++++++++++++++++++++++++++ src/screenshot_tool.cpp | 31 +++++++++++++-- src/util.cpp | 1 + 9 files changed, 231 insertions(+), 56 deletions(-) create mode 100644 .clangd create mode 100644 src/plugins/oshot_plugin.h create mode 100644 src/plugins/plugins.cpp diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..d2200db --- /dev/null +++ b/.clangd @@ -0,0 +1,14 @@ +CompileFlags: + Add: [-Wall, -Wextra] # flags shared by all files go in the top (unconditional) fragment +--- +If: + PathMatch: .*\.h$ +CompileFlags: + Remove: [-std=*] # strip any -std= picked up from compile_flags.txt + Add: [-xc, -std=c11] # -xc forces C, since a bare .h is ambiguous +--- +If: + PathExclude: .*\.h$ +CompileFlags: + Remove: [-std=*] + Add: [-std=c++20] diff --git a/include/screenshot_tool.hpp b/include/screenshot_tool.hpp index 27b280c..85f09ac 100644 --- a/include/screenshot_tool.hpp +++ b/include/screenshot_tool.hpp @@ -10,10 +10,9 @@ #include #include #include +#include #include -#include "cache.hpp" -#include "config.hpp" #include "imgui/imgui.h" #include "imgui/imgui_internal.h" #include "screen_capture.hpp" @@ -187,23 +186,6 @@ struct ErrorContext class ScreenshotTool { public: - ScreenshotTool() - : m_inputs{ g_config->File.ocr_path, - g_config->File.ocr_model, - g_config->File.ocr_get_repo, -#if defined(__unix__) && !defined(__APPLE__) - get_config_dir() / "models", -#else - "./models", -#endif - {}, - "", - {}, - "", - "" }, - m_current_color(rgba_t(g_cache->GetValue(CacheEntry::AnnColor, 0xFF0000FF))) - {} - Result<> Start(); Result<> StartWindow(); Result CreateTexture(void* tex, std::span data, int w, int h); @@ -216,6 +198,8 @@ class ScreenshotTool m_tool_textures[idx(type)]._TexID = static_cast(size_t(tex)); } + auto& GetImGuiIDTexts() { return m_imgui_id_texts; } + void SetOnImageReload(std::function fn) { m_on_image_reload = std::move(fn); } capture_result_t GetFinalImage(bool is_text_tools = false); @@ -323,6 +307,7 @@ class ScreenshotTool std::vector m_annotations; annotation_t m_current_annotation; rgba_t m_current_color; + std::unordered_map m_imgui_id_texts; std::array m_tool_thickness; bool m_is_drawing = false; bool m_is_color_picking = false; @@ -364,6 +349,8 @@ class ScreenshotTool } }; +extern ScreenshotTool g_ss_tool; + extern std::deque g_dropped_paths; #endif // !_SCREENSHOT_TOOL_HPP_ diff --git a/src/main.cpp b/src/main.cpp index 4c1e2b8..868d227 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -67,6 +67,7 @@ struct GLFWwindow; std::deque g_dropped_paths; std::unique_ptr g_config; std::unique_ptr g_cache; +ScreenshotTool g_ss_tool; bool g_is_systray = false; int g_scr_w{}, g_scr_h{}; Clipboard g_clipboard(SessionType::Unknown); diff --git a/src/main_tool_metal.mm b/src/main_tool_metal.mm index cdd6bce..2eb3255 100644 --- a/src/main_tool_metal.mm +++ b/src/main_tool_metal.mm @@ -65,15 +65,14 @@ void maximize_window() int run_main_tool() { - id device; - ScreenshotTool ss_tool; + id device; // vsync is controlled via the CAMetalLayer's displaySyncEnabled property instead. - ss_tool.SetOnCancel([&]() { + g_ss_tool.SetOnCancel([&]() { fmt::println(stderr, "Canceled screenshot"); glfwSetWindowShouldClose(window, GLFW_TRUE); }); - ss_tool.SetOnComplete([&](SavingOp op, const Result& result) { + g_ss_tool.SetOnComplete([&](SavingOp op, const Result& result) { MUST_OK(result, { error("Screenshot failed: {}", result.error_v()); glfwSetWindowShouldClose(window, GLFW_TRUE); @@ -84,17 +83,17 @@ int run_main_tool() glfwSetWindowShouldClose(window, GLFW_TRUE); }); - ss_tool.SetOnImageReload([&](const capture_result_t& cap) { + g_ss_tool.SetOnImageReload([&](const capture_result_t& cap) { // Release old texture automatically via ARC id newTex = create_metal_texture(device, cap.data.data(), cap.w, cap.h); - ss_tool.SetBackendTexture((__bridge void*)newTex); + g_ss_tool.SetBackendTexture((__bridge void*)newTex); }); // Setup Screenshot Tool // Calling it before starting the window so that // we can capture at the exact moment we launch - MUST_OK(ss_tool.Start(), { + MUST_OK(g_ss_tool.Start(), { error("Failed to start capture: {}", _r.error_v()); return EXIT_FAILURE; }); @@ -171,7 +170,7 @@ int run_main_tool() // Start the overlay window { - const Result<>& res = ss_tool.StartWindow(); + const Result<>& res = g_ss_tool.StartWindow(); MUST_OK(res, { error("Failed to start tool window: {}", res.error_v()); if (!g_is_systray) @@ -181,7 +180,7 @@ int run_main_tool() } // Create Metal texture from screenshot buffer - capture_result_t& cap = ss_tool.GetRawScreenshot(); + capture_result_t& cap = g_ss_tool.GetRawScreenshot(); MTLTextureDescriptor* desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm width:cap.w @@ -195,35 +194,35 @@ int run_main_tool() [metalTexture replaceRegion:region mipmapLevel:0 withBytes:cap.data.data() bytesPerRow:cap.w * 4]; // Pass to ImGui - ss_tool.SetBackendTexture((__bridge void*)metalTexture); + g_ss_tool.SetBackendTexture((__bridge void*)metalTexture); - ss_tool.SetToolTexture( + g_ss_tool.SetToolTexture( ToolType::Rectangle, (__bridge void*)create_metal_texture(device, ICON_SQUARE_RGBA, ICON_SQUARE_W, ICON_SQUARE_H)); - ss_tool.SetToolTexture( + g_ss_tool.SetToolTexture( ToolType::RectangleFilled, (__bridge void*)create_metal_texture(device, ICON_RECT_FILLED_RGBA, ICON_RECT_FILLED_W, ICON_RECT_FILLED_H)); - ss_tool.SetToolTexture(ToolType::CircleFilled, - (__bridge void*)create_metal_texture( - device, ICON_CIRCLE_FILLED_RGBA, ICON_CIRCLE_FILLED_W, ICON_CIRCLE_FILLED_H)); - ss_tool.SetToolTexture( + g_ss_tool.SetToolTexture(ToolType::CircleFilled, + (__bridge void*)create_metal_texture( + device, ICON_CIRCLE_FILLED_RGBA, ICON_CIRCLE_FILLED_W, ICON_CIRCLE_FILLED_H)); + g_ss_tool.SetToolTexture( ToolType::ToggleTextTools, (__bridge void*)create_metal_texture(device, ICON_TEXT_TOOLS_RGBA, ICON_TEXT_TOOLS_W, ICON_TEXT_TOOLS_H)); - ss_tool.SetToolTexture(ToolType::Line, - (__bridge void*)create_metal_texture(device, ICON_LINE_RGBA, ICON_LINE_W, ICON_LINE_H)); - ss_tool.SetToolTexture( + g_ss_tool.SetToolTexture(ToolType::Line, + (__bridge void*)create_metal_texture(device, ICON_LINE_RGBA, ICON_LINE_W, ICON_LINE_H)); + g_ss_tool.SetToolTexture( ToolType::Circle, (__bridge void*)create_metal_texture(device, ICON_CIRCLE_RGBA, ICON_CIRCLE_W, ICON_CIRCLE_H)); - ss_tool.SetToolTexture(ToolType::Arrow, - (__bridge void*)create_metal_texture(device, ICON_ARROW_RGBA, ICON_ARROW_W, ICON_ARROW_H)); - ss_tool.SetToolTexture( + g_ss_tool.SetToolTexture(ToolType::Arrow, + (__bridge void*)create_metal_texture(device, ICON_ARROW_RGBA, ICON_ARROW_W, ICON_ARROW_H)); + g_ss_tool.SetToolTexture( ToolType::Pencil, (__bridge void*)create_metal_texture(device, ICON_PENCIL_RGBA, ICON_PENCIL_W, ICON_PENCIL_H)); - ss_tool.SetToolTexture(ToolType::Text, - (__bridge void*)create_metal_texture(device, ICON_TEXT_RGBA, ICON_TEXT_W, ICON_TEXT_H)); + g_ss_tool.SetToolTexture(ToolType::Text, + (__bridge void*)create_metal_texture(device, ICON_TEXT_RGBA, ICON_TEXT_W, ICON_TEXT_H)); // Render loop MTLRenderPassDescriptor* rpd = [MTLRenderPassDescriptor new]; - while (!glfwWindowShouldClose(window) && ss_tool.IsActive()) + while (!glfwWindowShouldClose(window) && g_ss_tool.IsActive()) { glfwPollEvents(); @@ -252,7 +251,7 @@ int run_main_tool() ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); - ss_tool.RenderOverlay(); + g_ss_tool.RenderOverlay(); ImGui::Render(); diff --git a/src/main_tool_opengl3.cpp b/src/main_tool_opengl3.cpp index 8fd0c93..f781b37 100644 --- a/src/main_tool_opengl3.cpp +++ b/src/main_tool_opengl3.cpp @@ -103,13 +103,12 @@ int run_main_tool() // Setup Screenshot Tool // Calling it before starting the window so that // we can capture at the exact moment we launch - ScreenshotTool ss_tool; - ss_tool.SetOnCancel([&]() { + g_ss_tool.SetOnCancel([&]() { fmt::println(stderr, "Canceled screenshot"); glfwSwapInterval(0); // Disable vsync glfwSetWindowShouldClose(window, GLFW_TRUE); }); - ss_tool.SetOnComplete([&](SavingOp op, const Result& result) { + g_ss_tool.SetOnComplete([&](SavingOp op, const Result& result) { MUST_OK(result, { error("Screenshot failed: {}", result.error_v()); glfwSwapInterval(0); // Disable vsync @@ -123,7 +122,7 @@ int run_main_tool() glfwSetWindowShouldClose(window, GLFW_TRUE); }); - MUST_OK(ss_tool.Start(), { + MUST_OK(g_ss_tool.Start(), { error("Failed to start capture: {}", _r.error_v()); return EXIT_FAILURE; }); @@ -212,7 +211,7 @@ int run_main_tool() // Start the overlay window { - const Result<>& res = ss_tool.StartWindow(); + const Result<>& res = g_ss_tool.StartWindow(); MUST_OK(res, { error("Failed to start tool window: {}", res.error_v()); if (!g_is_systray) @@ -221,7 +220,7 @@ int run_main_tool() }); } - while (!glfwWindowShouldClose(window) && ss_tool.IsActive()) + while (!glfwWindowShouldClose(window) && g_ss_tool.IsActive()) { // Poll and handle events (inputs, window resize, etc.) // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your @@ -243,7 +242,7 @@ int run_main_tool() ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); - ss_tool.RenderOverlay(); + g_ss_tool.RenderOverlay(); // Rendering ImGui::Render(); diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h new file mode 100644 index 0000000..925f3b4 --- /dev/null +++ b/src/plugins/oshot_plugin.h @@ -0,0 +1,75 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#define OSHOT_API_VERSION 1u + +#define OCR_OUTPUT "ocr_output" +#define ZBAR_OUTPUT "barcode_output" + +typedef enum +{ + OSHOT_CAP_NONE = 0, + OSHOT_CAP_NETWORK = 1u << 0, + OSHOT_CAP_FS = 1u << 1, +} OSCapabilities; + +typedef enum +{ + OSHOT_LOG_DEBUG, + OSHOT_LOG_INFO, + OSHOT_LOG_WARN, + OSHOT_LOG_ERROR, +} OSLogLevel; + +typedef struct +{ + const char* p; + size_t len; +} oshot_str_t; + +uint32_t oshot_get_abi_version(void); +bool oshot_get_plugin_data_dir(oshot_str_t* ret); +bool oshot_get_text(const char* imgui_id, oshot_str_t* ret); +void oshot_set_text(const char* imgui_id, const oshot_str_t value); + +void oshot_display_msg(const OSLogLevel lvl, const oshot_str_t str); +void oshot_log(const OSLogLevel lvl, const oshot_str_t str); + +typedef struct +{ + int32_t w; + int32_t h; + uint8_t* rgba; +} oshot_capture_t; +oshot_capture_t oshot_get_capture(bool render_anns); + +/* ------------------------------------------------------------------ + * Plugin descriptor. + * One per plugin, returned by the single exported symbol below + * ---------------------------------------------------------------- */ +typedef struct +{ + const char* name; + uint32_t abi_version; + uint32_t capabilities; /* OR of oshot_capabilities_t, informational only */ + + void* (*init)(void); + void (*destroy)(void* state); + void (*render)(void* state); + void (*on_ocr_done)(void* state); +} oshot_plugin_t; + +/* Must return a pointer to a static, process-lifetime oshot_plugin_t, + * not something allocated per call. */ +oshot_plugin_t* oshot_host_get_plugin(void); + +#ifdef __cplusplus +} +#endif diff --git a/src/plugins/plugins.cpp b/src/plugins/plugins.cpp new file mode 100644 index 0000000..43e0db0 --- /dev/null +++ b/src/plugins/plugins.cpp @@ -0,0 +1,76 @@ +#include +#include + +#include "fmt/chrono.h" +#include "fmt/format.h" +#include "oshot_plugin.h" +#include "screenshot_tool.hpp" +#include "util.hpp" + +struct oshot_host_api_t +{ + uint32_t abi_version; + const char* plugin_name; +} g_api; + +uint32_t oshot_get_abi_version() +{ + return g_api.abi_version; +} + +void oshot_display_msg(const OSLogLevel lvl, const oshot_str_t str) +{ + const std::string& fmt = fmt::format("{}: {}", g_api.plugin_name, str.p); + switch (lvl) + { + case OSLogLevel::OSHOT_LOG_DEBUG: + spdlog::warn("OSHOT_LOG_DEBUG is not allowed when displaying a message."); + break; + case OSLogLevel::OSHOT_LOG_INFO: info("{}", fmt); break; + case OSLogLevel::OSHOT_LOG_WARN: warn("{}", fmt); break; + case OSLogLevel::OSHOT_LOG_ERROR: error("{}", fmt); break; + } +} + +void oshot_log(const OSLogLevel lvl, const oshot_str_t str) +{ + auto now = std::chrono::system_clock::now(); + + const std::string& fmt = fmt::format("[{:%%F_%%H-%%M-%%S}] {}: {}", now, g_api.plugin_name, str.p); + switch (lvl) + { + case OSLogLevel::OSHOT_LOG_DEBUG: spdlog::debug("{}", fmt); break; + case OSLogLevel::OSHOT_LOG_INFO: spdlog::info("{}", fmt); break; + case OSLogLevel::OSHOT_LOG_WARN: spdlog::warn("{}", fmt); break; + case OSLogLevel::OSHOT_LOG_ERROR: spdlog::error("{}", fmt); break; + } +} + +oshot_capture_t oshot_get_capture(bool render_anns) +{ + const capture_result_t& cap = g_ss_tool.GetFinalImage(render_anns); + + oshot_capture_t ret; + std::memcpy(ret.rgba, cap.data.data(), cap.data.size()); + ret.h = cap.h; + ret.w = cap.w; + + return ret; +} + +bool oshot_get_text(const char* imgui_id, oshot_str_t* ret) +{ + auto t = g_ss_tool.GetImGuiIDTexts(); + if (auto p = t.find(imgui_id); p != t.end()) + { + ret->p = p->second.c_str(); + ret->len = p->second.length(); + return true; + } + return false; +} + +void oshot_set_text(const char* imgui_id, const oshot_str_t ret) +{ + g_ss_tool.GetImGuiIDTexts().insert_or_assign(imgui_id, std::string(ret.p, ret.len)); +} diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 65f250e..c8a8bd3 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -28,6 +28,7 @@ #include "imgui/imgui_impl_opengl3_loader.h" #include "imgui/imgui_internal.h" #include "imgui/imgui_stdlib.h" +#include "plugins/oshot_plugin.h" #include "screen_capture.hpp" #include "tiny-process-library/process.hpp" #include "tinyfiledialogs.h" @@ -381,6 +382,24 @@ Result<> ScreenshotTool::StartWindow() else if (!fs::is_directory(m_inputs.ocr_model_downloaded_path)) SetError(m_download_errors, OcrDownloadError::InvalidPath, "Not a directory"); + m_inputs = { g_config->File.ocr_path, + g_config->File.ocr_model, + g_config->File.ocr_get_repo, +#if defined(__unix__) && !defined(__APPLE__) + get_config_dir() / "models", +#else + "./models", +#endif + {}, + "", + {}, + "", + "" }; + m_current_color = (rgba_t(g_cache->GetValue(CacheEntry::AnnColor, 0xFF0000FF))); + + m_imgui_id_texts.insert_or_assign(OCR_OUTPUT, m_inputs.ocr_results.data); + m_imgui_id_texts.insert_or_assign(ZBAR_OUTPUT, m_inputs.barcode_text); + return Ok(); } @@ -1065,8 +1084,12 @@ void ScreenshotTool::DrawSelectionBorder() UpdateCursor(); // Draw selection border - draw_list->AddRect( - ImVec2(sel_x, sel_y), ImVec2(sel_x + sel_w, sel_y + sel_h), IM_COL32(0, 150, 255, 255), 0.0f, 1.0f, ImDrawFlags_None); + draw_list->AddRect(ImVec2(sel_x, sel_y), + ImVec2(sel_x + sel_w, sel_y + sel_h), + IM_COL32(0, 150, 255, 255), + 0.0f, + 1.0f, + ImDrawFlags_None); if (!g_config->Runtime.enable_handles) return; @@ -1371,7 +1394,7 @@ void ScreenshotTool::DrawOcrTools() } } - ImGui::InputTextMultiline("##source", + ImGui::InputTextMultiline("##" OCR_OUTPUT, &m_inputs.ocr_results.data, ImVec2(-1, ImGui::GetTextLineHeight() * 8), g_config->File.allow_out_edit ? 0 : ImGuiInputTextFlags_ReadOnly); @@ -1419,7 +1442,7 @@ void ScreenshotTool::DrawBarDecodeTools() ImGui::TreePop(); } - ImGui::InputTextMultiline("##barcode", + ImGui::InputTextMultiline("##" ZBAR_OUTPUT, &m_inputs.barcode_text, ImVec2(-1, ImGui::GetTextLineHeight() * 8), g_config->File.allow_out_edit ? 0 : ImGuiInputTextFlags_ReadOnly); diff --git a/src/util.cpp b/src/util.cpp index dca778a..f7cefb4 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -11,6 +11,7 @@ #include #include +#include "cache.hpp" #include "clipboard.hpp" #include "config.hpp" #include "dotenv.hpp" From c974b090ce656b6bcad7e9285dba06c74352c445 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 26 Jun 2026 22:35:48 +0200 Subject: [PATCH 09/40] fix build --- include/cache.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/cache.hpp b/include/cache.hpp index 10833c3..cef9b12 100644 --- a/include/cache.hpp +++ b/include/cache.hpp @@ -8,6 +8,9 @@ #include "toml++/toml.hpp" #include "util.hpp" +// util.hpp +std::string expand_var(std::string ret); + enum class CacheEntry { AnnColor, From 9d45b623ae1060ab157c0f9d0476f46c81724a85 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 26 Jun 2026 23:06:43 +0200 Subject: [PATCH 10/40] plugins: fix some things from 5ef1047 --- include/screenshot_tool.hpp | 2 +- src/plugins/oshot_plugin.h | 12 +++-- src/plugins/plugins.cpp | 92 +++++++++++++++++++++++++++---------- src/screenshot_tool.cpp | 36 +++++++-------- 4 files changed, 94 insertions(+), 48 deletions(-) diff --git a/include/screenshot_tool.hpp b/include/screenshot_tool.hpp index 85f09ac..42d6cac 100644 --- a/include/screenshot_tool.hpp +++ b/include/screenshot_tool.hpp @@ -307,7 +307,7 @@ class ScreenshotTool std::vector m_annotations; annotation_t m_current_annotation; rgba_t m_current_color; - std::unordered_map m_imgui_id_texts; + std::unordered_map m_imgui_id_texts; std::array m_tool_thickness; bool m_is_drawing = false; bool m_is_color_picking = false; diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h index 925f3b4..c0cacea 100644 --- a/src/plugins/oshot_plugin.h +++ b/src/plugins/oshot_plugin.h @@ -10,7 +10,7 @@ extern "C" { #define OSHOT_API_VERSION 1u -#define OCR_OUTPUT "ocr_output" +#define OCR_OUTPUT "ocr_output" #define ZBAR_OUTPUT "barcode_output" typedef enum @@ -34,13 +34,16 @@ typedef struct size_t len; } oshot_str_t; +oshot_str_t oshot_str_new(const char* str, size_t n); +void oshot_str_free(oshot_str_t* str); + uint32_t oshot_get_abi_version(void); bool oshot_get_plugin_data_dir(oshot_str_t* ret); bool oshot_get_text(const char* imgui_id, oshot_str_t* ret); -void oshot_set_text(const char* imgui_id, const oshot_str_t value); +void oshot_set_text(const char* imgui_id, oshot_str_t value); -void oshot_display_msg(const OSLogLevel lvl, const oshot_str_t str); -void oshot_log(const OSLogLevel lvl, const oshot_str_t str); +void oshot_display_msg(OSLogLevel lvl, oshot_str_t str); +void oshot_log(OSLogLevel lvl, oshot_str_t str); typedef struct { @@ -49,6 +52,7 @@ typedef struct uint8_t* rgba; } oshot_capture_t; oshot_capture_t oshot_get_capture(bool render_anns); +void oshot_capture_free(oshot_capture_t* cap); /* ------------------------------------------------------------------ * Plugin descriptor. diff --git a/src/plugins/plugins.cpp b/src/plugins/plugins.cpp index 43e0db0..1933191 100644 --- a/src/plugins/plugins.cpp +++ b/src/plugins/plugins.cpp @@ -9,8 +9,8 @@ struct oshot_host_api_t { - uint32_t abi_version; - const char* plugin_name; + uint32_t abi_version = OSHOT_API_VERSION; + const char* plugin_name = ""; } g_api; uint32_t oshot_get_abi_version() @@ -18,31 +18,50 @@ uint32_t oshot_get_abi_version() return g_api.abi_version; } +oshot_str_t oshot_str_new(const char* str, size_t len) +{ + oshot_str_t r; + r.p = reinterpret_cast(malloc(len)); + if (r.p) + memcpy(const_cast(r.p), str, len); + r.len = r.p ? len : 0; + return r; +} + +void oshot_str_free(oshot_str_t* str) +{ + free((void*)str->p); + str->p = nullptr; + str->len = 0; +} + void oshot_display_msg(const OSLogLevel lvl, const oshot_str_t str) { - const std::string& fmt = fmt::format("{}: {}", g_api.plugin_name, str.p); + std::string_view msg(str.p, str.len); + const std::string& out = fmt::format("{}: {}", g_api.plugin_name, msg); switch (lvl) { case OSLogLevel::OSHOT_LOG_DEBUG: spdlog::warn("OSHOT_LOG_DEBUG is not allowed when displaying a message."); break; - case OSLogLevel::OSHOT_LOG_INFO: info("{}", fmt); break; - case OSLogLevel::OSHOT_LOG_WARN: warn("{}", fmt); break; - case OSLogLevel::OSHOT_LOG_ERROR: error("{}", fmt); break; + case OSLogLevel::OSHOT_LOG_INFO: info("{}", out); break; + case OSLogLevel::OSHOT_LOG_WARN: warn("{}", out); break; + case OSLogLevel::OSHOT_LOG_ERROR: error("{}", out); break; } } -void oshot_log(const OSLogLevel lvl, const oshot_str_t str) +void oshot_log(OSLogLevel lvl, oshot_str_t str) { auto now = std::chrono::system_clock::now(); - const std::string& fmt = fmt::format("[{:%%F_%%H-%%M-%%S}] {}: {}", now, g_api.plugin_name, str.p); + std::string_view msg(str.p, str.len); + const std::string& out = fmt::format("[{}] {}: {}", now, g_api.plugin_name, msg); switch (lvl) { - case OSLogLevel::OSHOT_LOG_DEBUG: spdlog::debug("{}", fmt); break; - case OSLogLevel::OSHOT_LOG_INFO: spdlog::info("{}", fmt); break; - case OSLogLevel::OSHOT_LOG_WARN: spdlog::warn("{}", fmt); break; - case OSLogLevel::OSHOT_LOG_ERROR: spdlog::error("{}", fmt); break; + case OSLogLevel::OSHOT_LOG_DEBUG: spdlog::debug("{}", out); break; + case OSLogLevel::OSHOT_LOG_INFO: spdlog::info("{}", out); break; + case OSLogLevel::OSHOT_LOG_WARN: spdlog::warn("{}", out); break; + case OSLogLevel::OSHOT_LOG_ERROR: spdlog::error("{}", out); break; } } @@ -50,27 +69,50 @@ oshot_capture_t oshot_get_capture(bool render_anns) { const capture_result_t& cap = g_ss_tool.GetFinalImage(render_anns); - oshot_capture_t ret; + oshot_capture_t ret{}; // zero-inits + + if (cap.data.empty() || cap.w <= 0 || cap.h <= 0) + return ret; // plugin must check ret.rgba == nullptr before use + + ret.rgba = reinterpret_cast(std::malloc(cap.data.size())); + if (!ret.rgba) + return ret; + std::memcpy(ret.rgba, cap.data.data(), cap.data.size()); - ret.h = cap.h; ret.w = cap.w; - + ret.h = cap.h; return ret; } +void oshot_capture_free(oshot_capture_t* cap) +{ + std::free(cap->rgba); + cap->rgba = nullptr; + cap->w = cap->h = 0; +} + bool oshot_get_text(const char* imgui_id, oshot_str_t* ret) { - auto t = g_ss_tool.GetImGuiIDTexts(); - if (auto p = t.find(imgui_id); p != t.end()) - { - ret->p = p->second.c_str(); - ret->len = p->second.length(); - return true; - } - return false; + auto& t = g_ss_tool.GetImGuiIDTexts(); + auto p = t.find(imgui_id); + if (p == t.end()) + return false; + + ret->p = reinterpret_cast(std::malloc(p->second->length())); + if (!ret->p) + return false; + + std::memcpy(const_cast(ret->p), p->second->c_str(), p->second->length()); + ret->len = p->second->length(); + return true; } -void oshot_set_text(const char* imgui_id, const oshot_str_t ret) +void oshot_set_text(const char* imgui_id, const oshot_str_t value) { - g_ss_tool.GetImGuiIDTexts().insert_or_assign(imgui_id, std::string(ret.p, ret.len)); + auto& t = g_ss_tool.GetImGuiIDTexts(); + auto it = t.find(imgui_id); + if (it == t.end()) + return; // unknown id -- nothing registered to write into + + it->second->assign(value.p, value.len); // mutate the live buffer, no temporaries } diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index c8a8bd3..d8af369 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -338,6 +338,24 @@ Result<> ScreenshotTool::Start() Result<> ScreenshotTool::StartWindow() { + m_inputs = { g_config->File.ocr_path, + g_config->File.ocr_model, + g_config->File.ocr_get_repo, +#if defined(__unix__) && !defined(__APPLE__) + get_config_dir() / "models", +#else + "./models", +#endif + {}, + "", + {}, + "", + "" }; + m_current_color = (rgba_t(g_cache->GetValue(CacheEntry::AnnColor, 0xFF0000FF))); + + m_imgui_id_texts.insert_or_assign(OCR_OUTPUT, &m_inputs.ocr_results.data); + m_imgui_id_texts.insert_or_assign(ZBAR_OUTPUT, &m_inputs.barcode_text); + m_state = ToolState::Selecting; m_show_text_tools = g_config->File.show_text_tools; @@ -382,24 +400,6 @@ Result<> ScreenshotTool::StartWindow() else if (!fs::is_directory(m_inputs.ocr_model_downloaded_path)) SetError(m_download_errors, OcrDownloadError::InvalidPath, "Not a directory"); - m_inputs = { g_config->File.ocr_path, - g_config->File.ocr_model, - g_config->File.ocr_get_repo, -#if defined(__unix__) && !defined(__APPLE__) - get_config_dir() / "models", -#else - "./models", -#endif - {}, - "", - {}, - "", - "" }; - m_current_color = (rgba_t(g_cache->GetValue(CacheEntry::AnnColor, 0xFF0000FF))); - - m_imgui_id_texts.insert_or_assign(OCR_OUTPUT, m_inputs.ocr_results.data); - m_imgui_id_texts.insert_or_assign(ZBAR_OUTPUT, m_inputs.barcode_text); - return Ok(); } From eaf73fc15fb256a0dfe4e9d601f166ffe4cd2247 Mon Sep 17 00:00:00 2001 From: Toni500github <88878648+Toni500github@users.noreply.github.com> Date: Sun, 28 Jun 2026 16:57:39 +0200 Subject: [PATCH 11/40] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1e8d6e0..46258b3 100644 --- a/README.md +++ b/README.md @@ -42,10 +42,10 @@ https://github.com/user-attachments/assets/800f50b3-95a6-47c4-b9bd-5a90c35941b2 | Shortcut | Action | | -------------- | ----------------------- | | `Ctrl+C/S` | Copy/Save selection as image | -| `Ctrl+A` ` | Select full image | -| `Ctrl+Z` ` | Undo | -| `Ctrl+G` ` | Toggle handles | -| `Ctrl+E` ` | Toggle text editing | +| `Ctrl+A` | Select full image | +| `Ctrl+Z` | Undo | +| `Ctrl+G` | Toggle handles | +| `Ctrl+E` | Toggle text editing | | `Esc` | Close | ## Installation From ba89d2d47fdd2486460439db9697debfdba73bad Mon Sep 17 00:00:00 2001 From: Toni500git Date: Tue, 30 Jun 2026 14:09:59 +0200 Subject: [PATCH 12/40] build: replace hand-rolled Makefile with a thin CMake wrapper The old Makefile and mk/common.mk rules had no header dependency tracking (no -MMD/-MP), so editing imgui.h during the 1.92.9 WIP migration didn't trigger a rebuild of liboshot_imgui.so. The result was a stale .so linked against fresh app code, with mismatched ImGuiIO layouts between the two. This is what IMGUI_CHECKVERSION() caught as an assertion failure in debug builds, and very likely also explains the earlier "toolbar click resets selection" bug, since ui_blocks_selection()/HandleSelectionInput() are unchanged between the working and broken commits. CMakeLists.txt already builds the same targets with proper compiler- driven dependency tracking and never showed either symptom. All CI already builds via CMake, so there's no remaining reason to keep a second, manually-synced build description around. Replace the root Makefile with a thin wrapper around `cmake --build`, keeping the existing CLI (make, clean, distclean, dist, DEBUG=0/1 -> build/release or build/debug). mk/common.mk and the per-lib Makefiles under src/libs/ are now deleted. Keeping it on a separate commit in case I want to roll this back. --- CMakeLists.txt | 2 +- Makefile | 183 ++++++++----------------- mk/common.mk | 123 ----------------- src/libs/cimgui/Makefile | 9 -- src/libs/clip/Makefile | 20 --- src/libs/fmt/Makefile | 12 -- src/libs/getopt_port/Makefile | 5 - src/libs/imgui/Makefile | 8 -- src/libs/nvdialog/Makefile | 33 ----- src/libs/tiny-process-library/Makefile | 20 --- src/libs/tinyfiledialogs/Makefile | 9 -- src/libs/toml++/Makefile | 8 -- src/libs/tray/Makefile | 13 -- 13 files changed, 56 insertions(+), 389 deletions(-) delete mode 100644 mk/common.mk delete mode 100644 src/libs/cimgui/Makefile delete mode 100644 src/libs/clip/Makefile delete mode 100644 src/libs/fmt/Makefile delete mode 100644 src/libs/getopt_port/Makefile delete mode 100644 src/libs/imgui/Makefile delete mode 100644 src/libs/nvdialog/Makefile delete mode 100644 src/libs/tiny-process-library/Makefile delete mode 100644 src/libs/tinyfiledialogs/Makefile delete mode 100644 src/libs/toml++/Makefile delete mode 100644 src/libs/tray/Makefile diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c24f3a..a22234a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -245,7 +245,7 @@ add_library(imgui SHARED ${IMGUI_SOURCES}) enable_lto(imgui) target_include_directories(imgui PUBLIC include/libs/imgui) -target_compile_definitions(imgui PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLAD) +target_compile_definitions(imgui PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLAD IMGUI_DISABLE_OBSOLETE_FUNCTIONS) target_link_libraries(imgui PUBLIC ${GLFW_TARGET}) if(APPLE) diff --git a/Makefile b/Makefile index 834c2a9..be45cb0 100644 --- a/Makefile +++ b/Makefile @@ -1,147 +1,74 @@ -CXX ?= g++ -TAR ?= bsdtar -PREFIX ?= /usr -VARS ?= -CXXSTD ?= c++20 - -DEBUG ?= 0 -WINDOWS_CMD ?= 0 - -COMPILER := $(shell $(CXX) --version | head -n1) - -ifeq ($(findstring g++,$(COMPILER)),g++) - export LTO_FLAGS = -flto=auto -ffat-lto-objects -else ifeq ($(findstring clang,$(COMPILER)),clang) - export LTO_FLAGS = -flto=thin -else - $(warning Unknown compiler: $(COMPILER). No LTO flags applied.) -endif - -UNAME_S := $(shell uname -s) -ifeq ($(UNAME_S),Linux) - LDLIBS += -lGL - CXXFLAGS += `pkg-config --static --cflags gio-2.0 appindicator3-0.1 x11` -DCLIP_ENABLE_IMAGE=1 - LDLIBS += `pkg-config --static --libs gio-2.0 appindicator3-0.1 x11 xrandr` - -else ifeq ($(UNAME_S),Darwin) #APPLE - LDFLAGS += -L/usr/local/lib -L/opt/local/lib -L/opt/homebrew/lib - LDLIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - #LDLIBS += -lglfw3 - #LDLIBS += -lglfw - - CXXFLAGS += -I/usr/local/include -I/opt/local/include -I/opt/homebrew/include - -else ifeq ($(findstring _NT,$(UNAME_S)),_NT) - LDLIBS += -ld3d11 -ldxgi -lgdi32 -lopengl32 -limm32 -lole32 -lcomdlg32 -luuid -lshcore -lshlwapi -lwindowscodecs - ifneq ($(WINDOWS_CMD),1) - CXXFLAGS += -mwindows - LDFLAGS += -mwindows - else - CXXFLAGS += -DWINDOWS_CMD - endif -endif - -# https://stackoverflow.com/a/1079861 -# WAY easier way to build debug and release builds -ifeq ($(DEBUG), 1) - BUILDDIR := build/debug - LTO_FLAGS := -fno-lto - SAN_FLAGS ?= -fsanitize=address -fsanitize=undefined - CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter \ - -DDEBUG=1 -fno-omit-frame-pointer $(DEBUG_CXXFLAGS) $(CXXFLAGS) - LDFLAGS += -Wl,-rpath,$(BUILDDIR) +# Thin Makefile wrapper around CMake. +# +# This file does NOT compile anything itself. All build logic (sources, +# per-platform deps, flags, library targets) lives in CMakeLists.txt. This +# exists purely so `make`/`make clean`/`make distclean`/etc. keep working +# for people and CI used to that interface, without maintaining a second, +# independently-drifting set of compile rules alongside CMakeLists.txt. + +CMAKE ?= cmake +PREFIX ?= /usr +DEBUG ?= 1 +WINDOWS_CMD ?= 0 +JOBS := $(shell echo $(MAKEFLAGS) | grep -oP '(?<=-j)\d+') +JOBS ?= $(shell nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4) + +NAME := oshot +VERSION := 0.4.6 +OLDVERSION := 0.4.5 +TARGET ?= $(NAME) + +ifeq ($(DEBUG),1) + BUILDDIR := build/debug + BUILD_TYPE := Debug else - # Check if an optimization flag is not already set - ifneq ($(filter -O%,$(CXXFLAGS)),) - $(info Keeping the existing optimization flag in CXXFLAGS) - else - CXXFLAGS := -O3 -march=native $(CXXFLAGS) - endif - BUILDDIR := build/release + BUILDDIR := build/release + BUILD_TYPE := Release endif -NAME = oshot -TARGET ?= $(NAME) -VERSION = 0.4.6 -OLDVERSION = 0.4.5 -SRC = $(wildcard src/*.cpp) -OBJ = $(patsubst src/%.cpp,$(BUILDDIR)/%.o,$(SRC)) -LDFLAGS += -L$(BUILDDIR) $(LTO_FLAGS) -LDLIBS += $(LIBS) `pkg-config --static --libs glfw3 tesseract zbar` -CXXFLAGS += $(LTO_FLAGS) -fvisibility-inlines-hidden -fvisibility=hidden -Iinclude -Iinclude/libs -std=$(CXXSTD) $(VARS) -DVERSION=\"$(VERSION)\" - -LIBS := \ - $(BUILDDIR)/liboshot_imgui.so \ - $(BUILDDIR)/liboshot_cimgui.so \ - $(BUILDDIR)/libfmt.a \ - $(BUILDDIR)/libclip.a \ - $(BUILDDIR)/libtray.a \ - $(BUILDDIR)/libnvdialog.a \ - $(BUILDDIR)/libtiny-process-library.a - -EXTRA_OBJ := \ - $(BUILDDIR)/toml.o \ - $(BUILDDIR)/tinyfiledialogs.o \ - $(BUILDDIR)/getopt.o - -all: $(BUILDDIR)/$(TARGET) +CMAKE_CONFIGURE_FLAGS := \ + -S . -B $(BUILDDIR) \ + -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) \ + -DWINDOWS_CMD=$(WINDOWS_CMD) \ + -DCMAKE_INSTALL_PREFIX=$(PREFIX) -$(BUILDDIR): - mkdir -p $(BUILDDIR) +.PHONY: all configure build clean distclean dist genver updatever install -$(BUILDDIR)/%.o: src/%.cpp - @mkdir -p $(dir $@) - $(CXX) $(CXXFLAGS) -c $< -o $@ +all: build -$(BUILDDIR)/liboshot_imgui.so: | $(BUILDDIR) - $(MAKE) -C src/libs/imgui BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) +# Re-configure whenever CMakeLists.txt changes or the build dir doesn't +# exist yet. CMake re-configures itself as needed beyond this too (e.g. if +# a referenced file changes), this just guarantees a fresh checkout works +# with a single `make`. +$(BUILDDIR)/CMakeCache.txt: CMakeLists.txt + $(CMAKE) $(CMAKE_CONFIGURE_FLAGS) -$(BUILDDIR)/libfmt.a: | $(BUILDDIR) - $(MAKE) -C src/libs/fmt BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) +configure: $(BUILDDIR)/CMakeCache.txt -$(BUILDDIR)/liboshot_cimgui.so: $(BUILDDIR)/liboshot_imgui.so | $(BUILDDIR) - $(MAKE) -C src/libs/cimgui BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) - -$(BUILDDIR)/toml.o: | $(BUILDDIR) - $(MAKE) -C src/libs/toml++ BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) - -$(BUILDDIR)/libclip.a: | $(BUILDDIR) - $(MAKE) -C src/libs/clip BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) - -$(BUILDDIR)/libtray.a: | $(BUILDDIR) - $(MAKE) -C src/libs/tray BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) - -$(BUILDDIR)/libnvdialog.a: | $(BUILDDIR) - $(MAKE) -C src/libs/nvdialog BUILDDIR=$(BUILDDIR) DEBUG=$(DEBUG) - -$(BUILDDIR)/tinyfiledialogs.o: | $(BUILDDIR) - $(MAKE) -C src/libs/tinyfiledialogs BUILDDIR=$(BUILDDIR) - -$(BUILDDIR)/libtiny-process-library.a: | $(BUILDDIR) - $(MAKE) -C src/libs/tiny-process-library BUILDDIR=$(BUILDDIR) CXXSTD=$(CXXSTD) DEBUG=$(DEBUG) - -$(BUILDDIR)/getopt.o: | $(BUILDDIR) - $(MAKE) -C src/libs/getopt_port BUILDDIR=$(BUILDDIR) +build: configure + $(CMAKE) --build $(BUILDDIR) --parallel $(JOBS) +# Generates version info ahead of time; CMakeLists.txt also runs this at +# configure time, so this target is mainly for manual/CI use outside a +# full configure+build cycle. genver: ./scripts/generateVersion.sh -$(BUILDDIR)/$(TARGET): genver $(OBJ) $(EXTRA_OBJ) $(LIBS) - $(CXX) -o $@ $(OBJ) $(EXTRA_OBJ) $(LDFLAGS) $(LDLIBS) - -dist: $(TARGET) - zip -j $(NAME)-v$(VERSION).zip LICENSE README.md $(BUILDDIR)/$(TARGET) - +# Removes built artifacts but keeps the CMake cache/config, so the next +# `make` is a fast incremental rebuild rather than a full re-configure. clean: - rm -rf $(BUILDDIR)/$(TARGET) $(OBJ) + $(CMAKE) --build $(BUILDDIR) --target clean distclean: - rm -rf $(BUILDDIR) $(OBJ) + rm -rf build find . -type f -name "*.tar.gz" -delete - find . -type f -name "*.o" -delete - find . -type f -name "*.a" -delete + find src -type f \( -name "*.o" -o -name "*.a" -o -name "*.so" -o -name "*.dylib" \) -delete + +dist: build + zip -j $(NAME)-v$(VERSION).zip LICENSE README.md $(BUILDDIR)/$(TARGET) + +install: build + $(CMAKE) --install $(BUILDDIR) --prefix $(PREFIX) updatever: sed -i "s#$(OLDVERSION)#$(VERSION)#g" $(wildcard .github/workflows/*.yml scripts/*) CMakeLists.txt compile_flags.txt - -.PHONY: $(TARGET) updatever distclean clean dist all diff --git a/mk/common.mk b/mk/common.mk deleted file mode 100644 index 213daab..0000000 --- a/mk/common.mk +++ /dev/null @@ -1,123 +0,0 @@ -# Shared build logic for src/libs/*/Makefile. -# -# Each lib's Makefile sets a handful of variables and then does: -# include ../../../mk/common.mk -# -# Required variables (set by the including Makefile): -# LIBKIND - object | static | shared -# SRC - source files, e.g. SRC = toml.cpp, or SRC := $(wildcard *.cpp) -# -# Variables required for LIBKIND = static or shared, ignored for object: -# LIBNAME - output name without the shared extension, e.g. liboshot_imgui -# (the .a/.so/.dylib/.dll suffix is added here) -# -# Variables required for LIBKIND = object only: -# TARGET - single output object file, e.g. toml.o -# -# Optional variables: -# CXX, CC, CXXSTD - default to g++/cc/c++20 -# CXXFLAGS, CFLAGS - extra per-lib flags, appended after the common ones -# EXTRA_LIBS - extra -L/-l flags for the link step (LIBKIND = shared only) -# LTO_FLAGS, DEBUG_CXXFLAGS, DEBUG, BUILDDIR - passed down from the top-level Makefile - -CXX ?= g++ -CC ?= cc -CXXSTD ?= c++20 - -# Override VISIBILITY := default in the including Makefile for libs that need -# to export symbols (toml++, cimgui currently do; most static/internal libs don't). -VISIBILITY ?= hidden - -# No default -I path here: every lib states its own include dirs explicitly -# before the include line (some use the bare include/libs/ dir, some use -# their own include/libs// subdir - it varies per lib, so it's not -# safe to assume one or the other generically). -CSTD ?= c11 - -CXXFLAGS += -std=$(CXXSTD) $(LTO_FLAGS) -fvisibility=$(VISIBILITY) -fvisibility-inlines-hidden -fPIC -CFLAGS += -std=$(CSTD) $(LTO_FLAGS) -fvisibility=$(VISIBILITY) -fPIC - -ifeq ($(DEBUG),1) - CXXFLAGS := -ggdb3 -Wall -Wextra -pedantic -Wno-unused-parameter \ - -DDEBUG=1 -fno-omit-frame-pointer $(DEBUG_CXXFLAGS) $(CXXFLAGS) -else - CXXFLAGS += -O3 -DNDEBUG -endif - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) - SHAREDEXT = dylib - SHAREDFLAGS = -dynamiclib -install_name @rpath/$(LIBNAME).$(SHAREDEXT) -else ifeq ($(findstring MINGW64_NT,$(UNAME_S)),MINGW64_NT) - SHAREDEXT = dll - SHAREDFLAGS = -shared - CXXFLAGS += -D_CRT_SECURE_NO_WARNINGS -else - CXXFLAGS += -Wall -Wextra - SHAREDEXT = so - SHAREDFLAGS = -shared -Wl,-soname,$(LIBNAME).$(SHAREDEXT) -endif - -OBJ := $(addsuffix .o,$(basename $(SRC))) - -# Output name for static/shared kinds; unused for object (TARGET is used instead there). -OUT_static = $(LIBNAME).a -OUT_shared = $(LIBNAME).$(SHAREDEXT) -OUT = $(OUT_$(LIBKIND)) - -all: $(if $(filter object,$(LIBKIND)),$(TARGET),$(OUT)) - -# --- object: compile a single source file straight to ../../../$(BUILDDIR)/$(TARGET) --- -# Picks CC/CFLAGS for a .c source, CXX/CXXFLAGS otherwise. -ifeq ($(LIBKIND),object) -ifeq ($(suffix $(SRC)),.c) -$(TARGET): - $(CC) $(SRC) $(CFLAGS) -c -o ../../../$(BUILDDIR)/$@ -else -$(TARGET): - $(CXX) $(SRC) $(CXXFLAGS) -c -o ../../../$(BUILDDIR)/$@ -endif -endif - -# --- static: archive OBJ into $(LIBNAME).a --- -ifeq ($(LIBKIND),static) -$(OUT): $(OBJ) - ar rcs $@ $^ - ranlib $@ - mv -f $@ ../../../$(BUILDDIR)/$@ -endif - -# --- shared: link OBJ into a platform shared library --- -ifeq ($(LIBKIND),shared) -$(OUT): $(OBJ) - $(CXX) $(CXXFLAGS) $(SHAREDFLAGS) -o $@ $^ $(EXTRA_LIBS) - mv -f $@ ../../../$(BUILDDIR)/$@ -endif - -%.o: %.cpp - $(CXX) $(CXX_DEFINES) $(CXXFLAGS) -c -o $@ $< - -%.o: %.cc - $(CXX) $(CXX_DEFINES) $(CXXFLAGS) -c -o $@ $< - -%.o: %.mm - $(CXX) $(CXX_DEFINES) $(CXXFLAGS) -c -o $@ $< - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - -%.o: %.m - $(CC) $(CFLAGS) -c -o $@ $< - -# Where `clean` looks for the installed artifact. Mirrors exactly what the -# build rules above write to, so clean never points at a path `all` doesn't -# actually produce (the previous per-lib Makefiles had drifted on this). -CLEANTARGET_object = ../../../$(BUILDDIR)/$(TARGET) -CLEANTARGET_static = ../../../$(BUILDDIR)/$(OUT) -CLEANTARGET_shared = ../../../$(BUILDDIR)/$(OUT) - -clean: - rm -f $(OBJ) $(TARGET) $(OUT) $(CLEANTARGET_$(LIBKIND)) - -.PHONY: all clean diff --git a/src/libs/cimgui/Makefile b/src/libs/cimgui/Makefile deleted file mode 100644 index b599dae..0000000 --- a/src/libs/cimgui/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -LIBKIND := shared -LIBNAME := liboshot_cimgui -SRC += cimgui.cpp -VISIBILITY := default - -CXXFLAGS += -I../../../include/libs/cimgui -I../../../include/libs/ -EXTRA_LIBS = -L../../../$(BUILDDIR) -loshot_imgui - -include ../../../mk/common.mk diff --git a/src/libs/clip/Makefile b/src/libs/clip/Makefile deleted file mode 100644 index a13f8f8..0000000 --- a/src/libs/clip/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -LIBKIND := static -LIBNAME := libclip -VISIBILITY := default - -CXXFLAGS += -I../../../include/libs/clip -DCLIP_ENABLE_IMAGE=1 - -UNAME_S := $(shell uname -s) -ifeq ($(findstring NT,$(UNAME_S)),NT) - CXXFLAGS += -D_CRT_SECURE_NO_WARNINGS - SRC += $(wildcard clip_win*.cpp) - # Check if we're in MSYS environment - ifneq (,$(findstring MSYS,$(shell uname -o))) - CXXFLAGS += -DMSYS_PROCESS_USE_SH - endif -else - SRC += clip_none.cpp -endif -SRC += clip.cpp image.cpp - -include ../../../mk/common.mk diff --git a/src/libs/fmt/Makefile b/src/libs/fmt/Makefile deleted file mode 100644 index 282a9c7..0000000 --- a/src/libs/fmt/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# Variables taken from {fmt} cmake build files -# I don't wanna use cmake -# cmd: cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF - -LIBKIND := static -LIBNAME := libfmt -SRC = format.cc os.cc -# CXX_DEFINES = -DFMT_LIB_EXPORT -Dfmt_EXPORTS - -CXXFLAGS += -I../../../include/libs - -include ../../../mk/common.mk diff --git a/src/libs/getopt_port/Makefile b/src/libs/getopt_port/Makefile deleted file mode 100644 index 8a81c92..0000000 --- a/src/libs/getopt_port/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -LIBKIND := object -SRC = getopt.c -TARGET = getopt.o - -include ../../../mk/common.mk diff --git a/src/libs/imgui/Makefile b/src/libs/imgui/Makefile deleted file mode 100644 index 4d1adef..0000000 --- a/src/libs/imgui/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -LIBKIND := shared -LIBNAME := liboshot_imgui -SRC := $(wildcard *.cpp) -VISIBILITY := default - -CXXFLAGS += -I../../../include/libs/imgui -DIMGUI_DISABLE_OBSOLETE_FUNCTIONS - -include ../../../mk/common.mk diff --git a/src/libs/nvdialog/Makefile b/src/libs/nvdialog/Makefile deleted file mode 100644 index 49af77d..0000000 --- a/src/libs/nvdialog/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -LIBKIND := static -LIBNAME := libnvdialog -VISIBILITY := default - -CFLAGS += -I../../../include/libs/nvdialog -Iimpl -Ibackend -O3 \ - -Wall -Wextra -Wconversion -Winline -Wno-sign-conversion \ - -Werror=format -Werror=format-security -Werror=write-strings \ - -DNVDIALOG_MAXBUF=4096 -DNVD_EXPORT_SYMBOLS -DNVD_STATIC_LINKAGE=1 - -PKGCONF ?= pkg-config - -# Sources common to every platform. -SRC := $(wildcard *.c) $(wildcard src/*.c) - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) - SRC += $(wildcard backend/cocoa/*.m) - CFLAGS += -DNVD_USE_COCOA=1 -fno-objc-arc - # Whatever links libnvdialog.a must additionally add: - # -framework AppKit -framework Cocoa -framework Foundation -framework UserNotifications -else ifeq ($(findstring NT,$(UNAME_S)),NT) - SRC += $(wildcard backend/win32/*.c) - # Whatever links libnvdialog.a must additionally add: - # -lcomdlg32 -lshell32 -luser32 -lgdi32 -lole32 -else - SRC += $(wildcard backend/gtk/*.c) - CFLAGS += `$(PKGCONF) --cflags gtk+-3.0 dbus-1` - # Whatever links libnvdialog.a must additionally add: - # `pkg-config --libs gtk+-3.0 dbus-1` -endif - -include ../../../mk/common.mk diff --git a/src/libs/tiny-process-library/Makefile b/src/libs/tiny-process-library/Makefile deleted file mode 100644 index 31d14b8..0000000 --- a/src/libs/tiny-process-library/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -LIBKIND := static -LIBNAME := libtiny-process-library -VISIBILITY := default - -CXXFLAGS += -I../../../include/libs/tiny-process-library - -UNAME_S := $(shell uname -s) -ifeq ($(findstring MINGW64_NT,$(UNAME_S)),MINGW64_NT) - CXXFLAGS += -D_CRT_SECURE_NO_WARNINGS - SRC += process_win.cpp - # Check if we're in MSYS environment - ifneq (,$(findstring MSYS,$(shell uname -o))) - CXXFLAGS += -DMSYS_PROCESS_USE_SH - endif -else - SRC += process_unix.cpp -endif -SRC += process.cpp - -include ../../../mk/common.mk diff --git a/src/libs/tinyfiledialogs/Makefile b/src/libs/tinyfiledialogs/Makefile deleted file mode 100644 index 4e45d76..0000000 --- a/src/libs/tinyfiledialogs/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -LIBKIND := object -SRC = tinyfiledialogs.c -TARGET = tinyfiledialogs.o -VISIBILITY := default -CSTD ?= c11 - -CFLAGS += -I../../../include/libs -O3 - -include ../../../mk/common.mk diff --git a/src/libs/toml++/Makefile b/src/libs/toml++/Makefile deleted file mode 100644 index 7c2e602..0000000 --- a/src/libs/toml++/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -LIBKIND := object -SRC = toml.cpp -TARGET = toml.o -VISIBILITY := default - -CXXFLAGS += -I../../../include/libs - -include ../../../mk/common.mk diff --git a/src/libs/tray/Makefile b/src/libs/tray/Makefile deleted file mode 100644 index 2bd0b7d..0000000 --- a/src/libs/tray/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -LIBKIND := static -LIBNAME := libtray -PKG_FLAGS := `pkg-config --cflags appindicator3-0.1` - -CXXFLAGS += $(PKG_FLAGS) -I../../../include/libs - -ifeq ($(shell uname -s),Darwin) - SRC := tray_darwin.mm -else - SRC := $(wildcard ./*.cpp) -endif - -include ../../../mk/common.mk From 35729c81ba66a86ff011f7485385639367f6d015 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Tue, 30 Jun 2026 22:07:52 +0200 Subject: [PATCH 13/40] plugins: add config getter API + organize the code --- Makefile | 2 +- include/config.hpp | 5 ++ src/plugins/oshot_plugin.h | 92 ++++++++++++++++++----- src/plugins/plugins.cpp | 148 +++++++++++++++++++++++++++++++------ 4 files changed, 205 insertions(+), 42 deletions(-) diff --git a/Makefile b/Makefile index be45cb0..3853247 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ CMAKE ?= cmake PREFIX ?= /usr -DEBUG ?= 1 +DEBUG ?= 0 WINDOWS_CMD ?= 0 JOBS := $(shell echo $(MAKEFLAGS) | grep -oP '(?<=-j)\d+') JOBS ?= $(shell nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4) diff --git a/include/config.hpp b/include/config.hpp index 979cc51..2381583 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -226,6 +226,11 @@ class Config } } + const toml::array* GetValueArray(const std::string_view value) const + { + return m_tbl.at_path(value).as_array(); + } + /** * Get the theme style variable and return a rgba type value * @param value The value we want diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h index c0cacea..037c630 100644 --- a/src/plugins/oshot_plugin.h +++ b/src/plugins/oshot_plugin.h @@ -28,22 +28,13 @@ typedef enum OSHOT_LOG_ERROR, } OSLogLevel; -typedef struct +typedef enum { - const char* p; - size_t len; -} oshot_str_t; - -oshot_str_t oshot_str_new(const char* str, size_t n); -void oshot_str_free(oshot_str_t* str); - -uint32_t oshot_get_abi_version(void); -bool oshot_get_plugin_data_dir(oshot_str_t* ret); -bool oshot_get_text(const char* imgui_id, oshot_str_t* ret); -void oshot_set_text(const char* imgui_id, oshot_str_t value); - -void oshot_display_msg(OSLogLevel lvl, oshot_str_t str); -void oshot_log(OSLogLevel lvl, oshot_str_t str); + OSHOT_VAL_STRING, + OSHOT_VAL_INT64, + OSHOT_VAL_BOOL, + OSHOT_VAL_DOUBLE +} OSValueKind; typedef struct { @@ -51,8 +42,24 @@ typedef struct int32_t h; uint8_t* rgba; } oshot_capture_t; -oshot_capture_t oshot_get_capture(bool render_anns); -void oshot_capture_free(oshot_capture_t* cap); + +typedef struct +{ + const char* p; + size_t len; +} oshot_str_t; + +typedef struct +{ + OSValueKind kind; + union + { + oshot_str_t s; + int64_t i; + bool b; + double d; + }; +} oshot_value_t; /* ------------------------------------------------------------------ * Plugin descriptor. @@ -70,8 +77,55 @@ typedef struct void (*on_ocr_done)(void* state); } oshot_plugin_t; -/* Must return a pointer to a static, process-lifetime oshot_plugin_t, - * not something allocated per call. */ +/* ------------------------------------------------------------------ + * ABI / identity + * ------------------------------------------------------------------ */ +uint32_t oshot_get_abi_version(void); +bool oshot_get_plugin_data_dir(oshot_str_t* ret); + +/* ------------------------------------------------------------------ + * oshot_str_t lifecycle + * ------------------------------------------------------------------ */ +oshot_str_t oshot_str_new(const char* str, size_t n); +void oshot_str_free(oshot_str_t* str); + +/* ------------------------------------------------------------------ + * Logging / host messaging + * ------------------------------------------------------------------ */ +void oshot_display_msg(OSLogLevel lvl, oshot_str_t str); +void oshot_log(OSLogLevel lvl, oshot_str_t str); +void oshot_debug(oshot_str_t str); // oshot_log(DEBUG, str); + +/* ------------------------------------------------------------------ + * Config (plugin namespace only) + * ------------------------------------------------------------------ */ +oshot_str_t oshot_config_get_string(const char* key, oshot_str_t fallback); +bool oshot_config_get_bool(const char* key, bool fallback); +int64_t oshot_config_get_int64(const char* key, int64_t fallback); +float oshot_config_get_float(const char* key, float fallback); +double oshot_config_get_double(const char* key, double fallback); +size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max); + +// Only frees OSHOT_VAL_STRING members +void oshot_value_array_free(oshot_value_t* arr, size_t n); + +/* ------------------------------------------------------------------ + * ImGui-bound text buffers + * ------------------------------------------------------------------ */ +bool oshot_get_text(const char* imgui_id, oshot_str_t* ret); +void oshot_set_text(const char* imgui_id, oshot_str_t value); + +/* ------------------------------------------------------------------ + * Capture acquisition + * ------------------------------------------------------------------ */ +oshot_capture_t oshot_get_capture(void); +void oshot_capture_free(oshot_capture_t* cap); + +/* ------------------------------------------------------------------ + * Plugin descriptor entry point + * Must return a pointer to a static, process-lifetime oshot_plugin_t, + * not something allocated per call. + * ------------------------------------------------------------------ */ oshot_plugin_t* oshot_host_get_plugin(void); #ifdef __cplusplus diff --git a/src/plugins/plugins.cpp b/src/plugins/plugins.cpp index 1933191..15b087e 100644 --- a/src/plugins/plugins.cpp +++ b/src/plugins/plugins.cpp @@ -1,6 +1,7 @@ #include #include +#include "config.hpp" #include "fmt/chrono.h" #include "fmt/format.h" #include "oshot_plugin.h" @@ -10,14 +11,20 @@ struct oshot_host_api_t { uint32_t abi_version = OSHOT_API_VERSION; - const char* plugin_name = ""; + oshot_plugin_t plugin = {}; } g_api; +/* ------------------------------------------------------------------ + * ABI / identity + * ------------------------------------------------------------------ */ uint32_t oshot_get_abi_version() { return g_api.abi_version; } +/* ------------------------------------------------------------------ + * oshot_str_t lifecycle + * ------------------------------------------------------------------ */ oshot_str_t oshot_str_new(const char* str, size_t len) { oshot_str_t r; @@ -35,10 +42,12 @@ void oshot_str_free(oshot_str_t* str) str->len = 0; } +/* ------------------------------------------------------------------ + * Logging / host messaging + * ------------------------------------------------------------------ */ void oshot_display_msg(const OSLogLevel lvl, const oshot_str_t str) { - std::string_view msg(str.p, str.len); - const std::string& out = fmt::format("{}: {}", g_api.plugin_name, msg); + const std::string& out = fmt::format("{}: {}", g_api.plugin.name, std::string_view(str.p, str.len)); switch (lvl) { case OSLogLevel::OSHOT_LOG_DEBUG: @@ -54,8 +63,7 @@ void oshot_log(OSLogLevel lvl, oshot_str_t str) { auto now = std::chrono::system_clock::now(); - std::string_view msg(str.p, str.len); - const std::string& out = fmt::format("[{}] {}: {}", now, g_api.plugin_name, msg); + const std::string& out = fmt::format("[{}] {}: {}", now, g_api.plugin.name, std::string_view(str.p, str.len)); switch (lvl) { case OSLogLevel::OSHOT_LOG_DEBUG: spdlog::debug("{}", out); break; @@ -65,32 +73,99 @@ void oshot_log(OSLogLevel lvl, oshot_str_t str) } } -oshot_capture_t oshot_get_capture(bool render_anns) +void oshot_debug(oshot_str_t str) { - const capture_result_t& cap = g_ss_tool.GetFinalImage(render_anns); + oshot_log(OSLogLevel::OSHOT_LOG_DEBUG, std::move(str)); +} - oshot_capture_t ret{}; // zero-inits +/* ------------------------------------------------------------------ + * Config + * ------------------------------------------------------------------ */ +oshot_str_t oshot_config_get_string(const char* key, oshot_str_t fallback) +{ + const std::string& str = g_config->GetValue(fmt::format("plugins.{}.{}", g_api.plugin.name, key), + std::string(fallback.p, fallback.len)); + return oshot_str_new(str.c_str(), str.length()); +} - if (cap.data.empty() || cap.w <= 0 || cap.h <= 0) - return ret; // plugin must check ret.rgba == nullptr before use +bool oshot_config_get_bool(const char* key, bool fallback) +{ + bool val = g_config->GetValue(fmt::format("plugins.{}.{}", g_api.plugin.name, key), fallback); + return val; +} - ret.rgba = reinterpret_cast(std::malloc(cap.data.size())); - if (!ret.rgba) - return ret; +int64_t oshot_config_get_int64(const char* key, int64_t fallback) +{ + int64_t val = g_config->GetValue(fmt::format("plugins.{}.{}", g_api.plugin.name, key), fallback); + return val; +} - std::memcpy(ret.rgba, cap.data.data(), cap.data.size()); - ret.w = cap.w; - ret.h = cap.h; - return ret; +float oshot_config_get_float(const char* key, float fallback) +{ + float val = g_config->GetValue(fmt::format("plugins.{}.{}", g_api.plugin.name, key), fallback); + return val; } -void oshot_capture_free(oshot_capture_t* cap) +double oshot_config_get_double(const char* key, double fallback) { - std::free(cap->rgba); - cap->rgba = nullptr; - cap->w = cap->h = 0; + double val = g_config->GetValue(fmt::format("plugins.{}.{}", g_api.plugin.name, key), fallback); + return val; +} + +size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max) +{ + const toml::array* arr = g_config->GetValueArray(fmt::format("plugins.{}.{}", g_api.plugin.name, key)); + if (!arr) + return 0; + + size_t i = 0; + for (auto&& el : *arr) + { + if (i == max) + break; + + oshot_value_t& val = *out[i]; + switch (el.type()) + { + case toml::node_type::string: + val.kind = OSValueKind::OSHOT_VAL_STRING; + val.s = oshot_str_new(el.as_string()->get().c_str(), el.as_string()->get().length()); + break; + + case toml::node_type::boolean: + val.kind = OSValueKind::OSHOT_VAL_BOOL; + val.b = el.as_boolean()->get(); + break; + + case toml::node_type::integer: + val.kind = OSValueKind::OSHOT_VAL_INT64; + val.i = el.as_integer()->get(); + break; + + case toml::node_type::floating_point: + val.kind = OSValueKind::OSHOT_VAL_DOUBLE; + val.d = el.as_floating_point()->get(); + break; + + default: + continue; // unsupported TOML type: skip, don't consume a slot + } + i++; + } + + return i; } +void oshot_value_array_free(oshot_value_t* arr, size_t n) +{ + for (size_t i = 0; i < n; ++i) + if (arr[i].kind == OSValueKind::OSHOT_VAL_STRING) + oshot_str_free(&arr[i].s); +} + +/* ------------------------------------------------------------------ + * ImGui-bound text buffers + * ------------------------------------------------------------------ */ bool oshot_get_text(const char* imgui_id, oshot_str_t* ret) { auto& t = g_ss_tool.GetImGuiIDTexts(); @@ -98,7 +173,7 @@ bool oshot_get_text(const char* imgui_id, oshot_str_t* ret) if (p == t.end()) return false; - ret->p = reinterpret_cast(std::malloc(p->second->length())); + ret->p = static_cast(std::malloc(p->second->length())); if (!ret->p) return false; @@ -116,3 +191,32 @@ void oshot_set_text(const char* imgui_id, const oshot_str_t value) it->second->assign(value.p, value.len); // mutate the live buffer, no temporaries } + +/* ------------------------------------------------------------------ + * Capture acquisition + * ------------------------------------------------------------------ */ +oshot_capture_t oshot_get_capture(void) +{ + const capture_result_t& cap = g_ss_tool.GetFinalImage(); + + oshot_capture_t ret{}; // zero-inits + + if (cap.data.empty() || cap.w <= 0 || cap.h <= 0) + return ret; // plugin must check ret.rgba == nullptr before use + + ret.rgba = static_cast(std::malloc(cap.data.size())); + if (!ret.rgba) + return ret; + + std::memcpy(ret.rgba, cap.data.data(), cap.data.size()); + ret.w = cap.w; + ret.h = cap.h; + return ret; +} + +void oshot_capture_free(oshot_capture_t* cap) +{ + std::free(cap->rgba); + cap->rgba = nullptr; + cap->w = cap->h = 0; +} From 3774be543fcd898e87912c5f0cce28c928898bbe Mon Sep 17 00:00:00 2001 From: Toni500git Date: Wed, 1 Jul 2026 13:15:04 +0200 Subject: [PATCH 14/40] plugins: first working end-to-end plugin load path --- CMakeLists.txt | 47 ++++++ include/config.hpp | 10 +- include/libs/dylib.hpp | 294 ++++++++++++++++++++++++++++++++++++ include/screenshot_tool.hpp | 15 +- include/util.hpp | 1 + src/libs/dylib/demangle.cpp | 74 +++++++++ src/libs/dylib/dylib.cpp | 246 ++++++++++++++++++++++++++++++ src/libs/dylib/format.cpp | 85 +++++++++++ src/libs/dylib/symbols.cpp | 274 +++++++++++++++++++++++++++++++++ src/main.cpp | 24 ++- src/plugins/oshot_plugin.h | 7 +- src/plugins/plugins.cpp | 28 +++- src/screenshot_tool.cpp | 82 ++++++++++ 13 files changed, 1164 insertions(+), 23 deletions(-) create mode 100644 include/libs/dylib.hpp create mode 100644 src/libs/dylib/demangle.cpp create mode 100644 src/libs/dylib/dylib.cpp create mode 100644 src/libs/dylib/format.cpp create mode 100644 src/libs/dylib/symbols.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a22234a..747823b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,10 +213,37 @@ endif() set_target_properties( ${PROJECT_NAME} PROPERTIES + CXX_VISIBILITY_PRESET default + VISIBILITY_INLINES_HIDDEN OFF BUILD_RPATH "${_rpath_origin}/../lib;$" INSTALL_RPATH "${_rpath_origin}/../lib" ) +# ----------------------------- +# oshot's plugin library +# ----------------------------- +add_library(oshot_plugin SHARED src/plugins/plugins.cpp) + +enable_lto(oshot_plugin) + +target_include_directories(oshot_plugin PUBLIC include/libs) +target_include_directories(oshot_plugin PUBLIC include/) +target_compile_definitions(oshot_plugin PRIVATE VERSION="${PROJECT_VERSION}") +target_compile_features(oshot_plugin PUBLIC cxx_std_20) + +target_link_libraries(oshot_plugin PUBLIC fmt) +set_target_properties( + oshot_plugin + PROPERTIES + CXX_VISIBILITY_PRESET default + VISIBILITY_INLINES_HIDDEN OFF + VERSION 1 + SOVERSION 1 +) + + +target_link_libraries(${PROJECT_NAME} PRIVATE oshot_plugin) + # ----------------------------- # fmt library # ----------------------------- @@ -389,6 +416,26 @@ set_target_properties( target_link_libraries(${PROJECT_NAME} PRIVATE clip) +# ----------------------------- +# dylib library (integrated from its own CMakeLists.txt) +# ----------------------------- + +file(GLOB DYLIB_SOURCES src/libs/dylib/*.cpp) +add_library(dylib STATIC ${DYLIB_SOURCES}) + +if(UNIX) + target_link_libraries(dylib PRIVATE dl) +endif() + +target_include_directories(dylib PUBLIC include/libs/) +target_compile_features(dylib PRIVATE cxx_std_20) +set_target_properties( + dylib + PROPERTIES CXX_STANDARD 20 CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON +) + +target_link_libraries(${PROJECT_NAME} PRIVATE dylib) + # ----------------------------- # nvdialog (integrated from its own CMakeLists.txt) # ----------------------------- diff --git a/include/config.hpp b/include/config.hpp index 2381583..84352c1 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -7,10 +7,7 @@ #include #include "fmt/format.h" - -// util.hpp -std::string expand_var(std::string ret); -bool hexstr_to_col(const std::string_view hex, uint32_t& out); +#include "util.hpp" #define TOML_HEADER_ONLY 0 #include "toml++/toml.hpp" @@ -226,10 +223,7 @@ class Config } } - const toml::array* GetValueArray(const std::string_view value) const - { - return m_tbl.at_path(value).as_array(); - } + const toml::array* GetValueArray(const std::string_view value) const { return m_tbl.at_path(value).as_array(); } /** * Get the theme style variable and return a rgba type value diff --git a/include/libs/dylib.hpp b/include/libs/dylib.hpp new file mode 100644 index 0000000..e8ed1b9 --- /dev/null +++ b/include/libs/dylib.hpp @@ -0,0 +1,294 @@ +/** + * @file dylib.hpp + * @version 3.0.1 + * @brief C++ cross-platform wrapper around dynamic loading of shared libraries + * @link https://github.com/martin-olivier/dylib + * + * @author Martin Olivier + * @copyright (c) 2025 Martin Olivier + * + * This library is released under MIT license + */ + +#pragma once + +#include +#include +#include +#include +#include + +#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) +#include +#endif + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#define DYLIB_UNDEFINE_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#define DYLIB_UNDEFINE_NOMINMAX +#endif +#include +#ifdef DYLIB_UNDEFINE_LEAN_AND_MEAN +#undef WIN32_LEAN_AND_MEAN +#undef DYLIB_UNDEFINE_LEAN_AND_MEAN +#endif +#ifdef DYLIB_UNDEFINE_NOMINMAX +#undef NOMINMAX +#undef DYLIB_UNDEFINE_NOMINMAX +#endif +#endif + +#ifdef _WIN32 +#define DYLIB_WIN_MAC_OTHER(win_def, mac_def, other_def) win_def +#define DYLIB_WIN_OTHER(win_def, other_def) win_def +#elif defined(__APPLE__) +#define DYLIB_WIN_MAC_OTHER(win_def, mac_def, other_def) mac_def +#define DYLIB_WIN_OTHER(win_def, other_def) other_def +#else +#define DYLIB_WIN_MAC_OTHER(win_def, mac_def, other_def) other_def +#define DYLIB_WIN_OTHER(win_def, other_def) other_def +#endif + +namespace dylib { + +using native_handle_type = DYLIB_WIN_OTHER(HINSTANCE, void *); +using native_symbol_type = DYLIB_WIN_OTHER(FARPROC, void *); + +static_assert(std::is_pointer::value, "Expecting HINSTANCE to be a pointer"); +static_assert(std::is_pointer::value, "Expecting FARPROC to be a pointer"); + +struct decorations { + const char *prefix; + const char *suffix; + + decorations() : prefix(""), suffix("") {} + decorations(const char *prefix, const char *suffix) : prefix(prefix), suffix(suffix) {} + + static decorations none() noexcept { + return {}; + } + + static decorations os_default() noexcept { + return { + DYLIB_WIN_OTHER("", "lib"), + DYLIB_WIN_MAC_OTHER(".dll", ".dylib", ".so"), + }; + } +}; + +enum symbol_type : std::uint8_t { + C, + CPP, +}; + +struct symbol_info { + std::string name; + std::string demangled_name; + symbol_type type; + bool loadable; +}; + +/** + * This exception is raised when the library failed to load a dynamic library or a symbol + * + * @param message the error message + */ +class exception : public std::runtime_error { +public: + explicit exception(const std::string &message) : std::runtime_error(message) {} +}; + +/** + * This exception is raised when the library failed to load or encountered symbol resolution issues + * + * @param message the error message + */ +class load_error : public exception { +public: + explicit load_error(const std::string &message) : exception(message) {} +}; + +/** + * This exception is raised when the library failed to collect or load symbols + * + * @param message the error message + */ +class symbol_error : public exception { +public: + explicit symbol_error(const std::string &message) : exception(message) {} +}; + +/** + * This exception is raised when the library could not find the requested symbol + * + * @param symbol the requested symbol + * @param error the error message + */ +class symbol_not_found : public symbol_error { +public: + explicit symbol_not_found(const std::string &symbol, const std::string &error) + : symbol_error("Could not get symbol '" + symbol + "':\n" + error) {} +}; + +/** + * This exception is raised when the library found multiple matching symbols + * + * @param symbol the requested symbol + * @param matching_symbols the list of matching symbols + */ +class symbol_multiple_matches : public symbol_error { +public: + explicit symbol_multiple_matches(const std::string &symbol, const std::string &matching_symbols) + : symbol_error("Could not get symbol '" + symbol + "', multiple matches:\n" + + matching_symbols) {} +}; + +/** + * This exception is raised when the library failed to load symbol list + * + * @param error the error message + */ +class symbol_collection_error : public symbol_error { +public: + explicit symbol_collection_error(const std::string &error) + : symbol_error("Could not collect symbols:\n" + error) {} +}; + +/** + * The dylib::library class can hold a dynamic library instance and interact with it + * by getting its symbols like functions or global variables + */ +class library { +public: + library(const library &) = delete; + library &operator=(const library &) = delete; + + library(library &&other) noexcept; + library &operator=(library &&other) noexcept; + + /** + * @brief Loads a dynamic library + * + * @throws dylib::load_error if the library could not be opened (including + * the case of the library file not being found) + * + * @param lib_path the path to the dynamic library to load + * @param decorations os decorations to append to the library name + */ + explicit library(const char *lib_path, decorations decorations = decorations::none()); + explicit library(const std::string &lib_path, decorations decorations = decorations::none()); +#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + explicit library(const std::filesystem::path &lib_path, + decorations decorations = decorations::none()); +#endif + + ~library(); + + /** + * Get a symbol from the dynamic library currently loaded in the object + * + * @throws dylib::symbol_not_found if the symbol could not be found + * @throws dylib::symbol_multiple_matches if multiple matching symbols were found + * @throws dylib::symbol_collection_error if an error occurred during symbols collection + * + * Those exceptions inherit from dylib::symbol_error + * + * @param symbol_name the symbol name to get from the dynamic library + * + * @return a pointer to the requested symbol + */ + native_symbol_type get_symbol(const char *symbol_name) const; + native_symbol_type get_symbol(const std::string &symbol_name) const; + + /** + * Get a function from the dynamic library currently loaded in the object + * + * @throws dylib::symbol_not_found if the symbol could not be found + * @throws dylib::symbol_multiple_matches if multiple matching symbols were found + * @throws dylib::symbol_collection_error if an error occurred during symbols collection + * + * Those exceptions inherit from dylib::symbol_error + * + * @param T the template argument must be the function prototype to get + * @param symbol_name the symbol name of a function to get from the dynamic library + * + * @return a pointer to the requested function + */ + template + T *get_function(const char *symbol_name) const { +#if defined(__GNUC__) && __GNUC__ >= 8 && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif +#ifdef __clang__ +#if __has_warning("-Wcast-function-type-mismatch") +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wcast-function-type-mismatch" +#endif +#endif + return reinterpret_cast(get_symbol(symbol_name)); +#ifdef __clang__ +#if __has_warning("-Wcast-function-type-mismatch") +#pragma clang diagnostic pop +#endif +#endif +#if defined(__GNUC__) && __GNUC__ >= 8 && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + } + + template + T *get_function(const std::string &symbol_name) const { + return get_function(symbol_name.c_str()); + } + + /** + * Get a variable from the dynamic library currently loaded in the object + * + * @throws dylib::symbol_not_found if the symbol could not be found + * @throws dylib::symbol_multiple_matches if multiple matching symbols were found + * @throws dylib::symbol_collection_error if an error occurred during symbols collection + * + * Those exceptions inherit from dylib::symbol_error + * + * @param T the template argument must be the type of the variable to get + * @param symbol_name the symbol name of a variable to get from the dynamic library + * + * @return a reference to the requested variable + */ + template + T &get_variable(const char *symbol_name) const { + return *reinterpret_cast(get_symbol(symbol_name)); + } + + template + T &get_variable(const std::string &symbol_name) const { + return get_variable(symbol_name.c_str()); + } + + /** + * Get the list of symbols from the dynamic library currently loaded in the object + * + * @throws dylib::symbol_collection_error if an error occurred during symbols collection + * + * @return the list of symbols in the dynamic library + */ + std::vector symbols() const; + + /** + * @return the dynamic library handle + */ + native_handle_type native_handle() noexcept; + +protected: + native_handle_type m_handle{nullptr}; +#ifdef __APPLE__ + int m_fd{-1}; +#endif +}; + +} // namespace dylib diff --git a/include/screenshot_tool.hpp b/include/screenshot_tool.hpp index 42d6cac..71d1b72 100644 --- a/include/screenshot_tool.hpp +++ b/include/screenshot_tool.hpp @@ -13,6 +13,8 @@ #include #include +#include "../src/plugins/oshot_plugin.h" +#include "dylib.hpp" #include "imgui/imgui.h" #include "imgui/imgui_internal.h" #include "screen_capture.hpp" @@ -108,6 +110,13 @@ enum class GeneralError : size_t COUNT, }; +struct plugin_entry_t +{ + dylib::library lib; + oshot_plugin_t* plugin; + void* state; +}; + struct point_t { float x{}; @@ -349,8 +358,8 @@ class ScreenshotTool } }; -extern ScreenshotTool g_ss_tool; - -extern std::deque g_dropped_paths; +extern ScreenshotTool g_ss_tool; +extern std::deque g_dropped_paths; +extern std::vector g_plugin_entries; #endif // !_SCREENSHOT_TOOL_HPP_ diff --git a/include/util.hpp b/include/util.hpp index 33e1e00..0e40a8a 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -270,6 +270,7 @@ std::vector encode_to_png(const capture_result_t& cap); std::string replace_str(std::string& str, const std::string_view from, const std::string_view to); std::string select_image(); +std::string expand_var(std::string ret); std::string col_to_hexstr(const rgba_t& col); bool acquire_tray_lock(); diff --git a/src/libs/dylib/demangle.cpp b/src/libs/dylib/demangle.cpp new file mode 100644 index 0000000..9b84428 --- /dev/null +++ b/src/libs/dylib/demangle.cpp @@ -0,0 +1,74 @@ +/** + * @file demangle.cpp + * + * @author Martin Olivier + * @copyright (c) 2025 Martin Olivier + * + * This library is released under MIT license + */ + +#include + +std::string format_symbol(std::string input); + +/************************ MSVC ************************/ +#if defined(_WIN32) && defined(_MSC_VER) + +#include +#include +#include + +#pragma comment(lib, "dbghelp.lib") + +std::string demangle_symbol(const char *symbol) { + DWORD sign_flags = UNDNAME_COMPLETE | UNDNAME_NO_FUNCTION_RETURNS | UNDNAME_NO_MS_KEYWORDS; + DWORD name_flags = UNDNAME_NAME_ONLY; + char undecorated[MAX_SYM_NAME]; + + // Get undecorated symbol signature + if (UnDecorateSymbolName(symbol, undecorated, MAX_SYM_NAME, sign_flags)) { + std::string signature = undecorated; + + // Get undecorated symbol name + if (UnDecorateSymbolName(symbol, undecorated, MAX_SYM_NAME, name_flags)) { + /* + * If symbol signature starts with symbol name, it means + * that this is a function, otherwise, this is a variable: + * + * signature: tools::adder(double, double) + * name: tools::adder + * + * signature: long ptr + * name: ptr + */ + if (signature.find(undecorated) == 0) + return format_symbol(signature); + else // This is a variable, no need to format it. + return undecorated; + } + } + + return ""; +} + +#else /************************ gcc, clang, MinGW ************************/ + +#include +#include + +std::string demangle_symbol(const char *symbol) { + std::string result; + char *demangled; + + demangled = abi::__cxa_demangle(symbol, nullptr, nullptr, nullptr); + if (!demangled) + return ""; + + result = format_symbol(demangled); + + free(demangled); + + return result; +} + +#endif diff --git a/src/libs/dylib/dylib.cpp b/src/libs/dylib/dylib.cpp new file mode 100644 index 0000000..df3932a --- /dev/null +++ b/src/libs/dylib/dylib.cpp @@ -0,0 +1,246 @@ +/** + * @file dylib.cpp + * + * @author Martin Olivier + * @copyright (c) 2025 Martin Olivier + * + * This library is released under MIT license + */ + +#ifndef _WIN32 +#include +#include +#endif + +#include +#include + +#include "dylib.hpp" + +using dylib::library; +using dylib::native_handle_type; +using dylib::native_symbol_type; +using dylib::symbol_info; + +/* + * internal_symbol_type and internal_symbol_info are needed + * because the namespace 'dylib' conflicts with the 'dylib' + * struct from witch is needed on macOS. + */ + +enum internal_symbol_type : std::uint8_t { + C, + CPP, +}; + +struct internal_symbol_info { + std::string name; + std::string demangled_name; + internal_symbol_type type; + bool loadable; +}; + +std::vector get_symbols(native_handle_type handle, int fd); +std::string demangle_symbol(const char *symbol); + +static native_handle_type open_lib(const char *path) noexcept { +#ifdef _WIN32 + return LoadLibraryA(path); +#else + return dlopen(path, RTLD_NOW | RTLD_LOCAL); +#endif +} + +static native_symbol_type locate_symbol(native_handle_type lib, const char *name) noexcept { +#ifdef _WIN32 + return GetProcAddress(lib, name); +#else + return dlsym(lib, name); +#endif +} + +static void close_lib(native_handle_type lib) noexcept { +#ifdef _WIN32 + FreeLibrary(lib); +#else + dlclose(lib); +#endif +} + +static std::string get_error_description() noexcept { +#ifdef _WIN32 + WORD lang = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); + char description[512]; + DWORD error_code; + DWORD length; + + error_code = GetLastError(); + if (!error_code) + return "Unknown error (GetLastError failed)"; + + length = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, error_code, lang, description, 512, + nullptr); + + return (length == 0) ? "Unknown error (FormatMessage failed)" : description; +#else + char *description = dlerror(); + + return (description == nullptr) ? "Unknown error (dlerror failed)" : description; +#endif +} + +library::library(library &&other) noexcept { + std::swap(m_handle, other.m_handle); +#ifdef __APPLE__ + std::swap(m_fd, other.m_fd); +#endif +} + +library &library::operator=(library &&other) noexcept { + if (this != &other) { + std::swap(m_handle, other.m_handle); +#ifdef __APPLE__ + std::swap(m_fd, other.m_fd); +#endif + } + return *this; +} + +library::library(const char *lib_path, dylib::decorations decorations) { + std::string lib_name; + std::string lib_dir; + std::string lib; + + if (!lib_path) + throw std::invalid_argument("The library path to lookup is null"); + + lib = lib_path; + +#ifdef _WIN32 + while (lib.find('\\') != std::string::npos) + lib.replace(lib.find('\\'), 1, "/"); +#endif + + if (lib.empty()) + throw std::invalid_argument("The library path to lookup is an empty string"); + if (lib.find('/') == std::string::npos) + throw std::invalid_argument("Could not load library '" + lib + "': invalid path"); + + lib_name = lib.substr(lib.find_last_of('/') + 1); + lib_dir = lib.substr(0, lib.find_last_of('/')); + + if (lib_name.empty()) + throw std::invalid_argument("Could not load library '" + lib + + "': a directory was provided"); + + lib = lib_dir + '/' + decorations.prefix + lib_name + decorations.suffix; + + m_handle = open_lib(lib.c_str()); + if (!m_handle) + throw load_error("Could not load library '" + lib + "':\n" + get_error_description()); + +#ifdef __APPLE__ + m_fd = open(lib.c_str(), O_RDONLY); + if (m_fd < 0) + throw load_error("Could not open file '" + lib + "':\n" + strerror(errno)); +#endif +} + +library::library(const std::string &lib_path, decorations decorations) + : library(lib_path.c_str(), decorations) {} + +#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) +library::library(const std::filesystem::path &lib_path, decorations decorations) + : library(lib_path.string(), decorations) {} +#endif + +library::~library() { + if (m_handle) + close_lib(m_handle); +#ifdef __APPLE__ + if (m_fd > -1) + close(m_fd); +#endif +} + +native_symbol_type library::get_symbol(const char *symbol_name) const { + std::vector matching_symbols; + std::string initial_error; + native_symbol_type symbol; + size_t symbol_name_len; + + if (!symbol_name) + throw std::invalid_argument("The symbol name to lookup is null"); + if (symbol_name[0] == '\0') + throw std::invalid_argument("The symbol name to lookup is an empty string"); + if (!m_handle) + throw std::logic_error("Attempted to use a moved library object"); + + symbol_name_len = strlen(symbol_name); + + symbol = locate_symbol(m_handle, symbol_name); + if (symbol) + return symbol; + + initial_error = get_error_description(); + + for (const auto &sym : symbols()) { + if (!sym.loadable) + continue; + + std::string demangled = demangle_symbol(sym.name.c_str()); + + if (demangled.find(symbol_name) == 0 && + (demangled.size() == symbol_name_len || demangled[symbol_name_len] == '(')) + matching_symbols.push_back(sym.name); + } + + switch (matching_symbols.size()) { + case 0: + throw symbol_not_found(symbol_name, initial_error); + case 1: + return locate_symbol(m_handle, matching_symbols.front().c_str()); + default: + std::string matching_symbols_display; + + for (auto &sym : matching_symbols) + matching_symbols_display += "- " + sym + '\n'; + + throw symbol_multiple_matches(symbol_name, matching_symbols_display); + } +} + +native_symbol_type library::get_symbol(const std::string &symbol_name) const { + return get_symbol(symbol_name.c_str()); +} + +native_handle_type library::native_handle() noexcept { + return m_handle; +} + +std::vector library::symbols() const { + std::vector internal_symbols; + std::vector symbols; + + if (!m_handle) + throw std::logic_error("Attempted to use a moved library object"); + + try { + internal_symbols = get_symbols(m_handle, DYLIB_WIN_MAC_OTHER(-1, m_fd, -1)); + + symbols.reserve(internal_symbols.size()); + + for (const auto &symbol : internal_symbols) { + symbols.push_back(symbol_info{ + symbol.name, + symbol.demangled_name, + static_cast(symbol.type), + symbol.loadable, + }); + } + + return symbols; + } catch (const std::runtime_error &e) { + throw symbol_collection_error(e.what()); + } +} diff --git a/src/libs/dylib/format.cpp b/src/libs/dylib/format.cpp new file mode 100644 index 0000000..0029d53 --- /dev/null +++ b/src/libs/dylib/format.cpp @@ -0,0 +1,85 @@ +/** + * @file format.cpp + * + * @author Martin Olivier + * @copyright (c) 2025 Martin Olivier + * + * This library is released under MIT license + */ + +#include + +static void replace_occurrences(std::string &symbol, const std::string &find, + const std::string &replace) { + size_t pos = 0; + + while ((pos = symbol.find(find, pos)) != std::string::npos) + symbol.replace(pos, find.length(), replace); +} + +/************************ MSVC ************************/ +#if defined(_WIN32) && defined(_MSC_VER) + +static void add_space_after_comma(std::string &symbol) { + std::string result; + + for (char c : symbol) { + if (c == ',') + result += ", "; + else + result += c; + } + + symbol = result; +} + +std::string format_symbol(std::string symbol) { + replace_occurrences(symbol, "(class ", "("); + replace_occurrences(symbol, " >", ">>"); + replace_occurrences(symbol, ">const", "> const"); + + add_space_after_comma(symbol); + + return symbol; +} + +#else /************************ gcc, clang, MinGW ************************/ + +static void add_sym_separator(std::string &symbol, char c) { + size_t pos = 0; + + while ((pos = symbol.find(c, pos)) != std::string::npos) { + if (pos && symbol[pos - 1] != ' ' && symbol[pos - 1] != '&' && symbol[pos - 1] != '*' && + symbol[pos - 1] != '(') { + symbol.replace(pos, 1, std::string(" ") + c); + pos += 2; + } else { + pos += 1; + } + } +} + +std::string format_symbol(std::string symbol) { + replace_occurrences(symbol, "std::__1::", "std::"); + replace_occurrences(symbol, "std::__cxx11::", "std::"); + + replace_occurrences(symbol, "[abi:cxx11]", ""); + replace_occurrences(symbol, "[abi:ue170006]", ""); + + replace_occurrences(symbol, "()", "(void)"); + replace_occurrences(symbol, "> >", ">>"); + + add_sym_separator(symbol, '*'); + add_sym_separator(symbol, '&'); + + return symbol; +} + +#endif diff --git a/src/libs/dylib/symbols.cpp b/src/libs/dylib/symbols.cpp new file mode 100644 index 0000000..3e31bd2 --- /dev/null +++ b/src/libs/dylib/symbols.cpp @@ -0,0 +1,274 @@ +/** + * @file symbols.cpp + * + * @author Martin Olivier + * @copyright (c) 2025 Martin Olivier + * + * This library is released under MIT license + */ + +#include +#include +#include +#include +#include +#include + +std::string demangle_symbol(const char *symbol); + +enum internal_symbol_type : std::uint8_t { + C, + CPP, +}; + +struct internal_symbol_info { + std::string name; + std::string demangled_name; + internal_symbol_type type; + bool loadable; +}; + +static void add_symbol(std::vector &result, const char *symbol, + bool loadable) { + internal_symbol_type type = internal_symbol_type::C; + std::string demangled; + + if (!symbol || strcmp(symbol, "") == 0) + return; + + demangled = demangle_symbol(symbol); + if (demangled.empty()) + demangled = symbol; + else + type = internal_symbol_type::CPP; + + /* + * In case of duplicate symbols, for example when loading a FAT binary, + * avoid duplicates and override loadable if the previous symbol was not loadable. + */ + for (auto &sym : result) { + if (sym.name == symbol) { + if (!sym.loadable) + sym.loadable = loadable; + return; + } + } + + result.push_back({symbol, demangled, type, loadable}); +} + +/************************ Windows ************************/ +#ifdef _WIN32 + +#include +#include + +std::vector get_symbols(HMODULE handle, int fd) { + std::vector symbols_list; + PIMAGE_EXPORT_DIRECTORY pExportDir; + PIMAGE_DOS_HEADER pDosHeader; + PIMAGE_NT_HEADERS pNTHeaders; + DWORD exportDirRVA; + DWORD *pNames; + + // Get the DOS header + pDosHeader = (PIMAGE_DOS_HEADER)handle; + if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) + throw std::runtime_error("Invalid DOS header"); + + // Get the NT headers + pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE *)handle + pDosHeader->e_lfanew); + if (pNTHeaders->Signature != IMAGE_NT_SIGNATURE) + throw std::runtime_error("Invalid NT headers"); + + // Get the export directory + exportDirRVA = + pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + if (exportDirRVA == 0) + throw std::runtime_error("No export directory found"); + + pExportDir = (PIMAGE_EXPORT_DIRECTORY)((BYTE *)handle + exportDirRVA); + + // Get the list of exported function names + pNames = (DWORD *)((BYTE *)handle + pExportDir->AddressOfNames); + + for (DWORD i = 0; i < pExportDir->NumberOfNames; ++i) { + const char *name = (const char *)((BYTE *)handle + pNames[i]); + + add_symbol(symbols_list, name, !!GetProcAddress(handle, name)); + } + + return symbols_list; +} + +/************************ Mac OS ************************/ +#elif defined(__APPLE__) + +#include +#include +#include +#include +#include +#include + +#if INTPTR_MAX == INT32_MAX +using mach_header_arch = mach_header; +using nlist_arch = nlist; +#define DYLIB_MH_MAGIC MH_MAGIC +#define DYLIB_MH_CIGAM MH_CIGAM +#elif INTPTR_MAX == INT64_MAX +using mach_header_arch = mach_header_64; +using nlist_arch = nlist_64; +#define DYLIB_MH_MAGIC MH_MAGIC_64 +#define DYLIB_MH_CIGAM MH_CIGAM_64 +#else +#error "Environment not 32 or 64-bit." +#endif + +static void get_symbols_at_off(std::vector &symbols_list, void *handle, + int fd, off_t offset) { + mach_header_arch mh; + uint32_t ncmds; + + lseek(fd, offset, SEEK_SET); + + read(fd, &mh, sizeof(mh)); + + ncmds = mh.ncmds; + + lseek(fd, offset + sizeof(mach_header_arch), SEEK_SET); + + for (uint32_t i = 0; i < ncmds; i++) { + struct load_command lc; + off_t cmd_offset; + + read(fd, &lc, sizeof(lc)); + + cmd_offset = lseek(fd, 0, SEEK_CUR); + + if (lc.cmd == LC_SYMTAB) { + std::vector symbols; + std::vector strtab; + struct symtab_command symtab; + + lseek(fd, cmd_offset - sizeof(lc), SEEK_SET); + read(fd, &symtab, sizeof(symtab)); + + symbols.resize(symtab.nsyms); + + lseek(fd, offset + symtab.symoff, SEEK_SET); + read(fd, symbols.data(), symtab.nsyms * sizeof(nlist_arch)); + + strtab.resize(symtab.strsize); + + lseek(fd, offset + symtab.stroff, SEEK_SET); + read(fd, strtab.data(), symtab.strsize); + + for (uint32_t j = 0; j < symtab.nsyms; j++) { + uint32_t strx; + char *name; + + strx = symbols[j].n_un.n_strx; + name = &strtab[strx]; + + if (name[0] == '_') + name++; + + add_symbol(symbols_list, name, !!dlsym(handle, name)); + } + } + + lseek(fd, cmd_offset + lc.cmdsize - sizeof(lc), SEEK_SET); + } +} + +std::vector get_symbols(void *handle, int fd) { + std::vector symbols_list; + uint32_t magic; + + lseek(fd, 0, SEEK_SET); + read(fd, &magic, sizeof(magic)); + lseek(fd, 0, SEEK_SET); + + if (magic == FAT_MAGIC || magic == FAT_CIGAM) { + std::vector fat_arches; + struct fat_header fat_header; + + read(fd, &fat_header, sizeof(fat_header)); + + fat_arches.resize(ntohl(fat_header.nfat_arch)); + + read(fd, fat_arches.data(), sizeof(struct fat_arch) * ntohl(fat_header.nfat_arch)); + + for (uint32_t i = 0; i < ntohl(fat_header.nfat_arch); i++) { + off_t off = ntohl(fat_arches[i].offset); + + get_symbols_at_off(symbols_list, handle, fd, off); + } + } else if (magic == DYLIB_MH_MAGIC || magic == DYLIB_MH_CIGAM) { + get_symbols_at_off(symbols_list, handle, fd, 0); + } else { + throw std::runtime_error("Unsupported file format"); + } + + return symbols_list; +} + +#else /************************ Linux ************************/ + +#include +#include +#include + +#if INTPTR_MAX == INT32_MAX +using ElfSym = Elf32_Sym; +#define DYLIB_ELF_ST_TYPE ELF32_ST_TYPE +#elif INTPTR_MAX == INT64_MAX +using ElfSym = Elf64_Sym; +#define DYLIB_ELF_ST_TYPE ELF64_ST_TYPE +#else +#error "Environment not 32 or 64-bit." +#endif + +std::vector get_symbols(void *handle, int fd) { + std::vector symbols_list; + struct link_map *map = nullptr; + unsigned long symentries = 0; + ElfSym *symtab = nullptr; + char *strtab = nullptr; + unsigned long size = 0; + + if (dlinfo(handle, RTLD_DI_LINKMAP, static_cast(&map)) != 0) { + const char *error = dlerror(); + throw std::runtime_error("dlinfo failed: " + + std::string(error ? error : "Unknown error (dlerror failed)")); + } + + for (auto *section = map->l_ld; section->d_tag != DT_NULL; ++section) { + if (section->d_tag == DT_SYMTAB) + symtab = (ElfSym *)section->d_un.d_ptr; + else if (section->d_tag == DT_STRTAB) + strtab = (char *)section->d_un.d_ptr; + else if (section->d_tag == DT_SYMENT) + symentries = section->d_un.d_val; + } + + if (!symtab || !strtab || symentries == 0) + return symbols_list; + + size = strtab - (char *)symtab; + + for (int i = 0; i < size / symentries; ++i) { + ElfSym *sym = &symtab[i]; + + if (DYLIB_ELF_ST_TYPE(symtab[i].st_info) == STT_FUNC) { + const char *name = &strtab[sym->st_name]; + + add_symbol(symbols_list, name, !!dlsym(handle, name)); + } + } + + return symbols_list; +} + +#endif diff --git a/src/main.cpp b/src/main.cpp index 868d227..9c3ce29 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,6 +31,7 @@ #include "getopt_port/getopt.h" #include "nvdialog/nvdialog_error.h" #include "oshot_png.h" +#include "plugins/oshot_plugin.h" #include "screen_capture.hpp" #include "screenshot_tool.hpp" #include "spdlog/sinks/basic_file_sink.h" @@ -64,13 +65,14 @@ struct GLFWwindow; // clang-format on // Extern variables declariaions -std::deque g_dropped_paths; -std::unique_ptr g_config; -std::unique_ptr g_cache; -ScreenshotTool g_ss_tool; -bool g_is_systray = false; -int g_scr_w{}, g_scr_h{}; -Clipboard g_clipboard(SessionType::Unknown); +std::deque g_dropped_paths; +std::unique_ptr g_config; +std::unique_ptr g_cache; +std::vector g_plugin_entries; +ScreenshotTool g_ss_tool; +bool g_is_systray = false; +int g_scr_w{}, g_scr_h{}; +Clipboard g_clipboard(SessionType::Unknown); std::error_code ec; @@ -199,6 +201,10 @@ static bool do_copy_image = false; void exit_handler(int) { + static std::atomic_flag ran = ATOMIC_FLAG_INIT; + if (ran.test_and_set()) + return; + quit.store(true); cv.notify_all(); #ifndef _WIN32 @@ -208,6 +214,10 @@ void exit_handler(int) extern_glfwTerminate(); trayMaker.Exit(); fs::remove(fs::temp_directory_path(ec) / fmt::format("oshot_{}.log", getpid())); + + for (plugin_entry_t& entry : g_plugin_entries) + if (entry.plugin->destroy) + entry.plugin->destroy(entry.state); } void exit_handler_nc() { diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h index 037c630..fb06894 100644 --- a/src/plugins/oshot_plugin.h +++ b/src/plugins/oshot_plugin.h @@ -67,8 +67,8 @@ typedef struct * ---------------------------------------------------------------- */ typedef struct { - const char* name; uint32_t abi_version; + const char* name; uint32_t capabilities; /* OR of oshot_capabilities_t, informational only */ void* (*init)(void); @@ -96,6 +96,11 @@ void oshot_display_msg(OSLogLevel lvl, oshot_str_t str); void oshot_log(OSLogLevel lvl, oshot_str_t str); void oshot_debug(oshot_str_t str); // oshot_log(DEBUG, str); +// convinience ig +void oshot_display_msg_s(OSLogLevel lvl, const char* str); +void oshot_log_s(OSLogLevel lvl, const char* str); +void oshot_debug_s(const char* str); // oshot_log(DEBUG, str); + /* ------------------------------------------------------------------ * Config (plugin namespace only) * ------------------------------------------------------------------ */ diff --git a/src/plugins/plugins.cpp b/src/plugins/plugins.cpp index 15b087e..0d82b16 100644 --- a/src/plugins/plugins.cpp +++ b/src/plugins/plugins.cpp @@ -10,8 +10,8 @@ struct oshot_host_api_t { - uint32_t abi_version = OSHOT_API_VERSION; - oshot_plugin_t plugin = {}; + uint32_t abi_version = OSHOT_API_VERSION; + oshot_plugin_t plugin = { "test" }; } g_api; /* ------------------------------------------------------------------ @@ -78,6 +78,27 @@ void oshot_debug(oshot_str_t str) oshot_log(OSLogLevel::OSHOT_LOG_DEBUG, std::move(str)); } +void oshot_display_msg_s(OSLogLevel lvl, const char* str) +{ + oshot_str_t s = oshot_str_new(str, strlen(str)); + oshot_display_msg(lvl, s); + oshot_str_free(&s); +} + +void oshot_log_s(OSLogLevel lvl, const char* str) +{ + oshot_str_t s = oshot_str_new(str, strlen(str)); + oshot_log(lvl, s); + oshot_str_free(&s); +} + +void oshot_debug_s(const char* str) +{ + oshot_str_t s = oshot_str_new(str, strlen(str)); + oshot_debug(s); + oshot_str_free(&s); +} + /* ------------------------------------------------------------------ * Config * ------------------------------------------------------------------ */ @@ -147,8 +168,7 @@ size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max) val.d = el.as_floating_point()->get(); break; - default: - continue; // unsupported TOML type: skip, don't consume a slot + default: continue; // unsupported TOML type: skip, don't consume a slot } i++; } diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index d8af369..7a5039b 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -256,6 +256,63 @@ static std::unordered_map& color_name_map() return map; } +static void load_plugins() +{ + const fs::path pluginDir = get_config_dir() / "plugins"; + fs::create_directories(pluginDir); + + for (const auto& plugin_dir : fs::directory_iterator(pluginDir, fs::directory_options::skip_permission_denied)) + { + if (!plugin_dir.is_directory()) + continue; + + const std::string expected = "lib" + plugin_dir.path().filename().string() + dylib::decorations::os_default().suffix; + + for (const auto& entry : + fs::directory_iterator(plugin_dir.path(), fs::directory_options::skip_permission_denied)) + { + if (entry.path().filename() != expected) + continue; + + try + { + dylib::library lib(entry.path().string()); + auto oshot_get_plugin = lib.get_function("oshot_host_get_plugin"); + oshot_plugin_t* plugin = oshot_get_plugin(); + + if (!plugin || plugin->abi_version != OSHOT_API_VERSION) + { + error("Plugin '{}' has incompatible ABI version, skipping", entry.path().stem().string()); + continue; + } + + if (!plugin->init) + continue; + + void* state = plugin->init(); + if (!state) + { + error("Failed to init plugin '{}'", entry.path().stem().string()); + continue; + } + + g_plugin_entries.emplace_back( + plugin_entry_t{ .lib = std::move(lib), .plugin = plugin, .state = state }); + + spdlog::info("loading plugin at {}!", entry.path().string()); + } + catch (const dylib::load_error& e) + { + error("Failed to load '{}' library: {}", entry.path().stem().string(), e.what()); + } + catch (const dylib::symbol_error& e) + { + error("Failed to get 'oshot_get_plugin()' symbol: {}", e.what()); + } + } + } +} + void apply_imgui_theme() { const std::string& base = g_config->File.theme_style; @@ -338,6 +395,9 @@ Result<> ScreenshotTool::Start() Result<> ScreenshotTool::StartWindow() { + static std::once_flag plugins_loaded; + std::call_once(plugins_loaded, [] { load_plugins(); }); + m_inputs = { g_config->File.ocr_path, g_config->File.ocr_model, g_config->File.ocr_get_repo, @@ -465,6 +525,25 @@ void ScreenshotTool::RenderOverlay() DrawDownloadOCRWindow(); DrawOcrTools(); DrawBarDecodeTools(); + for (plugin_entry_t& entry : g_plugin_entries) + { + oshot_plugin_t* plugin = entry.plugin; + if (!plugin->render || !plugin->name || plugin->name[0] == '\0') + continue; + + if (ImGui::CollapsingHeader(plugin->name)) + { + ImGui::PushID(plugin->name); + + ImVec2 child_size(0.0f, 0.0f); // auto-height, or let plugins set a preferred height + ImGui::BeginChild(plugin->name, child_size, ImGuiChildFlags_Borders); + + plugin->render(entry.state); + + ImGui::EndChild(); + ImGui::PopID(); + } + } ImGui::End(); } @@ -1360,6 +1439,9 @@ void ScreenshotTool::DrawOcrTools() { ClearError(ectx, OcrError::FailedToScan); m_inputs.ocr_results = std::move(result.get()); + for (plugin_entry_t& entry : g_plugin_entries) + if (entry.plugin->on_ocr_done) + entry.plugin->on_ocr_done(entry.state); } else { From 3eff4195c8adf04982cd99aa44ec800ace4e4330 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Thu, 2 Jul 2026 18:27:46 +0200 Subject: [PATCH 15/40] plugins: replace global g_api singleton with per-plugin runtime map g_api was a single global struct, so with more than one plugin loaded, config reads/writes and log lines could get misattributed to whichever plugin last touched it. Replace it with plugin_runtime_t, one instance per loaded plugin, keyed by a unique id in g_plugins. ScopedActivePlugin (RAII) sets g_current_plugin around every call into plugin code (init, render, on_ocr_done, destroy), so host-side oshot_* calls always resolve against the correct plugin, including reentrant calls. Also: - oshot_get_abi_version() now returns the host's constant instead of echoing back the active plugin's own version - config lookups now key off plugin id (unique) instead of display name (not guaranteed unique), fixing a settings collision between same-named plugins; ImGui PushID switched to id for the same reason - plugin id/name are validated at load time; duplicate ids are rejected instead of silently overwriting the existing entry - init() now runs after the runtime entry exists and is scoped active, so config reads during init() see correct values - on_ocr_done now receives a real result struct (text, confidence, psm) instead of requiring a re-fetch through the text-buffer side channel; allocated once per call and freed once, not leaked per plugin - plugin_entry_t / g_plugin_entries removed; shutdown destroy() now happens via plugin_runtime_t's destructor --- include/plugin.hpp | 57 +++++++++++++++++++++++++++ include/screenshot_tool.hpp | 14 +------ src/main.cpp | 24 ++++++------ src/plugins/oshot_plugin.h | 21 +++++++--- src/plugins/plugins.cpp | 32 +++++++-------- src/screenshot_tool.cpp | 78 +++++++++++++++++++++++++++++-------- 6 files changed, 161 insertions(+), 65 deletions(-) create mode 100644 include/plugin.hpp diff --git a/include/plugin.hpp b/include/plugin.hpp new file mode 100644 index 0000000..b20a683 --- /dev/null +++ b/include/plugin.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include + +#include "../src/plugins/oshot_plugin.h" +#include "dylib.hpp" + +struct plugin_runtime_t; + +extern std::unordered_map g_plugins; +extern plugin_runtime_t* g_current_plugin; // plain global, see above + +struct ScopedActivePlugin +{ + plugin_runtime_t* prev; + explicit ScopedActivePlugin(plugin_runtime_t* rt) : prev(g_current_plugin) { g_current_plugin = rt; } + ~ScopedActivePlugin() { g_current_plugin = prev; } +}; + +struct plugin_runtime_t +{ + std::string id; // must be validated + std::string config_prefix; // cached "plugins.." + std::filesystem::path data_dir; + + oshot_plugin_t* plugin = nullptr; // non-owning and static, process-lifetime per ABI contract + void* state = nullptr; // owned by the plugin; released via plugin->destroy() + dylib::library lib; + + plugin_runtime_t(std::string id, + std::string config_prefix, + std::filesystem::path data_dir, + oshot_plugin_t* plugin, + void* state, + dylib::library lib) + : id(std::move(id)), + config_prefix(std::move(config_prefix)), + data_dir(std::move(data_dir)), + plugin(plugin), + state(state), + lib(std::move(lib)) + {} + + ~plugin_runtime_t() + { + if (plugin && plugin->destroy && state) + { + ScopedActivePlugin _(this); // destroy() may still call oshot_log/config_get_* + plugin->destroy(state); + } + } + + plugin_runtime_t(const plugin_runtime_t&) = delete; + plugin_runtime_t& operator=(const plugin_runtime_t&) = delete; + plugin_runtime_t(plugin_runtime_t&&) = default; + plugin_runtime_t& operator=(plugin_runtime_t&&) = default; +}; diff --git a/include/screenshot_tool.hpp b/include/screenshot_tool.hpp index 71d1b72..f302aaa 100644 --- a/include/screenshot_tool.hpp +++ b/include/screenshot_tool.hpp @@ -13,8 +13,6 @@ #include #include -#include "../src/plugins/oshot_plugin.h" -#include "dylib.hpp" #include "imgui/imgui.h" #include "imgui/imgui_internal.h" #include "screen_capture.hpp" @@ -110,13 +108,6 @@ enum class GeneralError : size_t COUNT, }; -struct plugin_entry_t -{ - dylib::library lib; - oshot_plugin_t* plugin; - void* state; -}; - struct point_t { float x{}; @@ -358,8 +349,7 @@ class ScreenshotTool } }; -extern ScreenshotTool g_ss_tool; -extern std::deque g_dropped_paths; -extern std::vector g_plugin_entries; +extern ScreenshotTool g_ss_tool; +extern std::deque g_dropped_paths; #endif // !_SCREENSHOT_TOOL_HPP_ diff --git a/src/main.cpp b/src/main.cpp index 9c3ce29..6e08ace 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,7 +31,7 @@ #include "getopt_port/getopt.h" #include "nvdialog/nvdialog_error.h" #include "oshot_png.h" -#include "plugins/oshot_plugin.h" +#include "plugin.hpp" #include "screen_capture.hpp" #include "screenshot_tool.hpp" #include "spdlog/sinks/basic_file_sink.h" @@ -65,14 +65,16 @@ struct GLFWwindow; // clang-format on // Extern variables declariaions -std::deque g_dropped_paths; -std::unique_ptr g_config; -std::unique_ptr g_cache; -std::vector g_plugin_entries; -ScreenshotTool g_ss_tool; -bool g_is_systray = false; -int g_scr_w{}, g_scr_h{}; -Clipboard g_clipboard(SessionType::Unknown); +std::deque g_dropped_paths; +std::unique_ptr g_config; +std::unique_ptr g_cache; +ScreenshotTool g_ss_tool; +bool g_is_systray = false; +int g_scr_w{}, g_scr_h{}; +Clipboard g_clipboard(SessionType::Unknown); + +std::unordered_map g_plugins; +plugin_runtime_t* g_current_plugin; std::error_code ec; @@ -214,10 +216,6 @@ void exit_handler(int) extern_glfwTerminate(); trayMaker.Exit(); fs::remove(fs::temp_directory_path(ec) / fmt::format("oshot_{}.log", getpid())); - - for (plugin_entry_t& entry : g_plugin_entries) - if (entry.plugin->destroy) - entry.plugin->destroy(entry.state); } void exit_handler_nc() { diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h index fb06894..778ebe1 100644 --- a/src/plugins/oshot_plugin.h +++ b/src/plugins/oshot_plugin.h @@ -16,8 +16,8 @@ extern "C" { typedef enum { OSHOT_CAP_NONE = 0, - OSHOT_CAP_NETWORK = 1u << 0, - OSHOT_CAP_FS = 1u << 1, + OSHOT_CAP_NETWORK = 1 << 0, + OSHOT_CAP_FS = 1 << 1, } OSCapabilities; typedef enum @@ -61,20 +61,29 @@ typedef struct }; } oshot_value_t; +typedef struct +{ + oshot_str_t text; + int32_t confidence; // 0-100, or -1 if unavailable + int32_t psm; // tesseract::PageSegMode value +} oshot_ocr_result_t; + /* ------------------------------------------------------------------ * Plugin descriptor. * One per plugin, returned by the single exported symbol below * ---------------------------------------------------------------- */ typedef struct { - uint32_t abi_version; - const char* name; - uint32_t capabilities; /* OR of oshot_capabilities_t, informational only */ + uint32_t abi_version; + + const char* name; // display name, doesn't need to be unique + const char* id; // reverse-domain, e.g. "com.example.myplugin" + uint32_t capabilities; // OR of oshot_capabilities_t, informational only void* (*init)(void); void (*destroy)(void* state); void (*render)(void* state); - void (*on_ocr_done)(void* state); + void (*on_ocr_done)(void* state, const oshot_ocr_result_t* result); } oshot_plugin_t; /* ------------------------------------------------------------------ diff --git a/src/plugins/plugins.cpp b/src/plugins/plugins.cpp index 0d82b16..9708897 100644 --- a/src/plugins/plugins.cpp +++ b/src/plugins/plugins.cpp @@ -5,21 +5,16 @@ #include "fmt/chrono.h" #include "fmt/format.h" #include "oshot_plugin.h" +#include "plugin.hpp" #include "screenshot_tool.hpp" #include "util.hpp" -struct oshot_host_api_t -{ - uint32_t abi_version = OSHOT_API_VERSION; - oshot_plugin_t plugin = { "test" }; -} g_api; - /* ------------------------------------------------------------------ * ABI / identity * ------------------------------------------------------------------ */ uint32_t oshot_get_abi_version() { - return g_api.abi_version; + return OSHOT_API_VERSION; } /* ------------------------------------------------------------------ @@ -45,9 +40,9 @@ void oshot_str_free(oshot_str_t* str) /* ------------------------------------------------------------------ * Logging / host messaging * ------------------------------------------------------------------ */ -void oshot_display_msg(const OSLogLevel lvl, const oshot_str_t str) +void oshot_display_msg(const OSLogLevel lvl, oshot_str_t str) { - const std::string& out = fmt::format("{}: {}", g_api.plugin.name, std::string_view(str.p, str.len)); + const std::string& out = fmt::format("{}: {}", g_current_plugin->plugin->id, std::string_view(str.p, str.len)); switch (lvl) { case OSLogLevel::OSHOT_LOG_DEBUG: @@ -63,7 +58,8 @@ void oshot_log(OSLogLevel lvl, oshot_str_t str) { auto now = std::chrono::system_clock::now(); - const std::string& out = fmt::format("[{}] {}: {}", now, g_api.plugin.name, std::string_view(str.p, str.len)); + const std::string& out = + fmt::format("[{}] {}: {}", now, g_current_plugin->plugin->id, std::string_view(str.p, str.len)); switch (lvl) { case OSLogLevel::OSHOT_LOG_DEBUG: spdlog::debug("{}", out); break; @@ -104,43 +100,43 @@ void oshot_debug_s(const char* str) * ------------------------------------------------------------------ */ oshot_str_t oshot_config_get_string(const char* key, oshot_str_t fallback) { - const std::string& str = g_config->GetValue(fmt::format("plugins.{}.{}", g_api.plugin.name, key), - std::string(fallback.p, fallback.len)); + const std::string& str = + g_config->GetValue(g_current_plugin->config_prefix + key, std::string(fallback.p, fallback.len)); return oshot_str_new(str.c_str(), str.length()); } bool oshot_config_get_bool(const char* key, bool fallback) { - bool val = g_config->GetValue(fmt::format("plugins.{}.{}", g_api.plugin.name, key), fallback); + bool val = g_config->GetValue(g_current_plugin->config_prefix + key, fallback); return val; } int64_t oshot_config_get_int64(const char* key, int64_t fallback) { - int64_t val = g_config->GetValue(fmt::format("plugins.{}.{}", g_api.plugin.name, key), fallback); + int64_t val = g_config->GetValue(g_current_plugin->config_prefix + key, fallback); return val; } float oshot_config_get_float(const char* key, float fallback) { - float val = g_config->GetValue(fmt::format("plugins.{}.{}", g_api.plugin.name, key), fallback); + float val = g_config->GetValue(g_current_plugin->config_prefix + key, fallback); return val; } double oshot_config_get_double(const char* key, double fallback) { - double val = g_config->GetValue(fmt::format("plugins.{}.{}", g_api.plugin.name, key), fallback); + double val = g_config->GetValue(g_current_plugin->config_prefix + key, fallback); return val; } size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max) { - const toml::array* arr = g_config->GetValueArray(fmt::format("plugins.{}.{}", g_api.plugin.name, key)); + const toml::array* arr = g_config->GetValueArray(g_current_plugin->config_prefix + key); if (!arr) return 0; size_t i = 0; - for (auto&& el : *arr) + for (const toml::node& el : *arr) { if (i == max) break; diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 7a5039b..7f24478 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -28,6 +28,7 @@ #include "imgui/imgui_impl_opengl3_loader.h" #include "imgui/imgui_internal.h" #include "imgui/imgui_stdlib.h" +#include "plugin.hpp" #include "plugins/oshot_plugin.h" #include "screen_capture.hpp" #include "tiny-process-library/process.hpp" @@ -266,7 +267,8 @@ static void load_plugins() if (!plugin_dir.is_directory()) continue; - const std::string expected = "lib" + plugin_dir.path().filename().string() + dylib::decorations::os_default().suffix; + const std::string expected = + "lib" + plugin_dir.path().filename().string() + dylib::decorations::os_default().suffix; for (const auto& entry : fs::directory_iterator(plugin_dir.path(), fs::directory_options::skip_permission_denied)) @@ -280,24 +282,53 @@ static void load_plugins() auto oshot_get_plugin = lib.get_function("oshot_host_get_plugin"); oshot_plugin_t* plugin = oshot_get_plugin(); - if (!plugin || plugin->abi_version != OSHOT_API_VERSION) + if (!plugin || plugin->abi_version != oshot_get_abi_version()) { error("Plugin '{}' has incompatible ABI version, skipping", entry.path().stem().string()); continue; } - if (!plugin->init) + if (!plugin->render || !plugin->id || !plugin->name || plugin->name[0] == '\0') + { + error("Plugin '{}' doesn't define name/ID or render function", entry.path().stem().string()); + continue; + } + + if (plugin->id[0] == '.' || + !std::ranges::all_of(std::string_view(plugin->id), [](const unsigned char c) { + return (isalnum(c) || c == '-' || c == '_' || c == '=' || c == '.'); + })) + { + error("Plugin '{}' has an invalid ID", plugin->id); + continue; + } + + if (!std::ranges::all_of(std::string_view(plugin->name), [](const unsigned char c) { + return (isalnum(c) || c == '-' || c == '_' || c == '=' || c == ' '); + })) + { + error("Plugin '{}' contains chars other than -_= or alpha numerical", plugin->id); continue; + } - void* state = plugin->init(); - if (!state) + auto [it, inserted] = g_plugins.try_emplace(plugin->id, + plugin->id, + fmt::format("plugins.{}.", plugin->id), + get_config_dir() / "plugins" / plugin->id, + plugin, + nullptr, // state filled in below + std::move(lib)); + if (!inserted) { - error("Failed to init plugin '{}'", entry.path().stem().string()); + error("Duplicate plugin '{}'", plugin->id); continue; } - g_plugin_entries.emplace_back( - plugin_entry_t{ .lib = std::move(lib), .plugin = plugin, .state = state }); + if (plugin->init) + { + ScopedActivePlugin _(&it->second); + it->second.state = plugin->init(); + } spdlog::info("loading plugin at {}!", entry.path().string()); } @@ -525,19 +556,20 @@ void ScreenshotTool::RenderOverlay() DrawDownloadOCRWindow(); DrawOcrTools(); DrawBarDecodeTools(); - for (plugin_entry_t& entry : g_plugin_entries) + for (auto& [_, entry] : g_plugins) { oshot_plugin_t* plugin = entry.plugin; - if (!plugin->render || !plugin->name || plugin->name[0] == '\0') + if (!plugin->render || !plugin->id || !plugin->name || plugin->name[0] == '\0') continue; if (ImGui::CollapsingHeader(plugin->name)) { - ImGui::PushID(plugin->name); + ImGui::PushID(plugin->id); - ImVec2 child_size(0.0f, 0.0f); // auto-height, or let plugins set a preferred height - ImGui::BeginChild(plugin->name, child_size, ImGuiChildFlags_Borders); + // auto-height, or let plugins set a preferred height + ImGui::BeginChild(plugin->name, ImVec2(0.0f, 0.0f), ImGuiChildFlags_Borders); + ScopedActivePlugin _(&entry); plugin->render(entry.state); ImGui::EndChild(); @@ -1439,9 +1471,23 @@ void ScreenshotTool::DrawOcrTools() { ClearError(ectx, OcrError::FailedToScan); m_inputs.ocr_results = std::move(result.get()); - for (plugin_entry_t& entry : g_plugin_entries) - if (entry.plugin->on_ocr_done) - entry.plugin->on_ocr_done(entry.state); + if (!g_plugins.empty()) + { + oshot_ocr_result_t ocr{ + .text = + oshot_str_new(m_inputs.ocr_results.data.c_str(), m_inputs.ocr_results.data.length()), + .confidence = m_inputs.ocr_results.confidence, + .psm = m_inputs.ocr_results.psm, + }; + for (auto& [id, rt] : g_plugins) + { + if (!rt.plugin->on_ocr_done) + continue; + ScopedActivePlugin _(&rt); + rt.plugin->on_ocr_done(rt.state, &ocr); + } + oshot_str_free(&ocr.text); + } } else { From 1735fffe7291c4333b4025986c5533c7a4386414 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Thu, 2 Jul 2026 21:24:13 +0200 Subject: [PATCH 16/40] tool: ditch booleans states for GeneralContext+enums --- include/screenshot_tool.hpp | 56 +++++++++++++++++------- src/screenshot_tool.cpp | 87 +++++++++++++++++++------------------ 2 files changed, 84 insertions(+), 59 deletions(-) diff --git a/include/screenshot_tool.hpp b/include/screenshot_tool.hpp index f302aaa..1513394 100644 --- a/include/screenshot_tool.hpp +++ b/include/screenshot_tool.hpp @@ -80,6 +80,23 @@ enum class PrefTab Theme }; +enum class SubWindow +{ + OcrDownload, + About, + Preferences, + MainTextTools, + COUNT +}; + +enum class CurrentAction +{ + IsDrawing, + IsColorPicking, + IsTextPlacing, + COUNT +}; + enum class OcrDownloadError : size_t { InvalidRepo, @@ -155,31 +172,40 @@ struct inputs_results_t }; template -struct ErrorContext +struct GeneralContext +{ + std::bitset flags; + + void Set(Enum e, bool flag = true) { flags.set(idx(e), flag); } + + void Clear(Enum e) { flags.reset(idx(e)); } + + bool Has(Enum e) const { return flags.test(idx(e)); } + + template + bool HasAny(E... e) const + { + return (Has(e) || ...); + } +}; + +template +struct ErrorContext : public GeneralContext { - std::bitset flags; std::array texts; void Set(Enum e, std::string_view msg = {}) { - flags.set(idx(e)); + GeneralContext::Set(e); texts[idx(e)] = msg; } void Clear(Enum e) { - flags.reset(idx(e)); + GeneralContext::Clear(e); texts[idx(e)].clear(); } - bool Has(Enum e) const { return flags.test(idx(e)); } - - template - bool HasAny(E... e) const - { - return (Has(e) || ...); - } - const std::string& Get(Enum e) const { return texts[idx(e)]; } }; @@ -289,7 +315,6 @@ class ScreenshotTool selection_rect_t m_drag_start_selection; inputs_results_t m_inputs; - bool m_show_text_tools = true; ImVec2 m_drag_start_mouse; ImVec2 m_image_origin; @@ -302,6 +327,8 @@ class ScreenshotTool std::function m_on_image_reload; std::function&)> m_on_complete; + GeneralContext m_show_window; + GeneralContext m_current_actions; std::array m_tool_textures{}; ToolType m_current_tool = ToolType::kNone; std::vector m_annotations; @@ -309,9 +336,6 @@ class ScreenshotTool rgba_t m_current_color; std::unordered_map m_imgui_id_texts; std::array m_tool_thickness; - bool m_is_drawing = false; - bool m_is_color_picking = false; - bool m_is_text_placing = false; void CreateCopyTextButton(const std::string& text); void RefreshOcrModels(); diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 7f24478..bd24eec 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -45,8 +45,6 @@ using namespace std::chrono_literals; static constexpr ImVec4 error_color(1.0f, 0.0f, 0.0f, 1.0f); static constexpr ImVec2 origin(0, 0); static ImTextureRef logo_texture; -static bool show_preferences_window = false; -static bool show_toosl_window = false; constexpr rgba_t::rgba_t(ImVec4 vec) : r(static_cast(vec.x * 255.0f)), @@ -449,7 +447,7 @@ Result<> ScreenshotTool::StartWindow() m_state = ToolState::Selecting; - m_show_text_tools = g_config->File.show_text_tools; + m_show_window.Set(SubWindow::MainTextTools, g_config->File.show_text_tools); fit_to_screen(m_screenshot); SyncRuntimeFromConfig(); @@ -497,7 +495,8 @@ Result<> ScreenshotTool::StartWindow() void ScreenshotTool::RenderOverlay() { const bool disable_esc = - (m_is_text_placing || m_is_color_picking || show_preferences_window || show_toosl_window) && + (m_current_actions.Has(CurrentAction::IsTextPlacing) || m_current_actions.Has(CurrentAction::IsColorPicking) || + m_show_window.Has(SubWindow::Preferences) || m_show_window.Has(SubWindow::OcrDownload)) && !g_config->File.show_text_tools; static constexpr int minimal_win_flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings | @@ -539,7 +538,7 @@ void ScreenshotTool::RenderOverlay() { DrawAnnotationToolbar(); - if (m_is_color_picking) + if (m_current_actions.Has(CurrentAction::IsColorPicking)) HandleColorPickerInput(); else HandleAnnotationInput(); @@ -548,9 +547,10 @@ void ScreenshotTool::RenderOverlay() ImGui::End(); ImGui::PopStyleVar(); - if (m_state == ToolState::Selected && m_show_text_tools) + bool open = m_show_window.Has(SubWindow::MainTextTools); + if (m_state == ToolState::Selected && open) { - ImGui::Begin("Text tools", &m_show_text_tools, ImGuiWindowFlags_MenuBar); + ImGui::Begin("Text tools", &open, ImGuiWindowFlags_MenuBar); DrawMenuItems(); DrawPreferencesWindow(); DrawDownloadOCRWindow(); @@ -578,6 +578,7 @@ void ScreenshotTool::RenderOverlay() } ImGui::End(); } + m_show_window.Set(SubWindow::MainTextTools, open); HandleShortcutsInput(); @@ -766,17 +767,18 @@ void ScreenshotTool::HandleAnnotationInput() // overwrite m_current_annotation (including start.x/y = 0) while // m_is_text_placing stays true, causing the input window to reappear at // position (0, 0) the next time Text is selected. - if (m_is_text_placing && m_current_tool != ToolType::Text) + if (m_current_actions.Has(CurrentAction::IsTextPlacing) && m_current_tool != ToolType::Text) { m_current_annotation = {}; - m_is_text_placing = false; + m_current_actions.Clear(CurrentAction::IsTextPlacing); } if (m_current_tool == ToolType::Text) { - if (!m_is_text_placing && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ui_blocks_selection()) + if (!m_current_actions.Has(CurrentAction::IsTextPlacing) && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && + !ui_blocks_selection()) { - m_is_text_placing = true; + m_current_actions.Set(CurrentAction::IsTextPlacing); m_current_annotation.type = ToolType::Text; m_current_annotation.start = { mouse_pos.x, mouse_pos.y }; m_current_annotation.end = m_current_annotation.start; @@ -785,7 +787,7 @@ void ScreenshotTool::HandleAnnotationInput() m_current_annotation.text.clear(); } - if (m_is_text_placing) + if (m_current_actions.Has(CurrentAction::IsTextPlacing)) { const float padding_y = std::max(2.0f, (m_current_annotation.thickness - ImGui::GetTextLineHeight()) * 0.5f); @@ -823,7 +825,7 @@ void ScreenshotTool::HandleAnnotationInput() m_annotations.push_back(m_current_annotation); } m_current_annotation = {}; - m_is_text_placing = false; + m_current_actions.Clear(CurrentAction::IsTextPlacing); } ImGui::PopFont(); @@ -834,7 +836,7 @@ void ScreenshotTool::HandleAnnotationInput() if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { m_current_annotation = {}; - m_is_text_placing = false; + m_current_actions.Clear(CurrentAction::IsTextPlacing); } ImGui::End(); @@ -847,7 +849,7 @@ void ScreenshotTool::HandleAnnotationInput() if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ui_blocks_selection()) { - m_is_drawing = true; + m_current_actions.Set(CurrentAction::IsDrawing); m_current_annotation.type = m_current_tool; m_current_annotation.start = { mouse_pos.x, mouse_pos.y }; m_current_annotation.end = m_current_annotation.start; @@ -869,7 +871,7 @@ void ScreenshotTool::HandleAnnotationInput() } } - if (m_is_drawing && ImGui::IsMouseDown(ImGuiMouseButton_Left)) + if (m_current_actions.Has(CurrentAction::IsDrawing) && ImGui::IsMouseDown(ImGuiMouseButton_Left)) { m_current_annotation.end = { mouse_pos.x, mouse_pos.y }; @@ -887,9 +889,9 @@ void ScreenshotTool::HandleAnnotationInput() } } - if (m_is_drawing && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + if (m_current_actions.Has(CurrentAction::IsDrawing) && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) { - m_is_drawing = false; + m_current_actions.Clear(CurrentAction::IsDrawing); // Only add annotation if it has meaningful size or points bool should_add = false; @@ -1016,8 +1018,8 @@ void ScreenshotTool::HandleColorPickerInput() if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) { - m_current_color = c; - m_is_color_picking = false; + m_current_color = c; + m_current_actions.Clear(CurrentAction::IsColorPicking); } } @@ -1034,7 +1036,7 @@ void ScreenshotTool::HandleColorPickerInput() if (ImGui::IsMouseClicked(ImGuiMouseButton_Right) || ImGui::IsKeyPressed(ImGuiKey_Escape)) { - m_is_color_picking = false; + m_current_actions.Clear(CurrentAction::IsColorPicking); ImGui::SetMouseCursor(ImGuiMouseCursor_Arrow); } } @@ -1234,8 +1236,6 @@ void ScreenshotTool::DrawSelectionBorder() void ScreenshotTool::DrawMenuItems() { - static bool show_about = false; - if (ImGui::BeginMenuBar()) { // Now draw the menus @@ -1301,7 +1301,7 @@ void ScreenshotTool::DrawMenuItems() ImGui::Separator(); if (ImGui::MenuItem("Preferences...")) - show_preferences_window = true; + m_show_window.Set(SubWindow::Preferences); ImGui::EndMenu(); } @@ -1309,24 +1309,25 @@ void ScreenshotTool::DrawMenuItems() if (ImGui::BeginMenu("Tools")) { if (ImGui::MenuItem("Download OCR model")) - show_toosl_window = true; + m_show_window.Set(SubWindow::OcrDownload); ImGui::EndMenu(); } if (ImGui::BeginMenu("Help")) { if (ImGui::MenuItem("About")) - show_about = true; + m_show_window.Set(SubWindow::About); ImGui::EndMenu(); } ImGui::EndMenuBar(); } - if (show_about) + bool open = m_show_window.Has(SubWindow::About); + if (open) { ImGui::SetNextWindowSize(ImVec2(350, 250), ImGuiCond_FirstUseEver); - ImGui::Begin("About", &show_about, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings); + ImGui::Begin("About", &open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings); float window_width = ImGui::GetWindowSize().x; std::string_view text_display; @@ -1374,9 +1375,10 @@ void ScreenshotTool::DrawMenuItems() minimize_window(); if (ImGui::Button("Close")) - show_about = false; + m_show_window.Clear(SubWindow::About); ImGui::End(); } + m_show_window.Set(SubWindow::About, open); } void ScreenshotTool::DrawOcrTools() @@ -1686,7 +1688,7 @@ void ScreenshotTool::DrawAnnotationToolbar() if (ImGui::Button("Pick color")) { - m_is_color_picking = true; + m_current_actions.Set(CurrentAction::IsColorPicking); ImGui::CloseCurrentPopup(); } ImGui::SameLine(); @@ -1716,10 +1718,10 @@ void ScreenshotTool::DrawAnnotationToolbar() ImGui::SameLine(0, 16.0f); - if (!m_show_text_tools) + if (!m_show_window.Has(SubWindow::MainTextTools)) { if (ImGui::ImageButton("##ShowTextTools", m_tool_textures[idx(ToolType::ToggleTextTools)], ImVec2(24, 24))) - m_show_text_tools = true; + m_show_window.Set(SubWindow::MainTextTools); ImGui::SameLine(); } @@ -2131,7 +2133,7 @@ void ScreenshotTool::DrawPreferencesWindow() static Config::config_file_t config_snapshot; // config state at the moment the window opened static Config::theme_overrides_t theme_snapshot; // theme state at the moment the window opened - if (!show_preferences_window) + if (!m_show_window.Has(SubWindow::Preferences)) { prev_window_open = false; return; @@ -2203,7 +2205,7 @@ void ScreenshotTool::DrawPreferencesWindow() if (prefs_modified) ImGui::OpenPopup("Unsaved changes##pref"); else - show_preferences_window = false; + m_show_window.Clear(SubWindow::Preferences); // Either way, don't propagate to show_preferences_window yet, // the window_open local resets to true next frame automatically. } @@ -2252,14 +2254,14 @@ void ScreenshotTool::DrawPreferencesWindow() if (ImGui::Button("Save & Close", ImVec2(110, 0))) { save_current_tab(); - show_preferences_window = false; + m_show_window.Clear(SubWindow::Preferences); ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if (ImGui::Button("Discard", ImVec2(80, 0))) { discard_current_tab(); - show_preferences_window = false; + m_show_window.Clear(SubWindow::Preferences); ImGui::CloseCurrentPopup(); } ImGui::SameLine(); @@ -2287,7 +2289,7 @@ void ScreenshotTool::DrawPreferencesWindow() ImGui::End(); // Clean up tracking state after a confirmed close so the next open is fresh. - if (!show_preferences_window) + if (!m_show_window.Has(SubWindow::Preferences)) { prev_window_open = false; prefs_modified = false; @@ -2298,7 +2300,7 @@ void ScreenshotTool::DrawDownloadOCRWindow() { ErrorContext& ectx = m_download_errors; - if (!show_toosl_window) + if (!m_show_window.Has(SubWindow::OcrDownload)) return; static bool has_downloaded = false; @@ -2314,9 +2316,9 @@ void ScreenshotTool::DrawDownloadOCRWindow() const bool is_downloading = m_ocr_download && m_ocr_download->running.load(); - bool window_open = true; + bool open = m_show_window.Has(SubWindow::OcrDownload); ImGui::SetNextWindowSize(ImVec2(520, 0), ImGuiCond_FirstUseEver); // 0 = auto height - if (ImGui::Begin("Download OCR Model##ocr_download_window", &window_open, ImGuiWindowFlags_NoSavedSettings)) + if (ImGui::Begin("Download OCR Model##ocr_download_window", &open, ImGuiWindowFlags_NoSavedSettings)) { // Lock all inputs while a download is in flight if (is_downloading) @@ -2517,8 +2519,7 @@ void ScreenshotTool::DrawDownloadOCRWindow() ImGui::End(); } - if (!window_open) - show_toosl_window = false; + m_show_window.Set(SubWindow::OcrDownload, open); } void ScreenshotTool::DrawAnnotations() @@ -2643,7 +2644,7 @@ void ScreenshotTool::DrawAnnotations() draw_annotation(ann); // Render current annotation being drawn on top of committed ones - if (m_is_drawing) + if (m_current_actions.Has(CurrentAction::IsDrawing)) draw_annotation(m_current_annotation); } From 219c3b58993b8f0b8d5847664cdbd878acd52e95 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 3 Jul 2026 00:31:25 +0200 Subject: [PATCH 17/40] tool: add logs window also separate some plugins code away from screenshot_tool.cpp to plugins.cpp --- CMakeLists.txt | 2 +- include/plugin.hpp | 2 + include/screenshot_tool.hpp | 4 +- src/main.cpp | 4 +- src/plugins.cpp | 89 +++++++ src/plugins/oshot_plugin.h | 2 - .../{plugins.cpp => oshot_plugins.cpp} | 28 +-- src/screenshot_tool.cpp | 233 +++++++++++------- 8 files changed, 242 insertions(+), 122 deletions(-) create mode 100644 src/plugins.cpp rename src/plugins/{plugins.cpp => oshot_plugins.cpp} (87%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 747823b..65bda8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -222,7 +222,7 @@ set_target_properties( # ----------------------------- # oshot's plugin library # ----------------------------- -add_library(oshot_plugin SHARED src/plugins/plugins.cpp) +add_library(oshot_plugin SHARED src/plugins/oshot_plugins.cpp) enable_lto(oshot_plugin) diff --git a/include/plugin.hpp b/include/plugin.hpp index b20a683..bb4a2af 100644 --- a/include/plugin.hpp +++ b/include/plugin.hpp @@ -55,3 +55,5 @@ struct plugin_runtime_t plugin_runtime_t(plugin_runtime_t&&) = default; plugin_runtime_t& operator=(plugin_runtime_t&&) = default; }; + +void load_plugins(); diff --git a/include/screenshot_tool.hpp b/include/screenshot_tool.hpp index 1513394..27424da 100644 --- a/include/screenshot_tool.hpp +++ b/include/screenshot_tool.hpp @@ -86,6 +86,7 @@ enum class SubWindow About, Preferences, MainTextTools, + Logs, COUNT }; @@ -329,7 +330,7 @@ class ScreenshotTool GeneralContext m_show_window; GeneralContext m_current_actions; - std::array m_tool_textures{}; + std::array m_tool_textures; ToolType m_current_tool = ToolType::kNone; std::vector m_annotations; annotation_t m_current_annotation; @@ -358,6 +359,7 @@ class ScreenshotTool void DrawAnnotationToolbar(); void DrawPreferencesWindow(); void DrawDownloadOCRWindow(); + void DrawLogsWindow(); void UpdateHandleHoverState(); void UpdateCursor(); diff --git a/src/main.cpp b/src/main.cpp index 6e08ace..1f3474b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,6 +35,7 @@ #include "screen_capture.hpp" #include "screenshot_tool.hpp" #include "spdlog/sinks/basic_file_sink.h" +#include "spdlog/sinks/ringbuffer_sink.h" #include "spdlog/sinks/stdout_color_sinks.h" #include "switch_fnv1a.hpp" #include "tinyfiledialogs.h" @@ -387,7 +388,8 @@ int main(int argc, char* argv[]) } auto console = std::make_shared(); - spdlog::logger logger("oshot_logger", { console, file }); + auto imgui = std::make_shared(500); // keep last 500 lines + spdlog::logger logger("oshot_logger", { console, file, imgui }); spdlog::set_default_logger(std::make_shared(logger)); // [2026-03-10 17:24:07.593] [DEBUG] message diff --git a/src/plugins.cpp b/src/plugins.cpp new file mode 100644 index 0000000..91d7caf --- /dev/null +++ b/src/plugins.cpp @@ -0,0 +1,89 @@ +#include "plugin.hpp" +#include "util.hpp" + +void load_plugins() +{ + const fs::path pluginDir = get_config_dir() / "plugins"; + fs::create_directories(pluginDir); + + for (const auto& plugin_dir : fs::directory_iterator(pluginDir, fs::directory_options::skip_permission_denied)) + { + if (!plugin_dir.is_directory()) + continue; + + const std::string expected = + "lib" + plugin_dir.path().filename().string() + dylib::decorations::os_default().suffix; + + for (const auto& entry : + fs::directory_iterator(plugin_dir.path(), fs::directory_options::skip_permission_denied)) + { + if (entry.path().filename() != expected) + continue; + + try + { + dylib::library lib(entry.path().string()); + auto oshot_get_plugin = lib.get_function("oshot_host_get_plugin"); + oshot_plugin_t* plugin = oshot_get_plugin(); + + if (!plugin || plugin->abi_version != oshot_get_abi_version()) + { + error("Plugin '{}' has incompatible ABI version, skipping", entry.path().stem().string()); + continue; + } + + if (!plugin->render || !plugin->id || !plugin->name || plugin->name[0] == '\0') + { + error("Plugin '{}' doesn't define name/ID or render function", entry.path().stem().string()); + continue; + } + + if (plugin->id[0] == '.' || + !std::ranges::all_of(std::string_view(plugin->id), [](const unsigned char c) { + return (isalnum(c) || c == '-' || c == '_' || c == '=' || c == '.'); + })) + { + error("Plugin '{}' has an invalid ID", plugin->id); + continue; + } + + if (!std::ranges::all_of(std::string_view(plugin->name), [](const unsigned char c) { + return (isalnum(c) || c == '-' || c == '_' || c == '=' || c == ' '); + })) + { + error("Plugin '{}' contains chars other than -_= or alpha numerical", plugin->id); + continue; + } + + auto [it, inserted] = g_plugins.try_emplace(plugin->id, + plugin->id, + fmt::format("plugins.{}.", plugin->id), + get_config_dir() / "plugins" / plugin->id, + plugin, + nullptr, // state filled in below + std::move(lib)); + if (!inserted) + { + error("Duplicate plugin '{}'", plugin->id); + continue; + } + + if (plugin->init) + { + ScopedActivePlugin _(&it->second); + it->second.state = plugin->init(); + } + + spdlog::info("loading plugin at {}!", entry.path().string()); + } + catch (const dylib::load_error& e) + { + error("Failed to load '{}' library: {}", entry.path().stem().string(), e.what()); + } + catch (const dylib::symbol_error& e) + { + error("Failed to get 'oshot_get_plugin()' symbol: {}", e.what()); + } + } + } +} diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h index 778ebe1..6a3d543 100644 --- a/src/plugins/oshot_plugin.h +++ b/src/plugins/oshot_plugin.h @@ -101,12 +101,10 @@ void oshot_str_free(oshot_str_t* str); /* ------------------------------------------------------------------ * Logging / host messaging * ------------------------------------------------------------------ */ -void oshot_display_msg(OSLogLevel lvl, oshot_str_t str); void oshot_log(OSLogLevel lvl, oshot_str_t str); void oshot_debug(oshot_str_t str); // oshot_log(DEBUG, str); // convinience ig -void oshot_display_msg_s(OSLogLevel lvl, const char* str); void oshot_log_s(OSLogLevel lvl, const char* str); void oshot_debug_s(const char* str); // oshot_log(DEBUG, str); diff --git a/src/plugins/plugins.cpp b/src/plugins/oshot_plugins.cpp similarity index 87% rename from src/plugins/plugins.cpp rename to src/plugins/oshot_plugins.cpp index 9708897..b4b498c 100644 --- a/src/plugins/plugins.cpp +++ b/src/plugins/oshot_plugins.cpp @@ -38,29 +38,12 @@ void oshot_str_free(oshot_str_t* str) } /* ------------------------------------------------------------------ - * Logging / host messaging + * Logging * ------------------------------------------------------------------ */ -void oshot_display_msg(const OSLogLevel lvl, oshot_str_t str) +void oshot_log(const OSLogLevel lvl, oshot_str_t str) { const std::string& out = fmt::format("{}: {}", g_current_plugin->plugin->id, std::string_view(str.p, str.len)); switch (lvl) - { - case OSLogLevel::OSHOT_LOG_DEBUG: - spdlog::warn("OSHOT_LOG_DEBUG is not allowed when displaying a message."); - break; - case OSLogLevel::OSHOT_LOG_INFO: info("{}", out); break; - case OSLogLevel::OSHOT_LOG_WARN: warn("{}", out); break; - case OSLogLevel::OSHOT_LOG_ERROR: error("{}", out); break; - } -} - -void oshot_log(OSLogLevel lvl, oshot_str_t str) -{ - auto now = std::chrono::system_clock::now(); - - const std::string& out = - fmt::format("[{}] {}: {}", now, g_current_plugin->plugin->id, std::string_view(str.p, str.len)); - switch (lvl) { case OSLogLevel::OSHOT_LOG_DEBUG: spdlog::debug("{}", out); break; case OSLogLevel::OSHOT_LOG_INFO: spdlog::info("{}", out); break; @@ -74,13 +57,6 @@ void oshot_debug(oshot_str_t str) oshot_log(OSLogLevel::OSHOT_LOG_DEBUG, std::move(str)); } -void oshot_display_msg_s(OSLogLevel lvl, const char* str) -{ - oshot_str_t s = oshot_str_new(str, strlen(str)); - oshot_display_msg(lvl, s); - oshot_str_free(&s); -} - void oshot_log_s(OSLogLevel lvl, const char* str) { oshot_str_t s = oshot_str_new(str, strlen(str)); diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index bd24eec..5940033 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -23,6 +23,7 @@ #include "cache.hpp" #include "clipboard.hpp" #include "config.hpp" +#include "fmt/chrono.h" #include "fmt/format.h" #include "imgui/imgui.h" #include "imgui/imgui_impl_opengl3_loader.h" @@ -31,6 +32,7 @@ #include "plugin.hpp" #include "plugins/oshot_plugin.h" #include "screen_capture.hpp" +#include "spdlog/sinks/ringbuffer_sink.h" #include "tiny-process-library/process.hpp" #include "tinyfiledialogs.h" #include "tool_icons.h" @@ -255,93 +257,6 @@ static std::unordered_map& color_name_map() return map; } -static void load_plugins() -{ - const fs::path pluginDir = get_config_dir() / "plugins"; - fs::create_directories(pluginDir); - - for (const auto& plugin_dir : fs::directory_iterator(pluginDir, fs::directory_options::skip_permission_denied)) - { - if (!plugin_dir.is_directory()) - continue; - - const std::string expected = - "lib" + plugin_dir.path().filename().string() + dylib::decorations::os_default().suffix; - - for (const auto& entry : - fs::directory_iterator(plugin_dir.path(), fs::directory_options::skip_permission_denied)) - { - if (entry.path().filename() != expected) - continue; - - try - { - dylib::library lib(entry.path().string()); - auto oshot_get_plugin = lib.get_function("oshot_host_get_plugin"); - oshot_plugin_t* plugin = oshot_get_plugin(); - - if (!plugin || plugin->abi_version != oshot_get_abi_version()) - { - error("Plugin '{}' has incompatible ABI version, skipping", entry.path().stem().string()); - continue; - } - - if (!plugin->render || !plugin->id || !plugin->name || plugin->name[0] == '\0') - { - error("Plugin '{}' doesn't define name/ID or render function", entry.path().stem().string()); - continue; - } - - if (plugin->id[0] == '.' || - !std::ranges::all_of(std::string_view(plugin->id), [](const unsigned char c) { - return (isalnum(c) || c == '-' || c == '_' || c == '=' || c == '.'); - })) - { - error("Plugin '{}' has an invalid ID", plugin->id); - continue; - } - - if (!std::ranges::all_of(std::string_view(plugin->name), [](const unsigned char c) { - return (isalnum(c) || c == '-' || c == '_' || c == '=' || c == ' '); - })) - { - error("Plugin '{}' contains chars other than -_= or alpha numerical", plugin->id); - continue; - } - - auto [it, inserted] = g_plugins.try_emplace(plugin->id, - plugin->id, - fmt::format("plugins.{}.", plugin->id), - get_config_dir() / "plugins" / plugin->id, - plugin, - nullptr, // state filled in below - std::move(lib)); - if (!inserted) - { - error("Duplicate plugin '{}'", plugin->id); - continue; - } - - if (plugin->init) - { - ScopedActivePlugin _(&it->second); - it->second.state = plugin->init(); - } - - spdlog::info("loading plugin at {}!", entry.path().string()); - } - catch (const dylib::load_error& e) - { - error("Failed to load '{}' library: {}", entry.path().stem().string(), e.what()); - } - catch (const dylib::symbol_error& e) - { - error("Failed to get 'oshot_get_plugin()' symbol: {}", e.what()); - } - } - } -} - void apply_imgui_theme() { const std::string& base = g_config->File.theme_style; @@ -494,10 +409,9 @@ Result<> ScreenshotTool::StartWindow() void ScreenshotTool::RenderOverlay() { - const bool disable_esc = - (m_current_actions.Has(CurrentAction::IsTextPlacing) || m_current_actions.Has(CurrentAction::IsColorPicking) || - m_show_window.Has(SubWindow::Preferences) || m_show_window.Has(SubWindow::OcrDownload)) && - !g_config->File.show_text_tools; + const bool disable_esc = (m_current_actions.HasAny(CurrentAction::IsTextPlacing, CurrentAction::IsColorPicking) || + m_show_window.HasAny(SubWindow::OcrDownload, SubWindow::Preferences)) && + !g_config->File.show_text_tools; static constexpr int minimal_win_flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoResize | @@ -554,6 +468,7 @@ void ScreenshotTool::RenderOverlay() DrawMenuItems(); DrawPreferencesWindow(); DrawDownloadOCRWindow(); + DrawLogsWindow(); DrawOcrTools(); DrawBarDecodeTools(); for (auto& [_, entry] : g_plugins) @@ -1310,6 +1225,9 @@ void ScreenshotTool::DrawMenuItems() { if (ImGui::MenuItem("Download OCR model")) m_show_window.Set(SubWindow::OcrDownload); + ImGui::Separator(); + if (ImGui::MenuItem("Show Logs")) + m_show_window.Set(SubWindow::Logs); ImGui::EndMenu(); } @@ -2296,6 +2214,139 @@ void ScreenshotTool::DrawPreferencesWindow() } } +void ScreenshotTool::DrawLogsWindow() +{ + static std::shared_ptr imgui_ring; + if (!imgui_ring) + if (auto logger = spdlog::get("oshot_logger")) + imgui_ring = std::dynamic_pointer_cast(logger->sinks()[2]); + + if (!m_show_window.Has(SubWindow::Logs) || !imgui_ring) + return; + + auto level_color = [](spdlog::level::level_enum lvl) -> rgba_t { + switch (lvl) + { + case spdlog::level::trace: return rgba_t(0x888888FF); // gray + case spdlog::level::debug: return rgba_t(0x9999FFFF); // periwinkle + case spdlog::level::info: return rgba_t(0x00AEFFFF); // blueish + case spdlog::level::warn: return rgba_t(0xFFCC33FF); // amber + case spdlog::level::err: return rgba_t(0xFF4D4DFF); // red + case spdlog::level::critical: return rgba_t(0xFF0000FF); // pure red + default: return rgba_t(0xFFFFFFFF); // white + } + }; + + auto level_tag = [](spdlog::level::level_enum lvl) -> const char* { + switch (lvl) + { + case spdlog::level::trace: return "TRACE"; + case spdlog::level::debug: return "DEBUG"; + case spdlog::level::info: return "INFO"; + case spdlog::level::warn: return "WARN"; + case spdlog::level::err: return "ERROR"; + case spdlog::level::critical: return "CRIT"; + default: return "OFF"; + } + }; + + // Persistent UI state for this window + static ImGuiTextFilter text_filter; + static spdlog::level::level_enum min_level = spdlog::level::debug; + static bool autoscroll = true; + static spdlog::log_clock::time_point cleared_before{}; // "soft clear" marker + + bool open = m_show_window.Has(SubWindow::Logs); + ImGui::SetNextWindowSize(ImVec2(560, 400), ImGuiCond_FirstUseEver); + if (ImGui::Begin("Logs##logs_window", &open, ImGuiWindowFlags_NoSavedSettings)) + { + // --- Toolbar --- + if (ImGui::Button("Clear")) + cleared_before = spdlog::log_clock::now(); + + ImGui::SameLine(); + bool copy_all = ImGui::Button("Copy"); + ImGui::SameLine(); + ImGui::Checkbox("Auto-scroll", &autoscroll); + ImGui::SameLine(); + ImGui::SetNextItemWidth(110); + if (ImGui::BeginCombo("##min_level", level_tag(min_level))) + { + for (int i = spdlog::level::trace; i < spdlog::level::off; ++i) + { + auto lvl = toe(i); + bool selected = (lvl == min_level); + if (ImGui::Selectable(level_tag(lvl), selected)) + min_level = lvl; + if (selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + text_filter.Draw("Filter", 200); + + ImGui::Separator(); + + // --- Build filtered view --- + const std::vector& all = imgui_ring->last_raw(); + std::vector shown; + shown.reserve(all.size()); + for (const auto& msg : all) + { + if (msg.level < min_level || msg.time <= cleared_before) + continue; + if (!text_filter.PassFilter(msg.payload.data(), msg.payload.data() + msg.payload.size())) + continue; + shown.push_back(&msg); + } + + // --- Scrolling log region --- + ImGui::BeginChild("##log_scroll", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar); + + ImGuiListClipper clipper; + clipper.Begin(static_cast(shown.size())); + while (clipper.Step()) + { + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; ++i) + { + const auto& msg = *shown[i]; + auto time_ms = std::chrono::time_point_cast(msg.time); + const std::string& time_fmt = fmt::format("{:%H:%M:%S}", time_ms); + + ImGui::TextDisabled("%s", time_fmt.c_str()); + ImGui::SameLine(); + ImGui::TextColored(level_color(msg.level).to_imvec4(), "[%s]", level_tag(msg.level)); + ImGui::SameLine(); + ImGui::TextUnformatted(msg.payload.data(), msg.payload.data() + msg.payload.size()); + + if (ImGui::BeginPopupContextItem(fmt::format("ctx##{}", i).c_str())) + { + if (ImGui::MenuItem("Copy line")) + MUST_OK(g_clipboard.CopyText(msg.payload.data()), error("Failed to copy line log: {}", _r.error_v())); + ImGui::EndPopup(); + } + } + } + + if (copy_all) + { + std::string all_text; + for (const auto* msg : shown) + all_text += fmt::format("[{}] {}\n", level_tag(msg->level), msg->payload); + MUST_OK(g_clipboard.CopyText(all_text), error("Failed to copy logs: {}", _r.error_v())); + } + + if (autoscroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY() - 1.0f) + ImGui::SetScrollHereY(1.0f); + + ImGui::EndChild(); + ImGui::End(); + } + + m_show_window.Set(SubWindow::Logs, open); +} + void ScreenshotTool::DrawDownloadOCRWindow() { ErrorContext& ectx = m_download_errors; From 26c7ed62d25fc68a6bf4e5991934717e43a785b0 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 3 Jul 2026 12:58:05 +0200 Subject: [PATCH 18/40] misc: suppress some dialogs to just logs let's avoid annoying the user sometimes --- src/cache.cpp | 4 ++-- src/config.cpp | 10 +++++----- src/main.cpp | 2 +- src/plugins.cpp | 16 ++++++++-------- src/screenshot_tool.cpp | 8 ++++---- src/util.cpp | 6 +++--- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/cache.cpp b/src/cache.cpp index 3d09098..ad53c58 100644 --- a/src/cache.cpp +++ b/src/cache.cpp @@ -27,11 +27,11 @@ Cache::Cache(const std::string& cache_dir) : m_cache_dir_path(cache_dir) { if (!fs::exists(cache_dir)) { - warn("Oshot cache folder was not found. Creating folders at {}!", cache_dir); + spdlog::warn("Oshot cache folder was not found. Creating folders at {}!", cache_dir); fs::create_directories(cache_dir); } - MUST_OK(LoadCacheFile(), error("{}", _r.error_v())); + MUST_OK(LoadCacheFile(), spdlog::error("{}", _r.error_v())); } Cache::~Cache() diff --git a/src/config.cpp b/src/config.cpp index c17a3c1..f90df8b 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -15,14 +15,14 @@ Config::Config(const fs::path& configFile, const fs::path& configDir) { if (!fs::exists(configDir)) { - warn("Oshot config folder was not found, creating folders at {}!", configDir.string()); + spdlog::warn("Oshot config folder was not found, creating folders at {}!", configDir.string()); fs::create_directories(configDir); fs::create_directories(configDir / "models"); } if (!fs::exists(configFile)) { - warn("Config file {} not found, generating new one", configFile.string()); + spdlog::warn("Config file {} not found, generating new one", configFile.string()); GenerateConfig(configFile.string()); } } @@ -63,9 +63,9 @@ void Config::LoadConfigFile(const std::string& filename) File.allow_out_edit = GetValue("default.allow-edit-ocr", false); // deprecated File.allow_out_edit = GetValue("default.allow-text-edit", File.allow_out_edit); - const char* tessdata_prefix; - if (!File.pref_conf_to_env && (tessdata_prefix = getenv("TESSDATA_PREFIX"))) - File.ocr_path = tessdata_prefix; + const char* t; + if (!File.pref_conf_to_env && (t = getenv("TESSDATA_PREFIX"))) + File.ocr_path = t; } void Config::LoadThemeFile(const std::string& filename) diff --git a/src/main.cpp b/src/main.cpp index 1f3474b..4f865a9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -251,7 +251,7 @@ void capture_worker() do_copy_image = false; capture_result_t img = std::move(pending_image); lk.unlock(); - MUST_OK(g_clipboard.CopyImage(img), error("{}", _r.error_v())); + MUST_OK(g_clipboard.CopyImage(img), spdlog::error("{}", _r.error_v())); continue; } diff --git a/src/plugins.cpp b/src/plugins.cpp index 91d7caf..611ee00 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -28,13 +28,13 @@ void load_plugins() if (!plugin || plugin->abi_version != oshot_get_abi_version()) { - error("Plugin '{}' has incompatible ABI version, skipping", entry.path().stem().string()); + spdlog::critical("Plugin '{}' has incompatible ABI version, skipping", entry.path().stem().string()); continue; } if (!plugin->render || !plugin->id || !plugin->name || plugin->name[0] == '\0') { - error("Plugin '{}' doesn't define name/ID or render function", entry.path().stem().string()); + spdlog::critical("Plugin '{}' doesn't define name/ID or render function", entry.path().stem().string()); continue; } @@ -43,7 +43,7 @@ void load_plugins() return (isalnum(c) || c == '-' || c == '_' || c == '=' || c == '.'); })) { - error("Plugin '{}' has an invalid ID", plugin->id); + spdlog::critical("Plugin '{}' has an invalid ID", plugin->id); continue; } @@ -51,7 +51,7 @@ void load_plugins() return (isalnum(c) || c == '-' || c == '_' || c == '=' || c == ' '); })) { - error("Plugin '{}' contains chars other than -_= or alpha numerical", plugin->id); + spdlog::critical("Plugin '{}' contains chars other than -_= or alpha numerical", plugin->id); continue; } @@ -64,7 +64,7 @@ void load_plugins() std::move(lib)); if (!inserted) { - error("Duplicate plugin '{}'", plugin->id); + spdlog::warn("Duplicate plugin '{}'", plugin->id); continue; } @@ -74,15 +74,15 @@ void load_plugins() it->second.state = plugin->init(); } - spdlog::info("loading plugin at {}!", entry.path().string()); + info("loading plugin at {}!", entry.path().string()); } catch (const dylib::load_error& e) { - error("Failed to load '{}' library: {}", entry.path().stem().string(), e.what()); + spdlog::error("Failed to load '{}' library: {}", entry.path().stem().string(), e.what()); } catch (const dylib::symbol_error& e) { - error("Failed to get 'oshot_get_plugin()' symbol: {}", e.what()); + spdlog::error("Failed to get 'oshot_get_plugin()' symbol: {}", e.what()); } } } diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 5940033..1045def 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -2218,7 +2218,7 @@ void ScreenshotTool::DrawLogsWindow() { static std::shared_ptr imgui_ring; if (!imgui_ring) - if (auto logger = spdlog::get("oshot_logger")) + if (auto logger = spdlog::default_logger()) imgui_ring = std::dynamic_pointer_cast(logger->sinks()[2]); if (!m_show_window.Has(SubWindow::Logs) || !imgui_ring) @@ -2245,7 +2245,7 @@ void ScreenshotTool::DrawLogsWindow() case spdlog::level::info: return "INFO"; case spdlog::level::warn: return "WARN"; case spdlog::level::err: return "ERROR"; - case spdlog::level::critical: return "CRIT"; + case spdlog::level::critical: return "CRITICAL"; default: return "OFF"; } }; @@ -2323,7 +2323,7 @@ void ScreenshotTool::DrawLogsWindow() if (ImGui::BeginPopupContextItem(fmt::format("ctx##{}", i).c_str())) { if (ImGui::MenuItem("Copy line")) - MUST_OK(g_clipboard.CopyText(msg.payload.data()), error("Failed to copy line log: {}", _r.error_v())); + MUST_OK(g_clipboard.CopyText(msg.payload.data()), spdlog::error("Failed to copy line log: {}", _r.error_v())); ImGui::EndPopup(); } } @@ -2334,7 +2334,7 @@ void ScreenshotTool::DrawLogsWindow() std::string all_text; for (const auto* msg : shown) all_text += fmt::format("[{}] {}\n", level_tag(msg->level), msg->payload); - MUST_OK(g_clipboard.CopyText(all_text), error("Failed to copy logs: {}", _r.error_v())); + MUST_OK(g_clipboard.CopyText(all_text), spdlog::error("Failed to copy logs: {}", _r.error_v())); } if (autoscroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY() - 1.0f) diff --git a/src/util.cpp b/src/util.cpp index f7cefb4..16f9f96 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -211,7 +211,7 @@ void fit_to_screen(capture_result_t& img) bool ok = stbir_resize_uint8_linear(img.data.data(), img_w, img_h, 0, resized.data(), new_w, new_h, 0, STBIR_RGBA); if (!ok) { - warn("Failed to resize image: {}", STBI_ERROR); + spdlog::warn("Failed to resize image: {}", STBI_ERROR); return; } @@ -714,14 +714,14 @@ void build_font_atlas(ImGuiIO& io) const fs::path& path = get_font_path(font); if (path.empty()) { - warn("Font '{}' not found, skipping", font); + spdlog::warn("Font '{}' not found, skipping", font); continue; } ImFont* f = io.Fonts->AddFontFromFileTTF(path.string().c_str(), 16.0f, &font_cfg); if (!f) { - warn("Font '{}' failed to load", font); + spdlog::warn("Font '{}' failed to load", font); continue; } From 020de27aac8f25b60fd131710db3dde749785fa0 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 3 Jul 2026 16:01:59 +0200 Subject: [PATCH 19/40] build: try to fix macos/windows/debian package builds --- CMakeLists.txt | 99 +++++++++++++++++++++-------------- src/plugins.cpp | 8 +-- src/plugins/oshot_plugin.h | 4 +- src/plugins/oshot_plugins.cpp | 4 +- 4 files changed, 67 insertions(+), 48 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 65bda8a..aa4ba7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,9 +13,6 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") -set(CMAKE_CXX_VISIBILITY_PRESET hidden) -set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) - # LTO helper function(enable_lto target) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") @@ -72,6 +69,18 @@ pkg_check_modules(TESSERACT REQUIRED tesseract) pkg_check_modules(LEPTONICA REQUIRED lept) pkg_check_modules(ZBAR REQUIRED zbar) +# Homebrew's lept.pc points Cflags at .../include/leptonica directly (its +# own convention is `#include `), but our code uses +# `#include `, which needs the parent dir on the +# include path too. Add it defensively on every platform. +message(STATUS "LEPTONICA_INCLUDE_DIRS before: ${LEPTONICA_INCLUDE_DIRS}") +foreach(_lept_dir ${LEPTONICA_INCLUDE_DIRS}) + get_filename_component(_lept_parent_dir "${_lept_dir}" DIRECTORY) + list(APPEND LEPTONICA_INCLUDE_DIRS "${_lept_parent_dir}") +endforeach() +list(REMOVE_DUPLICATES LEPTONICA_INCLUDE_DIRS) +message(STATUS "LEPTONICA_INCLUDE_DIRS after: ${LEPTONICA_INCLUDE_DIRS}") + if(UNIX AND NOT APPLE) find_package(X11 REQUIRED) pkg_check_modules(APPINDICATOR appindicator3-0.1) @@ -111,7 +120,10 @@ target_compile_options( $<$:-ggdb3;-fno-omit-frame-pointer;-Wall;-Wextra;-pedantic;-Wno-unused-parameter> ) -target_compile_definitions(${PROJECT_NAME} PRIVATE VERSION="${PROJECT_VERSION}") +target_compile_definitions( + ${PROJECT_NAME} + PRIVATE VERSION="${PROJECT_VERSION}" TOML_HEADER_ONLY=0 +) target_include_directories( ${PROJECT_NAME} @@ -213,8 +225,6 @@ endif() set_target_properties( ${PROJECT_NAME} PROPERTIES - CXX_VISIBILITY_PRESET default - VISIBILITY_INLINES_HIDDEN OFF BUILD_RPATH "${_rpath_origin}/../lib;$" INSTALL_RPATH "${_rpath_origin}/../lib" ) @@ -222,26 +232,40 @@ set_target_properties( # ----------------------------- # oshot's plugin library # ----------------------------- -add_library(oshot_plugin SHARED src/plugins/oshot_plugins.cpp) +add_library( + oshot_plugin + SHARED + src/plugins/oshot_plugins.cpp + src/libs/toml++/toml.cpp +) enable_lto(oshot_plugin) -target_include_directories(oshot_plugin PUBLIC include/libs) -target_include_directories(oshot_plugin PUBLIC include/) +target_include_directories(oshot_plugin PUBLIC include/ include/libs) +target_include_directories( + oshot_plugin + PRIVATE + ${TESSERACT_INCLUDE_DIRS} + ${LEPTONICA_INCLUDE_DIRS} + ${ZBAR_INCLUDE_DIRS} +) target_compile_definitions(oshot_plugin PRIVATE VERSION="${PROJECT_VERSION}") target_compile_features(oshot_plugin PUBLIC cxx_std_20) target_link_libraries(oshot_plugin PUBLIC fmt) +target_link_libraries( + oshot_plugin + PRIVATE + nvdialog + ${TESSERACT_LIBRARIES} + ${LEPTONICA_LIBRARIES} + ${ZBAR_LIBRARIES} +) set_target_properties( oshot_plugin - PROPERTIES - CXX_VISIBILITY_PRESET default - VISIBILITY_INLINES_HIDDEN OFF - VERSION 1 - SOVERSION 1 + PROPERTIES VERSION 1 SOVERSION 1 WINDOWS_EXPORT_ALL_SYMBOLS ON ) - target_link_libraries(${PROJECT_NAME} PRIVATE oshot_plugin) # ----------------------------- @@ -255,6 +279,7 @@ enable_lto(fmt) target_include_directories(fmt PUBLIC include/libs) target_compile_features(fmt PUBLIC cxx_std_20) target_compile_definitions(fmt PUBLIC FMT_HEADER_ONLY=0) +set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE ON) target_link_libraries(${PROJECT_NAME} PRIVATE fmt) @@ -272,28 +297,26 @@ add_library(imgui SHARED ${IMGUI_SOURCES}) enable_lto(imgui) target_include_directories(imgui PUBLIC include/libs/imgui) -target_compile_definitions(imgui PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLAD IMGUI_DISABLE_OBSOLETE_FUNCTIONS) +target_compile_definitions( + imgui + PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLAD IMGUI_DISABLE_OBSOLETE_FUNCTIONS +) target_link_libraries(imgui PUBLIC ${GLFW_TARGET}) if(APPLE) find_library(METAL_FRAMEWORK Metal REQUIRED) find_library(FOUNDATION_FRAMEWORK Foundation REQUIRED) find_library(QUARTZCORE_FRAMEWORK QuartzCore REQUIRED) - target_link_libraries(imgui PUBLIC - ${METAL_FRAMEWORK} - ${FOUNDATION_FRAMEWORK} - ${QUARTZCORE_FRAMEWORK} + target_link_libraries( + imgui + PUBLIC + ${METAL_FRAMEWORK} + ${FOUNDATION_FRAMEWORK} + ${QUARTZCORE_FRAMEWORK} ) endif() -set_target_properties( - imgui - PROPERTIES - CXX_VISIBILITY_PRESET default - VISIBILITY_INLINES_HIDDEN OFF - VERSION 1.92.9 - SOVERSION 1 -) +set_target_properties(imgui PROPERTIES VERSION 1.92.9 SOVERSION 1) target_link_libraries(${PROJECT_NAME} PRIVATE imgui) @@ -305,14 +328,7 @@ add_library(cimgui SHARED src/libs/cimgui/cimgui.cpp) target_include_directories(cimgui PUBLIC include/libs include/libs/cimgui) target_link_libraries(cimgui PUBLIC imgui) -set_target_properties( - cimgui - PROPERTIES - CXX_VISIBILITY_PRESET default - VISIBILITY_INLINES_HIDDEN OFF - VERSION 1 - SOVERSION 1 -) +set_target_properties(cimgui PROPERTIES VERSION 1 SOVERSION 1) # ----------------------------- # Tray library (integrated from its own CMakeLists.txt) @@ -465,12 +481,15 @@ target_include_directories( PRIVATE src/libs/nvdialog/impl/ ) -set_target_properties(nvdialog PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON) +set_target_properties( + nvdialog + PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON POSITION_INDEPENDENT_CODE ON +) if(WIN32) target_link_libraries( nvdialog - PRIVATE comdlg32 shell32 user32 gdi32 ole32 + PUBLIC comdlg32 shell32 user32 gdi32 ole32 ) elseif(APPLE) target_compile_definitions(nvdialog PRIVATE NVD_USE_COCOA=1) @@ -558,10 +577,10 @@ target_link_libraries(${PROJECT_NAME} PRIVATE tiny-process-library) # Install # ----------------------------- -add_dependencies(${PROJECT_NAME} cimgui imgui) +add_dependencies(${PROJECT_NAME} cimgui imgui oshot_plugin) install( - TARGETS ${PROJECT_NAME} imgui cimgui + TARGETS ${PROJECT_NAME} imgui cimgui oshot_plugin RUNTIME DESTINATION bin COMPONENT runtime LIBRARY DESTINATION lib COMPONENT runtime ) diff --git a/src/plugins.cpp b/src/plugins.cpp index 611ee00..8568a43 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -28,13 +28,13 @@ void load_plugins() if (!plugin || plugin->abi_version != oshot_get_abi_version()) { - spdlog::critical("Plugin '{}' has incompatible ABI version, skipping", entry.path().stem().string()); + spdlog::error("Plugin '{}' has incompatible ABI version, skipping", entry.path().stem().string()); continue; } if (!plugin->render || !plugin->id || !plugin->name || plugin->name[0] == '\0') { - spdlog::critical("Plugin '{}' doesn't define name/ID or render function", entry.path().stem().string()); + spdlog::error("Plugin '{}' doesn't define name/ID or render function", entry.path().stem().string()); continue; } @@ -43,7 +43,7 @@ void load_plugins() return (isalnum(c) || c == '-' || c == '_' || c == '=' || c == '.'); })) { - spdlog::critical("Plugin '{}' has an invalid ID", plugin->id); + spdlog::error("Plugin '{}' has an invalid ID", plugin->id); continue; } @@ -51,7 +51,7 @@ void load_plugins() return (isalnum(c) || c == '-' || c == '_' || c == '=' || c == ' '); })) { - spdlog::critical("Plugin '{}' contains chars other than -_= or alpha numerical", plugin->id); + spdlog::error("Plugin '{}' contains chars other than -_= or alpha numerical", plugin->id); continue; } diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h index 6a3d543..80e8b59 100644 --- a/src/plugins/oshot_plugin.h +++ b/src/plugins/oshot_plugin.h @@ -105,8 +105,8 @@ void oshot_log(OSLogLevel lvl, oshot_str_t str); void oshot_debug(oshot_str_t str); // oshot_log(DEBUG, str); // convinience ig -void oshot_log_s(OSLogLevel lvl, const char* str); -void oshot_debug_s(const char* str); // oshot_log(DEBUG, str); +void oshot_logs(OSLogLevel lvl, const char* str); +void oshot_debugs(const char* str); // oshot_log(DEBUG, str); /* ------------------------------------------------------------------ * Config (plugin namespace only) diff --git a/src/plugins/oshot_plugins.cpp b/src/plugins/oshot_plugins.cpp index b4b498c..f2c12c6 100644 --- a/src/plugins/oshot_plugins.cpp +++ b/src/plugins/oshot_plugins.cpp @@ -57,14 +57,14 @@ void oshot_debug(oshot_str_t str) oshot_log(OSLogLevel::OSHOT_LOG_DEBUG, std::move(str)); } -void oshot_log_s(OSLogLevel lvl, const char* str) +void oshot_logs(OSLogLevel lvl, const char* str) { oshot_str_t s = oshot_str_new(str, strlen(str)); oshot_log(lvl, s); oshot_str_free(&s); } -void oshot_debug_s(const char* str) +void oshot_debugs(const char* str) { oshot_str_t s = oshot_str_new(str, strlen(str)); oshot_debug(s); From 184b764cbafb7e32f68682f2b6506e150cbf1612 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 3 Jul 2026 19:54:41 +0200 Subject: [PATCH 20/40] build: separate oshot common code into its own liboshot_common.a hope this fixes all macos and windows builds :sob: --- CMakeLists.txt | 262 +- include/libs/spdlog/fmt/bundled/args.h | 220 - include/libs/spdlog/fmt/bundled/base.h | 3010 ----------- include/libs/spdlog/fmt/bundled/chrono.h | 2246 --------- include/libs/spdlog/fmt/bundled/color.h | 637 --- include/libs/spdlog/fmt/bundled/compile.h | 588 --- include/libs/spdlog/fmt/bundled/core.h | 5 - .../libs/spdlog/fmt/bundled/fmt.license.rst | 27 - include/libs/spdlog/fmt/bundled/format-inl.h | 1948 -------- include/libs/spdlog/fmt/bundled/format.h | 4395 ----------------- include/libs/spdlog/fmt/bundled/os.h | 427 -- include/libs/spdlog/fmt/bundled/ostream.h | 167 - include/libs/spdlog/fmt/bundled/printf.h | 624 --- include/libs/spdlog/fmt/bundled/ranges.h | 851 ---- include/libs/spdlog/fmt/bundled/std.h | 727 --- include/libs/spdlog/fmt/bundled/xchar.h | 356 -- include/libs/spdlog/tweakme.h | 2 +- include/util.hpp | 20 +- src/globals.cpp | 18 + src/main.cpp | 13 - src/main_tool_metal.mm | 13 +- src/main_tool_opengl3.cpp | 14 +- src/plugins.cpp | 3 +- src/screenshot_tool.cpp | 19 +- src/util.cpp | 32 + 25 files changed, 217 insertions(+), 16407 deletions(-) delete mode 100644 include/libs/spdlog/fmt/bundled/args.h delete mode 100644 include/libs/spdlog/fmt/bundled/base.h delete mode 100644 include/libs/spdlog/fmt/bundled/chrono.h delete mode 100644 include/libs/spdlog/fmt/bundled/color.h delete mode 100644 include/libs/spdlog/fmt/bundled/compile.h delete mode 100644 include/libs/spdlog/fmt/bundled/core.h delete mode 100644 include/libs/spdlog/fmt/bundled/fmt.license.rst delete mode 100644 include/libs/spdlog/fmt/bundled/format-inl.h delete mode 100644 include/libs/spdlog/fmt/bundled/format.h delete mode 100644 include/libs/spdlog/fmt/bundled/os.h delete mode 100644 include/libs/spdlog/fmt/bundled/ostream.h delete mode 100644 include/libs/spdlog/fmt/bundled/printf.h delete mode 100644 include/libs/spdlog/fmt/bundled/ranges.h delete mode 100644 include/libs/spdlog/fmt/bundled/std.h delete mode 100644 include/libs/spdlog/fmt/bundled/xchar.h create mode 100644 src/globals.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index aa4ba7d..f9a7ec7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,14 @@ endif() set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") +# GCC/Clang default Release flags already include -O3; this just makes it +# explicit. Guarded because "-O3" is not a valid cl.exe switch and would +# otherwise spam D9002 (or hard-fail under /WX) on MSVC builds. +if(NOT MSVC) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") +endif() # LTO helper function(enable_lto target) @@ -31,6 +37,12 @@ function(enable_lto target) endfunction() # https://github.com/libcpr/cpr/blob/5f475522597b8f3721e2440daddeced7a969f24c/CMakeLists.txt#L39 +# NOTE: definitions are collected into OSHOT_OPTION_DEFINITIONS instead of +# using add_definitions(), which is directory-scoped and would otherwise leak +# into every target declared afterward -- including vendored third-party +# libs (fmt, imgui, tray, clip, dylib, nvdialog, tiny-process-library). +# They're applied to just ${PROJECT_NAME} once it exists (see below). +set(OSHOT_OPTION_DEFINITIONS "") macro(add_option OPTION_NAME OPTION_TEXT OPTION_DEFAULT DEFINE_OPTION) option(${OPTION_NAME} ${OPTION_TEXT} ${OPTION_DEFAULT}) if(DEFINED ENV{${OPTION_NAME}}) @@ -38,7 +50,7 @@ macro(add_option OPTION_NAME OPTION_TEXT OPTION_DEFAULT DEFINE_OPTION) set(${OPTION_NAME} $ENV{${OPTION_NAME}}) endif() if(${OPTION_NAME} AND DEFINE_OPTION) - add_definitions(-D${OPTION_NAME}=1) + list(APPEND OSHOT_OPTION_DEFINITIONS ${OPTION_NAME}=1) endif() message(STATUS " ${OPTION_NAME}: ${${OPTION_NAME}}") endmacro() @@ -65,9 +77,9 @@ else() endif() find_package(OpenGL REQUIRED) -pkg_check_modules(TESSERACT REQUIRED tesseract) -pkg_check_modules(LEPTONICA REQUIRED lept) -pkg_check_modules(ZBAR REQUIRED zbar) +pkg_check_modules(TESSERACT REQUIRED IMPORTED_TARGET tesseract) +pkg_check_modules(LEPTONICA REQUIRED IMPORTED_TARGET lept) +pkg_check_modules(ZBAR REQUIRED IMPORTED_TARGET zbar) # Homebrew's lept.pc points Cflags at .../include/leptonica directly (its # own convention is `#include `), but our code uses @@ -97,21 +109,34 @@ endif() # Main executable # ----------------------------- -file( - GLOB SRC - src/*.cpp - src/libs/toml++/toml.cpp +add_executable( + ${PROJECT_NAME} + src/main.cpp + src/main_tool_opengl3.cpp src/libs/getopt_port/getopt.c - src/libs/tinyfiledialogs/tinyfiledialogs.c ) - -add_executable(${PROJECT_NAME} ${SRC}) enable_lto(${PROJECT_NAME}) execute_process( COMMAND ./scripts/generateVersion.sh WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE OSHOT_VERSION_SCRIPT_RESULT ) +if(NOT OSHOT_VERSION_SCRIPT_RESULT EQUAL 0) + message( + WARNING + "scripts/generateVersion.sh failed or is unavailable " + "(exit ${OSHOT_VERSION_SCRIPT_RESULT}); generated version info may be stale or missing. " + "Note this script also won't run on a native Windows shell without sh on PATH (e.g. Git Bash/MSYS)." + ) +endif() + +if(OSHOT_OPTION_DEFINITIONS) + target_compile_definitions( + ${PROJECT_NAME} + PRIVATE ${OSHOT_OPTION_DEFINITIONS} + ) +endif() target_compile_definitions(${PROJECT_NAME} PRIVATE $<$:DEBUG=1>) target_compile_options( @@ -120,75 +145,65 @@ target_compile_options( $<$:-ggdb3;-fno-omit-frame-pointer;-Wall;-Wextra;-pedantic;-Wno-unused-parameter> ) -target_compile_definitions( - ${PROJECT_NAME} - PRIVATE VERSION="${PROJECT_VERSION}" TOML_HEADER_ONLY=0 -) +add_dependencies(${PROJECT_NAME} oshot_common oshot_plugin) -target_include_directories( - ${PROJECT_NAME} - PRIVATE - include/ - include/libs - ${TESSERACT_INCLUDE_DIRS} - ${LEPTONICA_INCLUDE_DIRS} - ${ZBAR_INCLUDE_DIRS} -) +target_link_libraries(${PROJECT_NAME} PRIVATE oshot_common oshot_plugin) -if(UNIX AND NOT APPLE) - target_include_directories( - ${PROJECT_NAME} - PRIVATE ${APPINDICATOR_INCLUDE_DIRS} - ) - target_compile_options(${PROJECT_NAME} PRIVATE ${APPINDICATOR_CFLAGS_OTHER}) +if(WIN32 AND NOT WINDOWS_CMD) + set_target_properties(${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE TRUE) endif() -target_compile_options( - ${PROJECT_NAME} - PRIVATE - ${TESSERACT_CFLAGS_OTHER} - ${LEPTONICA_CFLAGS_OTHER} - ${ZBAR_CFLAGS_OTHER} -) +if(APPLE) + target_sources(${PROJECT_NAME} PRIVATE src/main_tool_metal.mm) + set(_rpath_origin "@loader_path") +else() + set(_rpath_origin "$ORIGIN") +endif() -target_link_directories( +set_target_properties( ${PROJECT_NAME} - PRIVATE - ${TESSERACT_LIBRARY_DIRS} - ${LEPTONICA_LIBRARY_DIRS} - ${ZBAR_LIBRARY_DIRS} + PROPERTIES + BUILD_RPATH "${_rpath_origin}/../lib;$" + INSTALL_RPATH "${_rpath_origin}/../lib" ) -target_link_libraries( - ${PROJECT_NAME} - PRIVATE - OpenGL::GL - ${GLFW_TARGET} - ${TESSERACT_LIBRARIES} - ${LEPTONICA_LIBRARIES} - ${ZBAR_LIBRARIES} +# ----------------------------- +# Common library for shared code +# ----------------------------- +add_library( + oshot_common + STATIC + src/cache.cpp + src/clipboard.cpp + src/config.cpp + src/globals.cpp + src/plugins.cpp + src/screen_capture.cpp + src/screenshot_tool.cpp + src/text_extraction.cpp + src/util.cpp + src/libs/toml++/toml.cpp + src/libs/tinyfiledialogs/tinyfiledialogs.c ) -if(WIN32) - target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32 shcore d3d11 dxgi) +enable_lto(oshot_common) - if(NOT WINDOWS_CMD) - set_target_properties(${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE TRUE) +if(WIN32) + target_link_libraries(oshot_common PRIVATE ws2_32 shcore d3d11 dxgi) + if(MINGW) + target_link_options(${PROJECT_NAME} PRIVATE -Wl,--export-all-symbols) endif() elseif(APPLE) target_compile_options( - ${PROJECT_NAME} + oshot_common PRIVATE -fobjc-arc $<$:-stdlib=libc++> ) - - # Add Metal render loop source - target_sources(${PROJECT_NAME} PRIVATE src/main_tool_metal.mm) target_link_options( - ${PROJECT_NAME} + oshot_common PRIVATE $<$:-stdlib=libc++> ) target_link_libraries( - ${PROJECT_NAME} + oshot_common PRIVATE "-framework Metal" "-framework QuartzCore" @@ -197,77 +212,88 @@ elseif(APPLE) "-framework IOKit" "-framework OpenGL" ) -elseif(UNIX) - target_link_libraries(${PROJECT_NAME} PRIVATE X11::X11) +else() target_include_directories( - ${PROJECT_NAME} + oshot_common + PRIVATE ${APPINDICATOR_INCLUDE_DIRS} + ) + target_compile_options(oshot_common PRIVATE ${APPINDICATOR_CFLAGS_OTHER}) + + target_link_libraries(oshot_common PRIVATE X11::X11) + target_include_directories( + oshot_common PRIVATE SYSTEM ${GIO_INCLUDE_DIRS} ${XRANDR_INCLUDE_DIRS} ) target_link_libraries( - ${PROJECT_NAME} + oshot_common PRIVATE ${GIO_LIBRARIES} ${XRANDR_LIBRARIES} ) target_compile_options( - ${PROJECT_NAME} + oshot_common PRIVATE ${GIO_CFLAGS_OTHER} ${XRANDR_CFLAGS_OTHER} ) endif() -if(APPLE) - set(_rpath_origin "@loader_path") -else() - set(_rpath_origin "$ORIGIN") -endif() +target_link_libraries( + oshot_common + PUBLIC + fmt + imgui + tray + clip + dylib + nvdialog + tiny-process-library + PkgConfig::TESSERACT + PkgConfig::LEPTONICA + PkgConfig::ZBAR + OpenGL::GL + ${GLFW_TARGET} + PRIVATE Threads::Threads +) +target_compile_definitions( + oshot_common + PUBLIC VERSION="${PROJECT_VERSION}" TOML_HEADER_ONLY=0 +) -set_target_properties( - ${PROJECT_NAME} - PROPERTIES - BUILD_RPATH "${_rpath_origin}/../lib;$" - INSTALL_RPATH "${_rpath_origin}/../lib" +# NOTE: PkgConfig::TESSERACT / PkgConfig::ZBAR already propagate their own +# include dirs, link dirs, and compile options as usage requirements via +# target_link_libraries() above -- no need to add TESSERACT_*/ZBAR_* here too. +# LEPTONICA_INCLUDE_DIRS is the one exception: it was patched earlier in this +# file to add the parent directory for Homebrew's lept.pc convention, which +# PkgConfig::LEPTONICA's own interface include dirs don't have. +target_include_directories( + oshot_common + PUBLIC + include/ + include/libs + ${LEPTONICA_INCLUDE_DIRS} ) +target_compile_features(oshot_common PUBLIC cxx_std_20) + # ----------------------------- # oshot's plugin library # ----------------------------- -add_library( - oshot_plugin - SHARED - src/plugins/oshot_plugins.cpp - src/libs/toml++/toml.cpp -) +add_library(oshot_plugin SHARED src/plugins/oshot_plugins.cpp) -enable_lto(oshot_plugin) +add_dependencies(oshot_plugin oshot_common) target_include_directories(oshot_plugin PUBLIC include/ include/libs) -target_include_directories( - oshot_plugin - PRIVATE - ${TESSERACT_INCLUDE_DIRS} - ${LEPTONICA_INCLUDE_DIRS} - ${ZBAR_INCLUDE_DIRS} -) -target_compile_definitions(oshot_plugin PRIVATE VERSION="${PROJECT_VERSION}") + target_compile_features(oshot_plugin PUBLIC cxx_std_20) -target_link_libraries(oshot_plugin PUBLIC fmt) -target_link_libraries( - oshot_plugin - PRIVATE - nvdialog - ${TESSERACT_LIBRARIES} - ${LEPTONICA_LIBRARIES} - ${ZBAR_LIBRARIES} -) +target_link_libraries(oshot_plugin PUBLIC oshot_common) + +# Everything else is inherited from oshot_common set_target_properties( oshot_plugin PROPERTIES VERSION 1 SOVERSION 1 WINDOWS_EXPORT_ALL_SYMBOLS ON ) -target_link_libraries(${PROJECT_NAME} PRIVATE oshot_plugin) - # ----------------------------- # fmt library # ----------------------------- @@ -279,9 +305,6 @@ enable_lto(fmt) target_include_directories(fmt PUBLIC include/libs) target_compile_features(fmt PUBLIC cxx_std_20) target_compile_definitions(fmt PUBLIC FMT_HEADER_ONLY=0) -set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE ON) - -target_link_libraries(${PROJECT_NAME} PRIVATE fmt) # ----------------------------- # imgui library @@ -318,8 +341,6 @@ endif() set_target_properties(imgui PROPERTIES VERSION 1.92.9 SOVERSION 1) -target_link_libraries(${PROJECT_NAME} PRIVATE imgui) - # ----------------------------- # cimgui library (C-ABI plugins only) # ----------------------------- @@ -387,12 +408,6 @@ endif() target_include_directories(tray PUBLIC include/libs) target_compile_features(tray PRIVATE cxx_std_20) -set_target_properties( - tray - PROPERTIES CXX_STANDARD 20 CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON -) - -target_link_libraries(${PROJECT_NAME} PRIVATE tray) # ----------------------------- # clip library (integrated from its own CMakeLists.txt) @@ -425,12 +440,6 @@ endif() target_include_directories(clip PUBLIC include/libs/clip) target_compile_features(clip PRIVATE cxx_std_20) target_compile_definitions(clip PUBLIC CLIP_ENABLE_IMAGE=1) -set_target_properties( - clip - PROPERTIES CXX_STANDARD 20 CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON -) - -target_link_libraries(${PROJECT_NAME} PRIVATE clip) # ----------------------------- # dylib library (integrated from its own CMakeLists.txt) @@ -445,12 +454,6 @@ endif() target_include_directories(dylib PUBLIC include/libs/) target_compile_features(dylib PRIVATE cxx_std_20) -set_target_properties( - dylib - PROPERTIES CXX_STANDARD 20 CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON -) - -target_link_libraries(${PROJECT_NAME} PRIVATE dylib) # ----------------------------- # nvdialog (integrated from its own CMakeLists.txt) @@ -483,7 +486,7 @@ target_include_directories( set_target_properties( nvdialog - PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON POSITION_INDEPENDENT_CODE ON + PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON ) if(WIN32) @@ -519,8 +522,6 @@ else() target_link_libraries(nvdialog PRIVATE ${GTK_LIBRARIES} ${DBUS_LIBRARIES}) endif() -target_link_libraries(${PROJECT_NAME} PRIVATE nvdialog) - # ----------------------------- # tiny-process-library (integrated from its own CMakeLists.txt) # ----------------------------- @@ -546,7 +547,6 @@ else() endif() if(WIN32) - set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) target_sources( tiny-process-library PRIVATE "src/libs/tiny-process-library/process_win.cpp" @@ -565,13 +565,12 @@ else() ) endif() -target_link_libraries(tiny-process-library Threads::Threads) +target_link_libraries(tiny-process-library PUBLIC Threads::Threads) target_include_directories( tiny-process-library PUBLIC include/libs/tiny-process-library ) enable_lto(tiny-process-library) -target_link_libraries(${PROJECT_NAME} PRIVATE tiny-process-library) # ----------------------------- # Install @@ -583,6 +582,7 @@ install( TARGETS ${PROJECT_NAME} imgui cimgui oshot_plugin RUNTIME DESTINATION bin COMPONENT runtime LIBRARY DESTINATION lib COMPONENT runtime + ARCHIVE DESTINATION lib COMPONENT runtime ) install( diff --git a/include/libs/spdlog/fmt/bundled/args.h b/include/libs/spdlog/fmt/bundled/args.h deleted file mode 100644 index 5e5f40f..0000000 --- a/include/libs/spdlog/fmt/bundled/args.h +++ /dev/null @@ -1,220 +0,0 @@ -// Formatting library for C++ - dynamic argument lists -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_ARGS_H_ -#define FMT_ARGS_H_ - -#ifndef FMT_MODULE -# include // std::reference_wrapper -# include // std::unique_ptr -# include -#endif - -#include "format.h" // std_string_view - -FMT_BEGIN_NAMESPACE -namespace detail { - -template struct is_reference_wrapper : std::false_type {}; -template -struct is_reference_wrapper> : std::true_type {}; - -template auto unwrap(const T& v) -> const T& { return v; } -template -auto unwrap(const std::reference_wrapper& v) -> const T& { - return static_cast(v); -} - -// node is defined outside dynamic_arg_list to workaround a C2504 bug in MSVC -// 2022 (v17.10.0). -// -// Workaround for clang's -Wweak-vtables. Unlike for regular classes, for -// templates it doesn't complain about inability to deduce single translation -// unit for placing vtable. So node is made a fake template. -template struct node { - virtual ~node() = default; - std::unique_ptr> next; -}; - -class dynamic_arg_list { - template struct typed_node : node<> { - T value; - - template - FMT_CONSTEXPR typed_node(const Arg& arg) : value(arg) {} - - template - FMT_CONSTEXPR typed_node(const basic_string_view& arg) - : value(arg.data(), arg.size()) {} - }; - - std::unique_ptr> head_; - - public: - template auto push(const Arg& arg) -> const T& { - auto new_node = std::unique_ptr>(new typed_node(arg)); - auto& value = new_node->value; - new_node->next = std::move(head_); - head_ = std::move(new_node); - return value; - } -}; -} // namespace detail - -/** - * A dynamic list of formatting arguments with storage. - * - * It can be implicitly converted into `fmt::basic_format_args` for passing - * into type-erased formatting functions such as `fmt::vformat`. - */ -FMT_EXPORT template class dynamic_format_arg_store { - private: - using char_type = typename Context::char_type; - - template struct need_copy { - static constexpr detail::type mapped_type = - detail::mapped_type_constant::value; - - enum { - value = !(detail::is_reference_wrapper::value || - std::is_same>::value || - std::is_same>::value || - (mapped_type != detail::type::cstring_type && - mapped_type != detail::type::string_type && - mapped_type != detail::type::custom_type)) - }; - }; - - template - using stored_t = conditional_t< - std::is_convertible>::value && - !detail::is_reference_wrapper::value, - std::basic_string, T>; - - // Storage of basic_format_arg must be contiguous. - std::vector> data_; - std::vector> named_info_; - - // Storage of arguments not fitting into basic_format_arg must grow - // without relocation because items in data_ refer to it. - detail::dynamic_arg_list dynamic_args_; - - friend class basic_format_args; - - auto data() const -> const basic_format_arg* { - return named_info_.empty() ? data_.data() : data_.data() + 1; - } - - template void emplace_arg(const T& arg) { - data_.emplace_back(arg); - } - - template - void emplace_arg(const detail::named_arg& arg) { - if (named_info_.empty()) - data_.insert(data_.begin(), basic_format_arg(nullptr, 0)); - data_.emplace_back(detail::unwrap(arg.value)); - auto pop_one = [](std::vector>* data) { - data->pop_back(); - }; - std::unique_ptr>, decltype(pop_one)> - guard{&data_, pop_one}; - named_info_.push_back({arg.name, static_cast(data_.size() - 2u)}); - data_[0] = {named_info_.data(), named_info_.size()}; - guard.release(); - } - - public: - constexpr dynamic_format_arg_store() = default; - - operator basic_format_args() const { - return basic_format_args(data(), static_cast(data_.size()), - !named_info_.empty()); - } - - /** - * Adds an argument into the dynamic store for later passing to a formatting - * function. - * - * Note that custom types and string types (but not string views) are copied - * into the store dynamically allocating memory if necessary. - * - * **Example**: - * - * fmt::dynamic_format_arg_store store; - * store.push_back(42); - * store.push_back("abc"); - * store.push_back(1.5f); - * std::string result = fmt::vformat("{} and {} and {}", store); - */ - template void push_back(const T& arg) { - if (detail::const_check(need_copy::value)) - emplace_arg(dynamic_args_.push>(arg)); - else - emplace_arg(detail::unwrap(arg)); - } - - /** - * Adds a reference to the argument into the dynamic store for later passing - * to a formatting function. - * - * **Example**: - * - * fmt::dynamic_format_arg_store store; - * char band[] = "Rolling Stones"; - * store.push_back(std::cref(band)); - * band[9] = 'c'; // Changing str affects the output. - * std::string result = fmt::vformat("{}", store); - * // result == "Rolling Scones" - */ - template void push_back(std::reference_wrapper arg) { - static_assert( - need_copy::value, - "objects of built-in types and string views are always copied"); - emplace_arg(arg.get()); - } - - /** - * Adds named argument into the dynamic store for later passing to a - * formatting function. `std::reference_wrapper` is supported to avoid - * copying of the argument. The name is always copied into the store. - */ - template - void push_back(const detail::named_arg& arg) { - const char_type* arg_name = - dynamic_args_.push>(arg.name).c_str(); - if (detail::const_check(need_copy::value)) { - emplace_arg( - fmt::arg(arg_name, dynamic_args_.push>(arg.value))); - } else { - emplace_arg(fmt::arg(arg_name, arg.value)); - } - } - - /// Erase all elements from the store. - void clear() { - data_.clear(); - named_info_.clear(); - dynamic_args_ = {}; - } - - /// Reserves space to store at least `new_cap` arguments including - /// `new_cap_named` named arguments. - void reserve(size_t new_cap, size_t new_cap_named) { - FMT_ASSERT(new_cap >= new_cap_named, - "set of arguments includes set of named arguments"); - data_.reserve(new_cap); - named_info_.reserve(new_cap_named); - } - - /// Returns the number of elements in the store. - auto size() const noexcept -> size_t { return data_.size(); } -}; - -FMT_END_NAMESPACE - -#endif // FMT_ARGS_H_ diff --git a/include/libs/spdlog/fmt/bundled/base.h b/include/libs/spdlog/fmt/bundled/base.h deleted file mode 100644 index 620456b..0000000 --- a/include/libs/spdlog/fmt/bundled/base.h +++ /dev/null @@ -1,3010 +0,0 @@ -// Formatting library for C++ - the base API for char/UTF-8 -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_BASE_H_ -#define FMT_BASE_H_ - -#if defined(FMT_IMPORT_STD) && !defined(FMT_MODULE) -# define FMT_MODULE -#endif - -#ifndef FMT_MODULE -# include // CHAR_BIT -# include // FILE -# include // memcmp - -# include // std::enable_if -#endif - -// The fmt library version in the form major * 10000 + minor * 100 + patch. -#define FMT_VERSION 120100 - -// Detect compiler versions. -#if defined(__clang__) && !defined(__ibmxl__) -# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) -#else -# define FMT_CLANG_VERSION 0 -#endif -#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) -# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) -#else -# define FMT_GCC_VERSION 0 -#endif -#if defined(__ICL) -# define FMT_ICC_VERSION __ICL -#elif defined(__INTEL_COMPILER) -# define FMT_ICC_VERSION __INTEL_COMPILER -#else -# define FMT_ICC_VERSION 0 -#endif -#if defined(_MSC_VER) -# define FMT_MSC_VERSION _MSC_VER -#else -# define FMT_MSC_VERSION 0 -#endif - -// Detect standard library versions. -#ifdef _GLIBCXX_RELEASE -# define FMT_GLIBCXX_RELEASE _GLIBCXX_RELEASE -#else -# define FMT_GLIBCXX_RELEASE 0 -#endif -#ifdef _LIBCPP_VERSION -# define FMT_LIBCPP_VERSION _LIBCPP_VERSION -#else -# define FMT_LIBCPP_VERSION 0 -#endif - -#ifdef _MSVC_LANG -# define FMT_CPLUSPLUS _MSVC_LANG -#else -# define FMT_CPLUSPLUS __cplusplus -#endif - -// Detect __has_*. -#ifdef __has_feature -# define FMT_HAS_FEATURE(x) __has_feature(x) -#else -# define FMT_HAS_FEATURE(x) 0 -#endif -#ifdef __has_include -# define FMT_HAS_INCLUDE(x) __has_include(x) -#else -# define FMT_HAS_INCLUDE(x) 0 -#endif -#ifdef __has_builtin -# define FMT_HAS_BUILTIN(x) __has_builtin(x) -#else -# define FMT_HAS_BUILTIN(x) 0 -#endif -#ifdef __has_cpp_attribute -# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) -#else -# define FMT_HAS_CPP_ATTRIBUTE(x) 0 -#endif - -#define FMT_HAS_CPP14_ATTRIBUTE(attribute) \ - (FMT_CPLUSPLUS >= 201402L && FMT_HAS_CPP_ATTRIBUTE(attribute)) - -#define FMT_HAS_CPP17_ATTRIBUTE(attribute) \ - (FMT_CPLUSPLUS >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute)) - -// Detect C++14 relaxed constexpr. -#ifdef FMT_USE_CONSTEXPR -// Use the provided definition. -#elif FMT_GCC_VERSION >= 702 && FMT_CPLUSPLUS >= 201402L -// GCC only allows constexpr member functions in non-literal types since 7.2: -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66297. -# define FMT_USE_CONSTEXPR 1 -#elif FMT_ICC_VERSION -# define FMT_USE_CONSTEXPR 0 // https://github.com/fmtlib/fmt/issues/1628 -#elif FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VERSION >= 1912 -# define FMT_USE_CONSTEXPR 1 -#else -# define FMT_USE_CONSTEXPR 0 -#endif -#if FMT_USE_CONSTEXPR -# define FMT_CONSTEXPR constexpr -#else -# define FMT_CONSTEXPR -#endif - -// Detect consteval, C++20 constexpr extensions and std::is_constant_evaluated. -#ifdef FMT_USE_CONSTEVAL -// Use the provided definition. -#elif !defined(__cpp_lib_is_constant_evaluated) -# define FMT_USE_CONSTEVAL 0 -#elif FMT_CPLUSPLUS < 201709L -# define FMT_USE_CONSTEVAL 0 -#elif FMT_GLIBCXX_RELEASE && FMT_GLIBCXX_RELEASE < 10 -# define FMT_USE_CONSTEVAL 0 -#elif FMT_LIBCPP_VERSION && FMT_LIBCPP_VERSION < 10000 -# define FMT_USE_CONSTEVAL 0 -#elif defined(__apple_build_version__) && __apple_build_version__ < 14000029L -# define FMT_USE_CONSTEVAL 0 // consteval is broken in Apple clang < 14. -#elif FMT_MSC_VERSION && FMT_MSC_VERSION < 1929 -# define FMT_USE_CONSTEVAL 0 // consteval is broken in MSVC VS2019 < 16.10. -#elif defined(__cpp_consteval) -# define FMT_USE_CONSTEVAL 1 -#elif FMT_GCC_VERSION >= 1002 || FMT_CLANG_VERSION >= 1101 -# define FMT_USE_CONSTEVAL 1 -#else -# define FMT_USE_CONSTEVAL 0 -#endif -#if FMT_USE_CONSTEVAL -# define FMT_CONSTEVAL consteval -# define FMT_CONSTEXPR20 constexpr -#else -# define FMT_CONSTEVAL -# define FMT_CONSTEXPR20 -#endif - -// Check if exceptions are disabled. -#ifdef FMT_USE_EXCEPTIONS -// Use the provided definition. -#elif defined(__GNUC__) && !defined(__EXCEPTIONS) -# define FMT_USE_EXCEPTIONS 0 -#elif defined(__clang__) && !defined(__cpp_exceptions) -# define FMT_USE_EXCEPTIONS 0 -#elif FMT_MSC_VERSION && !_HAS_EXCEPTIONS -# define FMT_USE_EXCEPTIONS 0 -#else -# define FMT_USE_EXCEPTIONS 1 -#endif -#if FMT_USE_EXCEPTIONS -# define FMT_TRY try -# define FMT_CATCH(x) catch (x) -#else -# define FMT_TRY if (true) -# define FMT_CATCH(x) if (false) -#endif - -#ifdef FMT_NO_UNIQUE_ADDRESS -// Use the provided definition. -#elif FMT_CPLUSPLUS < 202002L -// Not supported. -#elif FMT_HAS_CPP_ATTRIBUTE(no_unique_address) -# define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]] -// VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485). -#elif FMT_MSC_VERSION >= 1929 && !FMT_CLANG_VERSION -# define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] -#endif -#ifndef FMT_NO_UNIQUE_ADDRESS -# define FMT_NO_UNIQUE_ADDRESS -#endif - -#if FMT_HAS_CPP17_ATTRIBUTE(fallthrough) -# define FMT_FALLTHROUGH [[fallthrough]] -#elif defined(__clang__) -# define FMT_FALLTHROUGH [[clang::fallthrough]] -#elif FMT_GCC_VERSION >= 700 && \ - (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520) -# define FMT_FALLTHROUGH [[gnu::fallthrough]] -#else -# define FMT_FALLTHROUGH -#endif - -// Disable [[noreturn]] on MSVC/NVCC because of bogus unreachable code warnings. -#if FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VERSION && !defined(__NVCC__) -# define FMT_NORETURN [[noreturn]] -#else -# define FMT_NORETURN -#endif - -#ifdef FMT_NODISCARD -// Use the provided definition. -#elif FMT_HAS_CPP17_ATTRIBUTE(nodiscard) -# define FMT_NODISCARD [[nodiscard]] -#else -# define FMT_NODISCARD -#endif - -#if FMT_GCC_VERSION || FMT_CLANG_VERSION -# define FMT_VISIBILITY(value) __attribute__((visibility(value))) -#else -# define FMT_VISIBILITY(value) -#endif - -// Detect pragmas. -#define FMT_PRAGMA_IMPL(x) _Pragma(#x) -#if FMT_GCC_VERSION >= 504 && !defined(__NVCOMPILER) -// Workaround a _Pragma bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59884 -// and an nvhpc warning: https://github.com/fmtlib/fmt/pull/2582. -# define FMT_PRAGMA_GCC(x) FMT_PRAGMA_IMPL(GCC x) -#else -# define FMT_PRAGMA_GCC(x) -#endif -#if FMT_CLANG_VERSION -# define FMT_PRAGMA_CLANG(x) FMT_PRAGMA_IMPL(clang x) -#else -# define FMT_PRAGMA_CLANG(x) -#endif -#if FMT_MSC_VERSION -# define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__)) -#else -# define FMT_MSC_WARNING(...) -#endif - -// Enable minimal optimizations for more compact code in debug mode. -FMT_PRAGMA_GCC(push_options) -#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE) -FMT_PRAGMA_GCC(optimize("Og")) -# define FMT_GCC_OPTIMIZED -#endif -FMT_PRAGMA_CLANG(diagnostic push) -FMT_PRAGMA_GCC(diagnostic push) - -#ifdef FMT_ALWAYS_INLINE -// Use the provided definition. -#elif FMT_GCC_VERSION || FMT_CLANG_VERSION -# define FMT_ALWAYS_INLINE inline __attribute__((always_inline)) -#else -# define FMT_ALWAYS_INLINE inline -#endif -// A version of FMT_ALWAYS_INLINE to prevent code bloat in debug mode. -#if defined(NDEBUG) || defined(FMT_GCC_OPTIMIZED) -# define FMT_INLINE FMT_ALWAYS_INLINE -#else -# define FMT_INLINE inline -#endif - -#ifndef FMT_BEGIN_NAMESPACE -# define FMT_BEGIN_NAMESPACE \ - namespace fmt { \ - inline namespace v12 { -# define FMT_END_NAMESPACE \ - } \ - } -#endif - -#ifndef FMT_EXPORT -# define FMT_EXPORT -# define FMT_BEGIN_EXPORT -# define FMT_END_EXPORT -#endif - -#ifdef _WIN32 -# define FMT_WIN32 1 -#else -# define FMT_WIN32 0 -#endif - -#if !defined(FMT_HEADER_ONLY) && FMT_WIN32 -# if defined(FMT_LIB_EXPORT) -# define FMT_API __declspec(dllexport) -# elif defined(FMT_SHARED) -# define FMT_API __declspec(dllimport) -# endif -#elif defined(FMT_LIB_EXPORT) || defined(FMT_SHARED) -# define FMT_API FMT_VISIBILITY("default") -#endif -#ifndef FMT_API -# define FMT_API -#endif - -#ifndef FMT_OPTIMIZE_SIZE -# define FMT_OPTIMIZE_SIZE 0 -#endif - -// FMT_BUILTIN_TYPE=0 may result in smaller library size at the cost of higher -// per-call binary size by passing built-in types through the extension API. -#ifndef FMT_BUILTIN_TYPES -# define FMT_BUILTIN_TYPES 1 -#endif - -#define FMT_APPLY_VARIADIC(expr) \ - using unused = int[]; \ - (void)unused { 0, (expr, 0)... } - -FMT_BEGIN_NAMESPACE - -// Implementations of enable_if_t and other metafunctions for older systems. -template -using enable_if_t = typename std::enable_if::type; -template -using conditional_t = typename std::conditional::type; -template using bool_constant = std::integral_constant; -template -using remove_reference_t = typename std::remove_reference::type; -template -using remove_const_t = typename std::remove_const::type; -template -using remove_cvref_t = typename std::remove_cv>::type; -template -using make_unsigned_t = typename std::make_unsigned::type; -template -using underlying_t = typename std::underlying_type::type; -template using decay_t = typename std::decay::type; -using nullptr_t = decltype(nullptr); - -#if (FMT_GCC_VERSION && FMT_GCC_VERSION < 500) || FMT_MSC_VERSION -// A workaround for gcc 4.9 & MSVC v141 to make void_t work in a SFINAE context. -template struct void_t_impl { - using type = void; -}; -template using void_t = typename void_t_impl::type; -#else -template using void_t = void; -#endif - -struct monostate { - constexpr monostate() {} -}; - -// An enable_if helper to be used in template parameters which results in much -// shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed -// to workaround a bug in MSVC 2019 (see #1140 and #1186). -#ifdef FMT_DOC -# define FMT_ENABLE_IF(...) -#else -# define FMT_ENABLE_IF(...) fmt::enable_if_t<(__VA_ARGS__), int> = 0 -#endif - -template constexpr auto min_of(T a, T b) -> T { - return a < b ? a : b; -} -template constexpr auto max_of(T a, T b) -> T { - return a > b ? a : b; -} - -FMT_NORETURN FMT_API void assert_fail(const char* file, int line, - const char* message); - -namespace detail { -// Suppresses "unused variable" warnings with the method described in -// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/. -// (void)var does not work on many Intel compilers. -template FMT_CONSTEXPR void ignore_unused(const T&...) {} - -constexpr auto is_constant_evaluated(bool default_value = false) noexcept - -> bool { -// Workaround for incompatibility between clang 14 and libstdc++ consteval-based -// std::is_constant_evaluated: https://github.com/fmtlib/fmt/issues/3247. -#if FMT_CPLUSPLUS >= 202002L && FMT_GLIBCXX_RELEASE >= 12 && \ - (FMT_CLANG_VERSION >= 1400 && FMT_CLANG_VERSION < 1500) - ignore_unused(default_value); - return __builtin_is_constant_evaluated(); -#elif defined(__cpp_lib_is_constant_evaluated) - ignore_unused(default_value); - return std::is_constant_evaluated(); -#else - return default_value; -#endif -} - -// Suppresses "conditional expression is constant" warnings. -template FMT_ALWAYS_INLINE constexpr auto const_check(T val) -> T { - return val; -} - -FMT_NORETURN FMT_API void assert_fail(const char* file, int line, - const char* message); - -#if defined(FMT_ASSERT) -// Use the provided definition. -#elif defined(NDEBUG) -// FMT_ASSERT is not empty to avoid -Wempty-body. -# define FMT_ASSERT(condition, message) \ - fmt::detail::ignore_unused((condition), (message)) -#else -# define FMT_ASSERT(condition, message) \ - ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \ - ? (void)0 \ - : ::fmt::assert_fail(__FILE__, __LINE__, (message))) -#endif - -#ifdef FMT_USE_INT128 -// Use the provided definition. -#elif defined(__SIZEOF_INT128__) && !defined(__NVCC__) && \ - !(FMT_CLANG_VERSION && FMT_MSC_VERSION) -# define FMT_USE_INT128 1 -using int128_opt = __int128_t; // An optional native 128-bit integer. -using uint128_opt = __uint128_t; -inline auto map(int128_opt x) -> int128_opt { return x; } -inline auto map(uint128_opt x) -> uint128_opt { return x; } -#else -# define FMT_USE_INT128 0 -#endif -#if !FMT_USE_INT128 -enum class int128_opt {}; -enum class uint128_opt {}; -// Reduce template instantiations. -inline auto map(int128_opt) -> monostate { return {}; } -inline auto map(uint128_opt) -> monostate { return {}; } -#endif - -#ifdef FMT_USE_BITINT -// Use the provided definition. -#elif FMT_CLANG_VERSION >= 1500 && !defined(__CUDACC__) -# define FMT_USE_BITINT 1 -#else -# define FMT_USE_BITINT 0 -#endif - -#if FMT_USE_BITINT -FMT_PRAGMA_CLANG(diagnostic ignored "-Wbit-int-extension") -template using bitint = _BitInt(N); -template using ubitint = unsigned _BitInt(N); -#else -template struct bitint {}; -template struct ubitint {}; -#endif // FMT_USE_BITINT - -// Casts a nonnegative integer to unsigned. -template -FMT_CONSTEXPR auto to_unsigned(Int value) -> make_unsigned_t { - FMT_ASSERT(std::is_unsigned::value || value >= 0, "negative value"); - return static_cast>(value); -} - -template -using unsigned_char = conditional_t; - -// A heuristic to detect std::string and std::[experimental::]string_view. -// It is mainly used to avoid dependency on <[experimental/]string_view>. -template -struct is_std_string_like : std::false_type {}; -template -struct is_std_string_like().find_first_of( - typename T::value_type(), 0))>> - : std::is_convertible().data()), - const typename T::value_type*> {}; - -// Check if the literal encoding is UTF-8. -enum { is_utf8_enabled = "\u00A7"[1] == '\xA7' }; -enum { use_utf8 = !FMT_WIN32 || is_utf8_enabled }; - -#ifndef FMT_UNICODE -# define FMT_UNICODE 1 -#endif - -static_assert(!FMT_UNICODE || use_utf8, - "Unicode support requires compiling with /utf-8"); - -template constexpr auto narrow(T*) -> char* { return nullptr; } -constexpr FMT_ALWAYS_INLINE auto narrow(const char* s) -> const char* { - return s; -} - -template -FMT_CONSTEXPR auto compare(const Char* s1, const Char* s2, size_t n) -> int { - if (!is_constant_evaluated() && sizeof(Char) == 1) return memcmp(s1, s2, n); - for (; n != 0; ++s1, ++s2, --n) { - if (*s1 < *s2) return -1; - if (*s1 > *s2) return 1; - } - return 0; -} - -namespace adl { -using namespace std; - -template -auto invoke_back_inserter() - -> decltype(back_inserter(std::declval())); -} // namespace adl - -template -struct is_back_insert_iterator : std::false_type {}; - -template -struct is_back_insert_iterator< - It, bool_constant()), - It>::value>> : std::true_type {}; - -// Extracts a reference to the container from *insert_iterator. -template -inline FMT_CONSTEXPR20 auto get_container(OutputIt it) -> - typename OutputIt::container_type& { - struct accessor : OutputIt { - FMT_CONSTEXPR20 accessor(OutputIt base) : OutputIt(base) {} - using OutputIt::container; - }; - return *accessor(it).container; -} -} // namespace detail - -// Parsing-related public API and forward declarations. -FMT_BEGIN_EXPORT - -/** - * An implementation of `std::basic_string_view` for pre-C++17. It provides a - * subset of the API. `fmt::basic_string_view` is used for format strings even - * if `std::basic_string_view` is available to prevent issues when a library is - * compiled with a different `-std` option than the client code (which is not - * recommended). - */ -template class basic_string_view { - private: - const Char* data_; - size_t size_; - - public: - using value_type = Char; - using iterator = const Char*; - - constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {} - - /// Constructs a string view object from a C string and a size. - constexpr basic_string_view(const Char* s, size_t count) noexcept - : data_(s), size_(count) {} - - constexpr basic_string_view(nullptr_t) = delete; - - /// Constructs a string view object from a C string. -#if FMT_GCC_VERSION - FMT_ALWAYS_INLINE -#endif - FMT_CONSTEXPR20 basic_string_view(const Char* s) : data_(s) { -#if FMT_HAS_BUILTIN(__builtin_strlen) || FMT_GCC_VERSION || FMT_CLANG_VERSION - if (std::is_same::value && !detail::is_constant_evaluated()) { - size_ = __builtin_strlen(detail::narrow(s)); // strlen is not constexpr. - return; - } -#endif - size_t len = 0; - while (*s++) ++len; - size_ = len; - } - - /// Constructs a string view from a `std::basic_string` or a - /// `std::basic_string_view` object. - template ::value&& std::is_same< - typename S::value_type, Char>::value)> - FMT_CONSTEXPR basic_string_view(const S& s) noexcept - : data_(s.data()), size_(s.size()) {} - - /// Returns a pointer to the string data. - constexpr auto data() const noexcept -> const Char* { return data_; } - - /// Returns the string size. - constexpr auto size() const noexcept -> size_t { return size_; } - - constexpr auto begin() const noexcept -> iterator { return data_; } - constexpr auto end() const noexcept -> iterator { return data_ + size_; } - - constexpr auto operator[](size_t pos) const noexcept -> const Char& { - return data_[pos]; - } - - FMT_CONSTEXPR void remove_prefix(size_t n) noexcept { - data_ += n; - size_ -= n; - } - - FMT_CONSTEXPR auto starts_with(basic_string_view sv) const noexcept - -> bool { - return size_ >= sv.size_ && detail::compare(data_, sv.data_, sv.size_) == 0; - } - FMT_CONSTEXPR auto starts_with(Char c) const noexcept -> bool { - return size_ >= 1 && *data_ == c; - } - FMT_CONSTEXPR auto starts_with(const Char* s) const -> bool { - return starts_with(basic_string_view(s)); - } - - FMT_CONSTEXPR auto compare(basic_string_view other) const -> int { - int result = - detail::compare(data_, other.data_, min_of(size_, other.size_)); - if (result != 0) return result; - return size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1); - } - - FMT_CONSTEXPR friend auto operator==(basic_string_view lhs, - basic_string_view rhs) -> bool { - return lhs.compare(rhs) == 0; - } - friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool { - return lhs.compare(rhs) != 0; - } - friend auto operator<(basic_string_view lhs, basic_string_view rhs) -> bool { - return lhs.compare(rhs) < 0; - } - friend auto operator<=(basic_string_view lhs, basic_string_view rhs) -> bool { - return lhs.compare(rhs) <= 0; - } - friend auto operator>(basic_string_view lhs, basic_string_view rhs) -> bool { - return lhs.compare(rhs) > 0; - } - friend auto operator>=(basic_string_view lhs, basic_string_view rhs) -> bool { - return lhs.compare(rhs) >= 0; - } -}; - -using string_view = basic_string_view; - -template class basic_appender; -using appender = basic_appender; - -// Checks whether T is a container with contiguous storage. -template struct is_contiguous : std::false_type {}; - -class context; -template class generic_context; -template class parse_context; - -// Longer aliases for C++20 compatibility. -template using basic_format_parse_context = parse_context; -using format_parse_context = parse_context; -template -using basic_format_context = - conditional_t::value, context, - generic_context>; -using format_context = context; - -template -using buffered_context = - conditional_t::value, context, - generic_context, Char>>; - -template class basic_format_arg; -template class basic_format_args; - -// A separate type would result in shorter symbols but break ABI compatibility -// between clang and gcc on ARM (#1919). -using format_args = basic_format_args; - -// A formatter for objects of type T. -template -struct formatter { - // A deleted default constructor indicates a disabled formatter. - formatter() = delete; -}; - -/// Reports a format error at compile time or, via a `format_error` exception, -/// at runtime. -// This function is intentionally not constexpr to give a compile-time error. -FMT_NORETURN FMT_API void report_error(const char* message); - -enum class presentation_type : unsigned char { - // Common specifiers: - none = 0, - debug = 1, // '?' - string = 2, // 's' (string, bool) - - // Integral, bool and character specifiers: - dec = 3, // 'd' - hex, // 'x' or 'X' - oct, // 'o' - bin, // 'b' or 'B' - chr, // 'c' - - // String and pointer specifiers: - pointer = 3, // 'p' - - // Floating-point specifiers: - exp = 1, // 'e' or 'E' (1 since there is no FP debug presentation) - fixed, // 'f' or 'F' - general, // 'g' or 'G' - hexfloat // 'a' or 'A' -}; - -enum class align { none, left, right, center, numeric }; -enum class sign { none, minus, plus, space }; -enum class arg_id_kind { none, index, name }; - -// Basic format specifiers for built-in and string types. -class basic_specs { - private: - // Data is arranged as follows: - // - // 0 1 2 3 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // |type |align| w | p | s |u|#|L| f | unused | - // +-----+-----+---+---+---+-+-+-+-----+---------------------------+ - // - // w - dynamic width info - // p - dynamic precision info - // s - sign - // u - uppercase (e.g. 'X' for 'x') - // # - alternate form ('#') - // L - localized - // f - fill size - // - // Bitfields are not used because of compiler bugs such as gcc bug 61414. - enum : unsigned { - type_mask = 0x00007, - align_mask = 0x00038, - width_mask = 0x000C0, - precision_mask = 0x00300, - sign_mask = 0x00C00, - uppercase_mask = 0x01000, - alternate_mask = 0x02000, - localized_mask = 0x04000, - fill_size_mask = 0x38000, - - align_shift = 3, - width_shift = 6, - precision_shift = 8, - sign_shift = 10, - fill_size_shift = 15, - - max_fill_size = 4 - }; - - unsigned data_ = 1 << fill_size_shift; - static_assert(sizeof(basic_specs::data_) * CHAR_BIT >= 18, ""); - - // Character (code unit) type is erased to prevent template bloat. - char fill_data_[max_fill_size] = {' '}; - - FMT_CONSTEXPR void set_fill_size(size_t size) { - data_ = (data_ & ~fill_size_mask) | - (static_cast(size) << fill_size_shift); - } - - public: - constexpr auto type() const -> presentation_type { - return static_cast(data_ & type_mask); - } - FMT_CONSTEXPR void set_type(presentation_type t) { - data_ = (data_ & ~type_mask) | static_cast(t); - } - - constexpr auto align() const -> align { - return static_cast((data_ & align_mask) >> align_shift); - } - FMT_CONSTEXPR void set_align(fmt::align a) { - data_ = (data_ & ~align_mask) | (static_cast(a) << align_shift); - } - - constexpr auto dynamic_width() const -> arg_id_kind { - return static_cast((data_ & width_mask) >> width_shift); - } - FMT_CONSTEXPR void set_dynamic_width(arg_id_kind w) { - data_ = (data_ & ~width_mask) | (static_cast(w) << width_shift); - } - - FMT_CONSTEXPR auto dynamic_precision() const -> arg_id_kind { - return static_cast((data_ & precision_mask) >> - precision_shift); - } - FMT_CONSTEXPR void set_dynamic_precision(arg_id_kind p) { - data_ = (data_ & ~precision_mask) | - (static_cast(p) << precision_shift); - } - - constexpr auto dynamic() const -> bool { - return (data_ & (width_mask | precision_mask)) != 0; - } - - constexpr auto sign() const -> sign { - return static_cast((data_ & sign_mask) >> sign_shift); - } - FMT_CONSTEXPR void set_sign(fmt::sign s) { - data_ = (data_ & ~sign_mask) | (static_cast(s) << sign_shift); - } - - constexpr auto upper() const -> bool { return (data_ & uppercase_mask) != 0; } - FMT_CONSTEXPR void set_upper() { data_ |= uppercase_mask; } - - constexpr auto alt() const -> bool { return (data_ & alternate_mask) != 0; } - FMT_CONSTEXPR void set_alt() { data_ |= alternate_mask; } - FMT_CONSTEXPR void clear_alt() { data_ &= ~alternate_mask; } - - constexpr auto localized() const -> bool { - return (data_ & localized_mask) != 0; - } - FMT_CONSTEXPR void set_localized() { data_ |= localized_mask; } - - constexpr auto fill_size() const -> size_t { - return (data_ & fill_size_mask) >> fill_size_shift; - } - - template ::value)> - constexpr auto fill() const -> const Char* { - return fill_data_; - } - template ::value)> - constexpr auto fill() const -> const Char* { - return nullptr; - } - - template constexpr auto fill_unit() const -> Char { - using uchar = unsigned char; - return static_cast(static_cast(fill_data_[0]) | - (static_cast(fill_data_[1]) << 8) | - (static_cast(fill_data_[2]) << 16)); - } - - FMT_CONSTEXPR void set_fill(char c) { - fill_data_[0] = c; - set_fill_size(1); - } - - template - FMT_CONSTEXPR void set_fill(basic_string_view s) { - auto size = s.size(); - set_fill_size(size); - if (size == 1) { - unsigned uchar = static_cast>(s[0]); - fill_data_[0] = static_cast(uchar); - fill_data_[1] = static_cast(uchar >> 8); - fill_data_[2] = static_cast(uchar >> 16); - return; - } - FMT_ASSERT(size <= max_fill_size, "invalid fill"); - for (size_t i = 0; i < size; ++i) - fill_data_[i & 3] = static_cast(s[i]); - } - - FMT_CONSTEXPR void copy_fill_from(const basic_specs& specs) { - set_fill_size(specs.fill_size()); - for (size_t i = 0; i < max_fill_size; ++i) - fill_data_[i] = specs.fill_data_[i]; - } -}; - -// Format specifiers for built-in and string types. -struct format_specs : basic_specs { - int width; - int precision; - - constexpr format_specs() : width(0), precision(-1) {} -}; - -/** - * Parsing context consisting of a format string range being parsed and an - * argument counter for automatic indexing. - */ -template class parse_context { - private: - basic_string_view fmt_; - int next_arg_id_; - - enum { use_constexpr_cast = !FMT_GCC_VERSION || FMT_GCC_VERSION >= 1200 }; - - FMT_CONSTEXPR void do_check_arg_id(int arg_id); - - public: - using char_type = Char; - using iterator = const Char*; - - constexpr explicit parse_context(basic_string_view fmt, - int next_arg_id = 0) - : fmt_(fmt), next_arg_id_(next_arg_id) {} - - /// Returns an iterator to the beginning of the format string range being - /// parsed. - constexpr auto begin() const noexcept -> iterator { return fmt_.begin(); } - - /// Returns an iterator past the end of the format string range being parsed. - constexpr auto end() const noexcept -> iterator { return fmt_.end(); } - - /// Advances the begin iterator to `it`. - FMT_CONSTEXPR void advance_to(iterator it) { - fmt_.remove_prefix(detail::to_unsigned(it - begin())); - } - - /// Reports an error if using the manual argument indexing; otherwise returns - /// the next argument index and switches to the automatic indexing. - FMT_CONSTEXPR auto next_arg_id() -> int { - if (next_arg_id_ < 0) { - report_error("cannot switch from manual to automatic argument indexing"); - return 0; - } - int id = next_arg_id_++; - do_check_arg_id(id); - return id; - } - - /// Reports an error if using the automatic argument indexing; otherwise - /// switches to the manual indexing. - FMT_CONSTEXPR void check_arg_id(int id) { - if (next_arg_id_ > 0) { - report_error("cannot switch from automatic to manual argument indexing"); - return; - } - next_arg_id_ = -1; - do_check_arg_id(id); - } - FMT_CONSTEXPR void check_arg_id(basic_string_view) { - next_arg_id_ = -1; - } - FMT_CONSTEXPR void check_dynamic_spec(int arg_id); -}; - -#ifndef FMT_USE_LOCALE -# define FMT_USE_LOCALE (FMT_OPTIMIZE_SIZE <= 1) -#endif - -// A type-erased reference to std::locale to avoid the heavy include. -class locale_ref { -#if FMT_USE_LOCALE - private: - const void* locale_; // A type-erased pointer to std::locale. - - public: - constexpr locale_ref() : locale_(nullptr) {} - - template - locale_ref(const Locale& loc) : locale_(&loc) { - // Check if std::isalpha is found via ADL to reduce the chance of misuse. - detail::ignore_unused(isalpha('x', loc)); - } - - inline explicit operator bool() const noexcept { return locale_ != nullptr; } -#endif // FMT_USE_LOCALE - - public: - template auto get() const -> Locale; -}; - -FMT_END_EXPORT - -namespace detail { - -// Specifies if `T` is a code unit type. -template struct is_code_unit : std::false_type {}; -template <> struct is_code_unit : std::true_type {}; -template <> struct is_code_unit : std::true_type {}; -template <> struct is_code_unit : std::true_type {}; -template <> struct is_code_unit : std::true_type {}; -#ifdef __cpp_char8_t -template <> struct is_code_unit : bool_constant {}; -#endif - -// Constructs fmt::basic_string_view from types implicitly convertible -// to it, deducing Char. Explicitly convertible types such as the ones returned -// from FMT_STRING are intentionally excluded. -template ::value)> -constexpr auto to_string_view(const Char* s) -> basic_string_view { - return s; -} -template ::value)> -constexpr auto to_string_view(const T& s) - -> basic_string_view { - return s; -} -template -constexpr auto to_string_view(basic_string_view s) - -> basic_string_view { - return s; -} - -template -struct has_to_string_view : std::false_type {}; -// detail:: is intentional since to_string_view is not an extension point. -template -struct has_to_string_view< - T, void_t()))>> - : std::true_type {}; - -/// String's character (code unit) type. detail:: is intentional to prevent ADL. -template ()))> -using char_t = typename V::value_type; - -enum class type { - none_type, - // Integer types should go first, - int_type, - uint_type, - long_long_type, - ulong_long_type, - int128_type, - uint128_type, - bool_type, - char_type, - last_integer_type = char_type, - // followed by floating-point types. - float_type, - double_type, - long_double_type, - last_numeric_type = long_double_type, - cstring_type, - string_type, - pointer_type, - custom_type -}; - -// Maps core type T to the corresponding type enum constant. -template -struct type_constant : std::integral_constant {}; - -#define FMT_TYPE_CONSTANT(Type, constant) \ - template \ - struct type_constant \ - : std::integral_constant {} - -FMT_TYPE_CONSTANT(int, int_type); -FMT_TYPE_CONSTANT(unsigned, uint_type); -FMT_TYPE_CONSTANT(long long, long_long_type); -FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type); -FMT_TYPE_CONSTANT(int128_opt, int128_type); -FMT_TYPE_CONSTANT(uint128_opt, uint128_type); -FMT_TYPE_CONSTANT(bool, bool_type); -FMT_TYPE_CONSTANT(Char, char_type); -FMT_TYPE_CONSTANT(float, float_type); -FMT_TYPE_CONSTANT(double, double_type); -FMT_TYPE_CONSTANT(long double, long_double_type); -FMT_TYPE_CONSTANT(const Char*, cstring_type); -FMT_TYPE_CONSTANT(basic_string_view, string_type); -FMT_TYPE_CONSTANT(const void*, pointer_type); - -constexpr auto is_integral_type(type t) -> bool { - return t > type::none_type && t <= type::last_integer_type; -} -constexpr auto is_arithmetic_type(type t) -> bool { - return t > type::none_type && t <= type::last_numeric_type; -} - -constexpr auto set(type rhs) -> int { return 1 << static_cast(rhs); } -constexpr auto in(type t, int set) -> bool { - return ((set >> static_cast(t)) & 1) != 0; -} - -// Bitsets of types. -enum { - sint_set = - set(type::int_type) | set(type::long_long_type) | set(type::int128_type), - uint_set = set(type::uint_type) | set(type::ulong_long_type) | - set(type::uint128_type), - bool_set = set(type::bool_type), - char_set = set(type::char_type), - float_set = set(type::float_type) | set(type::double_type) | - set(type::long_double_type), - string_set = set(type::string_type), - cstring_set = set(type::cstring_type), - pointer_set = set(type::pointer_type) -}; - -struct view {}; - -template -struct is_view : std::false_type {}; -template -struct is_view> : std::is_base_of {}; - -template struct named_arg; -template struct is_named_arg : std::false_type {}; -template struct is_static_named_arg : std::false_type {}; - -template -struct is_named_arg> : std::true_type {}; - -template struct named_arg : view { - const Char* name; - const T& value; - - named_arg(const Char* n, const T& v) : name(n), value(v) {} - static_assert(!is_named_arg::value, "nested named arguments"); -}; - -template constexpr auto count() -> int { return B ? 1 : 0; } -template constexpr auto count() -> int { - return (B1 ? 1 : 0) + count(); -} - -template constexpr auto count_named_args() -> int { - return count::value...>(); -} -template constexpr auto count_static_named_args() -> int { - return count::value...>(); -} - -template struct named_arg_info { - const Char* name; - int id; -}; - -// named_args is non-const to suppress a bogus -Wmaybe-uninitialized in gcc 13. -template -FMT_CONSTEXPR void check_for_duplicate(named_arg_info* named_args, - int named_arg_index, - basic_string_view arg_name) { - for (int i = 0; i < named_arg_index; ++i) { - if (named_args[i].name == arg_name) report_error("duplicate named arg"); - } -} - -template ::value)> -void init_named_arg(named_arg_info*, int& arg_index, int&, const T&) { - ++arg_index; -} -template ::value)> -void init_named_arg(named_arg_info* named_args, int& arg_index, - int& named_arg_index, const T& arg) { - check_for_duplicate(named_args, named_arg_index, arg.name); - named_args[named_arg_index++] = {arg.name, arg_index++}; -} - -template ::value)> -FMT_CONSTEXPR void init_static_named_arg(named_arg_info*, int& arg_index, - int&) { - ++arg_index; -} -template ::value)> -FMT_CONSTEXPR void init_static_named_arg(named_arg_info* named_args, - int& arg_index, int& named_arg_index) { - check_for_duplicate(named_args, named_arg_index, T::name); - named_args[named_arg_index++] = {T::name, arg_index++}; -} - -// To minimize the number of types we need to deal with, long is translated -// either to int or to long long depending on its size. -enum { long_short = sizeof(long) == sizeof(int) && FMT_BUILTIN_TYPES }; -using long_type = conditional_t; -using ulong_type = conditional_t; - -template -using format_as_result = - remove_cvref_t()))>; -template -using format_as_member_result = - remove_cvref_t::format_as(std::declval()))>; - -template -struct use_format_as : std::false_type {}; -// format_as member is only used to avoid injection into the std namespace. -template -struct use_format_as_member : std::false_type {}; - -// Only map owning types because mapping views can be unsafe. -template -struct use_format_as< - T, bool_constant>::value>> - : std::true_type {}; -template -struct use_format_as_member< - T, bool_constant>::value>> - : std::true_type {}; - -template > -using use_formatter = - bool_constant<(std::is_class::value || std::is_enum::value || - std::is_union::value || std::is_array::value) && - !has_to_string_view::value && !is_named_arg::value && - !use_format_as::value && !use_format_as_member::value>; - -template > -auto has_formatter_impl(T* p, buffered_context* ctx = nullptr) - -> decltype(formatter().format(*p, *ctx), std::true_type()); -template auto has_formatter_impl(...) -> std::false_type; - -// T can be const-qualified to check if it is const-formattable. -template constexpr auto has_formatter() -> bool { - return decltype(has_formatter_impl(static_cast(nullptr)))::value; -} - -// Maps formatting argument types to natively supported types or user-defined -// types with formatters. Returns void on errors to be SFINAE-friendly. -template struct type_mapper { - static auto map(signed char) -> int; - static auto map(unsigned char) -> unsigned; - static auto map(short) -> int; - static auto map(unsigned short) -> unsigned; - static auto map(int) -> int; - static auto map(unsigned) -> unsigned; - static auto map(long) -> long_type; - static auto map(unsigned long) -> ulong_type; - static auto map(long long) -> long long; - static auto map(unsigned long long) -> unsigned long long; - static auto map(int128_opt) -> int128_opt; - static auto map(uint128_opt) -> uint128_opt; - static auto map(bool) -> bool; - - template - static auto map(bitint) -> conditional_t; - template - static auto map(ubitint) - -> conditional_t; - - template ::value)> - static auto map(T) -> conditional_t< - std::is_same::value || std::is_same::value, Char, void>; - - static auto map(float) -> float; - static auto map(double) -> double; - static auto map(long double) -> long double; - - static auto map(Char*) -> const Char*; - static auto map(const Char*) -> const Char*; - template , - FMT_ENABLE_IF(!std::is_pointer::value)> - static auto map(const T&) -> conditional_t::value, - basic_string_view, void>; - - static auto map(void*) -> const void*; - static auto map(const void*) -> const void*; - static auto map(volatile void*) -> const void*; - static auto map(const volatile void*) -> const void*; - static auto map(nullptr_t) -> const void*; - template ::value || - std::is_member_pointer::value)> - static auto map(const T&) -> void; - - template ::value)> - static auto map(const T& x) -> decltype(map(format_as(x))); - template ::value)> - static auto map(const T& x) -> decltype(map(formatter::format_as(x))); - - template ::value)> - static auto map(T&) -> conditional_t(), T&, void>; - - template ::value)> - static auto map(const T& named_arg) -> decltype(map(named_arg.value)); -}; - -// detail:: is used to workaround a bug in MSVC 2017. -template -using mapped_t = decltype(detail::type_mapper::map(std::declval())); - -// A type constant after applying type_mapper. -template -using mapped_type_constant = type_constant, Char>; - -template ::value> -using stored_type_constant = std::integral_constant< - type, Context::builtin_types || TYPE == type::int_type ? TYPE - : type::custom_type>; -// A parse context with extra data used only in compile-time checks. -template -class compile_parse_context : public parse_context { - private: - int num_args_; - const type* types_; - using base = parse_context; - - public: - FMT_CONSTEXPR explicit compile_parse_context(basic_string_view fmt, - int num_args, const type* types, - int next_arg_id = 0) - : base(fmt, next_arg_id), num_args_(num_args), types_(types) {} - - constexpr auto num_args() const -> int { return num_args_; } - constexpr auto arg_type(int id) const -> type { return types_[id]; } - - FMT_CONSTEXPR auto next_arg_id() -> int { - int id = base::next_arg_id(); - if (id >= num_args_) report_error("argument not found"); - return id; - } - - FMT_CONSTEXPR void check_arg_id(int id) { - base::check_arg_id(id); - if (id >= num_args_) report_error("argument not found"); - } - using base::check_arg_id; - - FMT_CONSTEXPR void check_dynamic_spec(int arg_id) { - ignore_unused(arg_id); - if (arg_id < num_args_ && types_ && !is_integral_type(types_[arg_id])) - report_error("width/precision is not integer"); - } -}; - -// An argument reference. -template union arg_ref { - FMT_CONSTEXPR arg_ref(int idx = 0) : index(idx) {} - FMT_CONSTEXPR arg_ref(basic_string_view n) : name(n) {} - - int index; - basic_string_view name; -}; - -// Format specifiers with width and precision resolved at formatting rather -// than parsing time to allow reusing the same parsed specifiers with -// different sets of arguments (precompilation of format strings). -template struct dynamic_format_specs : format_specs { - arg_ref width_ref; - arg_ref precision_ref; -}; - -// Converts a character to ASCII. Returns '\0' on conversion failure. -template ::value)> -constexpr auto to_ascii(Char c) -> char { - return c <= 0xff ? static_cast(c) : '\0'; -} - -// Returns the number of code units in a code point or 1 on error. -template -FMT_CONSTEXPR auto code_point_length(const Char* begin) -> int { - if (const_check(sizeof(Char) != 1)) return 1; - auto c = static_cast(*begin); - return static_cast((0x3a55000000000000ull >> (2 * (c >> 3))) & 3) + 1; -} - -// Parses the range [begin, end) as an unsigned integer. This function assumes -// that the range is non-empty and the first character is a digit. -template -FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end, - int error_value) noexcept -> int { - FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', ""); - unsigned value = 0, prev = 0; - auto p = begin; - do { - prev = value; - value = value * 10 + unsigned(*p - '0'); - ++p; - } while (p != end && '0' <= *p && *p <= '9'); - auto num_digits = p - begin; - begin = p; - int digits10 = static_cast(sizeof(int) * CHAR_BIT * 3 / 10); - if (num_digits <= digits10) return static_cast(value); - // Check for overflow. - unsigned max = INT_MAX; - return num_digits == digits10 + 1 && - prev * 10ull + unsigned(p[-1] - '0') <= max - ? static_cast(value) - : error_value; -} - -FMT_CONSTEXPR inline auto parse_align(char c) -> align { - switch (c) { - case '<': return align::left; - case '>': return align::right; - case '^': return align::center; - } - return align::none; -} - -template constexpr auto is_name_start(Char c) -> bool { - return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '_'; -} - -template -FMT_CONSTEXPR auto parse_arg_id(const Char* begin, const Char* end, - Handler&& handler) -> const Char* { - Char c = *begin; - if (c >= '0' && c <= '9') { - int index = 0; - if (c != '0') - index = parse_nonnegative_int(begin, end, INT_MAX); - else - ++begin; - if (begin == end || (*begin != '}' && *begin != ':')) - report_error("invalid format string"); - else - handler.on_index(index); - return begin; - } - if (FMT_OPTIMIZE_SIZE > 1 || !is_name_start(c)) { - report_error("invalid format string"); - return begin; - } - auto it = begin; - do { - ++it; - } while (it != end && (is_name_start(*it) || ('0' <= *it && *it <= '9'))); - handler.on_name({begin, to_unsigned(it - begin)}); - return it; -} - -template struct dynamic_spec_handler { - parse_context& ctx; - arg_ref& ref; - arg_id_kind& kind; - - FMT_CONSTEXPR void on_index(int id) { - ref = id; - kind = arg_id_kind::index; - ctx.check_arg_id(id); - ctx.check_dynamic_spec(id); - } - FMT_CONSTEXPR void on_name(basic_string_view id) { - ref = id; - kind = arg_id_kind::name; - ctx.check_arg_id(id); - } -}; - -template struct parse_dynamic_spec_result { - const Char* end; - arg_id_kind kind; -}; - -// Parses integer | "{" [arg_id] "}". -template -FMT_CONSTEXPR auto parse_dynamic_spec(const Char* begin, const Char* end, - int& value, arg_ref& ref, - parse_context& ctx) - -> parse_dynamic_spec_result { - FMT_ASSERT(begin != end, ""); - auto kind = arg_id_kind::none; - if ('0' <= *begin && *begin <= '9') { - int val = parse_nonnegative_int(begin, end, -1); - if (val == -1) report_error("number is too big"); - value = val; - } else { - if (*begin == '{') { - ++begin; - if (begin != end) { - Char c = *begin; - if (c == '}' || c == ':') { - int id = ctx.next_arg_id(); - ref = id; - kind = arg_id_kind::index; - ctx.check_dynamic_spec(id); - } else { - begin = parse_arg_id(begin, end, - dynamic_spec_handler{ctx, ref, kind}); - } - } - if (begin != end && *begin == '}') return {++begin, kind}; - } - report_error("invalid format string"); - } - return {begin, kind}; -} - -template -FMT_CONSTEXPR auto parse_width(const Char* begin, const Char* end, - format_specs& specs, arg_ref& width_ref, - parse_context& ctx) -> const Char* { - auto result = parse_dynamic_spec(begin, end, specs.width, width_ref, ctx); - specs.set_dynamic_width(result.kind); - return result.end; -} - -template -FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end, - format_specs& specs, - arg_ref& precision_ref, - parse_context& ctx) -> const Char* { - ++begin; - if (begin == end) { - report_error("invalid precision"); - return begin; - } - auto result = - parse_dynamic_spec(begin, end, specs.precision, precision_ref, ctx); - specs.set_dynamic_precision(result.kind); - return result.end; -} - -enum class state { start, align, sign, hash, zero, width, precision, locale }; - -// Parses standard format specifiers. -template -FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end, - dynamic_format_specs& specs, - parse_context& ctx, type arg_type) - -> const Char* { - auto c = '\0'; - if (end - begin > 1) { - auto next = to_ascii(begin[1]); - c = parse_align(next) == align::none ? to_ascii(*begin) : '\0'; - } else { - if (begin == end) return begin; - c = to_ascii(*begin); - } - - struct { - state current_state = state::start; - FMT_CONSTEXPR void operator()(state s, bool valid = true) { - if (current_state >= s || !valid) - report_error("invalid format specifier"); - current_state = s; - } - } enter_state; - - using pres = presentation_type; - constexpr auto integral_set = sint_set | uint_set | bool_set | char_set; - struct { - const Char*& begin; - format_specs& specs; - type arg_type; - - FMT_CONSTEXPR auto operator()(pres pres_type, int set) -> const Char* { - if (!in(arg_type, set)) report_error("invalid format specifier"); - specs.set_type(pres_type); - return begin + 1; - } - } parse_presentation_type{begin, specs, arg_type}; - - for (;;) { - switch (c) { - case '<': - case '>': - case '^': - enter_state(state::align); - specs.set_align(parse_align(c)); - ++begin; - break; - case '+': - case ' ': - specs.set_sign(c == ' ' ? sign::space : sign::plus); - FMT_FALLTHROUGH; - case '-': - enter_state(state::sign, in(arg_type, sint_set | float_set)); - ++begin; - break; - case '#': - enter_state(state::hash, is_arithmetic_type(arg_type)); - specs.set_alt(); - ++begin; - break; - case '0': - enter_state(state::zero); - if (!is_arithmetic_type(arg_type)) - report_error("format specifier requires numeric argument"); - if (specs.align() == align::none) { - // Ignore 0 if align is specified for compatibility with std::format. - specs.set_align(align::numeric); - specs.set_fill('0'); - } - ++begin; - break; - // clang-format off - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': case '{': - // clang-format on - enter_state(state::width); - begin = parse_width(begin, end, specs, specs.width_ref, ctx); - break; - case '.': - enter_state(state::precision, - in(arg_type, float_set | string_set | cstring_set)); - begin = parse_precision(begin, end, specs, specs.precision_ref, ctx); - break; - case 'L': - enter_state(state::locale, is_arithmetic_type(arg_type)); - specs.set_localized(); - ++begin; - break; - case 'd': return parse_presentation_type(pres::dec, integral_set); - case 'X': specs.set_upper(); FMT_FALLTHROUGH; - case 'x': return parse_presentation_type(pres::hex, integral_set); - case 'o': return parse_presentation_type(pres::oct, integral_set); - case 'B': specs.set_upper(); FMT_FALLTHROUGH; - case 'b': return parse_presentation_type(pres::bin, integral_set); - case 'E': specs.set_upper(); FMT_FALLTHROUGH; - case 'e': return parse_presentation_type(pres::exp, float_set); - case 'F': specs.set_upper(); FMT_FALLTHROUGH; - case 'f': return parse_presentation_type(pres::fixed, float_set); - case 'G': specs.set_upper(); FMT_FALLTHROUGH; - case 'g': return parse_presentation_type(pres::general, float_set); - case 'A': specs.set_upper(); FMT_FALLTHROUGH; - case 'a': return parse_presentation_type(pres::hexfloat, float_set); - case 'c': - if (arg_type == type::bool_type) report_error("invalid format specifier"); - return parse_presentation_type(pres::chr, integral_set); - case 's': - return parse_presentation_type(pres::string, - bool_set | string_set | cstring_set); - case 'p': - return parse_presentation_type(pres::pointer, pointer_set | cstring_set); - case '?': - return parse_presentation_type(pres::debug, - char_set | string_set | cstring_set); - case '}': return begin; - default: { - if (*begin == '}') return begin; - // Parse fill and alignment. - auto fill_end = begin + code_point_length(begin); - if (end - fill_end <= 0) { - report_error("invalid format specifier"); - return begin; - } - if (*begin == '{') { - report_error("invalid fill character '{'"); - return begin; - } - auto alignment = parse_align(to_ascii(*fill_end)); - enter_state(state::align, alignment != align::none); - specs.set_fill( - basic_string_view(begin, to_unsigned(fill_end - begin))); - specs.set_align(alignment); - begin = fill_end + 1; - } - } - if (begin == end) return begin; - c = to_ascii(*begin); - } -} - -template -FMT_CONSTEXPR FMT_INLINE auto parse_replacement_field(const Char* begin, - const Char* end, - Handler&& handler) - -> const Char* { - ++begin; - if (begin == end) { - handler.on_error("invalid format string"); - return end; - } - int arg_id = 0; - switch (*begin) { - case '}': - handler.on_replacement_field(handler.on_arg_id(), begin); - return begin + 1; - case '{': handler.on_text(begin, begin + 1); return begin + 1; - case ':': arg_id = handler.on_arg_id(); break; - default: { - struct id_adapter { - Handler& handler; - int arg_id; - - FMT_CONSTEXPR void on_index(int id) { arg_id = handler.on_arg_id(id); } - FMT_CONSTEXPR void on_name(basic_string_view id) { - arg_id = handler.on_arg_id(id); - } - } adapter = {handler, 0}; - begin = parse_arg_id(begin, end, adapter); - arg_id = adapter.arg_id; - Char c = begin != end ? *begin : Char(); - if (c == '}') { - handler.on_replacement_field(arg_id, begin); - return begin + 1; - } - if (c != ':') { - handler.on_error("missing '}' in format string"); - return end; - } - break; - } - } - begin = handler.on_format_specs(arg_id, begin + 1, end); - if (begin == end || *begin != '}') - return handler.on_error("unknown format specifier"), end; - return begin + 1; -} - -template -FMT_CONSTEXPR void parse_format_string(basic_string_view fmt, - Handler&& handler) { - auto begin = fmt.data(), end = begin + fmt.size(); - auto p = begin; - while (p != end) { - auto c = *p++; - if (c == '{') { - handler.on_text(begin, p - 1); - begin = p = parse_replacement_field(p - 1, end, handler); - } else if (c == '}') { - if (p == end || *p != '}') - return handler.on_error("unmatched '}' in format string"); - handler.on_text(begin, p); - begin = ++p; - } - } - handler.on_text(begin, end); -} - -// Checks char specs and returns true iff the presentation type is char-like. -FMT_CONSTEXPR inline auto check_char_specs(const format_specs& specs) -> bool { - auto type = specs.type(); - if (type != presentation_type::none && type != presentation_type::chr && - type != presentation_type::debug) { - return false; - } - if (specs.align() == align::numeric || specs.sign() != sign::none || - specs.alt()) { - report_error("invalid format specifier for char"); - } - return true; -} - -// A base class for compile-time strings. -struct compile_string {}; - -template -FMT_VISIBILITY("hidden") // Suppress an ld warning on macOS (#3769). -FMT_CONSTEXPR auto invoke_parse(parse_context& ctx) -> const Char* { - using mapped_type = remove_cvref_t>; - constexpr bool formattable = - std::is_constructible>::value; - if (!formattable) return ctx.begin(); // Error is reported in the value ctor. - using formatted_type = conditional_t; - return formatter().parse(ctx); -} - -template struct arg_pack {}; - -template -class format_string_checker { - private: - type types_[max_of(1, NUM_ARGS)]; - named_arg_info named_args_[max_of(1, NUM_NAMED_ARGS)]; - compile_parse_context context_; - - using parse_func = auto (*)(parse_context&) -> const Char*; - parse_func parse_funcs_[max_of(1, NUM_ARGS)]; - - public: - template - FMT_CONSTEXPR explicit format_string_checker(basic_string_view fmt, - arg_pack) - : types_{mapped_type_constant::value...}, - named_args_{}, - context_(fmt, NUM_ARGS, types_), - parse_funcs_{&invoke_parse...} { - int arg_index = 0, named_arg_index = 0; - FMT_APPLY_VARIADIC( - init_static_named_arg(named_args_, arg_index, named_arg_index)); - ignore_unused(arg_index, named_arg_index); - } - - FMT_CONSTEXPR void on_text(const Char*, const Char*) {} - - FMT_CONSTEXPR auto on_arg_id() -> int { return context_.next_arg_id(); } - FMT_CONSTEXPR auto on_arg_id(int id) -> int { - context_.check_arg_id(id); - return id; - } - FMT_CONSTEXPR auto on_arg_id(basic_string_view id) -> int { - for (int i = 0; i < NUM_NAMED_ARGS; ++i) { - if (named_args_[i].name == id) return named_args_[i].id; - } - if (!DYNAMIC_NAMES) on_error("argument not found"); - return -1; - } - - FMT_CONSTEXPR void on_replacement_field(int id, const Char* begin) { - on_format_specs(id, begin, begin); // Call parse() on empty specs. - } - - FMT_CONSTEXPR auto on_format_specs(int id, const Char* begin, const Char* end) - -> const Char* { - context_.advance_to(begin); - if (id >= 0 && id < NUM_ARGS) return parse_funcs_[id](context_); - - // If id is out of range, it means we do not know the type and cannot parse - // the format at compile time. Instead, skip over content until we finish - // the format spec, accounting for any nested replacements. - for (int bracket_count = 0; - begin != end && (bracket_count > 0 || *begin != '}'); ++begin) { - if (*begin == '{') - ++bracket_count; - else if (*begin == '}') - --bracket_count; - } - return begin; - } - - FMT_NORETURN FMT_CONSTEXPR void on_error(const char* message) { - report_error(message); - } -}; - -/// A contiguous memory buffer with an optional growing ability. It is an -/// internal class and shouldn't be used directly, only via `memory_buffer`. -template class buffer { - private: - T* ptr_; - size_t size_; - size_t capacity_; - - using grow_fun = void (*)(buffer& buf, size_t capacity); - grow_fun grow_; - - protected: - // Don't initialize ptr_ since it is not accessed to save a few cycles. - FMT_MSC_WARNING(suppress : 26495) - FMT_CONSTEXPR buffer(grow_fun grow, size_t sz) noexcept - : size_(sz), capacity_(sz), grow_(grow) {} - - constexpr buffer(grow_fun grow, T* p = nullptr, size_t sz = 0, - size_t cap = 0) noexcept - : ptr_(p), size_(sz), capacity_(cap), grow_(grow) {} - - FMT_CONSTEXPR20 ~buffer() = default; - buffer(buffer&&) = default; - - /// Sets the buffer data and capacity. - FMT_CONSTEXPR void set(T* buf_data, size_t buf_capacity) noexcept { - ptr_ = buf_data; - capacity_ = buf_capacity; - } - - public: - using value_type = T; - using const_reference = const T&; - - buffer(const buffer&) = delete; - void operator=(const buffer&) = delete; - - auto begin() noexcept -> T* { return ptr_; } - auto end() noexcept -> T* { return ptr_ + size_; } - - auto begin() const noexcept -> const T* { return ptr_; } - auto end() const noexcept -> const T* { return ptr_ + size_; } - - /// Returns the size of this buffer. - constexpr auto size() const noexcept -> size_t { return size_; } - - /// Returns the capacity of this buffer. - constexpr auto capacity() const noexcept -> size_t { return capacity_; } - - /// Returns a pointer to the buffer data (not null-terminated). - FMT_CONSTEXPR auto data() noexcept -> T* { return ptr_; } - FMT_CONSTEXPR auto data() const noexcept -> const T* { return ptr_; } - - /// Clears this buffer. - FMT_CONSTEXPR void clear() { size_ = 0; } - - // Tries resizing the buffer to contain `count` elements. If T is a POD type - // the new elements may not be initialized. - FMT_CONSTEXPR void try_resize(size_t count) { - try_reserve(count); - size_ = min_of(count, capacity_); - } - - // Tries increasing the buffer capacity to `new_capacity`. It can increase the - // capacity by a smaller amount than requested but guarantees there is space - // for at least one additional element either by increasing the capacity or by - // flushing the buffer if it is full. - FMT_CONSTEXPR void try_reserve(size_t new_capacity) { - if (new_capacity > capacity_) grow_(*this, new_capacity); - } - - FMT_CONSTEXPR void push_back(const T& value) { - try_reserve(size_ + 1); - ptr_[size_++] = value; - } - - /// Appends data to the end of the buffer. - template -// Workaround for MSVC2019 to fix error C2893: Failed to specialize function -// template 'void fmt::v11::detail::buffer::append(const U *,const U *)'. -#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1940 - FMT_CONSTEXPR20 -#endif - void - append(const U* begin, const U* end) { - while (begin != end) { - auto size = size_; - auto free_cap = capacity_ - size; - auto count = to_unsigned(end - begin); - if (free_cap < count) { - grow_(*this, size + count); - size = size_; - free_cap = capacity_ - size; - count = count < free_cap ? count : free_cap; - } - // A loop is faster than memcpy on small sizes. - T* out = ptr_ + size; - for (size_t i = 0; i < count; ++i) out[i] = begin[i]; - size_ += count; - begin += count; - } - } - - template FMT_CONSTEXPR auto operator[](Idx index) -> T& { - return ptr_[index]; - } - template - FMT_CONSTEXPR auto operator[](Idx index) const -> const T& { - return ptr_[index]; - } -}; - -struct buffer_traits { - constexpr explicit buffer_traits(size_t) {} - constexpr auto count() const -> size_t { return 0; } - constexpr auto limit(size_t size) const -> size_t { return size; } -}; - -class fixed_buffer_traits { - private: - size_t count_ = 0; - size_t limit_; - - public: - constexpr explicit fixed_buffer_traits(size_t limit) : limit_(limit) {} - constexpr auto count() const -> size_t { return count_; } - FMT_CONSTEXPR auto limit(size_t size) -> size_t { - size_t n = limit_ > count_ ? limit_ - count_ : 0; - count_ += size; - return min_of(size, n); - } -}; - -// A buffer that writes to an output iterator when flushed. -template -class iterator_buffer : public Traits, public buffer { - private: - OutputIt out_; - enum { buffer_size = 256 }; - T data_[buffer_size]; - - static FMT_CONSTEXPR void grow(buffer& buf, size_t) { - if (buf.size() == buffer_size) static_cast(buf).flush(); - } - - void flush() { - auto size = this->size(); - this->clear(); - const T* begin = data_; - const T* end = begin + this->limit(size); - while (begin != end) *out_++ = *begin++; - } - - public: - explicit iterator_buffer(OutputIt out, size_t n = buffer_size) - : Traits(n), buffer(grow, data_, 0, buffer_size), out_(out) {} - iterator_buffer(iterator_buffer&& other) noexcept - : Traits(other), - buffer(grow, data_, 0, buffer_size), - out_(other.out_) {} - ~iterator_buffer() { - // Don't crash if flush fails during unwinding. - FMT_TRY { flush(); } - FMT_CATCH(...) {} - } - - auto out() -> OutputIt { - flush(); - return out_; - } - auto count() const -> size_t { return Traits::count() + this->size(); } -}; - -template -class iterator_buffer : public fixed_buffer_traits, - public buffer { - private: - T* out_; - enum { buffer_size = 256 }; - T data_[buffer_size]; - - static FMT_CONSTEXPR void grow(buffer& buf, size_t) { - if (buf.size() == buf.capacity()) - static_cast(buf).flush(); - } - - void flush() { - size_t n = this->limit(this->size()); - if (this->data() == out_) { - out_ += n; - this->set(data_, buffer_size); - } - this->clear(); - } - - public: - explicit iterator_buffer(T* out, size_t n = buffer_size) - : fixed_buffer_traits(n), buffer(grow, out, 0, n), out_(out) {} - iterator_buffer(iterator_buffer&& other) noexcept - : fixed_buffer_traits(other), - buffer(static_cast(other)), - out_(other.out_) { - if (this->data() != out_) { - this->set(data_, buffer_size); - this->clear(); - } - } - ~iterator_buffer() { flush(); } - - auto out() -> T* { - flush(); - return out_; - } - auto count() const -> size_t { - return fixed_buffer_traits::count() + this->size(); - } -}; - -template class iterator_buffer : public buffer { - public: - explicit iterator_buffer(T* out, size_t = 0) - : buffer([](buffer&, size_t) {}, out, 0, ~size_t()) {} - - auto out() -> T* { return &*this->end(); } -}; - -template -class container_buffer : public buffer { - private: - using value_type = typename Container::value_type; - - static FMT_CONSTEXPR void grow(buffer& buf, size_t capacity) { - auto& self = static_cast(buf); - self.container.resize(capacity); - self.set(&self.container[0], capacity); - } - - public: - Container& container; - - explicit container_buffer(Container& c) - : buffer(grow, c.size()), container(c) {} -}; - -// A buffer that writes to a container with the contiguous storage. -template -class iterator_buffer< - OutputIt, - enable_if_t::value && - is_contiguous::value, - typename OutputIt::container_type::value_type>> - : public container_buffer { - private: - using base = container_buffer; - - public: - explicit iterator_buffer(typename OutputIt::container_type& c) : base(c) {} - explicit iterator_buffer(OutputIt out, size_t = 0) - : base(get_container(out)) {} - - auto out() -> OutputIt { return OutputIt(this->container); } -}; - -// A buffer that counts the number of code units written discarding the output. -template class counting_buffer : public buffer { - private: - enum { buffer_size = 256 }; - T data_[buffer_size]; - size_t count_ = 0; - - static FMT_CONSTEXPR void grow(buffer& buf, size_t) { - if (buf.size() != buffer_size) return; - static_cast(buf).count_ += buf.size(); - buf.clear(); - } - - public: - FMT_CONSTEXPR counting_buffer() : buffer(grow, data_, 0, buffer_size) {} - - constexpr auto count() const noexcept -> size_t { - return count_ + this->size(); - } -}; - -template -struct is_back_insert_iterator> : std::true_type {}; - -template -struct has_back_insert_iterator_container_append : std::false_type {}; -template -struct has_back_insert_iterator_container_append< - OutputIt, InputIt, - void_t()) - .append(std::declval(), - std::declval()))>> : std::true_type {}; - -template -struct has_back_insert_iterator_container_insert_at_end : std::false_type {}; - -template -struct has_back_insert_iterator_container_insert_at_end< - OutputIt, InputIt, - void_t()) - .insert(get_container(std::declval()).end(), - std::declval(), - std::declval()))>> : std::true_type {}; - -// An optimized version of std::copy with the output value type (T). -template ::value&& - has_back_insert_iterator_container_append< - OutputIt, InputIt>::value)> -FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out) - -> OutputIt { - get_container(out).append(begin, end); - return out; -} - -template ::value && - !has_back_insert_iterator_container_append< - OutputIt, InputIt>::value && - has_back_insert_iterator_container_insert_at_end< - OutputIt, InputIt>::value)> -FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out) - -> OutputIt { - auto& c = get_container(out); - c.insert(c.end(), begin, end); - return out; -} - -template ::value && - (has_back_insert_iterator_container_append< - OutputIt, InputIt>::value || - has_back_insert_iterator_container_insert_at_end< - OutputIt, InputIt>::value)))> -FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt { - while (begin != end) *out++ = static_cast(*begin++); - return out; -} - -template -FMT_CONSTEXPR auto copy(basic_string_view s, OutputIt out) -> OutputIt { - return copy(s.begin(), s.end(), out); -} - -template -struct is_buffer_appender : std::false_type {}; -template -struct is_buffer_appender< - It, bool_constant< - is_back_insert_iterator::value && - std::is_base_of, - typename It::container_type>::value>> - : std::true_type {}; - -// Maps an output iterator to a buffer. -template ::value)> -auto get_buffer(OutputIt out) -> iterator_buffer { - return iterator_buffer(out); -} -template ::value)> -auto get_buffer(OutputIt out) -> buffer& { - return get_container(out); -} - -template -auto get_iterator(Buf& buf, OutputIt) -> decltype(buf.out()) { - return buf.out(); -} -template -auto get_iterator(buffer&, OutputIt out) -> OutputIt { - return out; -} - -// This type is intentionally undefined, only used for errors. -template struct type_is_unformattable_for; - -template struct string_value { - const Char* data; - size_t size; - auto str() const -> basic_string_view { return {data, size}; } -}; - -template struct custom_value { - using char_type = typename Context::char_type; - void* value; - void (*format)(void* arg, parse_context& parse_ctx, Context& ctx); -}; - -template struct named_arg_value { - const named_arg_info* data; - size_t size; -}; - -struct custom_tag {}; - -#if !FMT_BUILTIN_TYPES -# define FMT_BUILTIN , monostate -#else -# define FMT_BUILTIN -#endif - -// A formatting argument value. -template class value { - public: - using char_type = typename Context::char_type; - - union { - monostate no_value; - int int_value; - unsigned uint_value; - long long long_long_value; - unsigned long long ulong_long_value; - int128_opt int128_value; - uint128_opt uint128_value; - bool bool_value; - char_type char_value; - float float_value; - double double_value; - long double long_double_value; - const void* pointer; - string_value string; - custom_value custom; - named_arg_value named_args; - }; - - constexpr FMT_INLINE value() : no_value() {} - constexpr FMT_INLINE value(signed char x) : int_value(x) {} - constexpr FMT_INLINE value(unsigned char x FMT_BUILTIN) : uint_value(x) {} - constexpr FMT_INLINE value(signed short x) : int_value(x) {} - constexpr FMT_INLINE value(unsigned short x FMT_BUILTIN) : uint_value(x) {} - constexpr FMT_INLINE value(int x) : int_value(x) {} - constexpr FMT_INLINE value(unsigned x FMT_BUILTIN) : uint_value(x) {} - FMT_CONSTEXPR FMT_INLINE value(long x FMT_BUILTIN) : value(long_type(x)) {} - FMT_CONSTEXPR FMT_INLINE value(unsigned long x FMT_BUILTIN) - : value(ulong_type(x)) {} - constexpr FMT_INLINE value(long long x FMT_BUILTIN) : long_long_value(x) {} - constexpr FMT_INLINE value(unsigned long long x FMT_BUILTIN) - : ulong_long_value(x) {} - FMT_INLINE value(int128_opt x FMT_BUILTIN) : int128_value(x) {} - FMT_INLINE value(uint128_opt x FMT_BUILTIN) : uint128_value(x) {} - constexpr FMT_INLINE value(bool x FMT_BUILTIN) : bool_value(x) {} - - template - constexpr FMT_INLINE value(bitint x FMT_BUILTIN) : long_long_value(x) { - static_assert(N <= 64, "unsupported _BitInt"); - } - template - constexpr FMT_INLINE value(ubitint x FMT_BUILTIN) : ulong_long_value(x) { - static_assert(N <= 64, "unsupported _BitInt"); - } - - template ::value)> - constexpr FMT_INLINE value(T x FMT_BUILTIN) : char_value(x) { - static_assert( - std::is_same::value || std::is_same::value, - "mixing character types is disallowed"); - } - - constexpr FMT_INLINE value(float x FMT_BUILTIN) : float_value(x) {} - constexpr FMT_INLINE value(double x FMT_BUILTIN) : double_value(x) {} - FMT_INLINE value(long double x FMT_BUILTIN) : long_double_value(x) {} - - FMT_CONSTEXPR FMT_INLINE value(char_type* x FMT_BUILTIN) { - string.data = x; - if (is_constant_evaluated()) string.size = 0; - } - FMT_CONSTEXPR FMT_INLINE value(const char_type* x FMT_BUILTIN) { - string.data = x; - if (is_constant_evaluated()) string.size = 0; - } - template , - FMT_ENABLE_IF(!std::is_pointer::value)> - FMT_CONSTEXPR value(const T& x FMT_BUILTIN) { - static_assert(std::is_same::value, - "mixing character types is disallowed"); - auto sv = to_string_view(x); - string.data = sv.data(); - string.size = sv.size(); - } - FMT_INLINE value(void* x FMT_BUILTIN) : pointer(x) {} - FMT_INLINE value(const void* x FMT_BUILTIN) : pointer(x) {} - FMT_INLINE value(volatile void* x FMT_BUILTIN) - : pointer(const_cast(x)) {} - FMT_INLINE value(const volatile void* x FMT_BUILTIN) - : pointer(const_cast(x)) {} - FMT_INLINE value(nullptr_t) : pointer(nullptr) {} - - template ::value || - std::is_member_pointer::value)> - value(const T&) { - // Formatting of arbitrary pointers is disallowed. If you want to format a - // pointer cast it to `void*` or `const void*`. In particular, this forbids - // formatting of `[const] volatile char*` printed as bool by iostreams. - static_assert(sizeof(T) == 0, - "formatting of non-void pointers is disallowed"); - } - - template ::value)> - value(const T& x) : value(format_as(x)) {} - template ::value)> - value(const T& x) : value(formatter::format_as(x)) {} - - template ::value)> - value(const T& named_arg) : value(named_arg.value) {} - - template ::value || !FMT_BUILTIN_TYPES)> - FMT_CONSTEXPR20 FMT_INLINE value(T& x) : value(x, custom_tag()) {} - - FMT_ALWAYS_INLINE value(const named_arg_info* args, size_t size) - : named_args{args, size} {} - - private: - template ())> - FMT_CONSTEXPR value(T& x, custom_tag) { - using value_type = remove_const_t; - // T may overload operator& e.g. std::vector::reference in libc++. - if (!is_constant_evaluated()) { - custom.value = - const_cast(&reinterpret_cast(x)); - } else { - custom.value = nullptr; -#if defined(__cpp_if_constexpr) - if constexpr (std::is_same*>::value) - custom.value = const_cast(&x); -#endif - } - custom.format = format_custom; - } - - template ())> - FMT_CONSTEXPR value(const T&, custom_tag) { - // Cannot format an argument; to make type T formattable provide a - // formatter specialization: https://fmt.dev/latest/api.html#udt. - type_is_unformattable_for _; - } - - // Formats an argument of a custom type, such as a user-defined class. - template - static void format_custom(void* arg, parse_context& parse_ctx, - Context& ctx) { - auto f = formatter(); - parse_ctx.advance_to(f.parse(parse_ctx)); - using qualified_type = - conditional_t(), const T, T>; - // format must be const for compatibility with std::format and compilation. - const auto& cf = f; - ctx.advance_to(cf.format(*static_cast(arg), ctx)); - } -}; - -enum { packed_arg_bits = 4 }; -// Maximum number of arguments with packed types. -enum { max_packed_args = 62 / packed_arg_bits }; -enum : unsigned long long { is_unpacked_bit = 1ULL << 63 }; -enum : unsigned long long { has_named_args_bit = 1ULL << 62 }; - -template -struct is_output_iterator : std::false_type {}; - -template <> struct is_output_iterator : std::true_type {}; - -template -struct is_output_iterator< - It, T, - enable_if_t&>()++), - T>::value>> : std::true_type {}; - -template constexpr auto encode_types() -> unsigned long long { - return 0; -} - -template -constexpr auto encode_types() -> unsigned long long { - return static_cast(stored_type_constant::value) | - (encode_types() << packed_arg_bits); -} - -template -constexpr auto make_descriptor() -> unsigned long long { - return NUM_ARGS <= max_packed_args ? encode_types() - : is_unpacked_bit | NUM_ARGS; -} - -template -using arg_t = conditional_t, - basic_format_arg>; - -template -struct named_arg_store { - // args_[0].named_args points to named_args to avoid bloating format_args. - arg_t args[1u + NUM_ARGS]; - named_arg_info - named_args[static_cast(NUM_NAMED_ARGS)]; - - template - FMT_CONSTEXPR FMT_ALWAYS_INLINE named_arg_store(T&... values) - : args{{named_args, NUM_NAMED_ARGS}, values...} { - int arg_index = 0, named_arg_index = 0; - FMT_APPLY_VARIADIC( - init_named_arg(named_args, arg_index, named_arg_index, values)); - } - - named_arg_store(named_arg_store&& rhs) { - args[0] = {named_args, NUM_NAMED_ARGS}; - for (size_t i = 1; i < sizeof(args) / sizeof(*args); ++i) - args[i] = rhs.args[i]; - for (size_t i = 0; i < NUM_NAMED_ARGS; ++i) - named_args[i] = rhs.named_args[i]; - } - - named_arg_store(const named_arg_store& rhs) = delete; - auto operator=(const named_arg_store& rhs) -> named_arg_store& = delete; - auto operator=(named_arg_store&& rhs) -> named_arg_store& = delete; - operator const arg_t*() const { return args + 1; } -}; - -// An array of references to arguments. It can be implicitly converted to -// `basic_format_args` for passing into type-erased formatting functions -// such as `vformat`. It is a plain struct to reduce binary size in debug mode. -template -struct format_arg_store { - // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning. - using type = - conditional_t[max_of(1, NUM_ARGS)], - named_arg_store>; - type args; -}; - -// TYPE can be different from type_constant, e.g. for __float128. -template struct native_formatter { - private: - dynamic_format_specs specs_; - - public: - using nonlocking = void; - - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin(); - auto end = parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, TYPE); - if (const_check(TYPE == type::char_type)) check_char_specs(specs_); - return end; - } - - template - FMT_CONSTEXPR void set_debug_format(bool set = true) { - specs_.set_type(set ? presentation_type::debug : presentation_type::none); - } - - FMT_PRAGMA_CLANG(diagnostic ignored "-Wundefined-inline") - template - FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const - -> decltype(ctx.out()); -}; - -template -struct locking - : bool_constant::value == type::custom_type> {}; -template -struct locking>::nonlocking>> - : std::false_type {}; - -template FMT_CONSTEXPR inline auto is_locking() -> bool { - return locking::value; -} -template -FMT_CONSTEXPR inline auto is_locking() -> bool { - return locking::value || is_locking(); -} - -FMT_API void vformat_to(buffer& buf, string_view fmt, format_args args, - locale_ref loc = {}); - -#if FMT_WIN32 -FMT_API void vprint_mojibake(FILE*, string_view, format_args, bool); -#else // format_args is passed by reference since it is defined later. -inline void vprint_mojibake(FILE*, string_view, const format_args&, bool) {} -#endif -} // namespace detail - -// The main public API. - -template -FMT_CONSTEXPR void parse_context::do_check_arg_id(int arg_id) { - // Argument id is only checked at compile time during parsing because - // formatting has its own validation. - if (detail::is_constant_evaluated() && use_constexpr_cast) { - auto ctx = static_cast*>(this); - if (arg_id >= ctx->num_args()) report_error("argument not found"); - } -} - -template -FMT_CONSTEXPR void parse_context::check_dynamic_spec(int arg_id) { - using detail::compile_parse_context; - if (detail::is_constant_evaluated() && use_constexpr_cast) - static_cast*>(this)->check_dynamic_spec(arg_id); -} - -FMT_BEGIN_EXPORT - -// An output iterator that appends to a buffer. It is used instead of -// back_insert_iterator to reduce symbol sizes and avoid dependency. -template class basic_appender { - protected: - detail::buffer* container; - - public: - using container_type = detail::buffer; - - FMT_CONSTEXPR basic_appender(detail::buffer& buf) : container(&buf) {} - - FMT_CONSTEXPR20 auto operator=(T c) -> basic_appender& { - container->push_back(c); - return *this; - } - FMT_CONSTEXPR20 auto operator*() -> basic_appender& { return *this; } - FMT_CONSTEXPR20 auto operator++() -> basic_appender& { return *this; } - FMT_CONSTEXPR20 auto operator++(int) -> basic_appender { return *this; } -}; - -// A formatting argument. Context is a template parameter for the compiled API -// where output can be unbuffered. -template class basic_format_arg { - private: - detail::value value_; - detail::type type_; - - friend class basic_format_args; - - using char_type = typename Context::char_type; - - public: - class handle { - private: - detail::custom_value custom_; - - public: - explicit handle(detail::custom_value custom) : custom_(custom) {} - - void format(parse_context& parse_ctx, Context& ctx) const { - custom_.format(custom_.value, parse_ctx, ctx); - } - }; - - constexpr basic_format_arg() : type_(detail::type::none_type) {} - basic_format_arg(const detail::named_arg_info* args, size_t size) - : value_(args, size) {} - template - basic_format_arg(T&& val) - : value_(val), type_(detail::stored_type_constant::value) {} - - constexpr explicit operator bool() const noexcept { - return type_ != detail::type::none_type; - } - auto type() const -> detail::type { return type_; } - - /** - * Visits an argument dispatching to the appropriate visit method based on - * the argument type. For example, if the argument type is `double` then - * `vis(value)` will be called with the value of type `double`. - */ - template - FMT_CONSTEXPR FMT_INLINE auto visit(Visitor&& vis) const -> decltype(vis(0)) { - using detail::map; - switch (type_) { - case detail::type::none_type: break; - case detail::type::int_type: return vis(value_.int_value); - case detail::type::uint_type: return vis(value_.uint_value); - case detail::type::long_long_type: return vis(value_.long_long_value); - case detail::type::ulong_long_type: return vis(value_.ulong_long_value); - case detail::type::int128_type: return vis(map(value_.int128_value)); - case detail::type::uint128_type: return vis(map(value_.uint128_value)); - case detail::type::bool_type: return vis(value_.bool_value); - case detail::type::char_type: return vis(value_.char_value); - case detail::type::float_type: return vis(value_.float_value); - case detail::type::double_type: return vis(value_.double_value); - case detail::type::long_double_type: return vis(value_.long_double_value); - case detail::type::cstring_type: return vis(value_.string.data); - case detail::type::string_type: return vis(value_.string.str()); - case detail::type::pointer_type: return vis(value_.pointer); - case detail::type::custom_type: return vis(handle(value_.custom)); - } - return vis(monostate()); - } - - auto format_custom(const char_type* parse_begin, - parse_context& parse_ctx, Context& ctx) - -> bool { - if (type_ != detail::type::custom_type) return false; - parse_ctx.advance_to(parse_begin); - value_.custom.format(value_.custom.value, parse_ctx, ctx); - return true; - } -}; - -/** - * A view of a collection of formatting arguments. To avoid lifetime issues it - * should only be used as a parameter type in type-erased functions such as - * `vformat`: - * - * void vlog(fmt::string_view fmt, fmt::format_args args); // OK - * fmt::format_args args = fmt::make_format_args(); // Dangling reference - */ -template class basic_format_args { - private: - // A descriptor that contains information about formatting arguments. - // If the number of arguments is less or equal to max_packed_args then - // argument types are passed in the descriptor. This reduces binary code size - // per formatting function call. - unsigned long long desc_; - union { - // If is_packed() returns true then argument values are stored in values_; - // otherwise they are stored in args_. This is done to improve cache - // locality and reduce compiled code size since storing larger objects - // may require more code (at least on x86-64) even if the same amount of - // data is actually copied to stack. It saves ~10% on the bloat test. - const detail::value* values_; - const basic_format_arg* args_; - }; - - constexpr auto is_packed() const -> bool { - return (desc_ & detail::is_unpacked_bit) == 0; - } - constexpr auto has_named_args() const -> bool { - return (desc_ & detail::has_named_args_bit) != 0; - } - - FMT_CONSTEXPR auto type(int index) const -> detail::type { - int shift = index * detail::packed_arg_bits; - unsigned mask = (1 << detail::packed_arg_bits) - 1; - return static_cast((desc_ >> shift) & mask); - } - - template - using store = - detail::format_arg_store; - - public: - using format_arg = basic_format_arg; - - constexpr basic_format_args() : desc_(0), args_(nullptr) {} - - /// Constructs a `basic_format_args` object from `format_arg_store`. - template - constexpr FMT_ALWAYS_INLINE basic_format_args( - const store& s) - : desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)), - values_(s.args) {} - - template detail::max_packed_args)> - constexpr basic_format_args(const store& s) - : desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)), - args_(s.args) {} - - /// Constructs a `basic_format_args` object from a dynamic list of arguments. - constexpr basic_format_args(const format_arg* args, int count, - bool has_named = false) - : desc_(detail::is_unpacked_bit | detail::to_unsigned(count) | - (has_named ? +detail::has_named_args_bit : 0)), - args_(args) {} - - /// Returns the argument with the specified id. - FMT_CONSTEXPR auto get(int id) const -> format_arg { - auto arg = format_arg(); - if (!is_packed()) { - if (id < max_size()) arg = args_[id]; - return arg; - } - if (static_cast(id) >= detail::max_packed_args) return arg; - arg.type_ = type(id); - if (arg.type_ != detail::type::none_type) arg.value_ = values_[id]; - return arg; - } - - template - auto get(basic_string_view name) const -> format_arg { - int id = get_id(name); - return id >= 0 ? get(id) : format_arg(); - } - - template - FMT_CONSTEXPR auto get_id(basic_string_view name) const -> int { - if (!has_named_args()) return -1; - const auto& named_args = - (is_packed() ? values_[-1] : args_[-1].value_).named_args; - for (size_t i = 0; i < named_args.size; ++i) { - if (named_args.data[i].name == name) return named_args.data[i].id; - } - return -1; - } - - auto max_size() const -> int { - unsigned long long max_packed = detail::max_packed_args; - return static_cast(is_packed() ? max_packed - : desc_ & ~detail::is_unpacked_bit); - } -}; - -// A formatting context. -class context { - private: - appender out_; - format_args args_; - FMT_NO_UNIQUE_ADDRESS locale_ref loc_; - - public: - using char_type = char; ///< The character type for the output. - using iterator = appender; - using format_arg = basic_format_arg; - enum { builtin_types = FMT_BUILTIN_TYPES }; - - /// Constructs a `context` object. References to the arguments are stored - /// in the object so make sure they have appropriate lifetimes. - FMT_CONSTEXPR context(iterator out, format_args args, locale_ref loc = {}) - : out_(out), args_(args), loc_(loc) {} - context(context&&) = default; - context(const context&) = delete; - void operator=(const context&) = delete; - - FMT_CONSTEXPR auto arg(int id) const -> format_arg { return args_.get(id); } - inline auto arg(string_view name) const -> format_arg { - return args_.get(name); - } - FMT_CONSTEXPR auto arg_id(string_view name) const -> int { - return args_.get_id(name); - } - auto args() const -> const format_args& { return args_; } - - // Returns an iterator to the beginning of the output range. - FMT_CONSTEXPR auto out() const -> iterator { return out_; } - - // Advances the begin iterator to `it`. - FMT_CONSTEXPR void advance_to(iterator) {} - - FMT_CONSTEXPR auto locale() const -> locale_ref { return loc_; } -}; - -template struct runtime_format_string { - basic_string_view str; -}; - -/** - * Creates a runtime format string. - * - * **Example**: - * - * // Check format string at runtime instead of compile-time. - * fmt::print(fmt::runtime("{:d}"), "I am not a number"); - */ -inline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; } - -/// A compile-time format string. Use `format_string` in the public API to -/// prevent type deduction. -template struct fstring { - private: - static constexpr int num_static_named_args = - detail::count_static_named_args(); - - using checker = detail::format_string_checker< - char, static_cast(sizeof...(T)), num_static_named_args, - num_static_named_args != detail::count_named_args()>; - - using arg_pack = detail::arg_pack; - - public: - string_view str; - using t = fstring; - - // Reports a compile-time error if S is not a valid format string for T. - template - FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const char (&s)[N]) : str(s, N - 1) { - using namespace detail; - static_assert(count<(is_view>::value && - std::is_reference::value)...>() == 0, - "passing views as lvalues is disallowed"); - if (FMT_USE_CONSTEVAL) parse_format_string(s, checker(s, arg_pack())); -#ifdef FMT_ENFORCE_COMPILE_STRING - static_assert( - FMT_USE_CONSTEVAL && sizeof(s) != 0, - "FMT_ENFORCE_COMPILE_STRING requires format strings to use FMT_STRING"); -#endif - } - template ::value)> - FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const S& s) : str(s) { - auto sv = string_view(str); - if (FMT_USE_CONSTEVAL) - detail::parse_format_string(sv, checker(sv, arg_pack())); -#ifdef FMT_ENFORCE_COMPILE_STRING - static_assert( - FMT_USE_CONSTEVAL && sizeof(s) != 0, - "FMT_ENFORCE_COMPILE_STRING requires format strings to use FMT_STRING"); -#endif - } - template ::value&& - std::is_same::value)> - FMT_ALWAYS_INLINE fstring(const S&) : str(S()) { - FMT_CONSTEXPR auto sv = string_view(S()); - FMT_CONSTEXPR int unused = - (parse_format_string(sv, checker(sv, arg_pack())), 0); - detail::ignore_unused(unused); - } - fstring(runtime_format_string<> fmt) : str(fmt.str) {} - - // Returning by reference generates better code in debug mode. - FMT_ALWAYS_INLINE operator const string_view&() const { return str; } - auto get() const -> string_view { return str; } -}; - -template using format_string = typename fstring::t; - -template -using is_formattable = bool_constant::value, int*, T>, Char>, - void>::value>; -#ifdef __cpp_concepts -template -concept formattable = is_formattable, Char>::value; -#endif - -// A formatter specialization for natively supported types. -template -struct formatter::value != - detail::type::custom_type>> - : detail::native_formatter::value> { -}; - -/** - * Constructs an object that stores references to arguments and can be - * implicitly converted to `format_args`. `Context` can be omitted in which case - * it defaults to `context`. See `arg` for lifetime considerations. - */ -// Take arguments by lvalue references to avoid some lifetime issues, e.g. -// auto args = make_format_args(std::string()); -template (), - unsigned long long DESC = detail::make_descriptor()> -constexpr FMT_ALWAYS_INLINE auto make_format_args(T&... args) - -> detail::format_arg_store { - // Suppress warnings for pathological types convertible to detail::value. - FMT_PRAGMA_GCC(diagnostic ignored "-Wconversion") - return {{args...}}; -} - -template -using vargs = - detail::format_arg_store(), - detail::make_descriptor()>; - -/** - * Returns a named argument to be used in a formatting function. - * It should only be used in a call to a formatting function. - * - * **Example**: - * - * fmt::print("The answer is {answer}.", fmt::arg("answer", 42)); - */ -template -inline auto arg(const Char* name, const T& arg) -> detail::named_arg { - return {name, arg}; -} - -/// Formats a string and writes the output to `out`. -template , - char>::value)> -auto vformat_to(OutputIt&& out, string_view fmt, format_args args) - -> remove_cvref_t { - auto&& buf = detail::get_buffer(out); - detail::vformat_to(buf, fmt, args, {}); - return detail::get_iterator(buf, out); -} - -/** - * Formats `args` according to specifications in `fmt`, writes the result to - * the output iterator `out` and returns the iterator past the end of the output - * range. `format_to` does not append a terminating null character. - * - * **Example**: - * - * auto out = std::vector(); - * fmt::format_to(std::back_inserter(out), "{}", 42); - */ -template , - char>::value)> -FMT_INLINE auto format_to(OutputIt&& out, format_string fmt, T&&... args) - -> remove_cvref_t { - return vformat_to(out, fmt.str, vargs{{args...}}); -} - -template struct format_to_n_result { - /// Iterator past the end of the output range. - OutputIt out; - /// Total (not truncated) output size. - size_t size; -}; - -template ::value)> -auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args) - -> format_to_n_result { - using traits = detail::fixed_buffer_traits; - auto buf = detail::iterator_buffer(out, n); - detail::vformat_to(buf, fmt, args, {}); - return {buf.out(), buf.count()}; -} - -/** - * Formats `args` according to specifications in `fmt`, writes up to `n` - * characters of the result to the output iterator `out` and returns the total - * (not truncated) output size and the iterator past the end of the output - * range. `format_to_n` does not append a terminating null character. - */ -template ::value)> -FMT_INLINE auto format_to_n(OutputIt out, size_t n, format_string fmt, - T&&... args) -> format_to_n_result { - return vformat_to_n(out, n, fmt.str, vargs{{args...}}); -} - -struct format_to_result { - /// Pointer to just after the last successful write in the array. - char* out; - /// Specifies if the output was truncated. - bool truncated; - - FMT_CONSTEXPR operator char*() const { - // Report truncation to prevent silent data loss. - if (truncated) report_error("output is truncated"); - return out; - } -}; - -template -auto vformat_to(char (&out)[N], string_view fmt, format_args args) - -> format_to_result { - auto result = vformat_to_n(out, N, fmt, args); - return {result.out, result.size > N}; -} - -template -FMT_INLINE auto format_to(char (&out)[N], format_string fmt, T&&... args) - -> format_to_result { - auto result = vformat_to_n(out, N, fmt.str, vargs{{args...}}); - return {result.out, result.size > N}; -} - -/// Returns the number of chars in the output of `format(fmt, args...)`. -template -FMT_NODISCARD FMT_INLINE auto formatted_size(format_string fmt, - T&&... args) -> size_t { - auto buf = detail::counting_buffer<>(); - detail::vformat_to(buf, fmt.str, vargs{{args...}}, {}); - return buf.count(); -} - -FMT_API void vprint(string_view fmt, format_args args); -FMT_API void vprint(FILE* f, string_view fmt, format_args args); -FMT_API void vprintln(FILE* f, string_view fmt, format_args args); -FMT_API void vprint_buffered(FILE* f, string_view fmt, format_args args); - -/** - * Formats `args` according to specifications in `fmt` and writes the output - * to `stdout`. - * - * **Example**: - * - * fmt::print("The answer is {}.", 42); - */ -template -FMT_INLINE void print(format_string fmt, T&&... args) { - vargs va = {{args...}}; - if (detail::const_check(!detail::use_utf8)) - return detail::vprint_mojibake(stdout, fmt.str, va, false); - return detail::is_locking() ? vprint_buffered(stdout, fmt.str, va) - : vprint(fmt.str, va); -} - -/** - * Formats `args` according to specifications in `fmt` and writes the - * output to the file `f`. - * - * **Example**: - * - * fmt::print(stderr, "Don't {}!", "panic"); - */ -template -FMT_INLINE void print(FILE* f, format_string fmt, T&&... args) { - vargs va = {{args...}}; - if (detail::const_check(!detail::use_utf8)) - return detail::vprint_mojibake(f, fmt.str, va, false); - return detail::is_locking() ? vprint_buffered(f, fmt.str, va) - : vprint(f, fmt.str, va); -} - -/// Formats `args` according to specifications in `fmt` and writes the output -/// to the file `f` followed by a newline. -template -FMT_INLINE void println(FILE* f, format_string fmt, T&&... args) { - vargs va = {{args...}}; - return detail::const_check(detail::use_utf8) - ? vprintln(f, fmt.str, va) - : detail::vprint_mojibake(f, fmt.str, va, true); -} - -/// Formats `args` according to specifications in `fmt` and writes the output -/// to `stdout` followed by a newline. -template -FMT_INLINE void println(format_string fmt, T&&... args) { - return fmt::println(stdout, fmt, static_cast(args)...); -} - -FMT_PRAGMA_GCC(diagnostic pop) -FMT_PRAGMA_CLANG(diagnostic pop) -FMT_PRAGMA_GCC(pop_options) -FMT_END_EXPORT -FMT_END_NAMESPACE - -#ifdef FMT_HEADER_ONLY -# include "format.h" -#endif -#endif // FMT_BASE_H_ diff --git a/include/libs/spdlog/fmt/bundled/chrono.h b/include/libs/spdlog/fmt/bundled/chrono.h deleted file mode 100644 index 9fbeeed..0000000 --- a/include/libs/spdlog/fmt/bundled/chrono.h +++ /dev/null @@ -1,2246 +0,0 @@ -// Formatting library for C++ - chrono support -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_CHRONO_H_ -#define FMT_CHRONO_H_ - -#ifndef FMT_MODULE -# include -# include -# include // std::isfinite -# include // std::memcpy -# include -# include -# include -# include -# include -#endif - -#include "format.h" - -FMT_BEGIN_NAMESPACE - -// Enable safe chrono durations, unless explicitly disabled. -#ifndef FMT_SAFE_DURATION_CAST -# define FMT_SAFE_DURATION_CAST 1 -#endif -#if FMT_SAFE_DURATION_CAST - -// For conversion between std::chrono::durations without undefined -// behaviour or erroneous results. -// This is a stripped down version of duration_cast, for inclusion in fmt. -// See https://github.com/pauldreik/safe_duration_cast -// -// Copyright Paul Dreik 2019 -namespace safe_duration_cast { - -// DEPRECATED! -template ::value && - std::numeric_limits::is_signed == - std::numeric_limits::is_signed)> -FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec) - -> To { - ec = 0; - using F = std::numeric_limits; - using T = std::numeric_limits; - static_assert(F::is_integer, "From must be integral"); - static_assert(T::is_integer, "To must be integral"); - - // A and B are both signed, or both unsigned. - if (detail::const_check(F::digits <= T::digits)) { - // From fits in To without any problem. - } else { - // From does not always fit in To, resort to a dynamic check. - if (from < (T::min)() || from > (T::max)()) { - // outside range. - ec = 1; - return {}; - } - } - return static_cast(from); -} - -/// Converts From to To, without loss. If the dynamic value of from -/// can't be converted to To without loss, ec is set. -template ::value && - std::numeric_limits::is_signed != - std::numeric_limits::is_signed)> -FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec) - -> To { - ec = 0; - using F = std::numeric_limits; - using T = std::numeric_limits; - static_assert(F::is_integer, "From must be integral"); - static_assert(T::is_integer, "To must be integral"); - - if (detail::const_check(F::is_signed && !T::is_signed)) { - // From may be negative, not allowed! - if (fmt::detail::is_negative(from)) { - ec = 1; - return {}; - } - // From is positive. Can it always fit in To? - if (detail::const_check(F::digits > T::digits) && - from > static_cast(detail::max_value())) { - ec = 1; - return {}; - } - } - - if (detail::const_check(!F::is_signed && T::is_signed && - F::digits >= T::digits) && - from > static_cast(detail::max_value())) { - ec = 1; - return {}; - } - return static_cast(from); // Lossless conversion. -} - -template ::value)> -FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec) - -> To { - ec = 0; - return from; -} // function - -// clang-format off -/** - * converts From to To if possible, otherwise ec is set. - * - * input | output - * ---------------------------------|--------------- - * NaN | NaN - * Inf | Inf - * normal, fits in output | converted (possibly lossy) - * normal, does not fit in output | ec is set - * subnormal | best effort - * -Inf | -Inf - */ -// clang-format on -template ::value)> -FMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To { - ec = 0; - using T = std::numeric_limits; - static_assert(std::is_floating_point::value, "From must be floating"); - static_assert(std::is_floating_point::value, "To must be floating"); - - // catch the only happy case - if (std::isfinite(from)) { - if (from >= T::lowest() && from <= (T::max)()) { - return static_cast(from); - } - // not within range. - ec = 1; - return {}; - } - - // nan and inf will be preserved - return static_cast(from); -} // function - -template ::value)> -FMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To { - ec = 0; - static_assert(std::is_floating_point::value, "From must be floating"); - return from; -} - -/// Safe duration_cast between floating point durations -template ::value), - FMT_ENABLE_IF(std::is_floating_point::value)> -auto safe_duration_cast(std::chrono::duration from, - int& ec) -> To { - using From = std::chrono::duration; - ec = 0; - - // the basic idea is that we need to convert from count() in the from type - // to count() in the To type, by multiplying it with this: - struct Factor - : std::ratio_divide {}; - - static_assert(Factor::num > 0, "num must be positive"); - static_assert(Factor::den > 0, "den must be positive"); - - // the conversion is like this: multiply from.count() with Factor::num - // /Factor::den and convert it to To::rep, all this without - // overflow/underflow. let's start by finding a suitable type that can hold - // both To, From and Factor::num - using IntermediateRep = - typename std::common_type::type; - - // force conversion of From::rep -> IntermediateRep to be safe, - // even if it will never happen be narrowing in this context. - IntermediateRep count = - safe_float_conversion(from.count(), ec); - if (ec) { - return {}; - } - - // multiply with Factor::num without overflow or underflow - if (detail::const_check(Factor::num != 1)) { - constexpr auto max1 = detail::max_value() / - static_cast(Factor::num); - if (count > max1) { - ec = 1; - return {}; - } - constexpr auto min1 = std::numeric_limits::lowest() / - static_cast(Factor::num); - if (count < min1) { - ec = 1; - return {}; - } - count *= static_cast(Factor::num); - } - - // this can't go wrong, right? den>0 is checked earlier. - if (detail::const_check(Factor::den != 1)) { - using common_t = typename std::common_type::type; - count /= static_cast(Factor::den); - } - - // convert to the to type, safely - using ToRep = typename To::rep; - - const ToRep tocount = safe_float_conversion(count, ec); - if (ec) { - return {}; - } - return To{tocount}; -} -} // namespace safe_duration_cast -#endif - -namespace detail { - -// Check if std::chrono::utc_time is available. -#ifdef FMT_USE_UTC_TIME -// Use the provided definition. -#elif defined(__cpp_lib_chrono) -# define FMT_USE_UTC_TIME (__cpp_lib_chrono >= 201907L) -#else -# define FMT_USE_UTC_TIME 0 -#endif -#if FMT_USE_UTC_TIME -using utc_clock = std::chrono::utc_clock; -#else -struct utc_clock { - template void to_sys(T); -}; -#endif - -// Check if std::chrono::local_time is available. -#ifdef FMT_USE_LOCAL_TIME -// Use the provided definition. -#elif defined(__cpp_lib_chrono) -# define FMT_USE_LOCAL_TIME (__cpp_lib_chrono >= 201907L) -#else -# define FMT_USE_LOCAL_TIME 0 -#endif -#if FMT_USE_LOCAL_TIME -using local_t = std::chrono::local_t; -#else -struct local_t {}; -#endif - -} // namespace detail - -template -using sys_time = std::chrono::time_point; - -template -using utc_time = std::chrono::time_point; - -template -using local_time = std::chrono::time_point; - -namespace detail { - -// Prevents expansion of a preceding token as a function-style macro. -// Usage: f FMT_NOMACRO() -#define FMT_NOMACRO - -template struct null {}; -inline auto gmtime_r(...) -> null<> { return null<>(); } -inline auto gmtime_s(...) -> null<> { return null<>(); } - -// It is defined here and not in ostream.h because the latter has expensive -// includes. -template class formatbuf : public StreamBuf { - private: - using char_type = typename StreamBuf::char_type; - using streamsize = decltype(std::declval().sputn(nullptr, 0)); - using int_type = typename StreamBuf::int_type; - using traits_type = typename StreamBuf::traits_type; - - buffer& buffer_; - - public: - explicit formatbuf(buffer& buf) : buffer_(buf) {} - - protected: - // The put area is always empty. This makes the implementation simpler and has - // the advantage that the streambuf and the buffer are always in sync and - // sputc never writes into uninitialized memory. A disadvantage is that each - // call to sputc always results in a (virtual) call to overflow. There is no - // disadvantage here for sputn since this always results in a call to xsputn. - - auto overflow(int_type ch) -> int_type override { - if (!traits_type::eq_int_type(ch, traits_type::eof())) - buffer_.push_back(static_cast(ch)); - return ch; - } - - auto xsputn(const char_type* s, streamsize count) -> streamsize override { - buffer_.append(s, s + count); - return count; - } -}; - -inline auto get_classic_locale() -> const std::locale& { - static const auto& locale = std::locale::classic(); - return locale; -} - -template struct codecvt_result { - static constexpr size_t max_size = 32; - CodeUnit buf[max_size]; - CodeUnit* end; -}; - -template -void write_codecvt(codecvt_result& out, string_view in, - const std::locale& loc) { - FMT_PRAGMA_CLANG(diagnostic push) - FMT_PRAGMA_CLANG(diagnostic ignored "-Wdeprecated") - auto& f = std::use_facet>(loc); - FMT_PRAGMA_CLANG(diagnostic pop) - auto mb = std::mbstate_t(); - const char* from_next = nullptr; - auto result = f.in(mb, in.begin(), in.end(), from_next, std::begin(out.buf), - std::end(out.buf), out.end); - if (result != std::codecvt_base::ok) - FMT_THROW(format_error("failed to format time")); -} - -template -auto write_encoded_tm_str(OutputIt out, string_view in, const std::locale& loc) - -> OutputIt { - if (const_check(detail::use_utf8) && loc != get_classic_locale()) { - // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and - // gcc-4. -#if FMT_MSC_VERSION != 0 || \ - (defined(__GLIBCXX__) && \ - (!defined(_GLIBCXX_USE_DUAL_ABI) || _GLIBCXX_USE_DUAL_ABI == 0)) - // The _GLIBCXX_USE_DUAL_ABI macro is always defined in libstdc++ from gcc-5 - // and newer. - using code_unit = wchar_t; -#else - using code_unit = char32_t; -#endif - - using unit_t = codecvt_result; - unit_t unit; - write_codecvt(unit, in, loc); - // In UTF-8 is used one to four one-byte code units. - auto u = - to_utf8>(); - if (!u.convert({unit.buf, to_unsigned(unit.end - unit.buf)})) - FMT_THROW(format_error("failed to format time")); - return copy(u.c_str(), u.c_str() + u.size(), out); - } - return copy(in.data(), in.data() + in.size(), out); -} - -template ::value)> -auto write_tm_str(OutputIt out, string_view sv, const std::locale& loc) - -> OutputIt { - codecvt_result unit; - write_codecvt(unit, sv, loc); - return copy(unit.buf, unit.end, out); -} - -template ::value)> -auto write_tm_str(OutputIt out, string_view sv, const std::locale& loc) - -> OutputIt { - return write_encoded_tm_str(out, sv, loc); -} - -template -inline void do_write(buffer& buf, const std::tm& time, - const std::locale& loc, char format, char modifier) { - auto&& format_buf = formatbuf>(buf); - auto&& os = std::basic_ostream(&format_buf); - os.imbue(loc); - const auto& facet = std::use_facet>(loc); - auto end = facet.put(os, os, Char(' '), &time, format, modifier); - if (end.failed()) FMT_THROW(format_error("failed to format time")); -} - -template ::value)> -auto write(OutputIt out, const std::tm& time, const std::locale& loc, - char format, char modifier = 0) -> OutputIt { - auto&& buf = get_buffer(out); - do_write(buf, time, loc, format, modifier); - return get_iterator(buf, out); -} - -template ::value)> -auto write(OutputIt out, const std::tm& time, const std::locale& loc, - char format, char modifier = 0) -> OutputIt { - auto&& buf = basic_memory_buffer(); - do_write(buf, time, loc, format, modifier); - return write_encoded_tm_str(out, string_view(buf.data(), buf.size()), loc); -} - -template -using is_similar_arithmetic_type = - bool_constant<(std::is_integral::value && std::is_integral::value) || - (std::is_floating_point::value && - std::is_floating_point::value)>; - -FMT_NORETURN inline void throw_duration_error() { - FMT_THROW(format_error("cannot format duration")); -} - -// Cast one integral duration to another with an overflow check. -template ::value&& - std::is_integral::value)> -auto duration_cast(std::chrono::duration from) -> To { -#if !FMT_SAFE_DURATION_CAST - return std::chrono::duration_cast(from); -#else - // The conversion factor: to.count() == factor * from.count(). - using factor = std::ratio_divide; - - using common_rep = typename std::common_type::type; - common_rep count = from.count(); // This conversion is lossless. - - // Multiply from.count() by factor and check for overflow. - if (const_check(factor::num != 1)) { - if (count > max_value() / factor::num) throw_duration_error(); - const auto min = (std::numeric_limits::min)() / factor::num; - if (const_check(!std::is_unsigned::value) && count < min) - throw_duration_error(); - count *= factor::num; - } - if (const_check(factor::den != 1)) count /= factor::den; - int ec = 0; - auto to = - To(safe_duration_cast::lossless_integral_conversion( - count, ec)); - if (ec) throw_duration_error(); - return to; -#endif -} - -template ::value&& - std::is_floating_point::value)> -auto duration_cast(std::chrono::duration from) -> To { -#if FMT_SAFE_DURATION_CAST - // Preserve infinity and NaN. - if (!isfinite(from.count())) return static_cast(from.count()); - // Throwing version of safe_duration_cast is only available for - // integer to integer or float to float casts. - int ec; - To to = safe_duration_cast::safe_duration_cast(from, ec); - if (ec) throw_duration_error(); - return to; -#else - // Standard duration cast, may overflow. - return std::chrono::duration_cast(from); -#endif -} - -template ::value)> -auto duration_cast(std::chrono::duration from) -> To { - // Mixed integer <-> float cast is not supported by safe duration_cast. - return std::chrono::duration_cast(from); -} - -template -auto to_time_t(sys_time time_point) -> std::time_t { - // Cannot use std::chrono::system_clock::to_time_t since this would first - // require a cast to std::chrono::system_clock::time_point, which could - // overflow. - return detail::duration_cast>( - time_point.time_since_epoch()) - .count(); -} - -} // namespace detail - -FMT_BEGIN_EXPORT - -/** - * Converts given time since epoch as `std::time_t` value into calendar time, - * expressed in Coordinated Universal Time (UTC). Unlike `std::gmtime`, this - * function is thread-safe on most platforms. - */ -inline auto gmtime(std::time_t time) -> std::tm { - struct dispatcher { - std::time_t time_; - std::tm tm_; - - inline dispatcher(std::time_t t) : time_(t) {} - - inline auto run() -> bool { - using namespace fmt::detail; - return handle(gmtime_r(&time_, &tm_)); - } - - inline auto handle(std::tm* tm) -> bool { return tm != nullptr; } - - inline auto handle(detail::null<>) -> bool { - using namespace fmt::detail; - return fallback(gmtime_s(&tm_, &time_)); - } - - inline auto fallback(int res) -> bool { return res == 0; } - -#if !FMT_MSC_VERSION - inline auto fallback(detail::null<>) -> bool { - std::tm* tm = std::gmtime(&time_); - if (tm) tm_ = *tm; - return tm != nullptr; - } -#endif - }; - auto gt = dispatcher(time); - // Too big time values may be unsupported. - if (!gt.run()) FMT_THROW(format_error("time_t value out of range")); - return gt.tm_; -} - -template -inline auto gmtime(sys_time time_point) -> std::tm { - return gmtime(detail::to_time_t(time_point)); -} - -namespace detail { - -// Writes two-digit numbers a, b and c separated by sep to buf. -// The method by Pavel Novikov based on -// https://johnnylee-sde.github.io/Fast-unsigned-integer-to-time-string/. -inline void write_digit2_separated(char* buf, unsigned a, unsigned b, - unsigned c, char sep) { - unsigned long long digits = - a | (b << 24) | (static_cast(c) << 48); - // Convert each value to BCD. - // We have x = a * 10 + b and we want to convert it to BCD y = a * 16 + b. - // The difference is - // y - x = a * 6 - // a can be found from x: - // a = floor(x / 10) - // then - // y = x + a * 6 = x + floor(x / 10) * 6 - // floor(x / 10) is (x * 205) >> 11 (needs 16 bits). - digits += (((digits * 205) >> 11) & 0x000f00000f00000f) * 6; - // Put low nibbles to high bytes and high nibbles to low bytes. - digits = ((digits & 0x00f00000f00000f0) >> 4) | - ((digits & 0x000f00000f00000f) << 8); - auto usep = static_cast(sep); - // Add ASCII '0' to each digit byte and insert separators. - digits |= 0x3030003030003030 | (usep << 16) | (usep << 40); - - constexpr size_t len = 8; - if (const_check(is_big_endian())) { - char tmp[len]; - std::memcpy(tmp, &digits, len); - std::reverse_copy(tmp, tmp + len, buf); - } else { - std::memcpy(buf, &digits, len); - } -} - -template -FMT_CONSTEXPR inline auto get_units() -> const char* { - if (std::is_same::value) return "as"; - if (std::is_same::value) return "fs"; - if (std::is_same::value) return "ps"; - if (std::is_same::value) return "ns"; - if (std::is_same::value) - return detail::use_utf8 ? "µs" : "us"; - if (std::is_same::value) return "ms"; - if (std::is_same::value) return "cs"; - if (std::is_same::value) return "ds"; - if (std::is_same>::value) return "s"; - if (std::is_same::value) return "das"; - if (std::is_same::value) return "hs"; - if (std::is_same::value) return "ks"; - if (std::is_same::value) return "Ms"; - if (std::is_same::value) return "Gs"; - if (std::is_same::value) return "Ts"; - if (std::is_same::value) return "Ps"; - if (std::is_same::value) return "Es"; - if (std::is_same>::value) return "min"; - if (std::is_same>::value) return "h"; - if (std::is_same>::value) return "d"; - return nullptr; -} - -enum class numeric_system { - standard, - // Alternative numeric system, e.g. 十二 instead of 12 in ja_JP locale. - alternative -}; - -// Glibc extensions for formatting numeric values. -enum class pad_type { - // Pad a numeric result string with zeros (the default). - zero, - // Do not pad a numeric result string. - none, - // Pad a numeric result string with spaces. - space, -}; - -template -auto write_padding(OutputIt out, pad_type pad, int width) -> OutputIt { - if (pad == pad_type::none) return out; - return detail::fill_n(out, width, pad == pad_type::space ? ' ' : '0'); -} - -template -auto write_padding(OutputIt out, pad_type pad) -> OutputIt { - if (pad != pad_type::none) *out++ = pad == pad_type::space ? ' ' : '0'; - return out; -} - -// Parses a put_time-like format string and invokes handler actions. -template -FMT_CONSTEXPR auto parse_chrono_format(const Char* begin, const Char* end, - Handler&& handler) -> const Char* { - if (begin == end || *begin == '}') return begin; - if (*begin != '%') FMT_THROW(format_error("invalid format")); - auto ptr = begin; - while (ptr != end) { - pad_type pad = pad_type::zero; - auto c = *ptr; - if (c == '}') break; - if (c != '%') { - ++ptr; - continue; - } - if (begin != ptr) handler.on_text(begin, ptr); - ++ptr; // consume '%' - if (ptr == end) FMT_THROW(format_error("invalid format")); - c = *ptr; - switch (c) { - case '_': - pad = pad_type::space; - ++ptr; - break; - case '-': - pad = pad_type::none; - ++ptr; - break; - } - if (ptr == end) FMT_THROW(format_error("invalid format")); - c = *ptr++; - switch (c) { - case '%': handler.on_text(ptr - 1, ptr); break; - case 'n': { - const Char newline[] = {'\n'}; - handler.on_text(newline, newline + 1); - break; - } - case 't': { - const Char tab[] = {'\t'}; - handler.on_text(tab, tab + 1); - break; - } - // Year: - case 'Y': handler.on_year(numeric_system::standard, pad); break; - case 'y': handler.on_short_year(numeric_system::standard); break; - case 'C': handler.on_century(numeric_system::standard); break; - case 'G': handler.on_iso_week_based_year(); break; - case 'g': handler.on_iso_week_based_short_year(); break; - // Day of the week: - case 'a': handler.on_abbr_weekday(); break; - case 'A': handler.on_full_weekday(); break; - case 'w': handler.on_dec0_weekday(numeric_system::standard); break; - case 'u': handler.on_dec1_weekday(numeric_system::standard); break; - // Month: - case 'b': - case 'h': handler.on_abbr_month(); break; - case 'B': handler.on_full_month(); break; - case 'm': handler.on_dec_month(numeric_system::standard, pad); break; - // Day of the year/month: - case 'U': - handler.on_dec0_week_of_year(numeric_system::standard, pad); - break; - case 'W': - handler.on_dec1_week_of_year(numeric_system::standard, pad); - break; - case 'V': handler.on_iso_week_of_year(numeric_system::standard, pad); break; - case 'j': handler.on_day_of_year(pad); break; - case 'd': handler.on_day_of_month(numeric_system::standard, pad); break; - case 'e': - handler.on_day_of_month(numeric_system::standard, pad_type::space); - break; - // Hour, minute, second: - case 'H': handler.on_24_hour(numeric_system::standard, pad); break; - case 'I': handler.on_12_hour(numeric_system::standard, pad); break; - case 'M': handler.on_minute(numeric_system::standard, pad); break; - case 'S': handler.on_second(numeric_system::standard, pad); break; - // Other: - case 'c': handler.on_datetime(numeric_system::standard); break; - case 'x': handler.on_loc_date(numeric_system::standard); break; - case 'X': handler.on_loc_time(numeric_system::standard); break; - case 'D': handler.on_us_date(); break; - case 'F': handler.on_iso_date(); break; - case 'r': handler.on_12_hour_time(); break; - case 'R': handler.on_24_hour_time(); break; - case 'T': handler.on_iso_time(); break; - case 'p': handler.on_am_pm(); break; - case 'Q': handler.on_duration_value(); break; - case 'q': handler.on_duration_unit(); break; - case 'z': handler.on_utc_offset(numeric_system::standard); break; - case 'Z': handler.on_tz_name(); break; - // Alternative representation: - case 'E': { - if (ptr == end) FMT_THROW(format_error("invalid format")); - c = *ptr++; - switch (c) { - case 'Y': handler.on_year(numeric_system::alternative, pad); break; - case 'y': handler.on_offset_year(); break; - case 'C': handler.on_century(numeric_system::alternative); break; - case 'c': handler.on_datetime(numeric_system::alternative); break; - case 'x': handler.on_loc_date(numeric_system::alternative); break; - case 'X': handler.on_loc_time(numeric_system::alternative); break; - case 'z': handler.on_utc_offset(numeric_system::alternative); break; - default: FMT_THROW(format_error("invalid format")); - } - break; - } - case 'O': - if (ptr == end) FMT_THROW(format_error("invalid format")); - c = *ptr++; - switch (c) { - case 'y': handler.on_short_year(numeric_system::alternative); break; - case 'm': handler.on_dec_month(numeric_system::alternative, pad); break; - case 'U': - handler.on_dec0_week_of_year(numeric_system::alternative, pad); - break; - case 'W': - handler.on_dec1_week_of_year(numeric_system::alternative, pad); - break; - case 'V': - handler.on_iso_week_of_year(numeric_system::alternative, pad); - break; - case 'd': - handler.on_day_of_month(numeric_system::alternative, pad); - break; - case 'e': - handler.on_day_of_month(numeric_system::alternative, pad_type::space); - break; - case 'w': handler.on_dec0_weekday(numeric_system::alternative); break; - case 'u': handler.on_dec1_weekday(numeric_system::alternative); break; - case 'H': handler.on_24_hour(numeric_system::alternative, pad); break; - case 'I': handler.on_12_hour(numeric_system::alternative, pad); break; - case 'M': handler.on_minute(numeric_system::alternative, pad); break; - case 'S': handler.on_second(numeric_system::alternative, pad); break; - case 'z': handler.on_utc_offset(numeric_system::alternative); break; - default: FMT_THROW(format_error("invalid format")); - } - break; - default: FMT_THROW(format_error("invalid format")); - } - begin = ptr; - } - if (begin != ptr) handler.on_text(begin, ptr); - return ptr; -} - -template struct null_chrono_spec_handler { - FMT_CONSTEXPR void unsupported() { - static_cast(this)->unsupported(); - } - FMT_CONSTEXPR void on_year(numeric_system, pad_type) { unsupported(); } - FMT_CONSTEXPR void on_short_year(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_offset_year() { unsupported(); } - FMT_CONSTEXPR void on_century(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_iso_week_based_year() { unsupported(); } - FMT_CONSTEXPR void on_iso_week_based_short_year() { unsupported(); } - FMT_CONSTEXPR void on_abbr_weekday() { unsupported(); } - FMT_CONSTEXPR void on_full_weekday() { unsupported(); } - FMT_CONSTEXPR void on_dec0_weekday(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_dec1_weekday(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_abbr_month() { unsupported(); } - FMT_CONSTEXPR void on_full_month() { unsupported(); } - FMT_CONSTEXPR void on_dec_month(numeric_system, pad_type) { unsupported(); } - FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system, pad_type) { - unsupported(); - } - FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system, pad_type) { - unsupported(); - } - FMT_CONSTEXPR void on_iso_week_of_year(numeric_system, pad_type) { - unsupported(); - } - FMT_CONSTEXPR void on_day_of_year(pad_type) { unsupported(); } - FMT_CONSTEXPR void on_day_of_month(numeric_system, pad_type) { - unsupported(); - } - FMT_CONSTEXPR void on_24_hour(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_12_hour(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_minute(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_second(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_datetime(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_loc_date(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_loc_time(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_us_date() { unsupported(); } - FMT_CONSTEXPR void on_iso_date() { unsupported(); } - FMT_CONSTEXPR void on_12_hour_time() { unsupported(); } - FMT_CONSTEXPR void on_24_hour_time() { unsupported(); } - FMT_CONSTEXPR void on_iso_time() { unsupported(); } - FMT_CONSTEXPR void on_am_pm() { unsupported(); } - FMT_CONSTEXPR void on_duration_value() { unsupported(); } - FMT_CONSTEXPR void on_duration_unit() { unsupported(); } - FMT_CONSTEXPR void on_utc_offset(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_tz_name() { unsupported(); } -}; - -class tm_format_checker : public null_chrono_spec_handler { - private: - bool has_timezone_ = false; - - public: - constexpr explicit tm_format_checker(bool has_timezone) - : has_timezone_(has_timezone) {} - - FMT_NORETURN inline void unsupported() { - FMT_THROW(format_error("no format")); - } - - template - FMT_CONSTEXPR void on_text(const Char*, const Char*) {} - FMT_CONSTEXPR void on_year(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_short_year(numeric_system) {} - FMT_CONSTEXPR void on_offset_year() {} - FMT_CONSTEXPR void on_century(numeric_system) {} - FMT_CONSTEXPR void on_iso_week_based_year() {} - FMT_CONSTEXPR void on_iso_week_based_short_year() {} - FMT_CONSTEXPR void on_abbr_weekday() {} - FMT_CONSTEXPR void on_full_weekday() {} - FMT_CONSTEXPR void on_dec0_weekday(numeric_system) {} - FMT_CONSTEXPR void on_dec1_weekday(numeric_system) {} - FMT_CONSTEXPR void on_abbr_month() {} - FMT_CONSTEXPR void on_full_month() {} - FMT_CONSTEXPR void on_dec_month(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_iso_week_of_year(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_day_of_year(pad_type) {} - FMT_CONSTEXPR void on_day_of_month(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_24_hour(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_12_hour(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_minute(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_second(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_datetime(numeric_system) {} - FMT_CONSTEXPR void on_loc_date(numeric_system) {} - FMT_CONSTEXPR void on_loc_time(numeric_system) {} - FMT_CONSTEXPR void on_us_date() {} - FMT_CONSTEXPR void on_iso_date() {} - FMT_CONSTEXPR void on_12_hour_time() {} - FMT_CONSTEXPR void on_24_hour_time() {} - FMT_CONSTEXPR void on_iso_time() {} - FMT_CONSTEXPR void on_am_pm() {} - FMT_CONSTEXPR void on_utc_offset(numeric_system) { - if (!has_timezone_) FMT_THROW(format_error("no timezone")); - } - FMT_CONSTEXPR void on_tz_name() { - if (!has_timezone_) FMT_THROW(format_error("no timezone")); - } -}; - -inline auto tm_wday_full_name(int wday) -> const char* { - static constexpr const char* full_name_list[] = { - "Sunday", "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday"}; - return wday >= 0 && wday <= 6 ? full_name_list[wday] : "?"; -} -inline auto tm_wday_short_name(int wday) -> const char* { - static constexpr const char* short_name_list[] = {"Sun", "Mon", "Tue", "Wed", - "Thu", "Fri", "Sat"}; - return wday >= 0 && wday <= 6 ? short_name_list[wday] : "???"; -} - -inline auto tm_mon_full_name(int mon) -> const char* { - static constexpr const char* full_name_list[] = { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December"}; - return mon >= 0 && mon <= 11 ? full_name_list[mon] : "?"; -} -inline auto tm_mon_short_name(int mon) -> const char* { - static constexpr const char* short_name_list[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", - }; - return mon >= 0 && mon <= 11 ? short_name_list[mon] : "???"; -} - -template -struct has_tm_gmtoff : std::false_type {}; -template -struct has_tm_gmtoff> : std::true_type {}; - -template struct has_tm_zone : std::false_type {}; -template -struct has_tm_zone> : std::true_type {}; - -template ::value)> -auto set_tm_zone(T& time, char* tz) -> bool { - time.tm_zone = tz; - return true; -} -template ::value)> -auto set_tm_zone(T&, char*) -> bool { - return false; -} - -inline auto utc() -> char* { - static char tz[] = "UTC"; - return tz; -} - -// Converts value to Int and checks that it's in the range [0, upper). -template ::value)> -inline auto to_nonnegative_int(T value, Int upper) -> Int { - if (!std::is_unsigned::value && - (value < 0 || to_unsigned(value) > to_unsigned(upper))) { - FMT_THROW(format_error("chrono value is out of range")); - } - return static_cast(value); -} -template ::value)> -inline auto to_nonnegative_int(T value, Int upper) -> Int { - auto int_value = static_cast(value); - if (int_value < 0 || value > static_cast(upper)) - FMT_THROW(format_error("invalid value")); - return int_value; -} - -constexpr auto pow10(std::uint32_t n) -> long long { - return n == 0 ? 1 : 10 * pow10(n - 1); -} - -// Counts the number of fractional digits in the range [0, 18] according to the -// C++20 spec. If more than 18 fractional digits are required then returns 6 for -// microseconds precision. -template () / 10)> -struct count_fractional_digits { - static constexpr int value = - Num % Den == 0 ? N : count_fractional_digits::value; -}; - -// Base case that doesn't instantiate any more templates -// in order to avoid overflow. -template -struct count_fractional_digits { - static constexpr int value = (Num % Den == 0) ? N : 6; -}; - -// Format subseconds which are given as an integer type with an appropriate -// number of digits. -template -void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) { - constexpr auto num_fractional_digits = - count_fractional_digits::value; - - using subsecond_precision = std::chrono::duration< - typename std::common_type::type, - std::ratio<1, pow10(num_fractional_digits)>>; - - const auto fractional = d - detail::duration_cast(d); - const auto subseconds = - std::chrono::treat_as_floating_point< - typename subsecond_precision::rep>::value - ? fractional.count() - : detail::duration_cast(fractional).count(); - auto n = static_cast>(subseconds); - const int num_digits = count_digits(n); - - int leading_zeroes = (std::max)(0, num_fractional_digits - num_digits); - if (precision < 0) { - FMT_ASSERT(!std::is_floating_point::value, ""); - if (std::ratio_less::value) { - *out++ = '.'; - out = detail::fill_n(out, leading_zeroes, '0'); - out = format_decimal(out, n, num_digits); - } - } else if (precision > 0) { - *out++ = '.'; - leading_zeroes = min_of(leading_zeroes, precision); - int remaining = precision - leading_zeroes; - out = detail::fill_n(out, leading_zeroes, '0'); - if (remaining < num_digits) { - int num_truncated_digits = num_digits - remaining; - n /= to_unsigned(pow10(to_unsigned(num_truncated_digits))); - if (n != 0) out = format_decimal(out, n, remaining); - return; - } - if (n != 0) { - out = format_decimal(out, n, num_digits); - remaining -= num_digits; - } - out = detail::fill_n(out, remaining, '0'); - } -} - -// Format subseconds which are given as a floating point type with an -// appropriate number of digits. We cannot pass the Duration here, as we -// explicitly need to pass the Rep value in the duration_formatter. -template -void write_floating_seconds(memory_buffer& buf, Duration duration, - int num_fractional_digits = -1) { - using rep = typename Duration::rep; - FMT_ASSERT(std::is_floating_point::value, ""); - - auto val = duration.count(); - - if (num_fractional_digits < 0) { - // For `std::round` with fallback to `round`: - // On some toolchains `std::round` is not available (e.g. GCC 6). - using namespace std; - num_fractional_digits = - count_fractional_digits::value; - if (num_fractional_digits < 6 && static_cast(round(val)) != val) - num_fractional_digits = 6; - } - - fmt::format_to(std::back_inserter(buf), FMT_STRING("{:.{}f}"), - std::fmod(val * static_cast(Duration::period::num) / - static_cast(Duration::period::den), - static_cast(60)), - num_fractional_digits); -} - -template -class tm_writer { - private: - static constexpr int days_per_week = 7; - - const std::locale& loc_; - bool is_classic_; - OutputIt out_; - const Duration* subsecs_; - const std::tm& tm_; - - auto tm_sec() const noexcept -> int { - FMT_ASSERT(tm_.tm_sec >= 0 && tm_.tm_sec <= 61, ""); - return tm_.tm_sec; - } - auto tm_min() const noexcept -> int { - FMT_ASSERT(tm_.tm_min >= 0 && tm_.tm_min <= 59, ""); - return tm_.tm_min; - } - auto tm_hour() const noexcept -> int { - FMT_ASSERT(tm_.tm_hour >= 0 && tm_.tm_hour <= 23, ""); - return tm_.tm_hour; - } - auto tm_mday() const noexcept -> int { - FMT_ASSERT(tm_.tm_mday >= 1 && tm_.tm_mday <= 31, ""); - return tm_.tm_mday; - } - auto tm_mon() const noexcept -> int { - FMT_ASSERT(tm_.tm_mon >= 0 && tm_.tm_mon <= 11, ""); - return tm_.tm_mon; - } - auto tm_year() const noexcept -> long long { return 1900ll + tm_.tm_year; } - auto tm_wday() const noexcept -> int { - FMT_ASSERT(tm_.tm_wday >= 0 && tm_.tm_wday <= 6, ""); - return tm_.tm_wday; - } - auto tm_yday() const noexcept -> int { - FMT_ASSERT(tm_.tm_yday >= 0 && tm_.tm_yday <= 365, ""); - return tm_.tm_yday; - } - - auto tm_hour12() const noexcept -> int { - auto h = tm_hour(); - auto z = h < 12 ? h : h - 12; - return z == 0 ? 12 : z; - } - - // POSIX and the C Standard are unclear or inconsistent about what %C and %y - // do if the year is negative or exceeds 9999. Use the convention that %C - // concatenated with %y yields the same output as %Y, and that %Y contains at - // least 4 characters, with more only if necessary. - auto split_year_lower(long long year) const noexcept -> int { - auto l = year % 100; - if (l < 0) l = -l; // l in [0, 99] - return static_cast(l); - } - - // Algorithm: https://en.wikipedia.org/wiki/ISO_week_date. - auto iso_year_weeks(long long curr_year) const noexcept -> int { - auto prev_year = curr_year - 1; - auto curr_p = - (curr_year + curr_year / 4 - curr_year / 100 + curr_year / 400) % - days_per_week; - auto prev_p = - (prev_year + prev_year / 4 - prev_year / 100 + prev_year / 400) % - days_per_week; - return 52 + ((curr_p == 4 || prev_p == 3) ? 1 : 0); - } - auto iso_week_num(int tm_yday, int tm_wday) const noexcept -> int { - return (tm_yday + 11 - (tm_wday == 0 ? days_per_week : tm_wday)) / - days_per_week; - } - auto tm_iso_week_year() const noexcept -> long long { - auto year = tm_year(); - auto w = iso_week_num(tm_yday(), tm_wday()); - if (w < 1) return year - 1; - if (w > iso_year_weeks(year)) return year + 1; - return year; - } - auto tm_iso_week_of_year() const noexcept -> int { - auto year = tm_year(); - auto w = iso_week_num(tm_yday(), tm_wday()); - if (w < 1) return iso_year_weeks(year - 1); - if (w > iso_year_weeks(year)) return 1; - return w; - } - - void write1(int value) { - *out_++ = static_cast('0' + to_unsigned(value) % 10); - } - void write2(int value) { - const char* d = digits2(to_unsigned(value) % 100); - *out_++ = *d++; - *out_++ = *d; - } - void write2(int value, pad_type pad) { - unsigned int v = to_unsigned(value) % 100; - if (v >= 10) { - const char* d = digits2(v); - *out_++ = *d++; - *out_++ = *d; - } else { - out_ = detail::write_padding(out_, pad); - *out_++ = static_cast('0' + v); - } - } - - void write_year_extended(long long year, pad_type pad) { - // At least 4 characters. - int width = 4; - bool negative = year < 0; - if (negative) { - year = 0 - year; - --width; - } - uint32_or_64_or_128_t n = to_unsigned(year); - const int num_digits = count_digits(n); - if (negative && pad == pad_type::zero) *out_++ = '-'; - if (width > num_digits) - out_ = detail::write_padding(out_, pad, width - num_digits); - if (negative && pad != pad_type::zero) *out_++ = '-'; - out_ = format_decimal(out_, n, num_digits); - } - void write_year(long long year, pad_type pad) { - write_year_extended(year, pad); - } - - void write_utc_offset(long long offset, numeric_system ns) { - if (offset < 0) { - *out_++ = '-'; - offset = -offset; - } else { - *out_++ = '+'; - } - offset /= 60; - write2(static_cast(offset / 60)); - if (ns != numeric_system::standard) *out_++ = ':'; - write2(static_cast(offset % 60)); - } - - template ::value)> - void format_utc_offset(const T& tm, numeric_system ns) { - write_utc_offset(tm.tm_gmtoff, ns); - } - template ::value)> - void format_utc_offset(const T&, numeric_system ns) { - write_utc_offset(0, ns); - } - - template ::value)> - void format_tz_name(const T& tm) { - out_ = write_tm_str(out_, tm.tm_zone, loc_); - } - template ::value)> - void format_tz_name(const T&) { - out_ = std::copy_n(utc(), 3, out_); - } - - void format_localized(char format, char modifier = 0) { - out_ = write(out_, tm_, loc_, format, modifier); - } - - public: - tm_writer(const std::locale& loc, OutputIt out, const std::tm& tm, - const Duration* subsecs = nullptr) - : loc_(loc), - is_classic_(loc_ == get_classic_locale()), - out_(out), - subsecs_(subsecs), - tm_(tm) {} - - auto out() const -> OutputIt { return out_; } - - FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) { - out_ = copy(begin, end, out_); - } - - void on_abbr_weekday() { - if (is_classic_) - out_ = write(out_, tm_wday_short_name(tm_wday())); - else - format_localized('a'); - } - void on_full_weekday() { - if (is_classic_) - out_ = write(out_, tm_wday_full_name(tm_wday())); - else - format_localized('A'); - } - void on_dec0_weekday(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) return write1(tm_wday()); - format_localized('w', 'O'); - } - void on_dec1_weekday(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) { - auto wday = tm_wday(); - write1(wday == 0 ? days_per_week : wday); - } else { - format_localized('u', 'O'); - } - } - - void on_abbr_month() { - if (is_classic_) - out_ = write(out_, tm_mon_short_name(tm_mon())); - else - format_localized('b'); - } - void on_full_month() { - if (is_classic_) - out_ = write(out_, tm_mon_full_name(tm_mon())); - else - format_localized('B'); - } - - void on_datetime(numeric_system ns) { - if (is_classic_) { - on_abbr_weekday(); - *out_++ = ' '; - on_abbr_month(); - *out_++ = ' '; - on_day_of_month(numeric_system::standard, pad_type::space); - *out_++ = ' '; - on_iso_time(); - *out_++ = ' '; - on_year(numeric_system::standard, pad_type::space); - } else { - format_localized('c', ns == numeric_system::standard ? '\0' : 'E'); - } - } - void on_loc_date(numeric_system ns) { - if (is_classic_) - on_us_date(); - else - format_localized('x', ns == numeric_system::standard ? '\0' : 'E'); - } - void on_loc_time(numeric_system ns) { - if (is_classic_) - on_iso_time(); - else - format_localized('X', ns == numeric_system::standard ? '\0' : 'E'); - } - void on_us_date() { - char buf[8]; - write_digit2_separated(buf, to_unsigned(tm_mon() + 1), - to_unsigned(tm_mday()), - to_unsigned(split_year_lower(tm_year())), '/'); - out_ = copy(std::begin(buf), std::end(buf), out_); - } - void on_iso_date() { - auto year = tm_year(); - char buf[10]; - size_t offset = 0; - if (year >= 0 && year < 10000) { - write2digits(buf, static_cast(year / 100)); - } else { - offset = 4; - write_year_extended(year, pad_type::zero); - year = 0; - } - write_digit2_separated(buf + 2, static_cast(year % 100), - to_unsigned(tm_mon() + 1), to_unsigned(tm_mday()), - '-'); - out_ = copy(std::begin(buf) + offset, std::end(buf), out_); - } - - void on_utc_offset(numeric_system ns) { format_utc_offset(tm_, ns); } - void on_tz_name() { format_tz_name(tm_); } - - void on_year(numeric_system ns, pad_type pad) { - if (is_classic_ || ns == numeric_system::standard) - return write_year(tm_year(), pad); - format_localized('Y', 'E'); - } - void on_short_year(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) - return write2(split_year_lower(tm_year())); - format_localized('y', 'O'); - } - void on_offset_year() { - if (is_classic_) return write2(split_year_lower(tm_year())); - format_localized('y', 'E'); - } - - void on_century(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) { - auto year = tm_year(); - auto upper = year / 100; - if (year >= -99 && year < 0) { - // Zero upper on negative year. - *out_++ = '-'; - *out_++ = '0'; - } else if (upper >= 0 && upper < 100) { - write2(static_cast(upper)); - } else { - out_ = write(out_, upper); - } - } else { - format_localized('C', 'E'); - } - } - - void on_dec_month(numeric_system ns, pad_type pad) { - if (is_classic_ || ns == numeric_system::standard) - return write2(tm_mon() + 1, pad); - format_localized('m', 'O'); - } - - void on_dec0_week_of_year(numeric_system ns, pad_type pad) { - if (is_classic_ || ns == numeric_system::standard) - return write2((tm_yday() + days_per_week - tm_wday()) / days_per_week, - pad); - format_localized('U', 'O'); - } - void on_dec1_week_of_year(numeric_system ns, pad_type pad) { - if (is_classic_ || ns == numeric_system::standard) { - auto wday = tm_wday(); - write2((tm_yday() + days_per_week - - (wday == 0 ? (days_per_week - 1) : (wday - 1))) / - days_per_week, - pad); - } else { - format_localized('W', 'O'); - } - } - void on_iso_week_of_year(numeric_system ns, pad_type pad) { - if (is_classic_ || ns == numeric_system::standard) - return write2(tm_iso_week_of_year(), pad); - format_localized('V', 'O'); - } - - void on_iso_week_based_year() { - write_year(tm_iso_week_year(), pad_type::zero); - } - void on_iso_week_based_short_year() { - write2(split_year_lower(tm_iso_week_year())); - } - - void on_day_of_year(pad_type pad) { - auto yday = tm_yday() + 1; - auto digit1 = yday / 100; - if (digit1 != 0) - write1(digit1); - else - out_ = detail::write_padding(out_, pad); - write2(yday % 100, pad); - } - - void on_day_of_month(numeric_system ns, pad_type pad) { - if (is_classic_ || ns == numeric_system::standard) - return write2(tm_mday(), pad); - format_localized('d', 'O'); - } - - void on_24_hour(numeric_system ns, pad_type pad) { - if (is_classic_ || ns == numeric_system::standard) - return write2(tm_hour(), pad); - format_localized('H', 'O'); - } - void on_12_hour(numeric_system ns, pad_type pad) { - if (is_classic_ || ns == numeric_system::standard) - return write2(tm_hour12(), pad); - format_localized('I', 'O'); - } - void on_minute(numeric_system ns, pad_type pad) { - if (is_classic_ || ns == numeric_system::standard) - return write2(tm_min(), pad); - format_localized('M', 'O'); - } - - void on_second(numeric_system ns, pad_type pad) { - if (is_classic_ || ns == numeric_system::standard) { - write2(tm_sec(), pad); - if (subsecs_) { - if (std::is_floating_point::value) { - auto buf = memory_buffer(); - write_floating_seconds(buf, *subsecs_); - if (buf.size() > 1) { - // Remove the leading "0", write something like ".123". - out_ = copy(buf.begin() + 1, buf.end(), out_); - } - } else { - write_fractional_seconds(out_, *subsecs_); - } - } - } else { - // Currently no formatting of subseconds when a locale is set. - format_localized('S', 'O'); - } - } - - void on_12_hour_time() { - if (is_classic_) { - char buf[8]; - write_digit2_separated(buf, to_unsigned(tm_hour12()), - to_unsigned(tm_min()), to_unsigned(tm_sec()), ':'); - out_ = copy(std::begin(buf), std::end(buf), out_); - *out_++ = ' '; - on_am_pm(); - } else { - format_localized('r'); - } - } - void on_24_hour_time() { - write2(tm_hour()); - *out_++ = ':'; - write2(tm_min()); - } - void on_iso_time() { - on_24_hour_time(); - *out_++ = ':'; - on_second(numeric_system::standard, pad_type::zero); - } - - void on_am_pm() { - if (is_classic_) { - *out_++ = tm_hour() < 12 ? 'A' : 'P'; - *out_++ = 'M'; - } else { - format_localized('p'); - } - } - - // These apply to chrono durations but not tm. - void on_duration_value() {} - void on_duration_unit() {} -}; - -struct chrono_format_checker : null_chrono_spec_handler { - bool has_precision_integral = false; - - FMT_NORETURN inline void unsupported() { FMT_THROW(format_error("no date")); } - - template - FMT_CONSTEXPR void on_text(const Char*, const Char*) {} - FMT_CONSTEXPR void on_day_of_year(pad_type) {} - FMT_CONSTEXPR void on_24_hour(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_12_hour(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_minute(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_second(numeric_system, pad_type) {} - FMT_CONSTEXPR void on_12_hour_time() {} - FMT_CONSTEXPR void on_24_hour_time() {} - FMT_CONSTEXPR void on_iso_time() {} - FMT_CONSTEXPR void on_am_pm() {} - FMT_CONSTEXPR void on_duration_value() const { - if (has_precision_integral) - FMT_THROW(format_error("precision not allowed for this argument type")); - } - FMT_CONSTEXPR void on_duration_unit() {} -}; - -template ::value&& has_isfinite::value)> -inline auto isfinite(T) -> bool { - return true; -} - -template ::value)> -inline auto mod(T x, int y) -> T { - return x % static_cast(y); -} -template ::value)> -inline auto mod(T x, int y) -> T { - return std::fmod(x, static_cast(y)); -} - -// If T is an integral type, maps T to its unsigned counterpart, otherwise -// leaves it unchanged (unlike std::make_unsigned). -template ::value> -struct make_unsigned_or_unchanged { - using type = T; -}; - -template struct make_unsigned_or_unchanged { - using type = typename std::make_unsigned::type; -}; - -template ::value)> -inline auto get_milliseconds(std::chrono::duration d) - -> std::chrono::duration { - // This may overflow and/or the result may not fit in the target type. -#if FMT_SAFE_DURATION_CAST - using common_seconds_type = - typename std::common_type::type; - auto d_as_common = detail::duration_cast(d); - auto d_as_whole_seconds = - detail::duration_cast(d_as_common); - // This conversion should be nonproblematic. - auto diff = d_as_common - d_as_whole_seconds; - auto ms = detail::duration_cast>(diff); - return ms; -#else - auto s = detail::duration_cast(d); - return detail::duration_cast(d - s); -#endif -} - -template ::value)> -auto format_duration_value(OutputIt out, Rep val, int) -> OutputIt { - return write(out, val); -} - -template ::value)> -auto format_duration_value(OutputIt out, Rep val, int precision) -> OutputIt { - auto specs = format_specs(); - specs.precision = precision; - specs.set_type(precision >= 0 ? presentation_type::fixed - : presentation_type::general); - return write(out, val, specs); -} - -template -auto copy_unit(string_view unit, OutputIt out, Char) -> OutputIt { - return copy(unit.begin(), unit.end(), out); -} - -template -auto copy_unit(string_view unit, OutputIt out, wchar_t) -> OutputIt { - // This works when wchar_t is UTF-32 because units only contain characters - // that have the same representation in UTF-16 and UTF-32. - utf8_to_utf16 u(unit); - return copy(u.c_str(), u.c_str() + u.size(), out); -} - -template -auto format_duration_unit(OutputIt out) -> OutputIt { - if (const char* unit = get_units()) - return copy_unit(string_view(unit), out, Char()); - *out++ = '['; - out = write(out, Period::num); - if (const_check(Period::den != 1)) { - *out++ = '/'; - out = write(out, Period::den); - } - *out++ = ']'; - *out++ = 's'; - return out; -} - -class get_locale { - private: - union { - std::locale locale_; - }; - bool has_locale_ = false; - - public: - inline get_locale(bool localized, locale_ref loc) : has_locale_(localized) { - if (!localized) return; - ignore_unused(loc); - ::new (&locale_) std::locale( -#if FMT_USE_LOCALE - loc.template get() -#endif - ); - } - inline ~get_locale() { - if (has_locale_) locale_.~locale(); - } - inline operator const std::locale&() const { - return has_locale_ ? locale_ : get_classic_locale(); - } -}; - -template -struct duration_formatter { - using iterator = basic_appender; - iterator out; - // rep is unsigned to avoid overflow. - using rep = - conditional_t::value && sizeof(Rep) < sizeof(int), - unsigned, typename make_unsigned_or_unchanged::type>; - rep val; - int precision; - locale_ref locale; - bool localized = false; - using seconds = std::chrono::duration; - seconds s; - using milliseconds = std::chrono::duration; - bool negative; - - using tm_writer_type = tm_writer; - - duration_formatter(iterator o, std::chrono::duration d, - locale_ref loc) - : out(o), val(static_cast(d.count())), locale(loc), negative(false) { - if (d.count() < 0) { - val = 0 - val; - negative = true; - } - - // this may overflow and/or the result may not fit in the - // target type. - // might need checked conversion (rep!=Rep) - s = detail::duration_cast(std::chrono::duration(val)); - } - - // returns true if nan or inf, writes to out. - auto handle_nan_inf() -> bool { - if (isfinite(val)) return false; - if (isnan(val)) { - write_nan(); - return true; - } - // must be +-inf - if (val > 0) - std::copy_n("inf", 3, out); - else - std::copy_n("-inf", 4, out); - return true; - } - - auto days() const -> Rep { return static_cast(s.count() / 86400); } - auto hour() const -> Rep { - return static_cast(mod((s.count() / 3600), 24)); - } - - auto hour12() const -> Rep { - Rep hour = static_cast(mod((s.count() / 3600), 12)); - return hour <= 0 ? 12 : hour; - } - - auto minute() const -> Rep { - return static_cast(mod((s.count() / 60), 60)); - } - auto second() const -> Rep { return static_cast(mod(s.count(), 60)); } - - auto time() const -> std::tm { - auto time = std::tm(); - time.tm_hour = to_nonnegative_int(hour(), 24); - time.tm_min = to_nonnegative_int(minute(), 60); - time.tm_sec = to_nonnegative_int(second(), 60); - return time; - } - - void write_sign() { - if (!negative) return; - *out++ = '-'; - negative = false; - } - - void write(Rep value, int width, pad_type pad = pad_type::zero) { - write_sign(); - if (isnan(value)) return write_nan(); - uint32_or_64_or_128_t n = - to_unsigned(to_nonnegative_int(value, max_value())); - int num_digits = detail::count_digits(n); - if (width > num_digits) { - out = detail::write_padding(out, pad, width - num_digits); - } - out = format_decimal(out, n, num_digits); - } - - void write_nan() { std::copy_n("nan", 3, out); } - - template - void format_tm(const tm& time, Callback cb, Args... args) { - if (isnan(val)) return write_nan(); - get_locale loc(localized, locale); - auto w = tm_writer_type(loc, out, time); - (w.*cb)(args...); - out = w.out(); - } - - void on_text(const Char* begin, const Char* end) { - copy(begin, end, out); - } - - // These are not implemented because durations don't have date information. - void on_abbr_weekday() {} - void on_full_weekday() {} - void on_dec0_weekday(numeric_system) {} - void on_dec1_weekday(numeric_system) {} - void on_abbr_month() {} - void on_full_month() {} - void on_datetime(numeric_system) {} - void on_loc_date(numeric_system) {} - void on_loc_time(numeric_system) {} - void on_us_date() {} - void on_iso_date() {} - void on_utc_offset(numeric_system) {} - void on_tz_name() {} - void on_year(numeric_system, pad_type) {} - void on_short_year(numeric_system) {} - void on_offset_year() {} - void on_century(numeric_system) {} - void on_iso_week_based_year() {} - void on_iso_week_based_short_year() {} - void on_dec_month(numeric_system, pad_type) {} - void on_dec0_week_of_year(numeric_system, pad_type) {} - void on_dec1_week_of_year(numeric_system, pad_type) {} - void on_iso_week_of_year(numeric_system, pad_type) {} - void on_day_of_month(numeric_system, pad_type) {} - - void on_day_of_year(pad_type) { - if (handle_nan_inf()) return; - write(days(), 0); - } - - void on_24_hour(numeric_system ns, pad_type pad) { - if (handle_nan_inf()) return; - - if (ns == numeric_system::standard) return write(hour(), 2, pad); - auto time = tm(); - time.tm_hour = to_nonnegative_int(hour(), 24); - format_tm(time, &tm_writer_type::on_24_hour, ns, pad); - } - - void on_12_hour(numeric_system ns, pad_type pad) { - if (handle_nan_inf()) return; - - if (ns == numeric_system::standard) return write(hour12(), 2, pad); - auto time = tm(); - time.tm_hour = to_nonnegative_int(hour12(), 12); - format_tm(time, &tm_writer_type::on_12_hour, ns, pad); - } - - void on_minute(numeric_system ns, pad_type pad) { - if (handle_nan_inf()) return; - - if (ns == numeric_system::standard) return write(minute(), 2, pad); - auto time = tm(); - time.tm_min = to_nonnegative_int(minute(), 60); - format_tm(time, &tm_writer_type::on_minute, ns, pad); - } - - void on_second(numeric_system ns, pad_type pad) { - if (handle_nan_inf()) return; - - if (ns == numeric_system::standard) { - if (std::is_floating_point::value) { - auto buf = memory_buffer(); - write_floating_seconds(buf, std::chrono::duration(val), - precision); - if (negative) *out++ = '-'; - if (buf.size() < 2 || buf[1] == '.') - out = detail::write_padding(out, pad); - out = copy(buf.begin(), buf.end(), out); - } else { - write(second(), 2, pad); - write_fractional_seconds( - out, std::chrono::duration(val), precision); - } - return; - } - auto time = tm(); - time.tm_sec = to_nonnegative_int(second(), 60); - format_tm(time, &tm_writer_type::on_second, ns, pad); - } - - void on_12_hour_time() { - if (handle_nan_inf()) return; - format_tm(time(), &tm_writer_type::on_12_hour_time); - } - - void on_24_hour_time() { - if (handle_nan_inf()) { - *out++ = ':'; - handle_nan_inf(); - return; - } - - write(hour(), 2); - *out++ = ':'; - write(minute(), 2); - } - - void on_iso_time() { - on_24_hour_time(); - *out++ = ':'; - if (handle_nan_inf()) return; - on_second(numeric_system::standard, pad_type::zero); - } - - void on_am_pm() { - if (handle_nan_inf()) return; - format_tm(time(), &tm_writer_type::on_am_pm); - } - - void on_duration_value() { - if (handle_nan_inf()) return; - write_sign(); - out = format_duration_value(out, val, precision); - } - - void on_duration_unit() { out = format_duration_unit(out); } -}; - -} // namespace detail - -#if defined(__cpp_lib_chrono) && __cpp_lib_chrono >= 201907 -using weekday = std::chrono::weekday; -using day = std::chrono::day; -using month = std::chrono::month; -using year = std::chrono::year; -using year_month_day = std::chrono::year_month_day; -#else -// A fallback version of weekday. -class weekday { - private: - unsigned char value_; - - public: - weekday() = default; - constexpr explicit weekday(unsigned wd) noexcept - : value_(static_cast(wd != 7 ? wd : 0)) {} - constexpr auto c_encoding() const noexcept -> unsigned { return value_; } -}; - -class day { - private: - unsigned char value_; - - public: - day() = default; - constexpr explicit day(unsigned d) noexcept - : value_(static_cast(d)) {} - constexpr explicit operator unsigned() const noexcept { return value_; } -}; - -class month { - private: - unsigned char value_; - - public: - month() = default; - constexpr explicit month(unsigned m) noexcept - : value_(static_cast(m)) {} - constexpr explicit operator unsigned() const noexcept { return value_; } -}; - -class year { - private: - int value_; - - public: - year() = default; - constexpr explicit year(int y) noexcept : value_(y) {} - constexpr explicit operator int() const noexcept { return value_; } -}; - -class year_month_day { - private: - fmt::year year_; - fmt::month month_; - fmt::day day_; - - public: - year_month_day() = default; - constexpr year_month_day(const year& y, const month& m, const day& d) noexcept - : year_(y), month_(m), day_(d) {} - constexpr auto year() const noexcept -> fmt::year { return year_; } - constexpr auto month() const noexcept -> fmt::month { return month_; } - constexpr auto day() const noexcept -> fmt::day { return day_; } -}; -#endif // __cpp_lib_chrono >= 201907 - -template -struct formatter : private formatter { - private: - bool use_tm_formatter_ = false; - - public: - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - auto it = ctx.begin(), end = ctx.end(); - if (it != end && *it == 'L') { - ++it; - this->set_localized(); - } - use_tm_formatter_ = it != end && *it != '}'; - return use_tm_formatter_ ? formatter::parse(ctx) : it; - } - - template - auto format(weekday wd, FormatContext& ctx) const -> decltype(ctx.out()) { - auto time = std::tm(); - time.tm_wday = static_cast(wd.c_encoding()); - if (use_tm_formatter_) return formatter::format(time, ctx); - detail::get_locale loc(this->localized(), ctx.locale()); - auto w = detail::tm_writer(loc, ctx.out(), time); - w.on_abbr_weekday(); - return w.out(); - } -}; - -template -struct formatter : private formatter { - private: - bool use_tm_formatter_ = false; - - public: - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - auto it = ctx.begin(), end = ctx.end(); - use_tm_formatter_ = it != end && *it != '}'; - return use_tm_formatter_ ? formatter::parse(ctx) : it; - } - - template - auto format(day d, FormatContext& ctx) const -> decltype(ctx.out()) { - auto time = std::tm(); - time.tm_mday = static_cast(static_cast(d)); - if (use_tm_formatter_) return formatter::format(time, ctx); - detail::get_locale loc(false, ctx.locale()); - auto w = detail::tm_writer(loc, ctx.out(), time); - w.on_day_of_month(detail::numeric_system::standard, detail::pad_type::zero); - return w.out(); - } -}; - -template -struct formatter : private formatter { - private: - bool use_tm_formatter_ = false; - - public: - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - auto it = ctx.begin(), end = ctx.end(); - if (it != end && *it == 'L') { - ++it; - this->set_localized(); - } - use_tm_formatter_ = it != end && *it != '}'; - return use_tm_formatter_ ? formatter::parse(ctx) : it; - } - - template - auto format(month m, FormatContext& ctx) const -> decltype(ctx.out()) { - auto time = std::tm(); - time.tm_mon = static_cast(static_cast(m)) - 1; - if (use_tm_formatter_) return formatter::format(time, ctx); - detail::get_locale loc(this->localized(), ctx.locale()); - auto w = detail::tm_writer(loc, ctx.out(), time); - w.on_abbr_month(); - return w.out(); - } -}; - -template -struct formatter : private formatter { - private: - bool use_tm_formatter_ = false; - - public: - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - auto it = ctx.begin(), end = ctx.end(); - use_tm_formatter_ = it != end && *it != '}'; - return use_tm_formatter_ ? formatter::parse(ctx) : it; - } - - template - auto format(year y, FormatContext& ctx) const -> decltype(ctx.out()) { - auto time = std::tm(); - time.tm_year = static_cast(y) - 1900; - if (use_tm_formatter_) return formatter::format(time, ctx); - detail::get_locale loc(false, ctx.locale()); - auto w = detail::tm_writer(loc, ctx.out(), time); - w.on_year(detail::numeric_system::standard, detail::pad_type::zero); - return w.out(); - } -}; - -template -struct formatter : private formatter { - private: - bool use_tm_formatter_ = false; - - public: - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - auto it = ctx.begin(), end = ctx.end(); - use_tm_formatter_ = it != end && *it != '}'; - return use_tm_formatter_ ? formatter::parse(ctx) : it; - } - - template - auto format(year_month_day val, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto time = std::tm(); - time.tm_year = static_cast(val.year()) - 1900; - time.tm_mon = static_cast(static_cast(val.month())) - 1; - time.tm_mday = static_cast(static_cast(val.day())); - if (use_tm_formatter_) return formatter::format(time, ctx); - detail::get_locale loc(true, ctx.locale()); - auto w = detail::tm_writer(loc, ctx.out(), time); - w.on_iso_date(); - return w.out(); - } -}; - -template -struct formatter, Char> { - private: - format_specs specs_; - detail::arg_ref width_ref_; - detail::arg_ref precision_ref_; - basic_string_view fmt_; - - public: - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - auto it = ctx.begin(), end = ctx.end(); - if (it == end || *it == '}') return it; - - it = detail::parse_align(it, end, specs_); - if (it == end) return it; - - Char c = *it; - if ((c >= '0' && c <= '9') || c == '{') { - it = detail::parse_width(it, end, specs_, width_ref_, ctx); - if (it == end) return it; - } - - auto checker = detail::chrono_format_checker(); - if (*it == '.') { - checker.has_precision_integral = !std::is_floating_point::value; - it = detail::parse_precision(it, end, specs_, precision_ref_, ctx); - } - if (it != end && *it == 'L') { - specs_.set_localized(); - ++it; - } - end = detail::parse_chrono_format(it, end, checker); - fmt_ = {it, detail::to_unsigned(end - it)}; - return end; - } - - template - auto format(std::chrono::duration d, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto specs = specs_; - auto precision = specs.precision; - specs.precision = -1; - auto begin = fmt_.begin(), end = fmt_.end(); - // As a possible future optimization, we could avoid extra copying if width - // is not specified. - auto buf = basic_memory_buffer(); - auto out = basic_appender(buf); - detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_, - ctx); - detail::handle_dynamic_spec(specs.dynamic_precision(), precision, - precision_ref_, ctx); - if (begin == end || *begin == '}') { - out = detail::format_duration_value(out, d.count(), precision); - detail::format_duration_unit(out); - } else { - auto f = - detail::duration_formatter(out, d, ctx.locale()); - f.precision = precision; - f.localized = specs_.localized(); - detail::parse_chrono_format(begin, end, f); - } - return detail::write( - ctx.out(), basic_string_view(buf.data(), buf.size()), specs); - } -}; - -template struct formatter { - private: - format_specs specs_; - detail::arg_ref width_ref_; - basic_string_view fmt_ = - detail::string_literal(); - - protected: - auto localized() const -> bool { return specs_.localized(); } - FMT_CONSTEXPR void set_localized() { specs_.set_localized(); } - - FMT_CONSTEXPR auto do_parse(parse_context& ctx, bool has_timezone) - -> const Char* { - auto it = ctx.begin(), end = ctx.end(); - if (it == end || *it == '}') return it; - - it = detail::parse_align(it, end, specs_); - if (it == end) return it; - - Char c = *it; - if ((c >= '0' && c <= '9') || c == '{') { - it = detail::parse_width(it, end, specs_, width_ref_, ctx); - if (it == end) return it; - } - - if (*it == 'L') { - specs_.set_localized(); - ++it; - } - - end = detail::parse_chrono_format(it, end, - detail::tm_format_checker(has_timezone)); - // Replace the default format string only if the new spec is not empty. - if (end != it) fmt_ = {it, detail::to_unsigned(end - it)}; - return end; - } - - template - auto do_format(const std::tm& tm, FormatContext& ctx, - const Duration* subsecs) const -> decltype(ctx.out()) { - auto specs = specs_; - auto buf = basic_memory_buffer(); - auto out = basic_appender(buf); - detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_, - ctx); - - auto loc_ref = specs.localized() ? ctx.locale() : locale_ref(); - detail::get_locale loc(static_cast(loc_ref), loc_ref); - auto w = detail::tm_writer, Char, Duration>( - loc, out, tm, subsecs); - detail::parse_chrono_format(fmt_.begin(), fmt_.end(), w); - return detail::write( - ctx.out(), basic_string_view(buf.data(), buf.size()), specs); - } - - public: - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - return do_parse(ctx, detail::has_tm_gmtoff::value); - } - - template - auto format(const std::tm& tm, FormatContext& ctx) const - -> decltype(ctx.out()) { - return do_format(tm, ctx, nullptr); - } -}; - -// DEPRECATED! Reversed order of template parameters. -template -struct formatter, Char> : private formatter { - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - return this->do_parse(ctx, true); - } - - template - auto format(sys_time val, FormatContext& ctx) const - -> decltype(ctx.out()) { - std::tm tm = gmtime(val); - using period = typename Duration::period; - if (detail::const_check( - period::num == 1 && period::den == 1 && - !std::is_floating_point::value)) { - detail::set_tm_zone(tm, detail::utc()); - return formatter::format(tm, ctx); - } - Duration epoch = val.time_since_epoch(); - Duration subsecs = detail::duration_cast( - epoch - detail::duration_cast(epoch)); - if (subsecs.count() < 0) { - auto second = detail::duration_cast(std::chrono::seconds(1)); - if (tm.tm_sec != 0) { - --tm.tm_sec; - } else { - tm = gmtime(val - second); - detail::set_tm_zone(tm, detail::utc()); - } - subsecs += second; - } - return formatter::do_format(tm, ctx, &subsecs); - } -}; - -template -struct formatter, Char> - : formatter, Char> { - template - auto format(utc_time val, FormatContext& ctx) const - -> decltype(ctx.out()) { - return formatter, Char>::format( - detail::utc_clock::to_sys(val), ctx); - } -}; - -template -struct formatter, Char> - : private formatter { - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - return this->do_parse(ctx, false); - } - - template - auto format(local_time val, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto time_since_epoch = val.time_since_epoch(); - auto seconds_since_epoch = - detail::duration_cast(time_since_epoch); - // Use gmtime to prevent time zone conversion since local_time has an - // unspecified time zone. - std::tm t = gmtime(seconds_since_epoch.count()); - using period = typename Duration::period; - if (period::num == 1 && period::den == 1 && - !std::is_floating_point::value) { - return formatter::format(t, ctx); - } - auto subsecs = - detail::duration_cast(time_since_epoch - seconds_since_epoch); - return formatter::do_format(t, ctx, &subsecs); - } -}; - -FMT_END_EXPORT -FMT_END_NAMESPACE - -#endif // FMT_CHRONO_H_ diff --git a/include/libs/spdlog/fmt/bundled/color.h b/include/libs/spdlog/fmt/bundled/color.h deleted file mode 100644 index 2cbc53c..0000000 --- a/include/libs/spdlog/fmt/bundled/color.h +++ /dev/null @@ -1,637 +0,0 @@ -// 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. - -#ifndef FMT_COLOR_H_ -#define FMT_COLOR_H_ - -#include "format.h" - -FMT_BEGIN_NAMESPACE -FMT_BEGIN_EXPORT - -enum class color : uint32_t { - alice_blue = 0xF0F8FF, // rgb(240,248,255) - antique_white = 0xFAEBD7, // rgb(250,235,215) - aqua = 0x00FFFF, // rgb(0,255,255) - aquamarine = 0x7FFFD4, // rgb(127,255,212) - azure = 0xF0FFFF, // rgb(240,255,255) - beige = 0xF5F5DC, // rgb(245,245,220) - bisque = 0xFFE4C4, // rgb(255,228,196) - black = 0x000000, // rgb(0,0,0) - blanched_almond = 0xFFEBCD, // rgb(255,235,205) - blue = 0x0000FF, // rgb(0,0,255) - blue_violet = 0x8A2BE2, // rgb(138,43,226) - brown = 0xA52A2A, // rgb(165,42,42) - burly_wood = 0xDEB887, // rgb(222,184,135) - cadet_blue = 0x5F9EA0, // rgb(95,158,160) - chartreuse = 0x7FFF00, // rgb(127,255,0) - chocolate = 0xD2691E, // rgb(210,105,30) - coral = 0xFF7F50, // rgb(255,127,80) - cornflower_blue = 0x6495ED, // rgb(100,149,237) - cornsilk = 0xFFF8DC, // rgb(255,248,220) - crimson = 0xDC143C, // rgb(220,20,60) - cyan = 0x00FFFF, // rgb(0,255,255) - dark_blue = 0x00008B, // rgb(0,0,139) - dark_cyan = 0x008B8B, // rgb(0,139,139) - dark_golden_rod = 0xB8860B, // rgb(184,134,11) - dark_gray = 0xA9A9A9, // rgb(169,169,169) - dark_green = 0x006400, // rgb(0,100,0) - dark_khaki = 0xBDB76B, // rgb(189,183,107) - dark_magenta = 0x8B008B, // rgb(139,0,139) - dark_olive_green = 0x556B2F, // rgb(85,107,47) - dark_orange = 0xFF8C00, // rgb(255,140,0) - dark_orchid = 0x9932CC, // rgb(153,50,204) - dark_red = 0x8B0000, // rgb(139,0,0) - dark_salmon = 0xE9967A, // rgb(233,150,122) - dark_sea_green = 0x8FBC8F, // rgb(143,188,143) - dark_slate_blue = 0x483D8B, // rgb(72,61,139) - dark_slate_gray = 0x2F4F4F, // rgb(47,79,79) - dark_turquoise = 0x00CED1, // rgb(0,206,209) - dark_violet = 0x9400D3, // rgb(148,0,211) - deep_pink = 0xFF1493, // rgb(255,20,147) - deep_sky_blue = 0x00BFFF, // rgb(0,191,255) - dim_gray = 0x696969, // rgb(105,105,105) - dodger_blue = 0x1E90FF, // rgb(30,144,255) - fire_brick = 0xB22222, // rgb(178,34,34) - floral_white = 0xFFFAF0, // rgb(255,250,240) - forest_green = 0x228B22, // rgb(34,139,34) - fuchsia = 0xFF00FF, // rgb(255,0,255) - gainsboro = 0xDCDCDC, // rgb(220,220,220) - ghost_white = 0xF8F8FF, // rgb(248,248,255) - gold = 0xFFD700, // rgb(255,215,0) - golden_rod = 0xDAA520, // rgb(218,165,32) - gray = 0x808080, // rgb(128,128,128) - green = 0x008000, // rgb(0,128,0) - green_yellow = 0xADFF2F, // rgb(173,255,47) - honey_dew = 0xF0FFF0, // rgb(240,255,240) - hot_pink = 0xFF69B4, // rgb(255,105,180) - indian_red = 0xCD5C5C, // rgb(205,92,92) - indigo = 0x4B0082, // rgb(75,0,130) - ivory = 0xFFFFF0, // rgb(255,255,240) - khaki = 0xF0E68C, // rgb(240,230,140) - lavender = 0xE6E6FA, // rgb(230,230,250) - lavender_blush = 0xFFF0F5, // rgb(255,240,245) - lawn_green = 0x7CFC00, // rgb(124,252,0) - lemon_chiffon = 0xFFFACD, // rgb(255,250,205) - light_blue = 0xADD8E6, // rgb(173,216,230) - light_coral = 0xF08080, // rgb(240,128,128) - light_cyan = 0xE0FFFF, // rgb(224,255,255) - light_golden_rod_yellow = 0xFAFAD2, // rgb(250,250,210) - light_gray = 0xD3D3D3, // rgb(211,211,211) - light_green = 0x90EE90, // rgb(144,238,144) - light_pink = 0xFFB6C1, // rgb(255,182,193) - light_salmon = 0xFFA07A, // rgb(255,160,122) - light_sea_green = 0x20B2AA, // rgb(32,178,170) - light_sky_blue = 0x87CEFA, // rgb(135,206,250) - light_slate_gray = 0x778899, // rgb(119,136,153) - light_steel_blue = 0xB0C4DE, // rgb(176,196,222) - light_yellow = 0xFFFFE0, // rgb(255,255,224) - lime = 0x00FF00, // rgb(0,255,0) - lime_green = 0x32CD32, // rgb(50,205,50) - linen = 0xFAF0E6, // rgb(250,240,230) - magenta = 0xFF00FF, // rgb(255,0,255) - maroon = 0x800000, // rgb(128,0,0) - medium_aquamarine = 0x66CDAA, // rgb(102,205,170) - medium_blue = 0x0000CD, // rgb(0,0,205) - medium_orchid = 0xBA55D3, // rgb(186,85,211) - medium_purple = 0x9370DB, // rgb(147,112,219) - medium_sea_green = 0x3CB371, // rgb(60,179,113) - medium_slate_blue = 0x7B68EE, // rgb(123,104,238) - medium_spring_green = 0x00FA9A, // rgb(0,250,154) - medium_turquoise = 0x48D1CC, // rgb(72,209,204) - medium_violet_red = 0xC71585, // rgb(199,21,133) - midnight_blue = 0x191970, // rgb(25,25,112) - mint_cream = 0xF5FFFA, // rgb(245,255,250) - misty_rose = 0xFFE4E1, // rgb(255,228,225) - moccasin = 0xFFE4B5, // rgb(255,228,181) - navajo_white = 0xFFDEAD, // rgb(255,222,173) - navy = 0x000080, // rgb(0,0,128) - old_lace = 0xFDF5E6, // rgb(253,245,230) - olive = 0x808000, // rgb(128,128,0) - olive_drab = 0x6B8E23, // rgb(107,142,35) - orange = 0xFFA500, // rgb(255,165,0) - orange_red = 0xFF4500, // rgb(255,69,0) - orchid = 0xDA70D6, // rgb(218,112,214) - pale_golden_rod = 0xEEE8AA, // rgb(238,232,170) - pale_green = 0x98FB98, // rgb(152,251,152) - pale_turquoise = 0xAFEEEE, // rgb(175,238,238) - pale_violet_red = 0xDB7093, // rgb(219,112,147) - papaya_whip = 0xFFEFD5, // rgb(255,239,213) - peach_puff = 0xFFDAB9, // rgb(255,218,185) - peru = 0xCD853F, // rgb(205,133,63) - pink = 0xFFC0CB, // rgb(255,192,203) - plum = 0xDDA0DD, // rgb(221,160,221) - powder_blue = 0xB0E0E6, // rgb(176,224,230) - purple = 0x800080, // rgb(128,0,128) - rebecca_purple = 0x663399, // rgb(102,51,153) - red = 0xFF0000, // rgb(255,0,0) - rosy_brown = 0xBC8F8F, // rgb(188,143,143) - royal_blue = 0x4169E1, // rgb(65,105,225) - saddle_brown = 0x8B4513, // rgb(139,69,19) - salmon = 0xFA8072, // rgb(250,128,114) - sandy_brown = 0xF4A460, // rgb(244,164,96) - sea_green = 0x2E8B57, // rgb(46,139,87) - sea_shell = 0xFFF5EE, // rgb(255,245,238) - sienna = 0xA0522D, // rgb(160,82,45) - silver = 0xC0C0C0, // rgb(192,192,192) - sky_blue = 0x87CEEB, // rgb(135,206,235) - slate_blue = 0x6A5ACD, // rgb(106,90,205) - slate_gray = 0x708090, // rgb(112,128,144) - snow = 0xFFFAFA, // rgb(255,250,250) - spring_green = 0x00FF7F, // rgb(0,255,127) - steel_blue = 0x4682B4, // rgb(70,130,180) - tan = 0xD2B48C, // rgb(210,180,140) - teal = 0x008080, // rgb(0,128,128) - thistle = 0xD8BFD8, // rgb(216,191,216) - tomato = 0xFF6347, // rgb(255,99,71) - turquoise = 0x40E0D0, // rgb(64,224,208) - violet = 0xEE82EE, // rgb(238,130,238) - wheat = 0xF5DEB3, // rgb(245,222,179) - white = 0xFFFFFF, // rgb(255,255,255) - white_smoke = 0xF5F5F5, // rgb(245,245,245) - yellow = 0xFFFF00, // rgb(255,255,0) - yellow_green = 0x9ACD32 // rgb(154,205,50) -}; // enum class color - -enum class terminal_color : uint8_t { - black = 30, - red, - green, - yellow, - blue, - magenta, - cyan, - white, - bright_black = 90, - bright_red, - bright_green, - bright_yellow, - bright_blue, - bright_magenta, - bright_cyan, - bright_white -}; - -enum class emphasis : uint8_t { - bold = 1, - faint = 1 << 1, - italic = 1 << 2, - underline = 1 << 3, - blink = 1 << 4, - reverse = 1 << 5, - conceal = 1 << 6, - strikethrough = 1 << 7, -}; - -// 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 { - constexpr rgb() : r(0), g(0), b(0) {} - constexpr rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {} - constexpr rgb(uint32_t hex) - : r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {} - 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 { - -// A bit-packed variant of an RGB color, a terminal color, or unset color. -// see text_style for the bit-packing scheme. -struct color_type { - constexpr color_type() noexcept = default; - constexpr color_type(color rgb_color) noexcept - : value_(static_cast(rgb_color) | (1 << 24)) {} - constexpr color_type(rgb rgb_color) noexcept - : color_type(static_cast( - (static_cast(rgb_color.r) << 16) | - (static_cast(rgb_color.g) << 8) | rgb_color.b)) {} - constexpr color_type(terminal_color term_color) noexcept - : value_(static_cast(term_color) | (3 << 24)) {} - - constexpr auto is_terminal_color() const noexcept -> bool { - return (value_ & (1 << 25)) != 0; - } - - constexpr auto value() const noexcept -> uint32_t { - return value_ & 0xFFFFFF; - } - - constexpr color_type(uint32_t value) noexcept : value_(value) {} - - uint32_t value_ = 0; -}; -} // namespace detail - -/// A text style consisting of foreground and background colors and emphasis. -class text_style { - // The information is packed as follows: - // ┌──┐ - // │ 0│─┐ - // │..│ ├── foreground color value - // │23│─┘ - // ├──┤ - // │24│─┬── discriminator for the above value. 00 if unset, 01 if it's - // │25│─┘ an RGB color, or 11 if it's a terminal color (10 is unused) - // ├──┤ - // │26│──── overflow bit, always zero (see below) - // ├──┤ - // │27│─┐ - // │..│ │ - // │50│ │ - // ├──┤ │ - // │51│ ├── background color (same format as the foreground color) - // │52│ │ - // ├──┤ │ - // │53│─┘ - // ├──┤ - // │54│─┐ - // │..│ ├── emphases - // │61│─┘ - // ├──┤ - // │62│─┬── unused - // │63│─┘ - // └──┘ - // The overflow bits are there to make operator|= efficient. - // When ORing, we must throw if, for either the foreground or background, - // one style specifies a terminal color and the other specifies any color - // (terminal or RGB); in other words, if one discriminator is 11 and the - // other is 11 or 01. - // - // We do that check by adding the styles. Consider what adding does to each - // possible pair of discriminators: - // 00 + 00 = 000 - // 01 + 00 = 001 - // 11 + 00 = 011 - // 01 + 01 = 010 - // 11 + 01 = 100 (!!) - // 11 + 11 = 110 (!!) - // In the last two cases, the ones we want to catch, the third bit——the - // overflow bit——is set. Bingo. - // - // We must take into account the possible carry bit from the bits - // before the discriminator. The only potentially problematic case is - // 11 + 00 = 011 (a carry bit would make it 100, not good!), but a carry - // bit is impossible in that case, because 00 (unset color) means the - // 24 bits that precede the discriminator are all zero. - // - // This test can be applied to both colors simultaneously. - - public: - FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept - : style_(static_cast(em) << 54) {} - - FMT_CONSTEXPR auto operator|=(text_style rhs) -> text_style& { - if (((style_ + rhs.style_) & ((1ULL << 26) | (1ULL << 53))) != 0) - report_error("can't OR a terminal color"); - style_ |= rhs.style_; - return *this; - } - - friend FMT_CONSTEXPR auto operator|(text_style lhs, text_style rhs) - -> text_style { - return lhs |= rhs; - } - - FMT_CONSTEXPR auto operator==(text_style rhs) const noexcept -> bool { - return style_ == rhs.style_; - } - - FMT_CONSTEXPR auto operator!=(text_style rhs) const noexcept -> bool { - return !(*this == rhs); - } - - FMT_CONSTEXPR auto has_foreground() const noexcept -> bool { - return (style_ & (1 << 24)) != 0; - } - FMT_CONSTEXPR auto has_background() const noexcept -> bool { - return (style_ & (1ULL << 51)) != 0; - } - FMT_CONSTEXPR auto has_emphasis() const noexcept -> bool { - return (style_ >> 54) != 0; - } - FMT_CONSTEXPR auto get_foreground() const noexcept -> detail::color_type { - FMT_ASSERT(has_foreground(), "no foreground specified for this style"); - return style_ & 0x3FFFFFF; - } - FMT_CONSTEXPR auto get_background() const noexcept -> detail::color_type { - FMT_ASSERT(has_background(), "no background specified for this style"); - return (style_ >> 27) & 0x3FFFFFF; - } - FMT_CONSTEXPR auto get_emphasis() const noexcept -> emphasis { - FMT_ASSERT(has_emphasis(), "no emphasis specified for this style"); - return static_cast(style_ >> 54); - } - - private: - FMT_CONSTEXPR text_style(uint64_t style) noexcept : style_(style) {} - - friend FMT_CONSTEXPR auto fg(detail::color_type foreground) noexcept - -> text_style; - - friend FMT_CONSTEXPR auto bg(detail::color_type background) noexcept - -> text_style; - - uint64_t style_ = 0; -}; - -/// Creates a text style from the foreground (text) color. -FMT_CONSTEXPR inline auto fg(detail::color_type foreground) noexcept - -> text_style { - return foreground.value_; -} - -/// Creates a text style from the background color. -FMT_CONSTEXPR inline auto bg(detail::color_type background) noexcept - -> text_style { - return static_cast(background.value_) << 27; -} - -FMT_CONSTEXPR inline auto operator|(emphasis lhs, emphasis rhs) noexcept - -> text_style { - return text_style(lhs) | rhs; -} - -namespace detail { - -template struct ansi_color_escape { - FMT_CONSTEXPR ansi_color_escape(color_type text_color, - const char* esc) noexcept { - // If we have a terminal color, we need to output another escape code - // sequence. - if (text_color.is_terminal_color()) { - bool is_background = esc == string_view("\x1b[48;2;"); - uint32_t value = text_color.value(); - // Background ASCII codes are the same as the foreground ones but with - // 10 more. - if (is_background) value += 10u; - - buffer[size++] = static_cast('\x1b'); - buffer[size++] = static_cast('['); - - if (value >= 100u) { - buffer[size++] = static_cast('1'); - value %= 100u; - } - buffer[size++] = static_cast('0' + value / 10u); - buffer[size++] = static_cast('0' + value % 10u); - - buffer[size++] = static_cast('m'); - return; - } - - for (int i = 0; i < 7; i++) { - buffer[i] = static_cast(esc[i]); - } - rgb color(text_color.value()); - to_esc(color.r, buffer + 7, ';'); - to_esc(color.g, buffer + 11, ';'); - to_esc(color.b, buffer + 15, 'm'); - size = 19; - } - FMT_CONSTEXPR ansi_color_escape(emphasis em) noexcept { - uint8_t em_codes[num_emphases] = {}; - if (has_emphasis(em, emphasis::bold)) em_codes[0] = 1; - if (has_emphasis(em, emphasis::faint)) em_codes[1] = 2; - if (has_emphasis(em, emphasis::italic)) em_codes[2] = 3; - if (has_emphasis(em, emphasis::underline)) em_codes[3] = 4; - if (has_emphasis(em, emphasis::blink)) em_codes[4] = 5; - if (has_emphasis(em, emphasis::reverse)) em_codes[5] = 7; - if (has_emphasis(em, emphasis::conceal)) em_codes[6] = 8; - if (has_emphasis(em, emphasis::strikethrough)) em_codes[7] = 9; - - buffer[size++] = static_cast('\x1b'); - buffer[size++] = static_cast('['); - - for (size_t i = 0; i < num_emphases; ++i) { - if (!em_codes[i]) continue; - buffer[size++] = static_cast('0' + em_codes[i]); - buffer[size++] = static_cast(';'); - } - - buffer[size - 1] = static_cast('m'); - } - FMT_CONSTEXPR operator const Char*() const noexcept { return buffer; } - - FMT_CONSTEXPR auto begin() const noexcept -> const Char* { return buffer; } - FMT_CONSTEXPR auto end() const noexcept -> const Char* { - return buffer + size; - } - - private: - static constexpr size_t num_emphases = 8; - Char buffer[7u + 4u * num_emphases] = {}; - size_t size = 0; - - static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out, - char delimiter) noexcept { - out[0] = static_cast('0' + c / 100); - out[1] = static_cast('0' + c / 10 % 10); - out[2] = static_cast('0' + c % 10); - out[3] = static_cast(delimiter); - } - static FMT_CONSTEXPR auto has_emphasis(emphasis em, emphasis mask) noexcept - -> bool { - return static_cast(em) & static_cast(mask); - } -}; - -template -FMT_CONSTEXPR auto make_foreground_color(color_type foreground) noexcept - -> ansi_color_escape { - return ansi_color_escape(foreground, "\x1b[38;2;"); -} - -template -FMT_CONSTEXPR auto make_background_color(color_type background) noexcept - -> ansi_color_escape { - return ansi_color_escape(background, "\x1b[48;2;"); -} - -template -FMT_CONSTEXPR auto make_emphasis(emphasis em) noexcept - -> ansi_color_escape { - return ansi_color_escape(em); -} - -template inline void reset_color(buffer& buffer) { - auto reset_color = string_view("\x1b[0m"); - buffer.append(reset_color.begin(), reset_color.end()); -} - -template struct styled_arg : view { - const T& value; - text_style style; - styled_arg(const T& v, text_style s) : value(v), style(s) {} -}; - -template -void vformat_to(buffer& buf, text_style ts, basic_string_view fmt, - basic_format_args> args) { - if (ts.has_emphasis()) { - auto emphasis = make_emphasis(ts.get_emphasis()); - buf.append(emphasis.begin(), emphasis.end()); - } - if (ts.has_foreground()) { - auto foreground = make_foreground_color(ts.get_foreground()); - buf.append(foreground.begin(), foreground.end()); - } - if (ts.has_background()) { - auto background = make_background_color(ts.get_background()); - buf.append(background.begin(), background.end()); - } - vformat_to(buf, fmt, args); - if (ts != text_style()) reset_color(buf); -} -} // namespace detail - -inline void vprint(FILE* f, text_style ts, string_view fmt, format_args args) { - auto buf = memory_buffer(); - detail::vformat_to(buf, ts, fmt, args); - print(f, FMT_STRING("{}"), string_view(buf.begin(), buf.size())); -} - -/** - * Formats a string and prints it to the specified file stream using ANSI - * escape sequences to specify text formatting. - * - * **Example**: - * - * fmt::print(fmt::emphasis::bold | fg(fmt::color::red), - * "Elapsed time: {0:.2f} seconds", 1.23); - */ -template -void print(FILE* f, text_style ts, format_string fmt, T&&... args) { - vprint(f, ts, fmt.str, vargs{{args...}}); -} - -/** - * Formats a string and prints it to stdout using ANSI escape sequences to - * specify text formatting. - * - * **Example**: - * - * fmt::print(fmt::emphasis::bold | fg(fmt::color::red), - * "Elapsed time: {0:.2f} seconds", 1.23); - */ -template -void print(text_style ts, format_string fmt, T&&... args) { - return print(stdout, ts, fmt, std::forward(args)...); -} - -inline auto vformat(text_style ts, string_view fmt, format_args args) - -> std::string { - auto buf = memory_buffer(); - detail::vformat_to(buf, ts, fmt, args); - return fmt::to_string(buf); -} - -/** - * Formats arguments and returns the result as a string using ANSI escape - * sequences to specify text formatting. - * - * **Example**: - * - * ``` - * #include - * std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red), - * "The answer is {}", 42); - * ``` - */ -template -inline auto format(text_style ts, format_string fmt, T&&... args) - -> std::string { - return fmt::vformat(ts, fmt.str, vargs{{args...}}); -} - -/// Formats a string with the given text_style and writes the output to `out`. -template ::value)> -auto vformat_to(OutputIt out, text_style ts, string_view fmt, format_args args) - -> OutputIt { - auto&& buf = detail::get_buffer(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 out; - * fmt::format_to(std::back_inserter(out), - * fmt::emphasis::bold | fg(fmt::color::red), "{}", 42); - */ -template ::value)> -inline auto format_to(OutputIt out, text_style ts, format_string fmt, - T&&... args) -> OutputIt { - return vformat_to(out, ts, fmt.str, vargs{{args...}}); -} - -template -struct formatter, Char> : formatter { - template - auto format(const detail::styled_arg& arg, FormatContext& ctx) const - -> decltype(ctx.out()) { - const auto& ts = arg.style; - auto out = ctx.out(); - - bool has_style = false; - if (ts.has_emphasis()) { - has_style = true; - auto emphasis = detail::make_emphasis(ts.get_emphasis()); - out = detail::copy(emphasis.begin(), emphasis.end(), out); - } - if (ts.has_foreground()) { - has_style = true; - auto foreground = - detail::make_foreground_color(ts.get_foreground()); - out = detail::copy(foreground.begin(), foreground.end(), out); - } - if (ts.has_background()) { - has_style = true; - auto background = - detail::make_background_color(ts.get_background()); - out = detail::copy(background.begin(), background.end(), out); - } - out = formatter::format(arg.value, ctx); - if (has_style) { - auto reset_color = string_view("\x1b[0m"); - out = detail::copy(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 -FMT_CONSTEXPR auto styled(const T& value, text_style ts) - -> detail::styled_arg> { - return detail::styled_arg>{value, ts}; -} - -FMT_END_EXPORT -FMT_END_NAMESPACE - -#endif // FMT_COLOR_H_ diff --git a/include/libs/spdlog/fmt/bundled/compile.h b/include/libs/spdlog/fmt/bundled/compile.h deleted file mode 100644 index 64eb7a2..0000000 --- a/include/libs/spdlog/fmt/bundled/compile.h +++ /dev/null @@ -1,588 +0,0 @@ -// Formatting library for C++ - experimental format string compilation -// -// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_COMPILE_H_ -#define FMT_COMPILE_H_ - -#ifndef FMT_MODULE -# include // std::back_inserter -#endif - -#include "format.h" - -FMT_BEGIN_NAMESPACE -FMT_BEGIN_EXPORT - -// A compile-time string which is compiled into fast formatting code. -class compiled_string {}; - -template -struct is_compiled_string : std::is_base_of {}; - -/** - * Converts a string literal `s` into a format string that will be parsed at - * compile time and converted into efficient formatting code. Requires C++17 - * `constexpr if` compiler support. - * - * **Example**: - * - * // Converts 42 into std::string using the most efficient method and no - * // runtime format string processing. - * std::string s = fmt::format(FMT_COMPILE("{}"), 42); - */ -#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) -# define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::compiled_string) -#else -# define FMT_COMPILE(s) FMT_STRING(s) -#endif - -/** - * Converts a string literal into a format string that will be parsed at - * compile time and converted into efficient formatting code. Requires support - * for class types in constant template parameters (a C++20 feature). - * - * **Example**: - * - * // Converts 42 into std::string using the most efficient method and no - * // runtime format string processing. - * using namespace fmt::literals; - * std::string s = fmt::format("{}"_cf, 42); - */ -#if FMT_USE_NONTYPE_TEMPLATE_ARGS -inline namespace literals { -template constexpr auto operator""_cf() { - return FMT_COMPILE(Str.data); -} -} // namespace literals -#endif - -FMT_END_EXPORT - -namespace detail { - -template -constexpr auto first(const T& value, const Tail&...) -> const T& { - return value; -} - -#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) -template struct type_list {}; - -// Returns a reference to the argument at index N from [first, rest...]. -template -constexpr auto get([[maybe_unused]] const T& first, - [[maybe_unused]] const Args&... rest) -> const auto& { - static_assert(N < 1 + sizeof...(Args), "index is out of bounds"); - if constexpr (N == 0) - return first; - else - return detail::get(rest...); -} - -# if FMT_USE_NONTYPE_TEMPLATE_ARGS -template -constexpr auto get_arg_index_by_name(basic_string_view name) -> int { - if constexpr (is_static_named_arg()) { - if (name == T::name) return N; - } - if constexpr (sizeof...(Args) > 0) - return get_arg_index_by_name(name); - (void)name; // Workaround an MSVC bug about "unused" parameter. - return -1; -} -# endif - -template -FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view name) -> int { -# if FMT_USE_NONTYPE_TEMPLATE_ARGS - if constexpr (sizeof...(Args) > 0) - return get_arg_index_by_name<0, Args...>(name); -# endif - (void)name; - return -1; -} - -template -constexpr auto get_arg_index_by_name(basic_string_view name, - type_list) -> int { - return get_arg_index_by_name(name); -} - -template struct get_type_impl; - -template struct get_type_impl> { - using type = - remove_cvref_t(std::declval()...))>; -}; - -template -using get_type = typename get_type_impl::type; - -template struct is_compiled_format : std::false_type {}; - -template struct text { - basic_string_view data; - using char_type = Char; - - template - constexpr auto format(OutputIt out, const T&...) const -> OutputIt { - return write(out, data); - } -}; - -template -struct is_compiled_format> : std::true_type {}; - -template -constexpr auto make_text(basic_string_view s, size_t pos, size_t size) - -> text { - return {{&s[pos], size}}; -} - -template struct code_unit { - Char value; - using char_type = Char; - - template - constexpr auto format(OutputIt out, const T&...) const -> OutputIt { - *out++ = value; - return out; - } -}; - -// This ensures that the argument type is convertible to `const T&`. -template -constexpr auto get_arg_checked(const Args&... args) -> const T& { - const auto& arg = detail::get(args...); - if constexpr (detail::is_named_arg>()) { - return arg.value; - } else { - return arg; - } -} - -template -struct is_compiled_format> : std::true_type {}; - -// A replacement field that refers to argument N. -template struct field { - using char_type = Char; - - template - constexpr auto format(OutputIt out, const T&... args) const -> OutputIt { - const V& arg = get_arg_checked(args...); - if constexpr (std::is_convertible>::value) { - auto s = basic_string_view(arg); - return copy(s.begin(), s.end(), out); - } else { - return write(out, arg); - } - } -}; - -template -struct is_compiled_format> : std::true_type {}; - -// A replacement field that refers to argument with name. -template struct runtime_named_field { - using char_type = Char; - basic_string_view name; - - template - constexpr static auto try_format_argument( - OutputIt& out, - // [[maybe_unused]] due to unused-but-set-parameter warning in GCC 7,8,9 - [[maybe_unused]] basic_string_view arg_name, const T& arg) -> bool { - if constexpr (is_named_arg::type>::value) { - if (arg_name == arg.name) { - out = write(out, arg.value); - return true; - } - } - return false; - } - - template - constexpr auto format(OutputIt out, const T&... args) const -> OutputIt { - bool found = (try_format_argument(out, name, args) || ...); - if (!found) { - FMT_THROW(format_error("argument with specified name is not found")); - } - return out; - } -}; - -template -struct is_compiled_format> : std::true_type {}; - -// A replacement field that refers to argument N and has format specifiers. -template struct spec_field { - using char_type = Char; - formatter fmt; - - template - constexpr FMT_INLINE auto format(OutputIt out, const T&... args) const - -> OutputIt { - const auto& vargs = - fmt::make_format_args>(args...); - basic_format_context ctx(out, vargs); - return fmt.format(get_arg_checked(args...), ctx); - } -}; - -template -struct is_compiled_format> : std::true_type {}; - -template struct concat { - L lhs; - R rhs; - using char_type = typename L::char_type; - - template - constexpr auto format(OutputIt out, const T&... args) const -> OutputIt { - out = lhs.format(out, args...); - return rhs.format(out, args...); - } -}; - -template -struct is_compiled_format> : std::true_type {}; - -template -constexpr auto make_concat(L lhs, R rhs) -> concat { - return {lhs, rhs}; -} - -struct unknown_format {}; - -template -constexpr auto parse_text(basic_string_view str, size_t pos) -> size_t { - for (size_t size = str.size(); pos != size; ++pos) { - if (str[pos] == '{' || str[pos] == '}') break; - } - return pos; -} - -template -constexpr auto compile_format_string(S fmt); - -template -constexpr auto parse_tail(T head, S fmt) { - if constexpr (POS != basic_string_view(fmt).size()) { - constexpr auto tail = compile_format_string(fmt); - if constexpr (std::is_same, - unknown_format>()) - return tail; - else - return make_concat(head, tail); - } else { - return head; - } -} - -template struct parse_specs_result { - formatter fmt; - size_t end; - int next_arg_id; -}; - -enum { manual_indexing_id = -1 }; - -template -constexpr auto parse_specs(basic_string_view str, size_t pos, - int next_arg_id) -> parse_specs_result { - str.remove_prefix(pos); - auto ctx = - compile_parse_context(str, max_value(), nullptr, next_arg_id); - auto f = formatter(); - auto end = f.parse(ctx); - return {f, pos + fmt::detail::to_unsigned(end - str.data()), - next_arg_id == 0 ? manual_indexing_id : ctx.next_arg_id()}; -} - -template struct arg_id_handler { - arg_id_kind kind; - arg_ref arg_id; - - constexpr auto on_auto() -> int { - FMT_ASSERT(false, "handler cannot be used with automatic indexing"); - return 0; - } - constexpr auto on_index(int id) -> int { - kind = arg_id_kind::index; - arg_id = arg_ref(id); - return 0; - } - constexpr auto on_name(basic_string_view id) -> int { - kind = arg_id_kind::name; - arg_id = arg_ref(id); - return 0; - } -}; - -template struct parse_arg_id_result { - arg_id_kind kind; - arg_ref arg_id; - const Char* arg_id_end; -}; - -template -constexpr auto parse_arg_id(const Char* begin, const Char* end) { - auto handler = arg_id_handler{arg_id_kind::none, arg_ref{}}; - auto arg_id_end = parse_arg_id(begin, end, handler); - return parse_arg_id_result{handler.kind, handler.arg_id, arg_id_end}; -} - -template struct field_type { - using type = remove_cvref_t; -}; - -template -struct field_type::value>> { - using type = remove_cvref_t; -}; - -template -constexpr auto parse_replacement_field_then_tail(S fmt) { - using char_type = typename S::char_type; - constexpr auto str = basic_string_view(fmt); - constexpr char_type c = END_POS != str.size() ? str[END_POS] : char_type(); - if constexpr (c == '}') { - return parse_tail( - field::type, ARG_INDEX>(), fmt); - } else if constexpr (c != ':') { - FMT_THROW(format_error("expected ':'")); - } else { - constexpr auto result = parse_specs::type>( - str, END_POS + 1, NEXT_ID == manual_indexing_id ? 0 : NEXT_ID); - if constexpr (result.end >= str.size() || str[result.end] != '}') { - FMT_THROW(format_error("expected '}'")); - return 0; - } else { - return parse_tail( - spec_field::type, ARG_INDEX>{ - result.fmt}, - fmt); - } - } -} - -// Compiles a non-empty format string and returns the compiled representation -// or unknown_format() on unrecognized input. -template -constexpr auto compile_format_string(S fmt) { - using char_type = typename S::char_type; - constexpr auto str = basic_string_view(fmt); - if constexpr (str[POS] == '{') { - if constexpr (POS + 1 == str.size()) - FMT_THROW(format_error("unmatched '{' in format string")); - if constexpr (str[POS + 1] == '{') { - return parse_tail(make_text(str, POS, 1), fmt); - } else if constexpr (str[POS + 1] == '}' || str[POS + 1] == ':') { - static_assert(ID != manual_indexing_id, - "cannot switch from manual to automatic argument indexing"); - constexpr auto next_id = - ID != manual_indexing_id ? ID + 1 : manual_indexing_id; - return parse_replacement_field_then_tail, Args, - POS + 1, ID, next_id>(fmt); - } else { - constexpr auto arg_id_result = - parse_arg_id(str.data() + POS + 1, str.data() + str.size()); - constexpr auto arg_id_end_pos = arg_id_result.arg_id_end - str.data(); - constexpr char_type c = - arg_id_end_pos != str.size() ? str[arg_id_end_pos] : char_type(); - static_assert(c == '}' || c == ':', "missing '}' in format string"); - if constexpr (arg_id_result.kind == arg_id_kind::index) { - static_assert( - ID == manual_indexing_id || ID == 0, - "cannot switch from automatic to manual argument indexing"); - constexpr auto arg_index = arg_id_result.arg_id.index; - return parse_replacement_field_then_tail, - Args, arg_id_end_pos, - arg_index, manual_indexing_id>( - fmt); - } else if constexpr (arg_id_result.kind == arg_id_kind::name) { - constexpr auto arg_index = - get_arg_index_by_name(arg_id_result.arg_id.name, Args{}); - if constexpr (arg_index >= 0) { - constexpr auto next_id = - ID != manual_indexing_id ? ID + 1 : manual_indexing_id; - return parse_replacement_field_then_tail< - decltype(get_type::value), Args, arg_id_end_pos, - arg_index, next_id>(fmt); - } else if constexpr (c == '}') { - return parse_tail( - runtime_named_field{arg_id_result.arg_id.name}, fmt); - } else if constexpr (c == ':') { - return unknown_format(); // no type info for specs parsing - } - } - } - } else if constexpr (str[POS] == '}') { - if constexpr (POS + 1 == str.size()) - FMT_THROW(format_error("unmatched '}' in format string")); - return parse_tail(make_text(str, POS, 1), fmt); - } else { - constexpr auto end = parse_text(str, POS + 1); - if constexpr (end - POS > 1) { - return parse_tail(make_text(str, POS, end - POS), fmt); - } else { - return parse_tail(code_unit{str[POS]}, fmt); - } - } -} - -template ::value)> -constexpr auto compile(S fmt) { - constexpr auto str = basic_string_view(fmt); - if constexpr (str.size() == 0) { - return detail::make_text(str, 0, 0); - } else { - constexpr auto result = - detail::compile_format_string, 0, 0>(fmt); - return result; - } -} -#endif // defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) -} // namespace detail - -FMT_BEGIN_EXPORT - -#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) - -template ::value)> -FMT_INLINE FMT_CONSTEXPR_STRING auto format(const CompiledFormat& cf, - const T&... args) - -> std::basic_string { - auto s = std::basic_string(); - cf.format(std::back_inserter(s), args...); - return s; -} - -template ::value)> -constexpr FMT_INLINE auto format_to(OutputIt out, const CompiledFormat& cf, - const T&... args) -> OutputIt { - return cf.format(out, args...); -} - -template ::value)> -FMT_INLINE FMT_CONSTEXPR_STRING auto format(const S&, T&&... args) - -> std::basic_string { - if constexpr (std::is_same::value) { - constexpr auto str = basic_string_view(S()); - if constexpr (str.size() == 2 && str[0] == '{' && str[1] == '}') { - const auto& first = detail::first(args...); - if constexpr (detail::is_named_arg< - remove_cvref_t>::value) { - return fmt::to_string(first.value); - } else { - return fmt::to_string(first); - } - } - } - constexpr auto compiled = detail::compile(S()); - if constexpr (std::is_same, - detail::unknown_format>()) { - return fmt::format( - static_cast>(S()), - std::forward(args)...); - } else { - return fmt::format(compiled, std::forward(args)...); - } -} - -template ::value)> -FMT_CONSTEXPR auto format_to(OutputIt out, const S&, T&&... args) -> OutputIt { - constexpr auto compiled = detail::compile(S()); - if constexpr (std::is_same, - detail::unknown_format>()) { - return fmt::format_to( - out, static_cast>(S()), - std::forward(args)...); - } else { - return fmt::format_to(out, compiled, std::forward(args)...); - } -} -#endif - -template ::value)> -auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args) - -> format_to_n_result { - using traits = detail::fixed_buffer_traits; - auto buf = detail::iterator_buffer(out, n); - fmt::format_to(std::back_inserter(buf), fmt, std::forward(args)...); - return {buf.out(), buf.count()}; -} - -template ::value)> -FMT_CONSTEXPR20 auto formatted_size(const S& fmt, T&&... args) -> size_t { - auto buf = detail::counting_buffer<>(); - fmt::format_to(appender(buf), fmt, std::forward(args)...); - return buf.count(); -} - -template ::value)> -void print(std::FILE* f, const S& fmt, T&&... args) { - auto buf = memory_buffer(); - fmt::format_to(appender(buf), fmt, std::forward(args)...); - detail::print(f, {buf.data(), buf.size()}); -} - -template ::value)> -void print(const S& fmt, T&&... args) { - print(stdout, fmt, std::forward(args)...); -} - -template class static_format_result { - private: - char data[N]; - - public: - template ::value)> - explicit FMT_CONSTEXPR static_format_result(const S& fmt, T&&... args) { - *fmt::format_to(data, fmt, std::forward(args)...) = '\0'; - } - - auto str() const -> fmt::string_view { return {data, N - 1}; } - auto c_str() const -> const char* { return data; } -}; - -/** - * Formats arguments according to the format string `fmt_str` and produces - * a string of the exact required size at compile time. Both the format string - * and the arguments must be compile-time expressions. - * - * The resulting string can be accessed as a C string via `c_str()` or as - * a `fmt::string_view` via `str()`. - * - * **Example**: - * - * // Produces the static string "42" at compile time. - * static constexpr auto result = FMT_STATIC_FORMAT("{}", 42); - * const char* s = result.c_str(); - */ -#define FMT_STATIC_FORMAT(fmt_str, ...) \ - fmt::static_format_result< \ - fmt::formatted_size(FMT_COMPILE(fmt_str), __VA_ARGS__) + 1>( \ - FMT_COMPILE(fmt_str), __VA_ARGS__) - -FMT_END_EXPORT -FMT_END_NAMESPACE - -#endif // FMT_COMPILE_H_ diff --git a/include/libs/spdlog/fmt/bundled/core.h b/include/libs/spdlog/fmt/bundled/core.h deleted file mode 100644 index 8ca735f..0000000 --- a/include/libs/spdlog/fmt/bundled/core.h +++ /dev/null @@ -1,5 +0,0 @@ -// This file is only provided for compatibility and may be removed in future -// versions. Use fmt/base.h if you don't need fmt::format and fmt/format.h -// otherwise. - -#include "format.h" diff --git a/include/libs/spdlog/fmt/bundled/fmt.license.rst b/include/libs/spdlog/fmt/bundled/fmt.license.rst deleted file mode 100644 index 1cd1ef9..0000000 --- a/include/libs/spdlog/fmt/bundled/fmt.license.rst +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---- Optional exception to the license --- - -As an exception, if, as a result of your compiling your source code, portions -of this Software are embedded into a machine-executable object form of such -source code, you may redistribute such embedded portions in such object form -without including the above copyright and permission notices. diff --git a/include/libs/spdlog/fmt/bundled/format-inl.h b/include/libs/spdlog/fmt/bundled/format-inl.h deleted file mode 100644 index 945cb91..0000000 --- a/include/libs/spdlog/fmt/bundled/format-inl.h +++ /dev/null @@ -1,1948 +0,0 @@ -// Formatting library for C++ - implementation -// -// Copyright (c) 2012 - 2016, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_FORMAT_INL_H_ -#define FMT_FORMAT_INL_H_ - -#ifndef FMT_MODULE -# include -# include // errno -# include -# include -# include -#endif - -#if defined(_WIN32) && !defined(FMT_USE_WRITE_CONSOLE) -# include // _isatty -#endif - -#include "format.h" - -#if FMT_USE_LOCALE && !defined(FMT_MODULE) -# include -#endif - -#ifndef FMT_FUNC -# define FMT_FUNC -#endif - -FMT_BEGIN_NAMESPACE - -#ifndef FMT_CUSTOM_ASSERT_FAIL -FMT_FUNC void assert_fail(const char* file, int line, const char* message) { - // Use unchecked std::fprintf to avoid triggering another assertion when - // writing to stderr fails. - std::fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message); - abort(); -} -#endif - -#if FMT_USE_LOCALE -namespace detail { -using std::locale; -using std::numpunct; -using std::use_facet; -} // namespace detail -#else -namespace detail { -struct locale {}; -template struct numpunct { - auto grouping() const -> std::string { return "\03"; } - auto thousands_sep() const -> Char { return ','; } - auto decimal_point() const -> Char { return '.'; } -}; -template Facet use_facet(locale) { return {}; } -} // namespace detail -#endif // FMT_USE_LOCALE - -template auto locale_ref::get() const -> Locale { - using namespace detail; - static_assert(std::is_same::value, ""); -#if FMT_USE_LOCALE - if (locale_) return *static_cast(locale_); -#endif - return locale(); -} - -namespace detail { - -FMT_FUNC void format_error_code(detail::buffer& out, int error_code, - string_view message) noexcept { - // Report error code making sure that the output fits into - // inline_buffer_size to avoid dynamic memory allocation and potential - // bad_alloc. - out.try_resize(0); - static const char SEP[] = ": "; - static const char ERROR_STR[] = "error "; - // Subtract 2 to account for terminating null characters in SEP and ERROR_STR. - size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2; - auto abs_value = static_cast>(error_code); - if (detail::is_negative(error_code)) { - abs_value = 0 - abs_value; - ++error_code_size; - } - error_code_size += detail::to_unsigned(detail::count_digits(abs_value)); - auto it = appender(out); - if (message.size() <= inline_buffer_size - error_code_size) - fmt::format_to(it, FMT_STRING("{}{}"), message, SEP); - fmt::format_to(it, FMT_STRING("{}{}"), ERROR_STR, error_code); - FMT_ASSERT(out.size() <= inline_buffer_size, ""); -} - -FMT_FUNC void do_report_error(format_func func, int error_code, - const char* message) noexcept { - memory_buffer full_message; - func(full_message, error_code, message); - // Don't use fwrite_all because the latter may throw. - if (std::fwrite(full_message.data(), full_message.size(), 1, stderr) > 0) - std::fputc('\n', stderr); -} - -// A wrapper around fwrite that throws on error. -inline void fwrite_all(const void* ptr, size_t count, FILE* stream) { - size_t written = std::fwrite(ptr, 1, count, stream); - if (written < count) - FMT_THROW(system_error(errno, FMT_STRING("cannot write to file"))); -} - -template -FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result { - auto&& facet = use_facet>(loc.get()); - auto grouping = facet.grouping(); - auto thousands_sep = grouping.empty() ? Char() : facet.thousands_sep(); - return {std::move(grouping), thousands_sep}; -} -template -FMT_FUNC auto decimal_point_impl(locale_ref loc) -> Char { - return use_facet>(loc.get()).decimal_point(); -} - -#if FMT_USE_LOCALE -FMT_FUNC auto write_loc(appender out, loc_value value, - const format_specs& specs, locale_ref loc) -> bool { - auto locale = loc.get(); - // We cannot use the num_put facet because it may produce output in - // a wrong encoding. - using facet = format_facet; - if (std::has_facet(locale)) - return use_facet(locale).put(out, value, specs); - return facet(locale).put(out, value, specs); -} -#endif -} // namespace detail - -FMT_FUNC void report_error(const char* message) { -#if FMT_MSC_VERSION || defined(__NVCC__) - // Silence unreachable code warnings in MSVC and NVCC because these - // are nearly impossible to fix in a generic code. - volatile bool b = true; - if (!b) return; -#endif - FMT_THROW(format_error(message)); -} - -template typename Locale::id format_facet::id; - -template format_facet::format_facet(Locale& loc) { - auto& np = detail::use_facet>(loc); - grouping_ = np.grouping(); - if (!grouping_.empty()) separator_ = std::string(1, np.thousands_sep()); -} - -#if FMT_USE_LOCALE -template <> -FMT_API FMT_FUNC auto format_facet::do_put( - appender out, loc_value val, const format_specs& specs) const -> bool { - return val.visit( - detail::loc_writer<>{out, specs, separator_, grouping_, decimal_point_}); -} -#endif - -FMT_FUNC auto vsystem_error(int error_code, string_view fmt, format_args args) - -> std::system_error { - auto ec = std::error_code(error_code, std::generic_category()); - return std::system_error(ec, vformat(fmt, args)); -} - -namespace detail { - -template -inline auto operator==(basic_fp x, basic_fp y) -> bool { - return x.f == y.f && x.e == y.e; -} - -// Compilers should be able to optimize this into the ror instruction. -FMT_INLINE auto rotr(uint32_t n, uint32_t r) noexcept -> uint32_t { - r &= 31; - return (n >> r) | (n << (32 - r)); -} -FMT_INLINE auto rotr(uint64_t n, uint32_t r) noexcept -> uint64_t { - r &= 63; - return (n >> r) | (n << (64 - r)); -} - -// Implementation of Dragonbox algorithm: https://github.com/jk-jeon/dragonbox. -namespace dragonbox { -// Computes upper 64 bits of multiplication of a 32-bit unsigned integer and a -// 64-bit unsigned integer. -inline auto umul96_upper64(uint32_t x, uint64_t y) noexcept -> uint64_t { - return umul128_upper64(static_cast(x) << 32, y); -} - -// Computes lower 128 bits of multiplication of a 64-bit unsigned integer and a -// 128-bit unsigned integer. -inline auto umul192_lower128(uint64_t x, uint128_fallback y) noexcept - -> uint128_fallback { - uint64_t high = x * y.high(); - uint128_fallback high_low = umul128(x, y.low()); - return {high + high_low.high(), high_low.low()}; -} - -// Computes lower 64 bits of multiplication of a 32-bit unsigned integer and a -// 64-bit unsigned integer. -inline auto umul96_lower64(uint32_t x, uint64_t y) noexcept -> uint64_t { - return x * y; -} - -// Various fast log computations. -inline auto floor_log10_pow2_minus_log10_4_over_3(int e) noexcept -> int { - FMT_ASSERT(e <= 2936 && e >= -2985, "too large exponent"); - return (e * 631305 - 261663) >> 21; -} - -FMT_INLINE_VARIABLE constexpr struct div_small_pow10_infos_struct { - uint32_t divisor; - int shift_amount; -} div_small_pow10_infos[] = {{10, 16}, {100, 16}}; - -// Replaces n by floor(n / pow(10, N)) returning true if and only if n is -// divisible by pow(10, N). -// Precondition: n <= pow(10, N + 1). -template -auto check_divisibility_and_divide_by_pow10(uint32_t& n) noexcept -> bool { - // The numbers below are chosen such that: - // 1. floor(n/d) = floor(nm / 2^k) where d=10 or d=100, - // 2. nm mod 2^k < m if and only if n is divisible by d, - // where m is magic_number, k is shift_amount - // and d is divisor. - // - // Item 1 is a common technique of replacing division by a constant with - // multiplication, see e.g. "Division by Invariant Integers Using - // Multiplication" by Granlund and Montgomery (1994). magic_number (m) is set - // to ceil(2^k/d) for large enough k. - // The idea for item 2 originates from Schubfach. - constexpr auto info = div_small_pow10_infos[N - 1]; - FMT_ASSERT(n <= info.divisor * 10, "n is too large"); - constexpr uint32_t magic_number = - (1u << info.shift_amount) / info.divisor + 1; - n *= magic_number; - const uint32_t comparison_mask = (1u << info.shift_amount) - 1; - bool result = (n & comparison_mask) < magic_number; - n >>= info.shift_amount; - return result; -} - -// Computes floor(n / pow(10, N)) for small n and N. -// Precondition: n <= pow(10, N + 1). -template auto small_division_by_pow10(uint32_t n) noexcept -> uint32_t { - constexpr auto info = div_small_pow10_infos[N - 1]; - FMT_ASSERT(n <= info.divisor * 10, "n is too large"); - constexpr uint32_t magic_number = - (1u << info.shift_amount) / info.divisor + 1; - return (n * magic_number) >> info.shift_amount; -} - -// Computes floor(n / 10^(kappa + 1)) (float) -inline auto divide_by_10_to_kappa_plus_1(uint32_t n) noexcept -> uint32_t { - // 1374389535 = ceil(2^37/100) - return static_cast((static_cast(n) * 1374389535) >> 37); -} -// Computes floor(n / 10^(kappa + 1)) (double) -inline auto divide_by_10_to_kappa_plus_1(uint64_t n) noexcept -> uint64_t { - // 2361183241434822607 = ceil(2^(64+7)/1000) - return umul128_upper64(n, 2361183241434822607ull) >> 7; -} - -// Various subroutines using pow10 cache -template struct cache_accessor; - -template <> struct cache_accessor { - using carrier_uint = float_info::carrier_uint; - using cache_entry_type = uint64_t; - - static auto get_cached_power(int k) noexcept -> uint64_t { - FMT_ASSERT(k >= float_info::min_k && k <= float_info::max_k, - "k is out of range"); - static constexpr uint64_t pow10_significands[] = { - 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f, - 0xfd87b5f28300ca0e, 0x9e74d1b791e07e49, 0xc612062576589ddb, - 0xf79687aed3eec552, 0x9abe14cd44753b53, 0xc16d9a0095928a28, - 0xf1c90080baf72cb2, 0x971da05074da7bef, 0xbce5086492111aeb, - 0xec1e4a7db69561a6, 0x9392ee8e921d5d08, 0xb877aa3236a4b44a, - 0xe69594bec44de15c, 0x901d7cf73ab0acda, 0xb424dc35095cd810, - 0xe12e13424bb40e14, 0x8cbccc096f5088cc, 0xafebff0bcb24aaff, - 0xdbe6fecebdedd5bf, 0x89705f4136b4a598, 0xabcc77118461cefd, - 0xd6bf94d5e57a42bd, 0x8637bd05af6c69b6, 0xa7c5ac471b478424, - 0xd1b71758e219652c, 0x83126e978d4fdf3c, 0xa3d70a3d70a3d70b, - 0xcccccccccccccccd, 0x8000000000000000, 0xa000000000000000, - 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000, - 0xc350000000000000, 0xf424000000000000, 0x9896800000000000, - 0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000, - 0xba43b74000000000, 0xe8d4a51000000000, 0x9184e72a00000000, - 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000, - 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000, - 0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000, - 0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0, - 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940985, - 0xa18f07d736b90be6, 0xc9f2c9cd04674edf, 0xfc6f7c4045812297, - 0x9dc5ada82b70b59e, 0xc5371912364ce306, 0xf684df56c3e01bc7, - 0x9a130b963a6c115d, 0xc097ce7bc90715b4, 0xf0bdc21abb48db21, - 0x96769950b50d88f5, 0xbc143fa4e250eb32, 0xeb194f8e1ae525fe, - 0x92efd1b8d0cf37bf, 0xb7abc627050305ae, 0xe596b7b0c643c71a, - 0x8f7e32ce7bea5c70, 0xb35dbf821ae4f38c, 0xe0352f62a19e306f}; - return pow10_significands[k - float_info::min_k]; - } - - struct compute_mul_result { - carrier_uint result; - bool is_integer; - }; - struct compute_mul_parity_result { - bool parity; - bool is_integer; - }; - - static auto compute_mul(carrier_uint u, - const cache_entry_type& cache) noexcept - -> compute_mul_result { - auto r = umul96_upper64(u, cache); - return {static_cast(r >> 32), - static_cast(r) == 0}; - } - - static auto compute_delta(const cache_entry_type& cache, int beta) noexcept - -> uint32_t { - return static_cast(cache >> (64 - 1 - beta)); - } - - static auto compute_mul_parity(carrier_uint two_f, - const cache_entry_type& cache, - int beta) noexcept - -> compute_mul_parity_result { - FMT_ASSERT(beta >= 1, ""); - FMT_ASSERT(beta < 64, ""); - - auto r = umul96_lower64(two_f, cache); - return {((r >> (64 - beta)) & 1) != 0, - static_cast(r >> (32 - beta)) == 0}; - } - - static auto compute_left_endpoint_for_shorter_interval_case( - const cache_entry_type& cache, int beta) noexcept -> carrier_uint { - return static_cast( - (cache - (cache >> (num_significand_bits() + 2))) >> - (64 - num_significand_bits() - 1 - beta)); - } - - static auto compute_right_endpoint_for_shorter_interval_case( - const cache_entry_type& cache, int beta) noexcept -> carrier_uint { - return static_cast( - (cache + (cache >> (num_significand_bits() + 1))) >> - (64 - num_significand_bits() - 1 - beta)); - } - - static auto compute_round_up_for_shorter_interval_case( - const cache_entry_type& cache, int beta) noexcept -> carrier_uint { - return (static_cast( - cache >> (64 - num_significand_bits() - 2 - beta)) + - 1) / - 2; - } -}; - -template <> struct cache_accessor { - using carrier_uint = float_info::carrier_uint; - using cache_entry_type = uint128_fallback; - - static auto get_cached_power(int k) noexcept -> uint128_fallback { - FMT_ASSERT(k >= float_info::min_k && k <= float_info::max_k, - "k is out of range"); - - static constexpr uint128_fallback pow10_significands[] = { -#if FMT_USE_FULL_CACHE_DRAGONBOX - {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b}, - {0x9faacf3df73609b1, 0x77b191618c54e9ad}, - {0xc795830d75038c1d, 0xd59df5b9ef6a2418}, - {0xf97ae3d0d2446f25, 0x4b0573286b44ad1e}, - {0x9becce62836ac577, 0x4ee367f9430aec33}, - {0xc2e801fb244576d5, 0x229c41f793cda740}, - {0xf3a20279ed56d48a, 0x6b43527578c11110}, - {0x9845418c345644d6, 0x830a13896b78aaaa}, - {0xbe5691ef416bd60c, 0x23cc986bc656d554}, - {0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa9}, - {0x94b3a202eb1c3f39, 0x7bf7d71432f3d6aa}, - {0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc54}, - {0xe858ad248f5c22c9, 0xd1b3400f8f9cff69}, - {0x91376c36d99995be, 0x23100809b9c21fa2}, - {0xb58547448ffffb2d, 0xabd40a0c2832a78b}, - {0xe2e69915b3fff9f9, 0x16c90c8f323f516d}, - {0x8dd01fad907ffc3b, 0xae3da7d97f6792e4}, - {0xb1442798f49ffb4a, 0x99cd11cfdf41779d}, - {0xdd95317f31c7fa1d, 0x40405643d711d584}, - {0x8a7d3eef7f1cfc52, 0x482835ea666b2573}, - {0xad1c8eab5ee43b66, 0xda3243650005eed0}, - {0xd863b256369d4a40, 0x90bed43e40076a83}, - {0x873e4f75e2224e68, 0x5a7744a6e804a292}, - {0xa90de3535aaae202, 0x711515d0a205cb37}, - {0xd3515c2831559a83, 0x0d5a5b44ca873e04}, - {0x8412d9991ed58091, 0xe858790afe9486c3}, - {0xa5178fff668ae0b6, 0x626e974dbe39a873}, - {0xce5d73ff402d98e3, 0xfb0a3d212dc81290}, - {0x80fa687f881c7f8e, 0x7ce66634bc9d0b9a}, - {0xa139029f6a239f72, 0x1c1fffc1ebc44e81}, - {0xc987434744ac874e, 0xa327ffb266b56221}, - {0xfbe9141915d7a922, 0x4bf1ff9f0062baa9}, - {0x9d71ac8fada6c9b5, 0x6f773fc3603db4aa}, - {0xc4ce17b399107c22, 0xcb550fb4384d21d4}, - {0xf6019da07f549b2b, 0x7e2a53a146606a49}, - {0x99c102844f94e0fb, 0x2eda7444cbfc426e}, - {0xc0314325637a1939, 0xfa911155fefb5309}, - {0xf03d93eebc589f88, 0x793555ab7eba27cb}, - {0x96267c7535b763b5, 0x4bc1558b2f3458df}, - {0xbbb01b9283253ca2, 0x9eb1aaedfb016f17}, - {0xea9c227723ee8bcb, 0x465e15a979c1cadd}, - {0x92a1958a7675175f, 0x0bfacd89ec191eca}, - {0xb749faed14125d36, 0xcef980ec671f667c}, - {0xe51c79a85916f484, 0x82b7e12780e7401b}, - {0x8f31cc0937ae58d2, 0xd1b2ecb8b0908811}, - {0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa16}, - {0xdfbdcece67006ac9, 0x67a791e093e1d49b}, - {0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e1}, - {0xaecc49914078536d, 0x58fae9f773886e19}, - {0xda7f5bf590966848, 0xaf39a475506a899f}, - {0x888f99797a5e012d, 0x6d8406c952429604}, - {0xaab37fd7d8f58178, 0xc8e5087ba6d33b84}, - {0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a65}, - {0x855c3be0a17fcd26, 0x5cf2eea09a550680}, - {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f}, - {0xd0601d8efc57b08b, 0xf13b94daf124da27}, - {0x823c12795db6ce57, 0x76c53d08d6b70859}, - {0xa2cb1717b52481ed, 0x54768c4b0c64ca6f}, - {0xcb7ddcdda26da268, 0xa9942f5dcf7dfd0a}, - {0xfe5d54150b090b02, 0xd3f93b35435d7c4d}, - {0x9efa548d26e5a6e1, 0xc47bc5014a1a6db0}, - {0xc6b8e9b0709f109a, 0x359ab6419ca1091c}, - {0xf867241c8cc6d4c0, 0xc30163d203c94b63}, - {0x9b407691d7fc44f8, 0x79e0de63425dcf1e}, - {0xc21094364dfb5636, 0x985915fc12f542e5}, - {0xf294b943e17a2bc4, 0x3e6f5b7b17b2939e}, - {0x979cf3ca6cec5b5a, 0xa705992ceecf9c43}, - {0xbd8430bd08277231, 0x50c6ff782a838354}, - {0xece53cec4a314ebd, 0xa4f8bf5635246429}, - {0x940f4613ae5ed136, 0x871b7795e136be9a}, - {0xb913179899f68584, 0x28e2557b59846e40}, - {0xe757dd7ec07426e5, 0x331aeada2fe589d0}, - {0x9096ea6f3848984f, 0x3ff0d2c85def7622}, - {0xb4bca50b065abe63, 0x0fed077a756b53aa}, - {0xe1ebce4dc7f16dfb, 0xd3e8495912c62895}, - {0x8d3360f09cf6e4bd, 0x64712dd7abbbd95d}, - {0xb080392cc4349dec, 0xbd8d794d96aacfb4}, - {0xdca04777f541c567, 0xecf0d7a0fc5583a1}, - {0x89e42caaf9491b60, 0xf41686c49db57245}, - {0xac5d37d5b79b6239, 0x311c2875c522ced6}, - {0xd77485cb25823ac7, 0x7d633293366b828c}, - {0x86a8d39ef77164bc, 0xae5dff9c02033198}, - {0xa8530886b54dbdeb, 0xd9f57f830283fdfd}, - {0xd267caa862a12d66, 0xd072df63c324fd7c}, - {0x8380dea93da4bc60, 0x4247cb9e59f71e6e}, - {0xa46116538d0deb78, 0x52d9be85f074e609}, - {0xcd795be870516656, 0x67902e276c921f8c}, - {0x806bd9714632dff6, 0x00ba1cd8a3db53b7}, - {0xa086cfcd97bf97f3, 0x80e8a40eccd228a5}, - {0xc8a883c0fdaf7df0, 0x6122cd128006b2ce}, - {0xfad2a4b13d1b5d6c, 0x796b805720085f82}, - {0x9cc3a6eec6311a63, 0xcbe3303674053bb1}, - {0xc3f490aa77bd60fc, 0xbedbfc4411068a9d}, - {0xf4f1b4d515acb93b, 0xee92fb5515482d45}, - {0x991711052d8bf3c5, 0x751bdd152d4d1c4b}, - {0xbf5cd54678eef0b6, 0xd262d45a78a0635e}, - {0xef340a98172aace4, 0x86fb897116c87c35}, - {0x9580869f0e7aac0e, 0xd45d35e6ae3d4da1}, - {0xbae0a846d2195712, 0x8974836059cca10a}, - {0xe998d258869facd7, 0x2bd1a438703fc94c}, - {0x91ff83775423cc06, 0x7b6306a34627ddd0}, - {0xb67f6455292cbf08, 0x1a3bc84c17b1d543}, - {0xe41f3d6a7377eeca, 0x20caba5f1d9e4a94}, - {0x8e938662882af53e, 0x547eb47b7282ee9d}, - {0xb23867fb2a35b28d, 0xe99e619a4f23aa44}, - {0xdec681f9f4c31f31, 0x6405fa00e2ec94d5}, - {0x8b3c113c38f9f37e, 0xde83bc408dd3dd05}, - {0xae0b158b4738705e, 0x9624ab50b148d446}, - {0xd98ddaee19068c76, 0x3badd624dd9b0958}, - {0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d7}, - {0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4d}, - {0xd47487cc8470652b, 0x7647c32000696720}, - {0x84c8d4dfd2c63f3b, 0x29ecd9f40041e074}, - {0xa5fb0a17c777cf09, 0xf468107100525891}, - {0xcf79cc9db955c2cc, 0x7182148d4066eeb5}, - {0x81ac1fe293d599bf, 0xc6f14cd848405531}, - {0xa21727db38cb002f, 0xb8ada00e5a506a7d}, - {0xca9cf1d206fdc03b, 0xa6d90811f0e4851d}, - {0xfd442e4688bd304a, 0x908f4a166d1da664}, - {0x9e4a9cec15763e2e, 0x9a598e4e043287ff}, - {0xc5dd44271ad3cdba, 0x40eff1e1853f29fe}, - {0xf7549530e188c128, 0xd12bee59e68ef47d}, - {0x9a94dd3e8cf578b9, 0x82bb74f8301958cf}, - {0xc13a148e3032d6e7, 0xe36a52363c1faf02}, - {0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac2}, - {0x96f5600f15a7b7e5, 0x29ab103a5ef8c0ba}, - {0xbcb2b812db11a5de, 0x7415d448f6b6f0e8}, - {0xebdf661791d60f56, 0x111b495b3464ad22}, - {0x936b9fcebb25c995, 0xcab10dd900beec35}, - {0xb84687c269ef3bfb, 0x3d5d514f40eea743}, - {0xe65829b3046b0afa, 0x0cb4a5a3112a5113}, - {0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ac}, - {0xb3f4e093db73a093, 0x59ed216765690f57}, - {0xe0f218b8d25088b8, 0x306869c13ec3532d}, - {0x8c974f7383725573, 0x1e414218c73a13fc}, - {0xafbd2350644eeacf, 0xe5d1929ef90898fb}, - {0xdbac6c247d62a583, 0xdf45f746b74abf3a}, - {0x894bc396ce5da772, 0x6b8bba8c328eb784}, - {0xab9eb47c81f5114f, 0x066ea92f3f326565}, - {0xd686619ba27255a2, 0xc80a537b0efefebe}, - {0x8613fd0145877585, 0xbd06742ce95f5f37}, - {0xa798fc4196e952e7, 0x2c48113823b73705}, - {0xd17f3b51fca3a7a0, 0xf75a15862ca504c6}, - {0x82ef85133de648c4, 0x9a984d73dbe722fc}, - {0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebbb}, - {0xcc963fee10b7d1b3, 0x318df905079926a9}, - {0xffbbcfe994e5c61f, 0xfdf17746497f7053}, - {0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa634}, - {0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc1}, - {0xf9bd690a1b68637b, 0x3dfdce7aa3c673b1}, - {0x9c1661a651213e2d, 0x06bea10ca65c084f}, - {0xc31bfa0fe5698db8, 0x486e494fcff30a63}, - {0xf3e2f893dec3f126, 0x5a89dba3c3efccfb}, - {0x986ddb5c6b3a76b7, 0xf89629465a75e01d}, - {0xbe89523386091465, 0xf6bbb397f1135824}, - {0xee2ba6c0678b597f, 0x746aa07ded582e2d}, - {0x94db483840b717ef, 0xa8c2a44eb4571cdd}, - {0xba121a4650e4ddeb, 0x92f34d62616ce414}, - {0xe896a0d7e51e1566, 0x77b020baf9c81d18}, - {0x915e2486ef32cd60, 0x0ace1474dc1d122f}, - {0xb5b5ada8aaff80b8, 0x0d819992132456bb}, - {0xe3231912d5bf60e6, 0x10e1fff697ed6c6a}, - {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2}, - {0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb3}, - {0xddd0467c64bce4a0, 0xac7cb3f6d05ddbdf}, - {0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96c}, - {0xad4ab7112eb3929d, 0x86c16c98d2c953c7}, - {0xd89d64d57a607744, 0xe871c7bf077ba8b8}, - {0x87625f056c7c4a8b, 0x11471cd764ad4973}, - {0xa93af6c6c79b5d2d, 0xd598e40d3dd89bd0}, - {0xd389b47879823479, 0x4aff1d108d4ec2c4}, - {0x843610cb4bf160cb, 0xcedf722a585139bb}, - {0xa54394fe1eedb8fe, 0xc2974eb4ee658829}, - {0xce947a3da6a9273e, 0x733d226229feea33}, - {0x811ccc668829b887, 0x0806357d5a3f5260}, - {0xa163ff802a3426a8, 0xca07c2dcb0cf26f8}, - {0xc9bcff6034c13052, 0xfc89b393dd02f0b6}, - {0xfc2c3f3841f17c67, 0xbbac2078d443ace3}, - {0x9d9ba7832936edc0, 0xd54b944b84aa4c0e}, - {0xc5029163f384a931, 0x0a9e795e65d4df12}, - {0xf64335bcf065d37d, 0x4d4617b5ff4a16d6}, - {0x99ea0196163fa42e, 0x504bced1bf8e4e46}, - {0xc06481fb9bcf8d39, 0xe45ec2862f71e1d7}, - {0xf07da27a82c37088, 0x5d767327bb4e5a4d}, - {0x964e858c91ba2655, 0x3a6a07f8d510f870}, - {0xbbe226efb628afea, 0x890489f70a55368c}, - {0xeadab0aba3b2dbe5, 0x2b45ac74ccea842f}, - {0x92c8ae6b464fc96f, 0x3b0b8bc90012929e}, - {0xb77ada0617e3bbcb, 0x09ce6ebb40173745}, - {0xe55990879ddcaabd, 0xcc420a6a101d0516}, - {0x8f57fa54c2a9eab6, 0x9fa946824a12232e}, - {0xb32df8e9f3546564, 0x47939822dc96abfa}, - {0xdff9772470297ebd, 0x59787e2b93bc56f8}, - {0x8bfbea76c619ef36, 0x57eb4edb3c55b65b}, - {0xaefae51477a06b03, 0xede622920b6b23f2}, - {0xdab99e59958885c4, 0xe95fab368e45ecee}, - {0x88b402f7fd75539b, 0x11dbcb0218ebb415}, - {0xaae103b5fcd2a881, 0xd652bdc29f26a11a}, - {0xd59944a37c0752a2, 0x4be76d3346f04960}, - {0x857fcae62d8493a5, 0x6f70a4400c562ddc}, - {0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb953}, - {0xd097ad07a71f26b2, 0x7e2000a41346a7a8}, - {0x825ecc24c873782f, 0x8ed400668c0c28c9}, - {0xa2f67f2dfa90563b, 0x728900802f0f32fb}, - {0xcbb41ef979346bca, 0x4f2b40a03ad2ffba}, - {0xfea126b7d78186bc, 0xe2f610c84987bfa9}, - {0x9f24b832e6b0f436, 0x0dd9ca7d2df4d7ca}, - {0xc6ede63fa05d3143, 0x91503d1c79720dbc}, - {0xf8a95fcf88747d94, 0x75a44c6397ce912b}, - {0x9b69dbe1b548ce7c, 0xc986afbe3ee11abb}, - {0xc24452da229b021b, 0xfbe85badce996169}, - {0xf2d56790ab41c2a2, 0xfae27299423fb9c4}, - {0x97c560ba6b0919a5, 0xdccd879fc967d41b}, - {0xbdb6b8e905cb600f, 0x5400e987bbc1c921}, - {0xed246723473e3813, 0x290123e9aab23b69}, - {0x9436c0760c86e30b, 0xf9a0b6720aaf6522}, - {0xb94470938fa89bce, 0xf808e40e8d5b3e6a}, - {0xe7958cb87392c2c2, 0xb60b1d1230b20e05}, - {0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c3}, - {0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af4}, - {0xe2280b6c20dd5232, 0x25c6da63c38de1b1}, - {0x8d590723948a535f, 0x579c487e5a38ad0f}, - {0xb0af48ec79ace837, 0x2d835a9df0c6d852}, - {0xdcdb1b2798182244, 0xf8e431456cf88e66}, - {0x8a08f0f8bf0f156b, 0x1b8e9ecb641b5900}, - {0xac8b2d36eed2dac5, 0xe272467e3d222f40}, - {0xd7adf884aa879177, 0x5b0ed81dcc6abb10}, - {0x86ccbb52ea94baea, 0x98e947129fc2b4ea}, - {0xa87fea27a539e9a5, 0x3f2398d747b36225}, - {0xd29fe4b18e88640e, 0x8eec7f0d19a03aae}, - {0x83a3eeeef9153e89, 0x1953cf68300424ad}, - {0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd8}, - {0xcdb02555653131b6, 0x3792f412cb06794e}, - {0x808e17555f3ebf11, 0xe2bbd88bbee40bd1}, - {0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec5}, - {0xc8de047564d20a8b, 0xf245825a5a445276}, - {0xfb158592be068d2e, 0xeed6e2f0f0d56713}, - {0x9ced737bb6c4183d, 0x55464dd69685606c}, - {0xc428d05aa4751e4c, 0xaa97e14c3c26b887}, - {0xf53304714d9265df, 0xd53dd99f4b3066a9}, - {0x993fe2c6d07b7fab, 0xe546a8038efe402a}, - {0xbf8fdb78849a5f96, 0xde98520472bdd034}, - {0xef73d256a5c0f77c, 0x963e66858f6d4441}, - {0x95a8637627989aad, 0xdde7001379a44aa9}, - {0xbb127c53b17ec159, 0x5560c018580d5d53}, - {0xe9d71b689dde71af, 0xaab8f01e6e10b4a7}, - {0x9226712162ab070d, 0xcab3961304ca70e9}, - {0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d23}, - {0xe45c10c42a2b3b05, 0x8cb89a7db77c506b}, - {0x8eb98a7a9a5b04e3, 0x77f3608e92adb243}, - {0xb267ed1940f1c61c, 0x55f038b237591ed4}, - {0xdf01e85f912e37a3, 0x6b6c46dec52f6689}, - {0x8b61313bbabce2c6, 0x2323ac4b3b3da016}, - {0xae397d8aa96c1b77, 0xabec975e0a0d081b}, - {0xd9c7dced53c72255, 0x96e7bd358c904a22}, - {0x881cea14545c7575, 0x7e50d64177da2e55}, - {0xaa242499697392d2, 0xdde50bd1d5d0b9ea}, - {0xd4ad2dbfc3d07787, 0x955e4ec64b44e865}, - {0x84ec3c97da624ab4, 0xbd5af13bef0b113f}, - {0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58f}, - {0xcfb11ead453994ba, 0x67de18eda5814af3}, - {0x81ceb32c4b43fcf4, 0x80eacf948770ced8}, - {0xa2425ff75e14fc31, 0xa1258379a94d028e}, - {0xcad2f7f5359a3b3e, 0x096ee45813a04331}, - {0xfd87b5f28300ca0d, 0x8bca9d6e188853fd}, - {0x9e74d1b791e07e48, 0x775ea264cf55347e}, - {0xc612062576589dda, 0x95364afe032a819e}, - {0xf79687aed3eec551, 0x3a83ddbd83f52205}, - {0x9abe14cd44753b52, 0xc4926a9672793543}, - {0xc16d9a0095928a27, 0x75b7053c0f178294}, - {0xf1c90080baf72cb1, 0x5324c68b12dd6339}, - {0x971da05074da7bee, 0xd3f6fc16ebca5e04}, - {0xbce5086492111aea, 0x88f4bb1ca6bcf585}, - {0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6}, - {0x9392ee8e921d5d07, 0x3aff322e62439fd0}, - {0xb877aa3236a4b449, 0x09befeb9fad487c3}, - {0xe69594bec44de15b, 0x4c2ebe687989a9b4}, - {0x901d7cf73ab0acd9, 0x0f9d37014bf60a11}, - {0xb424dc35095cd80f, 0x538484c19ef38c95}, - {0xe12e13424bb40e13, 0x2865a5f206b06fba}, - {0x8cbccc096f5088cb, 0xf93f87b7442e45d4}, - {0xafebff0bcb24aafe, 0xf78f69a51539d749}, - {0xdbe6fecebdedd5be, 0xb573440e5a884d1c}, - {0x89705f4136b4a597, 0x31680a88f8953031}, - {0xabcc77118461cefc, 0xfdc20d2b36ba7c3e}, - {0xd6bf94d5e57a42bc, 0x3d32907604691b4d}, - {0x8637bd05af6c69b5, 0xa63f9a49c2c1b110}, - {0xa7c5ac471b478423, 0x0fcf80dc33721d54}, - {0xd1b71758e219652b, 0xd3c36113404ea4a9}, - {0x83126e978d4fdf3b, 0x645a1cac083126ea}, - {0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4}, - {0xcccccccccccccccc, 0xcccccccccccccccd}, - {0x8000000000000000, 0x0000000000000000}, - {0xa000000000000000, 0x0000000000000000}, - {0xc800000000000000, 0x0000000000000000}, - {0xfa00000000000000, 0x0000000000000000}, - {0x9c40000000000000, 0x0000000000000000}, - {0xc350000000000000, 0x0000000000000000}, - {0xf424000000000000, 0x0000000000000000}, - {0x9896800000000000, 0x0000000000000000}, - {0xbebc200000000000, 0x0000000000000000}, - {0xee6b280000000000, 0x0000000000000000}, - {0x9502f90000000000, 0x0000000000000000}, - {0xba43b74000000000, 0x0000000000000000}, - {0xe8d4a51000000000, 0x0000000000000000}, - {0x9184e72a00000000, 0x0000000000000000}, - {0xb5e620f480000000, 0x0000000000000000}, - {0xe35fa931a0000000, 0x0000000000000000}, - {0x8e1bc9bf04000000, 0x0000000000000000}, - {0xb1a2bc2ec5000000, 0x0000000000000000}, - {0xde0b6b3a76400000, 0x0000000000000000}, - {0x8ac7230489e80000, 0x0000000000000000}, - {0xad78ebc5ac620000, 0x0000000000000000}, - {0xd8d726b7177a8000, 0x0000000000000000}, - {0x878678326eac9000, 0x0000000000000000}, - {0xa968163f0a57b400, 0x0000000000000000}, - {0xd3c21bcecceda100, 0x0000000000000000}, - {0x84595161401484a0, 0x0000000000000000}, - {0xa56fa5b99019a5c8, 0x0000000000000000}, - {0xcecb8f27f4200f3a, 0x0000000000000000}, - {0x813f3978f8940984, 0x4000000000000000}, - {0xa18f07d736b90be5, 0x5000000000000000}, - {0xc9f2c9cd04674ede, 0xa400000000000000}, - {0xfc6f7c4045812296, 0x4d00000000000000}, - {0x9dc5ada82b70b59d, 0xf020000000000000}, - {0xc5371912364ce305, 0x6c28000000000000}, - {0xf684df56c3e01bc6, 0xc732000000000000}, - {0x9a130b963a6c115c, 0x3c7f400000000000}, - {0xc097ce7bc90715b3, 0x4b9f100000000000}, - {0xf0bdc21abb48db20, 0x1e86d40000000000}, - {0x96769950b50d88f4, 0x1314448000000000}, - {0xbc143fa4e250eb31, 0x17d955a000000000}, - {0xeb194f8e1ae525fd, 0x5dcfab0800000000}, - {0x92efd1b8d0cf37be, 0x5aa1cae500000000}, - {0xb7abc627050305ad, 0xf14a3d9e40000000}, - {0xe596b7b0c643c719, 0x6d9ccd05d0000000}, - {0x8f7e32ce7bea5c6f, 0xe4820023a2000000}, - {0xb35dbf821ae4f38b, 0xdda2802c8a800000}, - {0xe0352f62a19e306e, 0xd50b2037ad200000}, - {0x8c213d9da502de45, 0x4526f422cc340000}, - {0xaf298d050e4395d6, 0x9670b12b7f410000}, - {0xdaf3f04651d47b4c, 0x3c0cdd765f114000}, - {0x88d8762bf324cd0f, 0xa5880a69fb6ac800}, - {0xab0e93b6efee0053, 0x8eea0d047a457a00}, - {0xd5d238a4abe98068, 0x72a4904598d6d880}, - {0x85a36366eb71f041, 0x47a6da2b7f864750}, - {0xa70c3c40a64e6c51, 0x999090b65f67d924}, - {0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d}, - {0x82818f1281ed449f, 0xbff8f10e7a8921a5}, - {0xa321f2d7226895c7, 0xaff72d52192b6a0e}, - {0xcbea6f8ceb02bb39, 0x9bf4f8a69f764491}, - {0xfee50b7025c36a08, 0x02f236d04753d5b5}, - {0x9f4f2726179a2245, 0x01d762422c946591}, - {0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef6}, - {0xf8ebad2b84e0d58b, 0xd2e0898765a7deb3}, - {0x9b934c3b330c8577, 0x63cc55f49f88eb30}, - {0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fc}, - {0xf316271c7fc3908a, 0x8bef464e3945ef7b}, - {0x97edd871cfda3a56, 0x97758bf0e3cbb5ad}, - {0xbde94e8e43d0c8ec, 0x3d52eeed1cbea318}, - {0xed63a231d4c4fb27, 0x4ca7aaa863ee4bde}, - {0x945e455f24fb1cf8, 0x8fe8caa93e74ef6b}, - {0xb975d6b6ee39e436, 0xb3e2fd538e122b45}, - {0xe7d34c64a9c85d44, 0x60dbbca87196b617}, - {0x90e40fbeea1d3a4a, 0xbc8955e946fe31ce}, - {0xb51d13aea4a488dd, 0x6babab6398bdbe42}, - {0xe264589a4dcdab14, 0xc696963c7eed2dd2}, - {0x8d7eb76070a08aec, 0xfc1e1de5cf543ca3}, - {0xb0de65388cc8ada8, 0x3b25a55f43294bcc}, - {0xdd15fe86affad912, 0x49ef0eb713f39ebf}, - {0x8a2dbf142dfcc7ab, 0x6e3569326c784338}, - {0xacb92ed9397bf996, 0x49c2c37f07965405}, - {0xd7e77a8f87daf7fb, 0xdc33745ec97be907}, - {0x86f0ac99b4e8dafd, 0x69a028bb3ded71a4}, - {0xa8acd7c0222311bc, 0xc40832ea0d68ce0d}, - {0xd2d80db02aabd62b, 0xf50a3fa490c30191}, - {0x83c7088e1aab65db, 0x792667c6da79e0fb}, - {0xa4b8cab1a1563f52, 0x577001b891185939}, - {0xcde6fd5e09abcf26, 0xed4c0226b55e6f87}, - {0x80b05e5ac60b6178, 0x544f8158315b05b5}, - {0xa0dc75f1778e39d6, 0x696361ae3db1c722}, - {0xc913936dd571c84c, 0x03bc3a19cd1e38ea}, - {0xfb5878494ace3a5f, 0x04ab48a04065c724}, - {0x9d174b2dcec0e47b, 0x62eb0d64283f9c77}, - {0xc45d1df942711d9a, 0x3ba5d0bd324f8395}, - {0xf5746577930d6500, 0xca8f44ec7ee3647a}, - {0x9968bf6abbe85f20, 0x7e998b13cf4e1ecc}, - {0xbfc2ef456ae276e8, 0x9e3fedd8c321a67f}, - {0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101f}, - {0x95d04aee3b80ece5, 0xbba1f1d158724a13}, - {0xbb445da9ca61281f, 0x2a8a6e45ae8edc98}, - {0xea1575143cf97226, 0xf52d09d71a3293be}, - {0x924d692ca61be758, 0x593c2626705f9c57}, - {0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836d}, - {0xe498f455c38b997a, 0x0b6dfb9c0f956448}, - {0x8edf98b59a373fec, 0x4724bd4189bd5ead}, - {0xb2977ee300c50fe7, 0x58edec91ec2cb658}, - {0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ee}, - {0x8b865b215899f46c, 0xbd79e0d20082ee75}, - {0xae67f1e9aec07187, 0xecd8590680a3aa12}, - {0xda01ee641a708de9, 0xe80e6f4820cc9496}, - {0x884134fe908658b2, 0x3109058d147fdcde}, - {0xaa51823e34a7eede, 0xbd4b46f0599fd416}, - {0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91b}, - {0x850fadc09923329e, 0x03e2cf6bc604ddb1}, - {0xa6539930bf6bff45, 0x84db8346b786151d}, - {0xcfe87f7cef46ff16, 0xe612641865679a64}, - {0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07f}, - {0xa26da3999aef7749, 0xe3be5e330f38f09e}, - {0xcb090c8001ab551c, 0x5cadf5bfd3072cc6}, - {0xfdcb4fa002162a63, 0x73d9732fc7c8f7f7}, - {0x9e9f11c4014dda7e, 0x2867e7fddcdd9afb}, - {0xc646d63501a1511d, 0xb281e1fd541501b9}, - {0xf7d88bc24209a565, 0x1f225a7ca91a4227}, - {0x9ae757596946075f, 0x3375788de9b06959}, - {0xc1a12d2fc3978937, 0x0052d6b1641c83af}, - {0xf209787bb47d6b84, 0xc0678c5dbd23a49b}, - {0x9745eb4d50ce6332, 0xf840b7ba963646e1}, - {0xbd176620a501fbff, 0xb650e5a93bc3d899}, - {0xec5d3fa8ce427aff, 0xa3e51f138ab4cebf}, - {0x93ba47c980e98cdf, 0xc66f336c36b10138}, - {0xb8a8d9bbe123f017, 0xb80b0047445d4185}, - {0xe6d3102ad96cec1d, 0xa60dc059157491e6}, - {0x9043ea1ac7e41392, 0x87c89837ad68db30}, - {0xb454e4a179dd1877, 0x29babe4598c311fc}, - {0xe16a1dc9d8545e94, 0xf4296dd6fef3d67b}, - {0x8ce2529e2734bb1d, 0x1899e4a65f58660d}, - {0xb01ae745b101e9e4, 0x5ec05dcff72e7f90}, - {0xdc21a1171d42645d, 0x76707543f4fa1f74}, - {0x899504ae72497eba, 0x6a06494a791c53a9}, - {0xabfa45da0edbde69, 0x0487db9d17636893}, - {0xd6f8d7509292d603, 0x45a9d2845d3c42b7}, - {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b3}, - {0xa7f26836f282b732, 0x8e6cac7768d7141f}, - {0xd1ef0244af2364ff, 0x3207d795430cd927}, - {0x8335616aed761f1f, 0x7f44e6bd49e807b9}, - {0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a7}, - {0xcd036837130890a1, 0x36dba887c37a8c10}, - {0x802221226be55a64, 0xc2494954da2c978a}, - {0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6d}, - {0xc83553c5c8965d3d, 0x6f92829494e5acc8}, - {0xfa42a8b73abbf48c, 0xcb772339ba1f17fa}, - {0x9c69a97284b578d7, 0xff2a760414536efc}, - {0xc38413cf25e2d70d, 0xfef5138519684abb}, - {0xf46518c2ef5b8cd1, 0x7eb258665fc25d6a}, - {0x98bf2f79d5993802, 0xef2f773ffbd97a62}, - {0xbeeefb584aff8603, 0xaafb550ffacfd8fb}, - {0xeeaaba2e5dbf6784, 0x95ba2a53f983cf39}, - {0x952ab45cfa97a0b2, 0xdd945a747bf26184}, - {0xba756174393d88df, 0x94f971119aeef9e5}, - {0xe912b9d1478ceb17, 0x7a37cd5601aab85e}, - {0x91abb422ccb812ee, 0xac62e055c10ab33b}, - {0xb616a12b7fe617aa, 0x577b986b314d600a}, - {0xe39c49765fdf9d94, 0xed5a7e85fda0b80c}, - {0x8e41ade9fbebc27d, 0x14588f13be847308}, - {0xb1d219647ae6b31c, 0x596eb2d8ae258fc9}, - {0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bc}, - {0x8aec23d680043bee, 0x25de7bb9480d5855}, - {0xada72ccc20054ae9, 0xaf561aa79a10ae6b}, - {0xd910f7ff28069da4, 0x1b2ba1518094da05}, - {0x87aa9aff79042286, 0x90fb44d2f05d0843}, - {0xa99541bf57452b28, 0x353a1607ac744a54}, - {0xd3fa922f2d1675f2, 0x42889b8997915ce9}, - {0x847c9b5d7c2e09b7, 0x69956135febada12}, - {0xa59bc234db398c25, 0x43fab9837e699096}, - {0xcf02b2c21207ef2e, 0x94f967e45e03f4bc}, - {0x8161afb94b44f57d, 0x1d1be0eebac278f6}, - {0xa1ba1ba79e1632dc, 0x6462d92a69731733}, - {0xca28a291859bbf93, 0x7d7b8f7503cfdcff}, - {0xfcb2cb35e702af78, 0x5cda735244c3d43f}, - {0x9defbf01b061adab, 0x3a0888136afa64a8}, - {0xc56baec21c7a1916, 0x088aaa1845b8fdd1}, - {0xf6c69a72a3989f5b, 0x8aad549e57273d46}, - {0x9a3c2087a63f6399, 0x36ac54e2f678864c}, - {0xc0cb28a98fcf3c7f, 0x84576a1bb416a7de}, - {0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d6}, - {0x969eb7c47859e743, 0x9f644ae5a4b1b326}, - {0xbc4665b596706114, 0x873d5d9f0dde1fef}, - {0xeb57ff22fc0c7959, 0xa90cb506d155a7eb}, - {0x9316ff75dd87cbd8, 0x09a7f12442d588f3}, - {0xb7dcbf5354e9bece, 0x0c11ed6d538aeb30}, - {0xe5d3ef282a242e81, 0x8f1668c8a86da5fb}, - {0x8fa475791a569d10, 0xf96e017d694487bd}, - {0xb38d92d760ec4455, 0x37c981dcc395a9ad}, - {0xe070f78d3927556a, 0x85bbe253f47b1418}, - {0x8c469ab843b89562, 0x93956d7478ccec8f}, - {0xaf58416654a6babb, 0x387ac8d1970027b3}, - {0xdb2e51bfe9d0696a, 0x06997b05fcc0319f}, - {0x88fcf317f22241e2, 0x441fece3bdf81f04}, - {0xab3c2fddeeaad25a, 0xd527e81cad7626c4}, - {0xd60b3bd56a5586f1, 0x8a71e223d8d3b075}, - {0x85c7056562757456, 0xf6872d5667844e4a}, - {0xa738c6bebb12d16c, 0xb428f8ac016561dc}, - {0xd106f86e69d785c7, 0xe13336d701beba53}, - {0x82a45b450226b39c, 0xecc0024661173474}, - {0xa34d721642b06084, 0x27f002d7f95d0191}, - {0xcc20ce9bd35c78a5, 0x31ec038df7b441f5}, - {0xff290242c83396ce, 0x7e67047175a15272}, - {0x9f79a169bd203e41, 0x0f0062c6e984d387}, - {0xc75809c42c684dd1, 0x52c07b78a3e60869}, - {0xf92e0c3537826145, 0xa7709a56ccdf8a83}, - {0x9bbcc7a142b17ccb, 0x88a66076400bb692}, - {0xc2abf989935ddbfe, 0x6acff893d00ea436}, - {0xf356f7ebf83552fe, 0x0583f6b8c4124d44}, - {0x98165af37b2153de, 0xc3727a337a8b704b}, - {0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5d}, - {0xeda2ee1c7064130c, 0x1162def06f79df74}, - {0x9485d4d1c63e8be7, 0x8addcb5645ac2ba9}, - {0xb9a74a0637ce2ee1, 0x6d953e2bd7173693}, - {0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0438}, - {0x910ab1d4db9914a0, 0x1d9c9892400a22a3}, - {0xb54d5e4a127f59c8, 0x2503beb6d00cab4c}, - {0xe2a0b5dc971f303a, 0x2e44ae64840fd61e}, - {0x8da471a9de737e24, 0x5ceaecfed289e5d3}, - {0xb10d8e1456105dad, 0x7425a83e872c5f48}, - {0xdd50f1996b947518, 0xd12f124e28f7771a}, - {0x8a5296ffe33cc92f, 0x82bd6b70d99aaa70}, - {0xace73cbfdc0bfb7b, 0x636cc64d1001550c}, - {0xd8210befd30efa5a, 0x3c47f7e05401aa4f}, - {0x8714a775e3e95c78, 0x65acfaec34810a72}, - {0xa8d9d1535ce3b396, 0x7f1839a741a14d0e}, - {0xd31045a8341ca07c, 0x1ede48111209a051}, - {0x83ea2b892091e44d, 0x934aed0aab460433}, - {0xa4e4b66b68b65d60, 0xf81da84d56178540}, - {0xce1de40642e3f4b9, 0x36251260ab9d668f}, - {0x80d2ae83e9ce78f3, 0xc1d72b7c6b42601a}, - {0xa1075a24e4421730, 0xb24cf65b8612f820}, - {0xc94930ae1d529cfc, 0xdee033f26797b628}, - {0xfb9b7cd9a4a7443c, 0x169840ef017da3b2}, - {0x9d412e0806e88aa5, 0x8e1f289560ee864f}, - {0xc491798a08a2ad4e, 0xf1a6f2bab92a27e3}, - {0xf5b5d7ec8acb58a2, 0xae10af696774b1dc}, - {0x9991a6f3d6bf1765, 0xacca6da1e0a8ef2a}, - {0xbff610b0cc6edd3f, 0x17fd090a58d32af4}, - {0xeff394dcff8a948e, 0xddfc4b4cef07f5b1}, - {0x95f83d0a1fb69cd9, 0x4abdaf101564f98f}, - {0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f2}, - {0xea53df5fd18d5513, 0x84c86189216dc5ee}, - {0x92746b9be2f8552c, 0x32fd3cf5b4e49bb5}, - {0xb7118682dbb66a77, 0x3fbc8c33221dc2a2}, - {0xe4d5e82392a40515, 0x0fabaf3feaa5334b}, - {0x8f05b1163ba6832d, 0x29cb4d87f2a7400f}, - {0xb2c71d5bca9023f8, 0x743e20e9ef511013}, - {0xdf78e4b2bd342cf6, 0x914da9246b255417}, - {0x8bab8eefb6409c1a, 0x1ad089b6c2f7548f}, - {0xae9672aba3d0c320, 0xa184ac2473b529b2}, - {0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741f}, - {0x8865899617fb1871, 0x7e2fa67c7a658893}, - {0xaa7eebfb9df9de8d, 0xddbb901b98feeab8}, - {0xd51ea6fa85785631, 0x552a74227f3ea566}, - {0x8533285c936b35de, 0xd53a88958f872760}, - {0xa67ff273b8460356, 0x8a892abaf368f138}, - {0xd01fef10a657842c, 0x2d2b7569b0432d86}, - {0x8213f56a67f6b29b, 0x9c3b29620e29fc74}, - {0xa298f2c501f45f42, 0x8349f3ba91b47b90}, - {0xcb3f2f7642717713, 0x241c70a936219a74}, - {0xfe0efb53d30dd4d7, 0xed238cd383aa0111}, - {0x9ec95d1463e8a506, 0xf4363804324a40ab}, - {0xc67bb4597ce2ce48, 0xb143c6053edcd0d6}, - {0xf81aa16fdc1b81da, 0xdd94b7868e94050b}, - {0x9b10a4e5e9913128, 0xca7cf2b4191c8327}, - {0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f1}, - {0xf24a01a73cf2dccf, 0xbc633b39673c8ced}, - {0x976e41088617ca01, 0xd5be0503e085d814}, - {0xbd49d14aa79dbc82, 0x4b2d8644d8a74e19}, - {0xec9c459d51852ba2, 0xddf8e7d60ed1219f}, - {0x93e1ab8252f33b45, 0xcabb90e5c942b504}, - {0xb8da1662e7b00a17, 0x3d6a751f3b936244}, - {0xe7109bfba19c0c9d, 0x0cc512670a783ad5}, - {0x906a617d450187e2, 0x27fb2b80668b24c6}, - {0xb484f9dc9641e9da, 0xb1f9f660802dedf7}, - {0xe1a63853bbd26451, 0x5e7873f8a0396974}, - {0x8d07e33455637eb2, 0xdb0b487b6423e1e9}, - {0xb049dc016abc5e5f, 0x91ce1a9a3d2cda63}, - {0xdc5c5301c56b75f7, 0x7641a140cc7810fc}, - {0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9e}, - {0xac2820d9623bf429, 0x546345fa9fbdcd45}, - {0xd732290fbacaf133, 0xa97c177947ad4096}, - {0x867f59a9d4bed6c0, 0x49ed8eabcccc485e}, - {0xa81f301449ee8c70, 0x5c68f256bfff5a75}, - {0xd226fc195c6a2f8c, 0x73832eec6fff3112}, - {0x83585d8fd9c25db7, 0xc831fd53c5ff7eac}, - {0xa42e74f3d032f525, 0xba3e7ca8b77f5e56}, - {0xcd3a1230c43fb26f, 0x28ce1bd2e55f35ec}, - {0x80444b5e7aa7cf85, 0x7980d163cf5b81b4}, - {0xa0555e361951c366, 0xd7e105bcc3326220}, - {0xc86ab5c39fa63440, 0x8dd9472bf3fefaa8}, - {0xfa856334878fc150, 0xb14f98f6f0feb952}, - {0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d4}, - {0xc3b8358109e84f07, 0x0a862f80ec4700c9}, - {0xf4a642e14c6262c8, 0xcd27bb612758c0fb}, - {0x98e7e9cccfbd7dbd, 0x8038d51cb897789d}, - {0xbf21e44003acdd2c, 0xe0470a63e6bd56c4}, - {0xeeea5d5004981478, 0x1858ccfce06cac75}, - {0x95527a5202df0ccb, 0x0f37801e0c43ebc9}, - {0xbaa718e68396cffd, 0xd30560258f54e6bb}, - {0xe950df20247c83fd, 0x47c6b82ef32a206a}, - {0x91d28b7416cdd27e, 0x4cdc331d57fa5442}, - {0xb6472e511c81471d, 0xe0133fe4adf8e953}, - {0xe3d8f9e563a198e5, 0x58180fddd97723a7}, - {0x8e679c2f5e44ff8f, 0x570f09eaa7ea7649}, - {0xb201833b35d63f73, 0x2cd2cc6551e513db}, - {0xde81e40a034bcf4f, 0xf8077f7ea65e58d2}, - {0x8b112e86420f6191, 0xfb04afaf27faf783}, - {0xadd57a27d29339f6, 0x79c5db9af1f9b564}, - {0xd94ad8b1c7380874, 0x18375281ae7822bd}, - {0x87cec76f1c830548, 0x8f2293910d0b15b6}, - {0xa9c2794ae3a3c69a, 0xb2eb3875504ddb23}, - {0xd433179d9c8cb841, 0x5fa60692a46151ec}, - {0x849feec281d7f328, 0xdbc7c41ba6bcd334}, - {0xa5c7ea73224deff3, 0x12b9b522906c0801}, - {0xcf39e50feae16bef, 0xd768226b34870a01}, - {0x81842f29f2cce375, 0xe6a1158300d46641}, - {0xa1e53af46f801c53, 0x60495ae3c1097fd1}, - {0xca5e89b18b602368, 0x385bb19cb14bdfc5}, - {0xfcf62c1dee382c42, 0x46729e03dd9ed7b6}, - {0x9e19db92b4e31ba9, 0x6c07a2c26a8346d2}, - {0xc5a05277621be293, 0xc7098b7305241886}, - {0xf70867153aa2db38, 0xb8cbee4fc66d1ea8}, - {0x9a65406d44a5c903, 0x737f74f1dc043329}, - {0xc0fe908895cf3b44, 0x505f522e53053ff3}, - {0xf13e34aabb430a15, 0x647726b9e7c68ff0}, - {0x96c6e0eab509e64d, 0x5eca783430dc19f6}, - {0xbc789925624c5fe0, 0xb67d16413d132073}, - {0xeb96bf6ebadf77d8, 0xe41c5bd18c57e890}, - {0x933e37a534cbaae7, 0x8e91b962f7b6f15a}, - {0xb80dc58e81fe95a1, 0x723627bbb5a4adb1}, - {0xe61136f2227e3b09, 0xcec3b1aaa30dd91d}, - {0x8fcac257558ee4e6, 0x213a4f0aa5e8a7b2}, - {0xb3bd72ed2af29e1f, 0xa988e2cd4f62d19e}, - {0xe0accfa875af45a7, 0x93eb1b80a33b8606}, - {0x8c6c01c9498d8b88, 0xbc72f130660533c4}, - {0xaf87023b9bf0ee6a, 0xeb8fad7c7f8680b5}, - {0xdb68c2ca82ed2a05, 0xa67398db9f6820e2}, -#else - {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b}, - {0xce5d73ff402d98e3, 0xfb0a3d212dc81290}, - {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f}, - {0x86a8d39ef77164bc, 0xae5dff9c02033198}, - {0xd98ddaee19068c76, 0x3badd624dd9b0958}, - {0xafbd2350644eeacf, 0xe5d1929ef90898fb}, - {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2}, - {0xe55990879ddcaabd, 0xcc420a6a101d0516}, - {0xb94470938fa89bce, 0xf808e40e8d5b3e6a}, - {0x95a8637627989aad, 0xdde7001379a44aa9}, - {0xf1c90080baf72cb1, 0x5324c68b12dd6339}, - {0xc350000000000000, 0x0000000000000000}, - {0x9dc5ada82b70b59d, 0xf020000000000000}, - {0xfee50b7025c36a08, 0x02f236d04753d5b5}, - {0xcde6fd5e09abcf26, 0xed4c0226b55e6f87}, - {0xa6539930bf6bff45, 0x84db8346b786151d}, - {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b3}, - {0xd910f7ff28069da4, 0x1b2ba1518094da05}, - {0xaf58416654a6babb, 0x387ac8d1970027b3}, - {0x8da471a9de737e24, 0x5ceaecfed289e5d3}, - {0xe4d5e82392a40515, 0x0fabaf3feaa5334b}, - {0xb8da1662e7b00a17, 0x3d6a751f3b936244}, - {0x95527a5202df0ccb, 0x0f37801e0c43ebc9}, - {0xf13e34aabb430a15, 0x647726b9e7c68ff0} -#endif - }; - -#if FMT_USE_FULL_CACHE_DRAGONBOX - return pow10_significands[k - float_info::min_k]; -#else - static constexpr uint64_t powers_of_5_64[] = { - 0x0000000000000001, 0x0000000000000005, 0x0000000000000019, - 0x000000000000007d, 0x0000000000000271, 0x0000000000000c35, - 0x0000000000003d09, 0x000000000001312d, 0x000000000005f5e1, - 0x00000000001dcd65, 0x00000000009502f9, 0x0000000002e90edd, - 0x000000000e8d4a51, 0x0000000048c27395, 0x000000016bcc41e9, - 0x000000071afd498d, 0x0000002386f26fc1, 0x000000b1a2bc2ec5, - 0x000003782dace9d9, 0x00001158e460913d, 0x000056bc75e2d631, - 0x0001b1ae4d6e2ef5, 0x000878678326eac9, 0x002a5a058fc295ed, - 0x00d3c21bcecceda1, 0x0422ca8b0a00a425, 0x14adf4b7320334b9}; - - static const int compression_ratio = 27; - - // Compute base index. - int cache_index = (k - float_info::min_k) / compression_ratio; - int kb = cache_index * compression_ratio + float_info::min_k; - int offset = k - kb; - - // Get base cache. - uint128_fallback base_cache = pow10_significands[cache_index]; - if (offset == 0) return base_cache; - - // Compute the required amount of bit-shift. - int alpha = floor_log2_pow10(kb + offset) - floor_log2_pow10(kb) - offset; - FMT_ASSERT(alpha > 0 && alpha < 64, "shifting error detected"); - - // Try to recover the real cache. - uint64_t pow5 = powers_of_5_64[offset]; - uint128_fallback recovered_cache = umul128(base_cache.high(), pow5); - uint128_fallback middle_low = umul128(base_cache.low(), pow5); - - recovered_cache += middle_low.high(); - - uint64_t high_to_middle = recovered_cache.high() << (64 - alpha); - uint64_t middle_to_low = recovered_cache.low() << (64 - alpha); - - recovered_cache = - uint128_fallback{(recovered_cache.low() >> alpha) | high_to_middle, - ((middle_low.low() >> alpha) | middle_to_low)}; - FMT_ASSERT(recovered_cache.low() + 1 != 0, ""); - return {recovered_cache.high(), recovered_cache.low() + 1}; -#endif - } - - struct compute_mul_result { - carrier_uint result; - bool is_integer; - }; - struct compute_mul_parity_result { - bool parity; - bool is_integer; - }; - - static auto compute_mul(carrier_uint u, - const cache_entry_type& cache) noexcept - -> compute_mul_result { - auto r = umul192_upper128(u, cache); - return {r.high(), r.low() == 0}; - } - - static auto compute_delta(const cache_entry_type& cache, int beta) noexcept - -> uint32_t { - return static_cast(cache.high() >> (64 - 1 - beta)); - } - - static auto compute_mul_parity(carrier_uint two_f, - const cache_entry_type& cache, - int beta) noexcept - -> compute_mul_parity_result { - FMT_ASSERT(beta >= 1, ""); - FMT_ASSERT(beta < 64, ""); - - auto r = umul192_lower128(two_f, cache); - return {((r.high() >> (64 - beta)) & 1) != 0, - ((r.high() << beta) | (r.low() >> (64 - beta))) == 0}; - } - - static auto compute_left_endpoint_for_shorter_interval_case( - const cache_entry_type& cache, int beta) noexcept -> carrier_uint { - return (cache.high() - - (cache.high() >> (num_significand_bits() + 2))) >> - (64 - num_significand_bits() - 1 - beta); - } - - static auto compute_right_endpoint_for_shorter_interval_case( - const cache_entry_type& cache, int beta) noexcept -> carrier_uint { - return (cache.high() + - (cache.high() >> (num_significand_bits() + 1))) >> - (64 - num_significand_bits() - 1 - beta); - } - - static auto compute_round_up_for_shorter_interval_case( - const cache_entry_type& cache, int beta) noexcept -> carrier_uint { - return ((cache.high() >> (64 - num_significand_bits() - 2 - beta)) + - 1) / - 2; - } -}; - -FMT_FUNC auto get_cached_power(int k) noexcept -> uint128_fallback { - return cache_accessor::get_cached_power(k); -} - -// Various integer checks -template -auto is_left_endpoint_integer_shorter_interval(int exponent) noexcept -> bool { - const int case_shorter_interval_left_endpoint_lower_threshold = 2; - const int case_shorter_interval_left_endpoint_upper_threshold = 3; - return exponent >= case_shorter_interval_left_endpoint_lower_threshold && - exponent <= case_shorter_interval_left_endpoint_upper_threshold; -} - -// Remove trailing zeros from n and return the number of zeros removed (float). -FMT_INLINE auto remove_trailing_zeros(uint32_t& n, int s = 0) noexcept -> int { - FMT_ASSERT(n != 0, ""); - // Modular inverse of 5 (mod 2^32): (mod_inv_5 * 5) mod 2^32 = 1. - constexpr uint32_t mod_inv_5 = 0xcccccccd; - constexpr uint32_t mod_inv_25 = 0xc28f5c29; // = mod_inv_5 * mod_inv_5 - - while (true) { - auto q = rotr(n * mod_inv_25, 2); - if (q > max_value() / 100) break; - n = q; - s += 2; - } - auto q = rotr(n * mod_inv_5, 1); - if (q <= max_value() / 10) { - n = q; - s |= 1; - } - return s; -} - -// Removes trailing zeros and returns the number of zeros removed (double). -FMT_INLINE auto remove_trailing_zeros(uint64_t& n) noexcept -> int { - FMT_ASSERT(n != 0, ""); - - // Is n is divisible by 10^8? - constexpr uint32_t ten_pow_8 = 100000000u; - if ((n % ten_pow_8) == 0) { - // If yes, work with the quotient... - auto n32 = static_cast(n / ten_pow_8); - // ... and use the 32 bit variant of the function - int num_zeros = remove_trailing_zeros(n32, 8); - n = n32; - return num_zeros; - } - - // If n is not divisible by 10^8, work with n itself. - constexpr uint64_t mod_inv_5 = 0xcccccccccccccccd; - constexpr uint64_t mod_inv_25 = 0x8f5c28f5c28f5c29; // mod_inv_5 * mod_inv_5 - - int s = 0; - while (true) { - auto q = rotr(n * mod_inv_25, 2); - if (q > max_value() / 100) break; - n = q; - s += 2; - } - auto q = rotr(n * mod_inv_5, 1); - if (q <= max_value() / 10) { - n = q; - s |= 1; - } - - return s; -} - -// The main algorithm for shorter interval case -template -FMT_INLINE auto shorter_interval_case(int exponent) noexcept -> decimal_fp { - decimal_fp ret_value; - // Compute k and beta - const int minus_k = floor_log10_pow2_minus_log10_4_over_3(exponent); - const int beta = exponent + floor_log2_pow10(-minus_k); - - // Compute xi and zi - using cache_entry_type = typename cache_accessor::cache_entry_type; - const cache_entry_type cache = cache_accessor::get_cached_power(-minus_k); - - auto xi = cache_accessor::compute_left_endpoint_for_shorter_interval_case( - cache, beta); - auto zi = cache_accessor::compute_right_endpoint_for_shorter_interval_case( - cache, beta); - - // If the left endpoint is not an integer, increase it - if (!is_left_endpoint_integer_shorter_interval(exponent)) ++xi; - - // Try bigger divisor - ret_value.significand = zi / 10; - - // If succeed, remove trailing zeros if necessary and return - if (ret_value.significand * 10 >= xi) { - ret_value.exponent = minus_k + 1; - ret_value.exponent += remove_trailing_zeros(ret_value.significand); - return ret_value; - } - - // Otherwise, compute the round-up of y - ret_value.significand = - cache_accessor::compute_round_up_for_shorter_interval_case(cache, - beta); - ret_value.exponent = minus_k; - - // When tie occurs, choose one of them according to the rule - if (exponent >= float_info::shorter_interval_tie_lower_threshold && - exponent <= float_info::shorter_interval_tie_upper_threshold) { - ret_value.significand = ret_value.significand % 2 == 0 - ? ret_value.significand - : ret_value.significand - 1; - } else if (ret_value.significand < xi) { - ++ret_value.significand; - } - return ret_value; -} - -template auto to_decimal(T x) noexcept -> decimal_fp { - // Step 1: integer promotion & Schubfach multiplier calculation. - - using carrier_uint = typename float_info::carrier_uint; - using cache_entry_type = typename cache_accessor::cache_entry_type; - auto br = bit_cast(x); - - // Extract significand bits and exponent bits. - const carrier_uint significand_mask = - (static_cast(1) << num_significand_bits()) - 1; - carrier_uint significand = (br & significand_mask); - int exponent = - static_cast((br & exponent_mask()) >> num_significand_bits()); - - if (exponent != 0) { // Check if normal. - exponent -= exponent_bias() + num_significand_bits(); - - // Shorter interval case; proceed like Schubfach. - // In fact, when exponent == 1 and significand == 0, the interval is - // regular. However, it can be shown that the end-results are anyway same. - if (significand == 0) return shorter_interval_case(exponent); - - significand |= (static_cast(1) << num_significand_bits()); - } else { - // Subnormal case; the interval is always regular. - if (significand == 0) return {0, 0}; - exponent = - std::numeric_limits::min_exponent - num_significand_bits() - 1; - } - - const bool include_left_endpoint = (significand % 2 == 0); - const bool include_right_endpoint = include_left_endpoint; - - // Compute k and beta. - const int minus_k = floor_log10_pow2(exponent) - float_info::kappa; - const cache_entry_type cache = cache_accessor::get_cached_power(-minus_k); - const int beta = exponent + floor_log2_pow10(-minus_k); - - // Compute zi and deltai. - // 10^kappa <= deltai < 10^(kappa + 1) - const uint32_t deltai = cache_accessor::compute_delta(cache, beta); - const carrier_uint two_fc = significand << 1; - - // For the case of binary32, the result of integer check is not correct for - // 29711844 * 2^-82 - // = 6.1442653300000000008655037797566933477355632930994033813476... * 10^-18 - // and 29711844 * 2^-81 - // = 1.2288530660000000001731007559513386695471126586198806762695... * 10^-17, - // and they are the unique counterexamples. However, since 29711844 is even, - // this does not cause any problem for the endpoints calculations; it can only - // cause a problem when we need to perform integer check for the center. - // Fortunately, with these inputs, that branch is never executed, so we are - // fine. - const typename cache_accessor::compute_mul_result z_mul = - cache_accessor::compute_mul((two_fc | 1) << beta, cache); - - // Step 2: Try larger divisor; remove trailing zeros if necessary. - - // Using an upper bound on zi, we might be able to optimize the division - // better than the compiler; we are computing zi / big_divisor here. - decimal_fp ret_value; - ret_value.significand = divide_by_10_to_kappa_plus_1(z_mul.result); - uint32_t r = static_cast(z_mul.result - float_info::big_divisor * - ret_value.significand); - - if (r < deltai) { - // Exclude the right endpoint if necessary. - if (r == 0 && (z_mul.is_integer & !include_right_endpoint)) { - --ret_value.significand; - r = float_info::big_divisor; - goto small_divisor_case_label; - } - } else if (r > deltai) { - goto small_divisor_case_label; - } else { - // r == deltai; compare fractional parts. - const typename cache_accessor::compute_mul_parity_result x_mul = - cache_accessor::compute_mul_parity(two_fc - 1, cache, beta); - - if (!(x_mul.parity | (x_mul.is_integer & include_left_endpoint))) - goto small_divisor_case_label; - } - ret_value.exponent = minus_k + float_info::kappa + 1; - - // We may need to remove trailing zeros. - ret_value.exponent += remove_trailing_zeros(ret_value.significand); - return ret_value; - - // Step 3: Find the significand with the smaller divisor. - -small_divisor_case_label: - ret_value.significand *= 10; - ret_value.exponent = minus_k + float_info::kappa; - - uint32_t dist = r - (deltai / 2) + (float_info::small_divisor / 2); - const bool approx_y_parity = - ((dist ^ (float_info::small_divisor / 2)) & 1) != 0; - - // Is dist divisible by 10^kappa? - const bool divisible_by_small_divisor = - check_divisibility_and_divide_by_pow10::kappa>(dist); - - // Add dist / 10^kappa to the significand. - ret_value.significand += dist; - - if (!divisible_by_small_divisor) return ret_value; - - // Check z^(f) >= epsilon^(f). - // We have either yi == zi - epsiloni or yi == (zi - epsiloni) - 1, - // where yi == zi - epsiloni if and only if z^(f) >= epsilon^(f). - // Since there are only 2 possibilities, we only need to care about the - // parity. Also, zi and r should have the same parity since the divisor - // is an even number. - const auto y_mul = cache_accessor::compute_mul_parity(two_fc, cache, beta); - - // If z^(f) >= epsilon^(f), we might have a tie when z^(f) == epsilon^(f), - // or equivalently, when y is an integer. - if (y_mul.parity != approx_y_parity) - --ret_value.significand; - else if (y_mul.is_integer & (ret_value.significand % 2 != 0)) - --ret_value.significand; - return ret_value; -} -} // namespace dragonbox -} // namespace detail - -template <> struct formatter { - FMT_CONSTEXPR auto parse(format_parse_context& ctx) - -> format_parse_context::iterator { - return ctx.begin(); - } - - auto format(const detail::bigint& n, format_context& ctx) const - -> format_context::iterator { - auto out = ctx.out(); - bool first = true; - for (auto i = n.bigits_.size(); i > 0; --i) { - auto value = n.bigits_[i - 1u]; - if (first) { - out = fmt::format_to(out, FMT_STRING("{:x}"), value); - first = false; - continue; - } - out = fmt::format_to(out, FMT_STRING("{:08x}"), value); - } - if (n.exp_ > 0) - out = fmt::format_to(out, FMT_STRING("p{}"), - n.exp_ * detail::bigint::bigit_bits); - return out; - } -}; - -FMT_FUNC detail::utf8_to_utf16::utf8_to_utf16(string_view s) { - for_each_codepoint(s, [this](uint32_t cp, string_view) { - if (cp == invalid_code_point) FMT_THROW(std::runtime_error("invalid utf8")); - if (cp <= 0xFFFF) { - buffer_.push_back(static_cast(cp)); - } else { - cp -= 0x10000; - buffer_.push_back(static_cast(0xD800 + (cp >> 10))); - buffer_.push_back(static_cast(0xDC00 + (cp & 0x3FF))); - } - return true; - }); - buffer_.push_back(0); -} - -FMT_FUNC void format_system_error(detail::buffer& out, int error_code, - const char* message) noexcept { - FMT_TRY { - auto ec = std::error_code(error_code, std::generic_category()); - detail::write(appender(out), std::system_error(ec, message).what()); - return; - } - FMT_CATCH(...) {} - format_error_code(out, error_code, message); -} - -FMT_FUNC void report_system_error(int error_code, - const char* message) noexcept { - do_report_error(format_system_error, error_code, message); -} - -FMT_FUNC auto vformat(string_view fmt, format_args args) -> std::string { - // Don't optimize the "{}" case to keep the binary size small and because it - // can be better optimized in fmt::format anyway. - auto buffer = memory_buffer(); - detail::vformat_to(buffer, fmt, args); - return to_string(buffer); -} - -namespace detail { - -FMT_FUNC void vformat_to(buffer& buf, string_view fmt, format_args args, - locale_ref loc) { - auto out = appender(buf); - if (fmt.size() == 2 && equal2(fmt.data(), "{}")) - return args.get(0).visit(default_arg_formatter{out}); - parse_format_string(fmt, - format_handler<>{parse_context<>(fmt), {out, args, loc}}); -} - -template struct span { - T* data; - size_t size; -}; - -template auto flockfile(F* f) -> decltype(_lock_file(f)) { - _lock_file(f); -} -template auto funlockfile(F* f) -> decltype(_unlock_file(f)) { - _unlock_file(f); -} - -#ifndef getc_unlocked -template auto getc_unlocked(F* f) -> decltype(_fgetc_nolock(f)) { - return _fgetc_nolock(f); -} -#endif - -template -struct has_flockfile : std::false_type {}; - -template -struct has_flockfile()))>> - : std::true_type {}; - -// A FILE wrapper. F is FILE defined as a template parameter to make system API -// detection work. -template class file_base { - public: - F* file_; - - public: - file_base(F* file) : file_(file) {} - operator F*() const { return file_; } - - // Reads a code unit from the stream. - auto get() -> int { - int result = getc_unlocked(file_); - if (result == EOF && ferror(file_) != 0) - FMT_THROW(system_error(errno, FMT_STRING("getc failed"))); - return result; - } - - // Puts the code unit back into the stream buffer. - void unget(char c) { - if (ungetc(c, file_) == EOF) - FMT_THROW(system_error(errno, FMT_STRING("ungetc failed"))); - } - - void flush() { fflush(this->file_); } -}; - -// A FILE wrapper for glibc. -template class glibc_file : public file_base { - private: - enum { - line_buffered = 0x200, // _IO_LINE_BUF - unbuffered = 2 // _IO_UNBUFFERED - }; - - public: - using file_base::file_base; - - auto is_buffered() const -> bool { - return (this->file_->_flags & unbuffered) == 0; - } - - void init_buffer() { - if (this->file_->_IO_write_ptr < this->file_->_IO_write_end) return; - // Force buffer initialization by placing and removing a char in a buffer. - putc_unlocked(0, this->file_); - --this->file_->_IO_write_ptr; - } - - // Returns the file's read buffer. - auto get_read_buffer() const -> span { - auto ptr = this->file_->_IO_read_ptr; - return {ptr, to_unsigned(this->file_->_IO_read_end - ptr)}; - } - - // Returns the file's write buffer. - auto get_write_buffer() const -> span { - auto ptr = this->file_->_IO_write_ptr; - return {ptr, to_unsigned(this->file_->_IO_buf_end - ptr)}; - } - - void advance_write_buffer(size_t size) { this->file_->_IO_write_ptr += size; } - - auto needs_flush() const -> bool { - if ((this->file_->_flags & line_buffered) == 0) return false; - char* end = this->file_->_IO_write_end; - auto size = max_of(this->file_->_IO_write_ptr - end, 0); - return memchr(end, '\n', static_cast(size)); - } - - void flush() { fflush_unlocked(this->file_); } -}; - -// A FILE wrapper for Apple's libc. -template class apple_file : public file_base { - private: - enum { - line_buffered = 1, // __SNBF - unbuffered = 2 // __SLBF - }; - - public: - using file_base::file_base; - - auto is_buffered() const -> bool { - return (this->file_->_flags & unbuffered) == 0; - } - - void init_buffer() { - if (this->file_->_p) return; - // Force buffer initialization by placing and removing a char in a buffer. - if (!FMT_CLANG_ANALYZER) putc_unlocked(0, this->file_); - --this->file_->_p; - ++this->file_->_w; - } - - auto get_read_buffer() const -> span { - return {reinterpret_cast(this->file_->_p), - to_unsigned(this->file_->_r)}; - } - - auto get_write_buffer() const -> span { - return {reinterpret_cast(this->file_->_p), - to_unsigned(this->file_->_bf._base + this->file_->_bf._size - - this->file_->_p)}; - } - - void advance_write_buffer(size_t size) { - this->file_->_p += size; - this->file_->_w -= size; - } - - auto needs_flush() const -> bool { - if ((this->file_->_flags & line_buffered) == 0) return false; - return memchr(this->file_->_p + this->file_->_w, '\n', - to_unsigned(-this->file_->_w)); - } -}; - -// A fallback FILE wrapper. -template class fallback_file : public file_base { - private: - char next_; // The next unconsumed character in the buffer. - bool has_next_ = false; - - public: - using file_base::file_base; - - auto is_buffered() const -> bool { return false; } - auto needs_flush() const -> bool { return false; } - void init_buffer() {} - - auto get_read_buffer() const -> span { - return {&next_, has_next_ ? 1u : 0u}; - } - - auto get_write_buffer() const -> span { return {nullptr, 0}; } - - void advance_write_buffer(size_t) {} - - auto get() -> int { - has_next_ = false; - return file_base::get(); - } - - void unget(char c) { - file_base::unget(c); - next_ = c; - has_next_ = true; - } -}; - -#ifndef FMT_USE_FALLBACK_FILE -# define FMT_USE_FALLBACK_FILE 0 -#endif - -template -auto get_file(F* f, int) -> apple_file { - return f; -} -template -inline auto get_file(F* f, int) -> glibc_file { - return f; -} - -inline auto get_file(FILE* f, ...) -> fallback_file { return f; } - -using file_ref = decltype(get_file(static_cast(nullptr), 0)); - -template -class file_print_buffer : public buffer { - public: - explicit file_print_buffer(F*) : buffer(nullptr, size_t()) {} -}; - -template -class file_print_buffer::value>> - : public buffer { - private: - file_ref file_; - - static void grow(buffer& base, size_t) { - auto& self = static_cast(base); - self.file_.advance_write_buffer(self.size()); - if (self.file_.get_write_buffer().size == 0) self.file_.flush(); - auto buf = self.file_.get_write_buffer(); - FMT_ASSERT(buf.size > 0, ""); - self.set(buf.data, buf.size); - self.clear(); - } - - public: - explicit file_print_buffer(F* f) : buffer(grow, size_t()), file_(f) { - flockfile(f); - file_.init_buffer(); - auto buf = file_.get_write_buffer(); - set(buf.data, buf.size); - } - ~file_print_buffer() { - file_.advance_write_buffer(size()); - bool flush = file_.needs_flush(); - F* f = file_; // Make funlockfile depend on the template parameter F - funlockfile(f); // for the system API detection to work. - if (flush) fflush(file_); - } -}; - -#if !defined(_WIN32) || defined(FMT_USE_WRITE_CONSOLE) -FMT_FUNC auto write_console(int, string_view) -> bool { return false; } -#else -using dword = conditional_t; -extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( // - void*, const void*, dword, dword*, void*); - -FMT_FUNC bool write_console(int fd, string_view text) { - auto u16 = utf8_to_utf16(text); - return WriteConsoleW(reinterpret_cast(_get_osfhandle(fd)), u16.c_str(), - static_cast(u16.size()), nullptr, nullptr) != 0; -} -#endif - -#ifdef _WIN32 -// Print assuming legacy (non-Unicode) encoding. -FMT_FUNC void vprint_mojibake(std::FILE* f, string_view fmt, format_args args, - bool newline) { - auto buffer = memory_buffer(); - detail::vformat_to(buffer, fmt, args); - if (newline) buffer.push_back('\n'); - fwrite_all(buffer.data(), buffer.size(), f); -} -#endif - -FMT_FUNC void print(std::FILE* f, string_view text) { -#if defined(_WIN32) && !defined(FMT_USE_WRITE_CONSOLE) - int fd = _fileno(f); - if (_isatty(fd)) { - std::fflush(f); - if (write_console(fd, text)) return; - } -#endif - fwrite_all(text.data(), text.size(), f); -} -} // namespace detail - -FMT_FUNC void vprint_buffered(std::FILE* f, string_view fmt, format_args args) { - auto buffer = memory_buffer(); - detail::vformat_to(buffer, fmt, args); - detail::print(f, {buffer.data(), buffer.size()}); -} - -FMT_FUNC void vprint(std::FILE* f, string_view fmt, format_args args) { - if (!detail::file_ref(f).is_buffered() || !detail::has_flockfile<>()) - return vprint_buffered(f, fmt, args); - auto&& buffer = detail::file_print_buffer<>(f); - return detail::vformat_to(buffer, fmt, args); -} - -FMT_FUNC void vprintln(std::FILE* f, string_view fmt, format_args args) { - auto buffer = memory_buffer(); - detail::vformat_to(buffer, fmt, args); - buffer.push_back('\n'); - detail::print(f, {buffer.data(), buffer.size()}); -} - -FMT_FUNC void vprint(string_view fmt, format_args args) { - vprint(stdout, fmt, args); -} - -namespace detail { - -struct singleton { - unsigned char upper; - unsigned char lower_count; -}; - -inline auto is_printable(uint16_t x, const singleton* singletons, - size_t singletons_size, - const unsigned char* singleton_lowers, - const unsigned char* normal, size_t normal_size) - -> bool { - auto upper = x >> 8; - auto lower_start = 0; - for (size_t i = 0; i < singletons_size; ++i) { - auto s = singletons[i]; - auto lower_end = lower_start + s.lower_count; - if (upper < s.upper) break; - if (upper == s.upper) { - for (auto j = lower_start; j < lower_end; ++j) { - if (singleton_lowers[j] == (x & 0xff)) return false; - } - } - lower_start = lower_end; - } - - auto xsigned = static_cast(x); - auto current = true; - for (size_t i = 0; i < normal_size; ++i) { - auto v = static_cast(normal[i]); - auto len = (v & 0x80) != 0 ? (v & 0x7f) << 8 | normal[++i] : v; - xsigned -= len; - if (xsigned < 0) break; - current = !current; - } - return current; -} - -// This code is generated by support/printable.py. -FMT_FUNC auto is_printable(uint32_t cp) -> bool { - static constexpr singleton singletons0[] = { - {0x00, 1}, {0x03, 5}, {0x05, 6}, {0x06, 3}, {0x07, 6}, {0x08, 8}, - {0x09, 17}, {0x0a, 28}, {0x0b, 25}, {0x0c, 20}, {0x0d, 16}, {0x0e, 13}, - {0x0f, 4}, {0x10, 3}, {0x12, 18}, {0x13, 9}, {0x16, 1}, {0x17, 5}, - {0x18, 2}, {0x19, 3}, {0x1a, 7}, {0x1c, 2}, {0x1d, 1}, {0x1f, 22}, - {0x20, 3}, {0x2b, 3}, {0x2c, 2}, {0x2d, 11}, {0x2e, 1}, {0x30, 3}, - {0x31, 2}, {0x32, 1}, {0xa7, 2}, {0xa9, 2}, {0xaa, 4}, {0xab, 8}, - {0xfa, 2}, {0xfb, 5}, {0xfd, 4}, {0xfe, 3}, {0xff, 9}, - }; - static constexpr unsigned char singletons0_lower[] = { - 0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57, 0x58, 0x8b, 0x8c, 0x90, - 0x1c, 0x1d, 0xdd, 0x0e, 0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f, - 0x5c, 0x5d, 0x5f, 0xb5, 0xe2, 0x84, 0x8d, 0x8e, 0x91, 0x92, 0xa9, 0xb1, - 0xba, 0xbb, 0xc5, 0xc6, 0xc9, 0xca, 0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04, - 0x11, 0x12, 0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49, 0x4a, 0x5d, - 0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4, 0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf, - 0xe4, 0xe5, 0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a, - 0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e, 0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d, - 0xc9, 0xce, 0xcf, 0x0d, 0x11, 0x29, 0x45, 0x49, 0x57, 0x64, 0x65, 0x8d, - 0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x0d, - 0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5, - 0xd7, 0xf0, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf, 0xc5, 0xc7, - 0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, - 0x4e, 0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1, 0xb6, 0xb7, - 0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, - 0xfe, 0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f, 0x1f, 0x6e, - 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16, - 0x17, 0x1e, 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e, 0x7e, - 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, - 0x74, 0x75, 0x96, 0x2f, 0x5f, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf, - 0xc7, 0xcf, 0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98, 0x30, 0x8f, 0x1f, 0xc0, - 0xc1, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27, - 0x2f, 0xee, 0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90, 0x91, - 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7, - 0xfe, 0xff, - }; - static constexpr singleton singletons1[] = { - {0x00, 6}, {0x01, 1}, {0x03, 1}, {0x04, 2}, {0x08, 8}, {0x09, 2}, - {0x0a, 5}, {0x0b, 2}, {0x0e, 4}, {0x10, 1}, {0x11, 2}, {0x12, 5}, - {0x13, 17}, {0x14, 1}, {0x15, 2}, {0x17, 2}, {0x19, 13}, {0x1c, 5}, - {0x1d, 8}, {0x24, 1}, {0x6a, 3}, {0x6b, 2}, {0xbc, 2}, {0xd1, 2}, - {0xd4, 12}, {0xd5, 9}, {0xd6, 2}, {0xd7, 2}, {0xda, 1}, {0xe0, 5}, - {0xe1, 2}, {0xe8, 2}, {0xee, 32}, {0xf0, 4}, {0xf8, 2}, {0xf9, 2}, - {0xfa, 2}, {0xfb, 1}, - }; - static constexpr unsigned char singletons1_lower[] = { - 0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e, 0x9e, 0x9f, 0x06, 0x07, - 0x09, 0x36, 0x3d, 0x3e, 0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36, - 0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf, 0xbd, 0x35, 0xe0, 0x12, 0x87, - 0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a, - 0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5c, 0xb6, 0xb7, 0x1b, - 0x1c, 0x07, 0x08, 0x0a, 0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8, 0xa9, - 0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x66, - 0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27, - 0x28, 0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, 0xba, 0xbc, - 0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, - 0xcc, 0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e, 0x3f, 0xc5, 0xc6, - 0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c, - 0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66, - 0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0, - 0xae, 0xaf, 0x79, 0xcc, 0x6e, 0x6f, 0x93, - }; - static constexpr unsigned char normal0[] = { - 0x00, 0x20, 0x5f, 0x22, 0x82, 0xdf, 0x04, 0x82, 0x44, 0x08, 0x1b, 0x04, - 0x06, 0x11, 0x81, 0xac, 0x0e, 0x80, 0xab, 0x35, 0x28, 0x0b, 0x80, 0xe0, - 0x03, 0x19, 0x08, 0x01, 0x04, 0x2f, 0x04, 0x34, 0x04, 0x07, 0x03, 0x01, - 0x07, 0x06, 0x07, 0x11, 0x0a, 0x50, 0x0f, 0x12, 0x07, 0x55, 0x07, 0x03, - 0x04, 0x1c, 0x0a, 0x09, 0x03, 0x08, 0x03, 0x07, 0x03, 0x02, 0x03, 0x03, - 0x03, 0x0c, 0x04, 0x05, 0x03, 0x0b, 0x06, 0x01, 0x0e, 0x15, 0x05, 0x3a, - 0x03, 0x11, 0x07, 0x06, 0x05, 0x10, 0x07, 0x57, 0x07, 0x02, 0x07, 0x15, - 0x0d, 0x50, 0x04, 0x43, 0x03, 0x2d, 0x03, 0x01, 0x04, 0x11, 0x06, 0x0f, - 0x0c, 0x3a, 0x04, 0x1d, 0x25, 0x5f, 0x20, 0x6d, 0x04, 0x6a, 0x25, 0x80, - 0xc8, 0x05, 0x82, 0xb0, 0x03, 0x1a, 0x06, 0x82, 0xfd, 0x03, 0x59, 0x07, - 0x15, 0x0b, 0x17, 0x09, 0x14, 0x0c, 0x14, 0x0c, 0x6a, 0x06, 0x0a, 0x06, - 0x1a, 0x06, 0x59, 0x07, 0x2b, 0x05, 0x46, 0x0a, 0x2c, 0x04, 0x0c, 0x04, - 0x01, 0x03, 0x31, 0x0b, 0x2c, 0x04, 0x1a, 0x06, 0x0b, 0x03, 0x80, 0xac, - 0x06, 0x0a, 0x06, 0x21, 0x3f, 0x4c, 0x04, 0x2d, 0x03, 0x74, 0x08, 0x3c, - 0x03, 0x0f, 0x03, 0x3c, 0x07, 0x38, 0x08, 0x2b, 0x05, 0x82, 0xff, 0x11, - 0x18, 0x08, 0x2f, 0x11, 0x2d, 0x03, 0x20, 0x10, 0x21, 0x0f, 0x80, 0x8c, - 0x04, 0x82, 0x97, 0x19, 0x0b, 0x15, 0x88, 0x94, 0x05, 0x2f, 0x05, 0x3b, - 0x07, 0x02, 0x0e, 0x18, 0x09, 0x80, 0xb3, 0x2d, 0x74, 0x0c, 0x80, 0xd6, - 0x1a, 0x0c, 0x05, 0x80, 0xff, 0x05, 0x80, 0xdf, 0x0c, 0xee, 0x0d, 0x03, - 0x84, 0x8d, 0x03, 0x37, 0x09, 0x81, 0x5c, 0x14, 0x80, 0xb8, 0x08, 0x80, - 0xcb, 0x2a, 0x38, 0x03, 0x0a, 0x06, 0x38, 0x08, 0x46, 0x08, 0x0c, 0x06, - 0x74, 0x0b, 0x1e, 0x03, 0x5a, 0x04, 0x59, 0x09, 0x80, 0x83, 0x18, 0x1c, - 0x0a, 0x16, 0x09, 0x4c, 0x04, 0x80, 0x8a, 0x06, 0xab, 0xa4, 0x0c, 0x17, - 0x04, 0x31, 0xa1, 0x04, 0x81, 0xda, 0x26, 0x07, 0x0c, 0x05, 0x05, 0x80, - 0xa5, 0x11, 0x81, 0x6d, 0x10, 0x78, 0x28, 0x2a, 0x06, 0x4c, 0x04, 0x80, - 0x8d, 0x04, 0x80, 0xbe, 0x03, 0x1b, 0x03, 0x0f, 0x0d, - }; - static constexpr unsigned char normal1[] = { - 0x5e, 0x22, 0x7b, 0x05, 0x03, 0x04, 0x2d, 0x03, 0x66, 0x03, 0x01, 0x2f, - 0x2e, 0x80, 0x82, 0x1d, 0x03, 0x31, 0x0f, 0x1c, 0x04, 0x24, 0x09, 0x1e, - 0x05, 0x2b, 0x05, 0x44, 0x04, 0x0e, 0x2a, 0x80, 0xaa, 0x06, 0x24, 0x04, - 0x24, 0x04, 0x28, 0x08, 0x34, 0x0b, 0x01, 0x80, 0x90, 0x81, 0x37, 0x09, - 0x16, 0x0a, 0x08, 0x80, 0x98, 0x39, 0x03, 0x63, 0x08, 0x09, 0x30, 0x16, - 0x05, 0x21, 0x03, 0x1b, 0x05, 0x01, 0x40, 0x38, 0x04, 0x4b, 0x05, 0x2f, - 0x04, 0x0a, 0x07, 0x09, 0x07, 0x40, 0x20, 0x27, 0x04, 0x0c, 0x09, 0x36, - 0x03, 0x3a, 0x05, 0x1a, 0x07, 0x04, 0x0c, 0x07, 0x50, 0x49, 0x37, 0x33, - 0x0d, 0x33, 0x07, 0x2e, 0x08, 0x0a, 0x81, 0x26, 0x52, 0x4e, 0x28, 0x08, - 0x2a, 0x56, 0x1c, 0x14, 0x17, 0x09, 0x4e, 0x04, 0x1e, 0x0f, 0x43, 0x0e, - 0x19, 0x07, 0x0a, 0x06, 0x48, 0x08, 0x27, 0x09, 0x75, 0x0b, 0x3f, 0x41, - 0x2a, 0x06, 0x3b, 0x05, 0x0a, 0x06, 0x51, 0x06, 0x01, 0x05, 0x10, 0x03, - 0x05, 0x80, 0x8b, 0x62, 0x1e, 0x48, 0x08, 0x0a, 0x80, 0xa6, 0x5e, 0x22, - 0x45, 0x0b, 0x0a, 0x06, 0x0d, 0x13, 0x39, 0x07, 0x0a, 0x36, 0x2c, 0x04, - 0x10, 0x80, 0xc0, 0x3c, 0x64, 0x53, 0x0c, 0x48, 0x09, 0x0a, 0x46, 0x45, - 0x1b, 0x48, 0x08, 0x53, 0x1d, 0x39, 0x81, 0x07, 0x46, 0x0a, 0x1d, 0x03, - 0x47, 0x49, 0x37, 0x03, 0x0e, 0x08, 0x0a, 0x06, 0x39, 0x07, 0x0a, 0x81, - 0x36, 0x19, 0x80, 0xb7, 0x01, 0x0f, 0x32, 0x0d, 0x83, 0x9b, 0x66, 0x75, - 0x0b, 0x80, 0xc4, 0x8a, 0xbc, 0x84, 0x2f, 0x8f, 0xd1, 0x82, 0x47, 0xa1, - 0xb9, 0x82, 0x39, 0x07, 0x2a, 0x04, 0x02, 0x60, 0x26, 0x0a, 0x46, 0x0a, - 0x28, 0x05, 0x13, 0x82, 0xb0, 0x5b, 0x65, 0x4b, 0x04, 0x39, 0x07, 0x11, - 0x40, 0x05, 0x0b, 0x02, 0x0e, 0x97, 0xf8, 0x08, 0x84, 0xd6, 0x2a, 0x09, - 0xa2, 0xf7, 0x81, 0x1f, 0x31, 0x03, 0x11, 0x04, 0x08, 0x81, 0x8c, 0x89, - 0x04, 0x6b, 0x05, 0x0d, 0x03, 0x09, 0x07, 0x10, 0x93, 0x60, 0x80, 0xf6, - 0x0a, 0x73, 0x08, 0x6e, 0x17, 0x46, 0x80, 0x9a, 0x14, 0x0c, 0x57, 0x09, - 0x19, 0x80, 0x87, 0x81, 0x47, 0x03, 0x85, 0x42, 0x0f, 0x15, 0x85, 0x50, - 0x2b, 0x80, 0xd5, 0x2d, 0x03, 0x1a, 0x04, 0x02, 0x81, 0x70, 0x3a, 0x05, - 0x01, 0x85, 0x00, 0x80, 0xd7, 0x29, 0x4c, 0x04, 0x0a, 0x04, 0x02, 0x83, - 0x11, 0x44, 0x4c, 0x3d, 0x80, 0xc2, 0x3c, 0x06, 0x01, 0x04, 0x55, 0x05, - 0x1b, 0x34, 0x02, 0x81, 0x0e, 0x2c, 0x04, 0x64, 0x0c, 0x56, 0x0a, 0x80, - 0xae, 0x38, 0x1d, 0x0d, 0x2c, 0x04, 0x09, 0x07, 0x02, 0x0e, 0x06, 0x80, - 0x9a, 0x83, 0xd8, 0x08, 0x0d, 0x03, 0x0d, 0x03, 0x74, 0x0c, 0x59, 0x07, - 0x0c, 0x14, 0x0c, 0x04, 0x38, 0x08, 0x0a, 0x06, 0x28, 0x08, 0x22, 0x4e, - 0x81, 0x54, 0x0c, 0x15, 0x03, 0x03, 0x05, 0x07, 0x09, 0x19, 0x07, 0x07, - 0x09, 0x03, 0x0d, 0x07, 0x29, 0x80, 0xcb, 0x25, 0x0a, 0x84, 0x06, - }; - auto lower = static_cast(cp); - if (cp < 0x10000) { - return is_printable(lower, singletons0, - sizeof(singletons0) / sizeof(*singletons0), - singletons0_lower, normal0, sizeof(normal0)); - } - if (cp < 0x20000) { - return is_printable(lower, singletons1, - sizeof(singletons1) / sizeof(*singletons1), - singletons1_lower, normal1, sizeof(normal1)); - } - if (0x2a6de <= cp && cp < 0x2a700) return false; - if (0x2b735 <= cp && cp < 0x2b740) return false; - if (0x2b81e <= cp && cp < 0x2b820) return false; - if (0x2cea2 <= cp && cp < 0x2ceb0) return false; - if (0x2ebe1 <= cp && cp < 0x2f800) return false; - if (0x2fa1e <= cp && cp < 0x30000) return false; - if (0x3134b <= cp && cp < 0xe0100) return false; - if (0xe01f0 <= cp && cp < 0x110000) return false; - return cp < 0x110000; -} - -} // namespace detail - -FMT_END_NAMESPACE - -#endif // FMT_FORMAT_INL_H_ diff --git a/include/libs/spdlog/fmt/bundled/format.h b/include/libs/spdlog/fmt/bundled/format.h deleted file mode 100644 index 4a65300..0000000 --- a/include/libs/spdlog/fmt/bundled/format.h +++ /dev/null @@ -1,4395 +0,0 @@ -/* - Formatting library for C++ - - Copyright (c) 2012 - present, Victor Zverovich - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - --- Optional exception to the license --- - - As an exception, if, as a result of your compiling your source code, portions - of this Software are embedded into a machine-executable object form of such - source code, you may redistribute such embedded portions in such object form - without including the above copyright and permission notices. - */ - -#ifndef FMT_FORMAT_H_ -#define FMT_FORMAT_H_ - -#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES -# define _LIBCPP_REMOVE_TRANSITIVE_INCLUDES -# define FMT_REMOVE_TRANSITIVE_INCLUDES -#endif - -#include "base.h" - -// libc++ supports string_view in pre-c++17. -#if FMT_HAS_INCLUDE() && \ - (FMT_CPLUSPLUS >= 201703L || defined(_LIBCPP_VERSION)) -# define FMT_USE_STRING_VIEW -#endif - -#ifndef FMT_MODULE -# include // malloc, free - -# include // std::signbit -# include // std::byte -# include // uint32_t -# include // std::memcpy -# include // std::numeric_limits -# include // std::bad_alloc -# if defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI) -// Workaround for pre gcc 5 libstdc++. -# include // std::allocator_traits -# endif -# include // std::runtime_error -# include // std::string -# include // std::system_error - -// Check FMT_CPLUSPLUS to avoid a warning in MSVC. -# if FMT_HAS_INCLUDE() && FMT_CPLUSPLUS > 201703L -# include // std::bit_cast -# endif - -# if defined(FMT_USE_STRING_VIEW) -# include -# endif - -# if FMT_MSC_VERSION -# include // _BitScanReverse[64], _umul128 -# endif -#endif // FMT_MODULE - -#if defined(FMT_USE_NONTYPE_TEMPLATE_ARGS) -// Use the provided definition. -#elif defined(__NVCOMPILER) -# define FMT_USE_NONTYPE_TEMPLATE_ARGS 0 -#elif FMT_GCC_VERSION >= 903 && FMT_CPLUSPLUS >= 201709L -# define FMT_USE_NONTYPE_TEMPLATE_ARGS 1 -#elif defined(__cpp_nontype_template_args) && \ - __cpp_nontype_template_args >= 201911L -# define FMT_USE_NONTYPE_TEMPLATE_ARGS 1 -#elif FMT_CLANG_VERSION >= 1200 && FMT_CPLUSPLUS >= 202002L -# define FMT_USE_NONTYPE_TEMPLATE_ARGS 1 -#else -# define FMT_USE_NONTYPE_TEMPLATE_ARGS 0 -#endif - -#if defined __cpp_inline_variables && __cpp_inline_variables >= 201606L -# define FMT_INLINE_VARIABLE inline -#else -# define FMT_INLINE_VARIABLE -#endif - -// Check if RTTI is disabled. -#ifdef FMT_USE_RTTI -// Use the provided definition. -#elif defined(__GXX_RTTI) || FMT_HAS_FEATURE(cxx_rtti) || defined(_CPPRTTI) || \ - defined(__INTEL_RTTI__) || defined(__RTTI) -// __RTTI is for EDG compilers. _CPPRTTI is for MSVC. -# define FMT_USE_RTTI 1 -#else -# define FMT_USE_RTTI 0 -#endif - -// Visibility when compiled as a shared library/object. -#if defined(FMT_LIB_EXPORT) || defined(FMT_SHARED) -# define FMT_SO_VISIBILITY(value) FMT_VISIBILITY(value) -#else -# define FMT_SO_VISIBILITY(value) -#endif - -#if FMT_GCC_VERSION || FMT_CLANG_VERSION -# define FMT_NOINLINE __attribute__((noinline)) -#else -# define FMT_NOINLINE -#endif - -#ifdef FMT_DEPRECATED -// Use the provided definition. -#elif FMT_HAS_CPP14_ATTRIBUTE(deprecated) -# define FMT_DEPRECATED [[deprecated]] -#else -# define FMT_DEPRECATED /* deprecated */ -#endif - -// Detect constexpr std::string. -#if !FMT_USE_CONSTEVAL -# define FMT_USE_CONSTEXPR_STRING 0 -#elif defined(__cpp_lib_constexpr_string) && \ - __cpp_lib_constexpr_string >= 201907L -# if FMT_CLANG_VERSION && FMT_GLIBCXX_RELEASE -// clang + libstdc++ are able to work only starting with gcc13.3 -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113294 -# if FMT_GLIBCXX_RELEASE < 13 -# define FMT_USE_CONSTEXPR_STRING 0 -# elif FMT_GLIBCXX_RELEASE == 13 && __GLIBCXX__ < 20240521 -# define FMT_USE_CONSTEXPR_STRING 0 -# else -# define FMT_USE_CONSTEXPR_STRING 1 -# endif -# else -# define FMT_USE_CONSTEXPR_STRING 1 -# endif -#else -# define FMT_USE_CONSTEXPR_STRING 0 -#endif -#if FMT_USE_CONSTEXPR_STRING -# define FMT_CONSTEXPR_STRING constexpr -#else -# define FMT_CONSTEXPR_STRING -#endif - -// GCC 4.9 doesn't support qualified names in specializations. -namespace std { -template struct iterator_traits> { - using iterator_category = output_iterator_tag; - using value_type = T; - using difference_type = - decltype(static_cast(nullptr) - static_cast(nullptr)); - using pointer = void; - using reference = void; -}; -} // namespace std - -#ifdef FMT_THROW -// Use the provided definition. -#elif FMT_USE_EXCEPTIONS -# define FMT_THROW(x) throw x -#else -# define FMT_THROW(x) ::fmt::assert_fail(__FILE__, __LINE__, (x).what()) -#endif - -#ifdef __clang_analyzer__ -# define FMT_CLANG_ANALYZER 1 -#else -# define FMT_CLANG_ANALYZER 0 -#endif - -// Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of -// integer formatter template instantiations to just one by only using the -// largest integer type. This results in a reduction in binary size but will -// cause a decrease in integer formatting performance. -#if !defined(FMT_REDUCE_INT_INSTANTIATIONS) -# define FMT_REDUCE_INT_INSTANTIATIONS 0 -#endif - -FMT_BEGIN_NAMESPACE - -template -struct is_contiguous> - : std::true_type {}; - -namespace detail { - -// __builtin_clz is broken in clang with Microsoft codegen: -// https://github.com/fmtlib/fmt/issues/519. -#if !FMT_MSC_VERSION -# if FMT_HAS_BUILTIN(__builtin_clz) || FMT_GCC_VERSION || FMT_ICC_VERSION -# define FMT_BUILTIN_CLZ(n) __builtin_clz(n) -# endif -# if FMT_HAS_BUILTIN(__builtin_clzll) || FMT_GCC_VERSION || FMT_ICC_VERSION -# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) -# endif -#endif - -// Some compilers masquerade as both MSVC and GCC but otherwise support -// __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the -// MSVC intrinsics if the clz and clzll builtins are not available. -#if FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL) -// Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning. -# ifndef __clang__ -# pragma intrinsic(_BitScanReverse) -# ifdef _WIN64 -# pragma intrinsic(_BitScanReverse64) -# endif -# endif - -inline auto clz(uint32_t x) -> int { - FMT_ASSERT(x != 0, ""); - FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning. - unsigned long r = 0; - _BitScanReverse(&r, x); - return 31 ^ static_cast(r); -} -# define FMT_BUILTIN_CLZ(n) detail::clz(n) - -inline auto clzll(uint64_t x) -> int { - FMT_ASSERT(x != 0, ""); - FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning. - unsigned long r = 0; -# ifdef _WIN64 - _BitScanReverse64(&r, x); -# else - // Scan the high 32 bits. - if (_BitScanReverse(&r, static_cast(x >> 32))) - return 63 ^ static_cast(r + 32); - // Scan the low 32 bits. - _BitScanReverse(&r, static_cast(x)); -# endif - return 63 ^ static_cast(r); -} -# define FMT_BUILTIN_CLZLL(n) detail::clzll(n) -#endif // FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL) - -FMT_CONSTEXPR inline void abort_fuzzing_if(bool condition) { - ignore_unused(condition); -#ifdef FMT_FUZZ - if (condition) throw std::runtime_error("fuzzing limit reached"); -#endif -} - -#if defined(FMT_USE_STRING_VIEW) -template using std_string_view = std::basic_string_view; -#else -template struct std_string_view { - operator basic_string_view() const; -}; -#endif - -template struct string_literal { - static constexpr Char value[sizeof...(C)] = {C...}; - constexpr operator basic_string_view() const { - return {value, sizeof...(C)}; - } -}; -#if FMT_CPLUSPLUS < 201703L -template -constexpr Char string_literal::value[sizeof...(C)]; -#endif - -// Implementation of std::bit_cast for pre-C++20. -template -FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To { -#ifdef __cpp_lib_bit_cast - if (is_constant_evaluated()) return std::bit_cast(from); -#endif - auto to = To(); - // The cast suppresses a bogus -Wclass-memaccess on GCC. - std::memcpy(static_cast(&to), &from, sizeof(to)); - return to; -} - -inline auto is_big_endian() -> bool { -#ifdef _WIN32 - return false; -#elif defined(__BIG_ENDIAN__) - return true; -#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) - return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__; -#else - struct bytes { - char data[sizeof(int)]; - }; - return bit_cast(1).data[0] == 0; -#endif -} - -class uint128_fallback { - private: - uint64_t lo_, hi_; - - public: - constexpr uint128_fallback(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {} - constexpr uint128_fallback(uint64_t value = 0) : lo_(value), hi_(0) {} - - constexpr auto high() const noexcept -> uint64_t { return hi_; } - constexpr auto low() const noexcept -> uint64_t { return lo_; } - - template ::value)> - constexpr explicit operator T() const { - return static_cast(lo_); - } - - friend constexpr auto operator==(const uint128_fallback& lhs, - const uint128_fallback& rhs) -> bool { - return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_; - } - friend constexpr auto operator!=(const uint128_fallback& lhs, - const uint128_fallback& rhs) -> bool { - return !(lhs == rhs); - } - friend constexpr auto operator>(const uint128_fallback& lhs, - const uint128_fallback& rhs) -> bool { - return lhs.hi_ != rhs.hi_ ? lhs.hi_ > rhs.hi_ : lhs.lo_ > rhs.lo_; - } - friend constexpr auto operator|(const uint128_fallback& lhs, - const uint128_fallback& rhs) - -> uint128_fallback { - return {lhs.hi_ | rhs.hi_, lhs.lo_ | rhs.lo_}; - } - friend constexpr auto operator&(const uint128_fallback& lhs, - const uint128_fallback& rhs) - -> uint128_fallback { - return {lhs.hi_ & rhs.hi_, lhs.lo_ & rhs.lo_}; - } - friend constexpr auto operator~(const uint128_fallback& n) - -> uint128_fallback { - return {~n.hi_, ~n.lo_}; - } - friend FMT_CONSTEXPR auto operator+(const uint128_fallback& lhs, - const uint128_fallback& rhs) - -> uint128_fallback { - auto result = uint128_fallback(lhs); - result += rhs; - return result; - } - friend FMT_CONSTEXPR auto operator*(const uint128_fallback& lhs, uint32_t rhs) - -> uint128_fallback { - FMT_ASSERT(lhs.hi_ == 0, ""); - uint64_t hi = (lhs.lo_ >> 32) * rhs; - uint64_t lo = (lhs.lo_ & ~uint32_t()) * rhs; - uint64_t new_lo = (hi << 32) + lo; - return {(hi >> 32) + (new_lo < lo ? 1 : 0), new_lo}; - } - friend constexpr auto operator-(const uint128_fallback& lhs, uint64_t rhs) - -> uint128_fallback { - return {lhs.hi_ - (lhs.lo_ < rhs ? 1 : 0), lhs.lo_ - rhs}; - } - FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback { - if (shift == 64) return {0, hi_}; - if (shift > 64) return uint128_fallback(0, hi_) >> (shift - 64); - return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)}; - } - FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback { - if (shift == 64) return {lo_, 0}; - if (shift > 64) return uint128_fallback(lo_, 0) << (shift - 64); - return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)}; - } - FMT_CONSTEXPR auto operator>>=(int shift) -> uint128_fallback& { - return *this = *this >> shift; - } - FMT_CONSTEXPR void operator+=(uint128_fallback n) { - uint64_t new_lo = lo_ + n.lo_; - uint64_t new_hi = hi_ + n.hi_ + (new_lo < lo_ ? 1 : 0); - FMT_ASSERT(new_hi >= hi_, ""); - lo_ = new_lo; - hi_ = new_hi; - } - FMT_CONSTEXPR void operator&=(uint128_fallback n) { - lo_ &= n.lo_; - hi_ &= n.hi_; - } - - FMT_CONSTEXPR20 auto operator+=(uint64_t n) noexcept -> uint128_fallback& { - if (is_constant_evaluated()) { - lo_ += n; - hi_ += (lo_ < n ? 1 : 0); - return *this; - } -#if FMT_HAS_BUILTIN(__builtin_addcll) && !defined(__ibmxl__) - unsigned long long carry; - lo_ = __builtin_addcll(lo_, n, 0, &carry); - hi_ += carry; -#elif FMT_HAS_BUILTIN(__builtin_ia32_addcarryx_u64) && !defined(__ibmxl__) - unsigned long long result; - auto carry = __builtin_ia32_addcarryx_u64(0, lo_, n, &result); - lo_ = result; - hi_ += carry; -#elif defined(_MSC_VER) && defined(_M_X64) - auto carry = _addcarry_u64(0, lo_, n, &lo_); - _addcarry_u64(carry, hi_, 0, &hi_); -#else - lo_ += n; - hi_ += (lo_ < n ? 1 : 0); -#endif - return *this; - } -}; - -using uint128_t = conditional_t; - -#ifdef UINTPTR_MAX -using uintptr_t = ::uintptr_t; -#else -using uintptr_t = uint128_t; -#endif - -// Returns the largest possible value for type T. Same as -// std::numeric_limits::max() but shorter and not affected by the max macro. -template constexpr auto max_value() -> T { - return (std::numeric_limits::max)(); -} -template constexpr auto num_bits() -> int { - return std::numeric_limits::digits; -} -// std::numeric_limits::digits may return 0 for 128-bit ints. -template <> constexpr auto num_bits() -> int { return 128; } -template <> constexpr auto num_bits() -> int { return 128; } -template <> constexpr auto num_bits() -> int { return 128; } - -// A heterogeneous bit_cast used for converting 96-bit long double to uint128_t -// and 128-bit pointers to uint128_fallback. -template sizeof(From))> -inline auto bit_cast(const From& from) -> To { - constexpr auto size = static_cast(sizeof(From) / sizeof(unsigned short)); - struct data_t { - unsigned short value[static_cast(size)]; - } data = bit_cast(from); - auto result = To(); - if (const_check(is_big_endian())) { - for (int i = 0; i < size; ++i) - result = (result << num_bits()) | data.value[i]; - } else { - for (int i = size - 1; i >= 0; --i) - result = (result << num_bits()) | data.value[i]; - } - return result; -} - -template -FMT_CONSTEXPR20 inline auto countl_zero_fallback(UInt n) -> int { - int lz = 0; - constexpr UInt msb_mask = static_cast(1) << (num_bits() - 1); - for (; (n & msb_mask) == 0; n <<= 1) lz++; - return lz; -} - -FMT_CONSTEXPR20 inline auto countl_zero(uint32_t n) -> int { -#ifdef FMT_BUILTIN_CLZ - if (!is_constant_evaluated()) return FMT_BUILTIN_CLZ(n); -#endif - return countl_zero_fallback(n); -} - -FMT_CONSTEXPR20 inline auto countl_zero(uint64_t n) -> int { -#ifdef FMT_BUILTIN_CLZLL - if (!is_constant_evaluated()) return FMT_BUILTIN_CLZLL(n); -#endif - return countl_zero_fallback(n); -} - -FMT_INLINE void assume(bool condition) { - (void)condition; -#if FMT_HAS_BUILTIN(__builtin_assume) && !FMT_ICC_VERSION - __builtin_assume(condition); -#elif FMT_GCC_VERSION - if (!condition) __builtin_unreachable(); -#endif -} - -// Attempts to reserve space for n extra characters in the output range. -// Returns a pointer to the reserved range or a reference to it. -template ::value&& - is_contiguous::value)> -#if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION -__attribute__((no_sanitize("undefined"))) -#endif -FMT_CONSTEXPR20 inline auto -reserve(OutputIt it, size_t n) -> typename OutputIt::value_type* { - auto& c = get_container(it); - size_t size = c.size(); - c.resize(size + n); - return &c[size]; -} - -template -FMT_CONSTEXPR20 inline auto reserve(basic_appender it, size_t n) - -> basic_appender { - buffer& buf = get_container(it); - buf.try_reserve(buf.size() + n); - return it; -} - -template -constexpr auto reserve(Iterator& it, size_t) -> Iterator& { - return it; -} - -template -using reserve_iterator = - remove_reference_t(), 0))>; - -template -constexpr auto to_pointer(OutputIt, size_t) -> T* { - return nullptr; -} -template FMT_CONSTEXPR auto to_pointer(T*& ptr, size_t n) -> T* { - T* begin = ptr; - ptr += n; - return begin; -} -template -FMT_CONSTEXPR20 auto to_pointer(basic_appender it, size_t n) -> T* { - buffer& buf = get_container(it); - buf.try_reserve(buf.size() + n); - auto size = buf.size(); - if (buf.capacity() < size + n) return nullptr; - buf.try_resize(size + n); - return buf.data() + size; -} - -template ::value&& - is_contiguous::value)> -inline auto base_iterator(OutputIt it, - typename OutputIt::container_type::value_type*) - -> OutputIt { - return it; -} - -template -constexpr auto base_iterator(Iterator, Iterator it) -> Iterator { - return it; -} - -// is spectacularly slow to compile in C++20 so use a simple fill_n -// instead (#1998). -template -FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value) - -> OutputIt { - for (Size i = 0; i < count; ++i) *out++ = value; - return out; -} -template -FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* { - if (is_constant_evaluated()) return fill_n(out, count, value); - static_assert(sizeof(T) == 1, - "sizeof(T) must be 1 to use char for initialization"); - std::memset(out, value, to_unsigned(count)); - return out + count; -} - -template -FMT_CONSTEXPR FMT_NOINLINE auto copy_noinline(InputIt begin, InputIt end, - OutputIt out) -> OutputIt { - return copy(begin, end, out); -} - -// A public domain branchless UTF-8 decoder by Christopher Wellons: -// https://github.com/skeeto/branchless-utf8 -/* Decode the next character, c, from s, reporting errors in e. - * - * Since this is a branchless decoder, four bytes will be read from the - * buffer regardless of the actual length of the next character. This - * means the buffer _must_ have at least three bytes of zero padding - * following the end of the data stream. - * - * Errors are reported in e, which will be non-zero if the parsed - * character was somehow invalid: invalid byte sequence, non-canonical - * encoding, or a surrogate half. - * - * The function returns a pointer to the next character. When an error - * occurs, this pointer will be a guess that depends on the particular - * error, but it will always advance at least one byte. - */ -FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e) - -> const char* { - constexpr int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07}; - constexpr uint32_t mins[] = {4194304, 0, 128, 2048, 65536}; - constexpr int shiftc[] = {0, 18, 12, 6, 0}; - constexpr int shifte[] = {0, 6, 4, 2, 0}; - - int len = "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\2\2\2\2\3\3\4" - [static_cast(*s) >> 3]; - // Compute the pointer to the next character early so that the next - // iteration can start working on the next character. Neither Clang - // nor GCC figure out this reordering on their own. - const char* next = s + len + !len; - - using uchar = unsigned char; - - // Assume a four-byte character and load four bytes. Unused bits are - // shifted out. - *c = uint32_t(uchar(s[0]) & masks[len]) << 18; - *c |= uint32_t(uchar(s[1]) & 0x3f) << 12; - *c |= uint32_t(uchar(s[2]) & 0x3f) << 6; - *c |= uint32_t(uchar(s[3]) & 0x3f) << 0; - *c >>= shiftc[len]; - - // Accumulate the various error conditions. - *e = (*c < mins[len]) << 6; // non-canonical encoding - *e |= ((*c >> 11) == 0x1b) << 7; // surrogate half? - *e |= (*c > 0x10FFFF) << 8; // out of range? - *e |= (uchar(s[1]) & 0xc0) >> 2; - *e |= (uchar(s[2]) & 0xc0) >> 4; - *e |= uchar(s[3]) >> 6; - *e ^= 0x2a; // top two bits of each tail byte correct? - *e >>= shifte[len]; - - return next; -} - -constexpr FMT_INLINE_VARIABLE uint32_t invalid_code_point = ~uint32_t(); - -// Invokes f(cp, sv) for every code point cp in s with sv being the string view -// corresponding to the code point. cp is invalid_code_point on error. -template -FMT_CONSTEXPR void for_each_codepoint(string_view s, F f) { - auto decode = [f](const char* buf_ptr, const char* ptr) { - auto cp = uint32_t(); - auto error = 0; - auto end = utf8_decode(buf_ptr, &cp, &error); - bool result = f(error ? invalid_code_point : cp, - string_view(ptr, error ? 1 : to_unsigned(end - buf_ptr))); - return result ? (error ? buf_ptr + 1 : end) : nullptr; - }; - - auto p = s.data(); - const size_t block_size = 4; // utf8_decode always reads blocks of 4 chars. - if (s.size() >= block_size) { - for (auto end = p + s.size() - block_size + 1; p < end;) { - p = decode(p, p); - if (!p) return; - } - } - auto num_chars_left = to_unsigned(s.data() + s.size() - p); - if (num_chars_left == 0) return; - - // Suppress bogus -Wstringop-overflow. - if (FMT_GCC_VERSION) num_chars_left &= 3; - char buf[2 * block_size - 1] = {}; - copy(p, p + num_chars_left, buf); - const char* buf_ptr = buf; - do { - auto end = decode(buf_ptr, p); - if (!end) return; - p += end - buf_ptr; - buf_ptr = end; - } while (buf_ptr < buf + num_chars_left); -} - -FMT_CONSTEXPR inline auto display_width_of(uint32_t cp) noexcept -> size_t { - return to_unsigned( - 1 + (cp >= 0x1100 && - (cp <= 0x115f || // Hangul Jamo init. consonants - cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET - cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET - // CJK ... Yi except IDEOGRAPHIC HALF FILL SPACE: - (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) || - (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables - (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs - (cp >= 0xfe10 && cp <= 0xfe19) || // Vertical Forms - (cp >= 0xfe30 && cp <= 0xfe6f) || // CJK Compatibility Forms - (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms - (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Forms - (cp >= 0x20000 && cp <= 0x2fffd) || // CJK - (cp >= 0x30000 && cp <= 0x3fffd) || - // Miscellaneous Symbols and Pictographs + Emoticons: - (cp >= 0x1f300 && cp <= 0x1f64f) || - // Supplemental Symbols and Pictographs: - (cp >= 0x1f900 && cp <= 0x1f9ff)))); -} - -template struct is_integral : std::is_integral {}; -template <> struct is_integral : std::true_type {}; -template <> struct is_integral : std::true_type {}; - -template -using is_signed = - std::integral_constant::is_signed || - std::is_same::value>; - -template -using is_integer = - bool_constant::value && !std::is_same::value && - !std::is_same::value && - !std::is_same::value>; - -#if defined(FMT_USE_FLOAT128) -// Use the provided definition. -#elif FMT_CLANG_VERSION >= 309 && FMT_HAS_INCLUDE() -# define FMT_USE_FLOAT128 1 -#elif FMT_GCC_VERSION && defined(_GLIBCXX_USE_FLOAT128) && \ - !defined(__STRICT_ANSI__) -# define FMT_USE_FLOAT128 1 -#else -# define FMT_USE_FLOAT128 0 -#endif -#if FMT_USE_FLOAT128 -using float128 = __float128; -#else -struct float128 {}; -#endif - -template using is_float128 = std::is_same; - -template struct is_floating_point : std::is_floating_point {}; -template <> struct is_floating_point : std::true_type {}; - -template ::value> -struct is_fast_float : bool_constant::is_iec559 && - sizeof(T) <= sizeof(double)> {}; -template struct is_fast_float : std::false_type {}; - -template -using fast_float_t = conditional_t; - -template -using is_double_double = bool_constant::digits == 106>; - -#ifndef FMT_USE_FULL_CACHE_DRAGONBOX -# define FMT_USE_FULL_CACHE_DRAGONBOX 0 -#endif - -// An allocator that uses malloc/free to allow removing dependency on the C++ -// standard libary runtime. std::decay is used for back_inserter to be found by -// ADL when applied to memory_buffer. -template struct allocator : private std::decay { - using value_type = T; - - auto allocate(size_t n) -> T* { - FMT_ASSERT(n <= max_value() / sizeof(T), ""); - T* p = static_cast(malloc(n * sizeof(T))); - if (!p) FMT_THROW(std::bad_alloc()); - return p; - } - - void deallocate(T* p, size_t) { free(p); } - - constexpr friend auto operator==(allocator, allocator) noexcept -> bool { - return true; // All instances of this allocator are equivalent. - } - constexpr friend auto operator!=(allocator, allocator) noexcept -> bool { - return false; - } -}; - -template -FMT_CONSTEXPR auto maybe_set_debug_format(Formatter& f, bool set) - -> decltype(f.set_debug_format(set)) { - f.set_debug_format(set); -} -template -FMT_CONSTEXPR void maybe_set_debug_format(Formatter&, ...) {} - -} // namespace detail - -FMT_BEGIN_EXPORT - -// The number of characters to store in the basic_memory_buffer object itself -// to avoid dynamic memory allocation. -enum { inline_buffer_size = 500 }; - -/** - * A dynamically growing memory buffer for trivially copyable/constructible - * types with the first `SIZE` elements stored in the object itself. Most - * commonly used via the `memory_buffer` alias for `char`. - * - * **Example**: - * - * auto out = fmt::memory_buffer(); - * fmt::format_to(std::back_inserter(out), "The answer is {}.", 42); - * - * This will append "The answer is 42." to `out`. The buffer content can be - * converted to `std::string` with `to_string(out)`. - */ -template > -class basic_memory_buffer : public detail::buffer { - private: - T store_[SIZE]; - - // Don't inherit from Allocator to avoid generating type_info for it. - FMT_NO_UNIQUE_ADDRESS Allocator alloc_; - - // Deallocate memory allocated by the buffer. - FMT_CONSTEXPR20 void deallocate() { - T* data = this->data(); - if (data != store_) alloc_.deallocate(data, this->capacity()); - } - - static FMT_CONSTEXPR20 void grow(detail::buffer& buf, size_t size) { - detail::abort_fuzzing_if(size > 5000); - auto& self = static_cast(buf); - const size_t max_size = - std::allocator_traits::max_size(self.alloc_); - size_t old_capacity = buf.capacity(); - size_t new_capacity = old_capacity + old_capacity / 2; - if (size > new_capacity) - new_capacity = size; - else if (new_capacity > max_size) - new_capacity = max_of(size, max_size); - T* old_data = buf.data(); - T* new_data = self.alloc_.allocate(new_capacity); - // Suppress a bogus -Wstringop-overflow in gcc 13.1 (#3481). - detail::assume(buf.size() <= new_capacity); - // The following code doesn't throw, so the raw pointer above doesn't leak. - memcpy(new_data, old_data, buf.size() * sizeof(T)); - self.set(new_data, new_capacity); - // deallocate must not throw according to the standard, but even if it does, - // the buffer already uses the new storage and will deallocate it in - // destructor. - if (old_data != self.store_) self.alloc_.deallocate(old_data, old_capacity); - } - - public: - using value_type = T; - using const_reference = const T&; - - FMT_CONSTEXPR explicit basic_memory_buffer( - const Allocator& alloc = Allocator()) - : detail::buffer(grow), alloc_(alloc) { - this->set(store_, SIZE); - if (detail::is_constant_evaluated()) detail::fill_n(store_, SIZE, T()); - } - FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); } - - private: - template :: - propagate_on_container_move_assignment::value)> - FMT_CONSTEXPR20 auto move_alloc(basic_memory_buffer& other) -> bool { - alloc_ = std::move(other.alloc_); - return true; - } - // If the allocator does not propagate then copy the data from other. - template :: - propagate_on_container_move_assignment::value)> - FMT_CONSTEXPR20 auto move_alloc(basic_memory_buffer& other) -> bool { - T* data = other.data(); - if (alloc_ == other.alloc_ || data == other.store_) return true; - size_t size = other.size(); - // Perform copy operation, allocators are different. - this->resize(size); - detail::copy(data, data + size, this->data()); - return false; - } - - // Move data from other to this buffer. - FMT_CONSTEXPR20 void move(basic_memory_buffer& other) { - T* data = other.data(); - size_t size = other.size(), capacity = other.capacity(); - if (!move_alloc(other)) return; - if (data == other.store_) { - this->set(store_, capacity); - detail::copy(other.store_, other.store_ + size, store_); - } else { - this->set(data, capacity); - // Set pointer to the inline array so that delete is not called - // when deallocating. - other.set(other.store_, 0); - other.clear(); - } - this->resize(size); - } - - public: - /// Constructs a `basic_memory_buffer` object moving the content of the other - /// object to it. - FMT_CONSTEXPR20 basic_memory_buffer(basic_memory_buffer&& other) noexcept - : detail::buffer(grow) { - move(other); - } - - /// Moves the content of the other `basic_memory_buffer` object to this one. - auto operator=(basic_memory_buffer&& other) noexcept -> basic_memory_buffer& { - FMT_ASSERT(this != &other, ""); - deallocate(); - move(other); - return *this; - } - - // Returns a copy of the allocator associated with this buffer. - auto get_allocator() const -> Allocator { return alloc_; } - - /// Resizes the buffer to contain `count` elements. If T is a POD type new - /// elements may not be initialized. - FMT_CONSTEXPR void resize(size_t count) { this->try_resize(count); } - - /// Increases the buffer capacity to `new_capacity`. - void reserve(size_t new_capacity) { this->try_reserve(new_capacity); } - - using detail::buffer::append; - template - FMT_CONSTEXPR20 void append(const ContiguousRange& range) { - append(range.data(), range.data() + range.size()); - } -}; - -using memory_buffer = basic_memory_buffer; - -template -FMT_NODISCARD auto to_string(const basic_memory_buffer& buf) - -> std::string { - auto size = buf.size(); - detail::assume(size < std::string().max_size()); - return {buf.data(), size}; -} - -// A writer to a buffered stream. It doesn't own the underlying stream. -class writer { - private: - detail::buffer* buf_; - - // We cannot create a file buffer in advance because any write to a FILE may - // invalidate it. - FILE* file_; - - public: - inline writer(FILE* f) : buf_(nullptr), file_(f) {} - inline writer(detail::buffer& buf) : buf_(&buf) {} - - /// Formats `args` according to specifications in `fmt` and writes the - /// output to the file. - template void print(format_string fmt, T&&... args) { - if (buf_) - fmt::format_to(appender(*buf_), fmt, std::forward(args)...); - else - fmt::print(file_, fmt, std::forward(args)...); - } -}; - -class string_buffer { - private: - std::string str_; - detail::container_buffer buf_; - - public: - inline string_buffer() : buf_(str_) {} - - inline operator writer() { return buf_; } - inline auto str() -> std::string& { return str_; } -}; - -template -struct is_contiguous> : std::true_type { -}; - -// Suppress a misleading warning in older versions of clang. -FMT_PRAGMA_CLANG(diagnostic ignored "-Wweak-vtables") - -/// An error reported from a formatting function. -class FMT_SO_VISIBILITY("default") format_error : public std::runtime_error { - public: - using std::runtime_error::runtime_error; -}; - -class loc_value; - -FMT_END_EXPORT -namespace detail { -FMT_API auto write_console(int fd, string_view text) -> bool; -FMT_API void print(FILE*, string_view); -} // namespace detail - -namespace detail { -template struct fixed_string { - FMT_CONSTEXPR20 fixed_string(const Char (&s)[N]) { - detail::copy(static_cast(s), s + N, - data); - } - Char data[N] = {}; -}; - -// Converts a compile-time string to basic_string_view. -FMT_EXPORT template -constexpr auto compile_string_to_view(const Char (&s)[N]) - -> basic_string_view { - // Remove trailing NUL character if needed. Won't be present if this is used - // with a raw character array (i.e. not defined as a string). - return {s, N - (std::char_traits::to_int_type(s[N - 1]) == 0 ? 1 : 0)}; -} -FMT_EXPORT template -constexpr auto compile_string_to_view(basic_string_view s) - -> basic_string_view { - return s; -} - -// Returns true if value is negative, false otherwise. -// Same as `value < 0` but doesn't produce warnings if T is an unsigned type. -template ::value)> -constexpr auto is_negative(T value) -> bool { - return value < 0; -} -template ::value)> -constexpr auto is_negative(T) -> bool { - return false; -} - -// Smallest of uint32_t, uint64_t, uint128_t that is large enough to -// represent all values of an integral type T. -template -using uint32_or_64_or_128_t = - conditional_t() <= 32 && !FMT_REDUCE_INT_INSTANTIATIONS, - uint32_t, - conditional_t() <= 64, uint64_t, uint128_t>>; -template -using uint64_or_128_t = conditional_t() <= 64, uint64_t, uint128_t>; - -#define FMT_POWERS_OF_10(factor) \ - factor * 10, (factor) * 100, (factor) * 1000, (factor) * 10000, \ - (factor) * 100000, (factor) * 1000000, (factor) * 10000000, \ - (factor) * 100000000, (factor) * 1000000000 - -// Converts value in the range [0, 100) to a string. -// GCC generates slightly better code when value is pointer-size. -inline auto digits2(size_t value) -> const char* { - // Align data since unaligned access may be slower when crossing a - // hardware-specific boundary. - alignas(2) static const char data[] = - "0001020304050607080910111213141516171819" - "2021222324252627282930313233343536373839" - "4041424344454647484950515253545556575859" - "6061626364656667686970717273747576777879" - "8081828384858687888990919293949596979899"; - return &data[value * 2]; -} - -template constexpr auto getsign(sign s) -> Char { - return static_cast(((' ' << 24) | ('+' << 16) | ('-' << 8)) >> - (static_cast(s) * 8)); -} - -template FMT_CONSTEXPR auto count_digits_fallback(T n) -> int { - int count = 1; - for (;;) { - // Integer division is slow so do it for a group of four digits instead - // of for every digit. The idea comes from the talk by Alexandrescu - // "Three Optimization Tips for C++". See speed-test for a comparison. - if (n < 10) return count; - if (n < 100) return count + 1; - if (n < 1000) return count + 2; - if (n < 10000) return count + 3; - n /= 10000u; - count += 4; - } -} -#if FMT_USE_INT128 -FMT_CONSTEXPR inline auto count_digits(uint128_opt n) -> int { - return count_digits_fallback(n); -} -#endif - -#ifdef FMT_BUILTIN_CLZLL -// It is a separate function rather than a part of count_digits to workaround -// the lack of static constexpr in constexpr functions. -inline auto do_count_digits(uint64_t n) -> int { - // This has comparable performance to the version by Kendall Willets - // (https://github.com/fmtlib/format-benchmark/blob/master/digits10) - // but uses smaller tables. - // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)). - static constexpr uint8_t bsr2log10[] = { - 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, - 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, - 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, - 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20}; - auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63]; - static constexpr uint64_t zero_or_powers_of_10[] = { - 0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL), - 10000000000000000000ULL}; - return t - (n < zero_or_powers_of_10[t]); -} -#endif - -// Returns the number of decimal digits in n. Leading zeros are not counted -// except for n == 0 in which case count_digits returns 1. -FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int { -#ifdef FMT_BUILTIN_CLZLL - if (!is_constant_evaluated() && !FMT_OPTIMIZE_SIZE) return do_count_digits(n); -#endif - return count_digits_fallback(n); -} - -// Counts the number of digits in n. BITS = log2(radix). -template -FMT_CONSTEXPR auto count_digits(UInt n) -> int { -#ifdef FMT_BUILTIN_CLZ - if (!is_constant_evaluated() && num_bits() == 32) - return (FMT_BUILTIN_CLZ(static_cast(n) | 1) ^ 31) / BITS + 1; -#endif - // Lambda avoids unreachable code warnings from NVHPC. - return [](UInt m) { - int num_digits = 0; - do { - ++num_digits; - } while ((m >>= BITS) != 0); - return num_digits; - }(n); -} - -#ifdef FMT_BUILTIN_CLZ -// It is a separate function rather than a part of count_digits to workaround -// the lack of static constexpr in constexpr functions. -FMT_INLINE auto do_count_digits(uint32_t n) -> int { -// An optimization by Kendall Willets from https://bit.ly/3uOIQrB. -// This increments the upper 32 bits (log10(T) - 1) when >= T is added. -# define FMT_INC(T) (((sizeof(#T) - 1ull) << 32) - T) - static constexpr uint64_t table[] = { - FMT_INC(0), FMT_INC(0), FMT_INC(0), // 8 - FMT_INC(10), FMT_INC(10), FMT_INC(10), // 64 - FMT_INC(100), FMT_INC(100), FMT_INC(100), // 512 - FMT_INC(1000), FMT_INC(1000), FMT_INC(1000), // 4096 - FMT_INC(10000), FMT_INC(10000), FMT_INC(10000), // 32k - FMT_INC(100000), FMT_INC(100000), FMT_INC(100000), // 256k - FMT_INC(1000000), FMT_INC(1000000), FMT_INC(1000000), // 2048k - FMT_INC(10000000), FMT_INC(10000000), FMT_INC(10000000), // 16M - FMT_INC(100000000), FMT_INC(100000000), FMT_INC(100000000), // 128M - FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000), // 1024M - FMT_INC(1000000000), FMT_INC(1000000000) // 4B - }; - auto inc = table[FMT_BUILTIN_CLZ(n | 1) ^ 31]; - return static_cast((n + inc) >> 32); -} -#endif - -// Optional version of count_digits for better performance on 32-bit platforms. -FMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int { -#ifdef FMT_BUILTIN_CLZ - if (!is_constant_evaluated() && !FMT_OPTIMIZE_SIZE) return do_count_digits(n); -#endif - return count_digits_fallback(n); -} - -template constexpr auto digits10() noexcept -> int { - return std::numeric_limits::digits10; -} -template <> constexpr auto digits10() noexcept -> int { return 38; } -template <> constexpr auto digits10() noexcept -> int { return 38; } - -template struct thousands_sep_result { - std::string grouping; - Char thousands_sep; -}; - -template -FMT_API auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result; -template -inline auto thousands_sep(locale_ref loc) -> thousands_sep_result { - auto result = thousands_sep_impl(loc); - return {result.grouping, Char(result.thousands_sep)}; -} -template <> -inline auto thousands_sep(locale_ref loc) -> thousands_sep_result { - return thousands_sep_impl(loc); -} - -template -FMT_API auto decimal_point_impl(locale_ref loc) -> Char; -template inline auto decimal_point(locale_ref loc) -> Char { - return Char(decimal_point_impl(loc)); -} -template <> inline auto decimal_point(locale_ref loc) -> wchar_t { - return decimal_point_impl(loc); -} - -#ifndef FMT_HEADER_ONLY -FMT_BEGIN_EXPORT -extern template FMT_API auto thousands_sep_impl(locale_ref) - -> thousands_sep_result; -extern template FMT_API auto thousands_sep_impl(locale_ref) - -> thousands_sep_result; -extern template FMT_API auto decimal_point_impl(locale_ref) -> char; -extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t; -FMT_END_EXPORT -#endif // FMT_HEADER_ONLY - -// Compares two characters for equality. -template auto equal2(const Char* lhs, const char* rhs) -> bool { - return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]); -} -inline auto equal2(const char* lhs, const char* rhs) -> bool { - return memcmp(lhs, rhs, 2) == 0; -} - -// Writes a two-digit value to out. -template -FMT_CONSTEXPR20 FMT_INLINE void write2digits(Char* out, size_t value) { - if (!is_constant_evaluated() && std::is_same::value && - !FMT_OPTIMIZE_SIZE) { - memcpy(out, digits2(value), 2); - return; - } - *out++ = static_cast('0' + value / 10); - *out = static_cast('0' + value % 10); -} - -// Formats a decimal unsigned integer value writing to out pointing to a buffer -// of specified size. The caller must ensure that the buffer is large enough. -template -FMT_CONSTEXPR20 auto do_format_decimal(Char* out, UInt value, int size) - -> Char* { - FMT_ASSERT(size >= count_digits(value), "invalid digit count"); - unsigned n = to_unsigned(size); - while (value >= 100) { - // Integer division is slow so do it for a group of two digits instead - // of for every digit. The idea comes from the talk by Alexandrescu - // "Three Optimization Tips for C++". See speed-test for a comparison. - n -= 2; - write2digits(out + n, static_cast(value % 100)); - value /= 100; - } - if (value >= 10) { - n -= 2; - write2digits(out + n, static_cast(value)); - } else { - out[--n] = static_cast('0' + value); - } - return out + n; -} - -template -FMT_CONSTEXPR FMT_INLINE auto format_decimal(Char* out, UInt value, - int num_digits) -> Char* { - do_format_decimal(out, value, num_digits); - return out + num_digits; -} - -template >::value)> -FMT_CONSTEXPR auto format_decimal(OutputIt out, UInt value, int num_digits) - -> OutputIt { - if (auto ptr = to_pointer(out, to_unsigned(num_digits))) { - do_format_decimal(ptr, value, num_digits); - return out; - } - // Buffer is large enough to hold all digits (digits10 + 1). - char buffer[digits10() + 1]; - if (is_constant_evaluated()) fill_n(buffer, sizeof(buffer), '\0'); - do_format_decimal(buffer, value, num_digits); - return copy_noinline(buffer, buffer + num_digits, out); -} - -template -FMT_CONSTEXPR auto do_format_base2e(int base_bits, Char* out, UInt value, - int size, bool upper = false) -> Char* { - out += size; - do { - const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef"; - unsigned digit = static_cast(value & ((1u << base_bits) - 1)); - *--out = static_cast(base_bits < 4 ? static_cast('0' + digit) - : digits[digit]); - } while ((value >>= base_bits) != 0); - return out; -} - -// Formats an unsigned integer in the power of two base (binary, octal, hex). -template -FMT_CONSTEXPR auto format_base2e(int base_bits, Char* out, UInt value, - int num_digits, bool upper = false) -> Char* { - do_format_base2e(base_bits, out, value, num_digits, upper); - return out + num_digits; -} - -template ::value)> -FMT_CONSTEXPR inline auto format_base2e(int base_bits, OutputIt out, UInt value, - int num_digits, bool upper = false) - -> OutputIt { - if (auto ptr = to_pointer(out, to_unsigned(num_digits))) { - format_base2e(base_bits, ptr, value, num_digits, upper); - return out; - } - // Make buffer large enough for any base. - char buffer[num_bits()]; - if (is_constant_evaluated()) fill_n(buffer, sizeof(buffer), '\0'); - format_base2e(base_bits, buffer, value, num_digits, upper); - return detail::copy_noinline(buffer, buffer + num_digits, out); -} - -// A converter from UTF-8 to UTF-16. -class utf8_to_utf16 { - private: - basic_memory_buffer buffer_; - - public: - FMT_API explicit utf8_to_utf16(string_view s); - inline operator basic_string_view() const { - return {&buffer_[0], size()}; - } - inline auto size() const -> size_t { return buffer_.size() - 1; } - inline auto c_str() const -> const wchar_t* { return &buffer_[0]; } - inline auto str() const -> std::wstring { return {&buffer_[0], size()}; } -}; - -enum class to_utf8_error_policy { abort, replace }; - -// A converter from UTF-16/UTF-32 (host endian) to UTF-8. -template class to_utf8 { - private: - Buffer buffer_; - - public: - to_utf8() {} - explicit to_utf8(basic_string_view s, - to_utf8_error_policy policy = to_utf8_error_policy::abort) { - static_assert(sizeof(WChar) == 2 || sizeof(WChar) == 4, - "expected utf16 or utf32"); - if (!convert(s, policy)) { - FMT_THROW(std::runtime_error(sizeof(WChar) == 2 ? "invalid utf16" - : "invalid utf32")); - } - } - operator string_view() const { return string_view(&buffer_[0], size()); } - auto size() const -> size_t { return buffer_.size() - 1; } - auto c_str() const -> const char* { return &buffer_[0]; } - auto str() const -> std::string { return std::string(&buffer_[0], size()); } - - // Performs conversion returning a bool instead of throwing exception on - // conversion error. This method may still throw in case of memory allocation - // error. - auto convert(basic_string_view s, - to_utf8_error_policy policy = to_utf8_error_policy::abort) - -> bool { - if (!convert(buffer_, s, policy)) return false; - buffer_.push_back(0); - return true; - } - static auto convert(Buffer& buf, basic_string_view s, - to_utf8_error_policy policy = to_utf8_error_policy::abort) - -> bool { - for (auto p = s.begin(); p != s.end(); ++p) { - uint32_t c = static_cast(*p); - if (sizeof(WChar) == 2 && c >= 0xd800 && c <= 0xdfff) { - // Handle a surrogate pair. - ++p; - if (p == s.end() || (c & 0xfc00) != 0xd800 || (*p & 0xfc00) != 0xdc00) { - if (policy == to_utf8_error_policy::abort) return false; - buf.append(string_view("\xEF\xBF\xBD")); - --p; - continue; - } - c = (c << 10) + static_cast(*p) - 0x35fdc00; - } - if (c < 0x80) { - buf.push_back(static_cast(c)); - } else if (c < 0x800) { - buf.push_back(static_cast(0xc0 | (c >> 6))); - buf.push_back(static_cast(0x80 | (c & 0x3f))); - } else if ((c >= 0x800 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xffff)) { - buf.push_back(static_cast(0xe0 | (c >> 12))); - buf.push_back(static_cast(0x80 | ((c & 0xfff) >> 6))); - buf.push_back(static_cast(0x80 | (c & 0x3f))); - } else if (c >= 0x10000 && c <= 0x10ffff) { - buf.push_back(static_cast(0xf0 | (c >> 18))); - buf.push_back(static_cast(0x80 | ((c & 0x3ffff) >> 12))); - buf.push_back(static_cast(0x80 | ((c & 0xfff) >> 6))); - buf.push_back(static_cast(0x80 | (c & 0x3f))); - } else { - return false; - } - } - return true; - } -}; - -// Computes 128-bit result of multiplication of two 64-bit unsigned integers. -FMT_INLINE auto umul128(uint64_t x, uint64_t y) noexcept -> uint128_fallback { -#if FMT_USE_INT128 - auto p = static_cast(x) * static_cast(y); - return {static_cast(p >> 64), static_cast(p)}; -#elif defined(_MSC_VER) && defined(_M_X64) - auto hi = uint64_t(); - auto lo = _umul128(x, y, &hi); - return {hi, lo}; -#else - const uint64_t mask = static_cast(max_value()); - - uint64_t a = x >> 32; - uint64_t b = x & mask; - uint64_t c = y >> 32; - uint64_t d = y & mask; - - uint64_t ac = a * c; - uint64_t bc = b * c; - uint64_t ad = a * d; - uint64_t bd = b * d; - - uint64_t intermediate = (bd >> 32) + (ad & mask) + (bc & mask); - - return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32), - (intermediate << 32) + (bd & mask)}; -#endif -} - -namespace dragonbox { -// Computes floor(log10(pow(2, e))) for e in [-2620, 2620] using the method from -// https://fmt.dev/papers/Dragonbox.pdf#page=28, section 6.1. -inline auto floor_log10_pow2(int e) noexcept -> int { - FMT_ASSERT(e <= 2620 && e >= -2620, "too large exponent"); - static_assert((-1 >> 1) == -1, "right shift is not arithmetic"); - return (e * 315653) >> 20; -} - -inline auto floor_log2_pow10(int e) noexcept -> int { - FMT_ASSERT(e <= 1233 && e >= -1233, "too large exponent"); - return (e * 1741647) >> 19; -} - -// Computes upper 64 bits of multiplication of two 64-bit unsigned integers. -inline auto umul128_upper64(uint64_t x, uint64_t y) noexcept -> uint64_t { -#if FMT_USE_INT128 - auto p = static_cast(x) * static_cast(y); - return static_cast(p >> 64); -#elif defined(_MSC_VER) && defined(_M_X64) - return __umulh(x, y); -#else - return umul128(x, y).high(); -#endif -} - -// Computes upper 128 bits of multiplication of a 64-bit unsigned integer and a -// 128-bit unsigned integer. -inline auto umul192_upper128(uint64_t x, uint128_fallback y) noexcept - -> uint128_fallback { - uint128_fallback r = umul128(x, y.high()); - r += umul128_upper64(x, y.low()); - return r; -} - -FMT_API auto get_cached_power(int k) noexcept -> uint128_fallback; - -// Type-specific information that Dragonbox uses. -template struct float_info; - -template <> struct float_info { - using carrier_uint = uint32_t; - static const int exponent_bits = 8; - static const int kappa = 1; - static const int big_divisor = 100; - static const int small_divisor = 10; - static const int min_k = -31; - static const int max_k = 46; - static const int shorter_interval_tie_lower_threshold = -35; - static const int shorter_interval_tie_upper_threshold = -35; -}; - -template <> struct float_info { - using carrier_uint = uint64_t; - static const int exponent_bits = 11; - static const int kappa = 2; - static const int big_divisor = 1000; - static const int small_divisor = 100; - static const int min_k = -292; - static const int max_k = 341; - static const int shorter_interval_tie_lower_threshold = -77; - static const int shorter_interval_tie_upper_threshold = -77; -}; - -// An 80- or 128-bit floating point number. -template -struct float_info::digits == 64 || - std::numeric_limits::digits == 113 || - is_float128::value>> { - using carrier_uint = detail::uint128_t; - static const int exponent_bits = 15; -}; - -// A double-double floating point number. -template -struct float_info::value>> { - using carrier_uint = detail::uint128_t; -}; - -template struct decimal_fp { - using significand_type = typename float_info::carrier_uint; - significand_type significand; - int exponent; -}; - -template FMT_API auto to_decimal(T x) noexcept -> decimal_fp; -} // namespace dragonbox - -// Returns true iff Float has the implicit bit which is not stored. -template constexpr auto has_implicit_bit() -> bool { - // An 80-bit FP number has a 64-bit significand an no implicit bit. - return std::numeric_limits::digits != 64; -} - -// Returns the number of significand bits stored in Float. The implicit bit is -// not counted since it is not stored. -template constexpr auto num_significand_bits() -> int { - // std::numeric_limits may not support __float128. - return is_float128() ? 112 - : (std::numeric_limits::digits - - (has_implicit_bit() ? 1 : 0)); -} - -template -constexpr auto exponent_mask() -> - typename dragonbox::float_info::carrier_uint { - using float_uint = typename dragonbox::float_info::carrier_uint; - return ((float_uint(1) << dragonbox::float_info::exponent_bits) - 1) - << num_significand_bits(); -} -template constexpr auto exponent_bias() -> int { - // std::numeric_limits may not support __float128. - return is_float128() ? 16383 - : std::numeric_limits::max_exponent - 1; -} - -FMT_CONSTEXPR inline auto compute_exp_size(int exp) -> int { - auto prefix_size = 2; // sign + 'e' - auto abs_exp = exp >= 0 ? exp : -exp; - if (abs_exp < 100) return prefix_size + 2; - return prefix_size + (abs_exp >= 1000 ? 4 : 3); -} - -// Writes the exponent exp in the form "[+-]d{2,3}" to buffer. -template -FMT_CONSTEXPR auto write_exponent(int exp, OutputIt out) -> OutputIt { - FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range"); - if (exp < 0) { - *out++ = static_cast('-'); - exp = -exp; - } else { - *out++ = static_cast('+'); - } - auto uexp = static_cast(exp); - if (is_constant_evaluated()) { - if (uexp < 10) *out++ = '0'; - return format_decimal(out, uexp, count_digits(uexp)); - } - if (uexp >= 100u) { - const char* top = digits2(uexp / 100); - if (uexp >= 1000u) *out++ = static_cast(top[0]); - *out++ = static_cast(top[1]); - uexp %= 100; - } - const char* d = digits2(uexp); - *out++ = static_cast(d[0]); - *out++ = static_cast(d[1]); - return out; -} - -// A floating-point number f * pow(2, e) where F is an unsigned type. -template struct basic_fp { - F f; - int e; - - static constexpr int num_significand_bits = - static_cast(sizeof(F) * num_bits()); - - constexpr basic_fp() : f(0), e(0) {} - constexpr basic_fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {} - - // Constructs fp from an IEEE754 floating-point number. - template FMT_CONSTEXPR basic_fp(Float n) { assign(n); } - - // Assigns n to this and return true iff predecessor is closer than successor. - template ::value)> - FMT_CONSTEXPR auto assign(Float n) -> bool { - static_assert(std::numeric_limits::digits <= 113, "unsupported FP"); - // Assume Float is in the format [sign][exponent][significand]. - using carrier_uint = typename dragonbox::float_info::carrier_uint; - const auto num_float_significand_bits = - detail::num_significand_bits(); - const auto implicit_bit = carrier_uint(1) << num_float_significand_bits; - const auto significand_mask = implicit_bit - 1; - auto u = bit_cast(n); - f = static_cast(u & significand_mask); - auto biased_e = static_cast((u & exponent_mask()) >> - num_float_significand_bits); - // The predecessor is closer if n is a normalized power of 2 (f == 0) - // other than the smallest normalized number (biased_e > 1). - auto is_predecessor_closer = f == 0 && biased_e > 1; - if (biased_e == 0) - biased_e = 1; // Subnormals use biased exponent 1 (min exponent). - else if (has_implicit_bit()) - f += static_cast(implicit_bit); - e = biased_e - exponent_bias() - num_float_significand_bits; - if (!has_implicit_bit()) ++e; - return is_predecessor_closer; - } - - template ::value)> - FMT_CONSTEXPR auto assign(Float n) -> bool { - static_assert(std::numeric_limits::is_iec559, "unsupported FP"); - return assign(static_cast(n)); - } -}; - -using fp = basic_fp; - -// Normalizes the value converted from double and multiplied by (1 << SHIFT). -template -FMT_CONSTEXPR auto normalize(basic_fp value) -> basic_fp { - // Handle subnormals. - const auto implicit_bit = F(1) << num_significand_bits(); - const auto shifted_implicit_bit = implicit_bit << SHIFT; - while ((value.f & shifted_implicit_bit) == 0) { - value.f <<= 1; - --value.e; - } - // Subtract 1 to account for hidden bit. - const auto offset = basic_fp::num_significand_bits - - num_significand_bits() - SHIFT - 1; - value.f <<= offset; - value.e -= offset; - return value; -} - -// Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking. -FMT_CONSTEXPR inline auto multiply(uint64_t lhs, uint64_t rhs) -> uint64_t { -#if FMT_USE_INT128 - auto product = static_cast<__uint128_t>(lhs) * rhs; - auto f = static_cast(product >> 64); - return (static_cast(product) & (1ULL << 63)) != 0 ? f + 1 : f; -#else - // Multiply 32-bit parts of significands. - uint64_t mask = (1ULL << 32) - 1; - uint64_t a = lhs >> 32, b = lhs & mask; - uint64_t c = rhs >> 32, d = rhs & mask; - uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d; - // Compute mid 64-bit of result and round. - uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31); - return ac + (ad >> 32) + (bc >> 32) + (mid >> 32); -#endif -} - -FMT_CONSTEXPR inline auto operator*(fp x, fp y) -> fp { - return {multiply(x.f, y.f), x.e + y.e + 64}; -} - -template () == num_bits()> -using convert_float_result = - conditional_t::value || doublish, double, T>; - -template -constexpr auto convert_float(T value) -> convert_float_result { - return static_cast>(value); -} - -template -auto select(T true_value, F) -> T { - return true_value; -} -template -auto select(T, F false_value) -> F { - return false_value; -} - -template -FMT_CONSTEXPR FMT_NOINLINE auto fill(OutputIt it, size_t n, - const basic_specs& specs) -> OutputIt { - auto fill_size = specs.fill_size(); - if (fill_size == 1) return detail::fill_n(it, n, specs.fill_unit()); - if (const Char* data = specs.fill()) { - for (size_t i = 0; i < n; ++i) it = copy(data, data + fill_size, it); - } - return it; -} - -// Writes the output of f, padded according to format specifications in specs. -// size: output size in code units. -// width: output display width in (terminal) column positions. -template -FMT_CONSTEXPR auto write_padded(OutputIt out, const format_specs& specs, - size_t size, size_t width, F&& f) -> OutputIt { - static_assert(default_align == align::left || default_align == align::right, - ""); - unsigned spec_width = to_unsigned(specs.width); - size_t padding = spec_width > width ? spec_width - width : 0; - // Shifts are encoded as string literals because static constexpr is not - // supported in constexpr functions. - auto* shifts = - default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01"; - size_t left_padding = padding >> shifts[static_cast(specs.align())]; - size_t right_padding = padding - left_padding; - auto it = reserve(out, size + padding * specs.fill_size()); - if (left_padding != 0) it = fill(it, left_padding, specs); - it = f(it); - if (right_padding != 0) it = fill(it, right_padding, specs); - return base_iterator(out, it); -} - -template -constexpr auto write_padded(OutputIt out, const format_specs& specs, - size_t size, F&& f) -> OutputIt { - return write_padded(out, specs, size, size, f); -} - -template -FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes, - const format_specs& specs = {}) -> OutputIt { - return write_padded( - out, specs, bytes.size(), [bytes](reserve_iterator it) { - const char* data = bytes.data(); - return copy(data, data + bytes.size(), it); - }); -} - -template -auto write_ptr(OutputIt out, UIntPtr value, const format_specs* specs) - -> OutputIt { - int num_digits = count_digits<4>(value); - auto size = to_unsigned(num_digits) + size_t(2); - auto write = [=](reserve_iterator it) { - *it++ = static_cast('0'); - *it++ = static_cast('x'); - return format_base2e(4, it, value, num_digits); - }; - return specs ? write_padded(out, *specs, size, write) - : base_iterator(out, write(reserve(out, size))); -} - -// Returns true iff the code point cp is printable. -FMT_API auto is_printable(uint32_t cp) -> bool; - -inline auto needs_escape(uint32_t cp) -> bool { - if (cp < 0x20 || cp == 0x7f || cp == '"' || cp == '\\') return true; - if (const_check(FMT_OPTIMIZE_SIZE > 1)) return false; - return !is_printable(cp); -} - -template struct find_escape_result { - const Char* begin; - const Char* end; - uint32_t cp; -}; - -template -auto find_escape(const Char* begin, const Char* end) - -> find_escape_result { - for (; begin != end; ++begin) { - uint32_t cp = static_cast>(*begin); - if (const_check(sizeof(Char) == 1) && cp >= 0x80) continue; - if (needs_escape(cp)) return {begin, begin + 1, cp}; - } - return {begin, nullptr, 0}; -} - -inline auto find_escape(const char* begin, const char* end) - -> find_escape_result { - if (const_check(!use_utf8)) return find_escape(begin, end); - auto result = find_escape_result{end, nullptr, 0}; - for_each_codepoint(string_view(begin, to_unsigned(end - begin)), - [&](uint32_t cp, string_view sv) { - if (needs_escape(cp)) { - result = {sv.begin(), sv.end(), cp}; - return false; - } - return true; - }); - return result; -} - -template -auto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt { - *out++ = static_cast('\\'); - *out++ = static_cast(prefix); - Char buf[width]; - fill_n(buf, width, static_cast('0')); - format_base2e(4, buf, cp, width); - return copy(buf, buf + width, out); -} - -template -auto write_escaped_cp(OutputIt out, const find_escape_result& escape) - -> OutputIt { - auto c = static_cast(escape.cp); - switch (escape.cp) { - case '\n': - *out++ = static_cast('\\'); - c = static_cast('n'); - break; - case '\r': - *out++ = static_cast('\\'); - c = static_cast('r'); - break; - case '\t': - *out++ = static_cast('\\'); - c = static_cast('t'); - break; - case '"': FMT_FALLTHROUGH; - case '\'': FMT_FALLTHROUGH; - case '\\': *out++ = static_cast('\\'); break; - default: - if (escape.cp < 0x100) return write_codepoint<2, Char>(out, 'x', escape.cp); - if (escape.cp < 0x10000) - return write_codepoint<4, Char>(out, 'u', escape.cp); - if (escape.cp < 0x110000) - return write_codepoint<8, Char>(out, 'U', escape.cp); - for (Char escape_char : basic_string_view( - escape.begin, to_unsigned(escape.end - escape.begin))) { - out = write_codepoint<2, Char>(out, 'x', - static_cast(escape_char) & 0xFF); - } - return out; - } - *out++ = c; - return out; -} - -template -auto write_escaped_string(OutputIt out, basic_string_view str) - -> OutputIt { - *out++ = static_cast('"'); - auto begin = str.begin(), end = str.end(); - do { - auto escape = find_escape(begin, end); - out = copy(begin, escape.begin, out); - begin = escape.end; - if (!begin) break; - out = write_escaped_cp(out, escape); - } while (begin != end); - *out++ = static_cast('"'); - return out; -} - -template -auto write_escaped_char(OutputIt out, Char v) -> OutputIt { - Char v_array[1] = {v}; - *out++ = static_cast('\''); - if ((needs_escape(static_cast(v)) && v != static_cast('"')) || - v == static_cast('\'')) { - out = write_escaped_cp(out, - find_escape_result{v_array, v_array + 1, - static_cast(v)}); - } else { - *out++ = v; - } - *out++ = static_cast('\''); - return out; -} - -template -FMT_CONSTEXPR auto write_char(OutputIt out, Char value, - const format_specs& specs) -> OutputIt { - bool is_debug = specs.type() == presentation_type::debug; - return write_padded(out, specs, 1, [=](reserve_iterator it) { - if (is_debug) return write_escaped_char(it, value); - *it++ = value; - return it; - }); -} - -template class digit_grouping { - private: - std::string grouping_; - std::basic_string thousands_sep_; - - struct next_state { - std::string::const_iterator group; - int pos; - }; - auto initial_state() const -> next_state { return {grouping_.begin(), 0}; } - - // Returns the next digit group separator position. - auto next(next_state& state) const -> int { - if (thousands_sep_.empty()) return max_value(); - if (state.group == grouping_.end()) return state.pos += grouping_.back(); - if (*state.group <= 0 || *state.group == max_value()) - return max_value(); - state.pos += *state.group++; - return state.pos; - } - - public: - explicit digit_grouping(locale_ref loc, bool localized = true) { - if (!localized) return; - auto sep = thousands_sep(loc); - grouping_ = sep.grouping; - if (sep.thousands_sep) thousands_sep_.assign(1, sep.thousands_sep); - } - digit_grouping(std::string grouping, std::basic_string sep) - : grouping_(std::move(grouping)), thousands_sep_(std::move(sep)) {} - - auto has_separator() const -> bool { return !thousands_sep_.empty(); } - - auto count_separators(int num_digits) const -> int { - int count = 0; - auto state = initial_state(); - while (num_digits > next(state)) ++count; - return count; - } - - // Applies grouping to digits and writes the output to out. - template - auto apply(Out out, basic_string_view digits) const -> Out { - auto num_digits = static_cast(digits.size()); - auto separators = basic_memory_buffer(); - separators.push_back(0); - auto state = initial_state(); - while (int i = next(state)) { - if (i >= num_digits) break; - separators.push_back(i); - } - for (int i = 0, sep_index = static_cast(separators.size() - 1); - i < num_digits; ++i) { - if (num_digits - i == separators[sep_index]) { - out = copy(thousands_sep_.data(), - thousands_sep_.data() + thousands_sep_.size(), out); - --sep_index; - } - *out++ = static_cast(digits[to_unsigned(i)]); - } - return out; - } -}; - -FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) { - prefix |= prefix != 0 ? value << 8 : value; - prefix += (1u + (value > 0xff ? 1 : 0)) << 24; -} - -// Writes a decimal integer with digit grouping. -template -auto write_int(OutputIt out, UInt value, unsigned prefix, - const format_specs& specs, const digit_grouping& grouping) - -> OutputIt { - static_assert(std::is_same, UInt>::value, ""); - int num_digits = 0; - auto buffer = memory_buffer(); - switch (specs.type()) { - default: FMT_ASSERT(false, ""); FMT_FALLTHROUGH; - case presentation_type::none: - case presentation_type::dec: - num_digits = count_digits(value); - format_decimal(appender(buffer), value, num_digits); - break; - case presentation_type::hex: - if (specs.alt()) - prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0'); - num_digits = count_digits<4>(value); - format_base2e(4, appender(buffer), value, num_digits, specs.upper()); - break; - case presentation_type::oct: - num_digits = count_digits<3>(value); - // Octal prefix '0' is counted as a digit, so only add it if precision - // is not greater than the number of digits. - if (specs.alt() && specs.precision <= num_digits && value != 0) - prefix_append(prefix, '0'); - format_base2e(3, appender(buffer), value, num_digits); - break; - case presentation_type::bin: - if (specs.alt()) - prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0'); - num_digits = count_digits<1>(value); - format_base2e(1, appender(buffer), value, num_digits); - break; - case presentation_type::chr: - return write_char(out, static_cast(value), specs); - } - - unsigned size = (prefix != 0 ? prefix >> 24 : 0) + to_unsigned(num_digits) + - to_unsigned(grouping.count_separators(num_digits)); - return write_padded( - out, specs, size, size, [&](reserve_iterator it) { - for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8) - *it++ = static_cast(p & 0xff); - return grouping.apply(it, string_view(buffer.data(), buffer.size())); - }); -} - -#if FMT_USE_LOCALE -// Writes a localized value. -FMT_API auto write_loc(appender out, loc_value value, const format_specs& specs, - locale_ref loc) -> bool; -auto write_loc(basic_appender out, loc_value value, - const format_specs& specs, locale_ref loc) -> bool; -#endif -template -inline auto write_loc(OutputIt, const loc_value&, const format_specs&, - locale_ref) -> bool { - return false; -} - -template struct write_int_arg { - UInt abs_value; - unsigned prefix; -}; - -template -FMT_CONSTEXPR auto make_write_int_arg(T value, sign s) - -> write_int_arg> { - auto prefix = 0u; - auto abs_value = static_cast>(value); - if (is_negative(value)) { - prefix = 0x01000000 | '-'; - abs_value = 0 - abs_value; - } else { - constexpr unsigned prefixes[4] = {0, 0, 0x1000000u | '+', 0x1000000u | ' '}; - prefix = prefixes[static_cast(s)]; - } - return {abs_value, prefix}; -} - -template struct loc_writer { - basic_appender out; - const format_specs& specs; - std::basic_string sep; - std::string grouping; - std::basic_string decimal_point; - - template ::value)> - auto operator()(T value) -> bool { - auto arg = make_write_int_arg(value, specs.sign()); - write_int(out, static_cast>(arg.abs_value), arg.prefix, - specs, digit_grouping(grouping, sep)); - return true; - } - - template ::value)> - auto operator()(T) -> bool { - return false; - } -}; - -// Size and padding computation separate from write_int to avoid template bloat. -struct size_padding { - unsigned size; - unsigned padding; - - FMT_CONSTEXPR size_padding(int num_digits, unsigned prefix, - const format_specs& specs) - : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) { - if (specs.align() == align::numeric) { - auto width = to_unsigned(specs.width); - if (width > size) { - padding = width - size; - size = width; - } - } else if (specs.precision > num_digits) { - size = (prefix >> 24) + to_unsigned(specs.precision); - padding = to_unsigned(specs.precision - num_digits); - } - } -}; - -template -FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg arg, - const format_specs& specs) -> OutputIt { - static_assert(std::is_same>::value, ""); - - constexpr size_t buffer_size = num_bits(); - char buffer[buffer_size]; - if (is_constant_evaluated()) fill_n(buffer, buffer_size, '\0'); - const char* begin = nullptr; - const char* end = buffer + buffer_size; - - auto abs_value = arg.abs_value; - auto prefix = arg.prefix; - switch (specs.type()) { - default: FMT_ASSERT(false, ""); FMT_FALLTHROUGH; - case presentation_type::none: - case presentation_type::dec: - begin = do_format_decimal(buffer, abs_value, buffer_size); - break; - case presentation_type::hex: - begin = do_format_base2e(4, buffer, abs_value, buffer_size, specs.upper()); - if (specs.alt()) - prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0'); - break; - case presentation_type::oct: { - begin = do_format_base2e(3, buffer, abs_value, buffer_size); - // Octal prefix '0' is counted as a digit, so only add it if precision - // is not greater than the number of digits. - auto num_digits = end - begin; - if (specs.alt() && specs.precision <= num_digits && abs_value != 0) - prefix_append(prefix, '0'); - break; - } - case presentation_type::bin: - begin = do_format_base2e(1, buffer, abs_value, buffer_size); - if (specs.alt()) - prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0'); - break; - case presentation_type::chr: - return write_char(out, static_cast(abs_value), specs); - } - - // Write an integer in the format - // - // prefix contains chars in three lower bytes and the size in the fourth byte. - int num_digits = static_cast(end - begin); - // Slightly faster check for specs.width == 0 && specs.precision == -1. - if ((specs.width | (specs.precision + 1)) == 0) { - auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24)); - for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8) - *it++ = static_cast(p & 0xff); - return base_iterator(out, copy(begin, end, it)); - } - auto sp = size_padding(num_digits, prefix, specs); - unsigned padding = sp.padding; - return write_padded( - out, specs, sp.size, [=](reserve_iterator it) { - for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8) - *it++ = static_cast(p & 0xff); - it = detail::fill_n(it, padding, static_cast('0')); - return copy(begin, end, it); - }); -} - -template -FMT_CONSTEXPR FMT_NOINLINE auto write_int_noinline(OutputIt out, - write_int_arg arg, - const format_specs& specs) - -> OutputIt { - return write_int(out, arg, specs); -} - -template ::value && - !std::is_same::value && - !std::is_same::value)> -FMT_CONSTEXPR FMT_INLINE auto write(basic_appender out, T value, - const format_specs& specs, locale_ref loc) - -> basic_appender { - if (specs.localized() && write_loc(out, value, specs, loc)) return out; - return write_int_noinline(out, make_write_int_arg(value, specs.sign()), - specs); -} - -// An inlined version of write used in format string compilation. -template ::value && - !std::is_same::value && - !std::is_same::value && - !std::is_same>::value)> -FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value, - const format_specs& specs, locale_ref loc) - -> OutputIt { - if (specs.localized() && write_loc(out, value, specs, loc)) return out; - return write_int(out, make_write_int_arg(value, specs.sign()), specs); -} - -template -FMT_CONSTEXPR auto write(OutputIt out, Char value, const format_specs& specs, - locale_ref loc = {}) -> OutputIt { - // char is formatted as unsigned char for consistency across platforms. - using unsigned_type = - conditional_t::value, unsigned char, unsigned>; - return check_char_specs(specs) - ? write_char(out, value, specs) - : write(out, static_cast(value), specs, loc); -} - -template ::value)> -FMT_CONSTEXPR auto write(OutputIt out, basic_string_view s, - const format_specs& specs) -> OutputIt { - bool is_debug = specs.type() == presentation_type::debug; - if (specs.precision < 0 && specs.width == 0) { - auto&& it = reserve(out, s.size()); - return is_debug ? write_escaped_string(it, s) : copy(s, it); - } - - size_t display_width_limit = - specs.precision < 0 ? SIZE_MAX : to_unsigned(specs.precision); - size_t display_width = - !is_debug || specs.precision == 0 ? 0 : 1; // Account for opening '"'. - size_t size = !is_debug || specs.precision == 0 ? 0 : 1; - for_each_codepoint(s, [&](uint32_t cp, string_view sv) { - if (is_debug && needs_escape(cp)) { - counting_buffer buf; - write_escaped_cp(basic_appender(buf), - find_escape_result{sv.begin(), sv.end(), cp}); - // We're reinterpreting bytes as display width. That's okay - // because write_escaped_cp() only writes ASCII characters. - size_t cp_width = buf.count(); - if (display_width + cp_width <= display_width_limit) { - display_width += cp_width; - size += cp_width; - // If this is the end of the string, account for closing '"'. - if (display_width < display_width_limit && sv.end() == s.end()) { - ++display_width; - ++size; - } - return true; - } - - size += display_width_limit - display_width; - display_width = display_width_limit; - return false; - } - - size_t cp_width = display_width_of(cp); - if (cp_width + display_width <= display_width_limit) { - display_width += cp_width; - size += sv.size(); - // If this is the end of the string, account for closing '"'. - if (is_debug && display_width < display_width_limit && - sv.end() == s.end()) { - ++display_width; - ++size; - } - return true; - } - - return false; - }); - - struct bounded_output_iterator { - reserve_iterator underlying_iterator; - size_t bound; - - FMT_CONSTEXPR auto operator*() -> bounded_output_iterator& { return *this; } - FMT_CONSTEXPR auto operator++() -> bounded_output_iterator& { - return *this; - } - FMT_CONSTEXPR auto operator++(int) -> bounded_output_iterator& { - return *this; - } - FMT_CONSTEXPR auto operator=(char c) -> bounded_output_iterator& { - if (bound > 0) { - *underlying_iterator++ = c; - --bound; - } - return *this; - } - }; - - return write_padded( - out, specs, size, display_width, [=](reserve_iterator it) { - return is_debug - ? write_escaped_string(bounded_output_iterator{it, size}, s) - .underlying_iterator - : copy(s.data(), s.data() + size, it); - }); -} - -template ::value)> -FMT_CONSTEXPR auto write(OutputIt out, basic_string_view s, - const format_specs& specs) -> OutputIt { - auto data = s.data(); - auto size = s.size(); - if (specs.precision >= 0 && to_unsigned(specs.precision) < size) - size = to_unsigned(specs.precision); - - bool is_debug = specs.type() == presentation_type::debug; - if (is_debug) { - auto buf = counting_buffer(); - write_escaped_string(basic_appender(buf), s); - size = buf.count(); - } - - return write_padded( - out, specs, size, [=](reserve_iterator it) { - return is_debug ? write_escaped_string(it, s) - : copy(data, data + size, it); - }); -} - -template -FMT_CONSTEXPR auto write(OutputIt out, basic_string_view s, - const format_specs& specs, locale_ref) -> OutputIt { - return write(out, s, specs); -} - -template -FMT_CONSTEXPR auto write(OutputIt out, const Char* s, const format_specs& specs, - locale_ref) -> OutputIt { - if (specs.type() == presentation_type::pointer) - return write_ptr(out, bit_cast(s), &specs); - if (!s) report_error("string pointer is null"); - return write(out, basic_string_view(s), specs, {}); -} - -template ::value && - !std::is_same::value && - !std::is_same::value)> -FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { - auto abs_value = static_cast>(value); - bool negative = is_negative(value); - // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer. - if (negative) abs_value = ~abs_value + 1; - int num_digits = count_digits(abs_value); - auto size = (negative ? 1 : 0) + static_cast(num_digits); - if (auto ptr = to_pointer(out, size)) { - if (negative) *ptr++ = static_cast('-'); - format_decimal(ptr, abs_value, num_digits); - return out; - } - if (negative) *out++ = static_cast('-'); - return format_decimal(out, abs_value, num_digits); -} - -template -FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end, - format_specs& specs) -> const Char* { - FMT_ASSERT(begin != end, ""); - auto alignment = align::none; - auto p = begin + code_point_length(begin); - if (end - p <= 0) p = begin; - for (;;) { - switch (to_ascii(*p)) { - case '<': alignment = align::left; break; - case '>': alignment = align::right; break; - case '^': alignment = align::center; break; - } - if (alignment != align::none) { - if (p != begin) { - auto c = *begin; - if (c == '}') return begin; - if (c == '{') { - report_error("invalid fill character '{'"); - return begin; - } - specs.set_fill(basic_string_view(begin, to_unsigned(p - begin))); - begin = p + 1; - } else { - ++begin; - } - break; - } else if (p == begin) { - break; - } - p = begin; - } - specs.set_align(alignment); - return begin; -} - -template -FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan, - format_specs specs, sign s) -> OutputIt { - auto str = - isnan ? (specs.upper() ? "NAN" : "nan") : (specs.upper() ? "INF" : "inf"); - constexpr size_t str_size = 3; - auto size = str_size + (s != sign::none ? 1 : 0); - // Replace '0'-padding with space for non-finite values. - const bool is_zero_fill = - specs.fill_size() == 1 && specs.fill_unit() == '0'; - if (is_zero_fill) specs.set_fill(' '); - return write_padded(out, specs, size, - [=](reserve_iterator it) { - if (s != sign::none) - *it++ = detail::getsign(s); - return copy(str, str + str_size, it); - }); -} - -// A decimal floating-point number significand * pow(10, exp). -struct big_decimal_fp { - const char* significand; - int significand_size; - int exponent; -}; - -constexpr auto get_significand_size(const big_decimal_fp& f) -> int { - return f.significand_size; -} -template -inline auto get_significand_size(const dragonbox::decimal_fp& f) -> int { - return count_digits(f.significand); -} - -template -constexpr auto write_significand(OutputIt out, const char* significand, - int significand_size) -> OutputIt { - return copy(significand, significand + significand_size, out); -} -template -inline auto write_significand(OutputIt out, UInt significand, - int significand_size) -> OutputIt { - return format_decimal(out, significand, significand_size); -} -template -FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand, - int significand_size, int exponent, - const Grouping& grouping) -> OutputIt { - if (!grouping.has_separator()) { - out = write_significand(out, significand, significand_size); - return detail::fill_n(out, exponent, static_cast('0')); - } - auto buffer = memory_buffer(); - write_significand(appender(buffer), significand, significand_size); - detail::fill_n(appender(buffer), exponent, '0'); - return grouping.apply(out, string_view(buffer.data(), buffer.size())); -} - -template ::value)> -inline auto write_significand(Char* out, UInt significand, int significand_size, - int integral_size, Char decimal_point) -> Char* { - if (!decimal_point) return format_decimal(out, significand, significand_size); - out += significand_size + 1; - Char* end = out; - int floating_size = significand_size - integral_size; - for (int i = floating_size / 2; i > 0; --i) { - out -= 2; - write2digits(out, static_cast(significand % 100)); - significand /= 100; - } - if (floating_size % 2 != 0) { - *--out = static_cast('0' + significand % 10); - significand /= 10; - } - *--out = decimal_point; - format_decimal(out - integral_size, significand, integral_size); - return end; -} - -template >::value)> -inline auto write_significand(OutputIt out, UInt significand, - int significand_size, int integral_size, - Char decimal_point) -> OutputIt { - // Buffer is large enough to hold digits (digits10 + 1) and a decimal point. - Char buffer[digits10() + 2]; - auto end = write_significand(buffer, significand, significand_size, - integral_size, decimal_point); - return detail::copy_noinline(buffer, end, out); -} - -template -FMT_CONSTEXPR auto write_significand(OutputIt out, const char* significand, - int significand_size, int integral_size, - Char decimal_point) -> OutputIt { - out = detail::copy_noinline(significand, significand + integral_size, - out); - if (!decimal_point) return out; - *out++ = decimal_point; - return detail::copy_noinline(significand + integral_size, - significand + significand_size, out); -} - -template -FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand, - int significand_size, int integral_size, - Char decimal_point, - const Grouping& grouping) -> OutputIt { - if (!grouping.has_separator()) { - return write_significand(out, significand, significand_size, integral_size, - decimal_point); - } - auto buffer = basic_memory_buffer(); - write_significand(basic_appender(buffer), significand, significand_size, - integral_size, decimal_point); - grouping.apply( - out, basic_string_view(buffer.data(), to_unsigned(integral_size))); - return detail::copy_noinline(buffer.data() + integral_size, - buffer.end(), out); -} - -// Numbers with exponents greater or equal to the returned value will use -// the exponential notation. -template FMT_CONSTEVAL auto exp_upper() -> int { - return std::numeric_limits::digits10 != 0 - ? min_of(16, std::numeric_limits::digits10 + 1) - : 16; -} - -// Use the fixed notation if the exponent is in [-4, exp_upper), -// e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation. -constexpr auto use_fixed(int exp, int exp_upper) -> bool { - return exp >= -4 && exp < exp_upper; -} - -template class fallback_digit_grouping { - public: - constexpr fallback_digit_grouping(locale_ref, bool) {} - - constexpr auto has_separator() const -> bool { return false; } - - constexpr auto count_separators(int) const -> int { return 0; } - - template - constexpr auto apply(Out out, basic_string_view) const -> Out { - return out; - } -}; - -template -FMT_CONSTEXPR20 auto write_fixed(OutputIt out, const DecimalFP& f, - int significand_size, Char decimal_point, - const format_specs& specs, sign s, - locale_ref loc = {}) -> OutputIt { - using iterator = reserve_iterator; - - int exp = f.exponent + significand_size; - long long size = significand_size + (s != sign::none ? 1 : 0); - if (f.exponent >= 0) { - // 1234e5 -> 123400000[.0+] - size += f.exponent; - int num_zeros = specs.precision - exp; - abort_fuzzing_if(num_zeros > 5000); - if (specs.alt()) { - ++size; - if (num_zeros <= 0 && specs.type() != presentation_type::fixed) - num_zeros = 0; - if (num_zeros > 0) size += num_zeros; - } - auto grouping = Grouping(loc, specs.localized()); - size += grouping.count_separators(exp); - return write_padded( - out, specs, static_cast(size), [&](iterator it) { - if (s != sign::none) *it++ = detail::getsign(s); - it = write_significand(it, f.significand, significand_size, - f.exponent, grouping); - if (!specs.alt()) return it; - *it++ = decimal_point; - return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it; - }); - } - if (exp > 0) { - // 1234e-2 -> 12.34[0+] - int num_zeros = specs.alt() ? specs.precision - significand_size : 0; - size += 1 + max_of(num_zeros, 0); - auto grouping = Grouping(loc, specs.localized()); - size += grouping.count_separators(exp); - return write_padded( - out, specs, to_unsigned(size), [&](iterator it) { - if (s != sign::none) *it++ = detail::getsign(s); - it = write_significand(it, f.significand, significand_size, exp, - decimal_point, grouping); - return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it; - }); - } - // 1234e-6 -> 0.001234 - int num_zeros = -exp; - if (significand_size == 0 && specs.precision >= 0 && - specs.precision < num_zeros) { - num_zeros = specs.precision; - } - bool pointy = num_zeros != 0 || significand_size != 0 || specs.alt(); - size += 1 + (pointy ? 1 : 0) + num_zeros; - return write_padded( - out, specs, to_unsigned(size), [&](iterator it) { - if (s != sign::none) *it++ = detail::getsign(s); - *it++ = Char('0'); - if (!pointy) return it; - *it++ = decimal_point; - it = detail::fill_n(it, num_zeros, Char('0')); - return write_significand(it, f.significand, significand_size); - }); -} - -template -FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f, - const format_specs& specs, sign s, - int exp_upper, locale_ref loc) -> OutputIt { - Char point = specs.localized() ? detail::decimal_point(loc) : Char('.'); - int significand_size = get_significand_size(f); - int exp = f.exponent + significand_size - 1; - if (specs.type() == presentation_type::fixed || - (specs.type() != presentation_type::exp && - use_fixed(exp, specs.precision > 0 ? specs.precision : exp_upper))) { - return write_fixed(out, f, significand_size, point, specs, - s, loc); - } - - // Write value in the exponential format. - int num_zeros = 0; - long long size = significand_size + (s != sign::none ? 1 : 0); - if (specs.alt()) { - num_zeros = max_of(specs.precision - significand_size, 0); - size += num_zeros; - } else if (significand_size == 1) { - point = Char(); - } - size += (point ? 1 : 0) + compute_exp_size(exp); - char exp_char = specs.upper() ? 'E' : 'e'; - auto write = [=](reserve_iterator it) { - if (s != sign::none) *it++ = detail::getsign(s); - // Insert a decimal point after the first digit and add an exponent. - it = write_significand(it, f.significand, significand_size, 1, point); - if (num_zeros > 0) it = detail::fill_n(it, num_zeros, Char('0')); - *it++ = Char(exp_char); - return write_exponent(exp, it); - }; - auto usize = to_unsigned(size); - return specs.width > 0 - ? write_padded(out, specs, usize, write) - : base_iterator(out, write(reserve(out, usize))); -} - -template -FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& f, - const format_specs& specs, sign s, - int exp_upper, locale_ref loc) -> OutputIt { - if (is_constant_evaluated()) { - return do_write_float>(out, f, specs, s, - exp_upper, loc); - } else { - return do_write_float>(out, f, specs, s, - exp_upper, loc); - } -} - -template constexpr auto isnan(T value) -> bool { - return value != value; // std::isnan doesn't support __float128. -} - -template -struct has_isfinite : std::false_type {}; - -template -struct has_isfinite> - : std::true_type {}; - -template ::value&& has_isfinite::value)> -FMT_CONSTEXPR20 auto isfinite(T value) -> bool { - constexpr T inf = T(std::numeric_limits::infinity()); - if (is_constant_evaluated()) - return !detail::isnan(value) && value < inf && value > -inf; - return std::isfinite(value); -} -template ::value)> -FMT_CONSTEXPR auto isfinite(T value) -> bool { - T inf = T(std::numeric_limits::infinity()); - // std::isfinite doesn't support __float128. - return !detail::isnan(value) && value < inf && value > -inf; -} - -template ::value)> -FMT_INLINE FMT_CONSTEXPR auto signbit(T value) -> bool { - if (is_constant_evaluated()) { -#ifdef __cpp_if_constexpr - if constexpr (std::numeric_limits::is_iec559) { - auto bits = detail::bit_cast(static_cast(value)); - return (bits >> (num_bits() - 1)) != 0; - } -#endif - } - return std::signbit(static_cast(value)); -} - -inline FMT_CONSTEXPR20 void adjust_precision(int& precision, int exp10) { - // Adjust fixed precision by exponent because it is relative to decimal - // point. - if (exp10 > 0 && precision > max_value() - exp10) - FMT_THROW(format_error("number is too big")); - precision += exp10; -} - -class bigint { - private: - // A bigint is a number in the form bigit_[N - 1] ... bigit_[0] * 32^exp_. - using bigit = uint32_t; // A big digit. - using double_bigit = uint64_t; - enum { bigit_bits = num_bits() }; - enum { bigits_capacity = 32 }; - basic_memory_buffer bigits_; - int exp_; - - friend struct formatter; - - FMT_CONSTEXPR auto get_bigit(int i) const -> bigit { - return i >= exp_ && i < num_bigits() ? bigits_[i - exp_] : 0; - } - - FMT_CONSTEXPR void subtract_bigits(int index, bigit other, bigit& borrow) { - auto result = double_bigit(bigits_[index]) - other - borrow; - bigits_[index] = static_cast(result); - borrow = static_cast(result >> (bigit_bits * 2 - 1)); - } - - FMT_CONSTEXPR void remove_leading_zeros() { - int num_bigits = static_cast(bigits_.size()) - 1; - while (num_bigits > 0 && bigits_[num_bigits] == 0) --num_bigits; - bigits_.resize(to_unsigned(num_bigits + 1)); - } - - // Computes *this -= other assuming aligned bigints and *this >= other. - FMT_CONSTEXPR void subtract_aligned(const bigint& other) { - FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints"); - FMT_ASSERT(compare(*this, other) >= 0, ""); - bigit borrow = 0; - int i = other.exp_ - exp_; - for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j) - subtract_bigits(i, other.bigits_[j], borrow); - if (borrow != 0) subtract_bigits(i, 0, borrow); - FMT_ASSERT(borrow == 0, ""); - remove_leading_zeros(); - } - - FMT_CONSTEXPR void multiply(uint32_t value) { - bigit carry = 0; - const double_bigit wide_value = value; - for (size_t i = 0, n = bigits_.size(); i < n; ++i) { - double_bigit result = bigits_[i] * wide_value + carry; - bigits_[i] = static_cast(result); - carry = static_cast(result >> bigit_bits); - } - if (carry != 0) bigits_.push_back(carry); - } - - template ::value || - std::is_same::value)> - FMT_CONSTEXPR void multiply(UInt value) { - using half_uint = - conditional_t::value, uint64_t, uint32_t>; - const int shift = num_bits() - bigit_bits; - const UInt lower = static_cast(value); - const UInt upper = value >> num_bits(); - UInt carry = 0; - for (size_t i = 0, n = bigits_.size(); i < n; ++i) { - UInt result = lower * bigits_[i] + static_cast(carry); - carry = (upper * bigits_[i] << shift) + (result >> bigit_bits) + - (carry >> bigit_bits); - bigits_[i] = static_cast(result); - } - while (carry != 0) { - bigits_.push_back(static_cast(carry)); - carry >>= bigit_bits; - } - } - - template ::value || - std::is_same::value)> - FMT_CONSTEXPR void assign(UInt n) { - size_t num_bigits = 0; - do { - bigits_[num_bigits++] = static_cast(n); - n >>= bigit_bits; - } while (n != 0); - bigits_.resize(num_bigits); - exp_ = 0; - } - - public: - FMT_CONSTEXPR bigint() : exp_(0) {} - explicit bigint(uint64_t n) { assign(n); } - - bigint(const bigint&) = delete; - void operator=(const bigint&) = delete; - - FMT_CONSTEXPR void assign(const bigint& other) { - auto size = other.bigits_.size(); - bigits_.resize(size); - auto data = other.bigits_.data(); - copy(data, data + size, bigits_.data()); - exp_ = other.exp_; - } - - template FMT_CONSTEXPR void operator=(Int n) { - FMT_ASSERT(n > 0, ""); - assign(uint64_or_128_t(n)); - } - - FMT_CONSTEXPR auto num_bigits() const -> int { - return static_cast(bigits_.size()) + exp_; - } - - FMT_CONSTEXPR auto operator<<=(int shift) -> bigint& { - FMT_ASSERT(shift >= 0, ""); - exp_ += shift / bigit_bits; - shift %= bigit_bits; - if (shift == 0) return *this; - bigit carry = 0; - for (size_t i = 0, n = bigits_.size(); i < n; ++i) { - bigit c = bigits_[i] >> (bigit_bits - shift); - bigits_[i] = (bigits_[i] << shift) + carry; - carry = c; - } - if (carry != 0) bigits_.push_back(carry); - return *this; - } - - template FMT_CONSTEXPR auto operator*=(Int value) -> bigint& { - FMT_ASSERT(value > 0, ""); - multiply(uint32_or_64_or_128_t(value)); - return *this; - } - - friend FMT_CONSTEXPR auto compare(const bigint& b1, const bigint& b2) -> int { - int num_bigits1 = b1.num_bigits(), num_bigits2 = b2.num_bigits(); - if (num_bigits1 != num_bigits2) return num_bigits1 > num_bigits2 ? 1 : -1; - int i = static_cast(b1.bigits_.size()) - 1; - int j = static_cast(b2.bigits_.size()) - 1; - int end = i - j; - if (end < 0) end = 0; - for (; i >= end; --i, --j) { - bigit b1_bigit = b1.bigits_[i], b2_bigit = b2.bigits_[j]; - if (b1_bigit != b2_bigit) return b1_bigit > b2_bigit ? 1 : -1; - } - if (i != j) return i > j ? 1 : -1; - return 0; - } - - // Returns compare(lhs1 + lhs2, rhs). - friend FMT_CONSTEXPR auto add_compare(const bigint& lhs1, const bigint& lhs2, - const bigint& rhs) -> int { - int max_lhs_bigits = max_of(lhs1.num_bigits(), lhs2.num_bigits()); - int num_rhs_bigits = rhs.num_bigits(); - if (max_lhs_bigits + 1 < num_rhs_bigits) return -1; - if (max_lhs_bigits > num_rhs_bigits) return 1; - double_bigit borrow = 0; - int min_exp = min_of(min_of(lhs1.exp_, lhs2.exp_), rhs.exp_); - for (int i = num_rhs_bigits - 1; i >= min_exp; --i) { - double_bigit sum = double_bigit(lhs1.get_bigit(i)) + lhs2.get_bigit(i); - bigit rhs_bigit = rhs.get_bigit(i); - if (sum > rhs_bigit + borrow) return 1; - borrow = rhs_bigit + borrow - sum; - if (borrow > 1) return -1; - borrow <<= bigit_bits; - } - return borrow != 0 ? -1 : 0; - } - - // Assigns pow(10, exp) to this bigint. - FMT_CONSTEXPR20 void assign_pow10(int exp) { - FMT_ASSERT(exp >= 0, ""); - if (exp == 0) return *this = 1; - int bitmask = 1 << (num_bits() - - countl_zero(static_cast(exp)) - 1); - // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by - // repeated squaring and multiplication. - *this = 5; - bitmask >>= 1; - while (bitmask != 0) { - square(); - if ((exp & bitmask) != 0) *this *= 5; - bitmask >>= 1; - } - *this <<= exp; // Multiply by pow(2, exp) by shifting. - } - - FMT_CONSTEXPR20 void square() { - int num_bigits = static_cast(bigits_.size()); - int num_result_bigits = 2 * num_bigits; - basic_memory_buffer n(std::move(bigits_)); - bigits_.resize(to_unsigned(num_result_bigits)); - auto sum = uint128_t(); - for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) { - // Compute bigit at position bigit_index of the result by adding - // cross-product terms n[i] * n[j] such that i + j == bigit_index. - for (int i = 0, j = bigit_index; j >= 0; ++i, --j) { - // Most terms are multiplied twice which can be optimized in the future. - sum += double_bigit(n[i]) * n[j]; - } - bigits_[bigit_index] = static_cast(sum); - sum >>= num_bits(); // Compute the carry. - } - // Do the same for the top half. - for (int bigit_index = num_bigits; bigit_index < num_result_bigits; - ++bigit_index) { - for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;) - sum += double_bigit(n[i++]) * n[j--]; - bigits_[bigit_index] = static_cast(sum); - sum >>= num_bits(); - } - remove_leading_zeros(); - exp_ *= 2; - } - - // If this bigint has a bigger exponent than other, adds trailing zero to make - // exponents equal. This simplifies some operations such as subtraction. - FMT_CONSTEXPR void align(const bigint& other) { - int exp_difference = exp_ - other.exp_; - if (exp_difference <= 0) return; - int num_bigits = static_cast(bigits_.size()); - bigits_.resize(to_unsigned(num_bigits + exp_difference)); - for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j) - bigits_[j] = bigits_[i]; - fill_n(bigits_.data(), to_unsigned(exp_difference), 0U); - exp_ -= exp_difference; - } - - // Divides this bignum by divisor, assigning the remainder to this and - // returning the quotient. - FMT_CONSTEXPR auto divmod_assign(const bigint& divisor) -> int { - FMT_ASSERT(this != &divisor, ""); - if (compare(*this, divisor) < 0) return 0; - FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, ""); - align(divisor); - int quotient = 0; - do { - subtract_aligned(divisor); - ++quotient; - } while (compare(*this, divisor) >= 0); - return quotient; - } -}; - -// format_dragon flags. -enum dragon { - predecessor_closer = 1, - fixup = 2, // Run fixup to correct exp10 which can be off by one. - fixed = 4, -}; - -// Formats a floating-point number using a variation of the Fixed-Precision -// Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White: -// https://fmt.dev/papers/p372-steele.pdf. -FMT_CONSTEXPR20 inline void format_dragon(basic_fp value, - unsigned flags, int num_digits, - buffer& buf, int& exp10) { - bigint numerator; // 2 * R in (FPP)^2. - bigint denominator; // 2 * S in (FPP)^2. - // lower and upper are differences between value and corresponding boundaries. - bigint lower; // (M^- in (FPP)^2). - bigint upper_store; // upper's value if different from lower. - bigint* upper = nullptr; // (M^+ in (FPP)^2). - // Shift numerator and denominator by an extra bit or two (if lower boundary - // is closer) to make lower and upper integers. This eliminates multiplication - // by 2 during later computations. - bool is_predecessor_closer = (flags & dragon::predecessor_closer) != 0; - int shift = is_predecessor_closer ? 2 : 1; - if (value.e >= 0) { - numerator = value.f; - numerator <<= value.e + shift; - lower = 1; - lower <<= value.e; - if (is_predecessor_closer) { - upper_store = 1; - upper_store <<= value.e + 1; - upper = &upper_store; - } - denominator.assign_pow10(exp10); - denominator <<= shift; - } else if (exp10 < 0) { - numerator.assign_pow10(-exp10); - lower.assign(numerator); - if (is_predecessor_closer) { - upper_store.assign(numerator); - upper_store <<= 1; - upper = &upper_store; - } - numerator *= value.f; - numerator <<= shift; - denominator = 1; - denominator <<= shift - value.e; - } else { - numerator = value.f; - numerator <<= shift; - denominator.assign_pow10(exp10); - denominator <<= shift - value.e; - lower = 1; - if (is_predecessor_closer) { - upper_store = 1ULL << 1; - upper = &upper_store; - } - } - int even = static_cast((value.f & 1) == 0); - if (!upper) upper = &lower; - bool shortest = num_digits < 0; - if ((flags & dragon::fixup) != 0) { - if (add_compare(numerator, *upper, denominator) + even <= 0) { - --exp10; - numerator *= 10; - if (num_digits < 0) { - lower *= 10; - if (upper != &lower) *upper *= 10; - } - } - if ((flags & dragon::fixed) != 0) adjust_precision(num_digits, exp10 + 1); - } - // Invariant: value == (numerator / denominator) * pow(10, exp10). - if (shortest) { - // Generate the shortest representation. - num_digits = 0; - char* data = buf.data(); - for (;;) { - int digit = numerator.divmod_assign(denominator); - bool low = compare(numerator, lower) - even < 0; // numerator <[=] lower. - // numerator + upper >[=] pow10: - bool high = add_compare(numerator, *upper, denominator) + even > 0; - data[num_digits++] = static_cast('0' + digit); - if (low || high) { - if (!low) { - ++data[num_digits - 1]; - } else if (high) { - int result = add_compare(numerator, numerator, denominator); - // Round half to even. - if (result > 0 || (result == 0 && (digit % 2) != 0)) - ++data[num_digits - 1]; - } - buf.try_resize(to_unsigned(num_digits)); - exp10 -= num_digits - 1; - return; - } - numerator *= 10; - lower *= 10; - if (upper != &lower) *upper *= 10; - } - } - // Generate the given number of digits. - exp10 -= num_digits - 1; - if (num_digits <= 0) { - auto digit = '0'; - if (num_digits == 0) { - denominator *= 10; - digit = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0'; - } - buf.push_back(digit); - return; - } - buf.try_resize(to_unsigned(num_digits)); - for (int i = 0; i < num_digits - 1; ++i) { - int digit = numerator.divmod_assign(denominator); - buf[i] = static_cast('0' + digit); - numerator *= 10; - } - int digit = numerator.divmod_assign(denominator); - auto result = add_compare(numerator, numerator, denominator); - if (result > 0 || (result == 0 && (digit % 2) != 0)) { - if (digit == 9) { - const auto overflow = '0' + 10; - buf[num_digits - 1] = overflow; - // Propagate the carry. - for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) { - buf[i] = '0'; - ++buf[i - 1]; - } - if (buf[0] == overflow) { - buf[0] = '1'; - if ((flags & dragon::fixed) != 0) - buf.push_back('0'); - else - ++exp10; - } - return; - } - ++digit; - } - buf[num_digits - 1] = static_cast('0' + digit); -} - -// Formats a floating-point number using the hexfloat format. -template ::value)> -FMT_CONSTEXPR20 void format_hexfloat(Float value, format_specs specs, - buffer& buf) { - // float is passed as double to reduce the number of instantiations and to - // simplify implementation. - static_assert(!std::is_same::value, ""); - - using info = dragonbox::float_info; - - // Assume Float is in the format [sign][exponent][significand]. - using carrier_uint = typename info::carrier_uint; - - const auto num_float_significand_bits = detail::num_significand_bits(); - - basic_fp f(value); - f.e += num_float_significand_bits; - if (!has_implicit_bit()) --f.e; - - const auto num_fraction_bits = - num_float_significand_bits + (has_implicit_bit() ? 1 : 0); - const auto num_xdigits = (num_fraction_bits + 3) / 4; - - const auto leading_shift = ((num_xdigits - 1) * 4); - const auto leading_mask = carrier_uint(0xF) << leading_shift; - const auto leading_xdigit = - static_cast((f.f & leading_mask) >> leading_shift); - if (leading_xdigit > 1) f.e -= (32 - countl_zero(leading_xdigit) - 1); - - int print_xdigits = num_xdigits - 1; - if (specs.precision >= 0 && print_xdigits > specs.precision) { - const int shift = ((print_xdigits - specs.precision - 1) * 4); - const auto mask = carrier_uint(0xF) << shift; - const auto v = static_cast((f.f & mask) >> shift); - - if (v >= 8) { - const auto inc = carrier_uint(1) << (shift + 4); - f.f += inc; - f.f &= ~(inc - 1); - } - - // Check long double overflow - if (!has_implicit_bit()) { - const auto implicit_bit = carrier_uint(1) << num_float_significand_bits; - if ((f.f & implicit_bit) == implicit_bit) { - f.f >>= 4; - f.e += 4; - } - } - - print_xdigits = specs.precision; - } - - char xdigits[num_bits() / 4]; - detail::fill_n(xdigits, sizeof(xdigits), '0'); - format_base2e(4, xdigits, f.f, num_xdigits, specs.upper()); - - // Remove zero tail - while (print_xdigits > 0 && xdigits[print_xdigits] == '0') --print_xdigits; - - buf.push_back('0'); - buf.push_back(specs.upper() ? 'X' : 'x'); - buf.push_back(xdigits[0]); - if (specs.alt() || print_xdigits > 0 || print_xdigits < specs.precision) - buf.push_back('.'); - buf.append(xdigits + 1, xdigits + 1 + print_xdigits); - for (; print_xdigits < specs.precision; ++print_xdigits) buf.push_back('0'); - - buf.push_back(specs.upper() ? 'P' : 'p'); - - uint32_t abs_e; - if (f.e < 0) { - buf.push_back('-'); - abs_e = static_cast(-f.e); - } else { - buf.push_back('+'); - abs_e = static_cast(f.e); - } - format_decimal(appender(buf), abs_e, detail::count_digits(abs_e)); -} - -template ::value)> -FMT_CONSTEXPR20 void format_hexfloat(Float value, format_specs specs, - buffer& buf) { - format_hexfloat(static_cast(value), specs, buf); -} - -constexpr auto fractional_part_rounding_thresholds(int index) -> uint32_t { - // For checking rounding thresholds. - // The kth entry is chosen to be the smallest integer such that the - // upper 32-bits of 10^(k+1) times it is strictly bigger than 5 * 10^k. - // It is equal to ceil(2^31 + 2^32/10^(k + 1)). - // These are stored in a string literal because we cannot have static arrays - // in constexpr functions and non-static ones are poorly optimized. - return U"\x9999999a\x828f5c29\x80418938\x80068db9\x8000a7c6\x800010c7" - U"\x800001ae\x8000002b"[index]; -} - -template -FMT_CONSTEXPR20 auto format_float(Float value, int precision, - const format_specs& specs, bool binary32, - buffer& buf) -> int { - // float is passed as double to reduce the number of instantiations. - static_assert(!std::is_same::value, ""); - auto converted_value = convert_float(value); - - const bool fixed = specs.type() == presentation_type::fixed; - if (value == 0) { - if (precision <= 0 || !fixed) { - buf.push_back('0'); - return 0; - } - buf.try_resize(to_unsigned(precision)); - fill_n(buf.data(), precision, '0'); - return -precision; - } - - int exp = 0; - bool use_dragon = true; - unsigned dragon_flags = 0; - if (!is_fast_float() || is_constant_evaluated()) { - const auto inv_log2_10 = 0.3010299956639812; // 1 / log2(10) - using info = dragonbox::float_info; - const auto f = basic_fp(converted_value); - // Compute exp, an approximate power of 10, such that - // 10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1). - // This is based on log10(value) == log2(value) / log2(10) and approximation - // of log2(value) by e + num_fraction_bits idea from double-conversion. - auto e = (f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10; - exp = static_cast(e); - if (e > exp) ++exp; // Compute ceil. - dragon_flags = dragon::fixup; - } else { - // Extract significand bits and exponent bits. - using info = dragonbox::float_info; - auto br = bit_cast(static_cast(value)); - - const uint64_t significand_mask = - (static_cast(1) << num_significand_bits()) - 1; - uint64_t significand = (br & significand_mask); - int exponent = static_cast((br & exponent_mask()) >> - num_significand_bits()); - - if (exponent != 0) { // Check if normal. - exponent -= exponent_bias() + num_significand_bits(); - significand |= - (static_cast(1) << num_significand_bits()); - significand <<= 1; - } else { - // Normalize subnormal inputs. - FMT_ASSERT(significand != 0, "zeros should not appear here"); - int shift = countl_zero(significand); - FMT_ASSERT(shift >= num_bits() - num_significand_bits(), - ""); - shift -= (num_bits() - num_significand_bits() - 2); - exponent = (std::numeric_limits::min_exponent - - num_significand_bits()) - - shift; - significand <<= shift; - } - - // Compute the first several nonzero decimal significand digits. - // We call the number we get the first segment. - const int k = info::kappa - dragonbox::floor_log10_pow2(exponent); - exp = -k; - const int beta = exponent + dragonbox::floor_log2_pow10(k); - uint64_t first_segment; - bool has_more_segments; - int digits_in_the_first_segment; - { - const auto r = dragonbox::umul192_upper128( - significand << beta, dragonbox::get_cached_power(k)); - first_segment = r.high(); - has_more_segments = r.low() != 0; - - // The first segment can have 18 ~ 19 digits. - if (first_segment >= 1000000000000000000ULL) { - digits_in_the_first_segment = 19; - } else { - // When it is of 18-digits, we align it to 19-digits by adding a bogus - // zero at the end. - digits_in_the_first_segment = 18; - first_segment *= 10; - } - } - - // Compute the actual number of decimal digits to print. - if (fixed) adjust_precision(precision, exp + digits_in_the_first_segment); - - // Use Dragon4 only when there might be not enough digits in the first - // segment. - if (digits_in_the_first_segment > precision) { - use_dragon = false; - - if (precision <= 0) { - exp += digits_in_the_first_segment; - - if (precision < 0) { - // Nothing to do, since all we have are just leading zeros. - buf.try_resize(0); - } else { - // We may need to round-up. - buf.try_resize(1); - if ((first_segment | static_cast(has_more_segments)) > - 5000000000000000000ULL) { - buf[0] = '1'; - } else { - buf[0] = '0'; - } - } - } // precision <= 0 - else { - exp += digits_in_the_first_segment - precision; - - // When precision > 0, we divide the first segment into three - // subsegments, each with 9, 9, and 0 ~ 1 digits so that each fits - // in 32-bits which usually allows faster calculation than in - // 64-bits. Since some compiler (e.g. MSVC) doesn't know how to optimize - // division-by-constant for large 64-bit divisors, we do it here - // manually. The magic number 7922816251426433760 below is equal to - // ceil(2^(64+32) / 10^10). - const uint32_t first_subsegment = static_cast( - dragonbox::umul128_upper64(first_segment, 7922816251426433760ULL) >> - 32); - const uint64_t second_third_subsegments = - first_segment - first_subsegment * 10000000000ULL; - - uint64_t prod; - uint32_t digits; - bool should_round_up; - int number_of_digits_to_print = min_of(precision, 9); - - // Print a 9-digits subsegment, either the first or the second. - auto print_subsegment = [&](uint32_t subsegment, char* buffer) { - int number_of_digits_printed = 0; - - // If we want to print an odd number of digits from the subsegment, - if ((number_of_digits_to_print & 1) != 0) { - // Convert to 64-bit fixed-point fractional form with 1-digit - // integer part. The magic number 720575941 is a good enough - // approximation of 2^(32 + 24) / 10^8; see - // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case - // for details. - prod = ((subsegment * static_cast(720575941)) >> 24) + 1; - digits = static_cast(prod >> 32); - *buffer = static_cast('0' + digits); - number_of_digits_printed++; - } - // If we want to print an even number of digits from the - // first_subsegment, - else { - // Convert to 64-bit fixed-point fractional form with 2-digits - // integer part. The magic number 450359963 is a good enough - // approximation of 2^(32 + 20) / 10^7; see - // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case - // for details. - prod = ((subsegment * static_cast(450359963)) >> 20) + 1; - digits = static_cast(prod >> 32); - write2digits(buffer, digits); - number_of_digits_printed += 2; - } - - // Print all digit pairs. - while (number_of_digits_printed < number_of_digits_to_print) { - prod = static_cast(prod) * static_cast(100); - digits = static_cast(prod >> 32); - write2digits(buffer + number_of_digits_printed, digits); - number_of_digits_printed += 2; - } - }; - - // Print first subsegment. - print_subsegment(first_subsegment, buf.data()); - - // Perform rounding if the first subsegment is the last subsegment to - // print. - if (precision <= 9) { - // Rounding inside the subsegment. - // We round-up if: - // - either the fractional part is strictly larger than 1/2, or - // - the fractional part is exactly 1/2 and the last digit is odd. - // We rely on the following observations: - // - If fractional_part >= threshold, then the fractional part is - // strictly larger than 1/2. - // - If the MSB of fractional_part is set, then the fractional part - // must be at least 1/2. - // - When the MSB of fractional_part is set, either - // second_third_subsegments being nonzero or has_more_segments - // being true means there are further digits not printed, so the - // fractional part is strictly larger than 1/2. - if (precision < 9) { - uint32_t fractional_part = static_cast(prod); - should_round_up = - fractional_part >= fractional_part_rounding_thresholds( - 8 - number_of_digits_to_print) || - ((fractional_part >> 31) & - ((digits & 1) | (second_third_subsegments != 0) | - has_more_segments)) != 0; - } - // Rounding at the subsegment boundary. - // In this case, the fractional part is at least 1/2 if and only if - // second_third_subsegments >= 5000000000ULL, and is strictly larger - // than 1/2 if we further have either second_third_subsegments > - // 5000000000ULL or has_more_segments == true. - else { - should_round_up = second_third_subsegments > 5000000000ULL || - (second_third_subsegments == 5000000000ULL && - ((digits & 1) != 0 || has_more_segments)); - } - } - // Otherwise, print the second subsegment. - else { - // Compilers are not aware of how to leverage the maximum value of - // second_third_subsegments to find out a better magic number which - // allows us to eliminate an additional shift. 1844674407370955162 = - // ceil(2^64/10) < ceil(2^64*(10^9/(10^10 - 1))). - const uint32_t second_subsegment = - static_cast(dragonbox::umul128_upper64( - second_third_subsegments, 1844674407370955162ULL)); - const uint32_t third_subsegment = - static_cast(second_third_subsegments) - - second_subsegment * 10; - - number_of_digits_to_print = precision - 9; - print_subsegment(second_subsegment, buf.data() + 9); - - // Rounding inside the subsegment. - if (precision < 18) { - // The condition third_subsegment != 0 implies that the segment was - // of 19 digits, so in this case the third segment should be - // consisting of a genuine digit from the input. - uint32_t fractional_part = static_cast(prod); - should_round_up = - fractional_part >= fractional_part_rounding_thresholds( - 8 - number_of_digits_to_print) || - ((fractional_part >> 31) & - ((digits & 1) | (third_subsegment != 0) | - has_more_segments)) != 0; - } - // Rounding at the subsegment boundary. - else { - // In this case, the segment must be of 19 digits, thus - // the third subsegment should be consisting of a genuine digit from - // the input. - should_round_up = third_subsegment > 5 || - (third_subsegment == 5 && - ((digits & 1) != 0 || has_more_segments)); - } - } - - // Round-up if necessary. - if (should_round_up) { - ++buf[precision - 1]; - for (int i = precision - 1; i > 0 && buf[i] > '9'; --i) { - buf[i] = '0'; - ++buf[i - 1]; - } - if (buf[0] > '9') { - buf[0] = '1'; - if (fixed) - buf[precision++] = '0'; - else - ++exp; - } - } - buf.try_resize(to_unsigned(precision)); - } - } // if (digits_in_the_first_segment > precision) - else { - // Adjust the exponent for its use in Dragon4. - exp += digits_in_the_first_segment - 1; - } - } - if (use_dragon) { - auto f = basic_fp(); - bool is_predecessor_closer = binary32 ? f.assign(static_cast(value)) - : f.assign(converted_value); - if (is_predecessor_closer) dragon_flags |= dragon::predecessor_closer; - if (fixed) dragon_flags |= dragon::fixed; - // Limit precision to the maximum possible number of significant digits in - // an IEEE754 double because we don't need to generate zeros. - const int max_double_digits = 767; - if (precision > max_double_digits) precision = max_double_digits; - format_dragon(f, dragon_flags, precision, buf, exp); - } - if (!fixed && !specs.alt()) { - // Remove trailing zeros. - auto num_digits = buf.size(); - while (num_digits > 0 && buf[num_digits - 1] == '0') { - --num_digits; - ++exp; - } - buf.try_resize(num_digits); - } - return exp; -} - -template ::value)> -FMT_CONSTEXPR20 auto write(OutputIt out, T value, format_specs specs, - locale_ref loc = {}) -> OutputIt { - if (specs.localized() && write_loc(out, value, specs, loc)) return out; - - // Use signbit because value < 0 is false for NaN. - sign s = detail::signbit(value) ? sign::minus : specs.sign(); - - if (!detail::isfinite(value)) - return write_nonfinite(out, detail::isnan(value), specs, s); - - if (specs.align() == align::numeric && s != sign::none) { - *out++ = detail::getsign(s); - s = sign::none; - if (specs.width != 0) --specs.width; - } - - const int exp_upper = detail::exp_upper(); - int precision = specs.precision; - if (precision < 0) { - if (specs.type() != presentation_type::none) { - precision = 6; - } else if (is_fast_float::value && !is_constant_evaluated()) { - // Use Dragonbox for the shortest format. - auto dec = dragonbox::to_decimal(static_cast>(value)); - return write_float(out, dec, specs, s, exp_upper, loc); - } - } - - memory_buffer buffer; - if (specs.type() == presentation_type::hexfloat) { - if (s != sign::none) buffer.push_back(detail::getsign(s)); - format_hexfloat(convert_float(value), specs, buffer); - return write_bytes(out, {buffer.data(), buffer.size()}, - specs); - } - - if (specs.type() == presentation_type::exp) { - if (precision == max_value()) - report_error("number is too big"); - else - ++precision; - if (specs.precision != 0) specs.set_alt(); - } else if (specs.type() == presentation_type::fixed) { - if (specs.precision != 0) specs.set_alt(); - } else if (precision == 0) { - precision = 1; - } - int exp = format_float(convert_float(value), precision, specs, - std::is_same(), buffer); - - specs.precision = precision; - auto f = big_decimal_fp{buffer.data(), static_cast(buffer.size()), exp}; - return write_float(out, f, specs, s, exp_upper, loc); -} - -template ::value)> -FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt { - if (is_constant_evaluated()) return write(out, value, format_specs()); - - auto s = detail::signbit(value) ? sign::minus : sign::none; - auto mask = exponent_mask>(); - if ((bit_cast(value) & mask) == mask) - return write_nonfinite(out, std::isnan(value), {}, s); - - auto dec = dragonbox::to_decimal(static_cast>(value)); - auto significand = dec.significand; - int significand_size = count_digits(significand); - int exponent = dec.exponent + significand_size - 1; - if (use_fixed(exponent, detail::exp_upper())) { - return write_fixed>( - out, dec, significand_size, Char('.'), {}, s); - } - - // Write value in the exponential format. - const char* prefix = "e+"; - int abs_exponent = exponent; - if (exponent < 0) { - abs_exponent = -exponent; - prefix = "e-"; - } - auto has_decimal_point = significand_size != 1; - size_t size = std::is_pointer::value - ? 0u - : to_unsigned((s != sign::none ? 1 : 0) + significand_size + - (has_decimal_point ? 1 : 0) + - (abs_exponent >= 100 ? 5 : 4)); - if (auto ptr = to_pointer(out, size)) { - if (s != sign::none) *ptr++ = Char('-'); - if (has_decimal_point) { - auto begin = ptr; - ptr = format_decimal(ptr, significand, significand_size + 1); - *begin = begin[1]; - begin[1] = '.'; - } else { - *ptr++ = static_cast('0' + significand); - } - if (std::is_same::value) { - memcpy(ptr, prefix, 2); - ptr += 2; - } else { - *ptr++ = prefix[0]; - *ptr++ = prefix[1]; - } - if (abs_exponent >= 100) { - *ptr++ = static_cast('0' + abs_exponent / 100); - abs_exponent %= 100; - } - write2digits(ptr, static_cast(abs_exponent)); - return select::value>(ptr + 2, out); - } - auto it = reserve(out, size); - if (s != sign::none) *it++ = Char('-'); - // Insert a decimal point after the first digit and add an exponent. - it = write_significand(it, significand, significand_size, 1, - has_decimal_point ? Char('.') : Char()); - *it++ = Char('e'); - it = write_exponent(exponent, it); - return base_iterator(out, it); -} - -template ::value && - !is_fast_float::value)> -inline auto write(OutputIt out, T value) -> OutputIt { - return write(out, value, {}); -} - -template -auto write(OutputIt out, monostate, format_specs = {}, locale_ref = {}) - -> OutputIt { - FMT_ASSERT(false, ""); - return out; -} - -template -FMT_CONSTEXPR auto write(OutputIt out, basic_string_view value) - -> OutputIt { - return copy_noinline(value.begin(), value.end(), out); -} - -template ::value)> -constexpr auto write(OutputIt out, const T& value) -> OutputIt { - return write(out, to_string_view(value)); -} - -// FMT_ENABLE_IF() condition separated to workaround an MSVC bug. -template < - typename Char, typename OutputIt, typename T, - bool check = std::is_enum::value && !std::is_same::value && - mapped_type_constant::value != type::custom_type, - FMT_ENABLE_IF(check)> -FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { - return write(out, static_cast>(value)); -} - -template ::value)> -FMT_CONSTEXPR auto write(OutputIt out, T value, const format_specs& specs = {}, - locale_ref = {}) -> OutputIt { - return specs.type() != presentation_type::none && - specs.type() != presentation_type::string - ? write(out, value ? 1 : 0, specs, {}) - : write_bytes(out, value ? "true" : "false", specs); -} - -template -FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt { - auto it = reserve(out, 1); - *it++ = value; - return base_iterator(out, it); -} - -template -FMT_CONSTEXPR20 auto write(OutputIt out, const Char* value) -> OutputIt { - if (value) return write(out, basic_string_view(value)); - report_error("string pointer is null"); - return out; -} - -template ::value)> -auto write(OutputIt out, const T* value, const format_specs& specs = {}, - locale_ref = {}) -> OutputIt { - return write_ptr(out, bit_cast(value), &specs); -} - -template ::value == - type::custom_type && - !std::is_fundamental::value)> -FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> OutputIt { - auto f = formatter(); - auto parse_ctx = parse_context({}); - f.parse(parse_ctx); - auto ctx = basic_format_context(out, {}, {}); - return f.format(value, ctx); -} - -template -using is_builtin = - bool_constant::value || FMT_BUILTIN_TYPES>; - -// An argument visitor that formats the argument and writes it via the output -// iterator. It's a class and not a generic lambda for compatibility with C++11. -template struct default_arg_formatter { - using context = buffered_context; - - basic_appender out; - - void operator()(monostate) { report_error("argument not found"); } - - template ::value)> - void operator()(T value) { - write(out, value); - } - - template ::value)> - void operator()(T) { - FMT_ASSERT(false, ""); - } - - void operator()(typename basic_format_arg::handle h) { - // Use a null locale since the default format must be unlocalized. - auto parse_ctx = parse_context({}); - auto format_ctx = context(out, {}, {}); - h.format(parse_ctx, format_ctx); - } -}; - -template struct arg_formatter { - basic_appender out; - const format_specs& specs; - FMT_NO_UNIQUE_ADDRESS locale_ref locale; - - template ::value)> - FMT_CONSTEXPR FMT_INLINE void operator()(T value) { - detail::write(out, value, specs, locale); - } - - template ::value)> - void operator()(T) { - FMT_ASSERT(false, ""); - } - - void operator()(typename basic_format_arg>::handle) { - // User-defined types are handled separately because they require access - // to the parse context. - } -}; - -struct dynamic_spec_getter { - template ::value)> - FMT_CONSTEXPR auto operator()(T value) -> unsigned long long { - return is_negative(value) ? ~0ull : static_cast(value); - } - - template ::value)> - FMT_CONSTEXPR auto operator()(T) -> unsigned long long { - report_error("width/precision is not integer"); - return 0; - } -}; - -template -FMT_CONSTEXPR void handle_dynamic_spec( - arg_id_kind kind, int& value, - const arg_ref& ref, Context& ctx) { - if (kind == arg_id_kind::none) return; - auto arg = - kind == arg_id_kind::index ? ctx.arg(ref.index) : ctx.arg(ref.name); - if (!arg) report_error("argument not found"); - unsigned long long result = arg.visit(dynamic_spec_getter()); - if (result > to_unsigned(max_value())) - report_error("width/precision is out of range"); - value = static_cast(result); -} - -#if FMT_USE_NONTYPE_TEMPLATE_ARGS -template Str> -struct static_named_arg : view { - static constexpr auto name = Str.data; - - const T& value; - static_named_arg(const T& v) : value(v) {} -}; - -template Str> -struct is_named_arg> : std::true_type {}; - -template Str> -struct is_static_named_arg> : std::true_type { -}; - -template Str> -struct udl_arg { - template auto operator=(T&& value) const { - return static_named_arg(std::forward(value)); - } -}; -#else -template struct udl_arg { - const Char* str; - - template auto operator=(T&& value) const -> named_arg { - return {str, std::forward(value)}; - } -}; -#endif // FMT_USE_NONTYPE_TEMPLATE_ARGS - -template struct format_handler { - parse_context parse_ctx; - buffered_context ctx; - - void on_text(const Char* begin, const Char* end) { - copy_noinline(begin, end, ctx.out()); - } - - FMT_CONSTEXPR auto on_arg_id() -> int { return parse_ctx.next_arg_id(); } - FMT_CONSTEXPR auto on_arg_id(int id) -> int { - parse_ctx.check_arg_id(id); - return id; - } - FMT_CONSTEXPR auto on_arg_id(basic_string_view id) -> int { - parse_ctx.check_arg_id(id); - int arg_id = ctx.arg_id(id); - if (arg_id < 0) report_error("argument not found"); - return arg_id; - } - - FMT_INLINE void on_replacement_field(int id, const Char*) { - ctx.arg(id).visit(default_arg_formatter{ctx.out()}); - } - - auto on_format_specs(int id, const Char* begin, const Char* end) - -> const Char* { - auto arg = ctx.arg(id); - if (!arg) report_error("argument not found"); - // Not using a visitor for custom types gives better codegen. - if (arg.format_custom(begin, parse_ctx, ctx)) return parse_ctx.begin(); - - auto specs = dynamic_format_specs(); - begin = parse_format_specs(begin, end, specs, parse_ctx, arg.type()); - if (specs.dynamic()) { - handle_dynamic_spec(specs.dynamic_width(), specs.width, specs.width_ref, - ctx); - handle_dynamic_spec(specs.dynamic_precision(), specs.precision, - specs.precision_ref, ctx); - } - - arg.visit(arg_formatter{ctx.out(), specs, ctx.locale()}); - return begin; - } - - FMT_NORETURN void on_error(const char* message) { report_error(message); } -}; - -// It is used in format-inl.h and os.cc. -using format_func = void (*)(detail::buffer&, int, const char*); -FMT_API void do_report_error(format_func func, int error_code, - const char* message) noexcept; - -FMT_API void format_error_code(buffer& out, int error_code, - string_view message) noexcept; - -template -template -FMT_CONSTEXPR auto native_formatter::format( - const T& val, FormatContext& ctx) const -> decltype(ctx.out()) { - if (!specs_.dynamic()) - return write(ctx.out(), val, specs_, ctx.locale()); - auto specs = format_specs(specs_); - handle_dynamic_spec(specs.dynamic_width(), specs.width, specs_.width_ref, - ctx); - handle_dynamic_spec(specs.dynamic_precision(), specs.precision, - specs_.precision_ref, ctx); - return write(ctx.out(), val, specs, ctx.locale()); -} -} // namespace detail - -FMT_BEGIN_EXPORT - -// A generic formatting context with custom output iterator and character -// (code unit) support. Char is the format string code unit type which can be -// different from OutputIt::value_type. -template class generic_context { - private: - OutputIt out_; - basic_format_args args_; - locale_ref loc_; - - public: - using char_type = Char; - using iterator = OutputIt; - enum { builtin_types = FMT_BUILTIN_TYPES }; - - constexpr generic_context(OutputIt out, - basic_format_args args, - locale_ref loc = {}) - : out_(out), args_(args), loc_(loc) {} - generic_context(generic_context&&) = default; - generic_context(const generic_context&) = delete; - void operator=(const generic_context&) = delete; - - constexpr auto arg(int id) const -> basic_format_arg { - return args_.get(id); - } - auto arg(basic_string_view name) const - -> basic_format_arg { - return args_.get(name); - } - constexpr auto arg_id(basic_string_view name) const -> int { - return args_.get_id(name); - } - - constexpr auto out() const -> iterator { return out_; } - - void advance_to(iterator it) { - if (!detail::is_back_insert_iterator()) out_ = it; - } - - constexpr auto locale() const -> locale_ref { return loc_; } -}; - -class loc_value { - private: - basic_format_arg value_; - - public: - template ::value)> - loc_value(T value) : value_(value) {} - - template ::value)> - loc_value(T) {} - - template auto visit(Visitor&& vis) -> decltype(vis(0)) { - return value_.visit(vis); - } -}; - -// A locale facet that formats values in UTF-8. -// It is parameterized on the locale to avoid the heavy include. -template class format_facet : public Locale::facet { - private: - std::string separator_; - std::string grouping_; - std::string decimal_point_; - - protected: - virtual auto do_put(appender out, loc_value val, - const format_specs& specs) const -> bool; - - public: - static FMT_API typename Locale::id id; - - explicit format_facet(Locale& loc); - explicit format_facet(string_view sep = "", std::string grouping = "\3", - std::string decimal_point = ".") - : separator_(sep.data(), sep.size()), - grouping_(grouping), - decimal_point_(decimal_point) {} - - auto put(appender out, loc_value val, const format_specs& specs) const - -> bool { - return do_put(out, val, specs); - } -}; - -#define FMT_FORMAT_AS(Type, Base) \ - template \ - struct formatter : formatter { \ - template \ - FMT_CONSTEXPR auto format(Type value, FormatContext& ctx) const \ - -> decltype(ctx.out()) { \ - return formatter::format(value, ctx); \ - } \ - } - -FMT_FORMAT_AS(signed char, int); -FMT_FORMAT_AS(unsigned char, unsigned); -FMT_FORMAT_AS(short, int); -FMT_FORMAT_AS(unsigned short, unsigned); -FMT_FORMAT_AS(long, detail::long_type); -FMT_FORMAT_AS(unsigned long, detail::ulong_type); -FMT_FORMAT_AS(Char*, const Char*); -FMT_FORMAT_AS(detail::std_string_view, basic_string_view); -FMT_FORMAT_AS(std::nullptr_t, const void*); -FMT_FORMAT_AS(void*, const void*); - -template -struct formatter : formatter, Char> {}; - -template -class formatter, Char> - : public formatter, Char> {}; - -template -struct formatter, Char> : formatter {}; -template -struct formatter, Char> - : formatter {}; - -template -struct formatter - : detail::native_formatter {}; - -template -struct formatter>> - : formatter, Char> { - template - FMT_CONSTEXPR auto format(const T& value, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto&& val = format_as(value); // Make an lvalue reference for format. - return formatter, Char>::format(val, ctx); - } -}; - -/** - * Converts `p` to `const void*` for pointer formatting. - * - * **Example**: - * - * auto s = fmt::format("{}", fmt::ptr(p)); - */ -template auto ptr(T p) -> const void* { - static_assert(std::is_pointer::value, "fmt::ptr used with non-pointer"); - return detail::bit_cast(p); -} - -/** - * Converts `e` to the underlying type. - * - * **Example**: - * - * enum class color { red, green, blue }; - * auto s = fmt::format("{}", fmt::underlying(color::red)); // s == "0" - */ -template -constexpr auto underlying(Enum e) noexcept -> underlying_t { - return static_cast>(e); -} - -namespace enums { -template ::value)> -constexpr auto format_as(Enum e) noexcept -> underlying_t { - return static_cast>(e); -} -} // namespace enums - -#ifdef __cpp_lib_byte -template -struct formatter : formatter { - static auto format_as(std::byte b) -> unsigned char { - return static_cast(b); - } - template - auto format(std::byte b, Context& ctx) const -> decltype(ctx.out()) { - return formatter::format(format_as(b), ctx); - } -}; -#endif - -struct bytes { - string_view data; - - inline explicit bytes(string_view s) : data(s) {} -}; - -template <> struct formatter { - private: - detail::dynamic_format_specs<> specs_; - - public: - FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* { - return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, - detail::type::string_type); - } - - template - auto format(bytes b, FormatContext& ctx) const -> decltype(ctx.out()) { - auto specs = specs_; - detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, - specs.width_ref, ctx); - detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision, - specs.precision_ref, ctx); - return detail::write_bytes(ctx.out(), b.data, specs); - } -}; - -// group_digits_view is not derived from view because it copies the argument. -template struct group_digits_view { - T value; -}; - -/** - * Returns a view that formats an integer value using ',' as a - * locale-independent thousands separator. - * - * **Example**: - * - * fmt::print("{}", fmt::group_digits(12345)); - * // Output: "12,345" - */ -template auto group_digits(T value) -> group_digits_view { - return {value}; -} - -template struct formatter> : formatter { - private: - detail::dynamic_format_specs<> specs_; - - public: - FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* { - return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, - detail::type::int_type); - } - - template - auto format(group_digits_view view, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto specs = specs_; - detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, - specs.width_ref, ctx); - detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision, - specs.precision_ref, ctx); - auto arg = detail::make_write_int_arg(view.value, specs.sign()); - return detail::write_int( - ctx.out(), static_cast>(arg.abs_value), - arg.prefix, specs, detail::digit_grouping("\3", ",")); - } -}; - -template struct nested_view { - const formatter* fmt; - const T* value; -}; - -template -struct formatter, Char> { - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - return ctx.begin(); - } - template - auto format(nested_view view, FormatContext& ctx) const - -> decltype(ctx.out()) { - return view.fmt->format(*view.value, ctx); - } -}; - -template struct nested_formatter { - private: - basic_specs specs_; - int width_; - formatter formatter_; - - public: - constexpr nested_formatter() : width_(0) {} - - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - auto it = ctx.begin(), end = ctx.end(); - if (it == end) return it; - auto specs = format_specs(); - it = detail::parse_align(it, end, specs); - specs_ = specs; - Char c = *it; - auto width_ref = detail::arg_ref(); - if ((c >= '0' && c <= '9') || c == '{') { - it = detail::parse_width(it, end, specs, width_ref, ctx); - width_ = specs.width; - } - ctx.advance_to(it); - return formatter_.parse(ctx); - } - - template - auto write_padded(FormatContext& ctx, F write) const -> decltype(ctx.out()) { - if (width_ == 0) return write(ctx.out()); - auto buf = basic_memory_buffer(); - write(basic_appender(buf)); - auto specs = format_specs(); - specs.width = width_; - specs.copy_fill_from(specs_); - specs.set_align(specs_.align()); - return detail::write( - ctx.out(), basic_string_view(buf.data(), buf.size()), specs); - } - - auto nested(const T& value) const -> nested_view { - return nested_view{&formatter_, &value}; - } -}; - -inline namespace literals { -#if FMT_USE_NONTYPE_TEMPLATE_ARGS -template constexpr auto operator""_a() { - using char_t = remove_cvref_t; - return detail::udl_arg(); -} -#else -/** - * User-defined literal equivalent of `fmt::arg`. - * - * **Example**: - * - * using namespace fmt::literals; - * fmt::print("The answer is {answer}.", "answer"_a=42); - */ -constexpr auto operator""_a(const char* s, size_t) -> detail::udl_arg { - return {s}; -} -#endif // FMT_USE_NONTYPE_TEMPLATE_ARGS -} // namespace literals - -/// A fast integer formatter. -class format_int { - private: - // Buffer should be large enough to hold all digits (digits10 + 1), - // a sign and a null character. - enum { buffer_size = std::numeric_limits::digits10 + 3 }; - mutable char buffer_[buffer_size]; - char* str_; - - template - FMT_CONSTEXPR20 auto format_unsigned(UInt value) -> char* { - auto n = static_cast>(value); - return detail::do_format_decimal(buffer_, n, buffer_size - 1); - } - - template - FMT_CONSTEXPR20 auto format_signed(Int value) -> char* { - auto abs_value = static_cast>(value); - bool negative = value < 0; - if (negative) abs_value = 0 - abs_value; - auto begin = format_unsigned(abs_value); - if (negative) *--begin = '-'; - return begin; - } - - public: - FMT_CONSTEXPR20 explicit format_int(int value) : str_(format_signed(value)) {} - FMT_CONSTEXPR20 explicit format_int(long value) - : str_(format_signed(value)) {} - FMT_CONSTEXPR20 explicit format_int(long long value) - : str_(format_signed(value)) {} - FMT_CONSTEXPR20 explicit format_int(unsigned value) - : str_(format_unsigned(value)) {} - FMT_CONSTEXPR20 explicit format_int(unsigned long value) - : str_(format_unsigned(value)) {} - FMT_CONSTEXPR20 explicit format_int(unsigned long long value) - : str_(format_unsigned(value)) {} - - /// Returns the number of characters written to the output buffer. - FMT_CONSTEXPR20 auto size() const -> size_t { - return detail::to_unsigned(buffer_ - str_ + buffer_size - 1); - } - - /// Returns a pointer to the output buffer content. No terminating null - /// character is appended. - FMT_CONSTEXPR20 auto data() const -> const char* { return str_; } - - /// Returns a pointer to the output buffer content with terminating null - /// character appended. - FMT_CONSTEXPR20 auto c_str() const -> const char* { - buffer_[buffer_size - 1] = '\0'; - return str_; - } - - /// Returns the content of the output buffer as an `std::string`. - inline auto str() const -> std::string { return {str_, size()}; } -}; - -#if FMT_CLANG_ANALYZER -# define FMT_STRING_IMPL(s, base) s -#else -# define FMT_STRING_IMPL(s, base) \ - [] { \ - /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \ - /* Use a macro-like name to avoid shadowing warnings. */ \ - struct FMT_VISIBILITY("hidden") FMT_COMPILE_STRING : base { \ - using char_type = fmt::remove_cvref_t; \ - constexpr explicit operator fmt::basic_string_view() \ - const { \ - return fmt::detail::compile_string_to_view(s); \ - } \ - }; \ - using FMT_STRING_VIEW = \ - fmt::basic_string_view; \ - fmt::detail::ignore_unused(FMT_STRING_VIEW(FMT_COMPILE_STRING())); \ - return FMT_COMPILE_STRING(); \ - }() -#endif // FMT_CLANG_ANALYZER - -/** - * Constructs a legacy compile-time format string from a string literal `s`. - * - * **Example**: - * - * // A compile-time error because 'd' is an invalid specifier for strings. - * std::string s = fmt::format(FMT_STRING("{:d}"), "foo"); - */ -#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string) - -FMT_API auto vsystem_error(int error_code, string_view fmt, format_args args) - -> std::system_error; - -/** - * Constructs `std::system_error` with a message formatted with - * `fmt::format(fmt, args...)`. - * `error_code` is a system error code as given by `errno`. - * - * **Example**: - * - * // This throws std::system_error with the description - * // cannot open file 'madeup': No such file or directory - * // or similar (system message may vary). - * const char* filename = "madeup"; - * FILE* file = fopen(filename, "r"); - * if (!file) - * throw fmt::system_error(errno, "cannot open file '{}'", filename); - */ -template -auto system_error(int error_code, format_string fmt, T&&... args) - -> std::system_error { - return vsystem_error(error_code, fmt.str, vargs{{args...}}); -} - -/** - * Formats an error message for an error returned by an operating system or a - * language runtime, for example a file opening error, and writes it to `out`. - * The format is the same as the one used by `std::system_error(ec, message)` - * where `ec` is `std::error_code(error_code, std::generic_category())`. - * It is implementation-defined but normally looks like: - * - * : - * - * where `` is the passed message and `` is the system - * message corresponding to the error code. - * `error_code` is a system error code as given by `errno`. - */ -FMT_API void format_system_error(detail::buffer& out, int error_code, - const char* message) noexcept; - -// Reports a system error without throwing an exception. -// Can be used to report errors from destructors. -FMT_API void report_system_error(int error_code, const char* message) noexcept; - -inline auto vformat(locale_ref loc, string_view fmt, format_args args) - -> std::string { - auto buf = memory_buffer(); - detail::vformat_to(buf, fmt, args, loc); - return {buf.data(), buf.size()}; -} - -template -FMT_INLINE auto format(locale_ref loc, format_string fmt, T&&... args) - -> std::string { - return vformat(loc, fmt.str, vargs{{args...}}); -} - -template ::value)> -auto vformat_to(OutputIt out, locale_ref loc, string_view fmt, format_args args) - -> OutputIt { - auto&& buf = detail::get_buffer(out); - detail::vformat_to(buf, fmt, args, loc); - return detail::get_iterator(buf, out); -} - -template ::value)> -FMT_INLINE auto format_to(OutputIt out, locale_ref loc, format_string fmt, - T&&... args) -> OutputIt { - return fmt::vformat_to(out, loc, fmt.str, vargs{{args...}}); -} - -template -FMT_NODISCARD FMT_INLINE auto formatted_size(locale_ref loc, - format_string fmt, - T&&... args) -> size_t { - auto buf = detail::counting_buffer<>(); - detail::vformat_to(buf, fmt.str, vargs{{args...}}, loc); - return buf.count(); -} - -FMT_API auto vformat(string_view fmt, format_args args) -> std::string; - -/** - * Formats `args` according to specifications in `fmt` and returns the result - * as a string. - * - * **Example**: - * - * #include - * std::string message = fmt::format("The answer is {}.", 42); - */ -template -FMT_NODISCARD FMT_INLINE auto format(format_string fmt, T&&... args) - -> std::string { - return vformat(fmt.str, vargs{{args...}}); -} - -/** - * Converts `value` to `std::string` using the default format for type `T`. - * - * **Example**: - * - * std::string answer = fmt::to_string(42); - */ -template ::value)> -FMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(T value) -> std::string { - // The buffer should be large enough to store the number including the sign - // or "false" for bool. - char buffer[max_of(detail::digits10() + 2, 5)]; - return {buffer, detail::write(buffer, value)}; -} - -template ::value)> -FMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(const T& value) - -> std::string { - return to_string(format_as(value)); -} - -template ::value && - !detail::use_format_as::value)> -FMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(const T& value) - -> std::string { - auto buffer = memory_buffer(); - detail::write(appender(buffer), value); - return {buffer.data(), buffer.size()}; -} - -FMT_END_EXPORT -FMT_END_NAMESPACE - -#ifdef FMT_HEADER_ONLY -# define FMT_FUNC inline -# include "format-inl.h" -#endif - -// Restore _LIBCPP_REMOVE_TRANSITIVE_INCLUDES. -#ifdef FMT_REMOVE_TRANSITIVE_INCLUDES -# undef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES -#endif - -#endif // FMT_FORMAT_H_ diff --git a/include/libs/spdlog/fmt/bundled/os.h b/include/libs/spdlog/fmt/bundled/os.h deleted file mode 100644 index 94d730d..0000000 --- a/include/libs/spdlog/fmt/bundled/os.h +++ /dev/null @@ -1,427 +0,0 @@ -// Formatting library for C++ - optional OS-specific functionality -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_OS_H_ -#define FMT_OS_H_ - -#include "format.h" - -#ifndef FMT_MODULE -# include -# include -# include -# include // std::system_error - -# if FMT_HAS_INCLUDE() -# include // LC_NUMERIC_MASK on macOS -# endif -#endif // FMT_MODULE - -#ifndef FMT_USE_FCNTL -// UWP doesn't provide _pipe. -# if FMT_HAS_INCLUDE("winapifamily.h") -# include -# endif -# if (FMT_HAS_INCLUDE() || defined(__APPLE__) || \ - defined(__linux__)) && \ - (!defined(WINAPI_FAMILY) || \ - (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)) && \ - !defined(__wasm__) -# include // for O_RDONLY -# define FMT_USE_FCNTL 1 -# else -# define FMT_USE_FCNTL 0 -# endif -#endif - -#ifndef FMT_POSIX -# if defined(_WIN32) && !defined(__MINGW32__) -// Fix warnings about deprecated symbols. -# define FMT_POSIX(call) _##call -# else -# define FMT_POSIX(call) call -# endif -#endif - -// Calls to system functions are wrapped in FMT_SYSTEM for testability. -#ifdef FMT_SYSTEM -# define FMT_HAS_SYSTEM -# define FMT_POSIX_CALL(call) FMT_SYSTEM(call) -#else -# define FMT_SYSTEM(call) ::call -# ifdef _WIN32 -// Fix warnings about deprecated symbols. -# define FMT_POSIX_CALL(call) ::_##call -# else -# define FMT_POSIX_CALL(call) ::call -# endif -#endif - -// Retries the expression while it evaluates to error_result and errno -// equals to EINTR. -#ifndef _WIN32 -# define FMT_RETRY_VAL(result, expression, error_result) \ - do { \ - (result) = (expression); \ - } while ((result) == (error_result) && errno == EINTR) -#else -# define FMT_RETRY_VAL(result, expression, error_result) result = (expression) -#endif - -#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1) - -FMT_BEGIN_NAMESPACE -FMT_BEGIN_EXPORT - -/** - * A reference to a null-terminated string. It can be constructed from a C - * string or `std::string`. - * - * You can use one of the following type aliases for common character types: - * - * +---------------+-----------------------------+ - * | Type | Definition | - * +===============+=============================+ - * | cstring_view | basic_cstring_view | - * +---------------+-----------------------------+ - * | wcstring_view | basic_cstring_view | - * +---------------+-----------------------------+ - * - * This class is most useful as a parameter type for functions that wrap C APIs. - */ -template class basic_cstring_view { - private: - const Char* data_; - - public: - /// Constructs a string reference object from a C string. - basic_cstring_view(const Char* s) : data_(s) {} - - /// Constructs a string reference from an `std::string` object. - basic_cstring_view(const std::basic_string& s) : data_(s.c_str()) {} - - /// Returns the pointer to a C string. - auto c_str() const -> const Char* { return data_; } -}; - -using cstring_view = basic_cstring_view; -using wcstring_view = basic_cstring_view; - -#ifdef _WIN32 -FMT_API const std::error_category& system_category() noexcept; - -namespace detail { -FMT_API void format_windows_error(buffer& out, int error_code, - const char* message) noexcept; -} - -FMT_API std::system_error vwindows_error(int error_code, string_view fmt, - format_args args); - -/** - * Constructs a `std::system_error` object with the description of the form - * - * : - * - * where `` is the formatted message and `` is the - * system message corresponding to the error code. - * `error_code` is a Windows error code as given by `GetLastError`. - * If `error_code` is not a valid error code such as -1, the system message - * will look like "error -1". - * - * **Example**: - * - * // This throws a system_error with the description - * // cannot open file 'foo': The system cannot find the file specified. - * // or similar (system message may vary) if the file doesn't exist. - * const char *filename = "foo"; - * LPOFSTRUCT of = LPOFSTRUCT(); - * HFILE file = OpenFile(filename, &of, OF_READ); - * if (file == HFILE_ERROR) { - * throw fmt::windows_error(GetLastError(), - * "cannot open file '{}'", filename); - * } - */ -template -auto windows_error(int error_code, string_view message, const T&... args) - -> std::system_error { - return vwindows_error(error_code, message, vargs{{args...}}); -} - -// Reports a Windows error without throwing an exception. -// Can be used to report errors from destructors. -FMT_API void report_windows_error(int error_code, const char* message) noexcept; -#else -inline auto system_category() noexcept -> const std::error_category& { - return std::system_category(); -} -#endif // _WIN32 - -// std::system is not available on some platforms such as iOS (#2248). -#ifdef __OSX__ -template > -void say(const S& fmt, Args&&... args) { - std::system(format("say \"{}\"", format(fmt, args...)).c_str()); -} -#endif - -// A buffered file. -class buffered_file { - private: - FILE* file_; - - friend class file; - - inline explicit buffered_file(FILE* f) : file_(f) {} - - public: - buffered_file(const buffered_file&) = delete; - void operator=(const buffered_file&) = delete; - - // Constructs a buffered_file object which doesn't represent any file. - inline buffered_file() noexcept : file_(nullptr) {} - - // Destroys the object closing the file it represents if any. - FMT_API ~buffered_file() noexcept; - - public: - inline buffered_file(buffered_file&& other) noexcept : file_(other.file_) { - other.file_ = nullptr; - } - - inline auto operator=(buffered_file&& other) -> buffered_file& { - close(); - file_ = other.file_; - other.file_ = nullptr; - return *this; - } - - // Opens a file. - FMT_API buffered_file(cstring_view filename, cstring_view mode); - - // Closes the file. - FMT_API void close(); - - // Returns the pointer to a FILE object representing this file. - inline auto get() const noexcept -> FILE* { return file_; } - - FMT_API auto descriptor() const -> int; - - template - inline void print(string_view fmt, const T&... args) { - fmt::vargs vargs = {{args...}}; - detail::is_locking() ? fmt::vprint_buffered(file_, fmt, vargs) - : fmt::vprint(file_, fmt, vargs); - } -}; - -#if FMT_USE_FCNTL - -// A file. Closed file is represented by a file object with descriptor -1. -// Methods that are not declared with noexcept may throw -// fmt::system_error in case of failure. Note that some errors such as -// closing the file multiple times will cause a crash on Windows rather -// than an exception. You can get standard behavior by overriding the -// invalid parameter handler with _set_invalid_parameter_handler. -class FMT_API file { - private: - int fd_; // File descriptor. - - // Constructs a file object with a given descriptor. - explicit file(int fd) : fd_(fd) {} - - friend struct pipe; - - public: - // Possible values for the oflag argument to the constructor. - enum { - RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only. - WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only. - RDWR = FMT_POSIX(O_RDWR), // Open for reading and writing. - CREATE = FMT_POSIX(O_CREAT), // Create if the file doesn't exist. - APPEND = FMT_POSIX(O_APPEND), // Open in append mode. - TRUNC = FMT_POSIX(O_TRUNC) // Truncate the content of the file. - }; - - // Constructs a file object which doesn't represent any file. - inline file() noexcept : fd_(-1) {} - - // Opens a file and constructs a file object representing this file. - file(cstring_view path, int oflag); - - public: - file(const file&) = delete; - void operator=(const file&) = delete; - - inline file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; } - - // Move assignment is not noexcept because close may throw. - inline auto operator=(file&& other) -> file& { - close(); - fd_ = other.fd_; - other.fd_ = -1; - return *this; - } - - // Destroys the object closing the file it represents if any. - ~file() noexcept; - - // Returns the file descriptor. - inline auto descriptor() const noexcept -> int { return fd_; } - - // Closes the file. - void close(); - - // Returns the file size. The size has signed type for consistency with - // stat::st_size. - auto size() const -> long long; - - // Attempts to read count bytes from the file into the specified buffer. - auto read(void* buffer, size_t count) -> size_t; - - // Attempts to write count bytes from the specified buffer to the file. - auto write(const void* buffer, size_t count) -> size_t; - - // Duplicates a file descriptor with the dup function and returns - // the duplicate as a file object. - static auto dup(int fd) -> file; - - // Makes fd be the copy of this file descriptor, closing fd first if - // necessary. - void dup2(int fd); - - // Makes fd be the copy of this file descriptor, closing fd first if - // necessary. - void dup2(int fd, std::error_code& ec) noexcept; - - // Creates a buffered_file object associated with this file and detaches - // this file object from the file. - auto fdopen(const char* mode) -> buffered_file; - -# if defined(_WIN32) && !defined(__MINGW32__) - // Opens a file and constructs a file object representing this file by - // wcstring_view filename. Windows only. - static file open_windows_file(wcstring_view path, int oflag); -# endif -}; - -struct FMT_API pipe { - file read_end; - file write_end; - - // Creates a pipe setting up read_end and write_end file objects for reading - // and writing respectively. - pipe(); -}; - -// Returns the memory page size. -auto getpagesize() -> long; - -namespace detail { - -struct buffer_size { - constexpr buffer_size() = default; - size_t value = 0; - FMT_CONSTEXPR auto operator=(size_t val) const -> buffer_size { - auto bs = buffer_size(); - bs.value = val; - return bs; - } -}; - -struct ostream_params { - int oflag = file::WRONLY | file::CREATE | file::TRUNC; - size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768; - - constexpr ostream_params() {} - - template - ostream_params(T... params, int new_oflag) : ostream_params(params...) { - oflag = new_oflag; - } - - template - ostream_params(T... params, detail::buffer_size bs) - : ostream_params(params...) { - this->buffer_size = bs.value; - } - -// Intel has a bug that results in failure to deduce a constructor -// for empty parameter packs. -# if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 2000 - ostream_params(int new_oflag) : oflag(new_oflag) {} - ostream_params(detail::buffer_size bs) : buffer_size(bs.value) {} -# endif -}; - -} // namespace detail - -FMT_INLINE_VARIABLE constexpr auto buffer_size = detail::buffer_size(); - -/// A fast buffered output stream for writing from a single thread. Writing from -/// multiple threads without external synchronization may result in a data race. -class ostream : private detail::buffer { - private: - file file_; - - FMT_API ostream(cstring_view path, const detail::ostream_params& params); - - FMT_API static void grow(buffer& buf, size_t); - - public: - FMT_API ostream(ostream&& other) noexcept; - FMT_API ~ostream(); - - operator writer() { - detail::buffer& buf = *this; - return buf; - } - - inline void flush() { - if (size() == 0) return; - file_.write(data(), size() * sizeof(data()[0])); - clear(); - } - - template - friend auto output_file(cstring_view path, T... params) -> ostream; - - inline void close() { - flush(); - file_.close(); - } - - /// Formats `args` according to specifications in `fmt` and writes the - /// output to the file. - template void print(format_string fmt, T&&... args) { - vformat_to(appender(*this), fmt.str, vargs{{args...}}); - } -}; - -/** - * Opens a file for writing. Supported parameters passed in `params`: - * - * - ``: Flags passed to [open]( - * https://pubs.opengroup.org/onlinepubs/007904875/functions/open.html) - * (`file::WRONLY | file::CREATE | file::TRUNC` by default) - * - `buffer_size=`: Output buffer size - * - * **Example**: - * - * auto out = fmt::output_file("guide.txt"); - * out.print("Don't {}", "Panic"); - */ -template -inline auto output_file(cstring_view path, T... params) -> ostream { - return {path, detail::ostream_params(params...)}; -} -#endif // FMT_USE_FCNTL - -FMT_END_EXPORT -FMT_END_NAMESPACE - -#endif // FMT_OS_H_ diff --git a/include/libs/spdlog/fmt/bundled/ostream.h b/include/libs/spdlog/fmt/bundled/ostream.h deleted file mode 100644 index bf2371b..0000000 --- a/include/libs/spdlog/fmt/bundled/ostream.h +++ /dev/null @@ -1,167 +0,0 @@ -// Formatting library for C++ - std::ostream support -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_OSTREAM_H_ -#define FMT_OSTREAM_H_ - -#ifndef FMT_MODULE -# include // std::filebuf -#endif - -#ifdef _WIN32 -# ifdef __GLIBCXX__ -# include -# include -# endif -# include -#endif - -#include "chrono.h" // formatbuf - -#ifdef _MSVC_STL_UPDATE -# define FMT_MSVC_STL_UPDATE _MSVC_STL_UPDATE -#elif defined(_MSC_VER) && _MSC_VER < 1912 // VS 15.5 -# define FMT_MSVC_STL_UPDATE _MSVC_LANG -#else -# define FMT_MSVC_STL_UPDATE 0 -#endif - -FMT_BEGIN_NAMESPACE -namespace detail { - -// Generate a unique explicit instantiation in every translation unit using a -// tag type in an anonymous namespace. -namespace { -struct file_access_tag {}; -} // namespace -template -class file_access { - friend auto get_file(BufType& obj) -> FILE* { return obj.*FileMemberPtr; } -}; - -#if FMT_MSVC_STL_UPDATE -template class file_access; -auto get_file(std::filebuf&) -> FILE*; -#endif - -// Write the content of buf to os. -// It is a separate function rather than a part of vprint to simplify testing. -template -void write_buffer(std::basic_ostream& os, buffer& buf) { - const Char* buf_data = buf.data(); - using unsigned_streamsize = make_unsigned_t; - unsigned_streamsize size = buf.size(); - unsigned_streamsize max_size = to_unsigned(max_value()); - do { - unsigned_streamsize n = size <= max_size ? size : max_size; - os.write(buf_data, static_cast(n)); - buf_data += n; - size -= n; - } while (size != 0); -} - -template struct streamed_view { - const T& value; -}; -} // namespace detail - -// Formats an object of type T that has an overloaded ostream operator<<. -template -struct basic_ostream_formatter : formatter, Char> { - void set_debug_format() = delete; - - template - auto format(const T& value, Context& ctx) const -> decltype(ctx.out()) { - auto buffer = basic_memory_buffer(); - auto&& formatbuf = detail::formatbuf>(buffer); - auto&& output = std::basic_ostream(&formatbuf); - output.imbue(std::locale::classic()); // The default is always unlocalized. - output << value; - output.exceptions(std::ios_base::failbit | std::ios_base::badbit); - return formatter, Char>::format( - {buffer.data(), buffer.size()}, ctx); - } -}; - -using ostream_formatter = basic_ostream_formatter; - -template -struct formatter, Char> - : basic_ostream_formatter { - template - auto format(detail::streamed_view view, Context& ctx) const - -> decltype(ctx.out()) { - return basic_ostream_formatter::format(view.value, ctx); - } -}; - -/** - * Returns a view that formats `value` via an ostream `operator<<`. - * - * **Example**: - * - * fmt::print("Current thread id: {}\n", - * fmt::streamed(std::this_thread::get_id())); - */ -template -constexpr auto streamed(const T& value) -> detail::streamed_view { - return {value}; -} - -inline void vprint(std::ostream& os, string_view fmt, format_args args) { - auto buffer = memory_buffer(); - detail::vformat_to(buffer, fmt, args); - FILE* f = nullptr; -#if FMT_MSVC_STL_UPDATE && FMT_USE_RTTI - if (auto* buf = dynamic_cast(os.rdbuf())) - f = detail::get_file(*buf); -#elif defined(_WIN32) && defined(__GLIBCXX__) && FMT_USE_RTTI - auto* rdbuf = os.rdbuf(); - if (auto* sfbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf*>(rdbuf)) - f = sfbuf->file(); - else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf*>(rdbuf)) - f = fbuf->file(); -#endif -#ifdef _WIN32 - if (f) { - int fd = _fileno(f); - if (_isatty(fd)) { - os.flush(); - if (detail::write_console(fd, {buffer.data(), buffer.size()})) return; - } - } -#endif - detail::ignore_unused(f); - detail::write_buffer(os, buffer); -} - -/** - * Prints formatted data to the stream `os`. - * - * **Example**: - * - * fmt::print(cerr, "Don't {}!", "panic"); - */ -FMT_EXPORT template -void print(std::ostream& os, format_string fmt, T&&... args) { - fmt::vargs vargs = {{args...}}; - if (detail::const_check(detail::use_utf8)) return vprint(os, fmt.str, vargs); - auto buffer = memory_buffer(); - detail::vformat_to(buffer, fmt.str, vargs); - detail::write_buffer(os, buffer); -} - -FMT_EXPORT template -void println(std::ostream& os, format_string fmt, T&&... args) { - fmt::print(os, FMT_STRING("{}\n"), - fmt::format(fmt, std::forward(args)...)); -} - -FMT_END_NAMESPACE - -#endif // FMT_OSTREAM_H_ diff --git a/include/libs/spdlog/fmt/bundled/printf.h b/include/libs/spdlog/fmt/bundled/printf.h deleted file mode 100644 index cc066d8..0000000 --- a/include/libs/spdlog/fmt/bundled/printf.h +++ /dev/null @@ -1,624 +0,0 @@ -// Formatting library for C++ - legacy printf implementation -// -// Copyright (c) 2012 - 2016, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_PRINTF_H_ -#define FMT_PRINTF_H_ - -#ifndef FMT_MODULE -# include // std::find -# include // std::numeric_limits -#endif - -#include "format.h" - -FMT_BEGIN_NAMESPACE -FMT_BEGIN_EXPORT - -template class basic_printf_context { - private: - basic_appender out_; - basic_format_args args_; - - static_assert(std::is_same::value || - std::is_same::value, - "Unsupported code unit type."); - - public: - using char_type = Char; - enum { builtin_types = 1 }; - - /// Constructs a `printf_context` object. References to the arguments are - /// stored in the context object so make sure they have appropriate lifetimes. - basic_printf_context(basic_appender out, - basic_format_args args) - : out_(out), args_(args) {} - - auto out() -> basic_appender { return out_; } - void advance_to(basic_appender) {} - - auto locale() -> locale_ref { return {}; } - - auto arg(int id) const -> basic_format_arg { - return args_.get(id); - } -}; - -namespace detail { - -// Return the result via the out param to workaround gcc bug 77539. -template -FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr& out) -> bool { - for (out = first; out != last; ++out) { - if (*out == value) return true; - } - return false; -} - -template <> -inline auto find(const char* first, const char* last, char value, - const char*& out) -> bool { - out = - static_cast(memchr(first, value, to_unsigned(last - first))); - return out != nullptr; -} - -// Checks if a value fits in int - used to avoid warnings about comparing -// signed and unsigned integers. -template struct int_checker { - template static auto fits_in_int(T value) -> bool { - return value <= to_unsigned(max_value()); - } - inline static auto fits_in_int(bool) -> bool { return true; } -}; - -template <> struct int_checker { - template static auto fits_in_int(T value) -> bool { - return value >= (std::numeric_limits::min)() && - value <= max_value(); - } - inline static auto fits_in_int(int) -> bool { return true; } -}; - -struct printf_precision_handler { - template ::value)> - auto operator()(T value) -> int { - if (!int_checker::is_signed>::fits_in_int(value)) - report_error("number is too big"); - return max_of(static_cast(value), 0); - } - - template ::value)> - auto operator()(T) -> int { - report_error("precision is not integer"); - return 0; - } -}; - -// An argument visitor that returns true iff arg is a zero integer. -struct is_zero_int { - template ::value)> - auto operator()(T value) -> bool { - return value == 0; - } - - template ::value)> - auto operator()(T) -> bool { - return false; - } -}; - -template struct make_unsigned_or_bool : std::make_unsigned {}; - -template <> struct make_unsigned_or_bool { - using type = bool; -}; - -template class arg_converter { - private: - using char_type = typename Context::char_type; - - basic_format_arg& arg_; - char_type type_; - - public: - arg_converter(basic_format_arg& arg, char_type type) - : arg_(arg), type_(type) {} - - void operator()(bool value) { - if (type_ != 's') operator()(value); - } - - template ::value)> - void operator()(U value) { - bool is_signed = type_ == 'd' || type_ == 'i'; - using target_type = conditional_t::value, U, T>; - if (const_check(sizeof(target_type) <= sizeof(int))) { - // Extra casts are used to silence warnings. - using unsigned_type = typename make_unsigned_or_bool::type; - if (is_signed) - arg_ = static_cast(static_cast(value)); - else - arg_ = static_cast(static_cast(value)); - } else { - // glibc's printf doesn't sign extend arguments of smaller types: - // std::printf("%lld", -42); // prints "4294967254" - // but we don't have to do the same because it's a UB. - if (is_signed) - arg_ = static_cast(value); - else - arg_ = static_cast::type>(value); - } - } - - template ::value)> - void operator()(U) {} // No conversion needed for non-integral types. -}; - -// Converts an integer argument to T for printf, if T is an integral type. -// If T is void, the argument is converted to corresponding signed or unsigned -// type depending on the type specifier: 'd' and 'i' - signed, other - -// unsigned). -template -void convert_arg(basic_format_arg& arg, Char type) { - arg.visit(arg_converter(arg, type)); -} - -// Converts an integer argument to char for printf. -template class char_converter { - private: - basic_format_arg& arg_; - - public: - explicit char_converter(basic_format_arg& arg) : arg_(arg) {} - - template ::value)> - void operator()(T value) { - arg_ = static_cast(value); - } - - template ::value)> - void operator()(T) {} // No conversion needed for non-integral types. -}; - -// An argument visitor that return a pointer to a C string if argument is a -// string or null otherwise. -template struct get_cstring { - template auto operator()(T) -> const Char* { return nullptr; } - auto operator()(const Char* s) -> const Char* { return s; } -}; - -// Checks if an argument is a valid printf width specifier and sets -// left alignment if it is negative. -class printf_width_handler { - private: - format_specs& specs_; - - public: - inline explicit printf_width_handler(format_specs& specs) : specs_(specs) {} - - template ::value)> - auto operator()(T value) -> unsigned { - auto width = static_cast>(value); - if (detail::is_negative(value)) { - specs_.set_align(align::left); - width = 0 - width; - } - unsigned int_max = to_unsigned(max_value()); - if (width > int_max) report_error("number is too big"); - return static_cast(width); - } - - template ::value)> - auto operator()(T) -> unsigned { - report_error("width is not integer"); - return 0; - } -}; - -// Workaround for a bug with the XL compiler when initializing -// printf_arg_formatter's base class. -template -auto make_arg_formatter(basic_appender iter, format_specs& s) - -> arg_formatter { - return {iter, s, locale_ref()}; -} - -// The `printf` argument formatter. -template -class printf_arg_formatter : public arg_formatter { - private: - using base = arg_formatter; - using context_type = basic_printf_context; - - context_type& context_; - - void write_null_pointer(bool is_string = false) { - auto s = this->specs; - s.set_type(presentation_type::none); - write_bytes(this->out, is_string ? "(null)" : "(nil)", s); - } - - template void write(T value) { - detail::write(this->out, value, this->specs, this->locale); - } - - public: - printf_arg_formatter(basic_appender iter, format_specs& s, - context_type& ctx) - : base(make_arg_formatter(iter, s)), context_(ctx) {} - - void operator()(monostate value) { write(value); } - - template ::value)> - void operator()(T value) { - // MSVC2013 fails to compile separate overloads for bool and Char so use - // std::is_same instead. - if (!std::is_same::value) { - write(value); - return; - } - format_specs s = this->specs; - if (s.type() != presentation_type::none && - s.type() != presentation_type::chr) { - return (*this)(static_cast(value)); - } - s.set_sign(sign::none); - s.clear_alt(); - s.set_fill(' '); // Ignore '0' flag for char types. - // align::numeric needs to be overwritten here since the '0' flag is - // ignored for non-numeric types - if (s.align() == align::none || s.align() == align::numeric) - s.set_align(align::right); - detail::write(this->out, static_cast(value), s); - } - - template ::value)> - void operator()(T value) { - write(value); - } - - void operator()(const char* value) { - if (value) - write(value); - else - write_null_pointer(this->specs.type() != presentation_type::pointer); - } - - void operator()(const wchar_t* value) { - if (value) - write(value); - else - write_null_pointer(this->specs.type() != presentation_type::pointer); - } - - void operator()(basic_string_view value) { write(value); } - - void operator()(const void* value) { - if (value) - write(value); - else - write_null_pointer(); - } - - void operator()(typename basic_format_arg::handle handle) { - auto parse_ctx = parse_context({}); - handle.format(parse_ctx, context_); - } -}; - -template -void parse_flags(format_specs& specs, const Char*& it, const Char* end) { - for (; it != end; ++it) { - switch (*it) { - case '-': specs.set_align(align::left); break; - case '+': specs.set_sign(sign::plus); break; - case '0': specs.set_fill('0'); break; - case ' ': - if (specs.sign() != sign::plus) specs.set_sign(sign::space); - break; - case '#': specs.set_alt(); break; - default: return; - } - } -} - -template -auto parse_header(const Char*& it, const Char* end, format_specs& specs, - GetArg get_arg) -> int { - int arg_index = -1; - Char c = *it; - if (c >= '0' && c <= '9') { - // Parse an argument index (if followed by '$') or a width possibly - // preceded with '0' flag(s). - int value = parse_nonnegative_int(it, end, -1); - if (it != end && *it == '$') { // value is an argument index - ++it; - arg_index = value != -1 ? value : max_value(); - } else { - if (c == '0') specs.set_fill('0'); - if (value != 0) { - // Nonzero value means that we parsed width and don't need to - // parse it or flags again, so return now. - if (value == -1) report_error("number is too big"); - specs.width = value; - return arg_index; - } - } - } - parse_flags(specs, it, end); - // Parse width. - if (it != end) { - if (*it >= '0' && *it <= '9') { - specs.width = parse_nonnegative_int(it, end, -1); - if (specs.width == -1) report_error("number is too big"); - } else if (*it == '*') { - ++it; - specs.width = static_cast( - get_arg(-1).visit(detail::printf_width_handler(specs))); - } - } - return arg_index; -} - -inline auto parse_printf_presentation_type(char c, type t, bool& upper) - -> presentation_type { - using pt = presentation_type; - constexpr auto integral_set = sint_set | uint_set | bool_set | char_set; - switch (c) { - case 'd': return in(t, integral_set) ? pt::dec : pt::none; - case 'o': return in(t, integral_set) ? pt::oct : pt::none; - case 'X': upper = true; FMT_FALLTHROUGH; - case 'x': return in(t, integral_set) ? pt::hex : pt::none; - case 'E': upper = true; FMT_FALLTHROUGH; - case 'e': return in(t, float_set) ? pt::exp : pt::none; - case 'F': upper = true; FMT_FALLTHROUGH; - case 'f': return in(t, float_set) ? pt::fixed : pt::none; - case 'G': upper = true; FMT_FALLTHROUGH; - case 'g': return in(t, float_set) ? pt::general : pt::none; - case 'A': upper = true; FMT_FALLTHROUGH; - case 'a': return in(t, float_set) ? pt::hexfloat : pt::none; - case 'c': return in(t, integral_set) ? pt::chr : pt::none; - case 's': return in(t, string_set | cstring_set) ? pt::string : pt::none; - case 'p': return in(t, pointer_set | cstring_set) ? pt::pointer : pt::none; - default: return pt::none; - } -} - -template -void vprintf(buffer& buf, basic_string_view format, - basic_format_args args) { - using iterator = basic_appender; - auto out = iterator(buf); - auto context = basic_printf_context(out, args); - auto parse_ctx = parse_context(format); - - // Returns the argument with specified index or, if arg_index is -1, the next - // argument. - auto get_arg = [&](int arg_index) { - if (arg_index < 0) - arg_index = parse_ctx.next_arg_id(); - else - parse_ctx.check_arg_id(--arg_index); - auto arg = context.arg(arg_index); - if (!arg) report_error("argument not found"); - return arg; - }; - - const Char* start = parse_ctx.begin(); - const Char* end = parse_ctx.end(); - auto it = start; - while (it != end) { - if (!find(it, end, '%', it)) { - it = end; // find leaves it == nullptr if it doesn't find '%'. - break; - } - Char c = *it++; - if (it != end && *it == c) { - write(out, basic_string_view(start, to_unsigned(it - start))); - start = ++it; - continue; - } - write(out, basic_string_view(start, to_unsigned(it - 1 - start))); - - auto specs = format_specs(); - specs.set_align(align::right); - - // Parse argument index, flags and width. - int arg_index = parse_header(it, end, specs, get_arg); - if (arg_index == 0) report_error("argument not found"); - - // Parse precision. - if (it != end && *it == '.') { - ++it; - c = it != end ? *it : 0; - if ('0' <= c && c <= '9') { - specs.precision = parse_nonnegative_int(it, end, 0); - } else if (c == '*') { - ++it; - specs.precision = - static_cast(get_arg(-1).visit(printf_precision_handler())); - } else { - specs.precision = 0; - } - } - - auto arg = get_arg(arg_index); - // For d, i, o, u, x, and X conversion specifiers, if a precision is - // specified, the '0' flag is ignored - if (specs.precision >= 0 && is_integral_type(arg.type())) { - // Ignore '0' for non-numeric types or if '-' present. - specs.set_fill(' '); - } - if (specs.precision >= 0 && arg.type() == type::cstring_type) { - auto str = arg.visit(get_cstring()); - auto str_end = str + specs.precision; - auto nul = std::find(str, str_end, Char()); - auto sv = basic_string_view( - str, to_unsigned(nul != str_end ? nul - str : specs.precision)); - arg = sv; - } - if (specs.alt() && arg.visit(is_zero_int())) specs.clear_alt(); - if (specs.fill_unit() == '0') { - if (is_arithmetic_type(arg.type()) && specs.align() != align::left) { - specs.set_align(align::numeric); - } else { - // Ignore '0' flag for non-numeric types or if '-' flag is also present. - specs.set_fill(' '); - } - } - - // Parse length and convert the argument to the required type. - c = it != end ? *it++ : 0; - Char t = it != end ? *it : 0; - switch (c) { - case 'h': - if (t == 'h') { - ++it; - t = it != end ? *it : 0; - convert_arg(arg, t); - } else { - convert_arg(arg, t); - } - break; - case 'l': - if (t == 'l') { - ++it; - t = it != end ? *it : 0; - convert_arg(arg, t); - } else { - convert_arg(arg, t); - } - break; - case 'j': convert_arg(arg, t); break; - case 'z': convert_arg(arg, t); break; - case 't': convert_arg(arg, t); break; - case 'L': - // printf produces garbage when 'L' is omitted for long double, no - // need to do the same. - break; - default: --it; convert_arg(arg, c); - } - - // Parse type. - if (it == end) report_error("invalid format string"); - char type = static_cast(*it++); - if (is_integral_type(arg.type())) { - // Normalize type. - switch (type) { - case 'i': - case 'u': type = 'd'; break; - case 'c': - arg.visit(char_converter>(arg)); - break; - } - } - bool upper = false; - specs.set_type(parse_printf_presentation_type(type, arg.type(), upper)); - if (specs.type() == presentation_type::none) - report_error("invalid format specifier"); - if (upper) specs.set_upper(); - - start = it; - - // Format argument. - arg.visit(printf_arg_formatter(out, specs, context)); - } - write(out, basic_string_view(start, to_unsigned(it - start))); -} -} // namespace detail - -using printf_context = basic_printf_context; -using wprintf_context = basic_printf_context; - -using printf_args = basic_format_args; -using wprintf_args = basic_format_args; - -/// Constructs an `format_arg_store` object that contains references to -/// arguments and can be implicitly converted to `printf_args`. -template -inline auto make_printf_args(T&... args) - -> decltype(fmt::make_format_args>(args...)) { - return fmt::make_format_args>(args...); -} - -template struct vprintf_args { - using type = basic_format_args>; -}; - -template -inline auto vsprintf(basic_string_view fmt, - typename vprintf_args::type args) - -> std::basic_string { - auto buf = basic_memory_buffer(); - detail::vprintf(buf, fmt, args); - return {buf.data(), buf.size()}; -} - -/** - * Formats `args` according to specifications in `fmt` and returns the result - * as as string. - * - * **Example**: - * - * std::string message = fmt::sprintf("The answer is %d", 42); - */ -template -inline auto sprintf(string_view fmt, const T&... args) -> std::string { - return vsprintf(fmt, make_printf_args(args...)); -} -template -FMT_DEPRECATED auto sprintf(basic_string_view fmt, const T&... args) - -> std::wstring { - return vsprintf(fmt, make_printf_args(args...)); -} - -template -auto vfprintf(std::FILE* f, basic_string_view fmt, - typename vprintf_args::type args) -> int { - auto buf = basic_memory_buffer(); - detail::vprintf(buf, fmt, args); - size_t size = buf.size(); - return std::fwrite(buf.data(), sizeof(Char), size, f) < size - ? -1 - : static_cast(size); -} - -/** - * Formats `args` according to specifications in `fmt` and writes the output - * to `f`. - * - * **Example**: - * - * fmt::fprintf(stderr, "Don't %s!", "panic"); - */ -template -inline auto fprintf(std::FILE* f, string_view fmt, const T&... args) -> int { - return vfprintf(f, fmt, make_printf_args(args...)); -} -template -FMT_DEPRECATED auto fprintf(std::FILE* f, basic_string_view fmt, - const T&... args) -> int { - return vfprintf(f, fmt, make_printf_args(args...)); -} - -/** - * Formats `args` according to specifications in `fmt` and writes the output - * to `stdout`. - * - * **Example**: - * - * fmt::printf("Elapsed time: %.2f seconds", 1.23); - */ -template -inline auto printf(string_view fmt, const T&... args) -> int { - return vfprintf(stdout, fmt, make_printf_args(args...)); -} - -FMT_END_EXPORT -FMT_END_NAMESPACE - -#endif // FMT_PRINTF_H_ diff --git a/include/libs/spdlog/fmt/bundled/ranges.h b/include/libs/spdlog/fmt/bundled/ranges.h deleted file mode 100644 index 36b38e2..0000000 --- a/include/libs/spdlog/fmt/bundled/ranges.h +++ /dev/null @@ -1,851 +0,0 @@ -// Formatting library for C++ - range and tuple support -// -// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_RANGES_H_ -#define FMT_RANGES_H_ - -#ifndef FMT_MODULE -# include -# include -# include -# include -# include -#endif - -#include "format.h" - -#if FMT_HAS_CPP_ATTRIBUTE(clang::lifetimebound) -# define FMT_LIFETIMEBOUND [[clang::lifetimebound]] -#else -# define FMT_LIFETIMEBOUND -#endif -FMT_PRAGMA_CLANG(diagnostic error "-Wreturn-stack-address") - -FMT_BEGIN_NAMESPACE - -FMT_EXPORT -enum class range_format { disabled, map, set, sequence, string, debug_string }; - -namespace detail { - -template class is_map { - template static auto check(U*) -> typename U::mapped_type; - template static void check(...); - - public: - static constexpr bool value = - !std::is_void(nullptr))>::value; -}; - -template class is_set { - template static auto check(U*) -> typename U::key_type; - template static void check(...); - - public: - static constexpr bool value = - !std::is_void(nullptr))>::value && !is_map::value; -}; - -// C array overload -template -auto range_begin(const T (&arr)[N]) -> const T* { - return arr; -} -template auto range_end(const T (&arr)[N]) -> const T* { - return arr + N; -} - -template -struct has_member_fn_begin_end_t : std::false_type {}; - -template -struct has_member_fn_begin_end_t().begin()), - decltype(std::declval().end())>> - : std::true_type {}; - -// Member function overloads. -template -auto range_begin(T&& rng) -> decltype(static_cast(rng).begin()) { - return static_cast(rng).begin(); -} -template -auto range_end(T&& rng) -> decltype(static_cast(rng).end()) { - return static_cast(rng).end(); -} - -// ADL overloads. Only participate in overload resolution if member functions -// are not found. -template -auto range_begin(T&& rng) - -> enable_if_t::value, - decltype(begin(static_cast(rng)))> { - return begin(static_cast(rng)); -} -template -auto range_end(T&& rng) -> enable_if_t::value, - decltype(end(static_cast(rng)))> { - return end(static_cast(rng)); -} - -template -struct has_const_begin_end : std::false_type {}; -template -struct has_mutable_begin_end : std::false_type {}; - -template -struct has_const_begin_end< - T, void_t&>())), - decltype(detail::range_end( - std::declval&>()))>> - : std::true_type {}; - -template -struct has_mutable_begin_end< - T, void_t())), - decltype(detail::range_end(std::declval())), - // the extra int here is because older versions of MSVC don't - // SFINAE properly unless there are distinct types - int>> : std::true_type {}; - -template struct is_range_ : std::false_type {}; -template -struct is_range_ - : std::integral_constant::value || - has_mutable_begin_end::value)> {}; - -// tuple_size and tuple_element check. -template class is_tuple_like_ { - template ::type> - static auto check(U* p) -> decltype(std::tuple_size::value, 0); - template static void check(...); - - public: - static constexpr bool value = - !std::is_void(nullptr))>::value; -}; - -// Check for integer_sequence -#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VERSION >= 1900 -template -using integer_sequence = std::integer_sequence; -template using index_sequence = std::index_sequence; -template using make_index_sequence = std::make_index_sequence; -#else -template struct integer_sequence { - using value_type = T; - - static FMT_CONSTEXPR auto size() -> size_t { return sizeof...(N); } -}; - -template using index_sequence = integer_sequence; - -template -struct make_integer_sequence : make_integer_sequence {}; -template -struct make_integer_sequence : integer_sequence {}; - -template -using make_index_sequence = make_integer_sequence; -#endif - -template -using tuple_index_sequence = make_index_sequence::value>; - -template ::value> -class is_tuple_formattable_ { - public: - static constexpr bool value = false; -}; -template class is_tuple_formattable_ { - template - static auto all_true(index_sequence, - integer_sequence= 0)...>) -> std::true_type; - static auto all_true(...) -> std::false_type; - - template - static auto check(index_sequence) -> decltype(all_true( - index_sequence{}, - integer_sequence::type, - C>::value)...>{})); - - public: - static constexpr bool value = - decltype(check(tuple_index_sequence{}))::value; -}; - -template -FMT_CONSTEXPR void for_each(index_sequence, Tuple&& t, F&& f) { - using std::get; - // Using a free function get(Tuple) now. - const int unused[] = {0, ((void)f(get(t)), 0)...}; - ignore_unused(unused); -} - -template -FMT_CONSTEXPR void for_each(Tuple&& t, F&& f) { - for_each(tuple_index_sequence>(), - std::forward(t), std::forward(f)); -} - -template -void for_each2(index_sequence, Tuple1&& t1, Tuple2&& t2, F&& f) { - using std::get; - const int unused[] = {0, ((void)f(get(t1), get(t2)), 0)...}; - ignore_unused(unused); -} - -template -void for_each2(Tuple1&& t1, Tuple2&& t2, F&& f) { - for_each2(tuple_index_sequence>(), - std::forward(t1), std::forward(t2), - std::forward(f)); -} - -namespace tuple { -// Workaround a bug in MSVC 2019 (v140). -template -using result_t = std::tuple, Char>...>; - -using std::get; -template -auto get_formatters(index_sequence) - -> result_t(std::declval()))...>; -} // namespace tuple - -#if FMT_MSC_VERSION && FMT_MSC_VERSION < 1920 -// Older MSVC doesn't get the reference type correctly for arrays. -template struct range_reference_type_impl { - using type = decltype(*detail::range_begin(std::declval())); -}; - -template struct range_reference_type_impl { - using type = T&; -}; - -template -using range_reference_type = typename range_reference_type_impl::type; -#else -template -using range_reference_type = - decltype(*detail::range_begin(std::declval())); -#endif - -// We don't use the Range's value_type for anything, but we do need the Range's -// reference type, with cv-ref stripped. -template -using uncvref_type = remove_cvref_t>; - -template -struct range_format_kind_ - : std::integral_constant, T>::value - ? range_format::disabled - : is_map::value ? range_format::map - : is_set::value ? range_format::set - : range_format::sequence> {}; - -template -using range_format_constant = std::integral_constant; - -// These are not generic lambdas for compatibility with C++11. -template struct parse_empty_specs { - template FMT_CONSTEXPR void operator()(Formatter& f) { - f.parse(ctx); - detail::maybe_set_debug_format(f, true); - } - parse_context& ctx; -}; -template struct format_tuple_element { - using char_type = typename FormatContext::char_type; - - template - void operator()(const formatter& f, const T& v) { - if (i > 0) ctx.advance_to(detail::copy(separator, ctx.out())); - ctx.advance_to(f.format(v, ctx)); - ++i; - } - - int i; - FormatContext& ctx; - basic_string_view separator; -}; - -} // namespace detail - -FMT_EXPORT -template struct is_tuple_like { - static constexpr bool value = - detail::is_tuple_like_::value && !detail::is_range_::value; -}; - -FMT_EXPORT -template struct is_tuple_formattable { - static constexpr bool value = detail::is_tuple_formattable_::value; -}; - -template -struct formatter::value && - fmt::is_tuple_formattable::value>> { - private: - decltype(detail::tuple::get_formatters( - detail::tuple_index_sequence())) formatters_; - - basic_string_view separator_ = detail::string_literal{}; - basic_string_view opening_bracket_ = - detail::string_literal{}; - basic_string_view closing_bracket_ = - detail::string_literal{}; - - public: - FMT_CONSTEXPR formatter() {} - - FMT_CONSTEXPR void set_separator(basic_string_view sep) { - separator_ = sep; - } - - FMT_CONSTEXPR void set_brackets(basic_string_view open, - basic_string_view close) { - opening_bracket_ = open; - closing_bracket_ = close; - } - - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - auto it = ctx.begin(); - auto end = ctx.end(); - if (it != end && detail::to_ascii(*it) == 'n') { - ++it; - set_brackets({}, {}); - set_separator({}); - } - if (it != end && *it != '}') report_error("invalid format specifier"); - ctx.advance_to(it); - detail::for_each(formatters_, detail::parse_empty_specs{ctx}); - return it; - } - - template - auto format(const Tuple& value, FormatContext& ctx) const - -> decltype(ctx.out()) { - ctx.advance_to(detail::copy(opening_bracket_, ctx.out())); - detail::for_each2( - formatters_, value, - detail::format_tuple_element{0, ctx, separator_}); - return detail::copy(closing_bracket_, ctx.out()); - } -}; - -FMT_EXPORT -template struct is_range { - static constexpr bool value = - detail::is_range_::value && !detail::has_to_string_view::value; -}; - -namespace detail { - -template -using range_formatter_type = formatter, Char>; - -template -using maybe_const_range = - conditional_t::value, const R, R>; - -template -struct is_formattable_delayed - : is_formattable>, Char> {}; -} // namespace detail - -template struct conjunction : std::true_type {}; -template struct conjunction

: P {}; -template -struct conjunction - : conditional_t, P1> {}; - -FMT_EXPORT -template -struct range_formatter; - -template -struct range_formatter< - T, Char, - enable_if_t>, - is_formattable>::value>> { - private: - detail::range_formatter_type underlying_; - basic_string_view separator_ = detail::string_literal{}; - basic_string_view opening_bracket_ = - detail::string_literal{}; - basic_string_view closing_bracket_ = - detail::string_literal{}; - bool is_debug = false; - - template ::value)> - auto write_debug_string(Output& out, It it, Sentinel end) const -> Output { - auto buf = basic_memory_buffer(); - for (; it != end; ++it) buf.push_back(*it); - auto specs = format_specs(); - specs.set_type(presentation_type::debug); - return detail::write( - out, basic_string_view(buf.data(), buf.size()), specs); - } - - template ::value)> - auto write_debug_string(Output& out, It, Sentinel) const -> Output { - return out; - } - - public: - FMT_CONSTEXPR range_formatter() {} - - FMT_CONSTEXPR auto underlying() -> detail::range_formatter_type& { - return underlying_; - } - - FMT_CONSTEXPR void set_separator(basic_string_view sep) { - separator_ = sep; - } - - FMT_CONSTEXPR void set_brackets(basic_string_view open, - basic_string_view close) { - opening_bracket_ = open; - closing_bracket_ = close; - } - - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - auto it = ctx.begin(); - auto end = ctx.end(); - detail::maybe_set_debug_format(underlying_, true); - if (it == end) return underlying_.parse(ctx); - - switch (detail::to_ascii(*it)) { - case 'n': - set_brackets({}, {}); - ++it; - break; - case '?': - is_debug = true; - set_brackets({}, {}); - ++it; - if (it == end || *it != 's') report_error("invalid format specifier"); - FMT_FALLTHROUGH; - case 's': - if (!std::is_same::value) - report_error("invalid format specifier"); - if (!is_debug) { - set_brackets(detail::string_literal{}, - detail::string_literal{}); - set_separator({}); - detail::maybe_set_debug_format(underlying_, false); - } - ++it; - return it; - } - - if (it != end && *it != '}') { - if (*it != ':') report_error("invalid format specifier"); - detail::maybe_set_debug_format(underlying_, false); - ++it; - } - - ctx.advance_to(it); - return underlying_.parse(ctx); - } - - template - auto format(R&& range, FormatContext& ctx) const -> decltype(ctx.out()) { - auto out = ctx.out(); - auto it = detail::range_begin(range); - auto end = detail::range_end(range); - if (is_debug) return write_debug_string(out, std::move(it), end); - - out = detail::copy(opening_bracket_, out); - int i = 0; - for (; it != end; ++it) { - if (i > 0) out = detail::copy(separator_, out); - ctx.advance_to(out); - auto&& item = *it; // Need an lvalue - out = underlying_.format(item, ctx); - ++i; - } - out = detail::copy(closing_bracket_, out); - return out; - } -}; - -FMT_EXPORT -template -struct range_format_kind - : conditional_t< - is_range::value, detail::range_format_kind_, - std::integral_constant> {}; - -template -struct formatter< - R, Char, - enable_if_t::value != range_format::disabled && - range_format_kind::value != range_format::map && - range_format_kind::value != range_format::string && - range_format_kind::value != range_format::debug_string>, - detail::is_formattable_delayed>::value>> { - private: - using range_type = detail::maybe_const_range; - range_formatter, Char> range_formatter_; - - public: - using nonlocking = void; - - FMT_CONSTEXPR formatter() { - if (detail::const_check(range_format_kind::value != - range_format::set)) - return; - range_formatter_.set_brackets(detail::string_literal{}, - detail::string_literal{}); - } - - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - return range_formatter_.parse(ctx); - } - - template - auto format(range_type& range, FormatContext& ctx) const - -> decltype(ctx.out()) { - return range_formatter_.format(range, ctx); - } -}; - -// A map formatter. -template -struct formatter< - R, Char, - enable_if_t::value == range_format::map>, - detail::is_formattable_delayed>::value>> { - private: - using map_type = detail::maybe_const_range; - using element_type = detail::uncvref_type; - - decltype(detail::tuple::get_formatters( - detail::tuple_index_sequence())) formatters_; - bool no_delimiters_ = false; - - public: - FMT_CONSTEXPR formatter() {} - - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - auto it = ctx.begin(); - auto end = ctx.end(); - if (it != end) { - if (detail::to_ascii(*it) == 'n') { - no_delimiters_ = true; - ++it; - } - if (it != end && *it != '}') { - if (*it != ':') report_error("invalid format specifier"); - ++it; - } - ctx.advance_to(it); - } - detail::for_each(formatters_, detail::parse_empty_specs{ctx}); - return it; - } - - template - auto format(map_type& map, FormatContext& ctx) const -> decltype(ctx.out()) { - auto out = ctx.out(); - basic_string_view open = detail::string_literal{}; - if (!no_delimiters_) out = detail::copy(open, out); - int i = 0; - basic_string_view sep = detail::string_literal{}; - for (auto&& value : map) { - if (i > 0) out = detail::copy(sep, out); - ctx.advance_to(out); - detail::for_each2(formatters_, value, - detail::format_tuple_element{ - 0, ctx, detail::string_literal{}}); - ++i; - } - basic_string_view close = detail::string_literal{}; - if (!no_delimiters_) out = detail::copy(close, out); - return out; - } -}; - -// A (debug_)string formatter. -template -struct formatter< - R, Char, - enable_if_t::value == range_format::string || - range_format_kind::value == - range_format::debug_string>> { - private: - using range_type = detail::maybe_const_range; - using string_type = - conditional_t, - decltype(detail::range_begin(std::declval())), - decltype(detail::range_end(std::declval()))>::value, - detail::std_string_view, std::basic_string>; - - formatter underlying_; - - public: - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - return underlying_.parse(ctx); - } - - template - auto format(range_type& range, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto out = ctx.out(); - if (detail::const_check(range_format_kind::value == - range_format::debug_string)) - *out++ = '"'; - out = underlying_.format( - string_type{detail::range_begin(range), detail::range_end(range)}, ctx); - if (detail::const_check(range_format_kind::value == - range_format::debug_string)) - *out++ = '"'; - return out; - } -}; - -template -struct join_view : detail::view { - It begin; - Sentinel end; - basic_string_view sep; - - join_view(It b, Sentinel e, basic_string_view s) - : begin(std::move(b)), end(e), sep(s) {} -}; - -template -struct formatter, Char> { - private: - using value_type = -#ifdef __cpp_lib_ranges - std::iter_value_t; -#else - typename std::iterator_traits::value_type; -#endif - formatter, Char> value_formatter_; - - using view = conditional_t::value, - const join_view, - join_view>; - - public: - using nonlocking = void; - - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - return value_formatter_.parse(ctx); - } - - template - auto format(view& value, FormatContext& ctx) const -> decltype(ctx.out()) { - using iter = - conditional_t::value, It, It&>; - iter it = value.begin; - auto out = ctx.out(); - if (it == value.end) return out; - out = value_formatter_.format(*it, ctx); - ++it; - while (it != value.end) { - out = detail::copy(value.sep.begin(), value.sep.end(), out); - ctx.advance_to(out); - out = value_formatter_.format(*it, ctx); - ++it; - } - return out; - } -}; - -FMT_EXPORT -template struct tuple_join_view : detail::view { - const Tuple& tuple; - basic_string_view sep; - - tuple_join_view(const Tuple& t, basic_string_view s) - : tuple(t), sep{s} {} -}; - -// Define FMT_TUPLE_JOIN_SPECIFIERS to enable experimental format specifiers -// support in tuple_join. It is disabled by default because of issues with -// the dynamic width and precision. -#ifndef FMT_TUPLE_JOIN_SPECIFIERS -# define FMT_TUPLE_JOIN_SPECIFIERS 0 -#endif - -template -struct formatter, Char, - enable_if_t::value>> { - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - return do_parse(ctx, std::tuple_size()); - } - - template - auto format(const tuple_join_view& value, - FormatContext& ctx) const -> typename FormatContext::iterator { - return do_format(value, ctx, std::tuple_size()); - } - - private: - decltype(detail::tuple::get_formatters( - detail::tuple_index_sequence())) formatters_; - - FMT_CONSTEXPR auto do_parse(parse_context& ctx, - std::integral_constant) - -> const Char* { - return ctx.begin(); - } - - template - FMT_CONSTEXPR auto do_parse(parse_context& ctx, - std::integral_constant) - -> const Char* { - auto end = ctx.begin(); -#if FMT_TUPLE_JOIN_SPECIFIERS - end = std::get::value - N>(formatters_).parse(ctx); - if (N > 1) { - auto end1 = do_parse(ctx, std::integral_constant()); - if (end != end1) - report_error("incompatible format specs for tuple elements"); - } -#endif - return end; - } - - template - auto do_format(const tuple_join_view&, FormatContext& ctx, - std::integral_constant) const -> - typename FormatContext::iterator { - return ctx.out(); - } - - template - auto do_format(const tuple_join_view& value, FormatContext& ctx, - std::integral_constant) const -> - typename FormatContext::iterator { - using std::get; - auto out = - std::get::value - N>(formatters_) - .format(get::value - N>(value.tuple), ctx); - if (N <= 1) return out; - out = detail::copy(value.sep, out); - ctx.advance_to(out); - return do_format(value, ctx, std::integral_constant()); - } -}; - -namespace detail { -// Check if T has an interface like a container adaptor (e.g. std::stack, -// std::queue, std::priority_queue). -template class is_container_adaptor_like { - template static auto check(U* p) -> typename U::container_type; - template static void check(...); - - public: - static constexpr bool value = - !std::is_void(nullptr))>::value; -}; - -template struct all { - const Container& c; - auto begin() const -> typename Container::const_iterator { return c.begin(); } - auto end() const -> typename Container::const_iterator { return c.end(); } -}; -} // namespace detail - -template -struct formatter< - T, Char, - enable_if_t, - bool_constant::value == - range_format::disabled>>::value>> - : formatter, Char> { - using all = detail::all; - template - auto format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) { - struct getter : T { - static auto get(const T& v) -> all { - return {v.*(&getter::c)}; // Access c through the derived class. - } - }; - return formatter::format(getter::get(value), ctx); - } -}; - -FMT_BEGIN_EXPORT - -/// Returns a view that formats the iterator range `[begin, end)` with elements -/// separated by `sep`. -template -auto join(It begin, Sentinel end, string_view sep) -> join_view { - return {std::move(begin), end, sep}; -} - -/** - * Returns a view that formats `range` with elements separated by `sep`. - * - * **Example**: - * - * auto v = std::vector{1, 2, 3}; - * fmt::print("{}", fmt::join(v, ", ")); - * // Output: 1, 2, 3 - * - * `fmt::join` applies passed format specifiers to the range elements: - * - * fmt::print("{:02}", fmt::join(v, ", ")); - * // Output: 01, 02, 03 - */ -template ::value)> -auto join(Range&& r, string_view sep) - -> join_view { - return {detail::range_begin(r), detail::range_end(r), sep}; -} - -/** - * Returns an object that formats `std::tuple` with elements separated by `sep`. - * - * **Example**: - * - * auto t = std::tuple(1, 'a'); - * fmt::print("{}", fmt::join(t, ", ")); - * // Output: 1, a - */ -template ::value)> -FMT_CONSTEXPR auto join(const Tuple& tuple FMT_LIFETIMEBOUND, string_view sep) - -> tuple_join_view { - return {tuple, sep}; -} - -/** - * Returns an object that formats `std::initializer_list` with elements - * separated by `sep`. - * - * **Example**: - * - * fmt::print("{}", fmt::join({1, 2, 3}, ", ")); - * // Output: "1, 2, 3" - */ -template -auto join(std::initializer_list list, string_view sep) - -> join_view { - return join(std::begin(list), std::end(list), sep); -} - -FMT_END_EXPORT -FMT_END_NAMESPACE - -#endif // FMT_RANGES_H_ diff --git a/include/libs/spdlog/fmt/bundled/std.h b/include/libs/spdlog/fmt/bundled/std.h deleted file mode 100644 index 184c6d2..0000000 --- a/include/libs/spdlog/fmt/bundled/std.h +++ /dev/null @@ -1,727 +0,0 @@ -// Formatting library for C++ - formatters for standard library types -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_STD_H_ -#define FMT_STD_H_ - -#include "format.h" -#include "ostream.h" - -#ifndef FMT_MODULE -# include -# include -# include -# include -# include // std::reference_wrapper -# include -# include -# include -# include // std::type_info -# include // std::make_index_sequence - -// Check FMT_CPLUSPLUS to suppress a bogus warning in MSVC. -# if FMT_CPLUSPLUS >= 201703L -# if FMT_HAS_INCLUDE() && \ - (!defined(FMT_CPP_LIB_FILESYSTEM) || FMT_CPP_LIB_FILESYSTEM != 0) -# include -# endif -# if FMT_HAS_INCLUDE() -# include -# endif -# if FMT_HAS_INCLUDE() -# include -# endif -# endif -// Use > instead of >= in the version check because may be -// available after C++17 but before C++20 is marked as implemented. -# if FMT_CPLUSPLUS > 201703L && FMT_HAS_INCLUDE() -# include -# endif -# if FMT_CPLUSPLUS > 202002L && FMT_HAS_INCLUDE() -# include -# endif -#endif // FMT_MODULE - -#if FMT_HAS_INCLUDE() -# include -#endif - -// GCC 4 does not support FMT_HAS_INCLUDE. -#if FMT_HAS_INCLUDE() || defined(__GLIBCXX__) -# include -// Android NDK with gabi++ library on some architectures does not implement -// abi::__cxa_demangle(). -# ifndef __GABIXX_CXXABI_H__ -# define FMT_HAS_ABI_CXA_DEMANGLE -# endif -#endif - -#ifdef FMT_CPP_LIB_FILESYSTEM -// Use the provided definition. -#elif defined(__cpp_lib_filesystem) -# define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem -#else -# define FMT_CPP_LIB_FILESYSTEM 0 -#endif - -#ifdef FMT_CPP_LIB_VARIANT -// Use the provided definition. -#elif defined(__cpp_lib_variant) -# define FMT_CPP_LIB_VARIANT __cpp_lib_variant -#else -# define FMT_CPP_LIB_VARIANT 0 -#endif - -FMT_BEGIN_NAMESPACE -namespace detail { - -#if FMT_CPP_LIB_FILESYSTEM - -template -auto get_path_string(const std::filesystem::path& p, - const std::basic_string& native) { - if constexpr (std::is_same_v && std::is_same_v) - return to_utf8(native, to_utf8_error_policy::replace); - else - return p.string(); -} - -template -void write_escaped_path(basic_memory_buffer& quoted, - const std::filesystem::path& p, - const std::basic_string& native) { - if constexpr (std::is_same_v && - std::is_same_v) { - auto buf = basic_memory_buffer(); - write_escaped_string(std::back_inserter(buf), native); - bool valid = to_utf8::convert(quoted, {buf.data(), buf.size()}); - FMT_ASSERT(valid, "invalid utf16"); - } else if constexpr (std::is_same_v) { - write_escaped_string( - std::back_inserter(quoted), native); - } else { - write_escaped_string(std::back_inserter(quoted), p.string()); - } -} - -#endif // FMT_CPP_LIB_FILESYSTEM - -#if defined(__cpp_lib_expected) || FMT_CPP_LIB_VARIANT - -template -auto write_escaped_alternative(OutputIt out, const T& v, FormatContext& ctx) - -> OutputIt { - if constexpr (has_to_string_view::value) - return write_escaped_string(out, detail::to_string_view(v)); - if constexpr (std::is_same_v) return write_escaped_char(out, v); - - formatter, Char> underlying; - maybe_set_debug_format(underlying, true); - return underlying.format(v, ctx); -} -#endif - -#if FMT_CPP_LIB_VARIANT - -template struct is_variant_like_ : std::false_type {}; -template -struct is_variant_like_> : std::true_type {}; - -template class is_variant_formattable { - template - static auto check(std::index_sequence) -> std::conjunction< - is_formattable, Char>...>; - - public: - static constexpr bool value = decltype(check( - std::make_index_sequence::value>()))::value; -}; - -#endif // FMT_CPP_LIB_VARIANT - -#if FMT_USE_RTTI -inline auto normalize_libcxx_inline_namespaces(string_view demangled_name_view, - char* begin) -> string_view { - // Normalization of stdlib inline namespace names. - // libc++ inline namespaces. - // std::__1::* -> std::* - // std::__1::__fs::* -> std::* - // libstdc++ inline namespaces. - // std::__cxx11::* -> std::* - // std::filesystem::__cxx11::* -> std::filesystem::* - if (demangled_name_view.starts_with("std::")) { - char* to = begin + 5; // std:: - for (const char *from = to, *end = begin + demangled_name_view.size(); - from < end;) { - // This is safe, because demangled_name is NUL-terminated. - if (from[0] == '_' && from[1] == '_') { - const char* next = from + 1; - while (next < end && *next != ':') next++; - if (next[0] == ':' && next[1] == ':') { - from = next + 2; - continue; - } - } - *to++ = *from++; - } - demangled_name_view = {begin, detail::to_unsigned(to - begin)}; - } - return demangled_name_view; -} - -template -auto normalize_msvc_abi_name(string_view abi_name_view, OutputIt out) - -> OutputIt { - const string_view demangled_name(abi_name_view); - for (size_t i = 0; i < demangled_name.size(); ++i) { - auto sub = demangled_name; - sub.remove_prefix(i); - if (sub.starts_with("enum ")) { - i += 4; - continue; - } - if (sub.starts_with("class ") || sub.starts_with("union ")) { - i += 5; - continue; - } - if (sub.starts_with("struct ")) { - i += 6; - continue; - } - if (*sub.begin() != ' ') *out++ = *sub.begin(); - } - return out; -} - -template -auto write_demangled_name(OutputIt out, const std::type_info& ti) -> OutputIt { -# ifdef FMT_HAS_ABI_CXA_DEMANGLE - int status = 0; - size_t size = 0; - std::unique_ptr demangled_name_ptr( - abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &free); - - string_view demangled_name_view; - if (demangled_name_ptr) { - demangled_name_view = normalize_libcxx_inline_namespaces( - demangled_name_ptr.get(), demangled_name_ptr.get()); - } else { - demangled_name_view = string_view(ti.name()); - } - return detail::write_bytes(out, demangled_name_view); -# elif FMT_MSC_VERSION && defined(_MSVC_STL_UPDATE) - return normalize_msvc_abi_name(ti.name(), out); -# elif FMT_MSC_VERSION && defined(_LIBCPP_VERSION) - const string_view demangled_name = ti.name(); - std::string name_copy(demangled_name.size(), '\0'); - // normalize_msvc_abi_name removes class, struct, union etc that MSVC has in - // front of types - name_copy.erase(normalize_msvc_abi_name(demangled_name, name_copy.begin()), - name_copy.end()); - // normalize_libcxx_inline_namespaces removes the inline __1, __2, etc - // namespaces libc++ uses for ABI versioning On MSVC ABI + libc++ - // environments, we need to eliminate both of them. - const string_view normalized_name = - normalize_libcxx_inline_namespaces(name_copy, name_copy.data()); - return detail::write_bytes(out, normalized_name); -# else - return detail::write_bytes(out, string_view(ti.name())); -# endif -} - -#endif // FMT_USE_RTTI - -template -struct has_flip : std::false_type {}; - -template -struct has_flip().flip())>> - : std::true_type {}; - -template struct is_bit_reference_like { - static constexpr bool value = std::is_convertible::value && - std::is_nothrow_assignable::value && - has_flip::value; -}; - -// Workaround for libc++ incompatibility with C++ standard. -// According to the Standard, `bitset::operator[] const` returns bool. -#if defined(_LIBCPP_VERSION) && !defined(FMT_IMPORT_STD) -template -struct is_bit_reference_like> { - static constexpr bool value = true; -}; -#endif - -template -struct has_format_as : std::false_type {}; -template -struct has_format_as()))>> - : std::true_type {}; - -template -struct has_format_as_member : std::false_type {}; -template -struct has_format_as_member< - T, void_t::format_as(std::declval()))>> - : std::true_type {}; - -} // namespace detail - -template -auto ptr(const std::unique_ptr& p) -> const void* { - return p.get(); -} -template auto ptr(const std::shared_ptr& p) -> const void* { - return p.get(); -} - -#if FMT_CPP_LIB_FILESYSTEM - -template struct formatter { - private: - format_specs specs_; - detail::arg_ref width_ref_; - bool debug_ = false; - char path_type_ = 0; - - public: - FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; } - - FMT_CONSTEXPR auto parse(parse_context& ctx) { - auto it = ctx.begin(), end = ctx.end(); - if (it == end) return it; - - it = detail::parse_align(it, end, specs_); - if (it == end) return it; - - Char c = *it; - if ((c >= '0' && c <= '9') || c == '{') - it = detail::parse_width(it, end, specs_, width_ref_, ctx); - if (it != end && *it == '?') { - debug_ = true; - ++it; - } - if (it != end && (*it == 'g')) path_type_ = detail::to_ascii(*it++); - return it; - } - - template - auto format(const std::filesystem::path& p, FormatContext& ctx) const { - auto specs = specs_; - auto path_string = - !path_type_ ? p.native() - : p.generic_string(); - - detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_, - ctx); - if (!debug_) { - auto s = detail::get_path_string(p, path_string); - return detail::write(ctx.out(), basic_string_view(s), specs); - } - auto quoted = basic_memory_buffer(); - detail::write_escaped_path(quoted, p, path_string); - return detail::write(ctx.out(), - basic_string_view(quoted.data(), quoted.size()), - specs); - } -}; - -class path : public std::filesystem::path { - public: - auto display_string() const -> std::string { - const std::filesystem::path& base = *this; - return fmt::format(FMT_STRING("{}"), base); - } - auto system_string() const -> std::string { return string(); } - - auto generic_display_string() const -> std::string { - const std::filesystem::path& base = *this; - return fmt::format(FMT_STRING("{:g}"), base); - } - auto generic_system_string() const -> std::string { return generic_string(); } -}; - -#endif // FMT_CPP_LIB_FILESYSTEM - -template -struct formatter, Char> - : nested_formatter, Char> { - private: - // This is a functor because C++11 doesn't support generic lambdas. - struct writer { - const std::bitset& bs; - - template - FMT_CONSTEXPR auto operator()(OutputIt out) -> OutputIt { - for (auto pos = N; pos > 0; --pos) - out = detail::write(out, bs[pos - 1] ? Char('1') : Char('0')); - return out; - } - }; - - public: - template - auto format(const std::bitset& bs, FormatContext& ctx) const - -> decltype(ctx.out()) { - return this->write_padded(ctx, writer{bs}); - } -}; - -template -struct formatter : basic_ostream_formatter {}; - -#ifdef __cpp_lib_optional -template -struct formatter, Char, - std::enable_if_t::value>> { - private: - formatter, Char> underlying_; - static constexpr basic_string_view optional = - detail::string_literal{}; - static constexpr basic_string_view none = - detail::string_literal{}; - - public: - FMT_CONSTEXPR auto parse(parse_context& ctx) { - detail::maybe_set_debug_format(underlying_, true); - return underlying_.parse(ctx); - } - - template - auto format(const std::optional& opt, FormatContext& ctx) const - -> decltype(ctx.out()) { - if (!opt) return detail::write(ctx.out(), none); - - auto out = ctx.out(); - out = detail::write(out, optional); - ctx.advance_to(out); - out = underlying_.format(*opt, ctx); - return detail::write(out, ')'); - } -}; -#endif // __cpp_lib_optional - -#ifdef __cpp_lib_expected -template -struct formatter, Char, - std::enable_if_t<(std::is_void::value || - is_formattable::value) && - is_formattable::value>> { - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - return ctx.begin(); - } - - template - auto format(const std::expected& value, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto out = ctx.out(); - - if (value.has_value()) { - out = detail::write(out, "expected("); - if constexpr (!std::is_void::value) - out = detail::write_escaped_alternative(out, *value, ctx); - } else { - out = detail::write(out, "unexpected("); - out = detail::write_escaped_alternative(out, value.error(), ctx); - } - *out++ = ')'; - return out; - } -}; -#endif // __cpp_lib_expected - -#ifdef __cpp_lib_source_location -template <> struct formatter { - FMT_CONSTEXPR auto parse(parse_context<>& ctx) { return ctx.begin(); } - - template - auto format(const std::source_location& loc, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto out = ctx.out(); - out = detail::write(out, loc.file_name()); - out = detail::write(out, ':'); - out = detail::write(out, loc.line()); - out = detail::write(out, ':'); - out = detail::write(out, loc.column()); - out = detail::write(out, ": "); - out = detail::write(out, loc.function_name()); - return out; - } -}; -#endif - -#if FMT_CPP_LIB_VARIANT - -template struct is_variant_like { - static constexpr bool value = detail::is_variant_like_::value; -}; - -template struct formatter { - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - return ctx.begin(); - } - - template - auto format(const std::monostate&, FormatContext& ctx) const - -> decltype(ctx.out()) { - return detail::write(ctx.out(), "monostate"); - } -}; - -template -struct formatter, - detail::is_variant_formattable>>> { - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - return ctx.begin(); - } - - template - auto format(const Variant& value, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto out = ctx.out(); - - out = detail::write(out, "variant("); - FMT_TRY { - std::visit( - [&](const auto& v) { - out = detail::write_escaped_alternative(out, v, ctx); - }, - value); - } - FMT_CATCH(const std::bad_variant_access&) { - detail::write(out, "valueless by exception"); - } - *out++ = ')'; - return out; - } -}; - -#endif // FMT_CPP_LIB_VARIANT - -template <> struct formatter { - private: - format_specs specs_; - detail::arg_ref width_ref_; - bool debug_ = false; - - public: - FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; } - - FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* { - auto it = ctx.begin(), end = ctx.end(); - if (it == end) return it; - - it = detail::parse_align(it, end, specs_); - - char c = *it; - if (it != end && ((c >= '0' && c <= '9') || c == '{')) - it = detail::parse_width(it, end, specs_, width_ref_, ctx); - - if (it != end && *it == '?') { - debug_ = true; - ++it; - } - if (it != end && *it == 's') { - specs_.set_type(presentation_type::string); - ++it; - } - return it; - } - - template - FMT_CONSTEXPR20 auto format(const std::error_code& ec, - FormatContext& ctx) const -> decltype(ctx.out()) { - auto specs = specs_; - detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_, - ctx); - auto buf = memory_buffer(); - if (specs_.type() == presentation_type::string) { - buf.append(ec.message()); - } else { - buf.append(string_view(ec.category().name())); - buf.push_back(':'); - detail::write(appender(buf), ec.value()); - } - auto quoted = memory_buffer(); - auto str = string_view(buf.data(), buf.size()); - if (debug_) { - detail::write_escaped_string(std::back_inserter(quoted), str); - str = string_view(quoted.data(), quoted.size()); - } - return detail::write(ctx.out(), str, specs); - } -}; - -#if FMT_USE_RTTI -template <> struct formatter { - public: - FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* { - return ctx.begin(); - } - - template - auto format(const std::type_info& ti, Context& ctx) const - -> decltype(ctx.out()) { - return detail::write_demangled_name(ctx.out(), ti); - } -}; -#endif // FMT_USE_RTTI - -template -struct formatter< - T, char, - typename std::enable_if::value>::type> { - private: - bool with_typename_ = false; - - public: - FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* { - auto it = ctx.begin(); - auto end = ctx.end(); - if (it == end || *it == '}') return it; - if (*it == 't') { - ++it; - with_typename_ = FMT_USE_RTTI != 0; - } - return it; - } - - template - auto format(const std::exception& ex, Context& ctx) const - -> decltype(ctx.out()) { - auto out = ctx.out(); -#if FMT_USE_RTTI - if (with_typename_) { - out = detail::write_demangled_name(out, typeid(ex)); - *out++ = ':'; - *out++ = ' '; - } -#endif - return detail::write_bytes(out, string_view(ex.what())); - } -}; - -// We can't use std::vector::reference and -// std::bitset::reference because the compiler can't deduce Allocator and N -// in partial specialization. -template -struct formatter::value>> - : formatter { - template - FMT_CONSTEXPR auto format(const BitRef& v, FormatContext& ctx) const - -> decltype(ctx.out()) { - return formatter::format(v, ctx); - } -}; - -template -struct formatter, Char, - enable_if_t::value>> - : formatter { - template - auto format(const std::atomic& v, FormatContext& ctx) const - -> decltype(ctx.out()) { - return formatter::format(v.load(), ctx); - } -}; - -#ifdef __cpp_lib_atomic_flag_test -template -struct formatter : formatter { - template - auto format(const std::atomic_flag& v, FormatContext& ctx) const - -> decltype(ctx.out()) { - return formatter::format(v.test(), ctx); - } -}; -#endif // __cpp_lib_atomic_flag_test - -template struct formatter, Char> { - private: - detail::dynamic_format_specs specs_; - - template - FMT_CONSTEXPR auto do_format(const std::complex& c, - detail::dynamic_format_specs& specs, - FormatContext& ctx, OutputIt out) const - -> OutputIt { - if (c.real() != 0) { - *out++ = Char('('); - out = detail::write(out, c.real(), specs, ctx.locale()); - specs.set_sign(sign::plus); - out = detail::write(out, c.imag(), specs, ctx.locale()); - if (!detail::isfinite(c.imag())) *out++ = Char(' '); - *out++ = Char('i'); - *out++ = Char(')'); - return out; - } - out = detail::write(out, c.imag(), specs, ctx.locale()); - if (!detail::isfinite(c.imag())) *out++ = Char(' '); - *out++ = Char('i'); - return out; - } - - public: - FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { - if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin(); - return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, - detail::type_constant::value); - } - - template - auto format(const std::complex& c, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto specs = specs_; - if (specs.dynamic()) { - detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, - specs.width_ref, ctx); - detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision, - specs.precision_ref, ctx); - } - - if (specs.width == 0) return do_format(c, specs, ctx, ctx.out()); - auto buf = basic_memory_buffer(); - - auto outer_specs = format_specs(); - outer_specs.width = specs.width; - outer_specs.copy_fill_from(specs); - outer_specs.set_align(specs.align()); - - specs.width = 0; - specs.set_fill({}); - specs.set_align(align::none); - - do_format(c, specs, ctx, basic_appender(buf)); - return detail::write(ctx.out(), - basic_string_view(buf.data(), buf.size()), - outer_specs); - } -}; - -template -struct formatter, Char, - // Guard against format_as because reference_wrapper is - // implicitly convertible to T&. - enable_if_t, Char>::value && - !detail::has_format_as::value && - !detail::has_format_as_member::value>> - : formatter, Char> { - template - auto format(std::reference_wrapper ref, FormatContext& ctx) const - -> decltype(ctx.out()) { - return formatter, Char>::format(ref.get(), ctx); - } -}; - -FMT_END_NAMESPACE - -#endif // FMT_STD_H_ diff --git a/include/libs/spdlog/fmt/bundled/xchar.h b/include/libs/spdlog/fmt/bundled/xchar.h deleted file mode 100644 index 9334b87..0000000 --- a/include/libs/spdlog/fmt/bundled/xchar.h +++ /dev/null @@ -1,356 +0,0 @@ -// Formatting library for C++ - optional wchar_t and exotic character support -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_XCHAR_H_ -#define FMT_XCHAR_H_ - -#include "color.h" -#include "format.h" -#include "ostream.h" -#include "ranges.h" - -#ifndef FMT_MODULE -# include -# if FMT_USE_LOCALE -# include -# endif -#endif - -FMT_BEGIN_NAMESPACE -namespace detail { - -template -using is_exotic_char = bool_constant::value>; - -template struct format_string_char {}; - -template -struct format_string_char< - S, void_t())))>> { - using type = char_t; -}; - -template -struct format_string_char< - S, enable_if_t::value>> { - using type = typename S::char_type; -}; - -template -using format_string_char_t = typename format_string_char::type; - -inline auto write_loc(basic_appender out, loc_value value, - const format_specs& specs, locale_ref loc) -> bool { -#if FMT_USE_LOCALE - auto& numpunct = - std::use_facet>(loc.get()); - auto separator = std::wstring(); - auto grouping = numpunct.grouping(); - if (!grouping.empty()) separator = std::wstring(1, numpunct.thousands_sep()); - return value.visit(loc_writer{out, specs, separator, grouping, {}}); -#endif - return false; -} - -template -void vformat_to(buffer& buf, basic_string_view fmt, - basic_format_args> args, - locale_ref loc = {}) { - static_assert(!std::is_same::value, ""); - auto out = basic_appender(buf); - parse_format_string( - fmt, format_handler{parse_context(fmt), {out, args, loc}}); -} -} // namespace detail - -FMT_BEGIN_EXPORT - -using wstring_view = basic_string_view; -using wformat_parse_context = parse_context; -using wformat_context = buffered_context; -using wformat_args = basic_format_args; -using wmemory_buffer = basic_memory_buffer; - -template struct basic_fstring { - private: - basic_string_view str_; - - static constexpr int num_static_named_args = - detail::count_static_named_args(); - - using checker = detail::format_string_checker< - Char, static_cast(sizeof...(T)), num_static_named_args, - num_static_named_args != detail::count_named_args()>; - - using arg_pack = detail::arg_pack; - - public: - using t = basic_fstring; - - template >::value)> - FMT_CONSTEVAL FMT_ALWAYS_INLINE basic_fstring(const S& s) : str_(s) { - if (FMT_USE_CONSTEVAL) - detail::parse_format_string(s, checker(s, arg_pack())); - } - template ::value&& - std::is_same::value)> - FMT_ALWAYS_INLINE basic_fstring(const S&) : str_(S()) { - FMT_CONSTEXPR auto sv = basic_string_view(S()); - FMT_CONSTEXPR int ignore = - (parse_format_string(sv, checker(sv, arg_pack())), 0); - detail::ignore_unused(ignore); - } - basic_fstring(runtime_format_string fmt) : str_(fmt.str) {} - - operator basic_string_view() const { return str_; } - auto get() const -> basic_string_view { return str_; } -}; - -template -using basic_format_string = basic_fstring; - -template -using wformat_string = typename basic_format_string::t; -inline auto runtime(wstring_view s) -> runtime_format_string { - return {{s}}; -} - -template -constexpr auto make_wformat_args(T&... args) - -> decltype(fmt::make_format_args(args...)) { - return fmt::make_format_args(args...); -} - -#if !FMT_USE_NONTYPE_TEMPLATE_ARGS -inline namespace literals { -inline auto operator""_a(const wchar_t* s, size_t) -> detail::udl_arg { - return {s}; -} -} // namespace literals -#endif - -template -auto join(It begin, Sentinel end, wstring_view sep) - -> join_view { - return {begin, end, sep}; -} - -template ::value)> -auto join(Range&& range, wstring_view sep) - -> join_view { - return join(std::begin(range), std::end(range), sep); -} - -template -auto join(std::initializer_list list, wstring_view sep) - -> join_view { - return join(std::begin(list), std::end(list), sep); -} - -template ::value)> -auto join(const Tuple& tuple, basic_string_view sep) - -> tuple_join_view { - return {tuple, sep}; -} - -template ::value)> -auto vformat(basic_string_view fmt, - basic_format_args> args) - -> std::basic_string { - auto buf = basic_memory_buffer(); - detail::vformat_to(buf, fmt, args); - return {buf.data(), buf.size()}; -} - -template -auto format(wformat_string fmt, T&&... args) -> std::wstring { - return vformat(fmt::wstring_view(fmt), fmt::make_wformat_args(args...)); -} - -template -auto format_to(OutputIt out, wformat_string fmt, T&&... args) - -> OutputIt { - return vformat_to(out, fmt::wstring_view(fmt), - fmt::make_wformat_args(args...)); -} - -// Pass char_t as a default template parameter instead of using -// std::basic_string> to reduce the symbol size. -template , - FMT_ENABLE_IF(!std::is_same::value && - !std::is_same::value)> -auto format(const S& fmt, T&&... args) -> std::basic_string { - return vformat(detail::to_string_view(fmt), - fmt::make_format_args>(args...)); -} - -template , - FMT_ENABLE_IF(detail::is_exotic_char::value)> -inline auto vformat(locale_ref loc, const S& fmt, - basic_format_args> args) - -> std::basic_string { - auto buf = basic_memory_buffer(); - detail::vformat_to(buf, detail::to_string_view(fmt), args, loc); - return {buf.data(), buf.size()}; -} - -template , - FMT_ENABLE_IF(detail::is_exotic_char::value)> -inline auto format(locale_ref loc, const S& fmt, T&&... args) - -> std::basic_string { - return vformat(loc, detail::to_string_view(fmt), - fmt::make_format_args>(args...)); -} - -template , - FMT_ENABLE_IF(detail::is_output_iterator::value&& - detail::is_exotic_char::value)> -auto vformat_to(OutputIt out, const S& fmt, - basic_format_args> args) -> OutputIt { - auto&& buf = detail::get_buffer(out); - detail::vformat_to(buf, detail::to_string_view(fmt), args); - return detail::get_iterator(buf, out); -} - -template , - FMT_ENABLE_IF(detail::is_output_iterator::value && - !std::is_same::value && - !std::is_same::value)> -inline auto format_to(OutputIt out, const S& fmt, T&&... args) -> OutputIt { - return vformat_to(out, detail::to_string_view(fmt), - fmt::make_format_args>(args...)); -} - -template , - FMT_ENABLE_IF(detail::is_output_iterator::value&& - detail::is_exotic_char::value)> -inline auto vformat_to(OutputIt out, locale_ref loc, const S& fmt, - basic_format_args> args) - -> OutputIt { - auto&& buf = detail::get_buffer(out); - vformat_to(buf, detail::to_string_view(fmt), args, loc); - return detail::get_iterator(buf, out); -} - -template , - bool enable = detail::is_output_iterator::value && - detail::is_exotic_char::value> -inline auto format_to(OutputIt out, locale_ref loc, const S& fmt, T&&... args) - -> typename std::enable_if::type { - return vformat_to(out, loc, detail::to_string_view(fmt), - fmt::make_format_args>(args...)); -} - -template ::value&& - detail::is_exotic_char::value)> -inline auto vformat_to_n(OutputIt out, size_t n, basic_string_view fmt, - basic_format_args> args) - -> format_to_n_result { - using traits = detail::fixed_buffer_traits; - auto buf = detail::iterator_buffer(out, n); - detail::vformat_to(buf, fmt, args); - return {buf.out(), buf.count()}; -} - -template , - FMT_ENABLE_IF(detail::is_output_iterator::value&& - detail::is_exotic_char::value)> -inline auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args) - -> format_to_n_result { - return vformat_to_n(out, n, fmt::basic_string_view(fmt), - fmt::make_format_args>(args...)); -} - -template , - FMT_ENABLE_IF(detail::is_exotic_char::value)> -inline auto formatted_size(const S& fmt, T&&... args) -> size_t { - auto buf = detail::counting_buffer(); - detail::vformat_to(buf, detail::to_string_view(fmt), - fmt::make_format_args>(args...)); - return buf.count(); -} - -inline void vprint(std::FILE* f, wstring_view fmt, wformat_args args) { - auto buf = wmemory_buffer(); - detail::vformat_to(buf, fmt, args); - buf.push_back(L'\0'); - if (std::fputws(buf.data(), f) == -1) - FMT_THROW(system_error(errno, FMT_STRING("cannot write to file"))); -} - -inline void vprint(wstring_view fmt, wformat_args args) { - vprint(stdout, fmt, args); -} - -template -void print(std::FILE* f, wformat_string fmt, T&&... args) { - return vprint(f, wstring_view(fmt), fmt::make_wformat_args(args...)); -} - -template void print(wformat_string fmt, T&&... args) { - return vprint(wstring_view(fmt), fmt::make_wformat_args(args...)); -} - -template -void println(std::FILE* f, wformat_string fmt, T&&... args) { - return print(f, L"{}\n", fmt::format(fmt, std::forward(args)...)); -} - -template void println(wformat_string fmt, T&&... args) { - return print(L"{}\n", fmt::format(fmt, std::forward(args)...)); -} - -inline auto vformat(text_style ts, wstring_view fmt, wformat_args args) - -> std::wstring { - auto buf = wmemory_buffer(); - detail::vformat_to(buf, ts, fmt, args); - return {buf.data(), buf.size()}; -} - -template -inline auto format(text_style ts, wformat_string fmt, T&&... args) - -> std::wstring { - return fmt::vformat(ts, fmt, fmt::make_wformat_args(args...)); -} - -inline void vprint(std::wostream& os, wstring_view fmt, wformat_args args) { - auto buffer = basic_memory_buffer(); - detail::vformat_to(buffer, fmt, args); - detail::write_buffer(os, buffer); -} - -template -void print(std::wostream& os, wformat_string fmt, T&&... args) { - vprint(os, fmt, fmt::make_format_args>(args...)); -} - -template -void println(std::wostream& os, wformat_string fmt, T&&... args) { - print(os, L"{}\n", fmt::format(fmt, std::forward(args)...)); -} - -/// Converts `value` to `std::wstring` using the default format for type `T`. -template inline auto to_wstring(const T& value) -> std::wstring { - return format(FMT_STRING(L"{}"), value); -} -FMT_END_EXPORT -FMT_END_NAMESPACE - -#endif // FMT_XCHAR_H_ diff --git a/include/libs/spdlog/tweakme.h b/include/libs/spdlog/tweakme.h index d609298..d77385d 100644 --- a/include/libs/spdlog/tweakme.h +++ b/include/libs/spdlog/tweakme.h @@ -78,7 +78,7 @@ // In this case spdlog will try to include so set your -I flag // accordingly. // -// #define SPDLOG_FMT_EXTERNAL +#define SPDLOG_FMT_EXTERNAL /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// diff --git a/include/util.hpp b/include/util.hpp index 0e40a8a..418ba22 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -293,10 +293,22 @@ Result load_image_rgba(const std::string& path); Result get_config_image_out_fmt(); Result<> save_png(SavingOp op, const capture_result_t& img); -void minimize_window(); // Defined on main_tool_* -void maximize_window(); // Defined on main_tool_* -void extern_glfwTerminate(); // Defined on main_tool_* -void extern_glfwSwapInterval(int v); // Defined on main_tool_* +// Defined on main_tool_* +namespace +{ +void (*g_minimize_fn)() = nullptr; +void (*g_maximize_fn)() = nullptr; +void (*g_terminate_fn)() = nullptr; +void (*g_swap_interval_fn)(int) = nullptr; +} // namespace +void register_window_callbacks(void (*minimize_fn)(), + void (*maximize_fn)(), + void (*terminate_fn)(), + void (*swap_interval_fn)(int)); +void minimize_window(); +void maximize_window(); +void extern_glfwTerminate(); +void extern_glfwSwapInterval(int v); void fit_to_screen(capture_result_t& img); void rgba_to_grayscale(const uint8_t* rgba, uint8_t* result, int width, int height); void build_font_atlas(ImGuiIO& io); diff --git a/src/globals.cpp b/src/globals.cpp new file mode 100644 index 0000000..a175e07 --- /dev/null +++ b/src/globals.cpp @@ -0,0 +1,18 @@ +#include "cache.hpp" +#include "clipboard.hpp" +#include "config.hpp" +#include "plugin.hpp" +#include "screenshot_tool.hpp" +#include "util.hpp" + +// Extern variables declariaions +std::deque g_dropped_paths; +std::unique_ptr g_config; +std::unique_ptr g_cache; +ScreenshotTool g_ss_tool; +bool g_is_systray = false; +int g_scr_w{}, g_scr_h{}; +Clipboard g_clipboard(SessionType::Unknown); + +std::unordered_map g_plugins; +plugin_runtime_t* g_current_plugin; diff --git a/src/main.cpp b/src/main.cpp index 4f865a9..57df6cc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,7 +31,6 @@ #include "getopt_port/getopt.h" #include "nvdialog/nvdialog_error.h" #include "oshot_png.h" -#include "plugin.hpp" #include "screen_capture.hpp" #include "screenshot_tool.hpp" #include "spdlog/sinks/basic_file_sink.h" @@ -65,18 +64,6 @@ struct GLFWwindow; : (optarg != NULL)) // clang-format on -// Extern variables declariaions -std::deque g_dropped_paths; -std::unique_ptr g_config; -std::unique_ptr g_cache; -ScreenshotTool g_ss_tool; -bool g_is_systray = false; -int g_scr_w{}, g_scr_h{}; -Clipboard g_clipboard(SessionType::Unknown); - -std::unordered_map g_plugins; -plugin_runtime_t* g_current_plugin; - std::error_code ec; // Print the version and some other infos, then exit successfully diff --git a/src/main_tool_metal.mm b/src/main_tool_metal.mm index 2eb3255..4245e7d 100644 --- a/src/main_tool_metal.mm +++ b/src/main_tool_metal.mm @@ -24,24 +24,16 @@ void glfw_error_callback(int error, const char* description); void glfw_drop_callback(GLFWwindow*, int count, const char** paths); -void extern_glfwTerminate() -{ - glfwTerminate(); -} -void extern_glfwSwapInterval(int v) -{ - glfwSwapInterval(v); -} GLFWwindow* window = nullptr; -void minimize_window() +static void minimize_window_() { glfwIconifyWindow(window); glfwPollEvents(); // flush } -void maximize_window() +static void maximize_window_() { glfwRestoreWindow(window); glfwFocusWindow(window); @@ -65,6 +57,7 @@ void maximize_window() int run_main_tool() { + register_window_callbacks(minimize_window_, maximize_window_, glfwTerminate, glfwSwapInterval); id device; // vsync is controlled via the CAMetalLayer's displaySyncEnabled property instead. diff --git a/src/main_tool_opengl3.cpp b/src/main_tool_opengl3.cpp index f781b37..5f5091f 100644 --- a/src/main_tool_opengl3.cpp +++ b/src/main_tool_opengl3.cpp @@ -23,14 +23,6 @@ GLFWwindow* window = nullptr; void glfw_error_callback(int i_error, const char* description); void glfw_drop_callback(GLFWwindow*, int count, const char** paths); -void extern_glfwTerminate() -{ - glfwTerminate(); -} -void extern_glfwSwapInterval(int v) -{ - glfwSwapInterval(v); -} // Returns the GLFW monitor that currently contains the cursor. // Falls back to the primary monitor if the cursor position cannot be @@ -86,13 +78,13 @@ static GLFWmonitor* get_monitor_at_cursor() return glfwGetPrimaryMonitor(); } -void minimize_window() +static void minimize_window_() { glfwIconifyWindow(window); glfwPollEvents(); // flush } -void maximize_window() +static void maximize_window_() { glfwRestoreWindow(window); glfwFocusWindow(window); @@ -100,6 +92,8 @@ void maximize_window() int run_main_tool() { + register_window_callbacks(minimize_window_, maximize_window_, glfwTerminate, glfwSwapInterval); + // Setup Screenshot Tool // Calling it before starting the window so that // we can capture at the exact moment we launch diff --git a/src/plugins.cpp b/src/plugins.cpp index 8568a43..aca4f71 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -34,7 +34,8 @@ void load_plugins() if (!plugin->render || !plugin->id || !plugin->name || plugin->name[0] == '\0') { - spdlog::error("Plugin '{}' doesn't define name/ID or render function", entry.path().stem().string()); + spdlog::error("Plugin '{}' doesn't define name/ID or render function", + entry.path().stem().string()); continue; } diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 1045def..c5eac8e 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -1293,7 +1293,7 @@ void ScreenshotTool::DrawMenuItems() minimize_window(); if (ImGui::Button("Close")) - m_show_window.Clear(SubWindow::About); + open = false; ImGui::End(); } m_show_window.Set(SubWindow::About, open); @@ -2227,13 +2227,13 @@ void ScreenshotTool::DrawLogsWindow() auto level_color = [](spdlog::level::level_enum lvl) -> rgba_t { switch (lvl) { - case spdlog::level::trace: return rgba_t(0x888888FF); // gray - case spdlog::level::debug: return rgba_t(0x9999FFFF); // periwinkle - case spdlog::level::info: return rgba_t(0x00AEFFFF); // blueish - case spdlog::level::warn: return rgba_t(0xFFCC33FF); // amber - case spdlog::level::err: return rgba_t(0xFF4D4DFF); // red - case spdlog::level::critical: return rgba_t(0xFF0000FF); // pure red - default: return rgba_t(0xFFFFFFFF); // white + case spdlog::level::trace: return rgba_t(0x888888FF); // gray + case spdlog::level::debug: return rgba_t(0x9999FFFF); // periwinkle + case spdlog::level::info: return rgba_t(0x00AEFFFF); // blueish + case spdlog::level::warn: return rgba_t(0xFFCC33FF); // amber + case spdlog::level::err: return rgba_t(0xFF4D4DFF); // red + case spdlog::level::critical: return rgba_t(0xFF0000FF); // pure red + default: return rgba_t(0xFFFFFFFF); // white } }; @@ -2323,7 +2323,8 @@ void ScreenshotTool::DrawLogsWindow() if (ImGui::BeginPopupContextItem(fmt::format("ctx##{}", i).c_str())) { if (ImGui::MenuItem("Copy line")) - MUST_OK(g_clipboard.CopyText(msg.payload.data()), spdlog::error("Failed to copy line log: {}", _r.error_v())); + MUST_OK(g_clipboard.CopyText(msg.payload.data()), + spdlog::error("Failed to copy line log: {}", _r.error_v())); ImGui::EndPopup(); } } diff --git a/src/util.cpp b/src/util.cpp index 16f9f96..c51711b 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -610,6 +610,38 @@ fs::path get_home_pictures_dir() } #endif +void register_window_callbacks(void (*minimize_fn)(), + void (*maximize_fn)(), + void (*terminate_fn)(), + void (*swap_interval_fn)(int)) +{ + g_minimize_fn = minimize_fn; + g_maximize_fn = maximize_fn; + g_terminate_fn = terminate_fn; + g_swap_interval_fn = swap_interval_fn; +} + +void minimize_window() +{ + if (g_minimize_fn) + g_minimize_fn(); +} +void maximize_window() +{ + if (g_maximize_fn) + g_maximize_fn(); +} +void extern_glfwTerminate() +{ + if (g_terminate_fn) + g_terminate_fn(); +} +void extern_glfwSwapInterval(int v) +{ + if (g_swap_interval_fn) + g_swap_interval_fn(v); +} + std::string expand_var(std::string ret) { if (ret.empty()) From 50bf5249978ca1e69d990b9dc0b35c153bbd879e Mon Sep 17 00:00:00 2001 From: Toni500git Date: Sat, 4 Jul 2026 22:15:10 +0200 Subject: [PATCH 21/40] plugins: add cache getter API --- include/cache.hpp | 31 +++++++++++++--- src/plugins/oshot_plugin.h | 14 +++++-- src/plugins/oshot_plugins.cpp | 69 ++++++++++++++++++++++++----------- 3 files changed, 84 insertions(+), 30 deletions(-) diff --git a/include/cache.hpp b/include/cache.hpp index cef9b12..c47f3ec 100644 --- a/include/cache.hpp +++ b/include/cache.hpp @@ -34,9 +34,8 @@ class Cache * @param fallback Default value if couldn't retrive value */ template - T GetValue(CacheEntry e, const T& fallback, bool dont_expand_var = false) + T GetValue(const std::string_view key, const T& fallback, bool dont_expand_var = false) { - const std::string& key = m_cache_entries.at(e); const std::optional& ret = m_tbl["cache"][key].value(); if constexpr (toml::is_string) if (!dont_expand_var) @@ -47,15 +46,25 @@ class Cache return ret.value_or(fallback); } + /** + * Get value of a cache variables + * @param value The cache variable "path" (e.g "cache.source-path") + * @param fallback Default value if couldn't retrive value + */ + template + T GetValue(CacheEntry e, const T& fallback, bool dont_expand_var = false) + { + return GetValue(m_cache_entries.at(e), fallback, dont_expand_var); + } + /** * Set value of a cache variables * @param path The cache variable "path" (e.g "cache.source-path") */ template - void SetValue(CacheEntry e, const T& value) + void SetValue(const std::string_view key, const T& value) { - const std::string& key = m_cache_entries.at(e); - auto* section = m_tbl["cache"].as_table(); + auto* section = m_tbl["cache"].as_table(); if (!section) { m_tbl.insert_or_assign("cache", toml::table{}); @@ -64,13 +73,23 @@ class Cache section->insert_or_assign(key, value); } + /** + * Set value of a cache variables + * @param path The cache variable "path" (e.g "cache.source-path") + */ + template + void SetValue(CacheEntry e, const T& value) + { + SetValue(m_cache_entries.at(e), value); + } + private: static constexpr const char* mk_file_path = "cache.toml"; std::string m_cache_dir_path; toml::table m_tbl; - std::unordered_map m_cache_entries = { + const std::unordered_map m_cache_entries = { { CacheEntry::AnnColor, "default-color-picker-color" }, { CacheEntry::ImgSavePath, "last-saved-dir" }, }; diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h index 80e8b59..e9cce40 100644 --- a/src/plugins/oshot_plugin.h +++ b/src/plugins/oshot_plugin.h @@ -98,6 +98,9 @@ bool oshot_get_plugin_data_dir(oshot_str_t* ret); oshot_str_t oshot_str_new(const char* str, size_t n); void oshot_str_free(oshot_str_t* str); +// Only frees OSHOT_VAL_STRING members +void oshot_value_array_free(oshot_value_t* arr, size_t n); + /* ------------------------------------------------------------------ * Logging / host messaging * ------------------------------------------------------------------ */ @@ -114,12 +117,17 @@ void oshot_debugs(const char* str); // oshot_log(DEBUG, str); oshot_str_t oshot_config_get_string(const char* key, oshot_str_t fallback); bool oshot_config_get_bool(const char* key, bool fallback); int64_t oshot_config_get_int64(const char* key, int64_t fallback); -float oshot_config_get_float(const char* key, float fallback); double oshot_config_get_double(const char* key, double fallback); size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max); -// Only frees OSHOT_VAL_STRING members -void oshot_value_array_free(oshot_value_t* arr, size_t n); +/* ------------------------------------------------------------------ + * Cache (plugin namespace only) + * ------------------------------------------------------------------ */ +oshot_str_t oshot_cache_get_string(const char* key, oshot_str_t fallback); +bool oshot_cache_get_bool(const char* key, bool fallback); +int64_t oshot_cache_get_int64(const char* key, int64_t fallback); +double oshot_cache_get_double(const char* key, double fallback); +size_t oshot_cache_get_array(const char* key, oshot_value_t** out, size_t max); /* ------------------------------------------------------------------ * ImGui-bound text buffers diff --git a/src/plugins/oshot_plugins.cpp b/src/plugins/oshot_plugins.cpp index f2c12c6..225bf75 100644 --- a/src/plugins/oshot_plugins.cpp +++ b/src/plugins/oshot_plugins.cpp @@ -1,6 +1,7 @@ #include #include +#include "cache.hpp" #include "config.hpp" #include "fmt/chrono.h" #include "fmt/format.h" @@ -37,6 +38,13 @@ void oshot_str_free(oshot_str_t* str) str->len = 0; } +void oshot_value_array_free(oshot_value_t* arr, size_t n) +{ + for (size_t i = 0; i < n; ++i) + if (arr[i].kind == OSValueKind::OSHOT_VAL_STRING) + oshot_str_free(&arr[i].s); +} + /* ------------------------------------------------------------------ * Logging * ------------------------------------------------------------------ */ @@ -74,35 +82,31 @@ void oshot_debugs(const char* str) /* ------------------------------------------------------------------ * Config * ------------------------------------------------------------------ */ +template +static T get_config_value(const char* key, T fallback) +{ + return g_config->GetValue(g_current_plugin->config_prefix + key, fallback); +} + oshot_str_t oshot_config_get_string(const char* key, oshot_str_t fallback) { - const std::string& str = - g_config->GetValue(g_current_plugin->config_prefix + key, std::string(fallback.p, fallback.len)); + const std::string& str = get_config_value(key, std::string(fallback.p, fallback.len)); return oshot_str_new(str.c_str(), str.length()); } bool oshot_config_get_bool(const char* key, bool fallback) { - bool val = g_config->GetValue(g_current_plugin->config_prefix + key, fallback); - return val; + return get_config_value(key, fallback); } int64_t oshot_config_get_int64(const char* key, int64_t fallback) { - int64_t val = g_config->GetValue(g_current_plugin->config_prefix + key, fallback); - return val; -} - -float oshot_config_get_float(const char* key, float fallback) -{ - float val = g_config->GetValue(g_current_plugin->config_prefix + key, fallback); - return val; + return get_config_value(key, fallback); } -double oshot_config_get_double(const char* key, double fallback) +double oshot_config_get_double(const char* key, float fallback) { - double val = g_config->GetValue(g_current_plugin->config_prefix + key, fallback); - return val; + return get_config_value(key, fallback); } size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max) @@ -148,11 +152,34 @@ size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max) return i; } -void oshot_value_array_free(oshot_value_t* arr, size_t n) +/* ------------------------------------------------------------------ + * Cache + * ------------------------------------------------------------------ */ +template +static T get_cache_value(const char* key, T fallback) { - for (size_t i = 0; i < n; ++i) - if (arr[i].kind == OSValueKind::OSHOT_VAL_STRING) - oshot_str_free(&arr[i].s); + return g_cache->GetValue(g_current_plugin->config_prefix + key, fallback); +} + +oshot_str_t oshot_cache_get_string(const char* key, oshot_str_t fallback) +{ + const std::string& str = get_cache_value(key, std::string(fallback.p, fallback.len)); + return oshot_str_new(str.c_str(), str.length()); +} + +bool oshot_cache_get_bool(const char* key, bool fallback) +{ + return get_cache_value(key, fallback); +} + +int64_t oshot_cache_get_int64(const char* key, int64_t fallback) +{ + return get_cache_value(key, fallback); +} + +double oshot_cache_get_double(const char* key, float fallback) +{ + return get_cache_value(key, fallback); } /* ------------------------------------------------------------------ @@ -179,9 +206,9 @@ void oshot_set_text(const char* imgui_id, const oshot_str_t value) auto& t = g_ss_tool.GetImGuiIDTexts(); auto it = t.find(imgui_id); if (it == t.end()) - return; // unknown id -- nothing registered to write into + return; // unknown id - it->second->assign(value.p, value.len); // mutate the live buffer, no temporaries + it->second->assign(value.p, value.len); } /* ------------------------------------------------------------------ From f85f64944132ec5b8b5527292bfa48240fc36616 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Sat, 4 Jul 2026 23:16:12 +0200 Subject: [PATCH 22/40] plugins: add cache/config setter API --- include/cache.hpp | 2 + include/config.hpp | 31 +++ new.patch | 363 ++++++++++++++++++++++++++++++++++ src/plugins/oshot_plugin.h | 20 ++ src/plugins/oshot_plugins.cpp | 202 +++++++++++++++---- 5 files changed, 581 insertions(+), 37 deletions(-) create mode 100644 new.patch diff --git a/include/cache.hpp b/include/cache.hpp index c47f3ec..8c3a128 100644 --- a/include/cache.hpp +++ b/include/cache.hpp @@ -83,6 +83,8 @@ class Cache SetValue(m_cache_entries.at(e), value); } + const toml::array* GetValueArray(const std::string_view value) const { return m_tbl.at_path(value).as_array(); } + private: static constexpr const char* mk_file_path = "cache.toml"; diff --git a/include/config.hpp b/include/config.hpp index 84352c1..89d7523 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -163,6 +163,37 @@ class Config m_overrides[key] = std::move(o); } + /** + * Set value of a config variables + * @param path The config variable "path" (e.g "cache.source-path") + */ + template + void SetValue(const std::string_view key, const T& value) + { + toml::table* section = &m_tbl; + size_t start = 0; + + for (;;) + { + size_t dot = key.find('.', start); + if (dot == key.npos) + { + section->insert_or_assign(key.substr(start), value); + return; + } + + const std::string_view part = key.substr(start, dot - start); + auto* next = section->get(part); + if (!next || !next->is_table()) + { + section->insert_or_assign(part, toml::table{}); + next = section->get(part); + } + section = next->as_table(); + start = dot + 1; + } + } + /** * Get value of config variables * @param value The config variable "path" (e.g "config.source-path") diff --git a/new.patch b/new.patch new file mode 100644 index 0000000..2d03b77 --- /dev/null +++ b/new.patch @@ -0,0 +1,363 @@ +diff --git a/include/cache.hpp b/include/cache.hpp +index c47f3ec..8c3a128 100644 +--- a/include/cache.hpp ++++ b/include/cache.hpp +@@ -83,6 +83,8 @@ public: + SetValue(m_cache_entries.at(e), value); + } + ++ const toml::array* GetValueArray(const std::string_view value) const { return m_tbl.at_path(value).as_array(); } ++ + private: + static constexpr const char* mk_file_path = "cache.toml"; + +diff --git a/include/config.hpp b/include/config.hpp +index 84352c1..89d7523 100644 +--- a/include/config.hpp ++++ b/include/config.hpp +@@ -163,6 +163,37 @@ public: + m_overrides[key] = std::move(o); + } + ++ /** ++ * Set value of a config variables ++ * @param path The config variable "path" (e.g "cache.source-path") ++ */ ++ template ++ void SetValue(const std::string_view key, const T& value) ++ { ++ toml::table* section = &m_tbl; ++ size_t start = 0; ++ ++ for (;;) ++ { ++ size_t dot = key.find('.', start); ++ if (dot == key.npos) ++ { ++ section->insert_or_assign(key.substr(start), value); ++ return; ++ } ++ ++ const std::string_view part = key.substr(start, dot - start); ++ auto* next = section->get(part); ++ if (!next || !next->is_table()) ++ { ++ section->insert_or_assign(part, toml::table{}); ++ next = section->get(part); ++ } ++ section = next->as_table(); ++ start = dot + 1; ++ } ++ } ++ + /** + * Get value of config variables + * @param value The config variable "path" (e.g "config.source-path") +diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h +index e9cce40..546512b 100644 +--- a/src/plugins/oshot_plugin.h ++++ b/src/plugins/oshot_plugin.h +@@ -120,6 +120,16 @@ int64_t oshot_config_get_int64(const char* key, int64_t fallback); + double oshot_config_get_double(const char* key, double fallback); + size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max); + ++void oshot_config_set_string(const char* key, const oshot_str_t* val); ++void oshot_config_set_bool(const char* key, bool val); ++void oshot_config_set_int64(const char* key, int64_t val); ++void oshot_config_set_double(const char* key, double val); ++ ++// Only for forwarding an already-typed value (e.g. writing back an ++// oshot_value_t pulled from get_array). not the primary plugin-facing API. ++oshot_value_t oshot_config_get_value(const char* key, oshot_value_t fallback); ++void oshot_config_set_value(const char* key, const oshot_value_t* val); ++ + /* ------------------------------------------------------------------ + * Cache (plugin namespace only) + * ------------------------------------------------------------------ */ +@@ -129,6 +139,16 @@ int64_t oshot_cache_get_int64(const char* key, int64_t fallback); + double oshot_cache_get_double(const char* key, double fallback); + size_t oshot_cache_get_array(const char* key, oshot_value_t** out, size_t max); + ++void oshot_cache_set_string(const char* key, const oshot_str_t* val); ++void oshot_cache_set_bool(const char* key, bool val); ++void oshot_cache_set_int64(const char* key, int64_t val); ++void oshot_cache_set_double(const char* key, double val); ++ ++// Only for forwarding an already-typed value (e.g. writing back an ++// oshot_value_t pulled from get_array). not the primary plugin-facing API. ++oshot_value_t oshot_cache_get_value(const char* key, oshot_value_t fallback); ++void oshot_cache_set_value(const char* key, const oshot_value_t* val); ++ + /* ------------------------------------------------------------------ + * ImGui-bound text buffers + * ------------------------------------------------------------------ */ +diff --git a/src/plugins/oshot_plugins.cpp b/src/plugins/oshot_plugins.cpp +index 225bf75..ee4e91b 100644 +--- a/src/plugins/oshot_plugins.cpp ++++ b/src/plugins/oshot_plugins.cpp +@@ -1,15 +1,60 @@ +-#include + #include + + #include "cache.hpp" + #include "config.hpp" +-#include "fmt/chrono.h" + #include "fmt/format.h" + #include "oshot_plugin.h" + #include "plugin.hpp" + #include "screenshot_tool.hpp" + #include "util.hpp" + ++static size_t toml_get_array(const toml::array* arr, oshot_value_t** out, size_t max) ++{ ++ if (!arr) ++ return 0; ++ ++ size_t i = 0; ++ for (const toml::node& el : *arr) ++ { ++ if (i == max) ++ break; ++ ++ oshot_value_t& val = *out[i]; ++ switch (el.type()) ++ { ++ case toml::node_type::string: ++ val.kind = OSValueKind::OSHOT_VAL_STRING; ++ val.s = oshot_str_new(el.as_string()->get().c_str(), el.as_string()->get().length()); ++ break; ++ ++ case toml::node_type::boolean: ++ val.kind = OSValueKind::OSHOT_VAL_BOOL; ++ val.b = el.as_boolean()->get(); ++ break; ++ ++ case toml::node_type::integer: ++ val.kind = OSValueKind::OSHOT_VAL_INT64; ++ val.i = el.as_integer()->get(); ++ break; ++ ++ case toml::node_type::floating_point: ++ val.kind = OSValueKind::OSHOT_VAL_DOUBLE; ++ val.d = el.as_floating_point()->get(); ++ break; ++ ++ default: continue; // unsupported TOML type: skip, don't consume a slot ++ } ++ i++; ++ } ++ ++ return i; ++} ++ ++static std::string prefixed_key(const char* key) ++{ ++ return g_current_plugin->config_prefix + key; ++} ++ + /* ------------------------------------------------------------------ + * ABI / identity + * ------------------------------------------------------------------ */ +@@ -82,10 +127,14 @@ void oshot_debugs(const char* str) + /* ------------------------------------------------------------------ + * Config + * ------------------------------------------------------------------ */ ++ ++// --------------------- ++// Getter ++// --------------------- + template + static T get_config_value(const char* key, T fallback) + { +- return g_config->GetValue(g_current_plugin->config_prefix + key, fallback); ++ return g_config->GetValue(prefixed_key(key), fallback); + } + + oshot_str_t oshot_config_get_string(const char* key, oshot_str_t fallback) +@@ -104,61 +153,81 @@ int64_t oshot_config_get_int64(const char* key, int64_t fallback) + return get_config_value(key, fallback); + } + +-double oshot_config_get_double(const char* key, float fallback) ++double oshot_config_get_double(const char* key, double fallback) + { + return get_config_value(key, fallback); + } + + size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max) + { +- const toml::array* arr = g_config->GetValueArray(g_current_plugin->config_prefix + key); +- if (!arr) +- return 0; ++ return toml_get_array(g_config->GetValueArray(prefixed_key(key)), out, max); ++} + +- size_t i = 0; +- for (const toml::node& el : *arr) +- { +- if (i == max) +- break; ++// --------------------- ++// Setter ++// --------------------- ++template ++static void set_config_value(const char* key, T val) ++{ ++ g_config->SetValue(prefixed_key(key), val); ++} + +- oshot_value_t& val = *out[i]; +- switch (el.type()) +- { +- case toml::node_type::string: +- val.kind = OSValueKind::OSHOT_VAL_STRING; +- val.s = oshot_str_new(el.as_string()->get().c_str(), el.as_string()->get().length()); +- break; ++void oshot_config_set_string(const char* key, const oshot_str_t* val) ++{ ++ set_config_value(key, std::string(val->p, val->len)); ++} + +- case toml::node_type::boolean: +- val.kind = OSValueKind::OSHOT_VAL_BOOL; +- val.b = el.as_boolean()->get(); +- break; ++void oshot_config_set_bool(const char* key, bool val) ++{ ++ set_config_value(key, val); ++} + +- case toml::node_type::integer: +- val.kind = OSValueKind::OSHOT_VAL_INT64; +- val.i = el.as_integer()->get(); +- break; ++void oshot_config_set_int64(const char* key, int64_t val) ++{ ++ set_config_value(key, val); ++} + +- case toml::node_type::floating_point: +- val.kind = OSValueKind::OSHOT_VAL_DOUBLE; +- val.d = el.as_floating_point()->get(); +- break; ++void oshot_config_set_double(const char* key, double val) ++{ ++ set_config_value(key, val); ++} + +- default: continue; // unsupported TOML type: skip, don't consume a slot +- } +- i++; ++void oshot_config_set_value(const char* key, const oshot_value_t* val) ++{ ++ if (val->kind < OSHOT_VAL_STRING || val->kind > OSHOT_VAL_DOUBLE) ++ { ++ oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set config value: unknown kind"); ++ return; + } + +- return i; ++ switch (val->kind) ++ { ++ case OSValueKind::OSHOT_VAL_STRING: ++ if (!val->s.p) ++ oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set config value: string has null pointer"); ++ else ++ g_config->SetValue(prefixed_key(key), std::string(val->s.p, val->s.len)); ++ break; ++ ++ case OSValueKind::OSHOT_VAL_INT64: g_config->SetValue(prefixed_key(key), val->i); break; ++ ++ case OSValueKind::OSHOT_VAL_DOUBLE: g_config->SetValue(prefixed_key(key), val->d); break; ++ ++ case OSValueKind::OSHOT_VAL_BOOL: g_config->SetValue(prefixed_key(key), val->b); break; ++ } + } + + /* ------------------------------------------------------------------ + * Cache + * ------------------------------------------------------------------ */ ++ ++// --------------------- ++// Getter ++// --------------------- + template + static T get_cache_value(const char* key, T fallback) + { +- return g_cache->GetValue(g_current_plugin->config_prefix + key, fallback); ++ return g_cache->GetValue(prefixed_key(key), fallback); + } + + oshot_str_t oshot_cache_get_string(const char* key, oshot_str_t fallback) +@@ -177,11 +246,70 @@ int64_t oshot_cache_get_int64(const char* key, int64_t fallback) + return get_cache_value(key, fallback); + } + +-double oshot_cache_get_double(const char* key, float fallback) ++double oshot_cache_get_double(const char* key, double fallback) + { + return get_cache_value(key, fallback); + } + ++size_t oshot_cache_get_array(const char* key, oshot_value_t** out, size_t max) ++{ ++ return toml_get_array(g_cache->GetValueArray(prefixed_key(key)), out, max); ++} ++ ++// --------------------- ++// Setter ++// --------------------- ++template ++static void set_cache_value(const char* key, T val) ++{ ++ g_cache->SetValue(prefixed_key(key), val); ++} ++ ++void oshot_cache_set_string(const char* key, const oshot_str_t* val) ++{ ++ set_cache_value(key, std::string(val->p, val->len)); ++} ++ ++void oshot_cache_set_bool(const char* key, bool val) ++{ ++ set_cache_value(key, val); ++} ++ ++void oshot_cache_set_int64(const char* key, int64_t val) ++{ ++ set_cache_value(key, val); ++} ++ ++void oshot_cache_set_double(const char* key, double val) ++{ ++ set_cache_value(key, val); ++} ++ ++void oshot_cache_set_value(const char* key, const oshot_value_t* val) ++{ ++ if (val->kind < OSHOT_VAL_STRING || val->kind > OSHOT_VAL_DOUBLE) ++ { ++ oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set cache value: unknown kind"); ++ return; ++ } ++ ++ switch (val->kind) ++ { ++ case OSValueKind::OSHOT_VAL_STRING: ++ if (!val->s.p) ++ oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set cache value: string has null pointer"); ++ else ++ g_cache->SetValue(prefixed_key(key), std::string(val->s.p, val->s.len)); ++ break; ++ ++ case OSValueKind::OSHOT_VAL_INT64: g_cache->SetValue(prefixed_key(key), val->i); break; ++ ++ case OSValueKind::OSHOT_VAL_DOUBLE: g_cache->SetValue(prefixed_key(key), val->d); break; ++ ++ case OSValueKind::OSHOT_VAL_BOOL: g_cache->SetValue(prefixed_key(key), val->b); break; ++ } ++} ++ + /* ------------------------------------------------------------------ + * ImGui-bound text buffers + * ------------------------------------------------------------------ */ diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h index e9cce40..546512b 100644 --- a/src/plugins/oshot_plugin.h +++ b/src/plugins/oshot_plugin.h @@ -120,6 +120,16 @@ int64_t oshot_config_get_int64(const char* key, int64_t fallback); double oshot_config_get_double(const char* key, double fallback); size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max); +void oshot_config_set_string(const char* key, const oshot_str_t* val); +void oshot_config_set_bool(const char* key, bool val); +void oshot_config_set_int64(const char* key, int64_t val); +void oshot_config_set_double(const char* key, double val); + +// Only for forwarding an already-typed value (e.g. writing back an +// oshot_value_t pulled from get_array). not the primary plugin-facing API. +oshot_value_t oshot_config_get_value(const char* key, oshot_value_t fallback); +void oshot_config_set_value(const char* key, const oshot_value_t* val); + /* ------------------------------------------------------------------ * Cache (plugin namespace only) * ------------------------------------------------------------------ */ @@ -129,6 +139,16 @@ int64_t oshot_cache_get_int64(const char* key, int64_t fallback); double oshot_cache_get_double(const char* key, double fallback); size_t oshot_cache_get_array(const char* key, oshot_value_t** out, size_t max); +void oshot_cache_set_string(const char* key, const oshot_str_t* val); +void oshot_cache_set_bool(const char* key, bool val); +void oshot_cache_set_int64(const char* key, int64_t val); +void oshot_cache_set_double(const char* key, double val); + +// Only for forwarding an already-typed value (e.g. writing back an +// oshot_value_t pulled from get_array). not the primary plugin-facing API. +oshot_value_t oshot_cache_get_value(const char* key, oshot_value_t fallback); +void oshot_cache_set_value(const char* key, const oshot_value_t* val); + /* ------------------------------------------------------------------ * ImGui-bound text buffers * ------------------------------------------------------------------ */ diff --git a/src/plugins/oshot_plugins.cpp b/src/plugins/oshot_plugins.cpp index 225bf75..ee4e91b 100644 --- a/src/plugins/oshot_plugins.cpp +++ b/src/plugins/oshot_plugins.cpp @@ -1,15 +1,60 @@ -#include #include #include "cache.hpp" #include "config.hpp" -#include "fmt/chrono.h" #include "fmt/format.h" #include "oshot_plugin.h" #include "plugin.hpp" #include "screenshot_tool.hpp" #include "util.hpp" +static size_t toml_get_array(const toml::array* arr, oshot_value_t** out, size_t max) +{ + if (!arr) + return 0; + + size_t i = 0; + for (const toml::node& el : *arr) + { + if (i == max) + break; + + oshot_value_t& val = *out[i]; + switch (el.type()) + { + case toml::node_type::string: + val.kind = OSValueKind::OSHOT_VAL_STRING; + val.s = oshot_str_new(el.as_string()->get().c_str(), el.as_string()->get().length()); + break; + + case toml::node_type::boolean: + val.kind = OSValueKind::OSHOT_VAL_BOOL; + val.b = el.as_boolean()->get(); + break; + + case toml::node_type::integer: + val.kind = OSValueKind::OSHOT_VAL_INT64; + val.i = el.as_integer()->get(); + break; + + case toml::node_type::floating_point: + val.kind = OSValueKind::OSHOT_VAL_DOUBLE; + val.d = el.as_floating_point()->get(); + break; + + default: continue; // unsupported TOML type: skip, don't consume a slot + } + i++; + } + + return i; +} + +static std::string prefixed_key(const char* key) +{ + return g_current_plugin->config_prefix + key; +} + /* ------------------------------------------------------------------ * ABI / identity * ------------------------------------------------------------------ */ @@ -82,10 +127,14 @@ void oshot_debugs(const char* str) /* ------------------------------------------------------------------ * Config * ------------------------------------------------------------------ */ + +// --------------------- +// Getter +// --------------------- template static T get_config_value(const char* key, T fallback) { - return g_config->GetValue(g_current_plugin->config_prefix + key, fallback); + return g_config->GetValue(prefixed_key(key), fallback); } oshot_str_t oshot_config_get_string(const char* key, oshot_str_t fallback) @@ -104,61 +153,81 @@ int64_t oshot_config_get_int64(const char* key, int64_t fallback) return get_config_value(key, fallback); } -double oshot_config_get_double(const char* key, float fallback) +double oshot_config_get_double(const char* key, double fallback) { return get_config_value(key, fallback); } size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max) { - const toml::array* arr = g_config->GetValueArray(g_current_plugin->config_prefix + key); - if (!arr) - return 0; + return toml_get_array(g_config->GetValueArray(prefixed_key(key)), out, max); +} - size_t i = 0; - for (const toml::node& el : *arr) - { - if (i == max) - break; +// --------------------- +// Setter +// --------------------- +template +static void set_config_value(const char* key, T val) +{ + g_config->SetValue(prefixed_key(key), val); +} - oshot_value_t& val = *out[i]; - switch (el.type()) - { - case toml::node_type::string: - val.kind = OSValueKind::OSHOT_VAL_STRING; - val.s = oshot_str_new(el.as_string()->get().c_str(), el.as_string()->get().length()); - break; +void oshot_config_set_string(const char* key, const oshot_str_t* val) +{ + set_config_value(key, std::string(val->p, val->len)); +} - case toml::node_type::boolean: - val.kind = OSValueKind::OSHOT_VAL_BOOL; - val.b = el.as_boolean()->get(); - break; +void oshot_config_set_bool(const char* key, bool val) +{ + set_config_value(key, val); +} - case toml::node_type::integer: - val.kind = OSValueKind::OSHOT_VAL_INT64; - val.i = el.as_integer()->get(); - break; +void oshot_config_set_int64(const char* key, int64_t val) +{ + set_config_value(key, val); +} - case toml::node_type::floating_point: - val.kind = OSValueKind::OSHOT_VAL_DOUBLE; - val.d = el.as_floating_point()->get(); - break; +void oshot_config_set_double(const char* key, double val) +{ + set_config_value(key, val); +} - default: continue; // unsupported TOML type: skip, don't consume a slot - } - i++; +void oshot_config_set_value(const char* key, const oshot_value_t* val) +{ + if (val->kind < OSHOT_VAL_STRING || val->kind > OSHOT_VAL_DOUBLE) + { + oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set config value: unknown kind"); + return; } - return i; + switch (val->kind) + { + case OSValueKind::OSHOT_VAL_STRING: + if (!val->s.p) + oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set config value: string has null pointer"); + else + g_config->SetValue(prefixed_key(key), std::string(val->s.p, val->s.len)); + break; + + case OSValueKind::OSHOT_VAL_INT64: g_config->SetValue(prefixed_key(key), val->i); break; + + case OSValueKind::OSHOT_VAL_DOUBLE: g_config->SetValue(prefixed_key(key), val->d); break; + + case OSValueKind::OSHOT_VAL_BOOL: g_config->SetValue(prefixed_key(key), val->b); break; + } } /* ------------------------------------------------------------------ * Cache * ------------------------------------------------------------------ */ + +// --------------------- +// Getter +// --------------------- template static T get_cache_value(const char* key, T fallback) { - return g_cache->GetValue(g_current_plugin->config_prefix + key, fallback); + return g_cache->GetValue(prefixed_key(key), fallback); } oshot_str_t oshot_cache_get_string(const char* key, oshot_str_t fallback) @@ -177,11 +246,70 @@ int64_t oshot_cache_get_int64(const char* key, int64_t fallback) return get_cache_value(key, fallback); } -double oshot_cache_get_double(const char* key, float fallback) +double oshot_cache_get_double(const char* key, double fallback) { return get_cache_value(key, fallback); } +size_t oshot_cache_get_array(const char* key, oshot_value_t** out, size_t max) +{ + return toml_get_array(g_cache->GetValueArray(prefixed_key(key)), out, max); +} + +// --------------------- +// Setter +// --------------------- +template +static void set_cache_value(const char* key, T val) +{ + g_cache->SetValue(prefixed_key(key), val); +} + +void oshot_cache_set_string(const char* key, const oshot_str_t* val) +{ + set_cache_value(key, std::string(val->p, val->len)); +} + +void oshot_cache_set_bool(const char* key, bool val) +{ + set_cache_value(key, val); +} + +void oshot_cache_set_int64(const char* key, int64_t val) +{ + set_cache_value(key, val); +} + +void oshot_cache_set_double(const char* key, double val) +{ + set_cache_value(key, val); +} + +void oshot_cache_set_value(const char* key, const oshot_value_t* val) +{ + if (val->kind < OSHOT_VAL_STRING || val->kind > OSHOT_VAL_DOUBLE) + { + oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set cache value: unknown kind"); + return; + } + + switch (val->kind) + { + case OSValueKind::OSHOT_VAL_STRING: + if (!val->s.p) + oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set cache value: string has null pointer"); + else + g_cache->SetValue(prefixed_key(key), std::string(val->s.p, val->s.len)); + break; + + case OSValueKind::OSHOT_VAL_INT64: g_cache->SetValue(prefixed_key(key), val->i); break; + + case OSValueKind::OSHOT_VAL_DOUBLE: g_cache->SetValue(prefixed_key(key), val->d); break; + + case OSValueKind::OSHOT_VAL_BOOL: g_cache->SetValue(prefixed_key(key), val->b); break; + } +} + /* ------------------------------------------------------------------ * ImGui-bound text buffers * ------------------------------------------------------------------ */ From 60d7b525e763925a4e75be483db753f29f703b0d Mon Sep 17 00:00:00 2001 From: Toni500git Date: Sun, 5 Jul 2026 20:29:17 +0200 Subject: [PATCH 23/40] plugins: remove convinience functions for logging with oshot_str_borrow() also some CMakeLists.txt improvements --- .gitignore | 1 + CMakeLists.txt | 92 +++++---- new.patch | 363 ---------------------------------- src/plugins.cpp | 2 +- src/plugins/oshot_plugin.h | 19 +- src/plugins/oshot_plugins.cpp | 39 ++-- 6 files changed, 84 insertions(+), 432 deletions(-) delete mode 100644 new.patch diff --git a/.gitignore b/.gitignore index a684b7c..d237981 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /oshot_r /locale/ /include/version.h +/*.patch AppDir *.AppImage diff --git a/CMakeLists.txt b/CMakeLists.txt index f9a7ec7..b3859bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,9 @@ function(enable_lto target) PRIVATE $<$:-flto=auto;-ffat-lto-objects> ) target_link_options(${target} PRIVATE $<$:-flto=auto>) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + target_compile_options(${target} PRIVATE $<$:-flto>) + target_link_options(${target} PRIVATE $<$:-flto>) elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") target_compile_options( ${target} @@ -117,19 +120,19 @@ add_executable( ) enable_lto(${PROJECT_NAME}) -execute_process( - COMMAND ./scripts/generateVersion.sh +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version.h + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generateVersion.sh WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - RESULT_VARIABLE OSHOT_VERSION_SCRIPT_RESULT + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generateVersion.sh + COMMENT "Generating version header" ) -if(NOT OSHOT_VERSION_SCRIPT_RESULT EQUAL 0) - message( - WARNING - "scripts/generateVersion.sh failed or is unavailable " - "(exit ${OSHOT_VERSION_SCRIPT_RESULT}); generated version info may be stale or missing. " - "Note this script also won't run on a native Windows shell without sh on PATH (e.g. Git Bash/MSYS)." - ) -endif() +add_custom_target( + generate_version + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/version.h +) +add_dependencies(${PROJECT_NAME} generate_version) +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) if(OSHOT_OPTION_DEFINITIONS) target_compile_definitions( @@ -142,11 +145,13 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE $<$:DEBUG=1>) target_compile_options( ${PROJECT_NAME} PRIVATE - $<$:-ggdb3;-fno-omit-frame-pointer;-Wall;-Wextra;-pedantic;-Wno-unused-parameter> + -Wall + -Wextra + -pedantic + -Wno-unused-parameter + $<$:-ggdb3;-fno-omit-frame-pointer> ) -add_dependencies(${PROJECT_NAME} oshot_common oshot_plugin) - target_link_libraries(${PROJECT_NAME} PRIVATE oshot_common oshot_plugin) if(WIN32 AND NOT WINDOWS_CMD) @@ -267,10 +272,7 @@ target_compile_definitions( # PkgConfig::LEPTONICA's own interface include dirs don't have. target_include_directories( oshot_common - PUBLIC - include/ - include/libs - ${LEPTONICA_INCLUDE_DIRS} + PUBLIC include/ include/libs ${LEPTONICA_INCLUDE_DIRS} ) target_compile_features(oshot_common PUBLIC cxx_std_20) @@ -280,18 +282,17 @@ target_compile_features(oshot_common PUBLIC cxx_std_20) # ----------------------------- add_library(oshot_plugin SHARED src/plugins/oshot_plugins.cpp) -add_dependencies(oshot_plugin oshot_common) - -target_include_directories(oshot_plugin PUBLIC include/ include/libs) - target_compile_features(oshot_plugin PUBLIC cxx_std_20) target_link_libraries(oshot_plugin PUBLIC oshot_common) -# Everything else is inherited from oshot_common set_target_properties( oshot_plugin - PROPERTIES VERSION 1 SOVERSION 1 WINDOWS_EXPORT_ALL_SYMBOLS ON + PROPERTIES + VERSION 1 + SOVERSION 1 + WINDOWS_EXPORT_ALL_SYMBOLS ON + POSITION_INDEPENDENT_CODE ON ) # ----------------------------- @@ -339,7 +340,14 @@ if(APPLE) ) endif() -set_target_properties(imgui PROPERTIES VERSION 1.92.9 SOVERSION 1) +set_target_properties( + imgui + PROPERTIES + VERSION 1.92.9 + SOVERSION 1 + WINDOWS_EXPORT_ALL_SYMBOLS ON + POSITION_INDEPENDENT_CODE ON +) # ----------------------------- # cimgui library (C-ABI plugins only) @@ -349,7 +357,14 @@ add_library(cimgui SHARED src/libs/cimgui/cimgui.cpp) target_include_directories(cimgui PUBLIC include/libs include/libs/cimgui) target_link_libraries(cimgui PUBLIC imgui) -set_target_properties(cimgui PROPERTIES VERSION 1 SOVERSION 1) +set_target_properties( + cimgui + PROPERTIES + VERSION 1 + SOVERSION 1 + WINDOWS_EXPORT_ALL_SYMBOLS ON + POSITION_INDEPENDENT_CODE ON +) # ----------------------------- # Tray library (integrated from its own CMakeLists.txt) @@ -360,7 +375,7 @@ if(WIN32) else() if(UNIX) if(APPLE) - find_library(COCOA Cocoa REQUIRED) + find_library(COCOA_FRAMEWORK Cocoa REQUIRED) list(APPEND TRAY_SOURCES src/libs/tray/tray_darwin.mm) else() list(APPEND TRAY_SOURCES src/libs/tray/tray_linux.cpp) @@ -375,12 +390,11 @@ if(WIN32) tray PRIVATE TRAY_WINAPI=1 WIN32_LEAN_AND_MEAN NOMINMAX ) - #target_compile_options(tray PRIVATE "/MT$<$:d>") else() if(UNIX) if(APPLE) target_compile_definitions(tray PRIVATE TRAY_APPKIT=1) - target_link_libraries(tray PRIVATE ${COCOA}) + target_link_libraries(tray PRIVATE ${COCOA_FRAMEWORK}) else() target_compile_options( tray @@ -449,7 +463,7 @@ file(GLOB DYLIB_SOURCES src/libs/dylib/*.cpp) add_library(dylib STATIC ${DYLIB_SOURCES}) if(UNIX) - target_link_libraries(dylib PRIVATE dl) + target_link_libraries(dylib PRIVATE ${CMAKE_DL_LIBS}) endif() target_include_directories(dylib PUBLIC include/libs/) @@ -484,10 +498,7 @@ target_include_directories( PRIVATE src/libs/nvdialog/impl/ ) -set_target_properties( - nvdialog - PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON -) +set_target_properties(nvdialog PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON) if(WIN32) target_link_libraries( @@ -576,23 +587,20 @@ enable_lto(tiny-process-library) # Install # ----------------------------- -add_dependencies(${PROJECT_NAME} cimgui imgui oshot_plugin) +include(GNUInstallDirs) install( TARGETS ${PROJECT_NAME} imgui cimgui oshot_plugin - RUNTIME DESTINATION bin COMPONENT runtime - LIBRARY DESTINATION lib COMPONENT runtime - ARCHIVE DESTINATION lib COMPONENT runtime + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install( FILES LICENSE - DESTINATION share/licenses/${PROJECT_NAME} - COMPONENT documentation + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/licenses/${PROJECT_NAME} ) install( FILES oshot.desktop - DESTINATION share/applications - COMPONENT documentation + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications ) diff --git a/new.patch b/new.patch deleted file mode 100644 index 2d03b77..0000000 --- a/new.patch +++ /dev/null @@ -1,363 +0,0 @@ -diff --git a/include/cache.hpp b/include/cache.hpp -index c47f3ec..8c3a128 100644 ---- a/include/cache.hpp -+++ b/include/cache.hpp -@@ -83,6 +83,8 @@ public: - SetValue(m_cache_entries.at(e), value); - } - -+ const toml::array* GetValueArray(const std::string_view value) const { return m_tbl.at_path(value).as_array(); } -+ - private: - static constexpr const char* mk_file_path = "cache.toml"; - -diff --git a/include/config.hpp b/include/config.hpp -index 84352c1..89d7523 100644 ---- a/include/config.hpp -+++ b/include/config.hpp -@@ -163,6 +163,37 @@ public: - m_overrides[key] = std::move(o); - } - -+ /** -+ * Set value of a config variables -+ * @param path The config variable "path" (e.g "cache.source-path") -+ */ -+ template -+ void SetValue(const std::string_view key, const T& value) -+ { -+ toml::table* section = &m_tbl; -+ size_t start = 0; -+ -+ for (;;) -+ { -+ size_t dot = key.find('.', start); -+ if (dot == key.npos) -+ { -+ section->insert_or_assign(key.substr(start), value); -+ return; -+ } -+ -+ const std::string_view part = key.substr(start, dot - start); -+ auto* next = section->get(part); -+ if (!next || !next->is_table()) -+ { -+ section->insert_or_assign(part, toml::table{}); -+ next = section->get(part); -+ } -+ section = next->as_table(); -+ start = dot + 1; -+ } -+ } -+ - /** - * Get value of config variables - * @param value The config variable "path" (e.g "config.source-path") -diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h -index e9cce40..546512b 100644 ---- a/src/plugins/oshot_plugin.h -+++ b/src/plugins/oshot_plugin.h -@@ -120,6 +120,16 @@ int64_t oshot_config_get_int64(const char* key, int64_t fallback); - double oshot_config_get_double(const char* key, double fallback); - size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max); - -+void oshot_config_set_string(const char* key, const oshot_str_t* val); -+void oshot_config_set_bool(const char* key, bool val); -+void oshot_config_set_int64(const char* key, int64_t val); -+void oshot_config_set_double(const char* key, double val); -+ -+// Only for forwarding an already-typed value (e.g. writing back an -+// oshot_value_t pulled from get_array). not the primary plugin-facing API. -+oshot_value_t oshot_config_get_value(const char* key, oshot_value_t fallback); -+void oshot_config_set_value(const char* key, const oshot_value_t* val); -+ - /* ------------------------------------------------------------------ - * Cache (plugin namespace only) - * ------------------------------------------------------------------ */ -@@ -129,6 +139,16 @@ int64_t oshot_cache_get_int64(const char* key, int64_t fallback); - double oshot_cache_get_double(const char* key, double fallback); - size_t oshot_cache_get_array(const char* key, oshot_value_t** out, size_t max); - -+void oshot_cache_set_string(const char* key, const oshot_str_t* val); -+void oshot_cache_set_bool(const char* key, bool val); -+void oshot_cache_set_int64(const char* key, int64_t val); -+void oshot_cache_set_double(const char* key, double val); -+ -+// Only for forwarding an already-typed value (e.g. writing back an -+// oshot_value_t pulled from get_array). not the primary plugin-facing API. -+oshot_value_t oshot_cache_get_value(const char* key, oshot_value_t fallback); -+void oshot_cache_set_value(const char* key, const oshot_value_t* val); -+ - /* ------------------------------------------------------------------ - * ImGui-bound text buffers - * ------------------------------------------------------------------ */ -diff --git a/src/plugins/oshot_plugins.cpp b/src/plugins/oshot_plugins.cpp -index 225bf75..ee4e91b 100644 ---- a/src/plugins/oshot_plugins.cpp -+++ b/src/plugins/oshot_plugins.cpp -@@ -1,15 +1,60 @@ --#include - #include - - #include "cache.hpp" - #include "config.hpp" --#include "fmt/chrono.h" - #include "fmt/format.h" - #include "oshot_plugin.h" - #include "plugin.hpp" - #include "screenshot_tool.hpp" - #include "util.hpp" - -+static size_t toml_get_array(const toml::array* arr, oshot_value_t** out, size_t max) -+{ -+ if (!arr) -+ return 0; -+ -+ size_t i = 0; -+ for (const toml::node& el : *arr) -+ { -+ if (i == max) -+ break; -+ -+ oshot_value_t& val = *out[i]; -+ switch (el.type()) -+ { -+ case toml::node_type::string: -+ val.kind = OSValueKind::OSHOT_VAL_STRING; -+ val.s = oshot_str_new(el.as_string()->get().c_str(), el.as_string()->get().length()); -+ break; -+ -+ case toml::node_type::boolean: -+ val.kind = OSValueKind::OSHOT_VAL_BOOL; -+ val.b = el.as_boolean()->get(); -+ break; -+ -+ case toml::node_type::integer: -+ val.kind = OSValueKind::OSHOT_VAL_INT64; -+ val.i = el.as_integer()->get(); -+ break; -+ -+ case toml::node_type::floating_point: -+ val.kind = OSValueKind::OSHOT_VAL_DOUBLE; -+ val.d = el.as_floating_point()->get(); -+ break; -+ -+ default: continue; // unsupported TOML type: skip, don't consume a slot -+ } -+ i++; -+ } -+ -+ return i; -+} -+ -+static std::string prefixed_key(const char* key) -+{ -+ return g_current_plugin->config_prefix + key; -+} -+ - /* ------------------------------------------------------------------ - * ABI / identity - * ------------------------------------------------------------------ */ -@@ -82,10 +127,14 @@ void oshot_debugs(const char* str) - /* ------------------------------------------------------------------ - * Config - * ------------------------------------------------------------------ */ -+ -+// --------------------- -+// Getter -+// --------------------- - template - static T get_config_value(const char* key, T fallback) - { -- return g_config->GetValue(g_current_plugin->config_prefix + key, fallback); -+ return g_config->GetValue(prefixed_key(key), fallback); - } - - oshot_str_t oshot_config_get_string(const char* key, oshot_str_t fallback) -@@ -104,61 +153,81 @@ int64_t oshot_config_get_int64(const char* key, int64_t fallback) - return get_config_value(key, fallback); - } - --double oshot_config_get_double(const char* key, float fallback) -+double oshot_config_get_double(const char* key, double fallback) - { - return get_config_value(key, fallback); - } - - size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max) - { -- const toml::array* arr = g_config->GetValueArray(g_current_plugin->config_prefix + key); -- if (!arr) -- return 0; -+ return toml_get_array(g_config->GetValueArray(prefixed_key(key)), out, max); -+} - -- size_t i = 0; -- for (const toml::node& el : *arr) -- { -- if (i == max) -- break; -+// --------------------- -+// Setter -+// --------------------- -+template -+static void set_config_value(const char* key, T val) -+{ -+ g_config->SetValue(prefixed_key(key), val); -+} - -- oshot_value_t& val = *out[i]; -- switch (el.type()) -- { -- case toml::node_type::string: -- val.kind = OSValueKind::OSHOT_VAL_STRING; -- val.s = oshot_str_new(el.as_string()->get().c_str(), el.as_string()->get().length()); -- break; -+void oshot_config_set_string(const char* key, const oshot_str_t* val) -+{ -+ set_config_value(key, std::string(val->p, val->len)); -+} - -- case toml::node_type::boolean: -- val.kind = OSValueKind::OSHOT_VAL_BOOL; -- val.b = el.as_boolean()->get(); -- break; -+void oshot_config_set_bool(const char* key, bool val) -+{ -+ set_config_value(key, val); -+} - -- case toml::node_type::integer: -- val.kind = OSValueKind::OSHOT_VAL_INT64; -- val.i = el.as_integer()->get(); -- break; -+void oshot_config_set_int64(const char* key, int64_t val) -+{ -+ set_config_value(key, val); -+} - -- case toml::node_type::floating_point: -- val.kind = OSValueKind::OSHOT_VAL_DOUBLE; -- val.d = el.as_floating_point()->get(); -- break; -+void oshot_config_set_double(const char* key, double val) -+{ -+ set_config_value(key, val); -+} - -- default: continue; // unsupported TOML type: skip, don't consume a slot -- } -- i++; -+void oshot_config_set_value(const char* key, const oshot_value_t* val) -+{ -+ if (val->kind < OSHOT_VAL_STRING || val->kind > OSHOT_VAL_DOUBLE) -+ { -+ oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set config value: unknown kind"); -+ return; - } - -- return i; -+ switch (val->kind) -+ { -+ case OSValueKind::OSHOT_VAL_STRING: -+ if (!val->s.p) -+ oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set config value: string has null pointer"); -+ else -+ g_config->SetValue(prefixed_key(key), std::string(val->s.p, val->s.len)); -+ break; -+ -+ case OSValueKind::OSHOT_VAL_INT64: g_config->SetValue(prefixed_key(key), val->i); break; -+ -+ case OSValueKind::OSHOT_VAL_DOUBLE: g_config->SetValue(prefixed_key(key), val->d); break; -+ -+ case OSValueKind::OSHOT_VAL_BOOL: g_config->SetValue(prefixed_key(key), val->b); break; -+ } - } - - /* ------------------------------------------------------------------ - * Cache - * ------------------------------------------------------------------ */ -+ -+// --------------------- -+// Getter -+// --------------------- - template - static T get_cache_value(const char* key, T fallback) - { -- return g_cache->GetValue(g_current_plugin->config_prefix + key, fallback); -+ return g_cache->GetValue(prefixed_key(key), fallback); - } - - oshot_str_t oshot_cache_get_string(const char* key, oshot_str_t fallback) -@@ -177,11 +246,70 @@ int64_t oshot_cache_get_int64(const char* key, int64_t fallback) - return get_cache_value(key, fallback); - } - --double oshot_cache_get_double(const char* key, float fallback) -+double oshot_cache_get_double(const char* key, double fallback) - { - return get_cache_value(key, fallback); - } - -+size_t oshot_cache_get_array(const char* key, oshot_value_t** out, size_t max) -+{ -+ return toml_get_array(g_cache->GetValueArray(prefixed_key(key)), out, max); -+} -+ -+// --------------------- -+// Setter -+// --------------------- -+template -+static void set_cache_value(const char* key, T val) -+{ -+ g_cache->SetValue(prefixed_key(key), val); -+} -+ -+void oshot_cache_set_string(const char* key, const oshot_str_t* val) -+{ -+ set_cache_value(key, std::string(val->p, val->len)); -+} -+ -+void oshot_cache_set_bool(const char* key, bool val) -+{ -+ set_cache_value(key, val); -+} -+ -+void oshot_cache_set_int64(const char* key, int64_t val) -+{ -+ set_cache_value(key, val); -+} -+ -+void oshot_cache_set_double(const char* key, double val) -+{ -+ set_cache_value(key, val); -+} -+ -+void oshot_cache_set_value(const char* key, const oshot_value_t* val) -+{ -+ if (val->kind < OSHOT_VAL_STRING || val->kind > OSHOT_VAL_DOUBLE) -+ { -+ oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set cache value: unknown kind"); -+ return; -+ } -+ -+ switch (val->kind) -+ { -+ case OSValueKind::OSHOT_VAL_STRING: -+ if (!val->s.p) -+ oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set cache value: string has null pointer"); -+ else -+ g_cache->SetValue(prefixed_key(key), std::string(val->s.p, val->s.len)); -+ break; -+ -+ case OSValueKind::OSHOT_VAL_INT64: g_cache->SetValue(prefixed_key(key), val->i); break; -+ -+ case OSValueKind::OSHOT_VAL_DOUBLE: g_cache->SetValue(prefixed_key(key), val->d); break; -+ -+ case OSValueKind::OSHOT_VAL_BOOL: g_cache->SetValue(prefixed_key(key), val->b); break; -+ } -+} -+ - /* ------------------------------------------------------------------ - * ImGui-bound text buffers - * ------------------------------------------------------------------ */ diff --git a/src/plugins.cpp b/src/plugins.cpp index aca4f71..3930633 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -75,7 +75,7 @@ void load_plugins() it->second.state = plugin->init(); } - info("loading plugin at {}!", entry.path().string()); + spdlog::info("loading plugin at {}!", entry.path().string()); } catch (const dylib::load_error& e) { diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h index 546512b..4fc36b5 100644 --- a/src/plugins/oshot_plugin.h +++ b/src/plugins/oshot_plugin.h @@ -7,6 +7,7 @@ extern "C" { #include #include #include +#include #define OSHOT_API_VERSION 1u @@ -98,18 +99,22 @@ bool oshot_get_plugin_data_dir(oshot_str_t* ret); oshot_str_t oshot_str_new(const char* str, size_t n); void oshot_str_free(oshot_str_t* str); +static inline oshot_str_t oshot_str_borrow(const char* s) +{ + return (oshot_str_t){ s, s ? strlen(s) : 0 }; +} + // Only frees OSHOT_VAL_STRING members void oshot_value_array_free(oshot_value_t* arr, size_t n); /* ------------------------------------------------------------------ - * Logging / host messaging + * Logging * ------------------------------------------------------------------ */ void oshot_log(OSLogLevel lvl, oshot_str_t str); void oshot_debug(oshot_str_t str); // oshot_log(DEBUG, str); - -// convinience ig -void oshot_logs(OSLogLevel lvl, const char* str); -void oshot_debugs(const char* str); // oshot_log(DEBUG, str); +void oshot_error(oshot_str_t str); // oshot_log(ERROR, str); +void oshot_warn(oshot_str_t str); // oshot_log(WARN, str); +void oshot_info(oshot_str_t str); // oshot_log(INFO, str); /* ------------------------------------------------------------------ * Config (plugin namespace only) @@ -120,7 +125,7 @@ int64_t oshot_config_get_int64(const char* key, int64_t fallback); double oshot_config_get_double(const char* key, double fallback); size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max); -void oshot_config_set_string(const char* key, const oshot_str_t* val); +void oshot_config_set_string(const char* key, oshot_str_t val); void oshot_config_set_bool(const char* key, bool val); void oshot_config_set_int64(const char* key, int64_t val); void oshot_config_set_double(const char* key, double val); @@ -139,7 +144,7 @@ int64_t oshot_cache_get_int64(const char* key, int64_t fallback); double oshot_cache_get_double(const char* key, double fallback); size_t oshot_cache_get_array(const char* key, oshot_value_t** out, size_t max); -void oshot_cache_set_string(const char* key, const oshot_str_t* val); +void oshot_cache_set_string(const char* key, oshot_str_t val); void oshot_cache_set_bool(const char* key, bool val); void oshot_cache_set_int64(const char* key, int64_t val); void oshot_cache_set_double(const char* key, double val); diff --git a/src/plugins/oshot_plugins.cpp b/src/plugins/oshot_plugins.cpp index ee4e91b..7c3cb93 100644 --- a/src/plugins/oshot_plugins.cpp +++ b/src/plugins/oshot_plugins.cpp @@ -1,5 +1,3 @@ -#include - #include "cache.hpp" #include "config.hpp" #include "fmt/format.h" @@ -107,21 +105,22 @@ void oshot_log(const OSLogLevel lvl, oshot_str_t str) void oshot_debug(oshot_str_t str) { - oshot_log(OSLogLevel::OSHOT_LOG_DEBUG, std::move(str)); + oshot_log(OSLogLevel::OSHOT_LOG_DEBUG, str); +} + +void oshot_error(oshot_str_t str) +{ + oshot_log(OSLogLevel::OSHOT_LOG_ERROR, str); } -void oshot_logs(OSLogLevel lvl, const char* str) +void oshot_warn(oshot_str_t str) { - oshot_str_t s = oshot_str_new(str, strlen(str)); - oshot_log(lvl, s); - oshot_str_free(&s); + oshot_log(OSLogLevel::OSHOT_LOG_WARN, str); } -void oshot_debugs(const char* str) +void oshot_info(oshot_str_t str) { - oshot_str_t s = oshot_str_new(str, strlen(str)); - oshot_debug(s); - oshot_str_free(&s); + oshot_log(OSLogLevel::OSHOT_LOG_INFO, str); } /* ------------------------------------------------------------------ @@ -172,9 +171,9 @@ static void set_config_value(const char* key, T val) g_config->SetValue(prefixed_key(key), val); } -void oshot_config_set_string(const char* key, const oshot_str_t* val) +void oshot_config_set_string(const char* key, oshot_str_t val) { - set_config_value(key, std::string(val->p, val->len)); + set_config_value(key, std::string(val.p, val.len)); } void oshot_config_set_bool(const char* key, bool val) @@ -196,7 +195,7 @@ void oshot_config_set_value(const char* key, const oshot_value_t* val) { if (val->kind < OSHOT_VAL_STRING || val->kind > OSHOT_VAL_DOUBLE) { - oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set config value: unknown kind"); + oshot_log(OSLogLevel::OSHOT_LOG_ERROR, oshot_str_borrow("Failed to set config value: unknown kind")); return; } @@ -204,7 +203,8 @@ void oshot_config_set_value(const char* key, const oshot_value_t* val) { case OSValueKind::OSHOT_VAL_STRING: if (!val->s.p) - oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set config value: string has null pointer"); + oshot_log(OSLogLevel::OSHOT_LOG_ERROR, + oshot_str_borrow("Failed to set config value: string has null pointer")); else g_config->SetValue(prefixed_key(key), std::string(val->s.p, val->s.len)); break; @@ -265,9 +265,9 @@ static void set_cache_value(const char* key, T val) g_cache->SetValue(prefixed_key(key), val); } -void oshot_cache_set_string(const char* key, const oshot_str_t* val) +void oshot_cache_set_string(const char* key, oshot_str_t val) { - set_cache_value(key, std::string(val->p, val->len)); + set_cache_value(key, std::string(val.p, val.len)); } void oshot_cache_set_bool(const char* key, bool val) @@ -289,7 +289,7 @@ void oshot_cache_set_value(const char* key, const oshot_value_t* val) { if (val->kind < OSHOT_VAL_STRING || val->kind > OSHOT_VAL_DOUBLE) { - oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set cache value: unknown kind"); + oshot_log(OSLogLevel::OSHOT_LOG_ERROR, oshot_str_borrow("Failed to set cache value: unknown kind")); return; } @@ -297,7 +297,8 @@ void oshot_cache_set_value(const char* key, const oshot_value_t* val) { case OSValueKind::OSHOT_VAL_STRING: if (!val->s.p) - oshot_logs(OSLogLevel::OSHOT_LOG_ERROR, "Failed to set cache value: string has null pointer"); + oshot_log(OSLogLevel::OSHOT_LOG_ERROR, + oshot_str_borrow("Failed to set cache value: string has null pointer")); else g_cache->SetValue(prefixed_key(key), std::string(val->s.p, val->s.len)); break; From 480f56b3b6d944f8756ff15c7a912cf99466eed3 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Sun, 5 Jul 2026 22:44:21 +0200 Subject: [PATCH 24/40] build: add option to disable plugins at compile time --- CMakeLists.txt | 135 +++++++++++++++++++++++----------------- include/plugin.hpp | 9 ++- include/util.hpp | 3 + src/globals.cpp | 6 +- src/plugins.cpp | 8 ++- src/screenshot_tool.cpp | 21 ++++++- 6 files changed, 117 insertions(+), 65 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b3859bd..5db440b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,7 +52,7 @@ macro(add_option OPTION_NAME OPTION_TEXT OPTION_DEFAULT DEFINE_OPTION) # Allow overriding the option through an environment variable set(${OPTION_NAME} $ENV{${OPTION_NAME}}) endif() - if(${OPTION_NAME} AND DEFINE_OPTION) + if(${OPTION_NAME} AND ${DEFINE_OPTION}) list(APPEND OSHOT_OPTION_DEFINITIONS ${OPTION_NAME}=1) endif() message(STATUS " ${OPTION_NAME}: ${${OPTION_NAME}}") @@ -60,11 +60,11 @@ endmacro() # Options add_option(WINDOWS_CMD "Enable terminal support on Windows" OFF OFF) +add_option(DISABLE_PLUGINS "Disable plugins support" ON ON) # ----------------------------- # Dependencies # ----------------------------- - find_package(PkgConfig REQUIRED) find_package(Threads REQUIRED) find_package(glfw3 REQUIRED) @@ -111,7 +111,6 @@ endif() # ----------------------------- # Main executable # ----------------------------- - add_executable( ${PROJECT_NAME} src/main.cpp @@ -134,13 +133,6 @@ add_custom_target( add_dependencies(${PROJECT_NAME} generate_version) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -if(OSHOT_OPTION_DEFINITIONS) - target_compile_definitions( - ${PROJECT_NAME} - PRIVATE ${OSHOT_OPTION_DEFINITIONS} - ) -endif() - target_compile_definitions(${PROJECT_NAME} PRIVATE $<$:DEBUG=1>) target_compile_options( ${PROJECT_NAME} @@ -152,7 +144,10 @@ target_compile_options( $<$:-ggdb3;-fno-omit-frame-pointer> ) -target_link_libraries(${PROJECT_NAME} PRIVATE oshot_common oshot_plugin) +target_link_libraries(${PROJECT_NAME} PRIVATE oshot_common) +if(NOT DISABLE_PLUGINS) + target_link_libraries(${PROJECT_NAME} PRIVATE oshot_plugin) +endif() if(WIN32 AND NOT WINDOWS_CMD) set_target_properties(${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE TRUE) @@ -182,7 +177,6 @@ add_library( src/clipboard.cpp src/config.cpp src/globals.cpp - src/plugins.cpp src/screen_capture.cpp src/screenshot_tool.cpp src/text_extraction.cpp @@ -191,6 +185,14 @@ add_library( src/libs/tinyfiledialogs/tinyfiledialogs.c ) +if(OSHOT_OPTION_DEFINITIONS) + target_compile_definitions(oshot_common PUBLIC ${OSHOT_OPTION_DEFINITIONS}) +endif() + +if(NOT DISABLE_PLUGINS) + target_sources(oshot_common PRIVATE src/plugins.cpp) +endif() + enable_lto(oshot_common) if(WIN32) @@ -249,7 +251,6 @@ target_link_libraries( imgui tray clip - dylib nvdialog tiny-process-library PkgConfig::TESSERACT @@ -259,6 +260,10 @@ target_link_libraries( ${GLFW_TARGET} PRIVATE Threads::Threads ) +if(NOT DISABLE_PLUGINS) + target_link_libraries(oshot_common PUBLIC dylib) +endif() + target_compile_definitions( oshot_common PUBLIC VERSION="${PROJECT_VERSION}" TOML_HEADER_ONLY=0 @@ -280,20 +285,22 @@ target_compile_features(oshot_common PUBLIC cxx_std_20) # ----------------------------- # oshot's plugin library # ----------------------------- -add_library(oshot_plugin SHARED src/plugins/oshot_plugins.cpp) +if(NOT DISABLE_PLUGINS) + add_library(oshot_plugin SHARED src/plugins/oshot_plugins.cpp) -target_compile_features(oshot_plugin PUBLIC cxx_std_20) + target_compile_features(oshot_plugin PUBLIC cxx_std_20) -target_link_libraries(oshot_plugin PUBLIC oshot_common) + target_link_libraries(oshot_plugin PUBLIC oshot_common) -set_target_properties( - oshot_plugin - PROPERTIES - VERSION 1 - SOVERSION 1 - WINDOWS_EXPORT_ALL_SYMBOLS ON - POSITION_INDEPENDENT_CODE ON -) + set_target_properties( + oshot_plugin + PROPERTIES + VERSION 1 + SOVERSION 1 + WINDOWS_EXPORT_ALL_SYMBOLS ON + POSITION_INDEPENDENT_CODE ON + ) +endif() # ----------------------------- # fmt library @@ -316,7 +323,11 @@ if(APPLE) list(APPEND IMGUI_SOURCES src/libs/imgui/imgui_impl_metal.mm) endif() -add_library(imgui SHARED ${IMGUI_SOURCES}) +if(DISABLE_PLUGINS) + add_library(imgui STATIC ${IMGUI_SOURCES}) +else() + add_library(imgui SHARED ${IMGUI_SOURCES}) +endif() enable_lto(imgui) @@ -340,31 +351,35 @@ if(APPLE) ) endif() -set_target_properties( - imgui - PROPERTIES - VERSION 1.92.9 - SOVERSION 1 - WINDOWS_EXPORT_ALL_SYMBOLS ON - POSITION_INDEPENDENT_CODE ON -) +if(NOT DISABLE_PLUGINS) + set_target_properties( + imgui + PROPERTIES + VERSION 1.92.9 + SOVERSION 1 + WINDOWS_EXPORT_ALL_SYMBOLS ON + POSITION_INDEPENDENT_CODE ON + ) +endif() # ----------------------------- # cimgui library (C-ABI plugins only) # ----------------------------- -add_library(cimgui SHARED src/libs/cimgui/cimgui.cpp) - -target_include_directories(cimgui PUBLIC include/libs include/libs/cimgui) -target_link_libraries(cimgui PUBLIC imgui) -set_target_properties( - cimgui - PROPERTIES - VERSION 1 - SOVERSION 1 - WINDOWS_EXPORT_ALL_SYMBOLS ON - POSITION_INDEPENDENT_CODE ON -) +if(NOT DISABLE_PLUGINS) + add_library(cimgui SHARED src/libs/cimgui/cimgui.cpp) + + target_include_directories(cimgui PUBLIC include/libs include/libs/cimgui) + target_link_libraries(cimgui PUBLIC imgui) + set_target_properties( + cimgui + PROPERTIES + VERSION 1 + SOVERSION 1 + WINDOWS_EXPORT_ALL_SYMBOLS ON + POSITION_INDEPENDENT_CODE ON + ) +endif() # ----------------------------- # Tray library (integrated from its own CMakeLists.txt) @@ -459,15 +474,17 @@ target_compile_definitions(clip PUBLIC CLIP_ENABLE_IMAGE=1) # dylib library (integrated from its own CMakeLists.txt) # ----------------------------- -file(GLOB DYLIB_SOURCES src/libs/dylib/*.cpp) -add_library(dylib STATIC ${DYLIB_SOURCES}) +if(NOT DISABLE_PLUGINS) + file(GLOB DYLIB_SOURCES src/libs/dylib/*.cpp) + add_library(dylib STATIC ${DYLIB_SOURCES}) -if(UNIX) - target_link_libraries(dylib PRIVATE ${CMAKE_DL_LIBS}) -endif() + if(UNIX) + target_link_libraries(dylib PRIVATE ${CMAKE_DL_LIBS}) + endif() -target_include_directories(dylib PUBLIC include/libs/) -target_compile_features(dylib PRIVATE cxx_std_20) + target_include_directories(dylib PUBLIC include/libs/) + target_compile_features(dylib PRIVATE cxx_std_20) +endif() # ----------------------------- # nvdialog (integrated from its own CMakeLists.txt) @@ -589,11 +606,15 @@ enable_lto(tiny-process-library) include(GNUInstallDirs) -install( - TARGETS ${PROJECT_NAME} imgui cimgui oshot_plugin - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} -) +if(DISABLE_PLUGINS) + install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +else() + install( + TARGETS ${PROJECT_NAME} imgui cimgui oshot_plugin + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() install( FILES LICENSE diff --git a/include/plugin.hpp b/include/plugin.hpp index bb4a2af..ae0bf56 100644 --- a/include/plugin.hpp +++ b/include/plugin.hpp @@ -1,9 +1,10 @@ #pragma once -#include +#ifndef DISABLE_PLUGINS +# include -#include "../src/plugins/oshot_plugin.h" -#include "dylib.hpp" +# include "../src/plugins/oshot_plugin.h" +# include "dylib.hpp" struct plugin_runtime_t; @@ -57,3 +58,5 @@ struct plugin_runtime_t }; void load_plugins(); + +#endif diff --git a/include/util.hpp b/include/util.hpp index 418ba22..c8dcf85 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -258,6 +258,9 @@ static inline const std::string version_infos = fmt::format( "oshot v{} built from branch '{}' at {} commit '{}' ({}).\n" "Date: {}\n" "Tag: {}\n", +#ifdef DISABLE_PLUGINS + "NO PLUGINS SUPPORT", +#endif VERSION, GIT_BRANCH, GIT_DIRTY, diff --git a/src/globals.cpp b/src/globals.cpp index a175e07..95176ef 100644 --- a/src/globals.cpp +++ b/src/globals.cpp @@ -1,7 +1,9 @@ #include "cache.hpp" #include "clipboard.hpp" #include "config.hpp" -#include "plugin.hpp" +#ifndef DISABLE_PLUGINS +# include "plugin.hpp" +#endif #include "screenshot_tool.hpp" #include "util.hpp" @@ -14,5 +16,7 @@ bool g_is_systray = false; int g_scr_w{}, g_scr_h{}; Clipboard g_clipboard(SessionType::Unknown); +#ifndef DISABLE_PLUGINS std::unordered_map g_plugins; plugin_runtime_t* g_current_plugin; +#endif diff --git a/src/plugins.cpp b/src/plugins.cpp index 3930633..b0703b1 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -1,5 +1,7 @@ -#include "plugin.hpp" -#include "util.hpp" +#ifndef DISABLE_PLUGINS + +# include "plugin.hpp" +# include "util.hpp" void load_plugins() { @@ -88,3 +90,5 @@ void load_plugins() } } } + +#endif diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index c5eac8e..981012f 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -29,8 +29,13 @@ #include "imgui/imgui_impl_opengl3_loader.h" #include "imgui/imgui_internal.h" #include "imgui/imgui_stdlib.h" -#include "plugin.hpp" -#include "plugins/oshot_plugin.h" +#ifndef DISABLE_PLUGINS +# include "plugin.hpp" +# include "plugins/oshot_plugin.h" +#else +# define OCR_OUTPUT "ocr_output" +# define ZBAR_OUTPUT "barcode_output" +#endif #include "screen_capture.hpp" #include "spdlog/sinks/ringbuffer_sink.h" #include "tiny-process-library/process.hpp" @@ -339,8 +344,10 @@ Result<> ScreenshotTool::Start() Result<> ScreenshotTool::StartWindow() { +#ifndef DISABLE_PLUGINS static std::once_flag plugins_loaded; std::call_once(plugins_loaded, [] { load_plugins(); }); +#endif m_inputs = { g_config->File.ocr_path, g_config->File.ocr_model, @@ -471,6 +478,7 @@ void ScreenshotTool::RenderOverlay() DrawLogsWindow(); DrawOcrTools(); DrawBarDecodeTools(); +#ifndef DISABLE_PLUGINS for (auto& [_, entry] : g_plugins) { oshot_plugin_t* plugin = entry.plugin; @@ -491,6 +499,7 @@ void ScreenshotTool::RenderOverlay() ImGui::PopID(); } } +#endif ImGui::End(); } m_show_window.Set(SubWindow::MainTextTools, open); @@ -1268,6 +1277,12 @@ void ScreenshotTool::DrawMenuItems() ImGui::Text("%s", text_display.data()); ImGui::Spacing(); +#ifdef DISABLE_PLUGINS + text_display = centered_text("!!! NO PLUGINS SUPPORT !!!"); + ImGui::TextColored(get_confidence_color(0), "%s", text_display.data()); + ImGui::Spacing(); +#endif + // More version details text_display = "More Details:"; if (ImGui::TreeNode(text_display.data())) @@ -1391,6 +1406,7 @@ void ScreenshotTool::DrawOcrTools() { ClearError(ectx, OcrError::FailedToScan); m_inputs.ocr_results = std::move(result.get()); +#ifndef DISABLE_PLUGINS if (!g_plugins.empty()) { oshot_ocr_result_t ocr{ @@ -1408,6 +1424,7 @@ void ScreenshotTool::DrawOcrTools() } oshot_str_free(&ocr.text); } +#endif } else { From 000fe15f22c0048423d96aeb0b27670b2b01f165 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Wed, 8 Jul 2026 23:00:46 +0200 Subject: [PATCH 25/40] plugins: add preference tab support + some other changes finally pushed this damn commit :wilted_rose: --- CMakeLists.txt | 26 +++++-- Makefile | 10 +-- include/screenshot_tool.hpp | 3 + src/plugins.cpp | 29 +++++--- src/plugins/oshot_plugin.h | 9 ++- src/plugins/oshot_plugins.cpp | 9 +++ src/screenshot_tool.cpp | 127 +++++++++++++++++++++++++--------- 7 files changed, 159 insertions(+), 54 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5db440b..23055f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,10 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_POSITION_INDEPENDENT_CODE ON) +add_compile_options($<$:-fsanitize=address>) +add_compile_options($<$:-fno-omit-frame-pointer>) +add_link_options($<$:-fsanitize=address>) + # GCC/Clang default Release flags already include -O3; this just makes it # explicit. Guarded because "-O3" is not a valid cl.exe switch and would # otherwise spam D9002 (or hard-fail under /WX) on MSVC builds. @@ -42,7 +46,7 @@ endfunction() # https://github.com/libcpr/cpr/blob/5f475522597b8f3721e2440daddeced7a969f24c/CMakeLists.txt#L39 # NOTE: definitions are collected into OSHOT_OPTION_DEFINITIONS instead of # using add_definitions(), which is directory-scoped and would otherwise leak -# into every target declared afterward -- including vendored third-party +# into every target declared afterward - including vendored third-party # libs (fmt, imgui, tray, clip, dylib, nvdialog, tiny-process-library). # They're applied to just ${PROJECT_NAME} once it exists (see below). set(OSHOT_OPTION_DEFINITIONS "") @@ -59,8 +63,8 @@ macro(add_option OPTION_NAME OPTION_TEXT OPTION_DEFAULT DEFINE_OPTION) endmacro() # Options -add_option(WINDOWS_CMD "Enable terminal support on Windows" OFF OFF) -add_option(DISABLE_PLUGINS "Disable plugins support" ON ON) +add_option(WINDOWS_CMD "Enable terminal support on Windows" OFF ON) +add_option(DISABLE_PLUGINS "Disable plugins support" OFF ON) # ----------------------------- # Dependencies @@ -87,7 +91,7 @@ pkg_check_modules(ZBAR REQUIRED IMPORTED_TARGET zbar) # Homebrew's lept.pc points Cflags at .../include/leptonica directly (its # own convention is `#include `), but our code uses # `#include `, which needs the parent dir on the -# include path too. Add it defensively on every platform. +# include path too. message(STATUS "LEPTONICA_INCLUDE_DIRS before: ${LEPTONICA_INCLUDE_DIRS}") foreach(_lept_dir ${LEPTONICA_INCLUDE_DIRS}) get_filename_component(_lept_parent_dir "${_lept_dir}" DIRECTORY) @@ -144,15 +148,25 @@ target_compile_options( $<$:-ggdb3;-fno-omit-frame-pointer> ) -target_link_libraries(${PROJECT_NAME} PRIVATE oshot_common) +# oshot_plugin PUBLIC-links oshot_common (see below), so linking oshot_plugin +# alone pulls in oshot_common's usage requirements transitively. This is +# deliberate: it ensures oshot and oshot_plugin.so resolve globals.cpp's +# externs (g_ss_tool, g_config, g_cache, g_plugins, g_current_plugin, ...) +# to the same symbols at the same address. if(NOT DISABLE_PLUGINS) target_link_libraries(${PROJECT_NAME} PRIVATE oshot_plugin) +else() + target_link_libraries(${PROJECT_NAME} PRIVATE oshot_common) endif() if(WIN32 AND NOT WINDOWS_CMD) set_target_properties(${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE TRUE) endif() +if(UNIX AND NOT APPLE) + target_link_libraries(${PROJECT_NAME} PRIVATE X11::X11) +endif() + if(APPLE) target_sources(${PROJECT_NAME} PRIVATE src/main_tool_metal.mm) set(_rpath_origin "@loader_path") @@ -271,7 +285,7 @@ target_compile_definitions( # NOTE: PkgConfig::TESSERACT / PkgConfig::ZBAR already propagate their own # include dirs, link dirs, and compile options as usage requirements via -# target_link_libraries() above -- no need to add TESSERACT_*/ZBAR_* here too. +# target_link_libraries() above. # LEPTONICA_INCLUDE_DIRS is the one exception: it was patched earlier in this # file to add the parent directory for Homebrew's lept.pc convention, which # PkgConfig::LEPTONICA's own interface include dirs don't have. diff --git a/Makefile b/Makefile index 3853247..e80f3e1 100644 --- a/Makefile +++ b/Makefile @@ -8,16 +8,17 @@ CMAKE ?= cmake PREFIX ?= /usr -DEBUG ?= 0 -WINDOWS_CMD ?= 0 -JOBS := $(shell echo $(MAKEFLAGS) | grep -oP '(?<=-j)\d+') -JOBS ?= $(shell nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4) +JOBS := $(shell echo $(MAKEFLAGS) | grep -oP '(?<=-j)\d+' || nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4) NAME := oshot VERSION := 0.4.6 OLDVERSION := 0.4.5 TARGET ?= $(NAME) +DEBUG ?= 0 +WINDOWS_CMD ?= 0 +DISABLE_PLUGINS ?= 0 + ifeq ($(DEBUG),1) BUILDDIR := build/debug BUILD_TYPE := Debug @@ -30,6 +31,7 @@ CMAKE_CONFIGURE_FLAGS := \ -S . -B $(BUILDDIR) \ -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) \ -DWINDOWS_CMD=$(WINDOWS_CMD) \ + -DDISABLE_PLUGINS=$(DISABLE_PLUGINS) \ -DCMAKE_INSTALL_PREFIX=$(PREFIX) .PHONY: all configure build clean distclean dist genver updatever install diff --git a/include/screenshot_tool.hpp b/include/screenshot_tool.hpp index 27424da..0fa893c 100644 --- a/include/screenshot_tool.hpp +++ b/include/screenshot_tool.hpp @@ -77,6 +77,9 @@ enum class PrefTab { kNone = -1, Defaults = 0, +#ifndef DISABLE_PLUGINS + Plugins, +#endif Theme }; diff --git a/src/plugins.cpp b/src/plugins.cpp index b0703b1..7af95ab 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -1,5 +1,6 @@ #ifndef DISABLE_PLUGINS +# include "fmt/std.h" # include "plugin.hpp" # include "util.hpp" @@ -19,25 +20,35 @@ void load_plugins() for (const auto& entry : fs::directory_iterator(plugin_dir.path(), fs::directory_options::skip_permission_denied)) { - if (entry.path().filename() != expected) + const fs::path& path = entry.path(); + + if (!path.has_extension() || path.extension().string() != dylib::decorations::os_default().suffix) continue; + if (path.filename().string() != expected) + { + spdlog::warn("Found plugin filename '{}' at {}, expected '{}'. Skipping", + path.filename(), + path.parent_path().string(), + expected); + continue; + } + try { - dylib::library lib(entry.path().string()); + dylib::library lib(path.string()); auto oshot_get_plugin = lib.get_function("oshot_host_get_plugin"); oshot_plugin_t* plugin = oshot_get_plugin(); if (!plugin || plugin->abi_version != oshot_get_abi_version()) { - spdlog::error("Plugin '{}' has incompatible ABI version, skipping", entry.path().stem().string()); + spdlog::error("Plugin '{}' has incompatible ABI version, skipping", path.stem().string()); continue; } if (!plugin->render || !plugin->id || !plugin->name || plugin->name[0] == '\0') { - spdlog::error("Plugin '{}' doesn't define name/ID or render function", - entry.path().stem().string()); + spdlog::error("Plugin '{}' doesn't define name/ID or render function", path.stem().string()); continue; } @@ -54,7 +65,9 @@ void load_plugins() return (isalnum(c) || c == '-' || c == '_' || c == '=' || c == ' '); })) { - spdlog::error("Plugin '{}' contains chars other than -_= or alpha numerical", plugin->id); + spdlog::error("Plugin name '{}' in '{}' contains chars other than -_= or alpha numerical", + plugin->name, + plugin->id); continue; } @@ -77,11 +90,11 @@ void load_plugins() it->second.state = plugin->init(); } - spdlog::info("loading plugin at {}!", entry.path().string()); + spdlog::info("loading plugin at {}!", path.string()); } catch (const dylib::load_error& e) { - spdlog::error("Failed to load '{}' library: {}", entry.path().stem().string(), e.what()); + spdlog::error("Failed to load '{}' library: {}", path.stem().string(), e.what()); } catch (const dylib::symbol_error& e) { diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h index 4fc36b5..4a3834f 100644 --- a/src/plugins/oshot_plugin.h +++ b/src/plugins/oshot_plugin.h @@ -84,14 +84,19 @@ typedef struct void* (*init)(void); void (*destroy)(void* state); void (*render)(void* state); + void (*on_ocr_done)(void* state, const oshot_ocr_result_t* result); + + bool (*render_preferences)(void* state); + void (*on_save_preferences)(void* state); + void (*on_discard_preferences)(void* state); } oshot_plugin_t; /* ------------------------------------------------------------------ * ABI / identity * ------------------------------------------------------------------ */ -uint32_t oshot_get_abi_version(void); -bool oshot_get_plugin_data_dir(oshot_str_t* ret); +uint32_t oshot_get_abi_version(void); +oshot_str_t oshot_get_plugin_data_dir(void); /* ------------------------------------------------------------------ * oshot_str_t lifecycle diff --git a/src/plugins/oshot_plugins.cpp b/src/plugins/oshot_plugins.cpp index 7c3cb93..8fae1ef 100644 --- a/src/plugins/oshot_plugins.cpp +++ b/src/plugins/oshot_plugins.cpp @@ -61,6 +61,15 @@ uint32_t oshot_get_abi_version() return OSHOT_API_VERSION; } +oshot_str_t oshot_get_plugin_data_dir() +{ + const fs::path& p = g_current_plugin->data_dir; + if (!fs::exists(p)) + return oshot_str_borrow(NULL); + + return oshot_str_new(p.string().c_str(), p.string().length()); +} + /* ------------------------------------------------------------------ * oshot_str_t lifecycle * ------------------------------------------------------------------ */ diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 981012f..2b2cb0e 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -489,7 +489,7 @@ void ScreenshotTool::RenderOverlay() { ImGui::PushID(plugin->id); - // auto-height, or let plugins set a preferred height + // auto-height ImGui::BeginChild(plugin->name, ImVec2(0.0f, 0.0f), ImGuiChildFlags_Borders); ScopedActivePlugin _(&entry); @@ -1967,6 +1967,41 @@ static void draw_preference_edit_config(const std::function& refresh_mod } } +#ifndef DISABLE_PLUGINS +static void draw_preference_plugin(auto& plugin_dirty, bool& prefs_modified) +{ + ImGui::Text("Edit settings per plugin"); + ImGui::Spacing(); + + for (auto& [id, rt] : g_plugins) + { + oshot_plugin_t* pl = rt.plugin; + if (!pl->render_preferences) + { + spdlog::warn("Plugin '{}' doesn't have a render_preferences() function. Skipping", pl->id); + continue; + } + ScopedActivePlugin _(&rt); + + ImGui::PushID(pl->id); + ImGui::SeparatorText(fmt::format("{} ({})", pl->name, pl->id).c_str()); + ImGui::Spacing(); + + ImGui::BeginChild(pl->name, ImVec2(0.0f, 0.0f), ImGuiWindowFlags_AlwaysAutoResize); + if (pl->render_preferences(rt.state)) + { + plugin_dirty[id] = true; + prefs_modified = true; + } + ImGui::EndChild(); + + ImGui::PopID(); + + ImGui::Spacing(); + } +} +#endif + static void draw_theme_editor() { Config::theme_overrides_t& ov = g_config->theme_overrides; @@ -2057,7 +2092,11 @@ static void draw_theme_editor() void ScreenshotTool::DrawPreferencesWindow() { - static constexpr const char* items[2] = { "Defaults", "Theme" }; +#ifndef DISABLE_PLUGINS + static constexpr const char* items[] = { "Defaults", "Plugins", "Theme" }; +#else + static constexpr const char* items[] = { "Defaults", "Theme" }; +#endif static bool prefs_modified = false; static bool prev_window_open = false; @@ -2065,8 +2104,9 @@ void ScreenshotTool::DrawPreferencesWindow() const bool window_just_opened = !prev_window_open; static PrefTab selected_tab = PrefTab::Defaults; - static Config::config_file_t config_snapshot; // config state at the moment the window opened - static Config::theme_overrides_t theme_snapshot; // theme state at the moment the window opened + static Config::config_file_t config_snapshot; // config state at the moment the window opened + static Config::theme_overrides_t theme_snapshot; // theme state at the moment the window opened + static std::unordered_map plugin_dirty; if (!m_show_window.Has(SubWindow::Preferences)) { @@ -2077,45 +2117,61 @@ void ScreenshotTool::DrawPreferencesWindow() prev_window_open = true; auto save_current_tab = [&]() { - switch (selected_tab) + if (config_snapshot != g_config->File) { - case PrefTab::kNone: break; - case PrefTab::Defaults: - g_config->GenerateConfig(g_config->GetConfigPath(), true); - g_config->LoadConfigFile(g_config->GetConfigPath()); - SyncRuntimeFromConfig(); - if (!g_config->File.theme_file_path.empty()) - g_config->LoadThemeFile(g_config->File.theme_file_path); - apply_imgui_theme(); - config_snapshot = g_config->File; - theme_snapshot = g_config->theme_overrides; - break; + g_config->GenerateConfig(g_config->GetConfigPath(), true); + g_config->LoadConfigFile(g_config->GetConfigPath()); + SyncRuntimeFromConfig(); + if (!g_config->File.theme_file_path.empty()) + g_config->LoadThemeFile(g_config->File.theme_file_path); + apply_imgui_theme(); + config_snapshot = g_config->File; + theme_snapshot = g_config->theme_overrides; + } - case PrefTab::Theme: - if (!g_config->File.theme_file_path.empty()) - { - g_config->GenerateTheme(g_config->File.theme_file_path, true); - g_config->LoadThemeFile(g_config->File.theme_file_path); - color_name_map().clear(); - } - else - { - ImGui::OpenPopup("Theme file path is empty##theme_filepath_empty"); - } + if (theme_snapshot != g_config->theme_overrides) + { + if (!g_config->File.theme_file_path.empty()) + { + g_config->GenerateTheme(g_config->File.theme_file_path, true); + g_config->LoadThemeFile(g_config->File.theme_file_path); + color_name_map().clear(); + } + else + { + ImGui::OpenPopup("Theme file path is empty##theme_filepath_empty"); + } - apply_imgui_theme(); - theme_snapshot = g_config->theme_overrides; - break; + apply_imgui_theme(); + theme_snapshot = g_config->theme_overrides; } + +#ifndef DISABLE_PLUGINS + for (auto& [id, rt] : g_plugins) + { + if (!plugin_dirty[id] || !rt.plugin->on_save_preferences) + continue; + + ScopedActivePlugin _(&rt); + rt.plugin->on_save_preferences(rt.state); + plugin_dirty[id] = false; + } +#endif }; auto discard_current_tab = [&]() { - switch (selected_tab) + g_config->File = config_snapshot; + g_config->theme_overrides = theme_snapshot; +#ifndef DISABLE_PLUGINS + for (auto& [id, rt] : g_plugins) { - case PrefTab::kNone: break; - case PrefTab::Defaults: g_config->File = config_snapshot; break; - case PrefTab::Theme: g_config->theme_overrides = theme_snapshot; break; + if (!plugin_dirty[id] || !rt.plugin->on_discard_preferences) + continue; + ScopedActivePlugin _(&rt); + rt.plugin->on_discard_preferences(rt.state); + plugin_dirty[id] = false; } +#endif }; // Snapshot the config when the window first appears so Discard can restore it. @@ -2161,6 +2217,9 @@ void ScreenshotTool::DrawPreferencesWindow() { case PrefTab::kNone: break; case PrefTab::Defaults: draw_preference_edit_config([&] { RefreshOcrModels(); }, window_just_opened); break; +#ifndef DISABLE_PLUGINS + case PrefTab::Plugins: draw_preference_plugin(plugin_dirty, prefs_modified); break; +#endif case PrefTab::Theme: draw_theme_editor(); break; } ImGui::EndChild(); From 5d44c316a039e10b4ce7163c577b1c729d92ea45 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Thu, 9 Jul 2026 22:28:01 +0200 Subject: [PATCH 26/40] config: unify Config/Cache/plugin config behind shared TomlAPI base Each plugin now gets its own TomlAPI-backed config.toml, loaded at plugin load and persisted via the new SaveFile() after on_save_preferences commits changes. Plugins can still manage their own file/format via oshot_get_plugin_data_dir(). --- include/cache.hpp | 54 +------- include/config.hpp | 215 +++------------------------- include/plugin.hpp | 30 ++-- include/toml_api.hpp | 254 ++++++++++++++++++++++++++++++++++ src/cache.cpp | 18 +-- src/config.cpp | 63 +-------- src/plugins.cpp | 16 ++- src/plugins/oshot_plugin.h | 16 ++- src/plugins/oshot_plugins.cpp | 76 ++++------ src/screenshot_tool.cpp | 7 +- 10 files changed, 369 insertions(+), 380 deletions(-) create mode 100644 include/toml_api.hpp diff --git a/include/cache.hpp b/include/cache.hpp index 8c3a128..6fe5ce5 100644 --- a/include/cache.hpp +++ b/include/cache.hpp @@ -4,8 +4,7 @@ #include #include -#define TOML_HEADER_ONLY 0 -#include "toml++/toml.hpp" +#include "toml_api.hpp" #include "util.hpp" // util.hpp @@ -18,7 +17,7 @@ enum class CacheEntry COUNT }; -class Cache +class Cache : public TomlAPI { public: Cache(const std::string& cache_dir); @@ -28,68 +27,29 @@ class Cache const std::string& GetCacheDirPath() const { return m_cache_dir_path; } - /** - * Get value of a cache variables - * @param value The cache variable "path" (e.g "cache.source-path") - * @param fallback Default value if couldn't retrive value - */ - template - T GetValue(const std::string_view key, const T& fallback, bool dont_expand_var = false) - { - const std::optional& ret = m_tbl["cache"][key].value(); - if constexpr (toml::is_string) - if (!dont_expand_var) - return ret ? expand_var(ret.value()) : expand_var(fallback); - else - return ret ? ret.value() : fallback; - else - return ret.value_or(fallback); - } + using TomlAPI::GetValue; + using TomlAPI::SetValue; - /** - * Get value of a cache variables - * @param value The cache variable "path" (e.g "cache.source-path") - * @param fallback Default value if couldn't retrive value - */ + // CacheEntry convenience overloads are the ONLY thing Cache needs to add now template T GetValue(CacheEntry e, const T& fallback, bool dont_expand_var = false) { return GetValue(m_cache_entries.at(e), fallback, dont_expand_var); } - /** - * Set value of a cache variables - * @param path The cache variable "path" (e.g "cache.source-path") - */ - template - void SetValue(const std::string_view key, const T& value) - { - auto* section = m_tbl["cache"].as_table(); - if (!section) - { - m_tbl.insert_or_assign("cache", toml::table{}); - section = m_tbl["cache"].as_table(); - } - section->insert_or_assign(key, value); - } - - /** - * Set value of a cache variables - * @param path The cache variable "path" (e.g "cache.source-path") - */ template void SetValue(CacheEntry e, const T& value) { SetValue(m_cache_entries.at(e), value); } - const toml::array* GetValueArray(const std::string_view value) const { return m_tbl.at_path(value).as_array(); } +protected: + std::string BuildKey(std::string_view key) const override { return fmt::format("cache.{}", key); } private: static constexpr const char* mk_file_path = "cache.toml"; std::string m_cache_dir_path; - toml::table m_tbl; const std::unordered_map m_cache_entries = { { CacheEntry::AnnColor, "default-color-picker-color" }, diff --git a/include/config.hpp b/include/config.hpp index 89d7523..c7181a7 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -3,32 +3,13 @@ #include #include -#include #include #include "fmt/format.h" +#include "toml_api.hpp" #include "util.hpp" -#define TOML_HEADER_ONLY 0 -#include "toml++/toml.hpp" - -enum class ValueType -{ - kNone, - kString, - kBool, - kInt -}; - -struct override_config_value_t -{ - ValueType value_type = ValueType::kNone; - std::string string_value = ""; - bool bool_value = false; - int int_value = 0; -}; - -class Config +class Config : public TomlAPI { public: // Create .config directories and files and load the config file (args or default) @@ -47,19 +28,20 @@ class Config #else std::string ocr_path = "./models"; #endif - std::string ocr_get_repo = "tesseract-ocr/tessdata"; - std::string ocr_model = "eng"; - std::string theme_style = "auto"; - std::string theme_file_path = "theme.toml"; - std::string image_out_fmt = "oshot_{:%F_%H-%M}"; - int delay = 0; - bool allow_out_edit = false; - bool real_full_screen = false; - bool show_text_tools = true; - bool enable_vsync = true; - bool render_anns = true; - bool pref_conf_to_env = false; - bool ctrl_c_copy_img = true; + std::string ocr_get_repo = "tesseract-ocr/tessdata"; + std::string ocr_model = "eng"; + std::string theme_style = "auto"; + std::string theme_file_path = "theme.toml"; + std::string image_out_fmt = "oshot_{:%F_%H-%M}"; + int delay = 0; + bool allow_out_edit = false; + bool real_full_screen = false; + bool show_text_tools = true; + bool enable_vsync = true; + bool render_anns = true; + bool pref_conf_to_env = false; + bool ctrl_c_copy_img = true; + std::vector fonts; bool operator==(const config_file_t&) const = default; @@ -125,173 +107,27 @@ class Config */ void GenerateTheme(const std::string& filename, const bool force = false); - /** - * Override a config value from --override - * @param str The value to override. - * Must have a '=' for separating the name and value to override. - * NO spaces between - */ - void OverrideOption(const std::string& opt); - - /** - * Override a config value from --override - * @param key The value name to override. - * Must have a '=' for separating the name and value to override. - * NO spaces between - * @param value The value that will overwrite - */ - template - void OverrideOption(const std::string& key, const T& value) - { - override_config_value_t o; - if constexpr (std::is_same_v) - { - o.value_type = ValueType::kBool; - o.bool_value = value; - } - else if constexpr (std::is_convertible_v) - { - o.value_type = ValueType::kString; - o.string_value = value; - } - else if constexpr (std::is_convertible_v) - { - o.value_type = ValueType::kInt; - o.int_value = value; - } - - m_overrides[key] = std::move(o); - } - - /** - * Set value of a config variables - * @param path The config variable "path" (e.g "cache.source-path") - */ - template - void SetValue(const std::string_view key, const T& value) - { - toml::table* section = &m_tbl; - size_t start = 0; - - for (;;) - { - size_t dot = key.find('.', start); - if (dot == key.npos) - { - section->insert_or_assign(key.substr(start), value); - return; - } - - const std::string_view part = key.substr(start, dot - start); - auto* next = section->get(part); - if (!next || !next->is_table()) - { - section->insert_or_assign(part, toml::table{}); - next = section->get(part); - } - section = next->as_table(); - start = dot + 1; - } - } + using TomlAPI::GetValue; + using TomlAPI::SetValue; - /** - * Get value of config variables - * @param value The config variable "path" (e.g "config.source-path") - * @param fallback Default value if couldn't retrive value - */ template - T GetValue(const std::string_view value, - const T& fallback, - bool dont_expand_var = false, - bool is_theme = false) const - { - const auto& overridePos = m_overrides.find(value.data()); - - if (overridePos != m_overrides.end()) - { - const auto& ov = overridePos->second; - if constexpr (std::is_same()) - if (ov.value_type == ValueType::kBool) - return ov.bool_value; - if constexpr (std::is_same()) - if (ov.value_type == ValueType::kString) - return ov.string_value; - if constexpr (std::is_same()) - if (ov.value_type == ValueType::kInt) - return ov.int_value; - } - - const std::optional& ret = - is_theme ? m_theme_tbl.at_path(value).value() : m_tbl.at_path(value).value(); - if constexpr (toml::is_string) - if (!dont_expand_var) - return ret ? expand_var(ret.value()) : expand_var(fallback); - else - return ret ? ret.value() : fallback; - else - return ret.value_or(fallback); - } - - std::vector GetValueArrayStr(const std::string_view value, - const std::vector& fallback) const + T GetThemeValue(const std::string_view value, const T& fallback, bool dont_expand_var = true) const { - std::vector ret; - - // https://stackoverflow.com/a/78266628 - if (const toml::array* array_it = m_tbl.at_path(value).as_array()) - { - ret.reserve(array_it->size()); - array_it->for_each([&](auto&& el) { - if (const toml::value* str_elem = el.as_string()) - ret.push_back((*str_elem)->data()); - }); - - return ret; - } - else - { - return fallback; - } + return m_theme.GetValue(fmt::format("theme.{}", value), fallback, dont_expand_var); } - const toml::array* GetValueArray(const std::string_view value) const { return m_tbl.at_path(value).as_array(); } - - /** - * Get the theme style variable and return a rgba type value - * @param value The value we want - * @param fallback The default value if it doesn't exists - * @return rgba type variable - */ template T GetThemeStyleValue(const std::string_view value, const T& fallback, bool dont_expand_var = true) const { - return GetValue(fmt::format("theme.style.{}", value), fallback, dont_expand_var, true); + return m_theme.GetValue(fmt::format("theme.style.{}", value), fallback, dont_expand_var); } - /** - * Get the theme style variable and return a rgba type value - * @param value The value we want - * @param fallback The default value if it doesn't exists - * @return rgba type variable - */ - template - T GetThemeValue(const std::string_view value, const T& fallback, bool dont_expand_var = true) const - { - return GetValue(fmt::format("theme.{}", value), fallback, dont_expand_var, true); - } - - /** - * Get the theme color variable and return a rgba type value - * @param value The value we want - * @param fallback The default value if it doesn't exists - * @return rgba type variable - */ uint32_t GetThemeColorValue(const std::string_view value, const std::string& fallback, bool dont_expand_var = true) const { uint32_t out; - hexstr_to_col(GetValue(fmt::format("theme.colors.{}", value), fallback, dont_expand_var, true), + hexstr_to_col(m_theme.GetValue(fmt::format("theme.colors.{}", value), fallback, dont_expand_var), out); return out; } @@ -301,13 +137,8 @@ class Config const std::string& GetConfigDirPath() const { return m_config_dir_path; } private: - // Parsed config from LoadConfigFile() - toml::table m_tbl; - // Parsed theme from LoadThemeFile() - toml::table m_theme_tbl; - - std::unordered_map m_overrides; + TomlAPI m_theme; std::string m_config_path; std::string m_theme_path; diff --git a/include/plugin.hpp b/include/plugin.hpp index ae0bf56..da03500 100644 --- a/include/plugin.hpp +++ b/include/plugin.hpp @@ -5,6 +5,9 @@ # include "../src/plugins/oshot_plugin.h" # include "dylib.hpp" +# include "toml_api.hpp" + +namespace fs = std::filesystem; struct plugin_runtime_t; @@ -20,26 +23,33 @@ struct ScopedActivePlugin struct plugin_runtime_t { - std::string id; // must be validated - std::string config_prefix; // cached "plugins.." - std::filesystem::path data_dir; + std::string id; // must be validated + std::string config_prefix; // cached "plugins.." + fs::path data_dir; oshot_plugin_t* plugin = nullptr; // non-owning and static, process-lifetime per ABI contract void* state = nullptr; // owned by the plugin; released via plugin->destroy() dylib::library lib; - plugin_runtime_t(std::string id, - std::string config_prefix, - std::filesystem::path data_dir, - oshot_plugin_t* plugin, - void* state, - dylib::library lib) + TomlAPI config; // this plugin's own config, loaded from + fs::path config_path; // ~/.config/oshot/plugins//config.toml + + plugin_runtime_t(std::string id, + std::string config_prefix, + fs::path data_dir, + oshot_plugin_t* plugin, + void* state, + dylib::library lib, + TomlAPI config, + fs::path config_path) : id(std::move(id)), config_prefix(std::move(config_prefix)), data_dir(std::move(data_dir)), plugin(plugin), state(state), - lib(std::move(lib)) + lib(std::move(lib)), + config(std::move(config)), + config_path(std::move(config_path)) {} ~plugin_runtime_t() diff --git a/include/toml_api.hpp b/include/toml_api.hpp new file mode 100644 index 0000000..3e33d2e --- /dev/null +++ b/include/toml_api.hpp @@ -0,0 +1,254 @@ +#ifndef _TOML_API_HPP_ +#define _TOML_API_HPP_ + +#include +#include +#include +#include + +#include "util.hpp" + +#define TOML_HEADER_ONLY 0 +#include "toml++/toml.hpp" + +enum class ValueType +{ + kNone, + kString, + kBool, + kInt +}; + +struct override_config_value_t +{ + ValueType value_type = ValueType::kNone; + std::string string_value = ""; + bool bool_value = false; + int int_value = 0; +}; + +class TomlAPI +{ +public: + virtual ~TomlAPI() = default; + + template + void SetValue(const std::string_view key, const T& value) + { + SetValueImpl(BuildKey(key), value); + } + + template + T GetValue(const std::string_view key, const T& fallback, bool dont_expand_var = false) const + { + return GetValueImpl(BuildKey(key), fallback, dont_expand_var); + } + + /** + * Load config file and parse every config variables + * @param filename The config file path + */ + void LoadFile(const std::string& filename) + { + try + { + m_tbl = toml::parse_file(filename); + } + catch (const toml::parse_error& err) + { + die("Parsing toml file '{}' failed:\n" + "{}\n" + "\t(error occurred at line {} column {})", + filename, + err.description(), + err.source().begin.line, + err.source().begin.column); + } + } + + bool SaveFile(const std::string& tofile) + { + std::stringstream ss; + ss << m_tbl; + return SaveFile(ss.str(), tofile); + } + + // https://github.com/hyprwm/Hyprland/blob/2d2a5bebff72c73cd27db3b9e954b8fa2a7623e8/hyprpm/src/core/DataState.cpp#L24 + bool SaveFile(const std::string& str, const std::string& to) + { + // create temp file in a safe temp root + const fs::path temp_state = (fs::temp_directory_path() / ".temp-cache"); + std::ofstream of(temp_state, std::ios::trunc); + if (!of.good()) + return false; + + of << str; + of.close(); + + return fs::copy_file(temp_state, to, fs::copy_options::overwrite_existing); + } + + /** + * Override a config value from --override + * @param str The value to override. + * Must have a '=' for separating the name and value to override. + * NO spaces between + */ + void OverrideOption(const std::string& opt) + { + const size_t pos = opt.find('='); + if (pos == std::string::npos) + die("Option to override '{}' doesn't have an equal sign '=' for separating name and value\n" + "See --help for more information", + opt); + + std::string name{ opt.substr(0, pos) }; + const std::string& value = opt.substr(pos + 1); + + // usually the user finds incovinient to write "default.foo" + // for general config options + if (name.find('.') == name.npos) + name.insert(0, "default."); + + if (value == "true") + m_overrides[name] = { .value_type = ValueType::kBool, .bool_value = true }; + else if (value == "false") + m_overrides[name] = { .value_type = ValueType::kBool, .bool_value = false }; + else if ((value[0] == '"' && value.back() == '"') || (value[0] == '\'' && value.back() == '\'')) + m_overrides[name] = { .value_type = ValueType::kString, .string_value = value.substr(1, value.size() - 2) }; + else if (std::ranges::all_of(value, ::isdigit)) + m_overrides[name] = { .value_type = ValueType::kInt, .int_value = std::stoi(value) }; + else + die("looks like override value '{}' from '{}' is neither a bool, int or string value", value, name); + } + + /** + * Override a config value from --override + * @param key The value name to override. + * Must have a '=' for separating the name and value to override. + * NO spaces between + * @param value The value that will overwrite + */ + template + void OverrideOption(const std::string& key, const T& value) + { + override_config_value_t o; + if constexpr (std::is_same_v) + { + o.value_type = ValueType::kBool; + o.bool_value = value; + } + else if constexpr (std::is_convertible_v) + { + o.value_type = ValueType::kString; + o.string_value = value; + } + else if constexpr (std::is_convertible_v) + { + o.value_type = ValueType::kInt; + o.int_value = value; + } + + m_overrides[key] = std::move(o); + } + + std::vector GetValueArrayStr(const std::string_view value, + const std::vector& fallback) const + { + std::vector ret; + + // https://stackoverflow.com/a/78266628 + if (const toml::array* array_it = m_tbl.at_path(value).as_array()) + { + ret.reserve(array_it->size()); + array_it->for_each([&](auto&& el) { + if (const toml::value* str_elem = el.as_string()) + ret.push_back((*str_elem)->data()); + }); + + return ret; + } + else + { + return fallback; + } + } + + toml::table& GetTbl() { return m_tbl; } + const toml::table& GetTbl() const { return m_tbl; } + const toml::array* GetValueArray(const std::string_view value) const { return m_tbl.at_path(value).as_array(); } + +protected: + virtual std::string BuildKey(const std::string_view key) const { return std::string(key); } + + toml::table m_tbl; + + std::unordered_map m_overrides; + + /** + * Set value of a config variables + * @param path The config variable "path" (e.g "cache.source-path") + */ + template + void SetValueImpl(const std::string_view key, const T& value) + { + toml::table* section = &m_tbl; + size_t start = 0; + + for (;;) + { + size_t dot = key.find('.', start); + if (dot == key.npos) + { + section->insert_or_assign(key.substr(start), value); + return; + } + + const std::string_view part = key.substr(start, dot - start); + auto* next = section->get(part); + if (!next || !next->is_table()) + { + section->insert_or_assign(part, toml::table{}); + next = section->get(part); + } + section = next->as_table(); + start = dot + 1; + } + } + + /** + * Get value of config variables + * @param value The config variable "path" (e.g "config.source-path") + * @param fallback Default value if couldn't retrive value + */ + template + T GetValueImpl(const std::string_view value, const T& fallback, bool dont_expand_var = false) const + { + const auto& overridePos = m_overrides.find(value.data()); + + if (overridePos != m_overrides.end()) + { + const auto& ov = overridePos->second; + if constexpr (std::is_same()) + if (ov.value_type == ValueType::kBool) + return ov.bool_value; + if constexpr (std::is_same()) + if (ov.value_type == ValueType::kString) + return ov.string_value; + if constexpr (std::is_same()) + if (ov.value_type == ValueType::kInt) + return ov.int_value; + } + + const std::optional& ret = m_tbl.at_path(value).value(); + if constexpr (toml::is_string) + if (!dont_expand_var) + return ret ? expand_var(ret.value()) : expand_var(fallback); + else + return ret ? ret.value() : fallback; + else + return ret.value_or(fallback); + } +}; + +#endif // !_TOML_API_HPP_ diff --git a/src/cache.cpp b/src/cache.cpp index ad53c58..e308b1f 100644 --- a/src/cache.cpp +++ b/src/cache.cpp @@ -1,28 +1,12 @@ #include "cache.hpp" #include -#include #include #include "fmt/format.h" #include "toml++/toml.hpp" #include "util.hpp" -// https://github.com/hyprwm/Hyprland/blob/2d2a5bebff72c73cd27db3b9e954b8fa2a7623e8/hyprpm/src/core/DataState.cpp#L24 -static bool write_cache(const std::string& str, const std::string& to) -{ - // create temp file in a safe temp root - const fs::path temp_state = (fs::temp_directory_path() / ".temp-cache"); - std::ofstream of(temp_state, std::ios::trunc); - if (!of.good()) - return false; - - of << str; - of.close(); - - return fs::copy_file(temp_state, to, fs::copy_options::overwrite_existing); -} - Cache::Cache(const std::string& cache_dir) : m_cache_dir_path(cache_dir) { if (!fs::exists(cache_dir)) @@ -43,7 +27,7 @@ Cache::~Cache() "# YOU GONNA MESS SHIT UP. unless you know what you doing ofc\n"; ss << m_tbl; - if (!write_cache(ss.str(), mk_file_path)) + if (!SaveFile(ss.str(), mk_file_path)) error("Failed to write cache entry at path '{}'", mk_file_path); } diff --git a/src/config.cpp b/src/config.cpp index f90df8b..282a134 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1,6 +1,5 @@ #include "config.hpp" -#include #include #include #include @@ -29,20 +28,7 @@ Config::Config(const fs::path& configFile, const fs::path& configDir) void Config::LoadConfigFile(const std::string& filename) { - try - { - m_tbl = toml::parse_file(filename); - } - catch (const toml::parse_error& err) - { - die("Parsing config file '{}' failed:\n" - "{}\n" - "\t(error occurred at line {} column {})", - filename, - err.description(), - err.source().begin.line, - err.source().begin.column); - } + LoadFile(filename); File.ocr_path = GetValue("default.ocr-path", File.ocr_path); File.ocr_get_repo = GetValue("default.ocr-repo-downlaod", "tesseract-ocr/tessdata"); @@ -71,7 +57,6 @@ void Config::LoadConfigFile(const std::string& filename) void Config::LoadThemeFile(const std::string& filename) { m_theme_path = filename; - m_theme_tbl = {}; theme_overrides = {}; theme_overrides.colors.clear(); @@ -82,24 +67,12 @@ void Config::LoadThemeFile(const std::string& filename) if (fs::exists(filename)) { - try - { - m_theme_tbl = toml::parse_file(filename); - } - catch (const toml::parse_error& err) - { - die("Parsing theme file '{}' failed:\n" - "{}\n" - "\t(error occurred at line {} column {})", - filename, - err.description(), - err.source().begin.line, - err.source().begin.column); - } + m_theme.LoadFile(filename); + m_theme_path = filename; } theme_overrides_t& ov = theme_overrides; - if (const toml::table* colors = m_theme_tbl.at_path("theme.colors").as_table()) + if (const toml::table* colors = m_theme.GetTbl().at_path("theme.colors").as_table()) { colors->for_each( [&](const toml::key& k, const toml::value& v) { ov.colors[std::string(k.str())] = v.get(); }); @@ -115,34 +88,6 @@ void Config::LoadThemeFile(const std::string& filename) ov.smooth_animations = GetThemeValue("smooth-animations", false); } -void Config::OverrideOption(const std::string& opt) -{ - const size_t pos = opt.find('='); - if (pos == std::string::npos) - die("Option to override '{}' doesn't have an equal sign '=' for separating name and value\n" - "See --help for more information", - opt); - - std::string name{ opt.substr(0, pos) }; - const std::string& value = opt.substr(pos + 1); - - // usually the user finds incovinient to write "default.foo" - // for general config options - if (name.find('.') == name.npos) - name.insert(0, "default."); - - if (value == "true") - m_overrides[name] = { .value_type = ValueType::kBool, .bool_value = true }; - else if (value == "false") - m_overrides[name] = { .value_type = ValueType::kBool, .bool_value = false }; - else if ((value[0] == '"' && value.back() == '"') || (value[0] == '\'' && value.back() == '\'')) - m_overrides[name] = { .value_type = ValueType::kString, .string_value = value.substr(1, value.size() - 2) }; - else if (std::ranges::all_of(value, ::isdigit)) - m_overrides[name] = { .value_type = ValueType::kInt, .int_value = std::stoi(value) }; - else - die("looks like override value '{}' from '{}' is neither a bool, int or string value", value, name); -} - void Config::GenerateConfig(const std::string& filename, const bool force) { if (!force && fs::exists(filename) && diff --git a/src/plugins.cpp b/src/plugins.cpp index 7af95ab..f7176c9 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -71,13 +71,25 @@ void load_plugins() continue; } + fs::path plugin_config_dir = get_config_dir() / "plugins" / plugin->id; + fs::path plugin_config_path = plugin_config_dir / "config.toml"; + + fs::create_directories(plugin_config_dir); + + TomlAPI toml_api; + if (!fs::exists(plugin_config_path)) + std::ofstream(plugin_config_path).close(); + toml_api.LoadFile(plugin_config_path); + auto [it, inserted] = g_plugins.try_emplace(plugin->id, plugin->id, fmt::format("plugins.{}.", plugin->id), - get_config_dir() / "plugins" / plugin->id, + std::move(plugin_config_dir), plugin, nullptr, // state filled in below - std::move(lib)); + std::move(lib), + std::move(toml_api), + std::move(plugin_config_path)); if (!inserted) { spdlog::warn("Duplicate plugin '{}'", plugin->id); diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h index 4a3834f..2293014 100644 --- a/src/plugins/oshot_plugin.h +++ b/src/plugins/oshot_plugin.h @@ -95,7 +95,13 @@ typedef struct /* ------------------------------------------------------------------ * ABI / identity * ------------------------------------------------------------------ */ -uint32_t oshot_get_abi_version(void); +uint32_t oshot_get_abi_version(void); + +/* Returns an owned oshot_str_t (caller must oshot_str_free it) pointing + * to this plugin's private data directory, e.g. + * ~/.config/oshot/plugins// + * The host guarantees this directory exists by the time any plugin + * callback can run. Created at plugin-load time, before init(). */ oshot_str_t oshot_get_plugin_data_dir(void); /* ------------------------------------------------------------------ @@ -122,7 +128,13 @@ void oshot_warn(oshot_str_t str); // oshot_log(WARN, str); void oshot_info(oshot_str_t str); // oshot_log(INFO, str); /* ------------------------------------------------------------------ - * Config (plugin namespace only) + * Config (optional convenience helper) + * + * These functions persist plugin config as TOML, in a file the host + * manages on your behalf. You are not required to use them, if you + * prefer JSON, YAML, or anything else, ignore this section entirely + * and read/write your own file under the path returned by + * oshot_get_plugin_data_dir(), using whatever library you like. * ------------------------------------------------------------------ */ oshot_str_t oshot_config_get_string(const char* key, oshot_str_t fallback); bool oshot_config_get_bool(const char* key, bool fallback); diff --git a/src/plugins/oshot_plugins.cpp b/src/plugins/oshot_plugins.cpp index 8fae1ef..9065da5 100644 --- a/src/plugins/oshot_plugins.cpp +++ b/src/plugins/oshot_plugins.cpp @@ -1,5 +1,4 @@ #include "cache.hpp" -#include "config.hpp" #include "fmt/format.h" #include "oshot_plugin.h" #include "plugin.hpp" @@ -53,6 +52,29 @@ static std::string prefixed_key(const char* key) return g_current_plugin->config_prefix + key; } +static void set_toml_value(TomlAPI* api, const char* key, const oshot_value_t* val) +{ + if (val->kind < OSHOT_VAL_STRING || val->kind > OSHOT_VAL_DOUBLE) + { + oshot_error(oshot_str_borrow("Failed to set toml value: unknown kind")); + return; + } + + switch (val->kind) + { + case OSValueKind::OSHOT_VAL_STRING: + if (!val->s.p) + oshot_error(oshot_str_borrow("Failed to set toml value: string has null pointer")); + else + api->SetValue(key, std::string(val->s.p, val->s.len)); + break; + + case OSValueKind::OSHOT_VAL_INT64: api->SetValue(key, val->i); break; + case OSValueKind::OSHOT_VAL_DOUBLE: api->SetValue(key, val->d); break; + case OSValueKind::OSHOT_VAL_BOOL: api->SetValue(key, val->b); break; + } +} + /* ------------------------------------------------------------------ * ABI / identity * ------------------------------------------------------------------ */ @@ -142,7 +164,7 @@ void oshot_info(oshot_str_t str) template static T get_config_value(const char* key, T fallback) { - return g_config->GetValue(prefixed_key(key), fallback); + return g_current_plugin->config.GetValue(key, fallback); } oshot_str_t oshot_config_get_string(const char* key, oshot_str_t fallback) @@ -168,7 +190,7 @@ double oshot_config_get_double(const char* key, double fallback) size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max) { - return toml_get_array(g_config->GetValueArray(prefixed_key(key)), out, max); + return toml_get_array(g_current_plugin->config.GetValueArray(key), out, max); } // --------------------- @@ -177,7 +199,7 @@ size_t oshot_config_get_array(const char* key, oshot_value_t** out, size_t max) template static void set_config_value(const char* key, T val) { - g_config->SetValue(prefixed_key(key), val); + g_current_plugin->config.SetValue(key, val); } void oshot_config_set_string(const char* key, oshot_str_t val) @@ -202,28 +224,7 @@ void oshot_config_set_double(const char* key, double val) void oshot_config_set_value(const char* key, const oshot_value_t* val) { - if (val->kind < OSHOT_VAL_STRING || val->kind > OSHOT_VAL_DOUBLE) - { - oshot_log(OSLogLevel::OSHOT_LOG_ERROR, oshot_str_borrow("Failed to set config value: unknown kind")); - return; - } - - switch (val->kind) - { - case OSValueKind::OSHOT_VAL_STRING: - if (!val->s.p) - oshot_log(OSLogLevel::OSHOT_LOG_ERROR, - oshot_str_borrow("Failed to set config value: string has null pointer")); - else - g_config->SetValue(prefixed_key(key), std::string(val->s.p, val->s.len)); - break; - - case OSValueKind::OSHOT_VAL_INT64: g_config->SetValue(prefixed_key(key), val->i); break; - - case OSValueKind::OSHOT_VAL_DOUBLE: g_config->SetValue(prefixed_key(key), val->d); break; - - case OSValueKind::OSHOT_VAL_BOOL: g_config->SetValue(prefixed_key(key), val->b); break; - } + set_toml_value(&g_current_plugin->config, key, val); } /* ------------------------------------------------------------------ @@ -296,28 +297,7 @@ void oshot_cache_set_double(const char* key, double val) void oshot_cache_set_value(const char* key, const oshot_value_t* val) { - if (val->kind < OSHOT_VAL_STRING || val->kind > OSHOT_VAL_DOUBLE) - { - oshot_log(OSLogLevel::OSHOT_LOG_ERROR, oshot_str_borrow("Failed to set cache value: unknown kind")); - return; - } - - switch (val->kind) - { - case OSValueKind::OSHOT_VAL_STRING: - if (!val->s.p) - oshot_log(OSLogLevel::OSHOT_LOG_ERROR, - oshot_str_borrow("Failed to set cache value: string has null pointer")); - else - g_cache->SetValue(prefixed_key(key), std::string(val->s.p, val->s.len)); - break; - - case OSValueKind::OSHOT_VAL_INT64: g_cache->SetValue(prefixed_key(key), val->i); break; - - case OSValueKind::OSHOT_VAL_DOUBLE: g_cache->SetValue(prefixed_key(key), val->d); break; - - case OSValueKind::OSHOT_VAL_BOOL: g_cache->SetValue(prefixed_key(key), val->b); break; - } + set_toml_value(g_cache.get(), prefixed_key(key).c_str(), val); } /* ------------------------------------------------------------------ diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 2b2cb0e..f1d88da 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -2153,7 +2153,8 @@ void ScreenshotTool::DrawPreferencesWindow() continue; ScopedActivePlugin _(&rt); - rt.plugin->on_save_preferences(rt.state); + rt.plugin->on_save_preferences(rt.state); // plugin calls oshot_config_set_* here, populating rt.config + rt.config.SaveFile(rt.config_path.string()); plugin_dirty[id] = false; } #endif @@ -2218,9 +2219,9 @@ void ScreenshotTool::DrawPreferencesWindow() case PrefTab::kNone: break; case PrefTab::Defaults: draw_preference_edit_config([&] { RefreshOcrModels(); }, window_just_opened); break; #ifndef DISABLE_PLUGINS - case PrefTab::Plugins: draw_preference_plugin(plugin_dirty, prefs_modified); break; + case PrefTab::Plugins: draw_preference_plugin(plugin_dirty, prefs_modified); break; #endif - case PrefTab::Theme: draw_theme_editor(); break; + case PrefTab::Theme: draw_theme_editor(); break; } ImGui::EndChild(); From 389fc3f765be24592ea26be137dbe71e4e647b9e Mon Sep 17 00:00:00 2001 From: Toni500git Date: Thu, 9 Jul 2026 22:30:30 +0200 Subject: [PATCH 27/40] fix builds --- src/plugins.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins.cpp b/src/plugins.cpp index f7176c9..8b8e178 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -1,6 +1,5 @@ #ifndef DISABLE_PLUGINS -# include "fmt/std.h" # include "plugin.hpp" # include "util.hpp" @@ -28,7 +27,7 @@ void load_plugins() if (path.filename().string() != expected) { spdlog::warn("Found plugin filename '{}' at {}, expected '{}'. Skipping", - path.filename(), + path.filename().string(), path.parent_path().string(), expected); continue; From cccdc0cbcf5bf31b2a0d4b01dd00804586a4f4b3 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 10 Jul 2026 18:01:22 +0200 Subject: [PATCH 28/40] some changes --- include/cache.hpp | 2 +- include/toml_api.hpp | 6 ++++-- src/cache.cpp | 20 ++------------------ src/config.cpp | 4 ++-- src/screenshot_tool.cpp | 16 ++++++++-------- 5 files changed, 17 insertions(+), 31 deletions(-) diff --git a/include/cache.hpp b/include/cache.hpp index 6fe5ce5..46c44e0 100644 --- a/include/cache.hpp +++ b/include/cache.hpp @@ -44,7 +44,7 @@ class Cache : public TomlAPI } protected: - std::string BuildKey(std::string_view key) const override { return fmt::format("cache.{}", key); } + std::string BuildKey(const std::string_view key) const override { return fmt::format("cache.{}", key); } private: static constexpr const char* mk_file_path = "cache.toml"; diff --git a/include/toml_api.hpp b/include/toml_api.hpp index 3e33d2e..ff5426b 100644 --- a/include/toml_api.hpp +++ b/include/toml_api.hpp @@ -48,7 +48,7 @@ class TomlAPI * Load config file and parse every config variables * @param filename The config file path */ - void LoadFile(const std::string& filename) + void LoadFile(const std::string& filename, bool do_die = false) { try { @@ -56,13 +56,15 @@ class TomlAPI } catch (const toml::parse_error& err) { - die("Parsing toml file '{}' failed:\n" + const std::string& str = fmt::format( + "Parsing toml file '{}' failed:\n" "{}\n" "\t(error occurred at line {} column {})", filename, err.description(), err.source().begin.line, err.source().begin.column); + do_die ? die("{}", str) : error("{}", str); } } diff --git a/src/cache.cpp b/src/cache.cpp index e308b1f..cad683e 100644 --- a/src/cache.cpp +++ b/src/cache.cpp @@ -3,8 +3,6 @@ #include #include -#include "fmt/format.h" -#include "toml++/toml.hpp" #include "util.hpp" Cache::Cache(const std::string& cache_dir) : m_cache_dir_path(cache_dir) @@ -38,22 +36,8 @@ Result<> Cache::LoadCacheFile() // snapshot and switch to that directory. CdGuard guard(m_cache_dir_path); - try - { - if (fs::exists(mk_file_path)) - m_tbl = toml::parse_file(mk_file_path); - } - catch (const toml::parse_error& err) - { - return Err( - fmt::format("Parsing cache file '{}' failed:\n" - "{}\n" - "\t(error occurred at line {} column {})", - mk_file_path, - err.description(), - err.source().begin.line, - err.source().begin.column)); - } + if (fs::exists(mk_file_path)) + LoadFile(mk_file_path); return Ok(); } diff --git a/src/config.cpp b/src/config.cpp index 282a134..7987f87 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -6,7 +6,6 @@ #include "fmt/base.h" #include "fmt/os.h" -#include "toml++/toml.hpp" #include "util.hpp" Config::Config(const fs::path& configFile, const fs::path& configDir) @@ -17,6 +16,7 @@ Config::Config(const fs::path& configFile, const fs::path& configDir) spdlog::warn("Oshot config folder was not found, creating folders at {}!", configDir.string()); fs::create_directories(configDir); fs::create_directories(configDir / "models"); + fs::create_directories(configDir / "plugins"); } if (!fs::exists(configFile)) @@ -28,7 +28,7 @@ Config::Config(const fs::path& configFile, const fs::path& configDir) void Config::LoadConfigFile(const std::string& filename) { - LoadFile(filename); + LoadFile(filename, true); File.ocr_path = GetValue("default.ocr-path", File.ocr_path); File.ocr_get_repo = GetValue("default.ocr-repo-downlaod", "tesseract-ocr/tessdata"); diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index f1d88da..8aea4d6 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -1235,7 +1235,7 @@ void ScreenshotTool::DrawMenuItems() if (ImGui::MenuItem("Download OCR model")) m_show_window.Set(SubWindow::OcrDownload); ImGui::Separator(); - if (ImGui::MenuItem("Show Logs")) + if (ImGui::MenuItem("View Logs")) m_show_window.Set(SubWindow::Logs); ImGui::EndMenu(); } @@ -1270,11 +1270,11 @@ void ScreenshotTool::DrawMenuItems() // Centered labels text_display = centered_text("oshot v" VERSION); - ImGui::Text("%s", text_display.data()); + ImGui::TextUnformatted(text_display.data()); ImGui::Spacing(); text_display = centered_text("Screenshot tool for extracting text on the fly"); - ImGui::Text("%s", text_display.data()); + ImGui::TextUnformatted(text_display.data()); ImGui::Spacing(); #ifdef DISABLE_PLUGINS @@ -1289,7 +1289,7 @@ void ScreenshotTool::DrawMenuItems() { ImGui::BeginChild("##scrollable_region", ImVec2(0, 100), false, ImGuiWindowFlags_HorizontalScrollbar); - ImGui::Text("%s", version_infos.c_str()); + ImGui::TextUnformatted(version_infos.c_str()); if (ImGui::Button("Copy text")) g_clipboard.CopyText(version_infos); @@ -1297,12 +1297,12 @@ void ScreenshotTool::DrawMenuItems() ImGui::TreePop(); } - ImGui::Text("Version: v" VERSION); - ImGui::Text("Created by: Toni500"); - ImGui::Text("Copyright © 2026"); + ImGui::TextUnformatted("Version: v" VERSION); + ImGui::TextUnformatted("Created by: Toni500"); + ImGui::TextUnformatted("Copyright © 2026"); ImGui::Spacing(); - ImGui::Text("Support the project at "); + ImGui::TextUnformatted("Support the project at "); ImGui::SameLine(0, 1); if (ImGui::TextLinkOpenURL("Toni500github/oshot", "https://github.com/Toni500github/oshot")) minimize_window(); From 1b5e2f8bdfe44eadc15ef9df3d79082134f4ee0a Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 10 Jul 2026 20:05:10 +0200 Subject: [PATCH 29/40] annotation(menu): separate color picker settings into preferences --- include/config.hpp | 12 ++++++++++ include/screenshot_tool.hpp | 8 +++++++ src/config.cpp | 2 ++ src/screenshot_tool.cpp | 47 +++++++++++++++++-------------------- 4 files changed, 44 insertions(+), 25 deletions(-) diff --git a/include/config.hpp b/include/config.hpp index c7181a7..84ecdbf 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -34,6 +34,8 @@ class Config : public TomlAPI std::string theme_file_path = "theme.toml"; std::string image_out_fmt = "oshot_{:%F_%H-%M}"; int delay = 0; + int color_picker = 0; // 0 = "Bar - Square"; 1 = "Wheel - Triangle"; + int cpa_mode = 2; // color_picker_alpha_mode bool allow_out_edit = false; bool real_full_screen = false; bool show_text_tools = true; @@ -167,6 +169,16 @@ ocr-repo-downlaod = "{}" # Doesn't affect if opening external image (i.e. -f flag) delay = {} +# Which ImGui color picker widget to use for annotation colors. +# 0 = "Bar - Square"; 1 = "Wheel - Triangle" +color-picker = {} + +# Alpha (transparency) editing behavior for the annotation color picker. +# 0 = Disabled (alpha not editable) +# 1 = Inline slider +# 2 = Dedicated alpha bar +color-picker-alpha-mode = {} + # On some desktop environments (e.g. MATE), the compositor may cause # the capture window to look grainy or pixelated. Enabling this uses exclusive # fullscreen mode which bypasses the compositor and fixes it. diff --git a/include/screenshot_tool.hpp b/include/screenshot_tool.hpp index 0fa893c..ea7bf47 100644 --- a/include/screenshot_tool.hpp +++ b/include/screenshot_tool.hpp @@ -93,6 +93,14 @@ enum class SubWindow COUNT }; +// Used for config.hpp +enum class ColorPickerAlpha +{ + Disabled = 0, // alpha channel is not editable + Inline = 1, // alpha editable via the picker's inline slider + Bar = 2, // alpha editable via a dedicated alpha bar +}; + enum class CurrentAction { IsDrawing, diff --git a/src/config.cpp b/src/config.cpp index 7987f87..d21b305 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -110,6 +110,8 @@ void Config::GenerateConfig(const std::string& filename, const bool force) File.ocr_model, File.ocr_get_repo, File.delay, + File.color_picker, + File.cpa_mode, File.real_full_screen, File.enable_vsync, File.allow_out_edit, diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 8aea4d6..40261b5 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -1520,9 +1520,6 @@ void ScreenshotTool::DrawBarDecodeTools() void ScreenshotTool::DrawAnnotationToolbar() { - static int item_picker = 0; - static constexpr const char* color_pickers[2] = { "Bar - Square", "Wheel - Triangle" }; - const float sel_x = m_selection.get_x(); const float sel_y = m_selection.get_y(); const float sel_h = m_selection.get_height(); @@ -1577,7 +1574,15 @@ void ScreenshotTool::DrawAnnotationToolbar() else m_tool_thickness[idx(m_current_tool)] = std::clamp(m_tool_thickness[idx(m_current_tool)], 1.0f, 10.0f); - static ImGuiColorEditFlags color_picker_flags = ImGuiColorEditFlags_AlphaBar; + ImGuiColorEditFlags flags = g_config->File.color_picker == 0 ? ImGuiColorEditFlags_PickerHueBar + : ImGuiColorEditFlags_PickerHueWheel; + + switch (ColorPickerAlpha(g_config->File.cpa_mode)) + { + case ColorPickerAlpha::Disabled: flags |= ImGuiColorEditFlags_NoAlpha; break; + case ColorPickerAlpha::Bar: flags |= ImGuiColorEditFlags_AlphaBar; break; + case ColorPickerAlpha::Inline: /* no extra flag needed */ break; + } ImGui::TextUnformatted("Annotation Settings"); ImGui::Separator(); @@ -1604,23 +1609,6 @@ void ScreenshotTool::DrawAnnotationToolbar() ImGui::TextUnformatted("Thickness"); } - ImGui::Combo("Color picker", &item_picker, color_pickers, IM_ARRAYSIZE(color_pickers)); - - switch (item_picker) - { - case 0: - color_picker_flags |= ImGuiColorEditFlags_PickerHueBar; - color_picker_flags &= ~ImGuiColorEditFlags_PickerHueWheel; - break; - case 1: - color_picker_flags |= ImGuiColorEditFlags_PickerHueWheel; - color_picker_flags &= ~ImGuiColorEditFlags_PickerHueBar; - break; - } - ImGui::CheckboxFlags("Disable alpha edit", &color_picker_flags, ImGuiColorEditFlags_NoAlpha); - if (!(color_picker_flags & ImGuiColorEditFlags_NoAlpha)) - ImGui::CheckboxFlags("Show alpha bar", &color_picker_flags, ImGuiColorEditFlags_AlphaBar); - if (ImGui::Button("Pick color")) { m_current_actions.Set(CurrentAction::IsColorPicking); @@ -1630,7 +1618,7 @@ void ScreenshotTool::DrawAnnotationToolbar() HelpMarker("Click anywhere on the image to pick a color"); ImVec4 picker = m_current_color.to_imvec4(); - ImGui::ColorPicker4("Color", reinterpret_cast(&picker), color_picker_flags); + ImGui::ColorPicker4("Color", reinterpret_cast(&picker), flags); m_current_color = rgba_t(picker); g_cache->SetValue(CacheEntry::AnnColor, m_current_color.to_rgba()); @@ -1754,6 +1742,15 @@ static void draw_preference_edit_config(const std::function& refresh_mod "", "##config_theme_file_path", toml_filters, 1, [] { /* applied on Save */ }, g_config->File.theme_file_path); ImGui::Spacing(); + ImGui::Text("Color picker style"); + ImGui::Combo("##config_color_picker", &g_config->File.color_picker, "Bar - Square\0Wheel - Triangle\0\0"); + ImGui::Spacing(); + + ImGui::Text("Annotation alpha editing"); + ImGui::Combo( + "##config_color_picker_alpha_mode", &g_config->File.cpa_mode, "Disabled\0Inline slider\0Dedicated bar\0\0"); + ImGui::Spacing(); + // --- Checkboxes --- ImGui::Checkbox("Exclusive fullscreen##config_real_full_screen", &g_config->File.real_full_screen); ImGui::SameLine(); @@ -1792,7 +1789,7 @@ static void draw_preference_edit_config(const std::function& refresh_mod "Shortcut to use when copying the image selection.\n" "If disabled, the shortcut will be CTRL+SHIFT+C."); - // --- Image output format section --- + // --- Image filename output format section --- ImGui::Dummy(ImVec2(0, 8)); ImGui::Separator(); ImGui::Spacing(); @@ -2673,8 +2670,8 @@ void ScreenshotTool::DrawAnnotations() [&](const bool filled, const annotation_t& ann, const ImVec2& p1, const ImVec2& p2, const float t) { ImVec2 min(std::min(p1.x, p2.x), std::min(p1.y, p2.y)); ImVec2 max(std::max(p1.x, p2.x), std::max(p1.y, p2.y)); - filled ? draw_list->AddRectFilled(min, max, ann.color.to_abgr(), 0.0f, 0) - : draw_list->AddRect(min, max, ann.color.to_abgr(), t, 0.0f, 0); + filled ? draw_list->AddRectFilled(min, max, ann.color.to_abgr(), 0.0f, ImDrawFlags_None) + : draw_list->AddRect(min, max, ann.color.to_abgr(), 0.0f, t, ImDrawFlags_None); }; auto draw_circle_or_filled = From 836be33b193cb26979770f80094696fa4b55d26b Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 10 Jul 2026 20:07:53 +0200 Subject: [PATCH 30/40] fix windows build, but macos packaging is screwed --- src/plugins.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins.cpp b/src/plugins.cpp index 8b8e178..804a2c1 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -78,7 +78,7 @@ void load_plugins() TomlAPI toml_api; if (!fs::exists(plugin_config_path)) std::ofstream(plugin_config_path).close(); - toml_api.LoadFile(plugin_config_path); + toml_api.LoadFile(plugin_config_path.string()); auto [it, inserted] = g_plugins.try_emplace(plugin->id, plugin->id, From c1739d411a02627277ee23ee5d4cd2edf5b505bb Mon Sep 17 00:00:00 2001 From: Toni500git Date: Fri, 10 Jul 2026 20:13:01 +0200 Subject: [PATCH 31/40] disable asan for the sake of macos+windows builds --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23055f3..c95e7bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,9 +12,9 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_POSITION_INDEPENDENT_CODE ON) -add_compile_options($<$:-fsanitize=address>) -add_compile_options($<$:-fno-omit-frame-pointer>) -add_link_options($<$:-fsanitize=address>) +#add_compile_options($<$:-fsanitize=address>) +#add_compile_options($<$:-fno-omit-frame-pointer>) +#add_link_options($<$:-fsanitize=address>) # GCC/Clang default Release flags already include -O3; this just makes it # explicit. Guarded because "-O3" is not a valid cl.exe switch and would From 9b5fd3e965ba8e380ae5bd501796d89aba0bc7e8 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Sun, 12 Jul 2026 22:14:58 +0200 Subject: [PATCH 32/40] misc: remove --debug and set default log level to debug also make `mk_cache_entries` constexpr and array for, "perfomances" --- include/cache.hpp | 12 ++++++------ include/config.hpp | 7 +------ src/main.cpp | 5 +---- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/include/cache.hpp b/include/cache.hpp index 46c44e0..ea2cb21 100644 --- a/include/cache.hpp +++ b/include/cache.hpp @@ -2,7 +2,7 @@ #define _CACHE_HPP_ #include -#include +#include #include "toml_api.hpp" #include "util.hpp" @@ -34,13 +34,13 @@ class Cache : public TomlAPI template T GetValue(CacheEntry e, const T& fallback, bool dont_expand_var = false) { - return GetValue(m_cache_entries.at(e), fallback, dont_expand_var); + return GetValue(mk_cache_entries.at(idx(e)), fallback, dont_expand_var); } template void SetValue(CacheEntry e, const T& value) { - SetValue(m_cache_entries.at(e), value); + SetValue(mk_cache_entries.at(idx(e)), value); } protected: @@ -51,9 +51,9 @@ class Cache : public TomlAPI std::string m_cache_dir_path; - const std::unordered_map m_cache_entries = { - { CacheEntry::AnnColor, "default-color-picker-color" }, - { CacheEntry::ImgSavePath, "last-saved-dir" }, + static constexpr std::array mk_cache_entries = { + "default-color-picker-color", + "last-saved-dir" }; }; diff --git a/include/config.hpp b/include/config.hpp index 84ecdbf..f8577ba 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -58,11 +58,7 @@ class Config : public TomlAPI bool enable_handles = true; bool only_launch_tray = false; bool only_launch_gui = false; -#if DEBUG || (defined(_WIN32) && WINDOWS_CMD) - bool debug_print = true; -#else - bool debug_print = false; -#endif + bool operator==(const runtime_settings_t&) const = default; } Runtime; @@ -331,7 +327,6 @@ GENERAL OPTIONS: -g, --gui Only launch the GUI. -t, --tray Only launch system tray. - --debug Print debug statments. --gen-config [] Generate default config file. If PATH is omitted, saves to default location. Prompts before overwriting. )"); diff --git a/src/main.cpp b/src/main.cpp index 57df6cc..82acd51 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -131,7 +131,6 @@ static bool parseargs(int argc, char* argv[], const fs::path& configFile) {"source", required_argument, 0, 'f'}, {"override",required_argument, 0, 'O'}, - {"debug", no_argument, 0, "debug"_fnv1a16}, {"gen-config", optional_argument, 0, "gen-config"_fnv1a16}, {0,0,0,0} @@ -163,8 +162,6 @@ static bool parseargs(int argc, char* argv[], const fs::path& configFile) g_config->Runtime.only_launch_tray = true; break; case 'g': g_config->Runtime.only_launch_gui = true; break; - case "debug"_fnv1a16: - g_config->Runtime.debug_print = true; break; case "gen-config"_fnv1a16: if (OPTIONAL_ARGUMENT_IS_PRESENT) @@ -399,7 +396,7 @@ int main(int argc, char* argv[]) if (!g_config->File.theme_file_path.empty()) g_config->LoadThemeFile(g_config->File.theme_file_path); - spdlog::set_level(g_config->Runtime.debug_print ? spdlog::level::debug : spdlog::level::info); + spdlog::set_level(spdlog::level::debug); logger.info("=== oshot starting ==="); logger.info("Log file path: {}", file->filename()); From 887010feeb0140c50c20552412bbfd2006d8d19f Mon Sep 17 00:00:00 2001 From: Toni500git Date: Mon, 13 Jul 2026 00:15:04 +0200 Subject: [PATCH 33/40] build: fix incremental rebuilds from generated version header Avoid full rebuilds by preserving the generated version header when unchanged and fix its CMake dependency tracking. --- CMakeLists.txt | 15 ++++++++------- scripts/generateVersion.sh | 38 ++++++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c95e7bc..30e8edb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,19 +123,20 @@ add_executable( ) enable_lto(${PROJECT_NAME}) +set(VERSION_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/include/version.h) add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version.h + OUTPUT ${VERSION_HEADER} COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generateVersion.sh WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generateVersion.sh + DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/include/version.h.in + ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generateVersion.sh COMMENT "Generating version header" ) -add_custom_target( - generate_version - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/version.h +add_custom_target(generate_version + DEPENDS ${VERSION_HEADER} ) add_dependencies(${PROJECT_NAME} generate_version) -target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_compile_definitions(${PROJECT_NAME} PRIVATE $<$:DEBUG=1>) target_compile_options( @@ -186,7 +187,7 @@ set_target_properties( # ----------------------------- add_library( oshot_common - STATIC + OBJECT src/cache.cpp src/clipboard.cpp src/config.cpp diff --git a/scripts/generateVersion.sh b/scripts/generateVersion.sh index eeedae2..bb6836a 100755 --- a/scripts/generateVersion.sh +++ b/scripts/generateVersion.sh @@ -1,29 +1,35 @@ #!/bin/sh +set -e -# Shit stolen from Hyprland, ts script so gud +OUT="./include/version.h" +TMP="$(mktemp)" -# if the git directory doesn't exist, don't gather data to avoid overwriting, unless -# the version file is missing altogether (otherwise compiling will fail) -if [ ! -d ./.git ]; then - if [ -f ./include/version.h ]; then - exit 0 - fi +# If we're outside a git checkout and already have a version header, keep it. +if [ ! -d ./.git ] && [ -f "$OUT" ]; then + rm -f "$TMP" + exit 0 fi -cp -fr ./include/version.h.in ./include/version.h +cp ./include/version.h.in "$TMP" HASH=${HASH-$(git rev-parse HEAD)} BRANCH=${BRANCH-$(git branch --show-current)} -MESSAGE=${MESSAGE-$(git log -1 --pretty=%B | head -n 1 | sed -e 's/#//g' -e 's/\"//g')} +MESSAGE=${MESSAGE-$(git log -1 --pretty=%B | head -n1 | sed -e 's/#//g' -e 's/\"//g')} DATE=${DATE-$(git show --no-patch --format=%cd --date=local)} DIRTY=${DIRTY-$(git diff-index --quiet HEAD && echo clean || echo dirty)} TAG=${TAG-$(git describe --tags)} COMMITS=${COMMITS-$(git rev-list --count HEAD)} -sed -i -e "s#@HASH@#${HASH}#" ./include/version.h -sed -i -e "s#@BRANCH@#${BRANCH}#" ./include/version.h -sed -i -e "s#@MESSAGE@#${MESSAGE}#" ./include/version.h -sed -i -e "s#@DATE@#${DATE}#" ./include/version.h -sed -i -e "s#@DIRTY@#${DIRTY}#" ./include/version.h -sed -i -e "s#@TAG@#${TAG}#" ./include/version.h -sed -i -e "s#@COMMITS@#${COMMITS}#" ./include/version.h +sed -i -e "s#@HASH@#$HASH#" "$TMP" +sed -i -e "s#@BRANCH@#$BRANCH#" "$TMP" +sed -i -e "s#@MESSAGE@#$MESSAGE#" "$TMP" +sed -i -e "s#@DATE@#$DATE#" "$TMP" +sed -i -e "s#@DIRTY@#$DIRTY#" "$TMP" +sed -i -e "s#@TAG@#$TAG#" "$TMP" +sed -i -e "s#@COMMITS@#$COMMITS#" "$TMP" + +if [ ! -f "$OUT" ] || ! cmp -s "$TMP" "$OUT"; then + mv "$TMP" "$OUT" +else + rm "$TMP" +fi From b2a7df07cd8427f95eebcc6cbfca25eb111eed3f Mon Sep 17 00:00:00 2001 From: Toni500git Date: Mon, 13 Jul 2026 21:28:17 +0200 Subject: [PATCH 34/40] tool: don't scan OCR path while editing it was expensive plus forgot to check if the dir existed so it was kinda crashing --- src/screenshot_tool.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 40261b5..9930541 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -80,6 +80,9 @@ static void get_training_data_list(const std::string& datadir, std::vector& ectx = m_ocr_errors; get_training_data_list(m_inputs.ocr_path, m_ocr_models_list); + last_scanned_ocr_path = m_inputs.ocr_path; + if (m_ocr_models_list.empty()) { SetError(ectx, OcrError::InvalidPath, "Doesn't exist or is empty"); From 79c3ba55028e0f35b48d026a4471f4340fbaee41 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Mon, 13 Jul 2026 23:01:59 +0200 Subject: [PATCH 35/40] tool: improve a bit the scan error UX --- include/screenshot_tool.hpp | 3 ++- src/screenshot_tool.cpp | 35 +++++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/include/screenshot_tool.hpp b/include/screenshot_tool.hpp index ea7bf47..f2a16ea 100644 --- a/include/screenshot_tool.hpp +++ b/include/screenshot_tool.hpp @@ -121,7 +121,8 @@ enum class OcrError : size_t { InvalidModel, InvalidPath, - FailedToScan, + NeedToScanDir, + FailedToOCR, COUNT }; diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 9930541..2bea45d 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -1342,23 +1342,26 @@ void ScreenshotTool::DrawOcrTools() ImGui::PushID("OcrTools"); ImGui::SeparatorText("OCR"); + const bool need_to_scan = HasError(ectx, OcrError::NeedToScanDir); const bool invalid_path = HasError(ectx, OcrError::InvalidPath); const bool invalid_model = HasError(ectx, OcrError::InvalidModel); // --- Path input --- push_error_style(invalid_path); - draw_input_text_folder("Path", "##ocr_path", [] {}, ocr_path); - ImGui::SameLine(); - if (ImGui::Button("Scan")) + push_error_style(need_to_scan); + draw_input_text_folder("Path", "##ocr_path", [&] { SetError(ectx, OcrError::NeedToScanDir); }, ocr_path); + if (need_to_scan && ImGui::Button("Scan")) RefreshOcrModels(); + ImGui::SameLine(); const auto& it = std::find(m_ocr_models_list.begin(), m_ocr_models_list.end(), ocr_model); item_selected_idx = (it != m_ocr_models_list.end()) ? std::distance(m_ocr_models_list.begin(), it) : 0; pop_error_label(invalid_path, "Invalid!"); + pop_error_label(need_to_scan, "Need to scan new directory"); ImGui::SameLine(); HelpMarker("Full path to the OCR models (.traineddata). Supports drag-and-drop"); - // --- Model combo (only shown when path is valid) --- - if (!invalid_path) + // --- Model combo (only shown when path is valid and isn't changed) --- + if (!invalid_path && !need_to_scan) { push_error_style(invalid_model); if (ImGui::BeginCombo("Model", ocr_model.c_str(), ImGuiComboFlags_HeightLarge)) @@ -1392,21 +1395,21 @@ void ScreenshotTool::DrawOcrTools() } // --- Extract button + result details --- - if (!invalid_path && !invalid_model) + if (!invalid_path && !invalid_model && !need_to_scan) { if (ImGui::Button("Extract Text")) { const Result<>& configure_res = m_ocr_api.Configure(ocr_path.c_str(), ocr_model.c_str()); if (!configure_res.ok()) { - SetError(ectx, OcrError::FailedToScan, configure_res.error_v()); + SetError(ectx, OcrError::FailedToOCR, configure_res.error_v()); } else { Result result = m_ocr_api.ExtractTextCapture(GetFinalImage(true)); if (result.ok()) { - ClearError(ectx, OcrError::FailedToScan); + ClearError(ectx, OcrError::FailedToOCR); m_inputs.ocr_results = std::move(result.get()); #ifndef DISABLE_PLUGINS if (!g_plugins.empty()) @@ -1430,18 +1433,18 @@ void ScreenshotTool::DrawOcrTools() } else { - SetError(ectx, OcrError::FailedToScan, result.error_v()); + SetError(ectx, OcrError::FailedToOCR, result.error_v()); } } } ImGui::SameLine(); - if (HasError(ectx, OcrError::FailedToScan)) + if (HasError(ectx, OcrError::FailedToOCR)) { ImGui::SameLine(); ImGui::TextColored( - error_color, "Failed to initialize OCR: %s", GetError(ectx, OcrError::FailedToScan).c_str()); + error_color, "Failed to initialize OCR: %s", GetError(ectx, OcrError::FailedToOCR).c_str()); } else { @@ -3308,14 +3311,18 @@ void ScreenshotTool::SyncRuntimeFromConfig() void ScreenshotTool::RefreshOcrModels() { - static std::string last_scanned_ocr_path = m_inputs.ocr_path; + static std::string last_scanned_ocr_path = m_inputs.ocr_path; + ErrorContext& ectx = m_ocr_errors; + if (m_inputs.ocr_path == last_scanned_ocr_path) + { + ClearError(ectx, OcrError::NeedToScanDir); return; - - ErrorContext& ectx = m_ocr_errors; + } get_training_data_list(m_inputs.ocr_path, m_ocr_models_list); last_scanned_ocr_path = m_inputs.ocr_path; + ClearError(ectx, OcrError::NeedToScanDir); if (m_ocr_models_list.empty()) { From bbdd24800ce512b0690da658dd00824472db190d Mon Sep 17 00:00:00 2001 From: Toni500git Date: Tue, 14 Jul 2026 16:16:48 +0200 Subject: [PATCH 36/40] plugins(tool): add managing window with enable/disable button this kinda sucks and needs to be created a manifest standard ASAP --- include/cache.hpp | 2 +- include/plugin.hpp | 10 +++- include/screenshot_tool.hpp | 16 +++--- src/plugins.cpp | 33 ++++++++---- src/screenshot_tool.cpp | 102 +++++++++++++++++++++++++++++++++--- 5 files changed, 135 insertions(+), 28 deletions(-) diff --git a/include/cache.hpp b/include/cache.hpp index ea2cb21..9302392 100644 --- a/include/cache.hpp +++ b/include/cache.hpp @@ -1,8 +1,8 @@ #ifndef _CACHE_HPP_ #define _CACHE_HPP_ -#include #include +#include #include "toml_api.hpp" #include "util.hpp" diff --git a/include/plugin.hpp b/include/plugin.hpp index da03500..8ef98aa 100644 --- a/include/plugin.hpp +++ b/include/plugin.hpp @@ -26,9 +26,11 @@ struct plugin_runtime_t std::string id; // must be validated std::string config_prefix; // cached "plugins.." fs::path data_dir; + fs::path plugin_path; - oshot_plugin_t* plugin = nullptr; // non-owning and static, process-lifetime per ABI contract - void* state = nullptr; // owned by the plugin; released via plugin->destroy() + oshot_plugin_t* plugin = nullptr; // non-owning and static, process-lifetime per ABI contract + void* state = nullptr; // owned by the plugin; released via plugin->destroy() + const bool enabled = false; // set once, never chnaged dylib::library lib; TomlAPI config; // this plugin's own config, loaded from @@ -37,16 +39,20 @@ struct plugin_runtime_t plugin_runtime_t(std::string id, std::string config_prefix, fs::path data_dir, + fs::path plugin_path, oshot_plugin_t* plugin, void* state, + bool enabled, dylib::library lib, TomlAPI config, fs::path config_path) : id(std::move(id)), config_prefix(std::move(config_prefix)), data_dir(std::move(data_dir)), + plugin_path(std::move(plugin_path)), plugin(plugin), state(state), + enabled(enabled), lib(std::move(lib)), config(std::move(config)), config_path(std::move(config_path)) diff --git a/include/screenshot_tool.hpp b/include/screenshot_tool.hpp index f2a16ea..8dd3776 100644 --- a/include/screenshot_tool.hpp +++ b/include/screenshot_tool.hpp @@ -37,7 +37,7 @@ enum class ToolType : size_t Count }; -enum class ToolState +enum class ToolState : size_t { Idle, Capturing, @@ -83,12 +83,13 @@ enum class PrefTab Theme }; -enum class SubWindow +enum class SubWindow : size_t { OcrDownload, About, Preferences, MainTextTools, + ManagePlugins, Logs, COUNT }; @@ -98,7 +99,7 @@ enum class ColorPickerAlpha { Disabled = 0, // alpha channel is not editable Inline = 1, // alpha editable via the picker's inline slider - Bar = 2, // alpha editable via a dedicated alpha bar + Bar = 2, // alpha editable via a dedicated alpha bar, too }; enum class CurrentAction @@ -160,10 +161,10 @@ struct annotation_t ToolType type = ToolType::kNone; point_t start; point_t end; - std::string text; // For text tool - std::uint8_t count = 0; // For CounterBubble tool - std::vector points; // For pencil tool - rgba_t color = rgba_t::from_rgba(0xFF0000FF); // RGBA + std::string text; // For text tool + std::uint8_t count = 0; // For CounterBubble tool + std::vector points; // For pencil tool + rgba_t color = rgba_t(0xFF0000FF); // RGBA float thickness = 3.0f; }; @@ -371,6 +372,7 @@ class ScreenshotTool void DrawAnnotationToolbar(); void DrawPreferencesWindow(); void DrawDownloadOCRWindow(); + void DrawManagePluginsWindow(); void DrawLogsWindow(); void UpdateHandleHoverState(); diff --git a/src/plugins.cpp b/src/plugins.cpp index 804a2c1..0c73ab0 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -5,10 +5,10 @@ void load_plugins() { - const fs::path pluginDir = get_config_dir() / "plugins"; - fs::create_directories(pluginDir); + const fs::path pluginsDir = get_config_dir() / "plugins"; + fs::create_directories(pluginsDir); - for (const auto& plugin_dir : fs::directory_iterator(pluginDir, fs::directory_options::skip_permission_denied)) + for (const auto& plugin_dir : fs::directory_iterator(pluginsDir, fs::directory_options::skip_permission_denied)) { if (!plugin_dir.is_directory()) continue; @@ -21,15 +21,20 @@ void load_plugins() { const fs::path& path = entry.path(); - if (!path.has_extension() || path.extension().string() != dylib::decorations::os_default().suffix) - continue; + // TODO: add a *real* plugin management and metadata and do not load anything + // if plugin is set to disabled. + const std::string expected_disabled = expected + ".disabled"; + const std::string filename = path.filename().string(); + const bool is_enabled_file = filename == expected; + const bool is_disabled_file = filename == expected_disabled; - if (path.filename().string() != expected) + if (!is_enabled_file && !is_disabled_file) { - spdlog::warn("Found plugin filename '{}' at {}, expected '{}'. Skipping", - path.filename().string(), - path.parent_path().string(), - expected); + spdlog::warn("Found plugin filename '{}' at {}, expected '{}' or '{}'. Skipping", + filename, + path.string(), + expected, + expected_disabled); continue; } @@ -45,6 +50,8 @@ void load_plugins() continue; } + // TODO: add a *real* plugin management and metadata and do not load anything + // if plugin is set to disabled. if (!plugin->render || !plugin->id || !plugin->name || plugin->name[0] == '\0') { spdlog::error("Plugin '{}' doesn't define name/ID or render function", path.stem().string()); @@ -84,8 +91,10 @@ void load_plugins() plugin->id, fmt::format("plugins.{}.", plugin->id), std::move(plugin_config_dir), + std::move(path), plugin, nullptr, // state filled in below + is_enabled_file, std::move(lib), std::move(toml_api), std::move(plugin_config_path)); @@ -95,7 +104,9 @@ void load_plugins() continue; } - if (plugin->init) + // TODO: add a *real* plugin management and metadata and do not load anything + // if plugin is set to disabled. + if (is_enabled_file && plugin->init) { ScopedActivePlugin _(&it->second); it->second.state = plugin->init(); diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 2bea45d..0abf2bf 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -478,13 +478,17 @@ void ScreenshotTool::RenderOverlay() DrawMenuItems(); DrawPreferencesWindow(); DrawDownloadOCRWindow(); + DrawManagePluginsWindow(); DrawLogsWindow(); DrawOcrTools(); DrawBarDecodeTools(); #ifndef DISABLE_PLUGINS - for (auto& [_, entry] : g_plugins) + for (auto& [id, rt] : g_plugins) { - oshot_plugin_t* plugin = entry.plugin; + if (!rt.enabled) + continue; + + oshot_plugin_t* plugin = rt.plugin; if (!plugin->render || !plugin->id || !plugin->name || plugin->name[0] == '\0') continue; @@ -495,8 +499,8 @@ void ScreenshotTool::RenderOverlay() // auto-height ImGui::BeginChild(plugin->name, ImVec2(0.0f, 0.0f), ImGuiChildFlags_Borders); - ScopedActivePlugin _(&entry); - plugin->render(entry.state); + ScopedActivePlugin _(&rt); + plugin->render(rt.state); ImGui::EndChild(); ImGui::PopID(); @@ -1238,6 +1242,13 @@ void ScreenshotTool::DrawMenuItems() if (ImGui::MenuItem("Download OCR model")) m_show_window.Set(SubWindow::OcrDownload); ImGui::Separator(); + +#ifndef DISABLE_PLUGINS + if (ImGui::MenuItem("Manage Plugins")) + m_show_window.Set(SubWindow::ManagePlugins); + ImGui::Separator(); +#endif + if (ImGui::MenuItem("View Logs")) m_show_window.Set(SubWindow::Logs); ImGui::EndMenu(); @@ -1422,7 +1433,7 @@ void ScreenshotTool::DrawOcrTools() }; for (auto& [id, rt] : g_plugins) { - if (!rt.plugin->on_ocr_done) + if (!rt.enabled || !rt.plugin->on_ocr_done) continue; ScopedActivePlugin _(&rt); rt.plugin->on_ocr_done(rt.state, &ocr); @@ -1977,6 +1988,9 @@ static void draw_preference_plugin(auto& plugin_dirty, bool& prefs_modified) for (auto& [id, rt] : g_plugins) { + if (!rt.enabled) + continue; + oshot_plugin_t* pl = rt.plugin; if (!pl->render_preferences) { @@ -2151,7 +2165,7 @@ void ScreenshotTool::DrawPreferencesWindow() #ifndef DISABLE_PLUGINS for (auto& [id, rt] : g_plugins) { - if (!plugin_dirty[id] || !rt.plugin->on_save_preferences) + if (!plugin_dirty[id] || !rt.enabled || !rt.plugin->on_save_preferences) continue; ScopedActivePlugin _(&rt); @@ -2168,7 +2182,7 @@ void ScreenshotTool::DrawPreferencesWindow() #ifndef DISABLE_PLUGINS for (auto& [id, rt] : g_plugins) { - if (!plugin_dirty[id] || !rt.plugin->on_discard_preferences) + if (!plugin_dirty[id] || !rt.enabled || !rt.plugin->on_discard_preferences) continue; ScopedActivePlugin _(&rt); rt.plugin->on_discard_preferences(rt.state); @@ -2293,6 +2307,80 @@ void ScreenshotTool::DrawPreferencesWindow() } } +void ScreenshotTool::DrawManagePluginsWindow() +{ +#ifndef DISABLE_PLUGINS + if (!m_show_window.Has(SubWindow::ManagePlugins)) + return; + + bool open = m_show_window.Has(SubWindow::ManagePlugins); + ImGui::SetNextWindowSize(ImVec2(560, 400), ImGuiCond_FirstUseEver); + if (ImGui::Begin("Manage plugins##manage_plugins_window", &open, ImGuiWindowFlags_NoSavedSettings)) + { + ImGui::TextDisabled("Note: Changes takes effect after restart of oshot"); + ImGui::Spacing(); + + for (auto& [id, rt] : g_plugins) + { + ScopedActivePlugin _(&rt); + + oshot_plugin_t* plugin = rt.plugin; + ImGui::TextUnformatted(plugin->name); + ImGui::TextDisabled("%s", plugin->id); + + if (rt.plugin_path.has_extension() && rt.plugin_path.extension() != ".disabled") + { + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); // Red + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 0.3f, 0.3f, 1.0f)); // Light Red + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.8f, 0.0f, 0.0f, 1.0f)); // Dark Red + if (ImGui::Button("Disable")) + { + if (fs::exists(rt.plugin_path)) + { + fs::path disabled_path(rt.plugin_path); + disabled_path += ".disabled"; + std::error_code ec; + fs::rename(rt.plugin_path, disabled_path, ec); + if (!ec) + rt.plugin_path = std::move(disabled_path); + else + error("Failed to disable plugin '{}': {}", rt.id, ec.message()); + } + } + ImGui::PopStyleColor(3); + } + else + { + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.10f, 0.65f, 0.25f, 1.0f)); // Green + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.15f, 0.75f, 0.30f, 1.0f)); // Light Green + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.08f, 0.55f, 0.20f, 1.0f)); // Dark Green + if (ImGui::Button("Enable")) + { + if (fs::exists(rt.plugin_path)) + { + fs::path enabled_path(rt.plugin_path); + enabled_path.replace_extension(); + std::error_code ec; + fs::rename(rt.plugin_path, enabled_path, ec); + if (!ec) + rt.plugin_path = std::move(enabled_path); + else + error("Failed to enable plugin '{}': {}", rt.id, ec.message()); + } + } + ImGui::PopStyleColor(3); + } + + ImGui::Separator(); + ImGui::Spacing(); + } + ImGui::End(); + } + + m_show_window.Set(SubWindow::ManagePlugins, open); +#endif +} + void ScreenshotTool::DrawLogsWindow() { static std::shared_ptr imgui_ring; From 440b770ff0071dce269686325cb45a5e739d404f Mon Sep 17 00:00:00 2001 From: Toni500git Date: Tue, 14 Jul 2026 18:23:54 +0200 Subject: [PATCH 37/40] chores --- include/plugin.hpp | 1 - src/main_tool_metal.mm | 15 ++++++--------- src/main_tool_opengl3.cpp | 15 ++++++--------- src/screenshot_tool.cpp | 8 ++++---- 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/include/plugin.hpp b/include/plugin.hpp index 8ef98aa..ea6262c 100644 --- a/include/plugin.hpp +++ b/include/plugin.hpp @@ -70,7 +70,6 @@ struct plugin_runtime_t plugin_runtime_t(const plugin_runtime_t&) = delete; plugin_runtime_t& operator=(const plugin_runtime_t&) = delete; plugin_runtime_t(plugin_runtime_t&&) = default; - plugin_runtime_t& operator=(plugin_runtime_t&&) = default; }; void load_plugins(); diff --git a/src/main_tool_metal.mm b/src/main_tool_metal.mm index 4245e7d..71c0454 100644 --- a/src/main_tool_metal.mm +++ b/src/main_tool_metal.mm @@ -162,15 +162,12 @@ int run_main_tool() apply_imgui_theme(); // Start the overlay window - { - const Result<>& res = g_ss_tool.StartWindow(); - MUST_OK(res, { - error("Failed to start tool window: {}", res.error_v()); - if (!g_is_systray) - glfwTerminate(); - return EXIT_FAILURE; - }); - } + MUST_OK(g_ss_tool.StartWindow(), { + error("Failed to start tool window: {}", _r.error_v()); + if (!g_is_systray) + glfwTerminate(); + return EXIT_FAILURE; + }); // Create Metal texture from screenshot buffer capture_result_t& cap = g_ss_tool.GetRawScreenshot(); diff --git a/src/main_tool_opengl3.cpp b/src/main_tool_opengl3.cpp index 5f5091f..632b3a5 100644 --- a/src/main_tool_opengl3.cpp +++ b/src/main_tool_opengl3.cpp @@ -204,15 +204,12 @@ int run_main_tool() apply_imgui_theme(); // Start the overlay window - { - const Result<>& res = g_ss_tool.StartWindow(); - MUST_OK(res, { - error("Failed to start tool window: {}", res.error_v()); - if (!g_is_systray) - glfwTerminate(); - return EXIT_FAILURE; - }); - } + MUST_OK(g_ss_tool.StartWindow(), { + error("Failed to start tool window: {}", _r.error_v()); + if (!g_is_systray) + glfwTerminate(); + return EXIT_FAILURE; + }); while (!glfwWindowShouldClose(window) && g_ss_tool.IsActive()) { diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 0abf2bf..4dd7001 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -1272,7 +1272,7 @@ void ScreenshotTool::DrawMenuItems() float window_width = ImGui::GetWindowSize().x; std::string_view text_display; - auto centered_text = [&](const std::string_view text) -> std::string_view { + auto centered_text = [&](const std::string_view text) { float name_width = ImGui::CalcTextSize(text.data()).x; ImGui::SetCursorPosX((window_width - name_width) / 2); return text; @@ -2400,7 +2400,7 @@ void ScreenshotTool::DrawLogsWindow() case spdlog::level::warn: return rgba_t(0xFFCC33FF); // amber case spdlog::level::err: return rgba_t(0xFF4D4DFF); // red case spdlog::level::critical: return rgba_t(0xFF0000FF); // pure red - default: return rgba_t(0xFFFFFFFF); // white + default: return rgba_t(0xFFFFFFFF); // white } }; @@ -2491,7 +2491,7 @@ void ScreenshotTool::DrawLogsWindow() { if (ImGui::MenuItem("Copy line")) MUST_OK(g_clipboard.CopyText(msg.payload.data()), - spdlog::error("Failed to copy line log: {}", _r.error_v())); + error("Failed to copy line log: {}", _r.error_v())); ImGui::EndPopup(); } } @@ -2502,7 +2502,7 @@ void ScreenshotTool::DrawLogsWindow() std::string all_text; for (const auto* msg : shown) all_text += fmt::format("[{}] {}\n", level_tag(msg->level), msg->payload); - MUST_OK(g_clipboard.CopyText(all_text), spdlog::error("Failed to copy logs: {}", _r.error_v())); + MUST_OK(g_clipboard.CopyText(all_text), error("Failed to copy logs: {}", _r.error_v())); } if (autoscroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY() - 1.0f) From bef1a9fa5379d8fa2c1d84508aad4a28ed20563c Mon Sep 17 00:00:00 2001 From: Toni500git Date: Wed, 15 Jul 2026 16:51:20 +0200 Subject: [PATCH 38/40] plugins: save 8 bytes from padding in oshot_plugin_t from sizeof(oshot_plugin_t) == 88 to 80 --- src/plugins/oshot_plugin.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plugins/oshot_plugin.h b/src/plugins/oshot_plugin.h index 2293014..4df5839 100644 --- a/src/plugins/oshot_plugin.h +++ b/src/plugins/oshot_plugin.h @@ -75,11 +75,10 @@ typedef struct * ---------------------------------------------------------------- */ typedef struct { - uint32_t abi_version; - + uint32_t abi_version; + uint32_t capabilities; // OR of oshot_capabilities_t, informational only const char* name; // display name, doesn't need to be unique const char* id; // reverse-domain, e.g. "com.example.myplugin" - uint32_t capabilities; // OR of oshot_capabilities_t, informational only void* (*init)(void); void (*destroy)(void* state); From 737ddad15bb91f83622599a1378608ebadd06a03 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Wed, 15 Jul 2026 20:50:35 +0200 Subject: [PATCH 39/40] tool: fix regression about OCR model selection also don't bleed the combo list with error color --- include/screenshot_tool.hpp | 1 + src/screenshot_tool.cpp | 23 +++++++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/include/screenshot_tool.hpp b/include/screenshot_tool.hpp index 8dd3776..34bfa0e 100644 --- a/include/screenshot_tool.hpp +++ b/include/screenshot_tool.hpp @@ -341,6 +341,7 @@ class ScreenshotTool std::function m_on_image_reload; std::function&)> m_on_complete; + std::string m_last_scanned_ocr_path; GeneralContext m_show_window; GeneralContext m_current_actions; std::array m_tool_textures; diff --git a/src/screenshot_tool.cpp b/src/screenshot_tool.cpp index 4dd7001..6e39a0c 100644 --- a/src/screenshot_tool.cpp +++ b/src/screenshot_tool.cpp @@ -1375,7 +1375,14 @@ void ScreenshotTool::DrawOcrTools() if (!invalid_path && !need_to_scan) { push_error_style(invalid_model); - if (ImGui::BeginCombo("Model", ocr_model.c_str(), ImGuiComboFlags_HeightLarge)) + + const bool combo_open = ImGui::BeginCombo("Model", ocr_model.c_str(), ImGuiComboFlags_HeightLarge); + + // Don't infect the whole list of red + if (invalid_model) + ImGui::PopStyleColor(); + + if (combo_open) { static ImGuiTextFilter filter; if (ImGui::IsWindowAppearing()) @@ -1402,7 +1409,12 @@ void ScreenshotTool::DrawOcrTools() } ImGui::EndCombo(); } - pop_error_label(invalid_model, "Invalid!"); + + if (invalid_model) + { + ImGui::SameLine(); + ImGui::TextColored(error_color, "Invalid!"); + } } // --- Extract button + result details --- @@ -3399,17 +3411,16 @@ void ScreenshotTool::SyncRuntimeFromConfig() void ScreenshotTool::RefreshOcrModels() { - static std::string last_scanned_ocr_path = m_inputs.ocr_path; - ErrorContext& ectx = m_ocr_errors; + ErrorContext& ectx = m_ocr_errors; - if (m_inputs.ocr_path == last_scanned_ocr_path) + if (m_inputs.ocr_path == m_last_scanned_ocr_path) { ClearError(ectx, OcrError::NeedToScanDir); return; } get_training_data_list(m_inputs.ocr_path, m_ocr_models_list); - last_scanned_ocr_path = m_inputs.ocr_path; + m_last_scanned_ocr_path = m_inputs.ocr_path; ClearError(ectx, OcrError::NeedToScanDir); if (m_ocr_models_list.empty()) From 3b2a8d638f61c6c3f7873e5854fb689aef45cbf7 Mon Sep 17 00:00:00 2001 From: Toni500git Date: Sun, 19 Jul 2026 20:37:43 +0200 Subject: [PATCH 40/40] oshotpm: introduce a CLI plugin manager for oshot Ported from cufetchpm (customfetch) because apparently reinventing a package manager for every project I write is now a personality trait. And because starting a new codebase sucks ass. Adds a new oshotpm/ subtree with a shared lib (oshot_plugman) and its executable (oshotpm), wired into CMakeLists.txt behind the existing DISABLE_PLUGINS switch. Manifest format (oshot-plugin.toml) so far: - repo: name, git url, tracked git-hash - plugins[]: name, id, description, output_dir, licenses, authors, build_steps, platforms - top-level dependencies list (declared, not consumed yet) Management commands wired up in main.cpp: install, update, list [-v], enable/disable, uninstall, gen-manifest, help. Install accepts either a repo url/path (clone + build) or a local directory already on disk. State tracking: - StateManager persists installed repos/plugins to an auto-generated TOML state file - enable/disable works by renaming built libraries to/from a .disabled suffix, which is delightfully hacky and also fine Still missing / rough edges: - is_valid_name() is referenced in manifest.hpp comments but doesn't exist yet, so right now any name goes - the `dependencies` field in manifest_t is parsed into nothing, it's aspirational at best - no actual plugin conflict resolution beyond a boolean check - no signature/checksum verification on downloaded repos, so trust your sources - gen-manifest just dumps a canned template, no interactive mode Also, unrelated drive-by cleanup: - CMakeLists: -pedantic -> -Wpedantic, one-line generate_version target because vertical space is precious - moved the giant default config/theme TOML strings out of config.hpp into texts.hpp, config.hpp was starting to look like a novel - screenshot_tool.cpp: actually check the Result from CopyText() instead of silently launching it into the void --- CMakeLists.txt | 53 ++- include/config.hpp | 185 ---------- include/libs/nvdialog/nvdialog_error.h | 10 + include/platform.hpp | 60 ++++ include/texts.hpp | 332 ++++++++++++++++++ include/toml_api.hpp | 110 ++++-- include/util.hpp | 76 ++++- oshotpm/compile_flags.txt | 13 + oshotpm/include/manifest.hpp | 121 +++++++ oshotpm/include/plugin_manager.hpp | 86 +++++ oshotpm/include/state_manager.hpp | 101 ++++++ oshotpm/src/main.cpp | 456 +++++++++++++++++++++++++ oshotpm/src/manifest.cpp | 107 ++++++ oshotpm/src/plugin_manager.cpp | 319 +++++++++++++++++ oshotpm/src/state_manager.cpp | 134 ++++++++ src/config.cpp | 1 + src/libs/nvdialog/nvdialog_error.c | 2 +- src/libs/nvdialog/nvdialog_error.h | 5 +- src/main.cpp | 1 + src/screenshot_tool.cpp | 2 +- 20 files changed, 1948 insertions(+), 226 deletions(-) create mode 100644 include/platform.hpp create mode 100644 include/texts.hpp create mode 100644 oshotpm/compile_flags.txt create mode 100644 oshotpm/include/manifest.hpp create mode 100644 oshotpm/include/plugin_manager.hpp create mode 100644 oshotpm/include/state_manager.hpp create mode 100644 oshotpm/src/main.cpp create mode 100644 oshotpm/src/manifest.cpp create mode 100644 oshotpm/src/plugin_manager.cpp create mode 100644 oshotpm/src/state_manager.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 30e8edb..7b93f3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,9 +133,7 @@ add_custom_command( ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generateVersion.sh COMMENT "Generating version header" ) -add_custom_target(generate_version - DEPENDS ${VERSION_HEADER} -) +add_custom_target(generate_version DEPENDS ${VERSION_HEADER}) add_dependencies(${PROJECT_NAME} generate_version) target_compile_definitions(${PROJECT_NAME} PRIVATE $<$:DEBUG=1>) @@ -144,7 +142,7 @@ target_compile_options( PRIVATE -Wall -Wextra - -pedantic + -Wpedantic -Wno-unused-parameter $<$:-ggdb3;-fno-omit-frame-pointer> ) @@ -317,6 +315,53 @@ if(NOT DISABLE_PLUGINS) ) endif() +# ----------------------------- +# oshot_plugman and oshotpm (oshot plugin manager, CLI) +# ----------------------------- +if(NOT DISABLE_PLUGINS) + add_library( + oshot_plugman + SHARED + oshotpm/src/manifest.cpp + oshotpm/src/plugin_manager.cpp + oshotpm/src/state_manager.cpp + ) + enable_lto(oshot_plugman) + target_compile_definitions(oshot_plugman PRIVATE $<$:DEBUG=1>) + target_compile_options( + oshot_plugman + PRIVATE + -Wall + -Wextra + -Wpedantic + -Wno-unused-parameter + $<$:-ggdb3;-fno-omit-frame-pointer> + ) + + target_include_directories(oshot_plugman PUBLIC oshotpm/include/) + target_compile_features(oshot_plugman PUBLIC cxx_std_20) + target_link_libraries(oshot_plugman PUBLIC oshot_plugin) + + set_target_properties( + oshot_plugman + PROPERTIES + VERSION 1 + SOVERSION 1 + WINDOWS_EXPORT_ALL_SYMBOLS ON + POSITION_INDEPENDENT_CODE ON + ) + + add_executable(oshotpm oshotpm/src/main.cpp) + enable_lto(oshotpm) + set_target_properties( + oshotpm + PROPERTIES + BUILD_RPATH "${_rpath_origin}/../lib;$" + INSTALL_RPATH "${_rpath_origin}/../lib" + ) + target_link_libraries(oshotpm PUBLIC oshot_plugman) +endif() + # ----------------------------- # fmt library # ----------------------------- diff --git a/include/config.hpp b/include/config.hpp index f8577ba..b3b328c 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -146,189 +146,4 @@ class Config : public TomlAPI extern std::unique_ptr g_config; void apply_imgui_theme(); - -// default config -inline constexpr std::string_view AUTOCONFIG = R"#([default] -# Default Path to where we'll use all the '.traineddata' models. -# The TESSDATA_PREFIX environment variable supersedes this. -ocr-path = "{}" - -# Default OCR model. -ocr-model = "{}" - -# GitHub repository from where we are going to -# download an OCR '.traineddata' model. -# The models must be on the root directory of the repository -ocr-repo-downlaod = "{}" - -# Delay the app before acquiring a screenshot (in milliseconds) -# Doesn't affect if opening external image (i.e. -f flag) -delay = {} - -# Which ImGui color picker widget to use for annotation colors. -# 0 = "Bar - Square"; 1 = "Wheel - Triangle" -color-picker = {} - -# Alpha (transparency) editing behavior for the annotation color picker. -# 0 = Disabled (alpha not editable) -# 1 = Inline slider -# 2 = Dedicated alpha bar -color-picker-alpha-mode = {} - -# On some desktop environments (e.g. MATE), the compositor may cause -# the capture window to look grainy or pixelated. Enabling this uses exclusive -# fullscreen mode which bypasses the compositor and fixes it. -# Downside: the window may briefly take over the display on some setups. -real-full-screen = {} - -# Controls vertical sync (VSync). When enabled, the capture window renders in sync -# with your monitor's refresh rate, thus being smoother visually but uses slightly more CPU/GPU. -# Disable if the overlay feels sluggish or unresponsive. -vsync = {} - -# Allow the extracted output to be editable. -allow-text-edit = {} - -# Display the text tools (OCR, Bar/QR code scan) at startup. -show-text-tools = {} - -# Prefer using config variables over environment variable. -config-over-env = {} - -# Consider annotations when scanning (true) -# or only when saving the selection (false). -annotations-in-text-tools = {} - -# Copy image shortcut to use. -# true: CTRL+C -# false: CTRL+SHIFT+C -ctrl-c-copy-img = {} - -# Fonts to use for the application. Can be an absolute path, or just a name. -# You can combine multiple fonts for multiple language support. -# for example, using "Roboto-Regular.ttf" and "RobotoCJK-Regular.ttc" for Chinese, Japanese, and Korean support alongside English support. -# If empty, or non-existent (or commented out), oshot will use the default font for ImGUI. -fonts = [{}] - -# Format of the output image filename when saving. -# The .png extension is appended automatically. -# Uses {{fmt}} chrono specifiers. NOTE: -# the colon inside {{}} is required: {{:%F}} correct, {{%F}} will error. -# -# Default: "oshot_{{:%F_%H-%M}}" -image-out-fmt = "{}" - -# Base UI theme: "auto" (follow OS dark/light), "dark", "light", or "classic". -# Fine-grained overrides live in theme.toml. -theme = "{}" - -# Path to a theme file. Absolute or relative to this config's directory. -# Delete or comment out to use only the base theme above. -theme-file = "{}" -)#"; - -inline constexpr std::string_view AUTOTHEME = (R"( -# Drop this next to config.toml or point theme-file at its path. -# All sections and keys are optional — omit anything you don't want to override. - -[theme] -smooth-animations = false - -# --------------------------------------------------------------- -# Rounding (pixels, 0 = sharp corners, max ~12) -# --------------------------------------------------------------- -[theme.style] -window-rounding = 8.0 -frame-rounding = 4.0 -grab-rounding = 4.0 -tab-rounding = 4.0 - -# Border width in pixels. 0 = none, 1 = thin line. -window-border = 1.0 -frame-border = 0.0 - -# --------------------------------------------------------------- -# Color overrides -# Format: "#RRGGBBAA" -# Only the entries you list here are overridden; -# everything else falls back to the base theme. -# -# Full list of valid names: -# https://github.com/ocornut/imgui/blob/master/imgui.cpp -# (search for "GetStyleColorName") -# --------------------------------------------------------------- -[theme.colors] -# --- Text --- -Text = "#cdd6f4FF" -TextDisabled = "#6c7086FF" - -# --- Backgrounds --- -WindowBg = "#1e1e2eFF" -ChildBg = "#181825FF" -PopupBg = "#1e1e2eFF" -FrameBg = "#313244FF" -FrameBgHovered = "#45475aFF" -FrameBgActive = "#585b70FF" -MenuBarBg = "#181825FF" - -# --- Title bar --- -TitleBg = "#181825FF" -TitleBgActive = "#313244FF" - -# --- Borders --- -Border = "#585b70FF" -BorderShadow = "#00000000" - -# --- Scrollbar --- -ScrollbarBg = "#181825FF" -ScrollbarGrab = "#585b70FF" -ScrollbarGrabHovered = "#6c7086FF" -ScrollbarGrabActive = "#7f849cFF" - -# --- Buttons --- -Button = "#313244FF" -ButtonHovered = "#45475aFF" -ButtonActive = "#585b70FF" - -# --- Headers (selectables, tree nodes, collapsing headers) --- -Header = "#313244FF" -HeaderHovered = "#45475aFF" -HeaderActive = "#585b70FF" - -# --- Sliders / checkmarks --- -CheckMark = "#cba6f7FF" -SliderGrab = "#cba6f7FF" -SliderGrabActive = "#b4befeff" - -# --- Tabs --- -Tab = "#313244FF" -TabHovered = "#cba6f7FF" -TabSelected = "#45475aFF" - -# --- Misc --- -Separator = "#585b70FF" -ResizeGrip = "#cba6f7FF" -ResizeGripHovered = "#cba6f7FF" -ResizeGripActive = "#cba6f7FF" -PlotHistogram = "#2ba2f0FF" # original: "#e6b300FF" -)"); - -inline constexpr std::string_view oshot_help = (R"(Usage: oshot [OPTIONS]... -Lightweight Screenshot tool to extract text on the fly. - -GENERAL OPTIONS: - -h, --help Print this help menu. - -V, --version Print version and other infos about the build. - -f, --source Path to the image to use as background (use '-' for reading from stdin). - -C, --config Path to the config file to use (default: ~/.config/oshot/config.toml). - -O, --override