| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
| |
The terminal, the pixel surfaces and the web page reckoned when a timer
was due on the wall clock: set back, a timer waited until the clock came
again to the tick it had waited for (Pure's review 004). vega_clock is
the monotonic clock; timers are due on it, and a tick sets the time its
event sees from the wall clock (vega_now), as before.
check.py's clock_set_back runs a timer of 20 ms in the terminal with the
wall clock set back an hour 0.2 s in (Pure's build/clock-back.so, an
LD_PRELOAD of clock_gettime): 40 ticks in 0.8 s, where Vega before this
stops at 9. make check passes it --clock-back.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
text/upstream.py brings in a HarfBuzz release (default: the one the
build links) and the UCD of the Unicode version its tables came from,
builds that HarfBuzz as one static library from its amalgamated source
(no system package, any version), regenerates the Unicode tables and the
syllabic ones, holds the syllable machines to HarfBuzz's compiled ones,
and runs the text checks built against it: Unicode's conformance tests on
that UCD, random shaping against that HarfBuzz, the layout's promises,
the kern class tests, HarfBuzz's own suite. --corpus adds every installed
font (text/fonts.py, the corpus runner, now in the tree). What a new
version breaks shows as failing checks with the font and the input to
port a fix from; the generated files are left changed for review.
make check-text is those checks alone; UCD and HARFBUZZ_SRC default to
build/upstream's when the tool fetched them. Its first run found that
text/shape-build.c used clock_gettime without asking for POSIX, building
only because the system HarfBuzz's headers did. Against HarfBuzz 10.2.0
built from source and the 16.0.0 UCD, every check passes in about a
minute.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The kern table's class subtables, OpenType's and Apple's, as HarfBuzz
reads them (hb-aat-layout-kerx-table.hh, hb-ot-kern-table.hh): format 2's
class tables give byte offsets into a kerning array, format 3's byte
classes index a value list. Both go through the same pass as pairs
(marks skipped, the kerning split between the pair). Format 2 filters the
glyphs by the class tables' digests, as HarfBuzz's accelerator does, so a
digest's false positive reads class 0 there too; what a subtable reads
must lie within it, the last one's within the table. The build checks the
subtables as HarfBuzz's sanitizer does, and still refuses state machines
(format 1) and cross-stream kerning.
text/test-kern.py makes fonts with format 2 and 3 subtables in every
order, with the edge cases that reading has (value 1, glyphs outside a
table, offsets below the array or odd, values past a subtable's or the
table's end, classes and indexes past their counts): 24 fonts, 96 plans,
the same as HarfBuzz. make check runs it where fontTools is. HarfBuzz's
suite: 5017 of 5199 the same.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
text/harfbuzz-suite.py reads a HarfBuzz release's test/shape/data
(in-house, text-rendering-tests, aots: fonts and inputs, many added when a
font or a shaper once went wrong) and shapes every case both ways with the
new vega-symbols shape-cases: it compiles a font's section for the scripts
its cases need (guessed as HarfBuzz guesses them), then compares each run
with HarfBuzz's, glyph for glyph and unit for unit. The oracle is HarfBuzz
run live, not the recorded outputs, which depend on options Vega has no
counterpart for (font functions, sizes, output formats). Cases asking for
what Vega does not do (user features, variations, languages, context,
cluster levels, buffer flags, vertical text) and fonts of other systems are
left out and counted by why.
text/harfbuzz-suite.known lists what differs today, and why: AAT, the
character map built from what HarfBuzz lists rather than how it maps
(format 13, symbol maps into the private use area), variation selectors,
Arabic fallback with shared glyphs, kern format 2, Zawgyi, and one run
without a plan. Any other difference fails the run; a listed case that
agrees is named. make check-harfbuzz HARFBUZZ_SRC=... runs it (make check
too, when given): 5929 cases, 5199 compared, 1355 the same.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
vega_draw keeps what it wrote as spans (VegaSpan: a row, the columns it
was given, where its cells reached, its text and tone). A span written
where the same pen stopped follows the one before it (a field's name and
value, the help line, the prompt); one written after the pen moved (a
table's column, a list's label, a badge) starts afresh at its column, and
a badge sits flush with its end.
When the first font shapes, the pixels set type: a span and those
following it are one line of text, laid out as one paragraph in the font
stack (bidi and kerning cross the spans; each glyph takes the tone of the
span its character came from), from its column up to the nearest of its
spans' ends and the next span on the row, cut at a grapheme cluster
boundary with an ellipsis if it must be. The prompt gets a text cursor.
--symbols repeats: fonts in order of preference (at most 8); the cells,
when the first font does not shape, also fall back through them.
The check sets a label in one script, alone in its list, and holds it to
what the font that has it sets by itself (vega-symbols paragraph, which
now sizes itself to its text with width 0), pixel for pixel: Latin
kerning, Hangul, Arabic and Devanagari over DejaVu Sans, Noto Sans CJK KR
and FreeSans.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
vega_layout takes fonts in order of preference (VegaFonts). A grapheme
cluster goes to the first font that has all its characters (default
ignorables aside: shaping hides them); a cluster of Common and Inherited
characters stays in the font before it when that one has it, so the spaces
between Arabic words stay in the Arabic font; failing that, the first font
with its first character, else the first font. Runs split where the font
changes too. Positions are in the first font's units, a run's pen scaled
as a whole so rounding does not add up. Callers can narrow what a font
has (a symbol file holds only the glyphs its codes reach).
vega_default_ignorable is shape.c's HarfBuzz 10.2 set, now public.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The Indic shaper, from HarfBuzz 10.2's source: syllables found by the
Indic machine; each syllable's base consonant, its pre-base matras and
reph moved around it and masked for the basic features, applied one at
a time within the syllable; then matras, reph and pre-base-reordering
consonants placed again by what the features made. Vowel constraints,
Indic decompositions and compositions, dotted circles for broken
syllables, and per-syllable matching come with it.
Plans carry GSUB pauses (steps where the shaper does its part) and the
stages of the features the shaper asks whether they would substitute;
the runtime answers with each subtable's would_apply, as HarfBuzz does.
Masks are now the common ones and each shaper's own.
text/syllabic.py reads HarfBuzz's Ragel grammars (Indic, Khmer,
Myanmar) and compiles each to a minimal DFA with Ragel's scanner
semantics; beside the machines Ragel generated from the same grammars,
100,000 random runs each find no syllable that differs. It also reads
HarfBuzz's Indic table (Unicode 16) cell for cell.
Every installed font shapes as HarfBuzz does (213 fonts, 1,688 plans);
the Indic ones at 20,000 runs a plan (FreeSerif's eight scripts,
FreeSans, Unifont's nine without GSUB), and nine new-spec Noto Sans
fonts at 5,000.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
vega display --access joins the accessibility bus as AT-SPI2 objects for
screen readers such as Orca, with no toolkit, ATK or libdbus: dbus.c
speaks the D-Bus wire format (EXTERNAL authentication, headers, aligned
bodies, calls, replies, signals). The tree follows what the say surface
says: a heading, a label per field, a list box per list whose items know
their place and which is selected and focused, tables, the entry, the
keys as buttons; answers come from the app when asked, one object has the
focus, and focus moves are said as events. Assistive technology can act
too: Selection focuses a row, Action presses a key. The live loop now
draws only when something changed, so a screen reader's questions no
longer cost frames. The check walks the tree with gdbus on a private
session bus with at-spi-bus-launcher, and follows the focus through keys,
Selection, Action and the events.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
order
text/layout.c puts the checked parts together: a paragraph's levels,
scripts resolved for Common and Inherited characters, break
opportunities, one shaping to measure, lines broken at the last
opportunity that fits (trailing spaces hang, and a line that shapes
wider than measured backs off), then per line L1, runs of one level and
one script shaped again, the runs in L2's order and their glyphs placed.
test-layout checks 30,000 random mixed-script paragraphs: lines cover
the text, mandatory breaks end lines, lines fit when they can, and
glyphs come in the order UAX #9 gives the characters. vega-symbols
paragraph draws a layout through the symbol file's glyphs.
|
| |
|
|
|
|
|
|
|
| |
UAX #14 line breaking (LB1-LB31, numbers tailored as Unicode's tests
are) and UAX #29's grapheme cluster, word and sentence boundaries, each
from generated property tables, the rules taken in order, in linear time.
They pass all of Unicode 15.1's LineBreakTest (10,274 cases),
GraphemeBreakTest (1,187), WordBreakTest (1,826) and SentenceBreakTest
(512).
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
The build tool compiles a font's shaping plans the way HarfBuzz's planner
does (features, stages, masks, lookups per script and direction) and
carries them with the font's character map, advances and GDEF, GSUB and
GPOS tables in a section of the symbol file (VEGASYM4); glyphs shaping
reaches become symbols of their own. A small engine ports HarfBuzz 10's
default, Arabic and Hebrew shaping step for step and reads the tables in
place, every read bounds-checked. The build refuses a file whose shaping
differs from HarfBuzz's on random runs: DejaVu Sans agrees on 600,000
runs in six scripts both ways, and every installed font the tool accepts
agrees too, at 1.05-1.18 times HarfBuzz's time.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
| |
vega-surface.so is compiled against Pure's app and module layout, which a
node checks when it maps the surface (sizeof PureApp and PureModule): a
surface left from before a change of those headers was refused, and the
node showed no frame. It now depends on Pure's core headers and
serve/surface.h, as the vega command already depends on libpure.a.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Surfaces that read keys (the display, through evdev) had only a US
layout's letters. After the 한/영 key (Lang1, or AltRight standing for
it), letter keys now give jamo that compose syllables in the entry line
(surfaces/hangul.c): an initial, a vowel and an optional final, joined
vowels and finals, a final that moves on to a vowel after it (도깨비불),
Shift's doubled consonants, a lone jamo as its compatibility letter. The
syllable being composed shows after the entry line; Backspace takes it
back a jamo at a time before deleting what was typed; Enter, Tab, the
toggle or any key but a letter finishes it. The script language gains
hangul, letters HEX and back to drive it.
The check types ten cases through it (안녕하세요, 값을, 안자, 와원, 까원,
갑 after Backspace, 한글, ㅏ, 안ㅈ, 안녕 2) and follows the composing line
jamo by jamo; the messenger check has Alice type 안녕 on her display with
recorded keys, drawn on Bob's.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The vega host builds a second way, as build/vega-surface.so, which
pure-serve maps and runs beside its connection threads (pure-serve
--surface vega-surface.so -- display ..., Pure's design 010). There the
app it draws is a reader of the node's last save, read where it is,
and what people type goes to the node's owner: a key press as the key
input's event, the typed line as the text input's, each applied and
saved with the node's requests. It waits on its input devices and the
node's changes descriptor together, leaves timers and signals to the
node, and stops with it. The library calls the app model pure-serve
exports and links none of its own; it exports pure_surface_run alone.
Without --live or --input it takes no input: the node's saves alone draw
it.
The check gives a node an item over HTTP, then runs the display in the
node with recorded keys (an item, Enter, Tab, Space): the last frame is
the one vega tui draws for the same state and keys, it came back from
the display controller as drawn, and the node's views show both items.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
vega display --live reads the kernel's input events with no library:
keys become Pure's key names and the text they type on a US layout, going
through the TUI's own handling (the input line takes text, else the app
takes keys); a mouse moves an outlined pointer and clicks, a touch screen
presses where it is touched, scaled from the device's range; the line
pressed is the row. --input FILE reads recorded events to their end and
prints the last frame, which is how this screenless Pi checks it: after
typing two items with Shift, Enter, Tab, Space and a touch on a row, the
display's last frame is the TUI's after the same keys and click, and came
back from the display controller as drawn.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
vega display draws the same frames on a display with the kernel's mode
setting and no library between: a connected connector's mode on a CRTC, its
primary plane flipped between two dumb buffers by atomic commits, the grid
as many cells as fit. Frames are drawn in cached memory and copied over,
since blending over write-combined buffers read them back slowly (a 1080p
frame took 370 ms; now 20.6 ms with a vertical sync and the check below).
This Pi has no screen but its display controller has writeback connectors:
--writeback sets a mode on one and takes every frame back as the controller
put it out. Each came back exactly as drawn, and the new check finds it the
pixel surface's frame for the same grid, pixel for pixel.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
vega pixels runs the same scripts as tui --dump and writes each frame as
an image: the view's cells (only those on screen are evaluated) become
glyphs, each drawn once per size with the exact area of its curves, in its
tone's colour on its row's background. No page, no scene in between. A
1920x1350 grid takes 12 ms a frame here, writing the image included.
Symbol files carry the font's line now (format 3: ascent and descent where
format 2 kept zeros), the cell height and baseline; and the build tool takes
fonts in order, later ones filling the codes earlier ones lack: a CJK font
alone drew ambiguous-width arrows two cells wide in a one-cell grid, which
the new check caught, so a monospace Latin font comes first and Hangul after.
|
| |
|
|
|
|
|
| |
src/ held two parts, the surfaces that show modules to people and the
symbol format with its CPU and GPU drawing. As in Pure (design 009), top
level directories are now the parts, and the README says what each builds.
|
| |
|
|
|
|
| |
Pure builds the app model and the tree store as one library with headers in
core/; Vega no longer lists Pure's files, so a new one there cannot break it.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
OpenGL ES 3.1: the file's points go up as one storage buffer, each symbol
gets 16 row bands listing the curves they reach (cut by integer division of
doubled coordinates, so CPU and shader agree), and every pixel of a symbol's
box sums the exact area of its bands' curves, as vega_coverage does.
vega-symbols gpu draws every symbol against the CPU reference and times
1080p pages.
On the Pi 5's V3D it matches the reference (mean 0.001-0.1 levels, worst
4) but takes 142-757 ms a page, 83% of it in the area function. A sorting
network in registers made it 2.3x faster yet computes wrong rows in the
fragment stage with this driver, while the same code is exact in a compute
shader; so drawing each glyph size once into an atlas by compute comes next.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Symbol files (VEGASYM1) hold glyphs and icons as quadratic curves, verified
once per symbol and then read in place. vega-symbols builds them from fonts
(through FreeType, losslessly: twice the font's units keeps TrueType's
implied points whole) and from solid SVG paths (arcs included), refusing by
name what an icon asks for that symbols cannot hold.
The reference rasterizer computes each pixel's covered area exactly: every
curve's integral of clamp(1 - x) dy inside the pixel, split where it crosses
the pixel's sides. The Slug-style two-ray average first tried missed FreeType
by 15.4 levels on average at 12 px; exact area is within 1.2-3.5 at 8-16 px,
and where it differs most it matches 64x64 supersampling, not FreeType.
Reaching an outline costs 4.6-29x less than through FreeType, but the files
are 2.1-6.6x larger than glyf or CFF: design 002 has the numbers and the next
question (points shared along contours, lines without control points).
|
| |
|
|
|
|
|
|
|
|
| |
examples/board.aup is a kanban board: people add and move cards on
Vega's surfaces, programs post JSON to the same module served by
pure-serve, with no routes written. The checks write cards with the CLI
into a store, serve that store over HTTP where a program moves one and
adds another, and read it again with the CLI, the focus still on the
card it was on.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
vega web MODULE serves the screen to a browser (127.0.0.1 unless given
--listen): one dependency-free page draws the title, fields, lists as
listboxes and tables, with tones as colors and the focus highlighted. It
asks for the screen as JSON with the rows it can show per list or table,
so only those cells are evaluated, scrolled like the TUI around the
focus. Keys go as KeyboardEvent.code, which is Pure's key naming already;
typed text commits with Enter; a click or the wheel moves the focus
through pure_app_point; an event stream tells every open page of each
change. Scrolling, key presses and text commits are now shared helpers.
The checks drive it against the model (1,200 random steps: title, field,
rows, focus, the window of items with badges and tones), check a table's
columns and cells, post at random to every example, and in headless
Chromium over the DevTools protocol press keys, click a row and type
Korean text into the page itself.
|
| |
|
|
|
|
|
|
|
|
|
| |
Every surface takes --store PATH and runs the app on Pure's tree store,
so a list typed in the terminal is there the next time, on any surface.
Vega and the app carry no saving code; Vega saves the last frame changes
when it ends.
Checks let the CLI and the sentence surface take turns on one store and
match the model each time, and reopen an interactive session's store.
|
|
|
Vega reads a verified Pure module by convention: a table view with a
label column is a list (with optional badge, detail and tone), any other
table is a table, <table>_focus is its focused row, a title view is the
title and other views are fields. lib/vega.aup gives aup apps the tones,
which say what a row means; each surface decides how it looks or sounds.
vega tui draws the screen in a terminal, keeps the focused row in view
and evaluates only the cells on screen; vega cli prints plain lines for
pipes; vega say speaks the screen and each focus change as sentences.
Display width handles Hangul, CJK, emoji, combining marks and controls.
tests/check.py compares the CLI and NUI output with a reference model of
examples/todo.aup line for line, checks 9,600 TUI frames for scrolling,
focus, badge alignment and the number of cells evaluated, drives the
interactive TUI on a pseudo-terminal, and runs every aup example on every
surface.
|