From e8c7a7a49779a76f4376e0445add66d9d7b1e81d Mon Sep 17 00:00:00 2001 From: Manish Singh Date: Sat, 4 Jun 2005 00:17:06 +0000 Subject: [PATCH] plug-ins/pygimp/pygimp-api.h export our API to other modules in a saner 2005-06-03 Manish Singh * plug-ins/pygimp/pygimp-api.h * plug-ins/pygimp/gimpmodule.c: export our API to other modules in a saner fashion. Also add checks_get_shades method. * plug-ins/pygimp/procbrowser.c: Use new export API. * plug-ins/pygimp/pygimp-drawable.c (drw_mask_intersect): use Py_BuildValue to build the tuple. * plug-ins/pygimp/pygimp-image.c (img_repr): capitalization fix. * plug-ins/pygimp/pygimp-rgb.c * plug-ins/pygimp/pygimpcolor.h * plug-ins/pygimp/gimpcolormodule.c: beginnings of a wrapper to libgimpcolor. * plug-ins/pygimp/gimpfu.py * plug-ins/pygimp/gimpenums.py * plug-ins/pygimp/gimpenumsmodule.c: use gimp enum API to find out our enums. * plug-ins/pygimp/Makefile.am: hook in all of the above. --- ChangeLog | 25 ++ plug-ins/pygimp/Makefile.am | 37 ++- plug-ins/pygimp/gimpcolormodule.c | 382 ++++++++++++++++++++++++ plug-ins/pygimp/gimpenums.py | 331 +++------------------ plug-ins/pygimp/gimpenumsmodule.c | 120 ++++++++ plug-ins/pygimp/gimpfu.py | 7 +- plug-ins/pygimp/gimpmodule.c | 51 +++- plug-ins/pygimp/procbrowser.c | 40 +-- plug-ins/pygimp/pygimp-api.h | 81 ++++++ plug-ins/pygimp/pygimp-colors.c | 469 ++++++++++++++++++++++++++++++ plug-ins/pygimp/pygimp-drawable.c | 10 +- plug-ins/pygimp/pygimp-image.c | 2 +- plug-ins/pygimp/pygimp-rgb.c | 469 ++++++++++++++++++++++++++++++ plug-ins/pygimp/pygimpcolor.h | 39 +++ 14 files changed, 1705 insertions(+), 358 deletions(-) create mode 100644 plug-ins/pygimp/gimpcolormodule.c create mode 100644 plug-ins/pygimp/gimpenumsmodule.c create mode 100644 plug-ins/pygimp/pygimp-api.h create mode 100644 plug-ins/pygimp/pygimp-colors.c create mode 100644 plug-ins/pygimp/pygimp-rgb.c create mode 100644 plug-ins/pygimp/pygimpcolor.h diff --git a/ChangeLog b/ChangeLog index 2f63749f87..f81237fd65 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2005-06-03 Manish Singh + + * plug-ins/pygimp/pygimp-api.h + * plug-ins/pygimp/gimpmodule.c: export our API to other modules + in a saner fashion. Also add checks_get_shades method. + + * plug-ins/pygimp/procbrowser.c: Use new export API. + + * plug-ins/pygimp/pygimp-drawable.c (drw_mask_intersect): + use Py_BuildValue to build the tuple. + + * plug-ins/pygimp/pygimp-image.c (img_repr): capitalization fix. + + * plug-ins/pygimp/pygimp-rgb.c + * plug-ins/pygimp/pygimpcolor.h + * plug-ins/pygimp/gimpcolormodule.c: beginnings of a wrapper to + libgimpcolor. + + * plug-ins/pygimp/gimpfu.py + * plug-ins/pygimp/gimpenums.py + * plug-ins/pygimp/gimpenumsmodule.c: use gimp enum API to find out + our enums. + + * plug-ins/pygimp/Makefile.am: hook in all of the above. + 2005-06-03 Manish Singh * configure.in: build pygimp by default. diff --git a/plug-ins/pygimp/Makefile.am b/plug-ins/pygimp/Makefile.am index 5977e1d81d..540800d1c8 100644 --- a/plug-ins/pygimp/Makefile.am +++ b/plug-ins/pygimp/Makefile.am @@ -21,17 +21,19 @@ INCLUDES = -I$(top_srcdir) $(PYTHON_INCLUDES) $(PYGTK_CFLAGS) $(GTK_CFLAGS) pygimpdir = $(gimpplugindir)/python -pygimp_LTLIBRARIES = gimpmodule.la gimpprocbrowsermodule.la +pygimp_LTLIBRARIES = gimpmodule.la _gimpenumsmodule.la gimpcolormodule.la \ + gimpprocbrowsermodule.la gimpmodule_la_SOURCES = \ gimpmodule.c \ - pygimp-image.c \ - pygimp-drawable.c \ - pygimp-tile.c \ pygimp-display.c \ + pygimp-drawable.c \ + pygimp-image.c \ pygimp-parasite.c \ pygimp-pdb.c \ - pygimp.h + pygimp-tile.c \ + pygimp.h \ + pygimp-api.h gimpmodule_la_LDFLAGS = -module -avoid-version $(no_undefined) \ -export-symbols-regex initgimp @@ -43,6 +45,31 @@ gimpmodule_la_LIBADD = \ $(GLIB_LIBS) \ $(RT_LIBS) +_gimpenumsmodule_la_SOURCES = \ + gimpenumsmodule.c + +_gimpenumsmodule_la_LDFLAGS = -module -avoid-version \ + -export-symbols-regex init_gimpenums + +_gimpenumsmodule_la_LIBADD = \ + $(libgimp) \ + $(libgimpcolor) \ + $(libgimpbase) \ + $(GLIB_LIBS) \ + $(RT_LIBS) + +gimpcolormodule_la_SOURCES = \ + gimpcolormodule.c \ + pygimp-rgb.c \ + pygimpcolor.h + +gimpcolormodule_la_LDFLAGS = -module -avoid-version \ + -export-symbols-regex initgimpcolor + +gimpcolormodule_la_LIBADD = \ + $(libgimpcolor) \ + $(GLIB_LIBS) + gimpprocbrowsermodule_la_SOURCES = \ procbrowser.c diff --git a/plug-ins/pygimp/gimpcolormodule.c b/plug-ins/pygimp/gimpcolormodule.c new file mode 100644 index 0000000000..38c42bf270 --- /dev/null +++ b/plug-ins/pygimp/gimpcolormodule.c @@ -0,0 +1,382 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + Gimp-Python - allows the writing of Gimp plugins in Python. + Copyright (C) 2005 Manish Singh + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "pygimpcolor.h" + + +#if PY_VERSION_HEX >= 0x2030000 +#define ARG_UINTARRAY_FORMAT "(IIII)" +#else +#define ARG_UINTARRAY_FORMAT "(iiii)" +#endif + + +static PyObject * +pygimp_rgb_parse_name(PyObject *self, PyObject *args, PyObject *kwargs) +{ + char *name; + int len; + GimpRGB rgb; + gboolean success; + static char *kwlist[] = { "name", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#:rgb_parse_name", kwlist, + &name, &len)) + return NULL; + + rgb.a = 1.0; + success = gimp_rgb_parse_name(&rgb, name, len); + PyMem_Free(name); + + if (!success) { + PyErr_SetString(PyExc_ValueError, "unable to parse color name"); + return NULL; + } + + return pygimp_rgb_new(&rgb); +} + +static PyObject * +pygimp_rgb_parse_hex(PyObject *self, PyObject *args, PyObject *kwargs) +{ + char *hex; + int len; + GimpRGB rgb; + gboolean success; + static char *kwlist[] = { "hex", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#:rgb_parse_hex", kwlist, + &hex, &len)) + return NULL; + + rgb.a = 1.0; + success = gimp_rgb_parse_hex(&rgb, hex, len); + PyMem_Free(hex); + + if (!success) { + PyErr_SetString(PyExc_ValueError, "unable to parse hex value"); + return NULL; + } + + return pygimp_rgb_new(&rgb); +} + +static PyObject * +pygimp_rgb_parse_css(PyObject *self, PyObject *args, PyObject *kwargs) +{ + char *css; + int len; + GimpRGB rgb; + gboolean success, with_alpha = FALSE; + static char *kwlist[] = { "css", "with_alpha", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "s#|i:rgb_parse_css", kwlist, + &css, &len, &with_alpha)) + return NULL; + + if (with_alpha) + success = gimp_rgba_parse_css(&rgb, css, len); + else { + rgb.a = 1.0; + success = gimp_rgb_parse_css(&rgb, css, len); + } + + if (!success) { + PyErr_SetString(PyExc_ValueError, "unable to parse CSS color"); + return NULL; + } + + return pygimp_rgb_new(&rgb); +} + +static PyObject * +pygimp_rgb_list_names(PyObject *self) +{ + int num_names, i; + const char **names; + GimpRGB *colors; + PyObject *dict, *color; + + num_names = gimp_rgb_list_names(&names, &colors); + + dict = PyDict_New(); + if (!dict) + goto cleanup; + + for (i = 0; i < num_names; i++) { + color = pygimp_rgb_new(&colors[i]); + + if (!color) + goto bail; + + if (PyDict_SetItemString(dict, names[i], color) < 0) + { + Py_DECREF(color); + goto bail; + } + + Py_DECREF(color); + } + + goto cleanup; + +bail: + Py_DECREF(dict); + dict = NULL; + +cleanup: + g_free(names); + g_free(colors); + + return dict; +} + +#if 0 +static PyObject * +pygimp_bilinear(PyObject *self, PyObject *args, PyObject *kwargs) +{ + gdouble x, y; + gdouble values[4]; + static char *kwlist[] = { "x", "y", "values", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "dd(dddd):bilinear", kwlist, + &x, &y, + &values[0], &values[1], + &values[2], &values[3])) + return NULL; + + return PyFloat_FromDouble(gimp_bilinear(x, y, values)); +} + +static PyObject * +pygimp_bilinear_8(PyObject *self, PyObject *args, PyObject *kwargs) +{ + gdouble x, y; + char *values; + int len; + guchar r; + static char *kwlist[] = { "x", "y", "values", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "dds#:bilinear_8", kwlist, + &x, &y, &values, &len)) + return NULL; + + if (len != 4) { + PyErr_SetString(PyExc_ValueError, + "string must be exactly 4 bytes long"); + return NULL; + } + + r = gimp_bilinear_8(x, y, values); + + return PyString_FromStringAndSize(&r, 1); +} + +static PyObject * +pygimp_bilinear_32(PyObject *self, PyObject *args, PyObject *kwargs) +{ + gdouble x, y; + guint32 values[4]; + static char *kwlist[] = { "x", "y", "values", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "dd" ARG_UINTARRAY_FORMAT ":bilinear_32", + kwlist, + &x, &y, + &values[0], &values[1], + &values[2], &values[3])) + return NULL; + + return PyInt_FromLong(gimp_bilinear_32(x, y, values)); +} + +static PyObject * +pygimp_bilinear_pixels_8(PyObject *self, PyObject *args, PyObject *kwargs) +{ + Py_INCREF(Py_None); + return Py_None; +} + +typedef struct +{ + PyObject *func; + PyObject *data; +} ProxyData; + +static void +proxy_render(gdouble x, gdouble y, GimpRGB *color, gpointer pdata) +{ + ProxyData *data = pdata; + + if (data->data) + PyObject_CallFunction(data->func, "ddO&O", x, y, pygimp_rgb_new, color, + data->data); + else + PyObject_CallFunction(data->func, "ddO&", x, y, pygimp_rgb_new, color); +} + +static void +proxy_put_pixel(gint x, gint y, GimpRGB *color, gpointer pdata) +{ + ProxyData *data = pdata; + + if (data->data) + PyObject_CallFunction(data->func, "iiO&O", x, y, pygimp_rgb_new, color, + data->data); + else + PyObject_CallFunction(data->func, "iiO&", x, y, pygimp_rgb_new, color); +} + +static void +proxy_progress(gint min, gint max, gint current, gpointer pdata) +{ + ProxyData *data = pdata; + + if (data->data) + PyObject_CallFunction(data->func, "iiiO", min, max, current, + data->data); + else + PyObject_CallFunction(data->func, "iii", min, max, current); +} + +static PyObject * +pygimp_adaptive_supersample_area(PyObject *self, PyObject *args, PyObject *kwargs) +{ + gulong r; + + gint x1, y1, x2, y2, max_depth; + gdouble threshold; + PyObject *py_func_render = NULL, *py_data_render = NULL; + PyObject *py_func_put_pixel = NULL, *py_data_put_pixel = NULL; + PyObject *py_func_progress = NULL, *py_data_progress = NULL; + + GimpRenderFunc proxy_func_render = NULL; + GimpPutPixelFunc proxy_func_put_pixel = NULL; + GimpProgressFunc proxy_func_progress = NULL; + + ProxyData proxy_data_render, proxy_data_put_pixel, proxy_data_progress; + + static char *kwlist[] = { + "x1", "y1", "x2", "y2", "max_depth", "threshold", + "render_func", "render_data", + "put_pixel_func", "put_pixel_data", + "progress_func", "progress_data", + NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "iiiiid|OOOOOO" + ":adaptive_supersample_area", + kwlist, + &x1, &y1, &x2, &y2, &max_depth, &threshold, + &py_func_render, &py_data_render, + &py_func_put_pixel, &py_data_put_pixel, + &py_func_progress, &py_data_progress)) + return NULL; + +#define PROCESS_FUNC(n) G_STMT_START { \ + if (py_func_##n != NULL) { \ + if (!PyCallable_Check(py_func_##n)) { \ + PyErr_SetString(PyExc_TypeError, #n "_func " \ + "must be callable"); \ + return NULL; \ + } \ + \ + proxy_func_##n = proxy_##n; \ + \ + proxy_data_##n.func = py_func_##n; \ + proxy_data_##n.data = py_data_##n; \ + } \ +} G_STMT_END + + PROCESS_FUNC(render); + PROCESS_FUNC(put_pixel); + PROCESS_FUNC(progress); + +#undef PROCESS_FUNC + +#define PASS_FUNC(n) proxy_func_##n, &proxy_data_##n + + r = gimp_adaptive_supersample_area (x1, y1, x2, y2, max_depth, threshold, + PASS_FUNC(render), + PASS_FUNC(put_pixel), + PASS_FUNC(progress)); + +#undef PASS_FUNC + + return PyInt_FromLong(r); +} +#endif + +/* List of methods defined in the module */ + +static struct PyMethodDef gimpcolor_methods[] = { + {"rgb_parse_name", (PyCFunction)pygimp_rgb_parse_name, METH_VARARGS | METH_KEYWORDS}, + {"rgb_parse_hex", (PyCFunction)pygimp_rgb_parse_hex, METH_VARARGS | METH_KEYWORDS}, + {"rgb_parse_css", (PyCFunction)pygimp_rgb_parse_css, METH_VARARGS | METH_KEYWORDS}, + {"rgb_names", (PyCFunction)pygimp_rgb_list_names, METH_NOARGS}, +#if 0 + {"bilinear", (PyCFunction)pygimp_bilinear, METH_VARARGS | METH_KEYWORDS}, + {"bilinear_8", (PyCFunction)pygimp_bilinear_8, METH_VARARGS | METH_KEYWORDS}, + {"bilinear_32", (PyCFunction)pygimp_bilinear_32, METH_VARARGS | METH_KEYWORDS}, + //{"bilinear_pixels_8", (PyCFunction)pygimp_bilinear_pixels_8, METH_VARARGS | METH_KEYWORDS}, + {"adaptive_supersample_area", (PyCFunction)pygimp_adaptive_supersample_area, METH_VARARGS | METH_KEYWORDS}, +#endif + {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */ +}; + + +/* Initialization function for the module (*must* be called initgimpcolor) */ + +static char gimpcolor_doc[] = +"This module provides interfaces to allow you to write gimp plugins" +; + +DL_EXPORT(void) +initgimpcolor(void) +{ + PyObject *m, *d; + + init_pygobject(); + + /* Create the module and add the functions */ + m = Py_InitModule3("gimpcolor", gimpcolor_methods, gimpcolor_doc); + + d = PyModule_GetDict(m); + pyg_register_boxed(d, "RGB", GIMP_TYPE_RGB, &PyGimpRGB_Type); + + PyModule_AddObject(m, "RGB_COMPOSITE_NONE", + PyInt_FromLong(GIMP_RGB_COMPOSITE_NONE)); + PyModule_AddObject(m, "RGB_COMPOSITE_NORMAL", + PyInt_FromLong(GIMP_RGB_COMPOSITE_NORMAL)); + PyModule_AddObject(m, "RGB_COMPOSITE_BEHIND", + PyInt_FromLong(GIMP_RGB_COMPOSITE_BEHIND)); + + /* Check for errors */ + if (PyErr_Occurred()) + Py_FatalError("can't initialize module gimpcolor"); +} diff --git a/plug-ins/pygimp/gimpenums.py b/plug-ins/pygimp/gimpenums.py index e3e9682ce1..a317130b34 100644 --- a/plug-ins/pygimp/gimpenums.py +++ b/plug-ins/pygimp/gimpenums.py @@ -1,5 +1,5 @@ # Gimp-Python - allows the writing of Gimp plugins in Python. -# Copyright (C) 1997-2003 James Henstridge +# Copyright (C) 2005 Manish Singh # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,312 +17,47 @@ # gimpenums.py -- constants for use with the gimp module # -# this file contains constants that are useful for use in +# this file pulls in constants that are useful for use in # gimp plugins. Just add 'from gimpenums import *' to the top # of the script -# NOTE: This file is autogenerated by enumcode-py.pl. +from _gimpenums import * -# TRUE and FALSE constants ... -import __builtin__ -if not hasattr(__builtin__, 'True'): - __builtin__.True = (1 == 1) - __builtin__.False = (1 != 1) -del __builtin__ +# This is from pygtk/gtk/__init__.py +# Copyright (C) 1998-2003 James Henstridge -FALSE = False -TRUE = True +from warnings import warn as _warn -# Parasite Flags -PARASITE_PERSISTENT = 1 -PARASITE_UNDOABLE = 2 -PARASITE_ATTACH_PARENT = (0x80 << 8) -PARASITE_PARENT_PERSISTENT = (PARASITE_PERSISTENT << 8) -PARASITE_PARENT_UNDOABLE = (PARASITE_UNDOABLE << 8) -PARASITE_ATTACH_GRANDPARENT = (0x80 << 16) -PARASITE_GRANDPARENT_PERSISTENT = (PARASITE_PERSISTENT << 16) -PARASITE_GRANDPARENT_UNDOABLE = (PARASITE_UNDOABLE << 16) +class _DeprecatedConstant: + def __init__(self, value, name, suggestion): + self._v = value + self._name = name + self._suggestion = suggestion -# GimpAddMaskType -ADD_WHITE_MASK = 0 -ADD_BLACK_MASK = 1 -ADD_ALPHA_MASK = 2 -ADD_ALPHA_TRANSFER_MASK = 3 -ADD_SELECTION_MASK = 4 -ADD_COPY_MASK = 5 + def _deprecated(self, value): + message = '%s is deprecated, use %s instead' % (self._name, + self._suggestion) + _warn(message, DeprecationWarning, 3) + return value -# GimpBlendMode -FG_BG_RGB_MODE = 0 -FG_BG_HSV_MODE = 1 -FG_TRANSPARENT_MODE = 2 -CUSTOM_MODE = 3 + __nonzero__ = lambda self: self._deprecated(self._v == True) + __int__ = lambda self: self._deprecated(int(self._v)) + __str__ = lambda self: self._deprecated(str(self._v)) + __repr__ = lambda self: self._deprecated(repr(self._v)) + __cmp__ = lambda self, other: self._deprecated(cmp(self._v, other)) -# GimpBrushApplicationMode -BRUSH_HARD = 0 -BRUSH_SOFT = 1 +TRUE = _DeprecatedConstant(True, 'gimpenums.TRUE', 'True') +FALSE = _DeprecatedConstant(False, 'gimpenums.FALSE', 'False') -# GimpBucketFillMode -FG_BUCKET_FILL = 0 -BG_BUCKET_FILL = 1 -PATTERN_BUCKET_FILL = 2 +del _DeprecatedConstant -# GimpChannelOps -CHANNEL_OP_ADD = 0 -CHANNEL_OP_SUBTRACT = 1 -CHANNEL_OP_REPLACE = 2 -CHANNEL_OP_INTERSECT = 3 - -# GimpChannelType -RED_CHANNEL = 0 -GREEN_CHANNEL = 1 -BLUE_CHANNEL = 2 -GRAY_CHANNEL = 3 -INDEXED_CHANNEL = 4 -ALPHA_CHANNEL = 5 - -# GimpCloneType -IMAGE_CLONE = 0 -PATTERN_CLONE = 1 - -# GimpConvertDitherType -NO_DITHER = 0 -FS_DITHER = 1 -FSLOWBLEED_DITHER = 2 -FIXED_DITHER = 3 - -# GimpConvertPaletteType -MAKE_PALETTE = 0 -REUSE_PALETTE = 1 -WEB_PALETTE = 2 -MONO_PALETTE = 3 -CUSTOM_PALETTE = 4 - -# GimpConvolutionType -NORMAL_CONVOL = 0 -ABSOLUTE_CONVOL = 1 -NEGATIVE_CONVOL = 2 - -# GimpConvolveType -BLUR_CONVOLVE = 0 -SHARPEN_CONVOLVE = 1 - -# GimpDesaturateMode -DESATURATE_LIGHTNESS = 0 -DESATURATE_LUMINOSITY = 1 -DESATURATE_AVERAGE = 2 - -# GimpDodgeBurnType -DODGE = 0 -BURN = 1 - -# GimpFillType -FOREGROUND_FILL = 0 -BACKGROUND_FILL = 1 -WHITE_FILL = 2 -TRANSPARENT_FILL = 3 -PATTERN_FILL = 4 - -# GimpGradientSegmentColor -GRADIENT_SEGMENT_RGB = 0 -GRADIENT_SEGMENT_HSV_CCW = 1 -GRADIENT_SEGMENT_HSV_CW = 2 - -# GimpGradientSegmentType -GRADIENT_SEGMENT_LINEAR = 0 -GRADIENT_SEGMENT_CURVED = 1 -GRADIENT_SEGMENT_SINE = 2 -GRADIENT_SEGMENT_SPHERE_INCREASING = 3 -GRADIENT_SEGMENT_SPHERE_DECREASING = 4 - -# GimpGradientType -GRADIENT_LINEAR = 0 -GRADIENT_BILINEAR = 1 -GRADIENT_RADIAL = 2 -GRADIENT_SQUARE = 3 -GRADIENT_CONICAL_SYMMETRIC = 4 -GRADIENT_CONICAL_ASYMMETRIC = 5 -GRADIENT_SHAPEBURST_ANGULAR = 6 -GRADIENT_SHAPEBURST_SPHERICAL = 7 -GRADIENT_SHAPEBURST_DIMPLED = 8 -GRADIENT_SPIRAL_CLOCKWISE = 9 -GRADIENT_SPIRAL_ANTICLOCKWISE = 10 - -# GimpHistogramChannel -HISTOGRAM_VALUE = 0 -HISTOGRAM_RED = 1 -HISTOGRAM_GREEN = 2 -HISTOGRAM_BLUE = 3 -HISTOGRAM_ALPHA = 4 - -# GimpHueRange -ALL_HUES = 0 -RED_HUES = 1 -YELLOW_HUES = 2 -GREEN_HUES = 3 -CYAN_HUES = 4 -BLUE_HUES = 5 -MAGENTA_HUES = 6 - -# GimpIconType -ICON_TYPE_STOCK_ID = 0 -ICON_TYPE_INLINE_PIXBUF = 1 -ICON_TYPE_IMAGE_FILE = 2 - -# GimpImageBaseType -RGB = 0 -GRAY = 1 -INDEXED = 2 - -# GimpImageType -RGB_IMAGE = 0 -RGBA_IMAGE = 1 -GRAY_IMAGE = 2 -GRAYA_IMAGE = 3 -INDEXED_IMAGE = 4 -INDEXEDA_IMAGE = 5 - -# GimpInterpolationType -INTERPOLATION_NONE = 0 -INTERPOLATION_LINEAR = 1 -INTERPOLATION_CUBIC = 2 -INTERPOLATION_LANCZOS = 3 - -# GimpLayerModeEffects -NORMAL_MODE = 0 -DISSOLVE_MODE = 1 -BEHIND_MODE = 2 -MULTIPLY_MODE = 3 -SCREEN_MODE = 4 -OVERLAY_MODE = 5 -DIFFERENCE_MODE = 6 -ADDITION_MODE = 7 -SUBTRACT_MODE = 8 -DARKEN_ONLY_MODE = 9 -LIGHTEN_ONLY_MODE = 10 -HUE_MODE = 11 -SATURATION_MODE = 12 -COLOR_MODE = 13 -VALUE_MODE = 14 -DIVIDE_MODE = 15 -DODGE_MODE = 16 -BURN_MODE = 17 -HARDLIGHT_MODE = 18 -SOFTLIGHT_MODE = 19 -GRAIN_EXTRACT_MODE = 20 -GRAIN_MERGE_MODE = 21 -COLOR_ERASE_MODE = 22 - -# GimpMaskApplyMode -MASK_APPLY = 0 -MASK_DISCARD = 1 - -# GimpMergeType -EXPAND_AS_NECESSARY = 0 -CLIP_TO_IMAGE = 1 -CLIP_TO_BOTTOM_LAYER = 2 -FLATTEN_IMAGE = 3 - -# GimpMessageHandlerType -MESSAGE_BOX = 0 -CONSOLE = 1 -ERROR_CONSOLE = 2 - -# GimpOffsetType -OFFSET_BACKGROUND = 0 -OFFSET_TRANSPARENT = 1 - -# GimpOrientationType -ORIENTATION_HORIZONTAL = 0 -ORIENTATION_VERTICAL = 1 -ORIENTATION_UNKNOWN = 2 - -# GimpPDBArgType -PDB_INT32 = 0 -PDB_INT16 = 1 -PDB_INT8 = 2 -PDB_FLOAT = 3 -PDB_STRING = 4 -PDB_INT32ARRAY = 5 -PDB_INT16ARRAY = 6 -PDB_INT8ARRAY = 7 -PDB_FLOATARRAY = 8 -PDB_STRINGARRAY = 9 -PDB_COLOR = 10 -PDB_REGION = 11 -PDB_DISPLAY = 12 -PDB_IMAGE = 13 -PDB_LAYER = 14 -PDB_CHANNEL = 15 -PDB_DRAWABLE = 16 -PDB_SELECTION = 17 -PDB_BOUNDARY = 18 -PDB_PATH = 19 -PDB_PARASITE = 20 -PDB_STATUS = 21 -PDB_END = 22 - -# GimpPDBProcType -INTERNAL = 0 -PLUGIN = 1 -EXTENSION = 2 -TEMPORARY = 3 - -# GimpPDBStatusType -PDB_EXECUTION_ERROR = 0 -PDB_CALLING_ERROR = 1 -PDB_PASS_THROUGH = 2 -PDB_SUCCESS = 3 -PDB_CANCEL = 4 - -# GimpPaintApplicationMode -PAINT_CONSTANT = 0 -PAINT_INCREMENTAL = 1 - -# GimpProgressCommand -PROGRESS_COMMAND_START = 0 -PROGRESS_COMMAND_END = 1 -PROGRESS_COMMAND_SET_TEXT = 2 -PROGRESS_COMMAND_SET_VALUE = 3 -PROGRESS_COMMAND_PULSE = 4 - -# GimpRepeatMode -REPEAT_NONE = 0 -REPEAT_SAWTOOTH = 1 -REPEAT_TRIANGULAR = 2 - -# GimpRotationType -ROTATE_90 = 0 -ROTATE_180 = 1 -ROTATE_270 = 2 - -# GimpRunMode -RUN_INTERACTIVE = 0 -RUN_NONINTERACTIVE = 1 -RUN_WITH_LAST_VALS = 2 - -# GimpSizeType -PIXELS = 0 -POINTS = 1 - -# GimpStackTraceMode -STACK_TRACE_NEVER = 0 -STACK_TRACE_QUERY = 1 -STACK_TRACE_ALWAYS = 2 - -# GimpTransferMode -SHADOWS = 0 -MIDTONES = 1 -HIGHLIGHTS = 2 - -# GimpTransformDirection -TRANSFORM_FORWARD = 0 -TRANSFORM_BACKWARD = 1 - -# GimpUnit -UNIT_PIXEL = 0 -UNIT_INCH = 1 -UNIT_MM = 2 -UNIT_POINT = 3 -UNIT_PICA = 4 -UNIT_END = 5 +def exported_constants(): + import gobject, _gimpenums + constants = ['TRUE', 'FALSE'] + for name in dir(_gimpenums): + if isinstance(getattr(_gimpenums, name), gobject.GEnum): + constants.append(name) + return constants +__all__ = exported_constants() +del exported_constants diff --git a/plug-ins/pygimp/gimpenumsmodule.c b/plug-ins/pygimp/gimpenumsmodule.c new file mode 100644 index 0000000000..b7564cf116 --- /dev/null +++ b/plug-ins/pygimp/gimpenumsmodule.c @@ -0,0 +1,120 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + Gimp-Python - allows the writing of Gimp plugins in Python. + Copyright (C) 2005 Manish Singh + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include + +#include + +#include "pygimp-api.h" + + +static void +add_misc_enums(PyObject *m) +{ + PyModule_AddIntConstant(m, "PARASITE_PERSISTENT", + GIMP_PARASITE_PERSISTENT); + PyModule_AddIntConstant(m, "PARASITE_UNDOABLE", + GIMP_PARASITE_UNDOABLE); + PyModule_AddIntConstant(m, "PARASITE_ATTACH_PARENT", + GIMP_PARASITE_ATTACH_PARENT); + PyModule_AddIntConstant(m, "PARASITE_PARENT_PERSISTENT", + GIMP_PARASITE_PARENT_PERSISTENT); + PyModule_AddIntConstant(m, "PARASITE_PARENT_UNDOABLE", + GIMP_PARASITE_PARENT_UNDOABLE); + PyModule_AddIntConstant(m, "PARASITE_ATTACH_GRANDPARENT", + GIMP_PARASITE_ATTACH_GRANDPARENT); + PyModule_AddIntConstant(m, "PARASITE_GRANDPARENT_PERSISTENT", + GIMP_PARASITE_GRANDPARENT_PERSISTENT); + PyModule_AddIntConstant(m, "PARASITE_GRANDPARENT_UNDOABLE", + GIMP_PARASITE_GRANDPARENT_UNDOABLE); + + PyModule_AddIntConstant(m, "UNIT_PIXEL", + GIMP_UNIT_PIXEL); + PyModule_AddIntConstant(m, "UNIT_INCH", + GIMP_UNIT_INCH); + PyModule_AddIntConstant(m, "UNIT_MM", + GIMP_UNIT_MM); + PyModule_AddIntConstant(m, "UNIT_POINT", + GIMP_UNIT_POINT); + PyModule_AddIntConstant(m, "UNIT_PICA", + GIMP_UNIT_PICA); + + PyModule_AddIntConstant(m, "MIN_IMAGE_SIZE", + GIMP_MIN_IMAGE_SIZE); + PyModule_AddIntConstant(m, "MAX_IMAGE_SIZE", + GIMP_MAX_IMAGE_SIZE); + + PyModule_AddObject(m, "MIN_RESOLUTION", + PyFloat_FromDouble(GIMP_MIN_RESOLUTION)); + PyModule_AddObject(m, "MAX_RESOLUTION", + PyFloat_FromDouble(GIMP_MAX_RESOLUTION)); + + PyModule_AddObject(m, "MAX_MEMSIZE", + PyLong_FromUnsignedLongLong(GIMP_MAX_MEMSIZE)); +} + +static void +add_registered_enums(PyObject *m) +{ + int num_names, i; + const char **names; + + names = gimp_enums_get_type_names(&num_names); + + pyg_enum_add(m, "CheckSize", "GIMP_", GIMP_TYPE_CHECK_SIZE); + pyg_enum_add(m, "CheckType", "GIMP_", GIMP_TYPE_CHECK_TYPE); + + for (i = 0; i < num_names; i++) + pyg_enum_add(m, names[i] + 4, "GIMP_", g_type_from_name(names[i])); +} + + +/* Initialization function for the module (*must* be called initgimpenums) */ + +static char gimpenums_doc[] = +"This module provides interfaces to allow you to write gimp plugins" +; + +DL_EXPORT(void) +init_gimpenums(void) +{ + PyObject *m; + + init_pygobject(); + init_pygimp(); + + gimp_enums_init(); + + /* Create the module and add the functions */ + m = Py_InitModule3("_gimpenums", NULL, gimpenums_doc); + + add_misc_enums(m); + add_registered_enums(m); + + /* Check for errors */ + if (PyErr_Occurred()) + Py_FatalError("can't initialize module _gimpenums"); +} diff --git a/plug-ins/pygimp/gimpfu.py b/plug-ins/pygimp/gimpfu.py index 0427888d6c..ab6e0db354 100644 --- a/plug-ins/pygimp/gimpfu.py +++ b/plug-ins/pygimp/gimpfu.py @@ -62,7 +62,7 @@ element in their description tuple -- a 3-tuple of the form (lower,upper,step), which defines the limits for the slider or spinner.''' import string as _string -import gimp +import gimp, gimpenums from gimpenums import * pdb = gimp.pdb @@ -166,8 +166,9 @@ def register(func_name, blurb, help, author, copyright, date, menupath, raise error, ("parameter definition must contain at least 4 " "elements (%s given: %s)" % (len(ent), ent)) - if type(ent[0]) != type(42): - raise error, "parameter types must be integers" + if type(ent[0]) != gimpenums.PDBArgType and \ + type(ent[0]) != int: + raise error, "parameter types must be PDB argument types" if not letterCheck(ent[1]): raise error, "parameter name contains illegal characters" diff --git a/plug-ins/pygimp/gimpmodule.c b/plug-ins/pygimp/gimpmodule.c index a7f5e916ae..a3d97f518c 100644 --- a/plug-ins/pygimp/gimpmodule.c +++ b/plug-ins/pygimp/gimpmodule.c @@ -22,6 +22,10 @@ #endif #include "pygimp.h" + +#define _INSIDE_PYGIMP_ +#include "pygimp-api.h" + #include #if PY_VERSION_HEX >= 0x2030000 @@ -1318,6 +1322,29 @@ pygimp_fonts_refresh(PyObject *self) return Py_None; } +static PyObject * +pygimp_checks_get_shades(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int type; + guchar light, dark; + static char *kwlist[] = { "type", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:checks_get_shades", kwlist, + &type)) + return NULL; + + if (type < GIMP_CHECK_TYPE_LIGHT_CHECKS || + type > GIMP_CHECK_TYPE_BLACK_ONLY) { + PyErr_SetString(PyExc_ValueError, "Invalid check type"); + return NULL; + } + + gimp_checks_get_shades(type, &light, &dark); + + return Py_BuildValue("(ii)", light, dark); +} + static PyObject * pygimp_fonts_get_list(PyObject *self, PyObject *args, PyObject *kwargs) { @@ -1458,6 +1485,7 @@ static struct PyMethodDef gimp_methods[] = { {"get_progname", (PyCFunction)pygimp_get_progname, METH_NOARGS}, {"fonts_refresh", (PyCFunction)pygimp_fonts_refresh, METH_NOARGS}, {"fonts_get_list", (PyCFunction)pygimp_fonts_get_list, METH_VARARGS | METH_KEYWORDS}, + {"checks_get_shades", (PyCFunction)pygimp_checks_get_shades, METH_VARARGS | METH_KEYWORDS}, {"_id2image", (PyCFunction)id2image, METH_VARARGS}, {"_id2drawable", (PyCFunction)id2drawable, METH_VARARGS}, {"_id2display", (PyCFunction)id2display, METH_VARARGS}, @@ -1465,6 +1493,17 @@ static struct PyMethodDef gimp_methods[] = { }; +static struct _PyGimp_Functions pygimp_api_functions = { + pygimp_image_new, + pygimp_display_new, + pygimp_layer_new, + pygimp_channel_new, + + &PyGimpPDBFunction_Type, + pygimp_pdb_function_new +}; + + /* Initialization function for the module (*must* be called initgimp) */ static char gimp_module_documentation[] = @@ -1532,6 +1571,9 @@ initgimp(void) if (PyType_Ready(&PyGimpParasite_Type) < 0) return; + /* set the default python encoding to utf-8 */ + PyUnicode_SetDefaultEncoding("utf-8"); + /* Create the module and add the functions */ m = Py_InitModule4("gimp", gimp_methods, gimp_module_documentation, @@ -1554,11 +1596,10 @@ initgimp(void) PyDict_SetItemString(d, "PixelRgn", (PyObject *)&PyGimpPixelRgn_Type); PyDict_SetItemString(d, "Parasite", (PyObject *)&PyGimpParasite_Type); - /* these are private, for use in gimpprocbrowser */ - PyDict_SetItemString(d, "_PDBFunction", - (PyObject *)&PyGimpPDBFunction_Type); - PyDict_SetItemString(d, "_pdb_function_new", - PyCObject_FromVoidPtr(pygimp_pdb_function_new, NULL)); + /* for other modules */ + PyDict_SetItemString(d, "_PyGimp_API", + i=PyCObject_FromVoidPtr(&pygimp_api_functions, NULL)); + Py_DECREF(i); PyDict_SetItemString(d, "version", i=Py_BuildValue("(iii)", diff --git a/plug-ins/pygimp/procbrowser.c b/plug-ins/pygimp/procbrowser.c index 9a11098af5..d1b3182dcd 100644 --- a/plug-ins/pygimp/procbrowser.c +++ b/plug-ins/pygimp/procbrowser.c @@ -26,20 +26,11 @@ #include #include -#include +#include "pygimp-api.h" #include -typedef PyObject *(*PyGimpPDBFunctionNew)(const char *name, const char *blurb, - const char *help, const char *author, - const char *copyright, - const char *date, - GimpPDBProcType proc_type, - int n_params, int n_return_vals, - GimpParamDef *params, - GimpParamDef *return_vals); - typedef struct { PyObject *func; @@ -47,10 +38,6 @@ typedef struct } ProxyData; -static PyTypeObject *PyGimpPDBFunction_Type; -static PyGimpPDBFunctionNew pygimp_pdb_function_new; - - static GimpParamDef * copy_paramdefs(const GimpParamDef *paramdefs, gint n_params) { @@ -182,32 +169,11 @@ static char procbrowser_doc[] = DL_EXPORT(void) initgimpprocbrowser(void) { - PyObject *m, *pygimp; + PyObject *m; init_pygobject(); init_pygtk(); - - pygimp = PyImport_ImportModule("gimp"); - - if (pygimp) { - PyObject *module_dict = PyModule_GetDict(pygimp); - PyObject *type_object, *c_object; - - type_object = PyDict_GetItemString(module_dict, "_PDBFunction"); - c_object = PyDict_GetItemString(module_dict, "_pdb_function_new"); - - if (PyType_Check(type_object) && PyCObject_Check(c_object)) { - PyGimpPDBFunction_Type = (PyTypeObject*)type_object; - pygimp_pdb_function_new = PyCObject_AsVoidPtr(c_object); - } else { - PyErr_SetString(PyExc_RuntimeError, - "could not find compatible gimp module"); - return; - } - } else { - PyErr_SetString(PyExc_ImportError, "could not import gimp"); - return; - } + init_pygimp(); /* Create the module and add the functions */ m = Py_InitModule3("gimpprocbrowser", diff --git a/plug-ins/pygimp/pygimp-api.h b/plug-ins/pygimp/pygimp-api.h new file mode 100644 index 0000000000..ba9669df34 --- /dev/null +++ b/plug-ins/pygimp/pygimp-api.h @@ -0,0 +1,81 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + Gimp-Python - allows the writing of Gimp plugins in Python. + Copyright (C) 2005 Manish Singh + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + */ + +#ifndef _PYGIMP_API_H_ +#define _PYGIMP_API_H_ + +#include + +#include + +struct _PyGimp_Functions { + PyObject *(* image_new)(gint32 ID); + PyObject *(* display_new)(gint32 ID); + PyObject *(* layer_new)(gint32 ID); + PyObject *(* channel_new)(gint32 ID); + + PyTypeObject *PDBFunction_Type; + PyObject *(* pdb_function_new)(const char *name, const char *blurb, + const char *help, const char *author, + const char *copyright, const char *date, + GimpPDBProcType proc_type, + int n_params, int n_return_vals, + GimpParamDef *params, + GimpParamDef *return_vals); +}; + +#ifndef _INSIDE_PYGIMP_ + +#if defined(NO_IMPORT) || defined(NO_IMPORT_PYGIMP) +extern struct _PyGimp_Functions *_PyGimp_API; +#else +struct _PyGimp_Functions *_PyGimp_API; +#endif + +#define pygimp_image_new (_PyGimp_API->image_new) +#define pygimp_display_new (_PyGimp_API->display_new) +#define pygimp_drawable_new (_PyGimp_API->drawable_new) +#define pygimp_layer_new (_PyGimp_API->layer_new) +#define pygimp_channel_new (_PyGimp_API->channel_new) +#define PyGimpPDBFunction_Type (_PyGimp_API->PDBFunction_Type) +#define pygimp_pdb_function_new (_PyGimp_API->pdb_function_new) + +#define init_pygimp() G_STMT_START { \ + PyObject *gimpmodule = PyImport_ImportModule("gimp"); \ + if (gimpmodule != NULL) { \ + PyObject *mdict = PyModule_GetDict(gimpmodule); \ + PyObject *cobject = PyDict_GetItemString(mdict, "_PyGimp_API"); \ + if (PyCObject_Check(cobject)) \ + _PyGimp_API = PyCObject_AsVoidPtr(cobject); \ + else { \ + PyErr_SetString(PyExc_RuntimeError, \ + "could not find _PyGimp_API object"); \ + return; \ + } \ + } else { \ + PyErr_SetString(PyExc_ImportError, \ + "could not import gimp"); \ + return; \ + } \ +} G_STMT_END + +#endif /* ! _INSIDE_PYGIMP_ */ + +#endif /* _PYGIMP_API_H_ */ diff --git a/plug-ins/pygimp/pygimp-colors.c b/plug-ins/pygimp/pygimp-colors.c new file mode 100644 index 0000000000..ea1ae458fb --- /dev/null +++ b/plug-ins/pygimp/pygimp-colors.c @@ -0,0 +1,469 @@ +#define NO_IMPORT_PYGOBJECT + +#include "pygimpcolor.h" + +static PyObject * +rgb_set(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *r = NULL, *g = NULL, *b = NULL, *a = NULL; + GimpRGB tmprgb, *rgb; + static char *kwlist[] = { "r", "g", "b", "a", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOO:set", kwlist, + &r, &g, &b, &a)) + return NULL; + + if (!r && !g && !b && !a) { + PyErr_SetString(PyExc_TypeError, "must provide r,g,b or a arguments"); + return NULL; + } + + if ((r && (!g || !b)) || + (g && (!r || !b)) || + (b && (!r || !g))) { + PyErr_SetString(PyExc_TypeError, "must provide all 3 r,g,b arguments"); + return NULL; + } + + rgb = pyg_boxed_get(self, GimpRGB); + tmprgb = *rgb; + +#define SET_MEMBER(m) G_STMT_START { \ + if (PyInt_Check(m)) \ + tmprgb.m = (double) PyInt_AS_LONG(m) / 255.0; \ + else if (PyFloat_Check(m)) \ + tmprgb.m = PyFloat_AS_DOUBLE(m); \ + else { \ + PyErr_SetString(PyExc_TypeError, \ + #m " must be an int or a float"); \ + return NULL; \ + } \ +} G_STMT_END + + if (r) { + SET_MEMBER(r); + SET_MEMBER(g); + SET_MEMBER(b); + } + + if (a) + SET_MEMBER(a); + +#undef SET_MEMBER + + *rgb = tmprgb; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_set_alpha(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_a; + GimpRGB *rgb; + static char *kwlist[] = { "a", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O:set_alpha", kwlist, + &py_a)) + return NULL; + + rgb = pyg_boxed_get(self, GimpRGB); + + if (PyInt_Check(py_a)) + rgb->a = (double) PyInt_AS_LONG(py_a) / 255.0; + else if (PyFloat_Check(py_a)) + rgb->a = PyFloat_AS_DOUBLE(py_a); + else { + PyErr_SetString(PyExc_TypeError, "a must be an int or a float"); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_add(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *color; + gboolean with_alpha = FALSE; + static char *kwlist[] = { "color", "with_alpha", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|i:add", kwlist, + &PyGimpRGB_Type, &color, &with_alpha)) + return NULL; + + if (with_alpha) + gimp_rgba_add(pyg_boxed_get(self, GimpRGB), + pyg_boxed_get(color, GimpRGB)); + else + gimp_rgb_add(pyg_boxed_get(self, GimpRGB), + pyg_boxed_get(color, GimpRGB)); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_subtract(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *color; + gboolean with_alpha = FALSE; + static char *kwlist[] = { "color", "with_alpha", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|i:subtract", kwlist, + &PyGimpRGB_Type, &color, &with_alpha)) + return NULL; + + if (with_alpha) + gimp_rgba_subtract(pyg_boxed_get(self, GimpRGB), + pyg_boxed_get(color, GimpRGB)); + else + gimp_rgb_subtract(pyg_boxed_get(self, GimpRGB), + pyg_boxed_get(color, GimpRGB)); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_multiply(PyObject *self, PyObject *args, PyObject *kwargs) +{ + double factor; + gboolean with_alpha = FALSE; + static char *kwlist[] = { "factor", "with_alpha", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "d|i:multiply", kwlist, + &factor, &with_alpha)) + return NULL; + + if (with_alpha) + gimp_rgba_multiply(pyg_boxed_get(self, GimpRGB), factor); + else + gimp_rgb_multiply(pyg_boxed_get(self, GimpRGB), factor); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_distance(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *color; + gboolean alpha = FALSE; + double ret; + static char *kwlist[] = { "color", "alpha", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|i:distance", kwlist, + &PyGimpRGB_Type, &color, &alpha)) + return NULL; + + ret = gimp_rgb_distance(pyg_boxed_get(self, GimpRGB), + pyg_boxed_get(color, GimpRGB)); + + + return PyFloat_FromDouble(ret); +} + +static PyObject * +rgb_max(PyObject *self) +{ + return PyFloat_FromDouble(gimp_rgb_max(pyg_boxed_get(self, GimpRGB))); +} + +static PyObject * +rgb_min(PyObject *self) +{ + return PyFloat_FromDouble(gimp_rgb_min(pyg_boxed_get(self, GimpRGB))); +} + +static PyObject * +rgb_clamp(PyObject *self) +{ + gimp_rgb_clamp(pyg_boxed_get(self, GimpRGB)); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_gamma(PyObject *self, PyObject *args, PyObject *kwargs) +{ + double gamma; + static char *kwlist[] = { "gamma", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "d:gamma", kwlist, &gamma)) + return NULL; + + gimp_rgb_gamma(pyg_boxed_get(self, GimpRGB), gamma); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_intensity(PyObject *self) +{ + return PyFloat_FromDouble(gimp_rgb_intensity(pyg_boxed_get(self, GimpRGB))); +} + +static PyObject * +rgb_composite(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *color; + int mode = GIMP_RGB_COMPOSITE_NORMAL; + static char *kwlist[] = { "color", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!|i:composite", kwlist, + &PyGimpRGB_Type, &color, &mode)) + return NULL; + + if (mode < GIMP_RGB_COMPOSITE_NONE || mode > GIMP_RGB_COMPOSITE_BEHIND) { + PyErr_SetString(PyExc_TypeError, "composite type is not valid"); + return NULL; + } + + gimp_rgb_composite(pyg_boxed_get(self, GimpRGB), + pyg_boxed_get(color, GimpRGB), + mode); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_parse_name(PyObject *self, PyObject *args, PyObject *kwargs) +{ + char *name; + int len; + gboolean success; + static char *kwlist[] = { "name", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#:parse_name", kwlist, + &name, &len)) + return NULL; + + success = gimp_rgb_parse_name(pyg_boxed_get(self, GimpRGB), name, len); + PyMem_Free(name); + + if (!success) { + PyErr_SetString(PyExc_ValueError, "unable to parse color name"); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_parse_hex(PyObject *self, PyObject *args, PyObject *kwargs) +{ + char *hex; + int len; + gboolean success; + static char *kwlist[] = { "hex", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#:parse_hex", kwlist, + &hex, &len)) + return NULL; + + success = gimp_rgb_parse_hex(pyg_boxed_get(self, GimpRGB), hex, len); + PyMem_Free(hex); + + if (!success) { + PyErr_SetString(PyExc_ValueError, "unable to parse hex value"); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_parse_css(PyObject *self, PyObject *args, PyObject *kwargs) +{ + char *css; + int len; + gboolean success, with_alpha = FALSE; + static char *kwlist[] = { "css", "with_alpha", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "s#|i:parse_css", kwlist, + &css, &len, &with_alpha)) + return NULL; + + if (with_alpha) + success = gimp_rgba_parse_css(pyg_boxed_get(self, GimpRGB), css, len); + else + success = gimp_rgb_parse_css(pyg_boxed_get(self, GimpRGB), css, len); + + PyMem_Free(css); + + if (!success) { + PyErr_SetString(PyExc_ValueError, "unable to parse CSS color"); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef rgb_methods[] = { + { "set", (PyCFunction)rgb_set, METH_VARARGS|METH_KEYWORDS }, + { "set_alpha", (PyCFunction)rgb_set_alpha, METH_VARARGS|METH_KEYWORDS }, + { "add", (PyCFunction)rgb_add, METH_VARARGS|METH_KEYWORDS }, + { "subtract", (PyCFunction)rgb_subtract, METH_VARARGS|METH_KEYWORDS }, + { "multiply", (PyCFunction)rgb_multiply, METH_VARARGS|METH_KEYWORDS }, + { "distance", (PyCFunction)rgb_distance, METH_VARARGS|METH_KEYWORDS }, + { "max", (PyCFunction)rgb_max, METH_NOARGS }, + { "min", (PyCFunction)rgb_min, METH_NOARGS }, + { "clamp", (PyCFunction)rgb_clamp, METH_NOARGS }, + { "gamma", (PyCFunction)rgb_gamma, METH_VARARGS|METH_KEYWORDS }, + { "intensity", (PyCFunction)rgb_intensity, METH_NOARGS }, + { "composite", (PyCFunction)rgb_composite, METH_VARARGS|METH_KEYWORDS }, + { "parse_name", (PyCFunction)rgb_parse_name, METH_VARARGS|METH_KEYWORDS }, + { "parse_hex", (PyCFunction)rgb_parse_hex, METH_VARARGS|METH_KEYWORDS }, + { "parse_css", (PyCFunction)rgb_parse_css, METH_VARARGS|METH_KEYWORDS }, + { NULL, NULL, 0 } +}; + +#define MEMBER_ACCESSOR(m) \ +static PyObject * \ +rgb_get_ ## m(PyObject *self, void *closure) \ +{ \ + return PyFloat_FromDouble(pyg_boxed_get(self, GimpRGB)->m); \ +} \ +static int \ +rgb_set_ ## m(PyObject *self, PyObject *value, void *closure) \ +{ \ + GimpRGB *rgb = pyg_boxed_get(self, GimpRGB); \ + if (value == NULL) { \ + PyErr_SetString(PyExc_TypeError, "cannot delete value"); \ + return -1; \ + } \ + else if (PyInt_Check(value)) \ + rgb->m = (double) PyInt_AS_LONG(value) / 255.0; \ + else if (PyFloat_Check(value)) \ + rgb->m = PyFloat_AS_DOUBLE(value); \ + else { \ + PyErr_SetString(PyExc_TypeError, "type mismatch"); \ + return -1; \ + } \ + return 0; \ +} + +MEMBER_ACCESSOR(r); +MEMBER_ACCESSOR(g); +MEMBER_ACCESSOR(b); +MEMBER_ACCESSOR(a); + +#undef MEMBER_ACCESSOR + +static PyGetSetDef rgb_getsets[] = { + { "r", (getter)rgb_get_r, (setter)rgb_set_r }, + { "g", (getter)rgb_get_g, (setter)rgb_set_g }, + { "b", (getter)rgb_get_b, (setter)rgb_set_b }, + { "a", (getter)rgb_get_a, (setter)rgb_set_a }, + { "red", (getter)rgb_get_r, (setter)rgb_set_r }, + { "green", (getter)rgb_get_g, (setter)rgb_set_g }, + { "blue", (getter)rgb_get_b, (setter)rgb_set_b }, + { "alpha", (getter)rgb_get_a, (setter)rgb_set_a }, + { NULL, (getter)0, (setter)0 }, +}; + +static PyObject * +rgb_init(PyGBoxed *self, PyObject *args, PyObject *kwargs) +{ + PyObject *r, *g, *b, *a = NULL; + GimpRGB rgb; + static char *kwlist[] = { "r", "g", "b", "a", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "OOO|O:set", kwlist, + &r, &g, &b, &a)) + return NULL; + +#define SET_MEMBER(m) G_STMT_START { \ + if (PyInt_Check(m)) \ + rgb.m = (double) PyInt_AS_LONG(m) / 255.0; \ + else if (PyFloat_Check(m)) \ + rgb.m = PyFloat_AS_DOUBLE(m); \ + else { \ + PyErr_SetString(PyExc_TypeError, \ + #m " must be an int or a float"); \ + return NULL; \ + } \ +} G_STMT_END + + SET_MEMBER(r); + SET_MEMBER(g); + SET_MEMBER(b); + + if (a) + SET_MEMBER(a); + else + rgb.a = 1.0; + +#undef SET_MEMBER + + self->gtype = GIMP_TYPE_RGB; + self->free_on_dealloc = TRUE; + self->boxed = g_boxed_copy(GIMP_TYPE_RGB, &rgb); + + Py_INCREF(Py_None); + return Py_None; +} + +PyTypeObject PyGimpRGB_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "gimpcolor.RGB", /* tp_name */ + sizeof(PyGBoxed), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)0, /* tp_dealloc */ + (printfunc)0, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)0, /* tp_compare */ + (reprfunc)0, /* tp_repr */ + (PyNumberMethods*)0, /* tp_as_number */ + (PySequenceMethods*)0, /* tp_as_sequence */ + (PyMappingMethods*)0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)0, /* tp_repr */ + (getattrofunc)0, /* tp_getattro */ + (setattrofunc)0, /* tp_setattro */ + (PyBufferProcs*)0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + NULL, /* Documentation string */ + (traverseproc)0, /* tp_traverse */ + (inquiry)0, /* tp_clear */ + (richcmpfunc)0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)0, /* tp_iter */ + (iternextfunc)0, /* tp_iternext */ + rgb_methods, /* tp_methods */ + 0, /* tp_members */ + rgb_getsets, /* tp_getset */ + NULL, /* tp_base */ + NULL, /* tp_dict */ + (descrgetfunc)0, /* tp_descr_get */ + (descrsetfunc)0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)rgb_init, /* tp_init */ + (allocfunc)0, /* tp_alloc */ + (newfunc)0, /* tp_new */ + (freefunc)0, /* tp_free */ + (inquiry)0 /* tp_is_gc */ +}; + +PyObject * +pygimp_rgb_new(GimpRGB *rgb) +{ + return pyg_boxed_new(GIMP_TYPE_RGB, rgb, TRUE, TRUE); +} diff --git a/plug-ins/pygimp/pygimp-drawable.c b/plug-ins/pygimp/pygimp-drawable.c index 90f7967e2f..406e1d51f5 100644 --- a/plug-ins/pygimp/pygimp-drawable.c +++ b/plug-ins/pygimp/pygimp-drawable.c @@ -410,7 +410,6 @@ static PyObject * drw_mask_intersect(PyGimpDrawable *self) { int x, y, width, height; - PyObject *ret; if (!gimp_drawable_mask_intersect(self->ID, &x, &y, &width, &height)) { PyErr_Format(pygimp_error, @@ -419,14 +418,7 @@ drw_mask_intersect(PyGimpDrawable *self) return NULL; } - ret = PyTuple_New(4); - - PyTuple_SetItem(ret, 0, PyInt_FromLong(x)); - PyTuple_SetItem(ret, 1, PyInt_FromLong(y)); - PyTuple_SetItem(ret, 2, PyInt_FromLong(width)); - PyTuple_SetItem(ret, 3, PyInt_FromLong(height)); - - return ret; + return Py_BuildValue("(iiii)", x, y, width, height); } static PyObject * diff --git a/plug-ins/pygimp/pygimp-image.c b/plug-ins/pygimp/pygimp-image.c index 7f43c29313..d9a3fb076c 100644 --- a/plug-ins/pygimp/pygimp-image.c +++ b/plug-ins/pygimp/pygimp-image.c @@ -1220,7 +1220,7 @@ img_repr(PyGimpImage *self) gchar *name; name = gimp_image_get_name(self->ID); - s = PyString_FromFormat("", name ? name : "(null)"); + s = PyString_FromFormat("", name ? name : "(null)"); g_free(name); return s; diff --git a/plug-ins/pygimp/pygimp-rgb.c b/plug-ins/pygimp/pygimp-rgb.c new file mode 100644 index 0000000000..ea1ae458fb --- /dev/null +++ b/plug-ins/pygimp/pygimp-rgb.c @@ -0,0 +1,469 @@ +#define NO_IMPORT_PYGOBJECT + +#include "pygimpcolor.h" + +static PyObject * +rgb_set(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *r = NULL, *g = NULL, *b = NULL, *a = NULL; + GimpRGB tmprgb, *rgb; + static char *kwlist[] = { "r", "g", "b", "a", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOO:set", kwlist, + &r, &g, &b, &a)) + return NULL; + + if (!r && !g && !b && !a) { + PyErr_SetString(PyExc_TypeError, "must provide r,g,b or a arguments"); + return NULL; + } + + if ((r && (!g || !b)) || + (g && (!r || !b)) || + (b && (!r || !g))) { + PyErr_SetString(PyExc_TypeError, "must provide all 3 r,g,b arguments"); + return NULL; + } + + rgb = pyg_boxed_get(self, GimpRGB); + tmprgb = *rgb; + +#define SET_MEMBER(m) G_STMT_START { \ + if (PyInt_Check(m)) \ + tmprgb.m = (double) PyInt_AS_LONG(m) / 255.0; \ + else if (PyFloat_Check(m)) \ + tmprgb.m = PyFloat_AS_DOUBLE(m); \ + else { \ + PyErr_SetString(PyExc_TypeError, \ + #m " must be an int or a float"); \ + return NULL; \ + } \ +} G_STMT_END + + if (r) { + SET_MEMBER(r); + SET_MEMBER(g); + SET_MEMBER(b); + } + + if (a) + SET_MEMBER(a); + +#undef SET_MEMBER + + *rgb = tmprgb; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_set_alpha(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_a; + GimpRGB *rgb; + static char *kwlist[] = { "a", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O:set_alpha", kwlist, + &py_a)) + return NULL; + + rgb = pyg_boxed_get(self, GimpRGB); + + if (PyInt_Check(py_a)) + rgb->a = (double) PyInt_AS_LONG(py_a) / 255.0; + else if (PyFloat_Check(py_a)) + rgb->a = PyFloat_AS_DOUBLE(py_a); + else { + PyErr_SetString(PyExc_TypeError, "a must be an int or a float"); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_add(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *color; + gboolean with_alpha = FALSE; + static char *kwlist[] = { "color", "with_alpha", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|i:add", kwlist, + &PyGimpRGB_Type, &color, &with_alpha)) + return NULL; + + if (with_alpha) + gimp_rgba_add(pyg_boxed_get(self, GimpRGB), + pyg_boxed_get(color, GimpRGB)); + else + gimp_rgb_add(pyg_boxed_get(self, GimpRGB), + pyg_boxed_get(color, GimpRGB)); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_subtract(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *color; + gboolean with_alpha = FALSE; + static char *kwlist[] = { "color", "with_alpha", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|i:subtract", kwlist, + &PyGimpRGB_Type, &color, &with_alpha)) + return NULL; + + if (with_alpha) + gimp_rgba_subtract(pyg_boxed_get(self, GimpRGB), + pyg_boxed_get(color, GimpRGB)); + else + gimp_rgb_subtract(pyg_boxed_get(self, GimpRGB), + pyg_boxed_get(color, GimpRGB)); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_multiply(PyObject *self, PyObject *args, PyObject *kwargs) +{ + double factor; + gboolean with_alpha = FALSE; + static char *kwlist[] = { "factor", "with_alpha", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "d|i:multiply", kwlist, + &factor, &with_alpha)) + return NULL; + + if (with_alpha) + gimp_rgba_multiply(pyg_boxed_get(self, GimpRGB), factor); + else + gimp_rgb_multiply(pyg_boxed_get(self, GimpRGB), factor); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_distance(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *color; + gboolean alpha = FALSE; + double ret; + static char *kwlist[] = { "color", "alpha", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|i:distance", kwlist, + &PyGimpRGB_Type, &color, &alpha)) + return NULL; + + ret = gimp_rgb_distance(pyg_boxed_get(self, GimpRGB), + pyg_boxed_get(color, GimpRGB)); + + + return PyFloat_FromDouble(ret); +} + +static PyObject * +rgb_max(PyObject *self) +{ + return PyFloat_FromDouble(gimp_rgb_max(pyg_boxed_get(self, GimpRGB))); +} + +static PyObject * +rgb_min(PyObject *self) +{ + return PyFloat_FromDouble(gimp_rgb_min(pyg_boxed_get(self, GimpRGB))); +} + +static PyObject * +rgb_clamp(PyObject *self) +{ + gimp_rgb_clamp(pyg_boxed_get(self, GimpRGB)); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_gamma(PyObject *self, PyObject *args, PyObject *kwargs) +{ + double gamma; + static char *kwlist[] = { "gamma", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "d:gamma", kwlist, &gamma)) + return NULL; + + gimp_rgb_gamma(pyg_boxed_get(self, GimpRGB), gamma); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_intensity(PyObject *self) +{ + return PyFloat_FromDouble(gimp_rgb_intensity(pyg_boxed_get(self, GimpRGB))); +} + +static PyObject * +rgb_composite(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *color; + int mode = GIMP_RGB_COMPOSITE_NORMAL; + static char *kwlist[] = { "color", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!|i:composite", kwlist, + &PyGimpRGB_Type, &color, &mode)) + return NULL; + + if (mode < GIMP_RGB_COMPOSITE_NONE || mode > GIMP_RGB_COMPOSITE_BEHIND) { + PyErr_SetString(PyExc_TypeError, "composite type is not valid"); + return NULL; + } + + gimp_rgb_composite(pyg_boxed_get(self, GimpRGB), + pyg_boxed_get(color, GimpRGB), + mode); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_parse_name(PyObject *self, PyObject *args, PyObject *kwargs) +{ + char *name; + int len; + gboolean success; + static char *kwlist[] = { "name", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#:parse_name", kwlist, + &name, &len)) + return NULL; + + success = gimp_rgb_parse_name(pyg_boxed_get(self, GimpRGB), name, len); + PyMem_Free(name); + + if (!success) { + PyErr_SetString(PyExc_ValueError, "unable to parse color name"); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_parse_hex(PyObject *self, PyObject *args, PyObject *kwargs) +{ + char *hex; + int len; + gboolean success; + static char *kwlist[] = { "hex", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#:parse_hex", kwlist, + &hex, &len)) + return NULL; + + success = gimp_rgb_parse_hex(pyg_boxed_get(self, GimpRGB), hex, len); + PyMem_Free(hex); + + if (!success) { + PyErr_SetString(PyExc_ValueError, "unable to parse hex value"); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +rgb_parse_css(PyObject *self, PyObject *args, PyObject *kwargs) +{ + char *css; + int len; + gboolean success, with_alpha = FALSE; + static char *kwlist[] = { "css", "with_alpha", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "s#|i:parse_css", kwlist, + &css, &len, &with_alpha)) + return NULL; + + if (with_alpha) + success = gimp_rgba_parse_css(pyg_boxed_get(self, GimpRGB), css, len); + else + success = gimp_rgb_parse_css(pyg_boxed_get(self, GimpRGB), css, len); + + PyMem_Free(css); + + if (!success) { + PyErr_SetString(PyExc_ValueError, "unable to parse CSS color"); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef rgb_methods[] = { + { "set", (PyCFunction)rgb_set, METH_VARARGS|METH_KEYWORDS }, + { "set_alpha", (PyCFunction)rgb_set_alpha, METH_VARARGS|METH_KEYWORDS }, + { "add", (PyCFunction)rgb_add, METH_VARARGS|METH_KEYWORDS }, + { "subtract", (PyCFunction)rgb_subtract, METH_VARARGS|METH_KEYWORDS }, + { "multiply", (PyCFunction)rgb_multiply, METH_VARARGS|METH_KEYWORDS }, + { "distance", (PyCFunction)rgb_distance, METH_VARARGS|METH_KEYWORDS }, + { "max", (PyCFunction)rgb_max, METH_NOARGS }, + { "min", (PyCFunction)rgb_min, METH_NOARGS }, + { "clamp", (PyCFunction)rgb_clamp, METH_NOARGS }, + { "gamma", (PyCFunction)rgb_gamma, METH_VARARGS|METH_KEYWORDS }, + { "intensity", (PyCFunction)rgb_intensity, METH_NOARGS }, + { "composite", (PyCFunction)rgb_composite, METH_VARARGS|METH_KEYWORDS }, + { "parse_name", (PyCFunction)rgb_parse_name, METH_VARARGS|METH_KEYWORDS }, + { "parse_hex", (PyCFunction)rgb_parse_hex, METH_VARARGS|METH_KEYWORDS }, + { "parse_css", (PyCFunction)rgb_parse_css, METH_VARARGS|METH_KEYWORDS }, + { NULL, NULL, 0 } +}; + +#define MEMBER_ACCESSOR(m) \ +static PyObject * \ +rgb_get_ ## m(PyObject *self, void *closure) \ +{ \ + return PyFloat_FromDouble(pyg_boxed_get(self, GimpRGB)->m); \ +} \ +static int \ +rgb_set_ ## m(PyObject *self, PyObject *value, void *closure) \ +{ \ + GimpRGB *rgb = pyg_boxed_get(self, GimpRGB); \ + if (value == NULL) { \ + PyErr_SetString(PyExc_TypeError, "cannot delete value"); \ + return -1; \ + } \ + else if (PyInt_Check(value)) \ + rgb->m = (double) PyInt_AS_LONG(value) / 255.0; \ + else if (PyFloat_Check(value)) \ + rgb->m = PyFloat_AS_DOUBLE(value); \ + else { \ + PyErr_SetString(PyExc_TypeError, "type mismatch"); \ + return -1; \ + } \ + return 0; \ +} + +MEMBER_ACCESSOR(r); +MEMBER_ACCESSOR(g); +MEMBER_ACCESSOR(b); +MEMBER_ACCESSOR(a); + +#undef MEMBER_ACCESSOR + +static PyGetSetDef rgb_getsets[] = { + { "r", (getter)rgb_get_r, (setter)rgb_set_r }, + { "g", (getter)rgb_get_g, (setter)rgb_set_g }, + { "b", (getter)rgb_get_b, (setter)rgb_set_b }, + { "a", (getter)rgb_get_a, (setter)rgb_set_a }, + { "red", (getter)rgb_get_r, (setter)rgb_set_r }, + { "green", (getter)rgb_get_g, (setter)rgb_set_g }, + { "blue", (getter)rgb_get_b, (setter)rgb_set_b }, + { "alpha", (getter)rgb_get_a, (setter)rgb_set_a }, + { NULL, (getter)0, (setter)0 }, +}; + +static PyObject * +rgb_init(PyGBoxed *self, PyObject *args, PyObject *kwargs) +{ + PyObject *r, *g, *b, *a = NULL; + GimpRGB rgb; + static char *kwlist[] = { "r", "g", "b", "a", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "OOO|O:set", kwlist, + &r, &g, &b, &a)) + return NULL; + +#define SET_MEMBER(m) G_STMT_START { \ + if (PyInt_Check(m)) \ + rgb.m = (double) PyInt_AS_LONG(m) / 255.0; \ + else if (PyFloat_Check(m)) \ + rgb.m = PyFloat_AS_DOUBLE(m); \ + else { \ + PyErr_SetString(PyExc_TypeError, \ + #m " must be an int or a float"); \ + return NULL; \ + } \ +} G_STMT_END + + SET_MEMBER(r); + SET_MEMBER(g); + SET_MEMBER(b); + + if (a) + SET_MEMBER(a); + else + rgb.a = 1.0; + +#undef SET_MEMBER + + self->gtype = GIMP_TYPE_RGB; + self->free_on_dealloc = TRUE; + self->boxed = g_boxed_copy(GIMP_TYPE_RGB, &rgb); + + Py_INCREF(Py_None); + return Py_None; +} + +PyTypeObject PyGimpRGB_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "gimpcolor.RGB", /* tp_name */ + sizeof(PyGBoxed), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)0, /* tp_dealloc */ + (printfunc)0, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)0, /* tp_compare */ + (reprfunc)0, /* tp_repr */ + (PyNumberMethods*)0, /* tp_as_number */ + (PySequenceMethods*)0, /* tp_as_sequence */ + (PyMappingMethods*)0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)0, /* tp_repr */ + (getattrofunc)0, /* tp_getattro */ + (setattrofunc)0, /* tp_setattro */ + (PyBufferProcs*)0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + NULL, /* Documentation string */ + (traverseproc)0, /* tp_traverse */ + (inquiry)0, /* tp_clear */ + (richcmpfunc)0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)0, /* tp_iter */ + (iternextfunc)0, /* tp_iternext */ + rgb_methods, /* tp_methods */ + 0, /* tp_members */ + rgb_getsets, /* tp_getset */ + NULL, /* tp_base */ + NULL, /* tp_dict */ + (descrgetfunc)0, /* tp_descr_get */ + (descrsetfunc)0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)rgb_init, /* tp_init */ + (allocfunc)0, /* tp_alloc */ + (newfunc)0, /* tp_new */ + (freefunc)0, /* tp_free */ + (inquiry)0 /* tp_is_gc */ +}; + +PyObject * +pygimp_rgb_new(GimpRGB *rgb) +{ + return pyg_boxed_new(GIMP_TYPE_RGB, rgb, TRUE, TRUE); +} diff --git a/plug-ins/pygimp/pygimpcolor.h b/plug-ins/pygimp/pygimpcolor.h new file mode 100644 index 0000000000..aef6cc9161 --- /dev/null +++ b/plug-ins/pygimp/pygimpcolor.h @@ -0,0 +1,39 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + Gimp-Python - allows the writing of Gimp plugins in Python. + Copyright (C) 2003 Manish Singh + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _PYGIMPCOLOR_H_ +#define _PYGIMPCOLOR_H_ + +#include + +#include + +#include + +#include + +G_BEGIN_DECLS + +extern PyTypeObject PyGimpRGB_Type; +#define pygimp_rgb_check(v) (pyg_boxed_check((v), GIMP_TYPE_RGB)) +PyObject *pygimp_rgb_new(GimpRGB *rgb); + +G_END_DECLS + +#endif