[cairo] float-to-string conversion vs locale

Behdad Esfahbod behdad at cs.toronto.edu
Sat Apr 29 02:31:35 PDT 2006


On Sat, 29 Apr 2006, Alexander Larsson wrote:

> I just took a look at the float-to-string conversions in the postscript
> backend:
>
> _cairo_output_stream_printf (output_stream,
> 			 "%f %f moveto ",
> 			 _cairo_fixed_to_double (point->x),
> 			 _cairo_fixed_to_double (point->y));
>
> This is not locale-safe. In a locale with a decimal separator other than
> "." it will not produce valid postscript. Changing the locale to "C"
> while doing this is instead not threadsafe.

This is exactly the reason _cairo_output_stream_printf is there
in the first place:


/* Here's a limited reimplementation of printf.  The reason for doing
 * this is primarily to special case handling of doubles.  We want
 * locale independent formatting of doubles and we want to trim
 * trailing zeros.  This is handled by dtostr() above, and the code
 * below handles everything else by calling snprintf() to do the
 * formatting.  This functionality is only for internal use and we
 * only implement the formats we actually use.
 */
void
_cairo_output_stream_vprintf (cairo_output_stream_t *stream,
                              const char *fmt, va_list ap)


> For an approach to do this in a thread-safe way (the only good way I
> know of) see g_ascii_formatd() in glib (glib/gstrfuncs.c).

And it uses your code too:

/* Format a double in a locale independent way and trim trailing
 * zeros.  Based on code from Alex Larson <alexl at redhat.com>.
 * http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html
 */
int
_cairo_dtostr (char *buffer, size_t size, double d)


--behdad
http://behdad.org/

"Commandment Three says Do Not Kill, Amendment Two says Blood Will Spill"
	-- Dan Bern, "New American Language"


More information about the cairo mailing list