Revision: 3662 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3662&view=rev Author: mdboom Date: 2007-08-01 10:28:58 -0700 (Wed, 01 Aug 2007)
Log Message: ----------- Convert _ttconv.cpp to use raw Python/C API, rather than CXX. Modified Paths: -------------- trunk/matplotlib/src/_ttconv.cpp Modified: trunk/matplotlib/src/_ttconv.cpp =================================================================== --- trunk/matplotlib/src/_ttconv.cpp 2007-08-01 16:21:11 UTC (rev 3661) +++ trunk/matplotlib/src/_ttconv.cpp 2007-08-01 17:28:58 UTC (rev 3662) @@ -1,181 +1,204 @@ -#include "CXX/Extensions.hxx" -#include "CXX/Objects.hxx" -#include "ttconv/pprdrv.h" +/* + _ttconv.c -class ttconv_module : public Py::ExtensionModule<ttconv_module> -{ -public: - ttconv_module() - : Py::ExtensionModule<ttconv_module>( "ttconv" ) - { - add_varargs_method("convert_ttf_to_ps", - &ttconv_module::convert_ttf_to_ps, - ttconv_module::convert_ttf_to_ps__doc__); - add_varargs_method("get_pdf_charprocs", - &ttconv_module::get_pdf_charprocs, - ttconv_module::get_pdf_charprocs__doc__); + Python wrapper for TrueType conversion library in ../ttconv. + */ - initialize( "The ttconv module" ); - } +#include <Python.h> +#include "ttconv/pprdrv.h" +#include <vector> - Py::Object - convert_ttf_to_ps(const Py::Tuple& args); - static char convert_ttf_to_ps__doc__[]; - - Py::Object - get_pdf_charprocs(const Py::Tuple& args); - static char get_pdf_charprocs__doc__[]; -}; - -char ttconv_module::convert_ttf_to_ps__doc__[] = -"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." -; - /** * An implementation of TTStreamWriter that writes to a Python * file-like object. */ class PythonFileWriter : public TTStreamWriter { - Py::Callable _write_method; + PyObject* _write_method; public: - PythonFileWriter(const Py::Object& file_like_object) { - _write_method = file_like_object.getAttr( "write" ); + PythonFileWriter() { + _write_method = NULL; } + ~PythonFileWriter() { + if (_write_method) + Py_DECREF(_write_method); + } + + void set(PyObject* write_method) { + if (_write_method) + Py_DECREF(_write_method); + _write_method = write_method; + if (_write_method) + Py_INCREF(_write_method); + } + virtual void write(const char* a) { - Py::Tuple args(1); - args[0] = Py::String(a); - _write_method.apply(args); + if (_write_method) + PyObject_CallFunction(_write_method, "s", a); } }; -Py::Object -ttconv_module::convert_ttf_to_ps(const Py::Tuple & args) { - args.verify_length(3, 4); +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); + return 1; +} - std::string fname = Py::String(args[0]).as_std_string(); +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)) { + long value = PyInt_AsLong(item); + if (value == -1 && PyErr_Occurred()) + return 0; + result->push_back(value); + } + return 1; +} - PythonFileWriter python_file_writer(args[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; - long font_type = (long)Py::Int(args[2]); - if ( font_type != 3 && font_type != 42 ) { - throw Py::ValueError("Font type must be either 3 (raw Postscript) or 42 (embedded Truetype)"); + static char *kwlist[] = { "filename", "output", "fonttype", "glyph_ids", NULL }; + if (! PyArg_ParseTupleAndKeywords + (args, kwds, + "sO&i|O&:convert_ttf_to_ps", 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; } - std::vector<int> glyph_ids; - if ( args.size() == 4 ) { - if ( args[3] != Py::None() ) { - Py::SeqBase< Py::Int > py_glyph_ids = args[3]; - size_t num_glyphs = py_glyph_ids.size(); - // If there are no included glyphs, just return - if (num_glyphs == 0) { - return Py::Object(); - } - glyph_ids.reserve(num_glyphs); - for (size_t i = 0; i < num_glyphs; ++i) { - glyph_ids.push_back( (long) py_glyph_ids.getItem(i) ); - } - } - } - try { - insert_ttfont( fname.c_str(), python_file_writer, (font_type_enum) font_type, glyph_ids ); + insert_ttfont( filename, output, (font_type_enum)fonttype, glyph_ids ); } catch (TTException& e) { - throw Py::RuntimeError(e.getMessage()); + PyErr_SetString(PyExc_RuntimeError, e.getMessage()); + return NULL; + } catch (...) { + PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception"); + return NULL; } - return Py::Object(); + Py_INCREF(Py_None); + return Py_None; } -char ttconv_module::get_pdf_charprocs__doc__[] = -"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 path. 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" -; - -/** - * An implementation of TTStreamWriter that writes to a Python - * file-like object. - */ class PythonDictionaryCallback : public TTDictionaryCallback { - Py::Dict _dict; + PyObject* _dict; public: - PythonDictionaryCallback(const Py::Dict& dict) : _dict(dict) { - + PythonDictionaryCallback(PyObject* dict) { + _dict = dict; } virtual void add_pair(const char* a, const char* b) { - _dict.setItem(a, Py::String(b)); + PyObject* value = PyString_FromString(b); + if (value) + PyDict_SetItemString(_dict, a, value); } }; -Py::Object -ttconv_module::get_pdf_charprocs(const Py::Tuple & args) { - args.verify_length(1, 2); +static PyObject* +py_get_pdf_charprocs(PyObject* self, PyObject* args, PyObject* kwds) { + const char* filename; + std::vector<int> glyph_ids; + PyObject* result; - Py::Dict result; + static char *kwlist[] = { "filename", "glyph_ids", NULL }; + if (! PyArg_ParseTupleAndKeywords + (args, kwds, + "s|O&:convert_ttf_to_ps", kwlist, + &filename, + pyiterable_to_vector_int, + &glyph_ids)) + return NULL; - std::string fname = Py::String(args[0]).as_std_string(); + result = PyDict_New(); + if (!result) + return NULL; - std::vector<int> glyph_ids; - if ( args.size() == 2 ) { - if ( args[1] != Py::None() ) { - Py::SeqBase< Py::Int > py_glyph_ids = args[1]; - size_t num_glyphs = py_glyph_ids.size(); - // If there are no included glyphs, just return - if (num_glyphs == 0) { - return result; - } - glyph_ids.reserve(num_glyphs); - for (size_t i = 0; i < num_glyphs; ++i) { - glyph_ids.push_back( (long) py_glyph_ids.getItem(i) ); - } - } - } + PythonDictionaryCallback dict(result); - PythonDictionaryCallback dictCallback(result); - try { - ::get_pdf_charprocs( fname.c_str(), glyph_ids, dictCallback ); + ::get_pdf_charprocs( filename, glyph_ids, dict ); } catch (TTException& e) { - throw Py::RuntimeError(e.getMessage()); + PyErr_SetString(PyExc_RuntimeError, e.getMessage()); + return NULL; + } catch (...) { + PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception"); + return NULL; } return result; } -#if defined(_MSC_VER) -DL_EXPORT(void) -#elif defined(__cplusplus) - extern "C" void -#else -void +static PyMethodDef ttconv_methods[] = { + {"convert_ttf_to_ps", (PyCFunction)convert_ttf_to_ps, 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_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 path. 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" + }, + {NULL} /* Sentinel */ +}; + +#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ +#define PyMODINIT_FUNC void #endif -initttconv(void) +PyMODINIT_FUNC +initttconv(void) { - static ttconv_module* ttconv = new ttconv_module; + PyObject* m; + + m = Py_InitModule3("ttconv", ttconv_methods, + "Module to handle converting and subsetting TrueType " + "fonts to Postscript Type 3, Postscript Type 42 and " + "Pdf Type 3 fonts."); } + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ Matplotlib-checkins mailing list Matplotlib-checkins@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins