exportDiagramSvg function
Future<SvgSnapshot>
exportDiagramSvg(
- DiagramPublication publication, {
- required SvgOptions options,
- ImageProvider<
Object> imageProvider()?,
Prepares images through the canvas image loader for the pure SVG codec. Native text preserves line placement; mounted widgets use declared fallbacks.
Implementation
Future<SvgSnapshot> exportDiagramSvg(
DiagramPublication publication, {
required SvgOptions options,
ImageProvider<Object> Function(DiagramImageSource)? imageProvider,
}) async {
final document = publication.state.document;
final scene = publication.scene;
if (scene.documentId != document.id || scene.revision != document.revision) {
throw StateError('SVG output requires a revision-matched publication.');
}
final bounds = options.bounds;
options.validate();
final fonts = DiagramSvgResources(fonts: options.fonts).fonts;
var resourceBytes = 0;
void admitResource(int bytes) {
if (bytes > options.maximumResourceBytes - resourceBytes) {
throw StateError('SVG prepared resources exceed maximumResourceBytes.');
}
resourceBytes += bytes;
}
for (final font in fonts) {
admitResource(font.bytes.length);
}
final sources = DiagramSvgScene.imageSources(scene);
final images = DiagramImageCache(
provider: imageProvider,
maximumConcurrentLoads: options.resourceConcurrency,
loadTimeout: options.resourceTimeout,
maximumDecodedBytes: options.maximumDecodedImageBytes,
);
final resources = <String, DiagramSvgImage>{};
try {
// Keep a private handle while encoding, even if another load fails and
// disposes the cache. Release decoded storage before admitting another load.
await loadOutputResources(
sources,
(source) async {
final image = await images.loadOwned(source);
try {
final data = await encodeDiagramPngImage(image);
admitResource(data.lengthInBytes);
resources[source.uri] = DiagramSvgImage(data);
} finally {
image.dispose();
images.release(source);
}
return null;
},
concurrency: options.resourceConcurrency,
timeout: options.resourceTimeout,
);
return SvgSnapshot(
svg: DiagramSvgScene.encode(
scene,
bounds: bounds,
resources: DiagramSvgResources(images: resources, fonts: fonts),
),
documentId: document.id,
revision: document.revision,
textLayoutRevision: scene.textLayoutRevision,
bounds: bounds,
);
} finally {
images.dispose();
}
}