Mercurial > hg > svgui
comparison layer/WaveformLayer.cpp @ 1367:f5566f7271fe waverevision
Rework waveform renderer to use smooth paths, aiming to get near-pixel-identical results when zoomed out far enough for a single path not to be relevant
author | Chris Cannam |
---|---|
date | Wed, 31 Oct 2018 15:06:32 +0000 |
parents | c2a3ac0a6688 |
children | ca9a36a5ab76 |
comparison
equal
deleted
inserted
replaced
1366:c2a3ac0a6688 | 1367:f5566f7271fe |
---|---|
43 SingleColourLayer(), | 43 SingleColourLayer(), |
44 m_model(0), | 44 m_model(0), |
45 m_gain(1.0f), | 45 m_gain(1.0f), |
46 m_autoNormalize(false), | 46 m_autoNormalize(false), |
47 m_showMeans(true), | 47 m_showMeans(true), |
48 m_greyscale(true), | |
49 m_channelMode(SeparateChannels), | 48 m_channelMode(SeparateChannels), |
50 m_channel(-1), | 49 m_channel(-1), |
51 m_scale(LinearScale), | 50 m_scale(LinearScale), |
52 m_middleLineHeight(0.5), | 51 m_middleLineHeight(0.5), |
53 m_aggressive(false), | 52 m_aggressive(false), |
272 m_cacheValid = false; | 271 m_cacheValid = false; |
273 emit layerParametersChanged(); | 272 emit layerParametersChanged(); |
274 } | 273 } |
275 | 274 |
276 void | 275 void |
277 WaveformLayer::setUseGreyscale(bool useGreyscale) | |
278 { | |
279 if (m_greyscale == useGreyscale) return; | |
280 m_greyscale = useGreyscale; | |
281 m_cacheValid = false; | |
282 emit layerParametersChanged(); | |
283 } | |
284 | |
285 void | |
286 WaveformLayer::setChannelMode(ChannelMode channelMode) | 276 WaveformLayer::setChannelMode(ChannelMode channelMode) |
287 { | 277 { |
288 if (m_channelMode == channelMode) return; | 278 if (m_channelMode == channelMode) return; |
289 m_channelMode = channelMode; | 279 m_channelMode = channelMode; |
290 m_cacheValid = false; | 280 m_cacheValid = false; |
354 unit = "dB"; | 344 unit = "dB"; |
355 } | 345 } |
356 return true; | 346 return true; |
357 } | 347 } |
358 | 348 |
359 int | 349 double |
360 WaveformLayer::dBscale(double sample, int m) const | 350 WaveformLayer::dBscale(double sample, int m) const |
361 { | 351 { |
362 if (sample < 0.0) return dBscale(-sample, m); | 352 if (sample < 0.0) return dBscale(-sample, m); |
363 double dB = AudioLevel::multiplier_to_dB(sample); | 353 double dB = AudioLevel::multiplier_to_dB(sample); |
364 if (dB < -50.0) return 0; | 354 if (dB < -50.0) return 0; |
365 if (dB > 0.0) return m; | 355 if (dB > 0.0) return m; |
366 return int(((dB + 50.0) * m) / 50.0 + 0.1); | 356 return ((dB + 50.0) * m) / 50.0; |
367 } | 357 } |
368 | 358 |
369 int | 359 int |
370 WaveformLayer::getChannelArrangement(int &min, int &max, | 360 WaveformLayer::getChannelArrangement(int &min, int &max, |
371 bool &merging, bool &mixing) | 361 bool &merging, bool &mixing) |
545 | 535 |
546 } else { | 536 } else { |
547 paint = &viewPainter; | 537 paint = &viewPainter; |
548 } | 538 } |
549 | 539 |
550 paint->setRenderHint(QPainter::Antialiasing, false); | 540 paint->setRenderHint(QPainter::Antialiasing, true); |
551 | 541 |
552 if (m_middleLineHeight != 0.5) { | 542 if (m_middleLineHeight != 0.5) { |
553 paint->save(); | 543 paint->save(); |
554 double space = m_middleLineHeight * 2; | 544 double space = m_middleLineHeight * 2; |
555 if (space > 1.0) space = 2.0 - space; | 545 if (space > 1.0) space = 2.0 - space; |
762 channels = getChannelArrangement(minChannel, maxChannel, | 752 channels = getChannelArrangement(minChannel, maxChannel, |
763 mergingChannels, mixingChannels); | 753 mergingChannels, mixingChannels); |
764 if (channels == 0) return; | 754 if (channels == 0) return; |
765 | 755 |
766 QColor baseColour = getBaseQColor(); | 756 QColor baseColour = getBaseQColor(); |
767 vector<QColor> greys = getPartialShades(v); | |
768 | |
769 QColor midColour = baseColour; | 757 QColor midColour = baseColour; |
758 | |
770 if (midColour == Qt::black) { | 759 if (midColour == Qt::black) { |
771 midColour = Qt::gray; | 760 midColour = Qt::gray; |
772 } else if (v->hasLightBackground()) { | 761 } else if (v->hasLightBackground()) { |
773 midColour = midColour.light(150); | 762 midColour = midColour.light(150); |
774 } else { | 763 } else { |
775 midColour = midColour.light(50); | 764 midColour = midColour.light(50); |
776 } | 765 } |
777 | 766 |
778 int prevRangeBottom = -1, prevRangeTop = -1; | |
779 QColor prevRangeBottomColour = baseColour, prevRangeTopColour = baseColour; | |
780 | |
781 double gain = m_effectiveGains[ch]; | 767 double gain = m_effectiveGains[ch]; |
782 | 768 |
783 int m = (h / channels) / 2; | 769 int m = (h / channels) / 2; |
784 int my = m + (((ch - minChannel) * h) / channels); | 770 int my = m + (((ch - minChannel) * h) / channels); |
785 | 771 |
793 m_channelMode != MergeChannels) { | 779 m_channelMode != MergeChannels) { |
794 m = (h / channels); | 780 m = (h / channels); |
795 my = m + (((ch - minChannel) * h) / channels); | 781 my = m + (((ch - minChannel) * h) / channels); |
796 } | 782 } |
797 | 783 |
798 paint->setPen(greys[1]); | 784 // Horizontal axis along middle |
785 paint->setPen(QPen(midColour, 0)); | |
799 paint->drawLine(x0, my, x1, my); | 786 paint->drawLine(x0, my, x1, my); |
800 | 787 |
801 paintChannelScaleGuides(v, paint, rect, ch); | 788 paintChannelScaleGuides(v, paint, rect, ch); |
802 | 789 |
803 int rangeix = ch - minChannel; | 790 int rangeix = ch - minChannel; |
806 SVCERR << "paint channel " << ch << ": frame0 = " << frame0 << ", frame1 = " << frame1 << ", blockSize = " << blockSize << ", have " << ranges.size() << " range blocks of which ours is index " << rangeix << " with " << ranges[rangeix].size() << " ranges in it" << endl; | 793 SVCERR << "paint channel " << ch << ": frame0 = " << frame0 << ", frame1 = " << frame1 << ", blockSize = " << blockSize << ", have " << ranges.size() << " range blocks of which ours is index " << rangeix << " with " << ranges[rangeix].size() << " ranges in it" << endl; |
807 #else | 794 #else |
808 (void)frame1; // not actually used | 795 (void)frame1; // not actually used |
809 #endif | 796 #endif |
810 | 797 |
798 QPainterPath waveformPath; | |
799 QPainterPath meanPath; | |
800 QPainterPath clipPath; | |
801 vector<QPointF> individualSamplePoints; | |
802 | |
803 bool firstPoint = true; | |
804 | |
811 for (int x = x0; x <= x1; ++x) { | 805 for (int x = x0; x <= x1; ++x) { |
812 | 806 |
813 sv_frame_t f0, f1; | 807 sv_frame_t f0, f1; |
814 sv_frame_t i0, i1; | 808 sv_frame_t i0, i1; |
815 | 809 |
861 SVCERR << "No (or not enough) ranges for index i0 = " << i0 << " (there are " << r.size() << " range(s))" << endl; | 855 SVCERR << "No (or not enough) ranges for index i0 = " << i0 << " (there are " << r.size() << " range(s))" << endl; |
862 #endif | 856 #endif |
863 continue; | 857 continue; |
864 } | 858 } |
865 | 859 |
866 int rangeBottom = 0, rangeTop = 0, meanBottom = 0, meanTop = 0; | 860 double rangeBottom = 0, rangeTop = 0, meanBottom = 0, meanTop = 0; |
867 | 861 |
868 if (mergingChannels && ranges.size() > 1) { | 862 if (mergingChannels && ranges.size() > 1) { |
869 | 863 |
870 const auto &other = ranges[1]; | 864 const auto &other = ranges[1]; |
871 | 865 |
893 range.setMin((range.min() + other[i0].min()) / 2); | 887 range.setMin((range.min() + other[i0].min()) / 2); |
894 range.setAbsmean((range.absmean() + other[i0].absmean()) / 2); | 888 range.setAbsmean((range.absmean() + other[i0].absmean()) / 2); |
895 } | 889 } |
896 } | 890 } |
897 | 891 |
898 int greyLevels = 1; | |
899 if (m_greyscale && (m_scale == LinearScale)) greyLevels = 4; | |
900 | |
901 switch (m_scale) { | 892 switch (m_scale) { |
902 | 893 |
903 case LinearScale: | 894 case LinearScale: |
904 rangeBottom = int(double(m * greyLevels) * range.min() * gain); | 895 rangeBottom = range.min() * gain * m; |
905 rangeTop = int(double(m * greyLevels) * range.max() * gain); | 896 rangeTop = range.max() * gain * m; |
906 meanBottom = int(double(-m) * range.absmean() * gain); | 897 meanBottom = range.absmean() * gain * (-m); |
907 meanTop = int(double(m) * range.absmean() * gain); | 898 meanTop = range.absmean() * gain * m; |
908 break; | 899 break; |
909 | 900 |
910 case dBScale: | 901 case dBScale: |
911 if (!mergingChannels) { | 902 if (!mergingChannels) { |
912 int db0 = dBscale(range.min() * gain, m); | 903 double db0 = dBscale(range.min() * gain, m); |
913 int db1 = dBscale(range.max() * gain, m); | 904 double db1 = dBscale(range.max() * gain, m); |
914 rangeTop = std::max(db0, db1); | 905 rangeTop = std::max(db0, db1); |
915 meanTop = std::min(db0, db1); | 906 meanTop = std::min(db0, db1); |
916 if (mixingChannels) rangeBottom = meanTop; | 907 if (mixingChannels) rangeBottom = meanTop; |
917 else rangeBottom = dBscale(range.absmean() * gain, m); | 908 else rangeBottom = dBscale(range.absmean() * gain, m); |
909 meanBottom = rangeBottom; | |
910 } else { | |
911 rangeBottom = -dBscale(range.min() * gain, m); | |
912 rangeTop = dBscale(range.max() * gain, m); | |
913 meanBottom = -dBscale(range.absmean() * gain, m); | |
914 meanTop = dBscale(range.absmean() * gain, m); | |
915 } | |
916 break; | |
917 | |
918 case MeterScale: | |
919 if (!mergingChannels) { | |
920 double r0 = fabs(AudioLevel::multiplier_to_preview | |
921 (range.min() * gain, m)); | |
922 double r1 = fabs(AudioLevel::multiplier_to_preview | |
923 (range.max() * gain, m)); | |
924 rangeTop = std::max(r0, r1); | |
925 meanTop = std::min(r0, r1); | |
926 if (mixingChannels) rangeBottom = meanTop; | |
927 else rangeBottom = AudioLevel::multiplier_to_preview | |
928 (range.absmean() * gain, m); | |
918 meanBottom = rangeBottom; | 929 meanBottom = rangeBottom; |
919 } else { | 930 } else { |
920 rangeBottom = -dBscale(range.min() * gain, m * greyLevels); | 931 rangeBottom = -AudioLevel::multiplier_to_preview |
921 rangeTop = dBscale(range.max() * gain, m * greyLevels); | 932 (range.min() * gain, m); |
922 meanBottom = -dBscale(range.absmean() * gain, m); | 933 rangeTop = AudioLevel::multiplier_to_preview |
923 meanTop = dBscale(range.absmean() * gain, m); | 934 (range.max() * gain, m); |
935 meanBottom = -AudioLevel::multiplier_to_preview | |
936 (range.absmean() * gain, m); | |
937 meanTop = AudioLevel::multiplier_to_preview | |
938 (range.absmean() * gain, m); | |
924 } | 939 } |
925 break; | 940 break; |
926 | 941 } |
927 case MeterScale: | 942 |
928 if (!mergingChannels) { | 943 rangeBottom = my - rangeBottom; |
929 int r0 = abs(AudioLevel::multiplier_to_preview(range.min() * gain, m)); | 944 rangeTop = my - rangeTop; |
930 int r1 = abs(AudioLevel::multiplier_to_preview(range.max() * gain, m)); | 945 meanBottom = my - meanBottom; |
931 rangeTop = std::max(r0, r1); | 946 meanTop = my - meanTop; |
932 meanTop = std::min(r0, r1); | |
933 if (mixingChannels) rangeBottom = meanTop; | |
934 else rangeBottom = AudioLevel::multiplier_to_preview(range.absmean() * gain, m); | |
935 meanBottom = rangeBottom; | |
936 } else { | |
937 rangeBottom = -AudioLevel::multiplier_to_preview(range.min() * gain, m * greyLevels); | |
938 rangeTop = AudioLevel::multiplier_to_preview(range.max() * gain, m * greyLevels); | |
939 meanBottom = -AudioLevel::multiplier_to_preview(range.absmean() * gain, m); | |
940 meanTop = AudioLevel::multiplier_to_preview(range.absmean() * gain, m); | |
941 } | |
942 break; | |
943 } | |
944 | |
945 rangeBottom = my * greyLevels - rangeBottom; | |
946 rangeTop = my * greyLevels - rangeTop; | |
947 meanBottom = my - meanBottom; | |
948 meanTop = my - meanTop; | |
949 | |
950 int topFill = (rangeTop % greyLevels); | |
951 if (topFill > 0) topFill = greyLevels - topFill; | |
952 | |
953 int bottomFill = (rangeBottom % greyLevels); | |
954 | |
955 rangeTop = rangeTop / greyLevels; | |
956 rangeBottom = rangeBottom / greyLevels; | |
957 | 947 |
958 bool clipped = false; | 948 bool clipped = false; |
959 | 949 |
960 if (rangeTop < my - m) { rangeTop = my - m; } | 950 if (rangeTop < my - m) { rangeTop = my - m; } |
961 if (rangeTop > my + m) { rangeTop = my + m; } | 951 if (rangeTop > my + m) { rangeTop = my + m; } |
962 if (rangeBottom < my - m) { rangeBottom = my - m; } | 952 if (rangeBottom < my - m) { rangeBottom = my - m; } |
963 if (rangeBottom > my + m) { rangeBottom = my + m; } | 953 if (rangeBottom > my + m) { rangeBottom = my + m; } |
964 | 954 |
965 if (range.max() <= -1.0 || | 955 if (range.max() <= -1.0 || range.max() >= 1.0) { |
966 range.max() >= 1.0) clipped = true; | 956 clipped = true; |
957 } | |
967 | 958 |
968 if (meanBottom > rangeBottom) meanBottom = rangeBottom; | |
969 if (meanTop < rangeTop) meanTop = rangeTop; | |
970 | |
971 bool drawMean = m_showMeans; | 959 bool drawMean = m_showMeans; |
972 if (meanTop == rangeTop) { | 960 |
973 if (meanTop < meanBottom) ++meanTop; | 961 meanTop = meanTop - 0.5; |
974 else drawMean = false; | 962 meanBottom = meanBottom + 0.5; |
975 } | |
976 if (meanBottom == rangeBottom && m_scale == LinearScale) { | |
977 if (meanBottom > meanTop) --meanBottom; | |
978 else drawMean = false; | |
979 } | |
980 | |
981 if (showIndividualSample) { | |
982 paint->setPen(baseColour); | |
983 paint->drawRect(x-1, rangeTop-1, 2, 2); | |
984 if (rangeTop != rangeBottom) { // e.g. for "butterfly" merging mode | |
985 paint->drawRect(x-1, rangeBottom-1, 2, 2); | |
986 } | |
987 } | |
988 | 963 |
989 if (x != x0 && prevRangeBottom != -1) { | 964 if (meanTop <= rangeTop + 1.0) { |
990 if (prevRangeBottom > rangeBottom + 1 && | 965 meanTop = rangeTop + 1.0; |
991 prevRangeTop > rangeBottom + 1) { | 966 } |
992 // paint->setPen(midColour); | 967 if (meanBottom >= rangeBottom - 1.0 && m_scale == LinearScale) { |
993 paint->setPen(baseColour); | 968 meanBottom = rangeBottom - 1.0; |
994 paint->drawLine(x-1, prevRangeTop, x, rangeBottom + 1); | 969 } |
995 paint->setPen(prevRangeTopColour); | 970 if (meanTop > meanBottom - 1.0) { |
996 paint->drawPoint(x-1, prevRangeTop); | 971 drawMean = false; |
997 } else if (prevRangeBottom < rangeTop - 1 && | |
998 prevRangeTop < rangeTop - 1) { | |
999 // paint->setPen(midColour); | |
1000 paint->setPen(baseColour); | |
1001 paint->drawLine(x-1, prevRangeBottom, x, rangeTop - 1); | |
1002 paint->setPen(prevRangeBottomColour); | |
1003 paint->drawPoint(x-1, prevRangeBottom); | |
1004 } | |
1005 } | |
1006 | |
1007 if (m_model->isReady()) { | |
1008 if (clipped /*!!! || | |
1009 range.min() * gain <= -1.0 || | |
1010 range.max() * gain >= 1.0 */) { | |
1011 paint->setPen(Qt::red); //!!! getContrastingColour | |
1012 } else { | |
1013 paint->setPen(baseColour); | |
1014 } | |
1015 } else { | |
1016 paint->setPen(midColour); | |
1017 } | 972 } |
1018 | 973 |
1019 #ifdef DEBUG_WAVEFORM_PAINT_BY_PIXEL | 974 #ifdef DEBUG_WAVEFORM_PAINT_BY_PIXEL |
1020 SVCERR << "range " << rangeBottom << " -> " << rangeTop << ", means " << meanBottom << " -> " << meanTop << ", raw range " << range.min() << " -> " << range.max() << endl; | 975 SVCERR << "range " << rangeBottom << " -> " << rangeTop << ", means " << meanBottom << " -> " << meanTop << ", raw range " << range.min() << " -> " << range.max() << endl; |
1021 #endif | 976 #endif |
1022 | 977 |
1023 if (rangeTop == rangeBottom) { | 978 double rangeMiddle = (rangeTop + rangeBottom) / 2.0; |
1024 paint->drawPoint(x, rangeTop); | 979 bool trivialRange = (fabs(rangeTop - rangeBottom) < 1.0); |
980 double px = x + 0.5; | |
981 | |
982 if (showIndividualSample) { | |
983 individualSamplePoints.push_back(QPointF(px, rangeTop)); | |
984 if (!trivialRange) { | |
985 // common e.g. in "butterfly" merging mode | |
986 individualSamplePoints.push_back(QPointF(px, rangeBottom)); | |
987 } | |
988 } | |
989 | |
990 if (firstPoint) { | |
991 waveformPath = QPainterPath(QPointF(px, rangeMiddle)); | |
992 firstPoint = false; | |
1025 } else { | 993 } else { |
1026 paint->drawLine(x, rangeBottom, x, rangeTop); | 994 waveformPath.lineTo(QPointF(px, rangeMiddle)); |
1027 } | 995 } |
1028 | 996 |
1029 prevRangeTopColour = baseColour; | 997 if (!trivialRange) { |
1030 prevRangeBottomColour = baseColour; | 998 waveformPath.lineTo(QPointF(px, rangeTop)); |
1031 | 999 waveformPath.lineTo(QPointF(px, rangeBottom)); |
1032 if (m_greyscale && (m_scale == LinearScale) && m_model->isReady()) { | 1000 waveformPath.lineTo(QPointF(px, rangeMiddle)); |
1033 if (!clipped) { | 1001 } |
1034 if (rangeTop < rangeBottom) { | 1002 |
1035 if (topFill > 0 && | |
1036 (!drawMean || (rangeTop < meanTop - 1))) { | |
1037 paint->setPen(greys[topFill - 1]); | |
1038 paint->drawPoint(x, rangeTop); | |
1039 prevRangeTopColour = greys[topFill - 1]; | |
1040 } | |
1041 if (bottomFill > 0 && | |
1042 (!drawMean || (rangeBottom > meanBottom + 1))) { | |
1043 paint->setPen(greys[bottomFill - 1]); | |
1044 paint->drawPoint(x, rangeBottom); | |
1045 prevRangeBottomColour = greys[bottomFill - 1]; | |
1046 } | |
1047 } | |
1048 } | |
1049 } | |
1050 | |
1051 if (drawMean) { | 1003 if (drawMean) { |
1052 paint->setPen(midColour); | 1004 meanPath.moveTo(QPointF(px, meanBottom)); |
1053 paint->drawLine(x, meanBottom, x, meanTop); | 1005 meanPath.lineTo(QPointF(px, meanTop)); |
1054 } | 1006 } |
1055 | 1007 |
1056 prevRangeBottom = rangeBottom; | 1008 if (clipped) { |
1057 prevRangeTop = rangeTop; | 1009 if (trivialRange) { |
1010 clipPath.moveTo(QPointF(px, rangeMiddle)); | |
1011 clipPath.lineTo(QPointF(px+1, rangeMiddle)); | |
1012 } else { | |
1013 clipPath.moveTo(QPointF(px, rangeBottom)); | |
1014 clipPath.lineTo(QPointF(px, rangeTop)); | |
1015 } | |
1016 } | |
1017 } | |
1018 | |
1019 double penWidth = 1.0; | |
1020 | |
1021 if (m_model->isReady()) { | |
1022 paint->setPen(QPen(baseColour, penWidth)); | |
1023 } else { | |
1024 paint->setPen(QPen(midColour, penWidth)); | |
1025 } | |
1026 paint->drawPath(waveformPath); | |
1027 | |
1028 if (!clipPath.isEmpty()) { | |
1029 paint->save(); | |
1030 paint->setPen(QPen(ColourDatabase::getInstance()-> | |
1031 getContrastingColour(m_colour), penWidth)); | |
1032 paint->drawPath(clipPath); | |
1033 paint->restore(); | |
1034 } | |
1035 | |
1036 if (!meanPath.isEmpty()) { | |
1037 paint->save(); | |
1038 paint->setPen(QPen(midColour, penWidth)); | |
1039 paint->drawPath(meanPath); | |
1040 paint->restore(); | |
1041 } | |
1042 | |
1043 if (!individualSamplePoints.empty()) { | |
1044 paint->save(); | |
1045 paint->setPen(QPen(baseColour, penWidth)); | |
1046 double sz = ViewManager::scalePixelSize(2.0); | |
1047 for (QPointF p: individualSamplePoints) { | |
1048 paint->drawRect(QRectF(p.x() - sz/2, p.y() - sz/2, sz, sz)); | |
1049 } | |
1050 paint->restore(); | |
1058 } | 1051 } |
1059 } | 1052 } |
1060 | 1053 |
1061 void | 1054 void |
1062 WaveformLayer::paintChannelScaleGuides(LayerGeometryProvider *v, | 1055 WaveformLayer::paintChannelScaleGuides(LayerGeometryProvider *v, |
1237 case MeterScale: | 1230 case MeterScale: |
1238 vy = AudioLevel::multiplier_to_preview(value, m); | 1231 vy = AudioLevel::multiplier_to_preview(value, m); |
1239 break; | 1232 break; |
1240 | 1233 |
1241 case dBScale: | 1234 case dBScale: |
1242 vy = dBscale(value, m); | 1235 vy = int(dBscale(value, m)); |
1243 break; | 1236 break; |
1244 } | 1237 } |
1245 | 1238 |
1246 // SVCERR << "mergingChannels= " << mergingChannels << ", channel = " << channel << ", value = " << value << ", vy = " << vy << endl; | 1239 // SVCERR << "mergingChannels= " << mergingChannels << ", channel = " << channel << ", value = " << value << ", vy = " << vy << endl; |
1247 | 1240 |
1509 "middleLineHeight=\"%7\" " | 1502 "middleLineHeight=\"%7\" " |
1510 "aggressive=\"%8\" " | 1503 "aggressive=\"%8\" " |
1511 "autoNormalize=\"%9\"") | 1504 "autoNormalize=\"%9\"") |
1512 .arg(m_gain) | 1505 .arg(m_gain) |
1513 .arg(m_showMeans) | 1506 .arg(m_showMeans) |
1514 .arg(m_greyscale) | 1507 .arg(true) // Option removed, but effectively always on, so |
1508 // retained in the session file for compatibility | |
1515 .arg(m_channelMode) | 1509 .arg(m_channelMode) |
1516 .arg(m_channel) | 1510 .arg(m_channel) |
1517 .arg(m_scale) | 1511 .arg(m_scale) |
1518 .arg(m_middleLineHeight) | 1512 .arg(m_middleLineHeight) |
1519 .arg(m_aggressive) | 1513 .arg(m_aggressive) |
1534 | 1528 |
1535 bool showMeans = (attributes.value("showMeans") == "1" || | 1529 bool showMeans = (attributes.value("showMeans") == "1" || |
1536 attributes.value("showMeans") == "true"); | 1530 attributes.value("showMeans") == "true"); |
1537 setShowMeans(showMeans); | 1531 setShowMeans(showMeans); |
1538 | 1532 |
1539 bool greyscale = (attributes.value("greyscale") == "1" || | |
1540 attributes.value("greyscale") == "true"); | |
1541 setUseGreyscale(greyscale); | |
1542 | |
1543 ChannelMode channelMode = (ChannelMode) | 1533 ChannelMode channelMode = (ChannelMode) |
1544 attributes.value("channelMode").toInt(&ok); | 1534 attributes.value("channelMode").toInt(&ok); |
1545 if (ok) setChannelMode(channelMode); | 1535 if (ok) setChannelMode(channelMode); |
1546 | 1536 |
1547 int channel = attributes.value("channel").toInt(&ok); | 1537 int channel = attributes.value("channel").toInt(&ok); |
1553 float middleLineHeight = attributes.value("middleLineHeight").toFloat(&ok); | 1543 float middleLineHeight = attributes.value("middleLineHeight").toFloat(&ok); |
1554 if (ok) setMiddleLineHeight(middleLineHeight); | 1544 if (ok) setMiddleLineHeight(middleLineHeight); |
1555 | 1545 |
1556 bool aggressive = (attributes.value("aggressive") == "1" || | 1546 bool aggressive = (attributes.value("aggressive") == "1" || |
1557 attributes.value("aggressive") == "true"); | 1547 attributes.value("aggressive") == "true"); |
1558 setUseGreyscale(aggressive); | 1548 setAggressiveCacheing(aggressive); |
1559 | 1549 |
1560 bool autoNormalize = (attributes.value("autoNormalize") == "1" || | 1550 bool autoNormalize = (attributes.value("autoNormalize") == "1" || |
1561 attributes.value("autoNormalize") == "true"); | 1551 attributes.value("autoNormalize") == "true"); |
1562 setAutoNormalize(autoNormalize); | 1552 setAutoNormalize(autoNormalize); |
1563 } | 1553 } |