| Commit message (Collapse) | Author | Age | Files | Lines |
| | |
|
| |
|
|
|
|
| |
vega_text reads an i64 view or column as an integer and prints all of
its digits, so an ID past 2^53 shows as it is on the CLI, the TUI,
speech and the web surface, where a number would round.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
aup and Pure now have a bool (Pure 016): a view or column may be one.
vega_text writes it as true or false, as a string's interpolation does, so
every surface shows the same words: the CLI, the TUI's cells, speech and
the web surface's JSON (a value's text) and page. An app that wants other
words picks them with a conditional (if t.done { "done" } else { "" }).
The flags of the examples are bools: todo's done and urgent, today's done,
the stopwatch's running. vega.when takes the bool as it took the number.
bools checks a bool field and a bool column on the CLI, the TUI, speech
and the web surface: true and false, never 1 and 0.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
value's bidi within it
Speech wrote a value's C1 controls (U+009B is a CSI to some terminals),
DEL, line separators and bidi overrides as they were; the CLI and the
TUI wrote line separators (a pipe's reader may break its line there) and
the controls that turn text around (a terminal then reverses the rest of
its line, other values' cells too); the web page showed controls as they
were and let a label's override reverse its badge. Now every surface
shows controls, DEL, C1 and line and paragraph separators as pictures
(vega_visible); a terminal's cells show embeddings, overrides and
isolates as U+FFFD too (vega_cell); speech says a space for the one and
nothing for the other; the page shows the pictures and isolates each
value, while /screen's JSON keeps values as they are. screen_meaning
checks the CLI, the TUI, speech and the JSON against that rule, and that
nothing a value holds reaches any output as a control; the browser check
sees the page show it.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
examples/shared-board.aup is the board grown in Pure's research 105:
each node sends a changed card whole to the other (send changed {
..at }) and takes the other's whole when it is the later change
(cards[k] = Card { ..remote }), by its time and then by the node's
name, so both boards end the same whatever order changes come in. The
input the other node sends to is the output's like (message like). A
new field goes in the card and the output alone.
tests/check.py shared_board runs Alice's and Bob's nodes linked both
ways over pure://, sealed, each taking the other as its sender: cards
added, moved and given on either agree; Bob cut off, both give one card
(Bob first, Alice after) and Bob adds one; joined again, both boards
take Alice's and Bob's card.
|
| |
|
|
|
|
| |
pure_app_start and pure_app_replace now say in PureApp.why why they
refused, when they can (sends waiting on an output the module lacks).
Vega printed only the result's number; it prints the reason beside it.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
handle_input found escape sequences only whole within one read, so an
arrow whose ESC [ came in one read and its A in the next was Escape, [
and A (Pure's review 004, F5); a UTF-8 character cut the same way went
in pieces. A read's bytes are not the terminal's keys: now an escape
sequence, a mouse report or a character cut short waits for the next
read. An escape alone that nothing follows within 100 ms (vim's
ttimeoutlen) is the Escape key; the rest of a key already begun waits up
to a second.
check.py's interactive runs a third session with every key coming a
byte at a time, 50 ms apart, and the arrow's A 150 ms after its ESC [:
the focus moves, as when keys come whole; Vega before this marks the
wrong task done.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Bringing in HarfBuzz 14.5 and Unicode 18 broke both generators and showed
over ten changes to shaping output since 10.2. Following them is cloning
someone else's implementation, bugs and all, release after release: a
cost without end, and no compression of abstractions. So the text
subsystem stops here: no more chasing HarfBuzz's bugs and habits (AAT,
Zawgyi, Arabic fallback over shared glyphs stay refused), and upgrades
only when needed (a new script, a security problem), with
text/upstream.py. Left as a design task for later: compiling a font's
whole behaviour into Vega's own format at build time, so that shaping at
run time no longer tracks HarfBuzz.
|
| |
|
|
|
|
|
|
| |
Run against HarfBuzz 14.5.0 and Unicode 18.0.0, text/unicode.py met a
line breaking class it does not know (HH) and text/syllabic.py a table
laid out otherwise, and the tool had already emptied both files. A
generator's output now replaces its file only when it succeeds, and the
tool stops before building when one fails: those are what to port first.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
HarfBuzz 10.2's tables are Unicode 16.0, Vega's were the installed UCD's
15.1: characters new in 16.0 could be read two ways. The tables now come
from the 16.0 UCD, and the line breaking rules are revision 53's: LB13's
'x IS' split into LB15c (SP / IS NU, as in 'subtract .5') and LB15d; the
numbers of section 8.2's Example 7 made LB25 (new: IS x NU, PR x OP IS
NU); LB19 split, with LB19a letting quotation marks between East Asian
characters break; LB20a keeping a word-initial hyphen to its word; LB21a
narrowed to Hebrew, hyphen, then not Hebrew. vega_east_asian now covers
all of East_Asian_Width F, W and H.
Unicode 16.0's conformance tests all pass (bidi 770241 and 91707, line
breaks 16672, graphemes 1093, words 1826, sentences 512, normalization
19965). test-text reads NormalizationTest.txt plain or compressed, and
passes over a UCD of another version than the tables' (the installed
one here is 15.1). HarfBuzz's suite (5018 the same), the installed fonts'
and Noto's random runs, and the surfaces' checks agree as before.
|
| |
|
|
|
|
|
|
|
|
| |
A font whose GSUB grows the buffer past its bounds (text-rendering-tests'
GSUB-3) made vega_shape fail. HarfBuzz goes on with the glyphs of the last
pass that finished: every later pass does nothing, positions are the
default advances. Vega's buffer operations already stand still once the
buffer is unsuccessful, so it now goes on too, and a broken font shows
what HarfBuzz shows rather than nothing. HarfBuzz's suite: 5018 of 5199
the same, none failing.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The section now carries each sequence the font maps, a base and a
selector, with the glyph HarfBuzz gives the pair (a default one's the
base's own). As HarfBuzz's normalizer does, a sequence the font has
becomes that one glyph, the two characters' clusters merged; one it lacks
still passes on as two, the selector hidden. The header grows to 88 bytes
for the table.
The random check now mixes in the font's own sequences and stray
selectors: 30000 runs over Noto Sans CJK's 14787 ideographic variation
sequences are HarfBuzz's, and so are the installed fonts' and Noto's.
HarfBuzz's suite: 5014 of 5199 the same, none different; what is left is
what the build refuses and one run without a plan.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The shaping section's character map came from hb_face_collect_unicodes.
HarfBuzz's own suite showed where that list and its mapping part: it cuts
a format 13 map short (AdobeBlank2's whole Unicode to one glyph), and a
symbol map (3,0) it searches through the private use area, Latin and, in an
old Arabic font, Arabic too. Now every code point is asked with
hb_font_get_nominal_glyph (about 30 ms a font) and the map carried as
groups: codes going to consecutive glyphs, or all to one (12 bytes each,
so a format 13 map stays small).
HarfBuzz's suite: 5011 of 5199 cases the same (1355 before). The installed
fonts (213) and the Noto ones (21) still shape as HarfBuzz does on random
runs.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 live terminal checks forked a pty, started Vega's TUI, and only then
set the window size and sent SIGWINCH. A TUI that read the size first
drew its opening frames at the pty's default size, and replaying them
into the smaller screen failed now and then (one run in about eleven).
The child now sets the size on its own terminal before it starts.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The rest of HarfBuzz 10.2's Arabic shaper. Joining types now come from
HarfBuzz's own table (Unicode 16, with Syriac's Alaph and Dalath-Rish
groups the state machine's last two columns use), the general category
deciding where it has none, so Syriac shapes with fin2, fin3 and med2.
What stch multiplies is recorded and, after positioning, stretched under
the word before it, repeating pieces copied as often as fit. A font with
presentation forms but no Arabic features gets HarfBuzz's fallback
lookups, which the build tool writes as OpenType and the runtime applies
at their pause like any GSUB lookup.
The generator now reads HarfBuzz's generated tables through their lookup
functions' ranges and offsets: rows whose range starts mid-row have
blank cells in front, which the row comments alone miscounted (Arabic
Supplement); the Indic table, read again this way, did not change.
Noto Sans Syriac, FreeSans's Syriac, Unifont's Arabic and Noto Sans
Arabic shape as HarfBuzz does at 3,000 runs a plan; no installed font
is refused any more (213 fonts, 1,822 plans).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
The Thai shaper, from HarfBuzz 10.2's source: SARA AM comes apart into
NIKHAHIT and SARA AA, the NIKHAHIT moving back over the above-base marks
(and counting as a mark when advances are zeroed). A font with no Thai
script of its own (only DFLT or latn in GSUB) gets its marks shifted to
its private-use glyphs, Windows' before the Mac's, as the stacking
around the base asks; the planner records, as HarfBuzz's does, whether
the font had the script under its own tag.
Noto Sans Thai and Lao, TLWG Loma, FreeSerif's Thai, DejaVu Sans's Lao
and Unifont shape as HarfBuzz does at 3,000 runs a plan, and Loma with
its thai script taken out (so the private-use path runs) at 5,000.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The USE shaper, from HarfBuzz 10.2's source, for Sinhala, Tibetan,
Javanese, Balinese, Mongolian and the rest of its eighty-odd scripts
(and Indic fonts with the new dev3-style tags). The syllable machine
reads past CGJs and ZWNJs that marks follow; rphf goes on each
syllable's first glyphs and records the repha it made, pref records its
pre-base glyph, with substitution marks cleared between; a repha moves
before the first post-base glyph and pre-base vowels move back. Scripts
that join like Arabic take Arabic's forms (Mongolian's free variation
selectors their base's), the others join syllable to syllable. Marks
lose their advances before GPOS.
text/syllabic.py carries HarfBuzz's compressed USE table over as it is,
compiles the USE grammar with the others (100,000 random runs against
Ragel's machine: no syllable differs), and checks at compile time that
the categories syllabic.h names are the machines' own.
Noto Sans Sinhala, Javanese, Balinese, Mongolian, Noto Serif Tibetan,
FreeSerif's Sinhala and Unifont's five shape as HarfBuzz does at 5,000
runs a plan; all installed fonts (1,748 plans) and 21 Noto fonts too.
|
| |
|
|
|
|
|
| |
HarfBuzz's is_default_ignorable takes U+180B..180E from the Mongolian
block, not the fourth free variation selector (U+180F, default
ignorable since Unicode 14), so it keeps its own glyph rather than the
invisible one. Unifont's Mongolian showed it.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Two more shapers on the syllabic groundwork, from HarfBuzz 10.2's
source. Khmer reorders before any lookup: a coeng and Ro go before the
base, masked for pref, what follows them for cfar, a left matra goes
first; split matras decompose with U+17C1. Myanmar finds the base after
a kinzi, gives each glyph its place around it and sorts by place, and
zeroes mark advances before GPOS rather than after.
Noto Sans Khmer and Noto Sans Myanmar shape as HarfBuzz does at 20,000
runs a plan, and so do Unifont's Khmer and Myanmar (no GSUB).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
| |
HarfBuzz reorders marks by a modified combining class; for U+0C55 and
U+0C56 (canonical classes 84 and 91) it is 4 and 5, so they sort before
the virama. Vega had 0, which rustybuzz 0.20 uses; HarfBuzz 10.2's
hb-unicode.hh says otherwise, and Unifont's Telugu showed it.
|
| |
|
|
|
|
|
|
|
|
| |
HarfBuzz sorts each stage's lookups by index with hb_qsort, its copy of
Isaac Turner's quicksort, and then merges entries of the same lookup:
masks and joiner flags combine, but the per-syllable and random flags are
the first entry's. Which entry comes first is the quicksort's doing, so
the planner now sorts the same way instead of stably. Noto Sans
Malayalam, whose psts and rlig share a lookup, needed it: ma with a
combining dot joined across syllables in HarfBuzz and not here.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
HarfBuzz does
The planner now picks who positions as HarfBuzz 10.2 does: GPOS, the old
kern table when GPOS has no kern feature, and marks placed by combining
class and ink boxes when there is no GPOS; the Hangul shaper composes
syllables the font has whole, takes apart those it lacks into jamo for
ljmo, vjmo and tjmo, and moves tone marks before their syllable.
The section grows to an 80-byte header (the kern table, and each glyph's
ink box when a plan places marks without GPOS) and 88-byte plans (the
kern mask, the jamo masks). Kern tables are applied pair subtable by
pair subtable with HarfBuzz's own binary search; state machines, class
subtables and cross-stream kerning, which no installed font has, are
refused. The check spells Hangul syllables every way text does.
Every installed font Vega accepts shapes as HarfBuzz does (209 fonts,
1,520 plans, a thousand runs each), and the fonts refused before at
20,000 runs a plan: Noto Sans CJK KR and Baekmuk for Hangul, IPA Gothic
and Noto Mono for marks without GPOS, FreeSans, FreeSerif, Liberation
and DejaVu Sans ExtraLight for kern tables, Unifont's Latin, Greek,
Cyrillic, Hebrew and Hangul.
|
| |
|
|
|
|
| |
HarfBuzz's Hebrew presentation forms join U+05F2 and patah into U+FB1F;
Vega had U+05D9 there. Only fonts without a GPOS mark feature take the
rule, so no font Vega accepted showed it; Unifont's Hebrew did.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Chromium's accessibility tree
Lists are listboxes that keep the keyboard focus, the focused row their
active descendant, each option with its place in the whole list though
only the visible rows are drawn; tables are grids with row indices;
tones other than normal and muted are said, not only coloured; keys are
named buttons. The page now updates in place instead of rebuilding each
list, so the focus a screen reader follows survives every redraw. The
browser test reads Chromium's accessibility tree: roles, names, focus,
selection and the active descendant moving within the same list.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
| |
Joining types, general categories and scripts (with their ISO 15924
codes) as two-stage tables, canonical decompositions one step at a time,
and Extended_Pictographic, from the UCD by text/unicode.py.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
| |
A Hangul or CJK glyph is one em across, less than two cells of a
monospace Latin font (1.2 em for DejaVu Sans Mono), and was drawn from
the left of its cells, so syllables stood apart unevenly. A cached
glyph now keeps its advance in pixels, and a wide character's glyph is
drawn centred in its two cells.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
examples/messenger.aup keeps the lines typed here and sends each to the
other node, and keeps the other's. The check runs Alice's and Bob's
nodes, each with a key of its own, sealing to the other's and taking
lines only from the other (pure-serve --key, --send, --seal, --sender),
each drawn by Vega in the node, with a relay between them: a line typed
on Alice's display reaches Bob's node and is drawn on his, Bob's answer
posted by a program is drawn on hers, each last frame is the one the
vega command draws from that node's store, and the relay saw no line's
text nor a field's name, only one sealed session each way naming the
sender's key.
|
| |
|
|
|
|
|
|
|
| |
Vega in a node takes a second form, pixels --grid WxH --out PREFIX: each
frame the node's saves draw goes into PREFIX-N.ppm, no display
controller needed (one card takes one master, so a second node on the
machine draws this way). And in a node, recorded events no longer end
the surface: their last frame is printed when they end, and the node's
saves are drawn on until it stops, so an answer that comes later shows.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Each size's symbols are drawn on the CPU into one 8-bit atlas, every pixel
the exact area its curves cover, and text is a quad per glyph reading it.
A 1080p page of 11,382 glyphs composes in 1.07 ms at 16 px (it took 525 ms
computing coverage per fragment), and the composed pixels are the CPU
raster's exactly (worst difference 0 for DejaVu's ASCII, 1 for Noto's
11,172 Hangul syllables).
Computing coverage on the GPU lost on both counts: a compute pass filling
the atlas took 5-13x longer than one Cortex-A76 core (35 against 2.7 ms at
16 px), and its faster sorting-network form computed whole rows wrongly
under this Mesa V3D. Coverage now has one implementation, in C, and the
shaders only compose. vega_symbol_raster takes a row stride to draw into
the atlas in place.
|