Commit graph

13117 commits

Author SHA1 Message Date
Luca Bacci
0a547172dd Merge branch 'win32-thread-data' into 'master'
DWrite font backend thread-safety

Closes #886, #952, and #953

See merge request cairo/cairo!650
2026-05-07 19:20:37 +00:00
Uli Schlachter
ab5b9ba709 Merge branch 'cff-subset' into 'master'
[cff-subset] Add some missing range checks.

See merge request cairo/cairo!663
2026-05-07 15:47:47 +00:00
Uli Schlachter
e823f2071e Merge branch 'patch-2' into 'master'
Check surface for error in dwrite color-font code

See merge request cairo/cairo!662
2026-05-07 15:46:14 +00:00
Jonathan Kew
055e92a867 [cff-subset] Add some missing range checks. 2026-05-06 13:42:03 +01:00
Jonathan Kew
4af2d15cd5 Check surface for error in dwrite color-font code 2026-05-03 17:00:55 +00:00
Uli Schlachter
662b072733 Merge branch 'enhancements' into 'master'
Fixes for the new release

Closes #929 and #921

See merge request cairo/cairo!661
2026-05-01 12:01:14 +00:00
Luca Bacci
d97438f1be Drop unneeded assert
We can't ensure that no error happened whatsoever.

Fixes #929
2026-05-01 11:29:38 +02:00
Luca Bacci
01e522b200 Fix build with CAIRO_NO_MUTEX
The LibreOffice project builds Cairo with -DCAIRO_NO_MUTEX.
IMHO that's quite risky for big projects where you don't
control all the code that uses Cairo, but I assume they know
what they're doing.

This change should have been part of commit 87f7c60bf7, but
admittetly CAIRO_NO_MUTEX builds are not actively tested.

Fixes #921
2026-05-01 11:29:38 +02:00
Luca Bacci
8a8262e9cd cairo-script: Fix build on 64bit Windows with LZO enabled
lzo_uint is a typedef for a machine-sized unsigned integral.

We track sizes using unsigned long, which is machine-sized
on most (all?) Unices, but 32bit on 64bit Windows.

This means that lzo_uint and unsigned long are not really
interchangeable (should have used size_t!). Fix the build
by using intermediate variables. The cairo-script file format
ensures that uncompressed data fits within 4GB.

Fixes -Wincompatible-pointer-types errors.
2026-05-01 11:29:29 +02:00
Luca Bacci
339b1580ea Meson: Fix compilation with CLangCL
Support for __uint128_t in CLangCL is currently broken [1].
Avoid using that type for now.

As of today MSVC doesn't support 128-bit integral types;
with this change we get feature-parity between MSVC and
CLangCL, so this shouldn't be a problem.

References:

 * Clang-cl generates a call to an undefined symbol __udivti3
   https://github.com/llvm/llvm-project/issues/25679
2026-05-01 10:21:43 +02:00
Uli Schlachter
c85d74aa5a Merge branch 'fdselect-range' into 'master'
Range-check FDSelect value

See merge request cairo/cairo!660
2026-04-24 14:21:53 +00:00
Uli Schlachter
d0323d9773 Merge branch 'reinstate-font-map-for-placeholders' into 'master'
_cairo_scaled_font_keys_equal: Also check implementation font-face

Closes #876

See merge request cairo/cairo!659
2026-04-24 14:20:15 +00:00
Jonathan Kew
d80b44afa4 Range-check FDSelect value during CFF subsetting. 2026-04-19 13:01:56 +01:00
Uli Schlachter
4ca0d581cb Merge branch 'master' into 'master'
[cff-subset] check subrs offset is within font data

See merge request cairo/cairo!657
2026-04-18 13:17:19 +00:00
Jonathan Kew
86365d847b [cff-subset] check subrs offset is within font data 2026-04-18 13:17:19 +00:00
Jonathan Kew
7dc050967f Merge branch cairo:master into master 2026-04-18 09:09:58 +00:00
Uli Schlachter
9df734c87a Merge branch 'add-polygon-oom' into 'master'
Ensure converter's jmp_buf is set up before adding edges.

See merge request cairo/cairo!658
2026-04-18 08:27:16 +00:00
Luca Bacci
46d1e26cdb _cairo_scaled_font_keys_equal: Also check implementation font-face
"Placeholder" scaled fonts created temporarily by cairo-user-font.c never
get to have an original_font_face (that is, it's always NULL). This breaks
the font-map mapping. Also check the implementation font-face.

Fixes #876
2026-04-17 11:47:29 +02:00
Luca Bacci
d7b57cb8d1 D2DFactory: return raw pointers
See previous commit for details
2026-04-15 16:45:11 +02:00
Luca Bacci
ebbc6b1479 DWriteFactory: return raw pointers
Lifetimes are tied to the DLL so callers cannot extend it anyway

This also helps with performance a tiny bit by removing unneeded
atomic increments / decrements which can churn CPU caches in multi-
threaded scenarios.
2026-04-15 16:45:11 +02:00
Luca Bacci
df558f592b WICFactory: Make thread-safe
This fixes two issues:

1. A global IWICImagingFactory interface pointer was used directly from
   any apartment without marshaling. This goes against the rules of COM,
   and for all we know could lead to threading issues (perhaps it's not
   a problem in practice, but can't tell).
2. The COM apartment where the IWICImagingFactory is created could be
   finalized by the user. We take a reference on the STA but the thread
   could terminate. If the thread is on the MTA we don't take a reference
   at all. In such case the interface pointer would not be valid anymore
   (per the COM rules), but most importantly the WIC DLL is unloaded
   (this actually happens).

To avoid that we create a IWICImagingFactory transiently each time we
need it.

We could cache the interface pointer using something like IInitializeSpy
or the COM static store [1]. However performance is still great and we'll
likely drop use of WIC soon (see MR !607).

References:

 1. The COM static store, part 1: Introduction
    https://devblogs.microsoft.com/oldnewthing/20210208-00/?p=104812
2026-04-15 16:44:44 +02:00
Jonathan Kew
86ae4233bf Ensure converter's jmp_buf is set up before adding edges.
It's possible for a pool allocation to fail under glitter_scan_converter_add_edge,
in which case longjmp will be called to bail out, but the converter's jmp_buf
hasn't been appropriately initialized to catch the error.
2026-04-15 14:24:09 +01:00
Jonathan Kew
899e6a89f7 [cff-subset] check subrs offset is within font data 2026-04-12 14:10:25 +00:00
Luca Bacci
efd0cad9ae D2DFactory: Make thread-safe 2026-04-10 18:57:41 +02:00
Luca Bacci
61dc0938bf DWriteFactory: Release resources on library unload
We can release all cached DWrite objects
2026-04-10 18:57:41 +02:00
Luca Bacci
6bb69c6488 DWriteFactory: Make thread-safe
Use global variables but protect initialization via cairo_init_once
functions.
2026-04-10 18:57:41 +02:00
Luca Bacci
098ebb9c4e D2DFactory: Remove unused method and member object
This is likely an innocent copy-paste error, you can't get a DWrite
factory from a D2D1 factory.
2026-04-10 18:57:41 +02:00
Luca Bacci
42d5c42297 DWriteFactory: Remove unused method and member object
Remove code that has never been used
2026-04-10 18:57:40 +02:00
Luca Bacci
7fa1a901ea GDI: Rename _get_global_font_dc to _get_thread_font_dc
The HDC is thread-local since a long time, make this clear by
renaming the function.
2026-04-10 18:57:40 +02:00
Luca Bacci
1f5230dde0 GDI: Use thread data for font HDC
Use the newly-introduced thread data structure to store
the per-thread font HDC. As an added bonus, we can now
avoid leaking HDCs on module unlaods.
2026-04-10 18:57:40 +02:00
Luca Bacci
a9229136ea Win32: Add thread data structure
Add a data structure for thread-local storage. This will be useful
to keep per-thread D2D interface pointers (and more)
2026-04-10 18:57:32 +02:00
Luca Bacci
510a38b386 Atomics: Add _cairo_atomic_init_once_check
The new function check if the protected resource was initialized
or not. It's meant for cleanup on explicit module unload (dlclose
or FreeLibrary), where there can't be concurrent code using the
module anymore
2026-04-08 16:32:26 +02:00
Emmanuele Bassi
d3a35678a2 Merge branch 'recording-surface-finish-internal-helper' into 'master'
recording surface: Implement finish via reset

Closes #928

See merge request cairo/cairo!649
2026-03-03 13:59:07 +00:00
Luca Bacci
1adaf1e7c5 recording surface: Implement finish via reset
Rather than the other way round.

Fixes #928
2026-03-02 18:51:00 +01:00
Emmanuele Bassi
4fb80a9aef Merge branch 'test-fixes' into 'master'
Fix test runner on Windows and run tests in CI

Closes #887

See merge request cairo/cairo!609
2026-03-02 10:26:54 +00:00
Emmanuele Bassi
7cd2141f09 Merge branch 'dwrite' into 'master'
DWrite: Add support for COLRv1 fonts

Closes #903

See merge request cairo/cairo!625
2026-03-02 10:08:30 +00:00
Behdad Esfahbod
2a45892663 Merge branch 'rectangle-box-negative-extents' into 'master'
[matrix] Handle bounding-box extents overflow during transformation

See merge request cairo/cairo!645
2026-02-08 19:44:55 +00:00
Behdad Esfahbod
f0674b4c98 [rectanble Handle overflow in _cairo_box_from_doubles 2026-02-07 13:01:49 -07:00
Uli Schlachter
6b9e6dd0b3 Merge branch 'work/fix-leak-in-_cairo_pdf_surface_finish' into 'master'
_cairo_pdf_surface_finish: Fix leak in error conditions

See merge request cairo/cairo!644
2026-01-27 16:00:15 +00:00
Albert Astals Cid
b94bf30f03 _cairo_pdf_surface_finish: Fix leak in error conditions
Make sure surface->object_stream.stream is cleaned up even if things
failed

In poppler oss-fuzz tests we are getting this leak reported

Direct leak of 64 byte(s) in 1 object(s) allocated from:
	    #0 0x5747417eabd9 in __interceptor_calloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:74:3
	    #1 0x574742706f5b in _cairo_memory_stream_create cairo/src/cairo-output-stream.c:741:14
	    #2 0x5747426757b8 in _cairo_pdf_surface_open_object_stream cairo/src/cairo-pdf-surface.c:2307:34
	    #3 0x57474266b880 in _cairo_pdf_surface_finish cairo/src/cairo-pdf-surface.c:2700:14
	    #4 0x57474261afc6 in _cairo_surface_finish cairo/src/cairo-surface.c:1043:11
	    #5 0x57474261afc6 in cairo_surface_finish cairo/src/cairo-surface.c:1092:5
	    #6 0x57474270808a in _cairo_paginated_surface_finish cairo/src/cairo-paginated-surface.c:215:2
	    #7 0x5747426175c2 in _cairo_surface_finish cairo/src/cairo-surface.c:1043:11
	    #8 0x5747426175c2 in cairo_surface_destroy cairo/src/cairo-surface.c:978:2

This fixes it.

_cairo_pdf_surface_finish was succeeding past
_cairo_pdf_surface_open_object_stream that allocates surface->object_stream.stream,
failing when calling _cairo_pdf_surface_emit_font_subsets
and that memory was never freed
2026-01-24 11:37:50 +01:00
Luca Bacci
2050326dcc CI/MSVC: Exclude <builddir>/test/srcdir symlink from the artifacts
Otherwise latest GitLab fails with:

 > ERROR: Uploading artifacts as "archive" to coordinator... error
 >   error=couldn't execute POST against https://gitlab.freedesktop.org/api/v4/jobs/[...]/artifacts?artifact_format=zip[...]:
 >   Post "https://gitlab.freedesktop.org/api/v4/jobs/[...]/artifacts?artifact_format=zip[...]":
 >   read build/test/srcdir: Incorrect function. id=[...] token=[...]
2026-01-08 15:32:30 +01:00
Luca Bacci
1fdf7051d0 CI/MSVC: Build less
Avoid building subproject tests
2026-01-08 15:32:30 +01:00
Luca Bacci
30fdc7f338 CI: Do not store .git directory in artifacts
Otherwise gitlab-runner prints a few warnings:

 > Uploading artifacts...
 > WARNING: Part of .git directory is on the list of files to archive
 > WARNING: This may introduce unexpected problems
2026-01-08 15:32:30 +01:00
Luca Bacci
ce3a3e2d27 CI: Run tests on Windows 2026-01-08 15:32:30 +01:00
Luca Bacci
08dcac510b Tests/create-regions: skip if needed features are missing 2026-01-08 15:32:30 +01:00
Luca Bacci
15cb2d7acf Tests/font-variations: Cleanup resources in all cases
Otherwise the test runner detects leaks
2026-01-08 15:32:30 +01:00
Luca Bacci
1293ec674d Tests/pdf-operator-text: Check if pdf target is enabled
The same is done in pdf-mime-data.c
2026-01-08 15:32:30 +01:00
Luca Bacci
83e5d95ec2 Boilerplate/Win32: Switch to a DIB section
Thw Win32 boilerplate worked by creating an offscreen window
and creating a cairo surface that targets the client HDC.
However GDI clips the client HDC to the visible region of the
window, and that region is empty. In the end, every GDI drawing
operation turned into a no-op.

Rather than targeting HWNDs, it's much better to create a bitmap
(DIB Section) and draw via a memory HDC.

https://learn.microsoft.com/en-us/windows/win32/gdi/window-regions
https://devblogs.microsoft.com/oldnewthing/20030829-00/?p=42743
https://devblogs.microsoft.com/oldnewthing/20030902-00/?p=42693
2026-01-08 15:32:24 +01:00
Luca Bacci
2c354599a5 Boilerplate: Use backward slashes for system / popen commands on Windows
Both system() and popen() invoke the shell. Which shell is
invoked depends on the COMSPEC environment variable, but
usually it's CMD.exe.

CMD.exe doesn't quite like paths with forward slashes in its
command-line. Most of the times, the forward slash is mistaken
for a command line switch (the start of an option). For example:

  cmd /c "dir C:\Windows" works
  cmd /c "dir C:/Windows" doesn't work
2026-01-08 15:27:09 +01:00
Luca Bacci
626b3ab2f2 Boilerplate: Open pipe in binary mode on Windows
Open the pipe in binary mode on Windows to get the expected
byte counts. Note that the 'b' mode for popen is not portable
and so is used only on Windows:

> The behavior of popen() is specified for values of mode of "r",
> "w", "re", and "we". Other modes such as "rb" and "wb" might be
> supported by specific implementations, but these would not be
> portable features.

https://pubs.opengroup.org/onlinepubs/9799919799/functions/popen.html
2026-01-08 15:24:05 +01:00