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] =
'(';
2209 value_end_ofs = std::min(value_end_ofs, found_ofs);
2211 if (value_end_ofs + len_bias_num < str_maxncpy) {
2212 memmove(
str + value_end_ofs + len_bias_num,
str + value_end_ofs,
len - value_end_ofs + 1);
2213 memcpy(
str + value_end_ofs, str_tmp, len_bias_num);
2214 len += len_bias_num;
2215 found_ofs += len_bias_num;
2216 str_found += len_bias_num;
2220 int len_name = strlen(replace_str);
2221 int len_move = (
len - (found_ofs + len_name)) + 1;
2227 len_num = std::min(len_num, str_maxncpy);
2229 if (found_ofs + len_num + len_move > str_maxncpy) {
2231 len_move -= (found_ofs + len_num + len_move) - str_maxncpy;
2237 memmove(str_found + len_num, str_found + len_name, len_move);
2240 if (found_ofs + len_num > str_maxncpy) {
2242 len_num -= (found_ofs + len_num) - str_maxncpy;
2247 memcpy(str_found, str_tmp, len_num);
2252 str[str_maxncpy - 1] =
'\0';
2253 return found_ofs + len_num;
2257 char *
str,
int str_maxncpy,
char *str_tmp,
double scale_pref,
const bUnitDef *unit)
2262 str + ofs, str_maxncpy - ofs, str_tmp, scale_pref, unit, unit->
name_short, case_sensitive);
2264 str + ofs, str_maxncpy - ofs, str_tmp, scale_pref, unit, unit->
name_plural,
false);
2266 str + ofs, str_maxncpy - ofs, str_tmp, scale_pref, unit, unit->
name_alt, case_sensitive);
2268 str + ofs, str_maxncpy - ofs, str_tmp, scale_pref, unit, unit->
name,
false);
2309 const char *str_prev)
2314 if (str_prev && (unit ==
nullptr)) {
2319 if (unit ==
nullptr) {
2347 const double bias = (unit ==
nullptr) ? 0.0 : unit->
bias;
2349 return value * scalar + bias;
2353 char *
str,
int str_maxncpy,
const char *str_prev,
double scale_pref,
int system,
int type)
2360 double scale_pref_base = scale_pref;
2362 bool changed =
false;
2372 scale_pref_base *= default_unit->
scalar;
2376 if (
SNPRINTF(str_tmp,
"(%s)*%.9g",
str, default_unit->
scalar) <
sizeof(str_tmp)) {
2387 while (
unit_replace(
str, str_maxncpy, str_tmp, scale_pref_base, unit)) {
2397 for (
int system_iter = 0; system_iter <
UNIT_SYSTEM_TOT; system_iter++) {
2398 if (system_iter == system) {
2402 if (usys_iter ==
nullptr) {
2409 while ((ofs =
unit_replace(
str + ofs, str_maxncpy - ofs, str_tmp, scale_pref_base, unit))) {
2420 char *str_found =
str;
2422 while ((str_found = strchr(str_found,
SEP_CHR))) {
2423 bool op_found =
false;
2426 for (
const char *ch = str_found + 1; *ch !=
'\0'; ch++) {
2427 if (
ELEM(*ch,
' ',
'\t')) {
2435 *str_found++ = op_found ?
' ' :
'+';
2447 for (
const bUnitDef *unit = usys->
units; unit->
name && (str_maxncpy > 0); unit++) {
2448 if (unit->name_alt ==
nullptr) {
2452 const char *found =
unit_find_str(orig_str, unit->name_short, case_sensitive);
2453 if (found ==
nullptr) {
2457 int offset = int(found - orig_str);
2460 if (offset < str_maxncpy) {
2461 memcpy(
str, orig_str, offset);
2465 offset = str_maxncpy;
2469 orig_str += offset + strlen(unit->name_short);
2470 str_maxncpy -= offset;
2476 str_maxncpy -= len_name;
2487 if (usys ==
nullptr) {
2492 if (unit ==
nullptr) {
2519 if (usys ==
nullptr) {
2555 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)
@ B_UNIT_DEF_CASE_SENSITIVE
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)
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[]