Logo Search packages:      
Sourcecode: blender version File versions

charRGBA.c

/* 
 * $Id: charRGBA.c,v 1.2 2004/09/25 20:30:40 stiv Exp $
 *
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 *
 * 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. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * 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.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * This is a new part of Blender.
 *
 * Contributor(s): Willian P. Germano
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
*/

#include "charRGBA.h"

/* This file is heavily based on the old bpython Constant object code in
       Blender */

/*****************************************************************************/
/* Python charRGBA_Type callback function prototypes:               */
/*****************************************************************************/
static void charRGBA_dealloc( BPy_charRGBA * self );
static PyObject *charRGBA_getAttr( BPy_charRGBA * self, char *name );
static int charRGBA_setAttr( BPy_charRGBA * self, char *name, PyObject * v );
static PyObject *charRGBA_repr( BPy_charRGBA * self );

static int charRGBALength( BPy_charRGBA * self );

static PyObject *charRGBASubscript( BPy_charRGBA * self, PyObject * key );
static int charRGBAAssSubscript( BPy_charRGBA * self, PyObject * who,
                         PyObject * cares );

static PyObject *charRGBAItem( BPy_charRGBA * self, int i );
static int charRGBAAssItem( BPy_charRGBA * self, int i, PyObject * ob );
static PyObject *charRGBASlice( BPy_charRGBA * self, int begin, int end );
static int charRGBAAssSlice( BPy_charRGBA * self, int begin, int end,
                       PyObject * seq );

/*****************************************************************************/
/* Python charRGBA_Type Mapping Methods table:              */
/*****************************************************************************/
static PyMappingMethods charRGBAAsMapping = {
      ( inquiry ) charRGBALength,   /* mp_length                            */
      ( binaryfunc ) charRGBASubscript,   /* mp_subscript                 */
      ( objobjargproc ) charRGBAAssSubscript,   /* mp_ass_subscript */
};

/*****************************************************************************/
/* Python charRGBA_Type Sequence Methods table:             */
/*****************************************************************************/
static PySequenceMethods charRGBAAsSequence = {
      ( inquiry ) charRGBALength,   /* sq_length */
      ( binaryfunc ) 0, /* sq_concat */
      ( intargfunc ) 0, /* sq_repeat */
      ( intargfunc ) charRGBAItem,  /* sq_item */
      ( intintargfunc ) charRGBASlice,    /* sq_slice */
      ( intobjargproc ) charRGBAAssItem,  /* sq_ass_item */
      ( intintobjargproc ) charRGBAAssSlice,    /* sq_ass_slice       */
};

/*****************************************************************************/
/* Python charRGBA_Type structure definition:                     */
/*****************************************************************************/
PyTypeObject charRGBA_Type = {
      PyObject_HEAD_INIT( NULL ) 
      0,    /* ob_size */
      "charRGBA",       /* tp_name */
      sizeof( BPy_charRGBA ), /* tp_basicsize */
      0,                /* tp_itemsize */
      /* methods */
      ( destructor ) charRGBA_dealloc,    /* tp_dealloc */
      0,                /* tp_print */
      ( getattrfunc ) charRGBA_getAttr,   /* tp_getattr */
      ( setattrfunc ) charRGBA_setAttr,   /* tp_setattr */
      0,                /* tp_compare */
      ( reprfunc ) charRGBA_repr,   /* tp_repr */
      0,                /* tp_as_number */
      &charRGBAAsSequence,    /* tp_as_sequence */
      &charRGBAAsMapping,     /* tp_as_mapping */
      0,                /* tp_as_hash */
      0, 0, 0, 0, 0, 0,
      0,                /* tp_doc */
      0, 0, 0, 0, 0, 0,
      0,                /* tp_methods */
      0,                /* tp_members */
};

/*****************************************************************************/
/* Function:      charRGBA_New                                              */
/*****************************************************************************/
PyObject *charRGBA_New( char *rgba )
{
      BPy_charRGBA *charRGBA;

      charRGBA_Type.ob_type = &PyType_Type;

      charRGBA =
            ( BPy_charRGBA * ) PyObject_NEW( BPy_charRGBA,
                                     &charRGBA_Type );

      if( charRGBA == NULL )
            return EXPP_ReturnPyObjError( PyExc_MemoryError,
                                    "couldn't create charRGBA object" );

      /* rgba is a pointer to the first item of a char[4] array */
      charRGBA->rgba[0] = &rgba[0];
      charRGBA->rgba[1] = &rgba[1];
      charRGBA->rgba[2] = &rgba[2];
      charRGBA->rgba[3] = &rgba[3];

      return ( PyObject * ) charRGBA;
}

/*****************************************************************************/
/* Functions:      charRGBA_getCol and charRGBA_setCol             */
/* Description:    These functions get/set rgba color triplet values.   The  */
/*           get function returns a tuple, the set one accepts three     */
/*           chars (separated or in a tuple) as arguments.            */
/*****************************************************************************/
PyObject *charRGBA_getCol( BPy_charRGBA * self )
{
      PyObject *list = PyList_New( 4 );

      if( !list )
            return EXPP_ReturnPyObjError( PyExc_MemoryError,
                                    "couldn't create PyList" );

      PyList_SET_ITEM( list, 0, Py_BuildValue( "b", *( self->rgba[0] ) ) );
      PyList_SET_ITEM( list, 1, Py_BuildValue( "b", *( self->rgba[1] ) ) );
      PyList_SET_ITEM( list, 2, Py_BuildValue( "b", *( self->rgba[2] ) ) );
      PyList_SET_ITEM( list, 3, Py_BuildValue( "b", *( self->rgba[3] ) ) );

      return list;
}

PyObject *charRGBA_setCol( BPy_charRGBA * self, PyObject * args )
{
      int ok;
      char r = 0, g = 0, b = 0, a = 0;

      if( PyObject_Length( args ) == 4 )
            ok = PyArg_ParseTuple( args, "bbbb", &r, &g, &b, &a );

      else
            ok = PyArg_ParseTuple( args, "|(bbbb)", &r, &g, &b, &a );

      if( !ok )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected 1-byte ints [b,b,b,b] or b,b,b,b as arguments (or nothing)" );

      *( self->rgba[0] ) = EXPP_ClampInt( r, 0, 255 );
      *( self->rgba[1] ) = EXPP_ClampInt( g, 0, 255 );
      *( self->rgba[2] ) = EXPP_ClampInt( b, 0, 255 );
      *( self->rgba[3] ) = EXPP_ClampInt( a, 0, 255 );

      return EXPP_incr_ret( Py_None );
}

/*****************************************************************************/
/* Function:      charRGBA_dealloc                           */
/* Description: This is a callback function for the BPy_charRGBA type. It is */
/*          the destructor function.                         */
/*****************************************************************************/
static void charRGBA_dealloc( BPy_charRGBA * self )
{
      PyObject_DEL( self );
}

/*****************************************************************************/
/* Function:      charRGBA_getAttr                           */
/* Description: This is a callback function for the BPy_charRGBA type. It is */
/*          the function that accesses BPy_charRGBA member variables and */
/*          methods.                                   */
/*****************************************************************************/
static PyObject *charRGBA_getAttr( BPy_charRGBA * self, char *name )
{
      int i;

      if( strcmp( name, "__members__" ) == 0 )
            return Py_BuildValue( "[s,s,s,s]", "R", "G", "B", "A" );

      else if( !strcmp( name, "R" ) || !strcmp( name, "r" ) )
            i = 0;
      else if( !strcmp( name, "G" ) || !strcmp( name, "g" ) )
            i = 1;
      else if( !strcmp( name, "B" ) || !strcmp( name, "b" ) )
            i = 2;
      else if( !strcmp( name, "A" ) || !strcmp( name, "a" ) )
            i = 3;
      else
            return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
                                    "attribute not found" ) );

      return Py_BuildValue( "b", *( self->rgba[i] ) );
}

/*****************************************************************************/
/* Function:      charRGBA_setAttr                           */
/* Description: This is a callback function for the BPy_charRGBA type. It is */
/*          the function that changes BPy_charRGBA member variables.   */
/*****************************************************************************/
static int charRGBA_setAttr( BPy_charRGBA * self, char *name, PyObject * v )
{
      char value;

      if( !PyArg_Parse( v, "b", &value ) )
            return EXPP_ReturnIntError( PyExc_TypeError,
                                  "expected char argument" );

      value = EXPP_ClampInt( value, 0, 255 );

      if( !strcmp( name, "R" ) || !strcmp( name, "r" ) )
            *( self->rgba[0] ) = value;

      else if( !strcmp( name, "G" ) || !strcmp( name, "g" ) )
            *( self->rgba[1] ) = value;

      else if( !strcmp( name, "B" ) || !strcmp( name, "b" ) )
            *( self->rgba[2] ) = value;

      else if( !strcmp( name, "A" ) || !strcmp( name, "a" ) )
            *( self->rgba[3] ) = value;

      else
            return ( EXPP_ReturnIntError( PyExc_AttributeError,
                                    "attribute not found" ) );

      return 0;
}

/*****************************************************************************/
/* Section:  charRGBA as Mapping                             */
/*           These functions provide code to access charRGBA objects as  */
/*            mappings.                                */
/*****************************************************************************/
static int charRGBALength( BPy_charRGBA * self )
{
      return 4;
}

static PyObject *charRGBASubscript( BPy_charRGBA * self, PyObject * key )
{
      char *name = NULL;
      int i;

      if( PyNumber_Check( key ) )
            return charRGBAItem( self, ( int ) PyInt_AsLong( key ) );

      if( !PyArg_ParseTuple( key, "s", &name ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected int or string argument" );

      if( !strcmp( name, "R" ) || !strcmp( name, "r" ) )
            i = 0;
      else if( !strcmp( name, "G" ) || !strcmp( name, "g" ) )
            i = 1;
      else if( !strcmp( name, "B" ) || !strcmp( name, "b" ) )
            i = 2;
      else if( !strcmp( name, "A" ) || !strcmp( name, "a" ) )
            i = 3;
      else
            return EXPP_ReturnPyObjError( PyExc_AttributeError, name );

      return Py_BuildValue( "b", *( self->rgba[i] ) );
}

static int charRGBAAssSubscript( BPy_charRGBA * self, PyObject * key,
                         PyObject * v )
{
      char *name = NULL;
      int i;

      if( !PyNumber_Check( v ) )
            return EXPP_ReturnIntError( PyExc_TypeError,
                                  "value to assign must be a number" );

      if( PyNumber_Check( key ) )
            return charRGBAAssItem( self, ( int ) PyInt_AsLong( key ), v );

      if( !PyArg_Parse( key, "s", &name ) )
            return EXPP_ReturnIntError( PyExc_TypeError,
                                  "expected int or string argument" );

      if( !strcmp( name, "R" ) || !strcmp( name, "r" ) )
            i = 0;
      else if( !strcmp( name, "G" ) || !strcmp( name, "g" ) )
            i = 1;
      else if( !strcmp( name, "B" ) || !strcmp( name, "b" ) )
            i = 2;
      else if( !strcmp( name, "A" ) || !strcmp( name, "a" ) )
            i = 3;
      else
            return EXPP_ReturnIntError( PyExc_AttributeError, name );

      *( self->rgba[i] ) = EXPP_ClampInt( PyInt_AsLong( v ), 0, 255 );

      return 0;
}

/*****************************************************************************/
/* Section:  charRGBA as Sequence                           */
/*         These functions provide code to access charRGBA objects as    */
/*           sequences.                               */
/*****************************************************************************/
static PyObject *charRGBAItem( BPy_charRGBA * self, int i )
{
      if( i < 0 || i >= 4 )
            return EXPP_ReturnPyObjError( PyExc_IndexError,
                                    "array index out of range" );

      return Py_BuildValue( "b", *( self->rgba[i] ) );
}

static PyObject *charRGBASlice( BPy_charRGBA * self, int begin, int end )
{
      PyObject *list;
      int count;

      if( begin < 0 )
            begin = 0;
      if( end > 4 )
            end = 4;
      if( begin > end )
            begin = end;

      list = PyList_New( end - begin );

      for( count = begin; count < end; count++ )
            PyList_SetItem( list, count - begin,
                        PyInt_FromLong( *( self->rgba[count] ) ) );

      return list;
}

static int charRGBAAssItem( BPy_charRGBA * self, int i, PyObject * ob )
{
      if( i < 0 || i >= 4 )
            return EXPP_ReturnIntError( PyExc_IndexError,
                                  "array assignment index out of range" );

      if( !PyNumber_Check( ob ) )
            return EXPP_ReturnIntError( PyExc_IndexError,
                                  "color component must be a number" );

      *( self->rgba[i] ) = EXPP_ClampInt( PyInt_AsLong( ob ), 0, 255 );

      return 0;
}

static int charRGBAAssSlice( BPy_charRGBA * self, int begin, int end,
                       PyObject * seq )
{
      int count;

      if( begin < 0 )
            begin = 0;
      if( end > 4 )
            end = 4;
      if( begin > end )
            begin = end;

      if( !PySequence_Check( seq ) )
            return EXPP_ReturnIntError( PyExc_TypeError,
                                  "illegal argument type for built-in operation" );

      if( PySequence_Length( seq ) != ( end - begin ) )
            return EXPP_ReturnIntError( PyExc_TypeError,
                                  "size mismatch in slice assignment" );

      for( count = begin; count < end; count++ ) {
            char value;
            PyObject *ob = PySequence_GetItem( seq, count );

            if( !PyArg_Parse( ob, "b", &value ) ) {
                  Py_DECREF( ob );
                  return -1;
            }

            *( self->rgba[count] ) = EXPP_ClampInt( value, 0, 255 );

            Py_DECREF( ob );
      }

      return 0;
}

/*****************************************************************************/
/* Function:      charRGBA_repr                                   */
/* Description: This is a callback function for the BPy_charRGBA type. It  */
/*          builds a meaninful string to represent charRGBA objects.   */
/*****************************************************************************/
static PyObject *charRGBA_repr( BPy_charRGBA * self )
{
      char r, g, b, a;

      r = *( self->rgba[0] );
      g = *( self->rgba[1] );
      b = *( self->rgba[2] );
      a = *( self->rgba[3] );

      return PyString_FromFormat( "[%d, %d, %d, %d]", r, g, b, a );
}

Generated by  Doxygen 1.6.0   Back to index