evince魔改记
正如我在前文使用 evince 和 Papers所述evince、Papers和Edge都是优秀的软件但也都有不足之处。仅从功能性上而言Papers完美契合需求。但它处理含大图片文件时的速度太慢影响使用者阅读体验阅读感被切碎的感觉。这个问题在Papers的Issues已被提到。但我感觉到这个Issue可能并不会被快速修复。因此我决定在Papers修复该Bug前魔改Evince来契合我的需求。嗯干这件事对于正处于学术焦虑期的我而言可能和刷一晚上视频类似或许稍微好点狠狠耽误主线剧情。。。奈何忍不住。。。2025-11-06 至此本文阶段性结束先凑合用了。。。效果展示文章目录效果展示从源码安装修改为侧边栏的注释添加颜色为侧边栏的注释添加自动换行调整侧边栏宽度去掉侧边栏的图标其它从源码安装嗯第一个问题就让我头疼。鉴于我的技术水平我想我最讨厌的就是需要从源码安装软件了。首先现在是2025年11月5日evince的最新releases版本是48.1其实是49.alpha但这个版本已经无限接近papers了而且很不稳定。按照 https://askubuntu.com/a/1460772/1777641 有安装mesonsudo apt install mesonThen, cd to the source directory and run the commands,meson builddir --prefix/usr/local sudo ninja -C builddir installTo uninstall, runsudo ninja -C builddir uninstall不知道为什么在几次之后我的环境就会有这个报错不过不影响运行。Entity: line 22: parser error : Start tag expected, not found ?xpacket endw? ^只要没有error就通过了尽管会有些小瑕疵。注意最好用sudo -i进入root用户进行编译安装。我当时用普通用户的sudo一直报错换成root用户后就解决了。[2026-05-19] 重新编译meson setup --wipe builddir --prefix/usr/local修改同样由于我的代码水平和时间我只能用最小的修改来达到类似的目的。一切都是在GPT和它的兄弟姐妹们的协助下完成的。2025-11-05 在我用Llama3这篇文章测试发现好像evince也不是很快啊。。。edge这么强吗为侧边栏的注释添加颜色evince的侧边栏注释没有颜色而我一般喜欢用不同颜色的注释表达不同的含义这点我喜欢Papers。首先根据路径evince - shell - ev-sidebar-annotations.c找到ev-sidebar-annotations.c文件然后定位到job_finished_callback函数。可以看到下图的代码。嗯这个代码可太可爱了。这意味着我只需要拿到此时注释的颜色然后用html就可以给它添加颜色了。在中间添加GdkRGBA rgba;gchar*color_strNULL;ev_annotation_get_rgba(annot,rgba);color_strg_strdup_printf(#%02X%02X%02X,(int)(rgba.red*255),(int)(rgba.green*255),(int)(rgba.blue*255));再修改上图的代码为if(contents*contents!\0)markupg_strdup_printf(span foreground%s sizelarge★/span%s,color_str,contents);elsemarkupg_strdup_printf(span foreground%s sizelarge★/span%s,color_str,_(No Comment));在后面添加g_free(color_str);大致上就是这样效果如下其实我也不喜欢这个按照页面划分的多层注释每次想要看注释都需要按按钮才能完整显示。如下图修改即可。为侧边栏的注释添加自动换行原始的evince的注释是无法换行的但有时候我会写一些很长的注释这个时候就需要自动换行了。调教GPT帮我写了一个自动换行的函数大致的功能就是中文和英文都分为词组然后词组达到一定的宽度就添加一个换行符号。一个中文字符我当作一个中文词组一个英文单词我当作一个英文词组。/* 判断中文字符含中文标点 */staticgbooleanis_chinese(gunichar c){return(c0x4E00c0x9FFF)||// 常用汉字(c0x3000c0x303F)||// 中文标点(c0xFF00c0xFFEF);// 全角字符}/* 判断英文分隔符 */staticgbooleanis_english_separator(gunichar c){returng_unichar_isspace(c);// 包含空格、制表符、换行}/* 插入换行的函数按词组换行 */staticgchar*insert_linebreaks_by_width(constgchar*text,intmax_width,GtkWidget*widget){if(!text||!*text)returng_strdup();PangoLayout*layoutgtk_widget_create_pango_layout(widget,NULL);if(!layout)returng_strdup(text);GString*resultg_string_new(NULL);// 最终字符串GString*current_lineg_string_new(NULL);// 当前行累积字符串GString*current_wordg_string_new(NULL);// 当前词组constgchar*ptext;while(*p){gunichar cg_utf8_get_char(p);gchar buf[8]{0};gint leng_unichar_to_utf8(c,buf);if(is_chinese(c)){// 中文每个字符就是一个词组g_string_assign(current_word,buf);}elseif(is_english_separator(c)){// 英文分隔符结束当前英文词组同时输出分隔符if(current_word-len0){// 测量加入当前行后的宽度gchar*test_lineg_strdup_printf(%s%s,current_line-str,current_word-str);pango_layout_set_text(layout,test_line,-1);intwidth0;pango_layout_get_pixel_size(layout,width,NULL);g_free(test_line);if(widthmax_widthcurrent_line-len0){g_string_append(result,current_line-str);g_string_append_c(result,\n);g_string_truncate(current_line,0);}g_string_append(current_line,current_word-str);g_string_truncate(current_word,0);}// 分隔符本身也算宽度g_string_assign(current_word,buf);}else{// 英文字符累积成一个词组g_string_append_len(current_word,buf,len);pg_utf8_next_char(p);continue;}// 测试当前词加入行后的宽度gchar*test_lineg_strdup_printf(%s%s,current_line-str,current_word-str);pango_layout_set_text(layout,test_line,-1);intwidth0;pango_layout_get_pixel_size(layout,width,NULL);g_free(test_line);if(widthmax_widthcurrent_line-len0){g_string_append(result,current_line-str);g_string_append_c(result,\n);g_string_truncate(current_line,0);}g_string_append(current_line,current_word-str);g_string_truncate(current_word,0);pg_utf8_next_char(p);}if(current_word-len0)g_string_append(current_line,current_word-str);if(current_line-len0)g_string_append(result,current_line-str);g_string_free(current_line,TRUE);g_string_free(current_word,TRUE);g_object_unref(layout);returng_string_free(result,FALSE);}再用该换行函数替换原始内容。if(contents*contents!\0){gchar*wrapped_text;wrapped_textinsert_linebreaks_by_width(contents,260,priv-tree_view);markupg_strdup_printf(span foreground%s sizelarge★★★★★★★/span\n%s,color_str,wrapped_text);g_free(wrapped_text);}else//markup g_strdup_printf (span foreground%s sizelarge★★★★★★★/span\n%s, color_str, _(No Comment));markupg_strdup_printf(span foreground%s sizelarge★★★★★★★/span,color_str);最后的效果就是其实侧边栏的注释还有很多改进的地方例如把每个注释的分隔线更加粗一点。把前面的注释符号icon放到左上角。现在我只能通过图示的方式很好区分不同的注释。调整侧边栏宽度因为初始的侧边栏宽度太窄默认应该是132。而我习惯更宽一点方便看注释。找到文件shell/ev-window.c中的函数setup_sidebar_from_metadata。然后按照如下的代码修改。为了体现区别我把源代码注释然后修改后的代码放在下面。if (ev_metadata_get_int (priv-metadata, sidebar_size, sidebar_size)) gtk_paned_set_position (GTK_PANED (priv-hpaned), 300);去掉侧边栏的图标因为我觉得图标太占位置而且信息量不大。我决定去掉它。找到shell/evince-sidebar-annotations.ui然后去掉下面这段。其它用lt;替代。