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