|
|
|
/*
|
|
|
|
* This file is part of Chalk
|
|
|
|
*
|
|
|
|
* Copyright (c) 2006 Cyrille Berger <cberger@cberger.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 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.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "kis_grid_drawer.h"
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_GL
|
|
|
|
#include <tqgl.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "kis_config.h"
|
|
|
|
#include "kis_image.h"
|
|
|
|
#include "kis_perspective_grid.h"
|
|
|
|
#include "kis_perspective_grid_manager.h"
|
|
|
|
|
|
|
|
TQt::PenStyle GridDrawer::gs2style(TQ_UINT32 s)
|
|
|
|
{
|
|
|
|
switch(s)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
return TQt::DashLine;
|
|
|
|
case 2:
|
|
|
|
return TQt::DotLine;
|
|
|
|
case 3:
|
|
|
|
return TQt::DashDotLine;
|
|
|
|
case 4:
|
|
|
|
return TQt::DashDotDotLine;
|
|
|
|
default:
|
|
|
|
return TQt::SolidLine;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GridDrawer::drawPerspectiveGrid(KisImageSP image, const TQRect& /*wr*/, const KisSubPerspectiveGrid* grid)
|
|
|
|
{
|
|
|
|
Q_UNUSED(image);
|
|
|
|
KisConfig cfg;
|
|
|
|
TQPen mainPen = TQPen ( cfg.getGridMainColor(), 1, gs2style( cfg.getGridMainStyle() ) );
|
|
|
|
TQPen subdivisionPen = TQPen ( cfg.getGridSubdivisionColor(), 1, gs2style( cfg.getGridSubdivisionStyle() ) );
|
|
|
|
setPen(subdivisionPen );
|
|
|
|
// 1 -> top-left corner
|
|
|
|
// 2 -> top-right corner
|
|
|
|
// 3 -> bottom-right corner
|
|
|
|
// 4 -> bottom-left corner
|
|
|
|
// d12 line from top-left to top-right
|
|
|
|
// note that the notion of top-left is purely theorical
|
|
|
|
KisPerspectiveMath::LineEquation d12 = KisPerspectiveMath::computeLineEquation( grid->topLeft(), grid->topRight() ) ;
|
|
|
|
KisPoint v12 = KisPoint(*grid->topLeft() - *grid->topRight());
|
|
|
|
v12.setX( v12.x() / grid->subdivisions()); v12.setY( v12.y() / grid->subdivisions() );
|
|
|
|
KisPerspectiveMath::LineEquation d23 = KisPerspectiveMath::computeLineEquation( grid->topRight(), grid->bottomRight() );
|
|
|
|
KisPoint v23 = KisPoint(*grid->topRight() - *grid->bottomRight());
|
|
|
|
v23.setX( v23.x() / grid->subdivisions()); v23.setY( v23.y() / grid->subdivisions() );
|
|
|
|
KisPerspectiveMath::LineEquation d34 = KisPerspectiveMath::computeLineEquation( grid->bottomRight(), grid->bottomLeft() );
|
|
|
|
KisPerspectiveMath::LineEquation d41 = KisPerspectiveMath::computeLineEquation( grid->bottomLeft(), grid->topLeft() );
|
|
|
|
|
|
|
|
KisPoint horizVanishingPoint = KisPerspectiveMath::computeIntersection(d12,d34);
|
|
|
|
KisPoint vertVanishingPoint = KisPerspectiveMath::computeIntersection(d23,d41);
|
|
|
|
|
|
|
|
for(uint i = 1; i < static_cast<uint>(grid->subdivisions()); i ++)
|
|
|
|
{
|
|
|
|
KisPoint pol1 = *grid->topRight() + i * v12;
|
|
|
|
KisPerspectiveMath::LineEquation d1 = KisPerspectiveMath::computeLineEquation( &pol1, &vertVanishingPoint );
|
|
|
|
KisPoint pol1b = KisPerspectiveMath::computeIntersection(d1,d34);
|
|
|
|
drawLine( pol1.roundTQPoint(), pol1b.roundTQPoint() );
|
|
|
|
|
|
|
|
KisPoint pol2 = *grid->bottomRight() + i * v23;
|
|
|
|
KisPerspectiveMath::LineEquation d2 = KisPerspectiveMath::computeLineEquation( &pol2, &horizVanishingPoint );
|
|
|
|
KisPoint pol2b = KisPerspectiveMath::computeIntersection(d2,d41);
|
|
|
|
drawLine( pol2.roundTQPoint(), pol2b.roundTQPoint() );
|
|
|
|
}
|
|
|
|
setPen(mainPen);
|
|
|
|
drawLine( grid->topLeft(), grid->topRight() );
|
|
|
|
drawLine( grid->topRight(), grid->bottomRight() );
|
|
|
|
drawLine( grid->bottomRight(), grid->bottomLeft() );
|
|
|
|
drawLine( grid->bottomLeft(), grid->topLeft() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void GridDrawer::drawGrid(KisImageSP image, const TQRect& wr)
|
|
|
|
{
|
|
|
|
KisConfig cfg;
|
|
|
|
|
|
|
|
TQ_UINT32 offsetx = cfg.getGridOffsetX();
|
|
|
|
TQ_UINT32 offsety = cfg.getGridOffsetY();
|
|
|
|
TQ_UINT32 hspacing = cfg.getGridHSpacing();
|
|
|
|
TQ_UINT32 vspacing = cfg.getGridVSpacing();
|
|
|
|
TQ_UINT32 subdivision = cfg.getGridSubdivisions() - 1;
|
|
|
|
//double ihspsub = hspacing / (double)subdivision;
|
|
|
|
//double ivspsub = hspacing / (double)subdivision;
|
|
|
|
|
|
|
|
TQ_INT32 imageWidth = image->width();
|
|
|
|
TQ_INT32 imageHeight = image->height();
|
|
|
|
|
|
|
|
// Draw vertical line
|
|
|
|
TQPen mainPen = TQPen ( cfg.getGridMainColor(), 1, gs2style( cfg.getGridMainStyle() ) );
|
|
|
|
TQPen subdivisionPen = TQPen ( cfg.getGridSubdivisionColor(), 1, gs2style( cfg.getGridSubdivisionStyle() ) );
|
|
|
|
TQ_UINT32 i = 0;
|
|
|
|
for( TQ_INT32 x = offsetx; x <= wr.right(); x +=hspacing)
|
|
|
|
{
|
|
|
|
if( i == subdivision )
|
|
|
|
{
|
|
|
|
setPen(mainPen);
|
|
|
|
i = 0;
|
|
|
|
} else {
|
|
|
|
setPen(subdivisionPen);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if( x >= wr.x() )
|
|
|
|
{
|
|
|
|
// Always draw the full line otherwise the line stippling varies
|
|
|
|
// with the location of wr and we get glitchy patterns.
|
|
|
|
drawLine(x, 0, x, imageHeight);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Draw horizontal line
|
|
|
|
i = 0;
|
|
|
|
for( TQ_INT32 y = offsety; y <= wr.bottom(); y +=vspacing)
|
|
|
|
{
|
|
|
|
if( i == subdivision )
|
|
|
|
{
|
|
|
|
setPen(mainPen);
|
|
|
|
i = 0;
|
|
|
|
} else {
|
|
|
|
setPen(subdivisionPen);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if( y >= wr.y() )
|
|
|
|
{
|
|
|
|
drawLine(0, y, imageWidth, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
OpenGLGridDrawer::OpenGLGridDrawer()
|
|
|
|
{
|
|
|
|
#ifdef HAVE_GL
|
|
|
|
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
OpenGLGridDrawer::~OpenGLGridDrawer()
|
|
|
|
{
|
|
|
|
#ifdef HAVE_GL
|
|
|
|
glPopAttrib();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGridDrawer::setPen(const TQPen& pen)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_GL
|
|
|
|
TQt::PenStyle penStyle = pen.style();
|
|
|
|
|
|
|
|
if (penStyle == TQt::SolidLine) {
|
|
|
|
glDisable(GL_LINE_STIPPLE);
|
|
|
|
} else {
|
|
|
|
GLushort lineStipple;
|
|
|
|
|
|
|
|
switch (penStyle) {
|
|
|
|
case TQt::NoPen:
|
|
|
|
lineStipple = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case TQt::SolidLine:
|
|
|
|
lineStipple = 0xffff;
|
|
|
|
break;
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQColor penColor = pen.color();
|
|
|
|
|
|
|
|
glColor3ub(penColor.red(), penColor.green(), penColor.blue());
|
|
|
|
#else
|
|
|
|
Q_UNUSED(pen);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGridDrawer::drawLine(TQ_INT32 x1, TQ_INT32 y1, TQ_INT32 x2, TQ_INT32 y2)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_GL
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex2i(x1, y1);
|
|
|
|
glVertex2i(x2, y2);
|
|
|
|
glEnd();
|
|
|
|
#else
|
|
|
|
Q_UNUSED(x1);
|
|
|
|
Q_UNUSED(y1);
|
|
|
|
Q_UNUSED(x2);
|
|
|
|
Q_UNUSED(y2);
|
|
|
|
#endif
|
|
|
|
}
|