Commit b12033fd authored by Victor Zverovich's avatar Victor Zverovich

Handle grapheme clusters when computing width

parent e5ab813f
......@@ -45,6 +45,13 @@
#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__
# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
#else
......@@ -415,11 +422,6 @@ class output_range {
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.
inline size_t count_code_points(basic_string_view<char8_t> s) {
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);
}
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
# define FMT_USE_WINDOWS_H 0
#elif !defined(FMT_USE_WINDOWS_H)
......@@ -1583,7 +1611,7 @@ template <typename Range> class basic_writer {
size_t size() const { return size_; }
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 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment