Commit Graph
23 Commits
Author SHA1 Message Date
dotCooCoo 9a312e8ada Type: type in a composite font is measured in its own document's definition
- A file read for opening is laid out in the composite fonts registered
  then. Opening a document and reverting the front one now measure again
  the type set in a font named like a composite font that an open document
  defines, the font database holds or the session registered earlier. Type
  in other fonts, missing ones included, keeps the bounds it was read with.
- Switching to a document or closing the front one measures again the type
  set in a composite font whose definition changed, and any type without
  bounds.
- A document reverted while in the back measures its type in composite
  fonts when it comes to the front, not in the front document's.
- Text holding an inline graphic whose symbol's type was measured again
  takes the graphic's new size.
- A failed or panicked command puts the font database's composite fonts
  back with the documents.
- Setting a composite font to the definition an export lends keeps it after
  the export ends.
2026-11-08 14:23:43 -08:00
dotCooCoo 11f1d228de Type: Align to Path moves each character by its own font's metrics
Align to Path moved the whole line by the largest ascent and descent
among its characters. Each character now moves by its own font, size
and vertical scale. Ascender runs the top of the font's em box along
the path: the ideographic em box that the font's BASE table gives, or
in a Chinese, Japanese or Korean font the one that its typographic or
hhea box, a one-em box-drawing cross or its ideographs give; else an
em box centered on the cap height. Descender runs the bottom of the font's
bounding box along the path, and Center runs a line at half the height
of the top of the font's H along it. In vertical type, Ascender and
Descender move the characters half an em, and Center leaves them on
the path.

Existing documents with Align to Path set to Ascender, Descender or
Center lay their type out at a new distance from the path.
2026-11-09 03:14:41 +07:00
dotCooCoo c94269ff72 Type: Composite Fonts… sets each class of character in a font of its own
Squashed from #6244 onto main.
2026-11-09 03:08:23 +07:00
dotCooCoo dbcdbf2466 Open: the first frame uses the layouts the open made for type objects
Opening a document laid out every type object for its bounds and
baselines and threw the layouts away, and the first frame laid the same
objects out again. The open now keeps them, up to 128 MiB, and a frame
takes each one once.

A frame takes a layout only for a text object equal to the one laid out,
and only while the fonts, the system fallback setting and the hyphenation
exceptions are unchanged. When the last frame being drawn ends, the rest
are dropped if a frame took one, and all of them are dropped after eight
frames that take none. A layout with bitmap or color glyphs and a text
object with a gradient are not kept.
2026-11-08 11:42:45 +07:00
dotCooCoo 77d5f8bbea Type: tests compare opened documents with and without kept shaping plans
A new test binary opens a document of 13 type objects with the plans a
font face keeps and again while every shaped segment makes its own plan.
The document, its cached bounds and baselines included, and the first
frame's pixels must be the same. `test_fonts::keep_shape_plans` switches
the plans off; it exists only in tests and with the `test-fonts` feature.

The engine's open test now builds objects of one script and direction
that differ in kerning and language, and lays each one out in a font
database of its own, so a plan used for the wrong features fails its
comparison. It no longer sets Arabic, which could fall back to a system
font in one database and not the other.
2026-11-07 05:14:59 +07:00
dotCooCoo 25b42b2246 Type: layout keeps each font face's shaping plans
Every shaped segment built its own harfrust shaping plan, although a
plan depends only on the face, direction, script, language and features.
Opening a document lays out each type object once, so a document of many
short objects built thousands of identical plans.

A font face now keeps up to 32 plans, oldest dropped first, and shapes
with the one that matches. Feature ranges still come from the shape
call, so text with the same features over other ranges shares a plan.
The glyphs, bounds and baselines do not change.

Docs: docs/target-app-parity.md.
2026-11-07 05:14:59 +07:00
ruchirguitar 70f798b71d i18n: add Hindi interface and message catalog 2026-11-06 12:40:10 +07:00
Alex 31f05d3545 Find Font: a stand-in style is never the target, and the closest style comes from the catalog
A document font drawn in a substitute style stayed listed and could be chosen as the
replacement: the family is installed, so the old check passed, and Change sent the
unavailable style to text.replaceFont, which stored it and warned that the text is drawn
in a stand-in. The exact face now decides both the automatic choice and whether Change
is available; the row stays listed.

Listing System asked the font database for each family's style-less face, and for a
family not loaded yet that reads all its cataloged files, so opening the dialog could
load a whole font library. FontDb::closest_style answers from the catalog's weight and
slant instead, and the rows put that style first as before.

Tests: the dialog's 26 (the closest style is the face a style-less request resolves to,
a stand-in style is listed but not chosen) and the text crate's 474.
2026-11-05 04:47:34 +07:00
dotCooCoo 88b5170622 Glyphs panel: alternates for the current text selection
Squashed from #5442 onto main.
2026-11-04 22:29:53 +07:00
Don Omondi 0143e0f706 Fix #5483: a large font library no longer keeps the window from opening
The menu bar builds Type > Font in every frame, the first included, and
its family list waited for the scan of every installed font. When that
scan took longer than the 20 s first-frame watchdog (thousands of fonts
on a slow disk, or each file checked by antivirus), the app took the
graphics adapter for hung and started again without it, until none was
left and no window ever showed.

The menu now lists the fonts already loaded until the scan ends, then
all of them (FontDb::menu_family_list_now, installed_fonts_ready).
2026-11-04 21:37:48 +07:00
dotCooCoo 663c3264ca Type: list stylistic sets whose lookups come from FeatureVariations
A variable font can leave an ssNN feature empty in GSUB or GPOS and
supply its lookups through a FeatureVariations substitution. The
OpenType panel skipped those sets because the default feature has no
lookups. A set is now listed when a substitution in a variation record
replaces its feature with one that has lookups, and its name is read
from the default feature or the substituted one.

Records after one without conditions are ignored, and at most 4096
variation records and 4096 substitutions are read per table.

Follows #5447.
2026-11-04 15:41:05 +07:00
dotCooCoo 4fa4862613 Type: translate the numbered stylistic set label
StylisticSet.name now holds only a name the font supplies. The OpenType panel shows a set without one as `Set {n}` through tl!, so the label is translated, and each UI catalog has a `Set {n}` row.
2026-11-04 14:08:30 +07:00
dotCooCoo b72c822f1d Add font-aware OpenType stylistic sets menu 2026-11-04 14:08:30 +07:00
Dylan M. Taylor daf224755a Fonts: cap the name records and decoded bytes read per name id 2026-11-04 10:52:13 +07:00
dotCooCoo 9fd7d0a733 Type: place a contour-point caret on a composite as the outline is drawn
With SCALED_COMPONENT_OFFSET, a component's offset now scales each axis
by the length of that axis's basis vector, as the outline loader does,
instead of going through the whole matrix. A rotated or skewed
component's caret no longer lands away from its drawn point.
UNSCALED_COMPONENT_OFFSET now turns the scaling off when both flags are
set.
2026-11-04 08:12:22 +07:00
dotCooCoo 98ef01a6d3 Type: bound the glyphs a contour-point caret lookup reads
A composite glyph whose components expand into glyphs with no points
could make the contour-point caret lookup read billions of glyphs. The
whole lookup now shares a budget of 65,536 glyph reads and gives no
caret when it runs out, so the caret falls back to dividing the advance.
2026-11-04 08:12:22 +07:00
dotCooCoo 817bfceda3 Resolve GDEF contour-point ligature carets 2026-11-04 08:12:22 +07:00
dotCooCoo e1ea0ecad1 Type: the caret, a click and the arrow keys reach the characters inside a ligature
Squashed from #5225 onto main.
2026-11-03 16:38:36 +07:00
dotCooCoo 427bce12b0 Character: Font Size can measure the cap height, x-height or ICF box
Squashed from #5026 onto main.
2026-11-01 11:08:55 +07:00
dotCooCoo f87b8af62b Snap to Glyph: points land on glyph anchors and line up with x-height, character widths and angles
With View › Snap to Glyph and Smart Guides on, a point drawn near a single
line of live type now also lands on the anchor points of its glyphs and lines
up with its x-height (raised or lowered by Baseline Shift) and with the edges
of each character's advance width along the baseline (proximity guides). In
rotated type the baseline, x-height and proximity guides run at the type's
angle, and type of one glyph also has angular guides along the glyph's slanted
straight segments; a segment that Shift keeps to its angle slides onto them.
A paragraph shows glyph bounds only, so its baselines are no longer guides.

FontFace::x_height gives a face's x-height in font units.
2026-10-29 11:18:38 +07:00
Dylan M. Taylor 0e2815629f refactor(text): split flow and ruby layout phases 2026-10-27 17:47:12 +00:00
Dylan M. Taylor dec8b90e3a refactor(text): clarify line adjustment inputs 2026-10-27 17:47:12 +00:00
aiongg de14f93c05 refactor(text): move fontdb.rs items to fontdb/{build,cache,db,dirs,face,glyph_pen,lookup,names,scan,traits,wanted}.rs 2026-10-26 22:01:25 +00:00