Two problems in the Character Styles panel and its options dialog.
Opening the options took the panel menu's item, which is easy to miss; a double-click on a style's
row did nothing beyond applying the style a second time. A double-click on a user character style's
row now opens its Character Style Options (`ui.charStyleOptions`), as the menu item does. A single
click still applies the style, the second click of the double-click does not apply it again (the
Normal style's included), and with Shift, Cmd/Ctrl or Alt held the double-click only follows the
click rules. The built-in Normal style opens no dialog. Double-clicking a paragraph style's row similarly opens
its options, which are the rename dialog the Paragraph Styles panel menu opens (`ui.paramDialog`
running `paraStyle.rename`): paragraph styles have no full options window yet.
The dialog then grew with its content: the General section lists every attribute of the style, so
the window covered the screen and its buttons could sit below it. The content now scrolls both ways
inside a window at most 420 points tall (less on a short screen) and never wider than the points
left beside the section list, with one scroll offset per section. The dialog keeps a fixed width of
720 points, enough for the widest section's controls, in every section. The content's height is the
space the footer leaves, measured from the footer drawn last frame, so a large interface scale's
taller footer is reserved too and OK and Cancel stay visible. The section list stays outside the
scroll area, so scrolling a long section never moves the navigation; the section is read after the
list handles a click, so a newly picked section gets its own scroll offset in the same frame.
Tests:
`panels::text_styles::tests::double_clicking_a_character_style_row_opens_its_options` selects text,
double-clicks a character style's row and checks the dialog opens with the style's name, one apply
ran from the first click and the second click applied nothing; a paragraph style's row opens none.
`double_clicking_the_normal_style_opens_no_options` checks the Normal style opens none and is
applied once.
`dialogs::char_style_options::tests::the_sections_scroll_in_a_window_shorter_than_the_general_list`
draws the dialog on a 900 by 560 point screen and checks OK and Cancel stay on it, the dialog keeps
its 720-point width in two sections, and the General list is taller than its scroll area.
`every_section_and_the_buttons_fit_the_smallest_window` checks the app's minimum 800 by 500 point
window in all five sections: every section label, OK and Cancel are on the screen.
`a_scrolled_section_keeps_its_offset_after_switching_away_and_back` scrolls General, clicks Basic
Character Formats and then General again, and checks General''s content returns to the same place:
the section is read after the list handles the click, so no other section stores its offset.
`every_section_and_the_buttons_fit_the_smallest_window_at_twice_the_scale` checks the same in the
400 by 250 points the minimum window holds at 2x UI scale, before and after a wheel scrolls the
content.
Docs: type-parity (a panel row and the revision history), ui-parity (a panel row and the revision
history), target-app-parity (two evidence bullets and the revision history) and roadmap (the
revision history), with the status lines updated.
The type parity row no longer says the NumLock-on path was tried on
Windows: neither path has been run on a Windows machine yet. The comment
on the NumLock-off egui keys says Clear comes as the top-row 5, and the
test comment names the keys 0151 and 0234 actually use.
Follow-up to #5939. With NumLock off the keypad sends Insert, End, arrows,
Clear, Home and Page Up/Down; Windows still composes the code from them,
but the app also moved the caret, so the character landed elsewhere. With
Alt held, those keys without the extended-key flag now count as digits and
are taken out of the frame; the separate navigation keys keep their meaning.
Escape and Cmd+Enter (Ctrl+Enter on Windows and Linux) end text editing
and switch back to the tool that double-clicked into the type, or to the
Selection tool when there was none (`TypeTool::end_editing`). The
evidence lines in docs/type-parity.md, docs/ui-parity.md and
docs/target-app-parity.md, and the doc comments on `prev_tool` and
`claims_key`, said they always switch to the Selection tool.
While the Type tool edits text, Cmd+Enter on macOS and Ctrl+Enter on
Windows and Linux typed a line break. It now ends editing as Escape
does: the typed text stays, the type stays selected, and the tool used
before editing is selected again. A held chord ends editing once; its
repeats type nothing and do not open the Move dialog.
Enter, Shift+Enter and Ctrl+Enter on macOS still type line breaks, and
so does the chord with Alt or Shift. Cmd+Ctrl+Enter on macOS ends
editing too. A command bound to the chord still runs instead, and
editing continues. While an IME composes, the chord stays the IME's.
Bulgarian was not among the text languages, so Bulgarian text could not
be tagged and fonts drew their Russian-style Cyrillic. Bulgarian (bg)
is now in the language list (Character panel, character styles,
text.setFormat by name or tag, the Hyphenation preference's default
language), with CLDR's quotes, „…“ at either level. Shaped as bg, the
fonts' locl forms for BGR apply: in the bundled Source Sans 3 Italic,
в, д, ж, з, к, л and ю take their Bulgarian forms.
Fixes#5945
The Snap to Glyph section is drawn after every character attribute, so
in a short panel it appeared out of sight and the menu item seemed to do
nothing; its checkboxes were also dimmed with no way to turn Snap to
Glyph on from there. Choosing Show Snap to Glyph Options now scrolls the
panel to the section, which starts with a Snap to Glyph checkbox
(View > Snap to Glyph) that undims the guide options.
A Type Tools add-on command (Object › Plug-ins › Type Tools › Release Type on a
Path…, `addon.type.releasePath`): each selected type on a path becomes point
type with the same runs, character and paragraph attributes, on one straight
line whose baseline starts where its first character sat, and the plain path
it was set on, with its exact shape and transform, in its layer and stacking
place, with no fill or stroke. `mode` keeps both, the path only or the text
only; `keepOriginal` leaves the type on a path and adds the released objects
above it. Other objects are left alone, nothing to release makes no undo step,
the run is one undo step and the released objects are selected. The command
dialog previews it as Type on a Path Options does (#5360): Cancel leaves no
history, OK is one step. Tests, command_sweep cases, catalog rows in all 26
languages, docs/mcp.md and the parity docs (beyond Illustrator: scores
unchanged).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Choosing a replacement meant picking the family from one drop-down and its style
from another, and only then seeing what the style would be. Replace With Font now
lists rows of a family and one of its styles - the family's closest style first,
then each style it has - and one click sets both. A search above the list filters
the rows by family and style, as the Character panel's font menu searches.
Each list scrolls on its own: the document's fonts and the replacement rows keep
separate scroll states and scrollbars, and the replacement list is ten rows tall
at most, no taller than the rows it lists.
Review: the rows are rebuilt after a replacement, the search clears when the
dialog closes, and a double-click respects the same guard as the Change buttons;
the type-parity checklist has its status line and revision row.
Closes#4972.
The CJK table had an older manual tate-chu-yoko row that still said the
Up/Down and Left/Right settings remain, next to the current row that
lists Tate-chu-yoko Settings as done. The ruby row also said manual
tate-chu-yoko is missing, and a separate row marked ruby as missing.
Remove the older tate-chu-yoko row and the "ruby missing" row, and
leave the ruby row about ruby only.
With Preview on, the selected type on a path follows Effect, Flip, Align
to Path and Spacing while the dialog is open. Cancel puts it back with no
history step; OK keeps the previewed values as one undo step. Preview
starts off. The public pages list no Preview for this dialog, so this is
a VectorCraft choice, recorded as such in the parity docs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Apply wheel steps over the closed family fields in Character, Properties and Control, preserving event order and one undo step per effective notch. Document the supported controls and the application choices. Fixes#5253.
The OpenType panel gets a Position menu after Figure, with Default
Position, Superscript, Subscript, Numerator and Denominator. `numr` and
`dnom` join the extra features (the existing bits keep their indices),
so they round-trip through the stored tags and reach the shaper.
text.setStyle and text.setRangeStyle take `featureChanges`, which turns
features on or off on top of each character's own features in one
command and keeps every tag the list does not name. The Figure menu,
the Position menu and the checkboxes send it, so on a selection whose
characters have different features each character keeps its other
features. Reset OpenType Features still sends `features`.
Catalog rows for Position:, Default Position, Numerator and
Denominator; one line each in docs/type-parity.md and
docs/target-app-parity.md.
Character panel menu > Standard Vertical Roman Alignment, with Show East
Asian Options, is now a check item. It sets a new character attribute,
`standardVerticalRoman` (text.setFormat, text.setRangeStyle), off by
default and saved only when on. In vertical type the marked Latin
letters, digits and other characters that would lie on their side stand
upright one below the other, each in its upright cell. Spaces keep their
width and tate-chu-yoko blocks stay across the column. Horizontal type
keeps the mark and does not change. A combining mark shaped as its own
glyph turns with its letter, in Latin and CJK upright type alike.
Character Style Options labels the Character Alignment row "Character
Alignment" and gives Standard Vertical Roman Alignment its own checkbox.
Reset Panel turns the attribute off. PDF and SVG export place the glyphs
from the layout and need no change.
From the CodeRabbit review: the Serbian and Croatian quote marks name
their sources with the Pravopis's ISBN and links to CLDR's sr and hr
data, in the code and in docs/type-parity.md; the quotes test says what
it checks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011wCJ9DkszhZKxYL3LgcSfZ
Document Setup and Character › Language list Serbian: Cyrillic (sr-Cyrl),
Serbian: Latin (sr-Latn) and Croatian (hr). Text tagged Serbian is shaped
in it (#4940, #4959), so fonts draw their Serbian forms, the italic б,
г, д, п, т. Serbian quotes follow the Pravopis (Matica srpska 2010,
т. 168) and CLDR: „…” and ’…’; Croatian per CLDR: „…“ and ‚…‘.
Illustrator lists Croatian but not Serbian.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011wCJ9DkszhZKxYL3LgcSfZ
In the Tabs panel, a stop dragged on the ruler with Ctrl held (Command on
macOS) moves every stop by the same distance, set in one text.tabs.set and
one undo step. The stops keep their order, alignment, leaders and Align On,
and the ruler draws them at their new positions during the drag.
Ctrl is read when the drag starts, as the Left Indent marker reads it. A drag
that would take the leftmost stop below 0 leaves it at 0, and one that would
take the rightmost past 100,000 pt leaves it at 100,000 pt, keeping the
spacing of the others. A Ctrl-drag released off the ruler deletes only the
dragged stop, as a plain drag does. A plain drag still moves one stop.
Character panel > Language sets the selected characters' language;
text.setFormat and text.setRangeStyle take `language` by name or tag
(unknown: an error), and character styles carry it. Document Setup's
language list gains Hindi, Marathi, Gujarati, Bengali, Punjabi, Tamil,
Telugu, Kannada, Malayalam, Odia and Urdu, with catalog rows; the
Digits menu's numeral names move to a digits context, as Hindi is now
also a language name.
- A composite (Type 0) font is noted by its descendant CIDFont's BaseFont
(ISO 32000-1 9.7.4.1), not its own BaseFont, which ends in "-" and the
CMap name (9.7.6.1, e.g. Name-Identity-H); without one, the CMap name is
taken off the end of the BaseFont.
- A font name's family is the longest part before a hyphen (or the comma of
Arial,Bold) that names an available family, so Noto-Sans-Bold is Noto
Sans, Bold and Noto-Sans-CJK-JP is Noto Sans CJK JP; a shorter family
still matches when no longer one is available.
- A missing font is split only at a comma or before the first part that is a
style word (Helvetica-BoldOblique); otherwise the whole name is its family
(MS-PGothic is reported as MS PGothic, not MS).
Synthetic tests (no host fonts): Families::of builds the family list.
# Conflicts:
# docs/file-format-parity.md
# docs/gaps.md
# docs/type-parity.md
Highlight Alternate Glyphs no longer drops a lam-alef cluster's glyphs
outright: the ligature is clear when required shaping, or shaping with
liga left on (older fonts), gives it, so an optional feature such as
salt that changes it is highlighted again. is_lam_alef takes any
combining mark by Unicode general category (Arabic Extended-A/B/C
included) instead of a partial list. The test font maps the fatha to a
mark and skips marks in its ligature, so the mark-spanning test checks
the exact ligature glyph and cluster; it gains a salt lookup and test.
Also a one-line equivalent nonminimal_bool repair in pathops'
pathtools that strict Clippy needs on main.
Highlight Alternate Glyphs compares each glyph with required shaping
alone, which turns liga and calt off. Older Arabic fonts (such as the
legacy Arial of the Microsoft core fonts) put the mandatory lam-alef
ligature in liga instead of rlig, so every lam-alef was highlighted.
A lam + alef cluster (any alef form, marks allowed) is now never an
alternate candidate, whatever feature the font uses.
Adds a test font built in code (lam-alef under liga or rlig) and
host-independent regressions. Also two equivalent one-line repairs
strict Clippy needs on main: a nonminimal_bool in the Path Precision
Tools inspect check and is_none() in a gradient panel test.
Merges kept prepending each side's whole summary as "previously: …", so
target-app-parity.md's status line had grown to 66 MB (839 copies of its
Target clause), gaps.md's and ui-parity.md's to over 1 MB. Each status
line now names its latest change only, as the progress-docs standard has
it; the revision histories keep the earlier ones.
In typography and Illustrator, Shift+Enter inserts a soft return (forced
line break) rather than ending the paragraph. Text wraps to the next line
without applying paragraph-level spacing (space before/after, first-line
indents), list continuation lines keep their parent item without repeating
markers, and justified text does not stretch lines ending with a soft return.
- Forward active modifier keys for Enter in ui-egui shortcuts so the tool
detects Shift+Enter.
- Type tool inserts U+2028 (LINE SEPARATOR) on Shift+Enter.
- Text shaping and layout treat U+2028 as an invisible zero-advance control
character, breaking the line in point and area type.
- Paragraph spacing and list markers apply once per paragraph as intended.