如何使用 Python 获取 1200 英寸的 truetype 字体字符宽度?

2023-11-26

我可以使用 PIL 获取字符的高度和宽度(以像素为单位)(见下文),但是(除非我弄错了)像素大小取决于屏幕的 DPI,它可能会有所不同。相反,我想做的是以绝对单位(例如英寸或 1200 英寸)(“wordperfect 单位”)计算字符的宽度。

>>> # Getting pixels width with PIL
>>> font = ImageFont.truetype('/blah/Fonts/times.ttf' , 12)
>>> font.getsize('a')
(5, 14)

我想要这样做的原因是创建一个用于编写二进制 Word Perfect 文档的自动换行功能。 Word Perfect 要求在整个文本的有效点插入软换行代码,否则文件将被损坏且无法打开。问题是在哪里为可变宽度字体添加它们。

我意识到我并不完全理解像素与屏幕分辨率和字体大小之间的关系。我这一切都错了吗?


原始文本宽度通常计算为印刷师的要点,但由于用于字体定义的点被定义为 1/72 英寸,因此您可以轻松地将其转换为任何其他单位。

为了得到设计宽度一个字符(表示为em单位),您需要访问字体的低级数据。最简单的方法是pip install fonttools,它具有在尽可能最低的字体定义级别上工作的一切。

安装 fontTools 后,您可以:

  1. 加载字体数据——这需要实际字体文件的路径;

  2. 字符宽度存储为glyph宽度,这意味着您必须检索“字符到字形”映射;这是在cmap字体表:

    A。加载cmap为你的字体。最有用的是 Unicode 映射 - 一种字体可能包含其他字体。 b.加载字形集为你的字体。这是一个列表names对于该字体的字形。

  3. 然后,对于每个 Unicode 字符,首先查找其名称,然后使用该名称检索其设计单位的宽度。

  4. 不要忘记“设计单位”是基于字体的整体“设计宽度”。这可以是一个标准值1000(典型的 Type 1 字体),2048(典型的 TrueType 字体),或任何其他值。

这导致了这个函数:

from fontTools.ttLib import TTFont
from fontTools.ttLib.tables._c_m_a_p import CmapSubtable

font = TTFont('/Library/Fonts/Arial.ttf')
cmap = font['cmap']
t = cmap.getcmap(3,1).cmap
s = font.getGlyphSet()
units_per_em = font['head'].unitsPerEm

def getTextWidth(text,pointSize):
    total = 0
    for c in text:
        if ord(c) in t and t[ord(c)] in s:
            total += s[t[ord(c)]].width
        else:
            total += s['.notdef'].width
    total = total*float(pointSize)/units_per_em;
    return total

text = 'This is a test'

width = getTextWidth(text,12)

print ('Text: "%s"' % text)
print ('Width in points: %f' % width)
print ('Width in inches: %f' % (width/72))
print ('Width in cm: %f' % (width*2.54/72))
print ('Width in WP Units: %f' % (width*1200/72))

结果是:

Text: "This is a test"
Width in points: 67.353516
Width in inches: 0.935465
Width in cm: 2.376082
Width in WP Units: 1122.558594

与 Adob​​e InDesign 报告的内容进行比较时是正确的。 (请注意,每个字符kerning这里不适用!这将需要更多的代码。)

字体中未定义的字符将被默默地忽略,并且像通常所做的那样,字体的宽度.notdef字形被使用。如果您希望将此报告为错误,请删除if在函数中进行测试。

演员阵容float在函数中getTextWidth 所以这在 Python 2.7 和 3.5 下都有效,但请注意,如果您使用 Python 2.7 和更大值的 Unicode 字符(不是纯 ASCII),则需要重写该函数以正确使用 UTF8 字符。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Python 获取 1200 英寸的 truetype 字体字符宽度? 的相关文章

随机推荐

  • DeprecationWarning:Collection#find:改为传递函数

    我是node js 的新手 目前正在使用discord js 来制作Discord 机器人 一旦使用任何机器人命令 控制台就会打印 DeprecationWarning 例如 node 15656 DeprecationWarning Co
  • JOIN 子句中的 MYSQL 子查询 SELECT

    好吧 好吧 我必须将子查询放在JOIN子句 因为它选择多个列并将其放入SELECT子句不允许这样做 因为它给我一个操作数错误 无论如何 这是我的查询 SELECT c id c title c description c icon p id
  • VS 构建后显示“xxx.exe 不是有效的 Win32 应用程序”

    我已经在我的 Windows 7 64 PC 上的 Visual Studio 2015 使用 IDE 中成功开发了 WinAPI 应用程序 我通常在Release模式下测试程序 然后我对我的源代码进行了一些编辑 程序编译和链接没有错误 但
  • 反射调用函数并使用默认参数

    给定以下函数 fun function x Int 12 println x x 如何使用反射调用它而不指定x 或者以某种方式使用默认值 not硬编码 您可以使用callBy 它遵循默认值 function callBy emptyMap
  • 如何将 Facebook 相册集成到网站中? [复制]

    这个问题在这里已经有答案了 可能的重复 Facebook Api 如何访问我的相册 如何在网站内显示 Facebook 相册中的照片 您可以使用图形 API 来获取相册中的图像 如下所示 https graph facebook com A
  • LESS 中的双 & 符号

    我对 LESS 编译器中的双 符号行为感到困惑 Look heading type small font size 15px 将被编译为 heading heading type small font size 15px 那很好 But w
  • 更新和删除表中的不同行时是否可能出现死锁?

    在Oracle 10 版本中 即使同时对同一个表的不同行进行更新和删除 也会导致死锁吗 该表的主键由两列组成 并且没有任何与任何其他表关联 引用的外键 并且与其他表没有父 子关系 我相信 它不会造成僵局 但我在我的应用程序中遇到了问题 添加
  • C++和C#之间通过管道进行通信

    我想通过管道将数据从 C 应用程序发送到 C 应用程序 这是我所做的 这是 C 客户端 include stdafx h include
  • 为什么引入严格性的函数称为 seq?

    我明白了seq功能以及为什么有必要引入严格性以提高效率 我不明白的是 为什么这个原语被称为seq 与严格性无关 TL DR 米兰达称之为seq 它是在什么时候引入的sequence 可能 已经是 Monad 的事情了 并且 被称为stric
  • Angular/Chart.js 错误:无法创建图表:无法从给定项目获取上下文

    这确实是我第一次使用 Chart js 我将其导入到 Angular 组件中 我现在尝试创建一个简单的条形图 我的控制台中出现以下错误 core controller js 118 Failed to create chart can t
  • Heroku 上的 url_for with _external=True 不会在 URL 上附加服务器名称

    我已经在 Heroku 上部署了一个应用程序 但问题是当我的应用程序发送电子邮件时 它没有在 URL 中附加我的服务器名称 content Content text html verification email format user f
  • SQLite 架构信息元数据

    我需要获取 SQLite 数据库中的列名及其表 我需要的是一个包含 2 列的结果集 table name column name 在 MySQL 中 我可以通过数据库上的 SQL 查询来获取此信息INFORMATION SCHEMA 然而
  • opencv中如何合并轮廓?

    好的 我已经在这个项目上工作了一段时间了 我正在构建这个玩铬合金恐龙游戏的机器人 所以我尝试了其他方法来检测字符 例如 matchTemplate 甚至制作了自己的算法来定位对象 但我最喜欢这个 findcontours 这是我所拥有的 谁
  • 如何在 android 11 中的 /Android/media 中创建文件夹?

    我想在内部存储中创建一个新文件夹 但是在新版本的Android中 我们无法像以前创建文件夹一样创建文件夹了 但一些应用程序 例如 WhatsApp 会在 Android media 内创建文件夹 我想知道如何在此位置内创建文件夹 conte
  • Java 运行时.exec()

    我可以从命令行运行此命令 没有任何问题 验证脚本执行 c Python27 python feedvalidator feedvalidator src demo py https das dynalias org 8080 das cor
  • Heroku 中的 Django 错误:“请提供 ENGINE 值”

    我阅读并应用了 Heroku 上的 Django 入门 教程 但在同步数据库时遇到了问题 raise ImproperlyConfigured settings DATABASES is improperly configured djan
  • Angular4 材质输入无法正确显示

    我正在尝试将材质放入 angular4 项目中 在该项目中我用表格复制 粘贴了示例 当我输入客户名称时 编程部分按预期工作 它按应有的方式进行过滤 并且下表显示得非常好 问题是 mat form field 内的 matInput 未正确显
  • 使用 jQuery 检查是否至少选中了一个复选框

    我有五个复选框 使用 jQuery 我如何检查是否至少检查了其中之一
  • 显示更新时从 Flask 视图流式传输的数据

    我有一个可以生成数据并实时传输数据的视图 我不知道如何将此数据发送到可以在 HTML 模板中使用的变量 我当前的解决方案只是在数据到达时将其输出到空白页面 这是可行的 但我想将其包含在带有格式的更大页面中 当数据流式传输到页面时 如何更新
  • 如何使用 Python 获取 1200 英寸的 truetype 字体字符宽度?

    我可以使用 PIL 获取字符的高度和宽度 以像素为单位 见下文 但是 除非我弄错了 像素大小取决于屏幕的 DPI 它可能会有所不同 相反 我想做的是以绝对单位 例如英寸或 1200 英寸 wordperfect 单位 计算字符的宽度 gt