Repository navigation
Release 2026.44.1 - #841
Merged
Merged
Conversation
A vector snippet no longer carries a full copy of its source page. The new js/pdf/vector-cull.js trims the page content to what the cut box can reach: paths, text objects, images and Form XObjects that are provably outside the box are dropped, while graphics state, clipping paths, marked content, shadings and BX/EX sections are kept. Anything that cannot be read with certainty leaves the page untouched. The trimmed mini-PDF is only used when it is at most half the size of the full one. Mini-PDFs no longer carry the source page's annotations, and fonts and images shared by trimmed snippets of the same page are merged into one copy on save. Refs #509 Review: included as is; no changes were needed on top.
…ort (#769) The comments panel gets a filter bar for author, type, page range and date range, alongside the existing status filter, plus a clear-filters action and a bulk status change for the selection or all listed comments in one undo step. Sorting and grouping move into a pure module shared by the list and the exports. The CSV export now carries all fields (ids, dates, status history, replies, layer and bounds), and "Summarize Comments" builds a PDF report of the listed comments with a crop of each comment's location. Fixes #383 Review: included as is; no changes were needed on top. Note that the CSV column set has changed.
…775) The Layers panel follows the /OCProperties /D tree from the file: nested layers, labels, /Locked layers (shown with a lock, checkbox disabled) and /RBGroups (radio behaviour). "Set as default" stores the toggled state, and the next save writes it as /D /ON /OFF. The toggled state also applies to raster export, printing and the vector "save as PDF" print. The properties panel gets a "Layer" field: a markup can be put on a markup layer or on a layer of the drawing, in which case it gets /OC to that OCG on save, loads back on it and hides and shows with it. Fixes #377 Review fixes on top: - An adopted drawing layer whose markup layer was removed while other markup layers remained was dropped from /OCGs, /Order, /Locked, /RBGroups and /ON /OFF. Every adopted OCG known from the file now keeps its place; only the app's own keys are removed. - The drawing layer's /Name is no longer overwritten by the markup layer name (for example a " (2)" suffix or a rename in the panel). - Adopting a layer no longer turns the current view state into the file's default. Adopted layers keep their /D state; only "Set as default" changes it (laagstandZonderEigenLagen). - Regression tests for all three cases (save, reopen, check /OCGs, /Order, /RBGroups, /Locked, name and default state).
…771) Adds the paperclip annotation (PDF /FileAttachment): a ribbon tool that places an icon and embeds a picked file, with select, move and delete, properties (icon, description, file name and size, Open and Save As) and double-click to open. The saver writes /FS with an embedded file, /AF and its own appearance; the loader reads attachment annotations written by other tools, keeping undecodable streams raw. The attachments panel also lists page attachments and can open, save and delete them, and opening an executable attachment asks for confirmation first. Fixes #376 Review fixes on top: - The new ribbon button is added to the ribbon command list used for keyboard shortcuts. - A loaded attachment annotation whose content cannot be read is no longer rewritten without its embedded file: when it was not edited the original annotation stays untouched (file specification, unknown keys, /AP and popup), and when it was edited the new annotation reuses the original file specification. - Attachment content in the store is released when its document closes, unless another open document or the clipboard still uses it. - The confirmation list for executable attachments is extended (.msc, .chm, .url, .iso, .lnk, .scf, .application, .inf, .vhd, scripts and others), trailing dots and spaces no longer bypass it, and temp file names drop characters Windows does not allow.
…oving (#786) Move mode (G / mv) gets an inference engine on top of object snap: - Tracking lines: the cursor or a snap point of the moving selection aligns horizontally/vertically with endpoints, midpoints, corners and centres of other geometry (annotations and, when enabled, PDF content); H/V through the base point; hovering a point briefly acquires it as a tracking point, several guides give intersection snaps. - Extension lines of existing lines and wall faces beyond their endpoints. - Parallel / perpendicular to nearby lines, with guide and marker. - Polar guides around the base point from the existing polar settings. - Colour coding (red X, green Y, magenta parallel/perpendicular) with a tooltip naming the inference and the distance; guides drawn in single-page and continuous mode, axis colours follow a rotated view. - Shift locks the shown guide (falls back to the angle constraint when no guide is shown); X/Y axis lock intersects with guides. - A typed distance moves along the inferred direction; Tab switches the typed entry between distance and angle. - Priority: point object snaps > guide intersections > single guides > edge/grid. The selection never infers from or snaps onto itself. The pure geometry lives in js/tools/inference-engine.js (sorted-axis and grid point index, segment grid), session glue in move-inference.js and the overlay in inference-overlay.js. Corner-to-corner object snap now uses the point index instead of a 6000-point cap. New preferences toggle tracking, extension and parallel inference, translated for all locales. Fixes on top during review: with the Object snap master switch off the move is free again; tracking (including the H/V guides through the base point), extension and parallel guides are disabled then, polar stays independent as in the snap engine. The distance in the guide tooltip uses the real measure scale and shows points on a page without a scale instead of the 1 pt = 1 mm fallback. Regression tests for both. Fixes #519
Adds Dutch structural drawing tools as parametric symbols, together with a reinforcement category in the quantities engine so drawn bars feed a bending schedule and a weight schedule. - Rebar core (quantities/wapening.js): notation (12Ø10-150), bending shapes 00/11/21/51 with developed length per NEN-EN 1992-1-1 mandrel diameters, mass 0.00617·d² kg/m, bar collection from annotations, automatic bar marks and merging into bending-schedule rows. - New symbols: rebar detail (bending shape), bar in plan, reinforcement mesh in plan, slab with frost edge, end plate at beam, base plate at steel column (with edge-distance check per NEN-EN 1993-1-8 table 3.3). - Existing reinforcement cage, reinforcement bar and bar series now feed the schedule; cage gets beam length, bar marks and steel grade. - Standard schedules "buigstaat" and "wapeningsstaat"; per-field non-summable columns in the engine. - Palette entries, IFC classes, assistant prompt and MCP template docs. - Translations for all 40 locales; design notes in docs/constructie/wapening-en-staalverbindingen.md. - Tests for geometry, notation, schedule aggregation and save/load. Fixes on top during review: bolt holes follow NEN-EN 1090-2 table 11 for normal round holes (M12/M14 d+1, M16-M24 d+2, M27 and up d+3). Anchor holes in the base plate are a separate, documented size (default d+6 for setting tolerance, adjustable per symbol) that also drives the automatic edge distances and the distance check. A bar series now carries its own bar mark and steel grade (properties panel, save and load) and these reach the bending schedule; a bar series without a bar length no longer shows up as a 0 mm / 0 kg schedule line. Regression tests for each. Fixes #312
- Freehand tool reads every coalesced pointer sample (getCoalescedEvents) before the per-frame move batching; pen pressure drives a per-point width, mouse and touch keep a constant width. - Zero-phase smoothing plus centripetal Catmull-Rom; variable-width strokes render as filled outline rings with round caps, split at sharp corners and folding inner offsets (no spikes or holes, nonzero fill). - Palm rejection: touch is ignored while a pen is near, a second pointer never joins a stroke, optional pen-only mode. - Save: /Ink keeps the centre line in /InkList and the max width in /BS; the appearance stream draws the smoothed variable-width stroke. Per-point pressure, minimum width and smoothing round-trip in OPS_ keys. - Properties panel Ink section and freehand preferences (pressure on/off, minimum width, smoothing, pen only), translated in all locales. - Tests: width mapping, smoothing, outline geometry, palm filter, coalesced samples, mouse fallback and real saver/loader round-trip incl. rotation. Fixes on top during review: a dashed freehand stroke now writes its dash pattern into the appearance stream, so other readers show it dashed too. A filled outline cannot carry a dash, so a dashed stroke with pressure falls back to a stroked, dashed centre line at full width, on screen and in the appearance; the line style is part of the geometry cache key. The Ink key read in the loader no longer sits inside the arc comment block. Tests check the dash operator in the saved appearance and that the dash patterns match the screen. Fixes #385
…AD (#788) Eleven new assistant skills, grouped in tabs in the panel: - Reading the drawing: find on sheet, explain selection, compare sheets - Measuring and quantities: measure this, take off (schedule on the sheet), check the scale - Marking up: review sheet (numbered clouds on a "Review" layer), stamp and date, tidy markups - CAD drawings: bring in a drawing, export to CAD Skills are declarative: group, required app state (document, selection, measuring scale, two pages), input checks, the MCP tools they may use and an English guide that goes into the system prompt. A chip whose precondition fails shows the reason in the panel instead of sending. Skill messages carry the app state (page, selection, scale, date) for the model. Tests check every tool name and argument in the prompt against mcp-stdio/tools.json, the gates, the message composition and the translations in all 40 locales. Review fixes on top: - The tools a skill never calls on its own now also cover the indirect routes to saving, printing and irreversible edits: app_run_command, app_key, app_click_element, app_replace_text, app_snippet_cut, app_snippet_flatten, app_merge_pdf and app_install_extension. SKILL_TOOL_EXCEPTIONS allows the structural overview skill exactly the three it needs (copy a snippet, send it to the back, replace its own snippet), and the prompt states each exception and its single use. - Export to CAD asks before it overwrites an existing file, and always when the path is a drawing that was brought in. - The undo promise is limited to markups; changing an existing measuring scale, filling title block fields and importing CAD on an open document ask for confirmation first. - Regression tests for the forbidden list, the exceptions, the undo rule and the overwrite question.
…rt (#785) - Read aloud of the selection or the document from the current page on, in structure-tree order for tagged PDFs (content order otherwise), with play/pause/stop, voice and rate; the view follows the page being read. Web Speech is used when it has voices, otherwise native commands (SAPI via PowerShell, say, spd-say/espeak-ng) with a clear message when no engine exists. - Tags panel reads /StructTreeRoot lazily with pdf-lib (RoleMap, MCR/OBJR, MCIDs mapped to page text via pdf.js marked content), lets the user reorder children and edit /Alt; edits are written by the saver. - Accessibility check dialog: untagged documents, /MarkInfo, /Lang, figures without alt text, untagged or orphaned page content, and annotations without a description. - Translations for all 40 locales; tests for parsing, reading order, save round-trip, report and engine selection. Fixes #384. Review fixes on top: - Privacy: read aloud uses only local voices (localService true) by default. Online voices need an explicit opt-in in the read-aloud bar (preference readAloudAllowOnline, off by default) and are marked "(online)" in the voice list. An utterance always gets a local voice instead of the browser default; without a local voice for the language the bar says so, and with only online voices it offers the opt-in. - Save race: the saver remembers the structure edits it writes and clears only those. An alt text or order changed during a long save is kept, rebased on the saved structure, and keeps the document modified. - The tags panel, the check and read aloud first ask the open pdf.js document whether there is a structure tree; untagged files are no longer loaded whole into pdf-lib. - PowerShell for SAPI runs without -ExecutionPolicy Bypass (not needed for -Command). - Tests for the voice filter, the save race (pure and through the saver) and the structure check.
A replacement in a Type3 font was drawn live in Helvetica because the painter cannot use a Type3 font as a CSS font. The preview now renders the edited text through PDF.js from a small temporary PDF built with pdf-lib: one page with the same box, the page's fonts copied in (CharProcs and Resources included), and the new text drawn by the saver's own code path, so the glyph codes, positions and Standard-14 fallback for missing glyphs are the same as in the saved file. - text-edit-inplace: split the read-only analysis (analyseerPagina) and the encoder (maakInPlaceResultaat) out of applyForPage; Type3 widths are scaled by the FontMatrix and a Type3 glyph only counts as present when its name has a CharProcs entry. - text-edits: export tekenTextEdit (draw one edit like the saver). - type3-voorbeeld: debounced build per edit signature, stale builds and renders discarded or cancelled, cache per run and zoom, temp document freed when the edit goes away or the document closes; Helvetica preview stays while pending or on failure. - rendering: draw the bitmap in the page frame when available. - The pixel test builds the standard font directory with forward slashes, so pdf.js accepts it on Windows. Review fixes on top: - A cheap pre-check looks only at the page resources (/Font of the page and of its form XObjects) for a Type3 font, cached per pdf-lib document and page. Without one the build returns at once, before the page analysis and the temporary PDF, and the painter does not even create a cache entry or schedule a build when the shared document is loaded. - Tests that an edit in a regular font does no analysis, draws no temporary document and schedules nothing, and that a Type3 font inside a form XObject still counts.
An attachment annotation that came from the file and was not edited was rewritten on every save when its content could be read. The rebuilt file specification lost keys the app does not know, such as the collection item /CI or keys of other tools, and the original appearance was replaced. An unedited attachment annotation now stays in the file as it was, whether or not its content can be read. Edited ones are written anew, and keep the original file specification only when the content cannot be read, so the embedded file never disappears. Found by the release gate on a file with an attachment annotation made by another tool.
Collaborator
Author
Release gate (headless desktop build, ProductVersion 2026.44.1)All runs on an isolated test instance that was never the foreground window (13,609 samples, 0 hits). All 67 verification PDFs were md5-identical before and after.
New features, saved files checked with three external PDF libraries
Known, not new in this release (follow-ups): a plain dashed ink stroke without pressure is drawn solid by other readers; the layer view state is lost on Save As. |
This was referenced Oct 29, 2026
This was referenced Oct 29, 2026
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.
Open PDF Studio 2026.44.1
Merge with "Create a merge commit" (not squash or rebase), so each contributor's commit and authorship stays in the history.
Each reviewed pull request is included as one squashed commit with its original author. Problems found in review were fixed on top, with regression tests, inside the same commit; each commit message lists those fixes.
New
Faster
Fixes
Fixes #377
Fixes #376
Fixes #383
Fixes #519
Fixes #312
Fixes #385
Fixes #384
Fixes #509
Not in this release (still open)
#777 (split view) and #779 (tool sets) follow in 2026.44.2, after a change to the shared bitmap cache and a naming decision. The heavier PRs (#783, #773, #778, #789, #806, #803, #805, #801, #804, #796, #747, #810, #828) follow in later rounds.
Verification