warichu_is_a_character_attribute_set_saved_and_exported looked for Tj or
TJ anywhere in the exported PDF. The file ID in the trailer and the XMP is
a base64 hash that changes each second and now and then spells one of
them, so the test failed on main twice (bf3cf422e, 446bf59bc) while
export outlines warichu type every time. It now counts text-object lines
only, as the colour font PDF test already does.
* PDF import: outlined Indic glyphs keep their own stroke and transparency (#5235)
Follow-up to #6906, for two review findings on how a line kept as
outlines is joined into paths:
- Glyphs were joined when their stroke widths matched; dash, cap, join
and miter limit were ignored, so a dashed glyph took the stroke of the
solid one before it. They join only when the whole stroke matches.
- Translucent glyphs were joined into one fill, where overlapping marks
paint once instead of compositing as the file draws them. Only opaque
glyphs join.
Also records the fix in the PDF row of docs/target-app-parity.md and in
docs/roadmap.md, as AGENTS.md asks.
Tests: outlined_glyphs_stroked_differently_stay_apart and
outlined_translucent_glyphs_stay_apart (both fail without the change).
* PDF import: outlined Indic glyphs under a soft mask stay apart; check kept geometry (#5235)
Review follow-ups on #6957 and #6906:
- Glyphs kept as outlines under a soft mask were joined into one path,
so the mask was applied once to all of them where the file applies it
to each glyph. They now join only when no soft mask is active.
- The fallback tests counted outline nodes only. A new test compares the
kept outlines (element count and bounding box) with the same file
opened as outlines, so a dropped or moved glyph fails it.
Tests: outlined_glyphs_under_a_soft_mask_stay_apart (fails without the
change) and kept_glyphs_are_where_the_file_draws_them.
* PDF import: mask outlined Indic glyphs one by one under a soft mask (#5235)
Review follow-up on #6957. Keeping glyphs out of one shared path was not
enough: each path still went into the soft mask's queue and
flush_masked wrapped them all in one masked group, so a mask that is not
constant was applied once to every glyph, where overlapping glyphs
composite one by one in the file.
With a soft mask active the queued art is now drained before the first
glyph and after each one, so every glyph gets a mask of its own.
Test: outlined_glyphs_under_a_varying_soft_mask_are_masked_one_by_one
checks that each outlined glyph carries its own mask (0 of 3 without
the change).
* #6957: clarify soft-mask exception in glyph grouping docs
---------
Co-authored-by: ruchirguitar <info@jeevantirth.org>
Adds 1,813 @msg rows to zh-hans.tsv, one for each status and error message the
untranslated report listed for Simplified Chinese, except the 38 that open
pull requests translate in their own rows: the composite font, justification
order and Blob Brush connect end errors. The catalog test rejects a second row
for the same key, so leaving them out keeps the catalog consistent when those
pull requests merge.
The report now lists 40 zh-hans messages: those 38, and two that no catalog
has a row for yet. Its menu, tl!, undo label and swatch name sections are
unchanged. Placeholders, backticked names, quoted values and JavaScript
identifiers stay as in the source.
Docs: docs/localization-parity.md (zh-hans row), docs/target-app-parity.md.
- After a fill drag, the Live Paint Bucket stores the release point, so the
cursor swatch preview shows there instead of where the pointer last moved
before the press.
- Arrow nudges and Alt+arrow type spacing read Shift and Alt from the key
press, as the tool keys do, so a modifier released within the same frame
still makes a 10 pt nudge, a copy, or a spacing step.
- tool.setOption accepts cursorSwatchPreview for the Live Paint Bucket and
refuses a value that is not true or false.
The Polish catalog lacked a row for 1,854 of the status and error
messages that the untranslated report finds in the sources, so the
status bar showed those messages in English.
- pl.tsv gains 1,808 `@msg` rows: the errors of commands and their
parameter checks, scripts, file import and export, printing and
plug-ins. The translations are VectorCraft's own, written from the
English meaning with the catalog's conventions and its existing
feature names. Placeholders, parameter names, command ids and
literal values stay as the English writes them.
- 44 of the others get their Polish rows from open #7211, #7214,
#7116, #7330 and #1931, so this change leaves them out. 2 are
messages that no catalog has a row for yet. Menu strings, `tl!`
literals, undo labels and swatch names are unchanged.
- Two of the messages have two placeholders in a row. The catalog does
not load such a row, so those two are still shown in English.
- The Polish row of docs/localization-parity.md gives the catalog's
current counts.
Docs: docs/target-app-parity.md, docs/localization-parity.md.
In a document in picas, a bare number typed in Text Wrap Options › Offset
follows Preferences › Units › Numbers Without Units Are Points, as every
length field drawn by the shared unit field does: points while it is on
(the default), picas while it is off. A test covers both settings, and
the evidence line in docs/target-app-parity.md states the rule.
A straight compound path with Twist was read live up to 180° whatever
guides it held, and the live Twist was measured from bounds that take in
the guide members. A straight compound path with Twist whose guide
members reach past its other members now opens as its drawn look
instead of live, and so does a compound path made only of guides.
Compound paths whose guides lie inside their other members, a Twist of
0°, and single paths keep opening live.
The `.ai` writer keeps a graphic-style link only where the reader reads
the style live, so such an object is now written without the link, with
the existing style-link warning.
A CSV file that holds NUL bytes and has no byte-order mark was refused.
It is now read as UTF-16 when at least half of its two-byte units hold
a NUL byte, in the byte order that reads a line break. A file with fewer
NUL bytes (UTF-8 or Windows-1252 text with stray NUL bytes, or UTF-16
text made mostly of characters above U+00FF) is still refused, and so is
a file that reads a line break in both byte orders, has an odd length,
isn't valid UTF-16 in that order or holds a NUL character. Refused files
get the same message as before.
Reading a brush library numbers the second brush of a repeated name, so
the panel's row of that name previews and drags the first brush, and the
second brush has a numbered row of its own.
uk is in COMPLETE_MESSAGES, but the untranslated report listed status
and error messages with no Ukrainian row, so with the interface in
Ukrainian those messages showed in English.
- uk.tsv gains 1,811 `@msg` rows. The translations are VectorCraft's
own, written from the English meaning with the catalog's terms and
typography (« » around interface names, ’ inside words).
Placeholders, backticked names, command ids, double-quoted values and
bare true, false and null stay as the English writes them.
- The 41 rows that open #7211, #7214, #7116, #7330 and #817 add to
uk.tsv are left out, so the catalog keeps one row per key when they
merge (bundled_catalogs_are_consistent rejects a second row for a
key).
- The Ukrainian row of docs/localization-parity.md gives the catalog's
counts.
docs/control-protocol.md said the window has no OS decorations on
Windows and Linux. On Linux and the BSDs the app bar is the title bar by
default only on a Wayland session without server-side decorations, such
as GNOME, in a window not opened through XWayland; elsewhere the desktop
draws the frame unless VectorCraft Title Bar on Every Desktop or
VECTORCRAFT_TITLEBAR=app turns the app frame on. The paragraph now says
so.
docs/development.md said the custom title bar is the Linux default. It
now says where the app bar is the default title bar. The comment on
CUSTOM_TITLEBAR in apps/vectorcraft/src/titlebar.rs made the same
Windows and Linux claim and now names Windows only.
Reading a brush library now numbers the second and later brushes of a
repeated name, so the panel lists Twin and Twin 2 rather than two Twin
rows. The test expects those rows, and checks that rows of one name that
reach the panel unnumbered still preview and drag the first.
pt-br is in COMPLETE_MESSAGES, but the untranslated report listed 1,851
status and error messages with no pt-br row, so with the interface in
Brazilian Portuguese those messages showed in English.
- pt-br.tsv gains 1,812 `@msg` rows. The translations are VectorCraft's
own, written from the English meaning with the catalog's terms.
Placeholders, backticked names, command ids, parameter names,
double-quoted values and bare true, false and null stay as the English
writes them.
- The 39 messages that open #7211, #7214, #7116 and #7330 add pt-br rows
for are left out. bundled_catalogs_are_consistent rejects a second row
for the same key.
- The Portuguese row of docs/localization-parity.md gives the catalog's
counts: 9,260 rows, 3,445 of them `@msg` and 48 `@msgplural`.
The untranslated report missed messages that reach the status bar:
- MESSAGE_CRATES now includes effects, color, render, three-d and pathops,
whose errors the engine and the effects pass on (SVG filters, swatch
libraries, raster sizes and encoders, 3D solids, path operations).
- The scan reads the messages a .map_err closure returns, from each if
branch, match arm and the last expression of a block, the messages of
a handler that .map_err(name) names (a closure bound with let, or a
function), and the message given to a variant of an enum whose name
ends in Fail (CompileFail::Syntax). The steps of a script result's
path ([{i}]{place}, .{k}{place}) are not messages.
- The report and the VECTORCRAFT_I18N_DUMP_MESSAGES dump include the
phrases a parameter schema's error builds at run time (SCHEMA_PHRASES).
Missing translations stay report-only. On main at 0b29b2b1f6 the report
lists 126 more messages, missing in all 23 languages that translate
every message: 43,084 missing rows before, 45,983 after.
addon.pathtools.cornerSet and cornerRemove now refuse a key other than
id and anchors in an `items` member, with the standard unknown-parameter
error, instead of ignoring it. A misspelled `anchor` used to fall back
to the request's `anchors`, else the path's direct-selected anchors,
else every corner of the path. They also refuse `items` given together
with `ids`, which `items` replaces. Saved steps played with replay
still run as recorded.
Docs: docs/mcp.md, docs/target-app-parity.md.