CGImages created from a juce Image may be drawn after or during
changes to the underlying data. This change copies the required
data into a new buffer to ensure the CGImage data is always
independent from the juce image data.
When clicking in a TextEditor to position the caret, the caret would be
placed at the penultimate position when clicking at the end of a line
with trailing non-newline whitespaces.
Co-authored-by: Aga Janowicz <aga@roli.com>
Newlines get removed in the sanitised string, so we need to take extra
steps to keep track of their positions.
Co-authored-by: Aga Janowicz <aga@roli.com>
On Ubuntu 25.10, which includes Noto Color Emoji, I was seeing that the
FontsDemo would assert when attempting to render non-emoji text using
this font. It appears that FontConfig will tend to return Noto Color
Emoji when this family name is passed, even though the font may not
cover the required character set.
The new strategy is to use FontConfig as before, but then to check the
resolved font for coverage of the string. If the resolved font still
can't render the string, we relax the font matching constraints by
removing the family name from the pattern, then try matching again.
Harfbuzz doesn't support these font formats, so attempting to shape text
using these kinds of fonts will fail.
I noticed this on Ubuntu 25.10 for Arm, which seems to include pfb and
otf versions of some fonts. The FontsDemo would assert in cases where
the pfb font was selected instead of the otf font.
The default error handler could cause crashes, so we now set up a custom
error handler both when reading and writing PNGs.
The HeapBlock and BitmapData automatic variables have moved, so that
their destructors will still run as expected in the failure case. Note
that it's UB to call longjmp to unwind the stack to the previous setjmp,
if said unwinding would normally cause non-trivial destructors to run.
This partly reverts commit ad28684b10.
Prior to that change, getBrush() would always end up calling
SetTransform on gradient/image brushes. This is important because, when
drawing text, we combine the current brush transform with the text
transform. If we don't reset the brush transform each time, these
transforms end up accumulating across frames.
The code contains a performance optimisation for cases where the world
transform is translation only. In this case instead of applying the
brush transformation first and then the world translation, the order is
reversed. The translation is applied first and then the brush
transformation.
Flipping the transformations however is only correct in the special case
when both transformations are translation only.
This change is practically a no-op, because if the affected branch is
taken, then the world transform was not applied, so transform is a
unity matrix. But if transform was non-unity, then the wrong ordering
would cause an observable error.
Logically the brush transformation is nested inside the world
transformation so the right order is applying the brush transform first
followed by the world transform.
Reverts ca3abbb96d.
Prior to this fix gradually changing the Component scale would lead to
the jittery movement of drawn bitmaps, as their position would be
snapped to an arbitrary integral representation.