📄 cdraw.cpp
字号:
/*************************************************************************** CDraw.cpp (c) 2000-2003 Beno� 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 __CDRAW_CPP#include <qpainter.h>#include <qpen.h>#include <qbrush.h>#include <qapplication.h>#include <qpaintdevicemetrics.h>#include <qpicture.h>#include <qpixmap.h>#include <qbitmap.h>#include "gambas.h"#include "CFont.h"#include "CWidget.h"#include "CWindow.h"#include "CPicture.h"#include "CImage.h"#include "CDrawing.h"#include "CDrawingArea.h"#include "CPrinter.h"#include "CDraw.h"#define DRAW_STACK_MAX 8typedef struct { QPainter *p; QPainter *pm; void *device; QBitmap *mask; } CDRAW;#define THIS (draw_current)#define DP (THIS->p)#define DPM (THIS->pm)static CDRAW draw_stack[DRAW_STACK_MAX];static CDRAW *draw_current = 0;//static CFONT draw_font;//static CWIDGET *_device = 0;//static QPainter *DP = NULL;//static int draw_mode = DRAW_ON_NOTHING;//static bool delete_painter = false;static void *CLASS_Window;static void *CLASS_Picture;static void *CLASS_Drawing;static void *CLASS_DrawingArea;static void *CLASS_Printer;#define COLOR_TO_INT(color) ((color).rgb() ^ 0xFF000000)#define MASK_COLOR(col) ((col & 0xFF000000) ? Qt::color0 : Qt::color1)void DRAW_begin(void *device, QPainter *p){ if (THIS >= &draw_stack[DRAW_STACK_MAX - 1]) { GB.Error("Too many nested drawings"); return; } if (THIS == 0) THIS = draw_stack; else THIS++; THIS->p = p; THIS->pm = 0; THIS->device = device; THIS->mask = 0; if (device) GB.Ref(device); //qDebug("DRAW_begin: THIS = %p", THIS);}void DRAW_end(void){ void *device; if (!THIS) return; //if (THIS->mode != DRAW_ON_ITEM) // delete DP; device = THIS->device; delete DP; if (GB.Is(device, CLASS_Picture)) { if (DPM) { ((CPICTURE *)device)->pixmap->setMask(*THIS->mask); delete DPM; delete THIS->mask; } } else if (GB.Is(device, CLASS_DrawingArea)) { MyDrawingArea *wid = (MyDrawingArea *)(((CWIDGET *)device)->widget); if (wid->isCached()) wid->refreshBackground(); } if (device) GB.Unref(&device); if (THIS == draw_stack) THIS = 0; else THIS--; //qDebug("DRAW_end: THIS = %p", THIS);}int DRAW_status(void){ if (!THIS) return -1; else return (THIS - draw_stack);}void DRAW_restore(int status){ while (DRAW_status() != status) DRAW_end();}static bool check_painter(void){ if (!THIS) { GB.Error("No device"); return true; } else return false;}#define CHECK_PAINTER() if (check_painter()) returnvoid DRAW_set_font(QFont &f){ CHECK_PAINTER(); DP->setFont(f); if (DPM) DPM->setFont(f);}bool DRAW_must_resize_font(void){ return (THIS->device != CLASS_Printer);}BEGIN_METHOD_VOID(CDRAW_init) CLASS_Window = GB.FindClass("Window"); CLASS_Picture = GB.FindClass("Picture"); CLASS_Drawing = GB.FindClass("Drawing"); CLASS_DrawingArea = GB.FindClass("DrawingArea"); CLASS_Printer = GB.FindClass("Printer");END_METHODBEGIN_METHOD_VOID(CDRAW_exit) DRAW_restore(-1);END_METHODBEGIN_METHOD(CDRAW_begin, GB_OBJECT device) void *device = VARG(device); if (GB.CheckObject(device)) return; if (GB.Is(device, CLASS_Window)) { MyMainWindow *win = (MyMainWindow *)((CWIDGET *)device)->widget; //win->paintUnclip(true); DRAW_begin(device, new QPainter(win, true)); } else if (GB.Is(device, CLASS_Picture)) { CPICTURE *pict = (CPICTURE *)device; if (pict->pixmap->isNull()) { GB.Error("Bad picture"); return; } DRAW_begin(device, new QPainter(pict->pixmap)); if (pict->pixmap->mask()) { QPen pen; QBrush brush; THIS->mask = new QBitmap(*pict->pixmap->mask()); THIS->pm = new QPainter(THIS->mask); pen = THIS->p->pen(); THIS->pm->setPen(QPen(Qt::color1, pen.width(), pen.style())); brush = THIS->p->brush(); THIS->pm->setBrush(QBrush(Qt::color1, brush.style())); } } else if (GB.Is(device, CLASS_Drawing)) { CDRAWING *drawing = (CDRAWING *)device; DRAW_begin(device, new QPainter(drawing->picture)); } else if (GB.Is(device, CLASS_DrawingArea)) { MyDrawingArea *wid = (MyDrawingArea *)(((CWIDGET *)device)->widget); if (wid->isCached()) DRAW_begin(device, new QPainter(wid->background(), wid)); else DRAW_begin(device, new QPainter(wid, wid)); } else if (device == CLASS_Printer) { CPRINTER_init(); QPrinter *printer = CPRINTER_printer; DRAW_begin(device, new QPainter(printer)); } else goto _ERROR; return;_ERROR: GB.Error("Bad device");END_METHODBEGIN_METHOD_VOID(CDRAW_end) DRAW_end();END_METHODBEGIN_PROPERTY(CDRAW_background) CHECK_PAINTER(); if (READ_PROPERTY) GB.ReturnInteger(COLOR_TO_INT(DP->backgroundColor())); else { int col = VPROP(GB_INTEGER); DP->setBackgroundColor(QColor(col)); if (DPM) DPM->setBackgroundColor(MASK_COLOR(col)); }END_PROPERTYBEGIN_PROPERTY(CDRAW_transparent) CHECK_PAINTER(); if (READ_PROPERTY) GB.ReturnBoolean(DP->backgroundMode() == Qt::TransparentMode); else { DP->setBackgroundMode(VPROP(GB_BOOLEAN) ? Qt::TransparentMode : Qt::OpaqueMode); if (DPM) DPM->setBackgroundMode(VPROP(GB_BOOLEAN) ? Qt::TransparentMode : Qt::OpaqueMode); }END_PROPERTYBEGIN_PROPERTY(CDRAW_invert) CHECK_PAINTER(); if (READ_PROPERTY) GB.ReturnBoolean(DP->rasterOp() == Qt::XorROP); else DP->setRasterOp(VPROP(GB_BOOLEAN) ? Qt::XorROP : Qt::CopyROP);END_PROPERTYBEGIN_PROPERTY(CDRAW_foreground) QPen pen; CHECK_PAINTER(); if (READ_PROPERTY) GB.ReturnInteger(COLOR_TO_INT(DP->pen().color())); else { int col = VPROP(GB_INTEGER); pen = DP->pen(); DP->setPen(QPen(QColor(col), pen.width(), pen.style())); if (DPM) DPM->setPen(QPen(MASK_COLOR(col), pen.width(), pen.style())); }END_PROPERTYBEGIN_PROPERTY(CDRAW_line_width) QPen pen; CHECK_PAINTER(); if (READ_PROPERTY) GB.ReturnInteger(DP->pen().width()); else { pen = DP->pen(); DP->setPen(QPen(pen.color(), VPROP(GB_INTEGER), pen.style())); if (DPM) DPM->setPen(QPen(DPM->pen().color(), VPROP(GB_INTEGER), pen.style())); }END_PROPERTYBEGIN_PROPERTY(CDRAW_line_style) QPen pen; CHECK_PAINTER(); if (READ_PROPERTY) GB.ReturnInteger(DP->pen().style()); else { pen = DP->pen(); DP->setPen(QPen(pen.color(), pen.width(), (Qt::PenStyle)VPROP(GB_INTEGER))); if (DPM) DPM->setPen(QPen(DPM->pen().color(), pen.width(), (Qt::PenStyle)VPROP(GB_INTEGER))); }END_PROPERTYBEGIN_PROPERTY(CDRAW_fill_color) QBrush brush; CHECK_PAINTER(); if (READ_PROPERTY) GB.ReturnInteger(COLOR_TO_INT(DP->brush().color())); else { int col = VPROP(GB_INTEGER); brush = DP->brush(); DP->setBrush(QBrush(QColor(col), brush.style())); if (DPM) DPM->setBrush(QBrush(MASK_COLOR(col), brush.style())); }END_PROPERTYBEGIN_PROPERTY(CDRAW_fill_style) CHECK_PAINTER(); if (READ_PROPERTY) GB.ReturnInteger(DP->brush().style()); else { //qDebug("CDRAW_fill_style: THIS = %p DP = %p DPM = %p", THIS, DP, DPM); QBrush brush(DP->brush().color(), (Qt::BrushStyle)VPROP(GB_INTEGER)); DP->setBrush(brush); if (DPM) { QBrush brushm(DPM->brush().color(), (Qt::BrushStyle)VPROP(GB_INTEGER)); DPM->setBrush(brushm); } }END_PROPERTYBEGIN_PROPERTY(CDRAW_fill_x) CHECK_PAINTER(); if (READ_PROPERTY) GB.ReturnInteger(DP->brushOrigin().x()); else { DP->setBrushOrigin(VPROP(GB_INTEGER), DP->brushOrigin().y()); if (DPM) DPM->setBrushOrigin(VPROP(GB_INTEGER), DPM->brushOrigin().y()); }END_PROPERTYBEGIN_PROPERTY(CDRAW_fill_y) CHECK_PAINTER(); if (READ_PROPERTY) GB.ReturnInteger(DP->brushOrigin().y()); else { DP->setBrushOrigin(DP->brushOrigin().x(), VPROP(GB_INTEGER)); if (DPM) DPM->setBrushOrigin(DPM->brushOrigin().x(), VPROP(GB_INTEGER)); }END_PROPERTYBEGIN_PROPERTY(CDRAW_font) CHECK_PAINTER(); if (READ_PROPERTY) GB.ReturnObject(CFONT_create(DP->font(), CFONT_DRAW)); else { CFONT *font = (CFONT *)VPROP(GB_OBJECT); DRAW_set_font(*font->font); }END_PROPERTYBEGIN_METHOD(CDRAW_rect, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h) CHECK_PAINTER(); DP->drawRect(VARG(x), VARG(y), VARG(w), VARG(h)); if (DPM) DPM->drawRect(VARG(x), VARG(y), VARG(w), VARG(h));END_METHODBEGIN_METHOD(CDRAW_ellipse, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h; GB_FLOAT start; GB_FLOAT len) CHECK_PAINTER(); if (MISSING(start) || MISSING(len)) { DP->drawEllipse(VARG(x), VARG(y), VARG(w), VARG(h)); if (DPM) DPM->drawEllipse(VARG(x), VARG(y), VARG(w), VARG(h)); } else { DP->drawPie(VARG(x), VARG(y), VARG(w), VARG(h), (long)(VARG(start) * 16 + 0.5), (long)(VARG(len) * 16 + 0.5)); if (DPM) DPM->drawPie(VARG(x), VARG(y), VARG(w), VARG(h), (long)(VARG(start) * 16 + 0.5), (long)(VARG(len) * 16 + 0.5)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -