@eigenpal/docx-editor-core/layout-bridge/measuring
Text Measurement Module
Provides text measurement utilities for the layout engine. Uses Canvas API for accurate, cached measurements.
Functions (40)
buildFontStringfunctionSource ↗
Build a CSS font string from styling properties
Font sizes are in points and need to be converted to pixels for canvas. 1pt = 96/72 px ≈ 1.333px at standard web DPI.
Uses the font resolver to get category-appropriate fallback stacks (serif fonts get serif fallbacks, sans-serif get sans-serif, etc.) matching the same stacks used in rendering for consistent measurements.
declare function buildFontString(style: FontStyle): string;buildFontString( fontFamily: "Arial", fontSize: 12, bold: true ) // Returns: "bold 16px Arial, Arimo, Helvetica, sans-serif" (12pt = 16px)clampFloatingWrapMarginsfunctionSource ↗
When a float's wrap margins consume the entire content width (or more), there is no horizontal strip beside it for body text. Word renders the following lines at full content width instead of squeezing them into a 1-pixel column. Unchecked margins from near-full-width tables/images can exceed contentWidth and collapse every line to ~1 glyph (the "single character per line after a wide floating table" bug).
Returned margins are zeroed when: - either side alone is = contentWidth (no strip on that side at all), or - their sum is = contentWidth (no strip exists between the two sides).
declare function clampFloatingWrapMargins(leftMargin: number, rightMargin: number, contentWidth: number): {
leftMargin: number;
rightMargin: number;
};clearAllCachesfunctionSource ↗
Clear all measurement caches Call when fonts change, page width changes, or for testing
declare function clearAllCaches(): void;clearFontMetricsCachefunctionSource ↗
Clear the font metrics cache
declare function clearFontMetricsCache(): void;clearParagraphMeasureCachefunctionSource ↗
Clear the paragraph measure cache
declare function clearParagraphMeasureCache(): void;clearTextWidthCachefunctionSource ↗
Clear the text width cache
declare function clearTextWidthCache(): void;findCharacterAtXfunctionSource ↗
Find the character offset at a given X position within a text run
declare function findCharacterAtX(x: number, charWidths: number[]): number;getCachedFontMetricsfunctionSource ↗
Get cached font metrics or return undefined
declare function getCachedFontMetrics(fontFamily: string, fontSize: number, bold?: boolean, italic?: boolean): FontMetricsEntry | undefined;getCachedParagraphMeasurefunctionSource ↗
Get cached paragraph measurement or return undefined
declare function getCachedParagraphMeasure(block: ParagraphBlock, maxWidth: number): ParagraphMeasure | undefined;getCachedTextWidthfunctionSource ↗
Get cached text width or return undefined
declare function getCachedTextWidth(text: string, font: string, letterSpacing?: number): number | undefined;getCanvasContextfunctionSource ↗
Get or create a canvas 2D context for text measurement
declare function getCanvasContext(): CanvasRenderingContext2D;getFloatingMarginsfunctionSource ↗
declare function getFloatingMargins(lineY: number, lineHeight: number, zones: FloatingImageZone[] | undefined, paragraphYOffset: number): FloatingLineMargins;getFontCacheSizefunctionSource ↗
Get current font metrics cache size
declare function getFontCacheSize(): number;getFontMetricsfunctionSource ↗
Get typography metrics for a given font size and family
Uses Canvas TextMetrics API when available for precise metrics, falls back to ratio-based approximations.
declare function getFontMetrics(style: FontStyle): FontMetrics;getParagraphCacheSizefunctionSource ↗
Get current paragraph measure cache size
declare function getParagraphCacheSize(): number;getRunCharWidthsfunctionSource ↗
Get per-character widths for a text run (for click positioning)
declare function getRunCharWidths(run: TextRun): number[];getTextCacheSizefunctionSource ↗
Get current text width cache size
declare function getTextCacheSize(): number;getTotalCacheSizefunctionSource ↗
Get total size of all caches
declare function getTotalCacheSize(): number;getXForCharacterfunctionSource ↗
Get the X position of a character offset within a text run
declare function getXForCharacter(offset: number, charWidths: number[]): number;halfPtToPxfunctionSource ↗
Convert OOXML half-points to pixels OOXML font sizes are in half-points (24 = 12pt)
declare function halfPtToPx(halfPt: number): number;hashParagraphBlockfunctionSource ↗
Generate a simple hash for a paragraph block Used as cache key to identify identical content
declare function hashParagraphBlock(block: ParagraphBlock): string;measureBlocksWithFloatsfunctionSource ↗
Walk blocks and produce one Measure per block. Before measuring, this extracts floating exclusion zones (images / floating tables / floating textboxes), groups overlapping co-located floats, and threads the active zones plus cumulative Y into each measureBlock call.
Pass pageGeometry whenever the document may contain page/margin-anchored topAndBottom text boxes (e.g. a title banner pinned to the page top): without it their reserved band falls back to flow-relative Y and the band won't line up with where the painter places the box. Build it with the shared pageGeometryFromPage helper.
declare function measureBlocksWithFloats(blocks: FlowBlock[], contentWidth: number | number[], measureBlock: MeasureBlockFn, pageGeometry?: FloatPageGeometry): Measure[];measureParagraphfunctionSource ↗
Measure a paragraph block and compute line breaks
declare function measureParagraph(block: ParagraphBlock, maxWidth: number, options?: MeasureParagraphOptions): ParagraphMeasure;measureParagraphsfunctionSource ↗
Measure multiple paragraph blocks
declare function measureParagraphs(blocks: ParagraphBlock[], maxWidth: number): ParagraphMeasure[];measureRunfunctionSource ↗
Measure a run of text and return per-character widths for click positioning
declare function measureRun(text: string, style: FontStyle): RunMeasurement;measureTextfunctionSource ↗
Measure text and return full metrics
declare function measureText(text: string, style: FontStyle): TextMeasurement;measureTextWidthfunctionSource ↗
Measure the width of a text string with specific styling
declare function measureTextWidth(text: string, style: FontStyle): number;ptToPxfunctionSource ↗
Convert points to pixels
declare function ptToPx(pt: number): number;pxToHalfPtfunctionSource ↗
Convert pixels to OOXML half-points
declare function pxToHalfPt(px: number): number;pxToPtfunctionSource ↗
Convert pixels to points
declare function pxToPt(px: number): number;pxToTwipsfunctionSource ↗
Convert pixels to twips
declare function pxToTwips(px: number): number;rectsToFloatingZonesfunctionSource ↗
declare function rectsToFloatingZones(rects: FloatingExclusionRect[], contentWidth: number): FloatingImageZone[];resetCanvasContextfunctionSource ↗
Reset the canvas context (useful for testing)
declare function resetCanvasContext(): void;setCachedFontMetricsfunctionSource ↗
Store font metrics in cache
declare function setCachedFontMetrics(fontFamily: string, fontSize: number, bold: boolean, italic: boolean, metrics: FontMetricsEntry): void;setCachedParagraphMeasurefunctionSource ↗
Store paragraph measurement in cache
declare function setCachedParagraphMeasure(block: ParagraphBlock, maxWidth: number, measure: ParagraphMeasure): void;setCachedTextWidthfunctionSource ↗
Store text width in cache
declare function setCachedTextWidth(text: string, font: string, letterSpacing: number, width: number): void;setFontCacheSizefunctionSource ↗
Set the maximum size of the font metrics cache
declare function setFontCacheSize(size: number): void;setParagraphCacheSizefunctionSource ↗
Set the maximum size of the paragraph measure cache
declare function setParagraphCacheSize(size: number): void;setTextCacheSizefunctionSource ↗
Set the maximum size of the text width cache
declare function setTextCacheSize(size: number): void;twipsToPxfunctionSource ↗
Convert twips to pixels
declare function twipsToPx(twips: number): number;Interfaces (8)
FloatingExclusionRectinterfaceSource ↗
interface FloatingExclusionRect| Member | Type | Summary |
|---|---|---|
| distBottom | number | |
| distLeft | number | |
| distRight | number | |
| distTop | number | |
| height | number | |
| side | 'left' | 'right' | Which side the object is on for simple one-sided wrapping. |
| width | number | |
| wrapText? | WrapTextDirection | |
| wrapType? | string | |
| x | number | X position relative to the content area. |
| y | number | Y position relative to the content area. |
FloatingImageZoneinterfaceSource ↗
interface FloatingImageZone| Member | Type | Summary |
|---|---|---|
| bottomY | number | |
| fullWidthBlock? | boolean | Full-width vertical band (OOXML `topAndBottom` wrap): no text fits beside it, so any line overlapping `[topY, bottomY]` is pushed below the band. |
| leftMargin | number | |
| rightMargin | number | |
| segments? | FloatingLineSegmentZone[] | |
| topY | number |
FloatingLineSegmentZoneinterfaceSource ↗
interface FloatingLineSegmentZone| Member | Type | Summary |
|---|---|---|
| availableWidth | number | |
| leftOffset | number |
FontMetricsinterfaceSource ↗
Typography metrics for a font
interface FontMetrics| Member | Type | Summary |
|---|---|---|
| ascent | number | |
| descent | number | |
| fontFamily | string | |
| fontSize | number | |
| lineHeight | number | |
| singleLineRatio | number | OS/2 single-line ratio for OOXML line spacing calculation |
FontStyleinterfaceSource ↗
Font styling properties for measurement
interface FontStyle| Member | Type | Summary |
|---|---|---|
| bold? | boolean | |
| fontFamily? | string | |
| fontSize? | number | |
| italic? | boolean | |
| letterSpacing? | number |
MeasureParagraphOptionsinterfaceSource ↗
Options for paragraph measurement
interface MeasureParagraphOptions| Member | Type | Summary |
|---|---|---|
| floatingZones? | FloatingImageZone[] | Floating image exclusion zones that affect line widths |
| paragraphYOffset? | number | Y offset of this paragraph relative to the exclusion zones (default: 0) |
RunMeasurementinterfaceSource ↗
Result of measuring a run of text
interface RunMeasurement| Member | Type | Summary |
|---|---|---|
| charWidths | number[] | |
| metrics | FontMetrics | |
| width | number |
TextMeasurementinterfaceSource ↗
Result of measuring a text string
interface TextMeasurement| Member | Type | Summary |
|---|---|---|
| ascent | number | |
| descent | number | |
| height | number | |
| width | number |
Type aliases (2)
FloatPageGeometrytypeSource ↗
Page geometry (CSS px) used to resolve page/margin-relative anchored objects into content-area coordinates — currently the vertical anchor of a top-pinned topAndBottom band. Same shape the painter uses (see pageGeometryFromPage), so both paths resolve to identical positions.
type FloatPageGeometry = PageGeometry;MeasureBlockFntypeSource ↗
Block-measurement callback shape passed to [measureBlocksWithFloats](measureBlocksWithFloats). Adapters (React, Vue) supply this so they can decide platform-specific concerns (e.g. paragraph-measure caching, per-section width) while sharing the floating-zone orchestration. This is adapter-author API, not end-consumer API.
type MeasureBlockFn = (block: FlowBlock, contentWidth: number, floatingZones?: FloatingImageZone[], cumulativeY?: number) => Measure;