NCurses имеет ограниченное количество цветов фона (цвета переднего плана работают нормально) - PullRequest
0 голосов
/ 29 июня 2018

В результате возникла необычная проблема: при запуске программы я перебираю все поддерживаемые 256 цветов (здесь используются только значения по умолчанию) и создаю пару со всеми возможными перестановками - это приводит к 65535 парам того, что я ожидал быть любой комбинацией фг / бг. Я подтвердил, что эти пары соответствуют ожиданиям, печатая в stderr.

Просто чтобы проверить, мой терминал поддерживает 256 цветов, 64k пар и переназначение цвета / пары.

Здесь возникает проблема: при попытке напечатать произвольный цвет fg / bg через attrset (и проверить, что это, на самом деле, нужная пара, как указано выше), цвета переднего плана работают нормально, но цвет фона остается без изменений. Если я жестко закодирую все значения в один цвет bg, то это произойдет, как и ожидалось, и, аналогично, обеспечение того, чтобы каждая перестановка имела идентичные цвета fg / bg (т. Е. Ограничение числа различных пар fg / bg до 256), также работает как ожидалось, и если Я ограничиваю код генерации пары только для создания 256 разных пар, я вижу цвета фона, как и ожидалось.

По сути, это, кажется, своего рода ограничение на количество уникальных пар, которые могут быть созданы (256); если я использую все 64k пар цветов с bg = 0, я могу обратиться к любому заданному цвету по всем его 256 парам, и полученное окно будет таким же, как окно, в котором я установил все перестановки fg / bg (то есть, как если бы внутри ncurses использовал 0 для всех цветов bg.

Есть идеи, как бы я подошел к этому? Я не вижу проблем с памятью в valgrind, и из того, что я могу сказать, документация ncurses подразумевает, что мое использование поддерживается. Спасибо!

Вот код для генерации пар:

for(unsigned int c2 = 0; c2 < 256; c2++) {
        for(unsigned int c1 = 0; c1 < 256; c1++) {
            int pi = (c2)*256 + c1;
            init_extended_pair(pi, c1, c1);
            std::cerr << "init " << pi << " : " << c1 << ", " << c2 << "\n";
        }
    }

Расчет идентификаторов цветов (я убедился, что это работает независимо - +16 сопоставляет его с цветом ncurses по умолчанию, поскольку имеется только 216 одинаково расположенных цветов)

unsigned int CursesObject::getColor(ColorRGBA col) {
    short r, g, b, er, eg, eb;
    r = int(col.r);
    g = int(col.g);
    b = int(col.b);

    er = r * 5 / 255;
    eg = g * 5 / 255;
    eb = b * 5 / 255;

    unsigned int colID = eb + eg*6 + er * 36;
    return colID + 16;
}

Вычисление идентификаторов пар для заданного fg / bg в комплекте с отладочным кодом для получения значений цветов

void CursesObject::setColor(ColorRGBA fg, ColorRGBA bg) {
    if(fg == cfg && bg == cbg) return;
    else if(fg == bg) {
        attron(COLOR_PAIR(0));
        return;
    }
    //attrset(0x0);

    cfg = fg;
    cbg = bg;

    int pairID = this->getColor(fg) + (this->getColor(bg))*256;//\\\ + 16;
    //std::cout << "colorPair: " << pairID << " from cid = " << this->getColor(fg) << ", col = " << fg.toString() <<"\n";

    static int uidbgOff = 25;
    short dr, db, dg, bbr,bbb,bbg;
    int cp1, cp2;
    extended_pair_content(pairID, &cp1, &cp2);
    color_content(cp1, &dr, &dg, &db);
    color_content(cp2, &bbr, &bbg, &bbb);

    std::stringstream ss;
    ss << pairID << " : " << dr << ", " << dg << ", " << db << " | " << bbr << ", " << bbg << ", " << bbb << " reported, pair " << cp1 << ":" << cp2 <<", should be " << this->getColor(fg) << ":" << this->getColor(bg)<<"\n";



    //sleep(5);
    attrset(COLOR_PAIR(pairID));
    this->write({10,uidbgOff}, ss.str());
    uidbgOff++;
    //this->update();

}

Интересно, что если исходить из диагностических функций, этот код не должен работать вообще , даже только с цветами fg. Например, вывод при попытке печати красного, оранжевого и бирюзового цветов выглядит примерно так (он выдает правильные цвета, несмотря на сообщение о том, что они равны нулю или совершенно неправильный: красный должен быть 1k, 0,0 в порядке RGB - не 0, 0,1k):

4804: 0, 0, 1000 | 0, 0, 1000 сообщается, пара 196: 18, должно быть 196: 18

51664: 0, 0, 0 | 0, 0, 0 сообщается, пара 0: 0, должна быть 208: 201

59168: 0, 0, 0 | 0, 0, 0 сообщается, пара 0: 0, должна быть 32: 231

1 Ответ

0 голосов
/ 29 июня 2018

В этом примере используется сочетание вызовов, которые поддерживают расширенные цветовые пары, и те, которые не поддерживают. Вызовы attron, attrset сохраняют цветовую пару в 8-битном поле. Если вы использовали attr_on и attr_set, они сохраняют пару цветов в целом числе (намного больше, чем 8 бит). extended_pair_content основывается на последнем, что позволяет использовать пары цветов размером больше 32767.

...