My Project  0.0.16
QUCS Mapping
 All Classes Namespaces 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 
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 
57 // -------------------------------------------------------------
58 void ViewPainter::map(int x1, int y1, int& x, int& y)
59 {
60  float z;
61  z = float(x1)*Scale + DX;
62  x = TO_INT(z);
63  z = float(y1)*Scale + DY;
64  y = TO_INT(z);
65 }
66 
67 // -------------------------------------------------------------
68 void ViewPainter::drawPoint(int x1, int y1)
69 {
70  float z;
71  z = float(x1)*Scale + DX;
72  x1 = TO_INT(z);
73  z = float(y1)*Scale + DY;
74  y1 = TO_INT(z);
75 
76  Painter->drawPoint(x1, y1);
77 }
78 
79 // -------------------------------------------------------------
80 void ViewPainter::drawLine(int x1, int y1, int x2, int y2)
81 {
82  float z;
83  z = float(x1)*Scale + DX;
84  x1 = TO_INT(z);
85  z = float(y1)*Scale + DY;
86  y1 = TO_INT(z);
87  z = float(x2)*Scale + DX;
88  x2 = TO_INT(z);
89  z = float(y2)*Scale + DY;
90  y2 = TO_INT(z);
91 
92  Painter->drawLine(x1, y1, x2, y2);
93 }
94 
95 // -------------------------------------------------------------
96 void ViewPainter::drawLines(int x0, int y0, float *pp)
97 {
98  float z, DX_, DY_;
99  int x1, x2, y1, y2;
100  if(*pp < 0)
101  pp++;
102 
103  DX_ = DX + float(x0)*Scale;
104  DY_ = DY + float(y0)*Scale;
105 
106  while(*pp > GRAPHEND) {
107  if(*pp >= 0) {
108  z = DX_ + (*pp)*Scale;
109  x1 = TO_INT(z);
110  z = DY_ - (*(pp+1))*Scale;
111  y1 = TO_INT(z);
112  Painter->drawPoint(x1, y1);
113  }
114  while(*pp > BRANCHEND) { // until end of branch
115  z = DX_ + (*pp)*Scale;
116  x1 = TO_INT(z);
117  z = DY_ - (*(pp+1))*Scale;
118  y1 = TO_INT(z);
119  pp += 2;
120  while(*pp > STROKEEND) { // until end of stroke
121  z = DX_ + (*pp)*Scale;
122  x2 = TO_INT(z);
123  z = DY_ - (*(pp+1))*Scale;
124  y2 = TO_INT(z);
125  Painter->drawLine(x1, y1, x2, y2);
126  pp += 2;
127  if(*pp <= STROKEEND) break;
128 
129  z = DX_ + (*pp)*Scale;
130  x1 = TO_INT(z);
131  z = DY_ - (*(pp+1))*Scale;
132  y1 = TO_INT(z);
133  Painter->drawLine(x2, y2, x1, y1);
134  pp += 2;
135  }
136  if(*pp <= BRANCHEND) break; // end of line ?
137  pp++;
138  }
139  pp++;
140  }
141 }
142 
143 // -------------------------------------------------------------
144 void ViewPainter::drawStarSymbols(int x0, int y0, float *pp)
145 {
146  int x3, x1, x2, y1, y2;
147  float z, DX_, DY_;
148  if(*pp < 0)
149  pp++;
150 
151  DX_ = DX + float(x0)*Scale;
152  DY_ = DY + float(y0)*Scale;
153 
154  while(*pp > GRAPHEND) {
155  if(*pp >= 0) {
156  z = DX_ + (*(pp++))*Scale;
157  x0 = TO_INT(z-5.0*Scale);
158  x3 = TO_INT(z+5.0*Scale);
159  x1 = TO_INT(z-4.0*Scale);
160  x2 = TO_INT(z+4.0*Scale);
161  z = DY_ - (*(pp++))*Scale;
162  y0 = TO_INT(z);
163  y1 = TO_INT(z-4.0*Scale);
164  y2 = TO_INT(z+4.0*Scale);
165  Painter->drawLine(x0, y0, x3, y0); // horizontal line
166  Painter->drawLine(x1, y2, x2, y1); // upper left to lower right
167  Painter->drawLine(x2, y2, x1, y1); // upper right to lower left
168  }
169  else pp++;
170  }
171 }
172 
173 // -------------------------------------------------------------
174 void ViewPainter::drawCircleSymbols(int x0, int y0, float *pp)
175 {
176  int d;
177  float z, DX_, DY_;
178  if(*pp < 0)
179  pp++;
180 
181  z = 8.0*Scale;
182  d = TO_INT(z);
183  DX_ = DX + float(x0)*Scale;
184  DY_ = DY + float(y0)*Scale;
185 
186  while(*pp > GRAPHEND) {
187  if(*pp >= 0) {
188  z = DX_ + (*(pp++)-4.0)*Scale;
189  x0 = TO_INT(z);
190  z = DY_ - (*(pp++)+4.0)*Scale;
191  y0 = TO_INT(z);
192  Painter->drawEllipse(x0, y0, d, d);
193  }
194  else pp++;
195  }
196 }
197 
198 // -------------------------------------------------------------
199 void ViewPainter::drawArrowSymbols(int x0, int y0, float *pp)
200 {
201  int x1, x2, y1, y2;
202  float z, DX_, DY_;
203  if(*pp < 0)
204  pp++;
205 
206  DX_ = DX + float(x0)*Scale;
207  DY_ = DY + float(y0)*Scale;
208  y2 = TO_INT(DY_);
209 
210  while(*pp > GRAPHEND) {
211  if(*pp >= 0) {
212  z = DX_ + (*(pp++))*Scale;
213  x0 = TO_INT(z);
214  x1 = TO_INT(z-4.0*Scale);
215  x2 = TO_INT(z+4.0*Scale);
216  z = DY_ - (*(pp++))*Scale;
217  y0 = TO_INT(z);
218  y1 = TO_INT(z+7.0*Scale);
219  Painter->drawLine(x0, y0, x0, y2);
220  Painter->drawLine(x1, y1, x0, y0);
221  Painter->drawLine(x2, y1, x0, y0);
222  }
223  else pp++;
224  }
225 }
226 
227 // -------------------------------------------------------------
228 void ViewPainter::drawRect(int x1, int y1, int dx, int dy)
229 {
230  float z;
231  z = float(x1)*Scale + DX;
232  x1 = TO_INT(z);
233  z = float(y1)*Scale + DY;
234  y1 = TO_INT(z);
235  z = float(dx)*Scale;
236  dx = TO_INT(z);
237  z = float(dy)*Scale;
238  dy = TO_INT(z);
239 
240  Painter->drawRect(x1, y1, dx, dy);
241 }
242 
243 // -------------------------------------------------------------
244 void ViewPainter::drawRectD(int x1, int y1, int dx, int dy)
245 {
246  float z;
247  z = float(x1)*Scale + DX;
248  x1 = TO_INT(z);
249  z = float(y1)*Scale + DY;
250  y1 = TO_INT(z);
251 
252  Painter->drawRect(x1, y1, dx, dy);
253 }
254 
255 // -------------------------------------------------------------
256 void ViewPainter::drawRoundRect(int x1, int y1, int dx, int dy)
257 {
258  float z;
259  z = float(x1)*Scale + DX;
260  x1 = TO_INT(z);
261  z = float(y1)*Scale + DY;
262  y1 = TO_INT(z);
263  z = float(dx)*Scale;
264  dx = TO_INT(z);
265  z = float(dy)*Scale;
266  dy = TO_INT(z);
267 
268  Painter->drawRoundRect(x1, y1, dx, dy);
269 }
270 
271 // -------------------------------------------------------------
272 void ViewPainter::drawEllipse(int x1, int y1, int dx, int dy)
273 {
274  float z;
275  z = float(x1)*Scale + DX;
276  x1 = TO_INT(z);
277  z = float(y1)*Scale + DY;
278  y1 = TO_INT(z);
279  z = float(dx)*Scale;
280  dx = TO_INT(z);
281  z = float(dy)*Scale;
282  dy = TO_INT(z);
283 
284  Painter->drawEllipse(x1, y1, dx, dy);
285 }
286 
287 // -------------------------------------------------------------
288 // Returns width of text (and height if pointer is not null).
289 int ViewPainter::drawText(const QString& Text, int x1, int y1, int *Height)
290 {
291  float z;
292  z = float(x1)*Scale + DX;
293  x1 = TO_INT(z);
294  z = float(y1)*Scale + DY;
295  y1 = TO_INT(z);
296 
297  QRect r;
298  Painter->drawText(x1, y1, 0, 0, Qt::DontClip, Text, -1, &r);
299 
300  if(Height) *Height = r.height();
301  return r.width();
302 }
303 
304 // -------------------------------------------------------------
305 // Returns width of text (and height if pointer is not null).
306 int ViewPainter::drawTextMapped(const QString& Text, int x1, int y1,
307  int *Height)
308 {
309  QRect r;
310  int y = 0;
311  int x = 0;
312  int h = 0;
313  int w = 0;
314  int i = 0;
315 
316  while (!Text[i].isNull()) {
317  if ((Text[i].latin1() == '_' || Text[i].latin1() == '^') &&
318  !Text[i+1].isNull()) {
319  bool is_sub = Text[i++].latin1() == '_';
320  int len = 0;
321 
322  if (Text[i] == '{') {
323  i++;
324  while (!Text[i+len].isNull() && Text[i+len].latin1() != '}') len++;
325  }
326 
327 #ifdef __MINGW32__
328  float scale = 1.0;
329 #else
330  float scale = PrintScale;
331 #endif
332  QFont fbak = Painter->font();
333  QFont f = Painter->font();
334  f.setPointSizeFloat(f.pointSizeFloat()*0.8);
335  Painter->setFont(f);
336  Painter->drawText(x1+x,
337  y1+y + (is_sub ? +0.6 : -0.3) *
338  fbak.pointSizeFloat() * scale,
339  0, 0, Qt::DontClip,
340  Text.mid(i, len ? len : 1), -1, &r);
341  Painter->setFont(fbak);
342  x += r.width();
343  if (x > w) w = x;
344  i += len ? len + 1 : 1;
345  }
346  else
347  {
348  int len = 0;
349  while (!Text[i+len].isNull() && Text[i+len].latin1() != '_' &&
350  Text[i+len].latin1() != '^' && Text[i+len].latin1() != '\n')
351  len++;
352  Painter->drawText(x1+x, y1+y,
353  0, 0, Qt::DontClip, Text.mid(i, len), -1, &r);
354  if (h < r.height()) {
355  h = r.height();
356  }
357  x += r.width();
358  if (x > w) w = x;
359  if (Text[i+len].latin1() == '\n') {
360  y += h;
361  x = 0;
362  i++;
363  }
364  i += len;
365  }
366  }
367 
368  if(Height) *Height = y+h;
369  return w;
370 }
371 
372 // -------------------------------------------------------------
373 // Returns width of text (and height if pointer is not null).
374 void ViewPainter::drawArc(int x1, int y1, int w, int h, int Angle, int ArcLen)
375 {
376  float z;
377  z = float(x1)*Scale + DX;
378  x1 = TO_INT(z);
379  z = float(y1)*Scale + DY;
380  y1 = TO_INT(z);
381 
382  // Width and height get a different treatment due to some alaising artefacts.
383  // The following procedure was found empirically.
384  w = int(float(w)*Scale);
385  h = int(float(h)*Scale);
386  Painter->drawArc(x1, y1, w+1, h+1, Angle, ArcLen);
387 }
388 
389 // -------------------------------------------------------------
390 void ViewPainter::fillRect(int x1, int y1, int dx, int dy, const QColor& Color)
391 {
392  float z;
393  z = float(x1)*Scale + DX;
394  x1 = TO_INT(z);
395  z = float(y1)*Scale + DY;
396  y1 = TO_INT(z);
397 
398  z = float(dx)*Scale;
399  dx = TO_INT(z);
400  z = float(dy)*Scale;
401  dy = TO_INT(z);
402 
403  Painter->fillRect(x1, y1, dx, dy, QBrush(Color));
404 }
405 
406 // -------------------------------------------------------------
407 void ViewPainter::eraseRect(int x1, int y1, int dx, int dy)
408 {
409  float z;
410  z = float(x1)*Scale + DX;
411  x1 = TO_INT(z);
412  z = float(y1)*Scale + DY;
413  y1 = TO_INT(z);
414 
415  Painter->eraseRect(x1, y1, dx, dy);
416 }
417 
418 // -------------------------------------------------------------
419 // Draw little resize rectangles with center x1/y1 and size independent
420 // of zoom factor.
421 void ViewPainter::drawResizeRect(int x1, int y1)
422 {
423  float z;
424  z = float(x1)*Scale + DX;
425  x1 = TO_INT(z);
426  z = float(y1)*Scale + DY;
427  y1 = TO_INT(z);
428 
429  Painter->drawRect(x1-5, y1-5, 10, 10);
430 }