<div dir="ltr"><div style="font-family:tahoma,sans-serif" class="gmail_default">After spending several days of trying to track down weird behaviour when using Cairo, I finally found the culprit:</div><div style="font-family:tahoma,sans-serif" class="gmail_default">In cairo-misc.c there is a function called _cairo_strtod() that is intended as a replacement to the standard strtod(), meaning it should convert a string to a double. The difference according to the comment is that it "ignores locale and only accepts decimal points".</div><div style="font-family:tahoma,sans-serif" class="gmail_default"><br></div><div style="font-family:tahoma,sans-serif" class="gmail_default">However, in difference to the original strtod() function, it can't deal with negative numbers in strings and will always return "0" for them. Not good!</div><div style="font-family:tahoma,sans-serif" class="gmail_default">This is particularly relevant when dealing with variation fonts, as the axis parameters need to be given as a string and many of them have a negative range, which leads to faulty display of these fonts.</div><div style="font-family:tahoma,sans-serif" class="gmail_default"><br></div><div style="font-family:tahoma,sans-serif" class="gmail_default">I made a hotfix/verification in my own Cairo sources, and it seems to work fine, but I can't make a pull request at the moment, so I post it below, though there might be an easier way to fix this for sure:<br></div><div style="font-family:tahoma,sans-serif" class="gmail_default"><br></div><div style="font-family:tahoma,sans-serif" class="gmail_default"><span></span><pre style="font-family:Consolas;color:black;background:white none repeat scroll 0% 0%"><span style="color:blue">double</span>
_cairo_strtod (<span style="color:blue">const</span> <span style="color:blue">char</span> *<span style="color:gray">nptr</span>, <span style="color:blue">char</span> **<span style="color:gray">endptr</span>)
{
<span style="color:blue">const</span> <span style="color:blue">char</span> *decimal_point;
<span style="color:blue">int</span> decimal_point_len;
<span style="color:blue">const</span> <span style="color:blue">char</span> *p;
<span style="color:blue">char</span> buf[100];
<span style="color:blue">char</span> *bufptr;
<span style="color:blue">char</span> *bufend = buf + <span style="color:blue">sizeof</span>(buf) - 1;
<span style="color:blue">double</span> value;
<span style="color:blue">char</span> *end;
<span style="color:blue">int</span> delta;
<span style="color:rgb(43,145,175)">cairo_bool_t</span> have_dp;
<span style="color:blue">int</span> inv; <span style="color:green">//[TF]</span>
decimal_point = _cairo_get_locale_decimal_point ();
decimal_point_len = strlen (decimal_point);
<span style="color:rgb(111,0,138)">assert</span> (decimal_point_len != 0);
p = <span style="color:gray">nptr</span>;
bufptr = buf;
delta = 0;
have_dp = <span style="color:rgb(111,0,138)">FALSE</span>;
<span style="color:blue">while</span> (*p && _cairo_isspace (*p)) {
p++;
delta++;
}
inv = 1; <span style="color:green">//[TF]</span>
<span style="color:blue">while</span> (*p && (bufptr + decimal_point_len < bufend)) {
<span style="color:blue">if</span> (_cairo_isdigit (*p)) {
*bufptr++ = *p;
} <span style="color:blue">else</span> <span style="color:blue">if</span> (*p == <span style="color:rgb(163,21,21)">'-'</span>) { <span style="color:green">//[TF]</span>
inv = -1; <span style="color:green">//[TF]</span>
delta++; <span style="color:green">//[TF]</span>
} <span style="color:blue">else</span> <span style="color:blue">if</span> (*p == <span style="color:rgb(163,21,21)">'.'</span>) {
<span style="color:blue">if</span> (have_dp)
<span style="color:blue">break</span>;
strncpy (bufptr, decimal_point, decimal_point_len);
bufptr += decimal_point_len;
delta -= decimal_point_len - 1;
have_dp = <span style="color:rgb(111,0,138)">TRUE</span>;
} <span style="color:blue">else</span> {
<span style="color:blue">break</span>;
}
p++;
}
*bufptr = 0;
value = strtod (buf, &end) * inv; <span style="color:green">//[TF]</span>
<span style="color:blue">if</span> (<span style="color:gray">endptr</span>) {
<span style="color:blue">if</span> (end == buf)
*<span style="color:gray">endptr</span> = (<span style="color:blue">char</span>*)(<span style="color:gray">nptr</span>);
<span style="color:blue">else</span>
*<span style="color:gray">endptr</span> = (<span style="color:blue">char</span>*)(<span style="color:gray">nptr</span> + (end - buf) + delta);
}
<span style="color:blue">return</span> value;
}
</pre></div></div>