three-text 0.4.7 → 0.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/core/Text.d.ts +56 -0
- package/dist/core/cache/GlyphContourCollector.d.ts +38 -0
- package/dist/core/cache/GlyphGeometryBuilder.d.ts +60 -0
- package/dist/core/cache/sharedCaches.d.ts +15 -0
- package/dist/core/font/FontLoader.d.ts +9 -0
- package/dist/core/font/FontMetadata.d.ts +32 -0
- package/dist/core/font/TableDirectory.d.ts +7 -0
- package/dist/core/font/WoffConverter.d.ts +9 -0
- package/dist/core/font/constants.d.ts +14 -0
- package/dist/core/geometry/BoundaryClusterer.d.ts +8 -0
- package/dist/core/geometry/Extruder.d.ts +10 -0
- package/dist/core/geometry/PathOptimizer.d.ts +21 -0
- package/dist/core/geometry/Polygonizer.d.ts +56 -0
- package/dist/core/geometry/Tessellator.d.ts +14 -0
- package/dist/core/layout/LineBreak.d.ts +95 -0
- package/dist/core/layout/TextLayout.d.ts +59 -0
- package/dist/core/layout/TextRangeQuery.d.ts +11 -0
- package/dist/core/layout/constants.d.ts +7 -0
- package/dist/core/shaping/DrawCallbacks.d.ts +19 -0
- package/dist/core/shaping/HarfBuzzLoader.d.ts +6 -0
- package/dist/core/shaping/TextMeasurer.d.ts +5 -0
- package/dist/core/shaping/TextShaper.d.ts +35 -0
- package/dist/core/shaping/fontFeatures.d.ts +3 -0
- package/dist/core/types.d.ts +354 -0
- package/dist/hyphenation/HyphenationPatternLoader.d.ts +2 -0
- package/dist/hyphenation/index.d.ts +7 -0
- package/dist/hyphenation/types.d.ts +6 -0
- package/dist/index.cjs +4 -5
- package/dist/index.js +4 -5
- package/dist/index.min.cjs +2 -2
- package/dist/index.min.js +2 -2
- package/dist/index.umd.js +64 -17
- package/dist/index.umd.min.js +552 -550
- package/dist/utils/Cache.d.ts +14 -0
- package/dist/utils/Logger.d.ts +8 -0
- package/dist/utils/MinHeap.d.ts +14 -0
- package/dist/utils/PerformanceLogger.d.ts +20 -0
- package/dist/utils/loadBinary.d.ts +1 -0
- package/dist/utils/vectors.d.ts +75 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ High fidelity 3D mesh font geometry and text layout engine for the web
|
|
|
19
19
|
|
|
20
20
|
The library has a framework-agnostic core that returns raw vertex data, with lightweight adapters for [Three.js](https://threejs.org), [React Three Fiber](https://docs.pmnd.rs/react-three-fiber), [p5.js](https://p5js.org), [WebGL](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API), and [WebGPU](https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API)
|
|
21
21
|
|
|
22
|
-
Under the hood, three-text relies on [
|
|
22
|
+
Under the hood, three-text relies on [harfbuzzjs](https://github.com/harfbuzz/harfbuzzjs) (based on [HarfBuzz](https://github.com/harfbuzz/harfbuzz) by Behdad Esfahbod et al) for text shaping, [Knuth-Plass](http://www.eprg.org/G53DOC/pdfs/knuth-plass-breaking.pdf) line breaking (with [SILE](https://github.com/sile-typesetter/sile/blob/master/core/break.lua) being the cleanest modern reference), [Liang](https://tug.org/docs/liang/liang-thesis.pdf) hyphenation and the [TeX hyphenation patterns](https://github.com/hyphenation/tex-hyphen), [libtess.js](https://github.com/brendankenny/libtess.js) (based on the [GLU tessellator](https://www.songho.ca/opengl/gl_tessellation.html) by Eric Veach) for removing overlaps and triangulation, adaptive curve polygonization from Maxim Shemanarev's [Anti-Grain Geometry](https://web.archive.org/web/20060128212843/http://www.antigrain.com/research/adaptive_bezier/index.html), [Visvalingam-Whyatt](https://hull-repository.worktribe.com/preview/376364/000870493786962263.pdf) [line simplification](https://bost.ocks.org/mike/simplify/), as well as [woff-lib](https://github.com/countertype/woff-lib) and [brotli-lib](https://github.com/countertype/brotli-lib)
|
|
23
23
|
|
|
24
24
|
## Table of contents
|
|
25
25
|
|
|
@@ -79,11 +79,11 @@ Most users will just `import { Text } from 'three-text'` for Three.js projects
|
|
|
79
79
|
|
|
80
80
|
```javascript
|
|
81
81
|
import { Text } from 'three-text/three';
|
|
82
|
-
import {
|
|
82
|
+
import { woff2Decode } from 'woff-lib/woff2/decode';
|
|
83
83
|
import * as THREE from 'three';
|
|
84
84
|
|
|
85
85
|
Text.setHarfBuzzPath('/hb/hb.wasm');
|
|
86
|
-
Text.enableWoff2(
|
|
86
|
+
Text.enableWoff2(woff2Decode); // Optional, for WOFF2 support
|
|
87
87
|
const result = await Text.create({
|
|
88
88
|
text: 'Hello World',
|
|
89
89
|
font: '/fonts/Font.woff2',
|
|
@@ -118,14 +118,14 @@ function App() {
|
|
|
118
118
|
|
|
119
119
|
```javascript
|
|
120
120
|
import 'three-text/p5';
|
|
121
|
-
import {
|
|
121
|
+
import { woff2Decode } from 'woff-lib/woff2/decode';
|
|
122
122
|
|
|
123
123
|
let font;
|
|
124
124
|
let textResult;
|
|
125
125
|
|
|
126
126
|
function preload() {
|
|
127
127
|
loadThreeTextShaper('/hb/hb.wasm');
|
|
128
|
-
enableThreeTextWoff2(
|
|
128
|
+
enableThreeTextWoff2(woff2Decode); // Optional, for WOFF2 support
|
|
129
129
|
font = loadThreeTextFont('/fonts/Font.woff2');
|
|
130
130
|
}
|
|
131
131
|
|
|
@@ -983,7 +983,7 @@ Synthetic component benchmarks for tessellation, extrusion, and layout are avail
|
|
|
983
983
|
### Development
|
|
984
984
|
|
|
985
985
|
```bash
|
|
986
|
-
npm run dev # Watch mode with
|
|
986
|
+
npm run dev # Watch mode with rolldown
|
|
987
987
|
npm run serve # Start development server for demos
|
|
988
988
|
```
|
|
989
989
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { TextOptions, TextHandle, FontMetrics, LoadedFont, HarfBuzzInstance } from './types';
|
|
2
|
+
import type { HyphenationTrieNode } from '../hyphenation';
|
|
3
|
+
declare global {
|
|
4
|
+
interface Window {
|
|
5
|
+
hbjs?: any;
|
|
6
|
+
createHarfBuzz?: () => Promise<any>;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export declare class Text {
|
|
10
|
+
private static patternCache;
|
|
11
|
+
private static hbInitPromise;
|
|
12
|
+
private static fontCache;
|
|
13
|
+
private static fontCacheMemoryBytes;
|
|
14
|
+
private static maxFontCacheMemoryBytes;
|
|
15
|
+
private static fontIdCounter;
|
|
16
|
+
static enableWoff2(decoder: (data: ArrayBuffer | Uint8Array) => Uint8Array | Promise<Uint8Array>): void;
|
|
17
|
+
private static stableStringify;
|
|
18
|
+
private fontLoader;
|
|
19
|
+
private loadedFont?;
|
|
20
|
+
private currentFontId;
|
|
21
|
+
private geometryBuilder?;
|
|
22
|
+
private textShaper?;
|
|
23
|
+
private textLayout?;
|
|
24
|
+
private constructor();
|
|
25
|
+
static setHarfBuzzPath(path: string): void;
|
|
26
|
+
static setHarfBuzzBuffer(wasmBuffer: ArrayBuffer): void;
|
|
27
|
+
static init(): Promise<HarfBuzzInstance>;
|
|
28
|
+
static create(options: TextOptions): Promise<TextHandle>;
|
|
29
|
+
private static resolveFont;
|
|
30
|
+
private static loadAndCacheFont;
|
|
31
|
+
private static trackFontCacheAdd;
|
|
32
|
+
private static trackFontCacheRemove;
|
|
33
|
+
private static enforceFontCacheMemoryLimit;
|
|
34
|
+
private static generateFontContentHash;
|
|
35
|
+
private setLoadedFont;
|
|
36
|
+
private loadFont;
|
|
37
|
+
private createGeometry;
|
|
38
|
+
private prepareHyphenation;
|
|
39
|
+
private validateOptions;
|
|
40
|
+
private updateFontVariations;
|
|
41
|
+
private prepareLayout;
|
|
42
|
+
private applyColorSystem;
|
|
43
|
+
private calculateGlyphBounds;
|
|
44
|
+
private finalizeGeometry;
|
|
45
|
+
getFontMetrics(): FontMetrics;
|
|
46
|
+
static preloadPatterns(languages: string[], patternsPath?: string): Promise<void>;
|
|
47
|
+
static registerPattern(language: string, pattern: HyphenationTrieNode): void;
|
|
48
|
+
static setMaxFontCacheMemoryMB(limitMB: number): void;
|
|
49
|
+
getLoadedFont(): LoadedFont | undefined;
|
|
50
|
+
measureTextWidth(text: string, letterSpacing?: number): number;
|
|
51
|
+
getCacheSize(): number;
|
|
52
|
+
clearCache(): void;
|
|
53
|
+
private createGlyphAttributes;
|
|
54
|
+
private resetHelpers;
|
|
55
|
+
destroy(): void;
|
|
56
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Vec2 } from '../../utils/vectors';
|
|
2
|
+
import { GlyphContours } from '../types';
|
|
3
|
+
import { OptimizationStats } from '../geometry/PathOptimizer';
|
|
4
|
+
import { CurveFidelityConfig, GeometryOptimizationOptions } from '../types';
|
|
5
|
+
export declare class GlyphContourCollector {
|
|
6
|
+
private currentGlyphId;
|
|
7
|
+
private currentTextIndex;
|
|
8
|
+
private currentGlyphPaths;
|
|
9
|
+
private currentPath;
|
|
10
|
+
private currentPoint;
|
|
11
|
+
private currentGlyphBounds;
|
|
12
|
+
private collectedGlyphs;
|
|
13
|
+
private glyphPositions;
|
|
14
|
+
private glyphTextIndices;
|
|
15
|
+
private polygonizer;
|
|
16
|
+
private pathOptimizer;
|
|
17
|
+
private currentPosition;
|
|
18
|
+
constructor(curveFidelityConfig?: CurveFidelityConfig, optimizationConfig?: GeometryOptimizationOptions);
|
|
19
|
+
setPosition(x: number, y: number): void;
|
|
20
|
+
updatePosition(dx: number, dy: number): void;
|
|
21
|
+
beginGlyph(glyphId: number, textIndex: number): void;
|
|
22
|
+
finishGlyph(): void;
|
|
23
|
+
onMoveTo(x: number, y: number): void;
|
|
24
|
+
onLineTo(x: number, y: number): void;
|
|
25
|
+
onQuadTo(cx: number, cy: number, x: number, y: number): void;
|
|
26
|
+
onCubicTo(c1x: number, c1y: number, c2x: number, c2y: number, x: number, y: number): void;
|
|
27
|
+
onClosePath(): void;
|
|
28
|
+
private finishPath;
|
|
29
|
+
private updateBounds;
|
|
30
|
+
getCollectedGlyphs(): GlyphContours[];
|
|
31
|
+
getGlyphPositions(): Vec2[];
|
|
32
|
+
getTextIndices(): number[];
|
|
33
|
+
reset(): void;
|
|
34
|
+
setCurveFidelityConfig(config?: CurveFidelityConfig): void;
|
|
35
|
+
setCurveSteps(curveSteps?: number): void;
|
|
36
|
+
setGeometryOptimization(options?: GeometryOptimizationOptions): void;
|
|
37
|
+
getOptimizationStats(): OptimizationStats;
|
|
38
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { GlyphGeometryInfo, LoadedFont, GlyphCluster, GlyphData } from '../types';
|
|
2
|
+
import { CurveFidelityConfig, GeometryOptimizationOptions } from '../types';
|
|
3
|
+
import { Cache } from '../../utils/Cache';
|
|
4
|
+
export interface InstancedTextGeometry {
|
|
5
|
+
vertices: Float32Array;
|
|
6
|
+
normals: Float32Array;
|
|
7
|
+
indices: Uint32Array;
|
|
8
|
+
glyphInfos: GlyphGeometryInfo[];
|
|
9
|
+
planeBounds: {
|
|
10
|
+
min: {
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
z: number;
|
|
14
|
+
};
|
|
15
|
+
max: {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
z: number;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export declare class GlyphGeometryBuilder {
|
|
23
|
+
private cache;
|
|
24
|
+
private tessellator;
|
|
25
|
+
private extruder;
|
|
26
|
+
private fontId;
|
|
27
|
+
private cacheKeyPrefix;
|
|
28
|
+
private curveFidelityConfig?;
|
|
29
|
+
private curveSteps?;
|
|
30
|
+
private geometryOptimizationOptions?;
|
|
31
|
+
private clusterer;
|
|
32
|
+
private collector;
|
|
33
|
+
private drawCallbacks;
|
|
34
|
+
private loadedFont;
|
|
35
|
+
private wordCache;
|
|
36
|
+
private contourCache;
|
|
37
|
+
private clusteringCache;
|
|
38
|
+
private emptyGlyphs;
|
|
39
|
+
private clusterPositions;
|
|
40
|
+
private clusterContoursScratch;
|
|
41
|
+
private taskScratch;
|
|
42
|
+
constructor(cache: Cache<string, GlyphData>, loadedFont: LoadedFont);
|
|
43
|
+
getOptimizationStats(): import("../geometry/PathOptimizer").OptimizationStats;
|
|
44
|
+
setCurveFidelityConfig(config?: CurveFidelityConfig): void;
|
|
45
|
+
setCurveSteps(curveSteps?: number): void;
|
|
46
|
+
setGeometryOptimization(options?: GeometryOptimizationOptions): void;
|
|
47
|
+
setFontId(fontId: string): void;
|
|
48
|
+
private updateCacheKeyPrefix;
|
|
49
|
+
private getGeometryConfigSignature;
|
|
50
|
+
buildInstancedGeometry(clustersByLine: GlyphCluster[][], depth: number, removeOverlaps: boolean, isCFF: boolean, scale: number, separateGlyphs?: boolean, coloredTextIndices?: Set<number>): InstancedTextGeometry;
|
|
51
|
+
private getClusterKey;
|
|
52
|
+
private createGlyphInfo;
|
|
53
|
+
private getContoursForGlyph;
|
|
54
|
+
private tessellateGlyphCluster;
|
|
55
|
+
private extrudeAndPackage;
|
|
56
|
+
private tessellateGlyph;
|
|
57
|
+
private updatePlaneBounds;
|
|
58
|
+
getCacheStats(): import("../../utils/Cache").CacheStats;
|
|
59
|
+
clearCache(): void;
|
|
60
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Cache } from '../../utils/Cache';
|
|
2
|
+
import type { GlyphData, GlyphContours } from '../types';
|
|
3
|
+
export declare function getGlyphCacheKey(fontId: string, glyphId: number, depth: number, removeOverlaps: boolean): string;
|
|
4
|
+
export declare const globalGlyphCache: Cache<string, GlyphData>;
|
|
5
|
+
export declare function createGlyphCache(): Cache<string, GlyphData>;
|
|
6
|
+
export declare const globalContourCache: Cache<string, GlyphContours>;
|
|
7
|
+
export declare const globalWordCache: Cache<string, GlyphData>;
|
|
8
|
+
export declare const globalClusteringCache: Cache<string, {
|
|
9
|
+
glyphIds: number[];
|
|
10
|
+
positions: {
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
}[];
|
|
14
|
+
groups: number[][];
|
|
15
|
+
}>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { LoadedFont, HarfBuzzInstance } from '../types';
|
|
2
|
+
export declare class FontLoader {
|
|
3
|
+
private getHarfBuzzInstance;
|
|
4
|
+
constructor(getHarfBuzzInstance: () => Promise<HarfBuzzInstance>);
|
|
5
|
+
loadFont(fontBuffer: ArrayBuffer, fontVariations?: {
|
|
6
|
+
[key: string]: number;
|
|
7
|
+
}): Promise<LoadedFont>;
|
|
8
|
+
static destroyFont(loadedFont: LoadedFont): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ExtractedMetrics, FontMetrics, VerticalMetrics } from '../types';
|
|
2
|
+
export interface FontDataExtraction {
|
|
3
|
+
metrics: ExtractedMetrics;
|
|
4
|
+
features: {
|
|
5
|
+
tags: string[];
|
|
6
|
+
names: {
|
|
7
|
+
[tag: string]: string;
|
|
8
|
+
};
|
|
9
|
+
} | undefined;
|
|
10
|
+
}
|
|
11
|
+
export declare class FontMetadataExtractor {
|
|
12
|
+
static extractMetadata(fontBuffer: ArrayBuffer): ExtractedMetrics;
|
|
13
|
+
static extractFeatureTags(fontBuffer: ArrayBuffer): {
|
|
14
|
+
tags: string[];
|
|
15
|
+
names: {
|
|
16
|
+
[tag: string]: string;
|
|
17
|
+
};
|
|
18
|
+
} | undefined;
|
|
19
|
+
private static extractFeatureDataFromTable;
|
|
20
|
+
private static extractAxisNames;
|
|
21
|
+
private static getNameFromNameTable;
|
|
22
|
+
static extractAll(fontBuffer: ArrayBuffer): FontDataExtraction;
|
|
23
|
+
private static buildNameIndex;
|
|
24
|
+
private static getNameFromIndex;
|
|
25
|
+
private static extractMetricsWithIndex;
|
|
26
|
+
private static extractAxisNamesWithIndex;
|
|
27
|
+
private static extractFeaturesWithIndex;
|
|
28
|
+
private static extractFeatureData;
|
|
29
|
+
private static tagToString;
|
|
30
|
+
static getVerticalMetrics(metrics: ExtractedMetrics): VerticalMetrics;
|
|
31
|
+
static getFontMetrics(metrics: ExtractedMetrics): FontMetrics;
|
|
32
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type Woff2Decoder = (data: ArrayBuffer | Uint8Array) => Uint8Array | Promise<Uint8Array>;
|
|
2
|
+
export declare function setWoff2Decoder(decoder: Woff2Decoder): void;
|
|
3
|
+
export declare class WoffConverter {
|
|
4
|
+
static detectFormat(buffer: ArrayBuffer): 'woff' | 'woff2' | 'ttf/otf';
|
|
5
|
+
static decompressWoff(woffBuffer: ArrayBuffer): Promise<ArrayBuffer>;
|
|
6
|
+
static decompressWoff2(woff2Buffer: ArrayBuffer): Promise<ArrayBuffer>;
|
|
7
|
+
private static decompressZlib;
|
|
8
|
+
}
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const FONT_SIGNATURE_TRUE_TYPE = 65536;
|
|
2
|
+
export declare const FONT_SIGNATURE_OPEN_TYPE_CFF = 1330926671;
|
|
3
|
+
export declare const FONT_SIGNATURE_WOFF = 2001684038;
|
|
4
|
+
export declare const FONT_SIGNATURE_WOFF2 = 2001684018;
|
|
5
|
+
export declare const TABLE_TAG_HEAD = 1751474532;
|
|
6
|
+
export declare const TABLE_TAG_HHEA = 1751672161;
|
|
7
|
+
export declare const TABLE_TAG_OS2 = 1330851634;
|
|
8
|
+
export declare const TABLE_TAG_FVAR = 1719034226;
|
|
9
|
+
export declare const TABLE_TAG_STAT = 1398030676;
|
|
10
|
+
export declare const TABLE_TAG_NAME = 1851878757;
|
|
11
|
+
export declare const TABLE_TAG_CFF = 1128678944;
|
|
12
|
+
export declare const TABLE_TAG_CFF2 = 1128678962;
|
|
13
|
+
export declare const TABLE_TAG_GSUB = 1196643650;
|
|
14
|
+
export declare const TABLE_TAG_GPOS = 1196445523;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Vec3 } from '../../utils/vectors';
|
|
2
|
+
import type { GlyphContours } from '../types';
|
|
3
|
+
export declare class BoundaryClusterer {
|
|
4
|
+
constructor();
|
|
5
|
+
cluster(glyphContoursList: GlyphContours[], positions: Vec3[]): number[][];
|
|
6
|
+
private clusterSweepLine;
|
|
7
|
+
private getWorldBounds;
|
|
8
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ProcessedGeometry } from '../types';
|
|
2
|
+
export interface ExtrusionResult {
|
|
3
|
+
vertices: Float32Array;
|
|
4
|
+
normals: Float32Array;
|
|
5
|
+
indices: Uint32Array;
|
|
6
|
+
}
|
|
7
|
+
export declare class Extruder {
|
|
8
|
+
constructor();
|
|
9
|
+
extrude(geometry: ProcessedGeometry, depth: number | undefined, unitsPerEm: number): ExtrusionResult;
|
|
10
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Path } from '../types';
|
|
2
|
+
export interface OptimizationConfig {
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
areaThreshold: number;
|
|
5
|
+
}
|
|
6
|
+
export interface OptimizationStats {
|
|
7
|
+
pointsRemovedByVisvalingam: number;
|
|
8
|
+
originalPointCount: number;
|
|
9
|
+
}
|
|
10
|
+
export declare const DEFAULT_OPTIMIZATION_CONFIG: OptimizationConfig;
|
|
11
|
+
export declare class PathOptimizer {
|
|
12
|
+
private config;
|
|
13
|
+
private stats;
|
|
14
|
+
constructor(config: OptimizationConfig);
|
|
15
|
+
setConfig(config: OptimizationConfig): void;
|
|
16
|
+
optimizePath(path: Path): Path;
|
|
17
|
+
private simplifyPathVW;
|
|
18
|
+
private calculateTriangleArea;
|
|
19
|
+
getStats(): OptimizationStats;
|
|
20
|
+
resetStats(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Anti-Grain Geometry - Version 2.4
|
|
4
|
+
* Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
|
|
5
|
+
*
|
|
6
|
+
* This software is a partial port of the AGG library, specifically the adaptive
|
|
7
|
+
* subdivision algorithm for polygonization. The original software was available
|
|
8
|
+
* at http://www.antigrain.com and was distributed under the BSD 3-Clause License
|
|
9
|
+
*
|
|
10
|
+
* Redistribution and use in source and binary forms, with or without
|
|
11
|
+
* modification, are permitted provided that the following conditions
|
|
12
|
+
* are met:
|
|
13
|
+
*
|
|
14
|
+
* 1. Redistributions of source code must retain the above copyright
|
|
15
|
+
* notice, this list of conditions and the following disclaimer.
|
|
16
|
+
*
|
|
17
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
|
18
|
+
* notice, this list of conditions and the following disclaimer in
|
|
19
|
+
* the documentation and/or other materials provided with the
|
|
20
|
+
* distribution.
|
|
21
|
+
*
|
|
22
|
+
* 3. The name of the author may not be used to endorse or promote
|
|
23
|
+
* products derived from this software without specific prior
|
|
24
|
+
* written permission.
|
|
25
|
+
*
|
|
26
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
27
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
28
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
29
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
|
30
|
+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
31
|
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
32
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
33
|
+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
34
|
+
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
35
|
+
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
36
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
|
37
|
+
*/
|
|
38
|
+
import { Vec2 } from '../../utils/vectors';
|
|
39
|
+
import { CurveFidelityConfig } from '../types';
|
|
40
|
+
export declare const DEFAULT_CURVE_FIDELITY: CurveFidelityConfig;
|
|
41
|
+
export declare const COLLINEARITY_EPSILON = 0.000001;
|
|
42
|
+
export declare class Polygonizer {
|
|
43
|
+
private curveFidelityConfig;
|
|
44
|
+
private curveSteps;
|
|
45
|
+
constructor(curveFidelityConfig?: CurveFidelityConfig);
|
|
46
|
+
setCurveFidelityConfig(curveFidelityConfig?: CurveFidelityConfig): void;
|
|
47
|
+
setCurveSteps(curveSteps?: number): void;
|
|
48
|
+
polygonizeQuadratic(start: Vec2, control: Vec2, end: Vec2): Vec2[];
|
|
49
|
+
polygonizeCubic(start: Vec2, control1: Vec2, control2: Vec2, end: Vec2): Vec2[];
|
|
50
|
+
private lerp;
|
|
51
|
+
private polygonizeQuadraticFixedSteps;
|
|
52
|
+
private polygonizeCubicFixedSteps;
|
|
53
|
+
private recursiveQuadratic;
|
|
54
|
+
private recursiveCubic;
|
|
55
|
+
private addPoint;
|
|
56
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Path, ProcessedGeometry } from '../types';
|
|
2
|
+
export declare class Tessellator {
|
|
3
|
+
process(paths: Path[], removeOverlaps?: boolean, isCFF?: boolean, needsExtrusionContours?: boolean): ProcessedGeometry;
|
|
4
|
+
processContours(contours: number[][], removeOverlaps?: boolean, isCFF?: boolean, needsExtrusionContours?: boolean): ProcessedGeometry;
|
|
5
|
+
private tessellate;
|
|
6
|
+
private tessellateContours;
|
|
7
|
+
private pathsToContours;
|
|
8
|
+
private reverseContours;
|
|
9
|
+
private reverseContour;
|
|
10
|
+
private performTessellation;
|
|
11
|
+
private boundaryToContours;
|
|
12
|
+
private needsWindingNormalization;
|
|
13
|
+
private signedArea;
|
|
14
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { TextAlign, TextDirection, LineInfo, HyphenationPatternsMap } from '../types';
|
|
2
|
+
export declare enum ItemType {
|
|
3
|
+
BOX = 0,// character or word with fixed width
|
|
4
|
+
GLUE = 1,// stretchable/shrinkable space
|
|
5
|
+
PENALTY = 2,// potential breakpoint with penalty cost
|
|
6
|
+
DISCRETIONARY = 3
|
|
7
|
+
}
|
|
8
|
+
export declare enum FitnessClass {
|
|
9
|
+
VERY_LOOSE = 0,// lines stretching more than their stretchability
|
|
10
|
+
LOOSE = 1,// lines stretching 0.5 to 1.0 of their stretchability
|
|
11
|
+
DECENT = 2,// all other lines
|
|
12
|
+
TIGHT = 3
|
|
13
|
+
}
|
|
14
|
+
interface Item {
|
|
15
|
+
type: ItemType;
|
|
16
|
+
width: number;
|
|
17
|
+
text?: string;
|
|
18
|
+
originIndex?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface Box extends Item {
|
|
21
|
+
type: ItemType.BOX;
|
|
22
|
+
}
|
|
23
|
+
export interface Glue extends Item {
|
|
24
|
+
type: ItemType.GLUE;
|
|
25
|
+
stretch: number;
|
|
26
|
+
shrink: number;
|
|
27
|
+
}
|
|
28
|
+
export interface Penalty extends Item {
|
|
29
|
+
type: ItemType.PENALTY;
|
|
30
|
+
penalty: number;
|
|
31
|
+
flagged?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface Discretionary extends Item {
|
|
34
|
+
type: ItemType.DISCRETIONARY;
|
|
35
|
+
preBreak: string;
|
|
36
|
+
postBreak: string;
|
|
37
|
+
noBreak: string;
|
|
38
|
+
preBreakWidth: number;
|
|
39
|
+
penalty: number;
|
|
40
|
+
flagged?: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface LineBreakOptions {
|
|
43
|
+
text: string;
|
|
44
|
+
width?: number;
|
|
45
|
+
align?: TextAlign;
|
|
46
|
+
direction?: TextDirection;
|
|
47
|
+
hyphenate?: boolean;
|
|
48
|
+
language?: string;
|
|
49
|
+
measureText: (text: string) => number;
|
|
50
|
+
measureTextWidths?: (text: string) => number[];
|
|
51
|
+
respectExistingBreaks?: boolean;
|
|
52
|
+
hyphenationPatterns?: HyphenationPatternsMap;
|
|
53
|
+
unitsPerEm?: number;
|
|
54
|
+
letterSpacing?: number;
|
|
55
|
+
tolerance?: number;
|
|
56
|
+
pretolerance?: number;
|
|
57
|
+
emergencyStretch?: number;
|
|
58
|
+
autoEmergencyStretch?: number;
|
|
59
|
+
lefthyphenmin?: number;
|
|
60
|
+
righthyphenmin?: number;
|
|
61
|
+
linepenalty?: number;
|
|
62
|
+
adjdemerits?: number;
|
|
63
|
+
hyphenpenalty?: number;
|
|
64
|
+
exhyphenpenalty?: number;
|
|
65
|
+
doublehyphendemerits?: number;
|
|
66
|
+
finalhyphendemerits?: number;
|
|
67
|
+
}
|
|
68
|
+
interface LineBreakContext {
|
|
69
|
+
linePenalty: number;
|
|
70
|
+
adjDemerits: number;
|
|
71
|
+
doubleHyphenDemerits: number;
|
|
72
|
+
finalHyphenDemerits: number;
|
|
73
|
+
hyphenPenalty: number;
|
|
74
|
+
exHyphenPenalty: number;
|
|
75
|
+
currentAlign: TextAlign;
|
|
76
|
+
unitsPerEm?: number;
|
|
77
|
+
letterSpacingFU?: number;
|
|
78
|
+
}
|
|
79
|
+
export declare class LineBreak {
|
|
80
|
+
private static badness;
|
|
81
|
+
private static fitnessClass;
|
|
82
|
+
static findHyphenationPoints(word: string, language?: string, availablePatterns?: HyphenationPatternsMap, lefthyphenmin?: number, righthyphenmin?: number): number[];
|
|
83
|
+
static itemizeText(text: string, measureText: (text: string) => number, measureTextWidths: ((text: string) => number[]) | undefined, hyphenate?: boolean, language?: string, availablePatterns?: HyphenationPatternsMap, lefthyphenmin?: number, righthyphenmin?: number, context?: LineBreakContext, lineWidth?: number): Item[];
|
|
84
|
+
static isCJK(char: string): boolean;
|
|
85
|
+
static isCJClosingPunctuation(char: string): boolean;
|
|
86
|
+
static isCJOpeningPunctuation(char: string): boolean;
|
|
87
|
+
static isCJPunctuation(char: string): boolean;
|
|
88
|
+
private static itemizeCJKText;
|
|
89
|
+
private static itemizeParagraph;
|
|
90
|
+
private static itemizeWordBased;
|
|
91
|
+
private static lineBreak;
|
|
92
|
+
static breakText(options: LineBreakOptions): LineInfo[];
|
|
93
|
+
private static postLineBreak;
|
|
94
|
+
}
|
|
95
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { LineInfo, TextAlign, LoadedFont, LayoutOptions } from '../types';
|
|
2
|
+
export interface TextLayoutOptions extends LayoutOptions {
|
|
3
|
+
text: string;
|
|
4
|
+
letterSpacing: number;
|
|
5
|
+
}
|
|
6
|
+
export interface LayoutResult {
|
|
7
|
+
lines: LineInfo[];
|
|
8
|
+
}
|
|
9
|
+
export interface AlignmentOptions {
|
|
10
|
+
width?: number;
|
|
11
|
+
align: TextAlign;
|
|
12
|
+
planeBounds: {
|
|
13
|
+
min: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
z: number;
|
|
17
|
+
};
|
|
18
|
+
max: {
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
z: number;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export declare class TextLayout {
|
|
26
|
+
private loadedFont;
|
|
27
|
+
constructor(loadedFont: LoadedFont);
|
|
28
|
+
computeLines(options: TextLayoutOptions): LayoutResult;
|
|
29
|
+
applyAlignment(vertices: Float32Array, options: AlignmentOptions): {
|
|
30
|
+
offset: number;
|
|
31
|
+
adjustedBounds: {
|
|
32
|
+
min: {
|
|
33
|
+
x: number;
|
|
34
|
+
y: number;
|
|
35
|
+
z: number;
|
|
36
|
+
};
|
|
37
|
+
max: {
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
z: number;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
computeAlignmentOffset(options: AlignmentOptions): {
|
|
45
|
+
offset: number;
|
|
46
|
+
adjustedBounds: {
|
|
47
|
+
min: {
|
|
48
|
+
x: number;
|
|
49
|
+
y: number;
|
|
50
|
+
z: number;
|
|
51
|
+
};
|
|
52
|
+
max: {
|
|
53
|
+
x: number;
|
|
54
|
+
y: number;
|
|
55
|
+
z: number;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { GlyphGeometryInfo, TextRange, TextQueryOptions } from '../types';
|
|
2
|
+
export declare class TextRangeQuery {
|
|
3
|
+
private text;
|
|
4
|
+
private glyphsByTextIndex;
|
|
5
|
+
constructor(text: string, glyphs: GlyphGeometryInfo[]);
|
|
6
|
+
execute(options: TextQueryOptions): TextRange[];
|
|
7
|
+
private findByText;
|
|
8
|
+
private findByCharRange;
|
|
9
|
+
private createTextRange;
|
|
10
|
+
private calculateBounds;
|
|
11
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const FITNESS_TIGHT_THRESHOLD = 12;
|
|
2
|
+
export declare const FITNESS_NORMAL_THRESHOLD = 99;
|
|
3
|
+
export declare const DEFAULT_TOLERANCE = 800;
|
|
4
|
+
export declare const DEFAULT_PRETOLERANCE = 100;
|
|
5
|
+
export declare const DEFAULT_EMERGENCY_STRETCH = 0;
|
|
6
|
+
export declare const SPACE_STRETCH_RATIO = 0.5;
|
|
7
|
+
export declare const SPACE_SHRINK_RATIO: number;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { LoadedFont } from '../types';
|
|
2
|
+
import { GlyphContourCollector } from '../cache/GlyphContourCollector';
|
|
3
|
+
export declare class DrawCallbackHandler {
|
|
4
|
+
private moveTo_func;
|
|
5
|
+
private lineTo_func;
|
|
6
|
+
private quadTo_func;
|
|
7
|
+
private cubicTo_func;
|
|
8
|
+
private closePath_func;
|
|
9
|
+
private drawFuncsPtr;
|
|
10
|
+
private collector?;
|
|
11
|
+
private position;
|
|
12
|
+
setPosition(x: number, y: number): void;
|
|
13
|
+
updatePosition(dx: number, dy: number): void;
|
|
14
|
+
setCollector(collector: GlyphContourCollector): void;
|
|
15
|
+
createDrawFuncs(font: LoadedFont, collector: GlyphContourCollector): void;
|
|
16
|
+
getDrawFuncsPtr(): number;
|
|
17
|
+
destroy(font: LoadedFont): void;
|
|
18
|
+
}
|
|
19
|
+
export declare function getSharedDrawCallbackHandler(font: LoadedFont): DrawCallbackHandler;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { LoadedFont } from '../types';
|
|
2
|
+
export declare class TextMeasurer {
|
|
3
|
+
static measureTextWidths(loadedFont: LoadedFont, text: string, letterSpacing?: number): number[];
|
|
4
|
+
static measureTextWidth(loadedFont: LoadedFont, text: string, letterSpacing?: number): number;
|
|
5
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { LoadedFont, GlyphGeometryInfo, LineInfo, TextDirection, GlyphCluster, ColorOptions } from '../types';
|
|
2
|
+
import { GlyphGeometryBuilder } from '../cache/GlyphGeometryBuilder';
|
|
3
|
+
export interface ShapedResult {
|
|
4
|
+
geometry: any;
|
|
5
|
+
glyphInfos: GlyphGeometryInfo[];
|
|
6
|
+
planeBounds: {
|
|
7
|
+
min: {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
z: number;
|
|
11
|
+
};
|
|
12
|
+
max: {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
z: number;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
cacheStats?: {
|
|
19
|
+
hits: number;
|
|
20
|
+
misses: number;
|
|
21
|
+
hitRate: number;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export declare class TextShaper {
|
|
25
|
+
private loadedFont;
|
|
26
|
+
private geometryBuilder;
|
|
27
|
+
private cachedSpaceWidth;
|
|
28
|
+
constructor(loadedFont: LoadedFont, geometryBuilder: GlyphGeometryBuilder);
|
|
29
|
+
shapeLines(lineInfos: LineInfo[], scaledLineHeight: number, letterSpacing: number, align: string, direction: TextDirection, color?: [number, number, number] | ColorOptions, originalText?: string): GlyphCluster[][];
|
|
30
|
+
private shapeLineIntoClusters;
|
|
31
|
+
private calculateSpaceAdjustment;
|
|
32
|
+
private calculateCJKAdjustment;
|
|
33
|
+
clearCache(): void;
|
|
34
|
+
getCacheStats(): import("../..").CacheStats;
|
|
35
|
+
}
|