@empty-sekai/sekai-custom-profile-sdk 0.3.0

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.
Files changed (130) hide show
  1. package/LICENSE +235 -0
  2. package/LICENSE-EXCEPTION +32 -0
  3. package/NOTICE +11 -0
  4. package/README.en.md +456 -0
  5. package/README.md +458 -0
  6. package/dist/allium_renderer_wasm.js +14 -0
  7. package/dist/allium_renderer_wasm.wasm +0 -0
  8. package/dist/authoring.d.ts +14 -0
  9. package/dist/authoring.js +34 -0
  10. package/dist/cache/glyphPersistentCache.d.ts +145 -0
  11. package/dist/cache/glyphPersistentCache.js +346 -0
  12. package/dist/cache/indexedDbGlyphRecordStore.d.ts +26 -0
  13. package/dist/cache/indexedDbGlyphRecordStore.js +214 -0
  14. package/dist/cache/sessionImageResourceCache.d.ts +39 -0
  15. package/dist/cache/sessionImageResourceCache.js +156 -0
  16. package/dist/emscripten.d.ts +11 -0
  17. package/dist/emscripten.js +1 -0
  18. package/dist/fontProvider.d.ts +36 -0
  19. package/dist/fontProvider.js +84 -0
  20. package/dist/fontSdfAtlas.d.ts +92 -0
  21. package/dist/fontSdfAtlas.js +296 -0
  22. package/dist/gpu/browserSemanticResources.d.ts +64 -0
  23. package/dist/gpu/browserSemanticResources.js +232 -0
  24. package/dist/gpu/generalTextRenderPlacement.d.ts +8 -0
  25. package/dist/gpu/generalTextRenderPlacement.js +131 -0
  26. package/dist/gpu/previewTransformTextureLayout.d.ts +1 -0
  27. package/dist/gpu/previewTransformTextureLayout.js +12 -0
  28. package/dist/gpu/semanticCommandGeometry.d.ts +21 -0
  29. package/dist/gpu/semanticCommandGeometry.js +226 -0
  30. package/dist/gpu/semanticCommandPlanner.d.ts +131 -0
  31. package/dist/gpu/semanticCommandPlanner.js +203 -0
  32. package/dist/gpu/semanticTextGlyphBridge.d.ts +3 -0
  33. package/dist/gpu/semanticTextGlyphBridge.js +22 -0
  34. package/dist/gpu/semanticWebglSceneRenderer.d.ts +70 -0
  35. package/dist/gpu/semanticWebglSceneRenderer.js +211 -0
  36. package/dist/gpu/slotRanges.d.ts +5 -0
  37. package/dist/gpu/slotRanges.js +14 -0
  38. package/dist/gpu/webglSdfAtlasTexture.d.ts +17 -0
  39. package/dist/gpu/webglSdfAtlasTexture.js +72 -0
  40. package/dist/gpu/webglSdfGlyphPipeline.d.ts +26 -0
  41. package/dist/gpu/webglSdfGlyphPipeline.js +267 -0
  42. package/dist/gpu/webglSemanticCommandExecutor.d.ts +79 -0
  43. package/dist/gpu/webglSemanticCommandExecutor.js +686 -0
  44. package/dist/index.d.ts +18 -0
  45. package/dist/index.js +8 -0
  46. package/dist/interaction/numericTextRegions.d.ts +46 -0
  47. package/dist/interaction/numericTextRegions.js +44 -0
  48. package/dist/localizationProvider.d.ts +33 -0
  49. package/dist/localizationProvider.js +74 -0
  50. package/dist/originPrebuiltSdfAtlasPackage.d.ts +39 -0
  51. package/dist/originPrebuiltSdfAtlasPackage.js +316 -0
  52. package/dist/prebuiltSdfAtlas.d.ts +36 -0
  53. package/dist/prebuiltSdfAtlas.js +261 -0
  54. package/dist/protocol.d.ts +456 -0
  55. package/dist/protocol.js +1 -0
  56. package/dist/renderer.d.ts +218 -0
  57. package/dist/renderer.js +641 -0
  58. package/dist/resourceProvider.d.ts +24 -0
  59. package/dist/resourceProvider.js +41 -0
  60. package/dist/telemetry/rendererTelemetry.d.ts +158 -0
  61. package/dist/telemetry/rendererTelemetry.js +232 -0
  62. package/dist/third-party/freetype/FTL.txt +169 -0
  63. package/dist/types/atlas.d.ts +90 -0
  64. package/dist/types/atlas.js +1 -0
  65. package/dist/types/authoring.d.ts +81 -0
  66. package/dist/types/authoring.js +1 -0
  67. package/dist/types/core.d.ts +128 -0
  68. package/dist/types/core.js +1 -0
  69. package/dist/types/freeType.d.ts +54 -0
  70. package/dist/types/freeType.js +13 -0
  71. package/dist/types/glyph.d.ts +33 -0
  72. package/dist/types/glyph.js +1 -0
  73. package/dist/types/layout.d.ts +25 -0
  74. package/dist/types/layout.js +1 -0
  75. package/dist/types/text.d.ts +28 -0
  76. package/dist/types/text.js +1 -0
  77. package/dist/worker/glyphWorkScheduler.d.ts +29 -0
  78. package/dist/worker/glyphWorkScheduler.js +107 -0
  79. package/dist/worker-client.d.ts +114 -0
  80. package/dist/worker-client.js +413 -0
  81. package/dist/worker.d.ts +1 -0
  82. package/dist/worker.js +708 -0
  83. package/package.json +46 -0
  84. package/src/atlas.rs +652 -0
  85. package/src/authoring.ts +42 -0
  86. package/src/authoring_runtime.rs +303 -0
  87. package/src/cache/glyphPersistentCache.ts +463 -0
  88. package/src/cache/indexedDbGlyphRecordStore.ts +238 -0
  89. package/src/cache/sessionImageResourceCache.ts +186 -0
  90. package/src/edt.rs +97 -0
  91. package/src/emscripten.ts +17 -0
  92. package/src/fontProvider.ts +127 -0
  93. package/src/fontSdfAtlas.ts +431 -0
  94. package/src/geometry.rs +149 -0
  95. package/src/glyph_plan.rs +226 -0
  96. package/src/gpu/browserSemanticResources.ts +294 -0
  97. package/src/gpu/generalTextRenderPlacement.ts +175 -0
  98. package/src/gpu/previewTransformTextureLayout.ts +12 -0
  99. package/src/gpu/semanticCommandGeometry.ts +260 -0
  100. package/src/gpu/semanticCommandPlanner.ts +280 -0
  101. package/src/gpu/semanticTextGlyphBridge.ts +35 -0
  102. package/src/gpu/semanticWebglSceneRenderer.ts +261 -0
  103. package/src/gpu/slotRanges.ts +15 -0
  104. package/src/gpu/webglSdfAtlasTexture.ts +69 -0
  105. package/src/gpu/webglSdfGlyphPipeline.ts +299 -0
  106. package/src/gpu/webglSemanticCommandExecutor.ts +739 -0
  107. package/src/index.ts +84 -0
  108. package/src/interaction/numericTextRegions.ts +80 -0
  109. package/src/layout.rs +1882 -0
  110. package/src/lib.rs +1443 -0
  111. package/src/localizationProvider.ts +113 -0
  112. package/src/main.rs +55 -0
  113. package/src/masterdata_runtime.rs +496 -0
  114. package/src/originPrebuiltSdfAtlasPackage.ts +403 -0
  115. package/src/prebuiltSdfAtlas.ts +306 -0
  116. package/src/protocol.ts +150 -0
  117. package/src/renderer.ts +792 -0
  118. package/src/resourceProvider.ts +69 -0
  119. package/src/scene.rs +665 -0
  120. package/src/telemetry/rendererTelemetry.ts +358 -0
  121. package/src/types/atlas.ts +80 -0
  122. package/src/types/authoring.ts +85 -0
  123. package/src/types/core.ts +110 -0
  124. package/src/types/freeType.ts +63 -0
  125. package/src/types/glyph.ts +33 -0
  126. package/src/types/layout.ts +28 -0
  127. package/src/types/text.ts +28 -0
  128. package/src/worker/glyphWorkScheduler.ts +130 -0
  129. package/src/worker-client.ts +484 -0
  130. package/src/worker.ts +895 -0
@@ -0,0 +1,41 @@
1
+ export function profileResourceDescriptors(preparation) {
2
+ const resources = preparation.resources;
3
+ if (!Array.isArray(resources))
4
+ throw new Error("Profile preparation did not return a resource list");
5
+ return resources.map((entry) => {
6
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
7
+ throw new Error("Profile resource entry is invalid");
8
+ }
9
+ const request = entry;
10
+ const resource = request.resource;
11
+ const fallback = request.fallback;
12
+ if (!resource || typeof resource !== "object" || Array.isArray(resource)) {
13
+ throw new Error("Profile resource key is missing");
14
+ }
15
+ if (!fallback || typeof fallback !== "object" || Array.isArray(fallback)) {
16
+ throw new Error("Profile resource fallback metric is missing");
17
+ }
18
+ const { namespace, key } = resource;
19
+ const { width, height } = fallback;
20
+ if (typeof namespace !== "string" || typeof key !== "string" || typeof request.lookup_key !== "string") {
21
+ throw new Error("Profile resource identity is invalid");
22
+ }
23
+ if (!isMetric(width) || !isMetric(height))
24
+ throw new Error("Profile resource fallback metric is invalid");
25
+ const provenance = request.provenance;
26
+ if (provenance != null && (typeof provenance !== "object" || Array.isArray(provenance))) {
27
+ throw new Error("Profile resource provenance is invalid");
28
+ }
29
+ return {
30
+ id: `${namespace}\0${key}`,
31
+ namespace,
32
+ key,
33
+ role: request.lookup_key,
34
+ provenance: provenance == null ? {} : { ...provenance },
35
+ expectedSize: { width, height },
36
+ };
37
+ });
38
+ }
39
+ function isMetric(value) {
40
+ return typeof value === "number" && Number.isFinite(value) && value >= 0;
41
+ }
@@ -0,0 +1,158 @@
1
+ export type TelemetryLevel = "off" | "summary" | "trace";
2
+ export type RendererTelemetrySample = {
3
+ frameId: number;
4
+ gpuEpoch: number;
5
+ timingsMs: Record<string, number | null>;
6
+ workload: Record<string, number>;
7
+ recovery: {
8
+ contextLosses: number;
9
+ restoreMs: number | null;
10
+ [key: string]: number | null;
11
+ };
12
+ [key: string]: unknown;
13
+ };
14
+ export type TelemetryDistribution = {
15
+ p50: number;
16
+ p95: number;
17
+ max: number;
18
+ samples: number;
19
+ };
20
+ export type RendererTelemetrySnapshot = {
21
+ schemaVersion: 1;
22
+ level: Exclude<TelemetryLevel, "off">;
23
+ last: RendererTelemetrySample;
24
+ summary: Record<string, TelemetryDistribution>;
25
+ recordedFrames: number;
26
+ droppedFrames: number;
27
+ samples?: RendererTelemetrySample[];
28
+ };
29
+ export declare class RendererTelemetry {
30
+ private readonly level;
31
+ private readonly maxSamples;
32
+ private readonly summaryEvery;
33
+ private readonly samples;
34
+ private readonly timingValues;
35
+ private last;
36
+ private recordedFrames;
37
+ private droppedFrames;
38
+ private cachedSummary;
39
+ constructor(options?: {
40
+ level?: TelemetryLevel;
41
+ maxSamples?: number;
42
+ summaryEvery?: number;
43
+ });
44
+ record(sample: RendererTelemetrySample): void;
45
+ snapshot(): RendererTelemetrySnapshot | null;
46
+ stats(): {
47
+ level: TelemetryLevel;
48
+ recordedFrames: number;
49
+ retainedSamples: number;
50
+ droppedFrames: number;
51
+ };
52
+ }
53
+ export type RendererTelemetryOptions = {
54
+ level?: TelemetryLevel;
55
+ maxSamples?: number;
56
+ summaryEvery?: number;
57
+ };
58
+ export type RendererAtlasSummary = {
59
+ backend: "edt" | "analytic";
60
+ pages: number;
61
+ glyphs: number;
62
+ missingGlyphs: number;
63
+ generation: {
64
+ glyphs: number;
65
+ pixels: number;
66
+ glyphMs: number;
67
+ faceLoadMs: number;
68
+ };
69
+ cache: {
70
+ hits: number;
71
+ misses: number;
72
+ generations: number;
73
+ bytes: number;
74
+ sessionHits: number;
75
+ persistentHits: number;
76
+ persistentMisses: number;
77
+ persistentWritesQueued: number;
78
+ pinnedPages: number;
79
+ pageEvictions: number;
80
+ } | null;
81
+ };
82
+ export type RendererGpuSummary = {
83
+ drawCalls: number;
84
+ geometryBuilds: number;
85
+ vertexBytes: number;
86
+ textureUploads: number;
87
+ textureBytes: number;
88
+ stateUploadBytes: number;
89
+ maskUploadBytes: number;
90
+ glyphGeometryBuilds: number;
91
+ isolationBegins: number;
92
+ isolationComposites: number;
93
+ isolationTargetAllocations: number;
94
+ isolationTextureBytes: number;
95
+ };
96
+ export type RendererUploadSummary = {
97
+ stateUploadBytes: number;
98
+ maskUploadBytes: number;
99
+ commandMaskUploadBytes: number;
100
+ commandStateUploadBytes: number;
101
+ };
102
+ export type RendererRestoreUploadSummary = {
103
+ atlasUploadBytes: number;
104
+ atlasUploadRects: number;
105
+ textureUploads: number;
106
+ textureBytes: number;
107
+ };
108
+ export type RendererRuntimeSnapshot = {
109
+ schemaVersion: 1;
110
+ state: "ready" | "context-lost" | "destroyed";
111
+ gpuEpoch: number;
112
+ frames: number;
113
+ bootstrap: {
114
+ textCommands: number;
115
+ glyphInstances: number;
116
+ atlasUploadBytes: number;
117
+ atlasUploadRects: number;
118
+ };
119
+ atlas: RendererAtlasSummary;
120
+ lastGpu: RendererGpuSummary | null;
121
+ updates: RendererUploadSummary;
122
+ recovery: {
123
+ contextLosses: number;
124
+ contextRestores: number;
125
+ restoreFailures: number;
126
+ lastRestoreMs: number | null;
127
+ lastRestoreUploads: RendererRestoreUploadSummary | null;
128
+ };
129
+ telemetry: RendererTelemetrySnapshot | null;
130
+ };
131
+ /** Tracks aggregate rendering health without retaining source text, stable ids,
132
+ * resource URLs, font names, or player data. */
133
+ export declare class RendererRuntimeTelemetry {
134
+ private readonly telemetry;
135
+ private readonly atlas;
136
+ private readonly bootstrap;
137
+ private runtimeState;
138
+ private gpuEpoch;
139
+ private frames;
140
+ private lastGpu;
141
+ private updates;
142
+ private contextLosses;
143
+ private contextRestores;
144
+ private restoreFailures;
145
+ private lastRestoreMs;
146
+ private lastRestoreUploads;
147
+ constructor(options: RendererTelemetryOptions, atlas: RendererAtlasSummary, bootstrap: RendererRuntimeSnapshot["bootstrap"]);
148
+ state(): RendererRuntimeSnapshot["state"];
149
+ recordDraw(metrics: RendererGpuSummary, submitCpuMs: number): void;
150
+ recordPatch(patch: Partial<RendererUploadSummary>): void;
151
+ markContextLost(): void;
152
+ markContextRestored(restoreMs: number, uploads: RendererRestoreUploadSummary): void;
153
+ markRestoreFailed(restoreMs: number): void;
154
+ markDestroyed(): void;
155
+ snapshot(): RendererRuntimeSnapshot;
156
+ }
157
+ export declare function normalizeGpuTimerResult(nanoseconds: number | undefined, disjoint: boolean): number | null;
158
+ export declare function assertTelemetryPrivacy(value: unknown): void;
@@ -0,0 +1,232 @@
1
+ const MAX_TRACE_SAMPLES = 240;
2
+ export class RendererTelemetry {
3
+ level;
4
+ maxSamples;
5
+ summaryEvery;
6
+ samples = [];
7
+ timingValues = new Map();
8
+ last = null;
9
+ recordedFrames = 0;
10
+ droppedFrames = 0;
11
+ cachedSummary = {};
12
+ constructor(options = {}) {
13
+ this.level = options.level ?? "summary";
14
+ const requestedSamples = options.maxSamples ?? MAX_TRACE_SAMPLES;
15
+ this.maxSamples = Number.isFinite(requestedSamples)
16
+ ? Math.min(MAX_TRACE_SAMPLES, Math.max(1, Math.trunc(requestedSamples)))
17
+ : MAX_TRACE_SAMPLES;
18
+ this.summaryEvery = Math.max(1, options.summaryEvery ?? 30);
19
+ }
20
+ record(sample) {
21
+ if (this.level === "off")
22
+ return;
23
+ assertTelemetryPrivacy(sample);
24
+ const sanitized = structuredClone(sample);
25
+ this.last = sanitized;
26
+ this.recordedFrames += 1;
27
+ for (const [name, value] of Object.entries(sample.timingsMs)) {
28
+ if (value == null || !Number.isFinite(value))
29
+ continue;
30
+ const values = this.timingValues.get(name) ?? [];
31
+ values.push(value);
32
+ if (values.length > this.maxSamples)
33
+ values.splice(0, values.length - this.maxSamples);
34
+ this.timingValues.set(name, values);
35
+ }
36
+ if (this.level === "trace") {
37
+ this.samples.push(sanitized);
38
+ if (this.samples.length > this.maxSamples) {
39
+ this.droppedFrames += this.samples.length - this.maxSamples;
40
+ this.samples.splice(0, this.samples.length - this.maxSamples);
41
+ }
42
+ }
43
+ if (this.recordedFrames % this.summaryEvery === 0 || Object.keys(this.cachedSummary).length === 0) {
44
+ this.cachedSummary = summarize(this.timingValues);
45
+ }
46
+ }
47
+ snapshot() {
48
+ if (this.level === "off" || !this.last)
49
+ return null;
50
+ const snapshot = {
51
+ schemaVersion: 1,
52
+ level: this.level,
53
+ last: structuredClone(this.last),
54
+ summary: structuredClone(summarize(this.timingValues)),
55
+ recordedFrames: this.recordedFrames,
56
+ droppedFrames: this.droppedFrames,
57
+ };
58
+ if (this.level === "trace")
59
+ snapshot.samples = structuredClone(this.samples);
60
+ assertTelemetryPrivacy(snapshot);
61
+ return snapshot;
62
+ }
63
+ stats() {
64
+ return {
65
+ level: this.level,
66
+ recordedFrames: this.recordedFrames,
67
+ retainedSamples: this.samples.length,
68
+ droppedFrames: this.droppedFrames,
69
+ };
70
+ }
71
+ }
72
+ /** Tracks aggregate rendering health without retaining source text, stable ids,
73
+ * resource URLs, font names, or player data. */
74
+ export class RendererRuntimeTelemetry {
75
+ telemetry;
76
+ atlas;
77
+ bootstrap;
78
+ runtimeState = "ready";
79
+ gpuEpoch = 1;
80
+ frames = 0;
81
+ lastGpu = null;
82
+ updates = {
83
+ stateUploadBytes: 0,
84
+ maskUploadBytes: 0,
85
+ commandMaskUploadBytes: 0,
86
+ commandStateUploadBytes: 0,
87
+ };
88
+ contextLosses = 0;
89
+ contextRestores = 0;
90
+ restoreFailures = 0;
91
+ lastRestoreMs = null;
92
+ lastRestoreUploads = null;
93
+ constructor(options, atlas, bootstrap) {
94
+ this.telemetry = new RendererTelemetry(options);
95
+ this.atlas = structuredClone(atlas);
96
+ this.bootstrap = structuredClone(bootstrap);
97
+ assertTelemetryPrivacy(this.atlas);
98
+ }
99
+ state() {
100
+ return this.runtimeState;
101
+ }
102
+ recordDraw(metrics, submitCpuMs) {
103
+ this.lastGpu = structuredClone(metrics);
104
+ this.frames += 1;
105
+ this.telemetry.record({
106
+ frameId: this.frames,
107
+ gpuEpoch: this.gpuEpoch,
108
+ timingsMs: {
109
+ gpuSubmitCpu: finiteOrNull(submitCpuMs),
110
+ gpuTime: null,
111
+ total: finiteOrNull(submitCpuMs),
112
+ },
113
+ workload: {
114
+ drawCalls: metrics.drawCalls,
115
+ vertexBytes: metrics.vertexBytes,
116
+ textureUploads: metrics.textureUploads,
117
+ textureBytes: metrics.textureBytes,
118
+ dirtyBytes: this.updates.stateUploadBytes
119
+ + this.updates.maskUploadBytes
120
+ + this.updates.commandMaskUploadBytes
121
+ + this.updates.commandStateUploadBytes,
122
+ },
123
+ recovery: {
124
+ contextLosses: this.contextLosses,
125
+ contextRestores: this.contextRestores,
126
+ restoreFailures: this.restoreFailures,
127
+ restoreMs: this.lastRestoreMs,
128
+ },
129
+ });
130
+ }
131
+ recordPatch(patch) {
132
+ for (const key of Object.keys(this.updates)) {
133
+ this.updates[key] += patch[key] ?? 0;
134
+ }
135
+ }
136
+ markContextLost() {
137
+ if (this.runtimeState === "destroyed" || this.runtimeState === "context-lost")
138
+ return;
139
+ this.runtimeState = "context-lost";
140
+ this.contextLosses += 1;
141
+ }
142
+ markContextRestored(restoreMs, uploads) {
143
+ if (this.runtimeState === "destroyed")
144
+ return;
145
+ this.runtimeState = "ready";
146
+ this.contextRestores += 1;
147
+ this.gpuEpoch += 1;
148
+ this.lastRestoreMs = finiteOrNull(restoreMs);
149
+ this.lastRestoreUploads = structuredClone(uploads);
150
+ }
151
+ markRestoreFailed(restoreMs) {
152
+ if (this.runtimeState === "destroyed")
153
+ return;
154
+ this.runtimeState = "context-lost";
155
+ this.restoreFailures += 1;
156
+ this.lastRestoreMs = finiteOrNull(restoreMs);
157
+ }
158
+ markDestroyed() {
159
+ this.runtimeState = "destroyed";
160
+ }
161
+ snapshot() {
162
+ const snapshot = {
163
+ schemaVersion: 1,
164
+ state: this.runtimeState,
165
+ gpuEpoch: this.gpuEpoch,
166
+ frames: this.frames,
167
+ bootstrap: structuredClone(this.bootstrap),
168
+ atlas: structuredClone(this.atlas),
169
+ lastGpu: structuredClone(this.lastGpu),
170
+ updates: structuredClone(this.updates),
171
+ recovery: {
172
+ contextLosses: this.contextLosses,
173
+ contextRestores: this.contextRestores,
174
+ restoreFailures: this.restoreFailures,
175
+ lastRestoreMs: this.lastRestoreMs,
176
+ lastRestoreUploads: structuredClone(this.lastRestoreUploads),
177
+ },
178
+ telemetry: this.telemetry.snapshot(),
179
+ };
180
+ assertTelemetryPrivacy(snapshot);
181
+ return snapshot;
182
+ }
183
+ }
184
+ export function normalizeGpuTimerResult(nanoseconds, disjoint) {
185
+ if (disjoint || nanoseconds == null || !Number.isFinite(nanoseconds) || nanoseconds < 0)
186
+ return null;
187
+ return nanoseconds / 1_000_000;
188
+ }
189
+ const FORBIDDEN_FIELDS = new Set([
190
+ "rawtext",
191
+ "sourcecontent",
192
+ "userid",
193
+ "profileseq",
194
+ "documentdigest",
195
+ "fontpath",
196
+ "fonturl",
197
+ "character",
198
+ "scalar",
199
+ "cluster",
200
+ ]);
201
+ export function assertTelemetryPrivacy(value) {
202
+ visit(value, "telemetry");
203
+ }
204
+ function visit(value, path) {
205
+ if (value == null || typeof value !== "object")
206
+ return;
207
+ if (Array.isArray(value)) {
208
+ value.forEach((entry, index) => visit(entry, `${path}[${index}]`));
209
+ return;
210
+ }
211
+ for (const [key, child] of Object.entries(value)) {
212
+ const normalized = key.replace(/[_-]/g, "").toLowerCase();
213
+ if (FORBIDDEN_FIELDS.has(normalized))
214
+ throw new Error(`forbidden telemetry field ${path}.${key}`);
215
+ visit(child, `${path}.${key}`);
216
+ }
217
+ }
218
+ function summarize(values) {
219
+ return Object.fromEntries([...values.entries()].map(([name, source]) => {
220
+ const sorted = [...source].sort((a, b) => a - b);
221
+ const quantile = (q) => sorted[Math.min(sorted.length - 1, Math.floor((sorted.length - 1) * q))] ?? 0;
222
+ return [name, {
223
+ p50: quantile(0.5),
224
+ p95: quantile(0.95),
225
+ max: quantile(1),
226
+ samples: sorted.length,
227
+ }];
228
+ }));
229
+ }
230
+ function finiteOrNull(value) {
231
+ return Number.isFinite(value) && value >= 0 ? value : null;
232
+ }
@@ -0,0 +1,169 @@
1
+ The FreeType Project LICENSE
2
+ ----------------------------
3
+
4
+ 2006-Jan-27
5
+
6
+ Copyright 1996-2002, 2006 by
7
+ David Turner, Robert Wilhelm, and Werner Lemberg
8
+
9
+
10
+
11
+ Introduction
12
+ ============
13
+
14
+ The FreeType Project is distributed in several archive packages;
15
+ some of them may contain, in addition to the FreeType font engine,
16
+ various tools and contributions which rely on, or relate to, the
17
+ FreeType Project.
18
+
19
+ This license applies to all files found in such packages, and
20
+ which do not fall under their own explicit license. The license
21
+ affects thus the FreeType font engine, the test programs,
22
+ documentation and makefiles, at the very least.
23
+
24
+ This license was inspired by the BSD, Artistic, and IJG
25
+ (Independent JPEG Group) licenses, which all encourage inclusion
26
+ and use of free software in commercial and freeware products
27
+ alike. As a consequence, its main points are that:
28
+
29
+ o We don't promise that this software works. However, we will be
30
+ interested in any kind of bug reports. (`as is' distribution)
31
+
32
+ o You can use this software for whatever you want, in parts or
33
+ full form, without having to pay us. (`royalty-free' usage)
34
+
35
+ o You may not pretend that you wrote this software. If you use
36
+ it, or only parts of it, in a program, you must acknowledge
37
+ somewhere in your documentation that you have used the
38
+ FreeType code. (`credits')
39
+
40
+ We specifically permit and encourage the inclusion of this
41
+ software, with or without modifications, in commercial products.
42
+ We disclaim all warranties covering The FreeType Project and
43
+ assume no liability related to The FreeType Project.
44
+
45
+
46
+ Finally, many people asked us for a preferred form for a
47
+ credit/disclaimer to use in compliance with this license. We thus
48
+ encourage you to use the following text:
49
+
50
+ """
51
+ Portions of this software are copyright © <year> The FreeType
52
+ Project (www.freetype.org). All rights reserved.
53
+ """
54
+
55
+ Please replace <year> with the value from the FreeType version you
56
+ actually use.
57
+
58
+
59
+ Legal Terms
60
+ ===========
61
+
62
+ 0. Definitions
63
+ --------------
64
+
65
+ Throughout this license, the terms `package', `FreeType Project',
66
+ and `FreeType archive' refer to the set of files originally
67
+ distributed by the authors (David Turner, Robert Wilhelm, and
68
+ Werner Lemberg) as the `FreeType Project', be they named as alpha,
69
+ beta or final release.
70
+
71
+ `You' refers to the licensee, or person using the project, where
72
+ `using' is a generic term including compiling the project's source
73
+ code as well as linking it to form a `program' or `executable'.
74
+ This program is referred to as `a program using the FreeType
75
+ engine'.
76
+
77
+ This license applies to all files distributed in the original
78
+ FreeType Project, including all source code, binaries and
79
+ documentation, unless otherwise stated in the file in its
80
+ original, unmodified form as distributed in the original archive.
81
+ If you are unsure whether or not a particular file is covered by
82
+ this license, you must contact us to verify this.
83
+
84
+ The FreeType Project is copyright (C) 1996-2000 by David Turner,
85
+ Robert Wilhelm, and Werner Lemberg. All rights reserved except as
86
+ specified below.
87
+
88
+ 1. No Warranty
89
+ --------------
90
+
91
+ THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY
92
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
93
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94
+ PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
95
+ BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO
96
+ USE, OF THE FREETYPE PROJECT.
97
+
98
+ 2. Redistribution
99
+ -----------------
100
+
101
+ This license grants a worldwide, royalty-free, perpetual and
102
+ irrevocable right and license to use, execute, perform, compile,
103
+ display, copy, create derivative works of, distribute and
104
+ sublicense the FreeType Project (in both source and object code
105
+ forms) and derivative works thereof for any purpose; and to
106
+ authorize others to exercise some or all of the rights granted
107
+ herein, subject to the following conditions:
108
+
109
+ o Redistribution of source code must retain this license file
110
+ (`FTL.TXT') unaltered; any additions, deletions or changes to
111
+ the original files must be clearly indicated in accompanying
112
+ documentation. The copyright notices of the unaltered,
113
+ original files must be preserved in all copies of source
114
+ files.
115
+
116
+ o Redistribution in binary form must provide a disclaimer that
117
+ states that the software is based in part of the work of the
118
+ FreeType Team, in the distribution documentation. We also
119
+ encourage you to put an URL to the FreeType web page in your
120
+ documentation, though this isn't mandatory.
121
+
122
+ These conditions apply to any software derived from or based on
123
+ the FreeType Project, not just the unmodified files. If you use
124
+ our work, you must acknowledge us. However, no fee need be paid
125
+ to us.
126
+
127
+ 3. Advertising
128
+ --------------
129
+
130
+ Neither the FreeType authors and contributors nor you shall use
131
+ the name of the other for commercial, advertising, or promotional
132
+ purposes without specific prior written permission.
133
+
134
+ We suggest, but do not require, that you use one or more of the
135
+ following phrases to refer to this software in your documentation
136
+ or advertising materials: `FreeType Project', `FreeType Engine',
137
+ `FreeType library', or `FreeType Distribution'.
138
+
139
+ As you have not signed this license, you are not required to
140
+ accept it. However, as the FreeType Project is copyrighted
141
+ material, only this license, or another one contracted with the
142
+ authors, grants you the right to use, distribute, and modify it.
143
+ Therefore, by using, distributing, or modifying the FreeType
144
+ Project, you indicate that you understand and accept all the terms
145
+ of this license.
146
+
147
+ 4. Contacts
148
+ -----------
149
+
150
+ There are two mailing lists related to FreeType:
151
+
152
+ o freetype@nongnu.org
153
+
154
+ Discusses general use and applications of FreeType, as well as
155
+ future and wanted additions to the library and distribution.
156
+ If you are looking for support, start in this list if you
157
+ haven't found anything to help you in the documentation.
158
+
159
+ o freetype-devel@nongnu.org
160
+
161
+ Discusses bugs, as well as engine internals, design issues,
162
+ specific licenses, porting, etc.
163
+
164
+ Our home page can be found at
165
+
166
+ https://www.freetype.org
167
+
168
+
169
+ --- end of FTL.TXT ---
@@ -0,0 +1,90 @@
1
+ import type { GlyphBatchRequest } from "../protocol.js";
2
+ import type { GlyphRasterIdentity } from "../cache/glyphPersistentCache.js";
3
+ export type GlyphRasterPlan = {
4
+ region: string;
5
+ family: string;
6
+ fontSourceHash: string;
7
+ schemaNamespace: string;
8
+ fontEngineFingerprint: string;
9
+ rasterContractId: string;
10
+ contractId: string;
11
+ backend: "edt" | "analytic";
12
+ supersample: number;
13
+ baseSize: number;
14
+ spread: number;
15
+ atlasWidth: number;
16
+ atlasHeight: number;
17
+ glyphs: Array<{
18
+ ch: string;
19
+ glyphIndex: number;
20
+ identity: GlyphRasterIdentity;
21
+ }>;
22
+ missing: string[];
23
+ };
24
+ export type AtlasPixelRect = {
25
+ x: number;
26
+ y: number;
27
+ width: number;
28
+ height: number;
29
+ };
30
+ export type AtlasPlacement = {
31
+ page: number;
32
+ pageEpoch: number;
33
+ pixelRect: AtlasPixelRect;
34
+ u0: number;
35
+ v0: number;
36
+ u1: number;
37
+ v1: number;
38
+ };
39
+ export type AtlasGlyphRecord = {
40
+ key: string;
41
+ glyphIndex: number;
42
+ width: number;
43
+ height: number;
44
+ advance: number;
45
+ xOffset: number;
46
+ yOffset: number;
47
+ planeBearingX: number;
48
+ planeBearingY: number;
49
+ planeWidth: number;
50
+ planeHeight: number;
51
+ drawable: boolean;
52
+ pixels: Uint8Array;
53
+ };
54
+ export type AtlasGenerateRequest = GlyphBatchRequest & {
55
+ glyphs: Array<{
56
+ key: string;
57
+ char: string;
58
+ glyphIndex: number;
59
+ }>;
60
+ };
61
+ export type AtlasStats = {
62
+ pages: number;
63
+ pinnedPages: number;
64
+ glyphs: number;
65
+ atlasBytes: number;
66
+ evictions: number;
67
+ pageAllocations: number;
68
+ hardBudgetBytes: number;
69
+ };
70
+ export type AtlasResolveResult = {
71
+ leases: number[];
72
+ placements: Array<{
73
+ key: string;
74
+ placement: AtlasPlacement;
75
+ }>;
76
+ missingKeys: string[];
77
+ generated: AtlasGlyphRecord[];
78
+ stats: AtlasStats;
79
+ };
80
+ export type AtlasPageUpdate = {
81
+ page: number;
82
+ pageWidth: number;
83
+ pageEpoch: number;
84
+ revision: number;
85
+ fullUpload: boolean;
86
+ pixels: Uint8Array;
87
+ dirtyRects: Array<AtlasPixelRect & {
88
+ pixels: Uint8Array;
89
+ }>;
90
+ };
@@ -0,0 +1 @@
1
+ export {};