opentype.js使用 JavaScript 读写 OpenType 字体

联合创作 · 2023-09-22

opentype.js 是 TrueType 和 OpenType 字体的 JavaScript 解析器和编写器。

它使您可以从浏览器或 Node.js 访问文本的字母形式。

特征

  • 从一段文本中创建一条贝塞尔曲线路径。
  • 支持复合字形(重音字母)。
  • 支持 WOFF、OTF、TTF(均具有 TrueTypeglyf和 PostScriptcff轮廓)
  • 支持字距调整(使用 GPOS 或 kern 表)。
  • 支持连字。
  • 支持 TrueType 字体提示。
  • 支持阿拉伯文本渲染(参见问题 #364 和 PR #359 #361)
  • 可以选择低内存模式(参见#329)
  • 在浏览器和 Node.js 中运行。

安装

通过 CDN

在下一个示例中选择以下来源之一:

<!-- using global declaration --> <script src="https://your.favorite.cdn/opentype.js"></script> <script>opentype.parse(...)</script> <!-- using module declaration (need full path) --> <script type=module> import { parse } from "https://unpkg.com/opentype.js/dist/opentype.module.js"; parse(...); </script>

通过npm包管理器

npm install opentype.js
const opentype = require('opentype.js'); import opentype from 'opentype.js' import { load } from 'opentype.js'

用法

加载 WOFF/OTF/TTF 字体

// case 1: from an URL const buffer = fetch('/fonts/my.woff').then(res => res.arrayBuffer()); // case 2: from filesystem (node) const buffer = require('fs').promises.readFile('./my.woff'); // case 3: from an <input type=file id=myfile> const buffer = document.getElementById('myfile').files[0].arrayBuffer(); // if running in async context: const font = opentype.parse(await buffer); console.log(font); // if not running in async context: buffer.then(data => { const font = opentype.parse(data); console.log(font); })

加载 WOFF2 字体

WOFF2 Brotli 压缩性能比 WOFF 前身好 29% 。但是这种压缩也更复杂,并且会导致 opentype.js 库更重(~120KB => ~1400KB)。

要解决这个问题:预先解压缩字体(例如使用fontello/wawoff2)。

// promise-based utility to load libraries using the good old <script> tag const loadScript = (src) => new Promise((onload) => document.documentElement.append( Object.assign(document.createElement('script'), {src, onload}) )); const buffer = //...same as previous example... // load wawoff2 if needed and wait (!) for it to be ready if (!window.Module) { const path = 'https://unpkg.com/wawoff2@2.0.1/build/decompress_binding.js' const init = new Promise((done) => window.Module = { onRuntimeInitialized: done}); await loadScript(path).then(() => init); } // decompress before parsing const font = opentype.parse(Module.decompress(await buffer));

加载字体(1.x 样式)

此示例依赖于已弃用的.load()方法

// case 1: from an URL const font = opentype.load('./fonts/my.woff', {}, {isUrl: true}); // case 2: from filesystem const font = opentype.load('./fonts/my.woff', {}, {isUrl: false}); // ... play with `font` ... console.log(font.supported);

写字体

一旦你有了一个Font对象(通过使用opentype.load或从头开始创建一个新对象),你就可以将它作为二进制文件写回。

在浏览器中,您可以使用Font.download()指示浏览器下载二进制 .OTF 文件。该名称基于字体名称。

// Create the bézier paths for each of the glyphs. // Note that the .notdef glyph is required. const notdefGlyph = new opentype.Glyph({ name: '.notdef', advanceWidth: 650, path: new opentype.Path() }); const aPath = new opentype.Path(); aPath.moveTo(100, 0); aPath.lineTo(100, 700); // more drawing instructions... const aGlyph = new opentype.Glyph({ name: 'A', unicode: 65, advanceWidth: 650, path: aPath }); const glyphs = [notdefGlyph, aGlyph]; const font = new opentype.Font({ familyName: 'OpenTypeSans', styleName: 'Medium', unitsPerEm: 1000, ascender: 800, descender: -200, glyphs: glyphs}); font.download();

如果要检查字体,请使用font.toTables() 生成一个显示直接映射到二进制值的数据结构的对象。如果你想得到一个ArrayBuffer,使用font.toArrayBuffer()

字体对象

Font 表示加载的 OpenType 字体文件。它包含一组字形和方法,用于在绘图上下文中绘制文本,或获取表示文本的路径。

  • glyphs:字形对象的索引列表。
  • unitsPerEm: 字体中的 X/Y 坐标存储为整数。该值决定了网格的大小。常用值为 2048 和 4096。
  • ascender:距最高上升者基线的距离。以字体为单位,而不是像素。
  • descender:距最低下降基线的距离。以字体为单位,而不是像素。

Font.getPath(text, x, y, fontSize, options)

创建表示给定文本的路径。

  • x: 文本开头的水平位置。(默认值:0)
  • y:文本基线的垂直位置。(默认值:0)
  • fontSize: 以像素为单位的文本大小(默认值:72)。

选项是一个可选对象,包含:

  • kerning: 如果为 true 则考虑字距调整信息(默认值:true)
  • features:一个以OpenType 功能标签作为键的对象,以及一个用于启用每个功能的布尔值。目前仅支持连字功能“liga”和“rlig”(默认值:true)。
  • hinting: 如果 true 使用 TrueType 字体提示(如果可用)(默认值:false)。

注意:还有Font.getPaths相同的参数返回路径列表。

Font.draw(ctx, text, x, y, fontSize, options)

创建表示给定文本的路径。

  • ctx:二维绘图上下文,如 Canvas。
  • x: 文本开头的水平位置。(默认值:0)
  • y:文本基线的垂直位置。(默认值:0)
  • fontSize: 以像素为单位的文本大小(默认值:72)。

选项是一个可选对象,包含:

  • kerning: 如果为 true 则考虑字距调整信息(默认值:true)
  • features:一个以OpenType 功能标签作为键的对象,以及一个用于启用每个功能的布尔值。目前仅支持连字功能“liga”和“rlig”(默认值:true)。
  • hinting: 如果 true 使用 TrueType 字体提示(如果可用)(默认值:false)。

Font.drawPoints(ctx, text, x, y, fontSize, options)

绘制文本中所有字形的点。曲线上的点将以蓝色绘制,曲线外的点将以红色绘制。参数与Font.draw.

Font.drawMetrics(ctx, text, x, y, fontSize, options)

画线指示文本中所有字形的重要字体尺寸。黑线表示坐标系的原点(点 0,0)。蓝线表示字形边界框。绿线表示字形的前进宽度。

Font.stringToGlyphs(string)

将字符串转换为字形对象列表。请注意,由于可能的替换(例如连字),字符串和字形列表之间没有严格的一对一对应关系。返回的字形列表可以大于或小于给定字符串的长度。

Font.charToGlyph(char)

将字符转换为Glyph对象。如果找不到字形,则返回 null。请注意,此函数假定给定字符和字形之间存在一对一映射;对于复杂的脚本,情况可能并非如此。

Font.getKerningValue(leftGlyph, rightGlyph)

检索左字形(或其索引)和右字形(或其索引)之间的字距对的值。如果未找到字距对,则返回 0。在计算字形之间的间距时,字距值会添加到提前宽度中。

Font.getAdvanceWidth(text, fontSize, options)

返回文本的前进宽度。

这与 Path.getBoundingBox() 有所不同,例如,带后缀的空格会增加 advancewidth 但不会增加边界框,或者像书法 'f' 这样的悬垂字母可能具有比其 advance 宽度大得多的边界框。

这对应于 canvas2dContext.measureText(text).width

  • fontSize: 以像素为单位的文本大小(默认值:72)。
  • options: 请参见 Font.getPath

字形对象

一个字形是一个单独的标记,通常对应于一个字符。一些字形,例如连字,是许多字符的组合。字形是字体的基本构建块。

  • font: 对象的引用Font
  • name:字形名称(例如“Aring”、“five”)
  • unicode: 这个字形的主要 unicode 值(可以是undefined)。
  • unicodes: 此字形的 unicode 值列表(大多数情况下为 1,也可以为空)。
  • index: 字形的索引号。
  • advanceWidth: 绘制此字形时笔前进的宽度。
  • leftSideBearing:前一个字符到原点的水平距离(0, 0);负值表示悬垂
  • xMinyMinxMaxyMax:字形的边界框。
  • path:字形的原始、未缩放路径。

Glyph.getPath(x, y, fontSize)

获取一个缩放的字形 Path 对象,我们可以在绘图上下文中绘制。

  • x: 字形的水平位置。(默认值:0)
  • y:字形基线垂直位置。(默认值:0)
  • fontSize:以像素为单位的字体大小(默认值:72)。

Glyph.getBoundingBox()

计算给定字形的未缩放路径的最小边界框。返回opentype.BoundingBox包含 x1/y1/x2/y2 的对象。如果字形没有点(例如空格字符),则所有坐标都将为零。

Glyph.draw(ctx, x, y, fontSize)

在给定的上下文中绘制字形。

  • ctx:绘图上下文。
  • x: 字形的水平位置。(默认值:0)
  • y:字形基线垂直位置。(默认值:0)
  • fontSize:字体大小,以像素为单位(默认值:72)。

Glyph.drawPoints(ctx, x, y, fontSize)

在给定的上下文中绘制字形的点。曲线上的点将以蓝色绘制,曲线外的点将以红色绘制。参数与Glyph.draw.

Glyph.drawMetrics(ctx, x, y, fontSize)

画线指示文本中所有字形的重要字体尺寸。黑线表示坐标系的原点(点 0,0)。蓝线表示字形边界框。绿线表示字形的前进宽度。参数与Glyph.draw.

Glyph.toPathData(options)Glyph.toDOMElement(options)Glyph.toSVG(options)Glyph.fromSVG(pathData, options),

这些目前只是 Path 对象上对应对象的包装函数(请参阅那里的文档),但将来可能会扩展以传递 Glyph 数据以进行自动计算。

路径对象

一旦有了通过Font.getPath或 的路径Glyph.getPath,就可以使用它。

  • commands: 路径命令。每个命令都是一个包含类型和坐标的字典。有关示例,请参见下文。
  • fill: 的填充颜色PathColor 是一个代表CSS color 的字符串。(默认值:'黑色')
  • stroke: 的描边颜色PathColor 是一个代表CSS color 的字符串。(默认::null路径不会被描边)
  • strokeWidth: 的线条粗细Path。(默认值:1,但由于为strokenull,因此不会绘制笔划)

Path.draw(ctx)

在给定的 2D 上下文中绘制路径。这使用对象的fill,strokestrokeWidth属性Path

  • ctx:绘图上下文。

Path.getBoundingBox()

计算给定路径的最小边界框。返回opentype.BoundingBox包含 x1/y1/x2/y2 的对象。如果路径为空(例如空格字符),则所有坐标都将为零。

Path.toPathData(options)

将 Path 转换为一串路径数据指令。请参阅https://www.w3.org/TR/SVG/paths.html#PathData

  • options:
    • decimalPlaces:浮点值的小数位数。(默认值:2)
    • optimize:对路径数据应用一些优化,例如删除不必要/重复的命令(true/false,默认值:true)
    • flipY:是否翻转路径数据的Y轴,因为SVG和字体路径使用倒置的Y轴。(true:从边界框计算,false:禁用;默认值:true)
    • flipYBase:基础翻转计算的基础值。您可能希望根据字体的升序值和降序值来计算它。(默认:从路径数据的边界框自动计算)

Path.toSVG(options)

将路径转换为 ​​SVG <path> 元素,作为字符串。

  • options: 见 Path.toPathData

Path.fromSVG(pathData, options)

从 SVG 路径数据中检索路径。覆盖现有路径的路径数据

const path = new Path(); path.fromSVG('M0 0');

或直接创建新路径:

const path = Path.fromSVG('M0 0');
  • pathData:一串 SVG 路径命令,或者(仅在浏览器上下文中)一个SVGPathElement
  • options:
    • decimalPlacesoptimizeflipYflipYBase: 见 Path.toPathData
    • scale:应用于所有命令坐标的缩放值(默认值:1)
    • xy:应用于 x 或 y 轴上所有命令坐标的偏移量(默认值:0)

路径命令

  • 移动到:移动到新位置。这创建了一个新的轮廓。例子:{type: 'M', x: 100, y: 200}
  • Line To:从前一个位置到给定坐标画一条线。例子:{type: 'L', x: 100, y: 200}
  • Curve To : 绘制一条从当前位置到给定坐标的贝塞尔曲线。例子:{type: 'C', x1: 0, y1: 50, x2: 100, y2: 200, x: 100, y: 200}
  • Quad To:绘制从当前位置到给定坐标的二次贝塞尔曲线。例子:{type: 'Q', x1: 0, y1: 50, x: 100, y: 200}
  • 关闭:关闭路径。如果描边,这将从轮廓的第一个点到最后一个点画一条线。例子:{type: 'Z'}
浏览 7
点赞
评论
收藏
分享

手机扫一扫分享

编辑
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

编辑
举报