1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
// SPDX-License-Identifier: GPL-2.0-or-later
/** @file
* Utility functions to convert ascii representations to numbers
*/
#ifndef UTIL_NUM_CONVERTERS_H
#define UTIL_NUM_CONVERTERS_H
/*
* Authors:
* Felipe Corrêa da Silva Sanches <juca@members.fsf.org>
* Mohammad Aadil Shabier
*
*
* Copyright (C) 2006 Hugo Rodrigues
*
* Released under GNU GPL v2+, read the file 'COPYING' for more information.
*/
#include <iostream>
#include <cstring>
#include <sstream>
#include <vector>
namespace Inkscape {
namespace Util {
// while calling read_number(string, false), it's not obvious, what
// that false stands for. read_number(string, NO_WARNING)
// can be more explicit.
constexpr bool NO_WARNING = false;
/* convert ascii representation to double
* the function can only be used to convert numbers as given by gui elements that use localized representation
* @param value ascii representation of the number
* @return the converted number
*
* Setting warning to false disables conversion error warnings from
* this function. This can be useful in places, where the input type
* is not known beforehand. For example, see sp_feColorMatrix_set in
* sp-fecolormatrix.cpp
* Consider making warning = True by default since that's how it seems to be used everywhere?
*/
inline double read_number(gchar const *value, bool warning = true)
{
if (!value) {
g_warning("Called Inkscape::Util::read_number with value==null_ptr, this can lead to unexpected behaviour.");
return 0;
}
char *end;
double ret = g_ascii_strtod(value, &end);
if (*end) {
if (warning) {
g_warning("Inkscape::Util::read_number() Unable to convert \"%s\" to number", value);
}
// We could leave this out, too. If strtod can't convert
// anything, it will return zero.
ret = 0;
}
return ret;
}
inline bool read_bool(gchar const *value, bool default_value)
{
if (!value)
return default_value;
switch (value[0]) {
case 't':
if (strncmp(value, "true", 4) == 0)
return true;
break;
case 'f':
if (strncmp(value, "false", 5) == 0)
return false;
break;
}
return default_value;
}
/* convert ascii representation to double
* the function can only be used to convert numbers as given by gui elements that use localized representation
* numbers are delimited by space
* @param value ascii representation of the number
* @return the vector of the converted numbers
*/
inline std::vector<gdouble> read_vector(const gchar *value)
{
std::vector<gdouble> v;
gchar const *beg = value;
while (isspace(*beg) || (*beg == ','))
beg++;
while (*beg) {
char *end;
double ret = g_ascii_strtod(beg, &end);
if (end == beg) {
g_warning("Inkscape::Util::read_vector() Unable to convert \"%s\" to number", beg);
break;
}
v.push_back(ret);
beg = end;
while (isspace(*beg) || (*beg == ','))
beg++;
}
return v;
}
/*
* Format a number with any trailing zeros removed.
*/
inline std::string format_number(double val, unsigned int precision = 3)
{
std::ostringstream out;
out.imbue(std::locale("C"));
out.precision(precision);
out << std::fixed << val;
std::string ret = out.str();
while(ret.find(".") != std::string::npos
&& (ret.substr(ret.length() - 1, 1) == "0"
|| ret.substr(ret.length() - 1, 1) == "."))
ret.pop_back();
return ret;
}
} // namespace Util
} // namespace Inkscape
#endif // UTIL_NUM_CONVERTERS_H
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
|