热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PDF中的内嵌字体问题

写过论文的人大都清楚,最终提交的cameraready版本中的字体必须是Type1或TrueType的,而且所有字体都要内嵌到pdf文件中。最近正好遇到这样一个问题,camerar

写过论文的人大都清楚,最终提交的cameraready版本中的字体必须是Type 1或True Type的,而且所有字体都要内嵌到pdf文件中。最近正好遇到这样一个问题,cameraready提交后,编辑发现一些字体没内嵌,只能退回来修改。支持查看字体是否内嵌的工具很多,比如Adobe Reader、Evince、Foxit Reader等等,通常在“文件->属性->字体”这样的菜单下。下图是Evince的截图,可以看到Fonts标签里显示了字体列表,包括字体的类型和是否内嵌。

《PDF中的内嵌字体问题》

要找到哪些字体没有内嵌是非常容易的,但要搞清楚这些字体对应哪些内容就不容易了。经验有时候能起些作用,比如采用常用的Latex工具(例如CTex套件、TexEditor、TexStudio、Sublime-Text Latex Tools等等)编译出来的pdf中,正文部分的字体往往都是内嵌的,真正容易出问题的是那些图片,尤其是用Visio等工具生成的图片,这些工具导出pdf的时候,不一定会把字体内嵌。所以,可以打开论文的图片文件夹,把pdf图片挨个点开看看。

如果还是找不到还可以利用一些工具,比如xpdf(http://www.foolabs.com/xpdf/)中的pdffonts。在命令行输入:pdffonts xxx.pdf就能打印出pdf文件使用的所有字体,以及它们是否被内嵌了(下图中emb列)。除此以外,还有一个重要的信息,就是字体对应的编号(下图中的object列)。这个数字描述了在pdf文档中字体的唯一编号,所以通过该数字可以找到使用该字体的内容。

《PDF中的内嵌字体问题》

图中显示的Times New Roman字体没有内嵌,并且对应的object编号为161。用文本编辑器(如Vim、Sublime Text、Notepad++等)打开pdf文件后搜索“161 0 obj”,会看到类似下图的结果。在pdf中,obj和endobj之间的部分构成了一个最基本的object单元。要想更多了解pdf的结构,可以参考这篇文章,相比其它文章,作者写得更加浅显易懂。

《PDF中的内嵌字体问题》

上图中的object只是定义了字体本身,要找到使用该字体的内容还需要在pdf文档中搜索“161 0 R”,看看引用”161 0 obj”的object是什么。按照这个方法,在pdf中找到的内容如下图所示(由于object内容太长,引用的部分没有显示在图中),很容易就能发现字体其实用在图片中。

《PDF中的内嵌字体问题》

如果这些字体出现在正文里,可能需要一些额外的步骤,因为pdf的正文(记作stream object)一般是压缩过的(通常采用zlib中的flatecode),所以看到的都是乱码。为了看到这些内容,可以用pdftk或qpdf提供的工具来解压,对应的命令分别为:

pdftk test.pdf output test-d.pdf uncompress

qpdf --stream-data=uncompress input.pdf output.pdf

我在linux下发现pdftk工作不正常,最终是用qpdf解压的,stackoverflow上说可能是由bug造成的,不过用什么工具其实无所谓的。

后记:在了解pdf格式的过程中,发现其实pdf的设计非常灵活,或者说有点灵活过了头,导致编写parser成为一个极其复杂无趣的过程。那些成熟的pdf阅读器都是经过相当长的演化,不断修改才能兼容各种奇葩的pdf格式定义。为什么不把格式定的“死板”一些呢?这样对文件处理很有好处的呀,哪怕牺牲那么点效率。


推荐阅读
  • 本文总结了在多人协作开发环境中使用 Git 时常见的问题及其解决方案,包括错误合并分支的处理、使用 SourceTree 查找问题提交、Git 自动生成的提交信息解释、删除远程仓库文件夹而不删除本地文件的方法、合并冲突时的注意事项以及如何将多个提交合并为一个。 ... [详细]
  • Java高级工程师学习路径及面试准备指南
    本文基于一位朋友的PDF面试经验整理,涵盖了Java高级工程师所需掌握的核心知识点,包括数据结构与算法、计算机网络、数据库、操作系统等多个方面,并提供了详细的参考资料和学习建议。 ... [详细]
  • 本文分享了作者在使用LaTeX过程中的几点心得,涵盖了从文档编辑、代码高亮、图形绘制到3D模型展示等多个方面的内容。适合希望深入了解LaTeX高级功能的用户。 ... [详细]
  • 本文详细介绍了在PHP中如何获取和处理HTTP头部信息,包括通过cURL获取请求头信息、使用header函数发送响应头以及获取客户端HTTP头部的方法。同时,还探讨了PHP中$_SERVER变量的使用,以获取客户端和服务器的相关信息。 ... [详细]
  • 电商常用同义词库_【福利】不可错过的电商设计神器,提高工作效率
    开启高效设计,拒绝每天加班,设计助理插件,设计师高效设计神器,让你早下班的设计神器;今天介绍一款非常人性化的插 ... [详细]
  • 本文详细介绍了Socket在Linux内核中的实现机制,包括基本的Socket结构、协议操作集以及不同协议下的具体实现。通过这些内容,读者可以更好地理解Socket的工作原理。 ... [详细]
  • 本文探讨了当通过Nginx访问网站时出现504 Gateway Timeout错误的解决方案,特别是当请求处理时间超过30秒时的情况。文章提供了调整PHP-FPM配置的具体步骤,以延长请求超时时间。 ... [详细]
  • 如何高效学习鸿蒙操作系统:开发者指南
    本文探讨了开发者如何更有效地学习鸿蒙操作系统,提供了来自行业专家的建议,包括系统化学习方法、职业规划建议以及具体的开发技巧。 ... [详细]
  • 一、使用Microsoft.Office.Interop.Excel.DLL需要安装Office代码如下:2publicstaticboolExportExcel(S ... [详细]
  • Python网络编程:深入探讨TCP粘包问题及解决方案
    本文详细探讨了TCP协议下的粘包现象及其产生的原因,并提供了通过自定义报头解决粘包问题的具体实现方案。同时,对比了TCP与UDP协议在数据传输上的不同特性。 ... [详细]
  • 本文介绍了如何使用 Python 的 Pyglet 库加载并显示图像。Pyglet 是一个用于开发图形用户界面应用的强大工具,特别适用于游戏和多媒体项目。 ... [详细]
  • 使用Python构建网页版图像编辑器
    本文详细介绍了一款基于Python开发的网页版图像编辑工具,具备多种图像处理功能,如黑白转换、铅笔素描效果等。 ... [详细]
  • 1,滤波流程2,图像的金字塔分解(拉普拉斯金字塔)3,金字塔傅里叶频率组合滤波(本文完ÿ ... [详细]
  • 页面预渲染适用于主要包含静态内容的页面。对于依赖大量API调用的动态页面,建议采用SSR(服务器端渲染),如Nuxt等框架。更多优化策略可参见:https://github.com/HaoChuan9421/vue-cli3-optimization ... [详细]
  • MVC模式下的电子取证技术初探
    本文探讨了在MVC(模型-视图-控制器)架构下进行电子取证的技术方法,通过实际案例分析,提供了详细的取证步骤和技术要点。 ... [详细]
author-avatar
等待的承诺灬_231
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有