@mlightcad/mtext-renderer 0.11.0 → 0.11.2

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.
@@ -25,6 +25,13 @@ export declare class FontCacheManager {
25
25
  * @returns The font data if found, undefined otherwise
26
26
  */
27
27
  get(fileName: string): Promise<FontData | undefined>;
28
+ /**
29
+ * Finds a font in the cache by primary name or alias.
30
+ * Font names may include or omit a file extension (e.g. `romans` or `romans.shx`).
31
+ * @param fontName The font name or alias to look up
32
+ * @returns The font data if found, undefined otherwise
33
+ */
34
+ find(fontName: string): Promise<FontData | undefined>;
28
35
  /**
29
36
  * Deletes a font from the cache
30
37
  * @param fileName The font file name (key)
@@ -60,6 +60,10 @@ export declare abstract class BaseFont {
60
60
  * @returns The shape data for the character code, or undefined if not found
61
61
  */
62
62
  abstract getCodeShape(code: number, size: number): BaseTextShape | undefined;
63
+ /**
64
+ * Gets a named SHX shape glyph when supported by the font implementation.
65
+ */
66
+ getShapeByName(_name: string, _size: number): BaseTextShape | undefined;
63
67
  /**
64
68
  * Gets the scale factor for this font.
65
69
  * This is used to adjust the size of characters when rendering.
@@ -15,6 +15,8 @@ export interface FontInfo {
15
15
  * https://developer.mozilla.org/en-US/docs/Web/API/Encoding_API/Encodings
16
16
  */
17
17
  encoding?: string;
18
+ /** Where this font entry comes from */
19
+ source?: 'remote' | 'cache';
18
20
  }
19
21
  /**
20
22
  * Represents the status of a font loading operation
@@ -128,7 +128,8 @@ export declare class FontManager {
128
128
  setFontLoader(fontLoader: FontLoader): void;
129
129
  /**
130
130
  * Retrieves information about all available fonts in the system.
131
- * Loads font metadata from a CDN if not already loaded.
131
+ * Merges remote font metadata with fonts stored in IndexedDB (cache-only
132
+ * entries are included; remote entries win when names collide).
132
133
  * @returns Promise that resolves to an array of FontInfo objects
133
134
  * @throws {Error} If font metadata cannot be loaded from the CDN
134
135
  */
@@ -149,6 +150,27 @@ export declare class FontManager {
149
150
  * @returns Promise that resolves to an array of font load statuses
150
151
  */
151
152
  loadFontsByNames(names: string | readonly string[]): Promise<FontLoadStatus[]>;
153
+ /**
154
+ * Parses a user-uploaded font file, registers it for rendering, and stores
155
+ * it in IndexedDB when {@link enableFontCache} is true.
156
+ *
157
+ * Supported formats: `.shx`, `.ttf`, `.otf`, `.woff`.
158
+ *
159
+ * @param data - Font file contents or a browser `File` selected by the user
160
+ * @param fileName - Font file name (e.g. `custom.shx`, `simkai.ttf`). Required when `data` is an `ArrayBuffer`
161
+ * @param aliases - Optional alias names for the font (e.g. AutoCAD style names)
162
+ * @param encoding - Optional character encoding for SHX bigfonts
163
+ * @returns Promise that resolves to the font load status
164
+ */
165
+ cacheFont(data: ArrayBuffer | File, fileName?: string, aliases?: string[], encoding?: string): Promise<FontLoadStatus>;
166
+ /**
167
+ * Loads a font from IndexedDB by primary name or alias.
168
+ * No-op when {@link enableFontCache} is false.
169
+ *
170
+ * @param fontName - Font name or alias (with or without file extension)
171
+ * @returns True if the font was found in cache and registered for rendering
172
+ */
173
+ loadFontFromCache(fontName: string): Promise<boolean>;
152
174
  /**
153
175
  * Loads the specified fonts from URLs
154
176
  * @param urls - URLs of font files to load.
@@ -184,16 +206,28 @@ export declare class FontManager {
184
206
  * @returns The text shape for the character, or undefined if not found
185
207
  */
186
208
  getCharShape(char: string, fontName: string, size: number): BaseTextShape | undefined;
209
+ /**
210
+ * Resolves a named SHX shape glyph from the specified font.
211
+ */
212
+ getShapeByName(name: string, fontName: string, size: number): BaseTextShape | undefined;
213
+ /**
214
+ * Resolves an SHX shape glyph by numeric character code from the specified font.
215
+ */
216
+ getShapeByCode(code: number, fontName: string, size: number): BaseTextShape | undefined;
187
217
  /**
188
218
  * Gets the text shape from the first loaded default font that contains the character.
189
219
  * Used after primary and optional bigFont lookups per AutoCAD text-style semantics.
190
220
  */
191
221
  getCharShapeFromDefaults(char: string, size: number): BaseTextShape | undefined;
192
222
  /**
193
- * Gets the text shape from configured GDT / symbol fonts (e.g. `amgdt.shx`).
194
- * Used for AutoCAD percent codes and other symbol-font code points.
223
+ * Gets the text shape from configured GDT / symbol fonts (e.g. `amgdt.shx`)
224
+ * by font-internal character code.
225
+ *
226
+ * AutoCAD `%%` symbols resolve against SHX code points (e.g. 126, 129, 132),
227
+ * not Unicode text semantics. Use {@link BaseFont.getCodeShape} so BIGFONT and
228
+ * Unicode SHX fonts are queried consistently.
195
229
  */
196
- getCharShapeFromSymbolFonts(char: string, size: number): BaseTextShape | undefined;
230
+ getCodeShapeFromSymbolFonts(code: number, size: number): BaseTextShape | undefined;
197
231
  /**
198
232
  * Gets the scale factor for a specific font
199
233
  * @param fontName - The name of the font
@@ -233,6 +267,9 @@ export declare class FontManager {
233
267
  * Loads all fonts from the cache
234
268
  */
235
269
  getAllFontsFromCache(): Promise<void>;
270
+ private cachedFontDataToFontInfo;
271
+ private resolveUploadedFontType;
272
+ private buildUploadedFontAliases;
236
273
  /**
237
274
  * Registers a loaded font under its primary name and all aliases.
238
275
  */
@@ -55,6 +55,12 @@ export declare class ShxFont extends BaseFont {
55
55
  * @returns The shape data for the character code, or undefined if not found
56
56
  */
57
57
  getCodeShape(code: number, size: number): ShxTextShape | undefined;
58
+ /**
59
+ * Gets the shape data for a named SHX shape at a given size.
60
+ *
61
+ * Shape names are matched case-insensitively via the underlying SHX parser.
62
+ */
63
+ getShapeByName(name: string, size: number): ShxTextShape | undefined;
58
64
  /** True when the SHX glyph has drawable strokes or a non-zero pen advance. */
59
65
  private static hasRenderableStrokes;
60
66
  /**
@@ -1,6 +1,7 @@
1
1
  export * from './colorUtils';
2
2
  export * from './constants';
3
3
  export * from './mtext';
4
+ export * from './shape';
4
5
  export * from './mtextDataUtils';
5
6
  export * from './styleManager';
6
7
  export * from './types';
@@ -1,6 +1,6 @@
1
1
  import { FontManager } from '../font';
2
2
  import { StyleManager } from './styleManager';
3
- import { ColorSettings, MTextData, MTextLayout, TextStyle } from './types';
3
+ import { ColorSettings, MTextData, MTextLayout, ShapeData, TextStyle } from './types';
4
4
  import * as THREE from 'three';
5
5
  /**
6
6
  * Represents an AutoCAD MText object in Three.js.
@@ -101,6 +101,12 @@ export declare class MText extends THREE.Object3D {
101
101
  * @returns The created Three.js object, or undefined if creation fails
102
102
  */
103
103
  private loadMText;
104
+ /**
105
+ * Builds and places one SHX shape glyph.
106
+ */
107
+ loadShape(shapeData: ShapeData, style: TextStyle): THREE.Object3D<THREE.Object3DEventMap> | undefined;
108
+ private finalizePlacement;
109
+ private createShapeGroup;
104
110
  /**
105
111
  * Creates a group of text elements from MText data.
106
112
  * @param mtextData - The MText data to process
@@ -275,6 +275,19 @@ export declare class MTextProcessor {
275
275
  * @param group The group to add processed geometries to
276
276
  */
277
277
  private startNewParagraph;
278
+ /**
279
+ * Renders one SHX shape glyph for AutoCAD SHAPE entities.
280
+ *
281
+ * The glyph is resolved by {@link shapeName} first, then by {@link shapeNumber}.
282
+ */
283
+ processShapeGlyph(shapeName?: string, shapeNumber?: number): THREE.Object3D | undefined;
284
+ private resolveShapeGlyph;
285
+ /**
286
+ * Builds geometry for one glyph and appends it to the output buffers.
287
+ *
288
+ * @returns Horizontal advance width after width factor and oblique skew.
289
+ */
290
+ private buildShapeGeometry;
278
291
  /**
279
292
  * Render the specified texts
280
293
  * @param item Input texts to render
@@ -292,6 +305,7 @@ export declare class MTextProcessor {
292
305
  private processBlank;
293
306
  private recordVisualLineBreak;
294
307
  private recordCurrentLineLayout;
308
+ private processPercentSymbol;
295
309
  private processChar;
296
310
  private processLastLine;
297
311
  private initLineParams;
@@ -306,6 +320,7 @@ export declare class MTextProcessor {
306
320
  * @returns Return the text shape of the specified character
307
321
  */
308
322
  private shapeHasStrokeGeometry;
323
+ private resolvePercentSymbolShape;
309
324
  private getCharShape;
310
325
  private advanceToNextLine;
311
326
  private captureCurrentLineAdvance;
@@ -0,0 +1,25 @@
1
+ import { FontManager } from '../font';
2
+ import { StyleManager } from './styleManager';
3
+ import { ColorSettings, MTextLayout, ShapeData, TextStyle } from './types';
4
+ import * as THREE from 'three';
5
+ /**
6
+ * Represents one AutoCAD SHAPE entity in Three.js.
7
+ */
8
+ export declare class Shape extends THREE.Object3D {
9
+ private _shapeData;
10
+ private _style;
11
+ private _fontsInStyleLoaded;
12
+ private _styleManager;
13
+ private _fontManager;
14
+ private _colorSettings;
15
+ private _box;
16
+ constructor(shapeData: ShapeData, style: TextStyle, styleManager: StyleManager, fontManager: FontManager, colorSettings?: ColorSettings);
17
+ get box(): THREE.Box3;
18
+ get styleManager(): StyleManager;
19
+ get textStyle(): TextStyle;
20
+ createLayoutData(): MTextLayout;
21
+ asyncDraw(): Promise<void>;
22
+ syncDraw(): void;
23
+ private createPlacementData;
24
+ private getFontName;
25
+ }
@@ -1,46 +1,21 @@
1
+ import { PercentSymbolData } from '@mlightcad/mtext-parser';
1
2
  /**
2
3
  * AutoCAD percent-sign symbol codes (`%%c`, `%%d`, `%%p`) and their SHX
3
4
  * symbol-font code points.
4
5
  *
5
- * Named percent codes are expanded by {@link @mlightcad/mtext-parser} into Unicode
6
- * before rendering. AutoCAD itself does not rely on those Unicode code points in
7
- * the primary text font; it resolves the symbols through GDT / symbol SHX fonts
8
- * such as `amgdt.shx` using legacy control-code code points.
9
- *
10
- * References:
11
- * - AutoCAD "Text Symbols and Special Characters"
12
- * - AutoCAD "Control Codes and Special Characters" (`%%nnn`)
13
- * - Legacy SHX convention: 127 = degree, 128 = plus/minus, 129 = diameter
14
- * - Modern `amgdt.shx`: degree at 126/176, ± at 177, diameter at U+2205 (∅);
15
- * code 130 = angle (∠). Legacy bytes 127–128 must not be used when CJK mesh
16
- * fonts in the fallback chain expose unrelated glyphs at those code points.
6
+ * When {@link MTextParserOptions.yieldPercentSymbols} is enabled, the parser
7
+ * emits {@link TokenType.PERCENT_SYMBOL} tokens for these codes. AutoCAD itself
8
+ * does not rely on the Unicode expansions in the primary text font; it resolves
9
+ * the symbols through GDT / symbol SHX fonts such as `amgdt.shx` using legacy
10
+ * control-code code points.
17
11
  */
18
12
  export type AutoCadPercentSymbolCode = 'c' | 'd' | 'p';
19
13
  /**
20
14
  * Ordered SHX byte-code candidates for each named AutoCAD percent symbol.
21
- * Earlier entries are preferred when present in the symbol-font fallback chain
22
15
  * Earlier entries are preferred when present in {@link FontManager.symbolFonts}.
23
16
  */
24
17
  export declare const AUTOCAD_PERCENT_SYMBOL_CONTROL_CODES: Readonly<Record<AutoCadPercentSymbolCode, readonly number[]>>;
25
18
  /**
26
- * Returns whether a character originated from an AutoCAD named percent symbol.
27
- */
28
- export declare function isAutoCadPercentSymbolChar(char: string): boolean;
29
- /**
30
- * Returns whether a character likely came from an AutoCAD numeric percent code
31
- * (`%%ddd`) expanded by mtext-parser into {@link String.fromCharCode}.
32
- *
33
- * AutoCAD resolves these byte-oriented SHX code points from GDT / symbol fonts
34
- * (e.g. `amgdt.shx`), not from the primary text font—even when the text font
35
- * defines a glyph at the same code (as with `txt.shx` at code 132).
36
- */
37
- export declare function isAutoCadNumericPercentControlCodeChar(char: string): boolean;
38
- /**
39
- * Returns ordered SHX control-code characters to try in symbol-font fallbacks
40
- * for an AutoCAD percent-symbol Unicode expansion.
41
- */
42
- export declare function getShxControlCodeCandidates(char: string): readonly string[];
43
- /**
44
- * @deprecated Use {@link getShxControlCodeCandidates} instead.
19
+ * Returns ordered font code points to try for a parser-emitted percent symbol.
45
20
  */
46
- export declare function getShxControlCodeChar(char: string): string | undefined;
21
+ export declare function getPercentSymbolLookupCodes(data: PercentSymbolData): readonly number[];
@@ -177,6 +177,25 @@ export interface MTextData {
177
177
  /** Whether to collect per-character bounding boxes for picking. Default is true */
178
178
  collectCharBoxes?: boolean;
179
179
  }
180
+ /**
181
+ * Describes one AutoCAD SHAPE entity for rendering.
182
+ */
183
+ export interface ShapeData {
184
+ /** Shape name within the SHX font (DXF group 2). */
185
+ name?: string;
186
+ /** Numeric shape code within the SHX font. */
187
+ shapeNumber?: number;
188
+ /** Shape height (DXF group 40). */
189
+ size: number;
190
+ /** Insertion point in WCS coordinates. */
191
+ position: Point3d;
192
+ /** Rotation relative to the shape OCS X axis, in radians. */
193
+ rotation?: number;
194
+ /** Extrusion/normal vector. */
195
+ directionVector?: Point3d;
196
+ /** Relative X-scale factor. */
197
+ widthFactor?: number;
198
+ }
180
199
  /**
181
200
  * Represents a text style configuration that defines the visual appearance and formatting of text.
182
201
  * This interface contains properties that control various aspects of text rendering including font,
@@ -1,5 +1,5 @@
1
1
  import { StyleManager } from '../renderer/styleManager';
2
- import { ColorSettings, MTextData, MTextLayout, TextStyle } from '../renderer/types';
2
+ import { ColorSettings, MTextData, MTextLayout, ShapeData, TextStyle } from '../renderer/types';
3
3
  import * as THREE from 'three';
4
4
  /**
5
5
  * Represents a rendered MText object that extends THREE.Object3D with additional MText-specific properties.
@@ -55,6 +55,14 @@ export interface MTextBaseRenderer {
55
55
  * @returns A Promise resolving to a populated `MTextObject` ready to add to a scene.
56
56
  */
57
57
  syncRenderMText(mtextContent: MTextData, textStyle: TextStyle, colorSettings?: ColorSettings): MTextObject;
58
+ /**
59
+ * Render one SHX shape glyph synchronously.
60
+ */
61
+ syncRenderShape(shapeContent: ShapeData, textStyle: TextStyle, colorSettings?: ColorSettings): MTextObject;
62
+ /**
63
+ * Render one SHX shape glyph asynchronously.
64
+ */
65
+ asyncRenderShape(shapeContent: ShapeData, textStyle: TextStyle, colorSettings?: ColorSettings): Promise<MTextObject>;
58
66
  /**
59
67
  * Ensure the specified fonts are available to the renderer.
60
68
  *
@@ -1,5 +1,5 @@
1
1
  import { StyleManager } from '../renderer/styleManager';
2
- import { ColorSettings, MTextData, TextStyle } from '../renderer/types';
2
+ import { ColorSettings, MTextData, ShapeData, TextStyle } from '../renderer/types';
3
3
  import { MTextBaseRenderer, MTextObject } from './baseRenderer';
4
4
  /**
5
5
  * Main thread renderer for MText objects
@@ -30,6 +30,8 @@ export declare class MainThreadRenderer implements MTextBaseRenderer {
30
30
  * that default font is loaded and fonts needed in mtext are loaded.
31
31
  */
32
32
  syncRenderMText(mtextContent: MTextData, textStyle: TextStyle, colorSettings?: ColorSettings): MTextObject;
33
+ asyncRenderShape(shapeContent: ShapeData, textStyle: TextStyle, colorSettings?: ColorSettings): Promise<MTextObject>;
34
+ syncRenderShape(shapeContent: ShapeData, textStyle: TextStyle, colorSettings?: ColorSettings): MTextObject;
33
35
  /**
34
36
  * Load fonts in the main thread
35
37
  */
@@ -1,6 +1,6 @@
1
- import { DefaultFontsPreset } from '../font';
1
+ import { DefaultFontsPreset, FontLoadStatus } from '../font';
2
2
  import { StyleManager } from '../renderer';
3
- import { ColorSettings, MTextData, TextStyle } from '../renderer/types';
3
+ import { ColorSettings, MTextData, ShapeData, TextStyle } from '../renderer/types';
4
4
  import { MTextObject } from './baseRenderer';
5
5
  import { WebWorkerRendererConfig } from './webWorkerRenderer';
6
6
  export type RenderMode = 'main' | 'worker';
@@ -57,6 +57,8 @@ export declare class UnifiedRenderer {
57
57
  * @param colorSettings - Optional color context (ByLayer, ByBlock colors).
58
58
  */
59
59
  syncRenderMText(mtextContent: MTextData, textStyle: TextStyle, colorSettings?: ColorSettings): MTextObject;
60
+ asyncRenderShape(shapeContent: ShapeData, textStyle: TextStyle, colorSettings?: ColorSettings, _mode?: RenderMode): Promise<MTextObject>;
61
+ syncRenderShape(shapeContent: ShapeData, textStyle: TextStyle, colorSettings?: ColorSettings): MTextObject;
60
62
  /**
61
63
  * Sets the default font fallback chain on the active renderer and workers.
62
64
  */
@@ -83,6 +85,12 @@ export declare class UnifiedRenderer {
83
85
  name: string[];
84
86
  }>;
85
87
  }>;
88
+ /**
89
+ * Parse and cache a user-uploaded font file in IndexedDB.
90
+ * Always runs on the main-thread {@link FontManager} so the cache is shared
91
+ * with the web worker renderer.
92
+ */
93
+ cacheFont(data: ArrayBuffer | File, fileName?: string, aliases?: string[], encoding?: string): Promise<FontLoadStatus>;
86
94
  /**
87
95
  * Clean up resources
88
96
  */
@@ -1,5 +1,5 @@
1
1
  import { StyleManager } from '../renderer/styleManager';
2
- import { CharBox, ColorSettings, MTextData, TextStyle } from '../renderer/types';
2
+ import { CharBox, ColorSettings, MTextData, ShapeData, TextStyle } from '../renderer/types';
3
3
  import { MTextBaseRenderer, MTextObject } from './baseRenderer';
4
4
  /**
5
5
  * Configuration options for WebWorkerRenderer
@@ -171,6 +171,8 @@ export declare class WebWorkerRenderer implements MTextBaseRenderer {
171
171
  * Notes: It isn't supported yet.
172
172
  */
173
173
  syncRenderMText(_mtextContent: MTextData, _textStyle: TextStyle, _colorSettings?: ColorSettings): MTextObject;
174
+ asyncRenderShape(_shapeContent: ShapeData, _textStyle: TextStyle, _colorSettings?: ColorSettings): Promise<MTextObject>;
175
+ syncRenderShape(_shapeContent: ShapeData, _textStyle: TextStyle, _colorSettings?: ColorSettings): MTextObject;
174
176
  loadFonts(fonts: readonly string[]): Promise<{
175
177
  loaded: string[];
176
178
  }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mlightcad/mtext-renderer",
3
- "version": "0.11.0",
3
+ "version": "0.11.2",
4
4
  "description": "AutoCAD MText renderer based on Three.js",
5
5
  "license": "MIT",
6
6
  "author": "MLight Lee <mlight.lee@outlook.com>",
@@ -24,6 +24,16 @@
24
24
  "README.md",
25
25
  "package.json"
26
26
  ],
27
+ "nx": {
28
+ "targets": {
29
+ "build": {
30
+ "outputs": [
31
+ "{projectRoot}/dist",
32
+ "{projectRoot}/lib"
33
+ ]
34
+ }
35
+ }
36
+ },
27
37
  "keywords": [
28
38
  "autocad",
29
39
  "mtext",
@@ -33,7 +43,7 @@
33
43
  "3d-text"
34
44
  ],
35
45
  "dependencies": {
36
- "@mlightcad/mtext-parser": "^1.4.1",
46
+ "@mlightcad/mtext-parser": "^1.5.0",
37
47
  "@mlightcad/shx-parser": "^1.3.4",
38
48
  "iconv-lite": "^0.7.0",
39
49
  "idb": "^8.0.3",