NCurses的背景色似乎有限(前景色效果很好)

时间:2018-06-29 10:35:40

标签: c++ ncurses

最终在这里遇到一个不寻常的问题:在程序启动时,我遍历了所有受支持的256种颜色(仅在此处使用默认值),并创建了一个具有所有可能排列的对-这导致了65535对我的预期是所有可能的fg / bg组合。通过打印到stderr,我已经验证了这些对是否符合预期。

检查一下,我的终端支持256种颜色,64k对以及颜色/对重新分配。

问题出在这里:当尝试通过attrset打印任意fg / bg颜色(并验证实际上是上面打印的所需色对)时,前景色可以正常工作,但背景色仍然有效不变。如果我将所有值硬编码为单一的bg颜色,则可以按预期进行,并且同样,使每个排列具有相同的fg / bg颜色(即,将不同的fg / bg对的数量限制为256)也可以按预期工作,如果我将配对生成代码限制为只能产生256个不同的配对,我看到的是预期的背景颜色。

从根本上来说,这似乎对可以创建多少个唯一对的限制(256个);如果我使用bg = 0的所有64k颜色对,则可以通过其所有256对颜色对任何给定的颜色进行寻址,并且得到的窗口与我设置所有fg / bg排列的窗口相同(即,好像ncurses在内部所有bg颜色都使用0。

有什么想法我将如何处理?我没有在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";
        }
    }

计算颜色ID(我已经验证了它是独立工作的,因为只有216种等距颜色,所以+16会将其映射为默认ncurses颜色)

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的对ID,并附带调试代码以检索颜色值

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颜色也是如此。例如,尝试打印红色,橙色和蓝绿色时的输出是这样的(尽管报告颜色为零或完全错误,它仍会产生正确的颜色:红色应为RGB顺序为1k,0,0,而不是RGB, 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 :(得分:2)

该示例混合使用了支持扩展和不支持的颜色对。 attronattrset调用将颜色对存储在8位字段中。如果您使用attr_onattr_set,它们将颜色对存储为整数(远大于8位)。 extended_pa​​ir_content 基于后者,允许使用大于32767的颜色对。