Repository navigation
Conversation
Gerber files (.gbr, .gtl, .gbl, .gto, .gbo, .gts, .gbs, .gtp, .gbp, .gko, .gm1, .gml) are drawn as SVG at their real size by a built-in reader, and the vector engine takes them to PDF (vector), PNG, JPG, DXF and DWG. - Apertures C/R/O/P with holes, aperture macros with variables, expressions and every primitive, linear and circular draws (single- and multi-quadrant), regions, LPD/LPC, LM/LR/LS, nested aperture blocks, step and repeat, IPNEG. - KiCad colours on its dark background, by the layer's role (X2 file function, else the file name). - Clear polarity applied as geometry with Skia path operations, so the PDF stays vector; past a budget, painted in the background colour. - Defensive reading with budgets checked before allocation. - Read only, CAD field, learnt by the CAD donut (settings schema 87). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPxh5sc7UXmkshJ7pDMouF
- Count block flashes and step-and-repeat copies at their drawn size against their own budget, so a panel of a large board passes while blocks flashed inside blocks can't multiply without end. - A budget for macro primitives over all aperture definitions. - Numbers too long for their field fail as damaged files, not overflows. - dotnet format. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPxh5sc7UXmkshJ7pDMouF
KnifeLemon
requested changes
Nov 13, 2026
KnifeLemon
left a comment
Owner
There was a problem hiding this comment.
Thanks for this, @Ugoyo. It's a careful reader: the budgets, the reasoned InvalidDataExceptions, the gerbv/tracespace
comparison and the docs section make it easy to follow. Doing clear polarity with path operations instead of masks is
a nice touch for vector PDF. A few things should change before merge, mostly about crafted input getting past the
budgets.
- Block chains aren't depth-limited.
MaxBlockDepthonly counts lexical nesting (_frames.Count). A top-level
%ABD10*%can flash the previous block, the next one flashes that, and so on (two codes alternating are enough,
sinceCloseFrameoverwrites_blockApertures[code]). About 1 M links fit in about 22 MB and pass every budget.
With one overlapping clear object,GerberBlockFlash.Outline()->Run.Outline()recurses 1 M levels: a
StackOverflowException, which takes the whole app down. Without one, Svg.Skia meets a<use>chain just as deep.
Could eachGerberBlockcarry a depth (1 + the deepest block it flashes) that's refused pastMaxBlockDepth?
Also,ApertureBlockdoesn't count againstMaxApertures, and empty%ABD10*%%AB*%/ empty SR blocks pile up in
_image.Blocksuncounted. Please count opened blocks too. Subtract's overlap search can run for hours and ignores Cancel. The budget only grows whenhits.Count > 0,
butGrid.Afterwalks every entry of the cells it touches plus_large, and skipsk <= indexfor free. A layer
with one dark flash, 900 k clear flashes and then 1 M dark flashes at the same spot (rectangle aperture, about
8 MB) does about 1e12 iterations in the counting loop, which has noctcheck. Please count visited entries
against a budget and fall back to background painting when it's exceeded, and checkctin both counting loops.
Cell lists and_largeare filled in ascending index order, so a binary search to the firstk > indexwould
also help.GerberMacro.Evaluateand a%...%block with manyADwords could use actcheck too.- UTF-8 BOM.
Encoding.UTF8.GetStringkeeps U+FEFF, andchar.IsWhiteSpacesays no, so a BOM-prefixed file
reads%FS...as a word up to the*inside FS. The%pairing then shifts and the file fails onMOMM.
Skipping a leading U+FEFF fixes it. - Extent. Only X/Y/I/J are held to 100 m. Aperture parameters, macro parameters,
LS(up to 1e6) and SR
I/Jaren't, so a file can make a page thousands of km wide (the raster path then asks for a bitmap far over
SvgRenderer's cap). A1e308inch parameter times 25.4 becomesInfinityin the SVG. A range check on those
numbers, plus a final bounds check inGerberSvg.Write, would turn these into the usual reasoned error. - DXF/DWG gets the background. The full-size
<rect fill="#001023">becomes a closed LWPOLYLINE 2 mm around the
board in DXF, which gets in the way of the "board outline for the enclosure" use. The dark background is fine for
SVG, PDF and the pictures, so keep it there, but please leave it out of the DXF/DWG route.
Smaller:
RoleOfmaps.g1/.g2/.gl2to inner copper (and the docs say so), but those extensions aren't registered, so
the branch can't be reached. Either register them or drop it.- The drawn-segment budget counts a flash as at least 4 segments, so about 12 M placed
<use>instances can pass.
Svg.Skia builds a drawable per instance, so a separate cap on placed instances may be worth adding. .gml: please leave it out for now. It's also the GIS Geography Markup Language, which would fit the geo formats
later, and Eagle users can pick their milling layer by its other names.- The Excellon drill-file follow-up you mentioned is welcome, as a separate PR after this one.
- Heads-up, nothing to do on your side: #1444 has just taken schema 87, other open PRs want the next numbers, and
#1461 touches the samecadlists inFormatFieldsTests. We'll renumber and sort out the counts at merge time.
CI is green. Happy to look again once these are in.
- Block reference depth, not only lexical nesting, is limited: a chain of top-level blocks each flashing the previous one is refused. - Opened aperture and SR blocks (empty ones too) count against the budget. - A cap on shapes placed once blocks and copies are expanded (Svg.Skia makes a drawable per <use>), separate from the segment budget. - The overlap search is budgeted (grid entries visited) and checks the cancellation token in both counting loops; a binary search skips entries at or before the current index instead of scanning them. - Macro evaluation and extended-command runs check the cancellation token. - A leading UTF-8 BOM is skipped. - Aperture, macro, scale and step-and-repeat sizes are range-checked like coordinates, and the whole drawing's extent is checked before output. - The DXF/DWG route leaves out the board background rectangle. - Drop the unreachable .g1/.g2/.gl2 role branch, and .gml (GIS Geography Markup Language; Eagle's milling layer has other names). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPxh5sc7UXmkshJ7pDMouF
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPxh5sc7UXmkshJ7pDMouF
8 of 12 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this change?
Filee can now read Gerber files, the layers of a printed circuit board as KiCad, Eagle, Altium, EasyEDA and
other PCB programs write them for board makers (copper, solder mask, silkscreen, paste, board outline). A layer
becomes an SVG at its real size, and the vector engine takes it to PDF (vector), PNG, JPG… and DXF / DWG
(the board outline as CAD geometry, handy for the enclosure). Until now a
.gtlor-F_Cu.gbrwas an unknown file.The format is open and documented ("The Gerber Layer Format Specification", Ucamco), so it is unlike the closed CAD
formats closed as not planned (#1377, #1380). No issue or PR on it existed.
Filee.Engines/Vector/Gerber, built in, no dependency): coordinate format and units (FS, MO,G70/G71, leading/trailing zeros, absolute/incremental); standard apertures C, R, O, P with holes (also the
rectangular holes of older files); aperture macros with variables, expressions and every primitive (exposure off,
rotation about the macro origin); linear and circular draws (single- and multi-quadrant, full circles); regions with
several contours, arcs and cut-ins; LPD/LPC; LM/LR/LS; nested aperture blocks (AB); step and repeat (SR); IPNEG; the
X2 file function (also KiCad's
G04 #@! TF…comment form).file name:
-F_Cu,-B.SilkS,-Edge_Cuts,.gtl,.gbo,.g2…). Pale silkscreen and outlines wouldvanish on white, and this is what designers see in KiCad and Gerber viewers.
a dark object that a later clear object overlaps is replaced by its outline minus what stays clear, with Skia's
path operations. The PDF stays vector, and the SVG is really transparent there. A hole that is drawn over again is
not cut, so no anti-aliasing seam shows. Past a budget, clear objects are painted in the background colour, which
looks the same.
InvalidDataExceptionsaying what is wrong(a GIMP brush, which also uses
.gbr; RS-274-D without apertures; undefined apertures or macros; malformed numbers;an empty layer…). Budgets are checked before the memory is used: 256 MB file, 2 M objects, 10 M segments written
and 50 M drawn once blocks and copies are placed (a panel of a large board passes; blocks flashed inside blocks
can't multiply without end), 100 000 apertures, block depth 8, 10 000 SR copies, macro primitives, outline points,
expression length and depth, coordinates within 100 m. A file that just stops keeps what was read.
gerber, read only, category CAD, grade specialist, fieldcad(can be turned off; rule 5 ofFORMAT-RULES admits read-only formats). The CAD donut (PDF, PNG, SVG, DXF, DWG) fits it as it is. Extensions:
gbr ger gtl gbl gto gbo gts gbs gtp gbp gko gm1 gml, none taken before.this may need renumbering.
docs/ENGINES.md, the README format table.Not in this PR, on purpose: Excellon drill files (
.drl). Their main use is showing the holes on the copper,which needs several files of one board drawn together; that is a separate design (stacking layers), better reviewed
on its own. I'd propose it next if you want it.
Type of change
How was it tested?
dotnet format Filee.slnx --verify-no-changes --severity warndotnet build Filee.slnx -c Releasedotnet test: 63 new Gerber tests (GerberTests,GerberFormatTests) on layers generated by the tests, allpassing;
FormatFieldsTestscounters updated;TracingTestsknows Gerber → SVG isn't tracing. Engines: 18failures, the same as on main in this environment (Pandoc, FFmpeg and LibreOffice not installed, a Korean font
missing,
FolderIso632Tests); Core: 2, the tests that need a non-root user. App, filtered to profiles,donuts, settings, migrations, formats, fields and translations: 136 passed.
(KiCad, Eagle) and gerbv's examples (Eagle, OrCAD, Mentor, Protel, KiCad, hand-written tests). Real boards
render like gerbv's, apart from anti-aliasing along thin lines. Where shapes differ, the specification and
tracespace's reference SVGs agree with Filee: single-quadrant arcs, rotated macro circles,
xin macroexpressions, LS on draws, polarity inside step and repeat, nested aperture blocks (gerbv draws nothing). Two
files fail with a reason: an empty paste layer, and a board whose aperture definition is really damaged
(
R,0.03260.326).registry and the migration (covered by tests), not clicked through.
Not tested: the deprecated image commands IR, MI, OF, SF, AS, IJ, KO are ignored (the real files met write only
their neutral values,
OFA0B0,SFA1B1,MIA0B0); Gerber X3 component attributes are ignored like the otherattributes.
Screenshots (UI changes)
No UI change. These compare Filee's output (left, Gerber → SVG → PNG) with gerbv 2.10 (right), which was given the
same window and the layer colour Filee picked.
A KiCad board, layer by layer (tracespace's
clockblock): top copper, bottom copper, top silkscreen and topsolder mask, coloured from the file name (
-F_Cu,-B_Cu,-F_SilkS,-F_Mask).The hard cases: a real power plane with clear thermal reliefs (gerbv's
dsp.GP1), a macro thermal flashed inclear polarity, a moiré macro, step and repeat with dark and clear objects inside, a region with an arc cut-in,
multi-quadrant arcs, and nested aperture blocks, which gerbv doesn't draw at all.
Checklist
src/Filee.App/Assets/i18n/*.jsonfiles (none: format names aren't translated)THIRD-PARTY-NOTICES.md(none added)🤖 Generated with Claude Code