2008-04-24 14:49:12 +02:00
|
|
|
/***************************************************************************
|
|
|
|
|
|
|
|
CImage.cpp
|
|
|
|
|
|
|
|
(c) 2000-2007 Benoit Minisini <gambas@users.sourceforge.net>
|
|
|
|
|
|
|
|
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 1, 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.
|
|
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#define __CIMAGE_CPP
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <qpixmap.h>
|
|
|
|
#include <qbitmap.h>
|
|
|
|
#include <qnamespace.h>
|
|
|
|
#include <qpainter.h>
|
|
|
|
#include <qmatrix.h>
|
|
|
|
|
|
|
|
#ifdef OS_SOLARIS
|
|
|
|
/* Make math.h define M_PI and a few other things */
|
|
|
|
#define __EXTENSIONS__
|
|
|
|
/* Get definition for finite() */
|
|
|
|
#include <ieeefp.h>
|
|
|
|
#endif
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include "gambas.h"
|
|
|
|
#include "main.h"
|
|
|
|
|
|
|
|
#include "CScreen.h"
|
|
|
|
#include "CPicture.h"
|
|
|
|
#include "CDraw.h"
|
|
|
|
#include "CImage.h"
|
|
|
|
|
|
|
|
const char *CIMAGE_get_format(QString path)
|
|
|
|
{
|
|
|
|
int pos;
|
|
|
|
|
2008-04-29 15:40:55 +02:00
|
|
|
pos = path.lastIndexOf('.');
|
2008-04-24 14:49:12 +02:00
|
|
|
if (pos < 0)
|
|
|
|
return NULL;
|
|
|
|
|
2008-04-29 15:40:55 +02:00
|
|
|
path = path.mid(pos + 1).toLower();
|
2008-04-24 14:49:12 +02:00
|
|
|
|
|
|
|
if (path == "png")
|
|
|
|
return "PNG";
|
|
|
|
else if (path == "jpg" || path == "jpeg")
|
|
|
|
return "JPEG";
|
|
|
|
else if (path == "gif")
|
|
|
|
return "GIF";
|
|
|
|
else if (path == "bmp")
|
|
|
|
return "BMP";
|
|
|
|
else if (path == "xpm")
|
|
|
|
return "XPM";
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
|
|
|
|
Image
|
|
|
|
|
|
|
|
*******************************************************************************/
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
static void free_image(GB_IMG *img, void *image)
|
|
|
|
{
|
|
|
|
delete (QImage *)image;
|
|
|
|
}
|
2008-04-24 14:49:12 +02:00
|
|
|
|
2009-01-22 01:47:14 +01:00
|
|
|
static void *temp_image(GB_IMG *img)
|
|
|
|
{
|
|
|
|
QImage *image;
|
|
|
|
|
|
|
|
if (!img->data)
|
|
|
|
image = new QImage();
|
|
|
|
else
|
|
|
|
image = new QImage((uchar *)img->data, img->width, img->height, QImage::Format_ARGB32);
|
|
|
|
image->setAlphaBuffer(true);
|
|
|
|
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
static GB_IMG_OWNER _image_owner = {
|
|
|
|
"gb.qt4",
|
2009-01-27 14:39:38 +01:00
|
|
|
GB_IMAGE_BGRA,
|
2009-01-17 00:12:10 +01:00
|
|
|
free_image,
|
2009-01-27 14:39:38 +01:00
|
|
|
free_image,
|
|
|
|
temp_image
|
2009-01-17 00:12:10 +01:00
|
|
|
};
|
2008-04-24 14:49:12 +02:00
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
QImage *CIMAGE_get(CIMAGE *_object)
|
|
|
|
{
|
2009-01-27 14:39:38 +01:00
|
|
|
return (QImage *)IMAGE.Check(THIS_IMAGE, &_image_owner);
|
2009-01-17 00:12:10 +01:00
|
|
|
}
|
2008-04-24 14:49:12 +02:00
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
#define check_image CIMAGE_get
|
2008-04-24 14:49:12 +02:00
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
static void take_image(CIMAGE *_object, QImage *image)
|
|
|
|
{
|
|
|
|
IMAGE.Take(THIS_IMAGE, &_image_owner, image, image->width(), image->height(), image->bits());
|
|
|
|
}
|
2008-04-24 14:49:12 +02:00
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
CIMAGE *CIMAGE_create(QImage *image)
|
|
|
|
{
|
|
|
|
CIMAGE *img;
|
|
|
|
static GB_CLASS class_id = NULL;
|
2008-04-24 14:49:12 +02:00
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
if (!class_id)
|
|
|
|
class_id = GB.FindClass("Image");
|
2008-04-24 14:49:12 +02:00
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
GB.New(POINTER(&img), class_id, NULL, NULL);
|
|
|
|
|
|
|
|
if (image)
|
|
|
|
take_image(img, image);
|
|
|
|
else
|
|
|
|
take_image(img, new QImage());
|
|
|
|
|
|
|
|
return img;
|
|
|
|
}
|
2008-04-24 14:49:12 +02:00
|
|
|
|
|
|
|
BEGIN_PROPERTY(CIMAGE_picture)
|
|
|
|
|
|
|
|
CPICTURE *pict;
|
2009-01-17 00:12:10 +01:00
|
|
|
|
|
|
|
check_image(THIS);
|
2008-04-24 14:49:12 +02:00
|
|
|
|
|
|
|
GB.New(POINTER(&pict), GB.FindClass("Picture"), NULL, NULL);
|
2009-01-17 00:12:10 +01:00
|
|
|
if (!QIMAGE->isNull())
|
|
|
|
*pict->pixmap = QPixmap::fromImage(*QIMAGE);
|
2008-04-24 14:49:12 +02:00
|
|
|
|
|
|
|
GB.ReturnObject(pict);
|
|
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_METHOD(CIMAGE_resize, GB_INTEGER width; GB_INTEGER height)
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
check_image(THIS);
|
|
|
|
|
|
|
|
if (QIMAGE->isNull())
|
2008-04-24 14:49:12 +02:00
|
|
|
{
|
2009-01-17 00:12:10 +01:00
|
|
|
take_image(THIS, new QImage(VARG(width), VARG(height), QImage::Format_ARGB32));
|
2008-04-24 14:49:12 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-01-17 00:12:10 +01:00
|
|
|
take_image(THIS, new QImage(QIMAGE->copy(0, 0, VARG(width), VARG(height))));
|
2008-04-24 14:49:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_METHOD(CIMAGE_load, GB_STRING path)
|
|
|
|
|
|
|
|
QImage *p;
|
|
|
|
CIMAGE *img;
|
|
|
|
|
|
|
|
if (CPICTURE_load_image(&p, STRING(path), LENGTH(path)))
|
|
|
|
{
|
2008-04-29 15:40:55 +02:00
|
|
|
p->convertToFormat(QImage::Format_ARGB32);
|
2009-01-17 00:12:10 +01:00
|
|
|
img = CIMAGE_create(p);
|
2008-04-24 14:49:12 +02:00
|
|
|
GB.ReturnObject(img);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
GB.Error("Unable to load image");
|
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_METHOD(CIMAGE_save, GB_STRING path; GB_INTEGER quality)
|
|
|
|
|
|
|
|
QString path = TO_QSTRING(GB.FileName(STRING(path), LENGTH(path)));
|
|
|
|
bool ok = false;
|
|
|
|
const char *fmt = CIMAGE_get_format(path);
|
|
|
|
|
|
|
|
if (!fmt)
|
|
|
|
{
|
|
|
|
GB.Error("Unknown format");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
ok = QIMAGE->save(path, fmt, VARGOPT(quality, -1));
|
2008-04-24 14:49:12 +02:00
|
|
|
|
|
|
|
if (!ok)
|
|
|
|
GB.Error("Unable to save picture");
|
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_METHOD(CIMAGE_copy, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
check_image(THIS);
|
|
|
|
|
2008-04-24 14:49:12 +02:00
|
|
|
int x = VARGOPT(x, 0);
|
|
|
|
int y = VARGOPT(y, 0);
|
2009-01-17 00:12:10 +01:00
|
|
|
int w = VARGOPT(w, QIMAGE->width());
|
|
|
|
int h = VARGOPT(h, QIMAGE->height());
|
|
|
|
QImage *copy = new QImage();
|
2008-04-24 14:49:12 +02:00
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
*copy = QIMAGE->copy(x, y, w, h);
|
|
|
|
GB.ReturnObject(CIMAGE_create(copy));
|
2008-04-24 14:49:12 +02:00
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_METHOD(CIMAGE_stretch, GB_INTEGER width; GB_INTEGER height; GB_BOOLEAN smooth)
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
QImage *stretch;
|
2008-04-24 14:49:12 +02:00
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
check_image(THIS);
|
2008-04-24 14:49:12 +02:00
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
if (QIMAGE->isNull())
|
2008-04-24 14:49:12 +02:00
|
|
|
{
|
2009-01-17 00:12:10 +01:00
|
|
|
stretch = new QImage(VARG(width), VARG(height), QImage::Format_ARGB32);
|
2008-04-24 14:49:12 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-01-17 00:12:10 +01:00
|
|
|
stretch = new QImage();
|
2008-04-24 14:49:12 +02:00
|
|
|
if (VARGOPT(smooth, TRUE))
|
2009-01-17 00:12:10 +01:00
|
|
|
*stretch = QIMAGE->scaled(VARG(width), VARG(height), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
2008-04-24 14:49:12 +02:00
|
|
|
else
|
2009-01-17 00:12:10 +01:00
|
|
|
*stretch = QIMAGE->scaled(VARG(width), VARG(height));
|
2008-04-24 14:49:12 +02:00
|
|
|
}
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
GB.ReturnObject(CIMAGE_create(stretch));
|
2008-04-24 14:49:12 +02:00
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_METHOD_VOID(CIMAGE_flip)
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
QImage *mirror = new QImage();
|
|
|
|
|
|
|
|
check_image(THIS);
|
|
|
|
*mirror = QIMAGE->mirrored(true, false);
|
|
|
|
|
|
|
|
GB.ReturnObject(CIMAGE_create(mirror));
|
2008-04-24 14:49:12 +02:00
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_METHOD_VOID(CIMAGE_mirror)
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
QImage *mirror = new QImage();
|
|
|
|
|
|
|
|
check_image(THIS);
|
|
|
|
*mirror = QIMAGE->mirrored(false, true);
|
|
|
|
|
|
|
|
GB.ReturnObject(CIMAGE_create(mirror));
|
2008-04-24 14:49:12 +02:00
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_METHOD(CIMAGE_rotate, GB_FLOAT angle)
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
QImage *rotate = new QImage();
|
2008-04-24 14:49:12 +02:00
|
|
|
QMatrix mat;
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
check_image(THIS);
|
2008-04-24 14:49:12 +02:00
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
mat.rotate(VARG(angle) * -360.0 / 2 / M_PI);
|
|
|
|
*rotate = QIMAGE->transformed(mat);
|
|
|
|
GB.ReturnObject(CIMAGE_create(rotate));
|
2008-04-24 14:49:12 +02:00
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_METHOD(CIMAGE_draw, GB_OBJECT img; GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_INTEGER sx; GB_INTEGER sy; GB_INTEGER sw; GB_INTEGER sh)
|
|
|
|
|
|
|
|
int x, y, w, h, sx, sy, sw, sh;
|
|
|
|
CIMAGE *image = (CIMAGE *)VARG(img);
|
2009-01-17 00:12:10 +01:00
|
|
|
QImage *src, *dst;
|
2008-04-24 14:49:12 +02:00
|
|
|
double scale_x, scale_y;
|
|
|
|
|
|
|
|
if (GB.CheckObject(image))
|
|
|
|
return;
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
src = check_image(image);
|
|
|
|
dst = check_image(THIS);
|
2008-04-24 14:49:12 +02:00
|
|
|
|
|
|
|
x = VARGOPT(x, 0);
|
|
|
|
y = VARGOPT(y, 0);
|
|
|
|
w = VARGOPT(w, -1);
|
|
|
|
h = VARGOPT(h, -1);
|
|
|
|
|
|
|
|
sx = VARGOPT(sx, 0);
|
|
|
|
sy = VARGOPT(sy, 0);
|
2009-01-17 00:12:10 +01:00
|
|
|
sw = VARGOPT(sw, src->width());
|
|
|
|
sh = VARGOPT(sh, src->height());
|
2008-04-24 14:49:12 +02:00
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
DRAW_NORMALIZE(x, y, w, h, sx, sy, sw, sh, src->width(), src->height());
|
2008-04-24 14:49:12 +02:00
|
|
|
|
|
|
|
if (w != sw || h != sh)
|
|
|
|
{
|
2009-01-17 00:12:10 +01:00
|
|
|
QImage tmp;
|
|
|
|
|
2008-04-24 14:49:12 +02:00
|
|
|
scale_x = (double)w / sw;
|
|
|
|
scale_y = (double)h / sh;
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
tmp = src->scaled((int)(src->width() * scale_x + 0.5), (int)(src->height() * scale_y + 0.5), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
2008-04-24 14:49:12 +02:00
|
|
|
sx = (int)(sx * scale_x + 0.5);
|
|
|
|
sy = (int)(sy * scale_y + 0.5);
|
|
|
|
sw = w;
|
|
|
|
sh = h;
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
QPainter p(dst);
|
|
|
|
p.drawImage(x, y, tmp, sx, sy, sw, sh);
|
|
|
|
p.end();
|
|
|
|
}
|
|
|
|
else
|
2008-04-24 14:49:12 +02:00
|
|
|
{
|
2009-01-17 00:12:10 +01:00
|
|
|
QPainter p(dst);
|
|
|
|
p.drawImage(x, y, *src, sx, sy, sw, sh);
|
|
|
|
p.end();
|
2008-04-24 14:49:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
// Comes from the GIMP
|
|
|
|
|
|
|
|
typedef
|
|
|
|
struct {
|
|
|
|
float r;
|
|
|
|
float b;
|
|
|
|
float g;
|
|
|
|
float a;
|
|
|
|
}
|
|
|
|
RGB;
|
|
|
|
|
|
|
|
static void color_to_alpha(RGB *src, const RGB *color)
|
|
|
|
{
|
|
|
|
RGB alpha;
|
|
|
|
|
|
|
|
alpha.a = src->a;
|
|
|
|
|
|
|
|
if (color->r < 0.0001)
|
|
|
|
alpha.r = src->r;
|
|
|
|
else if (src->r > color->r)
|
|
|
|
alpha.r = (src->r - color->r) / (1.0 - color->r);
|
|
|
|
else if (src->r < color->r)
|
|
|
|
alpha.r = (color->r - src->r) / color->r;
|
|
|
|
else alpha.r = 0.0;
|
|
|
|
|
|
|
|
if (color->g < 0.0001)
|
|
|
|
alpha.g = src->g;
|
|
|
|
else if (src->g > color->g)
|
|
|
|
alpha.g = (src->g - color->g) / (1.0 - color->g);
|
|
|
|
else if (src->g < color->g)
|
|
|
|
alpha.g = (color->g - src->g) / (color->g);
|
|
|
|
else alpha.g = 0.0;
|
|
|
|
|
|
|
|
if (color->b < 0.0001)
|
|
|
|
alpha.b = src->b;
|
|
|
|
else if (src->b > color->b)
|
|
|
|
alpha.b = (src->b - color->b) / (1.0 - color->b);
|
|
|
|
else if (src->b < color->b)
|
|
|
|
alpha.b = (color->b - src->b) / (color->b);
|
|
|
|
else alpha.b = 0.0;
|
|
|
|
|
|
|
|
if (alpha.r > alpha.g)
|
|
|
|
{
|
|
|
|
if (alpha.r > alpha.b)
|
|
|
|
{
|
|
|
|
src->a = alpha.r;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
src->a = alpha.b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (alpha.g > alpha.b)
|
|
|
|
{
|
|
|
|
src->a = alpha.g;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
src->a = alpha.b;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src->a < 0.0001)
|
|
|
|
return;
|
|
|
|
|
|
|
|
src->r = (src->r - color->r) / src->a + color->r;
|
|
|
|
src->g = (src->g - color->g) / src->a + color->g;
|
|
|
|
src->b = (src->b - color->b) / src->a + color->b;
|
|
|
|
|
|
|
|
src->a *= alpha.a;
|
|
|
|
}
|
|
|
|
|
|
|
|
BEGIN_METHOD(CIMAGE_make_transparent, GB_INTEGER color)
|
|
|
|
|
2009-01-17 00:12:10 +01:00
|
|
|
QImage *img = check_image(THIS);
|
2008-04-24 14:49:12 +02:00
|
|
|
uchar *b = img->bits();
|
|
|
|
uchar *g = b + 1;
|
|
|
|
uchar *r = b + 2;
|
|
|
|
uchar *a = b + 3;
|
|
|
|
uchar *end = img->bits() + img->numBytes();
|
|
|
|
uint color = VARGOPT(color, 0xFFFFFFL);
|
|
|
|
RGB rgb_color;
|
|
|
|
RGB rgb_src;
|
|
|
|
|
|
|
|
rgb_color.b = (color & 0xFF) / 255.0;
|
|
|
|
rgb_color.g = ((color >> 8) & 0xFF) / 255.0;
|
|
|
|
rgb_color.r = ((color >> 16) & 0xFF) / 255.0;
|
|
|
|
rgb_color.a = 1.0;
|
|
|
|
|
|
|
|
while (b != end)
|
|
|
|
{
|
|
|
|
rgb_src.b = *b / 255.0;
|
|
|
|
rgb_src.g = *g / 255.0;
|
|
|
|
rgb_src.r = *r / 255.0;
|
|
|
|
rgb_src.a = *a / 255.0;
|
|
|
|
|
|
|
|
color_to_alpha(&rgb_src, &rgb_color);
|
|
|
|
|
|
|
|
*b = 255.0 * rgb_src.b + 0.5;
|
|
|
|
*g = 255.0 * rgb_src.g + 0.5;
|
|
|
|
*r = 255.0 * rgb_src.r + 0.5;
|
|
|
|
*a = 255.0 * rgb_src.a + 0.5;
|
|
|
|
|
|
|
|
b += 4;
|
|
|
|
g += 4;
|
|
|
|
r += 4;
|
|
|
|
a += 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GB_DESC CImageDesc[] =
|
|
|
|
{
|
|
|
|
GB_DECLARE("Image", sizeof(CIMAGE)),
|
|
|
|
|
|
|
|
GB_STATIC_METHOD("Load", "Image", CIMAGE_load, "(Path)s"),
|
|
|
|
GB_METHOD("Save", NULL, CIMAGE_save, "(Path)s[(Quality)i]"),
|
|
|
|
GB_METHOD("Resize", NULL, CIMAGE_resize, "(Width)i(Height)i"),
|
|
|
|
|
|
|
|
GB_METHOD("MakeTransparent", NULL, CIMAGE_make_transparent, "[(Color)i]"),
|
|
|
|
|
|
|
|
GB_METHOD("Copy", "Image", CIMAGE_copy, "[(X)i(Y)i(Width)i(Height)i]"),
|
|
|
|
GB_METHOD("Stretch", "Image", CIMAGE_stretch, "(Width)i(Height)i[(Smooth)b]"),
|
|
|
|
GB_METHOD("Flip", "Image", CIMAGE_flip, NULL),
|
|
|
|
GB_METHOD("Mirror", "Image", CIMAGE_mirror, NULL),
|
|
|
|
GB_METHOD("Rotate", "Image", CIMAGE_rotate, "(Angle)f"),
|
|
|
|
|
|
|
|
GB_METHOD("Draw", NULL, CIMAGE_draw, "(Image)Image;(X)i(Y)i[(Width)i(Height)i(SrcX)i(SrcY)i(SrcWidth)i(SrcHeight)i]"),
|
|
|
|
|
|
|
|
GB_PROPERTY_READ("Picture", "Picture", CIMAGE_picture),
|
|
|
|
|
|
|
|
GB_END_DECLARE
|
|
|
|
};
|
|
|
|
|