npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@evenrealities/pretext

v0.1.4

Published

Pixel-accurate font measurement library for Even Realities G2 glasses

Downloads

895

Readme

@evenrealities/pretext

Pixel-accurate font measurement library for Even Realities G2 smart glasses (EvenHub specifically). Predicts exact text layout dimensions matching the LVGL rendering engine used in the glasses firmware, so you can size UI containers precisely without guesswork. Inspired by pretext.

Note: Measurements have been manually compared and verified against the actual glasses rendering for most cases, but edge cases may exist where predictions differ from the firmware output. In particular, results may be off for characters that are not present in the firmware fonts, since the firmware and this library may handle missing glyphs differently in some cases.

Features

  • Text measurement — multi-line layout prediction with word wrapping
  • Kerning — per-character pair adjustments using the firmware's exact formula
  • Wide character support — Latin, Cyrillic, Greek, CJK (Chinese, Japanese, Korean), Bopomofo

Installation

npm install @evenrealities/pretext

API

getTextWidth(text: string): number

Returns the single-line pixel width of a string, with kerning applied.

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

const width = getTextWidth('Hello, world!');
// => 79 (pixels)

measureTextWrap(text: string, maxWidth: number): MeasureTextResult

Measures multi-line text layout within the given pixel width. Handles word wrapping at spaces and hyphens, CJK boundary breaks, explicit newlines, and hard breaks when no break opportunity exists.

maxWidth should be the inner content width — if your container has padding or borders, subtract them before calling. The returned height is pure text height; add your own padding/border to get the final container size.

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

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

// With padding + border:
const pad = 8, border = 2;
const inner = 300 - 2 * (pad + border);  // 280px available for text
const m = measureTextWrap('Hello world', inner);
const containerHeight = m.height + 2 * (pad + border);

Parameters:

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | text | string | — | The string to measure | | maxWidth | number | — | Available width for text in pixels (subtract padding/border first) |

Return type:

| Field | Type | Description | |-------|------|-------------| | lineCount | number | Number of lines after wrapping | | height | number | Total text height in pixels (lineCount * 27) | | lineWidths | number[] | Pixel width of each line |

pxTruncate(text: string, maxPx: number): string

Truncates a string to fit within a pixel budget, appending '...' if needed. Returns the original string if it already fits. Uses binary search for efficient fitting and is codepoint-aware (won't break surrogate pairs like emoji).

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

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

getAdvW(cp: number): number

Returns the raw advance width of a codepoint in 1/16px units (no kerning, no rounding). Follows the font fallback chain: evenroster -> evenroster_crylgrek -> cn. Primarily useful for debugging or building custom measurement logic.

Display Reference

The G2 glasses have a 576 x 288 pixel display rendered by LVGL with a fixed line height of 27px.

How It Works

The library embeds extracted font metrics from the LVGL C font files used in the G2 firmware. It replicates the firmware's text shaping pipeline:

  1. Glyph lookup — resolves each codepoint through a three-font fallback chain (Latin -> Cyrillic/Greek -> CJK)
  2. Kerning — applies pair adjustments using the firmware formula: (kern_value * kern_scale) >> 4
  3. Per-glyph rounding — each advance width is rounded to pixels individually ((adv + kern + 8) >> 4), matching LVGL's behavior exactly
  4. Line breaking — breaks at spaces, hyphens, and CJK boundaries, with hard breaks as fallback

Note: if the firmware font metrics change, this library must be updated to match.

Changelog

0.1.4

  • add Emoji font

0.1.3

  • Breaking: Removed containerPadding parameter from measureTextWrap. The function now measures pure text — callers should subtract padding/border from maxWidth before calling and add it back to the returned height. This avoids the inconsistency where padding was handled internally but border width was not.
  • Breaking: Removed measureList. Its logic was trivial (item count × 40px, plus basic width comparisons) and callers can replicate it inline with getTextWidth.

0.1.2

  • Initial public release with getTextWidth, measureTextWrap, pxTruncate, measureList, and getAdvW.