Commit Graph
920 Commits
Author SHA1 Message Date
divyanshu2074andBrandon Thomas e04dd0e785 fix(formats): support cell and paragraph borders in RTF export (#2207)
* fix(formats): support cell and paragraph borders in RTF export

* rustfmt

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:40:31 -04:00
divyanshu2074andBrandon Thomas 9cd34ebc80 fix(formats): preserve tilde characters in LaTeX URLs and raw arguments (#2202)
* fix(formats): preserve tilde characters in LaTeX URLs and raw arguments

* rustfmt

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:40:15 -04:00
divyanshu2074andBrandon Thomas d9ca2573a6 fix(engine): count multi-column spanning cells once in table formula ranges (#2200)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:40:00 -04:00
divyanshu2074andBrandon Thomas a114a79a69 fix(doc, formats): support OEM character set 255 in charset_code_page (#2195)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:39:37 -04:00
Antoine BoxhoandBrandon Thomas 61a626820e #1552: no spelling squiggle under the word being typed (#2183)
Word draws no red squiggle under the word being typed. It appears when the word ends or the
caret leaves it by a key or a click. The session records the word after a text command that
edits the caret's paragraph, with apostrophes and hyphens counted as the spelling check counts
them, and drops it once the caret is anywhere else. The layout leaves that one range out of the
spelling squiggles, and a caret move without an edit lays out only that paragraph again. F7 and
the Spelling pane still report the word, and grammar marks are unchanged.

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:39:21 -04:00
divyanshu2074andBrandon Thomas 545673d644 fix(formats): resolve sub-location and external URLs in RTF HYPERLINK fields (#2181)
* fix(formats): resolve sub-location and external URLs in RTF HYPERLINK fields

* rustfmt

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:39:05 -04:00
divyanshu2074andBrandon Thomas 973e6e12f5 fix(formats): support quoted and non-latin charset declarations in HTML decode (#2180)
* fix(formats): support quoted and non-latin charset declarations in HTML decode

* html: clippy (question_mark, collapsible_if) after merging main

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:38:50 -04:00
94e3dda6af SmartArt: type into items; open the Text Pane by double-click or frame button (#2170)
* SmartArt: typing with the graphic selected types into an item

Typing with a SmartArt graphic selected replaced the whole graphic with
the typed text. Now the text goes at the end of the current item (the
first before any is picked) and the Text Pane opens, as in Word. The
typing is one undo step.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* SmartArt: double-click or the frame button opens the Text Pane

A double-click on a SmartArt graphic opens its Text Pane. While a
graphic is selected, a Text Pane button sits on the left edge of its
frame, as in Word, and shows or hides the pane.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* SmartArt: the Text Pane closes with the graphic's selection

It opened by itself on the next graphic selected, because the pane flag
outlived the selection. The frame button hides while the pane is open.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:38:34 -04:00
divyanshu2074andBrandon Thomas 3031033790 fix(layout): support quoted bookmark names with spaces in PAGEREF fields (#2169)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:38:19 -04:00
95b5c71f80 Save writes the chosen file when its folder refuses a temporary file (macOS privacy protection) (#2138) (#2167)
* #2138: save writes the chosen file when its folder refuses a temporary file (macOS privacy protection)

On macOS a Save-panel pick inside a protected folder (Desktop, Documents…) grants
access to that file only, so the sibling .wordcraft-save-*.tmp was likely refused
with EPERM. On PermissionDenied creating the temporary file, write the destination
directly; a remaining permission error on macOS says where to allow access.
Untested on a Mac: the fallback path is pinned on Unix with a read-only folder.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* #2138: a failed save in a folder refusing the temporary file keeps the original

Review (FredApps): the in-place fallback truncated the destination before
writing, so a failure partway through lost the previous document.

The fallback now keeps the existing file's bytes in memory (up to 512 MB)
before writing it in place and writes them back if the save fails, or
removes a new file it created. If that write-back fails too, the error
says the file may be incomplete. A file over the limit isn't written in
place; the error suggests Save As.

Tests: the reviewer's partial-write test (read-only folder), a new file
removed on failure, and the size limit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P8veLveuUsJJm6UEcQPEuW

* #2138: keep the original untouched when no safe replacement is possible

When the folder refuses the sibling temporary file, an existing destination
is no longer overwritten in place (no in-memory rollback): it stays
byte-identical and the error says to use Save As to another folder or allow
access to the folder (macOS: Privacy & Security > Files and Folders). A
destination that doesn't exist yet is created exclusively and removed again
if the write fails.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P8veLveuUsJJm6UEcQPEuW

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:38:04 -04:00
divyanshu2074andBrandon Thomas 6cf7159a71 fix(formats): emit \landscape in RTF export when section is landscape (#2159)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:37:42 -04:00
divyanshu2074andBrandon Thomas 65127c2727 fix(formats): handle negative timezone offsets and flexible day digits in spreadsheet iso_datetime (#2154)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:37:27 -04:00
874e5a76a0 #2052: a second picture style, border or artistic effect replaces the first (#2148)
Picture Styles, Picture Border and Artistic Effects now draw again from the
bitmap under them (kept per drawn picture in Session::picture_looks), so
Thick Frame then Simple Frame is only a simple frame, a border replaces the
border and keeps the style, a style replaces the border, and an effect
replaces the effect ("none" removes it), as in Word. Transparency was already
absolute (#1175); the test pins it.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:37:12 -04:00
divyanshu2074andBrandon Thomas 720f8acd2c fix(layout): support field format switches without whitespace after \* (#2147)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:36:58 -04:00
2054f8fd88 fix(web): fall back after asynchronous save picker rejection (#2145)
Preserve AbortError cancellation and report download fallback failures without marking saves successful.

Fixes #1246

Assisted-by: OpenAI Codex

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:36:42 -04:00
4c8508cd93 Insert › Shapes menu: an icon for each shape and connector (#2142)
Each item shows a small drawn outline of what it inserts (rectangle,
oval, triangle, star, elbow connector...). The icons are drawn in code in
icons.rs as shape.<kind>; widgets::icon_menu_item draws the item.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:36:27 -04:00
divyanshu2074andBrandon Thomas e7babf364e fix(formats): trim whitespace when parsing numeric XML attributes in ODT (#2137)
* fix(formats): trim whitespace when parsing numeric XML attributes in ODT

* rustfmt

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:36:12 -04:00
divyanshu2074andBrandon Thomas c9468a13cb fix(docx): support self-closing w:compat in settings merge (#2131)
* fix(docx): support self-closing w:compat in settings merge

* Drop the duplicate divyanshu2074 entry in people.toml (already on main)

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:35:43 -04:00
divyanshu2074andBrandon Thomas e2d9224996 fix(formats): support relative font size values in HTML font tags (#2130)
* fix(formats): support relative font size values in HTML font tags

* Drop the duplicate divyanshu2074 entry in people.toml (already on main)

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:35:28 -04:00
divyanshu2074andBrandon Thomas eedf9c9740 fix(doc): strip negative sign when formatting numbers rounded to zero (#2122)
* fix(doc): strip negative sign when formatting numbers rounded to zero

* Drop the duplicate divyanshu2074 entry in people.toml (already on main)

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:35:13 -04:00
divyanshu2074andBrandon Thomas 5977112a0d render, pdf: fix vertical double and wave border rendering (#2113)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:34:58 -04:00
872b2bc99d DOCX: ink inside groups and drawing canvases survives saving (gap 2) (#2097)
* gap: nested ink WIP

* gap 2: native ink nested in groups and drawing canvases survives DOCX saves

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* gap 2: review round 1: ungrouping keeps nested ink; no orphan parts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* gap 2: Impact cell matches the restated impact

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* gap 2: only Word ink pins a group against Ungroup

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* gap 2: alternate ink must hold an a:graphic to be written as standalone

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* gap: nested ink WIP

* gap 2: native ink nested in groups and drawing canvases survives DOCX saves

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* gap 2: review round 1: ungrouping keeps nested ink; no orphan parts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* gap 2: Impact cell matches the restated impact

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* gap 2: only Word ink pins a group against Ungroup

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* gap 2: alternate ink must hold an a:graphic to be written as standalone

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:34:42 -04:00
Antoine BoxhoandBrandon Thomas aed0b71786 #1878: Rulers thin out with the zoom and span the caret's page (#2093)
Ruler numbers now thin out as the page shrinks on screen: a number
every 1, 2, 4, 8... units, whichever keeps them at least 30 px apart,
and the small ticks drop out below 4 px, with the text at its usual
size. A number gives way to an indent, tab or column marker sitting on
it, and the margins get ticks only. Both rulers use the caret page's
rect and scale in every layout, including One Page and Multiple Pages,
and follow the caret to another page. Tests cover the density rule, the
marks, the marker rule for indents, tab stops (set or dragged) and
table columns and rows, and the multi-page geometry.

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:34:26 -04:00
Antoine BoxhoandBrandon Thomas 0f5e945a69 #1945: Hide the Quick Access Toolbar and show it again (#2089)
The Quick Access Toolbar's menu ends with Hide Quick Access Toolbar, as Word's does. Show Quick Access Toolbar brings it back from the ribbon's right-click menu and from a check box on Customize Ribbon's Quick Access Toolbar page. The setting is kept between runs, and keytips skip the toolbar's digit badges while it is hidden. The UI command ui.quickAccessToolbar drives it from scripts and MCP. Regenerates docs/parity-checklist.md, which was behind the catalog. Adds my contributor entry.

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:34:10 -04:00
e50850d4dd RTF: formatting and paragraph-mark revisions are read and written (gap 19) (#2088)
* gap: RTF formatting revisions WIP

* gap 19: RTF formatting and paragraph-mark revisions

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* gap 19: review round 1: list kept on Reject; old formatting normalised; section marks; hostile borders

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* gap 19: review round 2: \oldcprops holds only the changed properties, as Word writes it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* gap 19: old formatting in styled paragraphs uses the style's size and font

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* gap 19: RTF import keeps main's heading and code normalisation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* gap 19: file-format-parity status line keeps main's history

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* gap 19: a paragraph that was a list item gets its old list back on Reject

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* gap 19: a numbered item made bulleted keeps its numbered list for Reject

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* gap 19: format matrix names the tracked section mark

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* rtf test: Writer has the section fields main added; rustfmt

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:33:46 -04:00
Marco ArnulfoandBrandon Thomas 166b95feba Proofing: a hyphenated word added to the dictionary is no longer flagged (fixes #2082) (#2085)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:33:30 -04:00
072acce71b Legacy form fields are drawn: check boxes, and drop-downs' selected entry (#2076)
* Legacy form fields are drawn: check boxes, and drop-downs' selected entry

Legacy form fields keep their w:ffData since the last round, but were
not drawn: a FORMCHECKBOX has an empty result, so a form of check
boxes came out with none, and a FORMDROPDOWN showed its saved result
rather than its selected entry.

- wordcraft-doc: `legacy_form` reads what layout needs from the kept
  w:ffData (kind, name, check box state and size, drop-down entries and
  selection, text field length); `InlineObject::legacy_form()`.
- wordcraft-layout: a check box takes the text line's height of room
  and is drawn as Word draws it; a drop-down shows its selected entry
  (w:result, else w:default, else the first).

Measured on Word's PDF export with a synthetic document (Calibri):

  text size | Word square | WordCraft
  8 pt      | 7.44        | 7.45
  10 pt     | 9.96        | 9.89
  12 pt     | 12.36       | 12.33
  20 pt     | 22.08       | 22.09
  w:size 15 | 16.08       | 15.99

The square sits 1.16 pt inside the line height on every side (room on
the line within 0.2 pt of Word's), has a 0.72 pt border and, checked,
an X from corner to corner in 0.48 pt lines; w:checked beats
w:default. docs/file-format-parity.md is updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Draw::Shape takes the dash list main added

---------

Co-authored-by: Daniele Mori <Dinasty@hotmail.it>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:33:15 -04:00
70fc00c80f Symbols keep their symbol font when the text font changes (#2036) (#2037)
* Symbols: a w:sym character keeps its symbol font when the text font changes (#2036)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* #2036: review round 3: docx test reads sym_font, paste drops the symbol font, astral symbols stay text

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* #2036: insert.symbol decides symbol or text per character

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-18 11:33:00 -04:00
20188e4610 A floating object's anchor takes no room on a line (#2033)
A line's first item stays on it even when it is wider than the line;
markers before it don't count. A floating object's anchor (a zero-size
object cluster) did count, so a picture a little wider than the line,
after an anchor, went to a second line and left the anchor an empty
line of its own above it. Word keeps the picture on the first line.
Anchors are now ignored like markers when deciding whether the line
already has content.

Co-authored-by: Daniele Mori <Dinasty@hotmail.it>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:32:22 -04:00
1b45615940 Insert › Shapes keeps the selected shape and text (#2019) (#2030)
Inserting a second shape removed the first: after an insert the new
shape stays selected, and `insert.shape` replaced the selection, so each
shape replaced the one before. Word draws a new shape beside whatever is
selected and never deletes it (checked by hand in Word for Windows: a
second shape is drawn over the first, which stays).

The new shape now goes after the selection, which is left alone, and
becomes the selection. Selected text stays too. A picture still replaces
a selected picture, which is what Word does as well (checked in Word for
Windows), so `insert.picture` is unchanged.

Tests: three shapes inserted in a row are all kept, which fails with the
old code (1 of 3 kept); a shape inserted over selected text keeps the
text and is selected itself; a picture inserted over a selected picture
replaces it.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 11:32:07 -04:00
Brandon ThomasandClaude Opus 5.5 7333a302f5 ci: File Close test expects the window kept (#1712); Polish coverage test skips French's newer strings
#2448's imported-Word close test predates #1996 (File › Close keeps the window), and #2492's French catalog carries keys the Polish catalog lacks, as the PR's own test change said.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 10:37:08 -04:00
c9a5191b70 i18n: French interface catalog completed (2,615 entries) with native-speaker review (#2492)
Adds the 402 entries the French catalog lacked: equation gallery (matrices, accents, brackets, integrals, operators, functions), built-in style and table-style names, citation styles, paper sizes, watermarks, and the Bookmark, Go To and Print dialog strings. Drops the obsolete 'Style: APA' entry. Terminology reviewed by a native French speaker and Word user. The Polish superset test exempts fr like the other catalogs carrying newer strings. Progress docs and people.toml updated.

Co-authored-by: Vivien JANNY <vivien@avertissance.fr>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:29:17 -04:00
492aceb960 Fonts Word embeds as subsets lay out the text set in them (#2240) (#2540)
* #2240: fonts Word embeds as subsets lay out the text set in them

Embedded fonts were registered under the family inside the font file. Word
embeds a subset ("embed only the characters used") under a made-up family
(___WRD_EMBED_SUB_46) and the text asks for it by the font table's name
(OBRBWW+Century Schoolbook), so it still fell back to a substitute. Each
embedded file now comes with its font table name, and its faces go by that
name when they don't already.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #2240: the black-circle fallback test passes its font's table name

main's new `circle_checks_face_coverage` test (#2582) called `add_document_fonts` with bare font
bytes; with this branch each embedded font comes with the name the document's font table gives
it, so the test passes "Times New Roman" alongside the face it renames to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:28:52 -04:00
ReesandBrandon Thomas ff39a5c357 fix(ui): deliver control input in inactive windows (#2420) (#2530)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:28:37 -04:00
ReesandBrandon Thomas 1595343fa0 fix(ui): expose save confirmation context to screen readers (#2489)
* fix(ui): expose save confirmation context (#1015)

* #1015: require alert-dialog semantics in save regression

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:28:20 -04:00
Fin WarmanandBrandon Thomas a5d817a9ef TOC: keep direct number tabs on refresh (task 276) (#2475)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:27:26 -04:00
09b822fdbe Update Field after save and reopen of a table of contents; no extra blank line per cycle (#2182) (#2553)
Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:27:11 -04:00
Bryan MarkandClaude Opus 5.5 8107581df2 Opening a DOCX no longer copies its pictures (#2441)
Each picture, and each embedded object or macro part kept for saving, was
copied out of the unzipped package (bytes.to_vec()), so a document with
pictures held them twice while it opened, and the package's copies were
left behind as freed memory. Package now holds its parts as Arc<Vec<u8>>,
the type the document keeps media and passthrough parts in, and hands them
over with get_shared. keep_unmodelled also searches the main part in place
instead of copying it.

A 92 MB document with 20 pictures on macOS 27: the app's footprint once
open 866 -> 772 MB (freed blocks kept 206 -> 118 MB, peak 915-932 ->
821-823 MB); wordcraft-cli info peak 319 -> 231 MB.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 10:26:56 -04:00
Fin WarmanandBrandon Thomas ca45f97ace Layout: exclude floating anchors from line font metrics (task 256) (#2462)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:26:32 -04:00
ReesandBrandon Thomas 9726d6f1cb fix(ui): offer Save As for imported Word files (#2448)
* SCRUM-47: offer Save As for imported Word files

* #2445: reject Save As answers for a replaced document

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:26:16 -04:00
Fin WarmanandBrandon Thomas 57dfacfc07 Layout: preserve equation baselines under exact line spacing (#2435)
* Layout: preserve equation baselines under exact line spacing (task 243)

* layout-parity: keep the cell-margin inheritance note on the Tables row

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:26:01 -04:00
Fin WarmanandBrandon Thomas 4cb4b2d231 244: inherit omitted cell margins (#2434)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:25:38 -04:00
PanyangYandBrandon Thomas a14948a23d DOCX: strict line heights with a unit are points under auto (#2329) (#2439)
Word 2024 saves Strict Open XML with measures written out with their unit:
the issue's file carries `w:spacing w:after="8pt" w:line="13.90pt"
w:lineRule="auto"` in its paragraph defaults. The reader sent `13.90`
straight into the `auto` branch, where a bare number counts 240ths of a
line (240 = single), so 13.90pt became a 13.9 multiple: 191.8 pt lines,
and the issue's document laid out as 10 pages against Word's 1.

Under `lineRule="auto"` a unit-suffixed height now reads through twips, as
Word renders it (ISO 29500 `ST_SignedTwipsMeasure`: 13.90 pt = 278 twips =
the 1.1583 multiple). A bare number still counts 240ths of a line;
`exact`/`atLeast` already read units as points.

Checked with the issue's file: 1 page with baselines on Word's (15.98 pt
line advance against Word's 16.10/15.96; paragraph advance 23.99 against
24.00; table lines 12.65 against 12.60/12.72), and a save/reopen keeps it.

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:25:14 -04:00
Fin WarmanandBrandon Thomas 4deb654862 Layout: keep narrow cell line widths (task 245) (#2436)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:24:58 -04:00
Fin WarmanandBrandon Thomas d7bd5bcd3c Layout: preserve additive spacing after section breaks (task 243) (#2433)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:24:41 -04:00
28d6260a81 #1789: Add Font imports every selected font file (#2404)
* Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #1789: cap font bytes waiting in the web inbox

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:24:26 -04:00
Fin WarmanandBrandon Thomas a492189a84 DOCX: preserve zero effect extents on rotated drawings (#2432)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:23:59 -04:00
5c4408f341 Paste: plain text keeps the formatting of the paragraph it lands in (#2423) (#2424)
Paste of plain text from another program gave every line after the first
a paragraph with default formatting. The text became a fragment of
unformatted paragraphs (Fragment::from_text), and insert_fragment keeps
the target's formatting only in the first one. Pasting several lines into
a right-to-left paragraph turned all but the first left-to-right, and the
text after the caret lost its paragraph formatting too.

Paste now inserts plain text as Keep Text Only does. Each line after the
first splits the paragraph as Enter does, so it keeps the paragraph's
direction, style, alignment, indents, spacing and list. Empty lines become
empty paragraphs with that formatting. Copies from WordCraft and HTML or
RTF from other programs keep their own formatting as before. A paste is
still one undo step.

Tests cover a right-to-left paragraph, empty lines and a final line break,
and a list. The typing and UI parity docs and the ROADMAP progress log
have rows for the change.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:23:43 -04:00
Marco ArnulfoandBrandon Thomas 8f0000de63 Text boxes: framed paragraphs run with the box's text, not drawn over each other (part of #2357) (#2383)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:23:27 -04:00
Marco ArnulfoandBrandon Thomas 9bed0156df OpenType ligatures follow w14:ligatures: model, DOCX read and write, shaping (#2351)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:23:12 -04:00