Incorporo-user commited on
Commit
8010824
·
verified ·
1 Parent(s): 2c34739

Inkvec 0.2: the presentation page, and Inkvec Studio Lite under studio/

Browse files
studio/assets/{engine.worker-DxLbviFI.js → engine.worker-wbMABDxy.js} RENAMED
@@ -1 +1 @@
1
- const i=self;let a=null,y=null,h=null,p=null,u=null;function w(e,t){if(!e.ok||!e.body||typeof TransformStream>"u")return e;const s=t||Number(e.headers.get("content-length"))||0;let n=0,r=0;const o=e.body.pipeThrough(new TransformStream({transform(l,d){n+=l.byteLength;const c=performance.now();c-r>40&&(r=c,i.postMessage({type:"loading",got:n,total:s})),d.enqueue(l)},flush(){i.postMessage({type:"loading",got:n,total:Math.max(s,n),done:!0})}}));return new Response(o,{status:e.status,headers:{"content-type":"application/wasm"}})}async function S(e){const t=typeof crossOriginIsolated<"u"&&crossOriginIsolated,s=t?"pkg-threads":"pkg",n=e.token?`?v=${e.token}`:"",r=new URL(`${s}/inkvec_studio_wasm.js${n}`,e.base).href,o=fetch(new URL(`${s}/inkvec_studio_wasm_bg.wasm${n}`,e.base));o.catch(()=>{}),a=await import(r),y=(await a.default({module_or_path:w(await o,e.wasmBytes?.[s])})).memory??null,i.postMessage({type:"instantiated",denoiserUrl:a.denoiser_model_url(),denoiserSha256:a.denoiser_model_sha256()});let d=1,c=null;if(t&&a.initThreadPool){const f=Math.max(1,Math.min(navigator.hardwareConcurrency||4,16)-1);try{await a.initThreadPool(f),d=f+1}catch(m){c=String(m?.message??m)}}p=e.generations?new Int32Array(e.generations):null,u=e.denoiserPort,u&&t&&(_(u),a.enable_denoiser()),h=new a.Studio,i.postMessage({type:"ready",threads:d,poolError:c,isolated:t,version:a.version(),denoiserUrl:a.denoiser_model_url(),denoiserSha256:a.denoiser_model_sha256(),denoiserRepo:a.denoiser_model_repo()})}function _(e){i.inkvecDenoiseSync=(t,s,n)=>{const r=t.length,o=new SharedArrayBuffer(8+Math.max(r*4,4096)),l=new Int32Array(o,0,2);if(e.postMessage({type:"run",input:t.slice(),width:s,height:n,shared:o}),Atomics.wait(l,0,0,6e5)==="timed-out")throw new Error("the denoiser did not answer in ten minutes");if(Atomics.load(l,0)!==1){const c=new TextDecoder().decode(new Uint8Array(o,8,Atomics.load(l,1)).slice());throw new Error(c||"the denoiser failed")}return new Float32Array(o,8,r).slice()}}function v(e){return p?Atomics.load(p,0)===e:!0}function M(e){const t=h;if(!t)throw new Error("the engine is not loaded");switch(e.op){case"capabilities":return JSON.parse(t.capabilities(!!e.supported,!!e.installed,e.bytes??void 0));case"open_bytes":return JSON.parse(t.open_bytes(e.bytes,e.name??void 0));case"trace":{const s=e.generation,n=t.trace(JSON.stringify(e.request),e.draftPx,e.draftSeconds,s,(r,o)=>i.postMessage({type:"stage",generation:s,name:r,ms:o}),v);return n===void 0?null:JSON.parse(n)}case"preview":return JSON.parse(t.preview(JSON.stringify(e.request),e.draftPx,e.draftSeconds));case"export":return t.export_files(JSON.stringify({request:e.request}),!!e.zip).map(n=>({name:n.name,data:n.data}));case"close":return t.close(),null;default:return JSON.parse(t.call(e.op,JSON.stringify(e.args??{})))}}function k(e){return e instanceof WebAssembly.RuntimeError||e instanceof RangeError&&/memory|allocation/i.test(e.message)||/unreachable|out of memory|memory access out of bounds/i.test(String(e?.message??e))}let g=Promise.resolve();i.onmessage=e=>{const t=e.data;g=g.then(async()=>{if(t.type==="init"){try{await S(t)}catch(n){i.postMessage({type:"loadfail",error:String(n?.stack??n)})}return}const s=performance.now();try{const n=M(t),r=[];if(t.op==="export")for(const o of n)r.push(o.data.buffer);i.postMessage({type:"reply",id:t.id,ok:!0,value:n,ms:performance.now()-s,mem:y?.buffer.byteLength??null},r)}catch(n){const r=String(n?.message??n);i.postMessage({type:"reply",id:t.id,ok:!1,error:r,crashed:k(n)})}})};
 
1
+ const i=self;let o=null,y=null,h=null,p=null,u=null;function w(e,t){if(!e.ok||!e.body||typeof TransformStream>"u")return e;const s=t||Number(e.headers.get("content-length"))||0;let n=0,r=0;const a=e.body.pipeThrough(new TransformStream({transform(l,d){n+=l.byteLength;const c=performance.now();c-r>40&&(r=c,i.postMessage({type:"loading",got:n,total:s})),d.enqueue(l)},flush(){i.postMessage({type:"loading",got:n,total:Math.max(s,n),done:!0})}}));return new Response(a,{status:e.status,headers:{"content-type":"application/wasm"}})}async function S(e){const t=typeof crossOriginIsolated<"u"&&crossOriginIsolated,s=t?"pkg-threads":"pkg",n=e.token?`?v=${e.token}`:"",r=new URL(`${s}/inkvec_studio_wasm.js${n}`,e.base).href,a=fetch(new URL(`${s}/inkvec_studio_wasm_bg.wasm${n}`,e.base));a.catch(()=>{}),o=await import(r),y=(await o.default({module_or_path:w(await a,e.wasmBytes?.[s])})).memory??null,i.postMessage({type:"instantiated",denoiserUrl:o.denoiser_model_url(),denoiserSha256:o.denoiser_model_sha256()});let d=1,c=null;if(t&&o.initThreadPool){const f=Math.max(1,Math.min(navigator.hardwareConcurrency||4,16)-1);try{await o.initThreadPool(f),d=f+1}catch(m){c=String(m?.message??m)}}p=e.generations?new Int32Array(e.generations):null,u=e.denoiserPort,u&&t&&(_(u),o.enable_denoiser()),h=new o.Studio,i.postMessage({type:"ready",threads:d,poolError:c,isolated:t,version:o.version(),denoiserUrl:o.denoiser_model_url(),denoiserSha256:o.denoiser_model_sha256(),denoiserRepo:o.denoiser_model_repo()})}function _(e){i.inkvecDenoiseSync=(t,s,n)=>{const r=t.length,a=new SharedArrayBuffer(8+Math.max(r*4,4096)),l=new Int32Array(a,0,2);if(e.postMessage({type:"run",input:t.slice(),width:s,height:n,shared:a}),Atomics.wait(l,0,0,6e5)==="timed-out")throw new Error("the denoiser did not answer in ten minutes");if(Atomics.load(l,0)!==1){const c=new TextDecoder().decode(new Uint8Array(a,8,Atomics.load(l,1)).slice());throw new Error(c||"the denoiser failed")}return new Float32Array(a,8,r).slice()}}function v(e){return p?Atomics.load(p,0)===e:!0}function M(e){const t=h;if(!t)throw new Error("the engine is not loaded");switch(e.op){case"capabilities":return JSON.parse(t.capabilities(!!e.supported,!!e.installed,e.bytes??void 0));case"open_bytes":return JSON.parse(t.open_bytes(e.bytes,e.name??void 0));case"trace":{const s=e.generation,n=t.trace(JSON.stringify(e.request),e.draftPx,e.draftSeconds,s,r=>i.postMessage({type:"progress",generation:s,json:r}),v);return n===void 0?null:JSON.parse(n)}case"preview":return JSON.parse(t.preview(JSON.stringify(e.request),e.draftPx,e.draftSeconds));case"export":return t.export_files(JSON.stringify({request:e.request}),!!e.zip).map(n=>({name:n.name,data:n.data}));case"close":return t.close(),null;default:return JSON.parse(t.call(e.op,JSON.stringify(e.args??{})))}}function k(e){return e instanceof WebAssembly.RuntimeError||e instanceof RangeError&&/memory|allocation/i.test(e.message)||/unreachable|out of memory|memory access out of bounds/i.test(String(e?.message??e))}let g=Promise.resolve();i.onmessage=e=>{const t=e.data;g=g.then(async()=>{if(t.type==="init"){try{await S(t)}catch(n){i.postMessage({type:"loadfail",error:String(n?.stack??n)})}return}const s=performance.now();try{const n=M(t),r=[];if(t.op==="export")for(const a of n)r.push(a.data.buffer);i.postMessage({type:"reply",id:t.id,ok:!0,value:n,ms:performance.now()-s,mem:y?.buffer.byteLength??null},r)}catch(n){const r=String(n?.message??n);i.postMessage({type:"reply",id:t.id,ok:!1,error:r,crashed:k(n)})}})};
studio/assets/main--3-Ll9JM.js DELETED
The diff for this file is too large to render. See raw diff
 
studio/assets/{main-C8vHcyec.css → main-BwYpaGSz.css} RENAMED
The diff for this file is too large to render. See raw diff
 
studio/assets/main-ai0rIBhL.js ADDED
The diff for this file is too large to render. See raw diff
 
studio/guide/getting-started.html CHANGED
@@ -152,7 +152,8 @@ right pane is yours.</p>
152
  <p>From step 4 on, a small table compares Auto's figures with yours: colour difference, nodes, paths
153
  and file size, with the change in each.</p>
154
  <p>What each control does is on the <a href="tune.html">Tune</a> page; the wizard shows the same controls, only
155
- fewer at a time.</p>
 
156
  <p>Along the bottom: <strong>Back</strong>, <strong>Skip to finish</strong> (jump to the last step, keeping everything chosen),
157
  and <strong>Next</strong>. On the last step, <strong>Finish</strong> closes the wizard and <strong>Export now</strong> closes it and opens
158
  the export sheet. At the top, <strong>Undo my changes</strong> puts every control and colour group back to where
 
152
  <p>From step 4 on, a small table compares Auto's figures with yours: colour difference, nodes, paths
153
  and file size, with the change in each.</p>
154
  <p>What each control does is on the <a href="tune.html">Tune</a> page; the wizard shows the same controls, only
155
+ fewer at a time. With the <strong>Fast</strong> engine it leaves out, as Tune does, the controls only Quality
156
+ reads (see <a href="tune.html#which-controls-each-engine-reads">which controls each engine reads</a>).</p>
157
  <p>Along the bottom: <strong>Back</strong>, <strong>Skip to finish</strong> (jump to the last step, keeping everything chosen),
158
  and <strong>Next</strong>. On the last step, <strong>Finish</strong> closes the wizard and <strong>Export now</strong> closes it and opens
159
  the export sheet. At the top, <strong>Undo my changes</strong> puts every control and colour group back to where
studio/guide/result.html CHANGED
@@ -18,7 +18,7 @@ that comparison found.</p>
18
  <p>From the top, the Result tab shows:</p>
19
  <ol>
20
  <li>The <strong>Denoiser</strong> and <strong>Editable</strong> settings (shared with Tune; see
21
- <a href="tune.html#the-denoiser-and-editable">Tune</a>).</li>
22
  <li><strong>Auto chose</strong>, while it has something to offer (see
23
  <a href="getting-started.html#the-choice-card-keep-auto-or-customise">Getting started</a>).</li>
24
  <li>The <strong>quality report</strong>.</li>
@@ -156,7 +156,7 @@ an artist drew by hand. This card counts three of those habits on your drawing:<
156
  </table>
157
  <p>Each bar shows your drawing's share, with the count, and a tick where hand-drawn files sit: the
158
  median of 1,544 SVGs drawn by artists, measured the same way. A plain trace starts near zero on
159
- the first two. <strong>Make it editable</strong> turns on <a href="tune.html#the-denoiser-and-editable">Editable structure</a>,
160
  which moves the bars towards the ticks. It costs a little colour accuracy (about 0.04 dE00 on
161
  icons); the quality report shows the price on your image.</p>
162
  <p>A drawing made only of lines and arcs has no curve handles and no curve joins, so only the last row
 
18
  <p>From the top, the Result tab shows:</p>
19
  <ol>
20
  <li>The <strong>Denoiser</strong> and <strong>Editable</strong> settings (shared with Tune; see
21
+ <a href="tune.html#the-engine-the-denoiser-and-editable">Tune</a>).</li>
22
  <li><strong>Auto chose</strong>, while it has something to offer (see
23
  <a href="getting-started.html#the-choice-card-keep-auto-or-customise">Getting started</a>).</li>
24
  <li>The <strong>quality report</strong>.</li>
 
156
  </table>
157
  <p>Each bar shows your drawing's share, with the count, and a tick where hand-drawn files sit: the
158
  median of 1,544 SVGs drawn by artists, measured the same way. A plain trace starts near zero on
159
+ the first two. <strong>Make it editable</strong> turns on <a href="tune.html#the-engine-the-denoiser-and-editable">Editable structure</a>,
160
  which moves the bars towards the ticks. It costs a little colour accuracy (about 0.04 dE00 on
161
  icons); the quality report shows the price on your image.</p>
162
  <p>A drawing made only of lines and arcs has no curve handles and no curve joins, so only the last row
studio/guide/shortcuts.html CHANGED
@@ -38,8 +38,8 @@
38
  <td>This guide, at the page about what is on screen</td>
39
  </tr>
40
  <tr>
41
- <td><kbd>Ctrl</kbd>+<kbd>1</kbd> … <kbd>Ctrl</kbd>+<kbd>8</kbd></td>
42
- <td>Choose a preset: Logo, Icon, Fine detail, Fewer paths, Photo or scan, Black &amp; white, Line art, Editable</td>
43
  </tr>
44
  <tr>
45
  <td><kbd>Esc</kbd></td>
 
38
  <td>This guide, at the page about what is on screen</td>
39
  </tr>
40
  <tr>
41
+ <td><kbd>Ctrl</kbd>+<kbd>1</kbd> … <kbd>Ctrl</kbd>+<kbd>9</kbd>, <kbd>Ctrl</kbd>+<kbd>0</kbd></td>
42
+ <td>Choose a preset: Logo, Icon, Fine detail, Fewer paths, Photo or scan, One-colour logo, Black no background, Two-tone scan, Line art, Editable</td>
43
  </tr>
44
  <tr>
45
  <td><kbd>Esc</kbd></td>
studio/guide/tune.html CHANGED
@@ -12,7 +12,7 @@
12
  <aside class="side"><a class="guidebrand" href="index.html"><img src="logo-mono.svg" alt=""> <span>Inkvec Studio</span></a><div class="grp"><h4>User guide</h4><a href="index.html">Overview</a><a href="install.html">Install and first launch</a><a href="getting-started.html">Getting started</a><a href="viewer.html">The viewer</a><a href="result.html">Result</a><a href="tune.html" aria-current="page">Tune</a><a href="palette.html">Palette and colour groups</a><a href="export.html">Export</a><a href="minify.html">Minify SVG</a><a href="fabricate.html">Fabricate</a><a href="batch.html">Batch</a><a href="settings.html">Settings</a><a href="shortcuts.html">Keyboard and mouse</a><a href="troubleshooting.html">Troubleshooting</a></div><div class="grp"><h4>Tutorials</h4><a href="tutorials/jpeg-logo.html">Clean up a JPEG logo</a><a href="tutorials/favicon-asset-pack.html">A favicon and an asset pack</a><a href="tutorials/vinyl-htv.html">Layered vinyl and iron-on</a><a href="tutorials/laser.html">Laser: DXF and G-code</a></div><div class="grp"><h4>Online</h4><a href="https://logolabs.github.io/inkvec/">Inkvec documentation</a><a href="https://logolabs.github.io/inkvec/studio/tune.html">This page on the web</a></div><p class="guidenote">This copy of the guide is part of the app and works without a network.</p></aside>
13
  <main><article><h1 id="tune-presets-and-every-control">Tune: presets and every control</h1>
14
  <p>The <strong>Tune</strong> half of the rail holds the settings for the next trace: eight presets, any presets you
15
- saved, and twenty-two controls. Moving any of them starts a draft at once and a full trace a moment
16
  later (see <a href="viewer.html#draft-and-full-traces">draft and full traces</a>); the readout at the foot of
17
  the rail shows what the change bought or cost.</p>
18
  <p><img alt="The Tune half of the rail: presets, then the Detail group with one control changed" src="img/tune.webp"></p>
@@ -35,9 +35,12 @@ are not sure where to start, <strong>Walk me through it</strong> at the top open
35
  has its own <strong>Reset</strong>. <strong>Output</strong> starts folded.</p>
36
  <p>The controls are the same ones the <code>inkvec</code> command line has; the Studio only gives them
37
  plain-language names. The table at the end of this page maps them.</p>
38
- <h2 id="the-denoiser-and-editable">The denoiser and Editable</h2>
39
- <p>Two settings sit above both halves of the rail, big, because they are the two people most often
40
  come for. Each is one control, shown once.</p>
 
 
 
41
  <p><strong>Denoiser</strong>: <strong>Off</strong>, <strong>Auto</strong> or <strong>On</strong>. The denoiser is a trained model that repairs JPEG, WebP
42
  and screenshot damage at the image's own size before tracing, so the colours are the ones the
43
  artwork was drawn with rather than the ones the compression left.</p>
@@ -57,8 +60,26 @@ an artist can edit: joins that are smooth, handles that lie on an axis and have
57
  lined up with each other, and shapes that are symmetric locked into exact mirrors. The outline stays
58
  within the same tolerance; the <a href="result.html#editability">Editability card</a> shows what it changed, and
59
  the quality report shows its price (about 0.04 dE00 on icons).</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  <h2 id="presets">Presets</h2>
61
- <p>A preset is a handful of settings chosen together. The tray shows the eight built-ins; the line
62
  under it describes the one selected.</p>
63
  <table>
64
  <thead>
@@ -101,22 +122,34 @@ under it describes the one selected.</p>
101
  <td><kbd>Ctrl</kbd>+<kbd>5</kbd></td>
102
  </tr>
103
  <tr>
104
- <td><strong>Black &amp; white</strong></td>
105
- <td>Stamps, signatures</td>
106
- <td>Black &amp; white on</td>
107
  <td><kbd>Ctrl</kbd>+<kbd>6</kbd></td>
108
  </tr>
109
  <tr>
 
 
 
 
 
 
 
 
 
 
 
 
110
  <td><strong>Line art</strong></td>
111
  <td>Uniform-stroke drawings</td>
112
  <td>Line art on</td>
113
- <td><kbd>Ctrl</kbd>+<kbd>7</kbd></td>
114
  </tr>
115
  <tr>
116
  <td><strong>Editable</strong></td>
117
  <td>Tidy nodes for an artist to edit</td>
118
  <td>Editable structure on</td>
119
- <td><kbd>Ctrl</kbd>+<kbd>8</kbd></td>
120
  </tr>
121
  </tbody>
122
  </table>
@@ -126,7 +159,7 @@ preset selected and counts the control as changed; <strong>Reset <em>N</em> chan
126
  <p><strong>Photo or scan</strong> needs the denoiser to do what it says. Without it the trace still runs, and the
127
  stage says the denoiser is missing and offers the download.</p>
128
  <h3 id="saving-your-own">Saving your own</h3>
129
- <p><strong>Save as preset</strong> stores all twenty-two controls exactly as they stand, under a name you give
130
  (up to 40 characters). It appears in the tray after the built-ins; the <strong>×</strong> on its chip forgets
131
  it. You can keep up to twelve. A saved preset is a complete snapshot rather than a list of
132
  differences, so it does not change if a future version changes the defaults.</p>
@@ -162,8 +195,13 @@ OKLab colour space) to be treated as one ink.
162
  genuinely different colours were merged.</p>
163
  <p><strong>Flat fills instead of gradients</strong> (off). Skips gradient fitting and fills every region with one
164
  colour. For flat artwork, or when the SVG must not contain gradients.</p>
165
- <p><strong>Black &amp; white</strong> (off). Two inks only: the Potrace-style mode, for stamps, signatures and scans
166
- of print.</p>
 
 
 
 
 
167
  <p><strong>Trace transparency</strong> (on). Transparency is traced as it is: holes stay holes, every ink carries
168
  its own opacity, and soft shadows, glows and feathered edges come back as translucent fills. Turned
169
  off, the image is laid on a solid background first and traced as solid colours, which fills holes
@@ -246,7 +284,11 @@ matters mainly when that is off.</p>
246
  <td><code>--no-gradients</code></td>
247
  </tr>
248
  <tr>
249
- <td>Black &amp; white</td>
 
 
 
 
250
  <td><code>--bilevel</code></td>
251
  </tr>
252
  <tr>
@@ -312,7 +354,7 @@ matters mainly when that is off.</p>
312
  </tbody>
313
  </table>
314
  <p><code>inkvec --help</code> lists them all with their exact spelling.</p><nav class="pagenav"><a class="prev" href="result.html"><span class="dir">Previous</span><span class="lbl">Result</span></a><a class="next" href="palette.html"><span class="dir">Next</span><span class="lbl">Palette and colour groups</span></a></nav></article></main>
315
- <aside class="rail"><h5>On this page</h5><ul><ul><li class="l2"><a href="#how-the-controls-work">How the controls work</a></li><li class="l2"><a href="#the-denoiser-and-editable">The denoiser and Editable</a></li><li class="l2"><a href="#presets">Presets</a><ul><li class="l3"><a href="#saving-your-own">Saving your own</a></li></ul></li><li class="l2"><a href="#detail">Detail</a></li><li class="l2"><a href="#colour">Colour</a></li><li class="l2"><a href="#shape">Shape</a></li><li class="l2"><a href="#output">Output</a></li><li class="l2"><a href="#the-same-controls-on-the-command-line">The same controls on the command line</a></li></ul></ul></aside>
316
  </div>
317
  </body>
318
  </html>
 
12
  <aside class="side"><a class="guidebrand" href="index.html"><img src="logo-mono.svg" alt=""> <span>Inkvec Studio</span></a><div class="grp"><h4>User guide</h4><a href="index.html">Overview</a><a href="install.html">Install and first launch</a><a href="getting-started.html">Getting started</a><a href="viewer.html">The viewer</a><a href="result.html">Result</a><a href="tune.html" aria-current="page">Tune</a><a href="palette.html">Palette and colour groups</a><a href="export.html">Export</a><a href="minify.html">Minify SVG</a><a href="fabricate.html">Fabricate</a><a href="batch.html">Batch</a><a href="settings.html">Settings</a><a href="shortcuts.html">Keyboard and mouse</a><a href="troubleshooting.html">Troubleshooting</a></div><div class="grp"><h4>Tutorials</h4><a href="tutorials/jpeg-logo.html">Clean up a JPEG logo</a><a href="tutorials/favicon-asset-pack.html">A favicon and an asset pack</a><a href="tutorials/vinyl-htv.html">Layered vinyl and iron-on</a><a href="tutorials/laser.html">Laser: DXF and G-code</a></div><div class="grp"><h4>Online</h4><a href="https://logolabs.github.io/inkvec/">Inkvec documentation</a><a href="https://logolabs.github.io/inkvec/studio/tune.html">This page on the web</a></div><p class="guidenote">This copy of the guide is part of the app and works without a network.</p></aside>
13
  <main><article><h1 id="tune-presets-and-every-control">Tune: presets and every control</h1>
14
  <p>The <strong>Tune</strong> half of the rail holds the settings for the next trace: eight presets, any presets you
15
+ saved, and twenty-three controls. Moving any of them starts a draft at once and a full trace a moment
16
  later (see <a href="viewer.html#draft-and-full-traces">draft and full traces</a>); the readout at the foot of
17
  the rail shows what the change bought or cost.</p>
18
  <p><img alt="The Tune half of the rail: presets, then the Detail group with one control changed" src="img/tune.webp"></p>
 
35
  has its own <strong>Reset</strong>. <strong>Output</strong> starts folded.</p>
36
  <p>The controls are the same ones the <code>inkvec</code> command line has; the Studio only gives them
37
  plain-language names. The table at the end of this page maps them.</p>
38
+ <h2 id="the-engine-the-denoiser-and-editable">The engine, the denoiser and Editable</h2>
39
+ <p>Three settings sit above both halves of the rail, big, because they are the ones people most often
40
  come for. Each is one control, shown once.</p>
41
+ <p><strong>Engine</strong>: <strong>Quality</strong> or <strong>Fast</strong>. Quality places every edge to a fraction of a pixel and fits
42
+ the fewest curves that match the image; it is the default and the closest trace. Fast traces each
43
+ shape in a single pass, many times quicker, for previews, batches and very large images.</p>
44
  <p><strong>Denoiser</strong>: <strong>Off</strong>, <strong>Auto</strong> or <strong>On</strong>. The denoiser is a trained model that repairs JPEG, WebP
45
  and screenshot damage at the image's own size before tracing, so the colours are the ones the
46
  artwork was drawn with rather than the ones the compression left.</p>
 
60
  lined up with each other, and shapes that are symmetric locked into exact mirrors. The outline stays
61
  within the same tolerance; the <a href="result.html#editability">Editability card</a> shows what it changed, and
62
  the quality report shows its price (about 0.04 dE00 on icons).</p>
63
+ <h3 id="which-controls-each-engine-reads">Which controls each engine reads</h3>
64
+ <p>Fast skips the stages several controls steer, so with Fast selected the Tune tab lists only the
65
+ controls that change a Fast trace, and a line at the top says how many more are for Quality. The
66
+ hidden ones keep their values: switch back to Quality and they are where you left them. The
67
+ <em>changed</em> counts and each group's <strong>Reset</strong> count and reset only the controls on show; choosing a
68
+ preset still sets every control. The <a href="getting-started.html#the-custom-wizard">Custom wizard</a> leaves
69
+ the same controls out.</p>
70
+ <p>Only Quality reads <strong>Precision</strong>, <strong>Time limit</strong>, <strong>Match repeated shapes</strong>, <strong>Match threshold</strong>,
71
+ <strong>Fewer paths</strong>, <strong>Repair crossing rings</strong>, <strong>Curve cost</strong> and <strong>Smooth-join angle</strong>. Every other
72
+ control changes the trace in both engines, though some only in company: <strong>Holes as cutouts</strong>
73
+ only with Trace transparency off, and <strong>Flat fills</strong> in Fast only where the image has a smooth
74
+ colour ramp. This was measured, not assumed: each control was moved on a range of images in both
75
+ engines, and a control counts as read by an engine if any of those moves changed the SVG it
76
+ wrote.</p>
77
+ <p><strong>Two tones by lightness</strong> and <strong>Line art</strong> trace the same way in either engine, with the fitter Quality
78
+ uses, so while either is on, Fast shows the same controls as Quality. (Line art that declines, on
79
+ a drawing that is not line art, leaves the trace to Fast, and those extra controls then do
80
+ nothing.)</p>
81
  <h2 id="presets">Presets</h2>
82
+ <p>A preset is a handful of settings chosen together. The tray shows the ten built-ins; the line
83
  under it describes the one selected.</p>
84
  <table>
85
  <thead>
 
122
  <td><kbd>Ctrl</kbd>+<kbd>5</kbd></td>
123
  </tr>
124
  <tr>
125
+ <td><strong>One-colour logo</strong></td>
126
+ <td>Black artwork on white</td>
127
+ <td>One colour on</td>
128
  <td><kbd>Ctrl</kbd>+<kbd>6</kbd></td>
129
  </tr>
130
  <tr>
131
+ <td><strong>Black, no background</strong></td>
132
+ <td>Black artwork, transparent</td>
133
+ <td>One colour and Transparent background on</td>
134
+ <td><kbd>Ctrl</kbd>+<kbd>7</kbd></td>
135
+ </tr>
136
+ <tr>
137
+ <td><strong>Two-tone scan</strong></td>
138
+ <td>Stamps, signatures, by lightness</td>
139
+ <td>Two tones by lightness on</td>
140
+ <td><kbd>Ctrl</kbd>+<kbd>8</kbd></td>
141
+ </tr>
142
+ <tr>
143
  <td><strong>Line art</strong></td>
144
  <td>Uniform-stroke drawings</td>
145
  <td>Line art on</td>
146
+ <td><kbd>Ctrl</kbd>+<kbd>9</kbd></td>
147
  </tr>
148
  <tr>
149
  <td><strong>Editable</strong></td>
150
  <td>Tidy nodes for an artist to edit</td>
151
  <td>Editable structure on</td>
152
+ <td><kbd>Ctrl</kbd>+<kbd>0</kbd></td>
153
  </tr>
154
  </tbody>
155
  </table>
 
159
  <p><strong>Photo or scan</strong> needs the denoiser to do what it says. Without it the trace still runs, and the
160
  stage says the denoiser is missing and offers the download.</p>
161
  <h3 id="saving-your-own">Saving your own</h3>
162
+ <p><strong>Save as preset</strong> stores all twenty-three controls exactly as they stand, under a name you give
163
  (up to 40 characters). It appears in the tray after the built-ins; the <strong>×</strong> on its chip forgets
164
  it. You can keep up to twelve. A saved preset is a complete snapshot rather than a list of
165
  differences, so it does not change if a future version changes the defaults.</p>
 
195
  genuinely different colours were merged.</p>
196
  <p><strong>Flat fills instead of gradients</strong> (off). Skips gradient fitting and fills every region with one
197
  colour. For flat artwork, or when the SVG must not contain gradients.</p>
198
+ <p><strong>One colour (black)</strong> (off). Every shape that is not the background is drawn black, light
199
+ colours included, on a white background; with <strong>Transparent background</strong> on, on nothing, so the
200
+ artwork can be placed on any design. Lettering on a coloured panel is cut out of a black panel.
201
+ For logos and lettering. The presets <em>One-colour logo</em> and <em>Black, no background</em> turn it on.</p>
202
+ <p><strong>Two tones by lightness</strong> (off). Dark becomes black and light becomes white, like a photocopy,
203
+ so light colours drop out: the Potrace-style mode, for stamps, signatures and scans of print (the
204
+ <em>Two-tone scan</em> preset). It wins over One colour when both are on.</p>
205
  <p><strong>Trace transparency</strong> (on). Transparency is traced as it is: holes stay holes, every ink carries
206
  its own opacity, and soft shadows, glows and feathered edges come back as translucent fills. Turned
207
  off, the image is laid on a solid background first and traced as solid colours, which fills holes
 
284
  <td><code>--no-gradients</code></td>
285
  </tr>
286
  <tr>
287
+ <td>One colour (black)</td>
288
+ <td><code>--monochrome</code></td>
289
+ </tr>
290
+ <tr>
291
+ <td>Two tones by lightness</td>
292
  <td><code>--bilevel</code></td>
293
  </tr>
294
  <tr>
 
354
  </tbody>
355
  </table>
356
  <p><code>inkvec --help</code> lists them all with their exact spelling.</p><nav class="pagenav"><a class="prev" href="result.html"><span class="dir">Previous</span><span class="lbl">Result</span></a><a class="next" href="palette.html"><span class="dir">Next</span><span class="lbl">Palette and colour groups</span></a></nav></article></main>
357
+ <aside class="rail"><h5>On this page</h5><ul><ul><li class="l2"><a href="#how-the-controls-work">How the controls work</a></li><li class="l2"><a href="#the-engine-the-denoiser-and-editable">The engine, the denoiser and Editable</a><ul><li class="l3"><a href="#which-controls-each-engine-reads">Which controls each engine reads</a></li></ul></li><li class="l2"><a href="#presets">Presets</a><ul><li class="l3"><a href="#saving-your-own">Saving your own</a></li></ul></li><li class="l2"><a href="#detail">Detail</a></li><li class="l2"><a href="#colour">Colour</a></li><li class="l2"><a href="#shape">Shape</a></li><li class="l2"><a href="#output">Output</a></li><li class="l2"><a href="#the-same-controls-on-the-command-line">The same controls on the command line</a></li></ul></ul></aside>
358
  </div>
359
  </body>
360
  </html>
studio/guide/viewer.html CHANGED
@@ -73,7 +73,7 @@ measured against.</p>
73
  <p><img alt="Wireframe, anchors and handles over the SVG at 4×" src="img/overlays.webp"></p>
74
  <p>A key to the marks appears at the right of the toolbar while any overlay is on. Anchors and
75
  handles are how you judge what the file will be like to edit: fewer nodes, and handles that line
76
- up, are easier to work with. <a href="tune.html#the-denoiser-and-editable">Editable structure</a> is the setting
77
  that moves them towards what an artist would draw.</p>
78
  <h2 id="detail-the-pixel-grid-under-the-edge">Detail: the pixel grid under the edge</h2>
79
  <p><strong>Detail</strong> draws the source's pixel grid under the SVG, one cell per source pixel, and zooms to
 
73
  <p><img alt="Wireframe, anchors and handles over the SVG at 4×" src="img/overlays.webp"></p>
74
  <p>A key to the marks appears at the right of the toolbar while any overlay is on. Anchors and
75
  handles are how you judge what the file will be like to edit: fewer nodes, and handles that line
76
+ up, are easier to work with. <a href="tune.html#the-engine-the-denoiser-and-editable">Editable structure</a> is the setting
77
  that moves them towards what an artist would draw.</p>
78
  <h2 id="detail-the-pixel-grid-under-the-edge">Detail: the pixel grid under the edge</h2>
79
  <p><strong>Detail</strong> draws the source's pixel grid under the SVG, one cell per source pixel, and zooms to
studio/index.html CHANGED
@@ -11,8 +11,8 @@
11
  <meta name="description" content="Turn a raster logo into an exact SVG, in your browser. Nothing is uploaded." />
12
  <link rel="icon" href="./favicon.svg" type="image/svg+xml" />
13
  <title>Inkvec Studio Lite</title>
14
- <script type="module" crossorigin src="./assets/main--3-Ll9JM.js"></script>
15
- <link rel="stylesheet" crossorigin href="./assets/main-C8vHcyec.css">
16
  <link rel="preload" href="./fonts/playfair-latin.woff2" as="font" type="font/woff2" crossorigin />
17
  <link rel="preload" href="./fonts/inter-latin.woff2" as="font" type="font/woff2" crossorigin />
18
  <style>
@@ -356,7 +356,7 @@ html.boot-go .boot-progress {
356
  </div>
357
  <footer class="boot-foot">
358
  <span>Runs in your browser. Your image never leaves this computer.</span>
359
- <span>Version 0.2.1 · Apache-2.0 · logolabs.org</span>
360
  </footer>
361
  </div>
362
  <div id="app"></div>
 
11
  <meta name="description" content="Turn a raster logo into an exact SVG, in your browser. Nothing is uploaded." />
12
  <link rel="icon" href="./favicon.svg" type="image/svg+xml" />
13
  <title>Inkvec Studio Lite</title>
14
+ <script type="module" crossorigin src="./assets/main-ai0rIBhL.js"></script>
15
+ <link rel="stylesheet" crossorigin href="./assets/main-BwYpaGSz.css">
16
  <link rel="preload" href="./fonts/playfair-latin.woff2" as="font" type="font/woff2" crossorigin />
17
  <link rel="preload" href="./fonts/inter-latin.woff2" as="font" type="font/woff2" crossorigin />
18
  <style>
 
356
  </div>
357
  <footer class="boot-foot">
358
  <span>Runs in your browser. Your image never leaves this computer.</span>
359
+ <span>Version 0.2.3 · Apache-2.0 · logolabs.org</span>
360
  </footer>
361
  </div>
362
  <div id="app"></div>
studio/pkg-threads/inkvec_studio_wasm.d.ts CHANGED
@@ -44,12 +44,19 @@ export class Studio {
44
  /**
45
  * Trace the open image (`start_trace`'s work), synchronously.
46
  *
47
- * `on_stage(name, ms)` is called as the pipeline passes each stage; `is_current()` is
48
- * asked, once the drawing is done, whether the page still wants this generation --
 
 
 
 
49
  * a drawing it has moved past is kept in the cache but not measured. Returns the
50
  * outcome as JSON (`trace:done`'s `outcome`), or `undefined` when it was retired.
 
 
 
51
  */
52
- trace(request: string, draft_px: number, draft_seconds: number, generation: number, on_stage: Function, is_current: Function): string | undefined;
53
  }
54
 
55
  /**
 
44
  /**
45
  * Trace the open image (`start_trace`'s work), synchronously.
46
  *
47
+ * `on_progress(json)` is called with what the engine reported (`trace:progress`'s
48
+ * payload, without the generation) whenever a stage starts, ends or says something,
49
+ * and at most every [`PROGRESS_MS`] for a loop's count. This worker is busy for the
50
+ * whole trace, so the pipeline's own thread is the only place progress can leave from;
51
+ * a count kept on rayon's workers shows at the next report made here. `is_current()`
52
+ * is asked, once the drawing is done, whether the page still wants this generation --
53
  * a drawing it has moved past is kept in the cache but not measured. Returns the
54
  * outcome as JSON (`trace:done`'s `outcome`), or `undefined` when it was retired.
55
+ *
56
+ * A trace here is never cancelled from inside: WebAssembly cannot unwind, so the page
57
+ * stops a trace nobody wants by terminating this worker (`engine.ts`).
58
  */
59
+ trace(request: string, draft_px: number, draft_seconds: number, generation: number, on_progress: Function, is_current: Function): string | undefined;
60
  }
61
 
62
  /**
studio/pkg-threads/inkvec_studio_wasm.js CHANGED
@@ -195,24 +195,31 @@ export class Studio {
195
  /**
196
  * Trace the open image (`start_trace`'s work), synchronously.
197
  *
198
- * `on_stage(name, ms)` is called as the pipeline passes each stage; `is_current()` is
199
- * asked, once the drawing is done, whether the page still wants this generation --
 
 
 
 
200
  * a drawing it has moved past is kept in the cache but not measured. Returns the
201
  * outcome as JSON (`trace:done`'s `outcome`), or `undefined` when it was retired.
 
 
 
202
  * @param {string} request
203
  * @param {number} draft_px
204
  * @param {number} draft_seconds
205
  * @param {number} generation
206
- * @param {Function} on_stage
207
  * @param {Function} is_current
208
  * @returns {string | undefined}
209
  */
210
- trace(request, draft_px, draft_seconds, generation, on_stage, is_current) {
211
  try {
212
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
213
  const ptr0 = passStringToWasm0(request, wasm.__wbindgen_export, wasm.__wbindgen_export2);
214
  const len0 = WASM_VECTOR_LEN;
215
- wasm.studio_trace(retptr, this.__wbg_ptr, ptr0, len0, draft_px, draft_seconds, generation, addBorrowedObject(on_stage), addBorrowedObject(is_current));
216
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
217
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
218
  var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
@@ -423,10 +430,6 @@ function __wbg_get_imports(memory) {
423
  const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
424
  return addHeapObject(ret);
425
  }, arguments); },
426
- __wbg_call_7bbd9cceba9949ad: function() { return handleError(function (arg0, arg1, arg2, arg3) {
427
- const ret = getObject(arg0).call(getObject(arg1), getObject(arg2), getObject(arg3));
428
- return addHeapObject(ret);
429
- }, arguments); },
430
  __wbg_error_757e9472f8410341: function(arg0, arg1) {
431
  let deferred0_0;
432
  let deferred0_1;
@@ -442,7 +445,7 @@ function __wbg_get_imports(memory) {
442
  const ret = Reflect.get(getObject(arg0), getObject(arg1));
443
  return addHeapObject(ret);
444
  }, arguments); },
445
- __wbg_inkvecDenoiseSync_9b982eb59f0480ef: function() { return handleError(function (arg0, arg1, arg2, arg3) {
446
  const ret = globalThis.inkvecDenoiseSync(getArrayF32FromWasm0(arg0, arg1), arg2 >>> 0, arg3 >>> 0);
447
  return addHeapObject(ret);
448
  }, arguments); },
 
195
  /**
196
  * Trace the open image (`start_trace`'s work), synchronously.
197
  *
198
+ * `on_progress(json)` is called with what the engine reported (`trace:progress`'s
199
+ * payload, without the generation) whenever a stage starts, ends or says something,
200
+ * and at most every [`PROGRESS_MS`] for a loop's count. This worker is busy for the
201
+ * whole trace, so the pipeline's own thread is the only place progress can leave from;
202
+ * a count kept on rayon's workers shows at the next report made here. `is_current()`
203
+ * is asked, once the drawing is done, whether the page still wants this generation --
204
  * a drawing it has moved past is kept in the cache but not measured. Returns the
205
  * outcome as JSON (`trace:done`'s `outcome`), or `undefined` when it was retired.
206
+ *
207
+ * A trace here is never cancelled from inside: WebAssembly cannot unwind, so the page
208
+ * stops a trace nobody wants by terminating this worker (`engine.ts`).
209
  * @param {string} request
210
  * @param {number} draft_px
211
  * @param {number} draft_seconds
212
  * @param {number} generation
213
+ * @param {Function} on_progress
214
  * @param {Function} is_current
215
  * @returns {string | undefined}
216
  */
217
+ trace(request, draft_px, draft_seconds, generation, on_progress, is_current) {
218
  try {
219
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
220
  const ptr0 = passStringToWasm0(request, wasm.__wbindgen_export, wasm.__wbindgen_export2);
221
  const len0 = WASM_VECTOR_LEN;
222
+ wasm.studio_trace(retptr, this.__wbg_ptr, ptr0, len0, draft_px, draft_seconds, generation, addBorrowedObject(on_progress), addBorrowedObject(is_current));
223
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
224
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
225
  var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
 
430
  const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
431
  return addHeapObject(ret);
432
  }, arguments); },
 
 
 
 
433
  __wbg_error_757e9472f8410341: function(arg0, arg1) {
434
  let deferred0_0;
435
  let deferred0_1;
 
445
  const ret = Reflect.get(getObject(arg0), getObject(arg1));
446
  return addHeapObject(ret);
447
  }, arguments); },
448
+ __wbg_inkvecDenoiseSync_4eb7a20f8b117e76: function() { return handleError(function (arg0, arg1, arg2, arg3) {
449
  const ret = globalThis.inkvecDenoiseSync(getArrayF32FromWasm0(arg0, arg1), arg2 >>> 0, arg3 >>> 0);
450
  return addHeapObject(ret);
451
  }, arguments); },
studio/pkg-threads/inkvec_studio_wasm_bg.wasm CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:b5de05eb83836d1dd2ba57ecc43cc743b10d0f69d2cdb4ccd7440dc5aefedccf
3
- size 5733382
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7f5572bed15d6a7884fb4af79ba6b34949ebd9cc0ffdbe4328565d87d24178ce
3
+ size 5845653
studio/pkg-threads/snippets/wasm-bindgen-rayon-38edf6e439f6d70d/src/workerHelpers.js CHANGED
@@ -51,7 +51,7 @@ waitForMsgType(self, 'wasm_bindgen_worker_init').then(async ({ init, receiver })
51
  // OTOH, even though it can't be inlined, it should be still reasonably
52
  // cheap since the requested file is already in cache (it was loaded by
53
  // the main thread).
54
- const pkg = await import('../../../inkvec_studio_wasm.js?v=b192891e1025');
55
  await pkg.default(init);
56
  postMessage({ type: 'wasm_bindgen_worker_ready' });
57
  pkg.wbg_rayon_start_worker(receiver);
 
51
  // OTOH, even though it can't be inlined, it should be still reasonably
52
  // cheap since the requested file is already in cache (it was loaded by
53
  // the main thread).
54
+ const pkg = await import('../../../inkvec_studio_wasm.js?v=05758cc93999');
55
  await pkg.default(init);
56
  postMessage({ type: 'wasm_bindgen_worker_ready' });
57
  pkg.wbg_rayon_start_worker(receiver);
studio/pkg/inkvec_studio_wasm.d.ts CHANGED
@@ -44,12 +44,19 @@ export class Studio {
44
  /**
45
  * Trace the open image (`start_trace`'s work), synchronously.
46
  *
47
- * `on_stage(name, ms)` is called as the pipeline passes each stage; `is_current()` is
48
- * asked, once the drawing is done, whether the page still wants this generation --
 
 
 
 
49
  * a drawing it has moved past is kept in the cache but not measured. Returns the
50
  * outcome as JSON (`trace:done`'s `outcome`), or `undefined` when it was retired.
 
 
 
51
  */
52
- trace(request: string, draft_px: number, draft_seconds: number, generation: number, on_stage: Function, is_current: Function): string | undefined;
53
  }
54
 
55
  /**
 
44
  /**
45
  * Trace the open image (`start_trace`'s work), synchronously.
46
  *
47
+ * `on_progress(json)` is called with what the engine reported (`trace:progress`'s
48
+ * payload, without the generation) whenever a stage starts, ends or says something,
49
+ * and at most every [`PROGRESS_MS`] for a loop's count. This worker is busy for the
50
+ * whole trace, so the pipeline's own thread is the only place progress can leave from;
51
+ * a count kept on rayon's workers shows at the next report made here. `is_current()`
52
+ * is asked, once the drawing is done, whether the page still wants this generation --
53
  * a drawing it has moved past is kept in the cache but not measured. Returns the
54
  * outcome as JSON (`trace:done`'s `outcome`), or `undefined` when it was retired.
55
+ *
56
+ * A trace here is never cancelled from inside: WebAssembly cannot unwind, so the page
57
+ * stops a trace nobody wants by terminating this worker (`engine.ts`).
58
  */
59
+ trace(request: string, draft_px: number, draft_seconds: number, generation: number, on_progress: Function, is_current: Function): string | undefined;
60
  }
61
 
62
  /**
studio/pkg/inkvec_studio_wasm.js CHANGED
@@ -193,24 +193,31 @@ export class Studio {
193
  /**
194
  * Trace the open image (`start_trace`'s work), synchronously.
195
  *
196
- * `on_stage(name, ms)` is called as the pipeline passes each stage; `is_current()` is
197
- * asked, once the drawing is done, whether the page still wants this generation --
 
 
 
 
198
  * a drawing it has moved past is kept in the cache but not measured. Returns the
199
  * outcome as JSON (`trace:done`'s `outcome`), or `undefined` when it was retired.
 
 
 
200
  * @param {string} request
201
  * @param {number} draft_px
202
  * @param {number} draft_seconds
203
  * @param {number} generation
204
- * @param {Function} on_stage
205
  * @param {Function} is_current
206
  * @returns {string | undefined}
207
  */
208
- trace(request, draft_px, draft_seconds, generation, on_stage, is_current) {
209
  try {
210
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
211
  const ptr0 = passStringToWasm0(request, wasm.__wbindgen_export, wasm.__wbindgen_export2);
212
  const len0 = WASM_VECTOR_LEN;
213
- wasm.studio_trace(retptr, this.__wbg_ptr, ptr0, len0, draft_px, draft_seconds, generation, addBorrowedObject(on_stage), addBorrowedObject(is_current));
214
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
215
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
216
  var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
@@ -360,10 +367,6 @@ function __wbg_get_imports() {
360
  const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
361
  return addHeapObject(ret);
362
  }, arguments); },
363
- __wbg_call_7bbd9cceba9949ad: function() { return handleError(function (arg0, arg1, arg2, arg3) {
364
- const ret = getObject(arg0).call(getObject(arg1), getObject(arg2), getObject(arg3));
365
- return addHeapObject(ret);
366
- }, arguments); },
367
  __wbg_error_757e9472f8410341: function(arg0, arg1) {
368
  let deferred0_0;
369
  let deferred0_1;
@@ -379,7 +382,7 @@ function __wbg_get_imports() {
379
  const ret = Reflect.get(getObject(arg0), getObject(arg1));
380
  return addHeapObject(ret);
381
  }, arguments); },
382
- __wbg_inkvecDenoiseSync_9b982eb59f0480ef: function() { return handleError(function (arg0, arg1, arg2, arg3) {
383
  const ret = globalThis.inkvecDenoiseSync(getArrayF32FromWasm0(arg0, arg1), arg2 >>> 0, arg3 >>> 0);
384
  return addHeapObject(ret);
385
  }, arguments); },
 
193
  /**
194
  * Trace the open image (`start_trace`'s work), synchronously.
195
  *
196
+ * `on_progress(json)` is called with what the engine reported (`trace:progress`'s
197
+ * payload, without the generation) whenever a stage starts, ends or says something,
198
+ * and at most every [`PROGRESS_MS`] for a loop's count. This worker is busy for the
199
+ * whole trace, so the pipeline's own thread is the only place progress can leave from;
200
+ * a count kept on rayon's workers shows at the next report made here. `is_current()`
201
+ * is asked, once the drawing is done, whether the page still wants this generation --
202
  * a drawing it has moved past is kept in the cache but not measured. Returns the
203
  * outcome as JSON (`trace:done`'s `outcome`), or `undefined` when it was retired.
204
+ *
205
+ * A trace here is never cancelled from inside: WebAssembly cannot unwind, so the page
206
+ * stops a trace nobody wants by terminating this worker (`engine.ts`).
207
  * @param {string} request
208
  * @param {number} draft_px
209
  * @param {number} draft_seconds
210
  * @param {number} generation
211
+ * @param {Function} on_progress
212
  * @param {Function} is_current
213
  * @returns {string | undefined}
214
  */
215
+ trace(request, draft_px, draft_seconds, generation, on_progress, is_current) {
216
  try {
217
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
218
  const ptr0 = passStringToWasm0(request, wasm.__wbindgen_export, wasm.__wbindgen_export2);
219
  const len0 = WASM_VECTOR_LEN;
220
+ wasm.studio_trace(retptr, this.__wbg_ptr, ptr0, len0, draft_px, draft_seconds, generation, addBorrowedObject(on_progress), addBorrowedObject(is_current));
221
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
222
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
223
  var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
 
367
  const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
368
  return addHeapObject(ret);
369
  }, arguments); },
 
 
 
 
370
  __wbg_error_757e9472f8410341: function(arg0, arg1) {
371
  let deferred0_0;
372
  let deferred0_1;
 
382
  const ret = Reflect.get(getObject(arg0), getObject(arg1));
383
  return addHeapObject(ret);
384
  }, arguments); },
385
+ __wbg_inkvecDenoiseSync_4eb7a20f8b117e76: function() { return handleError(function (arg0, arg1, arg2, arg3) {
386
  const ret = globalThis.inkvecDenoiseSync(getArrayF32FromWasm0(arg0, arg1), arg2 >>> 0, arg3 >>> 0);
387
  return addHeapObject(ret);
388
  }, arguments); },
studio/pkg/inkvec_studio_wasm_bg.wasm CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:b9ac51390a9a4e76b2d89f7fff0093c66bb2ecd560ca5ad8267b10a5d6141396
3
- size 5700735
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cfdf37c0cc3d661558b7a9e0338d9715b9a1b41f8305808e9750b71e188063df
3
+ size 5813486