Characters overlapping when they have changed color and are printed backwards
Asked Answered
D

1

8

enter image description here

As you can see the upper dark X's are cut even though there is space for them.

This happens because they have changed color and are printed backwards (from right to left).

Is this a bug, faulty code, a bad setup on my system or (I doubt it) like it is supposed to be?

Here is the code that generates this output:

#include <Windows.h>
#include <iostream>
void moveTo(int x,int y){
    COORD kord={x,y};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),kord);
}
void setColor(WORD attributes){
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), attributes);
}

void main(){
    for(int i=9;i+1;i--)
    {
        moveTo(i,0);
        std::cout.put('X');
    }
    for(int i=-10;i;i++)
    {
        moveTo(i+10,1);
        std::cout.put('X');
    }
    setColor(8);
    for(int i=9;i+1;i--)
    {
        moveTo(i,2);
        std::cout.put('X');
    }
    for(int i=-10;i;i++)
    {
        moveTo(i+10,3);
        std::cout.put('X');
    }
    setColor(7);
    for(int i=9;i+1;i--)
    {
        moveTo(i,4);
        std::cout.put('X');
    }
    for(int i=-10;i;i++)
    {
        moveTo(i+10,5);
        std::cout.put('X');
    }
    std::cin.get();
}
Dominate answered 21/1, 2012 at 16:52 Comment(11)
How do you know it's because they are backwards? Maybe you should use a letter that looks different when written backwards, like FExploitation
@Seth: Zalastax means, the characters are displayed sequentially from right to left. This looks like a bug in the console display code to me.Trabeated
I can reproduce this behaviour, using g++ version 4.5.2 on Windows 7. Strange!Trabeated
I repro too, VS2008 on Win7. Cool bug. Changing the console font fixes it.Triphthong
Zalastax: Are you using Windows 7 too? Anybody else: Does this occur in other versions of Windows?Trabeated
Yes! I am using Windows 7 Home Premium 64-bitDominate
Tested on Windows XP, bug not reproduced.Dominate
@Dominate I'm suspicious of the 'attributes'. Is the DWORD cleared? Are the bit-flags used different to the default attributes? Also, could this effectively be a z-order problem whereby drawing the character from right-to-left essentially over-writes a black column over the adjacent 'sprite'?Watercool
Works ok on Windows XP, I used mingw to compile the codeYaekoyael
If you change the background colour of the printed text, I suspect you'll see an extra pixel being filled at the end of each row regardless of direction. I would further assume there's some ancient historical reason for this, but I can't for the life of me think what it might be.Woolfolk
What font are you displaying in your console windows? Looks like a bitmap font?Orgasm
L
5

This is a bug in Windows.

As mentioned in the errata by Hans Passant:

I repro too, VS2008 on Win7. Cool bug. Changing the console font fixes it.

Let's use this bug isolation. I recognize this font as Petite Terminal, which implies you both most likely configured this project as a Win32 Console Application. The additional repro with GCC confirms this hypothesis, and we will assume, from a practical standpoint, that all of you were getting a 32-bit console application running inside of a Windows terminal.

The question becomes why it's writing exactly one additional column of pixels in the context of the default terminal font, color 8, and backwards writing into a console screen buffer.

Specifically, let's break this problem up into its component pieces:

  1. When a write is issued, a character is written to a location in the terminal array
  2. When the default color (7) is selected, pixels do not overflow into other buffers within the array
  3. When color 8 is selected, an additional column of pixels is written to the next region of the buffer, which is only visible when the text is recited backwards

Because of the presence of overspill in (3), this is a bug.

Quoting Raymond Chen:

The console rendering model assumes each character fits neatly inside its fixed-sized cell. When a new character is written to a cell, the old cell is overprinted with the new character, but if the old character has overhang or underhang, those extra pixels are left behind since they "spilled over" the required cell and infected neighbor cells. Similarly, if a neighboring character "spilled over", those "spillover pixels" would get erased.

The set of fonts that could be used in the console window was trimmed to the fonts that were tested and known to work acceptably in console windows. For English systems, this brought us down to Lucida Console and Terminal.

...

"Well, that's stupid. You should've stopped me from choosing a font that so clearly results in nonsense."

And that's what we did.

Not that I'm blaming Raymond on this one, but he authoritatively illustrates this as a "can't happen."

The selection and testing of console fonts for Windows should have caught this. The fact that it's even an issue at all is an aberration.

Lello answered 22/3, 2012 at 0:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.