Commits

Ronald Oussoren  committed 8e0941f

- add correct support for NSFont.fontWithName_matrix_ and NSFont.matrix
- also add NSFontIdentityMatrix
- and add a testcase for this

  • Participants
  • Parent commits cca37de

Comments (0)

Files changed (3)

File pyobjc/Lib/AppKit/test/test_nsfont.py

+import unittest
+import objc
+
+import AppKit
+
+class TestNSFont(unittest.TestCase):
+    def matrixEquals(self, value1, value2):
+        self.assertEquals(len(value1), len(value2))
+        for v1, v2 in zip(value1, value2):
+            # This should probably be 'assertAlmostEquals'
+            self.assertEquals(v1, v2)
+
+    def testConstants(self):
+        self.assert_(hasattr(AppKit, 'NSFontIdentityMatrix'))
+        self.assertEquals(AppKit.NSFontIdentityMatrix, None)
+
+    def testMatrixMethods(self):
+        o = AppKit.NSFont.boldSystemFontOfSize_(10);
+        m = o.matrix()
+        self.assert_(isinstance(m, tuple))
+        self.assertEquals(len(m), 6)
+
+        nm = o.fontName()
+
+        o = AppKit.NSFont.fontWithName_matrix_(nm, AppKit.NSFontIdentityMatrix)
+        self.assert_(o is not None)
+
+        m = o.matrix()
+        self.assert_(isinstance(m, tuple))
+        self.assertEquals(len(m), 6)
+
+        self.matrixEquals(m, (1.0, 0.0, 0.0, 1.0, 0.0, 0.0))
+
+        o = AppKit.NSFont.fontWithName_matrix_(nm, (1.0, 2.0, 3.0, 4.0, 5.0, 6.0))
+        self.assert_(o is not None)
+
+        m = o.matrix()
+        self.assert_(isinstance(m, tuple))
+        self.assertEquals(len(m), 6)
+
+        self.matrixEquals(m, (1.0, 2.0, 3.0, 4.0, 5.0, 6.0))
+
+        self.assertRaises(ValueError, AppKit.NSFont.fontWithName_matrix_, nm, "foo")
+        self.assertRaises(ValueError, AppKit.NSFont.fontWithName_matrix_, nm, (1, 2, 3, 4))
+        self.assertRaises(ValueError, AppKit.NSFont.fontWithName_matrix_, nm, (1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0))
+
+
+
+
+if __name__ == '__main__':
+   unittest.main( )

File pyobjc/Modules/AppKit/_AppKit.m

 };
 
 
+static int 
+fontMatrix(PyObject* d, const char* name, const float* value)
+{
+	int i;
+
+	if (value == NULL) {
+		return PyDict_SetItemString(d, name, Py_None);
+	}
+	PyObject* v = PyTuple_New(6);
+	if (v == NULL) {
+		return -1;
+	}
+
+	for (i = 0; i < 6; i++) {
+		PyObject* t;
+
+		t = PyFloat_FromDouble(value[i]);
+		if (t == NULL) {
+			Py_DECREF(v);
+			return -1;
+		}
+	}
+	
+	if (PyDict_SetItemString(d, name, v) == -1) {
+		Py_DECREF(v);
+		return -1;
+	}
+	Py_DECREF(v);
+	return 0;
+}
+
 
 void init_AppKit(void);
 
 	          if (res < 0) return;
 	  }
 	}
+
+
+	/* Some special constants */
+	fontMatrix(d, "NSFontIdentityMatrix", NSFontIdentityMatrix);
 }

File pyobjc/Modules/AppKit/_AppKitMapping_NSFont.m

  * NSFont mappings for 'difficult' methods:
  *
  * -positionsForCompositeSequence:numberOfGlyphs:pointArray:    [call, imp]
+ * -fontWithName:matrix:
  */
 #include <Python.h>
 #include <Foundation/Foundation.h>
 	return retValue;
 }
 
+
+static PyObject*
+call_NSFont_fontWithName_matrix_(
+	PyObject* method, PyObject* self, PyObject* arguments)
+{
+	struct objc_super super;
+	id  font;
+	id  typeface;
+	PyObject* pyFontMatrix;
+	float _fontMatrix[6];
+	float* volatile fontMatrix;
+	PyObject* seq;
+	int i, len;
+
+	if (!PyArg_ParseTuple(arguments, "O&O", 
+			PyObjCObject_Convert, &typeface, &pyFontMatrix)) {
+		return 0;
+	}
+
+	if (pyFontMatrix == Py_None) {
+		fontMatrix = NULL;
+
+	} else {
+		fontMatrix = _fontMatrix;
+
+		seq = PySequence_Fast(pyFontMatrix, "fontMatrix is not a sequence");
+		if (seq == NULL) {
+			return NULL;
+		}
+		
+		len = PySequence_Fast_GET_SIZE(seq);
+		if (len != 6) {
+			PyErr_SetString(PyExc_ValueError, "fontMatrix must be exactly 6 floats");
+			Py_DECREF(seq);
+			return NULL;
+		}
+
+		for (i = 0; i < len; i++) {
+			int r;
+
+			r = PyObjC_PythonToObjC(@encode(float), 
+				PySequence_Fast_GET_ITEM(seq, i),
+				fontMatrix + i);
+			if (r == -1) {
+				Py_DECREF(seq);
+				return NULL;
+			}
+		}
+		Py_DECREF(seq);
+	}
+
+	NS_DURING
+		PyObjC_InitSuperCls(&super,
+			PyObjCSelector_GetClass(method),
+			PyObjCClass_GetClass(self));
+
+		font = objc_msgSendSuper(&super,
+			PyObjCSelector_GetSelector(method),
+			typeface, fontMatrix);
+	NS_HANDLER
+		PyObjCErr_FromObjC(localException);
+		font = nil;
+	NS_ENDHANDLER
+
+	if (font == nil && PyErr_Occurred()) {
+		return NULL;
+	}
+
+	return PyObjC_IdToPython(font);
+}
+
+static id
+imp_NSFont_fontWithName_matrix_(
+	Class self, SEL sel, NSString* typeface, const float* fontMatrix)
+{
+	PyObject* args;
+	PyObject* result;
+	PyObject* v;
+	int i;
+	id retValue;
+
+	args = PyTuple_New(3);
+	if (args == NULL) {
+		PyObjCErr_ToObjC();
+		return nil;
+	}
+
+	v = PyObjC_ObjCToPython(@encode(Class), &self);
+	if (v == NULL) {
+		Py_DECREF(args);
+		PyObjCErr_ToObjC();
+		return nil;
+	}
+
+	PyTuple_SET_ITEM(args, 0, v);
+
+	v = PyObjC_IdToPython(typeface);
+	if (v == NULL) {
+		Py_DECREF(args);
+		PyObjCErr_ToObjC();
+		return nil;
+	}
+
+	PyTuple_SET_ITEM(args, 1, v);
+
+	if (fontMatrix == NULL) {
+		v = Py_None;
+		Py_INCREF(Py_None);
+	} else {
+		v = PyTuple_New(6);
+		if (v == NULL) {
+			Py_DECREF(args);
+			PyObjCErr_ToObjC();
+			return nil;
+		}
+		for (i = 0; i < 6; i++) {
+			PyObject* t = PyFloat_FromDouble(fontMatrix[i]);
+			if (t == NULL) {
+				Py_DECREF(v);
+				Py_DECREF(args);
+				PyObjCErr_ToObjC();
+				return nil;
+			}
+			PyTuple_SET_ITEM(v, i, t);
+		}
+	}
+	PyTuple_SET_ITEM(args, 2, v);
+
+	result = PyObjC_CallPython(self, sel, args, NULL);
+	Py_DECREF(args);
+	if (result == NULL) {
+		PyObjCErr_ToObjC();
+		return nil;
+	}
+
+	retValue = PyObjC_PythonToId(result);
+	Py_DECREF(result);
+	if (retValue == nil && PyErr_Occurred()) {
+		PyObjCErr_ToObjC();
+		return nil;
+	}
+
+	return retValue;
+}
+
+static PyObject*
+call_NSFont_matrix(
+	PyObject* method, PyObject* self, PyObject* arguments)
+{
+	struct objc_super super;
+	PyObject* pyFontMatrix;
+	float* fontMatrix;
+	int i;
+
+	if (!PyArg_ParseTuple(arguments, "")) {
+		return 0;
+	}
+
+	NS_DURING
+		PyObjC_InitSuper(&super,
+			PyObjCSelector_GetClass(method),
+			PyObjCObject_GetObject(self));
+
+		fontMatrix = (float*)objc_msgSendSuper(&super,
+			PyObjCSelector_GetSelector(method));
+	NS_HANDLER
+		PyObjCErr_FromObjC(localException);
+		fontMatrix = nil;
+	NS_ENDHANDLER
+
+	if (fontMatrix == nil && PyErr_Occurred()) {
+		return NULL;
+	}
+
+	pyFontMatrix = PyTuple_New(6);
+	if (pyFontMatrix == NULL) {
+		return NULL;
+	}
+	for (i = 0; i < 6; i++) {
+		PyObject* t = PyFloat_FromDouble(fontMatrix[i]);
+		if (t == NULL) {
+			Py_DECREF(pyFontMatrix);
+		}
+		PyTuple_SET_ITEM(pyFontMatrix, i, t);
+	}
+
+	return pyFontMatrix;
+}
+
+
 static int 
 _pyobjc_install_NSFont(void)
 {
 		return -1;
 	}
 
+	if (PyObjC_RegisterMethodMapping(objc_lookUpClass("NSFont"), 
+		@selector(fontWithName:matrix:),
+		call_NSFont_fontWithName_matrix_,
+		(IMP)imp_NSFont_fontWithName_matrix_) < 0 ) {
+
+		return -1;
+	}
+
+	if (PyObjC_RegisterMethodMapping(objc_lookUpClass("NSFont"), 
+		@selector(matrix),
+		call_NSFont_matrix,
+		(IMP)PyObjCUnsupportedMethod_IMP) < 0 ) {
+
+		return -1;
+	}
+
 	return 0;
 }