35#define TEMP_STR_SIZE 256
45#define UN_SC_KM 1000.0f
46#define UN_SC_HM 100.0f
47#define UN_SC_DAM 10.0f
51#define UN_SC_MM 0.001f
52#define UN_SC_UM 0.000001f
55#define UN_SC_MI 1609.344f
56#define UN_SC_FUR 201.168f
57#define UN_SC_CH 20.1168f
58#define UN_SC_YD 0.9144f
59#define UN_SC_FT 0.3048f
60#define UN_SC_IN 0.0254f
61#define UN_SC_MIL 0.0000254f
64#define UN_SC_MTON 1000.0f
65#define UN_SC_QL 100.0f
68#define UN_SC_DAG 0.01f
70#define UN_SC_MG 0.000001f
73#define UN_SC_ITON 907.18474f
74#define UN_SC_CWT 45.359237f
75#define UN_SC_ST 6.35029318f
76#define UN_SC_LB 0.45359237f
77#define UN_SC_OZ 0.028349523125f
80#define UN_SC_FAH 0.555555555555f
134#define UNIT_COLLECTION_LENGTH(def) (ARRAY_SIZE(def) - 1)
461 "square hectometers",
464 "Square Hectometers",
506 "square centimeters",
509 "Square Centimeters",
517 "square millimeters",
520 "Square Millimeters",
528 "square micrometers",
531 "Square Micrometers",
995 "kilometer per hour",
996 "kilometers per hour",
999 "Kilometers per hour",
1051 "meter per second squared",
1052 "meters per second squared",
1055 "Meters per second squared",
1073 "foot per second squared",
1074 "feet per second squared",
1077 "Feet per second squared",
1191 (
M_PI / 180.0) / 60.0,
1202 (
M_PI / 180.0) / 3600.0,
1519#define UNIT_SYSTEM_TOT (((sizeof(bUnitSystems) / B_UNIT_TYPE_TOT) / sizeof(void *)) - 1)
1598 double value_abs = value > 0.0 ? value : -value;
1600 for (
const bUnitDef *unit = unit_start ? unit_start : usys->
units; unit->
name; unit++) {
1608 if (value_abs >= unit->scalar * (0.1 -
EPS)) {
1613 if (value_abs >= unit->scalar * (1.0 -
EPS)) {
1633 const double scaled_value = value / unit->
scalar;
1634 *r_value_a = (value < 0.0 ?
ceil(scaled_value) :
floor(scaled_value)) * unit->
scalar;
1635 *r_value_b = value - (*r_value_a);
1650 if (unit ==
nullptr) {
1660 double value_conv = (value / unit->
scalar) - unit->
bias;
1661 bool strip_skip =
false;
1689 while (
i > 0 &&
str[
i] ==
'0') {
1693 if (
i > 0 &&
str[
i] ==
'.') {
1705 if (
i < str_maxncpy) {
1708 while (unit->
name_short[j] && (
i < str_maxncpy)) {
1714 if (
i >= str_maxncpy) {
1715 i = str_maxncpy - 1;
1757 double value_a, value_b;
1758 unit_dual_convert(value, usys, &unit_a, &unit_b, &value_a, &value_b, main_unit);
1761 if (unit_b > unit_a) {
1769 if (
i + 2 < str_maxncpy) {
1783 return usys !=
nullptr && usys->
units[0].
name !=
nullptr;
1793 int max_offset = usys->
length - 1;
1802 return usys->
units + std::min(units.
length, max_offset);
1807 return usys->
units + std::min(units.
mass, max_offset);
1812 return usys->
units + std::min(units.
time, max_offset);
1815 return usys->
units + 0;
1818 return usys->
units + 3;
1843 const bUnitDef *main_unit =
nullptr;
1864 char *
str,
int str_maxncpy,
double value,
int prec,
int system,
int type,
bool split,
bool pad)
1908 switch (unit_type) {
1929 return (ch >= 128 || isalpha(ch));
1934 if (substr ==
nullptr || substr[0] ==
'\0') {
1940 const char *str_found;
1941 if (case_sensitive) {
1942 str_found = strstr(
str, substr);
1950 if (str_found ==
str ||
1956 int len_name = strlen(substr);
2027 const char *str_found = strstr(remaining_str,
"-");
2029 if (str_found ==
nullptr) {
2034 if ((str_found !=
str) &&
ELEM(*(str_found - 1),
'e',
'E')) {
2038 if (*(str_found + 1) ==
' ') {
2042 return str_found + 1;
2054 for (
i = 0;
i < remaining_str_maxncpy;
i++) {
2055 if (remaining_str[
i] ==
'\0') {
2056 return remaining_str +
i;
2061 if (remaining_str !=
str &&
i != 0) {
2063 if ((remaining_str[
i] ==
'/') &&
ELEM(remaining_str[
i - 1],
't',
'T',
'm',
'M') &&
2064 ELEM(remaining_str[
i + 1],
's',
'S'))
2070 if (
ELEM(remaining_str[
i - 1],
'e',
'E')) {
2075 if (remaining_str[
i - 1] ==
' ') {
2080 return remaining_str +
i;
2084 return remaining_str +
i;
2107 bool changed =
false;
2109 char *remaining_str =
str;
2111 int remaining_str_maxncpy;
2113 remaining_str_maxncpy = str_maxncpy - int(remaining_str -
str);
2114 if (remaining_str_maxncpy <= 2) {
2121 memmove(remaining_str + 1, remaining_str, remaining_str_maxncpy - 2);
2122 *remaining_str =
'(';
2127 remaining_str_maxncpy = str_maxncpy - int(remaining_str -
str);
2128 memmove(remaining_str + 1, remaining_str, remaining_str_maxncpy - 2);
2129 *remaining_str =
')';
2145 for (
int i = start_ofs;
i > 0;
i--) {
2160 for (
i = start_ofs;
i < str_maxncpy;
i++) {
2161 if (!strchr(
"0123456789eE.",
str[
i])) {
2173 const char *replace_str,
2174 bool case_sensitive)
2176 if (str_maxncpy < 0) {
2183 if (str_found ==
nullptr) {
2187 int found_ofs = int(str_found -
str);
2196 if (unit->
bias != 0.0) {
2199 if (
len + 1 < str_maxncpy) {
2200 memmove(
str + prev_op_ofs + 1,
str + prev_op_ofs,
len - prev_op_ofs + 1);
2201 str[prev_op_ofs] =
'(';
2210 if (value_end_ofs + len_bias_num < str_maxncpy) {
2211 memmove(
str + value_end_ofs + len_bias_num,
str + value_end_ofs,
len - value_end_ofs + 1);
2212 memcpy(
str + value_end_ofs, str_tmp, len_bias_num);
2213 len += len_bias_num;
2214 found_ofs += len_bias_num;
2215 str_found += len_bias_num;
2219 int len_name = strlen(replace_str);
2220 int len_move = (
len - (found_ofs + len_name)) + 1;
2226 len_num = std::min(len_num, str_maxncpy);
2228 if (found_ofs + len_num + len_move > str_maxncpy) {
2230 len_move -= (found_ofs + len_num + len_move) - str_maxncpy;
2236 memmove(str_found + len_num, str_found + len_name, len_move);
2239 if (found_ofs + len_num > str_maxncpy) {
2241 len_num -= (found_ofs + len_num) - str_maxncpy;
2246 memcpy(str_found, str_tmp, len_num);
2251 str[str_maxncpy - 1] =
'\0';
2252 return found_ofs + len_num;
2256 char *
str,
int str_maxncpy,
char *str_tmp,
double scale_pref,
const bUnitDef *unit)
2261 str + ofs, str_maxncpy - ofs, str_tmp, scale_pref, unit, unit->
name_short, case_sensitive);
2263 str + ofs, str_maxncpy - ofs, str_tmp, scale_pref, unit, unit->
name_plural,
false);
2265 str + ofs, str_maxncpy - ofs, str_tmp, scale_pref, unit, unit->
name_alt, case_sensitive);
2267 str + ofs, str_maxncpy - ofs, str_tmp, scale_pref, unit, unit->
name,
false);
2308 const char *str_prev)
2313 if (str_prev && (unit ==
nullptr)) {
2318 if (unit ==
nullptr) {
2346 const double bias = (unit ==
nullptr) ? 0.0 : unit->
bias;
2348 return value * scalar + bias;
2352 char *
str,
int str_maxncpy,
const char *str_prev,
double scale_pref,
int system,
int type)
2359 double scale_pref_base = scale_pref;
2361 bool changed =
false;
2371 scale_pref_base *= default_unit->
scalar;
2375 if (
SNPRINTF(str_tmp,
"(%s)*%.9g",
str, default_unit->
scalar) <
sizeof(str_tmp)) {
2386 while (
unit_replace(
str, str_maxncpy, str_tmp, scale_pref_base, unit)) {
2396 for (
int system_iter = 0; system_iter <
UNIT_SYSTEM_TOT; system_iter++) {
2397 if (system_iter == system) {
2401 if (usys_iter ==
nullptr) {
2408 while ((ofs =
unit_replace(
str + ofs, str_maxncpy - ofs, str_tmp, scale_pref_base, unit))) {
2419 char *str_found =
str;
2421 while ((str_found = strchr(str_found,
SEP_CHR))) {
2422 bool op_found =
false;
2425 for (
const char *ch = str_found + 1; *ch !=
'\0'; ch++) {
2426 if (
ELEM(*ch,
' ',
'\t')) {
2434 *str_found++ = op_found ?
' ' :
'+';
2446 for (
const bUnitDef *unit = usys->
units; unit->
name && (str_maxncpy > 0); unit++) {
2447 if (unit->name_alt ==
nullptr) {
2451 const char *found =
unit_find_str(orig_str, unit->name_short, case_sensitive);
2452 if (found ==
nullptr) {
2456 int offset = int(found - orig_str);
2459 if (offset < str_maxncpy) {
2460 memcpy(
str, orig_str, offset);
2464 offset = str_maxncpy;
2468 orig_str += offset + strlen(unit->name_short);
2469 str_maxncpy -= offset;
2475 str_maxncpy -= len_name;
2486 if (usys ==
nullptr) {
2491 if (unit ==
nullptr) {
2518 if (usys ==
nullptr) {
2554 BLI_assert_msg(0,
"identifier for this unit is not specified yet");
#define BLI_assert_msg(a, msg)
MINLINE int integer_digits_d(double d)
MINLINE int max_ii(int a, int b)
#define SNPRINTF(dst, format,...)
size_t BLI_snprintf_rlen(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char char size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
int char * BLI_strcasestr(const char *s, const char *find) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
const char * BLI_str_find_prev_char_utf8(const char *p, const char *str_start) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1
#define BLI_STR_UTF8_DEGREE_SIGN
#define BLI_STR_UTF8_SUPERSCRIPT_2
#define BLI_STR_UTF8_SUPERSCRIPT_3
Compatibility-like things for windows.
#define USER_UNIT_ADAPTIVE
static void split(const char *text, const char *seps, char ***str, int *count)
int pad[32 - sizeof(int)]
float length(VecOp< float, D >) RET
const char * name_display
static bUnitCollection buCameraLenCollection
static const bUnitCollection * unit_get_system(int system, int type)
static bool ch_is_op_unary(char op)
void BKE_unit_name_to_alt(char *str, int str_maxncpy, const char *orig_str, int system, int type)
static bUnitCollection buImperialVolCollection
int BKE_unit_base_of_type_get(int system, int type)
static bUnitDef buImperialTempDef[]
static const bUnitCollection * bUnitSystems[][B_UNIT_TYPE_TOT]
static PreferredUnits preferred_units_from_UnitSettings(const UnitSettings &settings)
static bUnitCollection buNaturalTimeCollection
static bUnitDef buImperialAclDef[]
static size_t unit_as_string(char *str, int str_maxncpy, double value, int prec, const bUnitCollection *usys, const bUnitDef *unit, char pad)
static bUnitDef buWavelengthLenDef[]
bool BKE_unit_is_valid(int system, int type)
size_t BKE_unit_value_as_string(char *str, int str_maxncpy, double value, int prec, int type, const UnitSettings &settings, bool pad)
static bUnitCollection buMetricMassCollection
static const bUnitDef * unit_find_in_collection(const bUnitCollection *usys, const char *str)
size_t BKE_unit_value_as_string_scaled(char *str, int str_maxncpy, double value, int prec, int type, const UnitSettings &settings, bool pad)
static bUnitCollection buDummyCollection
static bUnitCollection buImperialVelCollection
static bUnitDef buDummyDef[]
static void unit_dual_convert(double value, const bUnitCollection *usys, bUnitDef const **r_unit_a, bUnitDef const **r_unit_b, double *r_value_a, double *r_value_b, const bUnitDef *main_unit)
static bool is_valid_unit_collection(const bUnitCollection *usys)
const char * BKE_unit_identifier_get(const void *usys_pt, int index)
static bUnitDef buCameraLenDef[]
static bUnitCollection buImperialAreaCollection
bool BKE_unit_is_suppressed(const void *usys_pt, int index)
static bUnitCollection buNaturalRotCollection
#define UNIT_COLLECTION_LENGTH(def)
static bUnitDef buImperialMassDef[]
void BKE_unit_system_get(int system, int type, void const **r_usys_pt, int *r_len)
static bUnitCollection buImperialTempCollection
static bUnitCollection buImperialAclCollection
static bUnitCollection buImperialMassCollection
static bUnitDef buPowerDef[]
static int unit_scale_str(char *str, int str_maxncpy, char *str_tmp, double scale_pref, const bUnitDef *unit, const char *replace_str, bool case_sensitive)
static const bUnitDef * unit_best_fit(double value, const bUnitCollection *usys, const bUnitDef *unit_start, int suppress)
static char * find_next_op(const char *str, char *remaining_str, int remaining_str_maxncpy)
static bUnitCollection buMetricAclCollection
double BKE_unit_value_scale(const UnitSettings &settings, const int unit_type, double value)
const char * BKE_unit_display_name_get(const void *usys_pt, int index)
static bUnitDef buFrequencyDef[]
static bUnitCollection buColorTempCollection
static bool unit_find(const char *str, const bUnitDef *unit)
const char * BKE_unit_name_get(const void *usys_pt, int index)
int BKE_unit_base_get(const void *usys_pt)
bool BKE_unit_replace_string(char *str, int str_maxncpy, const char *str_prev, double scale_pref, int system, int type)
double BKE_unit_apply_preferred_unit(const UnitSettings &settings, int type, double value)
static int unit_replace(char *str, int str_maxncpy, char *str_tmp, double scale_pref, const bUnitDef *unit)
double BKE_unit_scalar_get(const void *usys_pt, int index)
static bUnitDef buMetricMassDef[]
static const char * find_next_negative(const char *str, const char *remaining_str)
static bool ch_is_op(char op)
static const bUnitDef * unit_detect_from_str(const bUnitCollection *usys, const char *str, const char *str_prev)
double BKE_unit_closest_scalar(double value, int system, int type)
static bUnitCollection buMetricAreaCollection
static bUnitDef buMetricVelDef[]
static const bUnitDef * unit_default(const bUnitCollection *usys)
static size_t unit_as_string_split_pair(char *str, int str_maxncpy, double value, int prec, const bUnitCollection *usys, const bUnitDef *main_unit)
@ B_UNIT_DEF_CASE_SENSITIVE
static bUnitCollection buMetricVolCollection
static bool unit_distribute_negatives(char *str, const int str_maxncpy)
static int find_previous_non_value_char(const char *str, const int start_ofs)
static bUnitDef buNaturalRotDef[]
static bUnitDef buImperialAreaDef[]
static bUnitDef buImperialVelDef[]
static size_t unit_as_string_main(char *str, int str_maxncpy, double value, int prec, int type, bool split, bool pad, const PreferredUnits &units)
static const bUnitDef * get_preferred_display_unit_if_used(int type, const PreferredUnits &units)
double BKE_unit_base_scalar(int system, int type)
static bUnitDef buColorTempDef[]
static bUnitCollection buFrequencyCollection
static const char * unit_find_str(const char *str, const char *substr, bool case_sensitive)
static bUnitCollection buPowerCollection
bool BKE_unit_string_contains_unit(const char *str, int type)
size_t BKE_unit_value_as_string_adaptive(char *str, int str_maxncpy, double value, int prec, int system, int type, bool split, bool pad)
static bUnitDef buMetricAreaDef[]
static bUnitDef buMetricTempDef[]
static bUnitDef buMetricAclDef[]
static bUnitCollection buImperialLenCollection
static char * skip_unary_op(char *str)
static bUnitCollection buMetricTempCollection
static bUnitDef buMetricLenDef[]
static bUnitCollection buWavelengthLenCollection
static int find_end_of_value_chars(const char *str, const int str_maxncpy, const int start_ofs)
static bUnitDef buImperialVolDef[]
static bUnitDef buNaturalTimeDef[]
static bUnitDef buImperialLenDef[]
static const bUnitCollection buMetricLenCollection
static bUnitCollection buMetricVelCollection
BLI_INLINE bool isalpha_or_utf8(const int ch)
static bool unit_should_be_split(int type)
static bUnitDef buMetricVolDef[]