mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
Handle grapheme clusters when computing width
This commit is contained in:
@ -45,6 +45,13 @@
|
|||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
|
#ifndef FMT_USE_TEXT
|
||||||
|
# define FMT_USE_TEXT 0
|
||||||
|
#endif
|
||||||
|
#if FMT_USE_TEXT
|
||||||
|
# include <boost/text/grapheme_break.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
|
# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
|
||||||
#else
|
#else
|
||||||
@ -415,11 +422,6 @@ class output_range {
|
|||||||
sentinel end() const { return {}; } // Sentinel is not used yet.
|
sentinel end() const { return {}; } // Sentinel is not used yet.
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Char>
|
|
||||||
inline size_t count_code_points(basic_string_view<Char> s) {
|
|
||||||
return s.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Counts the number of code points in a UTF-8 string.
|
// Counts the number of code points in a UTF-8 string.
|
||||||
inline size_t count_code_points(basic_string_view<char8_t> s) {
|
inline size_t count_code_points(basic_string_view<char8_t> s) {
|
||||||
const char8_t* data = s.data();
|
const char8_t* data = s.data();
|
||||||
@ -912,6 +914,32 @@ inline It format_uint(It out, UInt value, int num_digits, bool upper = false) {
|
|||||||
return internal::copy_str<Char>(buffer, buffer + num_digits, out);
|
return internal::copy_str<Char>(buffer, buffer + num_digits, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
inline size_t compute_width(basic_string_view<Char> s) {
|
||||||
|
return s.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t compute_width(string_view s) {
|
||||||
|
#if FMT_USE_TEXT
|
||||||
|
basic_memory_buffer<uint32_t> code_points;
|
||||||
|
for (auto cp: boost::text::make_to_utf32_range(s)) code_points.push_back(cp);
|
||||||
|
size_t num_graphemes = 0;
|
||||||
|
for (auto g: boost::text::graphemes(code_points)) ++num_graphemes;
|
||||||
|
return num_graphemes;
|
||||||
|
#else
|
||||||
|
return s.size();
|
||||||
|
#endif // FMT_USE_TEXT
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t compute_width(basic_string_view<char8_t> s) {
|
||||||
|
#if FMT_USE_TEXT
|
||||||
|
return compute_width(string_view(
|
||||||
|
reinterpret_cast<const char*>(s.data(), s.size())));
|
||||||
|
#else
|
||||||
|
return count_code_points(s);
|
||||||
|
#endif // FMT_USE_TEXT
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# define FMT_USE_WINDOWS_H 0
|
# define FMT_USE_WINDOWS_H 0
|
||||||
#elif !defined(FMT_USE_WINDOWS_H)
|
#elif !defined(FMT_USE_WINDOWS_H)
|
||||||
@ -1583,7 +1611,7 @@ template <typename Range> class basic_writer {
|
|||||||
|
|
||||||
size_t size() const { return size_; }
|
size_t size() const { return size_; }
|
||||||
size_t width() const {
|
size_t width() const {
|
||||||
return internal::count_code_points(basic_string_view<Char>(s, size_));
|
return internal::compute_width(basic_string_view<Char>(s, size_));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename It> void operator()(It&& it) const {
|
template <typename It> void operator()(It&& it) const {
|
||||||
|
Reference in New Issue
Block a user