Commit fccc6234 authored by David Saxton's avatar David Saxton

* Switch to antialiasing for drawing grid (but not for plots atm, as that gives

  a blurred-pixelated-line effect).
* Switched to using mm for storing line widths, and adapted code to allow for
  QPen scaling in Qt4.

svn path=/trunk/KDE/kdeedu/kmplot/; revision=522140
parent cc022ad6
......@@ -507,7 +507,7 @@ void MainDlg::editColors()
// User edited the configuration - update your local copies of the
// configuration data
connect( colorsDialog, SIGNAL( settingsChanged() ), this, SLOT(updateSettings() ) );
connect( colorsDialog, SIGNAL( settingsChanged(const QString &) ), this, SLOT(updateSettings() ) );
colorsDialog->show();
}
......@@ -519,7 +519,7 @@ void MainDlg::editAxes()
coordsDialog = new CoordsConfigDialog( view->parser(), m_parent);
// User edited the configuration - update your local copies of the
// configuration data
connect( coordsDialog, SIGNAL( settingsChanged() ), this, SLOT(updateSettings() ) );
connect( coordsDialog, SIGNAL( settingsChanged(const QString &) ), this, SLOT(updateSettings() ) );
}
coordsDialog->show();
}
......@@ -532,7 +532,7 @@ void MainDlg::editScaling()
scalingDialog->addPage( new SettingsPageScaling( 0, "scalingSettings" ), i18n( "Scale" ), "scaling", i18n( "Edit Scaling" ) );
// User edited the configuration - update your local copies of the
// configuration data
connect( scalingDialog, SIGNAL( settingsChanged() ), this, SLOT(updateSettings() ) );
connect( scalingDialog, SIGNAL( settingsChanged(const QString &) ), this, SLOT(updateSettings() ) );
scalingDialog->show();
}
......@@ -544,7 +544,7 @@ void MainDlg::editFonts()
fontsDialog->addPage( new SettingsPageFonts( 0, "fontsSettings" ), i18n( "Fonts" ), "fonts", i18n( "Edit Fonts" ) );
// User edited the configuration - update your local copies of the
// configuration data
connect( fontsDialog, SIGNAL( settingsChanged() ), this, SLOT(updateSettings() ) );
connect( fontsDialog, SIGNAL( settingsChanged(const QString &) ), this, SLOT(updateSettings() ) );
fontsDialog->show();
}
......
......@@ -62,12 +62,25 @@
#include "View.h"
#include "View.moc"
// other includes
#include <assert.h>
#include <cmath>
//minimum and maximum x range. Should always be accessible.
double View::xmin = 0;
double View::xmax = 0;
View::View(bool const r, bool &mo, KMenu *p, QWidget* parent, KActionCollection *ac, const char* name ) : DCOPObject("View"), QWidget( parent, name , Qt::WStaticContents ), buffer( width(), height() ), m_popupmenu(p), m_modified(mo), m_readonly(r), m_dcop_client(KApplication::kApplication()->dcopClient()), m_ac(ac)
View::View(bool const r, bool &mo, KMenu *p, QWidget* parent, KActionCollection *ac, const char* name )
: DCOPObject("View"),
QWidget( parent, name , Qt::WStaticContents ),
dgr(this),
buffer( width(), height() ),
m_popupmenu(p),
m_modified(mo),
m_readonly(r),
m_dcop_client(KApplication::kApplication()->dcopClient()),
m_ac(ac)
{
csmode = csparam = -1;
cstype = 0;
......@@ -127,7 +140,6 @@ void View::draw(QPaintDevice *dev, int form)
QRect rc;
QPainter DC; // our painter
DC.begin(dev); // start painting widget
// DC.setRenderHint( QPainter::Antialiasing );
rc=DC.viewport();
w=rc.width();
h=rc.height();
......@@ -192,11 +204,11 @@ void View::draw(QPaintDevice *dev, int form)
s=1.;
}
dgr.borderThickness=(uint)(4*s);
dgr.axesLineWidth = (uint)( Settings::axesLineWidth()*s );
dgr.gridLineWidth = (uint)( Settings::gridLineWidth()*s );
dgr.ticWidth = (uint)( Settings::ticWidth()*s );
dgr.ticLength = (uint)( Settings::ticLength() );
dgr.borderThickness = 0.4;
dgr.axesLineWidth = Settings::axesLineWidth();
dgr.gridLineWidth = Settings::gridLineWidth();
dgr.ticWidth = Settings::ticWidth();
dgr.ticLength = Settings::ticLength();
dgr.axesColor = Settings::axesColor().rgb();
dgr.gridColor=Settings::gridColor().rgb();
dgr.Skal( tlgx, tlgy );
......@@ -209,7 +221,9 @@ void View::draw(QPaintDevice *dev, int form)
return;
}
DC.setRenderHint( QPainter::Antialiasing, true );
dgr.Plot(&DC);
PlotArea=dgr.GetPlotArea();
area=DC.xForm(PlotArea);
stepWidth=Settings::stepWidth();
......@@ -217,6 +231,11 @@ void View::draw(QPaintDevice *dev, int form)
isDrawing=true;
setCursor(Qt::WaitCursor );
stop_calculating = false;
// Antialiasing is *not* used for drawing the plots, as lines (of a shallow gradient)
// drawn one pixel at a time with antialiasing turned on do not look smooth -
// instead, they look like a pixelated line that has been blurred.
DC.setRenderHint( QPainter::Antialiasing, false );
for(QVector<Ufkt>::iterator ufkt=m_parser->ufkt.begin(); ufkt!=m_parser->ufkt.end() && !stop_calculating; ++ufkt)
if ( !ufkt->fname.isEmpty() )
plotfkt(ufkt, &DC);
......@@ -233,8 +252,6 @@ void View::plotfkt(Ufkt *ufkt, QPainter *pDC)
int iy, k, ke, mflg;
double x, y, dmin, dmax;
QPointF p1, p2;
QPen pen;
pen.setCapStyle(Qt::RoundCap);
iy=0;
y=0.0;
......@@ -272,23 +289,13 @@ void View::plotfkt(Ufkt *ufkt, QPainter *pDC)
if(fktmode=='x')
iy = m_parser->ixValue(ufkt->id)+1;
p_mode=0;
/// \todo ensure that this line width setting works for mediums other than screen
pen.setWidth((int)(ufkt->linewidth) );
if ( (ufkt->linewidth * s) < 1 )
{
// this checks that the pen width *after* transformation by QPainter is at least one pixel
// (a pen width of 0 is one pixel; but if the pen width is non-zero, then after scaling by s,
// the width could end up between 0 and 1 - resulting in a dotty line when drawing on the screen).
pen.setWidth( 0 );
}
pen.setColor(ufkt->color);
pDC->setPen(pen);
p_mode=0;
while(1)
{
pDC->setPen( penForPlot( ufkt, p_mode, pDC->renderHints() & QPainter::Antialiasing ) );
k=0;
ke=ufkt->parameters.count();
do
......@@ -424,34 +431,80 @@ void View::plotfkt(Ufkt *ufkt, QPainter *pDC)
}
while(++k<ke);
if(ufkt->f1_mode==1 && p_mode< 1) //draw the 1st derivative
{
p_mode=1;
pen.setWidth((int)(ufkt->f1_linewidth*s) );
pen.setColor(ufkt->f1_color);
pDC->setPen(pen);
}
else if(ufkt->f2_mode==1 && p_mode< 2) //draw the 2nd derivative
{
p_mode=2;
pen.setWidth((int)(ufkt->f2_linewidth*s) );
pen.setColor(ufkt->f2_color);
pDC->setPen(pen);
}
else if( ufkt->integral_mode==1 && p_mode< 3) //draw the integral
{
p_mode=3;
pen.setWidth((int)(ufkt->integral_linewidth*s) );
pen.setColor(ufkt->integral_color);
pDC->setPen(pen);
}
else break; //otherwise stop
// Advance to the next appropriate p_mode
if (ufkt->f1_mode==1 && p_mode< 1)
p_mode=1; //draw the 1st derivative
else if(ufkt->f2_mode==1 && p_mode< 2)
p_mode=2; //draw the 2nd derivative
else if( ufkt->integral_mode==1 && p_mode< 3)
p_mode=3; //draw the integral
else
break; // no derivatives or integrals left to draw
}
if ( stopProgressBar() )
if( stop_calculating)
KMessageBox::error(this,i18n("The drawing was cancelled by the user."));
}
QPen View::penForPlot( Ufkt *ufkt, int p_mode, bool antialias ) const
{
QPen pen;
pen.setCapStyle(Qt::RoundCap);
pen.setColor(ufkt->color);
double lineWidth_mm;
switch ( p_mode )
{
case 0:
lineWidth_mm = ufkt->linewidth;
break;
case 1:
lineWidth_mm = ufkt->f1_linewidth;
break;
case 2:
lineWidth_mm = ufkt->f2_linewidth;
break;
case 3:
lineWidth_mm = ufkt->integral_linewidth;
break;
default:
assert( !"Unknown p_mode" );
}
double width = mmToPenWidth( lineWidth_mm, antialias );
if ( (width*s < 3) && !antialias )
{
// Plots in general are curvy lines - so if a plot is drawn with a QPen
// of width 1 or 2, then we will get a patchy, twinkling line. So set
// the width to zero (i.e. a cosmetic pen).
width = 0;
}
pen.setWidthF( width );
return pen;
}
double View::mmToPenWidth( double width_mm, bool antialias ) const
{
/// \todo ensure that this line width setting works for mediums other than screen
double w = width_mm*10.0;
if ( !antialias )
{
// To avoid a twinkling, patchy line, have to adjust the pen width
// so that after scaling by QPainter (by a factor of s), it is of an
// integer width.
w = std::floor(w*s)/s;
}
return w;
}
void View::drawHeaderTable(QPainter *pDC)
{
QString alx, aly, atx, aty, dfx, dfy;
......
......@@ -112,6 +112,9 @@ public:
/// Menu actions for the sliders
KToggleAction *mnuSliders[ SLIDER_COUNT ];
void updateSliders(); /// show only needed sliders
/// Convert a width in mm to a suitable QPen width for drawing
double mmToPenWidth( double width_mm, bool antialias ) const;
public slots:
/// Called when the user want to cancel the drawing
......@@ -158,6 +161,8 @@ private:
void drawHeaderTable(QPainter *);
/// Draw the function plots.
void plotfkt(Ufkt *ufkt, QPainter*);
/// @return an appropriate pen for drawing the plot
QPen penForPlot( Ufkt * ufkt, int p_mode, bool antialias ) const;
/// Gets the greek pi symbol.
void setpi(QString *);
/// in trace mode checks, if the function is (near by) zero
......
......@@ -27,6 +27,7 @@
//local includes
#include "diagr.h"
#include "settings.h"
#include "View.h"
#ifdef __osf__
#include <nan.h>
......@@ -44,12 +45,14 @@ int isinf(double x)
#include <kdebug.h>
CDiagr::CDiagr()
CDiagr::CDiagr( View * _view )
{
view = _view;
frameColor=qRgb(0, 0, 0);
axesColor=qRgb(0, 0, 0);
gridColor=qRgb(192, 192, 192);
borderThickness=2;
borderThickness = 0.2;
axesLineWidth = Settings::axesLineWidth();
gridLineWidth = Settings::gridLineWidth();
ticWidth = Settings::ticWidth();
......@@ -108,7 +111,7 @@ void CDiagr::Skal( double ex, double ey )
void CDiagr::Plot(QPainter* pDC)
{
QPen pen(QColor(frameColor), borderThickness);
QPen pen(QColor(frameColor), view->mmToPenWidth( borderThickness, true ) );
if( g_mode != GRID_NONE )
drawGrid( pDC ); // draw the grid
......@@ -229,7 +232,7 @@ void CDiagr::drawAxes( QPainter* pDC ) // draw axes
if( Settings::showAxes() )
{
pDC->setPen( QPen( QColor(axesColor), axesLineWidth ) );
pDC->setPen( QPen( QColor(axesColor), view->mmToPenWidth(axesLineWidth, true) ) );
a=PlotArea.right();
b=TransyToPixel(0.);
pDC->Lineh(PlotArea.left(), b, a); // x-Achse
......@@ -251,22 +254,22 @@ void CDiagr::drawAxes( QPainter* pDC ) // draw axes
}
}
pDC->setPen( QPen( QColor(axesColor), ticWidth ) );
pDC->setPen( QPen( QColor(axesColor), view->mmToPenWidth(ticWidth, true) ) );
if( Settings::showAxes() )
{
da=oy-ticLength;
db=oy+ticLength;
tl= Settings::showFrame()? 0: ticLength;
da=oy-(ticLength*10.0);
db=oy+(ticLength*10.0);
tl= Settings::showFrame()? 0: (ticLength*10.0);
d=tsx;
if(da<(double)PlotArea.top())
{
a=PlotArea.top()-tl;
b=PlotArea.top()+ticLength;
b=PlotArea.top()+int(10.0*ticLength);
}
else if(db>(double)PlotArea.bottom())
{
b=PlotArea.bottom()+tl;
a=PlotArea.bottom()-ticLength;
a=PlotArea.bottom()-(10.0*ticLength);
}
else
{
......@@ -280,18 +283,18 @@ void CDiagr::drawAxes( QPainter* pDC ) // draw axes
d+=ex;
}
da=ox-ticLength;
db=ox+ticLength;
da=ox-(10.0*ticLength);
db=ox+(10.0*ticLength);
d=tsy;
if(da<(double)PlotArea.left())
{
a=PlotArea.left()-tl;
b=PlotArea.left()+ticLength;
b=PlotArea.left()+(10.0*ticLength);
}
else if(db>(double)PlotArea.right())
{
b=PlotArea.right()+tl;
a=PlotArea.right()-ticLength;
a=PlotArea.right()-(10.0*ticLength);
}
else
{
......@@ -307,8 +310,8 @@ void CDiagr::drawAxes( QPainter* pDC ) // draw axes
}
else if( Settings::showFrame() )
{
a=PlotArea.bottom()+ticLength;
b=PlotArea.top()-ticLength;
a=PlotArea.bottom()+(ticLength*10.0);
b=PlotArea.top()-(ticLength*10.0);
d=tsx;
while(d<xmd)
{
......@@ -317,8 +320,8 @@ void CDiagr::drawAxes( QPainter* pDC ) // draw axes
d+=ex;
}
a=PlotArea.left()+ticLength;
b=PlotArea.right()-ticLength;
a=PlotArea.left()+(ticLength*10.0);
b=PlotArea.right()-(ticLength*10.0);
d=tsy;
while(d<ymd)
{
......@@ -334,7 +337,7 @@ void CDiagr::drawGrid( QPainter* pDC )
{
double a, b;
double d, x, y;
QPen pen( QColor(gridColor), gridLineWidth );
QPen pen( QColor(gridColor), view->mmToPenWidth(gridLineWidth, true) );
pDC->setPen(pen);
if( g_mode==GRID_LINES )
......
......@@ -50,13 +50,15 @@
#define GRID_POLAR 3
//@}
class View;
/** @short This class manages the core drawing of the axes and the grid. */
class CDiagr
{
public:
/// Contructor. Members are set to initial values.
///@see Create()
CDiagr();
CDiagr( View * view );
/// Nothing to do for the destructor.
~CDiagr();
......@@ -91,14 +93,14 @@ public:
QRgb axesColor; ///< color of the axes
QRgb gridColor; ///< color of the grid
uint borderThickness, ///< current line width for the border frame
axesLineWidth, ///< current line width for the axes
gridLineWidth, ///< current line width for the grid
ticWidth, ///< current line width for the tics
ticLength, ///< current length of the tic lines
double borderThickness; ///< current line width for the border frame in mm
double axesLineWidth; ///< current line width for the axes in mm
double gridLineWidth; ///< current line width for the grid in mm
double ticWidth; ///< current line width for the tics in mm
double ticLength; ///< current length of the tic lines in mm
//@}
xclipflg, ///< clipflg is set to 1 if the plot is out of the plot aerea.
yclipflg; ///< clipflg is set to 1 if the plot is out of the plot aerea.
bool xclipflg; ///< clipflg is set to 1 if the plot is out of the plot aerea.
bool yclipflg; ///< clipflg is set to 1 if the plot is out of the plot aerea.
private:
......@@ -140,6 +142,8 @@ private:
QRect PlotArea; ///< plot area
QRect m_frame; ///< frame around the plot
View * view; ///< Pointer to parent View
};
#endif // diagr_included
......@@ -8,8 +8,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>491</width>
<height>432</height>
<width>240</width>
<height>380</height>
</rect>
</property>
<property name="windowTitle" >
......@@ -50,62 +50,58 @@
<property name="spacing" >
<number>6</number>
</property>
<item row="0" column="2" >
<widget class="QLabel" name="TextLabel2_2_2" >
<property name="text" >
<string>0.1mm</string>
<item row="0" column="1" >
<widget class="QDoubleSpinBox" name="lineWidthDerivative1" >
<property name="alignment" >
<set>Qt::AlignRight</set>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="KColorButton" name="colorDerivative1" >
<property name="enabled" >
<bool>false</bool>
<property name="suffix" >
<string> mm</string>
</property>
<property name="toolTip" >
<string>color of the plot line</string>
<property name="decimals" >
<number>1</number>
</property>
<property name="whatsThis" >
<string>Click this button to choose a color for the plot line.</string>
<property name="minimum" >
<double>0.1</double>
</property>
<property name="text" >
<string/>
<property name="singleStep" >
<double>0.1</double>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="textLabel2_2_2" >
<item row="0" column="0" >
<widget class="QLabel" name="textLabel1_3_2_2" >
<property name="text" >
<string>&amp;Color:</string>
<string>&amp;Line width:</string>
</property>
<property name="buddy" >
<cstring>colorDerivative1</cstring>
<cstring></cstring>
</property>
</widget>
</item>
<item row="0" column="0" >
<widget class="QLabel" name="textLabel1_3_2_2" >
<item row="1" column="0" >
<widget class="QLabel" name="textLabel2_2_2" >
<property name="text" >
<string>&amp;Line width:</string>
<string>&amp;Color:</string>
</property>
<property name="buddy" >
<cstring>lineWidthDerivative1</cstring>
<cstring>colorDerivative1</cstring>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="KIntNumInput" name="lineWidthDerivative1" >
<item row="1" column="1" >
<widget class="KColorButton" name="colorDerivative1" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="toolTip" >
<string>width of the plot line</string>
<string>color of the plot line</string>
</property>
<property name="whatsThis" >
<string>Change the width of the plot line in steps of 0.1mm.</string>
<string>Click this button to choose a color for the plot line.</string>
</property>
<property name="minimum" >
<number>1</number>
<property name="text" >
<string/>
</property>
</widget>
</item>
......@@ -141,35 +137,21 @@
<number>6</number>
</property>
<item row="0" column="1" >
<widget class="KIntNumInput" name="lineWidthDerivative2" >
<property name="enabled" >
<bool>false</bool>
<widget class="QDoubleSpinBox" name="lineWidthDerivative2" >
<property name="alignment" >
<set>Qt::AlignRight</set>
</property>
<property name="toolTip" >
<string>width of the plot line</string>
</property>
<property name="whatsThis" >
<string>Change the width of the plot line in steps of 0.1mm.</string>
<property name="suffix" >
<string> mm</string>
</property>
<property name="minimum" >
<property name="decimals" >
<number>1</number>
</property>
</widget>
</item>
<item row="0" column="2" >
<widget class="QLabel" name="TextLabel2_2" >
<property name="text" >
<string>0.1mm</string>
</property>
</widget>
</item>
<item row="0" column="0" >
<widget class="QLabel" name="textLabel1_3_2" >
<property name="text" >
<string>Line &amp;width:</string>
<property name="minimum" >
<double>0.1</double>
</property>
<property name="buddy" >
<cstring>lineWidthDerivative2</cstring>
<property name="singleStep" >
<double>0.1</double>
</property>
</widget>
</item>
......@@ -199,6 +181,16 @@
</property>
</widget>
</item>
<item row="0" column="0" >
<widget class="QLabel" name="textLabel1_3_2" >
<property name="text" >
<string>Line &amp;width:</string>
</property>
<property name="buddy" >
<cstring></cstring>
</property>
</widget>
</item>
</layout>
</widget>
</item>
......@@ -209,8 +201,8 @@
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
<width>51</width>
<height>41</height>
</size>
</property>
</spacer>
......@@ -227,13 +219,6 @@
<container>0</container>
<pixmap></pixmap>
</customwidget>
<customwidget>
<class>KIntNumInput</class>
<extends></extends>
<header>knuminput.h</header>
<container>0</container>
<pixmap></pixmap>
</customwidget>
</customwidgets>
<resources/>
<connections>
......
......@@ -11,8 +11,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>452</width>