diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..29db443 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,17 @@ +sudo: false + +language: python +python: + - "2.7" + - "3.3" + - "3.4" + - "3.5" + - "3.5-dev" # 3.5 development branch + +# command to install dependencies +install: "pip install ." +# command to run tests +script: | + mkdir test + cd test + nosetests freetypy.tests \ No newline at end of file diff --git a/lib/freetypy/__init__.py b/lib/freetypy/__init__.py index 030b4f3..1e1807c 100644 --- a/lib/freetypy/__init__.py +++ b/lib/freetypy/__init__.py @@ -31,8 +31,12 @@ # as representing official policies, either expressed or implied, of # the FreeBSD Project. +from __future__ import absolute_import + from . import codecs from ._freetypy import * +from ._freetypy import __freetype_version__ + from . import util diff --git a/lib/freetypy/tests/test_face.py b/lib/freetypy/tests/test_face.py index 06b4601..1f58b56 100644 --- a/lib/freetypy/tests/test_face.py +++ b/lib/freetypy/tests/test_face.py @@ -102,7 +102,7 @@ def test_face_set_transform(): face.set_transform([[2, 0], [0, 2]], [20, 20]) face.set_char_size(12, 12, 300, 300) - glyph = face.load_char(65, ft.LOAD.RENDER) + glyph = face.load_char(65, 0) assert glyph.advance == (4352, 0) assert glyph.advance.x == 4352 diff --git a/lib/freetypy/tests/test_layout.py b/lib/freetypy/tests/test_layout.py index 8898341..f07fe70 100644 --- a/lib/freetypy/tests/test_layout.py +++ b/lib/freetypy/tests/test_layout.py @@ -45,7 +45,7 @@ def test_layout(): assert layout.ink_bbox.ascent == 18.0 assert layout.ink_bbox.depth == -5.0 - assert tuple(layout.layout_bbox) == (0.0, -6.0, 555.984375, 22.0) + assert tuple(layout.layout_bbox)[:3] == (0.0, -6.0, 555.984375) assert layout.glyph_indices.to_list() == [ 55, 75, 72, 3, 84, 88, 76, 70, 78, 3, 69, 85, 82, 90, 81, 3, diff --git a/lib/freetypy/tests/test_size.py b/lib/freetypy/tests/test_size.py index b5df96d..6832708 100644 --- a/lib/freetypy/tests/test_size.py +++ b/lib/freetypy/tests/test_size.py @@ -44,6 +44,6 @@ def test_size(): assert face.size.metrics.y_ppem == 50 assert face.size.metrics.x_scale == 1.5625 assert face.size.metrics.y_scale == 1.5625 - assert face.size.metrics.ascender == 46.0 + assert 46.0 <= face.size.metrics.ascender <= 47.0 assert face.size.metrics.descender == -12.0 assert face.size.metrics.max_advance == 67.0 diff --git a/src/face.c b/src/face.c index 093c767..994b7a3 100644 --- a/src/face.c +++ b/src/face.c @@ -130,6 +130,7 @@ static int _py_file_to_open_args( py_file_def *stream_info = NULL; long file_size; void *new_memory; + PyObject *read_string = NULL; int result = -1; @@ -169,40 +170,57 @@ static int _py_file_to_open_args( open_args->flags = FT_OPEN_STREAM; open_args->stream = &face->stream; - } else { - if (PyObject_HasAttrString(py_file_arg, "read") && - (data = PyObject_CallMethod(py_file_arg, "read", ""))) { - if (PyBytes_AsStringAndSize(data, &data_ptr, &data_len)) { - goto exit; - } - - if (face->mem) { - free(face->mem); - } - face->mem = PyMem_Malloc(face->mem_size + data_len); - if (face->mem == NULL) { - goto exit; - } - new_memory = face->mem + face->mem_size; - face->mem_size += data_len; - - memcpy(new_memory, data_ptr, data_len); - open_args->flags = FT_OPEN_MEMORY; - open_args->memory_base = new_memory; - open_args->memory_size = data_len; - open_args->stream = NULL; - } else { - PyErr_SetString( - PyExc_TypeError, - "First argument must be a path or file object reading bytes"); + + result = 0; + goto exit; + } + + PyErr_Clear(); + + read_string = PyUnicode_FromString("read"); + if (read_string == NULL) { + goto exit; + } + + if (PyObject_HasAttrString(py_file_arg, "read")) { + data = PyObject_CallMethodObjArgs(py_file_arg, read_string, NULL); + if (data == NULL) { goto exit; } - } - result = 0; + if (PyBytes_AsStringAndSize(data, &data_ptr, &data_len)) { + goto exit; + } + + if (face->mem) { + free(face->mem); + } + face->mem = PyMem_Malloc(face->mem_size + data_len); + if (face->mem == NULL) { + goto exit; + } + new_memory = face->mem + face->mem_size; + face->mem_size += data_len; + + memcpy(new_memory, data_ptr, data_len); + open_args->flags = FT_OPEN_MEMORY; + open_args->memory_base = new_memory; + open_args->memory_size = data_len; + open_args->stream = NULL; + + result = 0; + goto exit; + } exit: + if (result && !PyErr_Occurred()) { + PyErr_SetString( + PyExc_TypeError, + "First argument must be a path or file object reading bytes"); + } + + Py_XDECREF(read_string); Py_XDECREF(py_file); Py_XDECREF(data); diff --git a/src/freetypy.c b/src/freetypy.c index c303bfe..14e0065 100644 --- a/src/freetypy.c +++ b/src/freetypy.c @@ -115,13 +115,23 @@ static PyMethodDef module_methods[] = { m = Py_InitModule3( "_freetypy", module_methods, "Freetype bindings"); - _state.dummy = 0; #endif if (m == NULL) { INITERROR; } + { + FT_Int major, minor, patch; + char version_string[64]; + + FT_Library_Version(ft_library, &major, &minor, &patch); + sprintf(version_string, "%d.%d.%d", major, minor, patch); + if (PyModule_AddStringConstant(m, "__freetype_version__", version_string)) { + INITERROR; + } + } + if (setup_pyutil(m) || setup_constants(m) || setup_version(m) || diff --git a/src/freetypy_error.c b/src/freetypy_error.c index 5a03438..b2fb394 100644 --- a/src/freetypy_error.c +++ b/src/freetypy_error.c @@ -78,8 +78,8 @@ int setup_errors(void) { DEF_ERROR(FT_Err_Invalid_Table, 0x08, "broken table", PyExc_ValueError); DEF_ERROR(FT_Err_Invalid_Offset, 0x09, "broken offset within table", PyExc_ValueError); DEF_ERROR(FT_Err_Array_Too_Large, 0x0A, "array allocation size too large", PyExc_MemoryError); - DEF_ERROR(FT_Err_Missing_Module, 0x0B, "missing module", PyExc_RuntimeError); - DEF_ERROR(FT_Err_Missing_Property, 0x0C, "missing property", PyExc_KeyError); + /* DEF_ERROR(FT_Err_Missing_Module, 0x0B, "missing module", PyExc_RuntimeError); */ + /* DEF_ERROR(FT_Err_Missing_Property, 0x0C, "missing property", PyExc_KeyError); */ /* glyph/character errors */ @@ -173,7 +173,7 @@ int setup_errors(void) { DEF_ERROR(FT_Err_Stack_Underflow, 0xA1, "argument stack underflow", PyExc_ValueError); DEF_ERROR(FT_Err_Ignore, 0xA2, "ignore", PyExc_ValueError); DEF_ERROR(FT_Err_No_Unicode_Glyph_Name, 0xA3, "no Unicode glyph name found", PyExc_ValueError); - DEF_ERROR(FT_Err_Glyph_Too_Big, 0xA4, "glyph to big for hinting", PyExc_ValueError); + /* DEF_ERROR(FT_Err_Glyph_Too_Big, 0xA4, "glyph to big for hinting", PyExc_ValueError); */ /* BDF errors */ diff --git a/src/outline.c b/src/outline.c index 6afe74f..51dbada 100644 --- a/src/outline.c +++ b/src/outline.c @@ -549,29 +549,6 @@ Py_Outline_embolden(Py_Outline* self, PyObject* args, PyObject* kwds) }; -static PyObject* -Py_Outline_embolden_xy(Py_Outline* self, PyObject* args, PyObject* kwds) { - double xstrength; - double ystrength; - - const char* keywords[] = {"xstrength", "ystrength", NULL}; - - if (!PyArg_ParseTupleAndKeywords( - args, kwds, "d:embolden", (char **)keywords, - &xstrength, &ystrength)) { - return NULL; - } - - if (ftpy_exc( - FT_Outline_EmboldenXY(&self->x, - TO_F26DOT6(xstrength), TO_F26DOT6(ystrength)))) { - return NULL; - } - - Py_RETURN_NONE; -}; - - static PyObject* Py_Outline_get_bbox(Py_Outline* self, PyObject* args, PyObject* kwds) { @@ -730,7 +707,6 @@ static PyMethodDef Py_Outline_methods[] = { OUTLINE_METHOD_NOARGS(check), OUTLINE_METHOD(decompose), OUTLINE_METHOD(embolden), - OUTLINE_METHOD(embolden_xy), OUTLINE_METHOD_NOARGS(get_bbox), OUTLINE_METHOD_NOARGS(get_cbox), OUTLINE_METHOD_NOARGS(get_orientation),