mcpField
F
font-measurement

font-measurement

github.com/even-realities设计与 UI79136 次安装1 周前更新
代码仓库

关于 font-measurement

font-measurement 是面向 Even Realities G2 智能眼镜界面开发者的 TypeScript 文本测量库。它依据眼镜 LVGL 渲染器的尺寸规则测量和截断文本。

主要功能

  1. 01测量单行文本像素宽度
  2. 02测量换行后的文本布局
  3. 03按像素预算截断文本
  4. 04查询字符原始前进宽度

适用场景

  1. 01调整 G2 屏幕文本容器尺寸
  2. 02检查含内边距和边框的换行
  3. 03将标签截断至像素限制

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/even-realities/everything-evenhub --skill font-measurement

安装后在 Claude Code 中输入/font-measurement确认已加载。

详细介绍

even-pretext:字体测量库

为 Even Realities G2 智能眼镜提供像素级精准的文本测量。可预测与眼镜固件中 LVGL 渲染引擎完全一致的布局尺寸。

注意: 对于固件字体中不存在的字符,结果可能会有偏差,因为在某些情况下,固件和此库对缺失字形的处理方式可能不同。

安装

npm install @evenrealities/pretext

显示常量

  • 屏幕:576 x 288 像素
  • 行高:27px(固定)
  • 列表项高度:40px(固定)
  • 列表项水平内边距:每侧 12px

API

所有函数均从 @evenrealities/pretext 导出。

getTextWidth(text: string): number

返回字符串的单行像素宽度(包含字距调整,不换行)。

import { getTextWidth } from '@evenrealities/pretext';
const width = getTextWidth('Hello, world!'); // => 79
measureTextWrap(text: string, maxWidth: number): MeasureTextResult

测量带有单词换行的多行文本布局。maxWidth 应为内容区域的内宽——调用前请减去内边距和边框。返回的 height 是纯文本高度。

import { measureTextWrap } from '@evenrealities/pretext';

const result = measureTextWrap('The quick brown fox jumps over the lazy dog', 200);
// => { lineCount: 2, height: 54, lineWidths: [192, 96] }

// With padding + border — caller handles the math:
const pad = 8, border = 2;
const m = measureTextWrap('Hello world', 300 - 2 * (pad + border));
const containerHeight = m.height + 2 * (pad + border);

参数:

参数类型默认值描述
textstring—要测量的字符串
maxWidthnumber—文本可用宽度,单位为像素(减去内边距/边框)

返回值:

字段类型描述
lineCountnumber换行后的行数
heightnumber文本总高度(lineCount * 27)
lineWidthsnumber[]每个换行后文本行的像素宽度
pxTruncate(text: string, maxPx: number): string

将字符串截短至指定像素宽度,并在需要时追加 '...'。如果原字符串已符合宽度限制,则原样返回。使用二分查找,并能正确处理 emoji/代理对。

import { pxTruncate } from '@evenrealities/pretext';

const label = pxTruncate('Hello, world!', 50); // => 'Hell...'
const fits  = pxTruncate('Hi', 50);            // => 'Hi'

参数:

参数类型描述
textstring要截短的字符串
maxPxnumber最大宽度,单位为像素

返回值: 如果原字符串符合宽度限制,则返回原字符串;否则返回以 '...' 结尾的截短字符串。

注意: 此函数仅适用于单行文本。对于多行文本,请逐行截短。

getAdvW(cp: number): number

返回码点的原始前进宽度,单位为 1/16px(不含字距调整,不进行舍入)。适用于调试或自定义测量逻辑。

计入内边距和边框

当 TextContainerProperty 设置了 paddingLength 或 borderWidth 时,SDK 的 LVGL 渲染器会从容器内部的可用文本区域中减去这些值。如果根据容器的完整宽度/高度测量文本,内容将溢出并出现滚动条。

内边距和边框如何影响文本区域
Container (width × height)
┌─ border (borderWidth pixels) ─────────────────────┐
│ ┌─ padding (paddingLength pixels) ──────────────┐ │
│ │                                                │ │
│ │   Text renders here                            │ │
│ │   innerWidth  = width  - 2*padding - 2*border  │ │
│ │   innerHeight = height - 2*padding - 2*border  │ │
│ │                                                │ │
│ └────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────┘
规则
  • paddingLength: N 会将四边的文本区域各缩小 N 像素
  • borderWidth: N 会将四边的文本区域各缩小 N 像素(边框绘制在容器内部)
  • 两者会叠加:每侧的总内缩量 = paddingLength + borderWidth
  • 如果两者均未设置,文本将使用容器的完整宽度/高度进行渲染
测量带有内边距/边框的容器文本
import { measureTextWrap } from '@evenrealities/pretext';

const containerW = 560;
const containerH = 258;
const padding = 8;  // paddingLength
const border = 1;   // borderWidth

const inset = padding + border;
const innerW = containerW - 2 * inset;
const innerH = containerH - 2 * inset;
const maxLines = Math.floor(innerH / 27);

// Measure and truncate against the INNER dimensions
const m = measureTextWrap(text, innerW);
if (m.lineCount > maxLines) {
  text = truncateToFitLines(text, innerW, maxLines);
}
常见错误
// WRONG — measures against container width, ignores padding/border
const m = measureTextWrap(text, 560);

// RIGHT — subtracts padding and border from both sides
const m = measureTextWrap(text, 560 - 2 * (padding + border));

常见模式

将文本容器调整为适配其内容
import { measureTextWrap } from '@evenrealities/pretext';

const containerWidth = 300;
const padding = 8;
const innerW = containerWidth - 2 * padding;
const result = measureTextWrap(myText, innerW);
const containerHeight = result.height + 2 * padding;
// Use Math.max(...result.lineWidths) + 2 * padding for tight container width
截短文本以适配容器
import { pxTruncate } from '@evenrealities/pretext';

// Single-line truncation
const label = pxTruncate(longText, containerWidth);

// Multiline: truncate each line individually
import { measureTextWrap } from '@evenrealities/pretext';
const { lineWidths } = measureTextWrap(longText, containerWidth);
// If the last line is too long after wrapping, truncate it

说明

在使用此库为 Even Realities 眼镜调整 UI 容器尺寸时:

  1. 创建容器前,务必使用此库预测文本尺寸。不要猜测像素尺寸。
  2. 行高为 27px——将行高乘以行数,得到文本容器高度。
  3. 列表项高度为 40px——将其乘以项目数量,再加上 2 * padding,得到列表容器高度。
  4. **最大显示尺寸为 576 x 288。**确保容器尺寸在此范围内。
  5. 与 glasses-ui 技能配合使用时,请使用 measureTextWrap 的结果精确设置容器的 width 和 height 属性。
  6. **当容器有 paddingLength 或 borderWidth 时,**测量文本前,请从容器尺寸中减去这些值。否则内容会溢出并出现滚动条。请参阅上文“计算内边距和边框”。

任务

$ARGUMENTS

评论

支持 Markdown