Qucs-GUI  0.0.18
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
viewpainter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  viewpainter.cpp - description
3  -------------------
4  begin : Tue Oct 05 2004
5  copyright : (C) 2004 by Michael Margraf
6  email : michael.margraf@alumni.tu-berlin.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 #include <QtGui>
18 #include "viewpainter.h"
19 #include "diagrams/graph.h"
20 
21 #include <math.h>
22 
23 
25 {
26  Painter = p;
27  DX = DY = Scale = 0.0;
28  FontScale = PrintScale = 1.0;
29 }
30 
32 {
33 }
34 
35 // -------------------------------------------------------------
36 void ViewPainter::init(QPainter *p, float Scale_, int DX_, int DY_, int dx_, int dy_, float FontScale_, float PrintScale_)
37 {
38  Painter = p;
39  Scale = Scale_;
40  FontScale = FontScale_;
41  PrintScale = PrintScale_;
42  DX = floor(float(DX_) * Scale) - float(dx_);
43  DY = floor(float(DY_) * Scale) - float(dy_);
44 
45  QFont f = p->font();
46  if(FontScale == 0.0)
47  FontScale = Scale;
48 #ifdef __MINGW32__
49  FontScale = Scale;
50 #endif
51  f.setPointSizeFloat( FontScale * float(f.pointSize()) );
52  p->setFont(f);
53  LineSpacing = p->fontMetrics().lineSpacing();
54  p->setWorldXForm(false); // we use our own coordinate transformation
55 
56  // Encourage Qt to antialias where possible for nicer drawings
57  p->setRenderHint(QPainter::Antialiasing, true);
58  // Also antialias text if possible
59  p->setRenderHint(QPainter::TextAntialiasing, true);
60 }
61 
62 // -------------------------------------------------------------
63 void ViewPainter::map(int x1, int y1, int& x, int& y)
64 {
65  float z;
66  z = float(x1)*Scale + DX;
67  x = TO_INT(z);
68  z = float(y1)*Scale + DY;
69  y = TO_INT(z);
70 }
71 
72 // -------------------------------------------------------------
73 void ViewPainter::drawPoint(int x1, int y1)
74 {
75  float z;
76  z = float(x1)*Scale + DX;
77  x1 = TO_INT(z);
78  z = float(y1)*Scale + DY;
79  y1 = TO_INT(z);
80 
81  Painter->drawPoint(x1, y1);
82 }
83 
84 // -------------------------------------------------------------
85 void ViewPainter::drawLine(int x1, int y1, int x2, int y2)
86 {
87  float z;
88  z = float(x1)*Scale + DX;
89  x1 = TO_INT(z);
90  z = float(y1)*Scale + DY;
91  y1 = TO_INT(z);
92  z = float(x2)*Scale + DX;
93  x2 = TO_INT(z);
94  z = float(y2)*Scale + DY;
95  y2 = TO_INT(z);
96 
97  Painter->drawLine(x1, y1, x2, y2);
98 }
99 
100 // -------------------------------------------------------------
101 void ViewPainter::drawLines(int x0, int y0, float *pp)
102 {
103  float z, DX_, DY_;
104  int x1, x2, y1, y2;
105  if(*pp < 0)
106  pp++;
107 
108  DX_ = DX + float(x0)*Scale;
109  DY_ = DY + float(y0)*Scale;
110 
111  while(*pp > GRAPHEND) {
112  if(*pp >= 0) {
113  z = DX_ + (*pp)*Scale;
114  x1 = TO_INT(z);
115  z = DY_ - (*(pp+1))*Scale;
116  y1 = TO_INT(z);
117  Painter->drawPoint(x1, y1);
118  }
119  while(*pp > BRANCHEND) { // until end of branch
120  z = DX_ + (*pp)*Scale;
121  x1 = TO_INT(z);
122  z = DY_ - (*(pp+1))*Scale;
123  y1 = TO_INT(z);
124  pp += 2;
125  while(*pp > STROKEEND) { // until end of stroke
126  z = DX_ + (*pp)*Scale;
127  x2 = TO_INT(z);
128  z = DY_ - (*(pp+1))*Scale;
129  y2 = TO_INT(z);
130  Painter->drawLine(x1, y1, x2, y2);
131  pp += 2;
132  if(*pp <= STROKEEND) break;
133 
134  z = DX_ + (*pp)*Scale;
135  x1 = TO_INT(z);
136  z = DY_ - (*(pp+1))*Scale;
137  y1 = TO_INT(z);
138  Painter->drawLine(x2, y2, x1, y1);
139  pp += 2;
140  }
141  if(*pp <= BRANCHEND) break; // end of line ?
142  pp++;
143  }
144  pp++;
145  }
146 }
147 
148 // -------------------------------------------------------------
149 void ViewPainter::drawStarSymbols(int x0, int y0, float *pp)
150 {
151  int x3, x1, x2, y1, y2;
152  float z, DX_, DY_;
153  if(*pp < 0)
154  pp++;
155 
156  DX_ = DX + float(x0)*Scale;
157  DY_ = DY + float(y0)*Scale;
158 
159  while(*pp > GRAPHEND) {
160  if(*pp >= 0) {
161  z = DX_ + (*(pp++))*Scale;
162  x0 = TO_INT(z-5.0*Scale);
163  x3 = TO_INT(z+5.0*Scale);
164  x1 = TO_INT(z-4.0*Scale);
165  x2 = TO_INT(z+4.0*Scale);
166  z = DY_ - (*(pp++))*Scale;
167  y0 = TO_INT(z);
168  y1 = TO_INT(z-4.0*Scale);
169  y2 = TO_INT(z+4.0*Scale);
170  Painter->drawLine(x0, y0, x3, y0); // horizontal line
171  Painter->drawLine(x1, y2, x2, y1); // upper left to lower right
172  Painter->drawLine(x2, y2, x1, y1); // upper right to lower left
173  }
174  else pp++;
175  }
176 }
177 
178 // -------------------------------------------------------------
179 void ViewPainter::drawCircleSymbols(int x0, int y0, float *pp)
180 {
181  int d;
182  float z, DX_, DY_;
183  if(*pp < 0)
184  pp++;
185 
186  z = 8.0*Scale;
187  d = TO_INT(z);
188  DX_ = DX + float(x0)*Scale;
189  DY_ = DY + float(y0)*Scale;
190 
191  while(*pp > GRAPHEND) {
192  if(*pp >= 0) {
193  z = DX_ + (*(pp++)-4.0)*Scale;
194  x0 = TO_INT(z);
195  z = DY_ - (*(pp++)+4.0)*Scale;
196  y0 = TO_INT(z);
197  Painter->drawEllipse(x0, y0, d, d);
198  }
199  else pp++;
200  }
201 }
202 
203 // -------------------------------------------------------------
204 void ViewPainter::drawArrowSymbols(int x0, int y0, float *pp)
205 {
206  int x1, x2, y1, y2;
207  float z, DX_, DY_;
208  if(*pp < 0)
209  pp++;
210 
211  DX_ = DX + float(x0)*Scale;
212  DY_ = DY + float(y0)*Scale;
213  y2 = TO_INT(DY_);
214 
215  while(*pp > GRAPHEND) {
216  if(*pp >= 0) {
217  z = DX_ + (*(pp++))*Scale;
218  x0 = TO_INT(z);
219  x1 = TO_INT(z-4.0*Scale);
220  x2 = TO_INT(z+4.0*Scale);
221  z = DY_ - (*(pp++))*Scale;
222  y0 = TO_INT(z);
223  y1 = TO_INT(z+7.0*Scale);
224  Painter->drawLine(x0, y0, x0, y2);
225  Painter->drawLine(x1, y1, x0, y0);
226  Painter->drawLine(x2, y1, x0, y0);
227  }
228  else pp++;
229  }
230 }
231 
232 // -------------------------------------------------------------
233 void ViewPainter::drawRect(int x1, int y1, int dx, int dy)
234 {
235  float z;
236  z = float(x1)*Scale + DX;
237  x1 = TO_INT(z);
238  z = float(y1)*Scale + DY;
239  y1 = TO_INT(z);
240  z = float(dx)*Scale;
241  dx = TO_INT(z);
242  z = float(dy)*Scale;
243  dy = TO_INT(z);
244 
245  Painter->drawRect(x1, y1, dx, dy);
246 }
247 
248 // -------------------------------------------------------------
249 void ViewPainter::drawRectD(int x1, int y1, int dx, int dy)
250 {
251  float z;
252  z = float(x1)*Scale + DX;
253  x1 = TO_INT(z);
254  z = float(y1)*Scale + DY;
255  y1 = TO_INT(z);
256 
257  Painter->drawRect(x1, y1, dx, dy);
258 }
259 
260 // -------------------------------------------------------------
261 void ViewPainter::drawRoundRect(int x1, int y1, int dx, int dy)
262 {
263  float z;
264  z = float(x1)*Scale + DX;
265  x1 = TO_INT(z);
266  z = float(y1)*Scale + DY;
267  y1 = TO_INT(z);
268  z = float(dx)*Scale;
269  dx = TO_INT(z);
270  z = float(dy)*Scale;
271  dy = TO_INT(z);
272 
273  Painter->drawRoundRect(x1, y1, dx, dy);
274 }
275 
276 // -------------------------------------------------------------
277 void ViewPainter::drawEllipse(int x1, int y1, int dx, int dy)
278 {
279  float z;
280  z = float(x1)*Scale + DX;
281  x1 = TO_INT(z);
282  z = float(y1)*Scale + DY;
283  y1 = TO_INT(z);
284  z = float(dx)*Scale;
285  dx = TO_INT(z);
286  z = float(dy)*Scale;
287  dy = TO_INT(z);
288 
289  Painter->drawEllipse(x1, y1, dx, dy);
290 }
291 
292 // -------------------------------------------------------------
293 // Returns width of text (and height if pointer is not null).
294 int ViewPainter::drawText(const QString& Text, int x1, int y1, int *Height)
295 {
296  float z;
297  z = float(x1)*Scale + DX;
298  x1 = TO_INT(z);
299  z = float(y1)*Scale + DY;
300  y1 = TO_INT(z);
301 
302  QRect r;
303  Painter->drawText(x1, y1, 0, 0, Qt::TextDontClip, Text, -1, &r);
304 
305  if(Height) *Height = r.height();
306  return r.width();
307 }
308 
309 // -------------------------------------------------------------
310 // Returns width of text (and height if pointer is not null).
311 int ViewPainter::drawTextMapped(const QString& Text, int x1, int y1,
312  int *Height)
313 {
314  QRect r;
315  int y = 0;
316  int x = 0;
317  int h = 0;
318  int w = 0;
319  int i = 0;
320 
321  while (Text.length()>i) {
322  if ((Text[i].latin1() == '_' || Text[i].latin1() == '^') &&
323  !Text[i+1].isNull()) {
324  bool is_sub = Text[i++].latin1() == '_';
325  int len = 0;
326 
327  if (Text[i] == '{') {
328  i++;
329  while (!Text[i+len].isNull() && Text[i+len].latin1() != '}') len++;
330  }
331 
332 #ifdef __MINGW32__
333  float scale = 1.0;
334 #else
335  float scale = PrintScale;
336 #endif
337  QFont fbak = Painter->font();
338  QFont f = Painter->font();
339  f.setPointSizeFloat(f.pointSizeFloat()*0.8);
340  Painter->setFont(f);
341  Painter->drawText(x1+x,
342  y1+y + (is_sub ? +0.6 : -0.3) *
343  fbak.pointSizeFloat() * scale,
344  0, 0, Qt::TextDontClip,
345  Text.mid(i, len ? len : 1), -1, &r);
346  Painter->setFont(fbak);
347  x += r.width();
348  if (x > w) w = x;
349  i += len ? len + 1 : 1;
350  }
351  else
352  {
353  int len = 0;
354  while (Text.length()>(i+len) && Text[i+len].latin1() != '_' &&
356  Text[i+len].latin1() != '^' && Text[i+len].latin1() != '\n')
357  len++;
358  Painter->drawText(x1+x, y1+y,
359  0, 0, Qt::TextDontClip, Text.mid(i, len), -1, &r);
360  if (h < r.height()) {
361  h = r.height();
362  }
363  x += r.width();
364  if (x > w) w = x;
365  if (Text.length()>(i+len)&&Text[i+len].latin1() == '\n') {
366  y += h;
367  x = 0;
368  i++;
369  }
370  i += len;
371  }
372  }
373 
374  if(Height) *Height = y+h;
375  return w;
376 }
377 
378 // -------------------------------------------------------------
379 // Returns width of text (and height if pointer is not null).
380 void ViewPainter::drawArc(int x1, int y1, int w, int h, int Angle, int ArcLen)
381 {
382  float z;
383  z = float(x1)*Scale + DX;
384  x1 = TO_INT(z);
385  z = float(y1)*Scale + DY;
386  y1 = TO_INT(z);
387 
388  // Width and height get a different treatment due to some alaising artefacts.
389  // The following procedure was found empirically.
390  w = int(float(w)*Scale);
391  h = int(float(h)*Scale);
392  Painter->drawArc(x1, y1, w+1, h+1, Angle, ArcLen);
393 }
394 
395 // -------------------------------------------------------------
396 void ViewPainter::fillRect(int x1, int y1, int dx, int dy, const QColor& Color)
397 {
398  float z;
399  z = float(x1)*Scale + DX;
400  x1 = TO_INT(z);
401  z = float(y1)*Scale + DY;
402  y1 = TO_INT(z);
403 
404  z = float(dx)*Scale;
405  dx = TO_INT(z);
406  z = float(dy)*Scale;
407  dy = TO_INT(z);
408 
409  Painter->fillRect(x1, y1, dx, dy, QBrush(Color));
410 }
411 
412 // -------------------------------------------------------------
413 void ViewPainter::eraseRect(int x1, int y1, int dx, int dy)
414 {
415  float z;
416  z = float(x1)*Scale + DX;
417  x1 = TO_INT(z);
418  z = float(y1)*Scale + DY;
419  y1 = TO_INT(z);
420 
421  Painter->eraseRect(x1, y1, dx, dy);
422 }
423 
424 // -------------------------------------------------------------
425 // Draw little resize rectangles with center x1/y1 and size independent
426 // of zoom factor.
427 void ViewPainter::drawResizeRect(int x1, int y1)
428 {
429  float z;
430  z = float(x1)*Scale + DX;
431  x1 = TO_INT(z);
432  z = float(y1)*Scale + DY;
433  y1 = TO_INT(z);
434 
435  Painter->drawRect(x1-5, y1-5, 10, 10);
436 }
void drawStarSymbols(int, int, float *)
void drawResizeRect(int, int)
QPainter * Painter
Definition: viewpainter.h:58
float Scale
Definition: viewpainter.h:59
void map(int, int, int &, int &)
Definition: viewpainter.cpp:63
#define BRANCHEND
Definition: graph.h:32
int LineSpacing
Definition: viewpainter.h:60
void drawLine(int, int, int, int)
Definition: viewpainter.cpp:85
void drawArrowSymbols(int, int, float *)
#define STROKEEND
Definition: graph.h:31
void drawCircleSymbols(int, int, float *)
void drawPoint(int, int)
Definition: viewpainter.cpp:73
void fillRect(int, int, int, int, const QColor &)
ViewPainter(QPainter *p=0)
Definition: viewpainter.cpp:24
int drawText(const QString &, int, int, int *Height=0)
void drawRoundRect(int, int, int, int)
Definition: element.h:82
void drawArc(int, int, int, int, int, int)
int drawTextMapped(const QString &, int, int, int *Height=0)
void drawRect(int, int, int, int)
void drawLines(int, int, float *)
#define TO_INT(f)
Definition: viewpainter.h:23
void drawRectD(int, int, int, int)
void init(QPainter *, float, int, int, int, int, float FontScale_=0.0, float PrintScale_=1.0)
Definition: viewpainter.cpp:36
float FontScale
Definition: viewpainter.h:59
#define GRAPHEND
Definition: graph.h:33
void eraseRect(int, int, int, int)
float PrintScale
Definition: viewpainter.h:59
void drawEllipse(int, int, int, int)