Using Python's own PRNG should make the code cleaner and allow for
reproducible stimulus files if that is desired via setting --seed (at
least for the same versions of the script, changing the kind and/or
order of the random calls will of course impact the output in the
future).
I did the following substitutions:
* rand.read(1)[0] % n and struct.unpack('@H', rand.read(2))[0] % n →
random.randrange(n)
* rand.read(1)[0] → random.randrange(256)
* rand.read(n) → [random.randrange(256) for _ in range(n)]
(better alternative would have been random.randbytes(n), but is only
available for Python >= 3.9, switching to this in the future will
impact output)
* list[rand.read(1) % len(list)] → random.choice(list)
We use pre-multiplied alpha color channels, but were having bad
rounding errors due to the alpha divider being truncated to an
integer.
The algorithm for pre-multiplying a color channel is:
alpha_divider = 0xffff / alpha
pre_mult_color = color / alpha_divider
In order to fix the rounding errors, we could turn ‘alpha_divider’
into a double.
That however would introduce a performance penalty since now we’d need
to do floating point math for each cell.
The algorithm can be trivially converted to:
pre_mult_color = color * alpha / 0xffff
Since both color and alpa values are < 65536, the multiplication is
“safe”; it will not overflow an uint32_t.
Closes#249
Dependency chains:
* pgolib -> terminal.c -> terminal.h -> wayland.h
* vtlib -> csi.c -> config.h -> wayland.h
wayland.h includes <primary-selection-unstable-v1.h>, which must be
generated by a custom_target() rule *before* any sources that require
it are built. Failure to fully specify these dependencies can otherwise
result in a race condition, where a dependent source file gets compiled
(and fails with a "header not found" error) before the header itself
has been generated.
Using Python's own PRNG should make the code cleaner and allow for
reproducible stimulus files if that is desired via setting --seed (at
least for the same versions of the script, changing the kind and/or
order of the random calls will of course impact the output in the
future).
I did the following substitutions:
* rand.read(1)[0] % n and struct.unpack('@H', rand.read(2))[0] % n →
random.randrange(n)
* rand.read(1)[0] → random.randrange(256)
* rand.read(n) → [random.randrange(256) for _ in range(n)]
(better alternative would have been random.randbytes(n), but is only
available for Python >= 3.9, switching to this in the future will
impact output)
* list[rand.read(1) % len(list)] → random.choice(list)
We use pre-multiplied alpha color channels, but were having bad
rounding errors due to the alpha divider being truncated to an
integer.
The algorithm for pre-multiplying a color channel is:
alpha_divider = 0xffff / alpha
pre_mult_color = color / alpha_divider
In order to fix the rounding errors, we could turn ‘alpha_divider’
into a double.
That however would introduce a performance penalty since now we’d need
to do floating point math for each cell.
The algorithm can be trivially converted to:
pre_mult_color = color * alpha / 0xffff
Since both color and alpa values are < 65536, the multiplication is
“safe”; it will not overflow an uint32_t.
Closes#249
Dependency chains:
* pgolib -> terminal.c -> terminal.h -> wayland.h
* vtlib -> csi.c -> config.h -> wayland.h
wayland.h includes <primary-selection-unstable-v1.h>, which must be
generated by a custom_target() rule *before* any sources that require
it are built. Failure to fully specify these dependencies can otherwise
result in a race condition, where a dependent source file gets compiled
(and fails with a "header not found" error) before the header itself
has been generated.
This extends the new ‘dpi-aware’ option with a new default value,
‘auto’.
When set to ‘auto’, fonts are sized using monitors’ DPI when output
scaling is disabled. When output scaling is enabled, fonts are instead
sized using the scaling factor.
The reasoning here is that a user that has enabled output scaling is
obviously *not* relying on DPI scaling.
Output scaling can also be a way to compensate for different viewing
distances, in which case we do *not* want to break that by using DPI
scaling.
Users can still force DPI-only font sizing by setting ‘dpi-aware=yes’,
or disable it completely by setting ‘dpi-aware=no’.
Take ‘\E(#0’ for example - this is *not* the same as ‘\E(0’.
Up until now, foot has however treated them as the same escape,
because the handler for ‘\E(0’ didn’t verify there weren’t any _other_
private characters present.
Fix this by turning the ‘private’ array into a single 4-byte
integer. This allows us to match *all* privates with a single
comparison.
Private characters are added to the LSB first, and MSB last. This
means we can check for single privates in pretty much the same way as
before:
switch (term->vt.private) {
case ‘?’:
...
break;
}
Checking for two (or more) is much uglier, but foot only supports
a *single* escape with two privates, and no escapes with three or
more:
switch (term->vt.private) {
case 0x243f: /* ‘?$’ */
...
break;
}
The ‘clear’ action remains simple (and fast), with a single write
operation.
Collecting privates is potentially _slightly_ more complex than
before; we now need mask and compare, instead of simply comparing,
when checking how many privates we already have.
We _could_ add a counter, which would make collecting privates easier,
but this would add an additional write to the ‘clean’ action which is
really bad since it’s in the hot path.