Qucs-GUI  0.0.19
/home/travis/build/Qucs/qucs/qucs/qucs/viewpainter.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                         viewpainter.cpp  -  description
00003                              -------------------
00004     begin                : Tue Oct 05 2004
00005     copyright            : (C) 2004 by Michael Margraf
00006     email                : michael.margraf@alumni.tu-berlin.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include "main.h"
00019 #include "viewpainter.h"
00020 #include "diagrams/graph.h"
00021 
00022 #include <QPainter>
00023 #include <QFont>
00024 #include <QDebug>
00025 
00026 ViewPainter::ViewPainter(QPainter *p)
00027 {
00028   Painter = p;
00029   DX = DY = Scale = 0.0;
00030   FontScale = PrintScale = 1.0;
00031 }
00032 
00033 ViewPainter::~ViewPainter()
00034 {
00035 }
00036 
00037 // -------------------------------------------------------------
00038 void ViewPainter::init(QPainter *p, float Scale_, int DX_, int DY_, 
00039            int dx_, int dy_, 
00040            float FontScale_, float PrintScale_)
00041 {
00042   Painter = p;
00043   Scale = Scale_;
00044   FontScale = FontScale_;
00045   PrintScale = PrintScale_;
00046   DX = float(DX_) * Scale - float(dx_);
00047   DY = float(DY_) * Scale - float(dy_);
00048 
00049   QFont f = p->font();
00050   if(FontScale == 0.0)
00051     FontScale = Scale;
00052 #ifdef __MINGW32__
00053   FontScale = Scale;
00054 #endif
00055   f.setPointSizeF( FontScale * float(f.pointSize()) );
00056   p->setFont(f);
00057   LineSpacing = p->fontMetrics().lineSpacing();
00058   p-> setMatrixEnabled(false);   // we use our own coordinate transformation
00059 
00060   QPainter::RenderHints hints = 0;
00061   // Ask to to antialias drawings if requested
00062   if (QucsSettings.GraphAntiAliasing) hints |= QPainter::Antialiasing;
00063   // Ask to antialias text if requested
00064   if (QucsSettings.TextAntiAliasing) hints |= QPainter::TextAntialiasing;
00065   p->setRenderHints(hints);
00066 }
00067 
00068 // -------------------------------------------------------------
00069 void ViewPainter::map(int x1, int y1, int& x, int& y)
00070 {
00071   float z;
00072   z = float(x1)*Scale + DX;
00073   x = TO_INT(z);
00074   z = float(y1)*Scale + DY;
00075   y = TO_INT(z);
00076 }
00077 
00078 // -------------------------------------------------------------
00079 void ViewPainter::drawPoint(int x1i, int y1i)
00080 {
00081   float x1, y1;
00082   x1 = float(x1i)*Scale + DX;
00083   y1 = float(y1i)*Scale + DY;
00084 
00085   Painter->drawPoint(QPointF(x1, y1));
00086 }
00087 
00088 // -------------------------------------------------------------
00089 void ViewPainter::drawLine(int x1i, int y1i, int x2i, int y2i)
00090 {
00091   float x1, y1, x2, y2;
00092   x1 = float(x1i)*Scale + DX;
00093   y1 = float(y1i)*Scale + DY;
00094   x2 = float(x2i)*Scale + DX;
00095   y2 = float(y2i)*Scale + DY;
00096 
00097   Painter->drawLine(QLineF(x1, y1, x2, y2));
00098 }
00099 
00100 // -------------------------------------------------------------
00104 void Graph::drawLines(int x0, int y0, ViewPainter *p) const
00105 {
00106   float DX_, DY_;
00107   float x1, y1;
00108   auto Scale = p->Scale;
00109   auto Painter = p->Painter;
00110   QVector<qreal> dashes;
00111 
00112   double Stroke=10., Space=0.;
00113   switch(Style) {
00114     case GRAPHSTYLE_DASH:
00115       Stroke = 10.; Space =  6.;
00116       break;
00117     case GRAPHSTYLE_DOT:
00118       Stroke =  2.; Space =  4.;
00119       break;
00120     case GRAPHSTYLE_LONGDASH:
00121       Stroke = 24.; Space =  8.;
00122       break;
00123     default:
00124       break;
00125   }
00126 
00127   QPen pen = Painter->pen();
00128   switch(Style) {
00129     case GRAPHSTYLE_DASH:
00130     case GRAPHSTYLE_DOT:
00131     case GRAPHSTYLE_LONGDASH:
00132       dashes << Stroke << Space;
00133       pen.setDashPattern(dashes);
00134       Painter->setPen(pen);
00135       break;
00136     default:
00137       pen.setStyle(Qt::SolidLine);
00138       break;
00139   }
00140   Painter->setPen(pen);
00141 
00142   auto pp = begin();
00143   if(!pp->isPt())
00144     pp++;
00145 
00146   DX_ = p->DX + float(x0)*Scale;
00147   DY_ = p->DY + float(y0)*Scale;
00148 
00149   while(!pp->isGraphEnd()) {
00150     if(pp->isStrokeEnd()) ++pp; // ??
00151     QPainterPath path;
00152     if(pp->isPt()) {
00153       x1 = DX_ + pp->getScrX()*Scale;
00154       y1 = DY_ - pp->getScrY()*Scale;
00155       path.moveTo(x1,y1);
00156       ++pp;
00157     }else{
00158       break;
00159     }
00160 
00161     while(!pp->isStrokeEnd()) {
00162       x1 = DX_ + pp->getScrX()*Scale;
00163       y1 = DY_ - pp->getScrY()*Scale;
00164       path.lineTo(x1,y1);
00165       ++pp;
00166     }
00167 
00168     Painter->drawPath(path);
00169   }
00170 }
00171 
00172 // -------------------------------------------------------------
00173 void Graph::drawStarSymbols(int x0i, int y0i, ViewPainter *p) const
00174 {
00175   float x3, x0, y0, x1, x2, y1, y2;
00176   float z, DX_, DY_;
00177   auto Scale = p->Scale;
00178   auto Painter = p->Painter;
00179   auto pp = begin();
00180   if(!pp->isPt())
00181     pp++;
00182 
00183   DX_ = p->DX + float(x0i)*Scale;
00184   DY_ = p->DY + float(y0i)*Scale;
00185 
00186   while(!pp->isGraphEnd()) {
00187     if(pp->isPt()) {
00188       z = DX_ + pp->getScrX()*Scale;
00189       x0 = z-5.0*Scale;
00190       x3 = z+5.0*Scale;
00191       x1 = z-4.0*Scale;
00192       x2 = z+4.0*Scale;
00193       z = DY_ - (pp++)->getScrY()*Scale;
00194       y0 = z;
00195       y1 = z-4.0*Scale;
00196       y2 = z+4.0*Scale;
00197       Painter->drawLine(QLineF(x0, y0, x3, y0)); // horizontal line
00198       Painter->drawLine(QLineF(x1, y2, x2, y1)); // upper left to lower right
00199       Painter->drawLine(QLineF(x2, y2, x1, y1)); // upper right to lower left
00200     }
00201     else  pp++;
00202   }
00203 }
00204 
00205 // -------------------------------------------------------------
00206 void Graph::drawCircleSymbols(int x0i, int y0i, ViewPainter *p) const
00207 {
00208   float x0, y0;
00209   float z, DX_, DY_;
00210   auto Scale = p->Scale;
00211   auto Painter = p->Painter;
00212   auto pp = begin();
00213   if(!pp->isPt())
00214     pp++;
00215 
00216   z = 8.0*Scale;
00217   DX_ = p->DX + float(x0i)*Scale;
00218   DY_ = p->DY + float(y0i)*Scale;
00219 
00220   while(!pp->isGraphEnd()) {
00221     if(pp->isPt()) {
00222       x0 = DX_ + (pp->getScrX()-4.0)*Scale;
00223       y0 = DY_ - ((pp++)->getScrY()+4.0)*Scale;
00224       Painter->drawEllipse(QRectF(x0, y0, z, z));
00225     }
00226     else  pp++;
00227   }
00228 }
00229 
00230 // -------------------------------------------------------------
00231 void Graph::drawArrowSymbols(int x0i, int y0i, ViewPainter *p) const
00232 {
00233   int x0, y0, x1, x2, y1, y2;
00234   float DX_, DY_;
00235   auto Scale = p->Scale;
00236   auto Painter = p->Painter;
00237   auto pp = begin();
00238   if(!pp->isPt())
00239     pp++;
00240 
00241   DX_ = p->DX + float(x0i)*Scale;
00242   DY_ = p->DY + float(y0i)*Scale;
00243   y2 = DY_;
00244 
00245   while(!pp->isGraphEnd()) {
00246     if(pp->isPt()) {
00247       x0 = DX_ + pp->getScrX()*Scale;
00248       x1 = x0-4.0*Scale;
00249       x2 = x0+4.0*Scale;
00250       y0 = DY_ - (pp++)->getScrY()*Scale;
00251       y1 = y0+7.0*Scale;
00252       Painter->drawLine(QLineF(x0, y0, x0, y2));
00253       Painter->drawLine(QLineF(x1, y1, x0, y0));
00254       Painter->drawLine(QLineF(x2, y1, x0, y0));
00255     }
00256     else  pp++;
00257   }
00258 }
00259 
00260 // -------------------------------------------------------------
00261 void ViewPainter::drawRect(int x1i, int y1i, int dxi, int dyi)
00262 {
00263   float x1, y1, dx, dy;
00264   x1 = float(x1i)*Scale + DX;
00265   y1 = float(y1i)*Scale + DY;
00266   dx = float(dxi)*Scale;
00267   dy = float(dyi)*Scale;
00268 
00269   Painter->drawRect(QRectF(x1, y1, dx, dy));
00270 }
00271 
00272 // -------------------------------------------------------------
00273 void ViewPainter::drawRectD(int x1i, int y1i, int dx, int dy)
00274 {
00275   float x1, y1;
00276   x1 = float(x1i)*Scale + DX;
00277   y1 = float(y1i)*Scale + DY;
00278 
00279   Painter->drawRect(QRectF(x1, y1, dx, dy));
00280 }
00281 
00282 // -------------------------------------------------------------
00283 void ViewPainter::drawRoundRect(int x1i, int y1i, int dxi, int dyi)
00284 {
00285   float x1, y1, dx, dy;
00286   x1 = float(x1i)*Scale + DX;
00287   y1 = float(y1i)*Scale + DY;
00288   dx = float(dxi)*Scale;
00289   dy = float(dyi)*Scale;
00290 
00291   Painter->drawRoundRect(QRectF(x1, y1, dx, dy));
00292 }
00293 
00294 // -------------------------------------------------------------
00295 void ViewPainter::drawEllipse(int x1i, int y1i, int dxi, int dyi)
00296 {
00297   float x1, y1, dx, dy;
00298   x1 = float(x1i)*Scale + DX;
00299   y1 = float(y1i)*Scale + DY;
00300   dx = float(dxi)*Scale;
00301   dy = float(dyi)*Scale;
00302 
00303   Painter->drawEllipse(QRectF(x1, y1, dx, dy));
00304 }
00305 
00306 // -------------------------------------------------------------
00307 // Returns width of text (and height if pointer is not null).
00308 int ViewPainter::drawText(const QString& Text, int x1i, int y1i, int *Height)
00309 {
00310   float x1, y1;
00311   x1= float(x1i)*Scale + DX;
00312   y1 = float(y1i)*Scale + DY;
00313 
00314   QRectF rf;
00315   rf = Painter->boundingRect(QRectF(x1, y1, 0, 0), Qt::TextDontClip, Text);
00316   Painter->drawText(QRectF(x1, y1, 0, 0), Qt::TextDontClip, Text);
00317 
00318   if(Height)  *Height = TO_INT(rf.height());
00319   return TO_INT(rf.width());
00320 }
00321 
00322 // -------------------------------------------------------------
00323 // Returns width of text (and height if pointer is not null).
00324 int ViewPainter::drawTextMapped(const QString& Text, int x1, int y1,
00325         int *Height)
00326 {
00327   QRectF rf;
00328   float y = 0.0;
00329   float x = 0.0;
00330   float h = 0.0;
00331   float w = 0.0;
00332   int i = 0;
00333 
00334   while (Text.length()>i) {
00335     if ((Text[i].toLatin1() == '_' || Text[i].toLatin1() == '^') &&
00336   !Text[i+1].isNull()) {
00337       bool is_sub = Text[i++].toLatin1() == '_';
00338       int len = 0;
00339 
00340       if (Text[i] == '{') {
00341         i++;
00342         while (!Text[i+len].isNull() && Text[i+len].toLatin1() != '}') len++;
00343       }
00344 
00345 #ifdef __MINGW32__
00346       float scale = 1.0;
00347 #else
00348       float scale = PrintScale;
00349 #endif
00350       QFont fbak = Painter->font();
00351       QFont f = Painter->font();
00352       f.setPointSizeF(f.pointSizeF()*0.8);
00353       Painter->setFont(f);
00354 
00355       rf = Painter->boundingRect(QRectF(x1+x,
00356       y1+y + (is_sub ? +0.6 : -0.3) *
00357       fbak.pointSizeF() * scale,
00358       0, 0), Qt::TextDontClip,
00359       Text.mid(i, len ? len : 1));
00360 
00361       Painter->drawText(QRectF(x1+x,
00362       y1+y + (is_sub ? +0.6 : -0.3) *
00363       fbak.pointSizeF() * scale,
00364       0, 0), Qt::TextDontClip,
00365       Text.mid(i, len ? len : 1));
00366 
00367       Painter->setFont(fbak);
00368       x += rf.width();
00369       if (x > w) w = x;
00370       i += len ? len + 1 : 1;
00371     }
00372     else
00373     {
00374       int len = 0;
00375       while (Text.length()>(i+len) && Text[i+len].toLatin1() != '_' &&
00377        Text[i+len].toLatin1() != '^' && Text[i+len].toLatin1() != '\n')
00378       len++;
00379 
00380       rf = Painter->boundingRect(QRectF(x1+x, y1+y, 0, 0),
00381          Qt::TextDontClip, Text.mid(i, len));
00382       Painter->drawText(QRectF(x1+x, y1+y, 0, 0),
00383       Qt::TextDontClip, Text.mid(i, len));
00384 
00385       if (h < rf.height()) {
00386         h = rf.height();
00387       }
00388       x += rf.width();
00389       if (x > w) w = x;
00390       if (Text.length()>(i+len)&&Text[i+len].toLatin1() == '\n') {
00391         y += h;
00392         x = 0;
00393         i++;
00394       }
00395       i += len;
00396     }
00397   }
00398 
00399   if(Height) *Height = y+h;
00400   return w;
00401 }
00402 
00403 // -------------------------------------------------------------
00404 void ViewPainter::drawArc(int x1i, int y1i, int wi, int hi, int Angle, int ArcLen)
00405 {
00406   float x1, y1, w, h;
00407   x1 = float(x1i)*Scale + DX;
00408   y1 = float(y1i)*Scale + DY;
00409   w = float(wi)*Scale;
00410   h = float(hi)*Scale;
00411 
00412   Painter->drawArc(QRectF(x1, y1, w, h), Angle, ArcLen);
00413 }
00414 
00415 // -------------------------------------------------------------
00416 void ViewPainter::fillRect(int x1i, int y1i, int dxi, int dyi, const QColor& Color)
00417 {
00418   float x1, y1, dx, dy;
00419   x1 = float(x1i)*Scale + DX;
00420   y1 = float(y1i)*Scale + DY;
00421 
00422   dx = float(dxi)*Scale;
00423   dy = float(dyi)*Scale;
00424 
00425   Painter->fillRect(QRectF(x1, y1, dx, dy), QBrush(Color));
00426 }
00427 
00428 // -------------------------------------------------------------
00429 void ViewPainter::eraseRect(int x1i, int y1i, int dx, int dy)
00430 {
00431   float x1, y1;
00432   x1 = float(x1i)*Scale + DX;
00433   y1 = float(y1i)*Scale + DY;
00434 
00435   Painter->eraseRect(QRectF(x1, y1, dx, dy));
00436 }
00437 
00438 // -------------------------------------------------------------
00439 // Draw little resize rectangles with center x1/y1 and size independent
00440 // of zoom factor.
00441 void ViewPainter::drawResizeRect(int x1i, int y1i)
00442 {
00443   float x1, y1;
00444   x1 = float(x1i)*Scale + DX;
00445   y1 = float(y1i)*Scale + DY;
00446 
00447   Painter->drawRect(QRectF(x1-5, y1-5, 10, 10));
00448 }
00449 
00450 // vim:ts=8:sw=2:noet
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines