首页 > 编程语言 >pdf.js源码分析-字体加载流程

pdf.js源码分析-字体加载流程

时间:2024-07-12 15:12:48浏览次数:10  
标签:js 源码 字体 pdf font properties 加载

pdf.js中的字体加载流程,下面演示一种Type1的字体的加载流程,会把一些兼容性的内容省去,只记录字体数据的加载过程中涉及到的方法和作用:

  1. evaluator.js -> handleSetFont:操作符列表中加载字体
  2. evaluator.js -> loadFont:加载字体的方法
  3. evaluator.js -> preEvaluateFont:对字体信息进行预处理,对pdf中的字体信息开始整理,类似于将pdf中的字典信息进行整理,拿到pdf中字体的信息
  4. evaluator.js -> translateFont:通过上一步获取的字体信息,开始对字体进行加载和转换,此时假设字体数据包含有descriptor对象
    在translateFont中会创建Font对象,首先是创建字体的properties属性,根据descriptor等获取到fontName等属性值,fontFile拿到字体的数据。
    下面是包含descriptor时创建的字体properties属性对象
const properties = {
      type,
      name: fontName.name,
      subtype,
      file: fontFile,
      length1,
      length2,
      length3,
      isInternalFont,
      loadedName: baseDict.loadedName,
      composite,
      fixedPitch: false,
      fontMatrix: dict.getArray("FontMatrix") || FONT_IDENTITY_MATRIX,
      firstChar,
      lastChar,
      toUnicode,
      bbox: descriptor.getArray("FontBBox") || dict.getArray("FontBBox"),
      ascent: descriptor.get("Ascent"),
      descent: descriptor.get("Descent"),
      xHeight: descriptor.get("XHeight") || 0,
      capHeight: descriptor.get("CapHeight") || 0,
      flags: descriptor.get("Flags"),
      italicAngle: descriptor.get("ItalicAngle") || 0,
      isType3Font,
      cssFontInfo,
      scaleFactors: glyphScaleFactors,
      systemFontInfo,
    };
  1. evaluator.js -> extractDataStructures:有了上面的properties之后,调用extractDataStructures方法来获取字体编码和differences的值,这个方法重要,根据字体数据的编码类型,比如StandardEncoding还是其他等,获取到字体的编码映射等。以及获取toUnicodeMap,这里关于字体的映射和differences限于篇幅,就不做多的赘述,另开文章详写。
  2. evaluator.js -> extractWidths:提取字体中字符的宽度,每个字符都有一个宽度,所以拿到对应字符之后再进行宽度校正
  3. evaluator.js -> new Font(fontName.name, fontFile, newProperties):创建Font字体对象
  4. fonts.js -> fontFile.isEmpty:这个isEmpty会读取字体数据,判断不为空来读取字体的字节数据
  5. fonts.js -> getFontFileType:获取字体的类型,[type, subtype] = getFontFileType(file, properties);
  6. fonts.js -> new Type1Font(name, file, properties):根据字体数据和属性properties来创建Type1Font,这里按照Type1类型的字体进行解析字体数据。
  7. type1_font.js -> new Type1Font(name, file, properties):根据字体数据和属性properties来创建Type1Font,这里按照Type1类型的字体进行解析字体数据。
  8. type1_font.js -> checkEExecFlag,getHeaderBlock,extractFontHeader来获取Type1字体的头数据
  9. type1_parser.js -> extractFontProgram:提取字体数据中的/CharStrings等token数据,这里时字体的规格数据
  10. type1_parser.js -> this.wrap(name,type2Charstrings,this.charstrings,subrs,properties):将字体数据进行包装,按照CFF格式进行组装拼接,这里是对字体格式进行,里面涉及的关于字体的内容比较多,这里不做过多赘述。CFF是紧凑型字体,这里还不会直接使用,通过CFF字体之后会再次convert为OTF字体
  11. type1_parser.js -> adjustWidths(properties):对字体宽度进行重新矫正,使用fontMatrix进行校正
  12. fonts.js -> convert(name, cff, properties):最后是将CFF的字体数据传入之后再进行组装成OTF字体数据,并且转换成unit8array的二进制数组,这个就是最后使用的字体数据了,进行loadFont的数据
  13. evaluator.js -> new TranslatedFont({loadedName: font.loadedName,font: translatedFont,dict: font,evaluatorOptions: this.options}):将OTF的字体再次进行转换,构造一个TranslatedFont对象,主要是包含了OTF的字体数据font值,以及用来发送字体加载完成的消息,也就是send方法,并且对Type3字体做处理,这里具体Type3字体的处理暂不赘述。
  14. evaluator.js -> handleSetFont:这里进入到let translated = await this.loadFont,将上面所生成的translatedFont对象作为字体数据,并且translatedFont调用send方法表示当前字体加载完成,将当前的消息发送到api.js中,此时调用的是commonobj,然后对象是Font类型
  15. api.js -> messageHandler.on("commonobj"):处理加载完字体发送过来的数据,const font = new FontFaceObject(exportedData, ...),这里将translatedFont中的font的data数据进行转换成FontFaceObject对象,这个FontFaceObject是pdf.js封装的用来进行处理FontFace字体对象的类,这样在使用FontFace的时候就是使用pdf.js中包装的FontFaceObject来将OTF中的字体数据和浏览器的FontFace对象之间进行关联
  16. api.js -> this.fontLoader.bind(font):使用fontLoader对上一步中的FontFaceObject字体进行加载,会调用FontFaceObject中的createNativeFontFace,也就是将pdf.js中的字体转换为FontFace这样的对象,这样创建浏览器的本地FontFace对象,这个FontFace加载的名字也就是后面要在设置字体的时候使用的font-family的名字,再通过document.fonts.add(fontFace)即完成字体到本地浏览器的加载
    以上便是pdf.js对于Type1字体加载的整个流程,其中并没有进行详细叙述,但是也大概包含了完整的从数据流到字体的流程,其中还包含几个重要步骤没有详细描述,比如FlateStream的加载和解析,相当于对flate编码的流数据进行解密。以及具体的CFF和OTF字体之间的转换,关键有一个是对于字体中header的一个描述使用。还有toUnicodeMap这样进行字体映射的内容的具体描述。
    下图是一个加载的具体流程,从左到右,从上到下的顺序

标签:js,源码,字体,pdf,font,properties,加载
From: https://www.cnblogs.com/xxss0903/p/18296837

相关文章

  • 【java计算机毕设】线上花店销售商城系统java MySQL ssm JSP maven项目代码源码+文档p
    目录1项目功能2项目介绍3项目地址 1项目功能【java计算机毕设】线上花店销售商城系统MySQLssmJSPmaven项目代码源码+文档PPT小组设计代码 2项目介绍系统功能:线上花卉小铺系统包括管理员、用户俩种角色。用户端:1.注册登录:游客填写基础信息,注册成为小铺用......
  • CRC_CCITT js版的计算函数
    CRC_CCITT,特征多项式:X16+X12+X5+1,即多项式系数为0x1021,初始值为全0,对于单个字节来说最高位先计算,不需要取反直接输出。functioncalculateCRC_CCITT(buffer){constPOLYNOMIAL=0x1021;letcrc=0x0000;//Initialvaluesettoall0sforthisspecificcase......
  • html+js实现选中左边的数据到右边
    效果后台要开发个功能,给游戏内的用户赠送道具,先把道具列表展示,然后选择要增送的道具,可以加上道具图片之类的,美化index.html页面没有美化,只是实现了效果。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device......
  • 基于SpringBoot+Vue+数据可视化的药品商场购物系统设计和实现(源码+LW+部署讲解)
    博主介绍:✌全网粉丝50W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、P......
  • 课程设计——基于JSP + Servlet的学生信息管理系统
    基于JSP+Servlet的学生信息管理系统该项目为课程设计项目1.总体功能描述本系统利用JavaWeb技术实现了学生信息管理系统,具有简单的学生信息管理功能。实现了以下功能模块:院系信息管理模块,学生信息管理模块,课程信息管理模块,成绩管理模块并能根据登入用户的权限自动......
  • threejs画布叠加在cesium画布上不显示
    这个问题可能是由于Three.js和Cesium在渲染顺序或者渲染上下文方面存在冲突导致的。Three.js和Cesium都是用于创建3D或2D地图的库,它们各自管理自己的渲染画布(WebGL上下文)。解决方法: 确保Cesium初始化先于Three.js。Cesium需要完全初始化并且渲染其画布之后,Three.js才能在同......
  • 毕业设计之python语音数据及标注核对审核系统设计与实现(python完整源码+说明文档+演示
    1项目介绍基于python的语音标注及审核系统的目的就是在于建立属于自己的一套识别系统,在日常的工作中,语音识别是一件非常重要的事情,比如说企业或事业单位当中。自动整理语音数据,保存到数据库当中,实现数据对应一致性,这样可以很大程度地进行数据的校验。2、项目技术项目后......
  • Python爬虫抓取笔趣阁小说(含源码)
    学习一下思路:1.我们进入需要爬取到的小说界面,右键开发者工具,选中元素显示,然后找到需要爬取的小说章节模块在代码中的位置。将a标签中的文本内容复制,然后ctrl+u打开源代码ctrl+f将刚刚的文本内容复制查找是否有这个模块。(比较爽的是,刚好这里有,可以不需要去查看网络请求......
  • js 数组方法 - 查找 - indexOf()、includes()、find()、findIndex()、filter()、lastI
    indexOf()该方法可以返回数组中指定元素的索引,如果不存在,则返回-1。constarr=["apple","banana","orange"];constindex=arr.indexOf("banana");console.log(index);//输出:1constarr2=["aaa","bbb","ccc",9......
  • Adnc 源码解析
    先看 Adnc.Demo.Usr.Api解决方案varstartAssembly=System.Reflection.Assembly.GetExecutingAssembly();varstartAssemblyName=startAssembly.GetName().Name??string.Empty;varlastName=startAssemblyName.Split('.').Last();varmigrationsAssembl......