Revision: 3662
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3662&view=rev
Author: mdboom
Date: 2007年08月01日 10:28:58 -0700 (2007年8月01日)
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.