This intends to provide a configurable rectangular "drop shadow". The
API is modeled after CSS/HTML5 Canvas where the element can be "bound"
to an existing rectangular shape (geometry and radius), the offset can
be used to place the shadow and color and blur configure the shadow.
The shadow's color fades into transparent.
TODO (in subsequent changes):
* Documentation
* Qt implementation
This allows creating multiple windows for example, and it will allow for
showing windows in those tests that require a mapped window.
As a bonus, the run() function on generated components is not consuming
anymore.
Reduce the dependency of the GLRenderer to a new trait that exposes the
EventLoopTarget and EventLoopProxy. Those are provided by either an
winit::event_loop::EventLoop or, once the loop is started using the
self-consuming run(), by the event loop target provided to the run_fn.
This way renderers can be created from either within run or before.
The initial event loop instance is kept in TLS. When starting the loop,
it's taken out and instead the event loop target is placed into a scoped
tls variable.
During rendering the GLRenderer's Option<WindowedContext<NotCurrent>>
is None. That however leads to any font_metrics() calls such as due to
implicit sizing to panic, because the call requires access to the
window's scale factor.
This is fixed by keeping a shared reference to the PossiblyCurrent
WindowedContext also in the GLRenderer.
The GL backend uses the item graphics cache for the image size function,
which uses a PropertyTracker. That tracker must have the Image's source
included in its dependencies, to avoid that when loading a HTML image
for example, the cache isn't invalidated when the source is changed
before the HTML image was loaded async. That's why the get() call on the
source property must happen from within the PropertyTracker's callback.
For all other items the default is the empty size.
This also required three fixes for the HTML image loading:
* The upload_pending property value was inverted, it needs to start
out as true (pending yes) and be set to false when it finished
loading (not pending anymore)
* Mark the upload_pending property as dirty before scheduling the
redraw, in case it's sync
* Pass the item rendering cache to the image_size function to ensure
that the Rc<CachedImage> is not only weak inside the image_cache
of the GLRendererData but also strong on the item.
Femtovg only accepts certain image sources. A comment in the source
suggests that a conversion could be done but that it's an expensive
operation the user should decide if it's okay or not. For us it's
okay, so let's do it.
Similarly, avoid the potential ImageSource::try_from failure when
querying just for the size, as GenericImage view has the dimensions we
need.
Allow images to be just decoded and uploaded to the GPU in a separate
step. This is in preparation to implicit size support, where the actual
dimension of the image can be determined by decoding it immediately when
needed and uploaded to the GPU later (when we can be sure to have a
current GL context).
For images loaded through HTMLImageElement this is trickier, in the
sense that - unlike when loading off disk - it is inherently async.
Therefore we use a Property<bool> that we toggle when loading is
complete, in order to mark any dependent bindings as dirty, after
reporting an initial (1, 1) size.
Move data structures shared between the GLRenderer and the
GLItemRenderer into a *ka-ching* shared data structure. This reduces the
amount of separate Rc instances.
Also moving the image loading functions from GLItemRenderer to
GLRendererData will allow for re-use from the GLRenderer in the future.
Our demos use some symbols such as the back arrow and the ugly style
uses a down arrow for the combo box. These symbols are not in Roboto and
also not in the default font font_kit gives us on macOS.
Therefore for WASM we switch over to DejaVu, which is bigger than
Roboto.
For macOS this patch implements rudimentary fallback list generation
using CTFontCopyDefaultCascadeListForLanguages. This needs further work
to respect the locale and correctly translate styles - eventually this
should go into font-kit.
A general aspect with the font fallback handling is that femtovg doesn't
support on-demand loading yet. Instead it uses owned_ttf_parser, so
every font will be read entirely off disk. That's why for macOS we trim
the list. We could perhaps do the analysis ourselves.
Linux and Windows are to follow.
Separate GLFont from GLFontMetrics, the latter being as light as keeping
primarily the request around (and canvas), the former holding the list
of font resolution.
* Fix passing the correct source clip rect (width and height were missing)
* Adjust to nanovg's image rendering model where the image is basically
a patter underneath the path rendered. So for a sub-image
we need to offset the image pattern and scale the pattern and the path.
Constrain the border width by the rectangle to avoid that the border
would cancel itself out when too big.
This fixes most of the checkbox rendering in the slide puzzle.
Represent a non-specified pixel size and font weight through a None option.
This is cleaner and has the added benefit that the backend can now
easily decide what the default size/weight should be.
For the GL backend a resolved font is just a handle (femtovg::FontId)
and we can cache that. Consequently we don't really need Rc<dyn Font>
but can let `fn font(...)` on the backend return a "resolved" font that
includes the pixel size, which in turn simplifies the Font trait
signatures.
The only caveat is that because on the item level we don't know what the
chosen backend type is, we can only receive a `dyn Font`, which means
it's wrapped - for now - in a Box.
Use a save/restore state pattern for the entire renderer instead of passing around clip rectangles as data structure.
That's less data copying and maps naturally to existing mechanisms,
which in turn can use their own dirty handling to make
save_state/restore_state as cheap as possible.
Re-apply the caching mechanism from the old renderer
that keeps weak references and drains them after frame rendering.
This fixes switching between the themes in the slide puzzle.
Create the font request on the text item side to reduce duplication and
remove the fallback logic from the font_weight accessor, in preparation
for automatic generation of that getter.