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

Reply via email to