summaryrefslogtreecommitdiff
path: root/projects/gerbolyze/index.html
diff options
context:
space:
mode:
authorjaseg <git@jaseg.de>2023-03-19 18:58:10 +0100
committerjaseg <git@jaseg.de>2023-03-19 18:58:10 +0100
commit1cf2411d4e021c010a3ddbb01764776db254c92a (patch)
tree747e304c7f55a3f328def721d0941e9b0f380bdb /projects/gerbolyze/index.html
parent3c6957467fc401648369905efae98c0a228af752 (diff)
parent520b18c751b20e96059d4bda84df011d81f76eb7 (diff)
downloadblog-1cf2411d4e021c010a3ddbb01764776db254c92a.tar.gz
blog-1cf2411d4e021c010a3ddbb01764776db254c92a.tar.bz2
blog-1cf2411d4e021c010a3ddbb01764776db254c92a.zip
deploy.py auto-commit
Diffstat (limited to 'projects/gerbolyze/index.html')
-rw-r--r--projects/gerbolyze/index.html639
1 files changed, 639 insertions, 0 deletions
diff --git a/projects/gerbolyze/index.html b/projects/gerbolyze/index.html
new file mode 100644
index 0000000..6090587
--- /dev/null
+++ b/projects/gerbolyze/index.html
@@ -0,0 +1,639 @@
+<!DOCTYPE html>
+<html><head>
+ <meta charset="utf-8">
+ <title>Gerbolyze | Home</title>
+ <meta name="description" content="">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="color-scheme" content="dark light">
+ <link rel="stylesheet" href="/style.css">
+</head>
+<body><nav>
+
+ <a href="/" title="Home">Home</a>
+ <a href="/blog/" title="Blog">Blog</a>
+ <a href="/projects/" title="Projects">Projects</a>
+ <a href="/about/" title="About">About</a>
+ <span class="spacer"></span>
+ <a href="https://git.jaseg.de/" title="cgit">cgit</a>
+ <a href="https://github.com/jaseg" title="Github">Github</a>
+ <a href="https://gitlab.com/neinseg" title="Gitlab">Gitlab</a>
+ <a href="https://chaos.social/jaseg" title="Mastodon">Mastodon</a>
+</nav>
+
+ <header>
+ <h1>Gerbolyze</h1>
+<ul class="breadcrumbs">
+ <li><a href="/">jaseg.de</a></li>
+ <li><a href="/projects/">Projects</a></li><li><a href="/projects/gerbolyze/">Gerbolyze</a></li>
+</ul>
+
+ </header>
+ <main>
+ <div class="links">
+ <a href="https://git.jaseg.de/gerbolyze.git">Sources</a>
+ <a href="https://github.com/jaseg/gerbolyze/issues">Issues</a>
+ <a href="https://gerbolyze.gitlab.io/gerbolyze">Docs</a>
+ <a href="https://pypi.org/project/gerbolyze">PyPI</a>
+ </div>
+ <div class="document">
+
+
+<p>Gerbolyze renders SVG vector and PNG/JPG raster images into existing gerber PCB manufacturing files.
+Vector data from SVG files is rendered losslessly <em>without</em> an intermediate rasterization/revectorization step.
+Still, gerbolyze supports (almost) the full SVG 1.1 spec including complex, self-intersecting paths with holes,
+patterns, dashes and transformations.</p>
+<p>Raster images can either be vectorized through contour tracing (like gerbolyze v1.0 did) or they can be embedded using
+high-resolution grayscale emulation while (mostly) guaranteeing trace/space design rules.</p>
+<p>Try gerbolyze online at <a class="reference external" href="https://dyna.kokoroyukuma.de/gerboweb">https://dyna.kokoroyukuma.de/gerboweb</a></p>
+<div class="figure">
+<img alt="pics/pcbway_sample_02_small.jpg" src="pics/pcbway_sample_02_small.jpg" style="width: 800px;" />
+<p class="caption">Drawing by <a class="reference external" href="https://twitter.com/fluffy2038/status/1317231121269104640">トーコ Toko</a> converted using Gerbolyze and printed at PCBWay.</p>
+</div>
+<p>Tooling for PCB art is quite limited in both open source and closed source ecosystems. Something as simple as putting a
+pretty picture on a PCB can be an extremely tedious task. Depending on the PCB tool used, various arcane incantations
+may be necessary and even modestly complex images will slow down most PCB tools to a crawl.</p>
+<p>Gerbolyze solves this problem in a toolchain-agnostic way by directly vectorizing SVG vector and PNG or JPG bitmap files
+onto existing gerber layers. Gerbolyze processes any spec-compliant SVG and &quot;gerbolyzes&quot; SVG vector data into a Gerber
+spec-compliant form. Gerbolyze has been tested against both the leading open-source KiCAD toolchain and the
+industry-standard Altium Designer. Gerbolyze is written with performance in mind and will happily vectorize tens of
+thousands of primitives, generating tens of megabytes of gerber code without crapping itself. With gerbolyze you can
+finally be confident that your PCB fab's toolchain will fall over before yours does if you overdo it with the high-poly
+anime silkscreen.</p>
+<p>Gerbolyze is based on <a class="reference external" href="https://gitlab.com/gerbolyze/gerbonara">gerbonara</a>.</p>
+<img alt="pics/process-overview.png" src="pics/process-overview.png" style="width: 800px;" />
+<div class="contents topic" id="contents">
+<p class="topic-title">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#tl-dr-produce-high-quality-artistic-pcbs-in-three-easy-steps" id="toc-entry-1">Tl;dr: Produce high-quality artistic PCBs in three easy steps!</a></li>
+<li><a class="reference internal" href="#quick-start-installation-any-platform" id="toc-entry-2">Quick Start Installation (Any Platform)</a></li>
+<li><a class="reference internal" href="#speeding-up-gerbolyze-using-natively-built-binaries" id="toc-entry-3">Speeding up gerbolyze using natively-built binaries</a><ul>
+<li><a class="reference internal" href="#build-from-source-any-distro" id="toc-entry-4">Build from source (any distro)</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#features" id="toc-entry-5">Features</a></li>
+<li><a class="reference internal" href="#algorithm-overview" id="toc-entry-6">Algorithm Overview</a></li>
+<li><a class="reference internal" href="#web-interface" id="toc-entry-7">Web interface</a></li>
+<li><a class="reference internal" href="#command-line-usage" id="toc-entry-8">Command-line usage</a><ul>
+<li><a class="reference internal" href="#gerbolyze-template" id="toc-entry-9"><tt class="docutils literal">gerbolyze template</tt></a><ul>
+<li><a class="reference internal" href="#options" id="toc-entry-10">Options:</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#gerbolyze-paste" id="toc-entry-11"><tt class="docutils literal">gerbolyze paste</tt></a><ul>
+<li><a class="reference internal" href="#options-1" id="toc-entry-12">Options:</a></li>
+<li><a class="reference internal" href="#outline-layers-1" id="toc-entry-13">Outline layers</a></li>
+<li><a class="reference internal" href="#subtraction-scripts" id="toc-entry-14">Subtraction scripts</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#svg-flatten-1" id="toc-entry-15"><tt class="docutils literal"><span class="pre">svg-flatten</span></tt></a><ul>
+<li><a class="reference internal" href="#options-2" id="toc-entry-16">Options:</a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference internal" href="#gerbolyze-image-vectorization" id="toc-entry-17">Gerbolyze image vectorization</a><ul>
+<li><a class="reference internal" href="#vectorizer-poisson-disc-the-default" id="toc-entry-18"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">poisson-disc</span></tt> (the default)</a></li>
+<li><a class="reference internal" href="#vectorizer-hex-grid" id="toc-entry-19"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">hex-grid</span></tt></a></li>
+<li><a class="reference internal" href="#vectorizer-square-grid" id="toc-entry-20"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">square-grid</span></tt></a></li>
+<li><a class="reference internal" href="#vectorizer-binary-contours" id="toc-entry-21"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">binary-contours</span></tt></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#gimp-halftone-preprocessing-guide" id="toc-entry-22">GIMP halftone preprocessing guide</a><ul>
+<li><a class="reference internal" href="#import-your-desired-artwork" id="toc-entry-23">1 Import your desired artwork</a></li>
+<li><a class="reference internal" href="#convert-the-image-to-grayscale" id="toc-entry-24">2 Convert the image to grayscale</a></li>
+<li><a class="reference internal" href="#fine-tune-the-image-s-contrast" id="toc-entry-25">3 Fine-tune the image's contrast</a></li>
+<li><a class="reference internal" href="#retouch-details" id="toc-entry-26">4 Retouch details</a></li>
+<li><a class="reference internal" href="#run-the-newsprint-filter" id="toc-entry-27">5 Run the newsprint filter</a></li>
+<li><a class="reference internal" href="#export-the-image-for-use-with-gerbolyze-vectorize" id="toc-entry-28">6 Export the image for use with <tt class="docutils literal">gerbolyze vectorize</tt></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#manufacturing-considerations" id="toc-entry-29">Manufacturing Considerations</a></li>
+<li><a class="reference internal" href="#limitations" id="toc-entry-30">Limitations</a><ul>
+<li><a class="reference internal" href="#svg-raster-features" id="toc-entry-31">SVG raster features</a></li>
+<li><a class="reference internal" href="#gerber-pass-through" id="toc-entry-32">Gerber pass-through</a></li>
+<li><a class="reference internal" href="#trace-space-design-rule-adherence" id="toc-entry-33">Trace/Space design rule adherence</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#gallery" id="toc-entry-34">Gallery</a></li>
+<li><a class="reference internal" href="#licensing" id="toc-entry-35">Licensing</a></li>
+</ul>
+</div>
+<div class="section" id="tl-dr-produce-high-quality-artistic-pcbs-in-three-easy-steps">
+<h2><a class="toc-backref" href="#toc-entry-1">Tl;dr: Produce high-quality artistic PCBs in three easy steps!</a></h2>
+<p>Gerbolyze works in three steps.</p>
+<ol class="arabic">
+<li><p class="first">Generate a scale-accurate template of the finished PCB from your CAD tool's gerber output:</p>
+<pre class="code literal-block">
+<span class="lineno"></span><span class="line">$ gerbolyze template --top template_top.svg [--bottom template_bottom.svg] my_gerber_dir
+</span></pre>
+</li>
+<li><p class="first">Load the resulting template image <a class="reference external" href="https://inkscape.org/">Inkscape</a> or another SVG editing program. Put your artwork on the appropriate SVG
+layer. Dark colors become filled gerber primitives, bright colors become unfilled primitives. You can directly put
+raster images (PNG/JPG) into this SVG as well, just position and scale them like everything else. SVG clips work for
+images, too. Masks are not supported.</p>
+</li>
+<li><p class="first">Vectorize the edited SVG template image drectly into the PCB's gerber files:</p>
+<pre class="code literal-block">
+<span class="lineno"></span><span class="line">$ gerbolyze paste --top template_top_edited.svg [--bottom ...] my_gerber_dir output_gerber_dir
+</span></pre>
+</li>
+</ol>
+</div>
+<div class="section" id="quick-start-installation-any-platform">
+<h2><a class="toc-backref" href="#toc-entry-2">Quick Start Installation (Any Platform)</a></h2>
+<pre class="code shell literal-block">
+<span class="lineno"></span><span class="line">python<span class="w"> </span>-m<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>--user<span class="w"> </span>gerbolyze
+</span></pre>
+<p>To uninstall, run</p>
+<pre class="code shell literal-block">
+<span class="lineno"></span><span class="line">python<span class="w"> </span>-m<span class="w"> </span>pip<span class="w"> </span>uninstall<span class="w"> </span>gerbolyze<span class="w"> </span>gerbonara<span class="w"> </span>resvg-wasi<span class="w"> </span>svg-flatten-wasi
+</span></pre>
+<p>To update, run</p>
+<pre class="code shell literal-block">
+<span class="lineno"></span><span class="line">python<span class="w"> </span>-m<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>--user<span class="w"> </span>--upgrade<span class="w"> </span>--upgrade-strategy<span class="w"> </span>eager<span class="w"> </span>gerbolyze
+</span></pre>
+</div>
+<div class="section" id="speeding-up-gerbolyze-using-natively-built-binaries">
+<h2><a class="toc-backref" href="#toc-entry-3">Speeding up gerbolyze using natively-built binaries</a></h2>
+<p>This will install gerbolyze's binary dependency resvg and gerbolyze's svg-flatten utility as pre-built cross-platform
+WASM binaries. When you first run gerbolyze, it will take some time (~30s) to link these binaries for your system. The
+output is cached, so any future run is going to be fast.</p>
+<p>WASM is slower than natively-built binaries. To speed up gerbolyze, you can natively build its two binary dependencies:</p>
+<ol class="arabic simple">
+<li>Install resvg natively using rust's cargo package manager: <tt class="docutils literal">cargo install resvg</tt></li>
+<li>Install gerbolyze's svg-flatten utility natively. You can get pre-built binaries from gerbolyze's gitlab CI jobs <a class="reference external" href="https://gitlab.com/gerbolyze/gerbolyze/-/pipelines?scope=tags&amp;page=1">at
+this link</a> by clicking the three dots on the
+right next to the version you want. These pre-built binaries should work on any x86_64 linux since they are
+statically linked. You can also build svg-flatten yourself by running <tt class="docutils literal">make</tt> inside the <tt class="docutils literal"><span class="pre">svg-flatten</span></tt> folder from
+a gerbolyze checkout.</li>
+</ol>
+<p>Gerbolyze will pick up these binaries when installed in your <tt class="docutils literal">$PATH</tt>. resvg is also picked up when it is installed by
+cargo in your home's <tt class="docutils literal"><span class="pre">~/.cargo</span></tt>, even if it's not in your <tt class="docutils literal">$PATH</tt>. You can override the resvg, usvg or svg-flatten
+binary that gerbolyze uses by giving it the absoulute path to a binary in the <tt class="docutils literal">$RESVG</tt>, <tt class="docutils literal">$USVG</tt> and <tt class="docutils literal">$SVG_FLATTEN</tt>
+environment variables.</p>
+<div class="section" id="build-from-source-any-distro">
+<h3><a class="toc-backref" href="#toc-entry-4">Build from source (any distro)</a></h3>
+<pre class="code sh literal-block">
+<span class="lineno"></span><span class="line">git<span class="w"> </span>clone<span class="w"> </span>--recurse-submodules<span class="w"> </span>https://git.jaseg.de/gerbolyze.git<span class="w"></span></span>
+<span class="lineno"></span><span class="line"><span class="w"></span><span class="nb">cd</span><span class="w"> </span>gerbolyze<span class="w"></span></span>
+<span class="lineno"></span><span class="line"><span class="w"></span></span>
+<span class="lineno"></span><span class="line"><span class="w"></span>python3<span class="w"> </span>-m<span class="w"> </span>venv<span class="w"></span></span>
+<span class="lineno"></span><span class="line"><span class="w"></span><span class="nb">source</span><span class="w"> </span>venv/bin/activate<span class="w"></span></span>
+<span class="lineno"></span><span class="line"><span class="w"></span>python3<span class="w"> </span>setup.py<span class="w"> </span>install
+</span></pre>
+</div>
+</div>
+<div class="section" id="features">
+<h2><a class="toc-backref" href="#toc-entry-5">Features</a></h2>
+<p>Input on the left, output on the right.</p>
+<img alt="pics/test_svg_readme_composited.png" src="pics/test_svg_readme_composited.png" style="width: 800px;" />
+<ul class="simple">
+<li>Almost full SVG 1.1 static spec coverage (!)<ul>
+<li>Paths with beziers, self-intersections and holes</li>
+<li>Strokes, even with dashes and markers</li>
+<li>Pattern fills and strokes</li>
+<li>Transformations and nested groups</li>
+<li>Proper text rendering with support for complex text layout (e.g. Arabic)</li>
+<li>&lt;image&gt; elements via either built-in vectorizer or built-in halftone processor</li>
+<li>(some) CSS</li>
+</ul>
+</li>
+<li>Writes Gerber, SVG or KiCAD S-Expression (<tt class="docutils literal">.kicad_mod</tt>) formats</li>
+<li>Can export from top/bottom SVGs to a whole gerber layer stack at once with filename autodetection</li>
+<li>Can export SVGs to <tt class="docutils literal">.kicad_mod</tt> files like svg2mod (but with full SVG support)</li>
+<li>Beziers flattening with configurable tolerance using actual math!</li>
+<li>Polygon intersection removal</li>
+<li>Polygon hole removal (!)</li>
+<li>Optionally vector-compositing of output: convert black/white/transparent image to black/transparent image</li>
+<li>Renders SVG templates from input gerbers for accurate and easy scaling and positioning of artwork</li>
+<li>layer masking with offset (e.g. all silk within 1mm of soldermask)</li>
+<li>Can read gerbers from zip files</li>
+<li>Limited SVG support for board outline layers (no fill/region support)</li>
+<li>Dashed lines supported on board outline layers</li>
+</ul>
+<p>Gerbolyze is the end-to-end &quot;paste this svg into these gerbers&quot; command that handles all layers on both board sides at
+once. The heavy-duty computer geometry logic of gerbolyze is handled by the svg-flatten utility (<tt class="docutils literal"><span class="pre">svg-flatten</span></tt>
+directory). svg-flatten reads an SVG file and renders it into a variety of output formats. svg-flatten can be used like
+a variant of the popular svg2mod that supports all of SVG and handles arbitrary input <tt class="docutils literal">&lt;path&gt;</tt> elements.</p>
+</div>
+<div class="section" id="algorithm-overview">
+<h2><a class="toc-backref" href="#toc-entry-6">Algorithm Overview</a></h2>
+<p>This is the algorithm gerbolyze uses to process a stack of gerbers.</p>
+<ul class="simple">
+<li>Map input files to semantic layers by their filenames</li>
+<li>For each layer:<ul>
+<li>load input gerber</li>
+<li>Pass mask layers through <tt class="docutils literal">gerbv</tt> for conversion to SVG</li>
+<li>Pass mask layers SVG through <tt class="docutils literal"><span class="pre">svg-flatten</span> <span class="pre">--dilate</span></tt></li>
+<li>Pass input SVG through <tt class="docutils literal"><span class="pre">svg-flatten</span> <span class="pre">--only-groups</span> [layer]</tt></li>
+<li>Overlay input gerber, mask and input svg</li>
+<li>Write result to output gerber</li>
+</ul>
+</li>
+</ul>
+<p>This is the algorithm svg-flatten uses to process an SVG.</p>
+<ul class="simple">
+<li>pass input SVG through <a class="reference external" href="https://github.com/RazrFalcon/resvg">usvg</a></li>
+<li>iterate depth-first through resulting SVG.<ul>
+<li>for groups: apply transforms and clip and recurse</li>
+<li>for images: Vectorize using selected vectorizer</li>
+<li>for paths:<ul>
+<li>flatten path using Cairo</li>
+<li>remove self-intersections using Clipper</li>
+<li>if stroke is set: process dash, then offset using Clipper</li>
+<li>apply pattern fills</li>
+<li>clip to clip-path</li>
+<li>remove holes using Clipper</li>
+</ul>
+</li>
+</ul>
+</li>
+<li>for KiCAD S-Expression export: vector-composite results using CavalierContours: subtract each clear output primitive
+from all previous dark output primitives</li>
+</ul>
+</div>
+<div class="section" id="web-interface">
+<h2><a class="toc-backref" href="#toc-entry-7">Web interface</a></h2>
+<p>You can try gerbolyze online at <a class="reference external" href="https://dyna.kokoroyukuma.de/gerboweb">https://dyna.kokoroyukuma.de/gerboweb</a></p>
+<p>The web interface does not expose all of gerbolyze's bells and whistles, but it allows you to simply paste a single SVG
+file on a board to try out gerbolyze. Upload your design on the web interface, then download the template for either the
+top or bottom side, and put your artwork on the appropriate layer of that template using <a class="reference external" href="https://inkscape.org/">Inkscape</a>. Finally, upload the
+modified template and let gerbolyze process your design.</p>
+</div>
+<div class="section" id="command-line-usage">
+<h2><a class="toc-backref" href="#toc-entry-8">Command-line usage</a></h2>
+<p id="command-line-usage-1">Generate SVG template from Gerber files:</p>
+<pre class="code shell literal-block">
+<span class="lineno"></span><span class="line">gerbolyze<span class="w"> </span>template<span class="w"> </span><span class="o">[</span>options<span class="o">]</span><span class="w"> </span><span class="o">[</span>--top<span class="p">|</span>--bottom<span class="o">]</span><span class="w"> </span>input_dir_or.zip<span class="w"> </span>output.svg
+</span></pre>
+<p>Render design from an SVG made with the template above into a set of gerber files:</p>
+<pre class="code shell literal-block">
+<span class="lineno"></span><span class="line">gerbolyze<span class="w"> </span>paste<span class="w"> </span><span class="o">[</span>options<span class="o">]</span><span class="w"> </span>artwork.svg<span class="w"> </span>input_dir_or.zip<span class="w"> </span>output_dir_or.zip
+</span></pre>
+<p>Use svg-flatten to convert an SVG file into Gerber or flattened SVG:</p>
+<pre class="code shell literal-block">
+<span class="lineno"></span><span class="line">svg-flatten<span class="w"> </span><span class="o">[</span>options<span class="o">]</span><span class="w"> </span>--format<span class="w"> </span><span class="o">[</span>gerber<span class="p">|</span>svg<span class="o">]</span><span class="w"> </span><span class="o">[</span>input_file.svg<span class="o">]</span><span class="w"> </span><span class="o">[</span>output_file<span class="o">]</span>
+</span></pre>
+<p>Use svg-flatten to convert an SVG file into the given layer of a KiCAD S-Expression (<tt class="docutils literal">.kicad_mod</tt>) file:</p>
+<pre class="code shell literal-block">
+<span class="lineno"></span><span class="line">svg-flatten<span class="w"> </span><span class="o">[</span>options<span class="o">]</span><span class="w"> </span>--format<span class="w"> </span>kicad<span class="w"> </span>--sexp-layer<span class="w"> </span>F.SilkS<span class="w"> </span>--sexp-mod-name<span class="w"> </span>My_Module<span class="w"> </span><span class="o">[</span>input_file.svg<span class="o">]</span><span class="w"> </span><span class="o">[</span>output_file<span class="o">]</span>
+</span></pre>
+<p>Use svg-flatten to convert an SVG file into a <tt class="docutils literal">.kicad_mod</tt> with SVG layers fed into separate KiCAD layers based on
+their IDs like the popular <tt class="docutils literal">svg2mod</tt> is doing:</p>
+<dl class="docutils">
+<dt>Note:</dt>
+<dd><p class="first">Right now, the input SVG's layers must have <em>ids</em> that match up KiCAD's s-exp layer names. Note that when you name
+a layer in Inkscape that only sets a <tt class="docutils literal">name</tt> attribute, but does not change the ID. In order to change the ID in
+Inkscape, you have to use Inkscape's &quot;object properties&quot; context menu function.</p>
+<p>Also note that svg-flatten expects the layer names KiCAD uses in their S-Expression format. These are <em>different</em> to
+the layer names KiCAD exposes in the UI (even though most of them match up!).</p>
+<p class="last">For your convenience, there is an SVG template with all the right layer names and IDs located next to this README.</p>
+</dd>
+</dl>
+<pre class="code shell literal-block">
+<span class="lineno"></span><span class="line">svg-flatten<span class="w"> </span><span class="o">[</span>options<span class="o">]</span><span class="w"> </span>--format<span class="w"> </span>kicad<span class="w"> </span>--sexp-mod-name<span class="w"> </span>My_Module<span class="w"> </span><span class="o">[</span>input_file.svg<span class="o">]</span><span class="w"> </span><span class="o">[</span>output_file<span class="o">]</span>
+</span></pre>
+<div class="section" id="gerbolyze-template">
+<h3><a class="toc-backref" href="#toc-entry-9"><tt class="docutils literal">gerbolyze template</tt></a></h3>
+<p>Usage: <tt class="docutils literal">gerbolyze template [OPTIONS] INPUT</tt></p>
+<p>Generate SVG template for gerbolyze paste from gerber files.</p>
+<p>INPUT may be a gerber file, directory of gerber files or zip file with gerber files. The output file contains a preview
+image of the input gerbers to allow you to position your artwork, as well as prepared Inkscape layers corresponding to
+each gerber layer. Simply place your artwork in this SVG template using Inkscape. Starting in v3.0, gerbolyze
+automatically keeps track of which board side (top or bottom) is contained in an SVG template.</p>
+<div class="section" id="options">
+<h4><a class="toc-backref" href="#toc-entry-10">Options:</a></h4>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">--top</span> | <span class="pre">--bottom</span></tt></dt>
+<dd>Output top or bottom side template. This affects both the preview image and the prepared Inkscape layers.</dd>
+<dt><tt class="docutils literal"><span class="pre">--vector</span> | <span class="pre">--raster</span></tt></dt>
+<dd>Embed preview renders into output file as SVG vector graphics instead of rendering them to PNG bitmaps. The
+resulting preview may slow down your SVG editor.</dd>
+<dt><tt class="docutils literal"><span class="pre">--raster-dpi</span> FLOAT</tt></dt>
+<dd>DPI for rastering preview</dd>
+<dt><tt class="docutils literal"><span class="pre">--bbox</span> TEXT</tt></dt>
+<dd>Output file bounding box. Format: &quot;w,h&quot; to force [w] mm by [h] mm output canvas OR &quot;x,y,w,h&quot; to force [w] mm by [h]
+mm output canvas with its bottom left corner at the given input gerber coördinates.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="gerbolyze-paste">
+<h3><a class="toc-backref" href="#toc-entry-11"><tt class="docutils literal">gerbolyze paste</tt></a></h3>
+<p>(see <a class="reference internal" href="#vectorization">below</a>)</p>
+<p>Usage: <tt class="docutils literal">gerbolyze paste [OPTIONS] INPUT_GERBERS OVERLAY_SVG OUTPUT_GERBERS</tt></p>
+<p>Render vector data and raster images from SVG file into gerbers. The SVG input file can be generated using <tt class="docutils literal">gerbolyze
+template</tt> and contains the name and board side of each layer. Note that for board outline layers, handling slightly
+differs from other layers as PCB fabs do not support filled Gerber regions on these layers.</p>
+<div class="section" id="options-1">
+<h4><a class="toc-backref" href="#toc-entry-12">Options:</a></h4>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">--bbox</span> TEXT</tt></dt>
+<dd>Output file bounding box. Format: &quot;w,h&quot; to force [w] mm by [h] mm output canvas OR &quot;x,y,w,h&quot; to force [w] mm by [h]
+mm output canvas with its bottom left corner at the given input gerber coördinates. This <strong>must match the ``--bbox`` value given to
+template</strong>!</dd>
+<dt><tt class="docutils literal"><span class="pre">--subtract</span> TEXT</tt></dt>
+<dd>Use user subtraction script from argument (see <a class="reference internal" href="#subtraction-script">below</a>)</dd>
+<dt><tt class="docutils literal"><span class="pre">--no-subtract</span></tt></dt>
+<dd>Disable subtraction (see <a class="reference internal" href="#subtraction-script">below</a>)</dd>
+<dt><tt class="docutils literal"><span class="pre">--dilate</span> FLOAT</tt></dt>
+<dd>Default dilation for subtraction operations in mm (see <a class="reference internal" href="#subtraction-script">below</a>)</dd>
+<dt><tt class="docutils literal"><span class="pre">--trace-space</span> FLOAT</tt></dt>
+<dd>Passed through to svg-flatten, see <a class="reference internal" href="#svg-flatten">below</a>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--vectorizer</span> TEXT</tt></dt>
+<dd>Passed through to svg-flatten, see <a class="reference internal" href="#svg-flatten">its description below</a>. Also have a look at <a class="reference internal" href="#vectorization">the examples below</a>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--vectorizer-map</span> TEXT</tt></dt>
+<dd>Passed through to svg-flatten, see <a class="reference internal" href="#svg-flatten">below</a>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--exclude-groups</span> TEXT</tt></dt>
+<dd>Passed through to svg-flatten, see <a class="reference internal" href="#svg-flatten">below</a>.</dd>
+</dl>
+</div>
+<div class="section" id="outline-layers-1">
+<span id="outline-layers"></span><h4><a class="toc-backref" href="#toc-entry-13">Outline layers</a></h4>
+<p>Outline layers require special handling since PCB fabs do not support filled G36/G37 polygons on these layers. The main
+difference between normal layers and outline layers is how strokes are handled. On outline layers, strokes are
+translated to normal Gerber draw commands (D01, D02 etc.) with an aperture set to the stroke's width instead of tracing
+them to G36/G37 filled regions. This means that on outline layers, SVG end caps and line join types do not work: All
+lines are redered with round joins and end caps.</p>
+<p>One exception from this are patterns, which work as expected for both fills and strokes with full support for joins and
+end caps.</p>
+<p>Dashed strokes are supported on outline layers and can be used to make easy mouse bites.</p>
+</div>
+<div class="section" id="subtraction-scripts">
+<span id="subtraction-script"></span><h4><a class="toc-backref" href="#toc-entry-14">Subtraction scripts</a></h4>
+<img alt="pics/subtract_example.png" src="pics/subtract_example.png" style="width: 800px;" />
+<p>Subtraction scripts tell <tt class="docutils literal">gerbolyze paste</tt> to remove an area around certain input layers to from an overlay layer.
+When a input layer is given in the subtraction script, gerbolyze will dilate (extend outwards) everything on this input
+layer and remove it from the target overlay layer. By default, Gerbolyze subtracts the mask layer from the silk layer to
+make sure there are no silk primitives that overlap bare copper, and subtracts each input layer from its corresponding
+overlay to make sure the two do not overlap. In the picture above you can see both at work: The overlay contains
+halftone primitives all over the place. The subtraction script has cut out an area around all pads (mask layer) and all
+existing silkscreen. You can turn off this behavior by passing <tt class="docutils literal"><span class="pre">--no-subtract</span></tt> or pass your own &quot;script&quot;.</p>
+<p>The syntax of these scripts is:</p>
+<pre class="code literal-block">
+<span class="lineno"></span><span class="line">{target layer} -= {source layer} {dilation} [; ...]
+</span></pre>
+<p>The target layer must be <tt class="docutils literal"><span class="pre">out.{layer</span> name}</tt> and the source layer <tt class="docutils literal"><span class="pre">in.{layer</span> name}</tt>. The layer names are gerbolyze's
+internal layer names, i.e.: <tt class="docutils literal">paste, silk, mask, copper, outline, drill</tt></p>
+<p>The dilation value is optional, but can be a float with a leading <tt class="docutils literal">+</tt> or <tt class="docutils literal">-</tt>. If given, before subtraction the
+source layer's features will be extended by that many mm. If not given, the dilation defaults to the value given by
+<tt class="docutils literal"><span class="pre">--dilate</span></tt> if given or 0.1 mm otherwise. To disable dilation, simply pass <tt class="docutils literal">+0</tt> here.</p>
+<p>Multiple commands can be separated by semicolons <tt class="docutils literal">;</tt> or line breaks.</p>
+<p>The default subtraction script is:</p>
+<pre class="code literal-block">
+<span class="lineno"></span><span class="line">out.silk -= in.mask</span>
+<span class="lineno"></span><span class="line">out.silk -= in.silk+0.5</span>
+<span class="lineno"></span><span class="line">out.mask -= in.mask+0.5</span>
+<span class="lineno"></span><span class="line">out.copper -= in.copper+0.5
+</span></pre>
+</div>
+</div>
+<div class="section" id="svg-flatten-1">
+<span id="svg-flatten"></span><h3><a class="toc-backref" href="#toc-entry-15"><tt class="docutils literal"><span class="pre">svg-flatten</span></tt></a></h3>
+<p>Usage: <tt class="docutils literal"><span class="pre">svg-flatten</span> <span class="pre">[OPTIONS]...</span> [INPUT_FILE] [OUTPUT_FILE]</tt></p>
+<p>Specify <tt class="docutils literal">-</tt> for stdin/stdout.</p>
+<div class="section" id="options-2">
+<h4><a class="toc-backref" href="#toc-entry-16">Options:</a></h4>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-h,</span> <span class="pre">--help</span></tt></dt>
+<dd>Print help and exit</dd>
+<dt><tt class="docutils literal"><span class="pre">-v,</span> <span class="pre">--version</span></tt></dt>
+<dd>Print version and exit</dd>
+<dt><tt class="docutils literal"><span class="pre">-o,</span> <span class="pre">--format</span></tt></dt>
+<dd>Output format. Supported: gerber, gerber-outline (for board outline layers), svg, s-exp (KiCAD S-Expression)</dd>
+<dt><tt class="docutils literal"><span class="pre">-p,</span> <span class="pre">--precision</span></tt></dt>
+<dd>Number of decimal places use for exported coordinates (gerber: 1-9, SVG: &gt;=0). Note that not all gerber viewers are
+happy with too many digits. 5 or 6 is a reasonable choice.</dd>
+<dt><tt class="docutils literal"><span class="pre">--clear-color</span></tt></dt>
+<dd>SVG color to use in SVG output for &quot;clear&quot; areas (default: white)</dd>
+<dt><tt class="docutils literal"><span class="pre">--dark-color</span></tt></dt>
+<dd>SVG color to use in SVG output for &quot;dark&quot; areas (default: black)</dd>
+<dt><tt class="docutils literal"><span class="pre">-f,</span> <span class="pre">--flip-gerber-polarity</span></tt></dt>
+<dd>Flip polarity of all output gerber primitives for --format gerber.</dd>
+<dt><tt class="docutils literal"><span class="pre">-d,</span> <span class="pre">--trace-space</span></tt></dt>
+<dd>Minimum feature size of elements in vectorized graphics (trace/space) in mm. Default: 0.1mm.</dd>
+<dt><tt class="docutils literal"><span class="pre">--no-header</span></tt></dt>
+<dd>Do not export output format header/footer, only export the primitives themselves</dd>
+<dt><tt class="docutils literal"><span class="pre">--flatten</span></tt></dt>
+<dd>Flatten output so it only consists of non-overlapping white polygons. This perform composition at the vector level.
+Potentially slow. This defaults to on when using KiCAD S-Exp export because KiCAD does not know polarity or colors.</dd>
+<dt><tt class="docutils literal"><span class="pre">--no-flatten</span></tt></dt>
+<dd>Disable automatic flattening for KiCAD S-Exp export</dd>
+<dt><tt class="docutils literal"><span class="pre">--dilate</span></tt></dt>
+<dd>Dilate output gerber primitives by this amount in mm. Used for masking out other layers.</dd>
+<dt><tt class="docutils literal"><span class="pre">-g,</span> <span class="pre">--only-groups</span></tt></dt>
+<dd>Comma-separated list of group IDs to export.</dd>
+<dt><tt class="docutils literal"><span class="pre">-b,</span> <span class="pre">--vectorizer</span></tt></dt>
+<dd>Vectorizer to use for bitmap images. One of poisson-disc (default), hex-grid, square-grid, binary-contours,
+dev-null. Have a look at <a class="reference internal" href="#vectorization">the examples below</a>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--vectorizer-map</span></tt></dt>
+<dd><p class="first">Map from image element id to vectorizer. Overrides --vectorizer. Format: id1=vectorizer,id2=vectorizer,...</p>
+<p class="last">You can use this to set a certain vectorizer for specific images, e.g. if you want to use both halftone
+vectorization and contour tracing in the same SVG. Note that you can set an <tt class="docutils literal">&lt;image&gt;</tt> element's SVG ID from within
+Inkscape though the context menu's Object Properties tool.</p>
+</dd>
+<dt><tt class="docutils literal"><span class="pre">--force-svg</span></tt></dt>
+<dd>Force SVG input irrespective of file name</dd>
+<dt><tt class="docutils literal"><span class="pre">--force-png</span></tt></dt>
+<dd>Force bitmap graphics input irrespective of file name</dd>
+<dt><tt class="docutils literal"><span class="pre">-s,</span> <span class="pre">--size</span></tt></dt>
+<dd>Bitmap mode only: Physical size of output image in mm. Format: 12.34x56.78</dd>
+<dt><tt class="docutils literal"><span class="pre">--sexp-mod-name</span></tt></dt>
+<dd>Module name for KiCAD S-Exp output. This is a mandatory argument if using S-Exp output.</dd>
+<dt><tt class="docutils literal"><span class="pre">--sexp-layer</span></tt></dt>
+<dd>Layer for KiCAD S-Exp output. Defaults to auto-detect layers from SVG layer/top-level group IDs. If given, SVG
+groups and layers are completely ignored and everything is simply vectorized into this layer, though you cna still
+use <tt class="docutils literal"><span class="pre">-g</span></tt> for group selection.</dd>
+<dt><tt class="docutils literal"><span class="pre">-a,</span> <span class="pre">--preserve-aspect-ratio</span></tt></dt>
+<dd>Bitmap mode only: Preserve aspect ratio of image. Allowed values are meet, slice. Can also parse full SVG
+preserveAspectRatio syntax.</dd>
+<dt><tt class="docutils literal"><span class="pre">--no-usvg</span></tt></dt>
+<dd>Do not preprocess input using usvg (do not use unless you know <em>exactly</em> what you're doing)</dd>
+<dt><tt class="docutils literal"><span class="pre">--usvg-dpi</span></tt></dt>
+<dd>Passed through to usvg's --dpi, in case the input file has different ideas of DPI than usvg has.</dd>
+<dt><tt class="docutils literal"><span class="pre">--scale</span></tt></dt>
+<dd>Scale input svg lengths by this factor (-o gerber only).</dd>
+<dt><tt class="docutils literal"><span class="pre">-e,</span> <span class="pre">--exclude-groups</span></tt></dt>
+<dd>Comma-separated list of group IDs to exclude from export. Takes precedence over --only-groups.</dd>
+</dl>
+</div>
+</div>
+</div>
+<div class="section" id="gerbolyze-image-vectorization">
+<span id="vectorization"></span><h2><a class="toc-backref" href="#toc-entry-17">Gerbolyze image vectorization</a></h2>
+<p>Gerbolyze has two built-in strategies to translate pixel images into vector images. One is its built-in halftone
+processor that tries to approximate grayscale. The other is its built-in binary vectorizer that traces contours in
+black-and-white images. Below are examples for the four options.</p>
+<p>The vectorizers can be used in isolation through <tt class="docutils literal"><span class="pre">svg-flatten</span></tt> with either an SVG input that contains an image or a
+PNG/JPG input.</p>
+<p>The vectorizer can be controlled globally using the <tt class="docutils literal"><span class="pre">--vectorizer</span></tt> flag in both <tt class="docutils literal">gerbolyze</tt> and <tt class="docutils literal"><span class="pre">svg-flatten</span></tt>. It
+can also be set on a per-image basis in both using <tt class="docutils literal"><span class="pre">--vectorizer-map</span> [image svg <span class="pre">id]=[option][&quot;,&quot;</span> <span class="pre">...]</span></tt>.</p>
+<!-- for f in vec_*.png; convert -background white -gravity center $f -resize 500x500 -extent 500x500 (basename -s .png $f)-square.png; end -->
+<!-- for vec in hexgrid square poisson contours; convert vec_"$vec"_whole-square.png vec_"$vec"_detail-square.png -background transparent -splice 25x0+0+0 +append -chop 25x0+0+0 vec_"$vec"_composited.png; end -->
+<div class="section" id="vectorizer-poisson-disc-the-default">
+<h3><a class="toc-backref" href="#toc-entry-18"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">poisson-disc</span></tt> (the default)</a></h3>
+<img alt="pics/vec_poisson_composited.png" src="pics/vec_poisson_composited.png" style="width: 800px;" />
+</div>
+<div class="section" id="vectorizer-hex-grid">
+<h3><a class="toc-backref" href="#toc-entry-19"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">hex-grid</span></tt></a></h3>
+<img alt="pics/vec_hexgrid_composited.png" src="pics/vec_hexgrid_composited.png" style="width: 800px;" />
+</div>
+<div class="section" id="vectorizer-square-grid">
+<h3><a class="toc-backref" href="#toc-entry-20"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">square-grid</span></tt></a></h3>
+<img alt="pics/vec_square_composited.png" src="pics/vec_square_composited.png" style="width: 800px;" />
+</div>
+<div class="section" id="vectorizer-binary-contours">
+<h3><a class="toc-backref" href="#toc-entry-21"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">binary-contours</span></tt></a></h3>
+<img alt="pics/vec_contours_composited.png" src="pics/vec_contours_composited.png" style="width: 800px;" />
+<p>The binary contours vectorizer requires a black-and-white binary input image. As you can see, like every bitmap tracer
+it will produce some artifacts. For artistic input this is usually not too bad as long as the input data is
+high-resolution. Antialiased edges in the input image are not only OK, they may even help with an accurate
+vectorization.</p>
+</div>
+</div>
+<div class="section" id="gimp-halftone-preprocessing-guide">
+<h2><a class="toc-backref" href="#toc-entry-22">GIMP halftone preprocessing guide</a></h2>
+<p>Gerbolyze has its own built-in halftone processor, but you can also use the high-quality &quot;newsprint&quot; filter built into
+<a class="reference external" href="https://gimp.org/">GIMP</a> instead if you like. This section will guide you through this. The PNG you get out of this can then be fed into
+gerbolyze using <tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">binary-contours</span></tt>.</p>
+<div class="section" id="import-your-desired-artwork">
+<h3><a class="toc-backref" href="#toc-entry-23">1 Import your desired artwork</a></h3>
+<p>Though anime or manga pictures are highly recommended, you can use any image including photographs. Be careful to select
+a picture with comparatively low detail that remains recognizable at very low resolution. While working on a screen this
+is hard to vizualize, but the grain resulting from the low resolution of a PCB's silkscreen is quite coarse.</p>
+<img alt="screenshots/02import02.png" src="screenshots/02import02.png" style="width: 800px;" />
+</div>
+<div class="section" id="convert-the-image-to-grayscale">
+<h3><a class="toc-backref" href="#toc-entry-24">2 Convert the image to grayscale</a></h3>
+<img alt="screenshots/06grayscale.png" src="screenshots/06grayscale.png" style="width: 800px;" />
+</div>
+<div class="section" id="fine-tune-the-image-s-contrast">
+<h3><a class="toc-backref" href="#toc-entry-25">3 Fine-tune the image's contrast</a></h3>
+<p>To look well on the PCB, contrast is critical. If your source image is in color, you may have lost some contrast during
+grayscale conversion. Now is the time to retouch that using the GIMP's color curve tool.</p>
+<p>When using the GIMP's newsprint filter, bright grays close to white and dark grays close to black will cause very small
+dots that might be beyond your PCB manufacturer's maximum resolution. To control this case, add small steps at the ends
+of the grayscale value curve as shown (exaggerated) in the picture below. These steps saturate very bright grays to
+white and very dark grays to black while preserving the values in the middle.</p>
+<img alt="screenshots/08curve_cut.png" src="screenshots/08curve_cut.png" style="width: 800px;" />
+</div>
+<div class="section" id="retouch-details">
+<h3><a class="toc-backref" href="#toc-entry-26">4 Retouch details</a></h3>
+<p>Therer might be small details that don't look right yet, such as the image's background color or small highlights that
+merge into the background now. You can manually change the color of any detail now using the GIMP's flood-fill tool.</p>
+<p>If you don't want the image's background to show up on the final PCB at all, just make it black.</p>
+<p>Particularly on low-resolution source images it may make sense to apply a blur with a radius similar to the following
+newsprint filter's cell size (10px) to smooth out the dot pattern generated by the newsprint filter.</p>
+<img alt="screenshots/09retouch.png" src="screenshots/09retouch.png" style="width: 800px;" />
+<p>In the following example, I retouched the highlights in the hair of the character in the picture to make them completely
+white instead of light-gray, so they still stand out nicely in the finished picture.</p>
+<img alt="screenshots/10retouched.png" src="screenshots/10retouched.png" style="width: 800px;" />
+</div>
+<div class="section" id="run-the-newsprint-filter">
+<h3><a class="toc-backref" href="#toc-entry-27">5 Run the newsprint filter</a></h3>
+<p>Now, run the GIMP's newsprint filter, under filters, distorts, newsprint.</p>
+<p>The first important settings is the spot size, which should be larger than your PCB's minimum detail size (about 10px
+with <tt class="docutils literal">gerbolyze render</tt> default settings for good-quality silkscreen). In general the cheap and fast standard option of chinese PCB houses will require a larger detail size, but when you order specialty options like large size, 4-layer or non-green color along with a longer turnaround time you'll get much better-quality silk screen.</p>
+<p>The second important setting is oversampling, which should be set to four or slightly higher. This improves the result
+of the edge reconstruction of <tt class="docutils literal">gerbolyze vectorize</tt>.</p>
+<img alt="screenshots/11newsprint.png" src="screenshots/11newsprint.png" style="width: 800px;" />
+<p>The following are examples on the detail resulting from the newsprint filter.</p>
+<img alt="screenshots/12newsprint.png" src="screenshots/12newsprint.png" style="width: 800px;" />
+</div>
+<div class="section" id="export-the-image-for-use-with-gerbolyze-vectorize">
+<h3><a class="toc-backref" href="#toc-entry-28">6 Export the image for use with <tt class="docutils literal">gerbolyze vectorize</tt></a></h3>
+<p>Simply export the image as a PNG file. Below are some pictures of the output <tt class="docutils literal">gerbolyze vectorize</tt> produced for this
+example.</p>
+<img alt="screenshots/14result_cut.png" src="screenshots/14result_cut.png" style="width: 800px;" />
+<img alt="screenshots/15result_cut.png" src="screenshots/15result_cut.png" style="width: 800px;" />
+</div>
+</div>
+<div class="section" id="manufacturing-considerations">
+<h2><a class="toc-backref" href="#toc-entry-29">Manufacturing Considerations</a></h2>
+<p>The main consideration when designing artwork for PCB processes is the processes' trace/space design rule. The two
+things you can do here is one, to be creative with graphical parts of the design and avoid extremely narrow lines,
+wedges or other thin features that will not come out well. Number two is to keep detail in raster images several times
+larger than the manufacturing processes native capability. For example, to target a trace/space design rule of 100 µm,
+the smallest detail in embedded raster graphics should not be much below 1mm.</p>
+<p>Gerbolyze's halftone vectorizers have built-in support for trace/space design rules. While they can still produce small
+artifacts that violate these rules, their output should be close enough to satifsy board houses and close enough for the
+result to look good. The way gerbolyze does this is to clip the halftone cell's values to zero whenevery they get too
+small, and to forcefully split or merge two neighboring cells when they get too close. While this process introduces
+slight steps at the top and bottom of grayscale response, for most inputs these are not noticeable.</p>
+<p>On the other hand, for SVG vector elements as well as for traced raster images, Gerbolyze cannot help with these design
+rules. There is no heuristic that would allow Gerbolyze to non-destructively &quot;fix&quot; a design here, so all that's on the
+roadmap here is to eventually include a gerber-level design rule checker.</p>
+<p>As far as board houses go, I have made good experiences with the popular Chinese board houses. In my experience, JLC
+will just produce whatever you send them with little fucks being given about design rule adherence or validity of the
+input gerbers. This is great if you just want artistic circuit boards without much of a hassle, and you don't care if
+they come out exactly as you imagined. The worst I've had happen was when an older version of gerbolyze generated
+polygons with holes assuming standard fill-rule processing. The in the board house's online gerber viewer things looked
+fine, and neither did they complain during file review. However, the resulting boards looked completely wrong because
+all the dark halftones were missing.</p>
+<p>PCBWay on the other hand has a much more rigurous file review process. They &lt;em&gt;will&lt;/em&gt; complain when you throw
+illegal garbage gerbers at them, and they will helpfully guide you through your design rule violations. In this way you
+get much more of a professional service from them and for designs that have to be functional their higher level of
+scrutiny definitely is a good thing. For the design you saw in the first picture in this article, I ended up begging
+them to just plot my files if it doesn't physically break their machines and to their credit, while they seemed unhappy
+about it they did it and the result looks absolutely stunning.</p>
+<p>PCBWay is a bit more expensive on their lowest-end offering than JLC, but I found that for anything else (large boards,
+multi-layer, gold plating etc.) their prices match. PCBWay offers a much broader range of manufacturing options such as
+flexible circuit boards, multi-layer boards, thick or thin substrates and high-temperature substrates.</p>
+<p>When in doubt about how your design is going to come out on the board, do not hesitate to contact your board house. Most
+of the end customer-facing online PCB services have a number of different factories that do a number of different
+fabrication processes for them depending on order parameters. Places like PCBWay have exceptional quality control and
+good customer service, but that is mostly focused on the technical aspects of the PCB. If you rely on visual aspects
+like silkscreen uniformity or solder mask color that is a strong no concern to everyone else in the electronics
+industry, you may find significant variations between manufacturers or even between orders with the same manufacturer
+and you may encounter challenges communicating your requirements.</p>
+</div>
+<div class="section" id="limitations">
+<h2><a class="toc-backref" href="#toc-entry-30">Limitations</a></h2>
+<div class="section" id="svg-raster-features">
+<h3><a class="toc-backref" href="#toc-entry-31">SVG raster features</a></h3>
+<p>Currently, SVG masks and filters are not supported. Though SVG is marketed as a &quot;vector graphics format&quot;, these two
+features are really raster primitives that all SVG viewers perform at the pixel level after rasterization. Since
+supporting these would likely not end up looking like what you want, it is not a planned feature. If you need masks or
+filters, simply export the relevant parts of the SVG as a PNG then include that in your template.</p>
+</div>
+<div class="section" id="gerber-pass-through">
+<h3><a class="toc-backref" href="#toc-entry-32">Gerber pass-through</a></h3>
+<p>Since gerbolyze has to composite your input gerbers with its own output, it has to fully parse and re-serialize them.
+gerbolyze <a class="reference external" href="https://gitlab.com/gerbolyze/gerbonara">gerbonara</a> for all its gerber parsing needs. Thus, gerbonara will interpret your gerbers and output will be in
+gerbonara's gerber &quot;dialect&quot;. If you find a corner case where this does not work and the output looks wrong, please file
+a bug report with an example file on the <a class="reference external" href="https://gitlab.com/gerbolyze/gerbonara">gerbonara</a> bug tracker. <em>Always</em> check the output files for errors before
+submitting them to production.</p>
+<p>Gerbolyze is provided without any warranty, but still please open an issue or <a class="reference external" href="mailto:gerbolyze&#64;jaseg.de">send me an email</a> if you find any errors or inconsistencies.</p>
+</div>
+<div class="section" id="trace-space-design-rule-adherence">
+<h3><a class="toc-backref" href="#toc-entry-33">Trace/Space design rule adherence</a></h3>
+<p>While the grayscale halftone vectorizers do a reasonable job adhering to a given trace/space design rule, they can still
+produce small parts of output that violate it. For the contour vectorizer as well as for all SVG primitives, you are
+responsible for adhering to design rules yourself as there is no algorithm that gerboyze could use to &quot;fix&quot; its input.</p>
+<p>A design rule checker is planned as a future addition to gerbolyze, but is not yet part of it. If in doubt, talk to your
+fab and consider doing a test run of your design before ordering assembled boards ;)</p>
+</div>
+</div>
+<div class="section" id="gallery">
+<h2><a class="toc-backref" href="#toc-entry-34">Gallery</a></h2>
+<img alt="pics/sample3.jpg" src="pics/sample3.jpg" style="width: 400px;" />
+<p>For a demonstration of <tt class="docutils literal">gerbolyze convert</tt>, check out the <a class="reference external" href="https://dyna.kokoroyukuma.de/protos/">Gerbolyze Protoboard Index</a>, where you can download gerber
+files for over 7.000 SMD and THT protoboard layouts.</p>
+</div>
+<div class="section" id="licensing">
+<h2><a class="toc-backref" href="#toc-entry-35">Licensing</a></h2>
+<p>This tool is licensed under the rather radical AGPLv3 license. Briefly, this means that you have to provide users of a
+webapp using this tool in the backend with this tool's source.</p>
+<p>I get that some people have issues with the AGPL. In case this license prevents you from using this software, please
+send me <a class="reference external" href="mailto:agpl.sucks&#64;jaseg.de">an email</a> and I can grant you an exception. I want this software to be useful to as
+many people as possible and I wouldn't want the license to be a hurdle to anyone. OTOH I see a danger of some cheap
+board house just integrating a fork into their webpage without providing their changes back upstream, and I want to
+avoid that so the default license is still AGPL.</p>
+</div>
+</div>
+ </main><footer>
+ Copyright © 2023 Jan Sebastian Götte
+ / <a href="/about/">About</a>
+ / <a href="/imprint/">Imprint</a>
+</footer>
+</body>
+</html>