Qucs-GUI
0.0.19
|
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