This was giving wonky results with images that do not fill the entire
card - and it's also unnecessary, since the Buggie image we have been
using, and the two I will be adding, are all small enough to not need
scaling anyway. :^)
`CardPainter::set_background_image_path()` immediately repaints the card
back and inverted card back bitmaps if they exist, so users just need
to `update()` that part of the screen. This is handled automatically by
`CardGame`, but other users will have to do this manually.
Instead of each card being responsible for painting its own bitmaps, we
now have a CardPainter which is responsible for this. It paints a given
card the first time it is requested, and then re-uses that bitmap when
requested in the future. This saves memory for duplicate cards (such as
in Spider where several sets of the same suit are used) or unused ones
(for example, the inverted cards which are only used by Hearts). It
also means we don't throw away bitmaps and then re-create identical
ones when starting a new game.
We get some nice memory savings from this:
| | Before | After | Before (Virtual) | After (Virtual) |
|:----------|---------:|---------:|-----------------:|----------------:|
| Hearts | 12.2 MiB | 9.3 MiB | 25.1 MiB | 22.2 MiB |
| Spider | 12.1 MiB | 10.1 MiB | 29.2 MiB | 22.9 MiB |
| Solitaire | 16.4 MiB | 9.0 MiB | 25.0 MiB | 21.9 MiB |
All these measurements taken from x86_64 build, from a fresh launch of
each game after the animation has finished, but without making any
moves. The Hearts value will go up once inverted cards start being
requested.
Because `card->value() == 11` is a lot less clear than `card->rank() ==
Cards::Rank::Queen`, and also safer.
Put this, along with the `Suit` enum, in the `Cards` namespace directly
instead of inside `Cards::Card`. Slightly less typing that way.
For now, the only feature of this is that it sets the background colour
from the `Games::Cards::BackgroundColor` config value. Later, other
card game configuration and shared behaviour can go here, to save
duplicating it in each game.
This currently has exactly one setting: The background colour for card
games. My thinking is, it's better to not have a Settings application
for each individual game we include in the system, since most will only
have a small number of settings, all Settings windows have tabs anyway,
and I don't want to flood the Settings app list unnecessarily.
As for having a single setting for all the card games: it's nice when
things match. :^)
Use Breadcrumbbars on_segment_change instead of on_segment_click.
This allows us to remove the manual handler invokation in the
open_child_directory_action
Instead of manually updating emoji.txt whenever new emoji are added,
we use Unicode's emoji-test.txt to generate emoji.txt on each build,
including only the emojis that Serenity supports at that time.
By using emoji-test.txt, we can also include all forms of each emoji
(fully-qualified, minimally-qualified, and unqualified) which can be
helpful when double-checking how certain forms are handled.
The Undo/Redo actions now tell you what kind of action will be
undone/redone. This is achieved by adding an "action text" field to the
ImageUndoCommand and having everyone who calls did_complete_action()
provide this text.
Instead of temporary changing the open file description's "blocking"
flag while doing a non-waiting recvfrom, we instead plumb the currently
wanted blocking behavior all the way through to the underlying socket.
This ensures that all the permissions checks are made against the
provided credentials. Previously we were just calling through directly
to the inode setters, which did no security checks!
Instead of getting credentials from Process::current(), we now require
that they be provided as input to the various VFS functions.
This ensures that an atomic set of credentials is used throughout an
entire VFS operation.
The non-AA outline ellipse was drawn outside the bounding rectangle
unlike all other ellipses. This commit now scales it to match the
size of the other ellipse drawing modes (AA, filled, etc).
This ensures that both mutable and immutable access to the protected
data of a process is serialized.
Note that there may still be multiple TOCTOU issues around this, as we
have a bunch of convenience accessors that make it easy to introduce
them. We'll need to audit those as well.
By protecting all the RefPtr<Custody> objects that may be accessed from
multiple threads at the same time (with spinlocks), we remove the need
for using LockRefPtr<Custody> (which is basically a RefPtr with a
built-in spinlock.)
Instead, allocate when acquiring the lock on m_fds struct, which is
safer to do in terms of safely mutating the m_fds struct, because we
don't use the big process lock in this syscall.
Required by Discord, which polyfills it by taking the existing native
object, polyfilling missing functions and setting window.performance to
it.
This is a hard requirement as this is done in strict mode with no
try/catch and thus causes their JavaScript to stop progressing.
We already did this but it called the @@iterator method of
%Array.prototype% visible to the user for example by overriding that
method. This should not be visible so we use a special version of
SuperCall now.
Although this already works in most cases in non-kvm serenity cases the
cosh and other math function tend to return incorrect values for
Infinity. This makes sure that whatever the underlying cosh function
returns Math.cosh conforms to the spec.
This allows us to treat unqualified, minimally-qualified, and
fully-qualified emojis the same as long as emoji filenames are in their
least qualified form (with respect to emoji presentation).
For example, the transgender flag emoji has 4 possible forms:
1F3F3 FE0F 200D 26A7 FE0F ; fully-qualified # 🏳️⚧️
1F3F3 200D 26A7 FE0F ; unqualified # 🏳⚧️
1F3F3 FE0F 200D 26A7 ; unqualified # 🏳️⚧
1F3F3 200D 26A7 ; unqualified # 🏳⚧
In order to treat them all as the same, we now drop all forms down
to 1F3F3 200D 26A7 (skipping any FE0F codepoints) and then do the
lookup for that form.