~ubuntu-branches/ubuntu/wily/qgis/wily

« back to all changes in this revision

Viewing changes to src/core/qgsmarkercatalogue.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Johan Van de Wauw
  • Date: 2010-07-11 20:23:24 UTC
  • mfrom: (3.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100711202324-5ktghxa7hracohmr
Tags: 1.4.0+12730-3ubuntu1
* Merge from Debian unstable (LP: #540941).
* Fix compilation issues with QT 4.7
* Add build-depends on libqt4-webkit-dev 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
  qgsmarkercatalogue.cpp
3
 
  -------------------
4
 
begin                : March 2005
5
 
copyright            : (C) 2005 by Radim Blazek
6
 
email                : blazek@itc.it
7
 
 ***************************************************************************/
8
 
/***************************************************************************
9
 
 *                                                                         *
10
 
 *   This program is free software; you can redistribute it and/or modify  *
11
 
 *   it under the terms of the GNU General Public License as published by  *
12
 
 *   the Free Software Foundation; either version 2 of the License, or     *
13
 
 *   (at your option) any later version.                                   *
14
 
 *                                                                         *
15
 
 ***************************************************************************/
16
 
#include <cmath>
17
 
#include <iostream>
18
 
 
19
 
#include <QPen>
20
 
#include <QBrush>
21
 
#include <QPainter>
22
 
#include <QPixmap>
23
 
#include <QString>
24
 
#include <QStringList>
25
 
#include <QRect>
26
 
#include <QPolygon>
27
 
#include <QDir>
28
 
#include <QPicture>
29
 
#include <QSvgRenderer>
30
 
 
31
 
#include "qgis.h"
32
 
#include "qgsapplication.h"
33
 
#include "qgsmarkercatalogue.h"
34
 
 
35
 
QgsMarkerCatalogue *QgsMarkerCatalogue::mMarkerCatalogue = 0;
36
 
 
37
 
QgsMarkerCatalogue::QgsMarkerCatalogue()
38
 
{
39
 
  // Init list
40
 
 
41
 
  // Hardcoded markers
42
 
  mList.append ( "hard:circle" );
43
 
  mList.append ( "hard:rectangle" );
44
 
  mList.append ( "hard:diamond" );
45
 
  mList.append ( "hard:cross" );
46
 
  mList.append ( "hard:cross2" );
47
 
  mList.append ( "hard:triangle");
48
 
  mList.append ( "hard:star");
49
 
 
50
 
  // SVG
51
 
  QString svgPath = QgsApplication::svgPath();
52
 
 
53
 
  // TODO recursiv ?
54
 
  QDir dir ( svgPath );
55
 
 
56
 
  QStringList dl = dir.entryList(QDir::Dirs);
57
 
 
58
 
  for ( QStringList::iterator it = dl.begin(); it != dl.end(); ++it ) {
59
 
    if ( *it == "." || *it == ".." ) continue;
60
 
 
61
 
    QDir dir2 ( svgPath + *it );
62
 
 
63
 
    QStringList dl2 = dir2.entryList("*.svg",QDir::Files);
64
 
 
65
 
    for ( QStringList::iterator it2 = dl2.begin(); it2 != dl2.end(); ++it2 ) {
66
 
      // TODO test if it is correct SVG
67
 
      mList.append ( "svg:" + svgPath + *it + "/" + *it2 );
68
 
    }
69
 
  }
70
 
}
71
 
 
72
 
QStringList QgsMarkerCatalogue::list()
73
 
{
74
 
  return mList;
75
 
}
76
 
 
77
 
QgsMarkerCatalogue::~QgsMarkerCatalogue()
78
 
{
79
 
}
80
 
 
81
 
QgsMarkerCatalogue *QgsMarkerCatalogue::instance()
82
 
{
83
 
  if ( !QgsMarkerCatalogue::mMarkerCatalogue ) {
84
 
    QgsMarkerCatalogue::mMarkerCatalogue = new QgsMarkerCatalogue();
85
 
  }
86
 
 
87
 
  return QgsMarkerCatalogue::mMarkerCatalogue;
88
 
}
89
 
QPixmap QgsMarkerCatalogue::pixmapMarker ( QString fullName, int size, QPen pen, QBrush brush, bool qtBug )
90
 
{
91
 
  //std::cerr << "QgsMarkerCatalogue::marker " << fullName.toLocal8Bit().data() << " sice:" << size << std::endl;
92
 
 
93
 
  //
94
 
  // First prepare the paintdevice that the marker will be drawn onto
95
 
  //
96
 
  QPixmap myPixmap;
97
 
  if ( fullName.left(5) == "hard:" ) 
98
 
        {
99
 
                        //Note teh +1 offset below is required because the 
100
 
                        //otherwise the icons are getting clipped
101
 
                        myPixmap = QPixmap (size+1,size+1);
102
 
        }
103
 
  else
104
 
        { 
105
 
                        // TODO Change this logic so width is size and height is same
106
 
                        // proportion of scale factor as in oritignal SVG TS XXX
107
 
                        if (size < 1) size=1;
108
 
                        //QPixmap myPixmap = QPixmap(width,height);
109
 
                        myPixmap = QPixmap(size,size);
110
 
        }
111
 
  // The following is window-system-conditional since (at least)
112
 
  // the combination of Qt 4.1.0 and RealVNC's Xvnc 4.1
113
 
  // will result in the pixmap becoming invisible if it is filled
114
 
  // with a non-opaque colour.
115
 
  // This is probably because Xvnc 4.1 doesn't have the RENDER
116
 
  // extension compiled into it.
117
 
#if defined(Q_WS_X11)
118
 
  // Do a runtime test to see if the X RENDER extension is available
119
 
  if ( myPixmap.x11PictureHandle() )
120
 
  {
121
 
#endif
122
 
    myPixmap.fill(QColor(255,255,255,0)); // transparent
123
 
#if defined(Q_WS_X11)
124
 
  }
125
 
  else
126
 
  {
127
 
    myPixmap.fill(QColor(255,255,255)); // opaque
128
 
  }
129
 
#endif
130
 
  QPainter myPainter(&myPixmap);
131
 
  myPainter.setRenderHint(QPainter::Antialiasing);
132
 
 
133
 
  //
134
 
  // Now pass the paintdevice along to have the marker rndered on it
135
 
  //
136
 
 
137
 
  if ( fullName.left(5) == "hard:" ) 
138
 
  {
139
 
    hardMarker ( &myPainter, fullName.mid(5), size, pen, brush, qtBug ); 
140
 
    return myPixmap;
141
 
  } 
142
 
  else if ( fullName.left(4) == "svg:" ) 
143
 
  {
144
 
    svgMarker ( &myPainter, fullName.mid(4), size ); 
145
 
    return myPixmap;
146
 
  }
147
 
  return QPixmap(); // empty
148
 
}
149
 
 
150
 
QPicture QgsMarkerCatalogue::pictureMarker ( QString fullName, int size, QPen pen, QBrush brush, bool qtBug )
151
 
{
152
 
 
153
 
  //
154
 
  // First prepare the paintdevice that the marker will be drawn onto
155
 
  //
156
 
  QPicture myPicture;
157
 
  if ( fullName.left(5) == "hard:" ) 
158
 
        {
159
 
                        //Note teh +1 offset below is required because the 
160
 
                        //otherwise the icons are getting clipped
161
 
                        myPicture = QPicture (size+1);
162
 
        }
163
 
  else
164
 
        { 
165
 
                        // TODO Change this logic so width is size and height is same
166
 
                        // proportion of scale factor as in oritignal SVG TS XXX
167
 
                        if (size < 1) size=1;
168
 
                        //QPicture myPicture = QPicture(width,height);
169
 
                        myPicture = QPicture(size);
170
 
        }
171
 
  QPainter myPainter(&myPicture);
172
 
  myPainter.setRenderHint(QPainter::Antialiasing);
173
 
 
174
 
  //
175
 
  // Now pass the paintdevice along to have the marker rndered on it
176
 
  //
177
 
 
178
 
  if ( fullName.left(5) == "hard:" ) 
179
 
  {
180
 
    hardMarker ( &myPainter, fullName.mid(5), size, pen, brush, qtBug ); 
181
 
    return myPicture;
182
 
  } 
183
 
  else if ( fullName.left(4) == "svg:" ) 
184
 
  {
185
 
    svgMarker ( &myPainter, fullName.mid(4), size ); 
186
 
    return myPicture;
187
 
  }
188
 
  return QPicture(); // empty
189
 
}
190
 
 
191
 
void QgsMarkerCatalogue::svgMarker ( QPainter * thepPainter, QString filename, int scaleFactor)
192
 
{
193
 
  QSvgRenderer mySVG;
194
 
  mySVG.load(filename);
195
 
  mySVG.render(thepPainter);
196
 
  return ;
197
 
}
198
 
 
199
 
void QgsMarkerCatalogue::hardMarker (QPainter * thepPainter, QString name, int s, QPen pen, QBrush brush, bool qtBug )
200
 
{
201
 
  // Size of polygon symbols is calculated so that the area is equal to circle with 
202
 
  // diameter mPointSize
203
 
 
204
 
  // Size for circle
205
 
  int half = (int)floor(s/2.0); // number of points from center
206
 
  int size = 2*half + 1;  // must be odd
207
 
  double area = 3.14 * (size/2.) * (size/2.);
208
 
 
209
 
  // Picture
210
 
  QPicture picture;
211
 
  thepPainter->begin(&picture);
212
 
  thepPainter->setRenderHint(QPainter::Antialiasing);
213
 
 
214
 
  // Also width must be odd otherwise there are discrepancies visible in canvas!
215
 
  int lw = (int)(2*floor((double)pen.width()/2)+1); // -> lw > 0
216
 
  pen.setWidth(lw);
217
 
  thepPainter->setPen ( pen );
218
 
  thepPainter->setBrush( brush);
219
 
  QRect box;
220
 
 
221
 
  if ( name == "circle" ) 
222
 
  {
223
 
    thepPainter->drawEllipse(0, 0, size, size);
224
 
  } 
225
 
  else if ( name == "rectangle" ) 
226
 
  {
227
 
    size = (int) (2*floor(sqrt(area)/2.) + 1);
228
 
    thepPainter->drawRect(0, 0, size, size);
229
 
  } 
230
 
  else if ( name == "diamond" ) 
231
 
  {
232
 
    half = (int) ( sqrt(area/2.) );
233
 
    QPolygon pa(4);
234
 
    pa.setPoint ( 0, 0, half);
235
 
    pa.setPoint ( 1, half, 2*half);
236
 
    pa.setPoint ( 2, 2*half, half);
237
 
    pa.setPoint ( 3, half, 0);
238
 
    thepPainter->drawPolygon ( pa );
239
 
  }
240
 
  // Warning! if pen width > 0 thepPainter->drawLine(x1,y1,x2,y2) will draw only (x1,y1,x2-1,y2-1) !
241
 
  // It is impossible to draw lines as rectangles because line width scaling would not work
242
 
  // (QPicture is scaled later in QgsVectorLayer)
243
 
  //  -> reset boundingRect for cross, cross2
244
 
  else if ( name == "cross" ) 
245
 
  {
246
 
    int add;
247
 
    if ( qtBug ) 
248
 
    {
249
 
      add = 1;  // lw always > 0
250
 
    } 
251
 
    else 
252
 
    {
253
 
      add = 0;
254
 
    }
255
 
 
256
 
    thepPainter->drawLine(0, half, size-1+add, half); // horizontal
257
 
    thepPainter->drawLine(half, 0, half, size-1+add); // vertical
258
 
    box.setRect ( 0, 0, size, size );
259
 
  }
260
 
  else if ( name == "cross2" ) 
261
 
  {
262
 
    half = (int) floor( s/2/sqrt(2.0));
263
 
    size = 2*half + 1;
264
 
 
265
 
    int add;
266
 
    if ( qtBug ) {
267
 
      add = 1;  // lw always > 0
268
 
    } else {
269
 
      add = 0;
270
 
    }
271
 
 
272
 
    int addwidth = (int) ( 0.5 * lw ); // width correction, cca lw/2 * cos(45)
273
 
 
274
 
    thepPainter->drawLine( 0, 0, size-1+add, size-1+add);
275
 
    thepPainter->drawLine( 0, size-1, size-1+add, 0-add);
276
 
 
277
 
    box.setRect ( -addwidth, -addwidth, size + 2*addwidth, size + 2*addwidth ); 
278
 
  }
279
 
  else if ( name == "triangle")
280
 
    {
281
 
      QPolygon pa(3);
282
 
      pa.setPoint ( 0, 0, size);
283
 
      pa.setPoint ( 1, size, size);
284
 
      pa.setPoint ( 2, half, 0);
285
 
      thepPainter->drawPolygon ( pa );
286
 
    }
287
 
  else if (name == "star")
288
 
    {
289
 
      int oneThird = (int)(floor(size/3+0.5));
290
 
      int twoThird = (int)(floor(size/3*2+0.5));
291
 
      QPolygon pa(10);
292
 
      pa.setPoint(0, half, 0);
293
 
      pa.setPoint(1, oneThird, oneThird);
294
 
      pa.setPoint(2, 0, oneThird);
295
 
      pa.setPoint(3, oneThird, half);
296
 
      pa.setPoint(4, 0, size);
297
 
      pa.setPoint(5, half, twoThird);
298
 
      pa.setPoint(6, size, size);
299
 
      pa.setPoint(7, twoThird, half);
300
 
      pa.setPoint(8, size, oneThird);
301
 
      pa.setPoint(9, twoThird, oneThird);
302
 
      thepPainter->drawPolygon ( pa );
303
 
    }
304
 
  if ( name == "cross" || name == "cross2" ) 
305
 
  {
306
 
    picture.setBoundingRect ( box ); 
307
 
  }
308
 
  thepPainter->end();
309
 
}
310