09a0573e61
[CONFIGURATION] Replace my old sourceforge mail address by the new one.
258 lines
30 KiB
C
258 lines
30 KiB
C
/***************************************************************************
|
|
|
|
cpoint_temp.h
|
|
|
|
(c) 2000-2017 Benoît Minisini <g4mba5@gmail.com>
|
|
|
|
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, 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., 51 Franklin Street, Fifth Floor, Boston,
|
|
MA 02110-1301, USA.
|
|
|
|
***************************************************************************/
|
|
|
|
#define IMPLEMENT_POINT_CLASS(__struct, __name, __gtype, __ctype, __sign, __return, __this, __rstruct, __rname) \
|
|
\
|
|
__struct * __struct##_create(__ctype x, __ctype y) \
|
|
{ \
|
|
__struct *p = GB.New(GB.FindClass(#__name), NULL, NULL); \
|
|
p->x = x; \
|
|
p->y = y; \
|
|
return p; \
|
|
} \
|
|
\
|
|
static inline __struct *__struct##_make(__struct *a, const __ctype x, const __ctype y) \
|
|
{ \
|
|
if (a->ob.ref <= 1) \
|
|
{ \
|
|
a->x = x; \
|
|
a->y = y; \
|
|
return a; \
|
|
} \
|
|
else \
|
|
return __struct##_create(x, y); \
|
|
} \
|
|
\
|
|
static __struct *_add_##__name(__struct *a, __struct *b, bool invert) \
|
|
{ \
|
|
return __struct##_make(a, a->x + b->x, a->y + b->y); \
|
|
} \
|
|
\
|
|
static __struct *_sub_##__name(__struct *a, __struct *b, bool invert) \
|
|
{ \
|
|
return __struct##_make(a, a->x - b->x, a->y - b->y); \
|
|
} \
|
|
\
|
|
static __struct *_mulf_##__name(__struct *a, double f, bool invert) \
|
|
{ \
|
|
return __struct##_make(a, a->x * f, a->y * f); \
|
|
} \
|
|
\
|
|
static __struct *_mulo_##__name(__struct *a, void *b, bool invert) \
|
|
{ \
|
|
return NULL; \
|
|
} \
|
|
\
|
|
static __struct *_divf_##__name(__struct *a, double f, bool invert) \
|
|
{ \
|
|
if (invert) \
|
|
return NULL; \
|
|
if (f == 0.0) \
|
|
return NULL; \
|
|
\
|
|
return __struct##_make(a, a->x / f, a->y / f); \
|
|
} \
|
|
\
|
|
static __struct *_divo_##__name(__struct *a, void *b, bool invert) \
|
|
{ \
|
|
return NULL; \
|
|
} \
|
|
\
|
|
static int _equal_##__name(__struct *a, __struct *b, bool invert) \
|
|
{ \
|
|
return a->x == b->x && a->y == b->y; \
|
|
} \
|
|
\
|
|
static double _fabs_##__name(__struct *a) \
|
|
{ \
|
|
return hypot(a->x, a->y); \
|
|
} \
|
|
\
|
|
static __struct *_neg_##__name(__struct *a) \
|
|
{ \
|
|
return __struct##_make(a, -a->x, -a->y); \
|
|
} \
|
|
\
|
|
static GB_OPERATOR_DESC _operator_##__name = \
|
|
{ \
|
|
.equal = (void *)_equal_##__name, \
|
|
.add = (void *)_add_##__name, \
|
|
.sub = (void *)_sub_##__name, \
|
|
.mulf = (void *)_mulf_##__name, \
|
|
.mulo = (void *)_mulo_##__name, \
|
|
.divf = (void *)_divf_##__name, \
|
|
.divo = (void *)_divo_##__name, \
|
|
.fabs = (void *)_fabs_##__name, \
|
|
.neg = (void *)_neg_##__name, \
|
|
}; \
|
|
\
|
|
char *__struct##_to_string(void *a, bool local) \
|
|
{ \
|
|
char *result = NULL; \
|
|
char *str; \
|
|
int len; \
|
|
\
|
|
__ctype x = ((__struct *)a)->x; \
|
|
__ctype y = ((__struct *)a)->y; \
|
|
\
|
|
result = GB.AddChar(result, '['); \
|
|
\
|
|
GB.NumberToString(local, x, NULL, &str, &len); \
|
|
result = GB.AddString(result, str, len); \
|
|
\
|
|
result = GB.AddChar(result, local ? ' ' : ','); \
|
|
\
|
|
GB.NumberToString(local, y, NULL, &str, &len); \
|
|
result = GB.AddString(result, str, len); \
|
|
\
|
|
result = GB.AddChar(result, ']'); \
|
|
\
|
|
return result; \
|
|
} \
|
|
\
|
|
static bool _convert_##__name(void *a, GB_TYPE type, GB_VALUE *conv) \
|
|
{ \
|
|
if (a) \
|
|
{ \
|
|
double norm = _fabs_##__name(a); \
|
|
\
|
|
switch (type) \
|
|
{ \
|
|
case GB_T_FLOAT: \
|
|
conv->_float.value = norm; \
|
|
return FALSE; \
|
|
\
|
|
case GB_T_SINGLE: \
|
|
conv->_single.value = norm; \
|
|
return FALSE; \
|
|
\
|
|
case GB_T_INTEGER: \
|
|
case GB_T_SHORT: \
|
|
case GB_T_BYTE: \
|
|
conv->_integer.value = norm; \
|
|
return FALSE; \
|
|
\
|
|
case GB_T_LONG: \
|
|
conv->_long.value = norm; \
|
|
return FALSE; \
|
|
\
|
|
case GB_T_STRING: \
|
|
case GB_T_CSTRING: \
|
|
conv->_string.value.addr = __struct##_to_string(a, type == GB_T_CSTRING); \
|
|
conv->_string.value.start = 0; \
|
|
conv->_string.value.len = GB.StringLength(conv->_string.value.addr); \
|
|
return FALSE; \
|
|
\
|
|
default: \
|
|
if (type == GB.FindClass("Point")) \
|
|
{ \
|
|
conv->_object.value = CPOINT_create(((__struct *)a)->x, ((__struct *)a)->y); \
|
|
return FALSE; \
|
|
} \
|
|
if (type == GB.FindClass("PointF")) \
|
|
{ \
|
|
conv->_object.value = CPOINTF_create(((__struct *)a)->x, ((__struct *)a)->y); \
|
|
return FALSE; \
|
|
} \
|
|
else \
|
|
return TRUE; \
|
|
} \
|
|
} \
|
|
else \
|
|
return TRUE; \
|
|
} \
|
|
\
|
|
\
|
|
BEGIN_METHOD(__name##_new, __gtype x; __gtype y; __gtype w; __gtype h) \
|
|
\
|
|
if (!MISSING(x) && !MISSING(y)) \
|
|
{ \
|
|
__this->x = VARG(x); \
|
|
__this->y = VARG(y); \
|
|
} \
|
|
\
|
|
END_METHOD \
|
|
\
|
|
BEGIN_METHOD(__name##_call, __gtype x; __gtype y) \
|
|
\
|
|
GB.ReturnObject(__struct##_create(VARGOPT(x, 0), VARGOPT(y, 0))); \
|
|
\
|
|
END_METHOD \
|
|
\
|
|
BEGIN_PROPERTY(__name##_X) \
|
|
\
|
|
if (READ_PROPERTY) \
|
|
__return(__this->x); \
|
|
else \
|
|
__this->x = VPROP(__gtype); \
|
|
\
|
|
END_PROPERTY \
|
|
\
|
|
BEGIN_PROPERTY(__name##_Y) \
|
|
\
|
|
if (READ_PROPERTY) \
|
|
__return(__this->y); \
|
|
else \
|
|
__this->y = VPROP(__gtype); \
|
|
\
|
|
END_PROPERTY \
|
|
\
|
|
BEGIN_METHOD_VOID(__name##_Copy) \
|
|
\
|
|
GB.ReturnObject(__struct##_create(__this->x, __this->y)); \
|
|
\
|
|
END_METHOD \
|
|
\
|
|
BEGIN_METHOD(__name##_InRect, GB_OBJECT rect) \
|
|
\
|
|
__rstruct *rect = VARG(rect); \
|
|
\
|
|
if (GB.CheckObject(rect)) \
|
|
return; \
|
|
\
|
|
GB.ReturnBoolean( \
|
|
(__this->x >= rect->x) && (__this->x < (rect->x + rect->w)) \
|
|
&& (__this->y >= rect->y) && (__this->y < (rect->y + rect->h)) \
|
|
); \
|
|
\
|
|
END_METHOD \
|
|
\
|
|
GB_DESC __name##Desc[] = \
|
|
{ \
|
|
GB_DECLARE(#__name, sizeof(__struct)), \
|
|
\
|
|
GB_METHOD("_new", NULL, __name##_new, "[(X)" __sign "(Y)" __sign), \
|
|
GB_STATIC_METHOD("_call", #__name, __name##_call, "[(X)" __sign "(Y)" __sign), \
|
|
\
|
|
GB_PROPERTY("X", __sign, __name##_X), \
|
|
GB_PROPERTY("Y", __sign, __name##_Y), \
|
|
\
|
|
GB_METHOD("Copy", #__name, __name##_Copy, NULL), \
|
|
GB_METHOD("InRect", "b", __name##_InRect, "(Rectangle)" #__rname ";"), \
|
|
\
|
|
GB_INTERFACE("_operator", &_operator_##__name), \
|
|
GB_INTERFACE("_convert", &_convert_##__name), \
|
|
\
|
|
GB_END_DECLARE \
|
|
};
|
|
|