Compare commits

..

118 Commits

Author SHA1 Message Date
Emmanuele Bassi 2d370768db Update CODEOWNERS file
GitLab has standardised the CODEOWNERS file and made it available on
self-hosted instances.
2023-10-19 13:23:46 +01:00
Matthias Clasen 7325121c63 Merge branch 'matthiasc/for-main' into 'main'
gsk: Cosmetics

See merge request GNOME/gtk!6490
2023-10-17 03:50:40 +00:00
Matthias Clasen 31abe56b7a gsk: Cosmetics 2023-10-16 23:32:37 -04:00
Matthias Clasen ca3fd16039 Merge branch 'matthiasc/for-main' into 'main'
dmabuf: Add a display getter

See merge request GNOME/gtk!6488
2023-10-17 02:45:33 +00:00
Matthias Clasen 4417509515 dmabuf: Add a display getter
Add private api to get the display of
a dmabuf texture. We will need it in
the following commit.
2023-10-16 22:29:20 -04:00
Matthias Clasen 9dc2e554e5 dmabuf: Tweak error messages 2023-10-16 22:29:10 -04:00
Matthias Clasen bfb01f5a4b Merge branch 'dmabuf-downloader' into 'main'
dmabuf: Split out GdkDmabuf and GdkDmabufDownloader

See merge request GNOME/gtk!6487
2023-10-16 23:31:21 +00:00
Benjamin Otte 570e80a9ff dmabuf: Split out GdkDmabuf and GdkDmabufDownloader
GdkDmabuf is a struct encapsulating all the values of a dmabuf, so
nothing to see here.

GdkDmabufDownloader is a vtable for a thing that can download dmabufs.
For now only one implementation exists, so this just looks like a ton
of work for no benefit.

The only neat thing is that gdkdmabuftexture.c got a whole lot tidier.
2023-10-16 18:56:52 -04:00
Artur S0 6d90d25a74 Update Russian translation 2023-10-16 11:57:47 +00:00
Matthias Clasen a7f6e65291 Merge branch 'matthiasc/for-main' into 'main'
Add a dmabuf debug flag

See merge request GNOME/gtk!6486
2023-10-15 16:43:45 +00:00
Matthias Clasen 59641b3c7b docs: Sync the list of debug flags
Make the docs for GDK_DEBUG match current reality.
2023-10-15 12:00:23 -04:00
Matthias Clasen 2f842b087c dmabuf: Cosmetics 2023-10-15 12:00:23 -04:00
Matthias Clasen 699f6a7993 Add a dmabuf debug flag
Add a new debug flag for dmabuf-related information,
and use it in gdkdmabuftexture.c.

This will let us separate out dmabuf debug spew from
opengl debug spew.
2023-10-15 11:05:32 -04:00
Matthias Clasen f04ba3bc60 Merge branch 'remove_ref_sink_on_gtk_filter' into 'main'
gtkfilechooserwidget: Replace g_object_ref_sink () with g_object_ref () on file filter

See merge request GNOME/gtk!6484
2023-10-15 11:28:29 +00:00
Matthias Clasen 09aac114d4 Merge branch 'fix-title-truncation' into 'main'
Fix window titles unexpectedly getting truncated

See merge request GNOME/gtk!6472
2023-10-15 11:27:40 +00:00
Matthias Clasen 9132600e1f Merge branch 'gbsneto/filechoosernativeportal-reverse' into 'main'
filechooserportal: Reverse file list

See merge request GNOME/gtk!6482
2023-10-15 11:26:25 +00:00
Matthias Clasen 5dcd6c7e12 Merge branch 'matthiasc/for-main' into 'main'
dmabufformatsbuilder: Make it work

See merge request GNOME/gtk!6485
2023-10-15 03:38:25 +00:00
Matthias Clasen 9f8d34ab01 dmabufformatsbuilder: Make it work
The qsort arguments were mixed up, leading to nonsense.
2023-10-14 23:04:00 -04:00
sid 7a4580fa89 gtkfilechooserwidget: Replace g_object_ref_sink () with g_object_ref () on file filter
GtkFileFilter doesn't inherit from GInitiallyUnowned anymore.
2023-10-14 21:54:49 +00:00
Matthias Clasen 45a7617cc8 Merge branch 'wip/otte/dmabuf-cleanups' into 'main'
Various dmabuf reworks

See merge request GNOME/gtk!6483
2023-10-14 20:54:27 +00:00
Benjamin Otte 57d8cc08a3 gdk: Add GDK_DEBUG=dmabuf-disable
I chose the name for consistency with gl-disable and vulkan-disable.
2023-10-14 22:30:17 +02:00
Benjamin Otte 1ca067a478 dmabuf: Add a GError to gdk_dmabuf_texture_builder_build() 2023-10-14 22:30:17 +02:00
Benjamin Otte 7a13e4f9b9 docs: Remove docs for private GdkDmabufFormat struct
This is a leftover from the design of the GdkDmabufFormats struct.
2023-10-14 22:30:17 +02:00
Benjamin Otte d101e17608 dmabuf: Use the new FormatsBuilder to initialize formats 2023-10-14 22:30:17 +02:00
Benjamin Otte 203a4fc45e dmabufformats: Add GdkDmabufFormatsBuilder
This is a utility object that helps in constructing GdkDmabufFormats.
2023-10-14 22:29:10 +02:00
Benjamin Otte a9823e05bb array: constify the additions array
We can only do that for by-value arrays, because compilers get confused
with const when there's too many dereferences going on.
2023-10-14 22:11:44 +02:00
Benjamin Otte 6f5833df28 dmabufformats: Mark a bunch of functions as pure 2023-10-14 22:11:44 +02:00
Sabri Ünal 5631ab6711 Update Turkish translation 2023-10-14 07:08:23 +00:00
Georges Basile Stavracas Neto 62fedf4eed filechooserportal: Reverse file list
To avoid O(n²) behaviour, GtkFileChooserNativePortal uses the
classic prepend tatict. However, it does not reverse the file
list after building it.

It's not a big deal since the portal does not specify the order
in which the files are sent. But it's nice nonetheless to send
the file list in the order in which files were passed originally.

Reversing the list has no meaningful performance impact.

Patch originally made by Bastien Nocera.

See https://github.com/flatpak/xdg-desktop-portal/issues/548
2023-10-13 16:12:12 -03:00
Emmanuele Bassi c274d073e0 Merge branch 'mzur-main-patch-48638' into 'main'
Fix docs for gtk_color_dialog_button_get_rgba

Closes #6155

See merge request GNOME/gtk!6479
2023-10-13 09:54:56 +00:00
Martin Zurowietz 8dda753505 Fix docs for gtk_color_dialog_button_get_rgba
The signal was incorrectly called "notify::color" but
it is "notify::rgba".

Resolves https://gitlab.gnome.org/GNOME/gtk/-/issues/6155
2023-10-13 06:57:05 +00:00
Matthias Clasen 4e66df79c4 Merge branch 'michaelweghorn/a11y_send_dbus_reply_on_set_current_value' into 'main'
a11y atspi: Send proper dbus reply when (not) changing value

Closes #6150

See merge request GNOME/gtk!6476
2023-10-12 14:05:49 +00:00
Emmanuele Bassi 71c7e61162 Merge branch 'michaelweghorn/a11y_dont_confuse_char_and_byte_count' into 'main'
a11y atspi: Don't use char count as byte count

Closes #6151

See merge request GNOME/gtk!6477
2023-10-12 13:40:40 +00:00
Michael Weghorn e39ecbf16d a11y atspi: Don't use char count as byte count
As mentioned in

    commit 368f2af634
    Author: Matthias Clasen <mclasen@redhat.com>
    Date:   Mon Oct 2 08:47:53 2023 -0400

        a11y: Be safe against non-UTF8 text

, the string insertion APIs take string + length
and only insert up to `length` bytes of the
given string.

The AT-SPI "TextChanged" event however
is using a character count, and `emit_text_changed`
also gets called with the character count
along with the string.

However, `g_strndup` used in `emit_text_changed`
so far takes a byte count, not a character count.

Adapt `emit_text_changed` to just use the
passed text as is and make it the responsibility
of the callers to pass only the actually
inserted/removed string.

Most of the callers in `gtk/a11y/gtkatspitext.c`
already did that. Adapt two missing ones to do
likewise.

Fixes: #6151
2023-10-12 11:58:32 +02:00
Michael Weghorn 0dbd2bd09e a11y atspi: Send proper dbus reply when (not) changing value
`gtk_accessible_range_default_set_current_value` needs
to return TRUE independent of whether the value was
actually changed, since that return value is required
for the proper dbus reply to be sent to AT-SPI.

Fixes a crash/assertion seen e.g. with the "Hypertext" gtk4-demo
example when trying to change "CurrentValue" for the
level bar via the AT-SPI Value interface:

    GLib-GIO:ERROR:../../../gio/gdbusconnection.c:4354:invoke_set_property_in_idle_cb: assertion failed: (error != NULL)
    Bail out! GLib-GIO:ERROR:../../../gio/gdbusconnection.c:4354:invoke_set_property_in_idle_cb: assertion failed: (error != NULL)
    Aborted

Fixes: #6150
2023-10-12 09:09:53 +02:00
Matthias Clasen 1297cc188d Merge branch 'add-six-lang' into 'main'
add hi-ja-et-fi-nb-th for gtkemojichooser

See merge request GNOME/gtk!6475
2023-10-11 22:13:54 +00:00
Benjamin Otte e584d17aad Merge branch 'dmabuf-texture-api' into 'main'
Add API for dmabuf textures

See merge request GNOME/gtk!6463
2023-10-11 20:25:50 +00:00
Matthias Clasen 4936965fb6 display: Get supported dmabuf formats
These are the dmabuf formats that we can import
into a GL context as an EGLImage, and successfully
download.

We skip the GdkDisplay:dmabuf-formats property
in the default value tests, since the nominal
default value is NULL, but the actual value is
constructed on demand.
2023-10-11 15:43:01 -04:00
Matthias Clasen e9cc53796e build: Error out if linux/dma-buf.h isn't found
This should always be present on Linux.
2023-10-11 15:43:01 -04:00
Matthias Clasen c93efe85dd Add GdkDmabufTexture
Add an implementation of GdkDmabufTexture.

For now, this implementation is rather minimal,
since we need a roundtrip through GL to convert
most nottrivial formats.
2023-10-11 15:43:01 -04:00
Matthias Clasen 44daa847ff Merge branch 'michaelweghorn/a11y_convert_negative_index_on_text_deletion' into 'main'
a11y: Convert negative text deletion index to actual offset

Closes #6149

See merge request GNOME/gtk!6473
2023-10-11 19:32:11 +00:00
Matthias Clasen d23e13aced Add GdkDmabufTextureBuilder
Add a builder for a new GdkTexture subclass that
wraps dmabuf buffers on Linux. For now, this is
just an API. The implementation will follow in
subsequent commits.
2023-10-11 14:54:21 -04:00
Matthias Clasen 40102a2b61 Add GdkDmabufFormats
This is an immutable struct containing information
about supported dma-buf formats and their properties.
2023-10-11 14:53:06 -04:00
sudip 49fbbfb6cc add hi-ja-et-fi-nb-th for gtkemojichooser 2023-10-12 00:07:59 +05:30
Michael Weghorn fefd856d67 a11y: Convert negative text deletion index to actual offset
`gtk_editable_delete_text` can be called with a
negative `end_pos`, in which case the characters
from the start pos to the end of the text are
removed. [1]

It e.g. gets called this way from
`gtk_editable_set_text`.

So far, that negative index was not converted,
but passed as is in the AT-SPI callback
`delete_text_cb` when calling the `text_changed`
handler (`emit_text_changed` in
`gtk/a11y/gtkatspicontext.c`) which just uses the
index as is, also in it's call to `g_strndup`,
resulting in a crash when negative indices are
used.

Fix this by converting negative values to the
actual end index in `delete_text_cb` before
calling the handler.

[1] https://docs.gtk.org/gtk3/method.Editable.delete_text.html

Fixes: #6149
2023-10-11 15:51:17 +02:00
Sergey Bugaev 39dab6d7bd widget: Queue a resize on Pango context changes
Updating a Pango context can influence the layout of widget, in
particular that of a GtkLabel, not only its rendering. Make sure to
queue a resize when updating the context.

In particular, this fixes window titles getting suddenly truncated when
moving a window from a HiDPI display to a low DPI one, after
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6190 has made font
hinting depend on the widget scale. With hinting enabled on low DPI,
the Pango layout needs ever so slightly more width to not get truncated.
There is plenty of space in the header bar that could be allocated to
the label, but for that to happen, it needs to know to queue a resize.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-10-11 15:39:37 +03:00
Matthias Clasen 7b5b78b065 Merge branch 'fix-a11y-text-signals-again' into 'main'
a11y: Avoid a crash

Closes #6146

See merge request GNOME/gtk!6470
2023-10-11 01:06:55 +00:00
Matthias Clasen 005b5042f6 Merge branch 'demo-frame-time' into 'main'
demo: Use the frame time for animation

See merge request GNOME/gtk!6468
2023-10-11 00:39:38 +00:00
Matthias Clasen b5149a483f Merge branch 'wip/chergert/update-stb' into 'main'
gsk/gl: update stb_rect_pack()

See merge request GNOME/gtk!6466
2023-10-11 00:38:36 +00:00
Matthias Clasen 15c43e5284 a11y: Avoid a crash
It is not safe to access text[end],
if text may not be NUL-terminated.

Fixes: #6146
2023-10-10 18:54:27 -04:00
Matthias Clasen fc4c0f769c Merge branch 'no-enums-in-bitfields' into 'main'
Stop using enums in bitfields

See merge request GNOME/gtk!6467
2023-10-10 22:48:11 +00:00
Sergey Bugaev e8ecbb2009 demo: Use the frame time for animation
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-10-10 11:38:13 +03:00
Sergey Bugaev 964affb1cc Stop using enums in bitfields
The C standard does not specify whether the underlying type of an enum
is signed or unsigned, and until C23 there was no way to control this
explicitly. GCC appears to make enums unsigned unless there is a
negative value among cases of the enum, in which case it becomes signed.
MSCV appears to make enums signed by default.

A bitfield of an enum type (which is not specificied in the C standard
either) behaves as if it was an instance of a numeric type with a
reduced value range. Specifically, a 'signed int val : 2;' bitfield will
have the possible values of -2, -1, 0, and 1, with the usual wraparound
behavior for the values that don't fit (although this too is
implementation-defined).

This causes the following issue, if we have:

typedef enum
{
  GTK_ZERO,
  GTK_ONE,
  GTK_TWO
} GtkFoo;

struct _GtkBar
{
  GtkFoo foo : 2;
};

and then assign bar.foo = GTK_TWO and read it back, it will have the
expected value of 2 (aka GTK_TWO) on GCC, but a value of -2 (not
matching any of the enum variants) on MSVC.

There does not seem to be any way to influence signedness of an enum
prior to C23, nor is there a 'unsigned GtkFoo foo : 2;' syntax. The only
remaining options seems to be never using enums in bitfields, which is
what this change implements.

In practice, this fixes GdkPipeIOStream crashing with an assertion when
trying to copy-paste in-app in MSVC builds on GTK.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-10-10 11:23:08 +03:00
Christian Hergert 05b51af2d5 gsk/gl: update stb_rect_pack() 2023-10-09 22:42:57 -07:00
Emmanuele Bassi 28e51c763b Merge branch 'disable_ccache_macos' into 'main'
Disable ccache in macOS job

See merge request GNOME/gtk!6458
2023-10-09 12:23:31 +00:00
Matthias Clasen ebf8e18319 Merge branch 'add-bn' into 'main'
add bengali language bn.data for gtkemojichooser

See merge request GNOME/gtk!6459
2023-10-09 03:03:10 +00:00
Christian Hergert d8bbe1c296 testsuite/gsk: add render test for mask(texture|color) 2023-10-06 10:52:53 -07:00
Christian Hergert c1417d3d4a gsk/gl: add fast path for texture masking color
This is useful for colorizing in the same fashion we do for the glyph
texture atlas. In fact, for small GdkTexture, you will end up in something
like the icon texture atlas.

The primary motivator for this optimization is to draw various glyph-like
features from VTE such as many forms of boxes, lines, arrows, etc.
2023-10-05 20:30:00 -07:00
René de Hesselle 3b4359d76d ci: Disable ccache in macOS job
As it turns out, ccache accelerates the build so much that it can
trigger a race condition in the gobject-introspection subproject. This
only surfaced recently as the introspection feature was previously
disabled due to missing build time dependencies.

The race condition surfaces as follows: the build breaks because
gobject-introspection starts to build Gdk-4.0.gir before
GdkPixbuf-2.0.gir, despite Gdk-4.0.gir depending on GdkPixbuf-2.0.gir.
2023-10-04 20:07:47 +02:00
sudip 16806294e3 add bengali language bn.data for gtkemojichooser 2023-10-04 18:52:10 +05:30
Luca Bacci 822425072b Merge branch '5724_gdk_win32_ignore_invalid_client_rect' into 'main'
Gdk4 Win32: ignore invalid client rects

Closes #5724

See merge request GNOME/gtk!6414
2023-10-04 07:58:55 +00:00
Emmanuele Bassi 7cc1283a26 Merge branch 'macos_introspec' into 'main'
Enable introspection in macOS CI

Closes Infrastructure/Infrastructure#935

See merge request GNOME/gtk!6453
2023-10-03 22:46:23 +00:00
René de Hesselle f4198706d1 Enable introspection in macOS CI
This requires providing pkg-config and bison as well as pre-built
wheels for Pycairo and PyGObject to make it work.
2023-10-03 21:00:14 +02:00
Jordi Mas i Hernandez 8478ba66fe Update Catalan translation
(cherry picked from commit d6fecef605)
2023-10-03 06:56:01 +00:00
Matthias Clasen 1d58de6ffb Merge branch 'a11y-textview-crash' into 'main'
a11y: Be safe against non-UTF8

Closes #6131

See merge request GNOME/gtk!6448
2023-10-02 17:34:21 +00:00
Emmanuele Bassi f5cec5c0f2 Apply 1 suggestion(s) to 1 file(s) 2023-10-02 13:16:17 +00:00
Matthias Clasen 368f2af634 a11y: Be safe against non-UTF8 text
The string we're passed here may not be zero-terminated
since our text insertion APIs take string + length. So
So be safe and copy the text we are interested in if
necessary.

Fixes: #6131
2023-10-02 08:49:41 -04:00
Matthias Clasen 66a9fee071 a11y: Emit text-changed after the insertion
This is necessary, since it is the default handler
that positions the iter at the inserted text, which
is what we assume here.
2023-10-02 08:49:31 -04:00
Matthias Clasen 6e0ac83d99 Merge branch 'print-dialog-revision' into 'main'
print dialog: Some API revisions

See merge request GNOME/gtk!6443
2023-10-01 14:01:33 +00:00
Matthias Clasen 12ad6b3157 gtk-demo: Add a demo for printing a stream
Add a Print button to the path fill demo,
and implement it using gtk_print_dialog_print.
2023-10-01 09:30:38 -04:00
Matthias Clasen fda9fd5ced print dialog: Some API revisions
Make gtk_print_dialog_setup_finish return a GtkPrintSetup
object, which encapsulates all the data that needs to be
transferred between the setup and print calls, and make
the print_file and print methods take an extra GtkPrintSetup
argument.

Change the print call to return an output stream, rather
than take an input stream. The results are now returned
when the output stream is closed.

With some further cleanup, this makes the GtkPrintDialog
object a proper builder object - you can create multiple
print dialogs from the same GtkPrintDialog object, in
parallel, and they won't interfere with each other.
2023-10-01 09:30:38 -04:00
Matthias Clasen 029ce83a69 print dialog: Cosmetics
Some minor cleanups.
2023-09-30 21:30:22 -04:00
Matthias Clasen 5ced6be416 printjob: Work with non-seekable fds
We want to pass a pipe fd in the future,
and those aren't seekable.
2023-09-30 21:30:22 -04:00
Matthias Clasen bbda833b01 demos: Cosmetics 2023-09-30 21:30:15 -04:00
Jonas Ådahl c86bc00330 Merge branch 'master' into 'main'
GdkSurface: prevent popups from appearing offscreen in edge cases

See merge request GNOME/gtk!5320
2023-09-30 15:03:33 +00:00
Matthias Clasen 68755c0fd2 Post-release version bump 2023-09-28 10:49:46 -04:00
Matthias Clasen 9090c28125 4.13.1 2023-09-28 09:50:16 -04:00
Matthias Clasen 3a3244891e Merge branch 'wip-print-dialog' into 'main'
wip: print dialog api

See merge request GNOME/gtk!5484
2023-09-28 01:18:26 +00:00
Matthias Clasen b55117334c gtk-demo: Add a print dialog 2023-09-27 20:50:52 -04:00
Matthias Clasen 02e5c7b9ad Add a print dialog
Add a simplified print api that only supports
printing preexisting pdf content. For now, it
only has a portal implementation.
2023-09-27 20:50:52 -04:00
Matthias Clasen 7268167f4c Merge branch 'matthiasc/for-main' into 'main'
print portal: Report errors properly

See merge request GNOME/gtk!6441
2023-09-27 21:52:13 +00:00
Matthias Clasen 93c7502cf7 printer: Add private search api 2023-09-27 17:37:11 -04:00
Matthias Clasen 789705cfe4 print portal: Report errors properly
The portal printoperation inmplementation
relies on the file printbackend to be available.
If it isn't, we should report a proper error
status insetad of running into assertions deep
inside the printoperation code.
2023-09-27 17:33:34 -04:00
Emmanuele Bassi 741471a1f8 Merge branch 'michaelweghorn/a11y_add_paragraph_role' into 'main'
a11y: Add paragraph role

See merge request GNOME/gtk!6432
2023-09-27 12:20:19 +00:00
Matthias Clasen f8da751cc2 Merge branch 'wip/chergert/rendernode-type-checks-for-refcount' into 'main'
gsk: remove excessive type checking within GSK

See merge request GNOME/gtk!6439
2023-09-27 12:12:18 +00:00
Matthias Clasen 8174842d9f Merge branch 'wip/chergert/rendernode-type-check' into 'main'
gsk/gl: remove TypeNode conformity checking for renderjob

See merge request GNOME/gtk!6438
2023-09-27 12:10:52 +00:00
Matthias Clasen e872952f36 Merge branch 'mcatanzaro/#6122' into 'main'
printoperation: fix case where operation may complete multiple twice

Closes #6122

See merge request GNOME/gtk!6437
2023-09-27 10:37:23 +00:00
Christian Hergert b010e46d13 gsk/gl: remove TypeNode conformity checking for renderjob
We don't need to be calling type node conformity checking from the tight
loop of the renderjob. Hoist that into the private header and use that
intead through via the Class pointer.
2023-09-26 18:36:56 -07:00
Christian Hergert eb646a8e8b gsk: remove excessive type checking within GSK
Anything that includes gskrendernodeprivate.h will get an alternate form
of ref/unref for render nodes which does not need to do type checking on
the parameter. We can expect that things are correct within GTK itself and
this saves excessive amounts of TypeNode conformities checking.
2023-09-26 18:28:34 -07:00
Michael Catanzaro 1e2975147d printoperation: fix some strange line spacing 2023-09-26 19:28:12 -05:00
Michael Catanzaro 653c10e8b6 printoperation: add some assertions
Let's assert that we schedule the idle callback exactly once.

These assertions are not perfect because if the callback executes before
we schedule it, then the assertion itself would be a use-after-free,
since I'm using the PrinterFinder to track whether the callback that
frees it has been scheduled. But in practice when using loupe's print
dialog, I was noticing the callback scheduled twice before it was
executed. The assertion would have caught this problem.
2023-09-26 19:25:41 -05:00
Michael Catanzaro dfbafdf047 printoperation: fix another case where operation may complete twice
This is a little tricky. At first, I thought we had a codepath where we
fail to schedule the idle that completes the print operation: if we take
the gtk_print_backend_printer_list_is_done path for each printer
backend, then printer_list_done_cb() is never executed and we never
schedule the idle. But in fact, in this case, then backends == NULL at
the bottom of find_printer(), and we'll schedule the idle there, so it's
OK. Except it's not really OK, because we'll schedule it even if a
printer was already found, resulting in the callback completing twice
and a double free.

Simplify this. Schedule the idle in find_printer() only if there are
*initially* no backends, not also if all backends are immediately ready
and already removed from consideration. Instead, always call
printer_list_done_cb() for every backend in find_printer_init(). After
the previous commit, printer_list_done_cb() will schedule the idle when
appropriate.

printer_list_done_cb() additionally disconnects signals that we did not
connect in this codepath, but it does so using
g_signal_handlers_disconnect_by_func, which is harmless. Otherwise, the
only extra work it's doing is scheduling the idle, and that's exactly
what find_printer_init() is missing.
2023-09-26 19:08:46 -05:00
Michael Catanzaro d8c821a851 printoperation: fix case where operation may complete multiple twice
If we are the final backend, then after removing ourselves there is no
backend remaining. We will schedule the idle even if it has already been
scheduled. This idle is required to run exactly once and executing it
twices results in a double free that crashes loupe when printing. It
also causes the user callback to execute twice, which could cause
similar problems.

Fixes #6122
2023-09-26 18:47:01 -05:00
Matthias Clasen 83376648d7 Merge branch 'wip/chergert/fix-clips-uaf' into 'main'
Fix potential UAF in renderjob clipping

See merge request GNOME/gtk!6436
2023-09-26 21:59:56 +00:00
Christian Hergert 089c34fa03 gsk/gl: use GdkArrayImpl for tracking modelview
Like the previous change, this uses GdkArrayImpl instead of GArray for
tracking modelview changes. This is less important than clip tracking
simple due to being used less, but it keeps the implementation synchronous
with the Clip tracking code.
2023-09-26 13:58:38 -07:00
Christian Hergert c846f8d745 gsk/gl: use GdkArrayImpl for Clip tracking
We can end up spending a lot of time in g_array_maybe_expand() through the
use of g_array_set_size() for clip tracking. That is somewhat due to the
simple nature of GArray being size-dynamic. Instead, we can use
GdkArrayImpl and let the compiler do what it does best to elide some
work and hoist other work into the calling function.

This also fixes a potential UAF in gsk_gl_render_job_push_contained_clip().
2023-09-26 13:58:35 -07:00
Emmanuele Bassi 79ebd76ac8 Merge branch 'wip/chergert/fix-gdkarrayimpl-from-c++' into 'main'
gdk: add missing G_END_DECLS to gdkarrayimpl.c

See merge request GNOME/gtk!6435
2023-09-26 18:48:02 +00:00
Christian Hergert 6eb9836eb0 gdk: add missing G_END_DECLS to gdkarrayimpl.c 2023-09-26 10:46:21 -07:00
Matthias Clasen 4a8f8a6eea Merge branch 'broadway-renderer-leak' into 'main'
broadway: Plug a leak in the GSK renderer

Closes #6120

See merge request GNOME/gtk!6434
2023-09-26 15:13:38 +00:00
Emmanuele Bassi 3ea723730b broadway: Do not add an extra reference when caching textures
We just created a GdkTexture, so we don't need to acquire a reference if
we're transferring the ownership to the node cache.
2023-09-26 14:44:05 +01:00
Emmanuele Bassi 90be2baf8b broadway: Plug another leak
When getting a colorized texture we're downloading the texture as a
Cairo surface, and then feeding it to another texture, but we never drop
the reference of the new surface.
2023-09-26 14:40:37 +01:00
Emmanuele Bassi 0b64fa88a1 docs: Clarify the behaviour of gdk_texture_new_for_surface()
Cairo surfaces are not GObject instances, so we should be more explicit
in the behaviour of the memory management, to avoid leaks.
2023-09-26 12:57:52 +01:00
Emmanuele Bassi c6cc446e63 broadway: Plug a leak in the GSK renderer
We are leaking the Cairo image surface when creating a new node.

Fixes: #6120
2023-09-26 12:49:32 +01:00
Benjamin Otte 0cad37760e Merge branch 'wip/otte/for-main' into 'main'
treeview: Fix crash in assertion

Closes #6114

See merge request GNOME/gtk!6433
2023-09-26 09:29:08 +00:00
Benjamin Otte e720008dca glcontext: Add gdk_gl_context_get_glsl_version_string()
This is in preparation for the new renderer.
2023-09-26 11:08:59 +02:00
Benjamin Otte 9c636a6136 array: Compute new size properly
Using "1 << x" means that we are shifting a signed 32bit integer, but we
want a gsize, which is an unsigned 64bit integer.

So now we don't overflow anymore if the array reaches a size of 2GB.
2023-09-26 11:08:59 +02:00
Benjamin Otte 1e24aa425e gdk: Fix compiler warning
gcc's -Wlto-type-mismatch found the hack, where we copied the wrong
prototype.
2023-09-26 11:08:59 +02:00
Benjamin Otte a8c597005a treeview: Fix crash in assertion
The fix in commit a267dfac5d is wrong.
The function can return FALSE in normal operation.

Instead do a check for node == NULL that gracefully returns FALSE instead.

Fixes: #6114
2023-09-26 11:08:32 +02:00
Aurimas Černius 97a781b380 Update Lithuanian translation
(cherry picked from commit 61276e9a76)
2023-09-25 19:58:12 +00:00
Rafael Fontenelle 313cadefe6 Update Brazilian Portuguese translation
(cherry picked from commit 90b8dcdf33)
2023-09-25 12:58:47 +00:00
Michael Weghorn 9f078bd5c9 a11y: Add paragraph role
Add new GTK_ACCESSIBLE_ROLE_PARAGRAPH role
for paragraphs.

ARIA has a paragraph role as well.

The paragraph role is used e.g. in document editors
like LibreOffice or web browsers like Firefox.

According to the ARIA spec [1], naming paragraphs
is forbidden (§ 5.2.8.6), and the superclass role
is section.

This role will be more useful once a way to expose
the textual data via the AT-SPI Text interface is
also available (s. issue #5912 [2]).

[1] https://www.w3.org/TR/wai-aria-1.2/
[2] https://gitlab.gnome.org/GNOME/gtk/-/issues/5912
2023-09-25 11:30:14 +02:00
Matthias Clasen 8ff4e27103 Merge branch 'wip/alice/dialog-crash' into 'main'
dialog: Check header bar type before calling track_default_decoration()

Closes #6116

See merge request GNOME/gtk!6430
2023-09-24 13:24:49 +00:00
Matthias Clasen 8389ca633d Merge branch 'matthiasc/for-main' into 'main'
tests: Split off some path utilities

See merge request GNOME/gtk!6431
2023-09-24 13:07:45 +00:00
Matthias Clasen 18fbec0fe1 Improve FOO_DEBUG=help output
Explain the all value a bit better.
2023-09-24 08:33:22 -04:00
Alice Mikhaylenko eb0a00067d dialog: Check header bar type before calling track_default_decoration()
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/6116
2023-09-24 15:38:19 +04:00
Alice Mikhaylenko 91216408e5 header-bar: Add a precondition to track_default_decoration() 2023-09-24 15:21:55 +04:00
G.Willems 4c46f5a8f7 GdkWin32: ignore invalid client rects
Gdk-Win32 uses GetClientRect() internally to query the surfaces coordinates,
but this API may fail in some transient contexts (observed when iconifying
a maximized window).
Check if the rect area is null, and don't update the surface position in
that case. This will keep the current surface size, until Win32 notifies
the new valid window state later.
This prevents using a nulled next_layout for toplevel size computation,
which would break widgets allocation once notified on gtk side.

Fixes #5724
Closes #5724
2023-09-19 20:29:04 +02:00
Campbell Jones 5c00dc7ef4 GdkSurface: prevent popups from appearing offscreen in edge cases
This commit adds a single additional condition to the maybe_flip_position
function in gdksurface.c. If a popup's unflipped position is below the
bounds of its containing area, the popup uses its flipped position
instead. This prevents tooltips from appearing below the bounds of the
screen when a small widget is positioned very close to the bottom edge of
the screen, such as in Budgie and XFCE panel applets.
2023-01-07 11:08:33 -05:00
110 changed files with 5857 additions and 8079 deletions
+12 -5
View File
@@ -217,25 +217,32 @@ macos-x86_64:
MESON_FORCE_BACKTRACKE: 1 MESON_FORCE_BACKTRACKE: 1
TMPDIR: /Users/Shared/work/tmp TMPDIR: /Users/Shared/work/tmp
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
CCACHE_DIR: /Users/Shared/work/ccache
PIP_CACHE_DIR: /Users/Shared/build/cache PIP_CACHE_DIR: /Users/Shared/build/cache
PIPENV_CACHE_DIR: $PIP_CACHE_DIR PIPENV_CACHE_DIR: $PIP_CACHE_DIR
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
EXTRA_MESON_FLAGS: "-Dgobject-introspection:werror=false"
before_script: before_script:
# Not using ccache on purpose as it accelerates the build so much that it
# can trigger race conditions in the gobject-introspection subproject.
- bash .gitlab-ci/show-info-osx.sh - bash .gitlab-ci/show-info-osx.sh
- python3 -m venv .venv - /opt/macports/bin/python3.10 -m venv .venv
- ln -s /opt/cmake/CMake.app/Contents/bin/cmake .venv/bin - ln -s /opt/cmake/CMake.app/Contents/bin/cmake .venv/bin
- ln -s /opt/ccache/ccache .venv/bin - ln -s /opt/pkg-config/bin/pkg-config .venv/bin
- ln -s /opt/bison/bin/bison .venv/bin
- source .venv/bin/activate - source .venv/bin/activate
- pip3 install meson==1.2.0 - pip3 install meson==1.2.0
- pip3 install ninja==1.11.1 - pip3 install ninja==1.11.1
- pip3 install /Users/Shared/build/pkgs/PyGObject-3.44.0-cp310-cp310-macosx_10_13_x86_64.whl
/Users/Shared/build/pkgs/pycairo-1.23.0-cp310-cp310-macosx_10_13_x86_64.whl
script: script:
- meson setup ${COMMON_MESON_FLAGS} - meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
-Dx11-backend=false -Dx11-backend=false
-Dbroadway-backend=true -Dbroadway-backend=true
-Dmacos-backend=true -Dmacos-backend=true
-Dmedia-gstreamer=disabled -Dmedia-gstreamer=disabled
-Dintrospection=disabled -Dintrospection=enabled
-Dcpp_std=c++11 -Dcpp_std=c++11
-Dpixman:tests=disabled -Dpixman:tests=disabled
-Dlibjpeg-turbo:simd=disabled -Dlibjpeg-turbo:simd=disabled
+32 -1
View File
@@ -1,4 +1,7 @@
Overview of Changes in 4.13.1, xx-xx-xxxx Overview of Changes in 4.13.2, xx-xx-xxxx
=========================================
Overview of Changes in 4.13.1, 28-09-2023
========================================= =========================================
* GtkTooltip: * GtkTooltip:
@@ -7,20 +10,32 @@ Overview of Changes in 4.13.1, xx-xx-xxxx
* GtkCenterLayout, GtkEntry, GtkSearchEntry: * GtkCenterLayout, GtkEntry, GtkSearchEntry:
- Fix some issues with baseline handling - Fix some issues with baseline handling
* GtkColorButton, GtkFontButton:
- Propagate focus-on-click
* GtkFileChooser: * GtkFileChooser:
- Make "Visit file" scroll to the file - Make "Visit file" scroll to the file
* GtkSwitch: * GtkSwitch:
- Respect text direction - Respect text direction
* GtkWindow:
- Don't assume titlebars are GtkHeaderBars
* Printing:
- Fix some problems with the portal implementation
- Add a new simple print API: GtkPrintDialog
* Paths: * Paths:
- GskPathMeasure performance has been improved - GskPathMeasure performance has been improved
- Add custom contours for circles, rounded rectangles and rectangles - Add custom contours for circles, rounded rectangles and rectangles
- Simplify GskPathPoint handling - Simplify GskPathPoint handling
- gsk_path_point_get_closest_point now returns the distance as well - gsk_path_point_get_closest_point now returns the distance as well
- Make GskPathBuilder simplify curves
* Input: * Input:
- Handle (some) single-key compose sequences - Handle (some) single-key compose sequences
- Fix active state tracking with sensitivity changes and grabs
* GSK: * GSK:
- Make the repeated gradients match between GL and cairo - Make the repeated gradients match between GL and cairo
@@ -29,6 +44,13 @@ Overview of Changes in 4.13.1, xx-xx-xxxx
- Restrict an optimization to the cases where it is crrect - Restrict an optimization to the cases where it is crrect
- Fix rendering of shadows with opacity - Fix rendering of shadows with opacity
- The Vulkan renderer now requires Vulkan 1.2 - The Vulkan renderer now requires Vulkan 1.2
- GL: Transition gradients unpremultiplied
- GL: Fix clipping of shadows
- GL: Some optimizations
- Broadway: Fix memory leaks in the renderer
* Wayland:
- Make activation more reliable
* macOS: * macOS:
- Clamp damage regions to the surface size - Clamp damage regions to the surface size
@@ -43,20 +65,29 @@ Overview of Changes in 4.13.1, xx-xx-xxxx
* Build: * Build:
- Fix build problems with C++ compilers - Fix build problems with C++ compilers
* Deprecations:
- gtk_window_present_with_time
* Translation updates * Translation updates
Brazilian Portuguese Brazilian Portuguese
British English British English
Catalan Catalan
Chinese (China)
Czech Czech
Danish Danish
Dutch
Esperanto
Galician Galician
Georgian Georgian
Italian Italian
Korean Korean
Latvian
Lithuanian Lithuanian
Persian
Polish Polish
Punjabi Punjabi
Slovenian Slovenian
Turkish
Overview of Changes in 4.13.0, 25-08-2023 Overview of Changes in 4.13.0, 25-08-2023
-6
View File
@@ -295,7 +295,6 @@
<file>gears.c</file> <file>gears.c</file>
<file>gestures.c</file> <file>gestures.c</file>
<file>glarea.c</file> <file>glarea.c</file>
<file>glyphs.c</file>
<file>gltransition.c</file> <file>gltransition.c</file>
<file>headerbar.c</file> <file>headerbar.c</file>
<file>hypertext.c</file> <file>hypertext.c</file>
@@ -340,7 +339,6 @@
<file>path_fill.c</file> <file>path_fill.c</file>
<file>path_maze.c</file> <file>path_maze.c</file>
<file>path_spinner.c</file> <file>path_spinner.c</file>
<file>path_sweep.c</file>
<file>path_walk.c</file> <file>path_walk.c</file>
<file>path_text.c</file> <file>path_text.c</file>
<file>peg_solitaire.c</file> <file>peg_solitaire.c</file>
@@ -428,10 +426,6 @@
<gresource prefix="/fontrendering"> <gresource prefix="/fontrendering">
<file>fontrendering.ui</file> <file>fontrendering.ui</file>
</gresource> </gresource>
<gresource prefix="/path_sweep">
<file>path_sweep.ui</file>
<file compressed="true">path_world.txt</file>
</gresource>
<gresource prefix="/path_walk"> <gresource prefix="/path_walk">
<file>path_walk.ui</file> <file>path_walk.ui</file>
<file compressed="true">path_world.txt</file> <file compressed="true">path_world.txt</file>
+4 -2
View File
@@ -34,7 +34,7 @@ transition (GtkWidget *widget,
{ {
DemoWidget *self = DEMO_WIDGET (widget); DemoWidget *self = DEMO_WIDGET (widget);
DemoLayout *demo_layout = DEMO_LAYOUT (gtk_widget_get_layout_manager (widget)); DemoLayout *demo_layout = DEMO_LAYOUT (gtk_widget_get_layout_manager (widget));
gint64 now = g_get_monotonic_time (); gint64 now = gdk_frame_clock_get_frame_time (frame_clock);
gtk_widget_queue_allocate (widget); gtk_widget_queue_allocate (widget);
@@ -66,11 +66,13 @@ clicked (GtkGestureClick *gesture,
gpointer data) gpointer data)
{ {
DemoWidget *self = data; DemoWidget *self = data;
GdkFrameClock *frame_clock;
if (self->tick_id != 0) if (self->tick_id != 0)
return; return;
self->start_time = g_get_monotonic_time (); frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
self->start_time = gdk_frame_clock_get_frame_time (frame_clock);
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), transition, NULL, NULL); self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), transition, NULL, NULL);
} }
File diff suppressed because it is too large Load Diff
-2
View File
@@ -34,7 +34,6 @@ demos = files([
'gestures.c', 'gestures.c',
'glarea.c', 'glarea.c',
'gltransition.c', 'gltransition.c',
'glyphs.c',
'headerbar.c', 'headerbar.c',
'hypertext.c', 'hypertext.c',
'iconscroll.c', 'iconscroll.c',
@@ -76,7 +75,6 @@ demos = files([
'path_fill.c', 'path_fill.c',
'path_maze.c', 'path_maze.c',
'path_spinner.c', 'path_spinner.c',
'path_sweep.c',
'path_walk.c', 'path_walk.c',
'path_text.c', 'path_text.c',
'peg_solitaire.c', 'peg_solitaire.c',
+98 -1
View File
@@ -2,10 +2,13 @@
* *
* This demo shows how to use GskPath to draw shapes that are (a bit) * This demo shows how to use GskPath to draw shapes that are (a bit)
* more complex than a rounded rectangle. * more complex than a rounded rectangle.
*
* It also demonstrates printing to a stream with GtkPrintDialog.
*/ */
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <cairo-pdf.h>
#include "paintable.h" #include "paintable.h"
@@ -165,6 +168,89 @@ gtk_logo_paintable_new (void)
return GDK_PAINTABLE (self); return GDK_PAINTABLE (self);
} }
static cairo_status_t
write_cairo (void *closure,
const unsigned char *data,
unsigned int length)
{
GOutputStream *stream = closure;
gsize written;
GError *error = NULL;
if (!g_output_stream_write_all (stream, data, length, &written, NULL, &error))
{
g_print ("Error writing pdf stream: %s\n", error->message);
g_error_free (error);
return CAIRO_STATUS_WRITE_ERROR;
}
return CAIRO_STATUS_SUCCESS;
}
static void
print_ready (GObject *source,
GAsyncResult *result,
gpointer data)
{
GtkPrintDialog *dialog = GTK_PRINT_DIALOG (source);
GError *error = NULL;
GOutputStream *stream;
GtkSnapshot *snapshot;
GdkPaintable *paintable;
GskRenderNode *node;
cairo_surface_t *surface;
cairo_t *cr;
stream = gtk_print_dialog_print_finish (dialog, result, &error);
if (stream == NULL)
{
g_print ("Failed to get output stream: %s\n", error->message);
g_error_free (error);
return;
}
snapshot = gtk_snapshot_new ();
paintable = gtk_picture_get_paintable (GTK_PICTURE (data));
gdk_paintable_snapshot (paintable, snapshot, 100, 100);
node = gtk_snapshot_free_to_node (snapshot);
surface = cairo_pdf_surface_create_for_stream (write_cairo, stream, 100, 100);
cr = cairo_create (surface);
gsk_render_node_draw (node, cr);
cairo_destroy (cr);
cairo_surface_destroy (surface);
gsk_render_node_unref (node);
if (!g_output_stream_close (stream, NULL, &error))
{
g_print ("Error from close: %s\n", error->message);
g_error_free (error);
}
g_object_unref (stream);
}
static void
print (GtkButton *button,
gpointer data)
{
GtkWidget *picture = data;
GtkPrintDialog *dialog;
dialog = gtk_print_dialog_new ();
gtk_print_dialog_print (dialog,
GTK_WINDOW (gtk_widget_get_root (picture)),
NULL,
NULL,
print_ready,
picture);
g_object_unref (dialog);
}
GtkWidget * GtkWidget *
do_path_fill (GtkWidget *do_widget) do_path_fill (GtkWidget *do_widget)
{ {
@@ -172,12 +258,21 @@ do_path_fill (GtkWidget *do_widget)
if (!window) if (!window)
{ {
GtkWidget *header, *button, *label;
GtkWidget *picture; GtkWidget *picture;
GdkPaintable *paintable; GdkPaintable *paintable;
window = gtk_window_new (); window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE); gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
gtk_window_set_default_size (GTK_WINDOW (window), 100, 100);
gtk_window_set_title (GTK_WINDOW (window), "Fill and Stroke"); gtk_window_set_title (GTK_WINDOW (window), "Fill and Stroke");
header = gtk_header_bar_new ();
button = gtk_button_new_from_icon_name ("printer-symbolic");
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
label = gtk_label_new ("Fill and Stroke");
gtk_widget_add_css_class (label, "title");
gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header), label);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paintable = gtk_logo_paintable_new (); paintable = gtk_logo_paintable_new ();
@@ -186,6 +281,8 @@ do_path_fill (GtkWidget *do_widget)
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE); gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
g_object_unref (paintable); g_object_unref (paintable);
g_signal_connect (button, "clicked", G_CALLBACK (print), picture);
gtk_window_set_child (GTK_WINDOW (window), picture); gtk_window_set_child (GTK_WINDOW (window), picture);
} }
-319
View File
@@ -1,319 +0,0 @@
/* Path/Sweep
*
* This demo shows how path intersections can be used.
*
* The world map that is used here is a path with 211 lines and 1569 cubic
* Bėzier segments in 121 contours.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#define GTK_TYPE_PATH_SWEEP (gtk_path_sweep_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathSweep, gtk_path_sweep, GTK, PATH_SWEEP, GtkWidget)
#define POINT_SIZE 8
enum {
PROP_0,
PROP_PATH,
N_PROPS
};
struct _GtkPathSweep
{
GtkWidget parent_instance;
GskPath *path;
graphene_rect_t bounds;
float y_pos;
gboolean in;
};
struct _GtkPathSweepClass
{
GtkWidgetClass parent_class;
};
static GParamSpec *properties[N_PROPS] = { NULL, };
G_DEFINE_TYPE (GtkPathSweep, gtk_path_sweep, GTK_TYPE_WIDGET)
static gboolean
intersection_cb (GskPath *path1,
const GskPathPoint *point1,
GskPath *path2,
const GskPathPoint *point2,
GskPathIntersection kind,
gpointer data)
{
GskPathBuilder *builder = data;
graphene_point_t p;
gsk_path_point_get_position (point1, path1, &p);
gsk_path_builder_add_circle (builder, &p, 4);
return TRUE;
}
static GskPath *
get_intersection_path (GskPath *path1,
GskPath *path2)
{
GskPathBuilder *builder = gsk_path_builder_new ();
gsk_path_foreach_intersection (path1, path2, intersection_cb, builder);
return gsk_path_builder_to_path (builder);
}
static void
gtk_path_sweep_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkPathSweep *self = GTK_PATH_SWEEP (widget);
GskStroke *stroke;
if (self->path == NULL)
return;
gtk_snapshot_save (snapshot);
stroke = gsk_stroke_new (2.0);
gtk_snapshot_append_stroke (snapshot, self->path, stroke, &(GdkRGBA) { 0, 0, 0, 1 });
if (self->in)
{
graphene_rect_t bounds;
GskPathBuilder *builder;
GskPath *line, *isecs;
gsk_path_get_stroke_bounds (self->path, stroke, &bounds);
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, bounds.origin.x, bounds.origin.y + self->y_pos);
gsk_path_builder_line_to (builder, bounds.origin.x + bounds.size.width, bounds.origin.y + self->y_pos);
line = gsk_path_builder_free_to_path (builder);
gtk_snapshot_append_stroke (snapshot, line, stroke, &(GdkRGBA) { 0, 0, 0, 1 });
isecs = get_intersection_path (self->path, line);
gtk_snapshot_append_fill (snapshot, isecs, GSK_FILL_RULE_WINDING, &(GdkRGBA) { 1, 0, 0, 1 });
gtk_snapshot_append_stroke (snapshot, isecs, stroke, &(GdkRGBA) { 0, 0, 0, 1 });
gsk_path_unref (isecs);
gsk_path_unref (line);
}
gsk_stroke_free (stroke);
gtk_snapshot_restore (snapshot);
}
static void
gtk_path_sweep_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkPathSweep *self = GTK_PATH_SWEEP (widget);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = (int) ceilf (self->bounds.size.width);
else
*minimum = *natural = (int) ceilf (self->bounds.size.height);
}
static void
gtk_path_sweep_set_path (GtkPathSweep *self,
GskPath *path)
{
if (self->path == path)
return;
g_clear_pointer (&self->path, gsk_path_unref);
graphene_rect_init (&self->bounds, 0, 0, 0, 0);
if (path)
{
GskStroke *stroke;
self->path = gsk_path_ref (path);
stroke = gsk_stroke_new (2.0);
gsk_path_get_stroke_bounds (path, stroke, &self->bounds);
gsk_stroke_free (stroke);
}
gtk_widget_queue_resize (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PATH]);
}
static void
gtk_path_sweep_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPathSweep *self = GTK_PATH_SWEEP (object);
switch (prop_id)
{
case PROP_PATH:
gtk_path_sweep_set_path (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_sweep_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPathSweep *self = GTK_PATH_SWEEP (object);
switch (prop_id)
{
case PROP_PATH:
g_value_set_boxed (value, self->path);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_sweep_dispose (GObject *object)
{
GtkPathSweep *self = GTK_PATH_SWEEP (object);
g_clear_pointer (&self->path, gsk_path_unref);
G_OBJECT_CLASS (gtk_path_sweep_parent_class)->dispose (object);
}
static void
gtk_path_sweep_class_init (GtkPathSweepClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_path_sweep_dispose;
object_class->set_property = gtk_path_sweep_set_property;
object_class->get_property = gtk_path_sweep_get_property;
widget_class->snapshot = gtk_path_sweep_snapshot;
widget_class->measure = gtk_path_sweep_measure;
properties[PROP_PATH] =
g_param_spec_boxed ("path", NULL, NULL,
GSK_TYPE_PATH,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
motion_cb (GtkEventControllerMotion *controller,
double x,
double y,
gpointer data)
{
GtkPathSweep *self = data;
self->y_pos = y;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
enter_cb (GtkEventControllerMotion *controller,
double x,
double y,
gpointer data)
{
GtkPathSweep *self = data;
self->in = TRUE;
self->y_pos = y;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
leave_cb (GtkEventControllerMotion *controller,
gpointer data)
{
GtkPathSweep *self = data;
self->in = FALSE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
gtk_path_sweep_init (GtkPathSweep *self)
{
GtkEventController *controller;
/* Data taken from
* https://commons.wikimedia.org/wiki/Maps_of_the_world#/media/File:Simplified_blank_world_map_without_Antartica_(no_borders).svg
*/
GBytes *data = g_resources_lookup_data ("/path_sweep/path_world.txt", 0, NULL);
GskPath *path = gsk_path_parse (g_bytes_get_data (data, NULL));
g_bytes_unref (data);
gtk_path_sweep_set_path (self, path);
gsk_path_unref (path);
controller = gtk_event_controller_motion_new ();
g_signal_connect (controller, "motion", G_CALLBACK (motion_cb), self);
g_signal_connect (controller, "enter", G_CALLBACK (enter_cb), self);
g_signal_connect (controller, "leave", G_CALLBACK (leave_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
GtkWidget *
gtk_path_sweep_new (void)
{
GtkPathSweep *self;
self = g_object_new (GTK_TYPE_PATH_SWEEP, NULL);
return GTK_WIDGET (self);
}
GtkWidget *
do_path_sweep (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilder *builder;
g_type_ensure (GTK_TYPE_PATH_SWEEP);
builder = gtk_builder_new_from_resource ("/path_sweep/path_sweep.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}
-17
View File
@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">World Map</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkPathSweep" id="view">
<property name="hexpand">true</property>
<property name="vexpand">true</property>
</object>
</child>
</object>
</property>
</object>
</interface>
+70 -3
View File
@@ -1,8 +1,9 @@
/* Pickers and Launchers /* Pickers and Launchers
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkFileLauncher, GtkUriLauncher * #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkPrintDialog, GtkFileLauncher, GtkUriLauncher
* *
* The dialogs are mainly intended for use in preference dialogs. * The dialogs are mainly intended for use in preference dialogs.
* They allow to select colors, fonts and applications. * They allow to select colors, fonts and files. There is also a
* print dialog.
* *
* The launchers let you open files or URIs in applications that * The launchers let you open files or URIs in applications that
* can handle them. * can handle them.
@@ -11,11 +12,13 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
static GtkWidget *app_picker; static GtkWidget *app_picker;
static GtkWidget *print_button;
static void static void
set_file (GFile *file, set_file (GFile *file,
gpointer data) gpointer data)
{ {
GFileInfo *info;
char *name; char *name;
if (!file) if (!file)
@@ -31,6 +34,13 @@ set_file (GFile *file,
gtk_widget_set_sensitive (app_picker, TRUE); gtk_widget_set_sensitive (app_picker, TRUE);
g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref); g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref);
info = g_file_query_info (file, "standard::content-type", 0, NULL, NULL);
if (strcmp (g_file_info_get_content_type (info), "application/pdf") == 0)
{
gtk_widget_set_sensitive (print_button, TRUE);
g_object_set_data_full (G_OBJECT (print_button), "file", g_object_ref (file), g_object_unref);
}
} }
static void static void
@@ -47,6 +57,10 @@ file_opened (GObject *source,
{ {
g_print ("%s\n", error->message); g_print ("%s\n", error->message);
g_error_free (error); g_error_free (error);
gtk_widget_set_sensitive (app_picker, FALSE);
g_object_set_data (G_OBJECT (app_picker), "file", NULL);
gtk_widget_set_sensitive (print_button, FALSE);
g_object_set_data (G_OBJECT (print_button), "file", NULL);
} }
set_file (file, data); set_file (file, data);
@@ -114,6 +128,53 @@ open_app (GtkButton *picker)
g_object_unref (launcher); g_object_unref (launcher);
} }
static void
print_file_done (GObject *source,
GAsyncResult *result,
gpointer data)
{
GtkPrintDialog *dialog = GTK_PRINT_DIALOG (source);
GError *error = NULL;
GCancellable *cancellable;
unsigned int id;
cancellable = g_task_get_cancellable (G_TASK (result));
id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (cancellable), "timeout"));
if (id)
g_source_remove (id);
if (!gtk_print_dialog_print_file_finish (dialog, result, &error))
{
g_print ("%s\n", error->message);
g_error_free (error);
}
}
static void
print_file (GtkButton *picker)
{
GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (picker)));
GtkPrintDialog *dialog;
GCancellable *cancellable;
GFile *file;
unsigned int id;
file = G_FILE (g_object_get_data (G_OBJECT (picker), "file"));
dialog = gtk_print_dialog_new ();
cancellable = g_cancellable_new ();
id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
20,
abort_mission, g_object_ref (cancellable), g_object_unref);
g_object_set_data (G_OBJECT (cancellable), "timeout", GUINT_TO_POINTER (id));
gtk_print_dialog_print_file (dialog, parent, NULL, file, cancellable, print_file_done, NULL);
g_object_unref (cancellable);
g_object_unref (dialog);
}
static void static void
open_uri_done (GObject *source, open_uri_done (GObject *source,
GAsyncResult *result, GAsyncResult *result,
@@ -234,8 +295,14 @@ do_pickers (GtkWidget *do_widget)
gtk_widget_set_sensitive (app_picker, FALSE); gtk_widget_set_sensitive (app_picker, FALSE);
g_signal_connect (app_picker, "clicked", G_CALLBACK (open_app), NULL); g_signal_connect (app_picker, "clicked", G_CALLBACK (open_app), NULL);
gtk_box_append (GTK_BOX (picker), app_picker); gtk_box_append (GTK_BOX (picker), app_picker);
gtk_grid_attach (GTK_GRID (table), picker, 1, 2, 1, 1);
print_button = gtk_button_new_from_icon_name ("printer-symbolic");
gtk_widget_set_tooltip_text (print_button, "Print file");
gtk_widget_set_sensitive (print_button, FALSE);
g_signal_connect (print_button, "clicked", G_CALLBACK (print_file), NULL);
gtk_box_append (GTK_BOX (picker), print_button);
gtk_grid_attach (GTK_GRID (table), picker, 1, 2, 1, 1);
label = gtk_label_new ("URI:"); label = gtk_label_new ("URI:");
gtk_widget_set_halign (label, GTK_ALIGN_START); gtk_widget_set_halign (label, GTK_ALIGN_START);
+45 -47
View File
@@ -2,8 +2,9 @@
# a merge request for files listed here, please add the following people to # a merge request for files listed here, please add the following people to
# the list of reviewers # the list of reviewers
# The syntax of this file is similar to the GitHub CODEOWNERS file: # The syntax of this file is defined in the GitLab documentation:
# https://help.github.com/articles/about-codeowners/ # https://docs.gitlab.com/ee/user/project/codeowners/reference.html
#
# Which, in turn, is similar to the .gitignore and .gitattributes files: # Which, in turn, is similar to the .gitignore and .gitattributes files:
# #
# - comments start with `#` # - comments start with `#`
@@ -14,64 +15,61 @@
# If you want to be responsible for code reviews in specific sections of # If you want to be responsible for code reviews in specific sections of
# the GTK code base, add yourself here. # the GTK code base, add yourself here.
# Maintainer [Maintainer]
* @matthiasc * @matthiasc
# Build system [Build system]
meson.build @ebassi @nirbheek meson.build @ebassi @nirbheek @xclaesse
*.py @ebassi *.py @ebassi
# CSS [CSS]
gtk/gtkcss*.[ch] @otte @baedert /gtk/gtkcss*.[ch] @otte @matthiasc
gtk/gtkstyle*.[ch] @otte @baedert /gtk/gtkstyle*.[ch] @otte @matthiasc
# Gestures [Gestures]
gtk/gtkeventcontroller* @carlosg /gtk/gtkeventcontroller* @carlosg
gtk/gtkgesture*.[ch] @carlosg /gtk/gtkgesture*.[ch] @carlosg
# GtkFileChooser [Input methods]
gtk/gtkfilechooser* @federico @ebassi /gtk/gtkimcontext* @carlosg
gtk/gtkfilesystem* @federico @ebassi
gtk/gtkfilefilter* @federico @ebassi
# GtkFontChooser [Media]
gtk/gtkfontchooser* @matthiasc /gtk/gtkmedia* @otte
# Input methods [GSK]
gtk/gtkimcontext* @carlosg /gsk/ @otte @chergert @ebassi
# Media [GL rendering]
gtk/gtkmedia* @otte /gsk/gl/ @otte @chergert
# GSK [Vulkan rendering]
gsk @otte @baedert @ebassi /gsk/vulkan @otte
# GL rendering [Documentation]
gsk/gl @baedert @ebassi /docs/ @ebassi @dboles
README.md @ebassi
CONTRIBUTING.md @ebassi @matthiasc
# Vulkan rendering [Wayland]
gsk/vulkan /gdk/wayland @jadahl
# Documentation [X11]
docs/ @ebassi @dboles /gdk/x11 @ofourdan @matthiasc @carlosg
# Wayland [macOS]
gdk/wayland @jadahl /gdk/macos @chergert
# X11 [Themes]
gdk/x11 @ofourdan @matthiasc /gtk/themes @lapoc @jimmac
# Themes [Inspector]
gtk/themes @lapoc @jimmac /gtk/inspector @otte @matthiasc
# Inspector [Layout managers]
gtk/inspector @otte @matthiasc /gtk/gtklayout* @ebassi
/gtk/gtkconstraint* @ebassi
# Layout managers [Accessibility]
gtk/gtklayout* @ebassi /gtk/gtkaccessible*.[ch] @ebassi @tyrylu @matthiasc
gtk/gtkconstraint* @ebassi /gtk/gtkatcontext*.[ch] @ebassi @tyrylu @matthiasc
/gtk/a11y @ebassi @tyrylu
# Accessibility
gtk/gtkaccessible*.[ch] @ebassi
gtk/gtkatcontext*.[ch] @ebassi
gtk/a11y @ebassi
-21
View File
@@ -12,11 +12,6 @@ SYNOPSIS
-------- --------
| **gtk4-path-tool** <COMMAND> [OPTIONS...] <PATH> | **gtk4-path-tool** <COMMAND> [OPTIONS...] <PATH>
| |
| **gtk4-path-tool** simplify [OPTIONS...] <PATH>
| **gtk4-path-tool** intersection [OPTIONS...] <PATH> <PATH>
| **gtk4-path-tool** union [OPTIONS...] <PATH> <PATH>
| **gtk4-path-tool** difference [OPTIONS...] <PATH> <PATH>
| **gtk4-path-tool** symmetric-difference [OPTIONS...] <PATH> <PATH>
| **gtk4-path-tool** decompose [OPTIONS...] <PATH> | **gtk4-path-tool** decompose [OPTIONS...] <PATH>
| **gtk4-path-tool** show [OPTIONS...] <PATH> | **gtk4-path-tool** show [OPTIONS...] <PATH>
| **gtk4-path-tool** render [OPTIONS...] <PATH> | **gtk4-path-tool** render [OPTIONS...] <PATH>
@@ -200,7 +195,6 @@ The interior of the path is filled.
The limit at which to clip miters at line joins. The default value is 4. The limit at which to clip miters at line joins. The default value is 4.
<<<<<<< HEAD
``--dashes=VALUE`` ``--dashes=VALUE``
The dash pattern to use for this stroke. A dash pattern is specified by The dash pattern to use for this stroke. A dash pattern is specified by
@@ -214,21 +208,6 @@ The interior of the path is filled.
The offset into the dash pattern where dashing should begin. The offset into the dash pattern where dashing should begin.
The default value is 0. The default value is 0.
Boolean Operations
^^^^^^^^^^^^^^^^^^
The ``intersection``, ``union``, ``difference`` and ``symmetric-difference`` commands
perform boolean operations on paths. Given two paths, they create a new path which
encircles the area that is the intersection, union, difference or symmetric difference
of the areas encircled by the paths.
Simplification
^^^^^^^^^^^^^^
The ``simplify`` command removes areas of overlap from a path such that the resulting
path encircles the same area, but every edge in the resulting path is a boundary between
the inside and the outside.
Reversing Reversing
^^^^^^^^^ ^^^^^^^^^
+28 -13
View File
@@ -170,35 +170,41 @@ This variable can be set to a list of debug options, which cause GDK to
print out different types of debugging information. Some of these options print out different types of debugging information. Some of these options
are only available when GTK has been configured with `-Ddebug=true`. are only available when GTK has been configured with `-Ddebug=true`.
`cursor` `misc`
: Information about cursor objects (only win32) : Miscellaneous information
`events`
: Information about events
`dnd`
: Information about drag-and-drop
`input`
: Information about input (mostly Windows)
`eventloop` `eventloop`
: Information about event loop operation (mostly macOS) : Information about event loop operation (mostly macOS)
`misc`
: Miscellaneous information
`frames` `frames`
: Information about the frame clock : Information about the frame clock
`settings` `settings`
: Information about xsettings : Information about xsettings
`opengl`
: Information about OpenGL
`vulkan`
: Information about Vulkan
`selection` `selection`
: Information about selections : Information about selections
`clipboard` `clipboard`
: Information about clipboards : Information about clipboards
`dnd` `dmabuf`
: Information about drag-and-drop : Information about dmabuf handling (Linux-only)
`opengl`
: Information about OpenGL
`vulkan`
: Information about Vulkan
A number of options affect behavior instead of logging: A number of options affect behavior instead of logging:
@@ -217,6 +223,9 @@ A number of options affect behavior instead of logging:
`gl-fractional` `gl-fractional`
: Enable fractional scaling for OpenGL. This is experimental : Enable fractional scaling for OpenGL. This is experimental
`gl-debug`
: Insert debugging information in OpenGL
`gl-legacy` `gl-legacy`
: Use a legacy OpenGL context : Use a legacy OpenGL context
@@ -244,6 +253,12 @@ A number of options affect behavior instead of logging:
`high-depth` `high-depth`
: Use high bit depth rendering if possible : Use high bit depth rendering if possible
`no-vsync`
: Repaint instantly (uses 100% CPU with animations)
`dmabuf-disable`
: Disable dmabuf support
The special value `all` can be used to turn on all debug options. The special The special value `all` can be used to turn on all debug options. The special
value `help` can be used to obtain a list of all supported debug options. value `help` can be used to obtain a list of all supported debug options.
+4 -1
View File
@@ -117,6 +117,8 @@ static const GdkDebugKey gdk_debug_keys[] = {
{ "vulkan", GDK_DEBUG_VULKAN, "Information about Vulkan" }, { "vulkan", GDK_DEBUG_VULKAN, "Information about Vulkan" },
{ "selection", GDK_DEBUG_SELECTION, "Information about selections" }, { "selection", GDK_DEBUG_SELECTION, "Information about selections" },
{ "clipboard", GDK_DEBUG_CLIPBOARD, "Information about clipboards" }, { "clipboard", GDK_DEBUG_CLIPBOARD, "Information about clipboards" },
{ "dmabuf", GDK_DEBUG_DMABUF, "Information about dmabuf buffers" },
{ "nograbs", GDK_DEBUG_NOGRABS, "Disable pointer and keyboard grabs (X11)", TRUE }, { "nograbs", GDK_DEBUG_NOGRABS, "Disable pointer and keyboard grabs (X11)", TRUE },
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals", TRUE }, { "portals", GDK_DEBUG_PORTALS, "Force use of portals", TRUE },
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals", TRUE }, { "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals", TRUE },
@@ -133,6 +135,7 @@ static const GdkDebugKey gdk_debug_keys[] = {
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings", TRUE }, { "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings", TRUE },
{ "high-depth", GDK_DEBUG_HIGH_DEPTH, "Use high bit depth rendering if possible", TRUE }, { "high-depth", GDK_DEBUG_HIGH_DEPTH, "Use high bit depth rendering if possible", TRUE },
{ "no-vsync", GDK_DEBUG_NO_VSYNC, "Repaint instantly (uses 100% CPU with animations)", TRUE }, { "no-vsync", GDK_DEBUG_NO_VSYNC, "Repaint instantly (uses 100% CPU with animations)", TRUE },
{ "dmabuf-disable", GDK_DEBUG_DMABUF_DISABLE, "Disable dmabuf support", TRUE },
}; };
@@ -263,7 +266,7 @@ gdk_parse_debug_var (const char *variable,
if (debug_enabled || keys[i].always_enabled) if (debug_enabled || keys[i].always_enabled)
fprintf (stderr, " %s%*s%s\n", keys[i].key, (int)(max_width - strlen (keys[i].key)), " ", keys[i].help); fprintf (stderr, " %s%*s%s\n", keys[i].key, (int)(max_width - strlen (keys[i].key)), " ", keys[i].help);
} }
fprintf (stderr, " %s%*s%s\n", "all", max_width - 3, " ", "Enable all values"); fprintf (stderr, " %s%*s%s\n", "all", max_width - 3, " ", "Enable all values. Other given values are subtracted");
fprintf (stderr, " %s%*s%s\n", "help", max_width - 4, " ", "Print this help"); fprintf (stderr, " %s%*s%s\n", "help", max_width - 4, " ", "Print this help");
fprintf (stderr, "\nMultiple values can be given, separated by : or space.\n"); fprintf (stderr, "\nMultiple values can be given, separated by : or space.\n");
} }
+3
View File
@@ -42,6 +42,9 @@
#include <gdk/gdkdevicetool.h> #include <gdk/gdkdevicetool.h>
#include <gdk/gdkdisplay.h> #include <gdk/gdkdisplay.h>
#include <gdk/gdkdisplaymanager.h> #include <gdk/gdkdisplaymanager.h>
#include <gdk/gdkdmabufformats.h>
#include <gdk/gdkdmabuftexture.h>
#include <gdk/gdkdmabuftexturebuilder.h>
#include <gdk/gdkdrag.h> #include <gdk/gdkdrag.h>
#include <gdk/gdkdragsurface.h> #include <gdk/gdkdragsurface.h>
#include <gdk/gdkdragsurfacesize.h> #include <gdk/gdkdragsurfacesize.h>
+7 -1
View File
@@ -183,7 +183,7 @@ gdk_array(reserve) (GdkArray *self,
return; return;
size = gdk_array(get_size) (self); size = gdk_array(get_size) (self);
new_size = 1 << g_bit_storage (MAX (GDK_ARRAY_REAL_SIZE (n), 16) - 1); new_size = ((gsize) 1) << g_bit_storage (MAX (GDK_ARRAY_REAL_SIZE (n), 16) - 1);
#ifdef GDK_ARRAY_PREALLOC #ifdef GDK_ARRAY_PREALLOC
if (self->start == self->preallocated) if (self->start == self->preallocated)
@@ -215,7 +215,11 @@ gdk_array(splice) (GdkArray *self,
gsize pos, gsize pos,
gsize removed, gsize removed,
gboolean stolen, gboolean stolen,
#ifdef GDK_ARRAY_BY_VALUE
const _T_ *additions,
#else
_T_ *additions, _T_ *additions,
#endif
gsize added) gsize added)
{ {
gsize size; gsize size;
@@ -318,3 +322,5 @@ gdk_array(get) (const GdkArray *self,
#undef GDK_ARRAY_TYPE_NAME #undef GDK_ARRAY_TYPE_NAME
#undef GDK_ARRAY_NO_MEMSET #undef GDK_ARRAY_NO_MEMSET
#endif #endif
G_END_DECLS
+19 -16
View File
@@ -36,23 +36,26 @@ typedef enum {
GDK_DEBUG_VULKAN = 1 << 8, GDK_DEBUG_VULKAN = 1 << 8,
GDK_DEBUG_SELECTION = 1 << 9, GDK_DEBUG_SELECTION = 1 << 9,
GDK_DEBUG_CLIPBOARD = 1 << 10, GDK_DEBUG_CLIPBOARD = 1 << 10,
GDK_DEBUG_DMABUF = 1 << 11,
/* flags below are influencing behavior */ /* flags below are influencing behavior */
GDK_DEBUG_NOGRABS = 1 << 11, GDK_DEBUG_NOGRABS = 1 << 12,
GDK_DEBUG_PORTALS = 1 << 12, GDK_DEBUG_PORTALS = 1 << 13,
GDK_DEBUG_NO_PORTALS = 1 << 13, GDK_DEBUG_NO_PORTALS = 1 << 14,
GDK_DEBUG_GL_DISABLE = 1 << 14, GDK_DEBUG_GL_DISABLE = 1 << 15,
GDK_DEBUG_GL_FRACTIONAL = 1 << 15, GDK_DEBUG_GL_FRACTIONAL = 1 << 16,
GDK_DEBUG_GL_LEGACY = 1 << 16, GDK_DEBUG_GL_LEGACY = 1 << 17,
GDK_DEBUG_GL_GLES = 1 << 17, GDK_DEBUG_GL_GLES = 1 << 18,
GDK_DEBUG_GL_DEBUG = 1 << 18, GDK_DEBUG_GL_DEBUG = 1 << 19,
GDK_DEBUG_GL_EGL = 1 << 19, GDK_DEBUG_GL_EGL = 1 << 20,
GDK_DEBUG_GL_GLX = 1 << 20, GDK_DEBUG_GL_GLX = 1 << 21,
GDK_DEBUG_GL_WGL = 1 << 21, GDK_DEBUG_GL_WGL = 1 << 22,
GDK_DEBUG_VULKAN_DISABLE = 1 << 22, GDK_DEBUG_VULKAN_DISABLE = 1 << 23,
GDK_DEBUG_VULKAN_VALIDATE = 1 << 23, GDK_DEBUG_VULKAN_VALIDATE = 1 << 24,
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 24, GDK_DEBUG_DEFAULT_SETTINGS= 1 << 25,
GDK_DEBUG_HIGH_DEPTH = 1 << 25, GDK_DEBUG_HIGH_DEPTH = 1 << 26,
GDK_DEBUG_NO_VSYNC = 1 << 26, GDK_DEBUG_NO_VSYNC = 1 << 27,
GDK_DEBUG_DMABUF_DISABLE = 1 << 28,
} GdkDebugFlags; } GdkDebugFlags;
extern guint _gdk_debug_flags; extern guint _gdk_debug_flags;
+85
View File
@@ -31,6 +31,9 @@
#include "gdkclipboardprivate.h" #include "gdkclipboardprivate.h"
#include "gdkdeviceprivate.h" #include "gdkdeviceprivate.h"
#include "gdkdisplaymanagerprivate.h" #include "gdkdisplaymanagerprivate.h"
#include "gdkdmabufformatsbuilderprivate.h"
#include "gdkdmabufformatsprivate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkeventsprivate.h" #include "gdkeventsprivate.h"
#include "gdkframeclockidleprivate.h" #include "gdkframeclockidleprivate.h"
#include "gdkglcontextprivate.h" #include "gdkglcontextprivate.h"
@@ -69,6 +72,7 @@ enum
PROP_COMPOSITED, PROP_COMPOSITED,
PROP_RGBA, PROP_RGBA,
PROP_INPUT_SHAPES, PROP_INPUT_SHAPES,
PROP_DMABUF_FORMATS,
LAST_PROP LAST_PROP
}; };
@@ -138,6 +142,10 @@ gdk_display_get_property (GObject *object,
g_value_set_boolean (value, gdk_display_supports_input_shapes (display)); g_value_set_boolean (value, gdk_display_supports_input_shapes (display));
break; break;
case PROP_DMABUF_FORMATS:
g_value_set_boxed (value, gdk_display_get_dmabuf_formats (display));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
} }
@@ -239,6 +247,11 @@ gdk_display_class_init (GdkDisplayClass *class)
TRUE, TRUE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
props[PROP_DMABUF_FORMATS] =
g_param_spec_boxed ("dmabuf-formats", NULL, NULL,
GDK_TYPE_DMABUF_FORMATS,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, LAST_PROP, props); g_object_class_install_properties (object_class, LAST_PROP, props);
/** /**
@@ -404,6 +417,8 @@ gdk_display_finalize (GObject *object)
g_list_free_full (display->seats, g_object_unref); g_list_free_full (display->seats, g_object_unref);
g_clear_pointer (&display->dmabuf_formats, gdk_dmabuf_formats_unref);
G_OBJECT_CLASS (gdk_display_parent_class)->finalize (object); G_OBJECT_CLASS (gdk_display_parent_class)->finalize (object);
} }
@@ -1824,6 +1839,76 @@ gdk_display_get_egl_display (GdkDisplay *self)
#endif #endif
} }
#ifdef HAVE_LINUX_DMA_BUF_H
static void
gdk_display_add_dmabuf_downloader (GdkDisplay *display,
const GdkDmabufDownloader *downloader,
GdkDmabufFormatsBuilder *builder)
{
gsize i;
downloader->add_formats (downloader, display, builder);
/* dmabuf_downloaders is NULL-terminated */
for (i = 0; i < G_N_ELEMENTS (display->dmabuf_downloaders) - 1; i++)
{
if (display->dmabuf_downloaders[i] == NULL)
break;
}
g_assert (i < G_N_ELEMENTS (display->dmabuf_downloaders));
display->dmabuf_downloaders[i] = downloader;
}
#endif
/* To support a drm format, we must be able to import it into GL
* using the relevant EGL extensions, and download it into a memory
* texture, possibly doing format conversion with shaders (in GSK).
*/
static void
init_dmabuf_formats (GdkDisplay *display)
{
GdkDmabufFormatsBuilder *builder;
if (display->dmabuf_formats != NULL)
return;
builder = gdk_dmabuf_formats_builder_new ();
#ifdef HAVE_LINUX_DMA_BUF_H
if (!GDK_DEBUG_CHECK (DMABUF_DISABLE))
{
gdk_display_prepare_gl (display, NULL);
gdk_display_add_dmabuf_downloader (display, gdk_dmabuf_get_direct_downloader (), builder);
}
#endif
display->dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (builder);
}
/**
* gdk_display_get_dmabuf_formats:
* @display: a `GdkDisplay`
*
* Returns the dma-buf formats that are supported on this display.
*
* GTK may use OpenGL or Vulkan to support some formats.
* Calling this function will then initialize them if they aren't yet.
*
* Returns: (transfer none): a `GdkDmabufFormats` object
*
* Since: 4.14
*/
GdkDmabufFormats *
gdk_display_get_dmabuf_formats (GdkDisplay *display)
{
init_dmabuf_formats (display);
return display->dmabuf_formats;
}
GdkDebugFlags GdkDebugFlags
gdk_display_get_debug_flags (GdkDisplay *display) gdk_display_get_debug_flags (GdkDisplay *display)
{ {
+4
View File
@@ -134,6 +134,10 @@ gboolean gdk_display_get_setting (GdkDisplay *display,
const char *name, const char *name,
GValue *value); GValue *value);
GDK_AVAILABLE_IN_4_14
GdkDmabufFormats *
gdk_display_get_dmabuf_formats (GdkDisplay *display);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplay, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplay, g_object_unref)
G_END_DECLS G_END_DECLS
+4
View File
@@ -25,6 +25,7 @@
#include "gdksurfaceprivate.h" #include "gdksurfaceprivate.h"
#include "gdkkeysprivate.h" #include "gdkkeysprivate.h"
#include "gdkdeviceprivate.h" #include "gdkdeviceprivate.h"
#include "gdkdmabufprivate.h"
#ifdef GDK_RENDERING_VULKAN #ifdef GDK_RENDERING_VULKAN
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
@@ -113,6 +114,9 @@ struct _GdkDisplay
guint have_egl_buffer_age : 1; guint have_egl_buffer_age : 1;
guint have_egl_no_config_context : 1; guint have_egl_no_config_context : 1;
guint have_egl_pixel_format_float : 1; guint have_egl_pixel_format_float : 1;
GdkDmabufFormats *dmabuf_formats;
const GdkDmabufDownloader *dmabuf_downloaders[4];
}; };
struct _GdkDisplayClass struct _GdkDisplayClass
+209
View File
@@ -0,0 +1,209 @@
/* gdkdmabuf.c
*
* Copyright 2023 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gdkdmabufprivate.h"
#include "gdkdebugprivate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkmemoryformatprivate.h"
#ifdef HAVE_LINUX_DMA_BUF_H
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/dma-buf.h>
#include <drm/drm_fourcc.h>
#include <epoxy/egl.h>
typedef struct _GdkDrmFormatInfo GdkDrmFormatInfo;
struct _GdkDrmFormatInfo
{
guint32 fourcc;
GdkMemoryFormat premultiplied_memory_format;
GdkMemoryFormat unpremultiplied_memory_format;
};
static GdkDrmFormatInfo supported_formats[] = {
{ DRM_FORMAT_ARGB8888, GDK_MEMORY_A8R8G8B8_PREMULTIPLIED, GDK_MEMORY_A8R8G8B8 },
{ DRM_FORMAT_RGBA8888, GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, GDK_MEMORY_R8G8B8A8 },
{ DRM_FORMAT_BGRA8888, GDK_MEMORY_B8G8R8A8_PREMULTIPLIED, GDK_MEMORY_B8G8R8A8 },
{ DRM_FORMAT_ABGR16161616F, GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED, GDK_MEMORY_R16G16B16A16_FLOAT },
{ DRM_FORMAT_RGB888, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8 },
{ DRM_FORMAT_BGR888, GDK_MEMORY_B8G8R8, GDK_MEMORY_B8G8R8 },
};
static GdkDrmFormatInfo *
get_drm_format_info (guint32 fourcc)
{
for (int i = 0; i < G_N_ELEMENTS (supported_formats); i++)
{
if (supported_formats[i].fourcc == fourcc)
return &supported_formats[i];
}
return NULL;
}
static void
gdk_dmabuf_direct_downloader_add_formats (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
GdkDmabufFormatsBuilder *builder)
{
gsize i;
for (i = 0; i < G_N_ELEMENTS (supported_formats); i++)
{
gdk_dmabuf_formats_builder_add_format (builder,
supported_formats[i].fourcc,
DRM_FORMAT_MOD_LINEAR);
}
}
static gboolean
gdk_dmabuf_direct_downloader_supports (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
const GdkDmabuf *dmabuf,
gboolean premultiplied,
GdkMemoryFormat *out_format,
GError **error)
{
GdkDrmFormatInfo *info;
info = get_drm_format_info (dmabuf->fourcc);
if (!info)
{
g_set_error (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
"Unsupported dmabuf format %.4s",
(char *) &dmabuf->fourcc);
return FALSE;
}
if (dmabuf->modifier != DRM_FORMAT_MOD_LINEAR)
{
g_set_error (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
"Unsupported dmabuf modifier %#lx (only linear buffers are supported)",
dmabuf->modifier);
return FALSE;
}
if (dmabuf->n_planes > 1)
{
g_set_error_literal (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_CREATION_FAILED,
"Multiplanar dmabufs are not supported");
return FALSE;
}
*out_format = premultiplied ? info->premultiplied_memory_format
: info->unpremultiplied_memory_format;
return TRUE;
}
static void
gdk_dmabuf_direct_downloader_do_download (GdkTexture *texture,
guchar *data,
gsize stride)
{
const GdkDmabuf *dmabuf;
gsize size;
unsigned int height;
gsize src_stride;
guchar *src_data;
int bpp;
GDK_DEBUG (DMABUF, "Using mmap() and memcpy() for downloading a dmabuf");
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
height = gdk_texture_get_height (texture);
bpp = gdk_memory_format_bytes_per_pixel (gdk_texture_get_format (texture));
src_stride = dmabuf->planes[0].stride;
size = dmabuf->planes[0].stride * height;
if (ioctl (dmabuf->planes[0].fd, DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_START|DMA_BUF_SYNC_READ }) < 0)
g_warning ("Failed to sync dma-buf: %s", g_strerror (errno));
src_data = mmap (NULL, size, PROT_READ, MAP_SHARED, dmabuf->planes[0].fd, dmabuf->planes[0].offset);
if (stride == src_stride)
memcpy (data, src_data, size);
else
{
for (unsigned int i = 0; i < height; i++)
memcpy (data + i * stride, src_data + i * src_stride, height * bpp);
}
munmap (src_data, size);
if (ioctl (dmabuf->planes[0].fd, DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_END|DMA_BUF_SYNC_READ }) < 0)
g_warning ("Failed to sync dma-buf: %s", g_strerror (errno));
}
static void
gdk_dmabuf_direct_downloader_download (const GdkDmabufDownloader *downloader,
GdkTexture *texture,
GdkMemoryFormat format,
guchar *data,
gsize stride)
{
GdkMemoryFormat src_format = gdk_texture_get_format (texture);
if (format == src_format)
gdk_dmabuf_direct_downloader_do_download (texture, data, stride);
else
{
const GdkDmabuf *dmabuf;
unsigned int width, height;
guchar *src_data;
gsize src_stride;
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
src_stride = dmabuf->planes[0].stride;
src_data = g_new (guchar, src_stride * height);
gdk_dmabuf_direct_downloader_do_download (texture, src_data, src_stride);
gdk_memory_convert (data, stride, format,
src_data, src_stride, src_format,
width, height);
g_free (src_data);
}
}
const GdkDmabufDownloader *
gdk_dmabuf_get_direct_downloader (void)
{
static const GdkDmabufDownloader downloader = {
gdk_dmabuf_direct_downloader_add_formats,
gdk_dmabuf_direct_downloader_supports,
gdk_dmabuf_direct_downloader_download,
};
return &downloader;
}
#endif /* HAVE_LINUX_DMA_BUF_H */
+215
View File
@@ -0,0 +1,215 @@
/* gdkdmabufformats.c
*
* Copyright 2023 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <glib-object.h>
#include "gdkdmabufformatsprivate.h"
/**
* GdkDmabufFormats:
*
* The `GdkDmabufFormats struct provides information about
* supported DMA buffer formats.
*
* You can query whether a given format is supported with
* [method@Gdk.DmabufFormats.contains] and you can iterate
* over the list of all supported formats with
* [method@Gdk.DmabufFormats.get_n_formats] and
* [method@Gdk.DmabufFormats.get_format].
*
* The list of supported formats is sorted by preference,
* with the best formats coming first.
*
* See [class@Gdk.DmabufTextureBuilder] for more information
* about DMA buffers.
*
* Note that DMA buffers only exist on Linux.
*
* Since: 4.14
*/
struct _GdkDmabufFormats
{
int ref_count;
gsize n_formats;
GdkDmabufFormat *formats;
};
G_DEFINE_BOXED_TYPE (GdkDmabufFormats, gdk_dmabuf_formats, gdk_dmabuf_formats_ref, gdk_dmabuf_formats_unref)
/**
* gdk_dmabuf_formats_ref:
* @formats: a `GdkDmabufFormats`
*
* Increases the reference count of @formats.
*
* Returns: the passed-in object
*
* Since: 4.14
*/
GdkDmabufFormats *
gdk_dmabuf_formats_ref (GdkDmabufFormats *formats)
{
formats->ref_count++;
return formats;
}
/**
* gdk_dmabuf_formats_unref:
* @formats: a `GdkDmabufFormats`
*
* Decreases the reference count of @formats.
*
* When the reference count reaches zero,
* the object is freed.
*
* Since: 4.14
*/
void
gdk_dmabuf_formats_unref (GdkDmabufFormats *formats)
{
formats->ref_count--;
if (formats->ref_count > 0)
return;
g_free (formats->formats);
g_free (formats);
}
/**
* gdk_dmabuf_formats_get_n_formats:
* @formats: a `GdkDmabufFormats`
*
* Returns the number of formats that the @formats object
* contains.
*
* Note that DMA buffers are a Linux concept, so on other
* platforms, [method@Gdk.DmabufFormats.get_n_formats] will
* always return zero.
*
* Returns: the number of formats
*
* Since: 4.14
*/
gsize
gdk_dmabuf_formats_get_n_formats (GdkDmabufFormats *formats)
{
return formats->n_formats;
}
/**
* gdk_dmabuf_formats_get_format:
* @formats: a `GdkDmabufFormats`
* @idx: the index of the format to return
* @fourcc: (out): return location for the format code
* @modifier: (out): return location for the format modifier
*
* Gets the fourcc code and modifier for a format
* that is contained in @formats.
*
* Since: 4.14
*/
void
gdk_dmabuf_formats_get_format (GdkDmabufFormats *formats,
gsize idx,
guint32 *fourcc,
guint64 *modifier)
{
GdkDmabufFormat *format;
g_return_if_fail (idx < formats->n_formats);
g_return_if_fail (fourcc != NULL);
g_return_if_fail (modifier != NULL);
format = &formats->formats[idx];
*fourcc = format->fourcc;
*modifier = format->modifier;
}
/**
* gdk_dmabuf_format_contains:
* @formats: a `GdkDmabufFormats`
* @fourcc: a format code
* @modfier: a format modifier
*
* Returns whether a given format is contained in @formats.
*
* Returns: `TRUE` if the format specified by the arguments
* is part of @formats
*
* Since: 4.14
*/
gboolean
gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
guint32 fourcc,
guint64 modifier)
{
for (gsize i = 0; i < formats->n_formats; i++)
{
GdkDmabufFormat *format = &formats->formats[i];
if (format->fourcc == fourcc && format->modifier == modifier)
return TRUE;
}
return FALSE;
}
/*< private >
* gdk_dmabuf_formats_new:
* @formats: the formats
* @n_formats: the length of @formats
*
* Creates a new `GdkDmabufFormats struct for
* the given formats.
*
* The @formats array is expected to be sorted
* by preference.
*
* Returns: (transfer full): the new `GdkDmabufFormats`
*
* Since: 4.14
*/
GdkDmabufFormats *
gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
gsize n_formats)
{
GdkDmabufFormats *self;
self = g_new0 (GdkDmabufFormats, 1);
self->ref_count = 1;
self->n_formats = n_formats;
self->formats = g_new (GdkDmabufFormat, n_formats);
memcpy (self->formats, formats, n_formats * sizeof (GdkDmabufFormat));
return self;
}
const GdkDmabufFormat *
gdk_dmabuf_formats_peek_formats (GdkDmabufFormats *self)
{
return self->formats;
}
+54
View File
@@ -0,0 +1,54 @@
/* gdkdmabufformats.h
*
* Copyright 2023 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_DMABUF_FORMATS (gdk_dmabuf_formats_get_type ())
GDK_AVAILABLE_IN_4_14
GType gdk_dmabuf_formats_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
GdkDmabufFormats * gdk_dmabuf_formats_ref (GdkDmabufFormats *formats);
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_formats_unref (GdkDmabufFormats *formats);
GDK_AVAILABLE_IN_4_14
gsize gdk_dmabuf_formats_get_n_formats (GdkDmabufFormats *formats) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_formats_get_format (GdkDmabufFormats *formats,
gsize idx,
guint32 *fourcc,
guint64 *modifier);
GDK_AVAILABLE_IN_4_14
gboolean gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
guint32 fourcc,
guint64 modifier) G_GNUC_PURE;
G_END_DECLS
+133
View File
@@ -0,0 +1,133 @@
/* gdkdmabufformats.c
*
* Copyright 2023 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include "gdkdmabufformatsbuilderprivate.h"
#include "gdkdmabufformatsprivate.h"
#define GDK_ARRAY_NAME gdk_dmabuf_formats_builder
#define GDK_ARRAY_TYPE_NAME GdkDmabufFormatsBuilder
#define GDK_ARRAY_ELEMENT_TYPE GdkDmabufFormat
#define GDK_ARRAY_BY_VALUE 1
#define GDK_ARRAY_PREALLOC 1024
#define GDK_ARRAY_NO_MEMSET 1
#include "gdk/gdkarrayimpl.c"
/* NB: We keep duplicates in the list for ease of use. Only when creating the final
* GdkDmabufFormats do we actually remove duplicates.
*/
GdkDmabufFormatsBuilder *
gdk_dmabuf_formats_builder_new (void)
{
GdkDmabufFormatsBuilder *result = g_new (GdkDmabufFormatsBuilder, 1);
gdk_dmabuf_formats_builder_init (result);
return result;
}
static int
gdk_dmabuf_format_compare (gconstpointer data_a,
gconstpointer data_b)
{
const GdkDmabufFormat *a = data_a;
const GdkDmabufFormat *b = data_b;
if (a->fourcc == b->fourcc)
return (a->modifier - b->modifier) >> 8 * (sizeof (gint64) - sizeof (gint));
else
return a->fourcc - b->fourcc;
}
static gboolean
gdk_dmabuf_format_equal (gconstpointer data_a,
gconstpointer data_b)
{
const GdkDmabufFormat *a = data_a;
const GdkDmabufFormat *b = data_b;
return a->fourcc == b->fourcc &&
a->modifier == b->modifier;
}
static void
gdk_dmabuf_formats_builder_sort (GdkDmabufFormatsBuilder *self)
{
qsort (gdk_dmabuf_formats_builder_get_data (self),
gdk_dmabuf_formats_builder_get_size (self),
sizeof (GdkDmabufFormat),
gdk_dmabuf_format_compare);
}
/* list must be sorted */
static void
gdk_dmabuf_formats_builder_remove_duplicates (GdkDmabufFormatsBuilder *self)
{
gsize i, j;
for (i = 1, j = 0; i < gdk_dmabuf_formats_builder_get_size (self); i++)
{
if (gdk_dmabuf_format_equal (gdk_dmabuf_formats_builder_get (self, i),
gdk_dmabuf_formats_builder_get (self, j)))
continue;
j++;
if (i != j)
*gdk_dmabuf_formats_builder_index (self, j) = *gdk_dmabuf_formats_builder_index (self, i);
}
}
GdkDmabufFormats *
gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self)
{
GdkDmabufFormats *formats;
gdk_dmabuf_formats_builder_sort (self);
gdk_dmabuf_formats_builder_remove_duplicates (self);
formats = gdk_dmabuf_formats_new (gdk_dmabuf_formats_builder_get_data (self),
gdk_dmabuf_formats_builder_get_size (self));
gdk_dmabuf_formats_builder_clear (self);
g_free (self);
return formats;
}
void
gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
guint32 fourcc,
guint64 modifier)
{
gdk_dmabuf_formats_builder_append (self, &(GdkDmabufFormat) { fourcc, modifier });
}
void
gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
GdkDmabufFormats *formats)
{
gdk_dmabuf_formats_builder_splice (self,
gdk_dmabuf_formats_builder_get_size (self),
0,
FALSE,
gdk_dmabuf_formats_peek_formats (formats),
gdk_dmabuf_formats_get_n_formats (formats));
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "gdkdmabufformats.h"
typedef struct GdkDmabufFormatsBuilder GdkDmabufFormatsBuilder;
GdkDmabufFormatsBuilder * gdk_dmabuf_formats_builder_new (void);
GdkDmabufFormats * gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self);
void gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
guint32 fourcc,
guint64 modifier);
void gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
GdkDmabufFormats *formats);
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include "gdkdmabufformats.h"
typedef struct _GdkDmabufFormat GdkDmabufFormat;
struct _GdkDmabufFormat
{
guint32 fourcc;
guint64 modifier;
};
GdkDmabufFormats * gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
gsize n_formats);
const GdkDmabufFormat * gdk_dmabuf_formats_peek_formats (GdkDmabufFormats *self);
+44
View File
@@ -0,0 +1,44 @@
#pragma once
#include "gdkdmabufformatsbuilderprivate.h"
#define GDK_DMABUF_MAX_PLANES 4
typedef struct _GdkDmabuf GdkDmabuf;
typedef struct _GdkDmabufDownloader GdkDmabufDownloader;
struct _GdkDmabuf
{
guint32 fourcc;
guint64 modifier;
unsigned int n_planes;
struct {
int fd;
unsigned int stride;
unsigned int offset;
} planes[GDK_DMABUF_MAX_PLANES];
};
struct _GdkDmabufDownloader
{
void (* add_formats) (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
GdkDmabufFormatsBuilder *builder);
gboolean (* supports) (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
const GdkDmabuf *dmabuf,
gboolean premultiplied,
GdkMemoryFormat *out_format,
GError **error);
void (* download) (const GdkDmabufDownloader *downloader,
GdkTexture *texture,
GdkMemoryFormat format,
guchar *data,
gsize stride);
};
#ifdef HAVE_LINUX_DMA_BUF_H
const GdkDmabufDownloader *
gdk_dmabuf_get_direct_downloader (void) G_GNUC_CONST;
#endif
+199
View File
@@ -0,0 +1,199 @@
/* gdkdmabuftexture.c
*
* Copyright 2023 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkdisplayprivate.h"
#include "gdkdmabufformatsbuilderprivate.h"
#include "gdktextureprivate.h"
#include <gdk/gdkglcontext.h>
#include <gdk/gdkgltexturebuilder.h>
#include <gdk/gdktexturedownloader.h>
#ifdef HAVE_LINUX_DMA_BUF_H
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/dma-buf.h>
#include <drm/drm_fourcc.h>
#include <epoxy/egl.h>
#endif
/**
* GdkDmabufTexture:
*
* A `GdkTexture` representing a dma-buf object.
*
* To create a `GdkDmabufTexture`, use the auxiliary
* [class@Gdk.DmabufTextureBuilder] object.
*
* Dma-buf textures can only be created on Linux.
*/
struct _GdkDmabufTexture
{
GdkTexture parent_instance;
GdkDisplay *display;
const GdkDmabufDownloader *downloader;
GdkDmabuf dmabuf;
GDestroyNotify destroy;
gpointer data;
};
struct _GdkDmabufTextureClass
{
GdkTextureClass parent_class;
};
G_DEFINE_QUARK (gdk-dmabuf-error-quark, gdk_dmabuf_error)
G_DEFINE_TYPE (GdkDmabufTexture, gdk_dmabuf_texture, GDK_TYPE_TEXTURE)
static void
gdk_dmabuf_texture_init (GdkDmabufTexture *self)
{
}
static void
gdk_dmabuf_texture_dispose (GObject *object)
{
GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (object);
if (self->destroy)
self->destroy (self->data);
G_OBJECT_CLASS (gdk_dmabuf_texture_parent_class)->dispose (object);
}
static void
gdk_dmabuf_texture_download (GdkTexture *texture,
GdkMemoryFormat format,
guchar *data,
gsize stride)
{
GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (texture);
self->downloader->download (self->downloader,
texture,
format,
data,
stride);
}
static void
gdk_dmabuf_texture_class_init (GdkDmabufTextureClass *klass)
{
GdkTextureClass *texture_class = GDK_TEXTURE_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
texture_class->download = gdk_dmabuf_texture_download;
gobject_class->dispose = gdk_dmabuf_texture_dispose;
}
GdkDisplay *
gdk_dmabuf_texture_get_display (GdkDmabufTexture *self)
{
return self->display;
}
const GdkDmabuf *
gdk_dmabuf_texture_get_dmabuf (GdkDmabufTexture *self)
{
return &self->dmabuf;
}
GdkTexture *
gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
GDestroyNotify destroy,
gpointer data,
GError **error)
{
#ifdef HAVE_LINUX_DMA_BUF_H
GdkDmabufTexture *self;
GdkTexture *update_texture;
GdkDisplay *display;
const GdkDmabuf *dmabuf;
GdkMemoryFormat format;
GError *local_error = NULL;
gsize i;
display = gdk_dmabuf_texture_builder_get_display (builder);
dmabuf = gdk_dmabuf_texture_builder_get_dmabuf (builder);
for (i = 0; display->dmabuf_downloaders[i] != NULL; i++)
{
if (local_error && g_error_matches (local_error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT))
g_clear_error (&local_error);
if (display->dmabuf_downloaders[i]->supports (display->dmabuf_downloaders[i],
display,
dmabuf,
gdk_dmabuf_texture_builder_get_premultiplied (builder),
&format,
local_error ? NULL : &local_error))
break;
}
if (display->dmabuf_downloaders[i] == NULL)
{
g_propagate_error (error, local_error);
return NULL;
}
self = g_object_new (GDK_TYPE_DMABUF_TEXTURE,
"width", gdk_dmabuf_texture_builder_get_width (builder),
"height", gdk_dmabuf_texture_builder_get_height (builder),
NULL);
GDK_TEXTURE (self)->format = format;
g_set_object (&self->display, display);
self->downloader = display->dmabuf_downloaders[i];
self->dmabuf = *dmabuf;
self->destroy = destroy;
self->data = data;
update_texture = gdk_dmabuf_texture_builder_get_update_texture (builder);
if (update_texture)
{
cairo_region_t *update_region = gdk_dmabuf_texture_builder_get_update_region (builder);
if (update_region)
{
update_region = cairo_region_copy (update_region);
cairo_region_intersect_rectangle (update_region,
&(cairo_rectangle_int_t) {
0, 0,
update_texture->width, update_texture->height
});
gdk_texture_set_diff (GDK_TEXTURE (self), update_texture, update_region);
}
}
return GDK_TEXTURE (self);
#else /* !HAVE_LINUX_DMA_BUF_H */
g_set_error_literal (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_NOT_AVAILABLE,
"dmabuf support disabled at compile-time.");
return NULL;
#endif
}
+48
View File
@@ -0,0 +1,48 @@
/* gdkdmabuftexture.h
*
* Copyright 2023 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdktypes.h>
#include <gdk/gdktexture.h>
G_BEGIN_DECLS
#define GDK_TYPE_DMABUF_TEXTURE (gdk_dmabuf_texture_get_type ())
#define GDK_DMABUF_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_DMABUF_TEXTURE, GdkDmabufTexture))
#define GDK_IS_DMABUF_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_DMABUF_TEXTURE))
#define GDK_DMABUF_ERROR (gdk_dmabuf_error_quark ())
typedef struct _GdkDmabufTexture GdkDmabufTexture;
typedef struct _GdkDmabufTextureClass GdkDmabufTextureClass;
GDK_AVAILABLE_IN_4_14
GType gdk_dmabuf_texture_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
GQuark gdk_dmabuf_error_quark (void) G_GNUC_CONST;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDmabufTexture, g_object_unref)
G_END_DECLS
+987
View File
@@ -0,0 +1,987 @@
/*
* Copyright © 2023 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Matthias Clasen <mclasen@redhat.com>
*/
#include "config.h"
#include "gdkdmabuftexturebuilder.h"
#include "gdkdebugprivate.h"
#include "gdkdisplay.h"
#include "gdkenumtypes.h"
#include "gdkdmabuftextureprivate.h"
#include <cairo-gobject.h>
struct _GdkDmabufTextureBuilder
{
GObject parent_instance;
GdkDisplay *display;
unsigned int width;
unsigned int height;
gboolean premultiplied;
GdkDmabuf dmabuf;
GdkTexture *update_texture;
cairo_region_t *update_region;
};
struct _GdkDmabufTextureBuilderClass
{
GObjectClass parent_class;
};
/**
* GdkDmabufTextureBuilder:
*
* `GdkDmabufTextureBuilder` is a builder used to construct [class@Gdk.Texture]
* objects from DMA buffers.
*
* DMA buffers are commonly called **_dma-bufs_**.
*
* DMA buffers a feature of the Linux kernel to enable efficient buffer and
* memory sharing between hardware such as codecs, GPUs, displays, cameras and the
* kernel drivers controlling them. For example, a decoder may want its output to
* be directly shared with the display server for rendering without a copy.
*
* Any device driver which participates in DMA buffer sharing, can do so as either
* the exporter or importer of buffers (or both).
*
* The memory that is shared via DMA buffers is usually stored in non-system memory
* (maybe in device's local memory or something else not directly accessible by the
* CPU), and accessing this memory from the CPU may have higher than usual overhead.
*
* In particular for graphics data, it is not uncommon that data consists of multiple
* separate blocks of memory, for example one block for each of the red, green and
* blue channels. These blocks are called **_planes_**. DMA buffers can have up to
* four planes. Even if the memory is a single block, the data can be organized in
* multiple planes, by specifying offsets from the beginning of the data.
*
* DMA buffers are exposed to user-space as file descriptors allowing to pass them
* between processes. If a DMA buffer has multiple planes, there is one file
* descriptor per plane.
*
* The format of the data (for graphics data, essentially its colorspace) is described
* by a 32-bit integer. These format identifiers are defined in the header file
* [drm/drm_fourcc.h](https://github.com/torvalds/linux/blob/master/include/uapi/drm/drm_fourcc.h)
* and commonly referred to as **_fourcc_** values, since they are identified by 4 ASCII
* characters. Additionally, each DMA buffer has a **_modifier_**, which is a 64-bit integer
* that describes driver-specific details of the memory layout, such as tiling or compression.
*
* The operation of `GdkDmabufTextureBuilder` is quite simple: Create a texture builder,
* set all the necessary properties, and then call [method@Gdk.DmabufTextureBuilder.build]
* to create the new texture.
*
* The required properties for a dma-buf texture are
* - The width and height in pixels
* - The `fourcc` code and `modifier` which identify the format and memory layout of the dma-buf
* - The file descriptor, offset and stride for each of the planes
*
* `GdkDmabufTextureBuilder` can be used for quick one-shot construction of
* textures as well as kept around and reused to construct multiple textures.
*
* Since: 4.14
*/
enum
{
PROP_0,
PROP_DISPLAY,
PROP_WIDTH,
PROP_HEIGHT,
PROP_FOURCC,
PROP_MODIFIER,
PROP_PREMULTIPLIED,
PROP_N_PLANES,
PROP_UPDATE_REGION,
PROP_UPDATE_TEXTURE,
N_PROPS
};
G_DEFINE_TYPE (GdkDmabufTextureBuilder, gdk_dmabuf_texture_builder, G_TYPE_OBJECT)
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gdk_dmabuf_texture_builder_dispose (GObject *object)
{
GdkDmabufTextureBuilder *self = GDK_DMABUF_TEXTURE_BUILDER (object);
g_clear_object (&self->update_texture);
g_clear_pointer (&self->update_region, cairo_region_destroy);
G_OBJECT_CLASS (gdk_dmabuf_texture_builder_parent_class)->dispose (object);
}
static void
gdk_dmabuf_texture_builder_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GdkDmabufTextureBuilder *self = GDK_DMABUF_TEXTURE_BUILDER (object);
switch (property_id)
{
case PROP_DISPLAY:
g_value_set_object (value, self->display);
break;
case PROP_WIDTH:
g_value_set_uint (value, self->width);
break;
case PROP_HEIGHT:
g_value_set_uint (value, self->height);
break;
case PROP_FOURCC:
g_value_set_uint (value, self->dmabuf.fourcc);
break;
case PROP_MODIFIER:
g_value_set_uint64 (value, self->dmabuf.modifier);
break;
case PROP_PREMULTIPLIED:
g_value_set_boolean (value, self->premultiplied);
break;
case PROP_N_PLANES:
g_value_set_uint (value, self->dmabuf.n_planes);
break;
case PROP_UPDATE_REGION:
g_value_set_boxed (value, self->update_region);
break;
case PROP_UPDATE_TEXTURE:
g_value_set_object (value, self->update_texture);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gdk_dmabuf_texture_builder_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GdkDmabufTextureBuilder *self = GDK_DMABUF_TEXTURE_BUILDER (object);
switch (property_id)
{
case PROP_DISPLAY:
gdk_dmabuf_texture_builder_set_display (self, g_value_get_object (value));
break;
case PROP_WIDTH:
gdk_dmabuf_texture_builder_set_width (self, g_value_get_uint (value));
break;
case PROP_HEIGHT:
gdk_dmabuf_texture_builder_set_height (self, g_value_get_uint (value));
break;
case PROP_FOURCC:
gdk_dmabuf_texture_builder_set_fourcc (self, g_value_get_uint (value));
break;
case PROP_MODIFIER:
gdk_dmabuf_texture_builder_set_modifier (self, g_value_get_uint64 (value));
break;
case PROP_PREMULTIPLIED:
gdk_dmabuf_texture_builder_set_premultiplied (self, g_value_get_boolean (value));
break;
case PROP_N_PLANES:
gdk_dmabuf_texture_builder_set_n_planes (self, g_value_get_uint (value));
break;
case PROP_UPDATE_REGION:
gdk_dmabuf_texture_builder_set_update_region (self, g_value_get_boxed (value));
break;
case PROP_UPDATE_TEXTURE:
gdk_dmabuf_texture_builder_set_update_texture (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = gdk_dmabuf_texture_builder_dispose;
gobject_class->get_property = gdk_dmabuf_texture_builder_get_property;
gobject_class->set_property = gdk_dmabuf_texture_builder_set_property;
/**
* GdkDmabufTextureBuilder:display: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_display org.gdk.Property.set=gdk_dmabuf_texture_builder_set_display)
*
* The display that this texture will be used on.
*
* Since: 4.14
*/
properties[PROP_DISPLAY] =
g_param_spec_object ("display", NULL, NULL,
GDK_TYPE_DISPLAY,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:width: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_width org.gdk.Property.set=gdk_dmabuf_texture_builder_set_width)
*
* The width of the texture.
*
* Since: 4.14
*/
properties[PROP_WIDTH] =
g_param_spec_uint ("width", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:height: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_height org.gdk.Property.set=gdk_dmabuf_texture_builder_set_height)
*
* The height of the texture.
*
* Since: 4.14
*/
properties[PROP_HEIGHT] =
g_param_spec_uint ("height", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:fourcc: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_fourcc org.gdk.Property.set=gdk_dmabuf_texture_builder_set_fourcc)
*
* The format of the texture, as a fourcc value.
*
* Since: 4.14
*/
properties[PROP_FOURCC] =
g_param_spec_uint ("fourcc", NULL, NULL,
0, 0xffffffff, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:modifier:
*
* The modifier.
*
* Since: 4.14
*/
properties[PROP_MODIFIER] =
g_param_spec_uint64 ("modifier", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:premultiplied:
*
* Whether the alpha channel is premultiplied into the others.
*
* Only relevant if the format has alpha.
*
* Since: 4.14
*/
properties[PROP_PREMULTIPLIED] =
g_param_spec_boolean ("premultiplied", NULL, NULL,
TRUE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:n-planes: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_n_planes org.gdk.Property.set=gdk_dmabuf_texture_builder_set_n_planes)
*
* The number of planes of the texture.
*
* Note that you can set properties for other planes,
* but they will be ignored when constructing the texture.
*
* Since: 4.14
*/
properties[PROP_N_PLANES] =
g_param_spec_uint ("n-planes", NULL, NULL,
0, 4, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:update-region: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_update_region org.gdk.Property.set=gdk_dmabuf_texture_builder_set_update_region)
*
* The update region for [property@Gdk.GLTextureBuilder:update-texture].
*
* Since: 4.14
*/
properties[PROP_UPDATE_REGION] =
g_param_spec_boxed ("update-region", NULL, NULL,
CAIRO_GOBJECT_TYPE_REGION,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:update-texture: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_update_texture org.gdk.Property.set=gdk_dmabuf_texture_builder_set_update_texture)
*
* The texture [property@Gdk.GLTextureBuilder:update-region] is an update for.
*
* Since: 4.14
*/
properties[PROP_UPDATE_TEXTURE] =
g_param_spec_object ("update-texture", NULL, NULL,
GDK_TYPE_TEXTURE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gdk_dmabuf_texture_builder_init (GdkDmabufTextureBuilder *self)
{
self->premultiplied = TRUE;
for (int i = 0; i < GDK_DMABUF_MAX_PLANES; i++)
self->dmabuf.planes[i].fd = -1;
}
/**
* gdk_dmabuf_texture_builder_new: (constructor):
*
* Creates a new texture builder.
*
* Returns: the new `GdkTextureBuilder`
*
* Since: 4.14
**/
GdkDmabufTextureBuilder *
gdk_dmabuf_texture_builder_new (void)
{
return g_object_new (GDK_TYPE_DMABUF_TEXTURE_BUILDER, NULL);
}
/**
* gdk_dmabuf_texture_builder_get_display:
* @self: a `GdkDmabufTextureBuilder
*
* Returns the display that this texture builder is
* associated with.
*
* Returns: (transfer none) (nullable): the display
*
* Since: 4.14
*/
GdkDisplay *
gdk_dmabuf_texture_builder_get_display (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), NULL);
return self->display;
}
/**
* gdk_dmabuf_texture_builder_set_display:
* @self: a `GdkDmabufTextureBuilder
* @display: the display
*
* Sets the display that this texture builder is
* associated with.
*
* The display is used to determine the supported
* dma-buf formats.
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_display (GdkDmabufTextureBuilder *self,
GdkDisplay *display)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
if (g_set_object (&self->display, display))
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DISPLAY]);
}
/**
* gdk_dmabuf_texture_builder_get_width: (attributes org.gdk.Method.get_property=width)
* @self: a `GdkDmabufTextureBuilder`
*
* Gets the width previously set via gdk_dmabuf_texture_builder_set_width() or
* 0 if the width wasn't set.
*
* Returns: The width
*
* Since: 4.14
*/
unsigned int
gdk_dmabuf_texture_builder_get_width (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
return self->width;
}
/**
* gdk_dmabuf_texture_builder_set_width: (attributes org.gdk.Method.set_property=width)
* @self: a `GdkDmabufTextureBuilder`
* @width: The texture's width or 0 to unset
*
* Sets the width of the texture.
*
* The width must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_width (GdkDmabufTextureBuilder *self,
unsigned int width)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
if (self->width == width)
return;
self->width = width;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_WIDTH]);
}
/**
* gdk_dmabuf_texture_builder_get_height: (attributes org.gdk.Method.get_property=height)
* @self: a `GdkDmabufTextureBuilder`
*
* Gets the height previously set via gdk_dmabuf_texture_builder_set_height() or
* 0 if the height wasn't set.
*
* Returns: The height
*
* Since: 4.14
*/
unsigned int
gdk_dmabuf_texture_builder_get_height (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
return self->height;
}
/**
* gdk_dmabuf_texture_builder_set_height: (attributes org.gdk.Method.set_property=height)
* @self: a `GdkDmabufTextureBuilder`
* @height: the texture's height or 0 to unset
*
* Sets the height of the texture.
*
* The height must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_height (GdkDmabufTextureBuilder *self,
unsigned int height)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
if (self->height == height)
return;
self->height = height;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HEIGHT]);
}
/**
* gdk_dmabuf_texture_builder_get_fourcc: (attributes org.gdk.Method.get_property=fourcc)
* @self: a `GdkDmabufTextureBuilder`
*
* Gets the format previously set via gdk_dmabuf_texture_builder_set_fourcc()
* or 0 if the format wasn't set.
*
* The format is specified as a fourcc code.
*
* Returns: The format
*
* Since: 4.14
*/
guint32
gdk_dmabuf_texture_builder_get_fourcc (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
return self->dmabuf.fourcc;
}
/**
* gdk_dmabuf_texture_builder_set_fourcc: (attributes org.gdk.Method.set_property=fourcc)
* @self: a `GdkDmabufTextureBuilder`
* @fourcc: the texture's format or 0 to unset
*
* Sets the format of the texture.
*
* The format is specified as a fourcc code.
*
* The format must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_fourcc (GdkDmabufTextureBuilder *self,
guint32 fourcc)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
if (self->dmabuf.fourcc == fourcc)
return;
self->dmabuf.fourcc = fourcc;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FOURCC]);
}
/**
* gdk_dmabuf_texture_builder_get_modifier:
* @self: a `GdkDmabufTextureBuilder`
*
* Gets the modifier value.
*
* Returns: the modifier
*
* Since: 4.14
*/
guint64
gdk_dmabuf_texture_builder_get_modifier (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
return self->dmabuf.modifier;
}
/**
* gdk_dmabuf_texture_builder_set_modifier:
* @self: a `GdkDmabufTextureBuilder`
* @modifier: the modifier value
*
* Sets the modifier.
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_modifier (GdkDmabufTextureBuilder *self,
guint64 modifier)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
if (self->dmabuf.modifier == modifier)
return;
self->dmabuf.modifier = modifier;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODIFIER]);
}
/**
* gdk_dmabuf_texture_builder_get_n_planes: (attributes org.gdk.Method.get_property=n-planes)
* @self: a `GdkDmabufTextureBuilder`
*
* Gets the number of planes.
*
* Returns: The number of planes
*
* Since: 4.14
*/
unsigned int
gdk_dmabuf_texture_builder_get_n_planes (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
return self->dmabuf.n_planes;
}
/**
* gdk_dmabuf_texture_builder_get_premultiplied:
* @self: a `GdkDmabufTextureBuilder`
*
* Whether the data is premultiplied.
*
* Returns: whether the data is premultiplied
*
* Since: 4.14
*/
gboolean
gdk_dmabuf_texture_builder_get_premultiplied (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), TRUE);
return self->premultiplied;
}
/**
* gdk_dmabuf_texture_builder_set_premultiplied:
* @self: a `GdkDmabufTextureBuilder`
* @premultiplied: whether the data is premultiplied
*
* Sets whether the data is premultiplied.
*
* Unless otherwise specified, all formats including alpha channels are assumed
* to be premultiplied.
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_premultiplied (GdkDmabufTextureBuilder *self,
gboolean premultiplied)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
if (self->premultiplied == premultiplied)
return;
self->premultiplied = premultiplied;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PREMULTIPLIED]);
}
/**
* gdk_dmabuf_texture_builder_set_n_planes: (attributes org.gdk.Method.set_property=n-planes)
* @self: a `GdkDmabufTextureBuilder`
* @n_planes: the number of planes
*
* Sets the number of planes of the texture.
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_n_planes (GdkDmabufTextureBuilder *self,
unsigned int n_planes)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
if (self->dmabuf.n_planes == n_planes)
return;
self->dmabuf.n_planes = n_planes;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_PLANES]);
}
/**
* gdk_dmabuf_texture_builder_get_fd:
* @self: a `GdkDmabufTextureBuilder`
* @plane: the plane to get the fd for
*
* Gets the file descriptor for a plane.
*
* Returns: the file descriptor
*
* Since: 4.14
*/
int
gdk_dmabuf_texture_builder_get_fd (GdkDmabufTextureBuilder *self,
unsigned int plane)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
g_return_val_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES, 0);
return self->dmabuf.planes[plane].fd;
}
/**
* gdk_dmabuf_texture_builder_set_fd:
* @self: a `GdkDmabufTextureBuilder`
* @plane: the plane to set the fd for
* @fd: the file descriptor
*
* Sets the file descriptor for a plane.
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_fd (GdkDmabufTextureBuilder *self,
unsigned int plane,
int fd)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
g_return_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES);
if (self->dmabuf.planes[plane].fd == fd)
return;
self->dmabuf.planes[plane].fd = fd;
}
/**
* gdk_dmabuf_texture_builder_get_stride:
* @self: a `GdkDmabufTextureBuilder`
* @plane: the plane to get the stride for
*
* Gets the stride value for a plane.
*
* Returns: the stride
*
* Since: 4.14
*/
unsigned int
gdk_dmabuf_texture_builder_get_stride (GdkDmabufTextureBuilder *self,
unsigned int plane)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
g_return_val_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES, 0);
return self->dmabuf.planes[plane].stride;
}
/**
* gdk_dmabuf_texture_builder_set_stride:
* @self: a `GdkDmabufTextureBuilder`
* @plane: the plane to set the stride for
* @stride: the stride value
*
* Sets the stride for a plane.
*
* The stride must be set for all planes before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_stride (GdkDmabufTextureBuilder *self,
unsigned int plane,
unsigned int stride)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
g_return_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES);
if (self->dmabuf.planes[plane].stride == stride)
return;
self->dmabuf.planes[plane].stride = stride;
}
/**
* gdk_dmabuf_texture_builder_get_offset:
* @self: a `GdkDmabufTextureBuilder`
* @plane: the plane to get the offset for
*
* Gets the offset value for a plane.
*
* Returns: the offset
*
* Since: 4.14
*/
unsigned int
gdk_dmabuf_texture_builder_get_offset (GdkDmabufTextureBuilder *self,
unsigned int plane)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
g_return_val_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES, 0);
return self->dmabuf.planes[plane].offset;
}
/**
* gdk_dmabuf_texture_builder_set_offset:
* @self: a `GdkDmabufTextureBuilder`
* @plane: the plane to set the offset for
* @offset: the offset value
*
* Sets the offset for a plane.
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_offset (GdkDmabufTextureBuilder *self,
unsigned int plane,
unsigned int offset)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
g_return_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES);
if (self->dmabuf.planes[plane].offset == offset)
return;
self->dmabuf.planes[plane].offset = offset;
}
/**
* gdk_dmabuf_texture_builder_get_update_texture: (attributes org.gdk.Method.get_property=update_texture)
* @self: a `GdkDmabufTextureBuilder`
*
* Gets the texture previously set via gdk_dmabuf_texture_builder_set_update_texture() or
* %NULL if none was set.
*
* Returns: (transfer none) (nullable): The texture
*
* Since: 4.14
*/
GdkTexture *
gdk_dmabuf_texture_builder_get_update_texture (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), NULL);
return self->update_texture;
}
/**
* gdk_dmabuf_texture_builder_set_update_texture: (attributes org.gdk.Method.set_property=update_texture)
* @self: a `GdkDmabufTextureBuilder`
* @texture: (nullable): the texture to update
*
* Sets the texture to be updated by this texture. See
* [method@Gdk.DmabufTextureBuilder.set_update_region] for an explanation.
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_update_texture (GdkDmabufTextureBuilder *self,
GdkTexture *texture)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
g_return_if_fail (texture == NULL || GDK_IS_TEXTURE (texture));
if (!g_set_object (&self->update_texture, texture))
return;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_UPDATE_TEXTURE]);
}
/**
* gdk_dmabuf_texture_builder_get_update_region: (attributes org.gdk.Method.get_property=update_region)
* @self: a `GdkDmabufTextureBuilder`
*
* Gets the region previously set via gdk_dmabuf_texture_builder_set_update_region() or
* %NULL if none was set.
*
* Returns: (transfer none) (nullable): The region
*
* Since: 4.14
*/
cairo_region_t *
gdk_dmabuf_texture_builder_get_update_region (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), NULL);
return self->update_region;
}
/**
* gdk_dmabuf_texture_builder_set_update_region: (attributes org.gdk.Method.set_property=update_region)
* @self: a `GdkDmabufTextureBuilder`
* @region: (nullable): the region to update
*
* Sets the region to be updated by this texture. Together with
* [property@Gdk.DmabufTextureBuilder:update-texture] this describes an
* update of a previous texture.
*
* When rendering animations of large textures, it is possible that
* consecutive textures are only updating contents in parts of the texture.
* It is then possible to describe this update via these two properties,
* so that GTK can avoid rerendering parts that did not change.
*
* An example would be a screen recording where only the mouse pointer moves.
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_update_region (GdkDmabufTextureBuilder *self,
cairo_region_t *region)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
if (self->update_region == region)
return;
g_clear_pointer (&self->update_region, cairo_region_destroy);
if (region)
self->update_region = cairo_region_reference (region);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_UPDATE_REGION]);
}
/**
* gdk_dmabuf_texture_builder_build:
* @self: a `GdkDmabufTextureBuilder`
* @destroy: (nullable): destroy function to be called when the texture is
* released
* @data: user data to pass to the destroy function
* @error: Return location for an error
*
* Builds a new `GdkTexture` with the values set up in the builder.
*
* It is a programming error to call this function if any mandatory
* property has not been set.
*
* If the dmabuf is not supported by GTK, %NULL will be returned and @error will be set.
*
* The `destroy` function gets called when the returned texture gets released.
*
* It is possible to call this function multiple times to create multiple textures,
* possibly with changing properties in between.
*
* It is the responsibility of the caller to keep the file descriptors for the planes
* open until the created texture is no longer used, and close them afterwards (possibly
* using the @destroy notify).
*
* Not all formats defined in the `drm_fourcc.h` header are supported. You can use
* [method@Gdk.Display.get_dmabuf_formats] to get a list of supported formats.
*
* Returns: (transfer full) (nullable): a newly built `GdkTexture` or `NULL`
* if the format is not supported
*
* Since: 4.14
*/
GdkTexture *
gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self,
GDestroyNotify destroy,
gpointer data,
GError **error)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), NULL);
g_return_val_if_fail (destroy == NULL || data != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
g_return_val_if_fail (self->width > 0, NULL);
g_return_val_if_fail (self->height > 0, NULL);
g_return_val_if_fail (self->dmabuf.fourcc != 0, NULL);
g_return_val_if_fail (self->dmabuf.n_planes > 0, NULL);
for (int i = 0; i < self->dmabuf.n_planes; i++)
g_return_val_if_fail (self->dmabuf.planes[i].fd != -1 || self->dmabuf.planes[i].offset != 0, NULL);
if (GDK_DEBUG_CHECK (DMABUF_DISABLE))
{
g_set_error_literal (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_NOT_AVAILABLE,
"dmabuf support disabled via GDK_DEBUG environment variable");
return NULL;
}
return gdk_dmabuf_texture_new_from_builder (self, destroy, data, error);
}
const GdkDmabuf *
gdk_dmabuf_texture_builder_get_dmabuf (GdkDmabufTextureBuilder *self)
{
return &self->dmabuf;
}
+122
View File
@@ -0,0 +1,122 @@
/*
* Copyright © 2023 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Matthias Clasen <mclasen@redhat.com>
*/
#pragma once
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_DMABUF_TEXTURE_BUILDER (gdk_dmabuf_texture_builder_get_type ())
GDK_AVAILABLE_IN_4_14
GDK_DECLARE_INTERNAL_TYPE (GdkDmabufTextureBuilder, gdk_dmabuf_texture_builder, GDK, DMABUF_TEXTURE_BUILDER, GObject)
GDK_AVAILABLE_IN_4_14
GdkDmabufTextureBuilder *gdk_dmabuf_texture_builder_new (void);
GDK_AVAILABLE_IN_4_14
GdkDisplay * gdk_dmabuf_texture_builder_get_display (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_display (GdkDmabufTextureBuilder *self,
GdkDisplay *display);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_width (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_width (GdkDmabufTextureBuilder *self,
unsigned int width);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_height (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_height (GdkDmabufTextureBuilder *self,
unsigned int height);
GDK_AVAILABLE_IN_4_14
guint32 gdk_dmabuf_texture_builder_get_fourcc (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_fourcc (GdkDmabufTextureBuilder *self,
guint32 fourcc);
GDK_AVAILABLE_IN_4_14
guint64 gdk_dmabuf_texture_builder_get_modifier (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_modifier (GdkDmabufTextureBuilder *self,
guint64 modifier);
GDK_AVAILABLE_IN_4_14
gboolean gdk_dmabuf_texture_builder_get_premultiplied (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_premultiplied (GdkDmabufTextureBuilder *self,
gboolean premultiplied);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_n_planes (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_n_planes (GdkDmabufTextureBuilder *self,
unsigned int n_planes);
GDK_AVAILABLE_IN_4_14
int gdk_dmabuf_texture_builder_get_fd (GdkDmabufTextureBuilder *self,
unsigned int plane) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_fd (GdkDmabufTextureBuilder *self,
unsigned int plane,
int fd);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_stride (GdkDmabufTextureBuilder *self,
unsigned int plane) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_stride (GdkDmabufTextureBuilder *self,
unsigned int plane,
unsigned int stride);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_offset (GdkDmabufTextureBuilder *self,
unsigned int plane) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_offset (GdkDmabufTextureBuilder *self,
unsigned int plane,
unsigned int offset);
GDK_AVAILABLE_IN_4_14
GdkTexture * gdk_dmabuf_texture_builder_get_update_texture (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_update_texture (GdkDmabufTextureBuilder *self,
GdkTexture *texture);
GDK_AVAILABLE_IN_4_14
cairo_region_t * gdk_dmabuf_texture_builder_get_update_region (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_update_region (GdkDmabufTextureBuilder *self,
cairo_region_t *region);
GDK_AVAILABLE_IN_4_14
GdkTexture * gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self,
GDestroyNotify destroy,
gpointer data,
GError **error);
G_END_DECLS
+21
View File
@@ -0,0 +1,21 @@
#pragma once
#include "gdkdmabuftexture.h"
#include "gdkdmabuftexturebuilder.h"
#include "gdkdmabufprivate.h"
G_BEGIN_DECLS
const GdkDmabuf * gdk_dmabuf_texture_builder_get_dmabuf (GdkDmabufTextureBuilder *builder);
GdkTexture * gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
GDestroyNotify destroy,
gpointer data,
GError **error);
GdkDisplay * gdk_dmabuf_texture_get_display (GdkDmabufTexture *self);
const GdkDmabuf * gdk_dmabuf_texture_get_dmabuf (GdkDmabufTexture *self);
G_END_DECLS
+16
View File
@@ -142,6 +142,22 @@ typedef enum
GDK_BUTTON4_MASK|GDK_BUTTON5_MASK) GDK_BUTTON4_MASK|GDK_BUTTON5_MASK)
/**
* GdkDmabufError:
* @GDK_DMABUF_ERROR_NOT_AVAILABLE: Dmabuf support is not available, because the OS
* is not Linux, or it was explicitly disabled at compile- or runtime
* @GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT: The requested format is not supported
* @GDK_DMABUF_ERROR_CREATION_FAILED: GTK failed to create the resource for other
* reasons
*
* Error enumeration for `GdkDmabufTexture`.
*/
typedef enum {
GDK_DMABUF_ERROR_NOT_AVAILABLE,
GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
GDK_DMABUF_ERROR_CREATION_FAILED,
} GdkDmabufError;
/** /**
* GdkGLError: * GdkGLError:
* @GDK_GL_ERROR_NOT_AVAILABLE: OpenGL support is not available * @GDK_GL_ERROR_NOT_AVAILABLE: OpenGL support is not available
+50
View File
@@ -1715,6 +1715,56 @@ gdk_gl_context_get_version (GdkGLContext *context,
*minor = gdk_gl_version_get_minor (&priv->gl_version); *minor = gdk_gl_version_get_minor (&priv->gl_version);
} }
const char *
gdk_gl_context_get_glsl_version_string (GdkGLContext *self)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
if (priv->api == GDK_GL_API_GL)
{
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 6)))
return "#version 460";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 5)))
return "#version 450";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 4)))
return "#version 440";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 3)))
return "#version 430";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 2)))
return "#version 420";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 1)))
return "#version 410";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 0)))
return "#version 400";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 3)))
return "#version 330";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
return "#version 150";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 1)))
return "#version 140";
else
return "#version 130";
}
else if (priv->api == GDK_GL_API_GLES)
{
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
return "#version 320 es";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 1)))
return "#version 310 es";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
return "#version 300 es";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
return "#version 300 es";
else
return "#version 100";
}
else
{
/* must be realized to be called */
g_assert_not_reached ();
}
}
/** /**
* gdk_gl_context_clear_current: * gdk_gl_context_clear_current:
* *
+2
View File
@@ -147,6 +147,8 @@ void gdk_gl_context_label_object_printf (GdkGLContext
const char *format, const char *format,
...) G_GNUC_PRINTF (4, 5); ...) G_GNUC_PRINTF (4, 5);
const char * gdk_gl_context_get_glsl_version_string (GdkGLContext *self);
gboolean gdk_gl_context_has_debug (GdkGLContext *self) G_GNUC_PURE; gboolean gdk_gl_context_has_debug (GdkGLContext *self) G_GNUC_PURE;
gboolean gdk_gl_context_use_es_bgra (GdkGLContext *context); gboolean gdk_gl_context_use_es_bgra (GdkGLContext *context);
+5 -2
View File
@@ -24,13 +24,16 @@
#include "gdksnapshotprivate.h" #include "gdksnapshotprivate.h"
#include "gdkprivate.h" #include "gdkprivate.h"
#include <graphene.h>
/* HACK: So we don't need to include any (not-yet-created) GSK or GTK headers */ /* HACK: So we don't need to include any (not-yet-created) GSK or GTK headers */
GdkSnapshot * gtk_snapshot_new (void); GdkSnapshot * gtk_snapshot_new (void);
void gtk_snapshot_push_debug (GdkSnapshot *snapshot, void gtk_snapshot_push_debug (GdkSnapshot *snapshot,
const char *message, const char *message,
...) G_GNUC_PRINTF (2, 3); ...) G_GNUC_PRINTF (2, 3);
void gtk_snapshot_pop (GdkSnapshot *snapshot); void gtk_snapshot_pop (GdkSnapshot *snapshot);
GdkPaintable * gtk_snapshot_free_to_paintable (GdkSnapshot *snapshot); GdkPaintable * gtk_snapshot_free_to_paintable (GdkSnapshot *snapshot,
const graphene_size_t *size);
/** /**
* GdkPaintable: * GdkPaintable:
@@ -118,7 +121,7 @@ gdk_paintable_default_get_current_image (GdkPaintable *paintable)
snapshot = gtk_snapshot_new (); snapshot = gtk_snapshot_new ();
gdk_paintable_snapshot (paintable, snapshot, width, height); gdk_paintable_snapshot (paintable, snapshot, width, height);
return gtk_snapshot_free_to_paintable (snapshot); return gtk_snapshot_free_to_paintable (snapshot, NULL);
} }
static GdkPaintableFlags static GdkPaintableFlags
+1 -1
View File
@@ -40,7 +40,7 @@ struct _GdkIOPipe
GCond cond; GCond cond;
guchar *buffer; guchar *buffer;
gsize size; gsize size;
GdkIOPipeState state : 2; guint state : 2; /* GdkIOPipeState */
guint input_closed : 1; guint input_closed : 1;
guint output_closed : 1; guint output_closed : 1;
}; };
+1 -1
View File
@@ -254,7 +254,7 @@ maybe_flip_position (int bounds_pos,
*flipped = TRUE; *flipped = TRUE;
secondary = rect_pos + (1 - rect_sign) * rect_size / 2 - offset - (1 - surface_sign) * surface_size / 2; secondary = rect_pos + (1 - rect_sign) * rect_size / 2 - offset - (1 - surface_sign) * surface_size / 2;
if (secondary >= bounds_pos && secondary + surface_size <= bounds_pos + bounds_size) if ((secondary >= bounds_pos && secondary + surface_size <= bounds_pos + bounds_size) || primary > bounds_pos + bounds_size)
return secondary; return secondary;
*flipped = FALSE; *flipped = FALSE;
+5 -3
View File
@@ -345,7 +345,9 @@ gdk_texture_init (GdkTexture *self)
* *
* Creates a new texture object representing the surface. * Creates a new texture object representing the surface.
* *
* @surface must be an image surface with format `CAIRO_FORMAT_ARGB32`. * The @surface must be an image surface with format `CAIRO_FORMAT_ARGB32`.
*
* The newly created texture will acquire a reference on the @surface.
* *
* Returns: a new `GdkTexture` * Returns: a new `GdkTexture`
*/ */
@@ -364,7 +366,7 @@ gdk_texture_new_for_surface (cairo_surface_t *surface)
* cairo_image_surface_get_stride (surface), * cairo_image_surface_get_stride (surface),
(GDestroyNotify) cairo_surface_destroy, (GDestroyNotify) cairo_surface_destroy,
cairo_surface_reference (surface)); cairo_surface_reference (surface));
texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface), texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface),
cairo_image_surface_get_height (surface), cairo_image_surface_get_height (surface),
GDK_MEMORY_DEFAULT, GDK_MEMORY_DEFAULT,
@@ -819,7 +821,7 @@ gdk_texture_set_render_data (GdkTexture *self,
GDestroyNotify notify) GDestroyNotify notify)
{ {
g_return_val_if_fail (data != NULL, FALSE); g_return_val_if_fail (data != NULL, FALSE);
if (self->render_key != NULL) if (self->render_key != NULL)
return FALSE; return FALSE;
+2
View File
@@ -96,6 +96,8 @@ typedef struct _GdkCairoContext GdkCairoContext;
typedef struct _GdkGLContext GdkGLContext; typedef struct _GdkGLContext GdkGLContext;
typedef struct _GdkVulkanContext GdkVulkanContext; typedef struct _GdkVulkanContext GdkVulkanContext;
typedef struct _GdkDmabufFormats GdkDmabufFormats;
/* /*
* GDK_DECLARE_INTERNAL_TYPE: * GDK_DECLARE_INTERNAL_TYPE:
* @ModuleObjName: The name of the new type, in camel case (like GtkWidget) * @ModuleObjName: The name of the new type, in camel case (like GtkWidget)
+8
View File
@@ -17,6 +17,11 @@ gdk_public_sources = files([
'gdkdevicetool.c', 'gdkdevicetool.c',
'gdkdisplay.c', 'gdkdisplay.c',
'gdkdisplaymanager.c', 'gdkdisplaymanager.c',
'gdkdmabuf.c',
'gdkdmabufformats.c',
'gdkdmabufformatsbuilder.c',
'gdkdmabuftexture.c',
'gdkdmabuftexturebuilder.c',
'gdkdrag.c', 'gdkdrag.c',
'gdkdragsurface.c', 'gdkdragsurface.c',
'gdkdragsurfacesize.c', 'gdkdragsurfacesize.c',
@@ -79,6 +84,9 @@ gdk_public_headers = files([
'gdkdisplay.h', 'gdkdisplay.h',
'gdkdisplaymanager.h', 'gdkdisplaymanager.h',
'gdkdrag.h', 'gdkdrag.h',
'gdkdmabufformats.h',
'gdkdmabuftexture.h',
'gdkdmabuftexturebuilder.h',
'gdkdragsurfacesize.h', 'gdkdragsurfacesize.h',
'gdkdrawcontext.h', 'gdkdrawcontext.h',
'gdkdrop.h', 'gdkdrop.h',
+4
View File
@@ -4442,6 +4442,10 @@ _gdk_win32_surface_request_layout (GdkSurface *surface)
{ {
_gdk_win32_get_window_rect (surface, &rect); _gdk_win32_get_window_rect (surface, &rect);
/* Keep current position if rect is invalid (i.e. queried in bad context) */
if (rect.right == rect.left || rect.bottom == rect.top)
return;
impl->next_layout.configured_width = (rect.right - rect.left + scale - 1) / scale; impl->next_layout.configured_width = (rect.right - rect.left + scale - 1) / scale;
impl->next_layout.configured_height = (rect.bottom - rect.top + scale - 1) / scale; impl->next_layout.configured_height = (rect.bottom - rect.top + scale - 1) / scale;
+7 -2
View File
@@ -453,7 +453,7 @@ get_colorized_texture (GdkTexture *texture,
const graphene_matrix_t *color_matrix, const graphene_matrix_t *color_matrix,
const graphene_vec4_t *color_offset) const graphene_vec4_t *color_offset)
{ {
cairo_surface_t *surface = gdk_texture_download_surface (texture); cairo_surface_t *surface;
cairo_surface_t *image_surface; cairo_surface_t *image_surface;
graphene_vec4_t pixel; graphene_vec4_t pixel;
guint32* pixel_data; guint32* pixel_data;
@@ -475,6 +475,7 @@ get_colorized_texture (GdkTexture *texture,
return g_object_ref (colorized->texture); return g_object_ref (colorized->texture);
} }
surface = gdk_texture_download_surface (texture);
image_surface = cairo_surface_map_to_image (surface, NULL); image_surface = cairo_surface_map_to_image (surface, NULL);
data = cairo_image_surface_get_data (image_surface); data = cairo_image_surface_get_data (image_surface);
width = cairo_image_surface_get_width (image_surface); width = cairo_image_surface_get_width (image_surface);
@@ -536,6 +537,8 @@ get_colorized_texture (GdkTexture *texture,
colorized_list, (GDestroyNotify)colorized_texture_free_list); colorized_list, (GDestroyNotify)colorized_texture_free_list);
} }
cairo_surface_destroy (surface);
return colorized_texture; return colorized_texture;
} }
@@ -611,7 +614,7 @@ gsk_broadway_renderer_add_node (GskRenderer *renderer,
} }
texture = gdk_texture_new_for_surface (image_surface); texture = gdk_texture_new_for_surface (image_surface);
g_ptr_array_add (self->node_textures, g_object_ref (texture)); /* Transfers ownership to node_textures */ g_ptr_array_add (self->node_textures, texture); /* Transfers ownership to node_textures */
texture_id = gdk_broadway_display_ensure_texture (display, texture); texture_id = gdk_broadway_display_ensure_texture (display, texture);
add_rect (nodes, &node->bounds, offset_x, offset_y); add_rect (nodes, &node->bounds, offset_x, offset_y);
@@ -902,6 +905,8 @@ gsk_broadway_renderer_add_node (GskRenderer *renderer,
add_float (nodes, width); add_float (nodes, width);
add_float (nodes, height); add_float (nodes, height);
add_uint32 (nodes, texture_id); add_uint32 (nodes, texture_id);
cairo_surface_destroy (surface);
} }
} }
+3 -4
View File
@@ -399,7 +399,6 @@ gsk_gl_driver_load_programs (GskGLDriver *self,
g_steal_pointer (&program); \ g_steal_pointer (&program); \
} G_STMT_END; } G_STMT_END;
# include "gskglprograms.defs" # include "gskglprograms.defs"
#undef GSK_GL_DEFINE_PROGRAM_CLIP
#undef GSK_GL_DEFINE_PROGRAM #undef GSK_GL_DEFINE_PROGRAM
#undef GSK_GL_ADD_UNIFORM #undef GSK_GL_ADD_UNIFORM
#undef GSK_GL_SHADER_SINGLE #undef GSK_GL_SHADER_SINGLE
@@ -1004,9 +1003,9 @@ gsk_gl_driver_release_render_target (GskGLDriver *self,
texture_id = render_target->texture_id; texture_id = render_target->texture_id;
texture = gsk_gl_texture_new (render_target->texture_id, texture = gsk_gl_texture_new (render_target->texture_id,
render_target->width, render_target->width,
render_target->height, render_target->height,
self->current_frame_id); self->current_frame_id);
g_hash_table_insert (self->textures, g_hash_table_insert (self->textures,
GUINT_TO_POINTER (texture_id), GUINT_TO_POINTER (texture_id),
g_steal_pointer (&texture)); g_steal_pointer (&texture));
+134 -61
View File
@@ -65,6 +65,14 @@ typedef struct _GskGLRenderClip
guint is_fully_contained : 1; guint is_fully_contained : 1;
} GskGLRenderClip; } GskGLRenderClip;
#define GDK_ARRAY_NAME clips
#define GDK_ARRAY_TYPE_NAME Clips
#define GDK_ARRAY_ELEMENT_TYPE GskGLRenderClip
#define GDK_ARRAY_BY_VALUE 1
#define GDK_ARRAY_PREALLOC 16
#define GDK_ARRAY_NO_MEMSET
#include "gdk/gdkarrayimpl.c"
typedef struct _GskGLRenderModelview typedef struct _GskGLRenderModelview
{ {
GskTransform *transform; GskTransform *transform;
@@ -77,6 +85,14 @@ typedef struct _GskGLRenderModelview
graphene_matrix_t matrix; graphene_matrix_t matrix;
} GskGLRenderModelview; } GskGLRenderModelview;
#define GDK_ARRAY_NAME modelviews
#define GDK_ARRAY_TYPE_NAME Modelviews
#define GDK_ARRAY_ELEMENT_TYPE GskGLRenderModelview
#define GDK_ARRAY_BY_VALUE 1
#define GDK_ARRAY_PREALLOC 16
#define GDK_ARRAY_NO_MEMSET
#include "gdk/gdkarrayimpl.c"
struct _GskGLRenderJob struct _GskGLRenderJob
{ {
/* The context containing the framebuffer we are drawing to. Generally this /* The context containing the framebuffer we are drawing to. Generally this
@@ -117,12 +133,12 @@ struct _GskGLRenderJob
/* An array of GskGLRenderModelview updated as nodes are processed. The /* An array of GskGLRenderModelview updated as nodes are processed. The
* current modelview is the last element. * current modelview is the last element.
*/ */
GArray *modelview; Modelviews modelview;
/* An array of GskGLRenderClip updated as nodes are processed. The /* An array of GskGLRenderClip updated as nodes are processed. The
* current clip is the last element. * current clip is the last element.
*/ */
GArray *clip; Clips clip;
/* Our current alpha state as we process nodes */ /* Our current alpha state as we process nodes */
float alpha; float alpha;
@@ -192,6 +208,26 @@ static void gsk_gl_render_job_visit_node (GskGLRenderJob
static gboolean gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job, static gboolean gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
const GskRenderNode *node, const GskRenderNode *node,
GskGLRenderOffscreen *offscreen); GskGLRenderOffscreen *offscreen);
static void gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
GdkTexture *texture,
gboolean ensure_mipmap,
GskGLRenderOffscreen *offscreen);
static inline GskGLRenderClip *
clips_grow_one (Clips *clips)
{
guint len = clips_get_size (clips);
clips_set_size (clips, len + 1);
return clips_get (clips, len);
}
static inline GskGLRenderModelview *
modelviews_grow_one (Modelviews *modelviews)
{
guint len = modelviews_get_size (modelviews);
modelviews_set_size (modelviews, len + 1);
return modelviews_get (modelviews, len);
}
static inline int static inline int
get_target_format (GskGLRenderJob *job, get_target_format (GskGLRenderJob *job,
@@ -238,7 +274,7 @@ gsk_rounded_rect_shrink_to_minimum (GskRoundedRect *self)
static inline gboolean G_GNUC_PURE static inline gboolean G_GNUC_PURE
node_supports_2d_transform (const GskRenderNode *node) node_supports_2d_transform (const GskRenderNode *node)
{ {
switch (gsk_render_node_get_node_type (node)) switch (GSK_RENDER_NODE_TYPE (node))
{ {
case GSK_COLOR_NODE: case GSK_COLOR_NODE:
case GSK_OPACITY_NODE: case GSK_OPACITY_NODE:
@@ -300,7 +336,7 @@ node_supports_transform (const GskRenderNode *node)
* opacity or color matrix. * opacity or color matrix.
*/ */
switch (gsk_render_node_get_node_type (node)) switch (GSK_RENDER_NODE_TYPE (node))
{ {
case GSK_COLOR_NODE: case GSK_COLOR_NODE:
case GSK_OPACITY_NODE: case GSK_OPACITY_NODE:
@@ -466,15 +502,10 @@ gsk_gl_render_job_set_modelview (GskGLRenderJob *job,
GskGLRenderModelview *modelview; GskGLRenderModelview *modelview;
g_assert (job != NULL); g_assert (job != NULL);
g_assert (job->modelview != NULL);
job->driver->stamps[UNIFORM_SHARED_MODELVIEW]++; job->driver->stamps[UNIFORM_SHARED_MODELVIEW]++;
g_array_set_size (job->modelview, job->modelview->len + 1); modelview = modelviews_grow_one (&job->modelview);
modelview = &g_array_index (job->modelview,
GskGLRenderModelview,
job->modelview->len - 1);
modelview->transform = transform; modelview->transform = transform;
@@ -499,26 +530,17 @@ gsk_gl_render_job_push_modelview (GskGLRenderJob *job,
GskGLRenderModelview *modelview; GskGLRenderModelview *modelview;
g_assert (job != NULL); g_assert (job != NULL);
g_assert (job->modelview != NULL);
g_assert (transform != NULL); g_assert (transform != NULL);
job->driver->stamps[UNIFORM_SHARED_MODELVIEW]++; job->driver->stamps[UNIFORM_SHARED_MODELVIEW]++;
g_array_set_size (job->modelview, job->modelview->len + 1); modelview = modelviews_grow_one (&job->modelview);
modelview = &g_array_index (job->modelview, if G_LIKELY (modelviews_get_size (&job->modelview) > 1)
GskGLRenderModelview,
job->modelview->len - 1);
if G_LIKELY (job->modelview->len > 1)
{ {
GskGLRenderModelview *last; GskGLRenderModelview *last = job->modelview.end - 2;
GskTransform *t = NULL; GskTransform *t = NULL;
last = &g_array_index (job->modelview,
GskGLRenderModelview,
job->modelview->len - 2);
/* Multiply given matrix with our previous modelview */ /* Multiply given matrix with our previous modelview */
t = gsk_transform_translate (gsk_transform_ref (last->transform), t = gsk_transform_translate (gsk_transform_ref (last->transform),
&(graphene_point_t) { &(graphene_point_t) {
@@ -552,8 +574,7 @@ gsk_gl_render_job_pop_modelview (GskGLRenderJob *job)
const GskGLRenderModelview *head; const GskGLRenderModelview *head;
g_assert (job != NULL); g_assert (job != NULL);
g_assert (job->modelview); g_assert (modelviews_get_size (&job->modelview) > 0);
g_assert (job->modelview->len > 0);
job->driver->stamps[UNIFORM_SHARED_MODELVIEW]++; job->driver->stamps[UNIFORM_SHARED_MODELVIEW]++;
@@ -564,11 +585,11 @@ gsk_gl_render_job_pop_modelview (GskGLRenderJob *job)
gsk_transform_unref (head->transform); gsk_transform_unref (head->transform);
job->modelview->len--; job->modelview.end--;
if (job->modelview->len >= 1) if (modelviews_get_size (&job->modelview) >= 1)
{ {
head = &g_array_index (job->modelview, GskGLRenderModelview, job->modelview->len - 1); head = job->modelview.end - 1;
job->scale_x = head->scale_x; job->scale_x = head->scale_x;
job->scale_y = head->scale_y; job->scale_y = head->scale_y;
@@ -588,14 +609,12 @@ gsk_gl_render_job_push_clip (GskGLRenderJob *job,
GskGLRenderClip *clip; GskGLRenderClip *clip;
g_assert (job != NULL); g_assert (job != NULL);
g_assert (job->clip != NULL);
g_assert (rect != NULL); g_assert (rect != NULL);
job->driver->stamps[UNIFORM_SHARED_CLIP_RECT]++; job->driver->stamps[UNIFORM_SHARED_CLIP_RECT]++;
g_array_set_size (job->clip, job->clip->len + 1); clip = clips_grow_one (&job->clip);
clip = &g_array_index (job->clip, GskGLRenderClip, job->clip->len - 1);
memcpy (&clip->rect, rect, sizeof *rect); memcpy (&clip->rect, rect, sizeof *rect);
clip->is_rectilinear = gsk_rounded_rect_is_rectilinear (rect); clip->is_rectilinear = gsk_rounded_rect_is_rectilinear (rect);
clip->is_fully_contained = FALSE; clip->is_fully_contained = FALSE;
@@ -610,16 +629,13 @@ gsk_gl_render_job_push_contained_clip (GskGLRenderJob *job)
GskGLRenderClip *old_clip; GskGLRenderClip *old_clip;
g_assert (job != NULL); g_assert (job != NULL);
g_assert (job->clip != NULL); g_assert (clips_get_size (&job->clip) > 0);
g_assert (job->clip->len > 0);
job->driver->stamps[UNIFORM_SHARED_CLIP_RECT]++; job->driver->stamps[UNIFORM_SHARED_CLIP_RECT]++;
old_clip = &g_array_index (job->clip, GskGLRenderClip, job->clip->len - 1); clip = clips_grow_one (&job->clip);
old_clip = clips_get (&job->clip, clips_get_size (&job->clip) - 2);
g_array_set_size (job->clip, job->clip->len + 1);
clip = &g_array_index (job->clip, GskGLRenderClip, job->clip->len - 1);
memcpy (&clip->rect.bounds, &old_clip->rect.bounds, sizeof (graphene_rect_t)); memcpy (&clip->rect.bounds, &old_clip->rect.bounds, sizeof (graphene_rect_t));
memset (clip->rect.corner, 0, sizeof clip->rect.corner); memset (clip->rect.corner, 0, sizeof clip->rect.corner);
clip->is_rectilinear = TRUE; clip->is_rectilinear = TRUE;
@@ -632,12 +648,11 @@ static void
gsk_gl_render_job_pop_clip (GskGLRenderJob *job) gsk_gl_render_job_pop_clip (GskGLRenderJob *job)
{ {
g_assert (job != NULL); g_assert (job != NULL);
g_assert (job->clip != NULL); g_assert (clips_get_size (&job->clip) > 0);
g_assert (job->clip->len > 0);
job->driver->stamps[UNIFORM_SHARED_CLIP_RECT]++; job->driver->stamps[UNIFORM_SHARED_CLIP_RECT]++;
job->current_clip--; job->current_clip--;
job->clip->len--; job->clip.end--;
} }
static inline void static inline void
@@ -719,7 +734,7 @@ gsk_gl_render_job_transform_bounds (GskGLRenderJob *job,
GskTransformCategory category; GskTransformCategory category;
g_assert (job != NULL); g_assert (job != NULL);
g_assert (job->modelview->len > 0); g_assert (modelviews_get_size (&job->modelview) > 0);
g_assert (rect != NULL); g_assert (rect != NULL);
g_assert (out_rect != NULL); g_assert (out_rect != NULL);
@@ -1214,12 +1229,12 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
{ {
cairo_move_to (cr, 0, 0); cairo_move_to (cr, 0, 0);
cairo_rectangle (cr, 0, 0, node->bounds.size.width, node->bounds.size.height); cairo_rectangle (cr, 0, 0, node->bounds.size.width, node->bounds.size.height);
if (gsk_render_node_get_node_type (node) == GSK_CAIRO_NODE) if (GSK_RENDER_NODE_TYPE (node) == GSK_CAIRO_NODE)
cairo_set_source_rgba (cr, 0.3, 0, 1, 0.25); cairo_set_source_rgba (cr, 0.3, 0, 1, 0.25);
else else
cairo_set_source_rgba (cr, 1, 0, 0, 0.25); cairo_set_source_rgba (cr, 1, 0, 0, 0.25);
cairo_fill_preserve (cr); cairo_fill_preserve (cr);
if (gsk_render_node_get_node_type (node) == GSK_CAIRO_NODE) if (GSK_RENDER_NODE_TYPE (node) == GSK_CAIRO_NODE)
cairo_set_source_rgba (cr, 0.3, 0, 1, 1); cairo_set_source_rgba (cr, 0.3, 0, 1, 1);
else else
cairo_set_source_rgba (cr, 1, 0, 0, 1); cairo_set_source_rgba (cr, 1, 0, 0, 1);
@@ -1512,7 +1527,7 @@ gsk_gl_render_job_visit_linear_gradient_node (GskGLRenderJob *job,
const graphene_point_t *start = gsk_linear_gradient_node_get_start (node); const graphene_point_t *start = gsk_linear_gradient_node_get_start (node);
const graphene_point_t *end = gsk_linear_gradient_node_get_end (node); const graphene_point_t *end = gsk_linear_gradient_node_get_end (node);
int n_color_stops = gsk_linear_gradient_node_get_n_color_stops (node); int n_color_stops = gsk_linear_gradient_node_get_n_color_stops (node);
gboolean repeat = gsk_render_node_get_node_type (node) == GSK_REPEATING_LINEAR_GRADIENT_NODE; gboolean repeat = GSK_RENDER_NODE_TYPE (node) == GSK_REPEATING_LINEAR_GRADIENT_NODE;
float x1 = job->offset_x + start->x; float x1 = job->offset_x + start->x;
float x2 = job->offset_x + end->x; float x2 = job->offset_x + end->x;
float y1 = job->offset_y + start->y; float y1 = job->offset_y + start->y;
@@ -1585,7 +1600,7 @@ gsk_gl_render_job_visit_radial_gradient_node (GskGLRenderJob *job,
float end = gsk_radial_gradient_node_get_end (node); float end = gsk_radial_gradient_node_get_end (node);
float hradius = gsk_radial_gradient_node_get_hradius (node); float hradius = gsk_radial_gradient_node_get_hradius (node);
float vradius = gsk_radial_gradient_node_get_vradius (node); float vradius = gsk_radial_gradient_node_get_vradius (node);
gboolean repeat = gsk_render_node_get_node_type (node) == GSK_REPEATING_RADIAL_GRADIENT_NODE; gboolean repeat = GSK_RENDER_NODE_TYPE (node) == GSK_REPEATING_RADIAL_GRADIENT_NODE;
float scale = 1.0f / (end - start); float scale = 1.0f / (end - start);
float bias = -start * scale; float bias = -start * scale;
@@ -1730,7 +1745,7 @@ gsk_gl_render_job_visit_rounded_clip_node (GskGLRenderJob *job,
* which both have rounded corners. * which both have rounded corners.
*/ */
if (job->clip->len <= 1) if (clips_get_size (&job->clip) <= 1)
need_offscreen = FALSE; need_offscreen = FALSE;
else if (gsk_rounded_rect_contains_rect (&job->current_clip->rect, &transformed_clip.bounds)) else if (gsk_rounded_rect_contains_rect (&job->current_clip->rect, &transformed_clip.bounds))
need_offscreen = FALSE; need_offscreen = FALSE;
@@ -2799,8 +2814,8 @@ static inline gboolean G_GNUC_PURE
equal_texture_nodes (const GskRenderNode *node1, equal_texture_nodes (const GskRenderNode *node1,
const GskRenderNode *node2) const GskRenderNode *node2)
{ {
if (gsk_render_node_get_node_type (node1) != GSK_TEXTURE_NODE || if (GSK_RENDER_NODE_TYPE (node1) != GSK_TEXTURE_NODE ||
gsk_render_node_get_node_type (node2) != GSK_TEXTURE_NODE) GSK_RENDER_NODE_TYPE (node2) != GSK_TEXTURE_NODE)
return FALSE; return FALSE;
if (gsk_texture_node_get_texture (node1) != if (gsk_texture_node_get_texture (node1) !=
@@ -3103,7 +3118,7 @@ gsk_gl_render_job_visit_shadow_node (GskGLRenderJob *job,
/* Shadow nodes recolor every pixel of the source texture, but leave the alpha in tact. /* Shadow nodes recolor every pixel of the source texture, but leave the alpha in tact.
* If the child is a color matrix node that doesn't touch the alpha, we can throw that away. */ * If the child is a color matrix node that doesn't touch the alpha, we can throw that away. */
if (gsk_render_node_get_node_type (shadow_child) == GSK_COLOR_MATRIX_NODE && if (GSK_RENDER_NODE_TYPE (shadow_child) == GSK_COLOR_MATRIX_NODE &&
!color_matrix_modifies_alpha (shadow_child)) !color_matrix_modifies_alpha (shadow_child))
shadow_child = gsk_color_matrix_node_get_child (shadow_child); shadow_child = gsk_color_matrix_node_get_child (shadow_child);
@@ -3123,7 +3138,7 @@ gsk_gl_render_job_visit_shadow_node (GskGLRenderJob *job,
continue; continue;
if (shadow->radius == 0 && if (shadow->radius == 0 &&
gsk_render_node_get_node_type (shadow_child) == GSK_TEXT_NODE) GSK_RENDER_NODE_TYPE (shadow_child) == GSK_TEXT_NODE)
{ {
if (dx != 0 || dy != 0) if (dx != 0 || dy != 0)
{ {
@@ -3317,6 +3332,53 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
} }
} }
static gboolean
gsk_gl_render_job_texture_mask_for_color (GskGLRenderJob *job,
const GskRenderNode *mask,
const GskRenderNode *color,
const graphene_rect_t *bounds)
{
int max_texture_size = job->command_queue->max_texture_size;
GdkTexture *texture = gsk_texture_node_get_texture (mask);
const GdkRGBA *rgba;
rgba = gsk_color_node_get_color (color);
if (RGBA_IS_CLEAR (rgba))
return TRUE;
if G_LIKELY (texture->width <= max_texture_size &&
texture->height <= max_texture_size &&
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, coloring)))
{
GskGLRenderOffscreen offscreen = {0};
float scale_x = mask->bounds.size.width / texture->width;
float scale_y = mask->bounds.size.height / texture->height;
gboolean use_mipmap;
guint16 cc[4];
use_mipmap = (scale_x * fabs (job->scale_x)) < 0.5 ||
(scale_y * fabs (job->scale_y)) < 0.5;
rgba_to_half (rgba, cc);
gsk_gl_render_job_upload_texture (job, texture, use_mipmap, &offscreen);
gsk_gl_program_set_uniform_texture_with_sync (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id,
offscreen.has_mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
GL_LINEAR,
offscreen.sync);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_offscreen_with_color (job, bounds, &offscreen, cc);
gsk_gl_render_job_end_draw (job);
return TRUE;
}
return FALSE;
}
static inline void static inline void
gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job, gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
const GskRenderNode *node) const GskRenderNode *node)
@@ -3326,6 +3388,17 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
GskGLRenderOffscreen source_offscreen = {0}; GskGLRenderOffscreen source_offscreen = {0};
GskGLRenderOffscreen mask_offscreen = {0}; GskGLRenderOffscreen mask_offscreen = {0};
/* If the mask is a texture and the source is a color node
* then we can take a shortcut and avoid offscreens.
*/
if (GSK_RENDER_NODE_TYPE (mask) == GSK_TEXTURE_NODE &&
GSK_RENDER_NODE_TYPE (source) == GSK_COLOR_NODE &&
gsk_mask_node_get_mask_mode (node) == GSK_MASK_MODE_ALPHA)
{
if (gsk_gl_render_job_texture_mask_for_color (job, mask, source, &node->bounds))
return;
}
source_offscreen.bounds = &node->bounds; source_offscreen.bounds = &node->bounds;
source_offscreen.force_offscreen = TRUE; source_offscreen.force_offscreen = TRUE;
source_offscreen.reset_clip = TRUE; source_offscreen.reset_clip = TRUE;
@@ -3946,7 +4019,7 @@ gsk_gl_render_job_visit_node (GskGLRenderJob *job,
if (!gsk_gl_render_job_update_clip (job, &node->bounds, &has_clip)) if (!gsk_gl_render_job_update_clip (job, &node->bounds, &has_clip))
return; return;
switch (gsk_render_node_get_node_type (node)) switch (GSK_RENDER_NODE_TYPE (node))
{ {
case GSK_BLEND_NODE: case GSK_BLEND_NODE:
gsk_gl_render_job_visit_blend_node (job, node); gsk_gl_render_job_visit_blend_node (job, node);
@@ -3999,12 +4072,12 @@ gsk_gl_render_job_visit_node (GskGLRenderJob *job,
if (i + 1 < n_children && if (i + 1 < n_children &&
job->current_clip->is_fully_contained && job->current_clip->is_fully_contained &&
gsk_render_node_get_node_type (child) == GSK_ROUNDED_CLIP_NODE) GSK_RENDER_NODE_TYPE (child) == GSK_ROUNDED_CLIP_NODE)
{ {
const GskRenderNode *grandchild = gsk_rounded_clip_node_get_child (child); const GskRenderNode *grandchild = gsk_rounded_clip_node_get_child (child);
const GskRenderNode *child2 = children[i + 1]; const GskRenderNode *child2 = children[i + 1];
if (gsk_render_node_get_node_type (grandchild) == GSK_COLOR_NODE && if (GSK_RENDER_NODE_TYPE (grandchild) == GSK_COLOR_NODE &&
gsk_render_node_get_node_type (child2) == GSK_BORDER_NODE && GSK_RENDER_NODE_TYPE (child2) == GSK_BORDER_NODE &&
gsk_border_node_get_uniform_color (child2) && gsk_border_node_get_uniform_color (child2) &&
rounded_rect_equal (gsk_rounded_clip_node_get_clip (child), rounded_rect_equal (gsk_rounded_clip_node_get_clip (child),
gsk_border_node_get_outline (child2))) gsk_border_node_get_outline (child2)))
@@ -4158,7 +4231,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
return FALSE; return FALSE;
} }
if (gsk_render_node_get_node_type (node) == GSK_TEXTURE_NODE && if (GSK_RENDER_NODE_TYPE (node) == GSK_TEXTURE_NODE &&
!offscreen->force_offscreen) !offscreen->force_offscreen)
{ {
GdkTexture *texture = gsk_texture_node_get_texture (node); GdkTexture *texture = gsk_texture_node_get_texture (node);
@@ -4531,8 +4604,8 @@ gsk_gl_render_job_new (GskGLDriver *driver,
job = g_new0 (GskGLRenderJob, 1); job = g_new0 (GskGLRenderJob, 1);
job->driver = g_object_ref (driver); job->driver = g_object_ref (driver);
job->command_queue = job->driver->command_queue; job->command_queue = job->driver->command_queue;
job->clip = g_array_sized_new (FALSE, FALSE, sizeof (GskGLRenderClip), 16); clips_init (&job->clip);
job->modelview = g_array_sized_new (FALSE, FALSE, sizeof (GskGLRenderModelview), 16); modelviews_init (&job->modelview);
job->framebuffer = framebuffer; job->framebuffer = framebuffer;
job->clear_framebuffer = !!clear_framebuffer; job->clear_framebuffer = !!clear_framebuffer;
job->default_framebuffer = default_framebuffer; job->default_framebuffer = default_framebuffer;
@@ -4582,16 +4655,16 @@ gsk_gl_render_job_free (GskGLRenderJob *job)
job->current_modelview = NULL; job->current_modelview = NULL;
job->current_clip = NULL; job->current_clip = NULL;
while (job->modelview->len > 0) while (job->modelview.end > job->modelview.start)
{ {
GskGLRenderModelview *modelview = &g_array_index (job->modelview, GskGLRenderModelview, job->modelview->len-1); GskGLRenderModelview *modelview = job->modelview.end-1;
g_clear_pointer (&modelview->transform, gsk_transform_unref); g_clear_pointer (&modelview->transform, gsk_transform_unref);
job->modelview->len--; job->modelview.end--;
} }
g_clear_object (&job->driver); g_clear_object (&job->driver);
g_clear_pointer (&job->region, cairo_region_destroy); g_clear_pointer (&job->region, cairo_region_destroy);
g_clear_pointer (&job->modelview, g_array_unref); modelviews_clear (&job->modelview);
g_clear_pointer (&job->clip, g_array_unref); clips_clear (&job->clip);
g_free (job); g_free (job);
} }
+12 -16
View File
@@ -19,8 +19,10 @@
#ifdef _MSC_VER #ifdef _MSC_VER
#define STBRP__NOTUSED(v) (void)(v) #define STBRP__NOTUSED(v) (void)(v)
#define STBRP__CDECL __cdecl
#else #else
#define STBRP__NOTUSED(v) (void)sizeof(v) #define STBRP__NOTUSED(v) (void)sizeof(v)
#define STBRP__CDECL
#endif #endif
enum enum
@@ -63,9 +65,6 @@ STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_ou
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
{ {
int i; int i;
#ifndef STBRP_LARGE_RECTS
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
#endif
for (i=0; i < num_nodes-1; ++i) for (i=0; i < num_nodes-1; ++i)
nodes[i].next = &nodes[i+1]; nodes[i].next = &nodes[i+1];
@@ -84,11 +83,7 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height,
context->extra[0].y = 0; context->extra[0].y = 0;
context->extra[0].next = &context->extra[1]; context->extra[0].next = &context->extra[1];
context->extra[1].x = (stbrp_coord) width; context->extra[1].x = (stbrp_coord) width;
#ifdef STBRP_LARGE_RECTS
context->extra[1].y = (1<<30); context->extra[1].y = (1<<30);
#else
context->extra[1].y = 65535;
#endif
context->extra[1].next = NULL; context->extra[1].next = NULL;
} }
@@ -160,6 +155,13 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
width -= width % c->align; width -= width % c->align;
STBRP_ASSERT(width % c->align == 0); STBRP_ASSERT(width % c->align == 0);
// if it can't possibly fit, bail immediately
if (width > c->width || height > c->height) {
fr.prev_link = NULL;
fr.x = fr.y = 0;
return fr;
}
node = c->active_head; node = c->active_head;
prev = &c->active_head; prev = &c->active_head;
while (node->x + width <= c->width) { while (node->x + width <= c->width) {
@@ -223,7 +225,7 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
} }
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
if (y + height < c->height) { if (y + height <= c->height) {
if (y <= best_y) { if (y <= best_y) {
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
best_x = xpos; best_x = xpos;
@@ -323,7 +325,7 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i
return res; return res;
} }
static int rect_height_compare(const void *a, const void *b) static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
{ {
const stbrp_rect *p = (const stbrp_rect *) a; const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b; const stbrp_rect *q = (const stbrp_rect *) b;
@@ -334,19 +336,13 @@ static int rect_height_compare(const void *a, const void *b)
return (p->w > q->w) ? -1 : (p->w < q->w); return (p->w > q->w) ? -1 : (p->w < q->w);
} }
static int rect_original_order(const void *a, const void *b) static int STBRP__CDECL rect_original_order(const void *a, const void *b)
{ {
const stbrp_rect *p = (const stbrp_rect *) a; const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b; const stbrp_rect *q = (const stbrp_rect *) b;
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
} }
#ifdef STBRP_LARGE_RECTS
#define STBRP__MAXVAL 0xffffffff
#else
#define STBRP__MAXVAL 0xffff
#endif
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
{ {
int i, all_rects_packed = 1; int i, all_rects_packed = 1;
+13 -5
View File
@@ -1,9 +1,15 @@
// stb_rect_pack.h - v0.99 - public domain - rectangle packing // stb_rect_pack.h - v1.01 - public domain - rectangle packing
// Sean Barrett 2014 // Sean Barrett 2014
// //
// Useful for e.g. packing rectangular textures into an atlas. // Useful for e.g. packing rectangular textures into an atlas.
// Does not do rotation. // Does not do rotation.
// //
// Before #including,
//
// #define STB_RECT_PACK_IMPLEMENTATION
//
// in the file that you want to have the implementation.
//
// Not necessarily the awesomest packing method, but better than // Not necessarily the awesomest packing method, but better than
// the totally naive one in stb_truetype (which is primarily what // the totally naive one in stb_truetype (which is primarily what
// this is meant to replace). // this is meant to replace).
@@ -31,9 +37,12 @@
// //
// Bugfixes / warning fixes // Bugfixes / warning fixes
// Jeremy Jaussaud // Jeremy Jaussaud
// Fabian Giesen
// //
// Version history: // Version history:
// //
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
// 0.99 (2019-02-07) warning fixes // 0.99 (2019-02-07) warning fixes
// 0.11 (2017-03-03) return packing success/fail result // 0.11 (2017-03-03) return packing success/fail result
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings // 0.10 (2016-10-25) remove cast-away-const to avoid warnings
@@ -72,11 +81,10 @@ typedef struct stbrp_context stbrp_context;
typedef struct stbrp_node stbrp_node; typedef struct stbrp_node stbrp_node;
typedef struct stbrp_rect stbrp_rect; typedef struct stbrp_rect stbrp_rect;
#ifdef STBRP_LARGE_RECTS
typedef int stbrp_coord; typedef int stbrp_coord;
#else
typedef unsigned short stbrp_coord; #define STBRP__MAXVAL 0x7fffffff
#endif // Mostly for internal use, but this is the maximum supported coordinate value.
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
// Assign packed locations to rectangles. The rectangles are of type // Assign packed locations to rectangles. The rectangles are of type
-13
View File
@@ -1749,19 +1749,6 @@ gsk_circle_contour_new (const graphene_point_t *center,
return (GskContour *) self; return (GskContour *) self;
} }
void
gsk_circle_contour_get_params (const GskContour *contour,
graphene_point_t *center,
float *radius,
gboolean *ccw)
{
const GskCircleContour *self = (const GskCircleContour *) contour;
*center = self->center;
*radius = self->radius;
*ccw = self->ccw;
}
/* }}} */ /* }}} */
/* {{{ Rectangle */ /* {{{ Rectangle */
-4
View File
@@ -36,10 +36,6 @@ GskContour * gsk_standard_contour_new (GskPathFlags
GskContour * gsk_circle_contour_new (const graphene_point_t *center, GskContour * gsk_circle_contour_new (const graphene_point_t *center,
float radius); float radius);
void gsk_circle_contour_get_params (const GskContour *contour,
graphene_point_t *center,
float *radius,
gboolean *ccw);
GskContour * gsk_rect_contour_new (const graphene_rect_t *rect); GskContour * gsk_rect_contour_new (const graphene_rect_t *rect);
GskContour * gsk_rounded_rect_contour_new (const GskRoundedRect *rounded_rect); GskContour * gsk_rounded_rect_contour_new (const GskRoundedRect *rounded_rect);
+181 -24
View File
@@ -2330,30 +2330,6 @@ gsk_curve_get_crossing (const GskCurve *curve,
return get_class (curve->op)->get_crossing (curve, point); return get_class (curve->op)->get_crossing (curve, point);
} }
float
gsk_curve_get_length_to (const GskCurve *curve,
float t)
{
return get_class (curve->op)->get_length_to (curve, t);
}
float
gsk_curve_get_length (const GskCurve *curve)
{
return gsk_curve_get_length_to (curve, 1);
}
float
gsk_curve_at_length (const GskCurve *curve,
float length,
float epsilon)
{
return get_class (curve->op)->get_at_length (curve, length, epsilon);
}
/* }}} */
/* {{{ Closest point */
static gboolean static gboolean
project_point_onto_line (const GskCurve *curve, project_point_onto_line (const GskCurve *curve,
const graphene_point_t *point, const graphene_point_t *point,
@@ -2475,6 +2451,187 @@ gsk_curve_get_closest_point (const GskCurve *curve,
return find_closest_point (curve, point, threshold, 0, 1, out_dist, out_t); return find_closest_point (curve, point, threshold, 0, 1, out_dist, out_t);
} }
float
gsk_curve_get_length_to (const GskCurve *curve,
float t)
{
return get_class (curve->op)->get_length_to (curve, t);
}
float
gsk_curve_get_length (const GskCurve *curve)
{
return gsk_curve_get_length_to (curve, 1);
}
/* Compute the inverse of the arclength using bisection,
* to a given precision
*/
float
gsk_curve_at_length (const GskCurve *curve,
float length,
float epsilon)
{
return get_class (curve->op)->get_at_length (curve, length, epsilon);
}
static inline void
_sincosf (float angle,
float *out_s,
float *out_c)
{
#ifdef HAVE_SINCOSF
sincosf (angle, out_s, out_c);
#else
*out_s = sinf (angle);
*out_c = cosf (angle);
#endif
}
static void
align_points (const graphene_point_t *p,
const graphene_point_t *a,
const graphene_point_t *b,
graphene_point_t *q,
int n)
{
graphene_vec2_t n1;
float angle;
float s, c;
get_tangent (a, b, &n1);
angle = - atan2f (graphene_vec2_get_y (&n1), graphene_vec2_get_x (&n1));
_sincosf (angle, &s, &c);
for (int i = 0; i < n; i++)
{
q[i].x = (p[i].x - a->x) * c - (p[i].y - a->y) * s;
q[i].y = (p[i].x - a->x) * s + (p[i].y - a->y) * c;
}
}
static int
filter_allowable (float t[3],
int n)
{
float g[3];
int j = 0;
for (int i = 0; i < n; i++)
if (0 < t[i] && t[i] < 1)
g[j++] = t[i];
for (int i = 0; i < j; i++)
t[i] = g[i];
return j;
}
/* find solutions for at^2 + bt + c = 0 */
static int
solve_quadratic (float a, float b, float c, float t[2])
{
float d;
int n = 0;
if (fabsf (a) > 0.0001)
{
if (b*b > 4*a*c)
{
d = sqrtf (b*b - 4*a*c);
t[n++] = (-b + d)/(2*a);
t[n++] = (-b - d)/(2*a);
}
else
{
t[n++] = -b / (2*a);
}
}
else if (fabsf (b) > 0.0001)
{
t[n++] = -c / b;
}
return n;
}
int
gsk_curve_get_curvature_points (const GskCurve *curve,
float t[3])
{
const graphene_point_t *pts = curve->cubic.points;
graphene_point_t p[4];
float a, b, c, d;
float x, y, z;
int n;
if (curve->op != GSK_PATH_CUBIC)
return 0; /* FIXME */
align_points (pts, &pts[0], &pts[3], p, 4);
a = p[2].x * p[1].y;
b = p[3].x * p[1].y;
c = p[1].x * p[2].y;
d = p[3].x * p[2].y;
x = - 3*a + 2*b + 3*c - d;
y = 3*a - b - 3*c;
z = c - a;
n = solve_quadratic (x, y, z, t);
return filter_allowable (t, n);
}
/* Find cusps inside the open interval from 0 to 1.
*
* According to Stone & deRose, A Geometric Characterization
* of Parametric Cubic curves, a necessary and sufficient
* condition is that the first derivative vanishes.
*/
int
gsk_curve_get_cusps (const GskCurve *curve,
float t[2])
{
const graphene_point_t *pts = curve->cubic.points;
graphene_point_t p[3];
float ax, bx, cx;
float ay, by, cy;
float tx[3];
int nx;
int n = 0;
if (curve->op != GSK_PATH_CUBIC)
return 0;
p[0].x = 3 * (pts[1].x - pts[0].x);
p[0].y = 3 * (pts[1].y - pts[0].y);
p[1].x = 3 * (pts[2].x - pts[1].x);
p[1].y = 3 * (pts[2].y - pts[1].y);
p[2].x = 3 * (pts[3].x - pts[2].x);
p[2].y = 3 * (pts[3].y - pts[2].y);
ax = p[0].x - 2 * p[1].x + p[2].x;
bx = - 2 * p[0].x + 2 * p[1].x;
cx = p[0].x;
nx = solve_quadratic (ax, bx, cx, tx);
nx = filter_allowable (tx, nx);
ay = p[0].y - 2 * p[1].y + p[2].y;
by = - 2 * p[0].y + 2 * p[1].y;
cy = p[0].y;
for (int i = 0; i < nx; i++)
{
float ti = tx[i];
if (0 < ti && ti < 1 &&
fabsf (ay * ti * ti + by * ti + cy) < 0.001)
t[n++] = ti;
}
return n;
}
/* }}} */ /* }}} */
/* vim:set foldmethod=marker expandtab: */ /* vim:set foldmethod=marker expandtab: */
File diff suppressed because it is too large Load Diff
-13
View File
@@ -187,19 +187,6 @@ int gsk_curve_get_curvature_points (const GskCurve
int gsk_curve_get_cusps (const GskCurve *curve, int gsk_curve_get_cusps (const GskCurve *curve,
float t[2]); float t[2]);
int gsk_curve_intersect (const GskCurve *curve1,
const GskCurve *curve2,
float *t1,
float *t2,
graphene_point_t *p,
GskPathIntersection *kind,
int n);
int gsk_curve_self_intersect (const GskCurve *curve,
float *t1,
graphene_point_t *p,
int n);
G_END_DECLS G_END_DECLS
-73
View File
@@ -144,79 +144,6 @@ gboolean gsk_path_foreach (GskPath
GskPathForeachFunc func, GskPathForeachFunc func,
gpointer user_data); gpointer user_data);
/**
* GskPathIntersection:
* @GSK_PATH_INTERSECTION_NONE: No intersection
* @GSK_PATH_INTERSECTION_NORMAL: A normal intersection, where the two paths
* cross each other
* @GSK_PATH_INTERSECTION_START: The start of a segment where the two paths coincide
* @GSK_PATH_INTERSECTION_END: The end of a segment where the two paths coincide
*
* The values of this enumeration classify intersections
* between paths.
*/
typedef enum
{
GSK_PATH_INTERSECTION_NONE,
GSK_PATH_INTERSECTION_NORMAL,
GSK_PATH_INTERSECTION_START,
GSK_PATH_INTERSECTION_END,
} GskPathIntersection;
/**
* GskPathIntersectionFunc:
* @path1: the first path
* @point1: the intersection as point on @path1
* @path2: the second path
* @point2: the intersection as point on @path2
* @kind: specify the nature of the intersection
* @user_data: user data
*
* Prototype of the callback to iterate through the
* intersections of two paths.
*
* Returns: %TRUE to continue iterating, %FALSE to
* immediately abort and not call the function again
*
* Since: 4.14
*/
typedef gboolean (* GskPathIntersectionFunc) (GskPath *path1,
const GskPathPoint *point1,
GskPath *path2,
const GskPathPoint *point2,
GskPathIntersection kind,
gpointer user_data);
GDK_AVAILABLE_IN_4_14
gboolean gsk_path_foreach_intersection (GskPath *path1,
GskPath *path2,
GskPathIntersectionFunc func,
gpointer user_data);
GDK_AVAILABLE_IN_4_14
GskPath * gsk_path_union (GskPath *first,
GskPath *second,
GskFillRule fill_rule);
GDK_AVAILABLE_IN_4_14
GskPath * gsk_path_intersection (GskPath *first,
GskPath *second,
GskFillRule fill_rule);
GDK_AVAILABLE_IN_4_14
GskPath * gsk_path_difference (GskPath *first,
GskPath *second,
GskFillRule fill_rule);
GDK_AVAILABLE_IN_4_14
GskPath * gsk_path_symmetric_difference (GskPath *first,
GskPath *second,
GskFillRule fill_rule);
GDK_AVAILABLE_IN_4_14
GskPath * gsk_path_simplify (GskPath *self,
GskFillRule fill_rule);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskPath, gsk_path_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskPath, gsk_path_unref)
G_END_DECLS G_END_DECLS
-705
View File
@@ -1,705 +0,0 @@
/*
* Copyright © 2020 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "config.h"
#include "gskpathprivate.h"
#include "gskcurveprivate.h"
#include "gskpathbuilder.h"
#include "gskpathpoint.h"
#include "gskcontourprivate.h"
typedef struct
{
gsize count;
gboolean closed;
gboolean z_is_empty;
} CountCurveData;
static gboolean
count_cb (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
CountCurveData *ccd = data;
(ccd->count)++;
if (op ==GSK_PATH_CLOSE)
{
ccd->closed = TRUE;
ccd->z_is_empty = graphene_point_equal (&pts[0], &pts[1]);
}
return TRUE;
}
static gsize
count_curves (const GskContour *contour,
gboolean *closed,
gboolean *z_is_empty)
{
CountCurveData data;
data.count = 0;
data.closed = FALSE;
data.z_is_empty = FALSE;
gsk_contour_foreach (contour, count_cb, &data);
*closed = data.closed;
*z_is_empty = data.z_is_empty;
return data.count;
}
typedef struct
{
GskPathPoint point1;
GskPathPoint point2;
GskPathIntersection kind;
} Intersection;
typedef struct
{
GskPath *path1;
GskPath *path2;
GskPathIntersectionFunc func;
gpointer data;
gsize contour1;
gsize contour2;
gsize idx1;
gsize idx2;
const GskContour *c1;
const GskContour *c2;
GskCurve curve1;
GskCurve curve2;
gboolean c1_closed;
gboolean c2_closed;
gboolean c1_z_is_empty;
gboolean c2_z_is_empty;
gsize c1_count;
gsize c2_count;
GArray *points;
GArray *all_points;
} PathIntersectData;
static gboolean
intersect_curve2 (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
PathIntersectData *pd = data;
float t1[10], t2[10];
graphene_point_t p[10];
GskPathIntersection kind[10];
int n;
if (op == GSK_PATH_MOVE)
{
if (gsk_contour_get_n_ops (pd->c2) == 1)
{
float dist, tt;
if (gsk_curve_get_closest_point (&pd->curve1, &pts[0], 1, &dist, &tt) && dist == 0)
{
Intersection is;
is.kind = GSK_PATH_INTERSECTION_NORMAL;
is.point1.contour = pd->contour1;
is.point1.idx = pd->idx1;
is.point1.t = tt;
is.point2.contour = pd->contour2;
is.point2.idx = 0;
is.point2.t = 1;
g_array_append_val (pd->points, is);
}
}
return TRUE;
}
if (op == GSK_PATH_CLOSE)
{
if (graphene_point_equal (&pts[0], &pts[1]))
return TRUE;
}
pd->idx2++;
gsk_curve_init_foreach (&pd->curve2, op, pts, n_pts, weight);
n = gsk_curve_intersect (&pd->curve1, &pd->curve2, t1, t2, p, kind, 19);
for (int i = 0; i < n; i++)
{
Intersection is;
is.point1.contour = pd->contour1;
is.point2.contour = pd->contour2;
is.point1.idx = pd->idx1;
is.point2.idx = pd->idx2;
is.point1.t = t1[i];
is.point2.t = t2[i];
is.kind = kind[i];
#if 0
g_print ("append p1 { %lu %lu %f } p2 { %lu %lu %f } %s\n",
is.point1.contour, is.point1.idx, is.point1.t,
is.point2.contour, is.point2.idx, is.point2.t,
kn[is.kind]);
#endif
g_array_append_val (pd->points, is);
}
return TRUE;
}
static gboolean
intersect_curve (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
PathIntersectData *pd = data;
GskBoundingBox b1, b2;
if (op == GSK_PATH_MOVE)
{
if (gsk_contour_get_n_ops (pd->c1) == 1)
{
GskPathPoint point;
float dist;
if (gsk_contour_get_closest_point (pd->c2, &pts[0], 1, &point, &dist) && dist == 0)
{
Intersection is;
is.kind = GSK_PATH_INTERSECTION_NORMAL;
is.point1.contour = pd->contour1;
is.point1.idx = 0;
is.point1.t = 1;
is.point2.contour = pd->contour2;
is.point2.idx = point.idx;
is.point2.t = point.t;
g_array_append_val (pd->points, is);
}
}
return TRUE;
}
if (op == GSK_PATH_CLOSE)
{
if (graphene_point_equal (&pts[0], &pts[1]))
return TRUE;
}
pd->idx1++;
gsk_curve_init_foreach (&pd->curve1, op, pts, n_pts, weight);
gsk_curve_get_bounds (&pd->curve1, &b1);
gsk_contour_get_bounds (pd->c2, &b2);
if (gsk_bounding_box_intersection (&b1, &b2, NULL))
{
pd->idx2 = 0;
if (!gsk_contour_foreach (pd->c2, intersect_curve2, pd))
return FALSE;
}
return TRUE;
}
static gboolean
gsk_path_point_near (const GskPathPoint *p1,
const GskPathPoint *p2,
gboolean closed,
gsize count,
gboolean z_is_empty,
float epsilon)
{
if (p1->idx == p2->idx && fabsf (p1->t - p2->t) < epsilon)
return TRUE;
if (p1->idx + 1 == p2->idx && (1 - p1->t + p2->t < epsilon))
return TRUE;
if (p2->idx + 1 == p1->idx && (1 - p2->t + p1->t < epsilon))
return TRUE;
if (closed)
{
if (p1->idx == 1 && p2->idx == count - 1 && (1 - p2->t + p1->t < epsilon))
return TRUE;
if (p2->idx == 1 && p1->idx == count - 1 && (1 - p1->t + p2->t < epsilon))
return TRUE;
}
if (closed && z_is_empty)
{
if (p1->idx == 1 && p2->idx == count - 2 && (1 - p2->t + p1->t < epsilon))
return TRUE;
if (p2->idx == 1 && p1->idx == count - 2 && (1 - p1->t + p2->t < epsilon))
return TRUE;
}
return FALSE;
}
static int cmp_path1 (gconstpointer p1, gconstpointer p2);
static void
default_contour_collect_intersections (const GskContour *contour1,
const GskContour *contour2,
PathIntersectData *pd)
{
pd->idx1 = 0;
g_array_set_size (pd->points, 0);
gsk_contour_foreach (contour1, intersect_curve, pd);
g_array_sort (pd->points, cmp_path1);
#if 0
g_print ("after sorting\n");
for (gsize i = 0; i < pd->points->len; i++)
{
Intersection *is = &g_array_index (pd->points, Intersection, i);
const char *kn[] = { "none", "normal", "start", "end" };
g_print ("p1 { %lu %lu %f } p2 { %lu %lu %f } %s\n",
is->point1.contour, is->point1.idx, is->point1.t,
is->point2.contour, is->point2.idx, is->point2.t,
kn[is->kind]);
}
#endif
for (gsize i = 0; i < pd->points->len; i++)
{
Intersection *is1 = &g_array_index (pd->points, Intersection, i);
for (gsize j = i + 1; j < pd->points->len; j++)
{
Intersection *is2 = &g_array_index (pd->points, Intersection, j);
if (!gsk_path_point_near (&is1->point1, &is2->point1,
pd->c1_closed, pd->c1_count, pd->c1_z_is_empty,
0.001))
continue;
if (!gsk_path_point_near (&is1->point2, &is2->point2,
pd->c2_closed, pd->c2_count, pd->c2_z_is_empty,
0.001))
continue;
if (is1->kind == GSK_PATH_INTERSECTION_NORMAL && is2->kind != GSK_PATH_INTERSECTION_NONE)
is1->kind = GSK_PATH_INTERSECTION_NONE;
else if (is2->kind == GSK_PATH_INTERSECTION_NORMAL && is1->kind != GSK_PATH_INTERSECTION_NONE)
is2->kind = GSK_PATH_INTERSECTION_NONE;
}
}
#if 0
g_print ("after collapsing\n");
for (gsize i = 0; i < pd->points->len; i++)
{
Intersection *is = &g_array_index (pd->points, Intersection, i);
const char *kn[] = { "none", "normal", "start", "end" };
g_print ("p1 { %lu %lu %f } p2 { %lu %lu %f } %s\n",
is->point1.contour, is->point1.idx, is->point1.t,
is->point2.contour, is->point2.idx, is->point2.t,
kn[is->kind]);
}
#endif
for (gsize i = 0; i < pd->points->len; i++)
{
Intersection *is1 = &g_array_index (pd->points, Intersection, i);
for (gsize j = i + 1; j < pd->points->len; j++)
{
Intersection *is2 = &g_array_index (pd->points, Intersection, j);
if (!gsk_path_point_near (&is1->point1, &is2->point1, FALSE, 0, FALSE, 0.001))
break;
if (!gsk_path_point_near (&is1->point2, &is2->point2,
pd->c2_closed, pd->c2_count, pd->c2_z_is_empty,
0.001))
break;
if ((is1->kind == GSK_PATH_INTERSECTION_END &&
is2->kind == GSK_PATH_INTERSECTION_START) ||
(is1->kind == GSK_PATH_INTERSECTION_START &&
is2->kind == GSK_PATH_INTERSECTION_END))
{
is1->kind = GSK_PATH_INTERSECTION_NONE;
is2->kind = GSK_PATH_INTERSECTION_NONE;
}
}
}
#if 0
g_print ("after merging segments\n");
for (gsize i = 0; i < pd->points->len; i++)
{
Intersection *is = &g_array_index (pd->points, Intersection, i);
const char *kn[] = { "none", "normal", "start", "end" };
g_print ("p1 { %lu %lu %f } p2 { %lu %lu %f } %s\n",
is->point1.contour, is->point1.idx, is->point1.t,
is->point2.contour, is->point2.idx, is->point2.t,
kn[is->kind]);
}
#endif
for (gsize j = 0; j < pd->points->len; j++)
{
Intersection *is = &g_array_index (pd->points, Intersection, j);
if (is->kind != GSK_PATH_INTERSECTION_NONE)
g_array_append_val (pd->all_points, *is);
}
}
static int
circle_intersect (const graphene_point_t *center1,
float radius1,
const graphene_point_t *center2,
float radius2,
graphene_point_t points[2])
{
float d;
float a, h;
graphene_point_t m;
graphene_vec2_t n;
g_assert (radius1 >= 0);
g_assert (radius2 >= 0);
d = graphene_point_distance (center1, center2, NULL, NULL);
if (d < fabsf (radius1 - radius2))
return 0;
if (d > radius1 + radius2)
return 0;
if (d == radius1 + radius2)
{
graphene_point_interpolate (center1, center2, radius1 / (radius1 + radius2), &points[0]);
return 1;
}
a = (radius1*radius1 - radius2*radius2 + d*d)/(2*d);
h = sqrtf (radius1*radius1 - a*a);
graphene_point_interpolate (center1, center2, a/d, &m);
graphene_vec2_init (&n, center2->y - center1->y, center1->x - center2->x);
graphene_vec2_normalize (&n, &n);
graphene_point_init (&points[0], m.x + graphene_vec2_get_x (&n) * h,
m.y + graphene_vec2_get_y (&n) * h);
graphene_point_init (&points[1], m.x - graphene_vec2_get_x (&n) * h,
m.y - graphene_vec2_get_y (&n) * h);
return 2;
}
static void
circle_contour_collect_intersections (const GskContour *contour1,
const GskContour *contour2,
PathIntersectData *pd)
{
graphene_point_t center1, center2;
float radius1, radius2;
gboolean ccw1, ccw2;
graphene_point_t p[2];
int n;
Intersection is[2];
gsk_circle_contour_get_params (contour1, &center1, &radius1, &ccw1);
gsk_circle_contour_get_params (contour2, &center2, &radius2, &ccw2);
if (graphene_point_equal (&center1, &center2) && radius1 == radius2)
{
is[0].kind = GSK_PATH_INTERSECTION_START;
is[0].point1.contour = pd->contour1;
is[0].point1.idx = 1;
is[0].point1.t = 0;
is[0].point2.contour = pd->contour2;
is[0].point2.idx = 1;
is[0].point2.t = 0;
is[1].kind = GSK_PATH_INTERSECTION_END;
is[1].point1.contour = pd->contour1;
is[1].point1.idx = 1;
is[1].point1.t = 1;
is[1].point2.contour = pd->contour2;
is[1].point2.idx = 1;
is[1].point2.t = 1;
if (ccw1 != ccw2)
{
is[0].point2.t = 1;
is[1].point2.t = 0;
}
g_array_append_val (pd->all_points, is[0]);
g_array_append_val (pd->all_points, is[1]);
return;
}
n = circle_intersect (&center1, radius1, &center2, radius2, p);
for (int i = 0; i < n; i++)
{
float d;
is[i].kind = GSK_PATH_INTERSECTION_NORMAL;
is[i].point1.contour = pd->contour1;
is[i].point2.contour = pd->contour2;
gsk_contour_get_closest_point (contour1, &p[i], 1, &is[i].point1, &d);
gsk_contour_get_closest_point (contour2, &p[i], 1, &is[i].point2, &d);
}
if (n == 1)
{
g_array_append_val (pd->all_points, is[0]);
}
else if (n == 2)
{
if (gsk_path_point_compare (&is[0].point1, &is[1].point1) < 0)
{
g_array_append_val (pd->all_points, is[0]);
g_array_append_val (pd->all_points, is[1]);
}
else
{
g_array_append_val (pd->all_points, is[1]);
g_array_append_val (pd->all_points, is[0]);
}
}
}
static void
contour_collect_intersections (const GskContour *contour1,
const GskContour *contour2,
PathIntersectData *pd)
{
if (strcmp (gsk_contour_get_type_name (contour1), "GskCircleContour") == 0 &&
strcmp (gsk_contour_get_type_name (contour2), "GskCircleContour") == 0)
circle_contour_collect_intersections (contour1, contour2, pd);
else
default_contour_collect_intersections (contour1, contour2, pd);
}
static int
cmp_path1 (gconstpointer p1,
gconstpointer p2)
{
const Intersection *i1 = p1;
const Intersection *i2 = p2;
int i;
i = gsk_path_point_compare (&i1->point1, &i2->point1);
if (i != 0)
return i;
return gsk_path_point_compare (&i1->point2, &i2->point2);
}
static gboolean
contour_foreach_intersection (const GskContour *contour1,
PathIntersectData *pd)
{
GskBoundingBox b1, b2;
gsk_contour_get_bounds (contour1, &b1);
g_array_set_size (pd->all_points, 0);
for (gsize i = 0; i < gsk_path_get_n_contours (pd->path2); i++)
{
const GskContour *contour2 = gsk_path_get_contour (pd->path2, i);
gsk_contour_get_bounds (contour1, &b2);
if (gsk_bounding_box_intersection (&b1, &b2, NULL))
{
pd->contour2 = i;
pd->c2 = contour2;
pd->c2_count = count_curves (contour2, &pd->c2_closed, &pd->c2_z_is_empty);
contour_collect_intersections (contour1, contour2, pd);
}
}
g_array_sort (pd->all_points, cmp_path1);
#if 0
g_print ("after sorting\n");
for (gsize i = 0; i < pd->all_points->len; i++)
{
Intersection *is = &g_array_index (pd->all_points, Intersection, i);
const char *kn[] = { "none", "normal", "start", "end" };
g_print ("p1 { %lu %lu %f } p2 { %lu %lu %f } %s\n",
is->point1.contour, is->point1.idx, is->point1.t,
is->point2.contour, is->point2.idx, is->point2.t,
kn[is->kind]);
}
for (gsize i = 0; i + 1 < pd->all_points->len; i++)
{
Intersection *is1 = &g_array_index (pd->all_points, Intersection, i);
Intersection *is2 = &g_array_index (pd->all_points, Intersection, i + 1);
if (gsk_path_point_equal (&is1->point1, &is2->point1) &&
gsk_path_point_equal (&is1->point2, &is2->point2))
{
if (is1->kind == GSK_PATH_INTERSECTION_END &&
is2->kind == GSK_PATH_INTERSECTION_START)
{
is1->kind = GSK_PATH_INTERSECTION_NONE;
is2->kind = GSK_PATH_INTERSECTION_NONE;
}
else
{
is2->kind = MAX (is1->kind, is2->kind);
is1->kind = GSK_PATH_INTERSECTION_NONE;
}
}
}
g_print ("emitting\n");
for (gsize i = 0; i < pd->all_points->len; i++)
{
Intersection *is = &g_array_index (pd->all_points, Intersection, i);
const char *kn[] = { "none", "normal", "start", "end" };
g_print ("p1 { %lu %lu %f } p2 { %lu %lu %f } %s\n",
is->point1.contour, is->point1.idx, is->point1.t,
is->point2.contour, is->point2.idx, is->point2.t,
kn[is->kind]);
}
#endif
for (gsize i = 0; i < pd->all_points->len; i++)
{
Intersection *is = &g_array_index (pd->all_points, Intersection, i);
if (is->kind != GSK_PATH_INTERSECTION_NONE)
{
if (!pd->func (pd->path1, &is->point1, pd->path2, &is->point2, is->kind, pd->data))
return FALSE;
}
}
return TRUE;
}
/**
* gsk_path_foreach_intersection:
* @path1: the first path
* @path2: the second path
* @func: (scope call) (closure user_data): the function to call for intersections
* @user_data: (nullable): user data passed to @func
*
* Finds intersections between two paths.
*
* This function finds intersections between @path1 and @path2,
* and calls @func for each of them, in increasing order for @path1.
*
* When segments of the paths coincide, the callback is called once
* for the start of the segment, with @GSK_PATH_INTERSECTION_START, and
* once for the end of the segment, with @GSK_PATH_INTERSECTION_END.
* Note that other intersections may occur between the start and end
* of such a segment.
*
* If @func returns `FALSE`, the iteration is stopped.
*
* Returns: `FALSE` if @func returned FALSE`, `TRUE` otherwise.
*
* Since: 4.14
*/
gboolean
gsk_path_foreach_intersection (GskPath *path1,
GskPath *path2,
GskPathIntersectionFunc func,
gpointer data)
{
PathIntersectData pd = {
.path1 = path1,
.path2 = path2,
.func = func,
.data = data,
};
gboolean ret;
pd.points = g_array_new (FALSE, FALSE, sizeof (Intersection));
pd.all_points = g_array_new (FALSE, FALSE, sizeof (Intersection));
ret = TRUE;
for (gsize i = 0; i < gsk_path_get_n_contours (path1); i++)
{
const GskContour *contour1 = gsk_path_get_contour (path1, i);
pd.contour1 = i;
pd.c1 = contour1;
pd.c1_count = count_curves (contour1, &pd.c1_closed, &pd.c1_z_is_empty);
pd.idx1 = 0;
if (!contour_foreach_intersection (contour1, &pd))
{
ret = FALSE;
break;
}
}
g_array_unref (pd.points);
g_array_unref (pd.all_points);
return ret;
}
/* vim:set foldmethod=marker expandtab: */
-1818
View File
File diff suppressed because it is too large Load Diff
-14
View File
@@ -56,19 +56,5 @@ gboolean gsk_path_foreach_with_tolerance (GskPath
void gsk_path_builder_add_contour (GskPathBuilder *builder, void gsk_path_builder_add_contour (GskPathBuilder *builder,
GskContour *contour); GskContour *contour);
typedef enum
{
GSK_PATH_OP_SIMPLIFY,
GSK_PATH_OP_UNION,
GSK_PATH_OP_INTERSECTION,
GSK_PATH_OP_DIFFERENCE,
GSK_PATH_OP_XOR
} GskPathOp;
GskPath * gsk_path_op (GskPathOp operation,
GskFillRule fill_rule,
GskPath *first,
GskPath *second);
G_END_DECLS G_END_DECLS
+12 -7
View File
@@ -287,15 +287,21 @@ gsk_render_node_alloc (GskRenderNodeType node_type)
* Returns: (transfer full): the `GskRenderNode` with an additional reference * Returns: (transfer full): the `GskRenderNode` with an additional reference
*/ */
GskRenderNode * GskRenderNode *
gsk_render_node_ref (GskRenderNode *node) (gsk_render_node_ref) (GskRenderNode *node)
{ {
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL); g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
g_atomic_ref_count_inc (&node->ref_count); return _gsk_render_node_ref (node);
return node;
} }
void
_gsk_render_node_unref (GskRenderNode *node)
{
if G_UNLIKELY (g_atomic_ref_count_dec (&node->ref_count))
GSK_RENDER_NODE_GET_CLASS (node)->finalize (node);
}
/** /**
* gsk_render_node_unref: * gsk_render_node_unref:
* @node: (transfer full): a `GskRenderNode` * @node: (transfer full): a `GskRenderNode`
@@ -306,12 +312,11 @@ gsk_render_node_ref (GskRenderNode *node)
* freed. * freed.
*/ */
void void
gsk_render_node_unref (GskRenderNode *node) (gsk_render_node_unref) (GskRenderNode *node)
{ {
g_return_if_fail (GSK_IS_RENDER_NODE (node)); g_return_if_fail (GSK_IS_RENDER_NODE (node));
if (g_atomic_ref_count_dec (&node->ref_count)) _gsk_render_node_unref (node);
GSK_RENDER_NODE_GET_CLASS (node)->finalize (node);
} }
+14
View File
@@ -21,6 +21,9 @@ extern GType gsk_render_node_types[];
#define GSK_IS_RENDER_NODE_TYPE(node,type) \ #define GSK_IS_RENDER_NODE_TYPE(node,type) \
(G_TYPE_INSTANCE_GET_CLASS ((node), GSK_TYPE_RENDER_NODE, GskRenderNodeClass)->node_type == (type)) (G_TYPE_INSTANCE_GET_CLASS ((node), GSK_TYPE_RENDER_NODE, GskRenderNodeClass)->node_type == (type))
#define GSK_RENDER_NODE_TYPE(node) \
(G_TYPE_INSTANCE_GET_CLASS ((node), GSK_TYPE_RENDER_NODE, GskRenderNodeClass)->node_type)
struct _GskRenderNode struct _GskRenderNode
{ {
GTypeInstance parent_instance; GTypeInstance parent_instance;
@@ -57,6 +60,8 @@ GType gsk_render_node_type_register_static (const char
gpointer gsk_render_node_alloc (GskRenderNodeType node_type); gpointer gsk_render_node_alloc (GskRenderNodeType node_type);
void _gsk_render_node_unref (GskRenderNode *node);
gboolean gsk_render_node_can_diff (const GskRenderNode *node1, gboolean gsk_render_node_can_diff (const GskRenderNode *node1,
const GskRenderNode *node2) G_GNUC_PURE; const GskRenderNode *node2) G_GNUC_PURE;
void gsk_render_node_diff (GskRenderNode *node1, void gsk_render_node_diff (GskRenderNode *node1,
@@ -87,6 +92,15 @@ gboolean gsk_container_node_is_disjoint (const GskRenderNode
gboolean gsk_render_node_use_offscreen_for_opacity (const GskRenderNode *node); gboolean gsk_render_node_use_offscreen_for_opacity (const GskRenderNode *node);
#define gsk_render_node_ref(node) _gsk_render_node_ref(node)
#define gsk_render_node_unref(node) _gsk_render_node_unref(node)
static inline GskRenderNode *
_gsk_render_node_ref (GskRenderNode *node)
{
g_atomic_ref_count_inc (&node->ref_count);
return node;
}
G_END_DECLS G_END_DECLS
-3
View File
@@ -28,9 +28,7 @@ gsk_public_sources = files([
'gskglshader.c', 'gskglshader.c',
'gskpath.c', 'gskpath.c',
'gskpathbuilder.c', 'gskpathbuilder.c',
'gskpathintersect.c',
'gskpathmeasure.c', 'gskpathmeasure.c',
'gskpathops.c',
'gskpathparser.c', 'gskpathparser.c',
'gskpathpoint.c', 'gskpathpoint.c',
'gskrenderer.c', 'gskrenderer.c',
@@ -47,7 +45,6 @@ gsk_private_sources = files([
'gskcairoblur.c', 'gskcairoblur.c',
'gskcontour.c', 'gskcontour.c',
'gskcurve.c', 'gskcurve.c',
'gskcurveintersect.c',
'gskdebug.c', 'gskdebug.c',
'gskprivate.c', 'gskprivate.c',
'gskprofiler.c', 'gskprofiler.c',
+3 -1
View File
@@ -714,7 +714,9 @@ emit_text_changed (GtkAtSpiContext *self,
"org.a11y.atspi.Event.Object", "org.a11y.atspi.Event.Object",
"TextChanged", "TextChanged",
g_variant_new ("(siiva{sv})", g_variant_new ("(siiva{sv})",
kind, start, end, g_variant_new_string (text), NULL), kind, start, end,
g_variant_new_string (text),
NULL),
NULL); NULL);
} }
+12 -3
View File
@@ -1614,7 +1614,10 @@ insert_text_cb (GtkEditable *editable,
return; return;
length = g_utf8_strlen (new_text, new_text_length); length = g_utf8_strlen (new_text, new_text_length);
changed->text_changed (changed->data, "insert", *position - length, length, new_text);
char *inserted_text = g_utf8_substring (new_text, 0, length);
changed->text_changed (changed->data, "insert", *position - length, length, inserted_text);
g_free (inserted_text);
} }
static void static void
@@ -1629,6 +1632,10 @@ delete_text_cb (GtkEditable *editable,
return; return;
text = gtk_editable_get_chars (editable, start, end); text = gtk_editable_get_chars (editable, start, end);
if (end < 0)
end = g_utf8_strlen(text, -1);
changed->text_changed (changed->data, "delete", start, end - start, text); changed->text_changed (changed->data, "delete", start, end - start, text);
g_free (text); g_free (text);
} }
@@ -1707,7 +1714,9 @@ insert_range_cb (GtkTextBuffer *buffer,
position = gtk_text_iter_get_offset (iter); position = gtk_text_iter_get_offset (iter);
length = g_utf8_strlen (text, len); length = g_utf8_strlen (text, len);
changed->text_changed (changed->data, "insert", position - length, length, text); char *inserted_text = g_utf8_substring (text, 0, length);
changed->text_changed (changed->data, "insert", position - length, length, inserted_text);
g_free (inserted_text);
update_cursor (buffer, changed); update_cursor (buffer, changed);
} }
@@ -1784,7 +1793,7 @@ buffer_changed (GtkWidget *widget,
if (changed->buffer) if (changed->buffer)
{ {
g_object_ref (changed->buffer); g_object_ref (changed->buffer);
g_signal_connect (changed->buffer, "insert-text", G_CALLBACK (insert_range_cb), changed); g_signal_connect_after (changed->buffer, "insert-text", G_CALLBACK (insert_range_cb), changed);
g_signal_connect (changed->buffer, "delete-range", G_CALLBACK (delete_range_cb), changed); g_signal_connect (changed->buffer, "delete-range", G_CALLBACK (delete_range_cb), changed);
g_signal_connect_after (changed->buffer, "delete-range", G_CALLBACK (delete_range_after_cb), changed); g_signal_connect_after (changed->buffer, "delete-range", G_CALLBACK (delete_range_after_cb), changed);
g_signal_connect_after (changed->buffer, "mark-set", G_CALLBACK (mark_set_cb), changed); g_signal_connect_after (changed->buffer, "mark-set", G_CALLBACK (mark_set_cb), changed);
+3
View File
@@ -171,6 +171,9 @@ gtk_accessible_role_to_atspi_role (GtkAccessibleRole role)
case GTK_ACCESSIBLE_ROLE_OPTION: case GTK_ACCESSIBLE_ROLE_OPTION:
return ATSPI_ROLE_OPTION_PANE; return ATSPI_ROLE_OPTION_PANE;
case GTK_ACCESSIBLE_ROLE_PARAGRAPH:
return ATSPI_ROLE_PARAGRAPH;
case GTK_ACCESSIBLE_ROLE_PRESENTATION: case GTK_ACCESSIBLE_ROLE_PRESENTATION:
return ATSPI_ROLE_INVALID; return ATSPI_ROLE_INVALID;
+4 -2
View File
@@ -454,7 +454,8 @@ gtk_dialog_constructed (GObject *object)
} }
g_list_free (children); g_list_free (children);
_gtk_header_bar_track_default_decoration (GTK_HEADER_BAR (priv->headerbar)); if (GTK_IS_HEADER_BAR (priv->headerbar))
_gtk_header_bar_track_default_decoration (GTK_HEADER_BAR (priv->headerbar));
} }
else else
{ {
@@ -1397,7 +1398,8 @@ gtk_dialog_buildable_add_child (GtkBuildable *buildable,
else if (g_str_equal (type, "titlebar")) else if (g_str_equal (type, "titlebar"))
{ {
priv->headerbar = GTK_WIDGET (child); priv->headerbar = GTK_WIDGET (child);
_gtk_header_bar_track_default_decoration (GTK_HEADER_BAR (priv->headerbar)); if (GTK_IS_HEADER_BAR (priv->headerbar))
_gtk_header_bar_track_default_decoration (GTK_HEADER_BAR (priv->headerbar));
gtk_window_set_titlebar (GTK_WINDOW (buildable), priv->headerbar); gtk_window_set_titlebar (GTK_WINDOW (buildable), priv->headerbar);
} }
else if (g_str_equal (type, "action")) else if (g_str_equal (type, "action"))
+5 -2
View File
@@ -12833,9 +12833,12 @@ gtk_tree_view_is_blank_at_pos (GtkTreeView *tree_view,
*column = real_column; *column = real_column;
gtk_tree_model_get_iter (priv->model, &iter, real_path); gtk_tree_model_get_iter (priv->model, &iter, real_path);
if (!_gtk_tree_view_find_node (tree_view, real_path, &tree, &node)) _gtk_tree_view_find_node (tree_view, real_path, &tree, &node);
if (node == NULL)
{ {
g_assert_not_reached (); if (!path)
gtk_tree_path_free (real_path);
return TRUE;
} }
/* Check if there's an expander arrow at (x, y) */ /* Check if there's an expander arrow at (x, y) */
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1
View File
@@ -209,6 +209,7 @@
#include <gtk/gtkpopover.h> #include <gtk/gtkpopover.h>
#include <gtk/gtkpopovermenu.h> #include <gtk/gtkpopovermenu.h>
#include <gtk/gtkpopovermenubar.h> #include <gtk/gtkpopovermenubar.h>
#include <gtk/gtkprintdialog.h>
#include <gtk/print/gtkprintcontext.h> #include <gtk/print/gtkprintcontext.h>
#include <gtk/print/gtkprintoperation.h> #include <gtk/print/gtkprintoperation.h>
#include <gtk/print/gtkprintoperationpreview.h> #include <gtk/print/gtkprintoperationpreview.h>
+2
View File
@@ -832,6 +832,7 @@ static const char *role_names[] = {
[GTK_ACCESSIBLE_ROLE_WINDOW] = NC_("accessibility", "window"), [GTK_ACCESSIBLE_ROLE_WINDOW] = NC_("accessibility", "window"),
[GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON] = NC_("accessibility", "toggle button"), [GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON] = NC_("accessibility", "toggle button"),
[GTK_ACCESSIBLE_ROLE_APPLICATION] = NC_("accessibility", "application"), [GTK_ACCESSIBLE_ROLE_APPLICATION] = NC_("accessibility", "application"),
[GTK_ACCESSIBLE_ROLE_PARAGRAPH] = NC_("accessibility", "paragraph"),
}; };
/*< private > /*< private >
@@ -912,6 +913,7 @@ static struct {
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_APPLICATION }, { GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_APPLICATION },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_DOCUMENT }, { GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_DOCUMENT },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_GENERIC }, { GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_GENERIC },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_PARAGRAPH },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_PRESENTATION }, { GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_PRESENTATION },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_RANGE }, { GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_RANGE },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_ROW_GROUP }, { GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_ROW_GROUP },
+1 -1
View File
@@ -46,7 +46,7 @@ static gboolean
gtk_accessible_range_default_set_current_value (GtkAccessibleRange *accessible_range, gtk_accessible_range_default_set_current_value (GtkAccessibleRange *accessible_range,
double value) double value)
{ {
return FALSE; return TRUE;
} }
static void static void
+1
View File
@@ -1103,6 +1103,7 @@ static guint8 naming[] = {
[GTK_ACCESSIBLE_ROLE_WINDOW] = NAME_FROM_AUTHOR, [GTK_ACCESSIBLE_ROLE_WINDOW] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED, [GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_APPLICATION] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED, [GTK_ACCESSIBLE_ROLE_APPLICATION] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_PARAGRAPH] = GTK_ACCESSIBLE_NAME_PROHIBITED,
}; };
/* < private > /* < private >
+1 -1
View File
@@ -511,7 +511,7 @@ gtk_color_dialog_button_set_dialog (GtkColorDialogButton *self,
* *
* This function is what should be used to obtain * This function is what should be used to obtain
* the color that was chosen by the user. To get * the color that was chosen by the user. To get
* informed about changes, listen to "notify::color". * informed about changes, listen to "notify::rgba".
* *
* Returns: the color * Returns: the color
* *
+4 -1
View File
@@ -1362,6 +1362,8 @@ typedef enum {
* @GTK_ACCESSIBLE_ROLE_APPLICATION: A toplevel element of a graphical user interface. * @GTK_ACCESSIBLE_ROLE_APPLICATION: A toplevel element of a graphical user interface.
* This is the role that GTK uses by default for windows. * This is the role that GTK uses by default for windows.
* Since: 4.12 * Since: 4.12
* @GTK_ACCESSIBLE_ROLE_PARAGRAPH: A paragraph of content.
* Since: 4.14
* *
* The accessible role for a [iface@Accessible] implementation. * The accessible role for a [iface@Accessible] implementation.
* *
@@ -1448,7 +1450,8 @@ typedef enum {
GTK_ACCESSIBLE_ROLE_WIDGET, GTK_ACCESSIBLE_ROLE_WIDGET,
GTK_ACCESSIBLE_ROLE_WINDOW, GTK_ACCESSIBLE_ROLE_WINDOW,
GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON GDK_AVAILABLE_ENUMERATOR_IN_4_10, GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON GDK_AVAILABLE_ENUMERATOR_IN_4_10,
GTK_ACCESSIBLE_ROLE_APPLICATION GDK_AVAILABLE_ENUMERATOR_IN_4_12 GTK_ACCESSIBLE_ROLE_APPLICATION GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GTK_ACCESSIBLE_ROLE_PARAGRAPH GDK_AVAILABLE_ENUMERATOR_IN_4_14
} GtkAccessibleRole; } GtkAccessibleRole;
/** /**
+1
View File
@@ -177,6 +177,7 @@ response_cb (GDBusConnection *connection,
self->custom_files = NULL; self->custom_files = NULL;
for (i = 0; uris[i]; i++) for (i = 0; uris[i]; i++)
self->custom_files = g_slist_prepend (self->custom_files, g_file_new_for_uri (uris[i])); self->custom_files = g_slist_prepend (self->custom_files, g_file_new_for_uri (uris[i]));
self->custom_files = g_slist_reverse (self->custom_files);
g_free (uris); g_free (uris);
g_variant_unref (response_data); g_variant_unref (response_data);
+2 -2
View File
@@ -4772,7 +4772,7 @@ gtk_file_chooser_widget_add_filter (GtkFileChooser *chooser,
return; return;
} }
g_object_ref_sink (filter); g_object_ref (filter);
g_list_store_append (impl->filters, filter); g_list_store_append (impl->filters, filter);
g_object_unref (filter); g_object_unref (filter);
@@ -6000,7 +6000,7 @@ set_current_filter (GtkFileChooserWidget *impl,
g_object_unref (impl->current_filter); g_object_unref (impl->current_filter);
impl->current_filter = filter; impl->current_filter = filter;
if (impl->current_filter) if (impl->current_filter)
g_object_ref_sink (impl->current_filter); g_object_ref (impl->current_filter);
gtk_drop_down_set_selected (GTK_DROP_DOWN (impl->filter_combo), filter_index); gtk_drop_down_set_selected (GTK_DROP_DOWN (impl->filter_combo), filter_index);
+2
View File
@@ -229,6 +229,8 @@ update_default_decoration (GtkHeaderBar *bar)
void void
_gtk_header_bar_track_default_decoration (GtkHeaderBar *bar) _gtk_header_bar_track_default_decoration (GtkHeaderBar *bar)
{ {
g_assert (GTK_IS_HEADER_BAR (bar));
bar->track_default_decoration = TRUE; bar->track_default_decoration = TRUE;
update_default_decoration (bar); update_default_decoration (bar);
+1 -1
View File
@@ -86,7 +86,7 @@ struct _GtkMenuTrackerItem
char *action_namespace; char *action_namespace;
char *action_and_target; char *action_and_target;
GMenuItem *item; GMenuItem *item;
GtkMenuTrackerItemRole role : 4; guint role : 4; /* GtkMenuTrackerItemRole */
guint is_separator : 1; guint is_separator : 1;
guint can_activate : 1; guint can_activate : 1;
guint sensitive : 1; guint sensitive : 1;
+1771
View File
File diff suppressed because it is too large Load Diff
+135
View File
@@ -0,0 +1,135 @@
/* GTK - The GIMP Toolkit
*
* Copyright (C) 2022 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gdk/gdk.h>
#include <gtk/gtkwindow.h>
#include <gtk/print/gtkprintsettings.h>
#include <gtk/print/gtkpagesetup.h>
G_BEGIN_DECLS
typedef struct _GtkPrintSetup GtkPrintSetup;
#define GTK_TYPE_PRINT_SETUP (gtk_print_setup_get_type ())
GDK_AVAILABLE_IN_4_14
GType gtk_print_setup_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
GtkPrintSetup *gtk_print_setup_ref (GtkPrintSetup *setup);
GDK_AVAILABLE_IN_4_14
void gtk_print_setup_unref (GtkPrintSetup *setup);
GDK_AVAILABLE_IN_4_14
GtkPrintSettings *
gtk_print_setup_get_print_settings (GtkPrintSetup *setup);
GDK_AVAILABLE_IN_4_14
GtkPageSetup * gtk_print_setup_get_page_setup (GtkPrintSetup *setup);
#define GTK_TYPE_PRINT_DIALOG (gtk_print_dialog_get_type ())
GDK_AVAILABLE_IN_4_14
G_DECLARE_FINAL_TYPE (GtkPrintDialog, gtk_print_dialog, GTK, PRINT_DIALOG, GObject)
GDK_AVAILABLE_IN_4_14
GtkPrintDialog *gtk_print_dialog_new (void);
GDK_AVAILABLE_IN_4_14
const char * gtk_print_dialog_get_title (GtkPrintDialog *self);
GDK_AVAILABLE_IN_4_14
void gtk_print_dialog_set_title (GtkPrintDialog *self,
const char *title);
GDK_AVAILABLE_IN_4_14
const char * gtk_print_dialog_get_accept_label (GtkPrintDialog *self);
GDK_AVAILABLE_IN_4_14
void gtk_print_dialog_set_accept_label (GtkPrintDialog *self,
const char *accept_label);
GDK_AVAILABLE_IN_4_14
gboolean gtk_print_dialog_get_modal (GtkPrintDialog *self);
GDK_AVAILABLE_IN_4_14
void gtk_print_dialog_set_modal (GtkPrintDialog *self,
gboolean modal);
GDK_AVAILABLE_IN_4_14
GtkPageSetup * gtk_print_dialog_get_page_setup (GtkPrintDialog *self);
GDK_AVAILABLE_IN_4_14
void gtk_print_dialog_set_page_setup (GtkPrintDialog *self,
GtkPageSetup *page_setup);
GDK_AVAILABLE_IN_4_14
GtkPrintSettings * gtk_print_dialog_get_print_settings (GtkPrintDialog *self);
GDK_AVAILABLE_IN_4_14
void gtk_print_dialog_set_print_settings (GtkPrintDialog *self,
GtkPrintSettings *print_settings);
GDK_AVAILABLE_IN_4_14
void gtk_print_dialog_setup (GtkPrintDialog *self,
GtkWindow *parent,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_4_14
GtkPrintSetup *gtk_print_dialog_setup_finish (GtkPrintDialog *self,
GAsyncResult *result,
GError **error);
GDK_AVAILABLE_IN_4_14
void gtk_print_dialog_print (GtkPrintDialog *self,
GtkWindow *parent,
GtkPrintSetup *setup,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_4_14
GOutputStream * gtk_print_dialog_print_finish (GtkPrintDialog *self,
GAsyncResult *result,
GError **error);
GDK_AVAILABLE_IN_4_14
void gtk_print_dialog_print_file (GtkPrintDialog *self,
GtkWindow *parent,
GtkPrintSetup *setup,
GFile *file,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_4_14
gboolean gtk_print_dialog_print_file_finish (GtkPrintDialog *self,
GAsyncResult *result,
GError **error);
G_END_DECLS
+1 -1
View File
@@ -70,7 +70,7 @@ typedef struct {
CachedSizeX cached_size_x; CachedSizeX cached_size_x;
CachedSizeY cached_size_y; CachedSizeY cached_size_y;
GtkSizeRequestMode request_mode : 3; guint request_mode : 3; /* GtkSizeRequestMode */
guint request_mode_valid : 1; guint request_mode_valid : 1;
struct { struct {
guint n_cached_requests : 15; guint n_cached_requests : 15;
+1 -1
View File
@@ -6536,7 +6536,7 @@ gtk_widget_update_default_pango_context (GtkWidget *widget)
return; return;
if (gtk_widget_update_pango_context (widget, context, _gtk_widget_get_direction (widget))) if (gtk_widget_update_pango_context (widget, context, _gtk_widget_get_direction (widget)))
gtk_widget_queue_draw (widget); gtk_widget_queue_resize (widget);
} }
/** /**
+9
View File
@@ -310,6 +310,7 @@ gtk_public_sources = files([
'gtkpopover.c', 'gtkpopover.c',
'gtkpopovermenu.c', 'gtkpopovermenu.c',
'gtkpopovermenubar.c', 'gtkpopovermenubar.c',
'gtkprintdialog.c',
'gtkprogressbar.c', 'gtkprogressbar.c',
'gtkpropertylookuplistmodel.c', 'gtkpropertylookuplistmodel.c',
'gtkrange.c', 'gtkrange.c',
@@ -549,6 +550,7 @@ gtk_public_headers = files([
'gtkpopover.h', 'gtkpopover.h',
'gtkpopovermenu.h', 'gtkpopovermenu.h',
'gtkpopovermenubar.h', 'gtkpopovermenubar.h',
'gtkprintdialog.h',
'gtkprogressbar.h', 'gtkprogressbar.h',
'gtkrange.h', 'gtkrange.h',
'gtkrecentmanager.h', 'gtkrecentmanager.h',
@@ -853,20 +855,27 @@ else
endif endif
foreach lang : [ foreach lang : [
'bn',
'de', 'de',
'da', 'da',
'fr', 'fr',
'es', 'es',
'et',
'fi',
'hi',
'hu', 'hu',
'it', 'it',
'ja',
'ko', 'ko',
'lt', 'lt',
'ms', 'ms',
'nb',
'nl', 'nl',
'pl', 'pl',
'pt', 'pt',
'ru', 'ru',
'sv', 'sv',
'th',
'uk', 'uk',
'zh' 'zh'
] ]
+24
View File
@@ -1338,6 +1338,30 @@ gtk_enumerate_printers (GtkPrinterFunc func,
} }
} }
static GtkPrinter *found_printer;
static gboolean
match_printer_name (GtkPrinter *printer,
gpointer data)
{
if (strcmp (gtk_printer_get_name (printer), (const char *)data) == 0)
{
found_printer = g_object_ref (printer);
return TRUE;
}
return FALSE;
}
GtkPrinter *
gtk_printer_find (const char *name)
{
found_printer = NULL;
gtk_enumerate_printers (match_printer_name, (gpointer) name, NULL, TRUE);
return g_steal_pointer (&found_printer);
}
GType GType
gtk_print_capabilities_get_type (void) gtk_print_capabilities_get_type (void)
{ {
+2
View File
@@ -69,4 +69,6 @@ GDK_AVAILABLE_IN_ALL
void gtk_print_job_set_status (GtkPrintJob *job, void gtk_print_job_set_status (GtkPrintJob *job,
GtkPrintStatus status); GtkPrintStatus status);
GtkPrinter * gtk_printer_find (const char *name);
G_END_DECLS G_END_DECLS
+3 -2
View File
@@ -699,8 +699,9 @@ gtk_print_job_send (GtkPrintJob *job,
g_return_if_fail (job->spool_io != NULL); g_return_if_fail (job->spool_io != NULL);
gtk_print_job_set_status (job, GTK_PRINT_STATUS_SENDING_DATA); gtk_print_job_set_status (job, GTK_PRINT_STATUS_SENDING_DATA);
g_io_channel_seek_position (job->spool_io, 0, G_SEEK_SET, NULL); if (g_io_channel_get_flags (job->spool_io) & G_IO_FLAG_IS_SEEKABLE)
g_io_channel_seek_position (job->spool_io, 0, G_SEEK_SET, NULL);
gtk_print_backend_print_stream (job->backend, job, gtk_print_backend_print_stream (job->backend, job,
job->spool_io, job->spool_io,
+22 -12
View File
@@ -384,6 +384,8 @@ find_file_printer (void)
for (l = backends; l; l = l->next) for (l = backends; l; l = l->next)
{ {
GtkPrintBackend *backend = l->data; GtkPrintBackend *backend = l->data;
/* FIXME: this needs changes for cpdb */
if (strcmp (G_OBJECT_TYPE_NAME (backend), "GtkPrintBackendFile") == 0) if (strcmp (G_OBJECT_TYPE_NAME (backend), "GtkPrintBackendFile") == 0)
{ {
printers = gtk_print_backend_get_printer_list (backend); printers = gtk_print_backend_get_printer_list (backend);
@@ -427,11 +429,6 @@ prepare_print_response (GDBusConnection *connection,
GtkPrintSettings *settings; GtkPrintSettings *settings;
GtkPageSetup *page_setup; GtkPageSetup *page_setup;
GtkPrinter *printer; GtkPrinter *printer;
char *filename;
char *uri;
int fd;
portal->result = GTK_PRINT_OPERATION_RESULT_APPLY;
v = g_variant_lookup_value (options, "settings", G_VARIANT_TYPE_VARDICT); v = g_variant_lookup_value (options, "settings", G_VARIANT_TYPE_VARDICT);
settings = gtk_print_settings_new_from_gvariant (v); settings = gtk_print_settings_new_from_gvariant (v);
@@ -444,15 +441,28 @@ prepare_print_response (GDBusConnection *connection,
g_variant_lookup (options, "token", "u", &portal->token); g_variant_lookup (options, "token", "u", &portal->token);
printer = find_file_printer (); printer = find_file_printer ();
if (printer)
{
char *filename;
int fd;
char *uri;
fd = g_file_open_tmp ("gtkprintXXXXXX", &filename, NULL); fd = g_file_open_tmp ("gtkprintXXXXXX", &filename, NULL);
uri = g_filename_to_uri (filename, NULL, NULL); uri = g_filename_to_uri (filename, NULL, NULL);
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_OUTPUT_URI, uri); gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_OUTPUT_URI, uri);
g_free (uri); g_free (uri);
close (fd); close (fd);
finish_print (portal, printer, page_setup, settings); finish_print (portal, printer, page_setup, settings);
g_free (filename); g_free (filename);
portal->result = GTK_PRINT_OPERATION_RESULT_APPLY;
}
else
{
portal->do_print = FALSE;
portal->result = GTK_PRINT_OPERATION_RESULT_ERROR;
}
} }
else else
{ {
+23 -10
View File
@@ -1056,6 +1056,7 @@ gtk_print_run_page_setup_dialog_async (GtkWindow *parent,
struct _PrinterFinder struct _PrinterFinder
{ {
gboolean found_printer; gboolean found_printer;
gboolean scheduled_callback;
GFunc func; GFunc func;
gpointer data; gpointer data;
char *printer_name; char *printer_name;
@@ -1088,6 +1089,14 @@ find_printer_idle (gpointer data)
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
static void
schedule_finder_callback (PrinterFinder *finder)
{
g_assert (!finder->scheduled_callback);
g_idle_add (find_printer_idle, finder);
finder->scheduled_callback = TRUE;
}
static void static void
printer_added_cb (GtkPrintBackend *backend, printer_added_cb (GtkPrintBackend *backend,
GtkPrinter *printer, GtkPrinter *printer,
@@ -1120,7 +1129,7 @@ printer_added_cb (GtkPrintBackend *backend,
} }
if (finder->found_printer) if (finder->found_printer)
g_idle_add (find_printer_idle, finder); schedule_finder_callback (finder);
} }
static void static void
@@ -1135,8 +1144,11 @@ printer_list_done_cb (GtkPrintBackend *backend,
gtk_print_backend_destroy (backend); gtk_print_backend_destroy (backend);
g_object_unref (backend); g_object_unref (backend);
if (finder->backends == NULL) /* If there are no more backends left after removing ourselves from the list
g_idle_add (find_printer_idle, finder); * above, then we're finished.
*/
if (finder->backends == NULL && !finder->found_printer)
schedule_finder_callback (finder);
} }
static void static void
@@ -1162,9 +1174,7 @@ find_printer_init (PrinterFinder *finder,
if (gtk_print_backend_printer_list_is_done (backend)) if (gtk_print_backend_printer_list_is_done (backend))
{ {
finder->backends = g_list_remove (finder->backends, backend); printer_list_done_cb (backend, finder);
gtk_print_backend_destroy (backend);
g_object_unref (backend);
} }
else else
{ {
@@ -1226,17 +1236,19 @@ find_printer (const char *printer,
if (g_module_supported ()) if (g_module_supported ())
finder->backends = gtk_print_backend_load_modules (); finder->backends = gtk_print_backend_load_modules ();
if (finder->backends == NULL)
{
schedule_finder_callback (finder);
return;
}
for (node = finder->backends; !finder->found_printer && node != NULL; node = next) for (node = finder->backends; !finder->found_printer && node != NULL; node = next)
{ {
next = node->next; next = node->next;
find_printer_init (finder, GTK_PRINT_BACKEND (node->data)); find_printer_init (finder, GTK_PRINT_BACKEND (node->data));
} }
if (finder->backends == NULL)
g_idle_add (find_printer_idle, finder);
} }
GtkPrintOperationResult GtkPrintOperationResult
_gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op, _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
gboolean show_dialog, gboolean show_dialog,
@@ -1248,6 +1260,7 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
else else
return gtk_print_operation_unix_run_dialog (op, show_dialog, parent, do_print); return gtk_print_operation_unix_run_dialog (op, show_dialog, parent, do_print);
} }
void void
_gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation *op, _gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation *op,
gboolean show_dialog, gboolean show_dialog,
+6 -1
View File
@@ -1,5 +1,5 @@
project('gtk', 'c', project('gtk', 'c',
version: '4.13.1', version: '4.13.2',
default_options: [ default_options: [
'buildtype=debugoptimized', 'buildtype=debugoptimized',
'warning_level=1', 'warning_level=1',
@@ -162,6 +162,7 @@ check_headers = [
'inttypes.h', 'inttypes.h',
'linux/input.h', 'linux/input.h',
'linux/memfd.h', 'linux/memfd.h',
'linux/dma-buf.h',
'locale.h', 'locale.h',
'memory.h', 'memory.h',
'stdint.h', 'stdint.h',
@@ -185,6 +186,10 @@ foreach h : check_headers
endif endif
endforeach endforeach
if os_linux and not cc.has_header('linux/dma-buf.h')
error('OS is Linux, but linux/dma-buf.h not found.')
endif
# Maths functions might be implemented in libm # Maths functions might be implemented in libm
libm = cc.find_library('m', required: false) libm = cc.find_library('m', required: false)
+165 -140
View File
File diff suppressed because it is too large Load Diff
+60 -55
View File
@@ -15,8 +15,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: lt\n" "Project-Id-Version: lt\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2023-09-03 14:34+0000\n" "POT-Creation-Date: 2023-09-25 12:58+0000\n"
"PO-Revision-Date: 2023-09-03 21:19+0300\n" "PO-Revision-Date: 2023-09-25 22:57+0300\n"
"Last-Translator: Aurimas Černius <aurisc4@gmail.com>\n" "Last-Translator: Aurimas Černius <aurisc4@gmail.com>\n"
"Language-Team: Lietuvių <gnome-lt@lists.akl.lt>\n" "Language-Team: Lietuvių <gnome-lt@lists.akl.lt>\n"
"Language: lt\n" "Language: lt\n"
@@ -59,31 +59,31 @@ msgstr "Nepavyko pateikti turinio kaip %s"
msgid "The current backend does not support OpenGL" msgid "The current backend does not support OpenGL"
msgstr "Dabartinė realizacija nepalaiko OpenGL" msgstr "Dabartinė realizacija nepalaiko OpenGL"
#: gdk/gdkdisplay.c:1245 gdk/gdksurface.c:1252 #: gdk/gdkdisplay.c:1244 gdk/gdksurface.c:1252
msgid "Vulkan support disabled via GDK_DEBUG" msgid "Vulkan support disabled via GDK_DEBUG"
msgstr "Vulkan palaikymas išjungtas naudojant GDK_DEBUG" msgstr "Vulkan palaikymas išjungtas naudojant GDK_DEBUG"
#: gdk/gdkdisplay.c:1277 #: gdk/gdkdisplay.c:1276
msgid "GL support disabled via GDK_DEBUG" msgid "GL support disabled via GDK_DEBUG"
msgstr "GL palaikymas išjungtas naudojant GDK_DEBUG" msgstr "GL palaikymas išjungtas naudojant GDK_DEBUG"
#: gdk/gdkdisplay.c:1575 #: gdk/gdkdisplay.c:1574
msgid "No EGL configuration available" msgid "No EGL configuration available"
msgstr "Nėra prieinamos EGL konfigūracijos" msgstr "Nėra prieinamos EGL konfigūracijos"
#: gdk/gdkdisplay.c:1583 #: gdk/gdkdisplay.c:1582
msgid "Failed to get EGL configurations" msgid "Failed to get EGL configurations"
msgstr "Nepavyko gauti EGL konfigūracijų" msgstr "Nepavyko gauti EGL konfigūracijų"
#: gdk/gdkdisplay.c:1613 #: gdk/gdkdisplay.c:1612
msgid "No EGL configuration with required features found" msgid "No EGL configuration with required features found"
msgstr "Nerasta EGL konfigūracija su reikiamomis savybėmis" msgstr "Nerasta EGL konfigūracija su reikiamomis savybėmis"
#: gdk/gdkdisplay.c:1620 #: gdk/gdkdisplay.c:1619
msgid "No perfect EGL configuration found" msgid "No perfect EGL configuration found"
msgstr "Nerasta puikiai tinkanti EGL konfigūracija" msgstr "Nerasta puikiai tinkanti EGL konfigūracija"
#: gdk/gdkdisplay.c:1662 #: gdk/gdkdisplay.c:1661
#, c-format #, c-format
msgid "EGL implementation is missing extension %s" msgid "EGL implementation is missing extension %s"
msgid_plural "EGL implementation is missing %2$d extensions: %1$s" msgid_plural "EGL implementation is missing %2$d extensions: %1$s"
@@ -91,23 +91,23 @@ msgstr[0] "EGL realizacijai trūksta %2$d plėtinio: %1$s"
msgstr[1] "EGL realizacijai trūksta %2$d plėtinių: %1$s" msgstr[1] "EGL realizacijai trūksta %2$d plėtinių: %1$s"
msgstr[2] "EGL realizacijai trūksta %2$d plėtinių: %1$s" msgstr[2] "EGL realizacijai trūksta %2$d plėtinių: %1$s"
#: gdk/gdkdisplay.c:1695 #: gdk/gdkdisplay.c:1694
msgid "libEGL not available in this sandbox" msgid "libEGL not available in this sandbox"
msgstr "libEGL šioje apribotoje veiksenoje neprieinama" msgstr "libEGL šioje apribotoje veiksenoje neprieinama"
#: gdk/gdkdisplay.c:1696 #: gdk/gdkdisplay.c:1695
msgid "libEGL not available" msgid "libEGL not available"
msgstr "libEGL neprieinama" msgstr "libEGL neprieinama"
#: gdk/gdkdisplay.c:1706 #: gdk/gdkdisplay.c:1705
msgid "Failed to create EGL display" msgid "Failed to create EGL display"
msgstr "Nepavyko sukurti EGL vaizduoklio" msgstr "Nepavyko sukurti EGL vaizduoklio"
#: gdk/gdkdisplay.c:1716 #: gdk/gdkdisplay.c:1715
msgid "Could not initialize EGL display" msgid "Could not initialize EGL display"
msgstr "Nepavyko inicializuoti EGL vaizduoklio" msgstr "Nepavyko inicializuoti EGL vaizduoklio"
#: gdk/gdkdisplay.c:1727 #: gdk/gdkdisplay.c:1726
#, c-format #, c-format
msgid "EGL version %d.%d is too old. GTK requires %d.%d" msgid "EGL version %d.%d is too old. GTK requires %d.%d"
msgstr "EGL versija %d.%d yra per sena. GTK reikalauja %d.%d" msgstr "EGL versija %d.%d yra per sena. GTK reikalauja %d.%d"
@@ -1039,18 +1039,18 @@ msgctxt "progress bar label"
msgid "%d%%" msgid "%d%%"
msgstr "%d%%" msgstr "%d%%"
#: gtk/deprecated/gtkcolorbutton.c:183 gtk/deprecated/gtkcolorbutton.c:311 #: gtk/deprecated/gtkcolorbutton.c:183 gtk/deprecated/gtkcolorbutton.c:314
#: gtk/gtkcolordialog.c:411 #: gtk/gtkcolordialog.c:411
msgid "Pick a Color" msgid "Pick a Color"
msgstr "Pasirinkite spalvą" msgstr "Pasirinkite spalvą"
#: gtk/deprecated/gtkcolorbutton.c:502 gtk/gtkcolorchooserwidget.c:313 #: gtk/deprecated/gtkcolorbutton.c:505 gtk/gtkcolorchooserwidget.c:313
#: gtk/gtkcolordialogbutton.c:335 #: gtk/gtkcolordialogbutton.c:335
#, c-format #, c-format
msgid "Red %d%%, Green %d%%, Blue %d%%, Alpha %d%%" msgid "Red %d%%, Green %d%%, Blue %d%%, Alpha %d%%"
msgstr "Raudona %d%%, Žalia %d%%, Mėlyna %d%%, Alfa %d%%" msgstr "Raudona %d%%, Žalia %d%%, Mėlyna %d%%, Alfa %d%%"
#: gtk/deprecated/gtkcolorbutton.c:508 gtk/gtkcolorchooserwidget.c:319 #: gtk/deprecated/gtkcolorbutton.c:511 gtk/gtkcolorchooserwidget.c:319
#: gtk/gtkcolordialogbutton.c:341 #: gtk/gtkcolordialogbutton.c:341
#, c-format #, c-format
msgid "Red %d%%, Green %d%%, Blue %d%%" msgid "Red %d%%, Green %d%%, Blue %d%%"
@@ -1060,17 +1060,17 @@ msgstr "Raudona %d%%, Žalia %d%%, Mėlyna %d%%"
msgid "Sans 12" msgid "Sans 12"
msgstr "Sans 12" msgstr "Sans 12"
#: gtk/deprecated/gtkfontbutton.c:507 gtk/deprecated/gtkfontbutton.c:621 #: gtk/deprecated/gtkfontbutton.c:507 gtk/deprecated/gtkfontbutton.c:624
#: gtk/gtkfontdialog.c:596 #: gtk/gtkfontdialog.c:596
msgid "Pick a Font" msgid "Pick a Font"
msgstr "Pasirinkite šriftą" msgstr "Pasirinkite šriftą"
#: gtk/deprecated/gtkfontbutton.c:597 gtk/gtkfilechooserwidget.c:3871 #: gtk/deprecated/gtkfontbutton.c:600 gtk/gtkfilechooserwidget.c:3871
#: gtk/gtkfontdialogbutton.c:126 gtk/inspector/visual.ui:169 #: gtk/gtkfontdialogbutton.c:126 gtk/inspector/visual.ui:169
msgid "Font" msgid "Font"
msgstr "Šriftas" msgstr "Šriftas"
#: gtk/deprecated/gtkfontbutton.c:1152 gtk/gtkfontdialogbutton.c:652 #: gtk/deprecated/gtkfontbutton.c:1155 gtk/gtkfontdialogbutton.c:652
msgctxt "font" msgctxt "font"
msgid "None" msgid "None"
msgstr "Nėra" msgstr "Nėra"
@@ -2134,7 +2134,7 @@ msgstr "_Dešinė:"
msgid "Paper Margins" msgid "Paper Margins"
msgstr "Popieriaus paraštės" msgstr "Popieriaus paraštės"
#: gtk/gtkentry.c:3673 #: gtk/gtkentry.c:3685
msgid "Insert Emoji" msgid "Insert Emoji"
msgstr "Įterpti emoji" msgstr "Įterpti emoji"
@@ -2292,7 +2292,7 @@ msgid "If you delete an item, it will be permanently lost."
msgstr "Jei ištrinsite elementą, jis bus negrįžtamai prarastas." msgstr "Jei ištrinsite elementą, jis bus negrįžtamai prarastas."
#: gtk/gtkfilechooserwidget.c:1185 gtk/gtkfilechooserwidget.c:1815 #: gtk/gtkfilechooserwidget.c:1185 gtk/gtkfilechooserwidget.c:1815
#: gtk/gtklabel.c:5695 gtk/gtktext.c:6145 gtk/gtktextview.c:9018 #: gtk/gtklabel.c:5695 gtk/gtktext.c:6147 gtk/gtktextview.c:9018
msgid "_Delete" msgid "_Delete"
msgstr "Iš_trinti" msgstr "Iš_trinti"
@@ -2630,19 +2630,19 @@ msgstr "Užverti"
msgid "Close the infobar" msgid "Close the infobar"
msgstr "Užverti informacijos juostą" msgstr "Užverti informacijos juostą"
#: gtk/gtklabel.c:5692 gtk/gtktext.c:6133 gtk/gtktextview.c:9006 #: gtk/gtklabel.c:5692 gtk/gtktext.c:6135 gtk/gtktextview.c:9006
msgid "Cu_t" msgid "Cu_t"
msgstr "_Iškirpti" msgstr "_Iškirpti"
#: gtk/gtklabel.c:5693 gtk/gtktext.c:6137 gtk/gtktextview.c:9010 #: gtk/gtklabel.c:5693 gtk/gtktext.c:6139 gtk/gtktextview.c:9010
msgid "_Copy" msgid "_Copy"
msgstr "_Kopijuoti" msgstr "_Kopijuoti"
#: gtk/gtklabel.c:5694 gtk/gtktext.c:6141 gtk/gtktextview.c:9014 #: gtk/gtklabel.c:5694 gtk/gtktext.c:6143 gtk/gtktextview.c:9014
msgid "_Paste" msgid "_Paste"
msgstr "Į_dėti" msgstr "Į_dėti"
#: gtk/gtklabel.c:5700 gtk/gtktext.c:6154 gtk/gtktextview.c:9039 #: gtk/gtklabel.c:5700 gtk/gtktext.c:6156 gtk/gtktextview.c:9039
msgid "Select _All" msgid "Select _All"
msgstr "P_ažymėti viską" msgstr "P_ažymėti viską"
@@ -3498,7 +3498,7 @@ msgstr "Nepavyko perkelti elemento su URI „%s“ į „%s“"
msgid "No registered application with name “%s” for item with URI “%s” found" msgid "No registered application with name “%s” for item with URI “%s” found"
msgstr "Nerasta registruota programa pavadinimu „%s“ elementui su URI „%s“" msgstr "Nerasta registruota programa pavadinimu „%s“ elementui su URI „%s“"
#: gtk/gtksearchentry.c:758 #: gtk/gtksearchentry.c:767
msgid "Clear Entry" msgid "Clear Entry"
msgstr "Išvalyti lauką" msgstr "Išvalyti lauką"
@@ -3589,7 +3589,7 @@ msgctxt "accessibility"
msgid "Sidebar" msgid "Sidebar"
msgstr "Šoninė juosta" msgstr "Šoninė juosta"
#: gtk/gtktext.c:6159 gtk/gtktextview.c:9044 #: gtk/gtktext.c:6161 gtk/gtktextview.c:9044
msgid "Insert _Emoji" msgid "Insert _Emoji"
msgstr "Įterpti _emoji" msgstr "Įterpti _emoji"
@@ -3967,8 +3967,8 @@ msgid "Surface"
msgstr "Paviršius" msgstr "Paviršius"
#: gtk/inspector/misc-info.ui:365 gtk/inspector/misc-info.ui:400 #: gtk/inspector/misc-info.ui:365 gtk/inspector/misc-info.ui:400
#: gtk/inspector/misc-info.ui:435 gtk/inspector/prop-editor.c:1150 #: gtk/inspector/misc-info.ui:435 gtk/inspector/prop-editor.c:1153
#: gtk/inspector/prop-editor.c:1533 gtk/inspector/window.ui:396 #: gtk/inspector/prop-editor.c:1536 gtk/inspector/window.ui:396
msgid "Properties" msgid "Properties"
msgstr "Savybės" msgstr "Savybės"
@@ -4020,7 +4020,7 @@ msgstr "Rodyklė: %p"
#. Translators: %s is a type name, for example #. Translators: %s is a type name, for example
#. * GtkPropertyExpression with value \"2.5\" #. * GtkPropertyExpression with value \"2.5\"
#. #.
#: gtk/inspector/prop-editor.c:824 #: gtk/inspector/prop-editor.c:827
#, c-format #, c-format
msgid "%s with value \"%s\"" msgid "%s with value \"%s\""
msgstr "%s su verte „%s“" msgstr "%s su verte „%s“"
@@ -4028,7 +4028,7 @@ msgstr "%s su verte „%s“"
#. Translators: Both %s are type names, for example #. Translators: Both %s are type names, for example
#. * GtkPropertyExpression with type GObject #. * GtkPropertyExpression with type GObject
#. #.
#: gtk/inspector/prop-editor.c:835 #: gtk/inspector/prop-editor.c:838
#, c-format #, c-format
msgid "%s with type %s" msgid "%s with type %s"
msgstr "%s su tipu %s" msgstr "%s su tipu %s"
@@ -4036,7 +4036,7 @@ msgstr "%s su tipu %s"
#. Translators: Both %s are type names, for example #. Translators: Both %s are type names, for example
#. * GtkObjectExpression for GtkStringObject 0x23456789 #. * GtkObjectExpression for GtkStringObject 0x23456789
#. #.
#: gtk/inspector/prop-editor.c:848 #: gtk/inspector/prop-editor.c:851
#, c-format #, c-format
msgid "%s for %s %p" msgid "%s for %s %p"
msgstr "%s %s %p" msgstr "%s %s %p"
@@ -4044,71 +4044,71 @@ msgstr "%s %s %p"
#. Translators: Both %s are type names, for example #. Translators: Both %s are type names, for example
#. * GtkPropertyExpression with value type: gchararray #. * GtkPropertyExpression with value type: gchararray
#. #.
#: gtk/inspector/prop-editor.c:878 #: gtk/inspector/prop-editor.c:881
#, c-format #, c-format
msgid "%s with value type %s" msgid "%s with value type %s"
msgstr "%s su %s tipo verte" msgstr "%s su %s tipo verte"
#: gtk/inspector/prop-editor.c:1227 #: gtk/inspector/prop-editor.c:1230
#, c-format #, c-format
msgid "Uneditable property type: %s" msgid "Uneditable property type: %s"
msgstr "Neredaguojamas savybės tipas: %s" msgstr "Neredaguojamas savybės tipas: %s"
#: gtk/inspector/prop-editor.c:1385 #: gtk/inspector/prop-editor.c:1388
msgctxt "column number" msgctxt "column number"
msgid "None" msgid "None"
msgstr "Nėra" msgstr "Nėra"
#: gtk/inspector/prop-editor.c:1422 #: gtk/inspector/prop-editor.c:1425
msgid "Attribute:" msgid "Attribute:"
msgstr "Atributas:" msgstr "Atributas:"
#: gtk/inspector/prop-editor.c:1425 #: gtk/inspector/prop-editor.c:1428
msgid "Model" msgid "Model"
msgstr "Modelis" msgstr "Modelis"
#: gtk/inspector/prop-editor.c:1430 #: gtk/inspector/prop-editor.c:1433
msgid "Column:" msgid "Column:"
msgstr "Stulpelis:" msgstr "Stulpelis:"
#. Translators: %s is a type name, for example #. Translators: %s is a type name, for example
#. * Action from 0x2345678 (GtkApplicationWindow) #. * Action from 0x2345678 (GtkApplicationWindow)
#. #.
#: gtk/inspector/prop-editor.c:1529 #: gtk/inspector/prop-editor.c:1532
#, c-format #, c-format
msgid "Action from: %p (%s)" msgid "Action from: %p (%s)"
msgstr "Veiksmas iš: %p (%s)" msgstr "Veiksmas iš: %p (%s)"
#: gtk/inspector/prop-editor.c:1584 #: gtk/inspector/prop-editor.c:1587
msgid "Reset" msgid "Reset"
msgstr "Atstatyti" msgstr "Atstatyti"
#: gtk/inspector/prop-editor.c:1592 #: gtk/inspector/prop-editor.c:1595
msgctxt "GtkSettings source" msgctxt "GtkSettings source"
msgid "Default" msgid "Default"
msgstr "Numatyta" msgstr "Numatyta"
#: gtk/inspector/prop-editor.c:1595 #: gtk/inspector/prop-editor.c:1598
msgctxt "GtkSettings source" msgctxt "GtkSettings source"
msgid "Theme" msgid "Theme"
msgstr "Tema" msgstr "Tema"
#: gtk/inspector/prop-editor.c:1598 #: gtk/inspector/prop-editor.c:1601
msgctxt "GtkSettings source" msgctxt "GtkSettings source"
msgid "XSettings" msgid "XSettings"
msgstr "XSettings" msgstr "XSettings"
#: gtk/inspector/prop-editor.c:1602 #: gtk/inspector/prop-editor.c:1605
msgctxt "GtkSettings source" msgctxt "GtkSettings source"
msgid "Application" msgid "Application"
msgstr "Programa" msgstr "Programa"
#: gtk/inspector/prop-editor.c:1605 #: gtk/inspector/prop-editor.c:1608
msgctxt "GtkSettings source" msgctxt "GtkSettings source"
msgid "Unknown" msgid "Unknown"
msgstr "Nežinoma" msgstr "Nežinoma"
#: gtk/inspector/prop-editor.c:1608 #: gtk/inspector/prop-editor.c:1611
msgid "Source:" msgid "Source:"
msgstr "Šaltinis:" msgstr "Šaltinis:"
@@ -7162,7 +7162,7 @@ msgstr ""
#: tools/gtk-builder-tool-enumerate.c:56 tools/gtk-builder-tool-preview.c:179 #: tools/gtk-builder-tool-enumerate.c:56 tools/gtk-builder-tool-preview.c:179
#: tools/gtk-builder-tool-preview.c:180 tools/gtk-builder-tool-screenshot.c:360 #: tools/gtk-builder-tool-preview.c:180 tools/gtk-builder-tool-screenshot.c:360
#: tools/gtk-builder-tool-simplify.c:2529 tools/gtk-builder-tool-validate.c:261 #: tools/gtk-builder-tool-simplify.c:2529 tools/gtk-builder-tool-validate.c:261
#: tools/gtk-rendernode-tool-info.c:200 tools/gtk-rendernode-tool-show.c:102 #: tools/gtk-rendernode-tool-info.c:202 tools/gtk-rendernode-tool-show.c:102
msgid "FILE" msgid "FILE"
msgstr "FAILAS" msgstr "FAILAS"
@@ -7445,37 +7445,37 @@ msgstr ""
" render Padaryti viršūnės atvaizdą\n" " render Padaryti viršūnės atvaizdą\n"
"\n" "\n"
#: tools/gtk-rendernode-tool-info.c:177 #: tools/gtk-rendernode-tool-info.c:179
#, c-format #, c-format
msgid "Number of nodes: %u\n" msgid "Number of nodes: %u\n"
msgstr "Viršūnių skaičius: %u\n" msgstr "Viršūnių skaičius: %u\n"
#: tools/gtk-rendernode-tool-info.c:184 #: tools/gtk-rendernode-tool-info.c:186
#, c-format #, c-format
msgid "Depth: %u\n" msgid "Depth: %u\n"
msgstr "Gylis: %u\n" msgstr "Gylis: %u\n"
#: tools/gtk-rendernode-tool-info.c:187 #: tools/gtk-rendernode-tool-info.c:189
#, c-format #, c-format
msgid "Bounds: %g x %g\n" msgid "Bounds: %g x %g\n"
msgstr "Paraštės: %g x %g\n" msgstr "Paraštės: %g x %g\n"
#: tools/gtk-rendernode-tool-info.c:188 #: tools/gtk-rendernode-tool-info.c:190
#, c-format #, c-format
msgid "Origin: %g %g\n" msgid "Origin: %g %g\n"
msgstr "Pradinė koordinatė: %g %g\n" msgstr "Pradinė koordinatė: %g %g\n"
#: tools/gtk-rendernode-tool-info.c:209 #: tools/gtk-rendernode-tool-info.c:211
msgid "Provide information about the render node." msgid "Provide information about the render node."
msgstr "Pateikti informaciją apie piešimo viršūnę." msgstr "Pateikti informaciją apie piešimo viršūnę."
#: tools/gtk-rendernode-tool-info.c:222 tools/gtk-rendernode-tool-show.c:130 #: tools/gtk-rendernode-tool-info.c:224 tools/gtk-rendernode-tool-show.c:130
#: tools/gtk-rendernode-tool-render.c:225 #: tools/gtk-rendernode-tool-render.c:225
#, c-format #, c-format
msgid "No .node file specified\n" msgid "No .node file specified\n"
msgstr "Nenurodytas .node failas\n" msgstr "Nenurodytas .node failas\n"
#: tools/gtk-rendernode-tool-info.c:228 #: tools/gtk-rendernode-tool-info.c:230
#, c-format #, c-format
msgid "Can only accept a single .node file\n" msgid "Can only accept a single .node file\n"
msgstr "Galima pateikti tik vieną .node failą\n" msgstr "Galima pateikti tik vieną .node failą\n"
@@ -7525,6 +7525,11 @@ msgstr "Galima piešti vienintelį .node failą į vienintelį išvesties failą
msgid "Error at %s: %s\n" msgid "Error at %s: %s\n"
msgstr "Klaida ties %s: %s\n" msgstr "Klaida ties %s: %s\n"
#: tools/gtk-rendernode-tool-utils.c:69
#, c-format
msgid "Failed to load node file: %s\n"
msgstr "Nepavyko įkelti viršūnių failo: %s\n"
#: tools/updateiconcache.c:1391 #: tools/updateiconcache.c:1391
#, c-format #, c-format
msgid "Failed to write header\n" msgid "Failed to write header\n"
+60 -55
View File
@@ -29,8 +29,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: GTK\n" "Project-Id-Version: GTK\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2023-09-05 19:13+0000\n" "POT-Creation-Date: 2023-09-21 10:15+0000\n"
"PO-Revision-Date: 2023-09-12 13:31-0300\n" "PO-Revision-Date: 2023-09-25 09:58-0300\n"
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n" "Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
"Language-Team: Brazilian Portuguese <https://br.gnome.org/traducao>\n" "Language-Team: Brazilian Portuguese <https://br.gnome.org/traducao>\n"
"Language: pt_BR\n" "Language: pt_BR\n"
@@ -79,55 +79,55 @@ msgstr "Não foi possível fornecer o conteúdo como %s"
msgid "The current backend does not support OpenGL" msgid "The current backend does not support OpenGL"
msgstr "O backend não oferece suporte a OpenGL" msgstr "O backend não oferece suporte a OpenGL"
#: gdk/gdkdisplay.c:1245 gdk/gdksurface.c:1252 #: gdk/gdkdisplay.c:1244 gdk/gdksurface.c:1252
msgid "Vulkan support disabled via GDK_DEBUG" msgid "Vulkan support disabled via GDK_DEBUG"
msgstr "Suporte a Vulkan desabilitado via GDK_DEBUG" msgstr "Suporte a Vulkan desabilitado via GDK_DEBUG"
#: gdk/gdkdisplay.c:1277 #: gdk/gdkdisplay.c:1276
msgid "GL support disabled via GDK_DEBUG" msgid "GL support disabled via GDK_DEBUG"
msgstr "Suporte a GL desabilitado via GDK_DEBUG" msgstr "Suporte a GL desabilitado via GDK_DEBUG"
#: gdk/gdkdisplay.c:1575 #: gdk/gdkdisplay.c:1574
msgid "No EGL configuration available" msgid "No EGL configuration available"
msgstr "Nenhuma configuração EGL está disponível" msgstr "Nenhuma configuração EGL está disponível"
#: gdk/gdkdisplay.c:1583 #: gdk/gdkdisplay.c:1582
msgid "Failed to get EGL configurations" msgid "Failed to get EGL configurations"
msgstr "Falha ao obter configurações EGL" msgstr "Falha ao obter configurações EGL"
#: gdk/gdkdisplay.c:1613 #: gdk/gdkdisplay.c:1612
msgid "No EGL configuration with required features found" msgid "No EGL configuration with required features found"
msgstr "" msgstr ""
"Não foi localizada nenhuma configuração EGL com os recursos necessários" "Não foi localizada nenhuma configuração EGL com os recursos necessários"
#: gdk/gdkdisplay.c:1620 #: gdk/gdkdisplay.c:1619
msgid "No perfect EGL configuration found" msgid "No perfect EGL configuration found"
msgstr "Nenhum configuração EGL perfeita localizada" msgstr "Nenhum configuração EGL perfeita localizada"
#: gdk/gdkdisplay.c:1662 #: gdk/gdkdisplay.c:1661
#, c-format #, c-format
msgid "EGL implementation is missing extension %s" msgid "EGL implementation is missing extension %s"
msgid_plural "EGL implementation is missing %2$d extensions: %1$s" msgid_plural "EGL implementation is missing %2$d extensions: %1$s"
msgstr[0] "A implementação de EGL não contém a extensão %s" msgstr[0] "A implementação de EGL não contém a extensão %s"
msgstr[1] "A implementação de EGL não contém %2$d extensões: %1$s" msgstr[1] "A implementação de EGL não contém %2$d extensões: %1$s"
#: gdk/gdkdisplay.c:1695 #: gdk/gdkdisplay.c:1694
msgid "libEGL not available in this sandbox" msgid "libEGL not available in this sandbox"
msgstr "libEGL não disponível nesta caixa de proteção" msgstr "libEGL não disponível nesta caixa de proteção"
#: gdk/gdkdisplay.c:1696 #: gdk/gdkdisplay.c:1695
msgid "libEGL not available" msgid "libEGL not available"
msgstr "libEGL não disponível" msgstr "libEGL não disponível"
#: gdk/gdkdisplay.c:1706 #: gdk/gdkdisplay.c:1705
msgid "Failed to create EGL display" msgid "Failed to create EGL display"
msgstr "Falha ao criar tela EGL" msgstr "Falha ao criar tela EGL"
#: gdk/gdkdisplay.c:1716 #: gdk/gdkdisplay.c:1715
msgid "Could not initialize EGL display" msgid "Could not initialize EGL display"
msgstr "Não foi possível inicializar a tela EGL" msgstr "Não foi possível inicializar a tela EGL"
#: gdk/gdkdisplay.c:1727 #: gdk/gdkdisplay.c:1726
#, c-format #, c-format
msgid "EGL version %d.%d is too old. GTK requires %d.%d" msgid "EGL version %d.%d is too old. GTK requires %d.%d"
msgstr "EGL versão %d.%d é muito velha. GTK requer %d.%d" msgstr "EGL versão %d.%d é muito velha. GTK requer %d.%d"
@@ -1092,18 +1092,18 @@ msgctxt "progress bar label"
msgid "%d%%" msgid "%d%%"
msgstr "%d%%" msgstr "%d%%"
#: gtk/deprecated/gtkcolorbutton.c:183 gtk/deprecated/gtkcolorbutton.c:311 #: gtk/deprecated/gtkcolorbutton.c:183 gtk/deprecated/gtkcolorbutton.c:314
#: gtk/gtkcolordialog.c:411 #: gtk/gtkcolordialog.c:411
msgid "Pick a Color" msgid "Pick a Color"
msgstr "Escolha uma cor" msgstr "Escolha uma cor"
#: gtk/deprecated/gtkcolorbutton.c:502 gtk/gtkcolorchooserwidget.c:313 #: gtk/deprecated/gtkcolorbutton.c:505 gtk/gtkcolorchooserwidget.c:313
#: gtk/gtkcolordialogbutton.c:335 #: gtk/gtkcolordialogbutton.c:335
#, c-format #, c-format
msgid "Red %d%%, Green %d%%, Blue %d%%, Alpha %d%%" msgid "Red %d%%, Green %d%%, Blue %d%%, Alpha %d%%"
msgstr "Vermelho %d%%, Verde %d%%, Azul %d%%, Alfa %d%%" msgstr "Vermelho %d%%, Verde %d%%, Azul %d%%, Alfa %d%%"
#: gtk/deprecated/gtkcolorbutton.c:508 gtk/gtkcolorchooserwidget.c:319 #: gtk/deprecated/gtkcolorbutton.c:511 gtk/gtkcolorchooserwidget.c:319
#: gtk/gtkcolordialogbutton.c:341 #: gtk/gtkcolordialogbutton.c:341
#, c-format #, c-format
msgid "Red %d%%, Green %d%%, Blue %d%%" msgid "Red %d%%, Green %d%%, Blue %d%%"
@@ -1113,17 +1113,17 @@ msgstr "Vermelho %d%%, Verde %d%%, Azul %d%%"
msgid "Sans 12" msgid "Sans 12"
msgstr "Sans 12" msgstr "Sans 12"
#: gtk/deprecated/gtkfontbutton.c:507 gtk/deprecated/gtkfontbutton.c:621 #: gtk/deprecated/gtkfontbutton.c:507 gtk/deprecated/gtkfontbutton.c:624
#: gtk/gtkfontdialog.c:596 #: gtk/gtkfontdialog.c:596
msgid "Pick a Font" msgid "Pick a Font"
msgstr "Selecione uma fonte" msgstr "Selecione uma fonte"
#: gtk/deprecated/gtkfontbutton.c:597 gtk/gtkfilechooserwidget.c:3871 #: gtk/deprecated/gtkfontbutton.c:600 gtk/gtkfilechooserwidget.c:3871
#: gtk/gtkfontdialogbutton.c:126 gtk/inspector/visual.ui:169 #: gtk/gtkfontdialogbutton.c:126 gtk/inspector/visual.ui:169
msgid "Font" msgid "Font"
msgstr "Fonte" msgstr "Fonte"
#: gtk/deprecated/gtkfontbutton.c:1152 gtk/gtkfontdialogbutton.c:652 #: gtk/deprecated/gtkfontbutton.c:1155 gtk/gtkfontdialogbutton.c:652
msgctxt "font" msgctxt "font"
msgid "None" msgid "None"
msgstr "Nenhuma" msgstr "Nenhuma"
@@ -2191,7 +2191,7 @@ msgstr "_Direita:"
msgid "Paper Margins" msgid "Paper Margins"
msgstr "Margens do papel" msgstr "Margens do papel"
#: gtk/gtkentry.c:3673 #: gtk/gtkentry.c:3685
msgid "Insert Emoji" msgid "Insert Emoji"
msgstr "Inserir emoji" msgstr "Inserir emoji"
@@ -2350,7 +2350,7 @@ msgid "If you delete an item, it will be permanently lost."
msgstr "Se você excluir um item, ele será permanentemente perdido." msgstr "Se você excluir um item, ele será permanentemente perdido."
#: gtk/gtkfilechooserwidget.c:1185 gtk/gtkfilechooserwidget.c:1815 #: gtk/gtkfilechooserwidget.c:1185 gtk/gtkfilechooserwidget.c:1815
#: gtk/gtklabel.c:5695 gtk/gtktext.c:6145 gtk/gtktextview.c:9018 #: gtk/gtklabel.c:5695 gtk/gtktext.c:6147 gtk/gtktextview.c:9018
msgid "_Delete" msgid "_Delete"
msgstr "E_xcluir" msgstr "E_xcluir"
@@ -2693,19 +2693,19 @@ msgstr "Fechar"
msgid "Close the infobar" msgid "Close the infobar"
msgstr "Fecha a barra de informações" msgstr "Fecha a barra de informações"
#: gtk/gtklabel.c:5692 gtk/gtktext.c:6133 gtk/gtktextview.c:9006 #: gtk/gtklabel.c:5692 gtk/gtktext.c:6135 gtk/gtktextview.c:9006
msgid "Cu_t" msgid "Cu_t"
msgstr "Recor_tar" msgstr "Recor_tar"
#: gtk/gtklabel.c:5693 gtk/gtktext.c:6137 gtk/gtktextview.c:9010 #: gtk/gtklabel.c:5693 gtk/gtktext.c:6139 gtk/gtktextview.c:9010
msgid "_Copy" msgid "_Copy"
msgstr "_Copiar" msgstr "_Copiar"
#: gtk/gtklabel.c:5694 gtk/gtktext.c:6141 gtk/gtktextview.c:9014 #: gtk/gtklabel.c:5694 gtk/gtktext.c:6143 gtk/gtktextview.c:9014
msgid "_Paste" msgid "_Paste"
msgstr "C_olar" msgstr "C_olar"
#: gtk/gtklabel.c:5700 gtk/gtktext.c:6154 gtk/gtktextview.c:9039 #: gtk/gtklabel.c:5700 gtk/gtktext.c:6156 gtk/gtktextview.c:9039
msgid "Select _All" msgid "Select _All"
msgstr "_Selecionar tudo" msgstr "_Selecionar tudo"
@@ -3569,7 +3569,7 @@ msgstr ""
"Não foi encontrado nenhum aplicativo registrado com o nome “%s” para o item " "Não foi encontrado nenhum aplicativo registrado com o nome “%s” para o item "
"com URI “%s”" "com URI “%s”"
#: gtk/gtksearchentry.c:758 #: gtk/gtksearchentry.c:767
msgid "Clear Entry" msgid "Clear Entry"
msgstr "Limpar entrada" msgstr "Limpar entrada"
@@ -3682,7 +3682,7 @@ msgctxt "accessibility"
msgid "Sidebar" msgid "Sidebar"
msgstr "Barra lateral" msgstr "Barra lateral"
#: gtk/gtktext.c:6159 gtk/gtktextview.c:9044 #: gtk/gtktext.c:6161 gtk/gtktextview.c:9044
msgid "Insert _Emoji" msgid "Insert _Emoji"
msgstr "Inserir _emoji" msgstr "Inserir _emoji"
@@ -4075,8 +4075,8 @@ msgid "Surface"
msgstr "Superfície" msgstr "Superfície"
#: gtk/inspector/misc-info.ui:365 gtk/inspector/misc-info.ui:400 #: gtk/inspector/misc-info.ui:365 gtk/inspector/misc-info.ui:400
#: gtk/inspector/misc-info.ui:435 gtk/inspector/prop-editor.c:1150 #: gtk/inspector/misc-info.ui:435 gtk/inspector/prop-editor.c:1153
#: gtk/inspector/prop-editor.c:1533 gtk/inspector/window.ui:396 #: gtk/inspector/prop-editor.c:1536 gtk/inspector/window.ui:396
msgid "Properties" msgid "Properties"
msgstr "Propriedades" msgstr "Propriedades"
@@ -4128,7 +4128,7 @@ msgstr "Ponteiro: %p"
#. Translators: %s is a type name, for example #. Translators: %s is a type name, for example
#. * GtkPropertyExpression with value \"2.5\" #. * GtkPropertyExpression with value \"2.5\"
#. #.
#: gtk/inspector/prop-editor.c:824 #: gtk/inspector/prop-editor.c:827
#, c-format #, c-format
msgid "%s with value \"%s\"" msgid "%s with value \"%s\""
msgstr "%s com valor “%s”" msgstr "%s com valor “%s”"
@@ -4136,7 +4136,7 @@ msgstr "%s com valor “%s”"
#. Translators: Both %s are type names, for example #. Translators: Both %s are type names, for example
#. * GtkPropertyExpression with type GObject #. * GtkPropertyExpression with type GObject
#. #.
#: gtk/inspector/prop-editor.c:835 #: gtk/inspector/prop-editor.c:838
#, c-format #, c-format
msgid "%s with type %s" msgid "%s with type %s"
msgstr "%s com tipo %s" msgstr "%s com tipo %s"
@@ -4144,7 +4144,7 @@ msgstr "%s com tipo %s"
#. Translators: Both %s are type names, for example #. Translators: Both %s are type names, for example
#. * GtkObjectExpression for GtkStringObject 0x23456789 #. * GtkObjectExpression for GtkStringObject 0x23456789
#. #.
#: gtk/inspector/prop-editor.c:848 #: gtk/inspector/prop-editor.c:851
#, c-format #, c-format
msgid "%s for %s %p" msgid "%s for %s %p"
msgstr "%s para %s %p" msgstr "%s para %s %p"
@@ -4152,71 +4152,71 @@ msgstr "%s para %s %p"
#. Translators: Both %s are type names, for example #. Translators: Both %s are type names, for example
#. * GtkPropertyExpression with value type: gchararray #. * GtkPropertyExpression with value type: gchararray
#. #.
#: gtk/inspector/prop-editor.c:878 #: gtk/inspector/prop-editor.c:881
#, c-format #, c-format
msgid "%s with value type %s" msgid "%s with value type %s"
msgstr "%s com tipo de valor %s" msgstr "%s com tipo de valor %s"
#: gtk/inspector/prop-editor.c:1227 #: gtk/inspector/prop-editor.c:1230
#, c-format #, c-format
msgid "Uneditable property type: %s" msgid "Uneditable property type: %s"
msgstr "Tipo de propriedade não editável: %s" msgstr "Tipo de propriedade não editável: %s"
#: gtk/inspector/prop-editor.c:1385 #: gtk/inspector/prop-editor.c:1388
msgctxt "column number" msgctxt "column number"
msgid "None" msgid "None"
msgstr "Nenhum" msgstr "Nenhum"
#: gtk/inspector/prop-editor.c:1422 #: gtk/inspector/prop-editor.c:1425
msgid "Attribute:" msgid "Attribute:"
msgstr "Atributo:" msgstr "Atributo:"
#: gtk/inspector/prop-editor.c:1425 #: gtk/inspector/prop-editor.c:1428
msgid "Model" msgid "Model"
msgstr "Modelo" msgstr "Modelo"
#: gtk/inspector/prop-editor.c:1430 #: gtk/inspector/prop-editor.c:1433
msgid "Column:" msgid "Column:"
msgstr "Coluna:" msgstr "Coluna:"
#. Translators: %s is a type name, for example #. Translators: %s is a type name, for example
#. * Action from 0x2345678 (GtkApplicationWindow) #. * Action from 0x2345678 (GtkApplicationWindow)
#. #.
#: gtk/inspector/prop-editor.c:1529 #: gtk/inspector/prop-editor.c:1532
#, c-format #, c-format
msgid "Action from: %p (%s)" msgid "Action from: %p (%s)"
msgstr "Ação de: %p (%s)" msgstr "Ação de: %p (%s)"
#: gtk/inspector/prop-editor.c:1584 #: gtk/inspector/prop-editor.c:1587
msgid "Reset" msgid "Reset"
msgstr "Redefinir" msgstr "Redefinir"
#: gtk/inspector/prop-editor.c:1592 #: gtk/inspector/prop-editor.c:1595
msgctxt "GtkSettings source" msgctxt "GtkSettings source"
msgid "Default" msgid "Default"
msgstr "Padrão" msgstr "Padrão"
#: gtk/inspector/prop-editor.c:1595 #: gtk/inspector/prop-editor.c:1598
msgctxt "GtkSettings source" msgctxt "GtkSettings source"
msgid "Theme" msgid "Theme"
msgstr "Tema" msgstr "Tema"
#: gtk/inspector/prop-editor.c:1598 #: gtk/inspector/prop-editor.c:1601
msgctxt "GtkSettings source" msgctxt "GtkSettings source"
msgid "XSettings" msgid "XSettings"
msgstr "XSettings" msgstr "XSettings"
#: gtk/inspector/prop-editor.c:1602 #: gtk/inspector/prop-editor.c:1605
msgctxt "GtkSettings source" msgctxt "GtkSettings source"
msgid "Application" msgid "Application"
msgstr "Aplicativo" msgstr "Aplicativo"
#: gtk/inspector/prop-editor.c:1605 #: gtk/inspector/prop-editor.c:1608
msgctxt "GtkSettings source" msgctxt "GtkSettings source"
msgid "Unknown" msgid "Unknown"
msgstr "Desconhecido" msgstr "Desconhecido"
#: gtk/inspector/prop-editor.c:1608 #: gtk/inspector/prop-editor.c:1611
msgid "Source:" msgid "Source:"
msgstr "Fonte:" msgstr "Fonte:"
@@ -7294,7 +7294,7 @@ msgstr ""
#: tools/gtk-builder-tool-enumerate.c:56 tools/gtk-builder-tool-preview.c:179 #: tools/gtk-builder-tool-enumerate.c:56 tools/gtk-builder-tool-preview.c:179
#: tools/gtk-builder-tool-preview.c:180 tools/gtk-builder-tool-screenshot.c:360 #: tools/gtk-builder-tool-preview.c:180 tools/gtk-builder-tool-screenshot.c:360
#: tools/gtk-builder-tool-simplify.c:2529 tools/gtk-builder-tool-validate.c:261 #: tools/gtk-builder-tool-simplify.c:2529 tools/gtk-builder-tool-validate.c:261
#: tools/gtk-rendernode-tool-info.c:200 tools/gtk-rendernode-tool-show.c:102 #: tools/gtk-rendernode-tool-info.c:202 tools/gtk-rendernode-tool-show.c:102
msgid "FILE" msgid "FILE"
msgstr "ARQUIVO" msgstr "ARQUIVO"
@@ -7580,37 +7580,37 @@ msgstr ""
" show Mostra o nó\n" " show Mostra o nó\n"
" render Faz uma captura de tela do nó\n" " render Faz uma captura de tela do nó\n"
#: tools/gtk-rendernode-tool-info.c:177 #: tools/gtk-rendernode-tool-info.c:179
#, c-format #, c-format
msgid "Number of nodes: %u\n" msgid "Number of nodes: %u\n"
msgstr "Número de nós: %u\n" msgstr "Número de nós: %u\n"
#: tools/gtk-rendernode-tool-info.c:184 #: tools/gtk-rendernode-tool-info.c:186
#, c-format #, c-format
msgid "Depth: %u\n" msgid "Depth: %u\n"
msgstr "Profundidade: %u\n" msgstr "Profundidade: %u\n"
#: tools/gtk-rendernode-tool-info.c:187 #: tools/gtk-rendernode-tool-info.c:189
#, c-format #, c-format
msgid "Bounds: %g x %g\n" msgid "Bounds: %g x %g\n"
msgstr "Limites: %g x %g\n" msgstr "Limites: %g x %g\n"
#: tools/gtk-rendernode-tool-info.c:188 #: tools/gtk-rendernode-tool-info.c:190
#, c-format #, c-format
msgid "Origin: %g %g\n" msgid "Origin: %g %g\n"
msgstr "Origem: %g %g\n" msgstr "Origem: %g %g\n"
#: tools/gtk-rendernode-tool-info.c:209 #: tools/gtk-rendernode-tool-info.c:211
msgid "Provide information about the render node." msgid "Provide information about the render node."
msgstr "Fornece informações sobre o nó de renderização." msgstr "Fornece informações sobre o nó de renderização."
#: tools/gtk-rendernode-tool-info.c:222 tools/gtk-rendernode-tool-show.c:130 #: tools/gtk-rendernode-tool-info.c:224 tools/gtk-rendernode-tool-show.c:130
#: tools/gtk-rendernode-tool-render.c:225 #: tools/gtk-rendernode-tool-render.c:225
#, c-format #, c-format
msgid "No .node file specified\n" msgid "No .node file specified\n"
msgstr "Nenhum arquivo .node especificado\n" msgstr "Nenhum arquivo .node especificado\n"
#: tools/gtk-rendernode-tool-info.c:228 #: tools/gtk-rendernode-tool-info.c:230
#, c-format #, c-format
msgid "Can only accept a single .node file\n" msgid "Can only accept a single .node file\n"
msgstr "Pode aceitar apenas um único arquivo .node\n" msgstr "Pode aceitar apenas um único arquivo .node\n"
@@ -7661,6 +7661,11 @@ msgstr ""
msgid "Error at %s: %s\n" msgid "Error at %s: %s\n"
msgstr "Erro em %s: %s\n" msgstr "Erro em %s: %s\n"
#: tools/gtk-rendernode-tool-utils.c:69
#, c-format
msgid "Failed to load node file: %s\n"
msgstr "Falha ao carregar o arquivo de nó: %s\n"
#: tools/updateiconcache.c:1391 #: tools/updateiconcache.c:1391
#, c-format #, c-format
msgid "Failed to write header\n" msgid "Failed to write header\n"
+514 -190
View File
File diff suppressed because it is too large Load Diff
+34 -31
View File
@@ -22,16 +22,16 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gtk\n" "Project-Id-Version: gtk\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2023-09-19 12:32+0000\n" "POT-Creation-Date: 2023-10-13 09:55+0000\n"
"PO-Revision-Date: 2023-09-19 18:25+0300\n" "PO-Revision-Date: 2023-10-14 08:00+0300\n"
"Last-Translator: Sabri Ünal <libreajans@gmail.com>\n" "Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n"
"Language-Team: Türkçe <takim@gnome.org.tr>\n" "Language-Team: Türkçe <takim@gnome.org.tr>\n"
"Language: tr\n" "Language: tr\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n" "Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 3.2.2\n" "X-Generator: Poedit 3.4\n"
#: gdk/broadway/gdkbroadway-server.c:135 #: gdk/broadway/gdkbroadway-server.c:135
#, c-format #, c-format
@@ -61,58 +61,58 @@ msgstr "İçerikler “%s” olarak sağlanamıyor"
msgid "Cannot provide contents as %s" msgid "Cannot provide contents as %s"
msgstr "İçerikler %s olarak sağlanamıyor" msgstr "İçerikler %s olarak sağlanamıyor"
#: gdk/gdkdisplay.c:156 gdk/gdkglcontext.c:442 #: gdk/gdkdisplay.c:163 gdk/gdkglcontext.c:442
msgid "The current backend does not support OpenGL" msgid "The current backend does not support OpenGL"
msgstr "Şimdiki arka uç OpenGLi desteklemiyor" msgstr "Şimdiki arka uç OpenGLi desteklemiyor"
#: gdk/gdkdisplay.c:1244 gdk/gdksurface.c:1252 #: gdk/gdkdisplay.c:1258 gdk/gdksurface.c:1252
msgid "Vulkan support disabled via GDK_DEBUG" msgid "Vulkan support disabled via GDK_DEBUG"
msgstr "Vulkan desteği GDK_DEBUG yoluyla devre dışı bırakılmış" msgstr "Vulkan desteği GDK_DEBUG yoluyla devre dışı bırakılmış"
#: gdk/gdkdisplay.c:1276 #: gdk/gdkdisplay.c:1290
msgid "GL support disabled via GDK_DEBUG" msgid "GL support disabled via GDK_DEBUG"
msgstr "GL desteği, GDK_DEBUG yoluyla devre dışı bırakılmış" msgstr "GL desteği, GDK_DEBUG yoluyla devre dışı bırakılmış"
#: gdk/gdkdisplay.c:1574 #: gdk/gdkdisplay.c:1588
msgid "No EGL configuration available" msgid "No EGL configuration available"
msgstr "Kullanılabilir EGL yapılandırması yok" msgstr "Kullanılabilir EGL yapılandırması yok"
#: gdk/gdkdisplay.c:1582 #: gdk/gdkdisplay.c:1596
msgid "Failed to get EGL configurations" msgid "Failed to get EGL configurations"
msgstr "EGL yapılandırmaları alınamadı" msgstr "EGL yapılandırmaları alınamadı"
#: gdk/gdkdisplay.c:1612 #: gdk/gdkdisplay.c:1626
msgid "No EGL configuration with required features found" msgid "No EGL configuration with required features found"
msgstr "Gerekli özellikleri olan EGL yapılandırması bulunamadı" msgstr "Gerekli özellikleri olan EGL yapılandırması bulunamadı"
#: gdk/gdkdisplay.c:1619 #: gdk/gdkdisplay.c:1633
msgid "No perfect EGL configuration found" msgid "No perfect EGL configuration found"
msgstr "Kusursuz EGL yapılandırması bulunamadı" msgstr "Kusursuz EGL yapılandırması bulunamadı"
#: gdk/gdkdisplay.c:1661 #: gdk/gdkdisplay.c:1675
#, c-format #, c-format
msgid "EGL implementation is missing extension %s" msgid "EGL implementation is missing extension %s"
msgid_plural "EGL implementation is missing %2$d extensions: %1$s" msgid_plural "EGL implementation is missing %2$d extensions: %1$s"
msgstr[0] "EGL uygulamasında %2$d eksik uzantı: %1$s" msgstr[0] "EGL uygulamasında %2$d eksik uzantı: %1$s"
# https://twitter.com/mserdark/status/932936929213079559 # https://twitter.com/mserdark/status/932936929213079559
#: gdk/gdkdisplay.c:1694 #: gdk/gdkdisplay.c:1708
msgid "libEGL not available in this sandbox" msgid "libEGL not available in this sandbox"
msgstr "libEGL bu kum havuzunda kullanılamıyor" msgstr "libEGL bu kum havuzunda kullanılamıyor"
#: gdk/gdkdisplay.c:1695 #: gdk/gdkdisplay.c:1709
msgid "libEGL not available" msgid "libEGL not available"
msgstr "libEGL kullanılamıyor" msgstr "libEGL kullanılamıyor"
#: gdk/gdkdisplay.c:1705 #: gdk/gdkdisplay.c:1719
msgid "Failed to create EGL display" msgid "Failed to create EGL display"
msgstr "EGL ekranı oluşturulamadı" msgstr "EGL ekranı oluşturulamadı"
#: gdk/gdkdisplay.c:1715 #: gdk/gdkdisplay.c:1729
msgid "Could not initialize EGL display" msgid "Could not initialize EGL display"
msgstr "EGL ekranı ilklendirilemedi" msgstr "EGL ekranı ilklendirilemedi"
#: gdk/gdkdisplay.c:1726 #: gdk/gdkdisplay.c:1740
#, c-format #, c-format
msgid "EGL version %d.%d is too old. GTK requires %d.%d" msgid "EGL version %d.%d is too old. GTK requires %d.%d"
msgstr "EGL sürümü %d.%d çok eski. GTK, %d.%d gerektiriyor" msgstr "EGL sürümü %d.%d çok eski. GTK, %d.%d gerektiriyor"
@@ -147,12 +147,12 @@ msgstr "Uygulama %s APIsini desteklemiyor"
#. translators: This is about OpenGL backend names, like #. translators: This is about OpenGL backend names, like
#. * "Trying to use X11 GLX, but EGL is already in use" #. * "Trying to use X11 GLX, but EGL is already in use"
#: gdk/gdkglcontext.c:1864 #: gdk/gdkglcontext.c:1914
#, c-format #, c-format
msgid "Trying to use %s, but %s is already in use" msgid "Trying to use %s, but %s is already in use"
msgstr "%s kullanılmaya çalışılıyor ancak şu anda %s kullanılıyor" msgstr "%s kullanılmaya çalışılıyor ancak şu anda %s kullanılıyor"
#: gdk/gdktexture.c:528 #: gdk/gdktexture.c:530
msgid "Unknown image format." msgid "Unknown image format."
msgstr "Bilinmeyen resim biçimi." msgstr "Bilinmeyen resim biçimi."
@@ -1719,6 +1719,11 @@ msgctxt "accessibility"
msgid "toggle button" msgid "toggle button"
msgstr "aç/kapat düğmesi" msgstr "aç/kapat düğmesi"
#: gtk/gtkaccessible.c:835
msgctxt "accessibility"
msgid "paragraph"
msgstr "paragraf"
#: gtk/gtkalertdialog.c:668 gtk/print/gtkcustompaperunixdialog.c:322 #: gtk/gtkalertdialog.c:668 gtk/print/gtkcustompaperunixdialog.c:322
#: gtk/gtkmessagedialog.c:166 gtk/ui/gtkassistant.ui:40 #: gtk/gtkmessagedialog.c:166 gtk/ui/gtkassistant.ui:40
msgid "_Close" msgid "_Close"
@@ -2204,11 +2209,11 @@ msgstr "Bu adda dosya zaten var"
#: gtk/gtkmessagedialog.c:179 gtk/gtkmountoperation.c:608 #: gtk/gtkmessagedialog.c:179 gtk/gtkmountoperation.c:608
#: gtk/print/gtkpagesetupunixdialog.c:282 gtk/print/gtkprintbackend.c:638 #: gtk/print/gtkpagesetupunixdialog.c:282 gtk/print/gtkprintbackend.c:638
#: gtk/print/gtkprintunixdialog.c:682 gtk/print/gtkprintunixdialog.c:839 #: gtk/print/gtkprintunixdialog.c:682 gtk/print/gtkprintunixdialog.c:839
#: gtk/gtkwindow.c:6242 gtk/ui/gtkappchooserdialog.ui:48 #: gtk/gtkwindow.c:6243 gtk/ui/gtkappchooserdialog.ui:48
#: gtk/ui/gtkassistant.ui:52 gtk/ui/gtkcolorchooserdialog.ui:36 #: gtk/ui/gtkassistant.ui:52 gtk/ui/gtkcolorchooserdialog.ui:36
#: gtk/ui/gtkfontchooserdialog.ui:27 #: gtk/ui/gtkfontchooserdialog.ui:27
msgid "_Cancel" msgid "_Cancel"
msgstr "_İptal Et" msgstr "İ_ptal"
#: gtk/gtkfilechoosernative.c:521 gtk/gtkfilechoosernative.c:594 #: gtk/gtkfilechoosernative.c:521 gtk/gtkfilechoosernative.c:594
#: gtk/gtkfiledialog.c:815 gtk/gtkplacessidebar.c:3149 #: gtk/gtkfiledialog.c:815 gtk/gtkplacessidebar.c:3149
@@ -2728,7 +2733,7 @@ msgid "Play"
msgstr "Oynat" msgstr "Oynat"
#: gtk/gtkmessagedialog.c:162 gtk/gtkmessagedialog.c:180 #: gtk/gtkmessagedialog.c:162 gtk/gtkmessagedialog.c:180
#: gtk/print/gtkprintbackend.c:639 gtk/gtkwindow.c:6243 #: gtk/print/gtkprintbackend.c:639 gtk/gtkwindow.c:6244
msgid "_OK" msgid "_OK"
msgstr "_Tamam" msgstr "_Tamam"
@@ -3144,7 +3149,7 @@ msgstr "Ba_ğlan"
#. if it wasn't cancelled show a dialog #. if it wasn't cancelled show a dialog
#: gtk/gtkplacesview.c:1353 #: gtk/gtkplacesview.c:1353
msgid "Unable to unmount volume" msgid "Unable to unmount volume"
msgstr "Birim ayrılamıyor" msgstr "Birim ayrılamadı"
#. Allow to cancel the operation #. Allow to cancel the operation
#: gtk/gtkplacesview.c:1445 #: gtk/gtkplacesview.c:1445
@@ -3200,7 +3205,7 @@ msgstr "_Bağlan"
#: gtk/gtkplacesview.c:1894 #: gtk/gtkplacesview.c:1894
msgid "Unable to get remote server location" msgid "Unable to get remote server location"
msgstr "Uzak sunucu konumu alınamıyor" msgstr "Uzak sunucu konumu alınamadı"
#: gtk/gtkplacesview.c:2038 gtk/gtkplacesview.c:2047 #: gtk/gtkplacesview.c:2038 gtk/gtkplacesview.c:2047
msgid "Networks" msgid "Networks"
@@ -3326,8 +3331,8 @@ msgstr "En olası nedeni geçici dosyanın oluşturulamamasıdır."
#. window #. window
#: gtk/print/gtkprintoperation-portal.c:264 #: gtk/print/gtkprintoperation-portal.c:264
#: gtk/print/gtkprintoperation-portal.c:584 #: gtk/print/gtkprintoperation-portal.c:594
#: gtk/print/gtkprintoperation-portal.c:653 gtk/print/gtkprintunixdialog.c:3008 #: gtk/print/gtkprintoperation-portal.c:663 gtk/print/gtkprintunixdialog.c:3008
msgid "Print" msgid "Print"
msgstr "Yazdır" msgstr "Yazdır"
@@ -3602,12 +3607,12 @@ msgstr "_Geri Al"
msgid "_Redo" msgid "_Redo"
msgstr "_Yinele" msgstr "_Yinele"
#: gtk/gtkwindow.c:6231 #: gtk/gtkwindow.c:6232
#, c-format #, c-format
msgid "Do you want to use GTK Inspector?" msgid "Do you want to use GTK Inspector?"
msgstr "GTK Denetleyicisi kullanmak istiyor musunuz?" msgstr "GTK Denetleyicisi kullanmak istiyor musunuz?"
#: gtk/gtkwindow.c:6233 #: gtk/gtkwindow.c:6234
#, c-format #, c-format
msgid "" msgid ""
"GTK Inspector is an interactive debugger that lets you explore and modify " "GTK Inspector is an interactive debugger that lets you explore and modify "
@@ -3618,7 +3623,7 @@ msgstr ""
"izin veren etkileşimli hata ayıklayıcıdır. Bunun kullanılması uygulamanın " "izin veren etkileşimli hata ayıklayıcıdır. Bunun kullanılması uygulamanın "
"kesilmesine ya da çökmesine neden olabilir." "kesilmesine ya da çökmesine neden olabilir."
#: gtk/gtkwindow.c:6238 #: gtk/gtkwindow.c:6239
msgid "Dont show this message again" msgid "Dont show this message again"
msgstr "Bu iletiyi yeniden gösterme" msgstr "Bu iletiyi yeniden gösterme"
@@ -7533,7 +7538,6 @@ msgstr "%d kübik"
#: tools/gtk-path-tool-info.c:159 #: tools/gtk-path-tool-info.c:159
#, c-format #, c-format
#| msgid "%d cubics"
msgid "%d conics" msgid "%d conics"
msgstr "%d konik" msgstr "%d konik"
@@ -7843,7 +7847,6 @@ msgstr "%s. satırda hata: %s\n"
#: tools/gtk-rendernode-tool-utils.c:69 #: tools/gtk-rendernode-tool-utils.c:69
#, c-format #, c-format
#| msgid "Failed to open file %s : %s\n"
msgid "Failed to load node file: %s\n" msgid "Failed to load node file: %s\n"
msgstr "Düğüm dosyası yüklenemedi: %s\n" msgstr "Düğüm dosyası yüklenemedi: %s\n"
@@ -0,0 +1,10 @@
mask {
source: color {
bounds: 0 0 16 16;
color: rgb(85,109,89);
}
mask: texture {
bounds: 0 0 16 16;
texture: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAAmJLR0QAKwYx2nIAAAIbSURBVCgVARAC7/0BRP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAD6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAEAADCAAAAAABE/wAAAAAAAAAAAAAAAAAAvAEAAAAARAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABRP/5AQAAAAAH/wAAAAAAAAAAAAAAAAAA+QEAAAAAB/8EAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAC+AAAAAABCAAAAAAAAAAAAAAAAAAAAvgAAAAAAQgAEAAD+AAAAAAC8AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABRP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADS0BDC/NHlFQAAAABJRU5ErkJggg==");
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

-551
View File
@@ -1,551 +0,0 @@
#include <gtk/gtk.h>
#include "gsk/gskcurveprivate.h"
static void
test_line_line_intersection (void)
{
GskCurve c1, c2;
graphene_point_t p1[2], p2[2];
float t1, t2;
graphene_point_t p;
GskPathIntersection kind;
int n;
graphene_point_init (&p1[0], 10, 0);
graphene_point_init (&p1[1], 10, 100);
graphene_point_init (&p2[0], 0, 10);
graphene_point_init (&p2[1], 100, 10);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_LINE, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_LINE, p2));
n = gsk_curve_intersect (&c1, &c2, &t1, &t2, &p, &kind, 1);
g_assert_cmpint (n, ==, 1);
g_assert_cmpfloat_with_epsilon (t1, 0.1, 0.0001);
g_assert_cmpfloat_with_epsilon (t2, 0.1, 0.0001);
g_assert_true (graphene_point_near (&p, &GRAPHENE_POINT_INIT (10, 10), 0.0001));
}
static void
test_line_line_end_intersection (void)
{
GskCurve c1, c2;
graphene_point_t p1[2], p2[2];
float t1, t2;
graphene_point_t p;
GskPathIntersection kind;
int n;
graphene_point_init (&p1[0], 10, 0);
graphene_point_init (&p1[1], 10, 100);
graphene_point_init (&p2[0], 10, 100);
graphene_point_init (&p2[1], 100, 10);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_LINE, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_LINE, p2));
n = gsk_curve_intersect (&c1, &c2, &t1, &t2, &p, &kind, 1);
g_assert_cmpint (n, ==, 1);
g_assert_cmpfloat_with_epsilon (t1, 1, 0.0001);
g_assert_cmpfloat_with_epsilon (t2, 0, 0.0001);
g_assert_true (graphene_point_near (&p, &GRAPHENE_POINT_INIT (10, 100), 0.0001));
}
static void
test_line_line_none_intersection (void)
{
GskCurve c1, c2;
graphene_point_t p1[2], p2[2];
float t1, t2;
graphene_point_t p;
GskPathIntersection kind;
int n;
graphene_point_init (&p1[0], 0, 0);
graphene_point_init (&p1[1], 10, 0);
graphene_point_init (&p2[0], 20, 0);
graphene_point_init (&p2[1], 30, 0);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_LINE, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_LINE, p2));
n = gsk_curve_intersect (&c1, &c2, &t1, &t2, &p, &kind, 1);
g_assert_cmpint (n, ==, 0);
graphene_point_init (&p1[0], 247.103424, 95.7965317);
graphene_point_init (&p1[1], 205.463974, 266.758484);
graphene_point_init (&p2[0], 183.735962, 355.968689);
graphene_point_init (&p2[1], 121.553253, 611.27655);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_LINE, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_LINE, p2));
n = gsk_curve_intersect (&c1, &c2, &t1, &t2, &p, &kind, 1);
g_assert_cmpint (n, ==, 0);
}
static void
test_line_line_parallel (void)
{
GskCurve c1, c2;
graphene_point_t p1[2], p2[2];
float t1[2], t2[2];
graphene_point_t p[2];
GskPathIntersection kind[2];
int n;
graphene_point_init (&p1[0], 10, 10);
graphene_point_init (&p1[1], 110, 10);
graphene_point_init (&p2[0], 20, 10);
graphene_point_init (&p2[1], 120, 10);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_LINE, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_LINE, p2));
n = gsk_curve_intersect (&c1, &c2, t1, t2, p, kind, 2);
g_assert_cmpint (n, ==, 2);
g_assert_cmpfloat_with_epsilon (t1[0], 0.1f, 0.01);
g_assert_cmpfloat_with_epsilon (t1[1], 1.f, 0.01);
g_assert_cmpfloat_with_epsilon (t2[0], 0.f, 0.01);
g_assert_cmpfloat_with_epsilon (t2[1], 0.9f, 0.01);
}
static void
test_line_line_same (void)
{
GskCurve c1, c2;
graphene_point_t p1[2], p2[2];
float t1[2], t2[2];
graphene_point_t p[2];
GskPathIntersection kind[2];
int n;
graphene_point_init (&p1[0], 10, 10);
graphene_point_init (&p1[1], 100, 10);
graphene_point_init (&p2[0], 10, 10);
graphene_point_init (&p2[1], 100, 10);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_LINE, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_LINE, p2));
n = gsk_curve_intersect (&c1, &c2, t1, t2, p, kind, 2);
g_assert_cmpint (n, ==, 2);
g_assert_cmpfloat_with_epsilon (t1[0], 0.f, 0.01);
g_assert_cmpfloat_with_epsilon (t1[1], 1.f, 0.01);
g_assert_cmpfloat_with_epsilon (t2[0], 0.f, 0.01);
g_assert_cmpfloat_with_epsilon (t2[1], 1.f, 0.01);
}
static void
test_line_curve_intersection (void)
{
GskCurve c1, c2;
graphene_point_t p1[4], p2[2];
float t1[9], t2[9];
graphene_point_t p[9];
GskPathIntersection kind[9];
int n;
GskBoundingBox b;
graphene_point_init (&p1[0], 0, 100);
graphene_point_init (&p1[1], 50, 100);
graphene_point_init (&p1[2], 50, 0);
graphene_point_init (&p1[3], 100, 0);
graphene_point_init (&p2[0], 0, 0);
graphene_point_init (&p2[1], 100, 100);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_CUBIC, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_LINE, p2));
n = gsk_curve_intersect (&c1, &c2, t1, t2, p, kind, 1);
g_assert_cmpint (n, ==, 1);
g_assert_cmpfloat_with_epsilon (t1[0], 0.5, 0.0001);
g_assert_cmpfloat_with_epsilon (t2[0], 0.5, 0.0001);
g_assert_true (graphene_point_near (&p[0], &GRAPHENE_POINT_INIT (50, 50), 0.0001));
gsk_curve_get_tight_bounds (&c1, &b);
gsk_bounding_box_contains_point (&b, &p[0]);
gsk_curve_get_tight_bounds (&c2, &b);
gsk_bounding_box_contains_point (&b, &p[0]);
}
static void
test_line_curve_multiple_intersection (void)
{
GskCurve c1, c2;
graphene_point_t p1[4], p2[2];
float t1[9], t2[9];
graphene_point_t p[9];
GskPathIntersection kind[9];
graphene_point_t pp;
int n;
GskBoundingBox b1, b2;
graphene_point_init (&p1[0], 100, 200);
graphene_point_init (&p1[1], 350, 100);
graphene_point_init (&p1[2], 100, 350);
graphene_point_init (&p1[3], 400, 300);
graphene_point_init (&p2[0], 0, 0);
graphene_point_init (&p2[1], 100, 100);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_CUBIC, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_LINE, p2));
n = gsk_curve_intersect (&c1, &c2, t1, t2, p, kind, 3);
g_assert_cmpint (n, ==, 0);
graphene_point_init (&p2[0], 0, 0);
graphene_point_init (&p2[1], 200, 200);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_CUBIC, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_LINE, p2));
n = gsk_curve_intersect (&c1, &c2, t1, t2, p, kind, 3);
g_assert_cmpint (n, ==, 1);
g_assert_cmpfloat_with_epsilon (t1[0], 0.136196628, 0.0001);
g_assert_cmpfloat_with_epsilon (t2[0], 0.88487947, 0.0001);
g_assert_true (graphene_point_near (&p[0], &GRAPHENE_POINT_INIT (176.975891, 176.975891), 0.001));
gsk_curve_get_point (&c1, t1[0], &pp);
g_assert_true (graphene_point_near (&p[0], &pp, 0.001));
gsk_curve_get_point (&c2, t2[0], &pp);
g_assert_true (graphene_point_near (&p[0], &pp, 0.001));
gsk_curve_get_tight_bounds (&c1, &b1);
gsk_curve_get_tight_bounds (&c2, &b2);
gsk_bounding_box_contains_point (&b1, &p[0]);
gsk_bounding_box_contains_point (&b2, &p[0]);
graphene_point_init (&p2[0], 0, 0);
graphene_point_init (&p2[1], 280, 280);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_CUBIC, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_LINE, p2));
n = gsk_curve_intersect (&c1, &c2, t1, t2, p, kind, 3);
g_assert_cmpint (n, ==, 2);
g_assert_cmpfloat_with_epsilon (t1[0], 0.136196628, 0.0001);
g_assert_cmpfloat_with_epsilon (t2[0], 0.632056773, 0.0001);
g_assert_true (graphene_point_near (&p[0], &GRAPHENE_POINT_INIT (176.975891, 176.975891), 0.001));
gsk_curve_get_point (&c1, t1[0], &pp);
g_assert_true (graphene_point_near (&p[0], &pp, 0.001));
gsk_curve_get_point (&c2, t2[0], &pp);
g_assert_true (graphene_point_near (&p[0], &pp, 0.001));
g_assert_cmpfloat_with_epsilon (t1[1], 0.499999911, 0.0001);
g_assert_cmpfloat_with_epsilon (t2[1], 0.825892806, 0.0001);
g_assert_true (graphene_point_near (&p[1], &GRAPHENE_POINT_INIT (231.25, 231.25), 0.001));
gsk_curve_get_point (&c1, t1[1], &pp);
g_assert_true (graphene_point_near (&p[1], &pp, 0.001));
gsk_curve_get_point (&c2, t2[1], &pp);
g_assert_true (graphene_point_near (&p[1], &pp, 0.001));
gsk_curve_get_tight_bounds (&c1, &b1);
gsk_curve_get_tight_bounds (&c2, &b2);
gsk_bounding_box_contains_point (&b1, &p[0]);
gsk_bounding_box_contains_point (&b1, &p[1]);
gsk_bounding_box_contains_point (&b2, &p[0]);
gsk_bounding_box_contains_point (&b2, &p[1]);
graphene_point_init (&p2[0], 0, 0);
graphene_point_init (&p2[1], 1000, 1000);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_CUBIC, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_LINE, p2));
n = gsk_curve_intersect (&c1, &c2, t1, t2, p, kind, 3);
g_assert_cmpint (n, ==, 3);
g_assert_cmpfloat_with_epsilon (t1[0], 0.863803446, 0.0001);
g_assert_cmpfloat_with_epsilon (t2[0], 0.305377066, 0.0001);
g_assert_true (graphene_point_near (&p[0], &GRAPHENE_POINT_INIT (305.377075, 305.377075), 0.001));
gsk_curve_get_point (&c1, t1[0], &pp);
g_assert_true (graphene_point_near (&p[0], &pp, 0.001));
gsk_curve_get_point (&c2, t2[0], &pp);
g_assert_true (graphene_point_near (&p[0], &pp, 0.001));
g_assert_cmpfloat_with_epsilon (t1[1], 0.136196628, 0.0001);
g_assert_cmpfloat_with_epsilon (t2[1], 0.176975891, 0.0001);
g_assert_true (graphene_point_near (&p[1], &GRAPHENE_POINT_INIT (176.975891, 176.975891), 0.001));
gsk_curve_get_point (&c1, t1[1], &pp);
g_assert_true (graphene_point_near (&p[1], &pp, 0.001));
gsk_curve_get_point (&c2, t2[1], &pp);
g_assert_true (graphene_point_near (&p[1], &pp, 0.001));
g_assert_cmpfloat_with_epsilon (t1[2], 0.5, 0.0001);
g_assert_cmpfloat_with_epsilon (t2[2], 0.231249988, 0.0001);
g_assert_true (graphene_point_near (&p[2], &GRAPHENE_POINT_INIT (231.249985, 231.249985), 0.001));
gsk_curve_get_point (&c1, t1[2], &pp);
g_assert_true (graphene_point_near (&p[2], &pp, 0.001));
gsk_curve_get_point (&c2, t2[2], &pp);
g_assert_true (graphene_point_near (&p[2], &pp, 0.001));
gsk_curve_get_tight_bounds (&c1, &b1);
gsk_curve_get_tight_bounds (&c2, &b2);
gsk_bounding_box_contains_point (&b1, &p[0]);
gsk_bounding_box_contains_point (&b1, &p[1]);
gsk_bounding_box_contains_point (&b1, &p[2]);
gsk_bounding_box_contains_point (&b2, &p[0]);
gsk_bounding_box_contains_point (&b2, &p[1]);
gsk_bounding_box_contains_point (&b2, &p[2]);
}
static void
test_line_curve_end_intersection (void)
{
GskCurve c1, c2;
graphene_point_t p1[4], p2[2];
float t1[9], t2[9];
graphene_point_t p[9];
GskPathIntersection kind[9];
int n;
graphene_point_init (&p1[0], 0, 100);
graphene_point_init (&p1[1], 50, 100);
graphene_point_init (&p1[2], 50, 0);
graphene_point_init (&p1[3], 100, 0);
graphene_point_init (&p2[0], 100, 0);
graphene_point_init (&p2[1], 100, 100);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_CUBIC, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_LINE, p2));
n = gsk_curve_intersect (&c1, &c2, t1, t2, p, kind, 1);
g_assert_cmpint (n, ==, 1);
g_assert_cmpfloat_with_epsilon (t1[0], 1, 0.0001);
g_assert_cmpfloat_with_epsilon (t2[0], 0, 0.0001);
g_assert_true (graphene_point_near (&p[0], &GRAPHENE_POINT_INIT (100, 0), 0.0001));
}
static void
test_line_curve_none_intersection (void)
{
GskCurve c1, c2;
graphene_point_t p1[4], p2[2];
float t1[9], t2[9];
graphene_point_t p[9];
GskPathIntersection kind[9];
int n;
graphene_point_init (&p1[0], 333, 78);
graphene_point_init (&p1[1], 415, 78);
graphene_point_init (&p1[2], 463, 131);
graphene_point_init (&p1[3], 463, 223);
graphene_point_init (&p2[0], 520, 476);
graphene_point_init (&p2[1], 502, 418);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_CUBIC, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_LINE, p2));
n = gsk_curve_intersect (&c1, &c2, t1, t2, p, kind, 1);
g_assert_cmpint (n, ==, 0);
}
static void
test_curve_curve_intersection (void)
{
GskCurve c1, c2;
graphene_point_t p1[4], p2[4];
float t1[9], t2[9];
graphene_point_t p[9];
GskPathIntersection kind[9];
int n;
GskBoundingBox b;
graphene_point_init (&p1[0], 0, 0);
graphene_point_init (&p1[1], 33.333, 100);
graphene_point_init (&p1[2], 66.667, 0);
graphene_point_init (&p1[3], 100, 100);
graphene_point_init (&p2[0], 0, 50);
graphene_point_init (&p2[1], 100, 0);
graphene_point_init (&p2[2], 20, 0); // weight 20
graphene_point_init (&p2[3], 50, 100);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_CUBIC, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_CONIC, p2));
n = gsk_curve_intersect (&c1, &c2, t1, t2, p, kind, 9);
g_assert_cmpint (n, ==, 2);
g_assert_cmpfloat (t1[0], <, 0.5);
g_assert_cmpfloat (t1[1], >, 0.5);
g_assert_cmpfloat (t2[0], <, 0.5);
g_assert_cmpfloat (t2[1], >, 0.5);
gsk_curve_get_tight_bounds (&c1, &b);
gsk_bounding_box_contains_point (&b, &p[0]);
gsk_curve_get_tight_bounds (&c2, &b);
gsk_bounding_box_contains_point (&b, &p[0]);
}
static void
test_curve_curve_end_intersection (void)
{
GskCurve c1, c2;
graphene_point_t p1[4], p2[4];
float t1[9], t2[9];
graphene_point_t p[9];
GskPathIntersection kind[9];
int n;
graphene_point_init (&p1[0], 0, 0);
graphene_point_init (&p1[1], 33.333, 100);
graphene_point_init (&p1[2], 66.667, 0);
graphene_point_init (&p1[3], 100, 100);
graphene_point_init (&p2[0], 100, 100);
graphene_point_init (&p2[1], 100, 0);
graphene_point_init (&p2[2], 20, 0);
graphene_point_init (&p2[3], 10, 0);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_CUBIC, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_CONIC, p2));
n = gsk_curve_intersect (&c1, &c2, t1, t2, p, kind, 9);
g_assert_cmpint (n, ==, 1);
g_assert_cmpfloat_with_epsilon (t1[0], 1, 0.0001);
g_assert_cmpfloat_with_epsilon (t2[0], 0, 0.0001);
}
static void
test_curve_curve_end_intersection2 (void)
{
GskCurve c, c1, c2;
graphene_point_t p1[4];
float t1[9], t2[9];
graphene_point_t p[9];
GskPathIntersection kind[9];
int n;
graphene_point_init (&p1[0], 200, 100);
graphene_point_init (&p1[1], 300, 300);
graphene_point_init (&p1[2], 100, 300);
graphene_point_init (&p1[3], 300, 100);
gsk_curve_init (&c, gsk_pathop_encode (GSK_PATH_CUBIC, p1));
gsk_curve_split (&c, 0.5, &c1, &c2);
n = gsk_curve_intersect (&c1, &c2, t1, t2, p, kind, 9);
g_assert_cmpint (n, ==, 2);
}
static void
test_curve_curve_max_intersection (void)
{
GskCurve c1, c2;
graphene_point_t p1[4], p2[4];
float t1[9], t2[9];
graphene_point_t p[9];
GskPathIntersection kind[9];
int n;
graphene_point_init (&p1[0], 106, 100);
graphene_point_init (&p1[1], 118, 264);
graphene_point_init (&p1[2], 129, 4);
graphene_point_init (&p1[3], 128, 182);
graphene_point_init (&p2[0], 54, 135);
graphene_point_init (&p2[1], 263, 136);
graphene_point_init (&p2[2], 2, 143);
graphene_point_init (&p2[3], 141, 150);
gsk_curve_init (&c1, gsk_pathop_encode (GSK_PATH_CUBIC, p1));
gsk_curve_init (&c2, gsk_pathop_encode (GSK_PATH_CUBIC, p2));
n = gsk_curve_intersect (&c1, &c2, t1, t2, p, kind, 9);
g_assert_cmpint (n, ==, 9);
}
/* This showed up as artifacts in the stroker when our
* intersection code failed to find intersections with
* horizontal lines
*/
static void
test_curve_intersection_horizontal_line (void)
{
GskCurve c1, c2;
float t1, t2;
graphene_point_t p;
GskPathIntersection kind;
int n;
gsk_curve_init (&c1,
gsk_pathop_encode (GSK_PATH_CONIC,
(const graphene_point_t[4]) {
GRAPHENE_POINT_INIT (200.000, 165.000),
GRAPHENE_POINT_INIT (220.858, 165.000),
GRAPHENE_POINT_INIT (1.4142, 0),
GRAPHENE_POINT_INIT (292.929, 92.929),
}));
gsk_curve_init_foreach (&c2,
GSK_PATH_LINE,
(const graphene_point_t[2]) {
GRAPHENE_POINT_INIT (300, 110),
GRAPHENE_POINT_INIT (100, 110),
},
2,
0);
n = gsk_curve_intersect (&c1, &c2, &t1, &t2, &p, &kind, 1);
g_assert_true (n == 1);
}
int
main (int argc, char *argv[])
{
(g_test_init) (&argc, &argv, NULL);
g_test_add_func ("/curve/intersection/line-line", test_line_line_intersection);
g_test_add_func ("/curve/intersection/line-line-none", test_line_line_none_intersection);
g_test_add_func ("/curve/intersection/line-line-end", test_line_line_end_intersection);
g_test_add_func ("/curve/intersection/line-line-parallel", test_line_line_parallel);
g_test_add_func ("/curve/intersection/line-line-same", test_line_line_same);
g_test_add_func ("/curve/intersection/line-curve", test_line_curve_intersection);
g_test_add_func ("/curve/intersection/line-curve-end", test_line_curve_end_intersection);
g_test_add_func ("/curve/intersection/line-curve-none", test_line_curve_none_intersection);
g_test_add_func ("/curve/intersection/line-curve-multiple", test_line_curve_multiple_intersection);
g_test_add_func ("/curve/intersection/curve-curve", test_curve_curve_intersection);
g_test_add_func ("/curve/intersection/curve-curve-end", test_curve_curve_end_intersection);
g_test_add_func ("/curve/intersection/curve-curve-end2", test_curve_curve_end_intersection2);
g_test_add_func ("/curve/intersection/curve-curve-max", test_curve_curve_max_intersection);
g_test_add_func ("/curve/intersection/horizontal-line", test_curve_intersection_horizontal_line);
return g_test_run ();
}

Some files were not shown because too many files have changed in this diff Show More