新闻中心

在borb中高效使用西里尔字母:自定义TrueType字体与低层PDF操作

2025-11-07
浏览次数:
返回列表

在borb中高效使用西里尔字母:自定义truetype字体与低层pdf操作

本文详细探讨了在Python `borb`库中处理西里尔字母的挑战与解决方案,特别是针对需要精细字符控制和高性能的场景。文章首先介绍了使用`Paragraph`和`Rectangle`的高层API方法,指出了其在处理大量字符时的性能瓶颈。随后,深入分析了基于低层PDF内容流操作的优化方案,并重点阐述了如何正确集成自定义TrueType字体以支持西里尔字母,同时解决了字符编码问题,最终实现了显著的性能提升。

引言:在borb中处理西里尔字母的挑战

在borb库中处理非拉丁字符集,如西里尔字母,常常会遇到字体支持问题。borb默认的字体可能不包含西里尔字母的字形,导致字符无法正确显示。对于需要精确控制每个字符位置的应用场景,如PDF文档的字符级修改,问题会变得更加复杂。本文将介绍两种在borb中实现西里尔字母渲染的方法:一种是易于理解但效率较低的高层API方法,另一种是性能优越但需要深入理解PDF底层机制的低层内容流方法。我们将重点解决如何在低层方法中正确集成自定义TrueType字体并处理西里尔字母编码。

方法一:使用高层API(Paragraph和Rectangle)

borb提供了一套高层API,通过Paragraph和Rectangle对象可以相对直观地在PDF页面上放置文本。这种方法允许用户指定自定义字体,从而解决西里尔字母的显示问题。

实现细节

首先,需要加载一个支持西里尔字母的TrueType字体(.ttf文件)。然后,对于每个要渲染的字符,创建一个Paragraph实例,并指定其字体、大小和内容。最后,使用paint方法将其绘制到指定Rectangle区域内的页面上。

以下是实现此方法的示例代码:

易标AI 易标AI

告别低效手工,迎接AI标书新时代!3分钟智能生成,行业唯一具备查重功能,自动避雷废标项

易标AI 135 查看详情 易标AI
from pathlib import Path
from decimal import Decimal
from borb.pdf.canvas.layout.text.paragraph import Paragraph
from borb.pdf.canvas.layout.shape.rectangle import Rectangle
from borb.pdf.canvas.font.true_type_font import TrueTypeFont
from borb.pdf.canvas.font.font import Font
from borb.pdf.page.page import Page

# 假设 symb_arr 是一个包含 Symbol 对象的数组
# class Symbol:
#     def __init__(self, s, x, y, w, h, f):
#         self.sym = s  # character
#         self.x_coord = x
#         self.y_coord = y
#         self.width = w
#         self.height = h
#         self.font_size = f

# 1. 加载自定义TrueType字体
font_path: Path = Path(__file__).parent / "TimesNewRomanRegular.ttf"
custom_font: Font = TrueTypeFont.true_type_font_from_file(font_path)

# 假设 page 是一个 borb.pdf.page.page.Page 对象
# 假设 symb_arr 是 Symbol 对象的列表
# 假设 font_size 已经定义

for i, s in enumerate(symb_arr):
    r: Rectangle = Rectangle(
        Decimal(s.x_coord),
        Decimal(s.y_coord),
        Decimal(s.width + 2),
        Decimal(s.height + 2),
    )
    Paragraph(s.sym, font_size=Decimal(s.font_size), font=custom_font).paint(page, r)

优点与局限性

  • 优点: 代码直观,易于理解和实现。borb内部会处理字体嵌入和字符编码的复杂性。
  • 局限性: 对于需要处理大量字符或进行频繁修改的场景,这种方法效率低下。每次调用Paragraph.paint都会涉及较多的内部操作,导致性能瓶颈。例如,处理两段PDF文档可能需要数秒。

方法二:使用低层PDF内容流操作实现高性能渲染

为了实现更高的性能,可以直接操作PDF的内容流(Content Stream)。PDF内容流使用一系列操作符来描述页面内容,例如设置字体、定位文本和显示文本等。这种方法提供了对PDF渲染过程的精细控制,但需要更深入地理解PDF规范。

低层操作的基本原理

PDF内容流是一系列指令的序列,这些指令被压缩并存储在页面对象的Contents字典中。通过构建这些指令,可以直接控制文本的渲染。

以下是使用低层语法渲染文本的示例代码:

import zlib
from decimal import Decimal
from borb.pdf.canvas.layout.text.paragraph import Paragraph
from borb.pdf.canvas.layout.shape.rectangle import Rectangle
from borb.pdf.canvas.font.true_type_font import TrueTypeFont
from borb.pdf.canvas.font.font import Font
from borb.pdf.page.page import Page
from borb.pdf.document.document import Document
from borb.pdf.canvas.geometry.rectangle import Rectangle as BorbRectangle
from borb.pdf.primitive.name import Name
from borb.pdf.primitive.stream import Stream
from borb.pdf.primitive.dictionary import Dictionary
from borb.pdf.primitive.string import String

# 假设 page 是一个 borb.pdf.page.page.Page 对象
# 假设 symb_arr 是 Symbol 对象的列表
# 假设 doc 是 borb.pdf.document.document.Document 对象

# 1. 创建内容流
content_stream = Stream()
content = b""""""
for s in symb_arr:
    # 注意:这里的 (%b) Tj 格式化字符串和编码是问题的关键
    # 后面会详细讨论如何正确处理西里尔字母编码
    content += b"""
        q
        BT
        /F1 %b Tf
        %b %b Td
        (%b) Tj
        ET
        Q
    """ % (bytes(format(s.font_size, '.4f'), 'utf-8'),
           bytes(format(s.x_coord, '.4f'), 'utf-8'),
           bytes(format(s.y_coord, '.4f'), 'utf-8'),
           bytes(str(s.sym), 'utf-8')) # 原始问题中的编码方式

content_stream[Name("DecodedBytes")] = content
content_stream[Name("Bytes")] = zlib.compress(content_stream["DecodedBytes"], 9)
content_stream[Name("Filter")] = Name("FlateDecode")
content_stream[Name("Length")] = Decimal(len(content_stream["Bytes"]))

# 2. 设置页面内容
page[Name("Contents")] = content_stream

# 3. 设置字体资源 (原始问题中的尝试)
page[Name("Resources")] = Dictionary()
# 原始问题尝试从现有页面复制字体资源,但这不适用于自定义字体
# page[Name("Resources")] = doc.get_page

以上就是在borb中高效使用西里尔字母:自定义TrueType字体与低层PDF操作的详细内容,更多请关注其它相关文章!


# 编码  # 肥料推广营销方案直播  # 铜梁网站建设平台有哪些  # 宁波营销推广途径有哪些  # 营销推广答辩问题汇总  # 沁阳优化网站排名哪里好  # 舟山抖音营销推广方法  # 保定网站建设方案书  # 文档  # 加载  # 库中  # 如何使用  # 这种方法  # 高性能  # 可以直接  # 是一个  # 西里尔  # 自定义  # canva  # 性能瓶颈  # stream  # pdf  # ai  # python  # 网站建设以及优化  # seo抖音区别  # 疑似含有营销推广内容 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: Python中高效访问嵌套字典与列表中的键值对  Win10如何开启蓝牙功能_Windows10找不到蓝牙开关解决方法  Composer中的^和~符号代表什么_精通Composer版本号语义化约束  Go语言中Map值调用指针接收器方法的限制与应对  如何在低配置电脑上搭建轻量级J*a环境_占用更小的环境选择技巧  邮政快递单号查询入口 邮政快递物流信息在线查询入口  魅族20怎样在浏览器开无图省流_iPhone魅族20浏览器开无图省流【流量节省】  写好的html代码怎么运行出来_运行写好的html代码方法【教程】  c++中为什么推荐使用using替代typedef_c++现代化类型别名  在VS Code中配置和运行Dart程序的完整步骤  J*aScript Promise链中如何正确终止后续.then执行并处理错误  使用 Pandas 高效处理 .dat 文件:数据清洗与数值计算实战  J*aScript中localStorage数据的获取、清洗与格式化教程  Fabric模组开发:自定义物品与物品组的现代管理方法  Django AJAX 文件上传教程:解决图片无法保存到模型的常见问题  邮政快递包裹最新位置 邮政快递实时追踪入口  C++如何实现异步操作_C++11使用std::future和std::async进行异步编程  J*aScript:在map操作中高效处理空数组  可靠CSGO开箱平台解析 CSGO开箱网合集  windows10怎么查看硬盘序列号_windows10硬盘id查询命令  文心一言怎样用批量生成做多版文案_文心一言用批量生成做多版文案【批量创作】  css链接悬停下划线样式如何自定义_使用::after结合content和transition  网易大神怎么保存别人动态的图片_网易大神动态图片保存方法  Win10怎么设置静态IP地址 Win10手动配置IP地址步骤【指南】  c++ 命名空间怎么用 c++ namespace使用指南  React/Next.js中实现列表项的动态选择与移动  曝R星经典之作开发图 设计简陋但信息密集!  J*aScript中赋值与自增运算符的复杂交互与执行机制  极速漫画官方主页网址 极速漫画漫画在线浏览官网链接  C++如何解决segmentation fault_C++段错误调试与原因分析  Win11怎么开启卓越性能模式 Win11电源选项启用高性能释放硬件潜力【方法】  Excel Power Pivot如何处理XML数据源 构建高级数据模型  R星幕后开发视频泄露 包含《GTA6》等多款大作  精准捕获:如何在页面中监听除特定元素外的所有点击事件  PPT平滑切换怎么做 PPT炫酷“平滑”切换动画制作教程【必学】  J*aScript实现单选按钮与关联输入框的联动禁用教程  如何有效阻止外部脚本意外修改内联样式的高度属性  12306选座如何查看座位示意图_12306座位示意图解读与使用  优化 Python 函数中的条件逻辑:解决 if-else 嵌套与参数选择问题  QQ邮箱电脑版登录入口_QQ邮箱官方网站登录平台  Golang如何通过reflect操作map_Golang reflect map操作与遍历技巧  微信语音通话掉线如何解决 微信语音通话稳定优化方法  sublime如何只显示或隐藏特定类型文件_sublime侧边栏文件过滤  html5 app怎么运行环境_配html5 app运行环境【教程】  vivo手机参数配置怎么增强信号_vivo手机参数配置信号增强方法  在J*a中如何使用Exception包装底层异常_异常包装与信息传递方法说明  俄罗斯方块最新版入口 俄罗斯方块在线玩官网入口  如何提高微信支付的安全性_微信支付安全防护与设置建议  微信群消息显示延迟如何解决 微信群消息刷新优化方法  抓大鹅解压小游戏 抓大鹅摸鱼解压入口 

搜索