krita

kis_grid_drawer.cpp

00001 /*
00002  * This file is part of Krita
00003  *
00004  *  Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  */
00020  
00021 #include "kis_grid_drawer.h"
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #ifdef HAVE_GL
00028 #include <qgl.h>
00029 #endif
00030 
00031 #include "kis_config.h"
00032 #include "kis_image.h"
00033 #include "kis_perspective_grid.h"
00034 #include "kis_perspective_grid_manager.h"
00035 
00036 Qt::PenStyle GridDrawer::gs2style(Q_UINT32 s)
00037 {
00038     switch(s)
00039     {
00040         case 1:
00041             return Qt::DashLine;
00042         case 2:
00043             return Qt::DotLine;
00044         case 3:
00045             return Qt::DashDotLine;
00046         case 4:
00047             return Qt::DashDotDotLine;
00048         default:
00049             return Qt::SolidLine;
00050     }
00051 }
00052 
00053 void GridDrawer::drawPerspectiveGrid(KisImageSP image, const QRect& /*wr*/, const KisSubPerspectiveGrid* grid)
00054 {
00055     Q_UNUSED(image);
00056     KisConfig cfg;
00057     QPen mainPen = QPen ( cfg.getGridMainColor(), 1, gs2style( cfg.getGridMainStyle() ) );
00058     QPen subdivisionPen =  QPen ( cfg.getGridSubdivisionColor(), 1, gs2style( cfg.getGridSubdivisionStyle() ) );
00059     setPen(subdivisionPen );
00060     // 1 -> top-left corner
00061     // 2 -> top-right corner
00062     // 3 -> bottom-right corner
00063     // 4 -> bottom-left corner
00064     // d12 line from top-left to top-right
00065     // note that the notion of top-left is purely theorical
00066     KisPerspectiveMath::LineEquation d12 = KisPerspectiveMath::computeLineEquation( grid->topLeft(), grid->topRight() ) ;
00067     KisPoint v12 = KisPoint(*grid->topLeft() - *grid->topRight());
00068     v12.setX( v12.x() / grid->subdivisions()); v12.setY( v12.y() / grid->subdivisions() );
00069     KisPerspectiveMath::LineEquation d23 = KisPerspectiveMath::computeLineEquation( grid->topRight(), grid->bottomRight() );
00070     KisPoint v23 = KisPoint(*grid->topRight() - *grid->bottomRight());
00071     v23.setX( v23.x() / grid->subdivisions()); v23.setY( v23.y() / grid->subdivisions() );
00072     KisPerspectiveMath::LineEquation d34 = KisPerspectiveMath::computeLineEquation( grid->bottomRight(), grid->bottomLeft() );
00073     KisPerspectiveMath::LineEquation d41 = KisPerspectiveMath::computeLineEquation( grid->bottomLeft(), grid->topLeft() );
00074     
00075     KisPoint horizVanishingPoint = KisPerspectiveMath::computeIntersection(d12,d34);
00076     KisPoint vertVanishingPoint = KisPerspectiveMath::computeIntersection(d23,d41);
00077     
00078     for(uint i = 1; i < static_cast<uint>(grid->subdivisions()); i ++)
00079     {
00080         KisPoint pol1 = *grid->topRight() + i * v12;
00081         KisPerspectiveMath::LineEquation d1 = KisPerspectiveMath::computeLineEquation( &pol1, &vertVanishingPoint );
00082         KisPoint pol1b =  KisPerspectiveMath::computeIntersection(d1,d34);
00083         drawLine( pol1.roundQPoint(), pol1b.roundQPoint() );
00084         
00085         KisPoint pol2 = *grid->bottomRight() + i * v23;
00086         KisPerspectiveMath::LineEquation d2 = KisPerspectiveMath::computeLineEquation( &pol2, &horizVanishingPoint );
00087         KisPoint pol2b = KisPerspectiveMath::computeIntersection(d2,d41);
00088         drawLine( pol2.roundQPoint(), pol2b.roundQPoint() );
00089     }
00090     setPen(mainPen);
00091     drawLine( grid->topLeft(), grid->topRight() );
00092     drawLine( grid->topRight(), grid->bottomRight() );
00093     drawLine( grid->bottomRight(), grid->bottomLeft() );
00094     drawLine( grid->bottomLeft(), grid->topLeft() );
00095 }
00096 
00097 void GridDrawer::drawGrid(KisImageSP image, const QRect& wr)
00098 {
00099     KisConfig cfg;
00100     
00101     Q_UINT32 offsetx = cfg.getGridOffsetX();
00102     Q_UINT32 offsety = cfg.getGridOffsetY();
00103     Q_UINT32 hspacing = cfg.getGridHSpacing();
00104     Q_UINT32 vspacing = cfg.getGridVSpacing();
00105     Q_UINT32 subdivision = cfg.getGridSubdivisions() - 1;
00106     //double ihspsub = hspacing / (double)subdivision;
00107     //double ivspsub = hspacing / (double)subdivision;
00108 
00109     Q_INT32 imageWidth = image->width();
00110     Q_INT32 imageHeight = image->height();
00111 
00112     // Draw vertical line
00113     QPen mainPen = QPen ( cfg.getGridMainColor(), 1, gs2style( cfg.getGridMainStyle() ) );
00114     QPen subdivisionPen = QPen ( cfg.getGridSubdivisionColor(), 1, gs2style( cfg.getGridSubdivisionStyle() ) );
00115     Q_UINT32 i = 0;
00116     for( Q_INT32 x = offsetx; x <= wr.right(); x +=hspacing)
00117     {
00118         if( i == subdivision )
00119         {
00120             setPen(mainPen);
00121             i = 0;
00122         } else {
00123             setPen(subdivisionPen);
00124             i++;
00125         }
00126         if( x >= wr.x() )
00127         {
00128             // Always draw the full line otherwise the line stippling varies
00129             // with the location of wr and we get glitchy patterns.
00130             drawLine(x, 0, x, imageHeight);
00131         }
00132     }
00133     // Draw horizontal line
00134     i = 0;
00135     for( Q_INT32 y = offsety; y <= wr.bottom(); y +=vspacing)
00136     {
00137         if( i == subdivision )
00138         {
00139             setPen(mainPen);
00140             i = 0;
00141         } else {
00142             setPen(subdivisionPen);
00143             i++;
00144         }
00145         if( y >= wr.y() )
00146         {
00147             drawLine(0, y, imageWidth, y);
00148         }
00149     }
00150 }
00151 
00152 OpenGLGridDrawer::OpenGLGridDrawer()
00153 {
00154 #ifdef HAVE_GL
00155     glPushAttrib(GL_ALL_ATTRIB_BITS);
00156 #endif
00157 }
00158 
00159 OpenGLGridDrawer::~OpenGLGridDrawer()
00160 {
00161 #ifdef HAVE_GL
00162     glPopAttrib();
00163 #endif
00164 }
00165 
00166 void OpenGLGridDrawer::setPen(const QPen& pen)
00167 {
00168 #ifdef HAVE_GL
00169     Qt::PenStyle penStyle = pen.style();
00170 
00171     if (penStyle == Qt::SolidLine) {
00172         glDisable(GL_LINE_STIPPLE);
00173     } else {
00174         GLushort lineStipple;
00175 
00176         switch (penStyle) {
00177         case Qt::NoPen:
00178             lineStipple = 0;
00179             break;
00180         default:
00181         case Qt::SolidLine:
00182             lineStipple = 0xffff;
00183             break;
00184         case Qt::DashLine:
00185             lineStipple = 0x3fff;
00186             break;
00187         case Qt::DotLine:
00188             lineStipple = 0x3333;
00189             break;
00190         case Qt::DashDotLine:
00191             lineStipple = 0x33ff;
00192             break;
00193         case Qt::DashDotDotLine:
00194             lineStipple = 0x333f;
00195             break;
00196         }
00197 
00198         glEnable(GL_LINE_STIPPLE);
00199         glLineStipple(1, lineStipple);
00200     }
00201 
00202     QColor penColor = pen.color();
00203 
00204     glColor3ub(penColor.red(), penColor.green(), penColor.blue());
00205 #else
00206     Q_UNUSED(pen);
00207 #endif
00208 }
00209 
00210 void OpenGLGridDrawer::drawLine(Q_INT32 x1, Q_INT32 y1, Q_INT32 x2, Q_INT32 y2)
00211 {
00212 #ifdef HAVE_GL
00213     glBegin(GL_LINES);
00214     glVertex2i(x1, y1);
00215     glVertex2i(x2, y2);
00216     glEnd();
00217 #else
00218     Q_UNUSED(x1);
00219     Q_UNUSED(y1);
00220     Q_UNUSED(x2);
00221     Q_UNUSED(y2);
00222 #endif
00223 }
KDE Home | KDE Accessibility Home | Description of Access Keys