Skip to content

Commit

Permalink
Long awaited fix for clipping issues with hard markers.
Browse files Browse the repository at this point in the history
Problem is caused by logic that wants to draw marker onto od number of pixel dimentions always, without having a large enough pixmap allocated to draw it onto.
There is still a problem with diamond marker but other markers are looking good.


git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@5151 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
timlinux committed Apr 3, 2006
1 parent ed8239e commit 904b3b7
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 48 deletions.
93 changes: 46 additions & 47 deletions src/core/qgsmarkercatalogue.cpp
Expand Up @@ -28,6 +28,7 @@ email : blazek@itc.it
#include <QPicture>
#include <QSvgRenderer>

#include "qgis.h"
#include "qgsapplication.h"
#include "qgsmarkercatalogue.h"

Expand Down Expand Up @@ -89,36 +90,12 @@ QPixmap QgsMarkerCatalogue::marker ( QString fullName, int size, QPen pen, QBrus
//std::cerr << "QgsMarkerCatalogue::marker " << fullName.toLocal8Bit().data() << " sice:" << size << std::endl;
if ( fullName.left(5) == "hard:" )
{
QPicture myPicture = hardMarker ( fullName.mid(5), size, pen, brush, qtBug );
QPixmap myPixmap = QPixmap (myPicture.width(),myPicture.height());

// The following is window-system-conditional since (at least)
// the combination of Qt 4.1.0 and RealVNC's Xvnc 4.1
// will result in the pixmap becoming invisible if it is filled
// with a non-opaque colour.
// This is probably because Xvnc 4.1 doesn't have the RENDER
// extension compiled into it.
#if defined(Q_WS_X11)
// Do a runtime test to see if the X RENDER extension is available
if ( myPixmap.x11PictureHandle() )
{
#endif
myPixmap.fill(QColor(255,255,255,0)); // transparent
#if defined(Q_WS_X11)
}
else
{
myPixmap.fill(QColor(255,255,255)); // opaque
}
#endif

QPainter myPainter(&myPixmap);
myPainter.drawPicture(0,0,myPicture);
return myPixmap;
} else if ( fullName.left(4) == "svg:" ) {
return hardMarker ( fullName.mid(5), size, pen, brush, qtBug );
}
else if ( fullName.left(4) == "svg:" )
{
return svgMarker ( fullName.mid(4), size );
}

return QPixmap(); // empty
}

Expand Down Expand Up @@ -160,38 +137,61 @@ QPixmap QgsMarkerCatalogue::svgMarker ( QString filename, int scaleFactor)
return myPixmap;
}

QPicture QgsMarkerCatalogue::hardMarker ( QString name, int s, QPen pen, QBrush brush, bool qtBug )
QPixmap QgsMarkerCatalogue::hardMarker ( QString name, int s, QPen pen, QBrush brush, bool qtBug )
{
QPixmap myPixmap = QPixmap (s+1,s+1);

// The following is window-system-conditional since (at least)
// the combination of Qt 4.1.0 and RealVNC's Xvnc 4.1
// will result in the pixmap becoming invisible if it is filled
// with a non-opaque colour.
// This is probably because Xvnc 4.1 doesn't have the RENDER
// extension compiled into it.
#if defined(Q_WS_X11)
// Do a runtime test to see if the X RENDER extension is available
if ( myPixmap.x11PictureHandle() )
{
#endif
myPixmap.fill(QColor(255,255,255,0)); // transparent
#if defined(Q_WS_X11)
}
else
{
myPixmap.fill(QColor(255,255,255)); // opaque
}
#endif

QPainter myPainter(&myPixmap);
// Size of polygon symbols is calculated so that the area is equal to circle with
// diameter mPointSize

QPicture picture;

// Size for circle
int half = (int)floor(s/2.0); // number of points from center
int size = 2*half + 1; // must be odd
double area = 3.14 * (size/2.) * (size/2.);

// Picture
QPainter picpainter;
picpainter.begin(&picture);
picpainter.setRenderHint(QPainter::Antialiasing);
QPicture picture;
myPainter.begin(&picture);
myPainter.setRenderHint(QPainter::Antialiasing);

// Also width must be odd otherwise there are discrepancies visible in canvas!
int lw = (int)(2*floor((double)pen.width()/2)+1); // -> lw > 0
pen.setWidth(lw);
picpainter.setPen ( pen );
picpainter.setBrush( brush);

myPainter.setPen ( pen );
myPainter.setBrush( brush);
QRect box;

if ( name == "circle" )
{
picpainter.drawEllipse(0, 0, size, size);
std::cout << "Drawing circle of " << size << std::endl;
myPainter.drawEllipse(0, 0, size, size);
}
else if ( name == "rectangle" )
{
size = (int) (2*floor(sqrt(area)/2.) + 1);
picpainter.drawRect(0, 0, size, size);
myPainter.drawRect(0, 0, size, size);
}
else if ( name == "diamond" )
{
Expand All @@ -201,9 +201,9 @@ QPicture QgsMarkerCatalogue::hardMarker ( QString name, int s, QPen pen, QBrush
pa.setPoint ( 1, half, 2*half);
pa.setPoint ( 2, 2*half, half);
pa.setPoint ( 3, half, 0);
picpainter.drawPolygon ( pa );
myPainter.drawPolygon ( pa );
}
// Warning! if pen width > 0 picpainter.drawLine(x1,y1,x2,y2) will draw only (x1,y1,x2-1,y2-1) !
// Warning! if pen width > 0 myPainter.drawLine(x1,y1,x2,y2) will draw only (x1,y1,x2-1,y2-1) !
// It is impossible to draw lines as rectangles because line width scaling would not work
// (QPicture is scaled later in QgsVectorLayer)
// -> reset boundingRect for cross, cross2
Expand All @@ -219,8 +219,8 @@ QPicture QgsMarkerCatalogue::hardMarker ( QString name, int s, QPen pen, QBrush
add = 0;
}

picpainter.drawLine(0, half, size-1+add, half); // horizontal
picpainter.drawLine(half, 0, half, size-1+add); // vertical
myPainter.drawLine(0, half, size-1+add, half); // horizontal
myPainter.drawLine(half, 0, half, size-1+add); // vertical
box.setRect ( 0, 0, size, size );
}
else if ( name == "cross2" )
Expand All @@ -237,18 +237,17 @@ QPicture QgsMarkerCatalogue::hardMarker ( QString name, int s, QPen pen, QBrush

int addwidth = (int) ( 0.5 * lw ); // width correction, cca lw/2 * cos(45)

picpainter.drawLine( 0, 0, size-1+add, size-1+add);
picpainter.drawLine( 0, size-1, size-1+add, 0-add);
myPainter.drawLine( 0, 0, size-1+add, size-1+add);
myPainter.drawLine( 0, size-1, size-1+add, 0-add);

box.setRect ( -addwidth, -addwidth, size + 2*addwidth, size + 2*addwidth );
}
picpainter.end();

if ( name == "cross" || name == "cross2" )
{
picture.setBoundingRect ( box );
}
myPainter.end();

return picture;
return myPixmap;
}

2 changes: 1 addition & 1 deletion src/core/qgsmarkercatalogue.h
Expand Up @@ -56,7 +56,7 @@ class QgsMarkerCatalogue{
QStringList mList;

/** Hard coded */
QPicture hardMarker ( QString name, int size, QPen pen, QBrush brush, bool qtBug = true );
QPixmap hardMarker ( QString name, int size, QPen pen, QBrush brush, bool qtBug = true );

};

Expand Down

0 comments on commit 904b3b7

Please sign in to comment.