<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>