evince 更改文档背景颜色

先说一下用的是 debian 6,evince 版本是 2.30.3。

去年在 evince 的邮件列表中问过这个问题,得到的回答是人手不够,并且这个功能不是太紧急,因此目前并不考虑实现。随着看 pdf 的时间越来越长,白色背景看着实在很不爽,但是又不懂 gtk 编程,因此想通过修改反色的行为来实现修改背景颜色的功能,即当选择了反色的时候并不是把背景和字体的颜色都反过来,而是把背景颜色修改为我喜欢的颜色,字体的颜色不变。

先到源里把代码下下来,grep 一下关键字“invert”加上人肉筛选加上 gdb 打断点后发现实现反色的功能在 libdocument/ev-document-misc.c:

void
ev_document_misc_invert_surface (cairo_surface_t *surface) {
#if CAIRO_VERSION > CAIRO_VERSION_ENCODE(1, 9, 2)
    cairo_t *cr;

    cr = cairo_create (surface);

    /* white + DIFFERENCE -> invert */
    cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
    cairo_set_source_rgb (cr, 1., 1., 1.);
    cairo_paint(cr);
    cairo_destroy (cr);
#else
    guchar *data;
    gint    rowstride;
    gint    width, height;
    gint    x, y;

    data = cairo_image_surface_get_data (surface);
    rowstride = cairo_image_surface_get_stride (surface);
    width = cairo_image_surface_get_width (surface);
    height = cairo_image_surface_get_height (surface);

    for (y = 0; y < height; y++) {
        guchar *p = data + y * rowstride;

        for (x = 0; x < width; x++) {
            p[0] = 255 - p[0];
            p[1] = 255 - p[1];
            p[2] = 255 - p[2];
            p += 4;
        }
    }

    cairo_surface_mark_dirty (surface);
#endif
}

经过 printf 确定走的是 #else 分支。简单的反色功能没有区分背景和字体的颜色,只是把每个点的 rgb 颜色给反过来(p[0],p[1],p[2] 分别表示 rgb 的值)。因为背景颜色大多是白色(或接近白色),所以改为

if ((245 <= p[0] && p[0] <= 255) &&
    (245 <= p[1] && p[1] <= 255) &&
    (245 <= p[2] && p[2] <= 255)) {
    p[0] = 204; /* cc */
    p[1] = 232; /* e8 */
    p[2] = 207; /* cf */
}

这样凡是 rgb 值落在 [245, 255] 中的颜色都会变成 #cce8cf,不管是背景颜色还是字体颜色。误伤是难免的,而且字体边沿还是有些白色的印迹去不掉,不过凑合着用是没问题了。然后重新编译(根据自己的需要修改选项,如果依赖不满足的话对照 configure 的输出一个个装就是了):

$ ./configure --prefix=/usr --enable-nls --disable-scrollkeeper --disable-dbus --disable-debug --disable-tests --disable-nautilus --disable-thumbnailer --disable-previewer --disable-comics --without-keyring --without-gconf --without-gtk-unix-print
$ make

编译完后不要急着 make install,这样会覆盖原来的版本。把原来的 /usr/lib/libevdocument.so.2.0.0 备份一下,用 libdocument/.libs 目录下新生成的 libevdocument.so.2.0.0 替换掉即可,这样每次勾选了“反色”之后背景就变成淡绿色了。不过取消选择之后并不会立即变回白色,而是需要改变一下 pdf 的大小重新刷新一下。

另外有一个修改 pdf 的内容以达到更改颜色的方法,原文在 这里

evince 直到现在的 gnome3.4 还没有更改背景颜色的功能,因为这个问题我都有一种冲动要换到 kde 了,不说 okular,就是 kde3 时代的 kpdf 都比现在的 evince 好用。但是在 kde 下的终端不给力,bbs 的 ascii 图根本没法看(vte-based 的就不会,但是使用 vte 的终端基本都是 gtk 写的,而 gtk 程序在 kde 下的外观惨不忍睹),而且旧的图标主题还不能直接用(我最喜欢的 tango 就不能直接用在 kde4 上,可能是有些图标的名称改变了,导致图标和功能错位)。最后还是妥协了,继续留在 gnome——准确点说是 gnome2,接受被抛弃的命运。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注