/*
5 * Authors: see git history
7 * Lauris Kaplinski <lauris@kaplinski.com>
8 * bulia byak <buliabyak@users.sf.net>
10 * Copyright (C) 2018 Authors
11 * Released under GNU GPL v2+, read the file
'COPYING' for more information.
22#include "stringstream.h"
31# define MAX(a,b) ((a < b) ? (b) : (a))
41 float const v = g_ascii_strtod(str, &e);
42 if ((gchar
const *) e == str) {
57 double const v = g_ascii_strtod(str, &e);
58 if ((gchar
const *) e == str) {
79 idigits = (int)
floor(log10(val)) + 1;
83 fprec =
MAX(
static_cast<int>(fprec),
static_cast<int>(tprec) - idigits);
85 val += 0.5 / pow(10.0, fprec);
87 double dival =
floor(val);
88 double fval = val - dival;
90 if (idigits > (
int)tprec) {
91 buf.append(std::to_string((
unsigned int)
floor(dival/pow(10.0, idigits-tprec) + .5)));
92 for(
unsigned int j=0; j<(
unsigned int)idigits-tprec; j++) {
96 buf.append(std::to_string((
unsigned int)dival));
99 if (fprec > 0 && fval > 0.0) {
105 int const int_dival = (int) dival;
106 s.append(std::to_string(int_dival));
112 }
while(fprec > 0 && fval > 0.0);
120 int eval = (int)
floor(log10(fabs(val)));
121 if (val == 0.0 || eval < min_exp) {
125 unsigned int maxnumdigitsWithoutExp =
126 eval<0?tprec+(
unsigned int)-eval+1:
127 eval+1<(int)tprec?tprec+1:
128 (
unsigned int)eval+1;
129 unsigned int maxnumdigitsWithExp = tprec + ( eval<0 ? 4 : 3 );
130 if (maxnumdigitsWithoutExp <= maxnumdigitsWithExp) {
133 val = eval < 0 ? val * pow(10.0, -eval) : val / pow(10.0, eval);
136 buf.append(std::to_string(eval));
165 if (!std::isfinite(v)) {
247 return std::vector<SVGLength>();
253 char *next = (
char *) str;
254 std::vector<SVGLength> list;
259 length.set(unit, value, computed);
260 list.push_back(length);
262 while (next && *next &&
263 (*next ==
',' || *next ==
' ' || *next ==
'\n' || *next ==
'\r' || *next ==
'\t')) {
269 if (!next || !*next) {
278#define UVAL(a,b) (((unsigned int) (a) << 8) | (unsigned int) (b))
291 float const v = g_ascii_strtod(str, (
char **) &e);
311 }
else if (!g_ascii_isalnum(e[0])) {
315 if (e[1] && g_ascii_isalnum(e[1])) {
325 *computed = v * 0.01;
328 *next = (
char *) e + 1;
331 }
else if (g_ascii_isspace(e[0]) && e[1] && g_ascii_isalpha(e[1])) {
349 }
else if (e[1] && !g_ascii_isalnum(e[2])) {
353 unsigned int const uval = UVAL(e[0], e[1]);
422 *next = (
char *) e + 2;
458std::string
SVGLength::toString(
const std::string &out_unit,
double doc_scale, std::optional<unsigned int> precision,
bool add_unit)
const
493bool SVGLength::fromString(
const std::string &input,
const std::string &default_unit, std::optional<double> doc_scale)
495 if (!
read((input + default_unit).c_str()))
496 if (!
read(input.c_str()))
502 scale(1 / *doc_scale);
511 Glib::ustring hack(
"px");
576 if (str ==
nullptr) {
581 double v = g_ascii_strtod(str, &u);
582 while (isspace(*u)) {
644 if (g_str_equal(str,
"left")) {
646 }
else if (g_str_equal(str,
"center")) {
648 }
else if (g_str_equal(str,
"right")) {
658 if (g_str_equal(str,
"top")) {
660 }
else if (g_str_equal(str,
"center")) {
662 }
else if (g_str_equal(str,
"bottom")) {
static double convert(double from_dist, Unit const *from, Unit const *to)
Convert distances.
double toValue(const std::string &out_unit) const
Caulate the length in a user unit.
std::string toString(const std::string &unit, double doc_scale, std::optional< unsigned int > precision={}, bool add_unit=true) const
Write out length in user unit, for the user to use.
void set(Unit u, float v)
bool read(char const *str)
std::string getUnit() const
Returns the unit used as a string.
bool isAbsolute()
Is this length an absolute value (uses an absolute unit).
std::string write() const
void readOrUnset(char const *str, Unit u=NONE, float v=0, float c=0)
void unset(Unit u=NONE, float v=0, float c=0)
bool fromString(const std::string &input, const std::string &unit, std::optional< double > scale={})
Read from user input, any non-unitised value is converted internally.
bool readAbsolute(char const *str)
void update(double em, double ex, double scale)
Utility functions to convert ascii representations to numbers.
auto floor(Geom::Rect const &rect)
std::string format_number(double val, unsigned int precision=3)
Helper class to stream background task notifications as a series of messages.
char const * refY_named_to_percent(char const *str)
char const * refX_named_to_percent(char const *str)
static unsigned sp_svg_length_read_lff(gchar const *str, SVGLength::Unit *unit, float *val, float *computed, char **next)
std::vector< SVGLength > sp_svg_length_list_read(gchar const *str)
std::string sp_svg_length_write_with_units(SVGLength const &length)
N.B. This routine will sometimes return strings with āeā notation, so is unsuitable for CSS lengths (...
unsigned int sp_svg_length_read_computed_absolute(gchar const *str, float *length)
static std::string sp_svg_number_write_d(double val, unsigned int tprec, unsigned int fprec)
bool svg_length_absolute_unit(SVGLength::Unit u)
double sp_svg_read_percentage(char const *str, double def)
std::string sp_svg_number_write_de(double val, unsigned int tprec, int min_exp)
unsigned int sp_svg_number_read_f(gchar const *str, float *val)
gchar const * sp_svg_length_get_css_units(SVGLength::Unit unit)
unsigned int sp_svg_number_read_d(gchar const *str, double *val)
unsigned int sp_svg_length_read_ldd(gchar const *str, SVGLength::Unit *unit, double *value, double *computed)
bool svg_length_absolute_unit(SVGLength::Unit unit)
char const * sp_svg_length_get_css_units(SVGLength::Unit unit)