NCurses 似乎具有有限数量的背景颜色(前景色效果很好)
NCurses appears to have a limited number of background colors (foreground colors work fine)
最终 运行 遇到了一个不寻常的问题:在程序启动时,我循环遍历所有支持的 256 种颜色(此处仅使用默认值)并创建一对包含所有可能排列的颜色——这导致65535 对我期望的每个 fg/bg 可能的组合。我已经通过打印到 stderr 来验证这些对是否符合预期。
只是为了检查一下,我的终端支持 256 种颜色、64k 对和 color/pair 重新分配。
问题出在这里:当尝试通过 attrset 打印任意 fg/bg 颜色时(并验证它实际上是上面打印的所需颜色对),前景色工作正常,但是背景颜色保持不变。如果我将所有值硬编码为单个 bg 颜色,它会按预期进行,同样,使每个排列具有相同的 fg/bg 颜色(即,将不同 fg/bg 对的数量限制为 256)也可以作为符合预期,如果我将配对生成代码限制为仅生成 256 对不同的配对,我会看到预期的背景颜色。
从根本上说,这似乎是对可以创建多少个唯一对的某种限制 (256);如果我使用 bg=0 的所有 64k 颜色对,我可以通过它的所有 256 对来寻址任何给定的颜色,结果 window 与我设置所有 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";
}
}
计算颜色 ID(我已经验证了这个独立工作 - +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 的对 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 - 而不是 0, 0,1k):
4804 : 0, 0, 1000 | 0, 0, 1000 reported, pair 196:18, should be 196:18
51664 : 0, 0, 0 | 0, 0, 0 reported, pair 0:0, should be 208:201
59168 : 0, 0, 0 | 0, 0, 0 reported, pair 0:0, should be 32:231
该示例混合使用了支持 扩展 颜色对和不支持的调用。 attron
、attrset
调用将颜色对存储在一个 8 位字段中。如果您使用 attr_on
和 attr_set
,它们会将颜色对存储为整数(远大于 8 位)。 extended_pair_content 建立在后者之上,允许使用大于 32767 的颜色对。
最终 运行 遇到了一个不寻常的问题:在程序启动时,我循环遍历所有支持的 256 种颜色(此处仅使用默认值)并创建一对包含所有可能排列的颜色——这导致65535 对我期望的每个 fg/bg 可能的组合。我已经通过打印到 stderr 来验证这些对是否符合预期。
只是为了检查一下,我的终端支持 256 种颜色、64k 对和 color/pair 重新分配。
问题出在这里:当尝试通过 attrset 打印任意 fg/bg 颜色时(并验证它实际上是上面打印的所需颜色对),前景色工作正常,但是背景颜色保持不变。如果我将所有值硬编码为单个 bg 颜色,它会按预期进行,同样,使每个排列具有相同的 fg/bg 颜色(即,将不同 fg/bg 对的数量限制为 256)也可以作为符合预期,如果我将配对生成代码限制为仅生成 256 对不同的配对,我会看到预期的背景颜色。
从根本上说,这似乎是对可以创建多少个唯一对的某种限制 (256);如果我使用 bg=0 的所有 64k 颜色对,我可以通过它的所有 256 对来寻址任何给定的颜色,结果 window 与我设置所有 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";
}
}
计算颜色 ID(我已经验证了这个独立工作 - +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 的对 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 - 而不是 0, 0,1k):
4804 : 0, 0, 1000 | 0, 0, 1000 reported, pair 196:18, should be 196:18
51664 : 0, 0, 0 | 0, 0, 0 reported, pair 0:0, should be 208:201
59168 : 0, 0, 0 | 0, 0, 0 reported, pair 0:0, should be 32:231
该示例混合使用了支持 扩展 颜色对和不支持的调用。 attron
、attrset
调用将颜色对存储在一个 8 位字段中。如果您使用 attr_on
和 attr_set
,它们会将颜色对存储为整数(远大于 8 位)。 extended_pair_content 建立在后者之上,允许使用大于 32767 的颜色对。