@@ -547,6 +547,112 @@ class BoxArea {
547547}
548548` ` `
549549
550+ ## Environments
551+
552+ Dropflow is designed to support a flexible configuration of environments . In the browser , it loads fonts (soon , images too ) via ` fetch ` and registers font buffers to ` document.fonts ` . In Nodejs , dropflow can load fonts synchronously via ` fs.readFileSync ` .
553+
554+ When you use the canvas backend with dropflow and ` node-canvas ` is present , it will call node - canvas ' s `registerFont`. Node-canvas doesn' t support font buffers , so you have to use file :// URLs.
555+
556+ If you want to use ` @napi-rs/canvas ` or ` skia-canvas ` , you ' ll need just a few lines of code to wire `flow.environment.registerFont` to the appropriate font registration APIs.
557+
558+ ### Hooks
559+
560+ There are 4 hooks you can override , documented below . They have default implementations based on whether dropflow was built for the browser or node (" browser" export condition or " default" ) but may not be sufficient for your use case .
561+
562+ ` ` ` ts
563+ const environment: Environment;
564+
565+ export interface Environment {
566+ /**
567+ * Must return a promise of a Uint8Array of dropflow.wasm. Typically this
568+ * just does a fetch() or fs.readFile.
569+ *
570+ * Since dropflow internally depends on WASM using top-level await, if you
571+ * want to change the location, you need to do it before importing dropflow.
572+ * To do that, import {environment} from 'dropflow/environment.js';
573+ *
574+ * Many package managers only guarantee the order of imports relative to other
575+ * imports, so you should usually call this in a separate module imported
576+ * before dropflow. See the README for an example.
577+ */
578+ wasmLocator(): Promise<Uint8Array>;
579+ /**
580+ * This will get called when a font in flow.fonts transitions to loaded or
581+ * when an already loaded font is added to flow.fonts. It's intended to be
582+ * used to add the font to the underlying paint target.
583+ *
584+ * Use ` face .getBuffer ` if the backend supports font buffers. You can use the
585+ * url property to access the file if it doesn't (node-canvas v2). The font
586+ * will be selected via ` face .uniqueFamily ` and nothing else.
587+ *
588+ * You can return an unregister function which will be called when the font
589+ * is no longer needed by dropflow (eg user called ` flow .fonts .delete ` ).
590+ */
591+ registerFont(face: LoadedFontFace): (() => void) | void;
592+ /**
593+ * Must return a promise of a buffer for the given URL. This used for fonts
594+ * and will be used for images.
595+ */
596+ resolveUrl(url: URL): Promise<ArrayBufferLike>
597+ /**
598+ * Same as ` resolveUrl ` , but synchronous if it's a file:// URL. This should
599+ * throw if URL is not a file:// URL, which would mean the user called
600+ * loadSync on a document with asynchronous-only URLs.
601+ */
602+ resolveUrlSync(url: URL): ArrayBufferLike;
603+ }
604+ ` ` `
605+
606+ ### Using ` @napi-rs/canvas `
607+
608+ ` ` ` ts
609+ import {GlobalFonts} from '@napi-rs/canvas';
610+ import * as flow from 'dropflow';
611+
612+ // Configure @napi-rs/canvas
613+ flow.environment.registerFont = face => {
614+ const key = GlobalFonts.register(face.getBuffer(), face.uniqueFamily);
615+ if (key) return () => GlobalFonts.remove(key);
616+ };
617+ ` ` `
618+
619+ ### Using ` skia-canvas `
620+
621+ ` ` ` ts
622+ import {FontLibrary} from 'skia-canvas';
623+ import * as flow from 'dropflow';
624+
625+ // Configure skia-canvas
626+ flow.environment.registerFont = face => {
627+ FontLibrary.use(face.uniqueFamily, fileURLToPath(face.url));
628+ };
629+ ` ` `
630+
631+ ### Overriding the WASM location
632+
633+ ` ` ` ts
634+ // dropflow.config.js
635+ //
636+ // This should usually go in its own file that is imported before dropflow,
637+ // because dropflow's own modules use top-level await to retrieve dropflow.wasm.
638+ // (Bundlers guarantee import order but only relative to other imports)
639+ import {environment} from 'dropflow/environment.js';
640+ // This will be the path to wasm if you're using Bun. Vite (others?) need ?url
641+ import wasmUrl from 'dropflow/dropflow.wasm';
642+ // or you can get it some other way
643+ // const wasmUrl = 'the/path/to/dropflow.wasm';
644+
645+ environment.wasmLocator = function () {
646+ return fetch(wasmUrl).then(res => {
647+ if (res.status === 200) {
648+ return res.arrayBuffer()
649+ } else {
650+ throw new Error(res.statusText);
651+ }
652+ });
653+ };
654+ ` ` `
655+
550656## Other
551657
552658### ` staticLayoutContribution `
0 commit comments