/* * Copyright (c) 2005 Adrian Page * * 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 of the License, 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.g * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_GL #include #include "kis_canvas.h" #include "kis_canvas_painter.h" #include "kis_opengl_canvas_painter.h" KisOpenGLCanvasPainter::KisOpenGLCanvasPainter() : m_active(false), m_widget(0) { } KisOpenGLCanvasPainter::KisOpenGLCanvasPainter(TQGLWidget *widget) : m_active(true), m_widget(widget) { prepareForDrawing(); } KisOpenGLCanvasPainter::~KisOpenGLCanvasPainter() { if (m_widget) { if (m_active) { end(); } m_widget->doneCurrent(); } } bool KisOpenGLCanvasPainter::begin(KisCanvasWidget *canvasWidget, bool /*unclipped*/) { m_widget = dynamic_cast(canvasWidget); if (m_widget != 0) { prepareForDrawing(); return true; } else { return false; } return false; } void KisOpenGLCanvasPainter::prepareForDrawing() { if (m_widget != 0) { m_widget->makeCurrent(); m_active = true; save(); glDrawBuffer(GL_FRONT); glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); glEnable(GL_BLEND); glMatrixMode(GL_TEXTURE); glLoadIdentity(); m_window = TQRect(0, 0, m_widget->width(), m_widget->height()); m_viewport = m_window; updateViewTransformation(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); setPen(m_defaultPen); } } void KisOpenGLCanvasPainter::updateViewTransformation() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); // We don't set the GL viewport directly from the TQt one as the GL // has a limited size. Instead we fold it into the projection matrix. glViewport(0, 0, m_widget->width(), m_widget->height()); glOrtho(0, m_widget->width(), m_widget->height(), 0, -1, 1); glTranslatef(m_viewport.x(), m_viewport.y(), 0.0); glScalef(static_cast(m_viewport.width()) / m_window.width(), static_cast(m_viewport.height()) / m_window.height(), 1.0); glTranslatef(-m_window.x(), -m_window.y(), 0.0); } bool KisOpenGLCanvasPainter::end() { if (m_active) { restore(); m_active = false; return true; } else { return false; } } void KisOpenGLCanvasPainter::save() { glPushAttrib(GL_ALL_ATTRIB_BITS); glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMatrixMode(GL_TEXTURE); glPushMatrix(); } void KisOpenGLCanvasPainter::restore() { glPopAttrib(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glMatrixMode(GL_TEXTURE); glPopMatrix(); } void KisOpenGLCanvasPainter::setPenStyle(TQt::PenStyle penStyle) { if (penStyle == TQt::SolidLine) { glDisable(GL_LINE_STIPPLE); } else { GLushort lineStipple; switch (penStyle) { case TQt::NoPen: lineStipple = 0; break; default: case TQt::DashLine: lineStipple = 0x3fff; break; case TQt::DotLine: lineStipple = 0x3333; break; case TQt::DashDotLine: lineStipple = 0x33ff; break; case TQt::DashDotDotLine: lineStipple = 0x333f; break; } glEnable(GL_LINE_STIPPLE); glLineStipple(1, lineStipple); } } TQFontMetrics KisOpenGLCanvasPainter::fontMetrics() const { return TQFontMetrics(TQFont()); } TQFontInfo KisOpenGLCanvasPainter::fontInfo() const { return TQFontInfo(TQFont()); } const TQFont& KisOpenGLCanvasPainter::font() const { return m_defaultFont; } void KisOpenGLCanvasPainter::setFont(const TQFont& /*font*/) { } const TQPen& KisOpenGLCanvasPainter::pen() const { return m_defaultPen; } void KisOpenGLCanvasPainter::setPen(const TQPen& pen) { setPenStyle(pen.style()); } void KisOpenGLCanvasPainter::setPen(TQt::PenStyle penStyle) { setPenStyle(penStyle); } void KisOpenGLCanvasPainter::setPen(const TQColor& /*color*/) { } const TQBrush& KisOpenGLCanvasPainter::brush() const { return m_defaultBrush; } void KisOpenGLCanvasPainter::setBrush(const TQBrush& /*brush*/) { } void KisOpenGLCanvasPainter::setBrush(TQt::BrushStyle /*brushStyle*/) { } void KisOpenGLCanvasPainter::setBrush(const TQColor& /*color*/) { } TQPoint KisOpenGLCanvasPainter::pos() const { return TQPoint(); } const TQColor& KisOpenGLCanvasPainter::backgroundColor() const { return m_defaultColor; } void KisOpenGLCanvasPainter::setBackgroundColor(const TQColor& /*color*/) { } TQt::BGMode KisOpenGLCanvasPainter::backgroundMode() const { return TQt::TransparentMode; } void KisOpenGLCanvasPainter::setBackgroundMode(TQt::BGMode /*bgMode*/) { } TQt::TQt::RasterOp KisOpenGLCanvasPainter::rasterOp() const { return TQt::CopyROP; } void KisOpenGLCanvasPainter::setRasterOp(TQt::RasterOp /*rasterOp*/) { } const TQPoint& KisOpenGLCanvasPainter::brushOrigin() const { return m_defaultBrushOrigin; } void KisOpenGLCanvasPainter::setBrushOrigin(int /*x*/, int /*y*/) { } void KisOpenGLCanvasPainter::setBrushOrigin(const TQPoint& /*origin*/) { } bool KisOpenGLCanvasPainter::hasViewXForm() const { return false; } bool KisOpenGLCanvasPainter::hasWorldXForm() const { return false; } void KisOpenGLCanvasPainter::setViewXForm(bool /*enable*/) { } TQRect KisOpenGLCanvasPainter::window() const { return m_window; } void KisOpenGLCanvasPainter::setWindow(const TQRect& r) { m_window = r; updateViewTransformation(); } void KisOpenGLCanvasPainter::setWindow(int x, int y, int w, int h) { setWindow(TQRect(x, y, w, h)); } TQRect KisOpenGLCanvasPainter::viewport() const { return m_viewport; } void KisOpenGLCanvasPainter::setViewport(const TQRect& r) { m_viewport = r; updateViewTransformation(); } void KisOpenGLCanvasPainter::setViewport(int x, int y, int w, int h) { setViewport(TQRect(x, y, w, h)); } void KisOpenGLCanvasPainter::setWorldXForm(bool /*enable*/) { } const TQWMatrix& KisOpenGLCanvasPainter::worldMatrix() const { return m_defaultWorldMatrix; } void KisOpenGLCanvasPainter::setWorldMatrix(const TQWMatrix& /*matrix*/, bool /*combine*/) { } void KisOpenGLCanvasPainter::saveWorldMatrix() { } void KisOpenGLCanvasPainter::restoreWorldMatrix() { } void KisOpenGLCanvasPainter::scale(double /*sx*/, double /*sy*/) { } void KisOpenGLCanvasPainter::shear(double /*sh*/, double /*sv*/) { } void KisOpenGLCanvasPainter::rotate(double /*a*/) { } void KisOpenGLCanvasPainter::translate(double dx, double dy) { glMatrixMode(GL_MODELVIEW); glTranslated(dx, dy, 0.0); } void KisOpenGLCanvasPainter::resetXForm() { } double KisOpenGLCanvasPainter::translationX() const { return 0; } double KisOpenGLCanvasPainter::translationY() const { return 0; } TQPoint KisOpenGLCanvasPainter::xForm(const TQPoint& point) const { return point; } TQRect KisOpenGLCanvasPainter::xForm(const TQRect& r) const { return r; } TQPointArray KisOpenGLCanvasPainter::xForm(const TQPointArray& pointArray) const { return pointArray; } TQPointArray KisOpenGLCanvasPainter::xForm(const TQPointArray& pointArray, int /*index*/, int /*npoints*/) const { return pointArray; } TQPoint KisOpenGLCanvasPainter::xFormDev(const TQPoint& point) const { return point; } TQRect KisOpenGLCanvasPainter::xFormDev(const TQRect& r) const { return r; } TQPointArray KisOpenGLCanvasPainter::xFormDev(const TQPointArray& pointArray) const { return pointArray; } TQPointArray KisOpenGLCanvasPainter::xFormDev(const TQPointArray& pointArray, int /*index*/, int /*npoints*/) const { return pointArray; } void KisOpenGLCanvasPainter::setClipping(bool /*enable*/) { } bool KisOpenGLCanvasPainter::hasClipping() const { return true; } TQRegion KisOpenGLCanvasPainter::clipRegion(TQPainter::CoordinateMode /*mode*/) const { return TQRegion(); } void KisOpenGLCanvasPainter::setClipRect(const TQRect& /*r*/, TQPainter::CoordinateMode /*mode*/) { } void KisOpenGLCanvasPainter::setClipRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, TQPainter::CoordinateMode /*mode*/) { } void KisOpenGLCanvasPainter::setClipRegion(const TQRegion& /*rgn*/, TQPainter::CoordinateMode /*mode*/) { } void KisOpenGLCanvasPainter::drawPoint(int x, int y) { glBegin(GL_POINTS); glVertex2i(x, y); glEnd(); } void KisOpenGLCanvasPainter::drawPoint(const TQPoint& point) { drawPoint(point.x(), point.y()); } void KisOpenGLCanvasPainter::drawPoints(const TQPointArray& pointArray, int index, int npoints) { int firstPointIndex = index; if (firstPointIndex < 0) { firstPointIndex = 0; } if (firstPointIndex > (int)pointArray.count() - 1) { return; } int lastPointIndex; if (npoints < 0) { lastPointIndex = pointArray.count() - 1; } else { lastPointIndex = firstPointIndex + npoints; if (lastPointIndex > (int)pointArray.count() - 1) { lastPointIndex = pointArray.count() - 1; } } glBegin(GL_POINTS); for (int pointIndex = firstPointIndex; pointIndex <= lastPointIndex; pointIndex++) { TQPoint point = pointArray.point(pointIndex); glVertex2i(point.x(), point.y()); } glEnd(); } void KisOpenGLCanvasPainter::moveTo(int /*x*/, int /*y*/) { } void KisOpenGLCanvasPainter::moveTo(const TQPoint& /*point*/) { } void KisOpenGLCanvasPainter::lineTo(int /*x*/, int /*y*/) { } void KisOpenGLCanvasPainter::lineTo(const TQPoint& /*point*/) { } void KisOpenGLCanvasPainter::drawLine(int x1, int y1, int x2, int y2) { glBegin(GL_LINES); glVertex2i(x1, y1); glVertex2i(x2, y2); glEnd(); } void KisOpenGLCanvasPainter::drawLine(const TQPoint& start, const TQPoint& end) { drawLine(start.x(), start.y(), end.x(), end.y()); } void KisOpenGLCanvasPainter::drawRect(int x, int y, int w, int h) { glBegin(GL_LINES); glVertex2i(x, y); glVertex2i(x + w - 1, y); glVertex2i(x + w - 1, y); glVertex2i(x + w - 1, y + h - 1); glVertex2i(x + w - 1, y + h - 1); glVertex2i(x, y + h - 1); glVertex2i(x, y + h - 1); glVertex2i(x, y); glEnd(); } void KisOpenGLCanvasPainter::drawRect(const TQRect& r) { drawRect(r.x(), r.y(), r.width(), r.height()); } void KisOpenGLCanvasPainter::drawWinFocusRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/) { } void KisOpenGLCanvasPainter::drawWinFocusRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, const TQColor& /*bgColor*/) { } void KisOpenGLCanvasPainter::drawWinFocusRect(const TQRect& /*r*/) { } void KisOpenGLCanvasPainter::drawWinFocusRect(const TQRect& /*r*/, const TQColor& /*bgColor*/) { } void KisOpenGLCanvasPainter::drawRoundRect(int x, int y, int w, int h, int /*xRnd*/, int /*yRnd*/) { glBegin(GL_LINES); glVertex2i(x, y); glVertex2i(x + w - 1, y); glVertex2i(x + w - 1, y); glVertex2i(x + w - 1, y + h - 1); glVertex2i(x + w - 1, y + h - 1); glVertex2i(x, y + h - 1); glVertex2i(x, y + h - 1); glVertex2i(x, y); glEnd(); } void KisOpenGLCanvasPainter::drawRoundRect(const TQRect& r, int /*xRnd*/, int /*yRnd*/) { drawRoundRect(r.x(), r.y(), r.width(), r.height()); } // void KisOpenGLCanvasPainter::drawRoundRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*xRnd*/, int /*yRnd*/) // { // } // // void KisOpenGLCanvasPainter::drawRoundRect(const TQRect& /*r*/, int /*xRnd*/, int /*yRnd*/) // { // } void KisOpenGLCanvasPainter::drawEllipse(int x, int y, int w, int h) { TQRect r(x, y, w, h); r = r.normalize(); TQPointArray points; points.makeEllipse(r.x(), r.y(), r.width(), r.height()); drawPoints(points); } void KisOpenGLCanvasPainter::drawEllipse(const TQRect& r) { drawEllipse(r.x(), r.y(), r.width(), r.height()); } void KisOpenGLCanvasPainter::drawArc(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*a*/, int /*alen*/) { } void KisOpenGLCanvasPainter::drawArc(const TQRect& /*r*/, int /*a*/, int /*alen*/) { } void KisOpenGLCanvasPainter::drawPie(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*a*/, int /*alen*/) { } void KisOpenGLCanvasPainter::drawPie(const TQRect& /*r*/, int /*a*/, int /*alen*/) { } void KisOpenGLCanvasPainter::drawChord(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*a*/, int /*alen*/) { } void KisOpenGLCanvasPainter::drawChord(const TQRect& /*r*/, int /*a*/, int /*alen*/) { } void KisOpenGLCanvasPainter::drawLineSegments(const TQPointArray& /*pointArray*/, int /*index*/, int /*nlines*/) { } void KisOpenGLCanvasPainter::drawPolyline(const TQPointArray& pointArray, int index, int npoints) { int firstPointIndex = index; if (firstPointIndex < 0) { firstPointIndex = 0; } if (firstPointIndex > (int)pointArray.count() - 2) { return; } int lastPointIndex; if (npoints < 0) { lastPointIndex = pointArray.count() - 1; } else { lastPointIndex = firstPointIndex + npoints - 1; if (lastPointIndex > (int)pointArray.count() - 1) { lastPointIndex = pointArray.count() - 1; } } if (firstPointIndex >= lastPointIndex) { return; } glBegin(GL_LINES); for (int pointIndex = firstPointIndex; pointIndex <= lastPointIndex; pointIndex++) { TQPoint point = pointArray.point(pointIndex); glVertex2i(point.x(), point.y()); } glEnd(); } void KisOpenGLCanvasPainter::drawPolygon(const TQPointArray& /*pointArray*/, bool /*winding*/, int /*index*/, int /*npoints*/) { } void KisOpenGLCanvasPainter::drawConvexPolygon(const TQPointArray& /*pointArray*/, int /*index*/, int /*npoints*/) { } TQPoint midpoint (const TQPoint& P1, const TQPoint& P2) { TQPoint temp; temp.setX((P1.x()+P2.x())/2); temp.setY((P1.y()+P2.y())/2); return temp; } #define MAX_LEVEL 5 void recursiveCurve (const TQPoint& P1, const TQPoint& P2, const TQPoint& P3, const TQPoint& P4, int level, TQValueList& dest) { if (level > MAX_LEVEL) { dest.append(midpoint(P1,P4)); return; } TQPoint L1, L2, L3, L4; TQPoint H, R1, R2, R3, R4; L1 = P1; L2 = midpoint(P1, P2); H = midpoint(P2, P3); R3 = midpoint(P3, P4); R4 = P4; L3 = midpoint(L2, H); R2 = midpoint(R3, H); L4 = midpoint(L3, R2); R1 = L4; recursiveCurve(L1, L2, L3, L4, level + 1, dest); recursiveCurve(R1, R2, R3, R4, level + 1, dest); } void KisOpenGLCanvasPainter::drawCubicBezier(const TQPointArray& pointArray, int index) { TQPoint P1, P2, P3, P4; TQValueList dest; P1 = pointArray[index++]; P2 = pointArray[index++]; P3 = pointArray[index++]; P4 = pointArray[index]; recursiveCurve(P1, P2, P3, P4, 1, dest); glBegin(GL_LINE_STRIP); glVertex2i(P1.x(), P1.y()); for (TQValueList::iterator it = dest.begin(); it != dest.end(); it++) { TQPoint point = (*it); glVertex2i(point.x(), point.y()); } glVertex2i(P4.x(), P4.y()); glEnd(); } void KisOpenGLCanvasPainter::drawPixmap(int /*x*/, int /*y*/, const TQPixmap& /*pixmap*/, int /*sx*/, int /*sy*/, int /*sw*/, int /*sh*/) { } void KisOpenGLCanvasPainter::drawPixmap(const TQPoint& /*point*/, const TQPixmap& /*pixmap*/, const TQRect& /*sr*/) { } void KisOpenGLCanvasPainter::drawPixmap(const TQPoint& /*point*/, const TQPixmap& /*pixmap*/) { } void KisOpenGLCanvasPainter::drawPixmap(const TQRect& /*r*/, const TQPixmap& /*pixmap*/) { } void KisOpenGLCanvasPainter::drawImage(int /*x*/, int /*y*/, const TQImage& /*image*/, int /*sx*/, int /*sy*/, int /*sw*/, int /*sh*/, int /*conversionFlags*/) { } void KisOpenGLCanvasPainter::drawImage(const TQPoint& /*point*/, const TQImage& /*image*/, const TQRect& /*sr*/, int /*conversionFlags*/) { } void KisOpenGLCanvasPainter::drawImage(const TQPoint& /*point*/, const TQImage& /*image*/, int /*conversion_flags*/) { } void KisOpenGLCanvasPainter::drawImage(const TQRect& /*r*/, const TQImage& /*image*/) { } void KisOpenGLCanvasPainter::drawTiledPixmap(int /*x*/, int /*y*/, int /*w*/, int /*h*/, const TQPixmap& /*pixmap*/, int /*sx*/, int /*sy*/) { } void KisOpenGLCanvasPainter::drawTiledPixmap(const TQRect& /*r*/, const TQPixmap& /*pixmap*/, const TQPoint& /*point*/) { } void KisOpenGLCanvasPainter::drawTiledPixmap(const TQRect& /*r*/, const TQPixmap& /*pixmap*/) { } void KisOpenGLCanvasPainter::fillRect(int x, int y, int w, int h, const TQBrush& /*brush*/) { // XXX: Set brush glRecti(x, y, x + w, y + h); } void KisOpenGLCanvasPainter::fillRect(const TQRect& r, const TQBrush& brush) { fillRect(r.x(), r.y(), r.width(), r.height(), brush); } void KisOpenGLCanvasPainter::eraseRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/) { } void KisOpenGLCanvasPainter::eraseRect(const TQRect& /*r*/) { } void KisOpenGLCanvasPainter::drawText(int /*x*/, int /*y*/, const TQString& /*text*/, int /*len*/, TQPainter::TextDirection /*dir*/) { } void KisOpenGLCanvasPainter::drawText(const TQPoint& /*point*/, const TQString& /*text*/, int /*len*/, TQPainter::TextDirection /*dir*/) { } void KisOpenGLCanvasPainter::drawText(int /*x*/, int /*y*/, const TQString& /*text*/, int /*pos*/, int /*len*/, TQPainter::TextDirection /*dir*/) { } void KisOpenGLCanvasPainter::drawText(const TQPoint& /*point*/, const TQString& /*text*/, int /*pos*/, int /*len*/, TQPainter::TextDirection /*dir*/) { } void KisOpenGLCanvasPainter::drawText(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*flags*/, const TQString& /*text*/, int /*len*/, TQRect */*br*/, TQTextParag **/*intern*/) { } void KisOpenGLCanvasPainter::drawText(const TQRect& /*r*/, int /*flags*/, const TQString& /*text*/, int /*len*/, TQRect */*br*/, TQTextParag **/*intern*/) { } void KisOpenGLCanvasPainter::drawTextItem(int /*x*/, int /*y*/, const TQTextItem& /*ti*/, int /*textflags*/) { } void KisOpenGLCanvasPainter::drawTextItem(const TQPoint& /*p*/, const TQTextItem& /*ti*/, int /*textflags*/) { } TQRect KisOpenGLCanvasPainter::boundingRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*flags*/, const TQString& /*text*/, int /*len*/, TQTextParag **/*intern*/) { return TQRect(); } TQRect KisOpenGLCanvasPainter::boundingRect(const TQRect& /*r*/, int /*flags*/, const TQString& /*text*/, int /*len*/, TQTextParag **/*intern*/) { return TQRect(); } int KisOpenGLCanvasPainter::tabStops() const { return 0; } void KisOpenGLCanvasPainter::setTabStops(int /*ts*/) { } int *KisOpenGLCanvasPainter::tabArray() const { return 0; } void KisOpenGLCanvasPainter::setTabArray(int */*ts*/) { } #endif // HAVE_GL