Skip to content

Commit

Permalink
Update version to 0.7.9.10
Browse files Browse the repository at this point in the history
Deprecated use of Q3Picture for marker symbols as part of the qt4 porting effort.
Markers are now loaded and renderered using the new QSvgRenderer that came with qt 4.1
onto a qpixmap. QgsSvgCache now stores these pixmaps intead of q3pictures.
Changed miscellanious other classes to deal wiht the knock-on effect of this cahnge.
A benifit of this change is that svgs are now rendered properly (overlooking caveaat below) 
and that the resampling code that was used to overcome poor svg scaling in qpitcure in qt3 is 
no longer used. Also we are able to support a richer subset of the svg format including 
possibility for animated svg in the future.

NOTE: there is still a small renderning issue where the background of the svg and various other
small issues - these will be fixed in follow up commits


git-svn-id: http://svn.osgeo.org/qgis/trunk@4721 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
timlinux committed Jan 23, 2006
1 parent 826096d commit eeff2cf
Show file tree
Hide file tree
Showing 21 changed files with 232 additions and 324 deletions.
3 changes: 3 additions & 0 deletions ChangeLog
@@ -1,6 +1,9 @@
/* ChangeLog,v 1.214 2004/11/12 00:42:21 gsherman Exp */
------------------------------------------------------------------------------
Version 0.8 'Joesephine' .... development version
2006-01-23 [timlinux] 0.7.9.10
** Dropped use of qpicture and resampling for point markers in favour of
qt4.1 qsvgrenderer new goodies
2006-01-09 [timlinux] 0.7.9.8
** Moved plugins into src/plugins
2006-01-08 [timlinux] 0.7.9.8
Expand Down
2 changes: 1 addition & 1 deletion configure.in
Expand Up @@ -29,7 +29,7 @@ dnl ---------------------------------------------------------------------------
MAJOR_VERSION=0
MINOR_VERSION=7
MICRO_VERSION=9
EXTRA_VERSION=9
EXTRA_VERSION=10
if test $EXTRA_VERSION -eq 0; then
VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}
else
Expand Down
13 changes: 6 additions & 7 deletions src/composer/qgscomposervectorlegend.cpp
Expand Up @@ -303,10 +303,10 @@ QRect QgsComposerVectorLegend::render ( QPainter *p )
if ( itemHeights[icnt] < mSymbolHeight ) { // init first
itemHeights[icnt] = mSymbolHeight;
}
Q3Picture pic = sym->getPointSymbolAsPicture(0,widthScale);
QRect br = pic.boundingRect();
QPixmap pic = sym->getPointSymbolAsPixmap(0,widthScale);

int h = (int) ( scale * br.height() );

int h = (int) ( scale * pic.height() );
if ( h > itemHeights[icnt] ) {
itemHeights[icnt] = h;
}
Expand Down Expand Up @@ -385,14 +385,13 @@ QRect QgsComposerVectorLegend::render ( QPainter *p )
double scale = map->symbolScale() * mComposition->scale();

// Get the picture of appropriate size directly from catalogue
Q3Picture pic = sym->getPointSymbolAsPicture(0,widthScale);
QPixmap pic = sym->getPointSymbolAsPixmap(0,widthScale);

QRect br = pic.boundingRect();

painter->save();
painter->scale(scale,scale);
painter->drawPicture ( static_cast<int>( (1.*mMargin+mSymbolWidth/2)/scale-br.x()-1.*br.width()/2),
static_cast<int>( (1.*localHeight+symbolHeight/2)/scale-br.y()-1.*br.height()/2),
painter->drawPixmap ( static_cast<int>( (1.*mMargin+mSymbolWidth/2)/scale-pic.width()-1.*pic.width()/2),
static_cast<int>( (1.*localHeight+symbolHeight/2)/scale-pic.height()-1.*pic.height()/2),
pic );
painter->restore();

Expand Down
44 changes: 12 additions & 32 deletions src/core/qgsmarkercatalogue.cpp
Expand Up @@ -25,6 +25,7 @@
#include <qrect.h>
#include <q3pointarray.h>
#include <qdir.h>
#include <QPicture>

#include "qgsapplication.h"
#include "qgssvgcache.h"
Expand Down Expand Up @@ -83,60 +84,39 @@ QgsMarkerCatalogue *QgsMarkerCatalogue::instance()
return QgsMarkerCatalogue::mMarkerCatalogue;
}

Q3Picture QgsMarkerCatalogue::marker ( QString fullName, int size, QPen pen, QBrush brush, int oversampling, bool qtBug )
QPixmap QgsMarkerCatalogue::marker ( QString fullName, int size, QPen pen, QBrush brush, int oversampling, bool qtBug )
{
//std::cerr << "QgsMarkerCatalogue::marker" << std::endl;
Q3Picture picture;

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

return picture; // empty
return QPixmap(); // empty
}

Q3Picture QgsMarkerCatalogue::svgMarker ( QString name, int s, int oversampling )
QPixmap QgsMarkerCatalogue::svgMarker ( QString name, int s, int oversampling )
{
Q3Picture picture;
QPainter painter;
painter.begin(&picture);

if ( oversampling <= 1 )
{
Q3Picture pic = QgsSVGCache::instance().getPicture(name);

QRect br = pic.boundingRect();

double scale = 1. * s / ( ( br.width() + br.height() ) / 2 ) ;

painter.scale ( scale, scale );
painter.drawPicture ( 0, 0, pic );

}
else
{
QPixmap pixmap = QgsSVGCache::instance().getPixmap(name,1.);

double scale = 1. * s / ( ( pixmap.width() + pixmap.height() ) / 2 ) ;

pixmap = QgsSVGCache::instance().getPixmap(name,scale);

painter.drawPixmap ( 0, 0, pixmap );

}
painter.end();

return picture;
return pixmap;
}

Q3Picture QgsMarkerCatalogue::hardMarker ( QString name, int s, QPen pen, QBrush brush, int oversampling, bool qtBug )
QPicture QgsMarkerCatalogue::hardMarker ( QString name, int s, QPen pen, QBrush brush, int oversampling, bool qtBug )
{
// Size of polygon symbols is calculated so that the area is equal to circle with
// diameter mPointSize

Q3Picture picture;
QPicture picture;

// Size for circle
int half = (int)floor(s/2.0); // number of points from center
Expand Down
8 changes: 4 additions & 4 deletions src/core/qgsmarkercatalogue.h
Expand Up @@ -21,7 +21,7 @@
#include <qbrush.h>
#include <qpen.h>
#include <qpixmap.h>
#include <q3picture.h>
#include <qpicture.h>
#include <qdom.h>
#include <qstringlist.h>

Expand All @@ -43,7 +43,7 @@ class QgsMarkerCatalogue{
/** Returns picture of the marker
* \param fullName full name, e.g. hard:circle, svg:/home/usr1/marker1.svg
*/
Q3Picture marker ( QString fullName, int size, QPen pen, QBrush brush, int oversampling = 1, bool qtBug = true );
QPixmap marker ( QString fullName, int size, QPen pen, QBrush brush, int oversampling = 1, bool qtBug = true );

private:

Expand All @@ -56,10 +56,10 @@ class QgsMarkerCatalogue{
QStringList mList;

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

/** Hard coded */
Q3Picture svgMarker ( QString name, int size, int oversampling = 1 );
QPixmap svgMarker ( QString name, int size, int oversampling = 1 );
};

#endif // QGSMARKERCATALOGUE_H
Expand Down
4 changes: 2 additions & 2 deletions src/core/qgsrenderer.h
Expand Up @@ -23,7 +23,7 @@ class QgsMapToPixel;
class QgsVectorLayer;
class QPainter;
class QgsDlgVectorLayerProperties;
class Q3Picture;
class QPixmap;
class QDomNode;
class QColor;

Expand Down Expand Up @@ -53,7 +53,7 @@ class QgsRenderer
@param f a pointer to the feature to be rendered
@param pic pointer to a marker from SVG (is only used by marker renderers)
@param scalefactor pointer to the scale factor for the marker image*/
virtual void renderFeature(QPainter* p, QgsFeature* f,Q3Picture* pic, double* scalefactor, bool selected, int oversampling = 1, double widthScale = 1.)=0;
virtual void renderFeature(QPainter* p, QgsFeature* f,QPixmap* pic, double* scalefactor, bool selected, int oversampling = 1, double widthScale = 1.)=0;
/**Reads the renderer configuration from an XML file
@param rnode the DOM node to read
@param vl the vector layer which will be associated with the renderer*/
Expand Down
127 changes: 39 additions & 88 deletions src/core/qgssvgcache.cpp
Expand Up @@ -27,6 +27,7 @@
#include "qgssvgcache.h"
//Added by qt3to4:
#include <QPixmap>
#include <QSvgRenderer>


QgsSVGCache::QgsSVGCache() {
Expand All @@ -35,60 +36,55 @@ QgsSVGCache::QgsSVGCache() {
pixelLimit = settings.readNumEntry("/qgis/svgcachesize", 200000);
totalPixels = 0;
}
QgsSVGCache::~QgsSVGCache()
{
//QMapIterator<QString, QSvgRenderer *> i(pictureMap);
//while (i.hasNext()) {
// i.next();
// delete i.value() ;
//}
//pictureMap.clear();
}

Q3Picture QgsSVGCache::getPicture(QString filename)
QSvgRenderer * QgsSVGCache::getPicture(QString filename)
{
PictureMap::const_iterator iter;
PictureMap::key_type key(filename);

iter = pictureMap.find(key);
PictureMap::const_iterator i = pictureMap.find(filename);
while (i != pictureMap.end())
{
return (*i).second ;
}

if (iter != pictureMap.end()) {
#if QGISDEBUG > 2
std::cerr<<"SVGCACHE: " << filename << " is already loaded"<<std::endl;
#endif
return iter->second;
}
QSvgRenderer * mySVG;
mySVG->load(filename);

#if QGISDEBUG > 2
std::cerr<<"SVGCACHE: loading " << filename << std::endl;
#endif

Q3Picture pic;
pic.load(filename,"svg");

pictureMap[key] = pic;
pictureMap[filename] = mySVG;

return pic;
return mySVG;
}

QPixmap QgsSVGCache::getPixmap(QString filename, double scaleFactor) {
QPixmap QgsSVGCache::getPixmap(QString filename, double scaleFactor)
{

// make the symbols smaller
scaleFactor *= 0.30;

PixmapMap::const_iterator iter;
PixmapMap::key_type key(filename, scaleFactor);
iter = pixmapMap.find(key);

// if we already have the pixmap, return it
if (iter != pixmapMap.end()) {
#if QGISDEBUG > 2
std::cerr<<"SVGCACHE: "<<filename<<"["<<scaleFactor
<<"] is already loaded"<<std::endl;
#endif
return iter->second;
std::pair<QString, double> myPair(filename, scaleFactor) ;
PixmapMap::iterator i = pixmapMap.find(myPair);
while (i != pixmapMap.end())
{
QPixmap myPixmap = i->second ;
return myPixmap;
}

// if not, try to load it
#if QGISDEBUG > 2
std::cerr<<"SVGCACHE: loading "<<filename<<"["<<scaleFactor<<"]"<<std::endl;
#endif
Q3Picture pic;
pic.load(filename,"svg");
int width=pic.boundingRect().width();
QSvgRenderer mySVG;
mySVG.load(filename);
int width=mySVG.defaultSize().width();
width=static_cast<int>(static_cast<double>(width)*scaleFactor);
int height=pic.boundingRect().height();
int height=mySVG.defaultSize().height();
height=static_cast<int>(static_cast<double>(height)*scaleFactor);

//prevent 0 width or height, which would cause a crash
Expand All @@ -99,63 +95,18 @@ QPixmap QgsSVGCache::getPixmap(QString filename, double scaleFactor) {
height = 1;
}

// render and rescale it (with smoothing)
QPixmap osPixmap(oversampling*width,oversampling*height);
osPixmap.fill(QColor(qRgb(255, 255, 0)));
QPainter p(&osPixmap);
p.scale(scaleFactor*oversampling,scaleFactor*oversampling);
p.drawPicture(0,0,pic);
QImage osImage = osPixmap.convertToImage();
// set a mask - this is probably terribly inefficient
osImage.setAlphaBuffer(true);
for (int i = 0; i < osImage.width(); ++i) {
for (int j = 0; j < osImage.height(); ++j) {
#ifdef Q_OS_MACX
// set opaque since pixels are transparent by default
QRgb pixel = osImage.pixel(i, j);
if (pixel != qRgba(255, 255, 0, 0)) {
osImage.setPixel(i, j, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), 255));
}
#else
// set transparent since pixels are opaque by default
if (osImage.pixel(i, j) == qRgb(255, 255, 0)) {
osImage.setPixel(i, j, qRgba(255, 255, 0, 0));
}
#endif
}
}
if (oversampling != 1)
osImage = osImage.smoothScale(width, height);
QPixmap pixmap = QPixmap(osImage);

// cache it if possible, and remove other pixmaps from the cache
// if it grows too large
if (width * height < pixelLimit) {
#if QGISDEBUG > 2
std::cerr<<"SVGCACHE: Caching "<<filename<<"["<<scaleFactor<<"]"
<<std::endl;
#endif
pixmapMap[key] = pixmap;
fifo.push(key);
totalPixels += width * height;
while (totalPixels > pixelLimit) {
#if QGISDEBUG > 2
std::cerr<<"SVGCACHE: Deleting "<<fifo.front().first<<"["
<<fifo.front().second<<"] from cache"<<std::endl;
#endif
QPixmap& oldPM(pixmapMap[fifo.front()]);
fifo.pop();
totalPixels -= oldPM.width() * oldPM.height();
}
}

return pixmap;
QPixmap myPixmap = QPixmap(width,height);
myPixmap.fill(QColor(255,255,255.0)); //transparent
QPainter myPainter(&myPixmap);
mySVG.render(&myPainter);
pixmapMap[std::pair<QString, double>(filename, scaleFactor)] = myPixmap;
return myPixmap;
}


void QgsSVGCache::clear() {
pixmapMap.clear();
fifo = std::queue<PixmapMap::key_type>();
fifo = std::queue<std::pair<QString, double> >();
totalPixels = 0;
}

Expand Down

0 comments on commit eeff2cf

Please sign in to comment.