From 774baa91f6a724d5ec00f3c192dc3b881ab4764a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Mon, 28 Dec 2009 01:19:27 +0000 Subject: [PATCH] [DEVELOPMENT ENVIRONMENT] * NEW: Do not apply the new DrawingArea.Painted property. [GB.DRAW] * NEW: The new Paint interface is now completed. Only its text part is rudimentary at the moment. [GB.QT4] * NEW: The Paint interface has been implemented on the following classes: Picture, Image, DrawingArea. * NEW: DrawingArea.Painted is a new property. When set, the Paint interface must be used inside the Draw event, instead of the old Draw interface. git-svn-id: svn://localhost/gambas/trunk@2530 867c0c6c-44f3-4631-809d-bfa615b0a4ec --- .../.src/Component/CPropertyInfo.class | 1 + gb.qt/share/gb.form.properties.h | 2 +- gb.qt4/gb.paint.h | 1 + gb.qt4/src/CClipboard.cpp | 10 - gb.qt4/src/CColor.cpp | 11 +- gb.qt4/src/CColor.h | 2 + gb.qt4/src/CDraw.cpp | 4 +- gb.qt4/src/CDraw.h | 1 + gb.qt4/src/CDrawingArea.cpp | 41 +- gb.qt4/src/CDrawingArea.h | 4 + gb.qt4/src/CImage.cpp | 4 +- gb.qt4/src/CPicture.cpp | 2 + gb.qt4/src/CPictureBox.cpp | 1 + gb.qt4/src/CWidget.cpp | 1 + gb.qt4/src/CWidget.h | 1 + gb.qt4/src/Makefile.am | 1 + gb.qt4/src/gb.qt.h | 26 +- gb.qt4/src/main.cpp | 1 + main/lib/draw/cpaint.c | 457 +++++++++++++----- main/lib/draw/cpaint.h | 1 + main/lib/draw/gb.draw.h | 7 +- main/lib/draw/gb.paint.h | 69 ++- main/lib/draw/main.c | 7 + 23 files changed, 467 insertions(+), 188 deletions(-) create mode 120000 gb.qt4/gb.paint.h diff --git a/app/src/gambas3/.src/Component/CPropertyInfo.class b/app/src/gambas3/.src/Component/CPropertyInfo.class index 50a9fb943..1da1ae005 100644 --- a/app/src/gambas3/.src/Component/CPropertyInfo.class +++ b/app/src/gambas3/.src/Component/CPropertyInfo.class @@ -72,6 +72,7 @@ Static Public Sub _init() $cRedirect["Menu.Enabled"] = True $cRedirect["Menu.Shortcut"] = True $cRedirect["DrawingArea.Cached"] = True + $cRedirect["DrawingArea.Painted"] = True $cRedirect["Timer.Enabled"] = True $cRedirect["WebView.Cached"] = True diff --git a/gb.qt/share/gb.form.properties.h b/gb.qt/share/gb.form.properties.h index 65075ed77..2c0f02a34 100644 --- a/gb.qt/share/gb.form.properties.h +++ b/gb.qt/share/gb.form.properties.h @@ -51,7 +51,7 @@ #define CCHECKBOX_PROPERTIES "*,Action,Text,Tristate,Value{CheckBox.False;True;None}" #define CRADIOBUTTON_PROPERTIES "*,Text,Value" #define CSPINBOX_PROPERTIES "*,Action,MinValue=0,MaxValue=100,Step=1,Wrap,Value,Border=True" -#define CDRAWINGAREA_PROPERTIES "*,Cached,Tracking,Focus,Merge,Border{Border.*}" +#define CDRAWINGAREA_PROPERTIES "*,Cached,Painted,Tracking,Focus,Merge,Border{Border.*}" #define CTREEVIEW_PROPERTIES "*,Mode{Select.*}=Single,Sorted,Editable,Border=True,ScrollBar{Scroll.*}=Both" #define CLISTVIEW_PROPERTIES "*,Mode{Select.*}=Single,Sorted,Editable,Border=True,ScrollBar{Scroll.*}=Both" #define CCOLUMNVIEW_PROPERTIES "*,Mode{Select.*}=Single,Sorted,Editable,Header=True,Resizable=False,AutoResize=True,Border=True,ScrollBar{Scroll.*}=Both" diff --git a/gb.qt4/gb.paint.h b/gb.qt4/gb.paint.h new file mode 120000 index 000000000..a516fe05c --- /dev/null +++ b/gb.qt4/gb.paint.h @@ -0,0 +1 @@ +../main/lib/draw/gb.paint.h \ No newline at end of file diff --git a/gb.qt4/src/CClipboard.cpp b/gb.qt4/src/CClipboard.cpp index d9398e3a3..b62b56068 100644 --- a/gb.qt4/src/CClipboard.cpp +++ b/gb.qt4/src/CClipboard.cpp @@ -45,8 +45,6 @@ CDRAG_INFO CDRAG_info = { 0 }; bool CDRAG_dragging = false; void *CDRAG_destination = 0; -static GB_CLASS CLASS_Image; - static CPICTURE *_picture = 0; static int _picture_x = -1; static int _picture_y = -1; @@ -149,12 +147,6 @@ static void paste(const QMimeData *data, const char *fmt) ***************************************************************************/ -BEGIN_METHOD_VOID(CCLIPBOARD_init) - - CLASS_Image = GB.FindClass("Image"); - -END_METHOD - BEGIN_METHOD_VOID(CCLIPBOARD_clear) QApplication::clipboard()->clear(); @@ -245,8 +237,6 @@ GB_DESC CClipboardDesc[] = GB_CONSTANT("Text", "i", 1), GB_CONSTANT("Image", "i", 2), - GB_STATIC_METHOD("_init", NULL, CCLIPBOARD_init, NULL), - GB_STATIC_METHOD("Clear", NULL, CCLIPBOARD_clear, NULL), GB_STATIC_PROPERTY_READ("Format", "s", CCLIPBOARD_format), diff --git a/gb.qt4/src/CColor.cpp b/gb.qt4/src/CColor.cpp index ba7cd922f..cf3304baf 100644 --- a/gb.qt4/src/CColor.cpp +++ b/gb.qt4/src/CColor.cpp @@ -27,7 +27,6 @@ #include #include "gambas.h" -#include "gb.image.h" #include "CWidget.h" #include "CColor.h" @@ -41,6 +40,16 @@ QColor CCOLOR_merge(const QColor &colorA, const QColor &colorB, int factor) return QColor(IMAGE.MergeColor(colorA.rgba(), colorB.rgba(), factor / 100.0)); } +QColor CCOLOR_make(GB_COLOR color) +{ + int b = color & 0xFF; + int g = (color >> 8) & 0xFF; + int r = (color >> 16) & 0xFF; + int a = (color >> 24) ^ 0xFF; + + return QColor(r, g, b, a); +} + static void get_hsv(int col) { static int last = 0; diff --git a/gb.qt4/src/CColor.h b/gb.qt4/src/CColor.h index 75962ac3b..ba06c365a 100644 --- a/gb.qt4/src/CColor.h +++ b/gb.qt4/src/CColor.h @@ -24,11 +24,13 @@ #define __CCOLOR_H #include "gambas.h" +#include "gb.image.h" #ifndef __CCOLOR_CPP extern GB_DESC CColorDesc[]; #endif QColor CCOLOR_merge(const QColor &colorA, const QColor &colorB, int factor = 50); +QColor CCOLOR_make(GB_COLOR color); #endif diff --git a/gb.qt4/src/CDraw.cpp b/gb.qt4/src/CDraw.cpp index b15819d27..b2c5f6174 100644 --- a/gb.qt4/src/CDraw.cpp +++ b/gb.qt4/src/CDraw.cpp @@ -339,12 +339,12 @@ static void set_font(GB_DRAW *d, GB_FONT font) static int is_inverted(GB_DRAW *d) { - return DP(d)->compositionMode() == QPainter::CompositionMode_Xor; + return DP(d)->compositionMode() == QPainter::RasterOp_SourceXorDestination; //QPainter::CompositionMode_Xor; } static void set_inverted(GB_DRAW *d, int inverted) { - DP(d)->setCompositionMode(inverted ? QPainter::CompositionMode_Xor : QPainter::CompositionMode_SourceOver); + DP(d)->setCompositionMode(inverted ? QPainter::RasterOp_SourceXorDestination : QPainter::CompositionMode_SourceOver); } static int is_transparent(GB_DRAW *d) diff --git a/gb.qt4/src/CDraw.h b/gb.qt4/src/CDraw.h index 24bd616c6..61fff83e2 100644 --- a/gb.qt4/src/CDraw.h +++ b/gb.qt4/src/CDraw.h @@ -32,6 +32,7 @@ #ifndef __CDRAW_C extern GB_DRAW_DESC DRAW_Interface; +extern DRAW_INTERFACE DRAW; #endif diff --git a/gb.qt4/src/CDrawingArea.cpp b/gb.qt4/src/CDrawingArea.cpp index e23c537ac..b64113a6e 100644 --- a/gb.qt4/src/CDrawingArea.cpp +++ b/gb.qt4/src/CDrawingArea.cpp @@ -28,6 +28,7 @@ #include #include "CDraw.h" +#include "cpaint_impl.h" #include "CDrawingArea.h" #ifndef NO_X_WINDOW @@ -51,6 +52,7 @@ MyDrawingArea::MyDrawingArea(QWidget *parent) : MyContainer(parent) _background = 0; _frozen = false; _event_mask = 0; + _use_paint = false; setMerge(false); setCached(false); setBackground(); @@ -159,10 +161,18 @@ void MyDrawingArea::paintEvent(QPaintEvent *event) //status = DRAW_status(); //DRAW_begin(NULL, p, width(), height()); - DRAW_begin(object); - - p = DRAW_get_current(); + if (_use_paint) + { + PAINT_begin(object); + p = PAINT_get_current(); + } + else + { + DRAW_begin(object); + p = DRAW_get_current(); + } + p->translate(-r.x(), -r.y()); p->setClipRect(r); //p->setClipRegion(event->region().intersect(contentsRect())); @@ -170,9 +180,9 @@ void MyDrawingArea::paintEvent(QPaintEvent *event) if (frame) p->save(); - //qDebug("MyDrawingArea::paintEvent %p", CWidget::get(this)); - GB.Raise(object, EVENT_draw, 0); + GB.Raise(object, EVENT_draw, 0); + if (!contentsRect().contains(event->rect())) { p->restore(); @@ -180,12 +190,11 @@ void MyDrawingArea::paintEvent(QPaintEvent *event) p->setRenderHint(QPainter::Antialiasing, false); drawFrame(p); } - - //DRAW_restore(status); - DRAW_end(); - //delete p; - - //paint.setClipRegion( event->region().intersect( contentsRect() ) ); + + if (_use_paint) + PAINT_end(); + else + DRAW_end(); paint.drawPixmap(r.x(), r.y(), *cache); delete cache; @@ -399,6 +408,14 @@ BEGIN_PROPERTY(CDRAWINGAREA_focus) END_PROPERTY +BEGIN_PROPERTY(CDRAWINGAREA_paint) + + if (READ_PROPERTY) + GB.ReturnBoolean(WIDGET->isPaint()); + else + WIDGET->setPaint(VPROP(GB_BOOLEAN)); + +END_PROPERTY GB_DESC CDrawingAreaDesc[] = { @@ -414,12 +431,14 @@ GB_DESC CDrawingAreaDesc[] = GB_PROPERTY("Focus", "b", CDRAWINGAREA_focus), GB_PROPERTY("Enabled", "b", CDRAWINGAREA_enabled), + GB_PROPERTY("Painted", "b", CDRAWINGAREA_paint), GB_METHOD("Clear", NULL, CDRAWINGAREA_clear, NULL), GB_EVENT("Draw", NULL, NULL, &EVENT_draw), GB_INTERFACE("Draw", &DRAW_Interface), + GB_INTERFACE("Paint", &PAINT_Interface), DRAWINGAREA_DESCRIPTION, diff --git a/gb.qt4/src/CDrawingArea.h b/gb.qt4/src/CDrawingArea.h index 36aead85d..c61018189 100644 --- a/gb.qt4/src/CDrawingArea.h +++ b/gb.qt4/src/CDrawingArea.h @@ -83,6 +83,9 @@ public: void setAllowFocus(bool f); bool isAllowFocus() { return focusPolicy() != Qt::NoFocus; } + + bool isPaint() { return _use_paint; } + void setPaint(bool on) { _use_paint = on; } protected: @@ -98,6 +101,7 @@ private: bool _merge; bool _focus; int _event_mask; + bool _use_paint; bool doResize(); }; diff --git a/gb.qt4/src/CImage.cpp b/gb.qt4/src/CImage.cpp index b39a4406d..57e3fc3e4 100644 --- a/gb.qt4/src/CImage.cpp +++ b/gb.qt4/src/CImage.cpp @@ -44,6 +44,7 @@ #include "CScreen.h" #include "CPicture.h" #include "CDraw.h" +#include "cpaint_impl.h" #include "CImage.h" const char *CIMAGE_get_format(QString path) @@ -335,7 +336,8 @@ GB_DESC CImageDesc[] = 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_INTERFACE("Paint", &PAINT_Interface), + GB_END_DECLARE }; diff --git a/gb.qt4/src/CPicture.cpp b/gb.qt4/src/CPicture.cpp index 39a3a4afd..cbb485808 100644 --- a/gb.qt4/src/CPicture.cpp +++ b/gb.qt4/src/CPicture.cpp @@ -36,6 +36,7 @@ #include "main.h" #include "CDraw.h" +#include "cpaint_impl.h" #include "CScreen.h" #include "CImage.h" #include "CPicture.h" @@ -415,6 +416,7 @@ GB_DESC CPictureDesc[] = GB_PROPERTY_READ("Image", "Image", CPICTURE_image), GB_INTERFACE("Draw", &DRAW_Interface), + GB_INTERFACE("Paint", &PAINT_Interface), GB_END_DECLARE }; diff --git a/gb.qt4/src/CPictureBox.cpp b/gb.qt4/src/CPictureBox.cpp index 9bba68dc5..7ad89fff6 100644 --- a/gb.qt4/src/CPictureBox.cpp +++ b/gb.qt4/src/CPictureBox.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "gambas.h" diff --git a/gb.qt4/src/CWidget.cpp b/gb.qt4/src/CWidget.cpp index ea99e9dc7..1ce3e8b98 100644 --- a/gb.qt4/src/CWidget.cpp +++ b/gb.qt4/src/CWidget.cpp @@ -71,6 +71,7 @@ GB_CLASS CLASS_Drawing; GB_CLASS CLASS_DrawingArea; GB_CLASS CLASS_Printer; GB_CLASS CLASS_ScrollView; +GB_CLASS CLASS_Image; #ifndef NO_X_WINDOW static QMap _x11_to_qt_keycode; diff --git a/gb.qt4/src/CWidget.h b/gb.qt4/src/CWidget.h index 655b8e159..5d4b4e16f 100644 --- a/gb.qt4/src/CWidget.h +++ b/gb.qt4/src/CWidget.h @@ -104,6 +104,7 @@ extern GB_CLASS CLASS_Drawing; extern GB_CLASS CLASS_DrawingArea; extern GB_CLASS CLASS_Printer; extern GB_CLASS CLASS_ScrollView; +extern GB_CLASS CLASS_Image; #else diff --git a/gb.qt4/src/Makefile.am b/gb.qt4/src/Makefile.am index 657b78ffc..6149a94be 100644 --- a/gb.qt4/src/Makefile.am +++ b/gb.qt4/src/Makefile.am @@ -42,6 +42,7 @@ gb_qt4_la_SOURCES = \ CImage.h CImage_moc.cpp CImage.cpp \ CClipboard.h CClipboard_moc.cpp CClipboard.cpp \ CDraw.h CDraw.cpp \ + cpaint_impl.h cpaint_impl.cpp \ CWatch.h CWatch_moc.cpp CWatch.cpp \ CScrollView.h CScrollView_moc.cpp CScrollView.cpp \ CDrawingArea.h CDrawingArea_moc.cpp CDrawingArea.cpp \ diff --git a/gb.qt4/src/gb.qt.h b/gb.qt4/src/gb.qt.h index 6c9fb9409..379038d86 100644 --- a/gb.qt4/src/gb.qt.h +++ b/gb.qt4/src/gb.qt.h @@ -25,14 +25,16 @@ #include "gambas.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #define QT_INTERFACE_VERSION 1 @@ -100,6 +102,14 @@ typedef } QT_DRAW_EXTRA; +typedef + struct { + QPainter *painter; + QPainterPath *path; + int fillRule; + } + QT_PAINT_EXTRA; + typedef void (*QT_FONT_FUNC)(QFont &, void *); diff --git a/gb.qt4/src/main.cpp b/gb.qt4/src/main.cpp index 354248035..e9dd90b64 100644 --- a/gb.qt4/src/main.cpp +++ b/gb.qt4/src/main.cpp @@ -1012,6 +1012,7 @@ int EXPORT GB_INIT(void) CLASS_DrawingArea = GB.FindClass("DrawingArea"); CLASS_Printer = GB.FindClass("Printer"); CLASS_ScrollView = GB.FindClass("ScrollView"); + CLASS_Image = GB.FindClass("Image"); QT_InitEventLoop(); diff --git a/main/lib/draw/cpaint.c b/main/lib/draw/cpaint.c index 45651ec83..5be6ab204 100644 --- a/main/lib/draw/cpaint.c +++ b/main/lib/draw/cpaint.c @@ -30,9 +30,13 @@ static GB_PAINT *_current = NULL; #define THIS _current #define PAINT _current->desc -#define THIS_EXTENTS ((PAINT_EXTENTS *)_object) -#define THIS_BRUSH ((PAINT_BRUSH *)_object) -#define THIS_MATRIX ((PAINT_MATRIX *)_object) +#define XTHIS ((PAINT_EXTENTS *)_object) + +#define MTHIS ((PAINT_MATRIX *)_object) +#define MPAINT (MTHIS->desc) + +#define BTHIS ((PAINT_BRUSH *)_object) +#define BPAINT (BTHIS->desc) static bool check_device() { @@ -45,7 +49,7 @@ static bool check_device() return FALSE; } -PUBLIC GB_PAINT *PAINT_get_current() +GB_PAINT *PAINT_get_current() { check_device(); return _current; @@ -68,11 +72,16 @@ bool PAINT_begin(void *device) return TRUE; } - GB.Alloc(POINTER(&paint), sizeof(GB_PAINT) + desc->size); + GB.Alloc(POINTER(&paint), sizeof(GB_PAINT)); + GB.Alloc(POINTER(&paint->extra), desc->size); + memset(paint->extra, 0, desc->size); + paint->desc = desc; paint->previous = _current; GB.Ref(device); paint->device = device; + paint->brush = NULL; + _current = paint; if (PAINT->Begin(paint)) @@ -94,9 +103,12 @@ void PAINT_end() paint = _current; _current = _current->previous; - PAINT->End(paint); - + paint->desc->End(paint); + + if (paint->brush) + GB.Unref(POINTER(&paint->brush)); GB.Unref(POINTER(&paint->device)); + GB.Free(POINTER(&paint->extra)); GB.Free(POINTER(&paint)); } @@ -105,7 +117,7 @@ void PAINT_end() #define IMPLEMENT_EXTENTS_PROPERTY(_method, _field) \ BEGIN_PROPERTY(_method) \ - GB.ReturnFloat(THIS_EXTENTS->ext._field); \ + GB.ReturnFloat(XTHIS->ext._field); \ END_PROPERTY IMPLEMENT_EXTENTS_PROPERTY(PaintExtents_X, x1) @@ -115,13 +127,13 @@ IMPLEMENT_EXTENTS_PROPERTY(PaintExtents_Y2, y2) BEGIN_PROPERTY(PaintExtents_Width) - GB.ReturnFloat(THIS_EXTENTS->ext.x2 - THIS_EXTENTS->ext.x1); + GB.ReturnFloat(XTHIS->ext.x2 - XTHIS->ext.x1); END_PROPERTY BEGIN_PROPERTY(PaintExtents_Height) - GB.ReturnFloat(THIS_EXTENTS->ext.y2 - THIS_EXTENTS->ext.y1); + GB.ReturnFloat(XTHIS->ext.y2 - XTHIS->ext.y1); END_PROPERTY @@ -132,10 +144,10 @@ BEGIN_METHOD(PaintExtents_Merge, GB_OBJECT extents) if (GB.CheckObject(extents)) return; - if (extents->ext.x1 < THIS_EXTENTS->ext.x1) THIS_EXTENTS->ext.x1 = extents->ext.x1; - if (extents->ext.y1 < THIS_EXTENTS->ext.y1) THIS_EXTENTS->ext.y1 = extents->ext.y1; - if (extents->ext.x2 > THIS_EXTENTS->ext.x2) THIS_EXTENTS->ext.x2 = extents->ext.x2; - if (extents->ext.y2 > THIS_EXTENTS->ext.y2) THIS_EXTENTS->ext.y2 = extents->ext.y2; + if (extents->ext.x1 < XTHIS->ext.x1) XTHIS->ext.x1 = extents->ext.x1; + if (extents->ext.y1 < XTHIS->ext.y1) XTHIS->ext.y1 = extents->ext.y1; + if (extents->ext.x2 > XTHIS->ext.x2) XTHIS->ext.x2 = extents->ext.x2; + if (extents->ext.y2 > XTHIS->ext.y2) XTHIS->ext.y2 = extents->ext.y2; END_METHOD @@ -157,81 +169,74 @@ GB_DESC PaintExtentsDesc[] = /**** PaintMatrix **********************************************************/ -static GB_PAINT_DESC *handle_matrix(void *_object, bool set, GB_TRANSFORM *pmatrix) +static PAINT_MATRIX *create_matrix(GB_PAINT_DESC *desc, GB_TRANSFORM *transform) { - if (!_object) - { - PAINT->Matrix(THIS, set, pmatrix); - return PAINT; - } - else - { - THIS_BRUSH->desc->Brush.Matrix(THIS_BRUSH->brush, set, pmatrix); - return THIS_BRUSH->desc; - } + PAINT_MATRIX *matrix; + GB.New(POINTER(&matrix), GB.FindClass("PaintMatrix"), NULL, NULL); + matrix->desc = desc; + matrix->transform = transform; + return matrix; } -#define IMPLEMENT_MATRIX_METHOD_VOID(_method, _code) \ -BEGIN_METHOD_VOID(_method) \ - GB_TRANSFORM matrix; \ - handle_matrix(_object, FALSE, &matrix)->Transform._code; \ - handle_matrix(_object, TRUE, &matrix); \ - RETURN_SELF(); \ +BEGIN_METHOD_VOID(PaintMatrix_Reset) + + MPAINT->Transform.Init(MTHIS->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); + RETURN_SELF(); + END_METHOD -#define IMPLEMENT_MATRIX_METHOD(_method, _arg, _code) \ -BEGIN_METHOD(_method, _arg) \ - GB_TRANSFORM matrix; \ - handle_matrix(_object, FALSE, &matrix)->Transform._code; \ - handle_matrix(_object, TRUE, &matrix); \ - RETURN_SELF(); \ +BEGIN_METHOD(PaintMatrix_Translate, GB_FLOAT tx; GB_FLOAT ty) + + MPAINT->Transform.Translate(MTHIS->transform, (float)VARG(tx), (float)VARG(ty)); + RETURN_SELF(); + END_METHOD -IMPLEMENT_MATRIX_METHOD_VOID(PaintMatrix_Reset, Init(matrix, 1, 0, 0, 1, 0, 0)) -IMPLEMENT_MATRIX_METHOD(PaintMatrix_Translate, GB_FLOAT tx; GB_FLOAT ty, Translate(matrix, VARG(tx), VARG(ty))) -IMPLEMENT_MATRIX_METHOD(PaintMatrix_Scale, GB_FLOAT sx; GB_FLOAT sy, Scale(matrix, VARG(sx), VARG(sy))) -IMPLEMENT_MATRIX_METHOD(PaintMatrix_Rotate, GB_FLOAT angle, Rotate(matrix, VARG(angle))) +BEGIN_METHOD(PaintMatrix_Scale, GB_FLOAT sx; GB_FLOAT sy) + + MPAINT->Transform.Scale(MTHIS->transform, (float)VARG(sx), (float)VARG(sy)); + RETURN_SELF(); + +END_METHOD + +BEGIN_METHOD(PaintMatrix_Rotate, GB_FLOAT angle) + + MPAINT->Transform.Rotate(MTHIS->transform, (float)VARG(angle)); + RETURN_SELF(); + +END_METHOD BEGIN_METHOD_VOID(PaintMatrix_Invert) - - GB_TRANSFORM matrix; - if (handle_matrix(_object, FALSE, &matrix)->Transform.Invert(matrix)) - { + + if (MPAINT->Transform.Invert(MTHIS->transform)) GB.ReturnNull(); - return; - } - handle_matrix(_object, TRUE, &matrix); - RETURN_SELF(); - -END_METHOD - -BEGIN_METHOD(PaintMatrix_Multiply, GB_OBJECT matrix2) - - GB_TRANSFORM matrix; - PAINT_MATRIX *matrix2 = (PAINT_MATRIX *)VARG(matrix2); - - if (GB.CheckObject(matrix2)) - return; - - handle_matrix(_object, FALSE, &matrix)->Transform.Multiply(matrix, matrix2->matrix); - handle_matrix(_object, TRUE, &matrix); - RETURN_SELF(); + else + RETURN_SELF(); END_METHOD +BEGIN_METHOD(PaintMatrix_Multiply, GB_OBJECT matrix) + + PAINT_MATRIX *matrix = (PAINT_MATRIX *)VARG(matrix); + + if (GB.CheckObject(matrix)) + return; + + MPAINT->Transform.Multiply(MTHIS->transform, matrix->transform); + RETURN_SELF(); + +END_METHOD GB_DESC PaintMatrixDesc[] = { - GB_DECLARE(".PaintMatrix", 0), GB_VIRTUAL_CLASS(), + GB_DECLARE("PaintMatrix", sizeof(PAINT_MATRIX)), GB_NOT_CREATABLE(), - //GB_METHOD("_new", NULL, PaintMatrix_new, "[(XX)f(YX)f(XY)f(YY)f(X0)f(Y0)f]"), - //GB_STATIC_METHOD("_call", "PaintMatrix", PaintMatrix_call, "[(XX)f(YX)f(XY)f(YY)f(X0)f(Y0)f]"), - GB_METHOD("Reset", ".PaintMatrix", PaintMatrix_Reset, NULL), - GB_METHOD("Translate", ".PaintMatrix", PaintMatrix_Translate, "(TX)f(TY)f"), - GB_METHOD("Scale", ".PaintMatrix", PaintMatrix_Scale, "(SX)f(SY)f"), - GB_METHOD("Rotate", ".PaintMatrix", PaintMatrix_Rotate, "(Angle)f"), - GB_METHOD("Invert", ".PaintMatrix", PaintMatrix_Invert, NULL), - GB_METHOD("Multiply", ".PaintMatrix", PaintMatrix_Multiply, "(Matrix)PaintMatrix;"), + GB_METHOD("Reset", "PaintMatrix", PaintMatrix_Reset, NULL), + GB_METHOD("Translate", "PaintMatrix", PaintMatrix_Translate, "(TX)f(TY)f"), + GB_METHOD("Scale", "PaintMatrix", PaintMatrix_Scale, "(SX)f(SY)f"), + GB_METHOD("Rotate", "PaintMatrix", PaintMatrix_Rotate, "(Angle)f"), + GB_METHOD("Invert", "PaintMatrix", PaintMatrix_Invert, NULL), + GB_METHOD("Multiply", "PaintMatrix", PaintMatrix_Multiply, "(Matrix)PaintMatrix;"), GB_END_DECLARE }; @@ -241,17 +246,83 @@ GB_DESC PaintMatrixDesc[] = BEGIN_METHOD_VOID(PaintBrush_free) - THIS_BRUSH->desc->Brush.Free(THIS_BRUSH->brush); + BPAINT->Brush.Free(BTHIS->brush); END_METHOD +BEGIN_PROPERTY(PaintBrush_Matrix) + + GB_TRANSFORM transform; + PAINT_MATRIX *matrix; + + if (READ_PROPERTY) + { + BPAINT->Transform.Create(&transform); + BPAINT->Brush.Matrix(BTHIS, FALSE, transform); + GB.ReturnObject(create_matrix(BPAINT, transform)); + } + else + { + matrix = (PAINT_MATRIX *)VPROP(GB_OBJECT); + if (!matrix) + BPAINT->Brush.Matrix(BTHIS, TRUE, NULL); + else + BPAINT->Brush.Matrix(BTHIS, TRUE, matrix->transform); + } + +END_PROPERTY + +BEGIN_METHOD_VOID(PaintBrush_Reset) + + BPAINT->Brush.Matrix(BTHIS->brush, TRUE, NULL); + +END_METHOD + +BEGIN_METHOD(PaintBrush_Translate, GB_FLOAT tx; GB_FLOAT ty) + + GB_TRANSFORM transform; + + BPAINT->Transform.Create(&transform); + BPAINT->Brush.Matrix(BTHIS->brush, FALSE, transform); + BPAINT->Transform.Translate(transform, (float)VARG(tx), (float)VARG(ty)); + BPAINT->Brush.Matrix(BTHIS->brush, TRUE, transform); + +END_METHOD + +BEGIN_METHOD(PaintBrush_Scale, GB_FLOAT sx; GB_FLOAT sy) + + GB_TRANSFORM transform; + + BPAINT->Transform.Create(&transform); + BPAINT->Brush.Matrix(BTHIS->brush, FALSE, transform); + BPAINT->Transform.Scale(transform, (float)VARG(sx), (float)VARG(sy)); + BPAINT->Brush.Matrix(BTHIS->brush, TRUE, transform); + +END_METHOD + +BEGIN_METHOD(PaintBrush_Rotate, GB_FLOAT angle) + + GB_TRANSFORM transform; + + BPAINT->Transform.Create(&transform); + BPAINT->Brush.Matrix(BTHIS->brush, FALSE, transform); + BPAINT->Transform.Rotate(transform, (float)VARG(angle)); + BPAINT->Brush.Matrix(BTHIS->brush, TRUE, transform); + +END_METHOD + + GB_DESC PaintBrushDesc[] = { GB_DECLARE("PaintBrush", sizeof(PAINT_BRUSH)), GB_NOT_CREATABLE(), GB_METHOD("_free", NULL, PaintBrush_free, NULL), - GB_PROPERTY_SELF("Matrix", ".PaintMatrix"), + GB_PROPERTY("Matrix", "PaintMatrix", PaintBrush_Matrix), + GB_METHOD("Reset", NULL, PaintBrush_Reset, NULL), + GB_METHOD("Translate", NULL, PaintBrush_Translate, "(TX)f(TY)f"), + GB_METHOD("Scale", NULL, PaintBrush_Scale, "(SX)f(SY)f"), + GB_METHOD("Rotate", NULL, PaintBrush_Rotate, "(Angle)f"), GB_END_DECLARE }; @@ -306,10 +377,17 @@ BEGIN_PROPERTY(Paint_Height) END_PROPERTY -BEGIN_PROPERTY(Paint_Resolution) +BEGIN_PROPERTY(Paint_ResolutionX) CHECK_DEVICE(); - GB.ReturnInteger(THIS->resolution); + GB.ReturnInteger(THIS->resolutionX); + +END_PROPERTY + +BEGIN_PROPERTY(Paint_ResolutionY) + + CHECK_DEVICE(); + GB.ReturnInteger(THIS->resolutionY); END_PROPERTY @@ -364,12 +442,86 @@ IMPLEMENT_PROPERTY_EXTENTS(Paint_ClipExtents, ClipExtents) IMPLEMENT_METHOD_PRESERVE(Paint_Fill, Fill) IMPLEMENT_METHOD_PRESERVE(Paint_Stroke, Stroke) IMPLEMENT_PROPERTY_EXTENTS(Paint_PathExtents, PathExtents) + +BEGIN_METHOD(Paint_PathContains, GB_FLOAT x; GB_FLOAT y) + + CHECK_DEVICE(); + GB.ReturnBoolean(PAINT->PathContains(THIS, (float)VARG(x), (float)VARG(y))); + +END_METHOD + IMPLEMENT_PROPERTY_INTEGER(Paint_FillRule, FillRule) IMPLEMENT_PROPERTY_INTEGER(Paint_LineCap, LineCap) IMPLEMENT_PROPERTY_INTEGER(Paint_LineJoin, LineJoin) IMPLEMENT_PROPERTY_INTEGER(Paint_Operator, Operator) IMPLEMENT_PROPERTY_FLOAT(Paint_LineWidth, LineWidth) IMPLEMENT_PROPERTY_FLOAT(Paint_MiterLimit, MiterLimit) + +BEGIN_PROPERTY(Paint_Brush) + + if (READ_PROPERTY) + GB.ReturnObject(THIS->brush); + else + { + PAINT_BRUSH *old_brush = THIS->brush; + PAINT_BRUSH *new_brush = (PAINT_BRUSH *)VPROP(GB_OBJECT); + if (new_brush) + { + GB.Ref(new_brush); + PAINT->SetBrush(THIS, new_brush->brush, new_brush->x, new_brush->y); + } + GB.Unref(POINTER(&old_brush)); + THIS->brush = new_brush; + } + +END_PROPERTY + +BEGIN_PROPERTY(Paint_Dash) + + GB_ARRAY array; + float *dashes; + int count, i; + + CHECK_DEVICE(); + + if (READ_PROPERTY) + { + PAINT->Dash(THIS, FALSE, &dashes, &count); + if (!count) + GB.ReturnNull(); + else + { + GB.Array.New(POINTER(&array), GB_T_FLOAT, count); + for (i = 0; i < count; i++) + *((double *)GB.Array.Get(array, i)) = (double)dashes[i]; + GB.ReturnObject(array); + } + GB.Free(POINTER(&dashes)); + } + else + { + array = (GB_ARRAY)VPROP(GB_OBJECT); + if (!array) + count = 0; + else + count = GB.Array.Count(array); + + if (!count) + { + PAINT->Dash(THIS, TRUE, NULL, &count); + } + else + { + GB.Alloc(POINTER(&dashes), sizeof(float) * count); + for (i = 0; i < count; i++) + dashes[i] = (float)*((double *)GB.Array.Get(array, i)); + PAINT->Dash(THIS, TRUE, &dashes, &count); + GB.Free(POINTER(&dashes)); + } + } + +END_PROPERTY + IMPLEMENT_PROPERTY_FLOAT(Paint_DashOffset, DashOffset) IMPLEMENT_METHOD(Paint_NewPath, NewPath) IMPLEMENT_METHOD(Paint_ClosePath, ClosePath) @@ -392,10 +544,10 @@ BEGIN_PROPERTY(Paint_Y) END_PROPERTY -BEGIN_METHOD(Paint_Arc, GB_FLOAT xc; GB_FLOAT yc; GB_FLOAT radius; GB_FLOAT angle1; GB_FLOAT angle2) +BEGIN_METHOD(Paint_Arc, GB_FLOAT xc; GB_FLOAT yc; GB_FLOAT radius; GB_FLOAT angle; GB_FLOAT length) CHECK_DEVICE(); - PAINT->Arc(THIS, VARG(xc), VARG(yc), VARG(radius), VARGOPT(angle1, 0.0), VARGOPT(angle2, M_PI * 2)); + PAINT->Arc(THIS, VARG(xc), VARG(yc), VARG(radius), VARGOPT(angle, 0.0), VARGOPT(length, M_PI * 2)); END_METHOD @@ -463,12 +615,15 @@ BEGIN_METHOD(Paint_TextExtents, GB_STRING text) END_METHOD -static void make_brush(GB_BRUSH brush) +static PAINT_BRUSH *make_brush(GB_PAINT *d, GB_BRUSH brush) { PAINT_BRUSH *that; GB.New(POINTER(&that), GB.FindClass("PaintBrush"), NULL, NULL); + that->desc = d->desc; that->brush = brush; + that->x = that->y = 0; GB.ReturnObject(that); + return that; } BEGIN_METHOD(Paint_Color, GB_INTEGER color) @@ -478,12 +633,13 @@ BEGIN_METHOD(Paint_Color, GB_INTEGER color) CHECK_DEVICE(); PAINT->Brush.Color(&brush, VARG(color)); - make_brush(brush); + make_brush(THIS, brush); END_METHOD -BEGIN_METHOD(Paint_Image, GB_OBJECT image; GB_FLOAT x; GB_FLOAT y; GB_INTEGER extend) +BEGIN_METHOD(Paint_Image, GB_OBJECT image; GB_FLOAT x; GB_FLOAT y) + PAINT_BRUSH *pb; GB_BRUSH brush; CHECK_DEVICE(); @@ -491,24 +647,40 @@ BEGIN_METHOD(Paint_Image, GB_OBJECT image; GB_FLOAT x; GB_FLOAT y; GB_INTEGER ex if (GB.CheckObject(VARG(image))) return; - PAINT->Brush.Image(&brush, (GB_IMAGE)VARG(image), (float)VARGOPT(x, 0), (float)VARGOPT(y, 0), VARGOPT(extend, GB_PAINT_EXTEND_PAD)); - make_brush(brush); + PAINT->Brush.Image(&brush, (GB_IMAGE)VARG(image)); + pb = make_brush(THIS, brush); + pb->x = (float)VARGOPT(x, 0); + pb->y = (float)VARGOPT(y, 0); END_METHOD -static void handle_color_stop(GB_BRUSH brush, GB_ARRAY positions, GB_ARRAY colors) -{ +BEGIN_METHOD(Paint_LinearGradient, GB_FLOAT x0; GB_FLOAT y0; GB_FLOAT x1; GB_FLOAT y1; GB_OBJECT colors; GB_OBJECT positions; GB_INTEGER extend) + + GB_BRUSH brush; + GB_ARRAY positions, colors; int nstop; + positions = (GB_ARRAY)VARG(positions); + if (GB.CheckObject(positions)) + return; + colors = (GB_ARRAY)VARG(colors); + if (GB.CheckObject(colors)) + return; + nstop = Min(GB.Array.Count(positions), GB.Array.Count(colors)); - if (nstop) - PAINT->Brush.SetColorStops(brush, nstop, (double *)GB.Array.Get(positions, 0), (GB_COLOR *)GB.Array.Get(colors, 0)); -} + + PAINT->Brush.LinearGradient(&brush, (float)VARG(x0), (float)VARG(y0), (float)VARG(x1), (float)VARG(y1), + nstop, (double *)GB.Array.Get(positions, 0), (GB_COLOR *)GB.Array.Get(colors, 0), VARGOPT(extend, GB_PAINT_EXTEND_PAD)); -BEGIN_METHOD(Paint_LinearGradient, GB_FLOAT x0; GB_FLOAT y0; GB_FLOAT x1; GB_FLOAT y1; GB_OBJECT positions; GB_OBJECT colors) + make_brush(THIS, brush); + +END_METHOD + +BEGIN_METHOD(Paint_RadialGradient, GB_FLOAT cx0; GB_FLOAT cy0; GB_FLOAT radius0; GB_FLOAT cx1; GB_FLOAT cy1; GB_FLOAT radius1; GB_OBJECT colors; GB_OBJECT positions; GB_INTEGER extend) GB_BRUSH brush; GB_ARRAY positions, colors; + int nstop; positions = (GB_ARRAY)VARG(positions); if (GB.CheckObject(positions)) @@ -517,32 +689,83 @@ BEGIN_METHOD(Paint_LinearGradient, GB_FLOAT x0; GB_FLOAT y0; GB_FLOAT x1; GB_FLO if (GB.CheckObject(colors)) return; - PAINT->Brush.LinearGradient(&brush, (float)VARG(x0), (float)VARG(y0), (float)VARG(x1), (float)VARG(y1)); - handle_color_stop(brush, positions, colors); - make_brush(brush); + nstop = Min(GB.Array.Count(positions), GB.Array.Count(colors)); + + PAINT->Brush.RadialGradient(&brush, (float)VARG(cx0), (float)VARG(cy0), (float)VARG(radius0), (float)VARG(cx1), (float)VARG(cy1), (float)VARG(radius1), + nstop, (double *)GB.Array.Get(positions, 0), (GB_COLOR *)GB.Array.Get(colors, 0), VARGOPT(extend, GB_PAINT_EXTEND_PAD)); + + make_brush(THIS, brush); END_METHOD -BEGIN_METHOD(Paint_RadialGradient, GB_FLOAT cx0; GB_FLOAT cy0; GB_FLOAT radius0; GB_FLOAT cx1; GB_FLOAT cy1; GB_FLOAT radius1; GB_OBJECT positions; GB_OBJECT colors) +BEGIN_PROPERTY(Paint_Matrix) - GB_BRUSH brush; - GB_ARRAY positions, colors; + GB_TRANSFORM transform; + PAINT_MATRIX *matrix; - positions = (GB_ARRAY)VARG(positions); - if (GB.CheckObject(positions)) - return; - colors = (GB_ARRAY)VARG(colors); - if (GB.CheckObject(colors)) - return; + CHECK_DEVICE(); - PAINT->Brush.RadialGradient(&brush, (float)VARG(cx0), (float)VARG(cy0), (float)VARG(radius0), (float)VARG(cx1), (float)VARG(cy1), (float)VARG(radius1)); - handle_color_stop(brush, positions, colors); - make_brush(brush); + if (READ_PROPERTY) + { + PAINT->Transform.Create(&transform); + PAINT->Matrix(THIS, FALSE, transform); + GB.ReturnObject(create_matrix(PAINT, transform)); + } + else + { + matrix = (PAINT_MATRIX *)VPROP(GB_OBJECT); + if (!matrix) + PAINT->Matrix(THIS, TRUE, NULL); + else + PAINT->Matrix(THIS, TRUE, matrix->transform); + } + +END_PROPERTY + +BEGIN_METHOD_VOID(Paint_Reset) + + CHECK_DEVICE(); + PAINT->Matrix(THIS, TRUE, NULL); END_METHOD +BEGIN_METHOD(Paint_Translate, GB_FLOAT tx; GB_FLOAT ty) -GB_DESC CPaintDesc[] = + GB_TRANSFORM transform; + + CHECK_DEVICE(); + PAINT->Transform.Create(&transform); + PAINT->Matrix(THIS, FALSE, transform); + PAINT->Transform.Translate(transform, (float)VARG(tx), (float)VARG(ty)); + PAINT->Matrix(THIS, TRUE, transform); + +END_METHOD + +BEGIN_METHOD(Paint_Scale, GB_FLOAT sx; GB_FLOAT sy) + + GB_TRANSFORM transform; + + CHECK_DEVICE(); + PAINT->Transform.Create(&transform); + PAINT->Matrix(THIS, FALSE, transform); + PAINT->Transform.Scale(transform, (float)VARG(sx), (float)VARG(sy)); + PAINT->Matrix(THIS, TRUE, transform); + +END_METHOD + +BEGIN_METHOD(Paint_Rotate, GB_FLOAT angle) + + GB_TRANSFORM transform; + + CHECK_DEVICE(); + PAINT->Transform.Create(&transform); + PAINT->Matrix(THIS, FALSE, transform); + PAINT->Transform.Rotate(transform, (float)VARG(angle)); + PAINT->Matrix(THIS, TRUE, transform); + +END_METHOD + +GB_DESC PaintDesc[] = { GB_DECLARE("Paint", 0), GB_VIRTUAL_CLASS(), @@ -586,7 +809,8 @@ GB_DESC CPaintDesc[] = GB_STATIC_PROPERTY_READ("H", "i", Paint_Height), GB_STATIC_PROPERTY_READ("Width", "i", Paint_Width), GB_STATIC_PROPERTY_READ("Height", "i", Paint_Height), - GB_STATIC_PROPERTY_READ("Resolution", "i", Paint_Resolution), + GB_STATIC_PROPERTY_READ("ResolutionX", "i", Paint_ResolutionX), + GB_STATIC_PROPERTY_READ("ResolutionY", "i", Paint_ResolutionY), GB_STATIC_METHOD("Save", NULL, Paint_Save, NULL), GB_STATIC_METHOD("Restore", NULL, Paint_Restore, NULL), @@ -608,10 +832,10 @@ GB_DESC CPaintDesc[] = //GB_STATIC_METHOD("InStroke", "b", Paint_InStroke, "(X)f(Y)f"), GB_STATIC_PROPERTY_READ("PathExtents", "PaintExtents", Paint_PathExtents), - //GB_STATIC_METHOD("PathContains", "b", Paint_InPath, "(X)f(Y)f"), + GB_STATIC_METHOD("PathContains", "b", Paint_PathContains, "(X)f(Y)f"), - //GB_STATIC_PROPERTY("Brush", "PaintBrush", Paint_Brush), - //GB_STATIC_PROPERTY("Dash", "Float[]", Paint_Dash), + GB_STATIC_PROPERTY("Brush", "PaintBrush", Paint_Brush), + GB_STATIC_PROPERTY("Dash", "Float[]", Paint_Dash), GB_STATIC_PROPERTY("DashOffset", "f", Paint_DashOffset), GB_STATIC_PROPERTY("FillRule", "i", Paint_FillRule), GB_STATIC_PROPERTY("LineCap", "i", Paint_LineCap), @@ -627,7 +851,7 @@ GB_DESC CPaintDesc[] = GB_STATIC_PROPERTY_READ("X", "f", Paint_X), GB_STATIC_PROPERTY_READ("Y", "f", Paint_Y), - GB_STATIC_METHOD("Arc", NULL, Paint_Arc, "(XC)f(YC)f(Radius)f[(Angle1)f(Angle2)f]"), + GB_STATIC_METHOD("Arc", NULL, Paint_Arc, "(XC)f(YC)f(Radius)f[(Angle)f(Length)f]"), //GB_STATIC_METHOD("ArcNegative", NULL, CAIRO_arc_negative, "(XC)f(YC)f(Radius)f[(Angle1)f(Angle2)f]"), GB_STATIC_METHOD("CurveTo", NULL, Paint_CurveTo, "(X1)f(Y1)f(X2)f(Y2)f(X3)f(Y3)f"), GB_STATIC_METHOD("LineTo", NULL, Paint_LineTo, "(X)f(Y)f"), @@ -639,11 +863,16 @@ GB_DESC CPaintDesc[] = GB_STATIC_METHOD("TextExtents", "TextExtents", Paint_TextExtents, "(Text)s"), GB_STATIC_METHOD("Color", "PaintBrush", Paint_Color, "(Color)i"), - GB_STATIC_METHOD("Image", "PaintBrush", Paint_Image, "(Image)Image;[(X)f(Y)f(Extend)i]"), - GB_STATIC_METHOD("LinearGradient", "PaintBrush", Paint_LinearGradient, "(X0)f(Y0)f(X1)f(Y1)f(Positions)Float[];(Colors)Integer[];"), - GB_STATIC_METHOD("RadialGradient", "PaintBrush", Paint_RadialGradient, "(CX0)f(CY0)f(Radius0)f(CX1)f(CY1)f(Radius1)f(Positions)Float[];(Colors)Integer[];"), + GB_STATIC_METHOD("Image", "PaintBrush", Paint_Image, "(Image)Image;[(X)f(Y)f]"), + GB_STATIC_METHOD("LinearGradient", "PaintBrush", Paint_LinearGradient, "(X0)f(Y0)f(X1)f(Y1)f(Colors)Integer[];(Positions)Float[];[(Extend)i]"), + GB_STATIC_METHOD("RadialGradient", "PaintBrush", Paint_RadialGradient, "(CX0)f(CY0)f(Radius0)f(CX1)f(CY1)f(Radius1)f(Colors)Integer[];(Positions)Float[];[(Extend)i]"), - GB_STATIC_PROPERTY_SELF("Matrix", ".PaintMatrix"), + GB_STATIC_PROPERTY("Matrix", "PaintMatrix", Paint_Matrix), + + GB_STATIC_METHOD("Reset", NULL, Paint_Reset, NULL), + GB_STATIC_METHOD("Translate", NULL, Paint_Translate, "(TX)f(TY)f"), + GB_STATIC_METHOD("Scale", NULL, Paint_Scale, "(SX)f(SY)f"), + GB_STATIC_METHOD("Rotate", NULL, Paint_Rotate, "(Angle)f"), GB_END_DECLARE }; diff --git a/main/lib/draw/cpaint.h b/main/lib/draw/cpaint.h index f2847b58f..6d723f9c6 100644 --- a/main/lib/draw/cpaint.h +++ b/main/lib/draw/cpaint.h @@ -29,6 +29,7 @@ #ifndef __CPAINT_C extern GB_DESC PaintExtentsDesc[]; +extern GB_DESC PaintMatrixDesc[]; extern GB_DESC PaintBrushDesc[]; extern GB_DESC PaintDesc[]; diff --git a/main/lib/draw/gb.draw.h b/main/lib/draw/gb.draw.h index ae045487b..5e404b6cf 100644 --- a/main/lib/draw/gb.draw.h +++ b/main/lib/draw/gb.draw.h @@ -169,7 +169,6 @@ typedef void (*Handle)(GB_DRAW *d, int x, int y, int w, int h, int vertical, int state); } Style; - // Cairo drawing model? I must look at QT Arthur painting model first! } GB_DRAW_DESC; @@ -181,6 +180,12 @@ typedef GB_DRAW *(*GetCurrent)(); void (*Begin)(void *); void (*End)(); + struct { + void *(*GetCurrent)(); + void (*Begin)(void *); + void (*End)(); + } + Paint; } DRAW_INTERFACE; diff --git a/main/lib/draw/gb.paint.h b/main/lib/draw/gb.paint.h index 7cadd1c7c..530d83571 100644 --- a/main/lib/draw/gb.paint.h +++ b/main/lib/draw/gb.paint.h @@ -92,7 +92,7 @@ typedef struct { GB_BASE ob; struct GB_PAINT_DESC *desc; // drawing driver - GB_TRANSFORM matrix; + GB_TRANSFORM transform; } PAINT_MATRIX; @@ -100,7 +100,8 @@ typedef struct { GB_BASE ob; struct GB_PAINT_DESC *desc; // drawing driver - GB_BRUSH brush; + GB_BRUSH brush; // brush + float x, y; // brush origin } PAINT_BRUSH; @@ -111,10 +112,11 @@ typedef void *device; // drawing object int width; // device width in device coordinates int height; // device height in device coordinates - int resolution; // device resolution in DPI - char extra[0]; // driver-specific state + int resolutionX; // device horizontal resolution in DPI + int resolutionY; // device vertical resolution in DPI + PAINT_BRUSH *brush; // current brush + void *extra; // driver-specific state } - PACKED GB_PAINT; typedef @@ -128,33 +130,33 @@ typedef void (*Save)(GB_PAINT *d); void (*Restore)(GB_PAINT *d); - void (*Font)(GB_PAINT *d, bool set, GB_FONT *font); + void (*Font)(GB_PAINT *d, int set, GB_FONT *font); - void (*Clip)(GB_PAINT *d, bool preserve); + void (*Clip)(GB_PAINT *d, int preserve); void (*ResetClip)(GB_PAINT *d); void (*ClipExtents)(GB_PAINT *d, GB_EXTENTS *ext); - void (*Fill)(GB_PAINT *d, bool preserve); - void (*Stroke)(GB_PAINT *d, bool preserve); + void (*Fill)(GB_PAINT *d, int preserve); + void (*Stroke)(GB_PAINT *d, int preserve); void (*PathExtents)(GB_PAINT *d, GB_EXTENTS *ext); - bool (*PathContains)(GB_PAINT *d, float x, float y); + int (*PathContains)(GB_PAINT *d, float x, float y); - void (*Dash)(GB_PAINT *d, bool set, float **dash, int *count); - void (*DashOffset)(GB_PAINT *d, bool set, float *offset); + void (*Dash)(GB_PAINT *d, int set, float **dash, int *count); + void (*DashOffset)(GB_PAINT *d, int set, float *offset); - void (*FillRule)(GB_PAINT *d, bool set, int *value); - void (*LineCap)(GB_PAINT *d, bool set, int *value); - void (*LineJoin)(GB_PAINT *d, bool set, int *value); - void (*LineWidth)(GB_PAINT *d, bool set, float *value); - void (*MiterLimit)(GB_PAINT *d, bool set, float *value); + void (*FillRule)(GB_PAINT *d, int set, int *value); + void (*LineCap)(GB_PAINT *d, int set, int *value); + void (*LineJoin)(GB_PAINT *d, int set, int *value); + void (*LineWidth)(GB_PAINT *d, int set, float *value); + void (*MiterLimit)(GB_PAINT *d, int set, float *value); - void (*Operator)(GB_PAINT *d, bool set, int *value); + void (*Operator)(GB_PAINT *d, int set, int *value); void (*NewPath)(GB_PAINT *d); void (*ClosePath)(GB_PAINT *d); - void (*Arc)(GB_PAINT *d, float xc, float yc, float radius, float a1, float a2); + void (*Arc)(GB_PAINT *d, float xc, float yc, float radius, float angle, float length); void (*Rectangle)(GB_PAINT *d, float x, float y, float width, float height); void (*GetCurrentPoint)(GB_PAINT *d, float *x, float *y); void (*MoveTo)(GB_PAINT *d, float x, float y); @@ -164,45 +166,34 @@ typedef void (*Text)(GB_PAINT *d, const char *text, int len); void (*TextExtents)(GB_PAINT *d, const char *text, int len, GB_EXTENTS *ext); - void (*Translate)(GB_PAINT *d, float tx, float ty); - void (*Scale)(GB_PAINT *d, float sx, float sy); - void (*Rotate)(GB_PAINT *d, float angle); - void (*Matrix)(GB_PAINT *d, bool set, GB_TRANSFORM *matrix); + void (*Matrix)(GB_PAINT *d, int set, GB_TRANSFORM matrix); - void (*SetBrush)(GB_PAINT *d, GB_BRUSH brush); + void (*SetBrush)(GB_PAINT *d, GB_BRUSH brush, float x, float y); struct { void (*Free)(GB_BRUSH brush); void (*Color)(GB_BRUSH *brush, GB_COLOR color); - void (*Image)(GB_BRUSH *brush, GB_IMAGE image, float x, float y, int extend); - void (*LinearGradient)(GB_BRUSH *brush, float x0, float y0, float x1, float y1); - void (*RadialGradient)(GB_BRUSH *brush, float cx0, float cy0, float r0, float cx1, float cy1, float r1); - void (*SetColorStops)(GB_BRUSH brush, int nstop, double *pos, GB_COLOR *color); - void (*Matrix)(GB_BRUSH brush, bool set, GB_TRANSFORM *matrix); + void (*Image)(GB_BRUSH *brush, GB_IMAGE image); + void (*LinearGradient)(GB_BRUSH *brush, float x0, float y0, float x1, float y1, int nstop, double *positions, GB_COLOR *colors, int extend); + void (*RadialGradient)(GB_BRUSH *brush, float cx0, float cy0, float r0, float cx1, float cy1, float r1, int nstop, double *positions, GB_COLOR *colors, int extend); + void (*Matrix)(GB_BRUSH brush, int set, GB_TRANSFORM matrix); } Brush; struct { + void (*Create)(GB_TRANSFORM *matrix); + void (*Delete)(GB_TRANSFORM *matrix); void (*Init)(GB_TRANSFORM matrix, float xx, float yx, float xy, float yy, float x0, float y0); void (*Translate)(GB_TRANSFORM matrix, float tx, float ty); void (*Scale)(GB_TRANSFORM matrix, float sx, float sy); void (*Rotate)(GB_TRANSFORM matrix, float angle); - bool (*Invert)(GB_TRANSFORM matrix); + int (*Invert)(GB_TRANSFORM matrix); void (*Multiply)(GB_TRANSFORM matrix, GB_TRANSFORM matrix2); } Transform; } GB_PAINT_DESC; -typedef - struct { - int version; - GB_PAINT *(*GetCurrent)(); - void (*Begin)(void *); - void (*End)(); - } - PAINT_INTERFACE; - #endif diff --git a/main/lib/draw/main.c b/main/lib/draw/main.c index ca0194c24..92a2adf2b 100644 --- a/main/lib/draw/main.c +++ b/main/lib/draw/main.c @@ -42,6 +42,10 @@ GB_DESC *GB_CLASSES [] EXPORT = CDrawClipDesc, CDrawStyleDesc, CDrawDesc, + PaintExtentsDesc, + PaintMatrixDesc, + PaintBrushDesc, + PaintDesc, NULL }; @@ -51,6 +55,9 @@ void *GB_DRAW_1[] EXPORT = (void *)DRAW_get_current, (void *)DRAW_begin, (void *)DRAW_end, + (void *)PAINT_get_current, + (void *)PAINT_begin, + (void *)PAINT_end, NULL };