1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-22 01:34:21 +00:00
Commit graph

1100 commits

Author SHA1 Message Date
Tom Poole
46c2a95905 JUCE version 8.0.1 2024-07-29 12:47:03 +01:00
reuk
12ef0a0200 HarfBuzz: Enable atexit to silence some CRT debug memory leak warnings
Before this change, after running a JUCE app on Windows under a
debugger, and quitting it normally (e.g. pressing the close title
button), the output log would display some memory leak diagnostics. This
is because HarfBuzz expects to clean up statics using atexit, but atexit
was not enabled. This change enables atexit on supported platforms,
including Windows.
2024-07-29 12:46:38 +01:00
Tom Poole
fc0fd3042f Bump version number to 8.0.1 2024-07-29 12:43:19 +01:00
attila
04d9d36b15 TextLayout: Fix ignored AttributedText::getLineSpacing() parameter 2024-07-22 13:16:06 +02:00
attila
5de96da34d Graphics: Suppress warnings emitted by harfbuzz 2024-07-18 19:15:18 +02:00
Oliver James
57d33150d3 Unicode: Fix incorrect character ordering in Latin text
This addresses issues that could occur when re-ordering text that
contained brackets or numerical separators.
2024-07-18 19:15:17 +02:00
reuk
b35688d9a4
SimpleShapedText: Avoid wrapping when WordWrap::none is requested 2024-07-11 18:00:07 +01:00
reuk
8642cfe6b3
Direct2D: Remove rectangular clip assertion
This assertion was intended to emulate a performance warning that could
be emitted by the D2D debug layer, but it often gets in the way during
development. To check for this performance issue, users can change
D2D1_DEBUG_LEVEL_NONE to D2D1_DEBUG_LEVEL_INFORMATION in
juce_DirectX_windows.h
2024-07-09 12:47:30 +01:00
reuk
4c1a93e8d8 FreeTypeTpeface: Avoid recreating FTTypefaceList at shutdown
Calling getInstance may recreate the list singleton if it has already
been destroyed. This should only happen if a Typeface instance is being
destroyed after the app/plugin has been shutdown, e.g. if the typeface
has static storage duration.
2024-07-08 13:16:57 +01:00
reuk
a4022df686
Direct2D: Fix issue where contexts would not clear properly after pushing multiple clip layers
This issue could be seen when calling setBufferedToImage on a component
with a transparent background with a size different to the component's
size.

The details are unclear to me, but it seems like both calling Clear on
the device context, and using the COPY blend mode, ignore alpha values
and instead use a constant alpha of 1.0 when there is a geometric
clipping layer active.

As a workaround for this issue, when clearing a rectangle we now pop all
active layers, fill their intersection using the COPY blend mode while
there are no layers active, and then reinstate the layers.

The new implementation is likely to be very slow, however I think this
code path is unlikely to be used frequently in practice. The main
use-case for rendering clear transparent areas is the rendering of
buffered component images, but such cases normally use axis-aligned
clipping regions, which should be able to use the faster path.
2024-07-04 13:03:56 +01:00
reuk
f3dfd0d9be
Direct2D: Update formatting in clipToImageAlpha 2024-07-04 13:03:35 +01:00
reuk
6402641d49
Direct2D: Avoid applying pending clip list in excludeClipRectangle unless the transform is non-trivial
Frequently, excludeClipRectangle will be called several times in a row,
in order to trim away borders on each side of a rectangle. When this
happens, we want to avoid creating geometric clip layers which exclude
only two or three of the borders, and instead wait until all borders
have been excluded before applying the clip list. This way, it may be
possible to simplify the clip list to a single rectangle, which can be
implemented using the faster axis-aligned clipping layer.
2024-07-04 13:03:35 +01:00
reuk
b0bd58c5e6
Direct2D: Refactor layer storage to keep strong references to geometries and opacity brushes
Also switches to the slightly newer layer parameters type.
2024-07-04 13:03:35 +01:00
reuk
e67e78803c
Direct2D: Tidy up implementation of createBitmap and remove lineStride parameter
The lineStride parameter is only required to be set when the 'data'
pointer is also set.
2024-07-04 13:03:34 +01:00
attila
18fa0bfa15 Upgrade to harfbuzz 9.0.0 2024-07-04 13:05:26 +02:00
attila
5b30f2571e Suppress warnings emitted by harfbuzz 9.0.0 2024-07-04 13:05:26 +02:00
reuk
9dda9d65a7
RenderingHelpers: Allow software renderer to replace content of filled rects 2024-06-27 18:10:22 +01:00
reuk
592e2795b8
Direct2D: Fix regression that caused closed paths to remain open 2024-06-27 18:10:22 +01:00
reuk
cc52e9322d
LowLevelGraphicsPostScriptRenderer: Remove support 2024-06-27 18:10:22 +01:00
reuk
9112911122
MinGW: Remove support 2024-06-27 18:10:21 +01:00
attila
3c4aa8d0ce TextLayout: Preserve leading whitespaces
This fixes the CodeEditorComponent regression present since
03e79f8f12.
2024-06-27 15:31:57 +00:00
attila
ef8417023e Represent tab characters with non-breaking space during shaping
This avoids assertions raised when shaping text containing tabs.
2024-06-27 15:31:57 +00:00
reuk
7bb71cc1ba Direct2D: Make path-rendering behaviour consistent with CoreGraphics and the software renderer
The other renderers implicitly start a new supath at the last path
location when a line or bezier segment is added without explicitly
starting a new subpath.
2024-06-26 14:33:26 +01:00
reuk
815da2ec6d Direct2D: Tidy up clearWindowRedirectionBitmap 2024-06-26 14:33:26 +01:00
reuk
fe1a11908e Direct2D: Fix data race when creating Direct2DPixelData instances on a background thread 2024-06-26 14:33:25 +01:00
Matt Gonzalez
0789048777 Direct2D: Set transform for tiled image brush 2024-06-26 14:33:25 +01:00
reuk
9ae52f3d7a Direct2D: Update backbuffer implementation
Problem description
===================

Firstly, the linked-list of pending presentations acted as a stack
(FILO).  If the swap chain thread and main thread processed frames at
varying rates, then the following sequence of events was possible:

Main thread           Swap chain thread       Queue state
---------------------------------------------------------
Push frame (1)                                [1]
Push frame (2)                                [2, 1]
                      Pop frame (2)           [1]
Push frame (3)                                [3, 1]
                      Pop frame (3)           [1]
                      Pop frame (1)           [] <--  Out of sequence!

Secondly, the swap chain's sequential flip model can only maintain a
valid back-buffer state as long as the list of dirty rects is correct,
and every pixel within the dirty rects is painted incrementally.

In the example above, if the main thread were to produce two frames
before the swap chain thread could present any frame, then presenting
*only* the frame 2 (skipping frame 1) may produce incorrect results when
combined with the existing back buffer. This is because regions updated
in frame 1 may not be updated in frame 2, so regions *only* updated in
frame 1 will be omitted from the back buffer.

Mitigation
==========

This patch removes the old stack of presentations and replaces it with a
slightly more complex mechanism that tracks two different Presentation
objects. At any time, up to one Presentation may be in use by the swap
chain thread (i.e. actively presenting), up to one Presentation may be
accumulating updated/dirty regions (i.e. painting), and up to one region
may be ready, awaiting display.

This scheme resolves the first issue described above by ensuring that
old frame data is not kept around. There is never more than one frame
awaiting display, which means that if the swap chain thread attempts to
display twice in a row (before the main thread produces a new frame),
the second attempt will be a no-op.

The second issue is resolved by accumulating changes into a single
Presentation whenever the main thread produces two or more frames in a
row. If there is already a 'ready' Presentation when the main thread
finishes painting, then all updated regions from the newest Presentation
will be added to the 'ready' Presentation, rather than replacing it.
When the swap chain thread is ready to present, it will therefore see
the result of all the accumulated Presentations produced by the main
thread, instead of just the newest Presentation.
2024-06-26 14:33:25 +01:00
attila
adbb0850ed Fix compilation error with C++20 2024-06-24 15:07:16 +00:00
reuk
2301f398aa
Fonts: Replace heavyweight leak detector in FTFaceWrapper 2024-06-20 17:52:22 +01:00
attila
4828bd886d Fix assertion during Font fallback
Since 4122427748 assertions are guarding
the FontOptions::withName, withStyle and withTypeface member functions.

Since then the only way to replace an existing typeface without hitting
these assertions is to clear all three fields before calling
withTypeface, which then sets all three values. It is always legal to
just clear an existing Typeface and rely on the name and style fields.
2024-06-20 08:45:17 +00:00
reuk
308619fb5f
TextLayout: Fix unused variable warning 2024-06-19 15:06:23 +01:00
attila
453e57bade Add erase() and drop() to Ranges and RangedValues 2024-06-18 15:29:42 +02:00
reuk
203934d949 HarfBuzz: Enable atexit to silence some CRT debug memory leak warnings
Before this change, after running a JUCE app on Windows under a
debugger, and quitting it normally (e.g. pressing the close title
button), the output log would display some memory leak diagnostics. This
is because HarfBuzz expects to clean up statics using atexit, but atexit
was not enabled. This change enables atexit on supported platforms,
including Windows.
2024-06-12 11:24:16 +01:00
Tom Poole
05b036272a Fix some Doxygen docstrings 2024-06-12 09:35:32 +01:00
reuk
8acd81e587
Direct2D: Allow drawing rects with very small widths/heights 2024-06-11 11:34:05 +01:00
reuk
2a264390e8
Direct2D: Update assertion to check for alignment against screen rather than current transform
This assertion is intended to mirror the behaviour of an
informational/performance diagnostic message raised by the D2D debugging
layer.

It seems the D2D diagnostic is raised when the proposed clip region is
aligned to the screen, not to the current transform.

Before this change, the assertion could incorrectly fire when clipping
to transformed rectangles. This could be seen when clicking the
star-shaped buttons in the ComponentTransformsDemo.

With this change in place, the assertion will still fire when e.g.
calling Graphics::reduceClipRegion on a screen-aligned rectangular path,
but will not fire when this path is skewed/rotated etc.
2024-06-11 11:34:04 +01:00
reuk
4122427748
FontOptions: Add some assertions to warn about misuse 2024-06-11 11:34:04 +01:00
reuk
d69dee0f5b
Font: Return correct result from getStringWidth after setting size in points
Previously, code such as the following would return a smaller string
width for larger tracking values:

    juce::Font f { juce::FontOptions{}.withPointHeight (16.0f) };
    const auto g = f.withExtraKerningFactor (1.0f);

    const auto a = f.getStringWidth ("foobar");
    const auto b = g.getStringWidth ("foobar");

With this change applied, the width 'b' is greater than the width 'a',
as expected.
2024-06-11 11:34:04 +01:00
attila
17611f74ca Minor code cleanup 2024-06-10 17:51:26 +02:00
attila
c2b461026b Fix shaping for text that uses a single CR for line breaking 2024-06-10 17:51:26 +02:00
reuk
659de5842f
Direct2D: Fix flickery resizing when using an internal resizer
Resizing using window manager functionality (e.g. clicking and dragging
in the non-client area) will send WM_SIZING to the window, which in turn
will enable continuous repainting in the D2D renderer until the resize
operation ends.

Continuous repainting is required in order for the window to display
correctly during the resize. Without continuous repainting, some frames
may not be completely painted, and may display with black areas,
producing a flickery effect.

When a resize is controlled entirely by the client, e.g. using the
corner resizer in the AudioPluginDemo standalone, WM_SIZING is never
posted. Instead, we assume that if the window has captured the cursor
during a setBounds call then it is probably resizing. We enable
continuous repainting in this case, and stop repainting once the window
releases the mouse.

An alternative appropach would be to add some kind of start/stop resize
API to ComponentPeer. I'm currently reluctant to do that because the
ComponentPeer API is already so large.
2024-05-31 11:43:30 +01:00
reuk
66a29f9762
GlyphArrangement: Avoid divide-by-zero in addFittedText 2024-05-31 11:43:29 +01:00
Matt Gonzalez
00c958ff3e
DirectWrite: Rework custom font collection loader
Removes redundant memory copies and sorts out issues with ownership of the font data
2024-05-31 11:43:29 +01:00
attila
51955453ef Remove TextLayout::createNativeLayout() 2024-05-30 12:21:35 +01:00
Oliver James
38f299a054 TextLayout: Respect the ReadingDirection parameter of AttributedString 2024-05-30 12:21:35 +01:00
Oliver James
03e79f8f12 TextLayout: Use new shaping engine
By utilising ShapedText in the TextLayout implementation.
2024-05-29 15:11:57 +02:00
attila
30daa356ca ShapedText::Detail: Add getSimpleShapedText() 2024-05-29 15:11:57 +02:00
attila
d794fac44c SimpleShapedText: Fix line break behaviour with text trailing whitespaces
This fixes an issue with the text wrapping logic for text chunks ending
in a whitespace.

When trying to fit a text chunk, the logic works with two values: width
with trailing whitespace, and width without trailing whitespace.

When the trailingWhitespacesShouldFit option is false, the logic
checks if "withoutTrailingWhitespace" can still fit inside the remaining
width.

Prior to this fix, it then decremented the remaining width with
"withoutTrailingWhitespace", but it should have used
"withTrailingWhitespace" for the decrement operation, always, regardless
of the value of the withTrailingWhitespacesShouldFit option.

This mistake only caused an observable issue when multiple fonts were
used for the shaping operation, and a different font would be used
immediately after a whitespace falling at the end of a line.
2024-05-29 15:11:57 +02:00
attila
aee65c147e JustifiedText: Fix line spacing for multi-font text
Prior to this change, the spacing between line N and line N + 1 would be
lineHeight (N).

This resulted in incorrect spacing when using multiple fonts in a text.

This commit uses the correct spacing, which is
maxDescent (N) + maxAscent (N + 1). This is also the same rule that was
used by TextLayout prior to JUCE 8, and the rule that CoreText's
AttributedString features are using as a general rule.

Note: lineHeight (N) = maxAscent (N) + maxDescent (N).
2024-05-29 15:11:57 +02:00
Matt Gonzalez
99adac2871
Direct2D: Skip invalid path elements when converting a Path to a Geometry 2024-05-28 16:08:55 +01:00