gambas-source-code/main/lib/draw/CDraw.c
Benoît Minisini 0a46a21588 [DEVELOPMENT ENVIRONMENT]
* BUG: Cannot clear all breakpoints while project is running.

[GB.DRAW]
* BUG: Remove useless Draw constants.

[GB.FORM]
* NEW: DirView.Renaming is a new property that returns if a directory is
  currently being renamed.
* BUG: DirChooser shortcuts are not active anymore when a directory is
  currently being renamed.

[GB.GTK]
* NEW: New arrangement properties behaviour: if the Padding property is not
  zero, then its value is the number of pixels used for container spacing 
  and margin. If Padding is zero, then spacing and margin is Desktop.Scale
  pixels.
* NEW: TreeView, ColumnView and ListView got a new Renaming property that
  returns if an item is currently being renamed.

[GB.QT4]
* NEW: New arrangement properties behaviour: if the Padding property is not
  zero, then its value is the number of pixels used for container spacing 
  and margin. If Padding is zero, then spacing and margin is Desktop.Scale
  pixels.
* NEW: TreeView, ColumnView and ListView got a new Renaming property that
  returns if an item is currently being renamed.


git-svn-id: svn://localhost/gambas/trunk@3638 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2011-03-06 00:21:43 +00:00

1306 lines
28 KiB
C

/***************************************************************************
CDraw.c
(c) 2000-2009 Benoît 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************************/
#define __CDRAW_C
#include "gb.image.h"
#include "matrix.h"
#include "main.h"
#include "crect.h"
#include "cpaint.h"
#include "CDraw.h"
static GB_DRAW *_current = NULL;
#define THIS _current
#define DRAW _current->desc
#define THIS_MATRIX ((MATRIX *)&(THIS->matrix))
#define CHECK_DEVICE() if (check_device()) return
static bool check_device()
{
if (!_current)
{
GB.Error("No current device");
return TRUE;
}
else
return FALSE;
}
GB_DRAW *DRAW_from_device(void *device)
{
GB_DRAW *d;
for (d = _current; d; d = d->previous)
{
if (d->device == device && d->opened)
break;
}
return d;
}
PUBLIC GB_DRAW *DRAW_get_current()
{
check_device();
return _current;
}
bool DRAW_open(GB_DRAW *draw)
{
if (draw->opened)
return FALSE;
//fprintf(stderr, "DRAW_open: %p\n", draw);
GB.Alloc(POINTER(&draw->extra), draw->desc->size);
memset(draw->extra, 0, draw->desc->size);
draw->opened = !draw->desc->Begin(draw);
return !draw->opened;
}
void DRAW_close(GB_DRAW *draw)
{
if (draw->opened)
{
//fprintf(stderr, "DRAW_close: %p\n", draw);
draw->desc->End(draw);
GB.Free(POINTER(&draw->extra));
draw->opened = FALSE;
}
}
bool DRAW_begin(void *device)
{
GB_DRAW_DESC *desc;
GB_DRAW *draw;
GB_CLASS klass;
GB_DRAW *other;
klass = GB.GetClass(device);
if (klass == GB.FindClass("Class"))
{
klass = (GB_CLASS)device;
desc = (GB_DRAW_DESC *)GB.GetClassInterface(klass, "StaticDraw");
}
else
{
desc = (GB_DRAW_DESC *)GB.GetClassInterface(klass, "Draw");
}
if (!desc)
{
GB.Error("Not a drawable object");
return TRUE;
}
GB.Alloc(POINTER(&draw), sizeof(GB_DRAW));
other = DRAW_from_device(device);
draw->desc = desc;
GB.Ref(device);
draw->device = device;
MATRIX_init(&draw->matrix);
draw->save = NULL;
draw->opened = FALSE;
draw->xform = FALSE;
draw->previous = _current;
_current = draw;
draw->paint = PAINT_from_device(device);
if (draw->paint)
PAINT_close(draw->paint);
if (other)
{
draw->extra = other->extra;
}
else
{
if (DRAW_open(draw))
return TRUE;
DRAW->SetBackground(draw, GB_DRAW_COLOR_DEFAULT);
DRAW->SetForeground(draw, GB_DRAW_COLOR_DEFAULT);
DRAW->Fill.SetColor(draw, GB_DRAW_COLOR_DEFAULT);
}
return FALSE;
}
void DRAW_end()
{
GB_DRAW *draw;
if (!_current)
return;
draw = _current;
_current = _current->previous;
DRAW_close(draw);
if (draw->paint)
PAINT_open(draw->paint);
GB.Unref(POINTER(&draw->device));
GB.Free(POINTER(&draw));
}
BEGIN_METHOD(CDRAW_begin, GB_OBJECT device)
void *device = VARG(device);
if (GB.CheckObject(device))
return;
DRAW_begin(device);
END_METHOD
BEGIN_METHOD_VOID(CDRAW_end)
DRAW_end();
END_METHOD
BEGIN_METHOD_VOID(CDRAW_exit)
while (_current)
DRAW_end();
END_METHOD
BEGIN_METHOD_VOID(CDRAW_save)
CHECK_DEVICE();
DRAW->Save(THIS);
END_METHOD
BEGIN_METHOD_VOID(CDRAW_restore)
CHECK_DEVICE();
DRAW->Restore(THIS);
END_METHOD
BEGIN_PROPERTY(CDRAW_device)
if (THIS)
GB.ReturnObject(THIS->device);
else
GB.ReturnNull();
END_PROPERTY
BEGIN_PROPERTY(CDRAW_width)
CHECK_DEVICE();
GB.ReturnInteger(THIS->width);
END_PROPERTY
BEGIN_PROPERTY(CDRAW_height)
CHECK_DEVICE();
GB.ReturnInteger(THIS->height);
END_PROPERTY
BEGIN_PROPERTY(CDRAW_resolution)
CHECK_DEVICE();
GB.ReturnInteger(THIS->resolution);
END_PROPERTY
static void handle_int_property(void *_param, int (*get)(GB_DRAW *), void (*set)(GB_DRAW *, int))
{
if (READ_PROPERTY)
GB.ReturnInteger((*get)(THIS));
else
(*set)(THIS, VPROP(GB_INTEGER));
}
BEGIN_PROPERTY(CDRAW_background)
CHECK_DEVICE();
handle_int_property(_param, DRAW->GetBackground, DRAW->SetBackground);
END_PROPERTY
BEGIN_PROPERTY(CDRAW_foreground)
CHECK_DEVICE();
handle_int_property(_param, DRAW->GetForeground, DRAW->SetForeground);
END_PROPERTY
BEGIN_PROPERTY(Draw_ClipRect)
CRECT *rect;
CHECK_DEVICE();
if (READ_PROPERTY)
{
if (!DRAW->Clip.IsEnabled(THIS))
{
GB.ReturnNull();
return;
}
rect = CRECT_create();
DRAW->Clip.Get(THIS, &rect->x, &rect->y, &rect->w, &rect->h);
GB.ReturnObject(rect);
}
else
{
rect = (CRECT *)VPROP(GB_OBJECT);
DRAW->Clip.SetEnabled(THIS, FALSE);
if (rect)
DRAW->Clip.Set(THIS, rect->x, rect->y, rect->w, rect->h);
}
END_PROPERTY
BEGIN_PROPERTY(CDRAW_clip_x)
int val;
CHECK_DEVICE();
DRAW->Clip.Get(THIS, &val, NULL, NULL, NULL);
GB.ReturnInteger(val);
END_PROPERTY
BEGIN_PROPERTY(CDRAW_clip_y)
int val;
CHECK_DEVICE();
DRAW->Clip.Get(THIS, NULL, &val, NULL, NULL);
GB.ReturnInteger(val);
END_PROPERTY
BEGIN_PROPERTY(CDRAW_clip_w)
int val;
CHECK_DEVICE();
DRAW->Clip.Get(THIS, NULL, NULL, &val, NULL);
GB.ReturnInteger(val);
END_PROPERTY
BEGIN_PROPERTY(CDRAW_clip_h)
int val;
CHECK_DEVICE();
DRAW->Clip.Get(THIS, NULL, NULL, NULL, &val);
GB.ReturnInteger(val);
END_PROPERTY
BEGIN_PROPERTY(CDRAW_clip_enabled)
CHECK_DEVICE();
if (READ_PROPERTY)
GB.ReturnBoolean(DRAW->Clip.IsEnabled(THIS));
else
DRAW->Clip.SetEnabled(THIS, VPROP(GB_BOOLEAN));
END_PROPERTY
BEGIN_METHOD(CDRAW_clip, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)
CHECK_DEVICE();
DRAW->Clip.Set(THIS, VARG(x), VARG(y), VARG(w), VARG(h));
END_PROPERTY
BEGIN_PROPERTY(CDRAW_invert)
CHECK_DEVICE();
if (READ_PROPERTY)
GB.ReturnBoolean(DRAW->IsInverted(THIS));
else
DRAW->SetInverted(THIS, VPROP(GB_BOOLEAN));
END_PROPERTY
BEGIN_PROPERTY(CDRAW_transparent)
CHECK_DEVICE();
if (READ_PROPERTY)
GB.ReturnBoolean(DRAW->IsTransparent(THIS));
else
DRAW->SetTransparent(THIS, VPROP(GB_BOOLEAN));
END_PROPERTY
BEGIN_PROPERTY(CDRAW_font)
CHECK_DEVICE();
if (READ_PROPERTY)
GB.ReturnObject(DRAW->GetFont(THIS));
else
DRAW->SetFont(THIS, VPROP(GB_OBJECT));
END_PROPERTY
BEGIN_PROPERTY(CDRAW_line_width)
CHECK_DEVICE();
handle_int_property(_param, DRAW->Line.GetWidth, DRAW->Line.SetWidth);
END_PROPERTY
BEGIN_PROPERTY(CDRAW_line_style)
CHECK_DEVICE();
handle_int_property(_param, DRAW->Line.GetStyle, DRAW->Line.SetStyle);
END_PROPERTY
BEGIN_PROPERTY(CDRAW_fill_color)
CHECK_DEVICE();
handle_int_property(_param, DRAW->Fill.GetColor, DRAW->Fill.SetColor);
END_PROPERTY
BEGIN_PROPERTY(CDRAW_fill_style)
CHECK_DEVICE();
handle_int_property(_param, DRAW->Fill.GetStyle, DRAW->Fill.SetStyle);
END_PROPERTY
BEGIN_PROPERTY(CDRAW_fill_x)
int x, y;
CHECK_DEVICE();
DRAW->Fill.GetOrigin(THIS, &x, &y);
if (READ_PROPERTY)
GB.ReturnInteger(x);
else
DRAW->Fill.SetOrigin(THIS, VPROP(GB_INTEGER), y);
END_PROPERTY
BEGIN_PROPERTY(CDRAW_fill_y)
int x, y;
CHECK_DEVICE();
DRAW->Fill.GetOrigin(THIS, &x, &y);
if (READ_PROPERTY)
GB.ReturnInteger(y);
else
DRAW->Fill.SetOrigin(THIS, x, VPROP(GB_INTEGER));
END_PROPERTY
BEGIN_METHOD(CDRAW_point, GB_INTEGER x; GB_INTEGER y)
int x, y;
CHECK_DEVICE();
x = VARG(x);
y = VARG(y);
if (THIS->xform)
MATRIX_map_point(THIS_MATRIX, &x, &y);
DRAW->Draw.Point(THIS, x, y);
END_METHOD
BEGIN_METHOD(CDRAW_line, GB_INTEGER x1; GB_INTEGER y1; GB_INTEGER x2; GB_INTEGER y2)
int x1, y1, x2, y2;
CHECK_DEVICE();
x1 = VARG(x1);
y1 = VARG(y1);
x2 = VARG(x2);
y2 = VARG(y2);
if (THIS->xform)
{
MATRIX_map_point(THIS_MATRIX, &x1, &y1);
MATRIX_map_point(THIS_MATRIX, &x2, &y2);
}
DRAW->Draw.Line(THIS, x1, y1, x2, y2);
END_METHOD
BEGIN_METHOD(CDRAW_rect, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)
int x, y, w, h;
CHECK_DEVICE();
x = VARG(x);
y = VARG(y);
w = VARG(w);
h = VARG(h);
if (w < 0)
x += w, w = (-w);
if (h < 0)
y += h, h = (-h);
if (THIS->xform)
MATRIX_map_rect(THIS_MATRIX, &x, &y, &w, &h);
if (w < 1 || h < 1)
return;
DRAW->Draw.Rect(THIS, x, y, w, h);
END_METHOD
BEGIN_METHOD(CDRAW_fill_rect, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_INTEGER color)
int x, y, w, h;
int fill_style, line_style, fill_color;
CHECK_DEVICE();
x = VARG(x);
y = VARG(y);
w = VARG(w);
h = VARG(h);
if (w < 0)
x += w, w = (-w);
if (h < 0)
y += h, h = (-h);
if (THIS->xform)
MATRIX_map_rect(THIS_MATRIX, &x, &y, &w, &h);
if (w < 1 || h < 1)
return;
line_style = DRAW->Line.GetStyle(THIS);
DRAW->Line.SetStyle(THIS, 0);
fill_style = DRAW->Fill.GetStyle(THIS);
DRAW->Fill.SetStyle(THIS, 1);
fill_color = DRAW->Fill.GetColor(THIS);
if (MISSING(color))
DRAW->Fill.SetColor(THIS, DRAW->GetBackground(THIS));
else
DRAW->Fill.SetColor(THIS, VARG(color));
DRAW->Draw.Rect(THIS, x, y, w, h);
DRAW->Line.SetStyle(THIS, line_style);
DRAW->Fill.SetStyle(THIS, fill_style);
DRAW->Fill.SetColor(THIS, fill_color);
END_METHOD
BEGIN_METHOD_VOID(CDRAW_clear)
int fill_style, line_style, fill_color, bg_color;
CHECK_DEVICE();
line_style = DRAW->Line.GetStyle(THIS);
DRAW->Line.SetStyle(THIS, 0);
fill_style = DRAW->Fill.GetStyle(THIS);
DRAW->Fill.SetStyle(THIS, 1);
bg_color = DRAW->GetBackground(THIS);
DRAW->SetBackground(THIS, GB_DRAW_COLOR_DEFAULT);
fill_color = DRAW->Fill.GetColor(THIS);
DRAW->Fill.SetColor(THIS, DRAW->GetBackground(THIS));
DRAW->Draw.Rect(THIS, 0, 0, THIS->width, THIS->height);
DRAW->Line.SetStyle(THIS, line_style);
DRAW->Fill.SetStyle(THIS, fill_style);
DRAW->SetBackground(THIS, bg_color);
DRAW->Fill.SetColor(THIS, fill_color);
END_METHOD
// BEGIN_METHOD(CDRAW_round_rect, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_FLOAT round)
//
// CHECK_DEVICE();
// DRAW->Draw.RoundRect(THIS, VARG(x), VARG(y), VARG(w), VARG(h), VARGOPT(round, 0.25));
//
// END_METHOD
BEGIN_METHOD(CDRAW_ellipse, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_FLOAT start; GB_FLOAT end)
int x, y, w, h;
CHECK_DEVICE();
x = VARG(x);
y = VARG(y);
w = VARG(w);
h = VARG(h);
if (THIS->xform)
MATRIX_map_rect(THIS_MATRIX, &x, &y, &w, &h);
if (w < 1 || h < 1)
return;
DRAW->Draw.Ellipse(THIS, x, y, w, h, VARGOPT(start, 0.0), VARGOPT(end, 0.0));
END_METHOD
BEGIN_METHOD(CDRAW_arc, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_FLOAT start; GB_FLOAT end)
int x, y, w, h;
CHECK_DEVICE();
x = VARG(x);
y = VARG(y);
w = VARG(w);
h = VARG(h);
if (THIS->xform)
MATRIX_map_rect(THIS_MATRIX, &x, &y, &w, &h);
if (w < 1 || h < 1)
return;
DRAW->Draw.Arc(THIS, x, y, w, h, VARGOPT(start, 0.0), VARGOPT(end, 0.0));
END_METHOD
BEGIN_METHOD(CDRAW_circle, GB_INTEGER x; GB_INTEGER y; GB_INTEGER radius; GB_FLOAT start; GB_FLOAT end)
int x, y, w, h;
int radius;
CHECK_DEVICE();
radius = VARG(radius);
if (radius <= 0)
return;
x = VARG(x) - radius + 1;
y = VARG(y) - radius + 1;
w = radius * 2 - 1;
h = radius * 2 - 1;
if (THIS->xform)
MATRIX_map_rect(THIS_MATRIX, &x, &y, &w, &h);
DRAW->Draw.Ellipse(THIS, x, y, w, h, VARGOPT(start, 0.0), VARGOPT(end, 0.0));
END_METHOD
BEGIN_METHOD(CDRAW_text, GB_STRING text; GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_INTEGER align)
int x, y, w, h;
CHECK_DEVICE();
x = VARG(x);
y = VARG(y);
w = VARGOPT(w, -1);
h = VARGOPT(h, -1);
if (THIS->xform)
{
if (w < 0 || h < 0)
MATRIX_map_point(THIS_MATRIX, &x, &y);
else
MATRIX_map_rect(THIS_MATRIX, &x, &y, &w, &h);
}
DRAW->Draw.Text(THIS, STRING(text), LENGTH(text), x, y, w, h, VARGOPT(align, GB_DRAW_ALIGN_DEFAULT));
END_METHOD
BEGIN_METHOD(CDRAW_text_width, GB_STRING text)
int w;
CHECK_DEVICE();
DRAW->Draw.TextSize(THIS, STRING(text), LENGTH(text), &w, NULL);
GB.ReturnInteger(w);
END_METHOD
BEGIN_METHOD(CDRAW_text_height, GB_STRING text)
int h;
CHECK_DEVICE();
DRAW->Draw.TextSize(THIS, STRING(text), LENGTH(text), NULL, &h);
GB.ReturnInteger(h);
END_METHOD
BEGIN_METHOD(CDRAW_rich_text, GB_STRING text; GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_INTEGER align)
int x, y, w, h;
CHECK_DEVICE();
x = VARG(x);
y = VARG(y);
w = VARGOPT(w, -1);
h = VARGOPT(h, -1);
if (THIS->xform)
{
if (w < 0 || h < 0)
MATRIX_map_point(THIS_MATRIX, &x, &y);
else
MATRIX_map_rect(THIS_MATRIX, &x, &y, &w, &h);
}
DRAW->Draw.RichText(THIS, STRING(text), LENGTH(text), x, y, w, h, VARGOPT(align, GB_DRAW_ALIGN_DEFAULT));
END_METHOD
BEGIN_METHOD(CDRAW_rich_text_width, GB_STRING text)
int w;
CHECK_DEVICE();
DRAW->Draw.RichTextSize(THIS, STRING(text), LENGTH(text), -1, &w, NULL);
GB.ReturnInteger(w);
END_METHOD
BEGIN_METHOD(CDRAW_rich_text_height, GB_STRING text; GB_INTEGER width)
int w = VARGOPT(width, -1);
int h;
CHECK_DEVICE();
DRAW->Draw.RichTextSize(THIS, STRING(text), LENGTH(text), w, NULL, &h);
GB.ReturnInteger(h);
END_METHOD
BEGIN_METHOD(CDRAW_polyline, GB_OBJECT points)
uint n;
GB_ARRAY points = VARG(points);
int *coord;
CHECK_DEVICE();
n = GB.Array.Count(points) / 2;
if (n == 0)
return;
coord = (int *)GB.Array.Get(points, 0);
if (THIS->xform)
coord = MATRIX_map_array(THIS_MATRIX, coord, n);
DRAW->Draw.Polyline(THIS, n, coord);
if (THIS->xform)
MATRIX_free_array(&coord);
END_METHOD
BEGIN_METHOD(CDRAW_polygon, GB_OBJECT points)
uint n;
GB_ARRAY points = VARG(points);
int *coord;
CHECK_DEVICE();
n = GB.Array.Count(points) / 2;
if (n == 0)
return;
coord = (int *)GB.Array.Get(points, 0);
if (THIS->xform)
coord = MATRIX_map_array(THIS_MATRIX, coord, n);
DRAW->Draw.Polygon(THIS, n, coord);
if (THIS->xform)
MATRIX_free_array(&coord);
END_METHOD
BEGIN_METHOD(CDRAW_picture, GB_OBJECT picture; GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_INTEGER sx; GB_INTEGER sy; GB_INTEGER sw; GB_INTEGER sh)
GB_PICTURE picture = VARG(picture);
GB_PICTURE_INFO info;
int x, y, w, h;
CHECK_DEVICE();
if (GB.CheckObject(picture))
return;
DRAW->GetPictureInfo(THIS, picture, &info);
x = VARGOPT(x, 0);
y = VARGOPT(y, 0);
w = VARGOPT(w, info.width);
h = VARGOPT(h, info.height);
w = VARGOPT(w, -1);
h = VARGOPT(h, -1);
if (THIS->xform)
MATRIX_map_rect(THIS_MATRIX, &x, &y, &w, &h);
DRAW->Draw.Picture(THIS, picture,
x, y, w, h,
VARGOPT(sx, 0), VARGOPT(sy, 0), VARGOPT(sw, -1), VARGOPT(sh, -1));
END_METHOD
BEGIN_METHOD(CDRAW_image, GB_OBJECT image; GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_INTEGER sx; GB_INTEGER sy; GB_INTEGER sw; GB_INTEGER sh)
GB_IMAGE image = VARG(image);
int x, y, w, h;
GB_IMG *info = (GB_IMG *)image;
CHECK_DEVICE();
if (GB.CheckObject(image))
return;
x = VARGOPT(x, 0);
y = VARGOPT(y, 0);
w = VARGOPT(w, info->width);
h = VARGOPT(h, info->height);
if (THIS->xform)
MATRIX_map_rect(THIS_MATRIX, &x, &y, &w, &h);
DRAW->Draw.Image(THIS, image,
x, y, w, h,
VARGOPT(sx, 0), VARGOPT(sy, 0), VARGOPT(sw, -1), VARGOPT(sh, -1));
END_METHOD
static uint blend_color(uint col, uint gray, uint alpha)
{
gray *= (0xFF - alpha);
return
((col & 0xFF) * alpha + gray) >> 8
| ((((col >> 8) & 0xFF) * alpha + gray) >> 8) << 8
| ((((col >> 16) & 0xFF) * alpha + gray) >> 8) << 16;
}
BEGIN_METHOD(CDRAW_zoom, GB_OBJECT image; GB_INTEGER zoom; GB_INTEGER x; GB_INTEGER y; GB_INTEGER sx; GB_INTEGER sy; GB_INTEGER sw; GB_INTEGER sh)
GB_IMAGE image = VARG(image);
GB_IMG *info = (GB_IMG *)image;
int zoom, size, size2;
int x, y, sx, sy, sw, sh;
int i, j, xr, yr;
uint col, col1, col2, last_col;
bool border;
int fill_style, fill_color;
uint a;
bool opaque;
CHECK_DEVICE();
if (GB.CheckObject(image))
return;
zoom = VARG(zoom);
if (zoom < 1)
{
GB.Error("Bad zoom factor");
return;
}
x = VARGOPT(x, 0);
y = VARGOPT(y, 0);
sx = VARGOPT(sx, 0);
sy = VARGOPT(sy, 0);
sw = VARGOPT(sw, info->width);
sh = VARGOPT(sh, info->height);
DRAW_NORMALIZE(x, y, sw, sh, sx, sy, sw, sh, info->width, info->height);
//DRAW->Fill.GetOrigin(THIS, &ox, &oy);
border = DRAW->Line.GetStyle(THIS);
if (zoom < 6 && !border)
{
DRAW->Fill.SetStyle(THIS, 1);
DRAW->Fill.SetColor(THIS, 0x979797);
DRAW->Draw.Rect(THIS, x, y, sw * zoom, sh * zoom);
DRAW->Draw.Image(THIS, image, x, y, sw * zoom, sh * zoom, sx, sy, sw, sh);
}
else
{
//IMAGE.Convert(info, GB_IMAGE_BGRA);
// May have to convert the image data
//if (info->format != GB_IMAGE_BGRA && info->format != GB_IMAGE_BGRX)
// GB.Alloc(POINTER(&conv), sw * sizeof(int));
size = zoom;
size2 = size / 2;
//if (border) size++;
fill_style = DRAW->Fill.GetStyle(THIS);
fill_color = DRAW->Fill.GetColor(THIS);
//last_style = -1;
//style = border;
last_col = 0;
col1 = 0;
col2 = 0;
a = 0xFF;
opaque = TRUE;
DRAW->Fill.SetStyle(THIS, 1); // FILL_SOLID
DRAW->Fill.SetColor(THIS, 0);
for (j = sy, yr = y; j < (sy + sh); j++, yr += zoom)
{
for (i = sx, xr = x; i < (sx + sw); i++, xr += zoom)
{
col = IMAGE.GetPixel(info, i, j);
if (col != last_col)
{
last_col = col;
a = (col >> 24) ^ 0xFF;
col &= 0xFFFFFF;
if (a < 0xFF)
{
if (a == 0)
{
col1 = 0x808080;
col2 = 0xC0C0C0;
}
else
{
col1 = blend_color(col, 0x80, a);
col2 = blend_color(col, 0xC0, a);
}
opaque = FALSE;
}
else
{
opaque = TRUE;
DRAW->Fill.SetColor(THIS, col);
}
}
if (opaque)
DRAW->Draw.Rect(THIS, xr, yr, size + 1, size + 1);
else
{
DRAW->Fill.SetColor(THIS, col1);
DRAW->Line.SetStyle(THIS, 0);
DRAW->Draw.Rect(THIS, xr, yr, size, size);
DRAW->Fill.SetColor(THIS, col2);
DRAW->Draw.Rect(THIS, xr + size2, yr, size - size2, size2);
DRAW->Draw.Rect(THIS, xr, yr + size2, size2, size - size2);
DRAW->Line.SetStyle(THIS, border);
if (border && a >= 16)
{
DRAW->Fill.SetStyle(THIS, 0);
DRAW->Draw.Rect(THIS, xr, yr, size + 1, size + 1);
DRAW->Fill.SetStyle(THIS, 1);
}
}
}
}
DRAW->Fill.SetStyle(THIS, fill_style);
DRAW->Fill.SetColor(THIS, fill_color);
}
END_METHOD
BEGIN_METHOD(CDRAW_tile, GB_OBJECT picture; GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)
int x, y, w, h;
GB_PICTURE picture = VARG(picture);
CHECK_DEVICE();
if (GB.CheckObject(picture))
return;
x = VARG(x);
y = VARG(y);
w = VARG(w);
h = VARG(h);
if (THIS->xform)
MATRIX_map_rect(THIS_MATRIX, &x, &y, &w, &h);
DRAW->Draw.TiledPicture(THIS, picture, x, y, w, h);
END_METHOD
BEGIN_METHOD_VOID(CDRAW_reset)
CHECK_DEVICE();
MATRIX_reset(THIS_MATRIX);
THIS->xform = FALSE;
END_METHOD
BEGIN_METHOD_VOID(CDRAW_push)
MATRIX *save;
CHECK_DEVICE();
GB.Alloc(POINTER(&save), sizeof(MATRIX));
*save = *THIS_MATRIX;
save->next = THIS->save;
THIS->save = save;
END_METHOD
BEGIN_METHOD_VOID(CDRAW_pop)
MATRIX *save;
CHECK_DEVICE();
if (!THIS->save)
{
MATRIX_reset(THIS_MATRIX);
return;
}
save = THIS->save;
THIS->save = save->next;
*THIS_MATRIX = *save;
GB.Free(POINTER(&save));
END_METHOD
BEGIN_METHOD(CDRAW_translate, GB_FLOAT dx; GB_FLOAT dy)
double dx = VARG(dx);
double dy = VARG(dy);
CHECK_DEVICE();
MATRIX_translate(THIS_MATRIX, dx, dy);
THIS->xform = !THIS->matrix.identity;
END_METHOD
BEGIN_METHOD(CDRAW_scale, GB_FLOAT dx; GB_FLOAT dy)
double dx = VARG(dx);
double dy = VARG(dy);
CHECK_DEVICE();
MATRIX_scale(THIS_MATRIX, dx, dy);
THIS->xform = !THIS->matrix.identity;
END_METHOD
// BEGIN_METHOD(CDRAW_rotate, GB_FLOAT a)
//
// double a = VARG(a);
//
// DP->rotate(a);
// if (DPM)
// DPM->rotate(a);
//
// END_METHOD
/****************************************************************************
Style API
****************************************************************************/
#define GET_COORD() \
int x, y, w, h; \
\
CHECK_DEVICE(); \
\
x = VARG(x); \
y = VARG(y); \
w = VARG(w); \
h = VARG(h); \
\
if (THIS->xform) \
MATRIX_map_rect(THIS_MATRIX, &x, &y, &w, &h); \
\
if (w < 1 || h < 1) \
return;
BEGIN_METHOD(CDRAW_style_arrow, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_INTEGER type; GB_INTEGER state)
GET_COORD();
DRAW->Style.Arrow(THIS, x, y, w, h, VARG(type), VARGOPT(state, GB_DRAW_STATE_NORMAL));
END_METHOD
BEGIN_METHOD(CDRAW_style_check, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_INTEGER value; GB_INTEGER state)
GET_COORD();
DRAW->Style.Check(THIS, x, y, w, h, VARG(value), VARGOPT(state, GB_DRAW_STATE_NORMAL));
END_METHOD
BEGIN_METHOD(CDRAW_style_option, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_BOOLEAN value; GB_INTEGER state)
GET_COORD();
DRAW->Style.Option(THIS, x, y, w, h, VARG(value), VARGOPT(state, GB_DRAW_STATE_NORMAL));
END_METHOD
BEGIN_METHOD(CDRAW_style_separator, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_BOOLEAN vertical; GB_INTEGER state)
GET_COORD();
DRAW->Style.Separator(THIS, x, y, w, h, VARGOPT(vertical, FALSE), VARGOPT(state, GB_DRAW_STATE_NORMAL));
END_METHOD
BEGIN_METHOD(CDRAW_style_button, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_BOOLEAN value; GB_INTEGER state; GB_BOOLEAN flat)
GET_COORD();
DRAW->Style.Button(THIS, x, y, w, h, VARG(value), VARGOPT(state, GB_DRAW_STATE_NORMAL), VARGOPT(flat, FALSE));
END_METHOD
BEGIN_METHOD(CDRAW_style_panel, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_INTEGER border; GB_INTEGER state)
GET_COORD();
DRAW->Style.Panel(THIS, x, y, w, h, VARG(border), VARGOPT(state, GB_DRAW_STATE_NORMAL));
END_METHOD
BEGIN_METHOD(CDRAW_style_handle, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_BOOLEAN vertical; GB_INTEGER state)
GET_COORD();
DRAW->Style.Handle(THIS, x, y, w, h, VARGOPT(vertical, FALSE), VARGOPT(state, GB_DRAW_STATE_NORMAL));
END_METHOD
BEGIN_METHOD(DrawStyle_Box, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_INTEGER state)
GET_COORD();
DRAW->Style.Box(THIS, x, y, w, h, VARGOPT(state, GB_DRAW_STATE_NORMAL));
END_METHOD
GB_DESC CDrawClipDesc[] =
{
GB_DECLARE(".Draw.Clip", 0), GB_VIRTUAL_CLASS(),
GB_STATIC_PROPERTY_READ("X", "i", CDRAW_clip_x),
GB_STATIC_PROPERTY_READ("Y", "i", CDRAW_clip_y),
GB_STATIC_PROPERTY_READ("W", "i", CDRAW_clip_w),
GB_STATIC_PROPERTY_READ("H", "i", CDRAW_clip_h),
GB_STATIC_PROPERTY_READ("Width", "i", CDRAW_clip_w),
GB_STATIC_PROPERTY_READ("Height", "i", CDRAW_clip_h),
GB_STATIC_PROPERTY("Enabled", "b", CDRAW_clip_enabled),
GB_STATIC_METHOD("_call", NULL, CDRAW_clip, "(X)i(Y)i(Width)i(Height)i"),
GB_END_DECLARE
};
GB_DESC CDrawStyleDesc[] =
{
GB_DECLARE(".Draw.Style", 0), GB_VIRTUAL_CLASS(),
GB_STATIC_METHOD("Arrow", NULL, CDRAW_style_arrow, "(X)i(Y)i(Width)i(Height)i(Type)i[(Flag)i]"),
GB_STATIC_METHOD("Check", NULL, CDRAW_style_check, "(X)i(Y)i(Width)i(Height)i(Value)i[(Flag)i]"),
GB_STATIC_METHOD("Option", NULL, CDRAW_style_option, "(X)i(Y)i(Width)i(Height)i(Value)b[(Flag)i]"),
GB_STATIC_METHOD("Separator", NULL, CDRAW_style_separator, "(X)i(Y)i(Width)i(Height)i[(Vertical)b(Flag)i]"),
GB_STATIC_METHOD("Button", NULL, CDRAW_style_button, "(X)i(Y)i(Width)i(Height)i(Value)b[(Flag)i(Flat)b]"),
GB_STATIC_METHOD("Panel", NULL, CDRAW_style_panel, "(X)i(Y)i(Width)i(Height)i(Border)i[(Flag)i]"),
GB_STATIC_METHOD("Handle", NULL, CDRAW_style_handle, "(X)i(Y)i(Width)i(Height)i[(Vertical)b(Flag)i]"),
GB_STATIC_METHOD("Box", NULL, DrawStyle_Box, "(X)i(Y)i(Width)i(Height)i[(Flag)i]"),
GB_END_DECLARE
};
GB_DESC CDrawDesc[] =
{
GB_DECLARE("Draw", 0), GB_VIRTUAL_CLASS(),
GB_STATIC_METHOD("_exit", NULL, CDRAW_exit, NULL),
GB_STATIC_METHOD("Begin", NULL, CDRAW_begin, "(Device)o"),
GB_STATIC_METHOD("End", NULL, CDRAW_end, NULL),
GB_STATIC_METHOD("Save", NULL, CDRAW_save, NULL),
GB_STATIC_METHOD("Restore", NULL, CDRAW_restore, NULL),
GB_STATIC_PROPERTY_READ("Device", "o", CDRAW_device),
GB_STATIC_PROPERTY_READ("W", "i", CDRAW_width),
GB_STATIC_PROPERTY_READ("H", "i", CDRAW_height),
GB_STATIC_PROPERTY_READ("Width", "i", CDRAW_width),
GB_STATIC_PROPERTY_READ("Height", "i", CDRAW_height),
GB_STATIC_PROPERTY_READ("Resolution", "i", CDRAW_resolution),
GB_STATIC_PROPERTY("ClipRect", "Rect", Draw_ClipRect),
GB_STATIC_PROPERTY_SELF("Clip", ".Draw.Clip"),
GB_STATIC_PROPERTY_SELF("Style", ".Draw.Style"),
GB_STATIC_PROPERTY("Background", "i", CDRAW_background),
GB_STATIC_PROPERTY("Foreground", "i", CDRAW_foreground),
//GB_STATIC_PROPERTY("BackColor", "i", CDRAW_background),
//GB_STATIC_PROPERTY("ForeColor", "i", CDRAW_foreground),
GB_STATIC_PROPERTY("Invert", "b", CDRAW_invert),
GB_STATIC_PROPERTY("Transparent", "b", CDRAW_transparent),
GB_STATIC_PROPERTY("Font", "Font", CDRAW_font),
GB_STATIC_PROPERTY("LineWidth", "i", CDRAW_line_width),
GB_STATIC_PROPERTY("LineStyle", "i", CDRAW_line_style),
GB_STATIC_PROPERTY("FillColor", "i", CDRAW_fill_color),
GB_STATIC_PROPERTY("FillStyle", "i", CDRAW_fill_style),
GB_STATIC_PROPERTY("FillX", "i", CDRAW_fill_x),
GB_STATIC_PROPERTY("FillY", "i", CDRAW_fill_y),
GB_STATIC_METHOD("Clear", NULL, CDRAW_clear, NULL),
GB_STATIC_METHOD("Point", NULL, CDRAW_point, "(X)i(Y)i"),
GB_STATIC_METHOD("Line", NULL, CDRAW_line, "(X1)i(Y1)i(X2)i(Y2)i"),
GB_STATIC_METHOD("Rect", NULL, CDRAW_rect, "(X)i(Y)i(Width)i(Height)i"),
GB_STATIC_METHOD("FillRect", NULL, CDRAW_fill_rect, "(X)i(Y)i(Width)i(Height)i[(Color)i]"),
//GB_STATIC_METHOD("RoundRect", NULL, CDRAW_round_rect, "(X)i(Y)i(Width)i(Height)i[(Round)f]"),
GB_STATIC_METHOD("Circle", NULL, CDRAW_circle, "(X)i(Y)i(Radius)i[(Start)f(End)f]"),
GB_STATIC_METHOD("Arc", NULL, CDRAW_arc, "(X)i(Y)i(Width)i(Height)i[(Start)f(End)f]"),
GB_STATIC_METHOD("Ellipse", NULL, CDRAW_ellipse, "(X)i(Y)i(Width)i(Height)i[(Start)f(End)f]"),
GB_STATIC_METHOD("Text", NULL, CDRAW_text, "(Text)s(X)i(Y)i[(Width)i(Height)i(Alignment)i)]"),
GB_STATIC_METHOD("TextWidth", "i", CDRAW_text_width, "(Text)s"),
GB_STATIC_METHOD("TextHeight", "i", CDRAW_text_height, "(Text)s"),
GB_STATIC_METHOD("RichText", NULL, CDRAW_rich_text, "(Text)s(X)i(Y)i[(Width)i(Height)i(Alignment)i)]"),
GB_STATIC_METHOD("RichTextWidth", "i", CDRAW_rich_text_width, "(Text)s"),
GB_STATIC_METHOD("RichTextHeight", "i", CDRAW_rich_text_height, "(Text)s[(Width)i]"),
GB_STATIC_METHOD("Polyline", NULL, CDRAW_polyline, "(Points)Integer[]"),
GB_STATIC_METHOD("Polygon", NULL, CDRAW_polygon, "(Points)Integer[]"),
GB_STATIC_METHOD("Picture", NULL, CDRAW_picture, "(Picture)Picture;(X)i(Y)i[(Width)i(Height)i(SrcX)i(SrcY)i(SrcWidth)i(SrcHeight)i]"),
GB_STATIC_METHOD("Tile", NULL, CDRAW_tile, "(Picture)Picture;(X)i(Y)i(Width)i(Height)i"),
GB_STATIC_METHOD("Image", NULL, CDRAW_image, "(Image)Image;(X)i(Y)i[(Width)i(Height)i(SrcX)i(SrcY)i(SrcWidth)i(SrcHeight)i]"),
GB_STATIC_METHOD("Zoom", NULL, CDRAW_zoom, "(Image)Image;(Zoom)i(X)i(Y)i[(SrcX)i(SrcY)i(SrcWidth)i(SrcHeight)i]"),
GB_STATIC_METHOD("Reset", NULL, CDRAW_reset, NULL),
GB_STATIC_METHOD("Push", NULL, CDRAW_push, NULL),
GB_STATIC_METHOD("Pop", NULL, CDRAW_pop, NULL),
GB_STATIC_METHOD("Translate", NULL, CDRAW_translate, "(DX)f(DY)f"),
GB_STATIC_METHOD("Scale", NULL, CDRAW_scale, "(SX)f(SY)f"),
GB_CONSTANT("Normal", "i", GB_DRAW_STATE_NORMAL),
GB_CONSTANT("Disabled", "i", GB_DRAW_STATE_DISABLED),
GB_CONSTANT("Focus", "i", GB_DRAW_STATE_FOCUS),
GB_CONSTANT("Hover", "i", GB_DRAW_STATE_HOVER),
//GB_CONSTANT("ToolButton", "i", GB_DRAW_STATE_TOOL_BUTTON),
#if 0
GB_STATIC_METHOD("Drawing", NULL, CDRAW_drawing, "(Drawing)Drawing;(X)i(Y)i[(Width)i(Height)i(SrcX)i(SrcY)i(SrcWidth)i(SrcHeight)i]"),
GB_STATIC_METHOD("Rotate", NULL, CDRAW_rotate, "(Angle)f"),
#endif
GB_END_DECLARE
};