pdfcn渲染层设计细节揭秘:PDF点与CSS像素的96/72转换及Primitives设计刻度体系
【免费下载链接】pdfcnBeautiful pdf components, built on Takumi and Forme. 100% Free, Zero config, one command setup.项目地址: https://gitcode.com/gh_mirrors/pd/pdfcn
pdfcn 是一个 100% 免费、零配置的 PDF 组件库,构建于 Takumi 与 Forme 双渲染引擎之上。这篇文章带你拆解 pdfcn 渲染层最核心的两个设计细节:PDF 点(pt)与 CSS 像素(px)之间的 96/72 换算机制,以及 Primitives 设计刻度体系如何让所有组件的尺寸、字号、间距"永远整齐"。即使你刚接触 PDF 开发,也能看懂这套优雅的分层设计。
为什么 PDF 开发绕不开"点"这个单位?
如果你写过 CSS,大概率只关心像素(px);但 PDF 是一门更老、更"物理"的格式:
| 概念 | 定义 | 常见场景 |
|---|---|---|
| PDF 点(pt) | 1 英寸的 1/72 | PDF 规范、react-pdf 等渲染器 |
| CSS 像素(px) | 1 英寸的 1/96(96 DPI 基准) | 浏览器渲染 |
两个单位的"物理"定义不同,于是有了那个关键的换算系数:
1 pt = 96 / 72 px = 4/3 px ≈ 1.333 px举个例子:A4 纸的宽度是595 pt。如果渲染到浏览器预览区,就要按 595 × 4/3 ≈ 793 px 来摆放,才能保证屏幕预览和打印出来的 PDF 尺寸一致。pdfcn 正是围绕这一条换算规则,设计了整个渲染层的边界。
96/72 转换:在"primitive 边界"一次性完成
pdfcn 的 Takumi 引擎底层是浏览器 CSS,数字长度默认按 96 DPI 的像素解释;而组件对外 API 却沿用 PDF 的点。这个矛盾在哪里解决?答案在 primitive 层——所有组件都建立在View、Text、Image、Link等最小单元之上,转换只在这条边界发生一次:
- 核心常量:pdf-primitives.tsx 中定义了
PDF_POINT_TO_CSS_PIXEL = 96 / 72与pointToCssPixel()函数 - 白名单机制:POINT_LENGTH_PROPERTIES 精确列出了
width、margin、padding、fontSize等"会接收点值"的属性,只有这些属性上的纯数字才会被乘以 4/3 - 样式归一化:normalizeTakumiStyle 顺带把
marginHorizontal、paddingVertical等简写展开为四边属性,并自动补齐borderStyle: solid
💡 设计精妙之处:因为转换发生在最底层,上层几十个组件(Table、Card、Invoice 等)完全无感知——你写
padding: 12就是 12 个点,物理尺寸天然对齐打印结果。
这个换算还被复用在预览系统里:preview-config.tsx 用它把 595×842(A4)等页面尺寸换算成浏览器像素,保证 playground 中"所见即所得"。
Primitives 设计刻度体系:一套"尺寸调色板"
光有单位换算还不够,pdfcn 用一组**原始刻度(Primitive Tokens)**约束所有可用数值,主题只需从刻度中"取色",这是它和 shadcn/ui 一脉相承的哲学。默认刻度定义在 primitives.ts,类型契约在 pdf-themes.ts。
📏 排版刻度:1.25 大三度比例
字号采用 Major Third(1.25)比例,以 12pt 为正文基准:
10 → 12 → 15 → 18 → 22 → 28 → 36(xs / sm / base / lg / xl / 2xl / 3xl)
正好覆盖脚注到 H1 标题,每级跳变幅度统一,视觉节奏自然。
📐 间距刻度:4pt 网格
所有间距都是 4pt 的整数倍:2 / 4 / 8 / 12 / 16 / 20 / 24 / 32 / 40 / 48 / 64。页边距、章节间隔、表格行距都从这一把"标尺"上取值,文档因此不会出现"差 1 个点"的错位感。
🔠 其他刻度
- 字重:400 / 500 / 600 / 700 四档
- 行高:1.2(紧凑标题)/ 1.4(正文)/ 1.6(长文阅读)
- 圆角:0 / 2 / 4 / 8pt 及
full(胶囊形) - 字距:-0.025 ~ 0.05(标题收紧、大写拉开)
双引擎分层:Forme 与 Takumi 如何共享同一套 API?
pdfcn 同时提供 Forme(@formepdf/react 封装)和 Takumi(自研 primitive)两套 base:
- Forme 侧:原生就是点单位,只需做样式数组合并,无需任何换算
- Takumi 侧:在 primitive 边界补上 96/72 转换
- 上层收益:同一份组件 API、同一套主题刻度,在两个引擎里渲染出的物理尺寸完全一致
9 个内置主题预设(professional、modern、minimal、corporate 等)都从这套 primitives 中派生,见 themes.ts,主题文档可参考 apps/web/content/docs/theming/。
新手如何理解这套设计的价值?
- 你只管写点(pt):
fontSize: 12、margin: 24,打印尺寸就是设计值 - 预览不失真:浏览器像素由 96/72 系数自动换算,屏幕与纸张对齐
- 组件永不"长歪":所有数值受刻度体系约束,9 套主题随意切换,布局依旧整齐
这就是 pdfcn 渲染层的完整故事:用一条 96/72 的边界换算解决"屏幕-纸张"单位鸿沟,用一套 Primitives 刻度解决"尺寸混乱"——两条线交汇,才有了"零配置、一条命令上手"的 PDF 组件体验。
【免费下载链接】pdfcnBeautiful pdf components, built on Takumi and Forme. 100% Free, Zero config, one command setup.项目地址: https://gitcode.com/gh_mirrors/pd/pdfcn
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考