font-measurement について
font-measurementは、Even Realities G2スマートグラス向けの画面を開発する人のためのTypeScriptテキスト計測ライブラリです。グラスのLVGLレンダラーに基づく寸法で、テキストの計測や切り詰めを行います。
主な機能
- 011行テキストのピクセル幅計測
- 02折り返し後のレイアウト計測
- 03ピクセル幅に合わせたテキスト切り詰め
- 04コードポイントの送り幅取得
活用シーン
- 01G2画面のテキストコンテナ寸法調整
- 02余白や枠線を含む折り返し確認
- 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
文字列の1行あたりのピクセル幅を返します(カーニング適用、折り返しなし)。
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);
パラメーター:
| パラメーター | 型 | デフォルト | 説明 |
|---|---|---|---|
text | string | — | 測定する文字列 |
maxWidth | number | — | テキストに使用できるピクセル単位の幅(パディング/ボーダーを差し引く) |
戻り値:
| フィールド | 型 | 説明 |
|---|---|---|
lineCount | number | 折り返し後の行数 |
height | number | テキスト全体の高さ(lineCount * 27) |
lineWidths | number[] | 折り返し後の各行のピクセル幅 |
pxTruncate(text: string, maxPx: number): string
文字列をピクセル幅の上限に収まるように切り詰め、必要に応じて '...' を追加します。すでに収まっている場合は、元の文字列をそのまま返します。二分探索を使用し、絵文字やサロゲートペアも正しく処理します。
import { pxTruncate } from '@evenrealities/pretext';
const label = pxTruncate('Hello, world!', 50); // => 'Hell...'
const fits = pxTruncate('Hi', 50); // => 'Hi'
パラメーター:
| パラメーター | 型 | 説明 |
|---|---|---|
text | string | 切り詰める文字列 |
maxPx | number | ピクセル単位の最大幅 |
戻り値: 収まる場合は元の文字列、収まらない場合は末尾に '...' が付いた切り詰め後の文字列です。
注: この関数は1行のテキスト専用です。複数行のテキストでは、各行を個別に切り詰めてください。
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を指定すると、4辺すべてのテキスト領域がNピクセル狭くなりますborderWidth: Nを指定すると、4辺すべてのテキスト領域が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 コンテナーのサイズを決める際は、次の点に従ってください。
- コンテナーを作成する前に、必ずこのライブラリを使用してテキストの寸法を予測してください。ピクセルサイズを推測しないでください。
- 行の高さは 27px です。行数を掛けてテキストコンテナーの高さを算出してください。
- リスト項目の高さは 40px です。項目数を掛け、
2 * paddingを加えてリストコンテナーの高さを算出してください。 - 最大表示サイズは 576 x 288 です。コンテナーがこの範囲内に収まるようにしてください。
- glasses-ui スキルと組み合わせる場合は、
measureTextWrapの結果を使用して、コンテナーのwidthとheightプロパティを正確に設定してください。 - コンテナーに
paddingLengthまたはborderWidthがある場合は、テキストを測定する前に、これらの値をコンテナーの寸法から差し引いてください。これを怠ると、コンテンツがオーバーフローしてスクロールバーが表示されます。上記の「パディングとボーダーの考慮」を参照してください。
タスク
$ARGUMENTS