<commit_before>#include "UnrealEnginePythonPrivatePCH.h"

#include "UEPyFPaintContext.h"

static PyObject *py_ue_fpaint_context_draw_line(ue_PyFPaintContext *self, PyObject * args) {
	float x1, y1, x2, y2;
	PyObject *py_linear_color = nullptr;
	PyObject *py_antialias = nullptr;
	float thickness = 1.0;

	if (!PyArg_ParseTuple(args, "(ff)(ff)|OOf:draw_line", &x1, &y1, &x2, &y2, &py_linear_color, &py_antialias, &thickness))
		return nullptr;

	FLinearColor tint = FLinearColor::White;

	if (py_linear_color) {
		if (ue_PyFLinearColor *linear_color = py_ue_is_flinearcolor(py_linear_color)) {
			tint = linear_color->color;
		}
		else {
			return PyErr_Format(PyExc_Exception, "argument is not a FlinearColor");
		}
	}

	FPaintContext context = self->paint_context;

	context.MaxLayer++;

	TArray<FVector2D> points;
	points.Add(FVector2D(x1, y1));
	points.Add(FVector2D(x2, y2));

	FSlateDrawElement::MakeLines(context.OutDrawElements, context.MaxLayer, context.AllottedGeometry.ToPaintGeometry(),
		points, context.MyClippingRect, ESlateDrawEffect::None, tint, (py_antialias && !PyObject_IsTrue(py_antialias)), thickness);

	Py_RETURN_NONE;
}

static PyObject *py_ue_fpaint_context_draw_lines(ue_PyFPaintContext *self, PyObject * args) {
	PyObject *py_points;
	PyObject *py_linear_color = nullptr;
	PyObject *py_antialias = nullptr;
	float thickness = 1.0;

	if (!PyArg_ParseTuple(args, "O|OOf:draw_line", &py_points, &py_linear_color, &py_antialias, &thickness))
		return nullptr;

	TArray<FVector2D> points;

	PyObject *py_iter = PyObject_GetIter(py_points);
	if (!py_iter)
		return PyErr_Format(PyExc_Exception, "argument is not an iterable of tuples");

	while (PyObject *py_item = PyIter_Next(py_iter)) {
		if (!PyTuple_Check(py_item)) {
			return PyErr_Format(PyExc_Exception, "iterable item is not a tuple");
			Py_DECREF(py_iter);
		}

		float x, y;
		if (!PyArg_ParseTuple(py_item, "ff", &x, &y)) {
			Py_DECREF(py_iter);
			return nullptr;
		}
		points.Add(FVector2D(x, y));
	}
	Py_DECREF(py_iter);

	FLinearColor tint = FLinearColor::White;

	if (py_linear_color) {
		if (ue_PyFLinearColor *linear_color = py_ue_is_flinearcolor(py_linear_color)) {
			tint = linear_color->color;
		}
		else {
			return PyErr_Format(PyExc_Exception, "argument is not a FlinearColor");
		}
	}

	FPaintContext context = self->paint_context;

	context.MaxLayer++;

	FSlateDrawElement::MakeLines(context.OutDrawElements, context.MaxLayer, context.AllottedGeometry.ToPaintGeometry(),
		points, context.MyClippingRect, ESlateDrawEffect::None, tint, (py_antialias && !PyObject_IsTrue(py_antialias)), thickness);

	Py_RETURN_NONE;
}

static PyMethodDef ue_PyFPaintContext_methods[] = {
	{ "draw_line", (PyCFunction)py_ue_fpaint_context_draw_line, METH_VARARGS, "" },
	{ "draw_lines", (PyCFunction)py_ue_fpaint_context_draw_lines, METH_VARARGS, "" },
	{ NULL }  /* Sentinel */
};

static PyObject *ue_PyFPaintContext_str(ue_PyFPaintContext *self)
{
	return PyUnicode_FromFormat("<unreal_engine.FPaintContext '%s'>",
		TCHAR_TO_UTF8(*self->paint_context.AllottedGeometry.ToString()));
}

static PyTypeObject ue_PyFPaintContextType = {
	PyVarObject_HEAD_INIT(NULL, 0)
	"unreal_engine.FPaintContext", /* tp_name */
	sizeof(ue_PyFPaintContext), /* tp_basicsize */
	0,                         /* tp_itemsize */
	0,       /* tp_dealloc */
	0,                         /* tp_print */
	0,                         /* tp_getattr */
	0,                         /* tp_setattr */
	0,                         /* tp_reserved */
	0,                         /* tp_repr */
	0,                         /* tp_as_number */
	0,                         /* tp_as_sequence */
	0,                         /* tp_as_mapping */
	0,                         /* tp_hash  */<commit_msg>added spline support to the drawing api<commit_after>#include "UnrealEnginePythonPrivatePCH.h"

#include "UEPyFPaintContext.h"

static PyObject *py_ue_fpaint_context_draw_line(ue_PyFPaintContext *self, PyObject * args) {
	float x1, y1, x2, y2;
	PyObject *py_linear_color = nullptr;
	PyObject *py_antialias = nullptr;
	float thickness = 1.0;

	if (!PyArg_ParseTuple(args, "(ff)(ff)|OOf:draw_line", &x1, &y1, &x2, &y2, &py_linear_color, &py_antialias, &thickness))
		return nullptr;

	FLinearColor tint = FLinearColor::White;

	if (py_linear_color) {
		if (ue_PyFLinearColor *linear_color = py_ue_is_flinearcolor(py_linear_color)) {
			tint = linear_color->color;
		}
		else {
			return PyErr_Format(PyExc_Exception, "argument is not a FlinearColor");
		}
	}

	FPaintContext context = self->paint_context;

	context.MaxLayer++;

	TArray<FVector2D> points;
	points.Add(FVector2D(x1, y1));
	points.Add(FVector2D(x2, y2));

	FSlateDrawElement::MakeLines(context.OutDrawElements, context.MaxLayer, context.AllottedGeometry.ToPaintGeometry(),
		points, context.MyClippingRect, ESlateDrawEffect::None, tint, (py_antialias && !PyObject_IsTrue(py_antialias)), thickness);

	Py_RETURN_NONE;
}

static PyObject *py_ue_fpaint_context_draw_spline(ue_PyFPaintContext *self, PyObject * args) {
	float x1, y1, dx1, dy1;
	float x2, y2, dx2, dy2;
	PyObject *py_linear_color = nullptr;

	float thickness = 1.0;

	if (!PyArg_ParseTuple(args, "(ff)(ff)(ff)(ff)|Of:draw_spline", &x1, &y1, &dx1, &dy1, &x2, &y2, &dx2, &dy2, &py_linear_color, &thickness))
		return nullptr;

	FLinearColor tint = FLinearColor::White;

	if (py_linear_color) {
		if (ue_PyFLinearColor *linear_color = py_ue_is_flinearcolor(py_linear_color)) {
			tint = linear_color->color;
		}
		else {
			return PyErr_Format(PyExc_Exception, "argument is not a FlinearColor");
		}
	}

	FPaintContext context = self->paint_context;

	context.MaxLayer++;

	FSlateDrawElement::MakeSpline(context.OutDrawElements, context.MaxLayer, context.AllottedGeometry.ToPaintGeometry(),
		FVector2D(x1, y1), FVector2D(dx1, dy1), FVector2D(x2, y2), FVector2D(dx2, dy2),
		context.MyClippingRect, thickness, ESlateDrawEffect::None, tint);

	Py_RETURN_NONE;
}


static PyObject *py_ue_fpaint_context_draw_lines(ue_PyFPaintContext *self, PyObject * args) {
	PyObject *py_points;
	PyObject *py_linear_color = nullptr;
	PyObject *py_antialias = nullptr;
	float thickness = 1.0;

	if (!PyArg_ParseTuple(args, "O|OOf:draw_lines", &py_points, &py_linear_color, &py_antialias, &thickness))
		return nullptr;

	TArray<FVector2D> points;

	PyObject *py_iter = PyObject_GetIter(py_points);
	if (!py_iter)
		return PyErr_Format(PyExc_Exception, "argument is not an iterable of tuples");

	while (PyObject *py_item = PyIter_Next(py_iter)) {
		if (!PyTuple_Check(py_item)) {
			return PyErr_Format(PyExc_Exception, "iterable item is not a tuple");
			Py_DECREF(py_iter);
		}

		float x, y;
		if (!PyArg_ParseTuple(py_item, "ff", &x, &y)) {
			Py_DECREF(py_iter);
			return nullptr;
		}
		points.Add(FVector2D(x, y));
	}
	Py_DECREF(py_iter);

	FLinearColor tint = FLinearColor::White;

	if (py_linear_color) {
		if (ue_PyFLinearColor *linear_color = py_ue_is_flinearcolor(py_linear_color)) {
			tint = linear_color->color;
		}
		else {
			return PyErr_Format(PyExc_Exception, "argument is not a FlinearColor");
		}
	}

	FPaintContext context = self->paint_context;

	context.MaxLayer++;

	FSlateDrawElement::MakeLines(context.OutDrawElements, context.MaxLayer, context.AllottedGeometry.ToPaintGeometry(),
		points, context.MyClippingRect, ESlateDrawEffect::None, tint, (py_antialias && !PyObject_IsTrue(py_antialias)), thickness);

	Py_RETURN_NONE;
}

static PyMethodDef ue_PyFPaintContext_methods[] = {
	{ "draw_line", (PyCFunction)py_ue_fpaint_context_draw_line, METH_VARARGS, "" },
	{ "draw_lines", (PyCFunction)py_ue_fpaint_context_draw_lines, METH_VARARGS, "" },
	{ "draw_spline", (PyCFunction)py_ue_fpaint_context_draw_spline, METH_VARARGS, "" },
	{ NULL }  /* Sentinel */
};

static PyObject *ue_PyFPaintContext_str(ue_PyFPaintContext *self)
{
	return PyUnicode_FromFormat("<unreal_engine.FPaintContext '%s'>",
		TCHAR_TO_UTF8(*self->paint_context.AllottedGeometry.ToString()));
}

static PyTypeObject ue_PyFPaintContextType = {
	PyVarObject_HEAD_INIT(NULL, 0)
	"unreal_engine.FPaintContext", /* tp_name */
	sizeof(ue_PyFPaintContext), /* tp_basicsize */
	0,                         /* tp_itemsize */
	0,       /* tp_dealloc */
	0,                         /* tp_print */
	0,                         /* tp_getattr */
	0,                         /* tp_setattr */
	0,                         /* tp_reserved */
	0,                         /* tp_repr */
	0,                         /* tp_as_number */
	0,                         /* tp_as_sequence */
	0,                         /* tp_as_mapping */
	0,                         /* tp_hash  */
{'fraction_non_alphanumeric': 0.12342803912435957, 'fraction_numerical': 0.011411271541686073, 'mean_word_length': 4.130824372759856, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2767330', 'n_tokens_mistral': 3287, 'n_tokens_neox': 3169, 'n_words': 547}