aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/matplotlib/py2/src/_ttconv.cpp
diff options
context:
space:
mode:
authorshumkovnd <shumkovnd@yandex-team.com>2023-11-10 14:39:34 +0300
committershumkovnd <shumkovnd@yandex-team.com>2023-11-10 16:42:24 +0300
commit77eb2d3fdcec5c978c64e025ced2764c57c00285 (patch)
treec51edb0748ca8d4a08d7c7323312c27ba1a8b79a /contrib/python/matplotlib/py2/src/_ttconv.cpp
parentdd6d20cadb65582270ac23f4b3b14ae189704b9d (diff)
downloadydb-77eb2d3fdcec5c978c64e025ced2764c57c00285.tar.gz
KIKIMR-19287: add task_stats_drawing script
Diffstat (limited to 'contrib/python/matplotlib/py2/src/_ttconv.cpp')
-rw-r--r--contrib/python/matplotlib/py2/src/_ttconv.cpp307
1 files changed, 307 insertions, 0 deletions
diff --git a/contrib/python/matplotlib/py2/src/_ttconv.cpp b/contrib/python/matplotlib/py2/src/_ttconv.cpp
new file mode 100644
index 0000000000..e0aa4611d2
--- /dev/null
+++ b/contrib/python/matplotlib/py2/src/_ttconv.cpp
@@ -0,0 +1,307 @@
+/* -*- mode: c++; c-basic-offset: 4 -*- */
+
+/*
+ _ttconv.c
+
+ Python wrapper for TrueType conversion library in ../ttconv.
+ */
+
+#include "mplutils.h"
+
+#include <Python.h>
+#include "ttconv/pprdrv.h"
+#include "py_exceptions.h"
+#include <vector>
+#include <cassert>
+
+/**
+ * An implementation of TTStreamWriter that writes to a Python
+ * file-like object.
+ */
+class PythonFileWriter : public TTStreamWriter
+{
+ PyObject *_write_method;
+
+ public:
+ PythonFileWriter()
+ {
+ _write_method = NULL;
+ }
+
+ ~PythonFileWriter()
+ {
+ Py_XDECREF(_write_method);
+ }
+
+ void set(PyObject *write_method)
+ {
+ Py_XDECREF(_write_method);
+ _write_method = write_method;
+ Py_XINCREF(_write_method);
+ }
+
+ virtual void write(const char *a)
+ {
+ PyObject *result = NULL;
+ if (_write_method) {
+ PyObject *decoded = NULL;
+ decoded = PyUnicode_DecodeLatin1(a, strlen(a), "");
+ if (decoded == NULL) {
+ throw py::exception();
+ }
+ result = PyObject_CallFunction(_write_method, (char *)"O", decoded);
+ Py_DECREF(decoded);
+ if (!result) {
+ throw py::exception();
+ }
+ Py_DECREF(result);
+ }
+ }
+};
+
+int fileobject_to_PythonFileWriter(PyObject *object, void *address)
+{
+ PythonFileWriter *file_writer = (PythonFileWriter *)address;
+
+ PyObject *write_method = PyObject_GetAttrString(object, "write");
+ if (write_method == NULL || !PyCallable_Check(write_method)) {
+ PyErr_SetString(PyExc_TypeError, "Expected a file-like object with a write method.");
+ return 0;
+ }
+
+ file_writer->set(write_method);
+ Py_DECREF(write_method);
+
+ return 1;
+}
+
+int pyiterable_to_vector_int(PyObject *object, void *address)
+{
+ std::vector<int> *result = (std::vector<int> *)address;
+
+ PyObject *iterator = PyObject_GetIter(object);
+ if (!iterator) {
+ return 0;
+ }
+
+ PyObject *item;
+ while ((item = PyIter_Next(iterator))) {
+#if PY3K
+ long value = PyLong_AsLong(item);
+#else
+ long value = PyInt_AsLong(item);
+#endif
+ Py_DECREF(item);
+ if (value == -1 && PyErr_Occurred()) {
+ return 0;
+ }
+ result->push_back((int)value);
+ }
+
+ Py_DECREF(iterator);
+
+ return 1;
+}
+
+static PyObject *convert_ttf_to_ps(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ const char *filename;
+ PythonFileWriter output;
+ int fonttype;
+ std::vector<int> glyph_ids;
+
+ static const char *kwlist[] = { "filename", "output", "fonttype", "glyph_ids", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kwds,
+#if PY_MAJOR_VERSION == 3
+ "yO&i|O&:convert_ttf_to_ps",
+#else
+ "sO&i|O&:convert_ttf_to_ps",
+#endif
+ (char **)kwlist,
+ &filename,
+ fileobject_to_PythonFileWriter,
+ &output,
+ &fonttype,
+ pyiterable_to_vector_int,
+ &glyph_ids)) {
+ return NULL;
+ }
+
+ if (fonttype != 3 && fonttype != 42) {
+ PyErr_SetString(PyExc_ValueError,
+ "fonttype must be either 3 (raw Postscript) or 42 "
+ "(embedded Truetype)");
+ return NULL;
+ }
+
+ try
+ {
+ insert_ttfont(filename, output, (font_type_enum)fonttype, glyph_ids);
+ }
+ catch (TTException &e)
+ {
+ PyErr_SetString(PyExc_RuntimeError, e.getMessage());
+ return NULL;
+ }
+ catch (const py::exception &)
+ {
+ return NULL;
+ }
+ catch (...)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+class PythonDictionaryCallback : public TTDictionaryCallback
+{
+ PyObject *_dict;
+
+ public:
+ PythonDictionaryCallback(PyObject *dict)
+ {
+ _dict = dict;
+ }
+
+ virtual void add_pair(const char *a, const char *b)
+ {
+ assert(a != NULL);
+ assert(b != NULL);
+ PyObject *value = PyBytes_FromString(b);
+ if (!value) {
+ throw py::exception();
+ }
+ if (PyDict_SetItemString(_dict, a, value)) {
+ Py_DECREF(value);
+ throw py::exception();
+ }
+ Py_DECREF(value);
+ }
+};
+
+static PyObject *py_get_pdf_charprocs(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ const char *filename;
+ std::vector<int> glyph_ids;
+ PyObject *result;
+
+ static const char *kwlist[] = { "filename", "glyph_ids", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kwds,
+#if PY_MAJOR_VERSION == 3
+ "y|O&:get_pdf_charprocs",
+#else
+ "s|O&:get_pdf_charprocs",
+#endif
+ (char **)kwlist,
+ &filename,
+ pyiterable_to_vector_int,
+ &glyph_ids)) {
+ return NULL;
+ }
+
+ result = PyDict_New();
+ if (!result) {
+ return NULL;
+ }
+
+ PythonDictionaryCallback dict(result);
+
+ try
+ {
+ ::get_pdf_charprocs(filename, glyph_ids, dict);
+ }
+ catch (TTException &e)
+ {
+ Py_DECREF(result);
+ PyErr_SetString(PyExc_RuntimeError, e.getMessage());
+ return NULL;
+ }
+ catch (const py::exception &)
+ {
+ Py_DECREF(result);
+ return NULL;
+ }
+ catch (...)
+ {
+ Py_DECREF(result);
+ PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
+ return NULL;
+ }
+
+ return result;
+}
+
+static PyMethodDef ttconv_methods[] =
+{
+ {
+ "convert_ttf_to_ps", (PyCFunction)convert_ttf_to_ps, METH_VARARGS | METH_KEYWORDS,
+ "convert_ttf_to_ps(filename, output, fonttype, glyph_ids)\n"
+ "\n"
+ "Converts the Truetype font into a Type 3 or Type 42 Postscript font, "
+ "optionally subsetting the font to only the desired set of characters.\n"
+ "\n"
+ "filename is the path to a TTF font file.\n"
+ "output is a Python file-like object with a write method that the Postscript "
+ "font data will be written to.\n"
+ "fonttype may be either 3 or 42. Type 3 is a \"raw Postscript\" font. "
+ "Type 42 is an embedded Truetype font. Glyph subsetting is not supported "
+ "for Type 42 fonts.\n"
+ "glyph_ids (optional) is a list of glyph ids (integers) to keep when "
+ "subsetting to a Type 3 font. If glyph_ids is not provided or is None, "
+ "then all glyphs will be included. If any of the glyphs specified are "
+ "composite glyphs, then the component glyphs will also be included."
+ },
+ {
+ "get_pdf_charprocs", (PyCFunction)py_get_pdf_charprocs, METH_VARARGS | METH_KEYWORDS,
+ "get_pdf_charprocs(filename, glyph_ids)\n"
+ "\n"
+ "Given a Truetype font file, returns a dictionary containing the PDF Type 3\n"
+ "representation of its paths. Useful for subsetting a Truetype font inside\n"
+ "of a PDF file.\n"
+ "\n"
+ "filename is the path to a TTF font file.\n"
+ "glyph_ids is a list of the numeric glyph ids to include.\n"
+ "The return value is a dictionary where the keys are glyph names and\n"
+ "the values are the stream content needed to render that glyph. This\n"
+ "is useful to generate the CharProcs dictionary in a PDF Type 3 font.\n"
+ },
+ {0, 0, 0, 0} /* Sentinel */
+};
+
+static const char *module_docstring =
+ "Module to handle converting and subsetting TrueType "
+ "fonts to Postscript Type 3, Postscript Type 42 and "
+ "Pdf Type 3 fonts.";
+
+#if PY3K
+static PyModuleDef ttconv_module = {
+ PyModuleDef_HEAD_INIT,
+ "ttconv",
+ module_docstring,
+ -1,
+ ttconv_methods,
+ NULL, NULL, NULL, NULL
+};
+
+PyMODINIT_FUNC
+PyInit_ttconv(void)
+{
+ PyObject* m;
+
+ m = PyModule_Create(&ttconv_module);
+
+ return m;
+}
+#else
+PyMODINIT_FUNC
+initttconv(void)
+{
+ Py_InitModule3("ttconv", ttconv_methods, module_docstring);
+}
+#endif