@@ -251,6 +251,7 @@ static void GraphMeterMode_reallocateGraphBuffer(Meter* this, const GraphDrawCon
251251 data -> nValues = nValues ;
252252}
253253
254+ #if 0 /* Unused code */
254255static size_t GraphMeterMode_valueCellIndex (unsigned int graphHeight , bool isPercentChart , int deltaExp , unsigned int y , unsigned int * scaleFactor , unsigned int * increment ) {
255256 assert (deltaExp >= 0 );
256257 assert (deltaExp < UINT16_WIDTH );
@@ -829,9 +830,9 @@ static void GraphMeterMode_computeColors(Meter* this, const GraphDrawContext* co
829830 }
830831 }
831832}
833+ #endif /* End of unused code */
832834
833835static void GraphMeterMode_recordNewValue (Meter * this , const GraphDrawContext * context ) {
834- uint8_t maxItems = context -> maxItems ;
835836 bool isPercentChart = context -> isPercentChart ;
836837 size_t nCellsPerValue = context -> nCellsPerValue ;
837838 if (!nCellsPerValue )
@@ -851,18 +852,23 @@ static void GraphMeterMode_recordNewValue(Meter* this, const GraphDrawContext* c
851852 valueStart = & valueStart [(nValues - 1 ) * nCellsPerValue ];
852853
853854 // Compute "sum" and "total"
854- double sum = 0.0 ;
855- if (this -> curItems > 0 ) {
856- sum = Meter_computeSum (this );
857- assert (sum >= 0.0 );
858- assert (sum <= DBL_MAX );
859- }
860- double total ;
855+ double total = 0.0 ;
861856 if (isPercentChart ) {
862- total = MAXIMUM (this -> total , sum );
857+ assert (this -> total >= 0.0 );
858+ total = this -> total ;
859+ valueStart [0 ].scaleExp = 0 ;
863860 } else {
861+ if (isPositive (this -> values [0 ]))
862+ total = this -> values [0 ];
863+
864+ if (this -> curItems > 1 && isgreater (this -> values [1 ], total ))
865+ total = this -> values [1 ];
866+
867+ if (total > DBL_MAX )
868+ total = DBL_MAX ;
869+
864870 int scaleExp = 0 ;
865- (void )frexp (sum , & scaleExp );
871+ (void )frexp (total , & scaleExp );
866872 if (scaleExp < 0 ) {
867873 scaleExp = 0 ;
868874 }
@@ -878,51 +884,25 @@ static void GraphMeterMode_recordNewValue(Meter* this, const GraphDrawContext* c
878884
879885 assert (graphHeight <= UINT16_MAX / 8 );
880886 double maxDots = (double )(int32_t )(graphHeight * 8 );
881- int numDots = 0 ;
882- if (total > 0.0 ) {
883- numDots = (int )ceil ((sum / total ) * maxDots );
884- assert (numDots >= 0 );
885- if (sum > 0.0 && numDots <= 0 ) {
886- numDots = 1 ; // Division of (sum / total) underflows
887+ for (uint8_t i = 0 ; i < 2 ; i ++ ) {
888+ double value = 0.0 ;
889+ if (i < this -> curItems && isPositive (this -> values [i ]))
890+ value = this -> values [i ];
891+
892+ if (value > total )
893+ value = total ;
894+
895+ int numDots = 0 ;
896+ if (total > 0.0 ) {
897+ numDots = (int )ceil ((value / total ) * maxDots );
898+ assert (numDots >= 0 );
899+ if (value > 0.0 && numDots <= 0 ) {
900+ numDots = 1 ; // Division of (value / total) underflows
901+ }
887902 }
888- }
889903
890- if (maxItems == 1 ) {
891904 assert (numDots <= UINT16_MAX );
892- valueStart [isPercentChart ? 0 : 1 ].numDots = (uint16_t )numDots ;
893- return ;
894- }
895-
896- // Clear cells
897- unsigned int y = ((unsigned int )numDots + 8 - 1 ) / 8 ; // Round up
898- size_t i = GraphMeterMode_valueCellIndex (graphHeight , isPercentChart , 0 , y , NULL , NULL );
899- if (i < nCellsPerValue ) {
900- memset (& valueStart [i ], 0 , (nCellsPerValue - i ) * sizeof (* valueStart ));
901- }
902-
903- if (sum <= 0.0 )
904- return ;
905-
906- int deltaExp = 0 ;
907- double scaledTotal = total ;
908- assert (scaledTotal > 0.0 );
909- while (true) {
910- numDots = (int )ceil ((sum / scaledTotal ) * maxDots );
911- if (numDots <= 0 ) {
912- numDots = 1 ; // Division of (sum / scaledTotal) underflows
913- }
914-
915- GraphMeterMode_computeColors (this , context , valueStart , deltaExp , scaledTotal , (unsigned int )numDots );
916-
917- if (isPercentChart || !(scaledTotal < DBL_MAX ) || (1U << deltaExp ) >= graphHeight ) {
918- break ;
919- }
920-
921- deltaExp ++ ;
922- scaledTotal *= 2.0 ;
923- if (scaledTotal > DBL_MAX ) {
924- scaledTotal = DBL_MAX ;
925- }
905+ valueStart [1 + i ].numDots = (uint16_t )numDots ;
926906 }
927907}
928908
@@ -942,6 +922,7 @@ static void GraphMeterMode_printScale(int exponent) {
942922 }
943923}
944924
925+ #if 0 /* Unused code */
945926static uint8_t GraphMeterMode_scaleCellDetails (uint8_t details , unsigned int scaleFactor ) {
946927 // Only the "top cell" of a record may need scaling like this; the cell does
947928 // not use the special meaning of bit 4.
@@ -969,6 +950,7 @@ static uint8_t GraphMeterMode_scaleCellDetails(uint8_t details, unsigned int sca
969950 }
970951 return 0x00 ;
971952}
953+ #endif /* End of unused code */
972954
973955static int GraphMeterMode_lookupCell (const Meter * this , const GraphDrawContext * context , int scaleExp , size_t valueIndex , unsigned int y , uint8_t * details ) {
974956 unsigned int graphHeight = (unsigned int )this -> h ;
@@ -995,50 +977,59 @@ static int GraphMeterMode_lookupCell(const Meter* this, const GraphDrawContext*
995977 int deltaExp = isPercentChart ? 0 : scaleExp - valueStart [0 ].scaleExp ;
996978 assert (deltaExp >= 0 );
997979
998- if (maxItems == 1 ) {
999- unsigned int numDots = valueStart [isPercentChart ? 0 : 1 ].numDots ;
980+ unsigned int numDots = valueStart [1 ].numDots ;
981+ if (numDots >= 1 ) {
982+ if (deltaExp + 1 < UINT16_WIDTH ) {
983+ numDots = ((numDots - 1 ) >> (deltaExp + 1 )) + 1 ;
984+ } else {
985+ numDots = 1 ;
986+ }
987+ }
988+ unsigned int blanksAtEnd = graphHeight * 4 - numDots ;
1000989
1001- if (numDots < 1 )
1002- goto cellIsEmpty ;
990+ numDots = valueStart [2 ].numDots ;
991+ if (numDots >= 1 ) {
992+ if (deltaExp + 1 < UINT16_WIDTH ) {
993+ numDots = ((numDots - 1 ) >> (deltaExp + 1 )) + 1 ;
994+ } else {
995+ numDots = 1 ;
996+ }
997+ }
998+ unsigned int blanksAtStart = graphHeight * 4 - numDots ;
1003999
1004- // Scale according to exponent difference. Round up.
1005- numDots = deltaExp < UINT16_WIDTH ? ((numDots - 1 ) >> deltaExp ) : 0 ;
1006- numDots ++ ;
1000+ if (graphHeight - 1 - y < blanksAtEnd / 8 )
1001+ goto cellIsEmpty ;
1002+ if (y < blanksAtStart / 8 )
1003+ goto cellIsEmpty ;
10071004
1008- if (y > ( numDots - 1 ) / 8 )
1009- goto cellIsEmpty ;
1005+ if (y * 2 == graphHeight - 1 && !( valueStart [ 1 ]. numDots || valueStart [ 2 ]. numDots ) )
1006+ goto cellIsEmpty ;
10101007
1008+ if (maxItems <= 1 || y * 2 > graphHeight - 1 ) {
10111009 itemIndex = 0 ;
1012- * details = 0xFF ;
1013- if (y == (numDots - 1 ) / 8 ) {
1014- const uint8_t dotAlignment = 2 ;
1015- unsigned int blanksAtTopCell = (8 - 1 - (numDots - 1 ) % 8 ) / dotAlignment * dotAlignment ;
1016- * details <<= blanksAtTopCell ;
1017- }
1010+ } else if (y * 2 < graphHeight - 1 ) {
1011+ itemIndex = 1 ;
10181012 } else {
1019- int deltaExpArg = deltaExp >= UINT16_WIDTH ? UINT16_WIDTH - 1 : deltaExp ;
1020-
1021- unsigned int scaleFactor ;
1022- size_t i = GraphMeterMode_valueCellIndex (graphHeight , isPercentChart , deltaExpArg , y , & scaleFactor , NULL );
1023- if (i >= nCellsPerValue )
1024- goto cellIsEmpty ;
1013+ itemIndex = valueStart [1 ].numDots >= valueStart [2 ].numDots ? 0 : 1 ;
1014+ }
10251015
1026- if (deltaExp >= UINT16_WIDTH ) {
1027- // Any "scaleFactor" value greater than 8 behaves the same as 8 for the
1028- // "scaleCellDetails" function.
1029- scaleFactor = 8 ;
1016+ if (y * 2 == graphHeight - 1 && valueStart [1 ].numDots > 8 && valueStart [2 ].numDots > 8 ) {
1017+ * details = valueStart [1 ].numDots >= valueStart [2 ].numDots ? 0x0F : 0xF0 ;
1018+ } else {
1019+ * details = 0xFF ;
1020+ const uint8_t dotAlignment = 2 ;
1021+ if (y == blanksAtStart / 8 ) {
1022+ blanksAtStart = (blanksAtStart % 8 ) / dotAlignment * dotAlignment ;
1023+ * details >>= blanksAtStart ;
1024+ }
1025+ if ((graphHeight - 1 - y ) == blanksAtEnd / 8 ) {
1026+ blanksAtEnd = (blanksAtEnd % 8 ) / dotAlignment * dotAlignment ;
1027+ * details = (uint8_t )((* details >> blanksAtEnd ) << blanksAtEnd );
10301028 }
1031-
1032- const GraphDataCell * cell = & valueStart [i ];
1033- itemIndex = cell -> c .itemNum - 1 ;
1034- * details = GraphMeterMode_scaleCellDetails (cell -> c .details , scaleFactor );
10351029 }
10361030 /* fallthrough */
10371031
10381032cellIsEmpty :
1039- if (y == 0 )
1040- * details |= 0xC0 ;
1041-
10421033 if (itemIndex == (uint8_t )-1 )
10431034 return BAR_SHADOW ;
10441035
@@ -1136,9 +1127,7 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
11361127
11371128 uint8_t maxItems = Meter_maxItems (this );
11381129 bool isPercentChart = Meter_isPercentChart (this );
1139- size_t nCellsPerValue = maxItems <= 1 ? maxItems : graphHeight ;
1140- if (!isPercentChart )
1141- nCellsPerValue *= 2 ;
1130+ size_t nCellsPerValue = maxItems < 1 ? maxItems : 3 ;
11421131
11431132 GraphDrawContext context = {
11441133 .maxItems = maxItems ,
0 commit comments