* 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.
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.
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.
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.
Open #7211, #7214 and #7116 add German rows for 38 of the messages this
branch translates. A second row for the same key fails
bundled_catalogs_are_consistent once both sides merge, so this branch
drops its 38 rows and leaves those messages to the other pull requests.
The German lines in docs/localization-parity.md and
docs/target-app-parity.md give the new counts.
A JPEG rounds each 8 x 8 block's tone on its own, which leaves a small
step at every block edge. Where a dark ground changes slowly, those steps
decided which of two palette colors a whole block got, and the trace
followed the block edges as a staircase.
The new deblock pass finds the block grid in the image: the mean step
between neighboring opaque pixels must peak at the same one of eight
positions at both block edges of a 16 px span, across and down. Cropped
JPEGs and JPEGs saved in another format are found the same way; pictures
of flat 8 x 8 cells are not. At each block edge, a stretch of eight lines
whose step is under the limit and whose pixels hold no edge has the step
spread over the eight pixels around the edge, as the deblocking filters
of ITU-T H.263 Annex J and MPEG-4 Part 2 Annex F.3.1 do. Larger steps are
kept. The limit, the edge guard and how much of each line's own step is
smoothed depend on the mode: Black and White smooths only the smallest
steps, and traces of more than 16 colors move every line of a stretch
by the same amount. The pass runs before the photo pre-filter and works
in strips of rows, so only its output is as large as the image.
A Live Paint Bucket click or drag over faces that already have the
fill, a stroke on an edge that already has the paint and width, Gap
Options with the options the groups have and no gap to close, and Make
or Merge given one Live Paint group alone now leave the document, the
undo and redo steps and the saved state as they are, and reply as
usual. Such a fill or stroke also leaves the recent colors as they are.
Gap Options with Close Gaps With Paths makes a group's faces again only
when it adds a path or what paint stops at changes, so the faces keep
their ids otherwise.
Type > Create Outlines dropped the fills and strokes of the type object
itself (the items around the Appearance panel's Characters row), so the
outlines no longer drew what the type drew. On type without effects of
its own, Object > Expand outlines the type with the same command, so it
lost them before Fill or Stroke could expand them.
- Create Outlines puts those items on paths of the type's whole outline:
the items below the Characters row on one path under the glyph paths,
the others on one path over them, in their order. Unplaced gradients
are fixed to the type's layout box, as the canvas paints them.
- object.expand.info reports the type object's own strokes, pattern
fills and gradient fills, measuring a gradient on the whole outline.
It counts them only when the type has an outline: type of only spaces
reports none of them.
- The stroke flag of object.expand.info counts every stroke Outline
Stroke outlines, not only the topmost one, for paths as well as type.
Expand skipped Stroke for a visible stroke under a stroke with no
paint.
Create Outlines still does not carry over the type object's own effects.
Docs: docs/mcp.md, docs/target-app-parity.md.
Invert Colors, the Convert to commands, Saturate, Adjust Color Balance,
the Blend commands and Recolor Artwork recorded an undo step even when
they changed no color, for example Invert Colors with fills and strokes
off, Saturate at 0 or a second Blend Front to Back. The empty step also
cleared the redo steps. paint.invert and paint.complement on whole
objects, Apply as Filter (addon.color.filter) and Apply Nearest Swatch
run the same pass and did the same.
These commands now run on a copy of the document and record the step
only when something changed. Convert to Indexed Color uses the same
helper. Recolor Artwork also compares the documents when it counted no
recolored paint, so rewriting a color group's swatches still records
its step.
The Limited palette's median cut ranks cuts by pixel-weighted gain. A
large near-black ground with faint noise therefore took two colors less
than 0.02 apart in Oklab, and the trace drew blotches of one over the
other.
With 9 to 16 colors, a cut whose two sides both have a dark gray mean
(Oklab lightness under 0.30, chroma under 0.03) and lie less than 0.03
apart now has its gain scaled by (distance / 0.03)^2 while the cut is
chosen. The ground keeps one color, and the color it would have taken
goes to another cut. Document Library without swatches follows Limited.
Other color counts, Full Tone and Automatic choose the same cuts as
before.
A graph draws the art of a column or marker design inside a series again
from the stored design. Rows, effects and graphic styles that a command
gave that art were lost the next time the graph's data, type or size
changed. The paint commands already left the art out.
- The appearance.* row and whole-appearance commands, effect.apply,
appearance.addEffect and the effect.* commands that edit, move or
remove an effect, threeD.mapGraphic, graphicStyle.apply,
graphicStyle.addFromLibrary with apply, transparency.set with a fill
or stroke item, and appearance.copyFrom (as the target) leave out any
object inside a series group other than a path directly in it, given
by id, selected or reached through target: "contents". They edit the
other objects given, and a command whose objects are all design art
is an error.
- appearance.transfer with design art as its target, or as its source
without copy, is an error.
- A Pathfinder effect no longer groups selected design art.
- The paint commands given a design's copy with a fill or stroke item
leave it out as well.
docs/mcp.md states the rule, and the Graphs line in
docs/target-app-parity.md names it.