Dragging a native window's only tab, or its only group, moves the
window and docks it on release. It took a frame's edges and its tab
strip but not its body's center, a rule meant for the bar, so the
center rectangle was neither a target nor filled under the pointer.
Such a move now joins the center as the tab or group drag would; the
bar still does not.
The ×'s glyph inset, size and hit area are set in one place (MACOS_CLOSE,
OTHER_CLOSE in render/native.rs). On macOS the glyph sits where macOS puts its
close button, and the hit area reaches 10 pt toward the leading edge and down
to the bar's bottom, past AppKit's corner resize area. Elsewhere the layout is
the same as before. CRAFT_DOCK_DEBUG_CLOSE=1 outlines the hit area and AppKit's
resize areas.
egui-winit starts RawInput::focused false and only a winit Focused event
sets it. A window that egui never heard was focused cancelled every tab,
group and window drag and every resize on its first frame. Gestures now
end on a focused-to-unfocused transition (or Escape); a window that
never reported focus still drags while the pointer is pressed in it.
A side split that leaves a half at its minimum is taken when the
dividers along that half can still travel, the groups beyond giving
way as they do for a dragged divider. An 80 pt group, whose halves
need 84, splits on all four sides and takes the rest from its
neighbour; only when the groups beyond are at their minimums too does
the drop join the group's tabs.
On macOS the native window is resizable by AppKit again, with its own areas
and cursors. The bar's buttons sit 19 pt in from the trailing edge, clear of
AppKit's corner area (about 15 pt into the window, a 19 pt square measured on
macOS 26), and the window sets no cursor of its own over AppKit's areas.
Elsewhere the bands are 6 pt deep with 16 pt corner Ls, and hand the resize
to the window system; the manual resize path is gone.
hayro-postscript 0.1.0 is the token scanner hayro-cmap uses for the
CMap streams PDFs embed. Its object reader skipped each `<<` or `>>`
by calling itself again, so a stream holding a long run of `<` or `>`
bytes recursed once per pair and aborted the process with a stack
overflow.
Vendor the crates.io package unchanged and patch `object::read` to
skip those runs in a loop, returning the same next object as before.
Wire it in like the other Hayro crates: workspace exclude,
[patch.crates-io] entry, SOURCE.json with registry and local hashes,
the backend test script, NOTICE, ATTRIBUTION.md and the reader README.
Tests cover a million `<` and a million `>` bytes, `<< /A 1 >>` and
nested `<<<< /X >>>>` runs.
* hayro-syntax: port PdfCraft's syntax fixes (ledger 17, 19, 20, 23, 4-ext, #3565, base_dimensions floor)
From PdfCraft a2ec27b47:
- (17), (19): a CCITT image with /Rows 0, or with fewer /Rows than its
/Height, decodes to the image height instead of zero or /Rows rows.
- (20): spaces or tabs between the stream keyword and its line break are
skipped, so the stream data starts after the line break.
- (4) extension: an inline image's EI followed by a delimiter (EI%, EI[)
ends the image; only a regular character makes it part of a longer token.
- (23): bytes above 0x7F between two EI candidates don't reject the first;
the operator look-ahead decides.
- #3565: a doubled sign (--280, +-280) is read and skipped as one number.
- Page::base_dimensions keeps a one-point floor after /UserUnit instead of
one raw unit.
Also a local bound: a CCITT /Columns past u32::MAX is refused instead of
wrapping to a small width that passed ccitt_size_ok.
Tests: content and number unit tests from PdfCraft, a stream unit test, a
synthetic page test for the floor, a CCITT /Columns unit test, and the two CCITT raster tests in
crates/pdf/tests/upstream_raster.rs.
* hayro-interpret: port PdfCraft's text fixes (ledger 30, 44, P2, P6, P8, 26-ext)
From PdfCraft a2ec27b47:
- (30): WinAnsi 0xA0 and 0xAD and MacRoman 0xCA read as an ordinary space
and hyphen (Annex D.2 gives them those glyph names) unless /Differences
names nbspace or sfthyphen.
- (44): a /ToUnicode /Identity-H or /Identity-V name reads two-byte codes
as their Unicode values; controls and lone surrogates give no text.
- P6: glyph names outside the Adobe Glyph List (f_i, hyphen.case,
uniXXXXXXXX) read by the glyph list specification's full mapping; names
that only number a glyph (C39, c251) give no text.
- P8: a substitute font whose charmap lacks a spacing character (U+2002 and
similar) draws its ordinary space instead of .notdef.
- P2: a Type 3 glyph's /FontBBox is transformed to device space before it
bounds the glyph's clip and shadings, so shaded glyphs draw at every
position.
- (26) extension: comma-below letters (s, t, k, l, n, r, G with comma) in
the standard-font stand-ins are the base letter with the font's comma,
scaled and placed under the baseline.
Tests: crates/pdf/tests/upstream_text.rs for (30), (44) and P6; the Type 3
shading and comma-below raster tests in crates/pdf/tests/upstream_raster.rs.
P8's PdfCraft test needs a Japanese substitute font and is not ported.
* hayro-syntax: refresh SOURCE.json local hashes for Cargo.lock, ascii_85.rs and filter/mod.rs
They changed in #241 and #253 without their local sha256 values.
Floating::new, single and stack draw a fresh id on each call, so a layout
built anew each frame opened a new OS window each frame. with_id gives such
a layout the same windows every frame. Debug builds log a warning once when
three frames running replace every native window with new ones holding the
same panels.
Each side zone reaches zone_depth into the body, or a quarter of the
body's smaller side when that is less. A tall narrow group's top and
bottom zones are no deeper than its left and right ones.
A divider dragged past the minimum of the group it shrinks moves on to
the next group along the axis, and so on until every group on that side
is at its minimum. The line follows same-axis splits up the tree and
ends at a split across the axis or beside a dock. Groups touching the
divider on the other side grow, up to their maximums, as before.
Stacked panels and the groups of a dock column cascade the same way.
The bands along a native window's edges leave out the bar's buttons, which
sit 4 pt in from the window's edge. Each corner is an L, 4 pt deep and 12 pt
along both edges. macOS windows are not resizable by AppKit, whose resize
areas reach over the ×; the bands resize them by InnerSize and OuterPosition,
since winit has no BeginResize there.
PdfCraft ledger hayro-interpret (31), its overflow part: a Type 0 function
with /BitsPerSample 32 computed 2_u32.pow(32), which overflows (a panic with
overflow checks on). The maximum is now ((1u64 << bps) - 1) as f32. The flat
sample array that (31) also brings is a performance change and is not part of
this commit. Test: function::type0::tests::thirty_two_bit_samples_do_not_overflow.
PdfCraft's other reader limits are already covered here: ASCII85 output is
bounded by the decode limit (#253), object-stream indexes are parsed once with
checked offsets, and direct objects nest at most 64 levels (PdfCraft: 128).
* pdf: keep a CID font's /W2 table past an out-of-range first CID; vendor hayro-cmap from PdfCraft
- hayro-interpret: a /W2 run whose first CID is past 65535 is skipped, as in
/W. A run starting at 4294967295 overflowed the CID counter and discarded
the whole table. Unit test in font::cid.
- hayro-cmap 0.1.0 is vendored from PdfCraft a2ec27b47 with its malformed-CMap
patch (PdfCraft #3177): bad bfchar/bfrange entries, an unresolvable usecmap
and an unparseable tail are skipped instead of failing the whole CMap. The
crate's tests come with it. Wired up like the other vendored Hayro crates
(workspace exclude, patch entry, SOURCE.json, backend test script); NOTICE,
ATTRIBUTION.md and vendor/README.craft-reader.md record the source.
* hayro-syntax: refuse an xref-stream subsection that runs past object number u32::MAX
The object number was start + i in unchecked u32: a subsection starting near
u32::MAX overflowed (a panic in debug builds, a wrong object number in
release). Covered in xref::tests::xref_stream_entries_need_backing_bytes.
* hayro-cmap: a binary usecmap counts against the nesting limit; /W2 checks the CID first
- hayro-cmap: a binary CMap's usecmap passed its own depth to the nested
parse, so a self-referencing binary CMap recursed until the stack
overflowed. It now counts like a text usecmap. Test:
self_referencing_binary_usecmap_stops_at_the_nesting_limit.
- hayro-interpret: the /W2 first-CID check runs before the run's metrics
are read, so an incomplete run past CID 65535 no longer discards the
rest of the table.
* hayro-syntax: refuse xref-stream object numbers past i32::MAX
ObjectIdentifier stores an i32; a number between i32::MAX and u32::MAX
was cast to a negative object number.
* i18n: scripts, direction and regional Han per language tag
scripts(tag) lists the ISO 15924 scripts a language's interface text is
written in, direction(tag) follows the main script, and han(tag) gives
the regional Han forms (SC, TC, HK, JP, KR) for picking a CJK face.
I18n::rtl uses direction.
* i18n: non_exhaustive Script and Han; regions that imply a script
pa-PK, uz-AF and az-IR are written in Arabic and sd-IN in Devanagari, as
CLDR's likely subtags give them. A script subtag still wins.
* i18n: han and catalog matching follow region-implied scripts
han(zh-US), zh-AU and the other regions CLDR writes in Traditional
characters give Traditional, and pa-PK picks a pa-arab catalog, never
Gurmukhi pa, as pa-Arab-PK does.
* i18n: Hani and yue-Hant pick Han forms by region; usual scripts for kk, ky, tg, ku, ms, ug
* i18n: base_direction of a paragraph from its first strong character