文字宽高计算
大约 3 分钟
文字宽高计算
自动成图时常需先知道文字排版后占多大,才能算表格行高、列宽或摆块位置。WebCAD 提供本地 WASM 与服务端 ODA 两种测量方式。
在线示例
| 示例 | 描述 | 链接 |
|---|---|---|
| 文字宽高计算 | measureTextLocal / measureTexts 本地与服务端对比 | 在线演示{target="_blank"} |
| 测量文字宽高(模板) | 同一批数据本地与服务端各测一次 | 在线演示{target="_blank"} |
API 一览
| API | 说明 |
|---|---|
measureTextLocal(item) | 同步本地测量一条;WASM 未就绪或无字体时返回 null |
measureTextsLocal(items) | 同步批量本地测量 |
measureTextsOnServer(mapid, version, items) | 指定模板批量服务端测量 |
measureTexts(items, options?) | 统一入口;默认 mode: 'auto' 按来源分流 |
const {
measureTextLocal,
measureTexts,
measureTextsOnServer
} = vjcad;本地测量
不入图、不等渲染帧,直接调 WASM 排版接口读 metrics:
const size = measureTextLocal({
type: 'TEXT',
text: '唯杰CAD',
height: 8,
styleName: 'Standard'
});
if (!size) {
// WASM 未初始化,或 MainView.fonts 尚未加载任何字体
return;
}
console.log(size.width, size.height, size.bounds, size.isFallbackFont);多行文字需给换行列宽 width(与 MTEXT 一致):
const m = measureTextLocal({
type: 'MTEXT',
text: '多行文字会按列宽自动换行',
height: 3,
width: 120
});按宽度依次摆放(不必先画再量)
const tags = ['图层', '线型', '颜色'];
const sizes = await measureTexts(
tags.map(text => ({ type: 'TEXT', text, height: 8 })),
{ mode: 'local' }
);
let x = 0;
tags.forEach((text, i) => {
const w = sizes[i]?.width ?? 0;
// 用 w 决定下一列起点…
x += w + 4;
});统一入口 measureTexts
const results = await measureTexts([
// 带克隆来源 → auto 模式下走服务端(模板真实字体)
{
text: '粉质粘土:褐黄色,可塑',
height: 2.5,
width: 30,
cloneSource: 'clone_96BA_template_sect_v1'
},
// 无克隆来源 → 本地 WASM
{ text: '普通文字', height: 3, type: 'TEXT', styleName: 'Standard' }
], {
mode: 'auto' // 'auto' | 'local' | 'server'
});
const [first] = results;
console.log(first?.width, first?.height, first?.geomHeight, first?.source);选项 ITextMeasureOptions
| 字段 | 说明 |
|---|---|
mode | 'auto'(默认)/ 'local' / 'server' |
mapid | mode: 'server' 时的默认模板地图 ID |
version | 默认模板版本,默认 'v1' |
请求项常用字段
| 字段 | 说明 |
|---|---|
type | 'TEXT' | 'MTEXT',默认 'MTEXT' |
text | 文字内容;MTEXT 可带 \P、\H 等格式码 |
height | 字高 |
width | MTEXT 换行列宽;0 表示不换行 |
styleName | 文字样式名(本地测时用于解析字体文件) |
widthFactor / obliqueAngle | 仅 TEXT |
cloneSource | 如 clone_96BA 或 clone_96BA_template_sect_v1;auto 时走服务端 |
templateMapId / templateVersion | 显式指定模板,也可不走 cloneSource |
handle | 服务端:模板中原型实体的 DWG handle |
fontFileName | 本地测量强制指定字体文件名 |
返回字段
| 字段 | 说明 |
|---|---|
width / height | 排版后的真实宽高;MTEXT 的 height 为逐行累加的逻辑高度 |
geomWidth / geomHeight | 内容包围盒尺寸;要让图元紧贴文字用这个 |
bounds | [minX, minY, maxX, maxY](相对插入点) |
source | 'local' 或 'server' |
isFallbackFont | 本地测量时指定字体被回退,结果仅供参考 |
测不了的位置返回 null,不会中断整批。
服务端测量
模板 DWG 里的字体(仿宋、宋体等)通常不在前端 MainView.fonts 中。本地 resolveFontForName 会静默回退到默认字体,中文字宽虽接近,但西文与标点差异会改变换行,多行高度跟着偏。服务端用 ODA 在真实 DWG 上排版(OdDbMText::actualWidth() / actualHeight()),结果与导出 DWG 一致。
const server = await measureTextsOnServer('template_sect', 'v1', [
{ handle: '96BA', text: '粉质粘土', height: 2.5, width: 30 }
]);- 需要后台支持
measureText命令 measureTexts的服务端部分按模板分组,每组合并成一次请求
与模板绘制的关系
从模板克隆的文字若要按导出效果算行高,应带 cloneSource(或 templateMapId)走服务端测量。详见 模板绘制。
注意事项
- 本地测量依赖 WASM 已初始化,且至少加载过一种字体(
MainView的fonts) isFallbackFont === true时不要当精确值用于出图排版- 服务端测量失败时对应项为
null,可回退本地并提示偏差风险