当它们改变颜色并向后打印时重叠的字符 [英] Characters overlapping when they have changed color and are printed backwards

查看:222
本文介绍了当它们改变颜色并向后打印时重叠的字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

>





这是因为它们改变了颜色并向后打印(从右到左)。

/ p>

这是一个错误,错误的代码,我的系统上的错误设置,或者(我怀疑),它应该是?



下面是生成此输出的代码:

  #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();
}


解决方案



如在勘误表中提到的 Hans Passant


我也是VS2008的Win7。酷的bug。更改控制台字体会修复它。


让我们使用这个bug隔离。我将此字体识别为小型 终端,这意味着你很可能将这个项目配置为Win32控制台应用程序。使用GCC的附加重现证实了这个假设,从实践的角度来看,我们将假设所有的人都得到一个在Windows终端内运行的32位控制台应用程序。



问题变成了为什么它在默认终端字体(颜色8)的上下文中正好写入一个额外的像素列,并向后写入控制台屏幕缓冲区



具体来说,让我们将这个问题分解成它的组成部分:


  1. 发出写入时,

  2. 当选择默认颜色(7)时,像素不会溢出到数组中的其他缓冲区


  3. 由于在(3)中存在溢出,这是一个错误。



    引用 Raymond Chen:


    控制台渲染模型假定每个字符都整齐地放在
    的固定大小细胞。当一个新的字符被写入一个单元格,
    旧单元格覆盖了新的字符,但如果旧的
    字符有悬垂或下划线,那些额外的像素留下
    ,因为他们溢出所需的单元格和感染的
    相邻单元格。类似地,如果相邻字符溢出,
    那些溢出像素将被擦除。



    可以在控制台中使用的字体集窗口被修剪
    到已测试并已知在控制台
    windows中可接受工作的字体。对于英语系统,这将我们带到Lucida控制台
    和Terminal。



    ...



    嗯,这很蠢,你应该阻止我选择一个字体
    ,这显然会导致废话。



    这就是我们做的。


    不是我指责雷蒙德在这个,但他授权说明这是一个不可能发生。



    Windows的控制台字体的选择和测试应该捕捉到这一点。事实上,它甚至是一个问题。


    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();
    }
    

    解决方案

    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.

    这篇关于当它们改变颜色并向后打印时重叠的字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆