acidvegas / acid-drop

Hacking the planet from a LilyGo T-Deck using custom firmware
GNU General Public License v3.0
23 stars 2 forks source link

Line wrapping causes miscalculation on the total lines that can fit on the screen #4

Closed acidvegas closed 1 month ago

acidvegas commented 1 month ago

Just documenting this here that we are aware of this issue and it is priority right now.

imnotacoder-eeeee commented 1 month ago

Assigning myself to this issue. I have found ways to solve this, although it causes a space between the input bar and chat buffer when a multi-line is passing the top of the buffer.

Changes to the calculated lines here will allow us to understand message length when word wrapped.

`int calculateLinesRequired(String message) { int linesRequired = 1; int lineWidth = 0;

for (unsigned int i = 0; i < message.length(); i++) {
    char c = message[i];
    if (c == '\x03') {
        // Skip color code sequences from calculate instead of render to solve nick overlay issue
        while (i < message.length() && (isdigit(message[i + 1]) || message[i + 1] == ',')) {
            i++;
            if (isdigit(message[i + 1])) {
                i++;
            }
            if (message[i] == ',' && isdigit(message[i + 1])) {
                i++;
            }
        }
    } else if (c != '\x02' && c != '\x0F' && c != '\x1F') { // Ignore other formatting codes as they are not as prevalent
        lineWidth += tft.textWidth(String(c));
        if (lineWidth > SCREEN_WIDTH) {
            linesRequired++;
            lineWidth = tft.textWidth(String(c));
        }
    }
}

return linesRequired;

} `

Adding these blocks to displayLines to calculate how many lines in the buffer must be deleted and then removing them from the bottom of the buffer, solving the issue where we need to enter false messages to get to the bottom of the buffer again

`void displayLines() { tft.fillRect(0, STATUS_BAR_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - STATUS_BAR_HEIGHT - INPUT_LINE_HEIGHT, TFT_BLACK);

int cursorY = STATUS_BAR_HEIGHT;
int totalLinesHeight = 0;
std::vector<int> lineHeights;

// Calculate total height needed for all lines
for (const String& line : lines) {
    int lineHeight = calculateLinesRequired(line) * CHAR_HEIGHT;
    lineHeights.push_back(lineHeight);
    totalLinesHeight += lineHeight;
}

// Remove lines from the top if they exceed the screen height
while (totalLinesHeight > SCREEN_HEIGHT - STATUS_BAR_HEIGHT - INPUT_LINE_HEIGHT) {
    totalLinesHeight -= lineHeights.front();
    lines.erase(lines.begin());
    mentions.erase(mentions.begin());
    lineHeights.erase(lineHeights.begin());
}`
imnotacoder-eeeee commented 1 month ago

Will work on a fork and do a PR. Although it is buggy, it works a lot better in the non-multi-buffer code base.

imnotacoder-eeeee commented 1 month ago

I have added a PR, the PR has the normalized colors as well. Current issue with this bug is that multi-lines get fully deleted when hitting the top of the buffer, causing a small gap in the bottom of the buffer that auto-corrects itself.

acidvegas commented 1 month ago

efdd8bc fixes the issue where colored messages were not calculated properly.

going to close this for now as word wrapping is not a "bug" anymore