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:
@@ -11,6 +11,8 @@ import vegaEmbed, { type Result as EmbedResult } from 'vega-embed';
|
||||
import type { VisualizationSpec } from 'vega-embed';
|
||||
import type { Config } from 'vega-lite';
|
||||
import { collectFontFamilies } from '@core/custom-theme';
|
||||
import { embedFontsInSvg } from '@core/chart-export';
|
||||
import type { FontAsset } from '@core/font-asset';
|
||||
|
||||
/** Options for `RenderHandle.toImageURL` (spec §08 → Per-chart export). */
|
||||
interface ImageExportOptions {
|
||||
@@ -31,6 +33,14 @@ interface ImageExportOptions {
|
||||
* it transparent. Default `null`.
|
||||
*/
|
||||
background?: string | null;
|
||||
/**
|
||||
* Uploaded font faces the chart references, embedded into the **SVG** as base64
|
||||
* `@font-face` rules so it renders the right type off-app (spec §08; scope doc
|
||||
* §4). Ignored for PNG (the raster already bakes in the glyphs). Omitted/empty
|
||||
* leaves only the family name, which falls back to a system font elsewhere. The
|
||||
* caller (which holds the font library) resolves which faces are referenced.
|
||||
*/
|
||||
embedFonts?: ReadonlyArray<FontAsset>;
|
||||
}
|
||||
|
||||
export interface RenderHandle {
|
||||
@@ -231,12 +241,15 @@ export async function renderSpec(
|
||||
node.replaceChildren();
|
||||
},
|
||||
async toImageURL(format, options = {}) {
|
||||
const { scale = 1, background = null } = options;
|
||||
const { scale = 1, background = null, embedFonts = [] } = options;
|
||||
if (format === 'svg') {
|
||||
// Vector — resolution-independent, so dpr/scale don't apply. A background
|
||||
// is added as a full-bleed rect rather than baked into the live view.
|
||||
const svg = await result.view.toSVG();
|
||||
return svgDataUrl(background ? withSvgBackground(svg, background) : svg);
|
||||
// Vector — resolution-independent, so dpr/scale don't apply. The view
|
||||
// writes only family names, so referenced uploaded faces are embedded as
|
||||
// @font-face data-URIs; a background is added as a full-bleed rect. Both
|
||||
// are injected into the serialized string, not the live view.
|
||||
let svg = embedFontsInSvg(await result.view.toSVG(), embedFonts);
|
||||
if (background) svg = withSvgBackground(svg, background);
|
||||
return svgDataUrl(svg);
|
||||
}
|
||||
// Multiply the requested scale by the device pixel ratio so a "1×" export is
|
||||
// as crisp as the chart on screen (the Retina fix — see ImageExportOptions).
|
||||
|
||||
Reference in New Issue
Block a user