From 1fa5bb2fd1e2bc73bfc0d64f24be1975e373e09b Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Thu, 25 Jan 2024 20:05:00 +0800 Subject: [PATCH] makeDetailsMask() use prevTopPoint --- Meter.c | 36 ++++++++++++++++++------------------ Meter.h | 1 - 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/Meter.c b/Meter.c index 76b770c3c..87457ab5f 100644 --- a/Meter.c +++ b/Meter.c @@ -477,7 +477,7 @@ static void GraphMeterMode_addItemAdjStack(GraphColorAdjStack* stack, double sca stack->nItems++; } -static uint16_t GraphMeterMode_makeDetailsMask(const GraphColorComputeState* prev, const GraphColorComputeState* new, double rem, int blanksAtTopCell) { +static uint16_t GraphMeterMode_makeDetailsMask(const GraphColorComputeState* prev, const GraphColorComputeState* new, double prevTopPoint, double rem, int blanksAtTopCell) { assert(new->nCellsPainted > prev->nCellsPainted); assert(rem >= 0.0); assert(rem < 1.0); @@ -487,6 +487,8 @@ static uint16_t GraphMeterMode_makeDetailsMask(const GraphColorComputeState* pre if (isItemOnEdge && rem > 0.0 && rem < (0.125 * dotAlignment)) rem = (0.125 * dotAlignment); + double maxBlanks = (1.0 - rem) * 8.0; + uint8_t blanksAtEnd; bool roundsUpInAscii = false; bool roundsDownInAscii = false; @@ -494,32 +496,30 @@ static uint16_t GraphMeterMode_makeDetailsMask(const GraphColorComputeState* pre assert(blanksAtTopCell < 8); blanksAtEnd = (uint8_t)blanksAtTopCell; roundsUpInAscii = true; - } else if (prev->nCellsPainted == 0 || prev->topPoint <= (double)(int)prev->nCellsPainted) { - blanksAtEnd = (uint8_t)((1.0 - rem) * 8.0) % 8; - } else if ((double)(int)new->nCellsPainted > new->topPoint) { - assert((int)new->nCellsPainted - new->topPoint < 1.0); + } else if (prev->nCellsPainted == 0 || (double)(int)prev->nCellsPainted >= prevTopPoint) { + blanksAtEnd = (uint8_t)maxBlanks % 8; + } else { // Unlike other conditions, this one rounds to nearest for visual reason. // In case of a tie, display the dot at lower position of the graph, // i.e. MSB of the "details" data. - double fraction = (1.0 - rem) * 8.0; - fraction -= (int)fraction; - double distance = ((double)(int)new->nCellsPainted - new->topPoint) * 8.0 + (1.0 - fraction) * 0.5; + double fraction = maxBlanks - (int)maxBlanks; + double distance = maxBlanks + ((double)(int)prev->nCellsPainted - prevTopPoint) * 8.0 + (1.0 - fraction) * 0.5; + if (distance <= 0.0) + distance = 0.0; + blanksAtEnd = (uint8_t)distance; // Tiebreaking direction that may be needed in the ASCII display mode. distance = distance - (int)distance; - assert(distance >= 0.0); assert(distance < 1.0); roundsUpInAscii = distance < 0.5; roundsDownInAscii = distance > 0.5; - } else { - blanksAtEnd = 0; } assert(blanksAtEnd < 8); uint8_t blanksAtStart; if (prev->nCellsPainted > 0) { - blanksAtStart = (uint8_t)((int)((1.0 - rem) * 8.0) - blanksAtEnd) % 8; + blanksAtStart = (uint8_t)((int)maxBlanks - blanksAtEnd) % 8; } else { // Always zero blanks for the first cell. // When an item would be painted with all cells (from the first cell to @@ -551,11 +551,11 @@ static uint16_t GraphMeterMode_makeDetailsMask(const GraphColorComputeState* pre } } else if ((mask & 0xBFFD) == 0x1FFC) { // 5 dots at start, 6 or 7 dots at end - assert((mask & 0xFFFD) == 0x1FFC); + assert(mask == 0x1FFC || mask == 0x1FFE); mask &= 0xF7FF; } else if ((mask & 0xBFFD) == 0x3FF8) { // 6 or 7 dots at start, 5 dots at end - assert((mask & 0xBFFF) == 0x3FF8); + assert(mask == 0x3FF8 || mask == 0x7FF8); mask &= 0xFFEF; } @@ -613,7 +613,6 @@ static void GraphMeterMode_computeColors(Meter* this, const GraphDrawContext* co GraphColorComputeState restart = { .valueSum = 0.0, - .topPoint = 0.0, .nCellsPainted = 0, .nItemsPainted = 0 }; @@ -668,7 +667,6 @@ static void GraphMeterMode_computeColors(Meter* this, const GraphDrawContext* co assert(new.valueSum < DBL_MAX || prev.valueSum + value >= DBL_MAX); } - new.topPoint = (new.valueSum / scaledTotal) * (double)(int)graphHeight; double area = (value / scaledTotal) * (double)(int)graphHeight; double rem = area; @@ -708,7 +706,8 @@ static void GraphMeterMode_computeColors(Meter* this, const GraphDrawContext* co assert(restart.nItemsPainted == prev.nItemsPainted); if (!rItemIsDetermined) { - stack.startPoint = new.topPoint; + double newTopPoint = (new.valueSum / scaledTotal) * (double)(int)graphHeight; + stack.startPoint = newTopPoint; rItemMinCells = nCells; rem = 0.0; } else if (rItemHasExtraCell) { @@ -782,8 +781,9 @@ static void GraphMeterMode_computeColors(Meter* this, const GraphDrawContext* co } if (nCells > 0 && new.nCellsPainted <= nCellsToPaint) { + double prevTopPoint = (prev.valueSum / scaledTotal) * (double)(int)graphHeight; int blanksAtTopCellArg = (new.nCellsPainted == nCellsToPaint) ? (int)blanksAtTopCell : -1; - uint16_t mask = GraphMeterMode_makeDetailsMask(&prev, &new, rem, blanksAtTopCellArg); + uint16_t mask = GraphMeterMode_makeDetailsMask(&prev, &new, prevTopPoint, rem, blanksAtTopCellArg); GraphColorCell* cellsStart = &valueStart[firstCellIndex + (size_t)increment * prev.nCellsPainted]; GraphMeterMode_paintCellsForItem(cellsStart, increment, prev.nItemsPainted, nCells, mask); diff --git a/Meter.h b/Meter.h index 734287cb8..73d5d36b6 100644 --- a/Meter.h +++ b/Meter.h @@ -145,7 +145,6 @@ typedef struct GraphDrawContext_ { This structure is intended to be used only as local variables. */ typedef struct GraphColorComputeState_ { double valueSum; - double topPoint; unsigned int nCellsPainted; uint8_t nItemsPainted; } GraphColorComputeState;