桌面应用图形学【免费下载链接】fontforgeFree (libre) font editor for Windows, Mac OS X and GNULinux项目地址https://gitcode.com/gh_mirrors/fo/fontforge点击查看免费下载Point 菜单Point Menu是 FontForge 轮廓字符视图Outline Character View中面向单个点与样条spline级编辑的核心命令集涵盖点类型切换Curve / Corner / Tangent、闭合路径起点重设、TrueType 隐式点控制、直线/圆弧化、样条插点、锚点添加与 Type3 裁剪路径等操作。读完本文你将掌握该菜单每个条目的适用场景、精确操作前提与底层实现原理并能在日常字形修整中直接落地使用。Point 菜单的适用范围与菜单结构Point 菜单只在轮廓字符视图中可用官方文档原话 This menu is only available in the Outline Character View。它既可以作为主菜单栏的 Point 菜单出现也可以在选择点后通过右键弹出见 fontforgeexe/cvpalettes.c 中的CVToolsPopupL3450 起菜单项通过CVMenuPointType、CVMerge等回调触发。从源码 fontforgeexe/charview.c 中定义的ptlist菜单表L11315-L11341可以看到完整菜单项按分隔线划分依次为分组菜单项点类型Curve、HVCurve、Corner、Tangent轮廓起点Make FirstTrueType 插值Can Be Interpolated、Cant Be Interpolated、Center Between Control Points锚点Add Anchor验证Acceptable Extrema样条操作Make Line、Make Arc、Insert Point On Spline At...、Name Point、Name Contour、Make Clip Path子菜单Tools工具列表当字体处于 Spiro 模式inspiro且系统带 libspiro时菜单整体切换为spiroptlistL11343-L11359点类型变为 G4 Curve、G2 Curve、Corner、Left Constraint、Right Constraint并保留 Make First、Add Anchor、Name Point、Name Contour 与 Tools。切换逻辑见CVMenuPointTypeL8705-L8711与cv_ptlistcheckL8742 起菜单项 ID 定义在 fontforgeexe/cv_mids.hCV_MID_Corner 2300 等。点类型切换Curve / Corner / Tangent条目行为Curve若所有选中点均为 Curve 点条目显示勾选选择该条目会把所有选中点改为 Curve 点。Corner若所有选中点均为 Corner 点条目显示勾选选择该条目会把所有选中点改为 Corner 点。Tangent若所有选中点均为 Tangent 点条目显示勾选选择该条目会把所有选中点改为 Tangent 点。注意勾选状态的判定是全选点同类型才勾选源码cv_ptlistcheckL8758-L8808逐个统计选中点的pointtype若所有选中点类型一致则checked (type pt_corner/pt_curve/pt_tangent)否则勾选被取消同时当没有任何选中点时菜单项被禁用disabled type-2。源码实现核心回调_CVMenuPointTypefontforgeexe/charview.c L8655-L8677做三件事根据菜单 ID 把目标类型映射为pt_corner/pt_tangent/pt_curve/pt_hvcurve遍历当前绘制层的所有SplinePointList对每个选中点调用SPChangePointType(sp, pointtype)修改类型调用CVCharChangedUpdate刷新视图。菜单表ptlist中还包含了文档未单独列出但真实存在的HVCurve条目L11317图标pointshvcurve.png它同样通过CVMenuPointType分发用于将点转为水平/垂直控制点类型。Spiro 模式下的点类型切换则走_CVMenuSpiroPointTypeL8679-L8702目标类型映射为SPIRO_G4/SPIRO_G2/SPIRO_CORNER/SPIRO_LEFT/SPIRO_RIGHT修改后调用SSRegenerateFromSpiros从 Spiro 控制点重新生成样条。Make First重新设定闭合路径的起点一个闭合路径中的每个点都以环状链表连接其中有一个首点first point它在轮廓起始位置、某些导出与指令处理中具有特殊意义。Make First的生效条件非常严格恰好选中一个点该点位于闭合路径上sel-first-prev ! NULL开路径无prev该点不是当前路径的首点。满足条件时该点即成为路径的新首点。源码_CVMenuMakeFirstfontforgeexe/charview.c L9588-L9612在检查anypoints!1 || sel-first-prevNULL || sel-firstselpt后直接执行sel-first sel-last selpt完成首点轮换菜单勾选检查逻辑cv_ptlistcheckL8848-L8850中CV_MID_MakeFirst的禁用条件与此完全一致cnt!1 || sel-first-prevNULL || sel-firstselpt。Spiro 模式对应的CV_MID_SpiroMakeFirst则以恰好一个 Spiro 点且无开放轮廓为启用前提通过轮转spiros数组实现。TrueType 隐式点Can Be Interpolated / Cant Be Interpolated背景TrueType 的插值省略机制编辑 TrueType 曲线时一个 on-curve 点如果恰好位于其两个控制点control points的正中间那么它可以从输出字体存储的点列表中省略编译 TrueType 时由插值机制隐式重建。这能让字库文件略微变小而且通常是有益的——所以默认状态下该点可以被插值Can Be Interpolated 条目被勾选。什么时候必须关闭插值插值的代价是一旦点被插值省略它就无法在指令instructions或参考点匹配reference point matching中被引用。因此在极少数需要该点参与 hinting 指令或参考点对齐的场景必须显式关闭插值选择Cant Be Interpolated强制该点写入输出字体。源码实现_CVMenuImplicitfontforgeexe/charview.c L8713-L8734通过遍历选中点设置spline-to-dontinterpolate dontinterpolate布尔标志CV_MID_NoImplicitPt对应dontinterpolatetrue。注意函数开头有一个前置检查if ( !cv-b.layerheads[cv-b.drawmode]-order2 ) return;—— 即该功能只在二阶order2TrueType 风格层上生效三阶 PostScript 层调用会被直接忽略这解释了为何文档将该命令限定在 TrueType 曲线编辑场景。Add Anchor Point...添加锚点Add Anchor Point...为当前字形添加一个新的锚点anchor point窗口中的最后一次点击位置将作为新锚点的默认位置。锚点是 GPOS 定位机制的基础通过锚点可以实现连字cursive、标点对基字mark to base、标点对连字mark to ligature、标点对标点mark to mark等多种字形附着定位详见文档 doc/sphinx/index.rst 的 Anchor Points and Classes 概述L878 起。命令执行路径CVAddAnchorfontforgeexe/charview.c L10095-L10109先用AnchorClassUnused检查是否已有未使用的锚点类若没有则弹出输入框通过SFFindOrAddAnchorClass创建锚点类最后调用ApGetInfo(cv, NULL)打开锚点信息对话框供你填写锚点名称、类型基线、连字附着、标点附着等与精确坐标。锚点信息对话框的完整字段说明见 doc/sphinx/ui/dialogs/getinfo.rst 的 Anchor Points Info 一节L123 起其中明确提到锚点也可以直接通过 Point 菜单的 Add Anchor 命令创建。快捷键方面doc/sphinx/ui/misc/HotKeys.rst 标注Ctrl-0即触发Add Anchor Point...L89。Acceptable Extrema允许样条存在极值极值extrema即轮廓上 X 或 Y 方向达到最大/最小值的点是字体验证器检查的常见对象。Acceptable Extrema用来告诉验证器当前样条上出现极值是可接受的无需报错。操作方式先选中样条的两个端点样条由其两个端点的连线区间界定再触发该命令。源码CVMenuAcceptableExtremafontforgeexe/charview.c L8639-L8653遍历所有样条凡s-from-selected s-to-selected的样条其acceptableextrema标志被翻转s-acceptableextrema !s-acceptableextrema勾选检查L8786-L8792则在所有选中样条标志一致时显示勾选状态。菜单定义可见该条目为可勾选toggle项L11330图标menuempty.png。Make Line将样条变为直线Make Line根据选中情况提供三种行为由_CVMenuMakeLine实现fontforge/splinechar.c L2466-L2565选中两个相邻点把两点之间的样条改为直线段。源码中对非弧模式会额外执行sp-nextcp sp-me; sp-next-to-prevcp sp-next-to-me; sp-next-to-noprevcp true即把两端的控制点折叠到点上并标记无前一控制点再SplineRefigure重算样条。选中两个点且它们分别是各自开放轮廓的端点用一条直线把两条开放轮廓连接合并起来。源码先收集恰好两个选中点校验双方均为端点sp1-prevNULL || sp1-nextNULL且互不相邻随后调用MakeShape生成连线必要时通过SplineSetReverse调整轮廓方向并合并两个SplinePointList。选中单个点且没有相邻选中点把该点的两个控制点移到点自身位置等价于文档所述 make its control points be on top of the point将曲线压平为该点的直线衔接。命令由CVMenuMakeLinefontforgeexe/charview.c L9657-L9660分发同时服务 Make Line 与 Make Arc 两个菜单项。Make Arc以椭圆弧连接两点Make Arc与 Make Line 的操作前提一致选中两个相邻点则把其间样条变为椭圆弧选中两个开放轮廓的端点则用椭圆弧连接两条轮廓。弧的求解是约束拟合问题FontForge 需要选择一条同时经过两个选中点、且与两点的切线斜率相切的椭圆。文档明确指出这组条件不足以唯一确定椭圆确定一个椭圆通常需要三个点和两条切线因此解往往是无穷多个FontForge 未必会选中你心中预设的那个椭圆并且某些输入约束组合根本无法被任何椭圆满足。为此 FontForge 采用了两阶段搜索策略先尝试寻找这样的椭圆其中一个选中点位于椭圆的某个轴axis上找不到时再做更一般化的搜索。以上描述对应_CVMenuMakeLine传入do_arctrue后由MakeShape完成的椭圆拟合流程fontforge/splinechar.c L2466 起。值得一提的隐藏功能按住Alt键再选择该菜单项FontForge 会把完整椭圆复制一份放进背景层background layer——文档原话说明这是当初调试用的功能但因挺酷而被保留。源码中对应e-u.mouse.state ksm_meta被作为ellipse_to_back参数传入L9659。Insert Point on Spline At...在样条上定点插入先在轮廓上选中某条样条的两个端点再触发Insert Point on Spline At...弹出对话框即可在样条上按指定坐标插入一个新点选择X单选与数值框在样条上找到 X 坐标等于给定值的位置插入点选择Y单选与数值框在样条上找到 Y 坐标等于给定值的位置插入点。对话框标题为 Insert a point on the given spline at either...源码_CVMenuInsertPtfontforgeexe/charview.c L9849-L9990。其计算流程回调IOSA_OKL9758-L9807具有代表性用CubicSolve(iosa-s-splines[which], val, ts)求解三次样条上达到该坐标的参数ts[]若无解则报 Out of RangeThe spline does not reach %g调用SplineBisect在该参数位置二分插入新点并用SplinePointCategorize重新归类点类型把新点精确移动到目标坐标同步平移其前后控制点再对相邻样条SplineRefigure重算若三次方程存在多个解则循环处理每个交点直到全部插入完成。代码约束还表明该命令一次只能作用于一条样条找到第二条候选样条时直接返回。Center Between Control Points创建可省略的 TrueType 点TrueType 中on-curve 点若正位于其两个控制点中间导出时该点可被省略与 Can Be Interpolated 共享同一机制。Center Between Control Points就是帮你更省力地制造出这种居中状态。源码_CVCenterCPfontforgeexe/charview.c L9997-L10053会根据选中点当前状态从三种修正策略enum movething中择一执行使me与控制点满足me (nextcp prevcp)/2mt_pt直接移动点本身到两个控制点的中点mt_ncp移动下一控制点使其相对点对称于前一控制点即让点保持不动、由控制点来迁就居中对二阶样条还会同步更新相邻点的prevcp并清除其noprevcp标记mt_pcp对称移动前一控制点逻辑与上相反。每个被处理的点都要求prev!NULL next!NULL且两侧控制点都存在!noprevcp !nonextcp处理前后调用SplineRefigure/SplineRefigureFixup保持曲线形状连贯。Name Contour为轮廓命名辅助线友好Name Contour允许给一条轮廓附加助记名称。该特性主要面向Guide line参考线层与背景Background层设计你可以给辅助线起诸如 X-Height、Cap-Height 之类的可读名字便于后续识别与脚本引用。源码_CVMenuNameContourfontforgeexe/charview.c L9692-L9739先确认选中的点全部属于同一条轮廓onlysel唯一性检查否则直接返回然后弹出gwwv_ask_string输入框把结果写入onlysel-contour_name字段空字符串则清除名字。菜单表中与之相邻的Name PointL11335则是给单个点命名_CVMenuNamePointL9662-L9677写入sp-name可视为同一命名体系在点层面的延伸。Make Clip Path设置 Type3 裁剪路径Make Clip Path仅对Type3 字体有意义。其行为将当前字形中选中的轮廓设为该层的裁剪路径clipping path若没有任何选中轮廓则清除裁剪路径is_clip_path标志置假。裁剪路径的语义在 doc/sphinx/ui/dialogs/multilayer.rst 的 Clipping Path 一节L90-L111有完整解释Type3 字体的每个层可以拥有自己的裁剪路径——只有落在裁剪路径内部的内容才会被绘制路径本身不参与绘制。该文档中同时给出了用Points-Make Clip Path修改裁剪路径的指引L108-L111。源码实现CVMakeClipPathfontforgeexe/charview.c L10060-L10088遍历当前绘制层的所有轮廓检测其中是否包含选中点据此把ss-is_clip_path置为对应布尔值并在发生变化时调用CVCharChangedUpdate刷新。补充右键菜单与快捷键速查除主菜单外Point 系列操作在选择点后的右键弹出菜单中也有等价入口。CVToolsPopupfontforgeexe/cvpalettes.c L3450-L3599在无选中点时提供工具列表Pointer、Magnify 等在有选中点时提供 Get Info...、Open Reference、Add Anchor以及点类型切换Curve/HVCurve/Corner/Tangent或 Spiro 模式下的 G4/G2/Corner/Left/Right Constraint、Merge、Merge to Line、Align Points 等命令MIDL_MakeLine、MIDL_MakeArc、MIDL_InsertPtOnSplineAt、MIDL_NamePoint、MIDL_NameContour均映射到与主菜单相同的回调L3425-L3445。常用快捷键doc/sphinx/ui/misc/HotKeys.rst快捷键命令Ctrl-0Add Anchor Point...L89实践中建议把本文涉及的菜单项与 doc/sphinx/ui/menus/pointmenu.rst 原文对照阅读菜单中多数命令的底层几何操作MakeShape、SplineBisect、SplineRefigure、SPChangePointType都集中在 fontforge/splinechar.c 与 fontforgeexe/charview.c 中是进一步研究点/样条编辑算法的入口。赞分享桌面应用图形学【免费下载链接】fontforgeFree (libre) font editor for Windows, Mac OS X and GNULinux项目地址https://gitcode.com/gh_mirrors/fo/fontforge点击查看免费下载相关推荐FontForge Element 菜单完全指南字形信息、样式变换、位图管理与轮廓运算FontForge Element 菜单完全指南字形信息、样式变换、位图管理与轮廓运算 导读 Element 元素菜单是 FontForge 中针对 字形桌面应用图形学FontForge 字体与字形创建实战从新建字体到逐点描绘轮廓的完整工作流FontForge 字体与字形创建实战从新建字体到逐点描绘轮廓的完整工作流 导读本篇教程聚焦 FontForge 中最基础也最核心的创作链路——新建字体、设桌面应用图形学FontForge 字形变体与锚点标记完全指南从 GSUB 变体替换到 GPOS 锚点定位FontForge 字形变体与锚点标记完全指南从 GSUB 变体替换到 GPOS 锚点定位 本篇技术指南围绕 FontForge 教程的经典章节 editex桌面应用图形学上一篇cartographer地图拼接技术多场景地图融合下一篇DiffTest差异对象处理的单元测试实践指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考