Mercurial > hg > svgui
comparison layer/SliceLayer.cpp @ 1383:86f319dd6ab9 spectrogramparam
Switch spectrum to antialiased drawing with considerable speedup for the dense areas; take horizontal scale height into account when rendering slice layer height
author | Chris Cannam |
---|---|
date | Wed, 07 Nov 2018 15:59:10 +0000 |
parents | 2df1af7ac752 |
children | 413e09f303ba |
comparison
equal
deleted
inserted
replaced
1382:2df1af7ac752 | 1383:86f319dd6ab9 |
---|---|
21 #include "base/RealTime.h" | 21 #include "base/RealTime.h" |
22 #include "ColourMapper.h" | 22 #include "ColourMapper.h" |
23 #include "ColourDatabase.h" | 23 #include "ColourDatabase.h" |
24 | 24 |
25 #include "PaintAssistant.h" | 25 #include "PaintAssistant.h" |
26 | |
27 #include "base/Profiler.h" | |
26 | 28 |
27 #include <QPainter> | 29 #include <QPainter> |
28 #include <QPainterPath> | 30 #include <QPainterPath> |
29 #include <QTextStream> | 31 #include <QTextStream> |
30 | 32 |
362 } | 364 } |
363 | 365 |
364 void | 366 void |
365 SliceLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const | 367 SliceLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const |
366 { | 368 { |
367 if (!m_sliceableModel || !m_sliceableModel->isOK() || | 369 if (!m_sliceableModel || |
370 !m_sliceableModel->isOK() || | |
368 !m_sliceableModel->isReady()) return; | 371 !m_sliceableModel->isReady()) return; |
369 | 372 |
373 Profiler profiler("SliceLayer::paint()"); | |
374 | |
370 paint.save(); | 375 paint.save(); |
371 paint.setRenderHint(QPainter::Antialiasing, m_plotStyle == PlotLines); | 376 paint.setRenderHint(QPainter::Antialiasing, true); |
372 paint.setBrush(Qt::NoBrush); | 377 paint.setBrush(Qt::NoBrush); |
373 | 378 |
374 if (v->getViewManager() && v->getViewManager()->shouldShowScaleGuides()) { | 379 if (v->getViewManager() && v->getViewManager()->shouldShowScaleGuides()) { |
375 if (!m_scalePoints.empty()) { | 380 if (!m_scalePoints.empty()) { |
376 paint.setPen(QColor(240, 240, 240)); //!!! and dark background? | 381 paint.setPen(QColor(240, 240, 240)); //!!! and dark background? |
391 } | 396 } |
392 | 397 |
393 int xorigin = getVerticalScaleWidth(v, true, paint) + 1; | 398 int xorigin = getVerticalScaleWidth(v, true, paint) + 1; |
394 m_xorigins[v->getId()] = xorigin; // for use in getFeatureDescription | 399 m_xorigins[v->getId()] = xorigin; // for use in getFeatureDescription |
395 | 400 |
396 int yorigin = v->getPaintHeight() - 20 - paint.fontMetrics().height() - 7; | 401 int yorigin = v->getPaintHeight() - getHorizontalScaleHeight(v, paint) - |
402 paint.fontMetrics().height(); | |
397 int h = yorigin - paint.fontMetrics().height() - 8; | 403 int h = yorigin - paint.fontMetrics().height() - 8; |
398 | 404 |
399 m_yorigins[v->getId()] = yorigin; // for getYForValue etc | 405 m_yorigins[v->getId()] = yorigin; // for getYForValue etc |
400 m_heights[v->getId()] = h; | 406 m_heights[v->getId()] = h; |
401 | 407 |
432 if (m_samplingMode != NearestSample) col1 = int(f1 / res); | 438 if (m_samplingMode != NearestSample) col1 = int(f1 / res); |
433 f0 = col0 * res; | 439 f0 = col0 * res; |
434 f1 = (col1 + 1) * res - 1; | 440 f1 = (col1 + 1) * res - 1; |
435 | 441 |
436 // cerr << "resolution " << res << ", col0 " << col0 << ", col1 " << col1 << ", f0 " << f0 << ", f1 " << f1 << endl; | 442 // cerr << "resolution " << res << ", col0 " << col0 << ", col1 " << col1 << ", f0 " << f0 << ", f1 " << f1 << endl; |
443 // cerr << "mh = " << mh << endl; | |
437 | 444 |
438 m_currentf0 = f0; | 445 m_currentf0 = f0; |
439 m_currentf1 = f1; | 446 m_currentf1 = f1; |
440 | 447 |
441 BiasCurve curve; | 448 BiasCurve curve; |
442 getBiasCurve(curve); | 449 getBiasCurve(curve); |
443 int cs = int(curve.size()); | 450 int cs = int(curve.size()); |
444 | 451 |
445 for (int col = col0; col <= col1; ++col) { | 452 for (int col = col0; col <= col1; ++col) { |
453 DenseThreeDimensionalModel::Column column = | |
454 m_sliceableModel->getColumn(col); | |
446 for (int bin = 0; bin < mh; ++bin) { | 455 for (int bin = 0; bin < mh; ++bin) { |
447 float value = m_sliceableModel->getValueAt(col, bin0 + bin); | 456 float value = column[bin0 + bin]; |
448 if (bin < cs) value *= curve[bin]; | 457 if (bin < cs) value *= curve[bin]; |
449 if (m_samplingMode == SamplePeak) { | 458 if (m_samplingMode == SamplePeak) { |
450 if (value > m_values[bin]) m_values[bin] = value; | 459 if (value > m_values[bin]) m_values[bin] = value; |
451 } else { | 460 } else { |
452 m_values[bin] += value; | 461 m_values[bin] += value; |
470 | 479 |
471 double nx = getXForBin(v, bin0); | 480 double nx = getXForBin(v, bin0); |
472 | 481 |
473 ColourMapper mapper(m_colourMap, m_colourInverted, 0, 1); | 482 ColourMapper mapper(m_colourMap, m_colourInverted, 0, 1); |
474 | 483 |
484 double ytop = 0, ybottom = 0; | |
485 bool firstBinOfPixel = true; | |
486 | |
475 for (int bin = 0; bin < mh; ++bin) { | 487 for (int bin = 0; bin < mh; ++bin) { |
476 | 488 |
477 double x = nx; | 489 double x = nx; |
478 nx = getXForBin(v, bin + bin0 + 1); | 490 nx = getXForBin(v, bin + bin0 + 1); |
479 | 491 |
480 double value = m_values[bin]; | 492 double value = m_values[bin]; |
481 double norm = 0.0; | 493 double norm = 0.0; |
482 double y = getYForValue(v, value, norm); | 494 double y = getYForValue(v, value, norm); |
483 | 495 |
484 if (m_plotStyle == PlotLines) { | 496 if (y < ytop || firstBinOfPixel) { |
485 | 497 ytop = y; |
486 if (bin == 0) { | 498 } |
487 path.moveTo((x + nx) / 2, y); | 499 if (y > ybottom || firstBinOfPixel) { |
488 } else { | 500 ybottom = y; |
489 path.lineTo((x + nx) / 2, y); | 501 } |
502 | |
503 if (int(nx) != int(x) || bin+1 == mh) { | |
504 | |
505 if (m_plotStyle == PlotLines) { | |
506 | |
507 auto px = (x + nx) / 2; | |
508 | |
509 if (bin == 0) { | |
510 path.moveTo(px, y); | |
511 } else { | |
512 if (ytop != ybottom) { | |
513 path.lineTo(px, ybottom); | |
514 path.lineTo(px, ytop); | |
515 path.moveTo(px, ybottom); | |
516 } else { | |
517 path.lineTo(px, ytop); | |
518 } | |
519 } | |
520 | |
521 } else if (m_plotStyle == PlotSteps) { | |
522 | |
523 if (bin == 0) { | |
524 path.moveTo(x, y); | |
525 } else { | |
526 path.lineTo(x, ytop); | |
527 } | |
528 path.lineTo(nx, ytop); | |
529 | |
530 } else if (m_plotStyle == PlotBlocks) { | |
531 | |
532 path.moveTo(x, yorigin); | |
533 path.lineTo(x, ytop); | |
534 path.lineTo(nx, ytop); | |
535 path.lineTo(nx, yorigin); | |
536 path.lineTo(x, yorigin); | |
537 | |
538 } else if (m_plotStyle == PlotFilledBlocks) { | |
539 | |
540 paint.fillRect(QRectF(x, ytop, nx - x, yorigin - ytop), | |
541 mapper.map(norm)); | |
490 } | 542 } |
491 | 543 |
492 } else if (m_plotStyle == PlotSteps) { | 544 firstBinOfPixel = true; |
493 | 545 |
494 if (bin == 0) { | 546 } else { |
495 path.moveTo(x, y); | 547 firstBinOfPixel = false; |
496 } else { | 548 } |
497 path.lineTo(x, y); | |
498 } | |
499 path.lineTo(nx, y); | |
500 | |
501 } else if (m_plotStyle == PlotBlocks) { | |
502 | |
503 path.moveTo(x, yorigin); | |
504 path.lineTo(x, y); | |
505 path.lineTo(nx, y); | |
506 path.lineTo(nx, yorigin); | |
507 path.lineTo(x, yorigin); | |
508 | |
509 } else if (m_plotStyle == PlotFilledBlocks) { | |
510 | |
511 paint.fillRect(QRectF(x, y, nx - x, yorigin - y), mapper.map(norm)); | |
512 } | |
513 | |
514 } | 549 } |
515 | 550 |
516 if (m_plotStyle != PlotFilledBlocks) { | 551 if (m_plotStyle != PlotFilledBlocks) { |
517 paint.drawPath(path); | 552 paint.drawPath(path); |
518 } | 553 } |
542 } | 577 } |
543 | 578 |
544 // int h = (rect.height() * 3) / 4; | 579 // int h = (rect.height() * 3) / 4; |
545 // int y = (rect.height() / 2) - (h / 2); | 580 // int y = (rect.height() / 2) - (h / 2); |
546 | 581 |
547 int yorigin = v->getPaintHeight() - 20 - paint.fontMetrics().height() - 6; | 582 int yorigin = v->getPaintHeight() - getHorizontalScaleHeight(v, paint) - |
583 paint.fontMetrics().height(); | |
548 int h = yorigin - paint.fontMetrics().height() - 8; | 584 int h = yorigin - paint.fontMetrics().height() - 8; |
549 if (h < 0) return; | 585 if (h < 0) return; |
550 | 586 |
551 QRect actual(rect.x(), rect.y() + yorigin - h, rect.width(), h); | 587 QRect actual(rect.x(), rect.y() + yorigin - h, rect.width(), h); |
552 | 588 |