mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Fonts: carry uploaded faces through export/import + embed in SVG export
This commit is contained in:
@@ -18,6 +18,8 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import type { VisualizationSpec } from 'vega-embed';
|
||||
import type { Config } from 'vega-lite';
|
||||
import { referencedUploadedFonts } from '@core/chart-export';
|
||||
import type { FitMode } from '@core/rendering';
|
||||
import { DatasetNotFoundError, prepareSpecForRender } from '@core/rendering';
|
||||
import {
|
||||
@@ -30,6 +32,7 @@ import { renderSpec, type RenderHandle } from '../services/chart-renderer';
|
||||
import { useAppStore } from '../stores/AppStore';
|
||||
import { useCustomThemeStore } from '../stores/CustomThemeStore';
|
||||
import { useDatasetStore } from '../stores/DatasetStore';
|
||||
import { useFontStore } from '../stores/FontStore';
|
||||
import { usePreviewStore } from '../stores/PreviewStore';
|
||||
import { selectShownText, useSnippetStore } from '../stores/SnippetStore';
|
||||
import { useUserSettingsStore } from '../stores/UserSettingsStore';
|
||||
@@ -159,6 +162,11 @@ function PreviewSettings() {
|
||||
export function LivePreview() {
|
||||
const hostRef = useRef<HTMLDivElement>(null);
|
||||
const handleRef = useRef<RenderHandle | null>(null);
|
||||
// The config the live view was last rendered with — read at SVG export to find
|
||||
// which uploaded fonts the chart references (a font may live only in the theme
|
||||
// config, not the spec). Tracks `handleRef`: set together, valid whenever a
|
||||
// handle is.
|
||||
const configRef = useRef<Config | null>(null);
|
||||
const generationRef = useRef(0);
|
||||
// Serializes node mutations across overlapping renders: each render chains onto
|
||||
// the previous one's promise so only one vega-embed ever touches the shared host
|
||||
@@ -296,6 +304,7 @@ export function LivePreview() {
|
||||
return;
|
||||
}
|
||||
handleRef.current = handle;
|
||||
configRef.current = config;
|
||||
setChartReady(true);
|
||||
setError(null);
|
||||
clearBusy();
|
||||
@@ -354,7 +363,18 @@ export function LivePreview() {
|
||||
): Promise<string | null> => {
|
||||
const handle = handleRef.current;
|
||||
if (!handle) return null;
|
||||
return await handle.toImageURL(format, options);
|
||||
// Embed the referenced uploaded faces into an SVG so it renders off-app
|
||||
// (spec §08). Read fresh: a font can be uploaded after the last render, and
|
||||
// configRef holds the config that render used (a font may be theme-only).
|
||||
const embedFonts =
|
||||
format === 'svg'
|
||||
? referencedUploadedFonts(
|
||||
selectShownText(useSnippetStore.getState()),
|
||||
configRef.current,
|
||||
useFontStore.getState().fonts,
|
||||
)
|
||||
: undefined;
|
||||
return await handle.toImageURL(format, { ...options, embedFonts });
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user