Use std::to_chars for formatting float numbers as well

this gives us a larger representation in many cases since it tries to
represent floats to max precision, but that tradeoff is worth it for
dropping 2000 lines of C code.
This commit is contained in:
Kovid Goyal 2025-11-19 10:56:27 +05:30
parent be304b6f99
commit 2a10f39e68
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 8 additions and 1888 deletions

View File

@ -149,7 +149,7 @@
},
{
"name": "fast_css_transform",
"headers": "calibre/utils/cpp_binding.h calibre/utils/stb_sprintf.h",
"headers": "calibre/utils/cpp_binding.h",
"sources": "calibre/srv/fast_css_transform.cpp",
"inc_dirs": "perfect-hashing",
"needs_c++": "17"

View File

@ -26,8 +26,6 @@
#include <frozen/unordered_map.h>
#include <frozen/string.h>
#include "../utils/cpp_binding.h"
#define STB_SPRINTF_IMPLEMENTATION
#include "../utils/stb_sprintf.h"
// character classes {{{
static inline bool
@ -465,9 +463,10 @@ class Token {
double new_val = convert_font_size(val, lit->second);
if (val == new_val) return false;
char txt[128];
// stbsp_snprintf is locale independent unlike std::snprintf
int num = stbsp_snprintf(txt, sizeof(txt), "%grem", new_val);
if (num <= 0) throw std::runtime_error("Failed to format font size");
auto res = std::to_chars(txt, txt + sizeof(txt)-8, new_val, std::chars_format::general);
if (res.ec != std::errc()) throw std::runtime_error("Failed to format font size");
size_t num = res.ptr - txt;
txt[num++] = 'r'; txt[num++] = 'e'; txt[num++] = 'm';
set_ascii_text(txt, num);
return true;
}

View File

@ -64,11 +64,11 @@ class TestTransform(SimpleTest):
u('a:url( "( )" /**/ )', 'a:url("( )")')
u('a:url( "(/*)" )', 'a:url( "(/*)" )', url_callback=lambda x: x)
d('font-size: 197583965730245.28px', 'font-size: 1.2349e+13rem')
d('font-size: 197583965730245.28px', 'font-size: 1.234899785814033e+13rem')
d('font-size: 19.28px', 'font-size: 1.205rem')
d('font-size:+19.28px', 'font-size:1.205rem')
d('font-size: .28in', 'font-size: 1.68rem')
d('font-size: +.28in', 'font-size: 1.68rem')
d('font-size: .28in', 'font-size: 1.6800000000000002rem')
d('font-size: +.28in', 'font-size: 1.6800000000000002rem')
d(r'f\ont-s\69z\65 : 16\px', 'font-size: 1rem')
d('font -size: 16px', 'font -size: 16px')
d('font-/* */size: 1/*x*/6/**/p/**/x !important', 'font-size: 1rem !important')

File diff suppressed because it is too large Load Diff