PageSourceSearch

https://www.developers.thinkfree.com/docs/assets/js/2737473d.7ce3d66e.js

js thinkfree.com collected 2026-10-02 03:29:59 UTC 8,252 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkthinkfree_developers_docs=self.webpackChunkthinkfree_developers_docs||[]).push([[2250],{2913(e,r,n){n.r(r),n.d(r,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"metafile-renderer/overview","title":"Metafile Renderer guide","description":"Metafile Renderer is a TypeScript parser and renderer for Windows Metafile formats. Parsing has no runtime dependency.","source":"@site/docs/metafile-renderer/overview.md","sourceDirName":"metafile-renderer","slug":"/metafile-renderer/","permalink":"/docs/metafile-renderer/","draft":false,"unlisted":true,"tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"unlisted":true,"title":"Metafile Renderer guide","slug":"/metafile-renderer/","sidebar_position":1}}');var s=n(4848),i=n(8453);const d={unlisted:!0,title:"Metafile Renderer guide",slug:"/metafile-renderer/",sidebar_position:1},a="Parse and render WMF, EMF, and EMF+",o={},l=[{value:"Choose an operating mode",id:"choose-an-operating-mode",level:2},{value:"Public TypeScript surface",id:"public-typescript-surface",level:2},{value:"Parse without rendering",id:"parse-without-rendering",level:2},{value:"Render in the browser",id:"render-in-the-browser",level:2},{value:"Performance and deployment",id:"performance-and-deployment",level:2},{value:"Troubleshooting",id:"troubleshooting",level:2}];function c(e){const r={code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.header,{children:(0,s.jsx)(r.h1,{id:"parse-and-render-wmf-emf-and-emf",children:"Parse and render WMF, EMF, and EMF+"})}),"\n",(0,s.jsx)(r.p,{children:"Metafile Renderer is a TypeScript parser and renderer for Windows Metafile formats. Parsing has no runtime dependency.\nPNG rendering uses a Skia-based rendering backend and metric-compatible fonts so the same input can be evaluated in a\nbrowser or Node.js."}),"\n",(0,s.jsx)("span",{className:"status-pill private",children:"Private developer preview"}),"\n",(0,s.jsxs)(r.p,{children:["The current source tag is ",(0,s.jsx)(r.strong,{children:"v0.1.2"}),". The package manifest is private and the tagged GitHub Release currently has no\ndownloadable package asset. Use the Playground for evaluation or obtain an approved source snapshot from Thinkfree. Do\nnot depend on a public npm package or copy individual implementation files."]}),"\n",(0,s.jsx)(r.h2,{id:"choose-an-operating-mode",children:"Choose an operating mode"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Mode"}),(0,s.jsx)(r.th,{children:"Dependencies"}),(0,s.jsx)(r.th,{children:"Result"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Parse only"}),(0,s.jsx)(r.td,{children:"TypeScript core"}),(0,s.jsx)(r.td,{children:"Records and decoded fields"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Browser render"}),(0,s.jsx)(r.td,{children:"TypeScript core, rendering runtime, fonts"}),(0,s.jsx)(r.td,{children:"PNG preview"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Node.js render"}),(0,s.jsx)(r.td,{children:"TypeScript core, rendering runtime, bundled or system fonts"}),(0,s.jsx)(r.td,{children:"PNG bytes"})]})]})]}),"\n",(0,s.jsx)(r.h2,{id:"public-typescript-surface",children:"Public TypeScript surface"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ts",children:"import {\n  CanvasKitRenderer,\n  enumerateEmf,\n  parseEmf,\n  parseWmf,\n  playEmf,\n  playWmf,\n} from 'metafile-renderer';\n"})}),"\n",(0,s.jsxs)(r.p,{children:["The public barrel exposes WMF/EMF parsing, EMF enumeration, playback, the renderer interface, and\n",(0,s.jsx)(r.code,{children:"CanvasKitRenderer"}),". Rendering also requires runtime and font assets. Their bootstrap and distribution path are not yet\na stable public package contract, so use the approved source snapshot that matches your renderer assets rather than\ninventing deep imports."]}),"\n",(0,s.jsx)(r.h2,{id:"parse-without-rendering",children:"Parse without rendering"}),"\n",(0,s.jsx)(r.p,{children:"Parsing does not require WASM or fonts and is suitable for inspection, indexing, and security preflight checks."}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ts",children:"import {parseWmf, parseEmf, enumerateEmf} from 'metafile-renderer';\n\nconst parsedWmf = parseWmf(wmfBytes);\nconst parsedEmf = parseEmf(emfBytes);\n\nfor (const record of enumerateEmf(emfBytes)) {\n  console.log(record.type, record.fields);\n}\n"})}),"\n",(0,s.jsx)(r.h2,{id:"render-in-the-browser",children:"Render in the browser"}),"\n",(0,s.jsxs)(r.p,{children:["Use the ",(0,s.jsx)("a",{href:"/playground/metafile-renderer/",children:"Metafile Renderer Playground"})," to verify browser rendering before\nintegrating a private source snapshot. The selected file stays in the browser; the Playground produces a PNG preview\nand reports the detected format and output dimensions."]}),"\n",(0,s.jsx)(r.h2,{id:"performance-and-deployment",children:"Performance and deployment"}),"\n",(0,s.jsx)(r.p,{children:"The complete font set includes large CJK fonts. For a production application, cache the renderer and fonts with immutable\nURLs and load Korean, Japanese, Simplified Chinese, and Traditional Chinese families only when the document requires them."}),"\n",(0,s.jsx)(r.p,{children:"Limit input byte size and output dimensions before rendering. The renderer caps dimensions, but an application should\nalso apply its own memory and execution-time limits. Do not treat a successfully parsed metafile as trusted active content."}),"\n",(0,s.jsx)(r.p,{children:"The source corpus currently covers 3,509 WMF files and 994 EMF/EMF+ files, with 143 decoded record types exercised by\nround-trip tests. Corpus coverage is useful evidence, not a promise that every producer-specific file renders identically."}),"\n",(0,s.jsx)(r.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Symptom"}),(0,s.jsx)(r.th,{children:"Check"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Rendering runtime does not initialize"}),(0,s.jsx)(r.td,{children:"Verify that all renderer assets came from the same approved snapshot and that CSP permits them"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Rendering assets fail to load"}),(0,s.jsx)(r.td,{children:"Check the browser network panel, MIME types, and asset caching"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Text is missing or substituted"}),(0,s.jsx)(r.td,{children:"Confirm the required font family was loaded"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Browser starts slowly"}),(0,s.jsx)(r.td,{children:"Reduce the initial font set and enable long-lived asset caching"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Output size is unexpected"}),(0,s.jsx)(r.td,{children:"Pass explicit dimensions or derive the native size from the metafile header"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Output differs from Windows"}),(0,s.jsx)(r.td,{children:"Check font substitution, antialiasing, CJK weight, and producer-specific records"})]})]})]}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("a",{href:"/playground/metafile-renderer/",children:"Open the Metafile Renderer Playground"})," to upload a WMF or EMF file and render it\nlocally with the bundled browser engine and fonts."]})]})}function h(e={}){const{wrapper:r}={...(0,i.R)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},8453(e,r,n){n.d(r,{R:()=>d,x:()=>a});var t=n(6540);const s={},i=t.createContext(s);function d(e){const r=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),t.createElement(i.Provider,{value:r},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.