Символы перекрываются, когда они изменили цвет и напечатаны задом наперед - PullRequest
7 голосов
/ 21 января 2012

enter image description here

Как видите, верхние темные буквы Х вырезаны, хотя для них есть место.

Это происходит потому, что они изменили цвет и напечатаны в обратном направлении (справа налево).

Это ошибка, неисправный код, плохая настройка в моей системе или (я сомневаюсь в этом), как это должно быть?

Вот код, который генерирует этот вывод:

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

1 Ответ

4 голосов
/ 22 марта 2012

Это ошибка в Windows.

Как упоминается в опечатках Ганс Пассант :

Я также повторяю,VS2008 на Win7.Классный баг.Изменение шрифта консоли исправляет это.

Давайте используем эту изоляцию от ошибок.Я распознаю этот шрифт как Petite Terminal , что подразумевает, что вы, скорее всего, настроили этот проект как консольное приложение Win32.Дополнительная репродукция с GCC подтверждает эту гипотезу, и мы предположим, с практической точки зрения, что все вы получаете 32-разрядное консольное приложение, работающее внутри терминала Windows.

Вопрос становится почему записывает ровно один дополнительный столбец пикселей в контексте шрифта терминала по умолчанию, цвета 8, и обратно записывает в консольный буфер .

В частности, давайте разберем этопроблема на составляющие части:

  1. Когда выдается запись, символ записывается в местоположение в массиве терминалов
  2. Когда выбран цвет по умолчанию (7), пикселине перетекать в другие буферы в массиве
  3. Когда выбран цвет 8, дополнительный столбец пикселей записывается в следующую область буфера, которая видна только при повторном чтении текста

Из-за наличия переполнения в (3), это ошибка.

Цитата Раймонд Чен:

В модели рендеринга консоли предполагается, что каждый символ помещается в ячейке фиксированного размера.Когда новый символ записывается в ячейку, старая ячейка печатается с новым символом, но если старый символ имеет вылет или подвисание, эти дополнительные пиксели остаются позади, так как они «пролились» на требуемую ячейку и зараженные соседние ячейки.Точно так же, если соседний символ «перетек», эти «побочные пиксели» будут стерты.

Набор шрифтов, которые можно использовать в окне консоли, был обрезан до шрифтов, которые были протестированы и которые, как известно, работалиприемлемо в консольных окнах.Для английских систем это привело нас к консоли и терминалу Lucida.

...

"Ну, это глупо. Вы должны были помешать мне выбрать шрифт, который так явно приводит керунда. "

И это то, что мы сделали.

Не то, чтобы я обвинял Рэймонда в этом, но он авторитетно иллюстрирует это как" не может случиться ".

Выбор и тестирование консольных шрифтов для Windows должно было это уловить.Тот факт, что это вообще проблема, является отклонением.

...