static PyObject * complex_repr(PyComplexObject *v) { int precision = 0; char format_code = 'r'; PyObject *result = NULL; /* If these are non-NULL, they'll need to be freed. */ char *pre = NULL; char *im = NULL; /* These do not need to be freed. re is either an alias for pre or a pointer to a constant. lead and tail are pointers to constants. */ const char *re = NULL; const char *lead = ""; const char *tail = ""; if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) { /* Real part is +0: just output the imaginary part and do not include parens. */ re = ""; im = PyOS_double_to_string(v->cval.imag, format_code, precision, 0, NULL); if (!im) { PyErr_NoMemory(); goto done; } } else { /* Format imaginary part with sign, real part without. Include parens in the result. */ pre = PyOS_double_to_string(v->cval.real, format_code, precision, 0, NULL); if (!pre) { PyErr_NoMemory(); goto done; } re = pre; im = PyOS_double_to_string(v->cval.imag, format_code, precision, Py_DTSF_SIGN, NULL); if (!im) { PyErr_NoMemory(); goto done; } lead = "("; tail = ")"; } result = PyUnicode_FromFormat("%s%s%sj%s", lead, re, im, tail); done: PyMem_Free(im); PyMem_Free(pre); return result; }
static PyObject* speedup_pdf_float(PyObject *self, PyObject *args) { double f = 0.0, a = 0.0; char *buf = "0", *dot; void *free_buf = NULL; int precision = 6, l = 0; PyObject *ret; if(!PyArg_ParseTuple(args, "d", &f)) return NULL; a = fabs(f); if (a > 1.0e-7) { if(a > 1) precision = min(max(0, 6-(int)log10(a)), 6); buf = PyOS_double_to_string(f, 'f', precision, 0, NULL); if (buf != NULL) { free_buf = (void*)buf; if (precision > 0) { l = strlen(buf) - 1; while (l > 0 && buf[l] == '0') l--; if (buf[l] == ',' || buf[l] == '.') buf[l] = 0; else buf[l+1] = 0; if ( (dot = strchr(buf, ',')) ) *dot = '.'; } } else if (!PyErr_Occurred()) PyErr_SetString(PyExc_TypeError, "Float->str failed."); } ret = PyUnicode_FromString(buf); if (free_buf != NULL) PyMem_Free(free_buf); return ret; }
static int append_command_string( DecomposeToStringData *data, FT_Pos *points, size_t npoints, char *command) { size_t i; size_t len; char *buf; if (data->prefix) { len = strlen(command); if (to_string_expand_buffer(data, len)) { return -1; } strncpy(data->buffer + data->cursor, command, data->buffer_size - data->cursor); data->cursor += len; } for (i = 0; i < npoints; ++i) { buf = PyOS_double_to_string(FROM_F26DOT6(points[i]), 'r', 0, 0, NULL); len = strnlen(buf, 64); if (to_string_expand_buffer(data, len)) { return -1; } strncpy(data->buffer + data->cursor, buf, data->buffer_size - data->cursor); data->cursor += len; PyMem_Free(buf); if (i < npoints - 1) { data->buffer[data->cursor++] = ' '; } } if (!data->prefix) { len = strlen(command); if (to_string_expand_buffer(data, len)) { return -1; } strncpy(data->buffer + data->cursor, command, data->buffer_size - data->cursor); data->cursor += len; } return 0; }
/* much of this is taken from unicodeobject.c */ static int format_float_internal(PyObject *value, const InternalFormatSpec *format, _PyUnicodeWriter *writer) { char *buf = NULL; /* buffer returned from PyOS_double_to_string */ Py_ssize_t n_digits; Py_ssize_t n_remainder; Py_ssize_t n_total; int has_decimal; double val; int precision, default_precision = 6; Py_UCS4 type = format->type; int add_pct = 0; Py_ssize_t index; NumberFieldWidths spec; int flags = 0; int result = -1; Py_UCS4 maxchar = 127; Py_UCS4 sign_char = '\0'; int float_type; /* Used to see if we have a nan, inf, or regular float. */ PyObject *unicode_tmp = NULL; /* Locale settings, either from the actual locale or from a hard-code pseudo-locale */ LocaleInfo locale = STATIC_LOCALE_INFO_INIT; if (format->precision > INT_MAX) { PyErr_SetString(PyExc_ValueError, "precision too big"); goto done; } precision = (int)format->precision; if (format->alternate) flags |= Py_DTSF_ALT; if (type == '\0') { /* Omitted type specifier. Behaves in the same way as repr(x) and str(x) if no precision is given, else like 'g', but with at least one digit after the decimal point. */ flags |= Py_DTSF_ADD_DOT_0; type = 'r'; default_precision = 0; } if (type == 'n') /* 'n' is the same as 'g', except for the locale used to format the result. We take care of that later. */ type = 'g'; val = PyFloat_AsDouble(value); if (val == -1.0 && PyErr_Occurred()) goto done; if (type == '%') { type = 'f'; val *= 100; add_pct = 1; } if (precision < 0) precision = default_precision; else if (type == 'r') type = 'g'; /* Cast "type", because if we're in unicode we need to pass a 8-bit char. This is safe, because we've restricted what "type" can be. */ buf = PyOS_double_to_string(val, (char)type, precision, flags, &float_type); if (buf == NULL) goto done; n_digits = strlen(buf); if (add_pct) { /* We know that buf has a trailing zero (since we just called strlen() on it), and we don't use that fact any more. So we can just write over the trailing zero. */ buf[n_digits] = '%'; n_digits += 1; } if (format->sign != '+' && format->sign != ' ' && format->width == -1 && format->type != 'n' && !format->thousands_separators) { /* Fast path */ result = _PyUnicodeWriter_WriteASCIIString(writer, buf, n_digits); PyMem_Free(buf); return result; } /* Since there is no unicode version of PyOS_double_to_string, just use the 8 bit version and then convert to unicode. */ unicode_tmp = _PyUnicode_FromASCII(buf, n_digits); PyMem_Free(buf); if (unicode_tmp == NULL) goto done; /* Is a sign character present in the output? If so, remember it and skip it */ index = 0; if (PyUnicode_READ_CHAR(unicode_tmp, index) == '-') { sign_char = '-'; ++index; --n_digits; } /* Determine if we have any "remainder" (after the digits, might include decimal or exponent or both (or neither)) */ parse_number(unicode_tmp, index, index + n_digits, &n_remainder, &has_decimal); /* Determine the grouping, separator, and decimal point, if any. */ if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : (format->thousands_separators ? LT_DEFAULT_LOCALE : LT_NO_LOCALE), &locale) == -1) goto done; /* Calculate how much memory we'll need. */ n_total = calc_number_widths(&spec, 0, sign_char, unicode_tmp, index, index + n_digits, n_remainder, has_decimal, &locale, format, &maxchar); /* Allocate the memory. */ if (_PyUnicodeWriter_Prepare(writer, n_total, maxchar) == -1) goto done; /* Populate the memory. */ result = fill_number(writer, &spec, unicode_tmp, index, index + n_digits, NULL, 0, format->fill_char, &locale, 0); done: Py_XDECREF(unicode_tmp); free_locale_info(&locale); return result; }
static int format_complex_internal(PyObject *value, const InternalFormatSpec *format, _PyUnicodeWriter *writer) { double re; double im; char *re_buf = NULL; /* buffer returned from PyOS_double_to_string */ char *im_buf = NULL; /* buffer returned from PyOS_double_to_string */ InternalFormatSpec tmp_format = *format; Py_ssize_t n_re_digits; Py_ssize_t n_im_digits; Py_ssize_t n_re_remainder; Py_ssize_t n_im_remainder; Py_ssize_t n_re_total; Py_ssize_t n_im_total; int re_has_decimal; int im_has_decimal; int precision, default_precision = 6; Py_UCS4 type = format->type; Py_ssize_t i_re; Py_ssize_t i_im; NumberFieldWidths re_spec; NumberFieldWidths im_spec; int flags = 0; int result = -1; Py_UCS4 maxchar = 127; enum PyUnicode_Kind rkind; void *rdata; Py_UCS4 re_sign_char = '\0'; Py_UCS4 im_sign_char = '\0'; int re_float_type; /* Used to see if we have a nan, inf, or regular float. */ int im_float_type; int add_parens = 0; int skip_re = 0; Py_ssize_t lpad; Py_ssize_t rpad; Py_ssize_t total; PyObject *re_unicode_tmp = NULL; PyObject *im_unicode_tmp = NULL; /* Locale settings, either from the actual locale or from a hard-code pseudo-locale */ LocaleInfo locale = STATIC_LOCALE_INFO_INIT; if (format->precision > INT_MAX) { PyErr_SetString(PyExc_ValueError, "precision too big"); goto done; } precision = (int)format->precision; /* Zero padding is not allowed. */ if (format->fill_char == '0') { PyErr_SetString(PyExc_ValueError, "Zero padding is not allowed in complex format " "specifier"); goto done; } /* Neither is '=' alignment . */ if (format->align == '=') { PyErr_SetString(PyExc_ValueError, "'=' alignment flag is not allowed in complex format " "specifier"); goto done; } re = PyComplex_RealAsDouble(value); if (re == -1.0 && PyErr_Occurred()) goto done; im = PyComplex_ImagAsDouble(value); if (im == -1.0 && PyErr_Occurred()) goto done; if (format->alternate) flags |= Py_DTSF_ALT; if (type == '\0') { /* Omitted type specifier. Should be like str(self). */ type = 'r'; default_precision = 0; if (re == 0.0 && copysign(1.0, re) == 1.0) skip_re = 1; else add_parens = 1; } if (type == 'n') /* 'n' is the same as 'g', except for the locale used to format the result. We take care of that later. */ type = 'g'; if (precision < 0) precision = default_precision; else if (type == 'r') type = 'g'; /* Cast "type", because if we're in unicode we need to pass a 8-bit char. This is safe, because we've restricted what "type" can be. */ re_buf = PyOS_double_to_string(re, (char)type, precision, flags, &re_float_type); if (re_buf == NULL) goto done; im_buf = PyOS_double_to_string(im, (char)type, precision, flags, &im_float_type); if (im_buf == NULL) goto done; n_re_digits = strlen(re_buf); n_im_digits = strlen(im_buf); /* Since there is no unicode version of PyOS_double_to_string, just use the 8 bit version and then convert to unicode. */ re_unicode_tmp = _PyUnicode_FromASCII(re_buf, n_re_digits); if (re_unicode_tmp == NULL) goto done; i_re = 0; im_unicode_tmp = _PyUnicode_FromASCII(im_buf, n_im_digits); if (im_unicode_tmp == NULL) goto done; i_im = 0; /* Is a sign character present in the output? If so, remember it and skip it */ if (PyUnicode_READ_CHAR(re_unicode_tmp, i_re) == '-') { re_sign_char = '-'; ++i_re; --n_re_digits; } if (PyUnicode_READ_CHAR(im_unicode_tmp, i_im) == '-') { im_sign_char = '-'; ++i_im; --n_im_digits; } /* Determine if we have any "remainder" (after the digits, might include decimal or exponent or both (or neither)) */ parse_number(re_unicode_tmp, i_re, i_re + n_re_digits, &n_re_remainder, &re_has_decimal); parse_number(im_unicode_tmp, i_im, i_im + n_im_digits, &n_im_remainder, &im_has_decimal); /* Determine the grouping, separator, and decimal point, if any. */ if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : (format->thousands_separators ? LT_DEFAULT_LOCALE : LT_NO_LOCALE), &locale) == -1) goto done; /* Turn off any padding. We'll do it later after we've composed the numbers without padding. */ tmp_format.fill_char = '\0'; tmp_format.align = '<'; tmp_format.width = -1; /* Calculate how much memory we'll need. */ n_re_total = calc_number_widths(&re_spec, 0, re_sign_char, re_unicode_tmp, i_re, i_re + n_re_digits, n_re_remainder, re_has_decimal, &locale, &tmp_format, &maxchar); /* Same formatting, but always include a sign, unless the real part is * going to be omitted, in which case we use whatever sign convention was * requested by the original format. */ if (!skip_re) tmp_format.sign = '+'; n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, im_unicode_tmp, i_im, i_im + n_im_digits, n_im_remainder, im_has_decimal, &locale, &tmp_format, &maxchar); if (skip_re) n_re_total = 0; /* Add 1 for the 'j', and optionally 2 for parens. */ calc_padding(n_re_total + n_im_total + 1 + add_parens * 2, format->width, format->align, &lpad, &rpad, &total); if (lpad || rpad) maxchar = Py_MAX(maxchar, format->fill_char); if (_PyUnicodeWriter_Prepare(writer, total, maxchar) == -1) goto done; rkind = writer->kind; rdata = writer->data; /* Populate the memory. First, the padding. */ result = fill_padding(writer, n_re_total + n_im_total + 1 + add_parens * 2, format->fill_char, lpad, rpad); if (result == -1) goto done; if (add_parens) { PyUnicode_WRITE(rkind, rdata, writer->pos, '('); writer->pos++; } if (!skip_re) { result = fill_number(writer, &re_spec, re_unicode_tmp, i_re, i_re + n_re_digits, NULL, 0, 0, &locale, 0); if (result == -1) goto done; } result = fill_number(writer, &im_spec, im_unicode_tmp, i_im, i_im + n_im_digits, NULL, 0, 0, &locale, 0); if (result == -1) goto done; PyUnicode_WRITE(rkind, rdata, writer->pos, 'j'); writer->pos++; if (add_parens) { PyUnicode_WRITE(rkind, rdata, writer->pos, ')'); writer->pos++; } writer->pos += rpad; done: PyMem_Free(re_buf); PyMem_Free(im_buf); Py_XDECREF(re_unicode_tmp); Py_XDECREF(im_unicode_tmp); free_locale_info(&locale); return result; }
Py::Object _path_module::convert_to_svg(const Py::Tuple& args) { args.verify_length(5); PathIterator path(args[0]); agg::trans_affine trans = py_to_agg_transformation_matrix(args[1].ptr(), false); Py::Object clip_obj = args[2]; bool do_clip; agg::rect_base<double> clip_rect(0, 0, 0, 0); if (clip_obj.isNone() || !clip_obj.isTrue()) { do_clip = false; } else { double x1, y1, x2, y2; Py::Tuple clip_tuple(clip_obj); x1 = Py::Float(clip_tuple[0]); y1 = Py::Float(clip_tuple[1]); x2 = Py::Float(clip_tuple[2]); y2 = Py::Float(clip_tuple[3]); clip_rect.init(x1, y1, x2, y2); do_clip = true; } bool simplify; Py::Object simplify_obj = args[3]; if (simplify_obj.isNone()) { simplify = path.should_simplify(); } else { simplify = simplify_obj.isTrue(); } int precision = Py::Int(args[4]); #if PY_VERSION_HEX < 0x02070000 char format[64]; snprintf(format, 64, "%s.%dg", "%", precision); #endif typedef agg::conv_transform<PathIterator> transformed_path_t; typedef PathNanRemover<transformed_path_t> nan_removal_t; typedef PathClipper<nan_removal_t> clipped_t; typedef PathSimplifier<clipped_t> simplify_t; transformed_path_t tpath(path, trans); nan_removal_t nan_removed(tpath, true, path.has_curves()); clipped_t clipped(nan_removed, do_clip, clip_rect); simplify_t simplified(clipped, simplify, path.simplify_threshold()); size_t buffersize = path.total_vertices() * (precision + 5) * 4; char* buffer = (char *)malloc(buffersize); char* p = buffer; const char codes[] = {'M', 'L', 'Q', 'C'}; const int waits[] = { 1, 1, 2, 3}; int wait = 0; unsigned code; double x = 0, y = 0; while ((code = simplified.vertex(&x, &y)) != agg::path_cmd_stop) { if (wait == 0) { *p++ = '\n'; if (code == 0x4f) { *p++ = 'z'; *p++ = '\n'; continue; } *p++ = codes[code-1]; wait = waits[code-1]; } else { *p++ = ' '; } #if PY_VERSION_HEX >= 0x02070000 char* str; str = PyOS_double_to_string(x, 'g', precision, 0, NULL); p += snprintf(p, buffersize - (p - buffer), str); PyMem_Free(str); *p++ = ' '; str = PyOS_double_to_string(y, 'g', precision, 0, NULL); p += snprintf(p, buffersize - (p - buffer), str); PyMem_Free(str); #else char str[64]; PyOS_ascii_formatd(str, 64, format, x); p += snprintf(p, buffersize - (p - buffer), str); *p++ = ' '; PyOS_ascii_formatd(str, 64, format, y); p += snprintf(p, buffersize - (p - buffer), str); #endif --wait; } #if PY3K PyObject* result = PyUnicode_FromStringAndSize(buffer, p - buffer); #else PyObject* result = PyString_FromStringAndSize(buffer, p - buffer); #endif free(buffer); return Py::Object(result, true); }
static PyObject * complex_format(PyComplexObject *v, int precision, char format_code) { PyObject *result = NULL; Py_ssize_t len; /* If these are non-NULL, they'll need to be freed. */ char *pre = NULL; char *im = NULL; char *buf = NULL; /* These do not need to be freed. re is either an alias for pre or a pointer to a constant. lead and tail are pointers to constants. */ char *re = NULL; char *lead = ""; char *tail = ""; if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) { re = ""; im = PyOS_double_to_string(v->cval.imag, format_code, precision, 0, NULL); if (!im) { PyErr_NoMemory(); goto done; } } else { /* Format imaginary part with sign, real part without */ pre = PyOS_double_to_string(v->cval.real, format_code, precision, 0, NULL); if (!pre) { PyErr_NoMemory(); goto done; } re = pre; im = PyOS_double_to_string(v->cval.imag, format_code, precision, Py_DTSF_SIGN, NULL); if (!im) { PyErr_NoMemory(); goto done; } lead = "("; tail = ")"; } /* Alloc the final buffer. Add one for the "j" in the format string, and one for the trailing zero. */ len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2; buf = PyMem_Malloc(len); if (!buf) { PyErr_NoMemory(); goto done; } PyOS_snprintf(buf, len, "%s%s%sj%s", lead, re, im, tail); result = PyUnicode_FromString(buf); done: PyMem_Free(im); PyMem_Free(pre); PyMem_Free(buf); return result; }