1
1
mirror of https://gitlab.gnome.org/GNOME/gimp.git synced 2025-10-06 01:12:40 +02:00

Compare commits

...

533 Commits

Author SHA1 Message Date
Alx Sa
9243da158f Merge branch 'alxsa-lcms2-fast-float' into 'master'
Issue #9536: Enable LCMS2 Fast Float plug-in

Closes #9536

See merge request GNOME/gimp!2391
2025-10-05 18:16:17 +00:00
Bruno Lopes
ebd6e64dc8 build/linux: Fix Flatpak building after gexiv2 dep declaration 2025-10-05 14:53:41 -03:00
Bruno Lopes
4768a4283d gitlab-ci: Add comment explaining Flatpak timeout 2025-10-05 13:45:55 -03:00
Bruno Lopes
fe4a698928 gitlab-ci: Bump Flatpak timeout for 90min again for rebuilding purposes
When we bump some dependency (e.g. Poppler), even the ones which
don't link to it will be rebuild, so 30min is not enough even
with the ORAS caching.
2025-10-05 13:41:27 -03:00
Bruno Lopes
d8d73266bc build/linux: Update poppler module to 25.10
Synced from
6d4124f7b8
2025-10-04 18:51:18 -03:00
Bruno Lopes
356c2baec5 gitlab-ci, build/windows: Remove forgotten comment about fixed #12284 2025-10-04 16:16:49 -03:00
Bruno Lopes
aea7042aa1 meson: Support Windows native paths (aka backslashes) on -Dprefix
Closes: #12284
2025-10-04 16:12:00 -03:00
Alan Mortensen
97944a5415 Update Danish translation
(cherry picked from commit d81cfcc325)
2025-10-04 12:48:26 +00:00
Alx Sa
a5182a010f tools: Fix missing cursor for MyPaint Brush tool
Resolves #15001
In the MyPaint Brushes v2 port (ea8b9dc1),
I implemented a cursor_update () function from the
parent class. However, I did not call the parent's
version of the function afterwards, so the MyPaint
Brush cursor was not being redrawn. This patch
adds the call to fix the cursor display issue.
2025-10-03 22:14:52 +00:00
Øyvind Kolås
9c2c5ff183 meson, app: depend on GEGL-0.4.64 2025-10-03 23:56:36 +02:00
Bruno Lopes
f09007507f Declare gexiv2 dependency on many targets (due to gimpmetadata.h)
Our build files were relying 'sysroot' to find gexiv2.h but this is
not possible with Apple Clang om which sysroot points to macOS SDK.
So, exotic environments like Homebrew were failing. Let's fix this.
2025-10-03 18:31:53 -03:00
Bruno Lopes
2b91551f4e gitlab-ci: Complete cbe56ff3 2025-10-03 09:03:26 -03:00
Bruno Lopes
cbe56ff388 gitlab-ci: Remove dangling MSYSTEM_PREFIX on Win job names
It makes them consistent with other non-Windows jobs so
easier to read.
2025-10-02 21:37:33 -03:00
Anders Jonsson
7cec3f52b9 .gitlab: fix template typo 2025-10-03 00:54:09 +02:00
Alx Sa
81c67e5614 tools: Don't commit Filter Tool without a filter
The Filter Tool is a "hidden" tool that we switch to
when applying a filter. Like other tools, it commits when
we save our image. However, we may no longer have an
active filter in the tool when we do so (like, after applying
an NDE filter). Because we check the drawable from the
filter to confirm whether we should force NDE or not,
this can cause a CRITICAL when we try to access a now
non-existent filter.

This patch extends the "if (filter_tool->filter)" check to
cover the full commit check process, to prevent the bug.
2025-10-02 12:07:25 +00:00
Øyvind Kolås
67fa72a94e meson, app: depend on babl-0.1.116 2025-10-02 13:22:29 +02:00
Yuri Chornoivan
6587256c3a Update Ukrainian translation 2025-10-02 08:21:41 +00:00
Bruno Lopes
ad9dbf2c8b tools: Drop bashism/gnushism in read command 2025-10-01 21:26:25 -03:00
Bruno Lopes
2f0bfc569b meson: Fix wrong debugging_format detection on clang-cl and msvc 2025-10-01 20:13:33 -03:00
Alx Sa
36330a271a tools: Prevent bucket fill on link/vector layers
Resolves #14993
We currently prevent paint tools from painting on
link or vector layers. However, we had not added this
protection to the bucket fill tool. This patch copies over
the relevant if statements to prevent this.
2025-10-01 13:23:09 +00:00
Jehan
baa4825880 app: use the new release/ alias URLs for the "Learn more" link of…
… Release Notes tab.
2025-10-01 14:40:18 +02:00
Jehan
8c910c2b6b tools: improve release stats.
- Interactively query the release version from standard input.
- Compute the logical previous version but also the previous release in
  time. For instance the logical previous release of GIMP 3.0.6 will be
  3.0.4 but the time-wise previous release will be 3.1.4.
- Some statistics will use the logical previous release whereas others
  the time-wise one.
2025-10-01 14:39:51 +02:00
Marco Ciampa
a025cfe41b Updated Italian translation 2025-10-01 12:37:59 +02:00
Jehan
41035c7589 plug-ins: fix memory management and handle multi-file zip.
We should not call archive_entry_free() since man
archive_read_next_header explicitly says that the returned entry is an
internal object:

> This is a convenience wrapper around archive_read_next_header2() that
> reuses an internal struct archive_entry object for each request.

The only reason why it was not crashing is that we were not properly
freeing the archive itself so internal objects were hanging! The man
archive_read says:

> Once you have finished reading data from the archive, you should call
> archive_read_close() to close the archive, then call archive_read_free()
> to release all resources, including all memory allocated by the library.

Therefore this code add archive_read_free() at the end and removes
archive_entry_free().

Furthermore we now verify if the zip archive contains any other file.
Unlike all other compression formats we were supporting until now, zip
is a full multi-file container format and we are always only trying to
read the first file listed in the archive. This likely means that this
file was not meant to be opened this way. In any case, still try to load
the first file as an image, yet raise a warning about the existence of
more files in the archive.
2025-09-30 20:14:01 +02:00
Jehan
7275569079 plug-ins: localize strings and improve extension list.
- Uppercase first letter of blurbs.
- Make the blurb and documentation strings localizable and localized.
- Add the compression format extension to the list of extensions. I am
  unsure why it was set as FIXME, because it does work perfectly (per
  tests) as a generic (de)compressor plug-in for any of the image
  formats we support. Not even this, but I am even putting the generic
  extension first, because sometimes we take the first listed extension
  of a load procedure to determine the source file format. Yet the only
  thing we can say *generically* about a file loaded by these procedures
  is that it was compressed with the associated container format!
- For the new zip-support, do not show xcf.zip and xcfzip extensions in
  the list. I don't think we want to promote these new extensions as
  standard XCF variants, even though in practice this will still work
  fine. Instead add hgt.zip (but again, after the generic zip, cf.
  previous point), because we know that this is a commonly used format
  combination for HGT files.
2025-09-30 19:53:36 +02:00
Jehan
dfafb7c6f2 NEWS: add new feature and clean out backported enhancements.
Various items have been moved to gimp-3-0 branch (commit f2c13d319e) and
some were already duplicated.
2025-09-30 17:50:39 +02:00
Aleksandr Prokudin
25d1b7f8c3 Update Russian translation 2025-09-30 17:12:29 +02:00
Bruno Lopes
0edf615333 libgimp: Improve .gir and .vapi dependencies by using unified list
To avoid bugs like: #14902
2025-09-30 11:29:51 -03:00
Aefgh Threenine
daf23e1a50 Update Thai translation 2025-09-29 23:54:22 +00:00
Alx Sa
b633b4b9c7 python: Remove layer offsets on ORA export
When exporting formats that use image procedures
(like PNG), if we don't remove the layer offsets then
the image is cut off on export. This is because we
size the image to the layer size, but then the layer offsets
move it off the canvas. This patch fixes the issue for
ORA export.
2025-09-29 18:55:20 -03:00
Yuri Chornoivan
cfa3fd6bb7 Update Ukrainian translation 2025-09-29 20:00:05 +00:00
Yuri Chornoivan
669685d1d8 Update Ukrainian translation 2025-09-29 19:51:36 +00:00
Alx Sa
f032153596 plug-ins: Add zip decompression support
This patch adds support for decompressing .zip files and
loading an image within. This allows us to load zipped
images like hgt.zip and other compressed formats.
2025-09-29 19:28:18 +00:00
Jehan
13639b1d3d NEWS: update. 2025-09-29 21:06:08 +02:00
Jehan
eb0bfe7bdb Issue #13553: pop an error dialog up only for specific GIO error.
This fixes 46d9a09698. There was a reason why this was not implemented
as an assert-type error nor as a user-facing error: network problems
happen.

We cannot pop an error up every time:

* The computer is offline! 😱 GIMP is not made to be run as a connected
  software and working on GIMP with a non-connected computer is a
  perfectly valid way of using GIMP.
* gimp.org is down (it's rare, but it happens and it should not have any
  impact to creators with GIMP).
* You are behind some kind of proxy or other complicated network
  configuration which GIO is not able to pass through.
* And any other reason which could make your GIMP not able to read the
  remote json file…

Instead let's check the more particular domain and error code, though
even this I hesitated between doing this change or simply reverting
commit 46d9a09698.
Indeed it's still quite a generic G_IO_ERROR_NOT_SUPPORTED error, so I
do hope we cannot get it in other normal conditions where reading a
remote link may fail. The last thing we want is GIMP popping up errors
which are neither bugs in our code, nor environment issues for which
anyone can do anything about.
2025-09-29 20:31:40 +02:00
Asier Saratsua Garmendia
393ca59e79 Update Basque translation 2025-09-29 17:59:37 +00:00
Jehan
3a698a05a1 plug-ins: only set the file if it's actually an inner XCF file.
Soon we will officially support .hgt.zip files (see !2483) but in fact,
even without this, the file-compressor actually support any other
formats we support, compressed into one of the container formats
supported by this plug-in.

This fixes such error message:

> gimp_image_set_file: failure to set file 'file:///home/jehan/Documents/gimp-splash-deleteme.png.gz' with extension 'gz'. The extension must be '.xcf' (or a compressed variant).
2025-09-29 17:46:33 +02:00
Jehan
f4a7da1ee3 app, pdb: similar to the previous commit, but for files loaded with…
… gimp_file_load().

We make sure that the load procedure associated to the file is the one
used for the inner-file (in case of imbricated files into container
formats).

Also let's set the imported file unless it's a XCF inner format.
2025-09-29 17:46:32 +02:00
Jehan
bb9d8df855 app: make sure we only consider the inner file load procedure to…
… determine if a file is XCF.

This was kinda already working for files loaded through the GUI. Yet the
code in file_open_file_proc_is_import() was assuming a file loaded
through the file-compressor plug-in is necessarily XCF.

Even though it is the original use, the code in file-compressor is
actually generic and is able to load any supported format additionally
compressed with gz, bz2 or xz.
Furthermore, we will soon support zip-ped imaged, explicitly to support
the format .hgt.zip which is quite common (see !2483). So remove any
logic of a file loaded by file-compressor as meaning it's a compressed
XCF.
2025-09-29 17:46:32 +02:00
Kolbjørn Stuestøl
78e68efd06 Update Norwegian Nynorsk translation 2025-09-29 15:15:57 +00:00
Ekaterine Papava
2fa82d51ee Update Georgian translation 2025-09-29 14:52:02 +00:00
Martin
f223dae9fe Update Slovenian translation 2025-09-29 13:21:27 +00:00
luzpaz
9daf5d2e5d libgimpconfig: fix typo in gimpconfig-params.c
Fixes source comment typo and modifies whitespace for readability.
2025-09-29 11:07:55 +00:00
Bruno Lopes
789af76a32 app: Move "Documentation" link one line up over (community) "Tutorials"
Users were thinking the tutorials are some kind of official docs,
but they are not maintained as the official GIMP help website,
they are more like informal documentation about GIMP made public.

Let's clarify this reordering the buttons.
2025-09-29 07:32:12 -03:00
Bruno Lopes
f9ba343558 build/windows: Stay on Inno 6.5.4 to avoid (potentially) broken 6.6.0 Dark Mode
It was announced by the devs on Google Groups that they are on preview state.

I will need time to conform our scripts to the upcoming 6.6.0.
So, let's not risk creating installers with broken UI.
2025-09-28 22:12:16 -03:00
Bruno Lopes
014aa5ae6f build/linux: Patch mypaint brushes on AppImage and Snap too
Following 2f6b7591
2025-09-28 21:39:00 -03:00
Bruno Lopes
47eac319b1 build/linux: Silence noisy warnings about GTK_MODULES
From GTK mouth:
https://gitlab.gnome.org/GNOME/gtk/-/blob/3.24.50/gtk/gtkmodules.c?ref_type=tags#L250
2025-09-28 19:58:25 -03:00
Bruno Lopes
3bde6195f6 build/windows, gimp-data: Prepare to Inno Setup 6.6.0 2025-09-28 18:19:18 -03:00
Bruno Lopes
b0689f565b build/linux: Little improvement on libheif plugins bundling 2025-09-28 08:25:27 -03:00
Bruno Lopes
1e46438ced build/linux: Fix libproxy/libpxbackend errors on Snap 2025-09-28 08:02:52 -03:00
Bruno Lopes
2b32496195 build/linux: Remove some uneeded lines after move to Trixie 2025-09-28 07:41:45 -03:00
Bruno Lopes
de62139894 build/linux: Fix GJS bundling on AppImage
It have an undeclared dependency on GioUnix typelib.
2025-09-28 07:40:20 -03:00
Bruno Lopes
f774ad7f16 Revert "Issue #13001: build/linux: Sandbox XDG_DATA_DIRS on AppImage"
This reverts commit bc095d5c83.

Sandboxing XDG_DATA_DIRS, while can fix the crash due to share/mime,
on the other hand makes impossible to call share/applications
associated with such mimes on host.

So, since we bumped the AppImage to Debian Trixie so the Glib
crash due to mime is gone, we can (and should) revert the
wrong sandboxing without problems.
2025-09-27 19:58:02 -03:00
Bruno Lopes
f53a843c3d gitlab-ci, build: Move to Debian Trixie on AppImage only
Fixes: #13001 #13106 #13492 #13647 #14779

AppImage jobs are now built with Trixie to adress #13001 and many others.

To have two Debian versions with less complexity possible, I needed to:
- Revert the prevalence of the AppImage CI (now nonreloc comes first);
- Revert the use of Clang on Debian (also to save 120MB from registry,
  since we now have 4 Docker images, each one with its own STEP cache!).
In short, .gitlab-ci.yml will look more like before I changing it a lot.
2025-09-27 18:58:18 -03:00
Bruno Lopes
46d9a09698 app: Use 'g_message' (like the help plug-in) when GVFSd-HTTP is not present
Closes #13553

Such issue tends to affect only AppImage users (e.g. when running it in
KDE installations). This is because AppImage files are not ran by
any host helper (e.g. snapd or flatpak) to connect to GVFSd and is
not possible to bundle GVFSd due to its own nature (it is daemon).

Since GVFS is listed in the INSTALL file as a required dependency, it is
fair enough to be more clear when it is not present, otherwise users will
have outdated GIMP without knowing (like happened in macOS in the past).

We are already doing this with GIMP help plug-in by the way. The
difference is that, at GIMP start, such techinical error message can
be surprising, but even so it is needed as feedback for fail on the
update check button in the end of day. Let's follow GIMP help on this.
2025-09-27 11:39:36 -03:00
Kolbjørn Stuestøl
355d695607 Update Norwegian Nynorsk translation 2025-09-27 11:44:30 +00:00
Alx Sa
714e9041d8 pdb: Set choice args to default in gimp-file-load
This patch resolves the same issue as 8021b464,
but for `gimp-file-load`.
2025-09-26 23:57:51 +00:00
Jehan
24c8f86c85 app: minor indentation cleanup. 2025-09-26 23:30:37 +02:00
Jehan
f50145c155 po: remove files which should not be in POTFILES.in.
This file is part of po-tags/ domain, and in fact, it's even in the
POTFILES.skip of the main po/ domain.
2025-09-26 21:53:28 +02:00
Gabriele
7f8298467b Issue #11869: use a custom AppMenu for macOS 2025-09-26 11:43:47 +00:00
Alx Sa
23a9758a7b libgimpwidgets: Update hex color as you type
This patch connects the gimp_color_hex_entry_events ()
function to "key-release-event" and adjusts the code
to update valid colors as you type. Pressing Enter
will work as before, converting back to the last valid
color if an invalid one is typed.
2025-09-25 11:48:17 +00:00
Jehan
0af9261980 app: fix rendering background of Colormap dockable.
The rgba variable would be used uninitialized. This needs to be moved
one loop level up so that the color extracted at each cell start
position is properly reused (and also so that the full transparent color
at no-entry position is properly set and reused too).
2025-09-25 01:27:54 +02:00
Martin
77d25750a7 Update Slovenian translation 2025-09-24 20:36:59 +00:00
luzpaz
155e951fa6 app: Fix description typo
This patch fixes a minor typo in a user-facing description within app/path/gimpvectorlayer.c  
This was found via codespell.
2025-09-24 17:24:28 +00:00
Jehan
5a22a9b931 app: make sure we don't crash dereferencing a NULL GError.
I think most, if not all, failure cases of file_open_with_proc_and_display()
should allocate a GError by now. But just in case we missed some edge
case, better not crash.
For instance, we were crashing when opening a remote file because of
this line before the previous commit was pushed.
2025-09-24 19:15:47 +02:00
Jehan
2187f0a49c app: fix opening remote files.
This got broken with commit 66cdecb0fa. It is now possible to open
remote files again.
2025-09-24 19:10:33 +02:00
luzpaz
91418131a0 app, libgimp*, pdb, themes: Fix description typos
This patch fixes minor typos in user-facing descriptions
and internal comments found by Codespell.
2025-09-24 16:50:15 +00:00
Yuri Chornoivan
645d23cd37 Update Ukrainian translation 2025-09-24 16:13:51 +00:00
Jehan
28fa2e5fc7 app, libgimp, pdb: new function gimp_link_layer_get_mime_type().
As discussed with NikcDC, this will be useful, for instance for the SVG
export to know the mime type of the linked file. If not PNG, JPG or SVG,
we may want to output a small warning that some viewers may not be able
to read such files, since the SVG spec makes the support of these 3
formats only as mandatory.
2025-09-24 16:11:01 +02:00
Bruno Lopes
c13bf1af19 build: Move loose scripts in meson subdir to tools
The build dir looks "prettier" without the meson subdir.
With prettier I mean: just the OSes subdirs.
2025-09-24 09:07:47 -03:00
Martin
9337c55599 Update Slovenian translation 2025-09-24 11:26:55 +00:00
Ekaterine Papava
947995248a Update Georgian translation 2025-09-24 05:09:40 +00:00
Jehan
abcfbfbca5 NEWS: update. 2025-09-24 03:06:56 +02:00
Jehan
b121ddd6f8 app, pdb: do not leak a GFile in gimp_temp_file() or any future…
… PDB API which will return a newly allocated GFile.

Though gimp_temp_file() was so far the only such case where a returned
GFile was being leaked, it may happen again. So the PDB must instead
assume that all returned GFile-s have their own reference and take over
said reference.

And therefore update all other functions to increase the internal
GFile-s reference counts.
2025-09-24 02:22:43 +02:00
Jehan
ba1de3b68e app, libgimp, pdb: add GimpLinkLayer base API.
Still more to be done, but this is the basic, working API.
2025-09-24 01:56:52 +02:00
Jehan
6552e3200d libgimp: add gimp_item_is_vector_layer() and fix some "Since" annotations. 2025-09-24 00:46:59 +02:00
Bruno Lopes
4d97212cf9 build/linux: Sync with Beta manifest regarding whitespaces 2025-09-23 16:56:32 -03:00
Yuri Chornoivan
54b64252df Update Ukrainian translation 2025-09-23 18:56:50 +00:00
Bruno Lopes
c79db4c15a gitlab-ci: Unify build jobs timeout by bumping them to 30min
While 20min is being enough, the jobs are completing
too close of the due time (due to awful runners like
OSU or Win32 stuckness). Let's prevent failures, then.
2025-09-23 15:38:25 -03:00
Bruno Lopes
cecb937a0b gitlab-ci: Reduce Flatpak timeout to 20min like AppImage and Snap, after ORAS 2025-09-23 12:18:03 -03:00
Bruno Lopes
fe4dbeb911 build/linux: ORAS works! Let's do some cosmetical changes on Flatpak deps script 2025-09-23 12:17:53 -03:00
Bruno Lopes
fdb4111e3f build/windows: Temporarely show flatpak deps building to see if ORAS caching is working 2025-09-23 11:52:18 -03:00
Bruno Lopes
72533aaf8e build/linux: Do not cache babl and gegl builds binaries to ORAS image
They should be passed only at artifact level.
2025-09-23 11:52:15 -03:00
Marco Ciampa
ccc4eacac3 Updated Italian translation 2025-09-23 16:14:49 +02:00
Bruno Lopes
8e9b7bfce6 build/linux: Test built packages binary caching on Flatpak with ORAS
If this works, our flatpak builds will behave like on AppImage,
Snap and Windows, I mean: with all precompiled binaries.
2025-09-23 10:37:42 -03:00
Sabri Ünal
17552c0e11 Update Turkish translation 2025-09-23 13:08:08 +00:00
Sabri Ünal
f428089947 Update Turkish translation 2025-09-23 13:07:56 +00:00
Rico Tzschichholz
6260590cf4 libgimp: Additionally pass gio-[unix,windows]-2.0 to vapigen
Fixes https://gitlab.gnome.org/GNOME/gimp/issues/14902
2025-09-23 08:41:05 -03:00
Jehan
c5e77fb8bb po-windows-installer: fix building the pot file.
When running `ninja gimp30-windows-installer-pot`, we had this error:

```
[0/2] Running external command gimp30-windows-installer-pot
/usr/bin/xgettext: warning: ITS rule file 'gimp-ms-installer-config.its' does not exist; check your gettext installation
/usr/bin/xgettext: warning: file 'build/windows/installer/lang/setup.isl.xml.in' extension 'xml' is unknown; will try C
```
2025-09-23 12:13:48 +02:00
Jehan
b50781730c NEWS: update. 2025-09-23 11:56:04 +02:00
Emin Tufan Çetin
2b669917c2 Update Turkish translation 2025-09-23 09:54:29 +00:00
Martin
7d22110cfb Update Slovenian translation 2025-09-23 07:33:11 +00:00
luming zh
86cc15cbf0 Update Chinese (China) translation 2025-09-23 00:31:05 +00:00
luming zh
865e6363e1 Update Chinese (China) translation 2025-09-23 00:24:04 +00:00
Jehan
789d82355c app, pdb: "Add Layer Mask" dialog asks whether to edit mask immediately.
While there are cases when you want to edit the mask straight away (this is
often the case when starting with a white or black mask), in many other cases,
the mask may be already as you want it per its initialization (e.g. when
initializing with a channel, selection, the alpha channel, etc.).

Until now, the Add Mask dialog was always switching to the "Edit Layer Mask"
mode by default, which forced an additional unneeded click each time you created
a mask (and were in a case where you initialize the mask as you want it
directly).

Now adding "Edit mask immediately" feature in the "Add Layer Mask dialog":

* It's checked by default to keep historical behavior.
* As most other dialogs, the last value is remembered, allowing people with
  repetitive workflow not to have to repeatedly set the settings each and every
  time.
* This default is also visible and settable in Preferences > Interface > Dialog
  Defaults.
2025-09-22 22:04:32 +02:00
Bruno Lopes
82cb3ae6fe gitlab: Print filenames in meson_health 2025-09-22 16:02:24 -03:00
Bruno Lopes
1a7f673b7d gitlab: Check gimp-data submodule too on meson-health job 2025-09-22 11:19:43 -03:00
Gabriele Barbero
8f57d4bdff gui: fix quit lose unsaved changes macOS
When quitting the application using "Quit" from the dock's right-click menu,
GIMP does not follow our standard quit procedure. Instead, macOS forces the
application to close, which may result in losing unsaved changes.

By adding a delegate that intercepts the applicationShouldTerminate call,
we ensure our quit code is used, preventing macOS from handling the shutdown
directly.
2025-09-22 13:29:52 +00:00
Jehan
aa9e437d42 tools: better logic for the splash image text.
Change of series must always have their own splash image (which will
stay the same within the whole series).
Development releases though will have a new splash image most of the
time (but it is not mandatory).

See rule edicted in commit Infrastructure/gimp-web-devel@061f544.
2025-09-22 12:39:23 +02:00
Jehan
ec4daa643e tools: use release news alias URL.
While we don't know the accurate URL of every release before
publication, we now know the alias it will have in the shape:
https://www.gimp.org/release/<version>

Cf. commit Infrastructure/gimp-web@bca40810
2025-09-22 12:30:08 +02:00
Bruno Lopes
308963c271 build/linux: Don't allow openjph update on Flatpak
It have broken includes starting with 0.23.0
2025-09-21 22:43:54 -03:00
Bruno Lopes
4d0fef9482 build/linux: Update graphviz module to 14.0.0 2025-09-21 22:41:14 -03:00
Bruno Lopes
d5f3fa77db build/linux: Improve bund_usr check added in 5bc2f26c 2025-09-21 21:37:25 -03:00
Jehan
dbf0c39bb3 app: use more recent harfbuzz API.
hb_ft_font_lock_face() (and unlock) exists since harfbuzz 2.6.5 and our
current requirement for this dependency is 2.8.2.

Fixes this compilation warning:

> app/text/gimpfont.c:1196:3: warning: ‘hb_ft_font_get_face’ is deprecated: Use 'hb_ft_font_get_ft_face' instead [-Wdeprecated-declarations]
>  1196 |   face = hb_ft_font_get_face (hb_font);
2025-09-22 00:43:11 +02:00
Bruno Lopes
56f72c24ba build/windows: Add .pdb bundling condition after bundle() improvement 2025-09-21 18:17:22 -03:00
Jehan
a0676125a1 app: fix build warning on Windows.
Fixes following warning, seen on CI:

> ./app/dialogs/about-dialog.c:549:7: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
2025-09-21 22:46:48 +02:00
Bruno Lopes
c472800eae build/windows: Do not build exiv2 on 32-bit since it uses ancient MSVCRT 2025-09-21 16:33:12 -03:00
Bruno Lopes
63b4d69e48 build/linux: Drop --permissive mode introduced in 5bc2f26c
It was an awful design of mine.
2025-09-21 14:44:11 -03:00
Jehan
70bf795dfb libgimp: avoiding a build warning on Windows.
Seen in the CI:

> ../libgimp/gimpui.c:406:1: warning: 'gimp_ui_get_foreign_window' defined but not used [-Wunused-function]
2025-09-21 19:18:30 +02:00
Bruno Lopes
a7c4320312 build/windows: Stop Windows script if bundle target do not exist 2025-09-21 11:32:17 -03:00
Bruno Lopes
5bc2f26cb0 build/linux: Stop AppImage script if bund_usr target do not exist 2025-09-20 20:31:24 -03:00
Lukas Oberhuber
cacb8d2035 clipboard: Fix #14639
This is the recommended fix from Gtk to use our own mime type rather than depend on a mimetype
that has a different expectation of payload.

This means drag and drop of colors uses `application/x-geglcolor` rather than `application/x-color` which expects an RGBA color rather than a structure.
2025-09-21 00:06:15 +01:00
Aurimas Černius
c8ed51bb52 Update Lithuanian translation 2025-09-20 20:39:03 +00:00
Sabri Ünal
264a65e0b3 Update Turkish translation 2025-09-20 15:29:10 +00:00
Alx Sa
e27353216c plug-ins: Fix display lag in Small Tiles
Resolves #14932

In Small Tiles, we update the preview whenever
the number of segments slider is dragged. However,
while we reacted to the slider moving, we actually grab
the number from the GimpProcedureConfig object.
As a result, there's a lag between the signal firing and the
config object updating, so we don't grab the latest change.
This patch alters the signal to run when "notify::num-tiles"
is called, resulting in the update function having the updated
number.
2025-09-20 15:21:45 +00:00
Sabri Ünal
49fc3ad0bd Update Turkish translation 2025-09-20 09:05:26 +00:00
Sabri Ünal
5b71d1a10d Update Turkish translation 2025-09-20 06:37:52 +00:00
Lukas Oberhuber
06bcef3273 macos plugins: Improves dock icon flashing from #12150
This means additional icons don't stick around. However, this is the easy workaround to turning everything into a proper plugin with .plist files.
2025-09-20 00:10:06 +01:00
Bruno Lopes
17b23b6f26 build/windows: Fix submission info code after Microsoft guys feedback
Thanks to https://github.com/kswanny and https://github.com/knangunu.
2025-09-19 09:23:23 -03:00
Bruno Lopes
413114f9d0 gitlab: Print message when 'branches-check' job have no errors 2025-09-18 07:49:10 -03:00
Bruno Lopes
c2f0afb4bd gitlab: Fix master exception on branches check 2025-09-17 22:38:24 -03:00
Bruno Lopes
b945d77ed7 gitlab: Do not check for master branch 2025-09-17 22:33:33 -03:00
Bruno Lopes
7c04605d14 gitlab: Add job to warn about "dead" branches
It is quite common for we developers (me included) to forget to
delete already merged branches. Let's fix this mess with a job.
2025-09-17 22:27:06 -03:00
Jehan
25edb3cc64 libgimpbase: let's use a stable version for "Since:" annotation. 2025-09-17 22:20:57 +02:00
Bruno Lopes
b773c3ac48 build/windows: Complete dirty 32-bit exiv2 workaround 2025-09-17 15:58:29 -03:00
Bruno Lopes
9551519f23 build/windows: Extremely dirty workaround for 32-bit sake 2025-09-17 15:51:39 -03:00
Bruno Lopes
a9d2700631 build/windows: More self_build organization to support MINGW32 2025-09-17 15:14:42 -03:00
Bruno Lopes
5375ca63d5 build/windows: Fix remaining Clang-oriented options of self_build on MINGW32 2025-09-17 14:45:33 -03:00
Bruno Lopes
78acdd8882 build/windows: Fix typo on Clang color check 2025-09-17 14:18:31 -03:00
Bruno Lopes
b5dda733dc build/windows: Fix failing build due to Clang color on MINGW32 2025-09-17 14:13:31 -03:00
Bruno Lopes
e17567d001 build/windows: Build exiv2 with Meson so make the .dll name expected by gexiv2 2025-09-17 09:30:32 -03:00
Bruno Lopes
4a0ea33bc5 build/windows: Uncomment .pdb installing on Meson mode of self_build function 2025-09-17 09:25:58 -03:00
Bruno Lopes
a2d106e3fa build/windows: Build exiv2 with setlocale patch 2025-09-17 07:36:03 -03:00
Jehan
4ebd340688 NEWS: update. 2025-09-17 12:30:14 +02:00
Bruno Lopes
15f047f6c0 build/windows: Restore comments on 2_bundle-gimp-uni_sym.py 2025-09-16 13:30:19 -03:00
Bruno Lopes
484d0fbcf4 build/linux: Fix PostScript support on Snap with proper env var 2025-09-16 12:10:24 -03:00
Bruno Lopes
b70186bc99 build/linux: Bundle needed files for PostScript support on AppImage 2025-09-16 12:10:21 -03:00
Marco Ciampa
4a656a1db0 Updated Italian translation 2025-09-16 15:26:56 +02:00
Anders Jonsson
cb565344e9 Issue #14878: fix missing spin boxes in Map to Object plug-in
Light position spin boxes in Map to Object could be missing
or shown when they shouldn't be due to reuse of a variable.

Fixes #14878
2025-09-16 10:37:02 +00:00
Bruno Lopes
c8971ac2ae build/windows: Try to fix failing .patch download on @creiter runners 2025-09-16 07:12:16 -03:00
Bruno Lopes
3ec63979d8 build/windows: Make possible to apply remote .patch on self builds 2025-09-15 21:00:09 -03:00
Bruno Lopes
c72e36c6a2 gitlab-ci, build/windows: Fix broken env after 5ccc5252 2025-09-15 19:21:45 -03:00
Bruno Lopes
5ccc525281 build/windows: Add colored output and .pdb support for Cmake self builds 2025-09-15 14:40:29 -03:00
Jehan
84eaa94842 plug-ins: align with __attribute__ keyword.
The bug in old Bugzilla #138357 report was happening on icc on ia64 with
-no-gcc option. It does look like after all these years, this is still a
GCC attribute, but we use the same attributes on babl and GEGL code. So
to be fair, it'd be useless to only forbid using it on GIMP code. And
that makes for much less ugly code.

Note that C11 has _Alignas() and C23 alignas() specifiers. These are
standard, but we are typically still more into C99 code. Let's see if we
move on to C11 some day… But for now, let's use __attribute__.

Also I am unsure how much this issue is still relevant nowadays. Maybe
even without specified alignment, it would now work fine with icc on
IA-64. 🤷
Or maybe it really doesn't matter that much because Itanium has been
discontinued in 2019, though I guess existing hardware will still be
around for a bit longer.
2025-09-15 19:36:29 +02:00
Alx Sa
bc7cc0b698 path: Update SVG tag when exporting paths
Per Martin Owens of Inkscape and Jonathan Watt,
one of the SVG specification editors
(https://jwatt.org/svg/authoring/#doctype-declaration),
we should not export the DTD with the GimpPath SVG.
This patch also adds an explicit SVG version to the
<svg> tag.
2025-09-15 17:28:33 +00:00
Alx Sa
602300ec8e pdb, app, libgimp, libgimpconfig: Stroke/Fill Vector Layer PDB
This patch adds additional API for setting the stroke/fill
properties of vector layers. You can now set/get color, stroke
width and stroke style via the PDB. Pattern get/set API is not
yet implemented.

This patch also updates a missing parameter check for GimpVectorLayer
in gimp_config_param_spec_duplicate (), and adds additional API
in /app to make it easier to safely retrieve GimpVectorLayerOptions.
2025-09-15 14:14:46 +00:00
Sabri Ünal
64e276c3b5 Update Turkish translation 2025-09-15 12:12:02 +00:00
Marco Ciampa
96394377e6 Fix in Italian translation 2025-09-15 09:52:28 +02:00
Juliano de Souza Camargo
a926e013da Update Brazilian Portuguese translation 2025-09-14 13:03:24 +00:00
Kolbjørn Stuestøl
2d74278860 Update Norwegian Nynorsk translation 2025-09-13 17:03:47 +00:00
Kolbjørn Stuestøl
e1e4c0f400 Update Norwegian Nynorsk translation 2025-09-13 16:59:09 +00:00
Bruno Lopes
5fc3c29f5c build/windows: Fix custom build options not being passed to Meson and Cmake 2025-09-13 09:32:37 -03:00
Nathan Follens
de4fb3470c Update Dutch translation 2025-09-12 23:30:17 +00:00
Nathan Follens
ddfce634a8 Update Dutch translation 2025-09-12 23:30:05 +00:00
Bruno Lopes
527f4964fe build/linux: Update ghostscript module to 10.06.0
Synced from: 5ce8488408
2025-09-12 10:59:05 -03:00
Bruno Lopes
be2e47114d build/windows: Forgot '-and' in previous commit 2025-09-12 07:51:36 -03:00
Bruno Lopes
11b81e25a4 build/windows: Only use meson in pure Meson built dependencies 2025-09-12 07:44:26 -03:00
Jehan
4ca05cb38d app: fix crash when json parsing fails.
The argument is already a URI, not a GFile.
2025-09-11 23:31:03 +02:00
Jehan
bb9aad1e87 app: fix crash on invalid previously picked layer.
This happened to our artist in residency. She had a crash when
gimp_image_pick_layer() was apparently run with a non-NULL yet invalid
previously_picked layer. So let's make sure that we clear the stored
item pointer when the object gets finalized.
2025-09-11 23:31:03 +02:00
Bruno Lopes
4dceeb174a libgimp: Only list gio_specific on Glib 2.86 and newer
Since GioUnix-2.0 namespaces were buggy in previous versions
2025-09-11 12:16:34 -03:00
Jehan
9819457f31 meson: add deprecation warnings on GLib and GTK/GDK API usages.
I discover GLIB_VERSION_MIN_REQUIRED and GLIB_VERSION_MAX_ALLOWED. The
former will make so that we won't have deprecation warnings anymore if
ever we use a function which has been deprecated recently (as long as it
was not deprecated at the minimum required version). The latter will
make so that we get deprecation warnings for any function added after
the minimum required version.

Note that ideally both should be at the same version, but since we have
a bunch of GLIB_CHECK_VERSION() protected conditional code, we would get
compilation warnings even on correctly protected code. So just keep the
small discrepancy until we can finally bump our minimum requirement.

Also add the equivalent macros for GTK/GDK.
2025-09-11 16:23:57 +02:00
Jehan
7c947ef1af app, libgimpbase, plug-ins: deprecate GimpPixPipe.
This really feels like internal API which we'd want to keep private (and
used by core plug-ins only).

Also as Jacob noticed, it's not even included in libgimpbase/gimpbase.h
so plug-ins wishing to use this API need to include this file
specifically anyway (but the header is still installed and the API is
introspected).

Since we cannot remove these functions now that GIMP 3 was published,
for API stability, I am only deprecating them both in the C API with
macros and in the bindings with GObject Introspection annotations.
Therefore any third-party plug-in developer trying to use these
functions in a plug-in will get build-time or run-time warnings.

Then when we'll move on to GIMP 4 development, we can remove the
deprecation and simply make this file private-only use instead.
2025-09-11 16:23:57 +02:00
Ekaterine Papava
03beda6e2a Update Georgian translation 2025-09-11 10:56:59 +00:00
Bruno Lopes
a7d867c8bc libgimp: List gio_specific as dependency for .typelib
This is required starting with Glib 2.86.0.
2025-09-11 07:44:38 -03:00
Jehan
6584f92748 NEWS: update. 2025-09-10 18:42:17 +02:00
Kolbjørn Stuestøl
593f0abf09 Update Norwegian Nynorsk translation 2025-09-10 15:22:52 +00:00
Kolbjørn Stuestøl
a734b4a3a4 Update Norwegian Nynorsk translation 2025-09-10 15:21:39 +00:00
Estecka
0fd280db5c Issue #14777: Fix bad axis centering on zoom-out.
This was simply caused by two variables having been swapped.

Gimp 2 used to work properly because there were two separate mix-ups that
cancelled each other: one in the function arguments, and one in the code
itself. Gimp 3 had fixed the error in the arguments, but not in the code,
thus enabling the bug.
2025-09-09 17:44:55 +00:00
Nathan Follens
443d0a2f7b Update Dutch translation 2025-09-09 16:09:04 +00:00
Nathan Follens
ed01c1b7f4 Update Dutch translation 2025-09-09 16:08:54 +00:00
Nathan Follens
904f283932 Update Dutch translation 2025-09-09 16:08:39 +00:00
Bruno Lopes
9026d18039 app: Make possible to append _NT_SYMBOL_PATH 2025-09-09 12:57:46 -03:00
Sabri Ünal
8a5825b66f Update Turkish translation 2025-09-09 14:53:26 +00:00
Cheesequake
71caf7eb05 Issue #13746: change incorrect variable to check for changes in y-axis 2025-09-08 14:41:41 -03:00
Yuri Chornoivan
bf6092c728 Update Ukrainian translation 2025-09-08 14:06:30 +00:00
luming zh
6d74a880f9 Update Chinese (China) translation 2025-09-08 08:59:29 +00:00
Martin
1a953c5c73 Update Slovenian translation 2025-09-08 08:28:52 +00:00
Balázs Meskó
1564efb519 Update Hungarian translation 2025-09-08 06:38:12 +00:00
Alx Sa
3e96397770 dialogs: Add palette format filters to import dialog
GIMP supports importing a number of palette formats
such as Adobe Swatch Exchange and SwatchBooker.
However, this is not immediately apparent from the import
palette dialogue.
This patch adds the currently supported palette formats as
filters in the dialogue, both to let users hide irrelevant files from
view and to highlight which formats we support.
2025-09-08 01:40:41 +00:00
Alx Sa
c8cf2219ce libgimpbase, libgimpwidgets, tools, app: Remove warnings
This patch fixes a few (mostly Windows-specific) warnings on build.
* Hides functions like gimp_get_foreign_window () and variables
like transient_set that aren't used in Windows.
* Changes hollow_g_shell_quote () to not return a const gchar *,
since the value it returns is actually not const.
* Cast update_interval to double to remove warning about mixing
enums and doubles in division.
2025-09-07 18:41:13 +00:00
luming zh
2865aa7f03 Update Chinese (China) translation 2025-09-07 00:30:17 +00:00
Bruno Lopes
013f9c7f0c build/windows: Fix prefixes priority in libraries bundling 2025-09-06 19:46:50 -03:00
Bruno Lopes
8ea6e4031e build/windows: Add support to Cmake builds on self_build function
This can be useful in the future if we need to build some dependency that
does not use Meson (hope we will not need that but anyway)
2025-09-06 18:39:06 -03:00
Bruno Lopes
69359a16c1 build/linux: Update openexr module to 3.4.0 and add openjph module
Synced from: 4318fbbef2
2025-09-06 16:31:38 -03:00
Alx Sa
4d84ac748b Issue #12012: Don't require GUI for C source and HTML export 2025-09-06 19:25:57 +00:00
Bruno Lopes
1dcc8585ef gitlab-ci: Move from unmaintained Kaniko to Buildah
Closes: #14796

There is no other doable option than Buildah. I also tested the
other Kaniko alternatives pointed by GitLab documentation which
were Docker-in-Docker and Buildkit but none worked unprivileged.

Regression: our logs will be a bit more noisy compared to Kaniko.
See: https://github.com/containers/buildah/issues/6362
2025-09-06 16:05:40 -03:00
cheesequake
8a3fb8c08e Issue #14763: Clean new images whether linked layers or not.
Moving the gimp_image_undo_free and gimp_image_clean_all
functions outside the link layer check prevents the image getting
dirty. Hence, closing a new linked layer image without changes
doesn't open a save changes dialog anymore.
2025-09-06 17:33:58 +00:00
Bruno Lopes
4509ec92f5 build/windows: Revert wrongly pushed change 2025-09-06 14:33:52 -03:00
Bruno Lopes
ee43316839 meson: Fix .pdb installation condition on Linux and macOS 2025-09-06 14:17:57 -03:00
Alx Sa
0782b9166b display: Guard private->initial_monitor when NULL
On some systems, it is possible for gimp_image_window_switch_page ()
to be signaled when private->initial_monitor has been set to NULL but
we don't yet have a GtkWindow. This eventually produces a CRITICAL
when gimp_dialog_factory_add_foreign () is run with a NULL monitor.

This patch adds a condition so that gimp_image_window_session_update ()
is not run with a NULL monitor in those cases.
2025-09-06 16:01:07 +00:00
Gabriele Barbero
5a34856e38 core: fix wrong if condition in gimp_drawable_duplicate
Probably a typo: the wrong control variable was used in the if statement.
This caused a segfault when duplicating a drawable if new_filter was NULL.
2025-09-06 17:04:51 +02:00
Bruno Lopes
9ec28cec54 app: Fix stuck debug dialog on Xorg (X11) too 2025-09-06 10:45:04 -03:00
Bruno Lopes
d6d959c6c9 app: Add margin around buttons of gimpcriticaldialog
The dialog was inconsistent. Let's fix that.
2025-09-06 10:42:35 -03:00
Marco Ciampa
83c18ee0f2 Fix of frame term in Italian translation 2025-09-06 14:40:32 +02:00
Marco Ciampa
5a5e0b6fee Little fix in Italian translation 2025-09-06 14:18:56 +02:00
Cristian Secară
acf0920d82 Update Romanian translation 2025-09-06 11:56:07 +00:00
Jehan
58efcf6312 app: fix dropping a dockable above/below the only dock in a dockbook.
There is no bug report that I know of as it was reported directly by
Aryeom. When a dock had only a single dockbook, if we tried to move one
of the dockable to the above or below target areas, it would fail.

The reason is that we were not counting the dockables correctly so the
code thought we were trying to move from a dockbook containing a single
dockable (single tab).
2025-09-06 12:35:52 +02:00
Cristian Secară
e3c8910da7 Update Romanian translation 2025-09-06 09:46:06 +00:00
Alevtina Karashokova
01c1949dd5 Update Russian translation 2025-09-05 11:34:57 +00:00
Alx Sa
599a6c7afe core: Fix Lab & CMYK ACB palette import
Converts the babl formats for Adobe Color Book
Lab and CMYK formats to "float", to prevent a crash
when accessing u8 Lab colors that have negative values
and CMYK colors that are too dark.
2025-09-05 11:02:13 +00:00
Jehan
16bb162894 menus: add specific link layer actions in Layer menu. 2025-09-05 12:44:02 +02:00
Bruno Lopes
65258d6183 build/linux: Update poppler module to 25.09.1 2025-09-04 20:21:08 -03:00
Gabriele Barbero
6e80f98390 plug-ins: use a temporary image to get the buffer...
...with filters during Recompose

Previously, get_buffer_with_filters() inserted and removed a temporary
copy of a layer in the original image. This caused the image to appear
modified, adding entries in the undo history and prompting the user to save
changes, even though the image itself was not actually changed.

This patch modifies the function to create a temporary image and perform
the layer insert operation there. Filters are applied as before,
but the original image remains untouched, avoiding unwanted undo entries
and mark the image as modified.
2025-09-04 20:05:22 +02:00
Yuri Chornoivan
e18eaff1dc Update Ukrainian translation 2025-09-04 16:11:49 +00:00
luming zh
a4c780f6c9 Update Chinese (China) translation 2025-09-04 09:31:58 +00:00
Martin
0665e3fb5c Update Slovenian translation 2025-09-04 08:59:22 +00:00
Ekaterine Papava
9f9bf1003d Update Georgian translation 2025-09-04 07:17:19 +00:00
Ekaterine Papava
8b560f835e Update Georgian translation 2025-09-04 07:01:30 +00:00
Marco Ciampa
2a9eb5aa66 Small fix in Italian translation 2025-09-04 08:43:57 +02:00
Alx Sa
002b22c150 plug-ins: Fix ZDI-CAN-27793
GIMP ILBM File Parsing Stack-based Buffer Overflow
Remote Code Execution Vulnerability

Adds a check to file-iff.c to ensure the palette_size is
between 0 and 256.
2025-09-04 04:45:43 +00:00
luming zh
d27c580144 Update Chinese (China) translation 2025-09-04 02:28:31 +00:00
Bruno Lopes
4738472fcd tools: Drop bashisms on milestones info fetching 2025-09-03 21:13:34 -03:00
Jacob Boerema
4eb106f2bf plug-ins: fix ZDI-CAN-27823
GIMP XWD File Parsing Heap-based Buffer Overflow Remote Code Execution
Vulnerability.

Check offset in colormap is valid before writing to it.

Closes #14814
2025-09-03 18:38:53 -04:00
Alx Sa
53b18653bc plug-ins: Fix ZDI-CAN-27836
ZDI-CAN-27836: GIMP FF File Parsing Integer Overflow
Remote Code Execution Vulnerability

This patch increases the row_size data type to gsize and checks if it
would overflow based on the width given. It also makes sure the image
size does not exceed GIMP's image size limits.
2025-09-03 22:10:34 +00:00
Anders Jonsson
2012eef75c plug-ins: remove doubled word in dicom string 2025-09-03 23:03:07 +02:00
Jacob Boerema
fb31ddf322 plug-ins: fix ZDI-CAN-27878
GIMP WBMP File Parsing Integer Overflow Remote Code Execution
Vulnerability

We recently fixed one instance of not upgrading the size, but forgot
the other. Fix that here by casting to (gsize). While we're at it,
also add a warning, when reading more data fails unexpectedly.

Closes #14812
2025-09-03 15:25:55 -04:00
Jacob Boerema
0f309f9a8d plug-ins: fix dicom plug-in ZDI-CAN-27863
GIMP DCM File Parsing Heap-based Buffer Overflow Remote Code Execution
Vulnerability

This adds more safety checks and sets actual GError's instead of just
calling gimp_quit.

Closes #14811
2025-09-03 13:34:36 -04:00
Jehan
05e90b1cde app: optimize the detection of filters with aux input.
As reported by Liam, apparently for someone with a lot of filters, these
node creations just to check the aux input may add up noticeable time on
boot (it may also depend on the OS too? I didn't have any noticeable
delay personally).

Unfortunately we cannot know the presence of an aux input just with
class introspection because they can be registered by the op at runtime.

This optimization is therefore twofold:

* Since we know which filters have an aux input among all the ones with
  hardcoded actions, we also hardcode this data. It means we only do the
  actual check on non-hardcoded operations (third-party filters but also
  GEGL operations which are not specifically listed in our code).
* I only do these checks once, stored by name in a hash table, because
  filters_actions_setup() is actually run several times (for different
  menus).

This should improve startup time a lot for people who experienced this
delay.
2025-09-03 18:38:16 +02:00
Marco Ciampa
e4cb1e485e Small fix in Italian translation 2025-09-03 17:40:45 +02:00
Jehan
03f7cf58b8 tools: also parse milestone infos automatically. 2025-09-03 16:18:14 +02:00
Alx Sa
5f4329d324 plug-ins: Fix ZDI-CAN-27684
Prevent overflow attack by checking if
output >= max, not just output > max.
2025-09-03 13:41:10 +00:00
lillolollo
1a144f35a6 plug-ins: fix file-exr warning and a possible memory leak 2025-09-03 12:59:39 +00:00
Bruno Lopes
8287302b50 build/linux: Update Poppler to 25.09 and manually disable awful -DENABLE_GPGME
Ported from: a125318890
2025-09-03 09:38:43 -03:00
Marco Ciampa
98dbff1e99 Updated Italian translation 2025-09-02 21:14:26 +02:00
Bruno Lopes
53a1d07ffd tools: Remove last bashisms in new release-stats.sh
'paste' is a bit opaque but at least more portable.
2025-09-02 16:08:53 -03:00
Bruno Lopes
0191e0a485 tools: Drop bashisms on new release-stats.sh versioning evaluation 2025-09-02 15:53:58 -03:00
Anders Jonsson
fc4eb6730c plug-ins: add missing include to fix build 2025-09-02 20:02:01 +02:00
Bruno Lopes
459090836a gitlab-ci: Use 'ref:' on flatpak_ci_initiative.yml for CI safety
Not making use of 'ref:' makes GitLab fetch the latest version of
the *initiative.yml with the latest fixes and such. That would
not be a problem and even desirable maintenance-wise but that
allows GNOME to add anything on our .gitlab-ci.yml at any time.

This is hard to debug and can break our CI. For example,
see: https://gitlab.gnome.org/GNOME/citemplates/-/issues/35.
2025-09-02 14:58:12 -03:00
Jehan
81c844d2ca tools: tweak script so that it outputs statistics in release news format.
Though most of the stats we were pulling came from this, let's format it
exactly how we have done in many latest release news.
Also add automatic stats pulling too of our many side repositories.
2025-09-02 19:08:48 +02:00
Jehan
51ba945eb1 plug-ins: add reminder to obsolete scripts in favor of proper Script-fu plug-ins.
Closure of #10652 made me realize we should probably leave a warning
reminder.
2025-09-02 19:08:48 +02:00
Marco Ciampa
87def70e1e Updated Italian translation 2025-09-02 17:39:32 +02:00
Aleksandr Prokudin
35257782ca Update Russian translation 2025-09-02 02:35:51 +02:00
Balázs Úr
238718b667 Update Hungarian translation 2025-09-01 20:30:02 +00:00
Balázs Úr
95cbadd277 Update Hungarian translation 2025-09-01 14:01:03 +00:00
Athmane MOKRAOUI
88d6dfea04 Update Kabyle translation 2025-09-01 10:52:51 +00:00
luming zh
6b1834ec9e Update Chinese (China) translation 2025-08-31 23:46:06 +00:00
luming zh
10319fc883 Update Chinese (China) translation 2025-08-31 23:41:43 +00:00
Jehan
624f049e66 Post-release version bump to 3.1.5. 2025-09-01 00:35:08 +02:00
Bruno Lopes
0c5e5c0094 build/windows: Remove last remnant of $GIMP_BASE on Installer script
This completes 87101276
2025-08-31 16:22:30 -03:00
Jehan
50978f18b6 Release GIMP 3.1.4. 2025-08-31 19:24:36 +02:00
Bruno Lopes
cb4316d07a gitlab-ci: Always use the Debian image of our Registry
Some jobs were using the Debian image from Docker Hub registry:
- meson-health
- clang-format
- cppcheck
- sources-debian
- dev-docs
- dist-appimage-weekly

The reason was that we don't need a bigger image suited for builds
($CI_REGISTRY_IMAGE:build-debian-${DEB_VERSION}-${RUNNER}), but
it relied entirely on luck. If we push too much commits in a day, it
could surpass the Docker Hub limit. So, let's use our own image always.
2025-08-31 13:28:53 -03:00
Jehan
a530892fb5 desktop: update release date. 2025-08-31 18:05:14 +02:00
Jehan
ad3ec69183 NEWS: update.
Forgotten new libgimp/PDB API.
2025-08-31 17:49:24 +02:00
Jehan
6c1c497ce0 libgimpwidgets: fix build warning.
This fixes the following warning when compiling with CLang:

> libgimpwidgets/gimppropwidgets.c:3961:11: warning: variable 'unit_type' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
>  3961 |       if (pspec_unit && GIMP_IS_PARAM_SPEC_UNIT (pspec_unit))

If a unit property name is set, it must be a valid unit property. Let's
check, output a CRITICAL and return NULL otherwise.
2025-08-31 17:49:24 +02:00
Jehan
b1e52381f5 libgimp*, plug-ins: add and use new GIMP_WARNING_API_BREAK() macro.
This macro will generate a #warning message when we'll move on to 3.99
series (which means we will be on our way to GIMP 4). And it will become
an #error message on 4.0.0, hence preventing us from releasing unless we
actually resolve all these warnings.

Resolution may mean actually breaking the API/ABI, or just deciding that
it's not a good idea in the end, or finding another solution. But
something will have to be decided.

Please everyone use this macro when you discover issues where it looks
like we could improve the API (in a breaking way) so that we don't
forget when approaching GIMP 4 (pushing further the improvement).

Updating the 2 place where I was already using a GIMP_CHECK_VERSION()
with #warning, and adding a new usage in the compose plug-in, per
discussion in MR !2424.
2025-08-31 17:49:24 +02:00
Bruno Lopes
27a89a0c8a build/linux: Update exiv2 module to 0.28.7 2025-08-31 12:50:42 -03:00
Jehan
a636aea98d Issue #14781: Moving link layers freezes GIMP.
Though I can't reproduce on Linux, the performance log seems to show we
spend too much time inside filters_actions_update(). Instead of creating
nodes at each update, let's just store the information about which
filter action has pad, since this should not change within the timespan
of a given session.
2025-08-31 11:56:51 -03:00
Bruno Lopes
62727a654c build/windows: Always run 'pacman -Suy' on 'gimp-win' job
Runners do not remember the MSYS2 repo cache between jobs since
they are not relying on any Docker caching.

The problem is that GIMP could link to different lib versions than
babl and GEGL, but that is the way local shell executors work anyway.
2025-08-31 11:58:09 -03:00
Yuri Chornoivan
2e05a4b1d9 Update Ukrainian translation 2025-08-31 14:41:16 +00:00
Alx Sa
0faa10ddd6 plug-ins: Remove metadata on J2K and PSB export
Exiv2 does not yet support metadata export for PSB
and J2K export. For now, we will turn off the metadata
options when exporting in these formats.
2025-08-31 13:22:28 +00:00
Yuri Chornoivan
d16fe453b6 Update Ukrainian translation 2025-08-31 12:50:56 +00:00
Kolbjørn Stuestøl
e5c04e449e Update Norwegian Nynorsk translation 2025-08-31 12:33:19 +00:00
Bruno Lopes
8a3603828b gimp-data: Bump commit to reduce RAM usage on icon scripts 2025-08-31 08:46:38 -03:00
Martin
4b252bddec Update Slovenian translation 2025-08-31 11:29:34 +00:00
Martin
b42ba20657 Update Slovenian translation 2025-08-31 11:21:00 +00:00
Anders Jonsson
c5ddbf5732 Update Swedish translation 2025-08-31 10:26:13 +00:00
Anders Jonsson
1e5be02d8c Update Swedish translation 2025-08-31 09:43:47 +00:00
Alx Sa
cf9d39c3d7 plug-ins: Fix Recompose for YCbCr decomposed images
The strings used in decompose.c's "decompose-type" do not match
the values of compose_type for YCbCr values. This means that when
using non-interactive Recompose, there's no match and the Recompose
fails. We'll need to wait until the next API break to fix the strings.
For now, we will do additional checks if the normal compose_type check
fails and also compare the four YCbCr types from Decompose.
2025-08-31 01:53:28 +00:00
Jehan
1365b8a08b NEWS: update. 2025-08-30 22:30:57 +02:00
Jehan
51ffd78d2a gimp-data: bump to fix Windows 32-bit build job. 2025-08-30 21:47:46 +02:00
Ondřej Míchal
d985b9b377 app: Align edit tool button with text entry
The button for opening the edit panel for editing a brush / gradient /
pressure curves looks misaligned because it is added to the end of the
horizontal box and its icon is aligned to the end of the button instead
of its center.

This adds puts the text entry and the edit button into the same
horizontal box and fixes the image alignment.
2025-08-30 19:10:02 +00:00
Liam Quin (ankh/demib0y/barefootliam)
760ef381fe fix crash on build or startup if extensions file does not exist 2025-08-30 18:41:03 +00:00
Corentin Noël
19e230e9cb plug-ins: Allow for more specific print settings with portals
In the case the "create-custom-widget" signal is not emitted (typically when
using the print portal), it is necessary to open a second dialog to fine-tune
the print settings.
2025-08-30 15:41:49 +00:00
Bruno Lopes
04622852fa build/linux: Update exiv2 module to 0.28.6
Ported from 91e327ab7a
2025-08-30 10:28:51 -03:00
Bruno Lopes
2f6b75913b Issue #14461: build/linux: Patch mypaint-brushes module with 'gridmap'
Alex's patch from https://github.com/mypaint/mypaint-brushes/pull/7

Since mypaint project is long time gone, we need to patch ourserves.
2025-08-30 10:25:03 -03:00
Jehan
883498916a desktop: update release date. 2025-08-30 14:01:22 +02:00
Jehan
8e2a0381d7 app: generalize code for filter action sensitivity.
Remove most of the per-action special-casing. This won't scale, and in
fact it already doesn't work well with all generated actions from GEGL
operations. Considering that any third-party operation will generate an
action too, this just can't work.

Instead we know that:

- Filters on group, vector and link layers must always be run
  non-destructively.
- Non-interactive filters are always run destructively and therefore
  cannot be run on group, vector or link layers.
- GEGL graph as well, unless a specific environment is set.
- All operations with auxiliary inputs cannot be run non-destructively
  (yet) either and therefore must also be deactivated on these layer
  types.

A few more actions are still special-cased (in particular regarding
being used on grayscale drawable or on formats with an alpha channel),
though it would be nice if we could generalize these somehow eventually
too.
2025-08-30 13:58:02 +02:00
Jehan
c732dfd4ca gimp-data: new splash image. 2025-08-30 13:00:18 +02:00
Jehan
38c379cd92 app: properly forbid paint tools to draw on link layers and forbid…
… filter tools to merge filters, both on link and vector layers.
2025-08-30 10:12:17 +02:00
Jehan
9a780bc7d4 app: missing break!
Argh! This got broken in commit 6e91826865.
2025-08-30 09:46:06 +02:00
Jehan
db18d739e5 app: cleanly downgrade link layers with NULL links.
This will be a bit more robust to potentially invalid files with a NULL
link.
2025-08-30 09:42:15 +02:00
Jehan
2c44689fe2 app, po: localize various strings which were blocked by string freeze. 2025-08-30 09:15:28 +02:00
Bruno Lopes
cc4821ffcb build/windows: Make $store_changelog handle <li demo=""> 2025-08-29 09:05:59 -03:00
Jehan
35b972c854 app, desktop: update demo tour for vector layers. 2025-08-29 13:15:24 +02:00
Asier Saratsua Garmendia
2a3d54bee9 Update Basque translation 2025-08-29 09:15:18 +00:00
Asier Saratsua Garmendia
c0d2a7fadd Update Basque translation 2025-08-29 08:47:23 +00:00
Asier Saratsua Garmendia
a5aaed7929 Update Basque translation 2025-08-29 08:22:22 +00:00
Jehan
4ed035affd gimp-data: bump to fix building with old librsvg (#14544). 2025-08-28 23:33:49 +02:00
Jehan
44d90a389e NEWS: update. 2025-08-28 23:20:44 +02:00
Jehan
4f3aee5e83 Issue #14759: link layers (of vector files) initial dimensions will fill…
… the whole canvas while keeping aspect ratio of the source image.

The previous dimensions were not entirely "out of the blue" since they
were taken from the file, but very often dimensions from vector images
are kinda bogus (apart from aspect ratio, they don't mean much) anyway.

Now we will just fill the canvas box by default.

When changing the source file of an existing link layer though (through
Link Layer properties), the dimensions will be within the current layer
bounding box.

Also I realized that we need to also store the link width/height in the
XCF because the buffer width/height may not be right (in case a
transform matrix was applied). This commit therefore breaks XCF file
with link layers made in the last 2 days. Since we have not made even a
dev release, it's probably fine to do this and not bump the XCF version.
2025-08-28 23:13:03 +02:00
Jehan
9519901150 libgimp, plug-ins: implement loading SVG breaking aspect ratio.
Previous implementation was always keeping ratio. If the width/height
argument were of a different aspect, librsvg simply fits the image with
original aspect within the box. Now we will appropriately scale
differently on both dimensions to have the image fill the whole box.

Note that this doesn't work with librsvg before 2.46.0 (not that it's
not possible, just that I haven't looked at how it should be implemented
there (which would be a different implementation anyway since there is
no cairo step).

Finally I add a build warning for when we'll prepare for GIMP 4, as the
pixel density arg needs to be split in 2 (each dimension can have its
own PPI), even though this is not really needed right now.
2025-08-28 23:13:03 +02:00
Jehan
d8712a525b plug-ins: fix compilation with librsvg < 2.46.0.
Note that it's not actually tested with an old librsvg, but only forcing
this code path with a new librsvg and fixing the compilation
errors/warnings which are outputted.
2025-08-28 23:13:03 +02:00
Jacob Boerema
640fb89f13 libgimpbase: improve parasite API documentation 2025-08-28 16:00:56 -04:00
Jacob Boerema
24ca35625b app: add "..." to Fill/Stroke command
Since it opens a dialog it should have ... at the end
2025-08-28 13:18:32 -04:00
Jacob Boerema
769b911018 app: add help ids for vector layer commands 2025-08-28 13:17:16 -04:00
Jacob Boerema
84b450b7bd app: Give Open as Link Layer it's own help id
Each menu command should have its own help id, so we define a new
help id for opening a link layer.
2025-08-28 12:18:05 -04:00
Bruno Lopes
4ec1368af9 build/linux: Remove 'x-checker-data' while not on stable Ghostscript
Following faf0fd74
2025-08-28 12:16:14 -03:00
Alx Sa
520aeacd8c widgets: Follow theme mode on Critical Dialog (Win)
Following the improvement in fe4cbb65, the Critical Dialogue
uses the native titlebar in Windows. This means it no longer
adapts to dark and light mode automatically.
Since we don't want GimpCriticalDialog to be dependent on
internal GIMP code, this patch copies over the fallback code
in gimp_window_set_title_bar_theme () (which sets the title bar
based on the background color) when the dialogue is realized.
2025-08-28 03:50:21 +00:00
Bruno Lopes
0fb3c8bb67 gimp-data: Bump commit again to drop UNIX-only EX_SOFTWARE 2025-08-27 22:01:38 -03:00
Bruno Lopes
1f0f8d1a2c gimp-data: Bump gimp-data to reduce stuckness on Windows 2025-08-27 21:46:59 -03:00
Bruno Lopes
be667ac007 app/core: Declare libarchive dependency introduced by 6597dabe
Otherwise, the '-I' param will not be set and Apple Clang will
fail on exotic environments like Homebrew on
which not everything is in the common 'includedir'.
2025-08-27 16:38:10 -03:00
Jehan
16a1283f07 Issue #14758: link layers resize can not be undone. 2025-08-27 19:36:02 +02:00
Jehan
1f79e4314e Issue #14760: fix wrong offset when scaling a link layer.
This commit also makes the scaling detection a bit more forgiving to
"imperfect" scale matrix by using an epsilon low enough that it probably
won't make much of a big difference, transform-wise, while it would make
a big difference quality-wise.
2025-08-27 19:35:56 +02:00
Jacob Boerema
55627934c5 plug-ins: add more file plug-in loading tests
Adds a few tga, j2k, wbmp and wmf tests.
2025-08-27 11:11:32 -04:00
Alx Sa
61c67d012b plug-ins: Fix CRITICALs and GUI issues in file-ps
Resolves #14761 (and other issues)
* Clears out the selection on GimpPageSelector on load so
that it does not try to "redraw" areas when the dialogue is closed
* Fixes layout on load dialogue to better match 2.10 (and use less
vertical space)
* Now that we have a unit property, replace the call to
gimp_label_string_widget_get_widget () with a direct connection to
changes in the config's "unit". This both fixes a CRITICAL caused by
setting a signal on a non-existent object, and restores the function
that adjusts the dimensions when the unit is changed from inches to
millimeters and back.
2025-08-27 13:02:59 +00:00
Ondřej Míchal
faf0fd7401 build/linux: Re-add ghostscript using a new release candidate
This is not a full new release but we might as well test the new
release-candidate to see if it fixes the build issues with GCC 15.

Partially reverts 4ae861f5ac
2025-08-27 09:39:49 -03:00
Gabriele Barbero
eeeaca928b tools: implement shortcuts in text tool...
...for toggle bold/italic/underline.

This commit adds support for common formatting shortcuts in the Text Tool:
- Ctrl+B: Toggle bold
- Ctrl+I: Toggle italic
- Ctrl+U: Toggle underline
2025-08-27 11:21:51 +00:00
Jehan
73979309ab po: add new localized source files.
Thanks to Anders for reminding me!
2025-08-27 11:34:04 +02:00
Jehan
97bf7e1bfa app: rework load/save of link layers.
- We now bump to XCF version 25 since vector layers were implemented in
  XCF 24.
- Fix some now broken code in saving/loading, also rename
  PROP_LINK_LAYER_DATA to simply PROP_LINK_LAYER and use the generic
  gimp_layer_from_layer() which I created in commit afb8867bce and is
  also used for text and vector layers.
- Add a PROP_TRANSFORM layer property. It is separate from
  PROP_LINK_LAYER because I will likely reuse this for other (all even)
  types of layers as well.
2025-08-27 11:34:04 +02:00
Jehan
95f1d768c3 app: link layers must still have a converted buffer.
Otherwise we may end up with discrepancy such as layers having a u8
buffer on a u16 image.
2025-08-27 11:34:04 +02:00
Jehan
66cdecb0fa app, menus, pdb: new file-open-as-link-layers action.
Revert the logic of opening all files as link layers back into loading
their current content as normal layers.
Instead just add a new action dedicated to open images as link layers
and add it to the File menu.

Per UX discussions with Aryeom.
2025-08-27 11:34:04 +02:00
Jehan
8280058c5a app: properly reapply the transform matrix after link layer source updated.
Also make sure that a link layer duplicate shows the proper contents
too!
2025-08-27 11:34:04 +02:00
Jehan
2821dbab58 app: add generic support for less destructive transform tools.
This commit will make all transform tools run on a link layer cumulate
their transform matrix on top of the previous transform steps. It means
that as long as you don't edit the pixels another way (e.g. with a paint
tool), all your transformations will apply as a single transformation.

For instance it means that applying several transform tool steps on a
monitored link layer will be less destructive than applying the exact
same transformations on the exact same "normal" layer contents.
Even scaling an image to 1x1 then back to a big size will work very
fine!

Note nevertheless the following limitations in current implementation:

* The link layer with transformations will still show as a standard link
  layer. Nothing says it has transformation applied on it right now.
* To drop transformations applied on a link layer, you have to discard
  the link info, then monitor the link again. A specific action in the
  contextual menu could be worth it.
* This should work with all transform tools (scale, rotation, unified,
  perspective, 3D, even Warp…) but it won't work for the Flip tool, nor
  will it work for the Transform actions. I will need to implement
  GimpItem's rotate(), flip() and resize() methods next.
* The layer mask would still be destructively transformed (I have not
  made any tests with layer masks yet, but this should be done next
  too).
* I think that the "scaled-only" property is now meaningless. It is now
  being replaced by the presence of the GimpMatrix3. Nevertheless I have
  still not removed this property.
* The load/save code has not been redone yet to include all these
  changes.

The kind of caveats we'd have to know about (and which are not planned
for change, because it's just how it is):

* Any intermediate interpolation methods are dropped when cumulating
  transform steps. Only the last interpolation is stored. This is
  because anyway the interpolation is only there as the best algorithm
  where we visually see the less quality loss. Applying several
  transformations as a single matrix will always be visually better than
  applying several matrices (whatever the intermediate interpolation
  methods chosen).
* This only works with the "Adjust" clipping method (basically no
  clipping) because 2 transform steps with clipping won't produce the
  same result as the multiplied matrix with clipping. It means that
  applying a transform with clipping will downgrade your link layer to
  being a normal layer.
  The only issue I have with this is how to best convey that clipping is
  a major setting setting here, which disables our less-destructive
  abilities. Right now, people will just have to "know" it.
* Vector link layers in particular will have 2 levels of
  non/less-destructivity transforms. In particular any scaling (both
  through "Scale Image", "Scale Layers" and transform tools — since I
  added code to detect a matrix doing only scaling and optionally
  translation) done **first** will be completely non-destructive since
  we will simply reload the original vector source at the right
  dimensions. Any other kind of transforms will be appended through the
  cumulative matrix, as raster link layers. This also includes scaling
  done **after** other transforms, since we cannot easily move the
  scaling first (matrix multiplication is not commutative). This second
  level of scaling will therefore be *less* destructive, but still
  destructive.
  It is possible eventually to improve the whole thing if we add some
  day the ability to request loading a vector image with a transform
  matrix (it will then be up to each vector format plug-in to support
  this feature or not).

Note: it could be argued that this whole implementation could in fact be
moved over to base layers, since it would allow also less-destructivity
when applying multiple transformations in a row. We would only merge
results once we edit pixels more directly.
But I think that it's not a bad idea to experiment with this new code in
the link layer. Eventually I may likely move this to the parent
GimpLayer if no blocking issues are found.
2025-08-27 11:34:04 +02:00
Jehan
7c7587bb2d app: replace #ifndef/#define macros by #pragma once. 2025-08-27 11:34:04 +02:00
Jehan
3e5fce27cb app: move logic to know if a link layer is being monitored to GimpLink.
Instead of keeping a "modified" property in GimpLinkLayer, we just check
if the link is being monitored. It's also a better wording because we
may "discard the link information" without actually modifying the layer
pixels.

Also I now actually shut down the file monitoring process. This can be a
bit expensive so when we don't need it, let's really free the
GFileMonitor.

This commit also fixes scaling of link layer (which got broken along the
way) and improves the undo code.

Note: I'll probably want to modify the XCF flags, but let's do this in
the end, depending on further changes too.
2025-08-27 11:34:04 +02:00
Jehan
4128c789f9 app: more efficient GimpLink rendering.
We now re-render a link (by loading its file) immediately upon setting
the new file, i.e. during the calls of gimp_link_new() or
gimp_link_set_file(). As part of this change:

* A GimpLink now stores a GeglBuffer. And this is changed each time a
  file change happens (per the GFileMonitor). In particular that also
  means that gimp_link_get_buffer() does not reload the image file at
  each call for no reasons, and gimp_link_is_broken() does not have a
  `recheck` argument either. This is much more efficient.
* These 2 functions also have a GimpProgress and GError now. We use this
  among other things to pass on a specific GimpProgress object. In
  particular, the image file dialogs now show correct loading
  progression again.
* As a general rule, the code is less confusing as we don't have to
  wonder whether a GimpLink is ready. We can assume it always is, from
  now on.

Note that gimp_link_duplicate() does not trigger a reload of the image
file. Since we assume that the source GimpLink is supposed to be
up-to-date already, we just copy its buffer as-is as an optimization.
2025-08-27 11:34:04 +02:00
Jehan
0b8397ff56 app: "Discard Links" and undo should trigger thumbnail update.
Even if no actual drawable change may have happen, let's manually
trigger an "update" signal, hence triggering thumbnail updates too, but
also contextual menu update in the Layers dockable.
2025-08-27 11:34:04 +02:00
Jehan
9b0f426fbd app: all images (except remote files, XCF and compressed XCF) opened as links.
This is still mostly a test of workflow. It is based on the idea that
link layers are normal yet enhanced layers: eventually we should be able
to have some improved less-destructive scaling/rotation (even without
NDE transform effects); you can manually drop the link anytime anyway
(hence getting back to the good old fully destructive workflow); any
pixel editing automatically drops the link too.

Now this still raises quite a lot of questions:

* The link can be confusing to people used to the old way and they may
  not realize that editing the original file separately would also
  update the render in this file (which may not be what they wanted;
  maybe they just wanted to grab a snapshot of this file at a given
  time).
* You could also want to link XCF files.
* You could also want to link remote files (especially in a controlled
  network environment).
* Linked images are currently taken as a whole; we definitely want layer
  support to handle multi-layer image formats (so that you could link
  only a single layer, or a collection of layers; do we want to be able
  to edit visibility of linked layers separately too? Would be neat). So
  how would we handle automatic linking when opening a file? Maybe we
  just reproduce the layer structure as link layers (one link layer
  monitoring only one layer from the linked file)?

Anyway this is work-in-progress, UX-wise.
2025-08-27 11:34:04 +02:00
Jehan
674939e225 app, libgimpbase, pdb: rework layer dialog.
This commit changes the following:

- It's now possible to set whether to store an absolute or relative path
  when editing link layer properties.
- New layer dialog doesn't propose an "Image link" fill type anymore.
  Link layers won't be created this way (see in a future commit).
2025-08-27 11:34:04 +02:00
Jehan
a60487aedd app: link layers can now be stored with relative or absolute paths.
By default, we set them as relative paths. This seems like the more
practical and allows for relocatable folders when one work with project
folders containing all their assets.

We don't have yet a way to set this to being absolute path, but it will
come in a further commit.
2025-08-27 11:34:04 +02:00
Jehan
2dac66d979 app: fix gimp_link_layer_duplicate() for modified link layers. 2025-08-27 11:34:04 +02:00
Jehan
f4a2158458 app: scale linked raster images back from source file.
Unless other types of edits have been done on a link layer (e.g.
painting), we avoid quality loss by multiple scaling of raster link
layers by always re-scaling from the source file.
2025-08-27 11:34:04 +02:00
Jehan
28bf061f4d app: properly handle vector images as link layers.
This commit was edited after GIMP 3.0, now that we have dedicated
support for loading vector images with GimpVectorLoadProcedure.

- By default, when loaded as GimpLinkLayer, vector images are loaded at
  a size so that they are exactly contained in the image.
- When scaled with Scale Layer dialog, link layers of type vector are
  re-loaded from the source file to always stay perfectly crisp.
2025-08-27 11:34:03 +02:00
Jehan
0b5aa01bb9 app: more rebasing after GIMP 3.0 release. 2025-08-27 11:34:03 +02:00
Jehan
f45244f991 app: fix branch after rebasing.
return_if_no_layer() doesn't exist anymore. The 2 layers actions are now
multi-layer aware.
2025-08-27 11:34:03 +02:00
Jehan
39185d43ba app: GimpLink should emit "changed" signal idly.
Even though G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT should normally
happen when we are *probably* at the last change of a set of changes,
the keyword is clearly *probably* as I had 5 or 6 of these events when
saving a single image.

There is no need for our link layer to reload a same image that many
times in under a second. Instead, just emit our "changed" signal in an
idly source to avoid uselessly duplicating events.
2025-08-27 11:34:03 +02:00
Jehan
6c86e80019 app: port branch to meson. 2025-08-27 11:34:03 +02:00
Jehan
3e6fed839a app: salvage link layers of dimension 0.
Similar to commit 06be074650, but now for
link layers. Their dimension are also determined by their contents so
anyway let's be more resistant from some forms of file corruption.
2025-08-27 11:34:03 +02:00
Jehan
6e91826865 app: add saving/loading of link layers. 2025-08-27 11:34:03 +02:00
Jehan
20083bcabe app: new link layers.
These are layers who content depends on another source (right now only
an external image). This can be useful when for instance working at
several people on a single artwork, hence being able to load new
versions of an image without even touching anything in the XCF (for
instance, say you draw an animated character while someone else is
taking care of the background).

Similarly to what we do for text layers, once you start modifying the
contents, it turns into a "normal" layer. The link information is still
available though, so it is possible to revert to the monitoring state
with the menu item "Monitor Linked Image" which appear when a link layer
became a normal layer.

This is not finale as I'm still experimenting. In particular, I have not
implemented XCF saving/loading yet for this new layer type.
2025-08-27 11:34:03 +02:00
Jehan
ac63b1d8fb app: new GimpLink object.
A GimpLink is just a class monitoring an image file and sending a
"changed" signal when it changes. This will be used to implement link
layers, whose contents is based on an external file.
This is only a simple first version. Future versions may also allow to
monitor specific layers in an image file, or a layer in the same XCF
image which you'd want to link instead of duplicating it.
2025-08-27 11:34:03 +02:00
Asier Saratsua Garmendia
d1dca0a881 Update Basque translation 2025-08-27 08:00:58 +00:00
Asier Sarasua Garmendia
8a771a2a51 Update Basque translation 2025-08-27 07:54:51 +00:00
Ondřej Míchal
33f6117539 plug-ins/filter-browser: Remove Pippins's copyright
This note was relevant when the plug-in used GEGL code for collecting
available GEGL operations. This is no longer the case and thus the
copyright can be dropped.
2025-08-26 23:50:37 +00:00
Jehan
b80a2341cf NEWS: update. 2025-08-27 00:07:12 +02:00
Cristian Secară
3ad4b063b0 Update Romanian translation 2025-08-26 18:40:05 +00:00
Ekaterine Papava
de2b54faa6 Update Georgian translation 2025-08-24 11:49:21 +00:00
Alx Sa
30d31ac709 widgets: Auto-update fill/stroke editor colors
When creating a GimpFillEditor or GimpStrokeEditor with
edit-context == TRUE, a color button is created next to the
foreground/background option. However, the color of the
item associated with the button doesn't change until the
user confirms it in the corresponding dialogue. This prevents
"live-previewing" color changes on vector layers or text outlines.

This patch adds a call to gimp_color_button_set_update () when the
color buttons are created in GimpFillEditor (which GimpStrokeEditor
inherits from). This allows live-previewing on vector layer fill/stroke
and text outlines, as we currently support with text color from the
tool options.
2025-08-23 16:23:50 +00:00
Bruno Lopes
5d308e9ed9 build/windows: Explain the purpose of the bundling script 2025-08-22 21:28:52 -03:00
Bruno Lopes
e52b49e0a3 build/windows: Prevent *bundle*sym.py script from being called outside Meson 2025-08-22 20:50:15 -03:00
Bruno Lopes
565804f26e meson: Complete fae39c79 regarding bug_report_url placement 2025-08-22 20:00:18 -03:00
Bruno Lopes
c734c0f33f build/linux: Make bund_usr function more robust on AppImage script 2025-08-22 19:55:31 -03:00
Jacob Boerema
1a96fb55f9 libgimp: Modernize setting "Exif.Image.DateTime"
by using g_date_time_format, and additionally also set the timezone
(even though using that is less common in Exif, it can't hurt for us
to add it).
2025-08-22 15:16:49 -04:00
Jacob Boerema
922e409045 libgimp: fix XMP modification date separators
Similar to issue #14731, when exporting we incorrectly set
the date/month/year separators to : instead of -.

This commit fixes that.
2025-08-22 15:14:20 -04:00
Jacob Boerema
3211ab1408 libgimp: fix #14644 Wrong comment synchronized with metadata
On export, when synchronizing the comment with the metadata equivalents,
we did not consider that the comment could have been changed in the
export dialog comment field. In fact, we already updated the metadata
before that happened in gimp_image_metadata_save_prepare.

To fix that
- We remove it from the above mentioned function, since that is too
early.
- Add the (possibly) updated comment to the exported_image as a
comment parasite so that we can access the updated value, but only
when synchronizing metadata is allowed, and saving comments is enabled.
- Synchronize the comment, taken from the parasite, with its metadata
counterparts in gimp_image_metadata_save_filter, but only when
synchronizing is allowed and saving comments is enabled.

Note that due to this the synchronized metadata comments are only
visible in the exported file. The metadata in the opened image is
not updated.
2025-08-22 15:12:23 -04:00
Alx Sa
2c91604509 pdb, libgimp: Add PDB get/set for fade-length and fade-repeat
This patch adds PDB functions to get and set the PaintOptions
fade-length and fade-repeat properties. This settings can be
used together with gimp_context_set_emulate_brush_dynamics ()
to further control how the paint strokes are drawn in a script
or plug-in.
2025-08-22 17:43:40 +00:00
Jacob Boerema
f02910d00f libgimpbase: fix #14731 incorrect day/month separators in XMP metadata
In 6b10cce6 I introduced setting created date/time metadata for new
images. However, I made a mistake there by using : instead of - between
year, month and day for the XMP metadata tags.

This commit fixes that.
2025-08-22 12:31:48 -04:00
Bruno Lopes
2346acbfc2 devel-docs: Add macOS versioning instructions too
And a bit of space because the file was getting hard to read
2025-08-22 10:12:08 -03:00
Bruno Lopes
7764eab3f6 devel-docs: Mention min-support key of content/gimp_versions.json 2025-08-22 09:55:52 -03:00
Bruno Lopes
ca43c6f20c build/windows: Make "etc\ssl\" part of Python component on Installer 2025-08-22 09:47:48 -03:00
Bruno Lopes
05cde48a3e build/linux: 'xdg-email' works on Snap package 2025-08-22 09:38:04 -03:00
Asier Saratsua Garmendia
4bf7ed4265 Update Basque translation 2025-08-22 05:48:50 +00:00
Asier Saratsua Garmendia
0aa7af0f11 Update Basque translation 2025-08-22 05:43:22 +00:00
Ekaterine Papava
d2beafd0e9 Update Georgian translation 2025-08-22 04:00:52 +00:00
Luming Zh
fa683ca0ce Update Chinese (China) translation 2025-08-22 01:17:25 +00:00
Luming Zh
4fa0a63ca4 Update Chinese (China) translation 2025-08-22 01:05:56 +00:00
Bruno Lopes
d2720dca0c Issue #14722: Bundle cert.pem for internet connection on Python
Closes #14722

Python internal/standard libraries like 'urllib' (present on all
packages we distribute like AppImage and DMG) requires that.
2025-08-21 19:28:54 -03:00
Martin
d72bc4704e Update Slovenian translation 2025-08-21 19:18:40 +00:00
Yuri Chornoivan
eb30705545 Update Ukrainian translation 2025-08-21 18:50:37 +00:00
Bruno Lopes
807e263b87 gimp-data: Bump commit 2025-08-21 14:52:09 -03:00
Bruno Lopes
fae39c792d meson: Move '-Dbug-report-url' message to more visible place
The reasioning is at: 137bf019
2025-08-21 12:15:26 -03:00
Bruno Lopes
3290dd9b8f Revert "meson: Move '-Dbug-report-url' message to the bottom to be more visible"
This reverts commit 137bf01928 pushed by
accident.
2025-08-21 12:11:38 -03:00
Bruno Lopes
137bf01928 meson: Move '-Dbug-report-url' message to the bottom to be more visible
While I checked that all the "main" downstreamers make use of it
(ArchLinux, Fedora, Ubuntu, Debian, Ubuntu, MSYS2, macports),
it is so hidden that we can't guarantee anyone will
actually see it in the future in the middle of many lines.
2025-08-21 12:07:05 -03:00
Bruno Lopes
8f895aaa8c gitlab-ci, devel-docs: Add instructions on maintaining DEB_VERSION 2025-08-21 11:52:38 -03:00
Bruno Lopes
b4952addb9 gitlab-ci: Do not generate developer docs on AppImage
We already do not build them on Flatpak and Snap, since
the debian-nonreloc job is enough to test that on Linux.
2025-08-21 11:28:40 -03:00
Bruno Lopes
5856941814 meson: Fix false positive in xdg-email check
And do not output a warning since it is never avaiable on Windows.
2025-08-21 11:25:52 -03:00
Bruno Lopes
1e5639a47d meson: Drop arbitrary libsocket check introduced since Meson port
It is present since 2.99.2 tag but nothing makes use of 'HAVE_LIBSOCKET'.
2025-08-21 09:07:15 -03:00
Bruno Lopes
e8b6f05659 gitlab-ci: Remove redundancy on Store job rules 2025-08-21 07:42:03 -03:00
Michael Natterer
6eaf357af9 app: make GimpViewRenderer::border_type and ::border_color private 2025-08-21 08:15:42 +02:00
Bruno Lopes
da16988ee0 build/windows: Fix 'ARM64' typo in TWAIN defines of Installer script 2025-08-20 16:56:08 -03:00
Bruno Lopes
f9809354d5 Issue #14716: app: Set PATH to prevent DLL Hell on Windows
Closes: #14716

This ports the macOS trick to avoid loading binaries from the host.

SetDllDirectory (and its modern counterpart AddDllDirectory) are
not enough since we do not have control about all processes.
2025-08-20 16:51:21 -03:00
Bruno Lopes
ad03d6c94a build/linux: Update imath module to 3.2.1 2025-08-20 14:22:54 -03:00
Bruno Lopes
f6704a84fa build/linux: Remove dangling .patch files after org.gimp.GIMP.HEIC drop
x265 is not being built anymore since eefc2bea
2025-08-20 14:21:20 -03:00
Anders Jonsson
5c35946c51 plug-ins: make filter browser labels translatable 2025-08-20 14:47:24 +02:00
Bruno Lopes
6245e4ee70 .gitlab: Add comment telling how to generate packages on MRs 2025-08-20 09:24:49 -03:00
Bruno Lopes
0c6d7c15bc build/windows: Reorganize MSIX script messages to be consistent with Installer 2025-08-20 07:07:37 -03:00
Michael Natterer
0d7cea41ad app: remove gimp_view_renderer_set_border_color(). Instead, add values
STYLE_FG and STYLE_BG to enum GimpViewBorderType, where FG uses the
actual style FG, and BG is simply transparent. Default to STYLE_FG
instead of BLACK (which is BLACK's actual intention).  Also, don't
leak all GeglColors of all view renderers.
2025-08-20 10:18:39 +02:00
Jordi Mas
c63d7bc226 Fixes to Catalan translation 2025-08-20 04:41:42 +02:00
Bruno Lopes
3d14a2652d gitlab-ci: Drop -x86 suffix on Installer jobs in favor of -eol
This fixes the redundancy with [win32-ps, mingw32].
2025-08-19 20:22:06 -03:00
Bruno Lopes
8993939008 gitlab-ci: Make possible to create .exe installer and .msix outside GNOME/gimp
This fixes the windows-aarch64 runner blocking contributors (not devs) CI on,
for example, MRs. Now, a x64-only artifact can be created in such cases.
2025-08-19 19:17:50 -03:00
Nathan Follens
3c85dfe6e9 Update Dutch translation 2025-08-19 17:52:06 +00:00
Martin
96be4a79d3 Update Slovenian translation 2025-08-19 17:34:01 +00:00
Kolbjørn Stuestøl
381bee5dbb Update Norwegian Nynorsk translation 2025-08-19 17:00:16 +00:00
Kolbjørn Stuestøl
0f12dcc772 Update Norwegian Nynorsk translation 2025-08-19 16:45:43 +00:00
Yuri Chornoivan
293300cafd Update Ukrainian translation 2025-08-19 15:49:02 +00:00
Yuri Chornoivan
898ab7c9c6 Update Ukrainian translation 2025-08-19 15:41:02 +00:00
Bruno Lopes
f3a8e0c041 gitlab-ci: Explain why sources and dev-docs are not run in MRs 2025-08-19 11:00:29 -03:00
Bruno Lopes
2b779c6a11 gitlab-ci: Simplify a bit environment variables on Dockerfile
We aren't using them from ENVIRON so that is no need to replicate.
2025-08-19 10:38:12 -03:00
Bruno Lopes
735ae9f123 gitlab-ci: Set WORKDIR on debian jobs Dockerfile 2025-08-19 10:24:40 -03:00
Michael Natterer
09203bb93e app: rename GIMP_VIEW_BG_USE_STYLE to GIMP_VIEW_BG_STYLE 2025-08-19 15:19:23 +02:00
Bruno Lopes
1d5a1c9972 gitlab-ci: Remove some dangling GIMP_CI_* variables
They are never used, specially (by redundancy) the ones
of jobs which are already triggered on commits.
2025-08-19 09:57:33 -03:00
Michael Natterer
fb04b7cb8f app: get rid of GimpViewRenderer's separate "icon_surface", and get
rid of implicit knowledge about the surface's scale factor.

- render everything to renderer->surface
- pass the widget scale factor around explicitely when rendering
  to the surface
- when drawing the surface to the widget, get the scale factor from
  the surface itself.
2025-08-19 14:35:58 +02:00
Bruno Lopes
6fe919c6e2 gitlab-ci: Drop debian -x64 suffix on non-Appimage jobs in favor of -nonreloc
It is a bit too long and not the ideal naming but with the new one we avoid
the -x64 arch suffix which feels redundant due to the [x86_64_v3] added by GL
2025-08-19 08:53:30 -03:00
Bruno Lopes
1c7a43a021 gitlab-ci: Drop WORKSHOP_OPTION var in unstable series
It was introduced in 74a05bc9 but we are not stable anymore
2025-08-19 08:18:17 -03:00
Alx Sa
4b67eb9cd0 paths, tools: Prevent CRITICAL when discarding empty vector layer
Resolves #14705
The path tool prevents creating a vector layer from an empty path.
However, the menu option "Path to Vector Layers" does not have this check.
This patch updates the check to constrain it to just one path.
Additionally, it adds a check for the path being NULL before trying to use
it in g_set_object ().
2025-08-19 00:10:22 -04:00
Bruno Lopes
baa5e0690e build/windows: Little improvement to config_clean.h comment 2025-08-18 19:47:00 -03:00
Bruno Lopes
ffa2946b18 build/windows: Change $a64_bundle to $arm64_bundle on MSIX script
This new naming is consistent with the Installer script.
2025-08-18 19:41:07 -03:00
Bruno Lopes
8710127641 build/windows: Add optional one-arch support to Windows installer
This removes the old custom DIR/DDIR code from the era of the
installer was built locally. Now, it will refer to bundles so
making the .exe installer based on the bundles available,
not enforcing the developer to download all bundles anymore.

We will not use such new facility on CI since we distribute an
universal installer with all arches since 2.8 for good reasons.
This will not change, we will continue to create multi-arch .exe.

The main advantage is locally. Now the .iss script can
recognize at ISCC build time the bundles on the machine,
to create, for example, an one-arch installer. This is very
fast and practival for local hacking the installer scripts.

Of course, this also makes the installer script powerful and
consistent with all other dist scripts which already can do
one-arch packages (appimage, flatpak, snap and msix).
2025-08-18 16:54:19 -03:00
Bruno Lopes
cfb1b539f2 build/windows: Organize tookit section of Installer script to be consistent 2025-08-18 16:53:08 -03:00
Anders Jonsson
11b35908fa app: add missing context to make translations be used
gimp_action_group_add_actions has a loop that expected all strings
to have a context since msg_context was set. Without a context
the original string was used.
2025-08-18 20:56:57 +02:00
Bruno Lopes
6ddb33135c build/windows: Add comment about parity with MSIX on Installer scripts 2025-08-18 15:44:00 -03:00
Bruno Lopes
125e355c44 build/windows, devel-docs: The minimum Windows version is actually 10.0.18362.0
DWMWA_USE_IMMERSIVE_DARK_MODE and activeCodePage were introduced on "1903"
The Store version manifest was already using this as minimum version since
day 1, so the commit just extends that minimum version to the Installer.

While is unlikely that users will be affected, we can revert this commit if:
1) LTSC/LTSB users report on tracker that is not possible to install GIMP;
2) we confirm that GIMP works on this machine even with that incompatible API.
2025-08-18 15:10:27 -03:00
Aleksandr Prokudin
edc6f5a4b1 Update Russian translation 2025-08-18 19:37:41 +02:00
Bruno Lopes
246d73de04 build/windows: Drop absurd custom translation of WindowsVersionNotSupported
This have nothing to do with the OS build version but mostly with the
OS arch. Yeah, the original Inno string is obscure but at least not false.
2025-08-18 14:13:44 -03:00
Michael Natterer
c2195a24ca app: redo preview backgrounds completely
While there is a style "background color", the idea of a "widget
background color" is completely bogus, the widget background can be a
gradient or whatever.

- Get rid of "background" in GimpViewable's preview API, only leave the
  "foreground color" there for things like brushes or fonts.
- In GimpViewRenderer, add the background types to be used to class and
  instance, so each renderer type can choose what it needs.
- Render all previews to alpha surfaces, and do the background
  for all renderers generically in gimp_view_renderer_real_draw(),
  then render the preview surface on top of it.
2025-08-18 14:05:54 +02:00
Bruno Lopes
977bcae71e build/windows: Make Inno source section more simple (again) 2025-08-18 07:49:56 -03:00
Marco Ciampa
31293376ee Small fix in Italian translation 2025-08-18 10:01:13 +02:00
Bruno Lopes
42e72b29c1 build/windows: Clarify meson.build file of Installer lang files 2025-08-17 18:36:21 -03:00
Anders Jonsson
31a267a8f1 po: update POTFILES.in 2025-08-17 22:48:28 +02:00
Bruno Lopes
193cf720c6 build/windows: Make self_build function work with every meson project 2025-08-17 15:02:15 -03:00
Yuri Chornoivan
94dcb39659 Update Ukrainian translation 2025-08-17 14:56:10 +00:00
Ekaterine Papava
af6bb31f89 Update Georgian translation 2025-08-17 10:27:35 +00:00
Ekaterine Papava
fe10197298 Update Georgian translation 2025-08-17 10:20:49 +00:00
Martin
e67068d92f Update Slovenian translation 2025-08-17 08:56:01 +00:00
Alx Sa
54f39cef6d core: Add 3.2 to version_string
With vector layers, gimp_image_get_xcf_version () needs
a case 24 to set the version string to 3.2.
2025-08-16 23:44:09 -04:00
Jehan
ada86282de app: reimplement saving/loading of vector layers and bump to XCF 24.
We now have a proper PROP_VECTOR_LAYER property in the XCF which will
store the various data relevant to vector layers.
This also fixes saving this new type of layers at all, since it was
broken in MR !773.
2025-08-16 23:44:09 -04:00
Jehan
afb8867bce app: make gimp_text_layer_from_layer() into a generic gimp_layer_from_layer().
This same code will also be usable for GimpVectorLayer and
GimpLinkLayer. It was made generic so that we don't copy the same code
over and over.
Now it also supports the case when the layer to copy was already added
to the image, which is going to be necessary for GimpVectorLayer.
2025-08-17 02:20:19 +00:00
Jehan
9f17f97198 app: small cleanup in GimpVectorLayer.
- Some coding style bugs.
- Factorize setting vector layer options into
  gimp_vector_layer_set_vector_options(), making sure all code paths to
  update the options do the same thing.
- Ceil the vector layer size since stroke width is a double. C rounds
  towards zero, which means we may still have too small buffer.
2025-08-17 02:20:19 +00:00
Jehan
41a464cb9a app: move functions to look up GimpData into core.
These functions should not be for the PDB only. The core will soon need
these too (e.g. to load resources linked from a XCF file).

So gimp_pdb_get_data_factory() is moved to gimp_get_data_factory() in
Gimp class. And gimp_pdb_get_data_factory_item() is moved to
gimp_data_factory_get_data() in GimpDataFactory class.
2025-08-17 02:20:19 +00:00
Jehan
4a93a04a6b app: move GeglColor handling code in their own function and properly…
… take care of the NULL value.

Up until now, the NULL color was simply not stored in the XCF. I.e. we
had a FILTER_PROP_COLOR argument type (under PROP_FILTER_ARGUMENT) whose
data was just… nothing.

Now we'll just always store a 0 uint32 (just like we do for NULL
string). On load though, we'll continue recognizing both nothing (thanks
to the payload size) or zero.
2025-08-17 02:20:19 +00:00
Alx Sa
a1cd2a2588 path, tools, pdb: UX updates to vector layers
This patch improves vector layer UX based on feedback.
In summary:
* Makes vector layer editable from the Path tool
* Adds initial PDB for creating vector layers in scripts
* Size vector layers to the path size, rather than image
* Transform tools utilize the path for resizing
* Path tool automatically selects vector layer path
2025-08-17 02:20:19 +00:00
Henk Boom
60ed90e10a vectors: Implement vector layers from GSoC 2006
Ports the work done by Hendrik Boom, Martin Nordholts, Gilles Rochefort,
and Jacob Boerema to Gimp 2.99/3.0.
2025-08-17 02:20:19 +00:00
Alx Sa
03443ffcc1 text: Don't call size_changed when typing
This patch provides a temporary fix for issue
14442. Currently, gimp_drawable_size_changed ()
is called whenever a drawable's size changes (like by
scaling, rotating, resizing, etc). When called, it resizes
filters to the layer's new width and height.
Unfortunately, it is currently also called when typing new
text, as that changes the layer size too. This causes filters
like Drop Shadow to be cut-off because they originally
extended outside the bounds of the layer.

This patch checks if the layer has been rasterized - if it hasn't,
then size_changed () is not called. As stated, this is a temporary
fix for GIMP 3.1.4, and will likely be replaced with a more
permanent fix for GIMP 3.2
2025-08-17 01:33:14 +00:00
Bruno Lopes
4f6036e3e6 build/windows: Remove redundant error check on Windows deps script 2025-08-16 22:28:48 -03:00
Bruno Lopes
20d37cbe45 build/windows: Improve native error catching on .ps1 scripts 2025-08-16 22:16:47 -03:00
Luming Zh
949f9b586b Update Chinese (China) translation 2025-08-17 00:12:32 +00:00
Luming Zh
ee50e5f1c7 Update Chinese (China) translation 2025-08-17 00:06:19 +00:00
Martin
4fb5857123 Update Slovenian translation 2025-08-16 22:57:54 +00:00
Martin
53f714f8bc Update Slovenian translation 2025-08-16 22:44:05 +00:00
lillolollo
52ffd75330 Issue #14689: Add translation context for Extensions
Extensions is used both for file extensions and for
GIMP's planned Extension format. This patch adds translation
context so translators know which one we're referring to.
2025-08-16 19:54:31 +00:00
Anders Jonsson
6a7911655b po-*: update POTFILES.in
Add the new filter browser to POTFILES.in of po-plug-ins.

POTFILES.skip of po-python and po-script-fu also needed
updating to ignore the new subfolder under plug-ins.
2025-08-16 18:29:38 +02:00
Martin
522d73a922 Update Slovenian translation 2025-08-16 15:10:30 +00:00
Yuri Chornoivan
a5d282fc80 Update Ukrainian translation 2025-08-16 14:23:53 +00:00
Bruno Lopes
87f670b5d1 gitlab-ci: Update Pipeline types summary with meson-health and appimage
This documents meson-health and appimage

Also, remove the speed comments because these pipelines will
run automatically regardless of the developer intention.
2025-08-16 10:37:23 -03:00
Philipp Kiemle
0022e9738e Update German translation 2025-08-16 13:13:50 +00:00
Bruno Lopes
634dd304d7 meson: Do not check for DirectX SDK in hardcoded MSVC dirs
MSYS2 provides the same needed library so let's just find it properly.

Note: even when we do have MSVC support we should never hardcode .build
files. Setting paths to be searched on MSVC is the job of LIB env var.
2025-08-16 09:56:16 -03:00
lillolollo
d0af548894 plug-ins: Fix memory leaks in file-gif-load.c 2025-08-16 12:38:05 +00:00
Jordi Mas
a8934067a9 Update Catalan translation 2025-08-16 11:51:38 +02:00
Bruno Lopes
3b11006eed build/windows: Replace f333aa35 text regarding MSIX <> EXE parity 2025-08-15 21:51:07 -03:00
Bruno Lopes
f333aa354b build/windows: Make clearer that the MSIX should be identical to the Installer 2025-08-15 21:32:52 -03:00
Bruno Lopes
9a118dd887 build/windows: Remove some empty lines on Windows build scripts 2025-08-15 21:20:41 -03:00
Marco Ciampa
f5518cd69a Updated Italian translation 2025-08-15 23:52:49 +02:00
Bruno Lopes
0570ea2b0b gitlab-ci: More ccache remnants cleanup on Windows builds 2025-08-15 18:41:21 -03:00
Bruno Lopes
891e55829c gitlab-ci: Remove $UMFPACK var from crossbuilds era 2025-08-15 18:38:05 -03:00
Kolbjørn Stuestøl
b43e4df63f Update Norwegian Nynorsk translation 2025-08-15 20:06:28 +00:00
Bruno Lopes
a6545f3511 meson: Add option to generate DWARF symbols on Windows
By default, it is evaluated to CodeView since this is the format we
use on .exe installer and .msix for many reasons (see git log).

However, some people may not use standard debugging tools for
Windows but, for example, GDB, so they need DWARF symbols since
GDB debugger (and the GCC toolchain) have limited Windows support.
2025-08-15 14:56:16 -03:00
Yuri Chornoivan
b4eda82a93 Update Ukrainian translation 2025-08-15 17:52:26 +00:00
Anders Jonsson
3f13511015 plug-ins: make JPEG 2000 codestream title translatable 2025-08-15 18:31:32 +02:00
lillolollo
d261d466e9 app/core prevent memory leak 2025-08-15 12:08:30 -04:00
Yuri Chornoivan
162725bd8c Update Ukrainian translation 2025-08-15 16:08:27 +00:00
Jacob Boerema
3d91452507 plug-ins: fix issues in wbmp discovered in coverity 2025-08-15 11:59:10 -04:00
Bruno Lopes
d8a264283b build/linux: Take AppStream metadata for Snap package
Like the Flatpak and, at a lesser extent, AppImage.
2025-08-15 10:34:31 -03:00
Bruno Lopes
bb1d96528d build/linux: Update Snap README regarding babl and GEGL tagging 2025-08-15 10:34:11 -03:00
Alx Sa
ede124ff85 tools: Fix crash in passthrough composited preview
Resolves #13087
We use gimp_layer_get_effective_mode () to retrieve
a simplified layer mode for optimization purposes
(e.g. if it's effectively NORMAL, we can do less processing).
GimpTransformGridTool used this function when the user
requests Composited Preview to only apply transforms to
individual layers in a group if absolutely necessary.
This means that sometimes, it returns NORMAL instead of
PASS_THROUGH depending on the number and types of
layers in the group.

Since 71aff497, when we remove a filter we also update the
effective mode of the group layer. However, this leads to an
infinite loop scenario where the effective mode change causes
the TransformGridTool to repeatedly remove and add a filter
until GIMP crashes.

This patch changes the gimp_transform_grid_tool_add_filter ()
check to always get the actual mode rather than the effective mode.
This prevents the effective mode change from causing an infinite loop,
but does mean that we now always apply transforms to all layers of the
group even if the composite preview would work fine.
2025-08-15 06:03:13 +00:00
Alx Sa
aa9aa9e489 core, plug-ins: Fix bugs noted by Coverity scan
Fixes the following warnings from Coverity:
* file-paa.c: Casts "width" to guint32 to prevent overflow.
  Also, fix checks so that RGBA_8888 textures will be read.
* file-png.c: Free variables if APNG is not fully loaded
* file-seattle-filmworks.c: Verify fseek () doesn't exceed
  length of file
* file-tim.c: Casts "width" to guint32 to prevent overflow
* guillotine.c: Free "file" if image creation fails
* gimpitem.c: Initialize offset_x/y to 0 to remove warning
2025-08-15 03:38:27 +00:00
Bruno Lopes
f890c5ab68 build/windows: Rely on output (not on error code) on 'msix_trust' check 2025-08-14 22:46:34 -03:00
Bruno Lopes
9eee96328b build/linux: appimagetool now supports specifying .appimage path on .zsync
See: https://github.com/AppImage/appimagetool/pull/111
2025-08-14 21:44:15 -03:00
Jacob Boerema
634ebf97e7 plug-ins: fix overwriting sketchbook tiff group layer mode
in the tiff loader
Found with the coverity scan.
2025-08-14 18:58:03 -04:00
Bruno Lopes
79a92ce439 build/linux: Use $CRAFT_PART_INSTALL for libheif plugins detection on Snap
$CRAFT_STAGE was being used but that is wrong since nothing is staged yet.
$CRAFT_PART_INSTALL is the right place where the packages are available.
2025-08-14 19:32:22 -03:00
Bruno Lopes
eefc2bea1a build/linux: Drop org.gimp.*.HEIC in favor of org.freedesktop.*.codecs-extra
See: https://github.com/flathub/org.gimp.GIMP/issues/414
2025-08-14 19:32:19 -03:00
Bruno Lopes
f7cfd4ef39 gitlab-ci: Catch gimp-flatpak-builder.log artifact
Otherwise we don't know what happened in GIMP build. It
is too verbose to output on GitLab runner console due to
flatpak-builder awful messages about .debug stripping.
2025-08-14 19:25:02 -03:00
Bruno Lopes
0c1963ca7c build/linux: Only submit snaps to Snap Store on releases 2025-08-14 19:21:30 -03:00
Bruno Lopes
0868cf3cd3 build/linux: More fixes to the README 2025-08-14 16:21:24 -03:00
Bruno Lopes
bb26b9f81d build/linux: Fix some typos on Snap README 2025-08-14 16:19:15 -03:00
Bruno Lopes
052eb474cc build/linux: Add Snap maintenance README like Flatpak and MSIX
But, right now, the "## Stable and Development releases"
section is not applicable due to the pass over being WIP:
https://github.com/snapcrafters/gimp/issues/447
2025-08-14 16:16:17 -03:00
Jehan
abf026fc54 plug-ins: add a pygimp.interp on macOS too. 2025-08-14 17:28:34 +00:00
Bruno Lopes
9bf03bc8f6 build/windows: Bump MaxVersionTested on AppxManifest to 10.0.26100.0 (24H2)
I have been using the MSIX on that version since some time without problems.
2025-08-14 13:23:42 -03:00
Bruno Lopes
202ae26c80 build/windows: WinSDK package name on winget don't have the revision digit 2025-08-14 13:21:50 -03:00
Bruno Lopes
973ae3eef2 build/windows: On WinSDK not found message, recommend to install MaxVersionTested 2025-08-14 13:12:32 -03:00
Bruno Lopes
b04841d993 build/windows: Print error message when WinSDK is not found by MSIX script 2025-08-14 12:53:36 -03:00
Bruno Lopes
437ba0aa46 gitlab-ci: Remove redundancy on dist-flatpak-weekly rules 2025-08-14 11:58:19 -03:00
Michael Natterer
caa0df8e22 app: use GipmRow for the recent files on the welcome dialog. Enables
correct aspect ratios and popup previews, and removes lots of code.
2025-08-14 16:53:02 +02:00
Michael Natterer
5b765fc665 app: enable popup previews on GimpImagefile 2025-08-14 16:53:02 +02:00
Bruno Lopes
f5fa753dc2 gitlab-ci: Remove crossbuilds remnants on cppcheck 2025-08-14 11:30:57 -03:00
Bruno Lopes
d59c230560 gitlab-ci: Remove bogus cache: comment on deps-flatpak
For the same reason of 3e958583 this will not work.
And even if we manage to have it configured for
containers in the future, it would be slow like b51f2b52.
2025-08-14 11:02:26 -03:00
Bruno Lopes
3e9585839e gitlab-ci: Remove bogus cache: key on file-plug-in-tests
GNOME Infra does not enable local caching and
we don't have distributed/remote caching either.
2025-08-14 10:57:39 -03:00
Bruno Lopes
a6b09d8029 gitlab-ci: Do not pull whole repo on Snap job (since we don't use Launchpad)
Following: 5da4b890
2025-08-14 10:47:19 -03:00
Bruno Lopes
56a5dea720 gitlab-ci: Test reducing Snap builds timeout to 20min
Seems we not need more than that even in the deps stage.
2025-08-14 10:42:49 -03:00
Anders Jonsson
c3079a7ad4 Update Swedish translation 2025-08-14 12:48:46 +00:00
Aleksandr Prokudin
50e96b181f Update Russian translation 2025-08-14 14:09:55 +02:00
Alx Sa
c35abbe090 plug-ins: Fix signed JPEG 2000 import
Our JPEG 2000 plug-in assumed all imported images
are unsigned - however, it's possible to store signed data
as well.
This patch adds a check to see if the image has the `sgnd`
flag set to TRUE. If so, we offset the signed data to get it
into the unsigned range before converting to an image.
2025-08-14 05:27:26 +00:00
Alx Sa
6211ec8d2c plug-ins: Revert b98fe0c3
Resolves #14412
While b98fe0c3 resolved issue 10133,
it broke exporting text layers as text on
single layers, since they would be merged
beforehand. This patch reverts the change
until we find a solution that resolves both
problems.
2025-08-14 05:00:09 +00:00
Bruno Lopes
1730c62187 build/windows: Add comment inside *_sym.py script explaning its situation
While it is already explained on meson.build, it is desirable to
explain inside the script too in the case someone browse the files.
2025-08-13 22:16:03 -03:00
Bruno Lopes
ff157df094 build/windows: Reorder Win bundling script to be consistent with AppImage
The AppImage script organization is way more clear to understand what is
needed to make a GIMP bundle so let's reproduce here with adaptations.
2025-08-13 22:13:42 -03:00
Bruno Lopes
03172b7196 build/windows: Put (not used) Lua below Python on bundling script 2025-08-13 22:13:38 -03:00
Anders Jonsson
e5260cd60f Update Swedish translation 2025-08-14 00:59:54 +00:00
Bruno Lopes
56838c1194 build/windows: Remove random empty line on Win bundling script 2025-08-13 20:25:53 -03:00
Jehan
841b5ddfb9 AUTHORS: update. 2025-08-14 01:15:04 +02:00
Jehan
0d50753cca Revert (partly) "app, pdb, libgimp: use "#pragma once" instead of:"
This reverts commit 246f9d284f.

This only reverts the part modifying libgimp* headers. All the part
switching to #pragma once in app/ was kept. See #14668.
2025-08-14 00:59:16 +02:00
Jehan
6cc054ee4e Revert "pdb, libgimp: more #pragma once, and formatting cleanup"
This reverts commit be3597e3c7.

See https://gitlab.gnome.org/GNOME/gimp/-/issues/14668
2025-08-14 00:54:55 +02:00
Jehan
bbb0be8413 Revert "libgimpwidgets: #pragma once, and formatting and ordering"
This reverts commit c71661bf24.

See https://gitlab.gnome.org/GNOME/gimp/-/issues/14668
2025-08-14 00:54:52 +02:00
Jehan
92c096d699 Revert "libgimpmath: #pragma once"
This reverts commit 74bf171611.

See https://gitlab.gnome.org/GNOME/gimp/-/issues/14668
2025-08-14 00:54:50 +02:00
Jehan
9308de3137 Revert "libgimpconfig: #pragma once, and some formatting"
This reverts commit 47a8ab5a66.

See https://gitlab.gnome.org/GNOME/gimp/-/issues/14668
2025-08-14 00:54:28 +02:00
Jehan
946a362d9b Revert "libgimpbase: #pragma once"
This reverts commit 06cd254954.

GObject Introspection tools somehow fail to introspect some macros in a
very bizarre way. See issue #14668.

I thought #pragma once was somewhat standard, but it turns out it's not.
And Wikipedia even stays about this:

> While #pragma once is available in most modern compilers, its
> implementation is tricky and might not always be reliable.

Anyway clearly it's not reliable at least regarding GIR tools. I believe
we should hold up on using #pragma once at the very least within our
libgimp* libraries. It is probably fine for app/ or plug-ins/ where we
don't need to introspect anything (and so far we haven't had any
compilation mishap because of this preprocessing directive).
2025-08-14 00:03:26 +02:00
Jehan
decc8dec6c desktop: prepare AppStream metadata for GIMP 3.1.4. 2025-08-13 19:41:32 +02:00
Jehan
048c86ffcf app: properly escape characters which need to be.
This fixes handling of text with for instance an ampersand (as in the
next AppStream release note listing).
2025-08-13 19:41:32 +02:00
Jehan
8470ec8b10 libgimpbase: add a #warning to be activated when we move on to GIMP 4.
The name GIMP_METADATA_SAVE_UPDATE does feel a bit ugly but we need to
keep the GIMP_METADATA_SAVE_ prefix, otherwise we would break the GIR
bindings. cf. commit 27fead082a.

Make a warning for ourselves to happen when we are closing onto GIMP 4.
Then we can make a decision whether or not we want to rename this enum
value.
2025-08-13 19:41:32 +02:00
Jehan
f35cc4693c NEWS: update. 2025-08-13 19:41:32 +02:00
Bruno Lopes
632cbd9ed3 build/windows: Drop 'replacesameversion' in favor of 'ignoreversion' on Inno 6.5.0
They are now mutually exclusive.
2025-08-13 13:32:51 -03:00
Bruno Lopes
5b97d96349 build/windows: From Inno 6.5.0, 'is' (Icelandic) language is unofficial 2025-08-13 13:32:48 -03:00
Bruno Lopes
b24fc1b74b build/windows: Go back to latest Inno since the Task Dialog is fixed on 6.5.0
Reverts: 8a6a6516

See: 9e493a15d9/whatsnew.htm (L243)
2025-08-13 13:31:54 -03:00
Bruno Lopes
ebec92aec7 build/windows: Add comment about purpose of each list in all-deps-uni.txt 2025-08-13 08:23:45 -03:00
Jordi Mas
861e406393 Update Catalan translation 2025-08-13 08:14:40 +02:00
Gabriele Barbero
b65bd2bd4c widgets: ignore GDK_MOD2_MASK when...
...remapping shortcuts with GDK_META_MASK

On macOS, the Command key is GDK_META_MASK. But when setting a shortcut,
GDK_MOD2_MASK is added too. This extra modifier makes it hard to check
if the shortcut is already in use. GIMP sees it as a different combination,
even if it's really the same. Now, when GDK_META_MASK is used, we remove
GDK_MOD2_MASK. This helps GIMP detect existing shortcuts correctly
and avoid duplicates.
2025-08-13 03:22:57 +00:00
Bruno Lopes
2e12de6747 build/linux: Change collapsible section ID to the more technical '*_submission'
We already use '*_submission' on the MSIX script.

Submission is the first act, the one which we trigger on CI.
The publishing is done by the store (Flathub or Snap Store).
2025-08-12 22:38:49 -03:00
Michael Natterer
9f789e68d5 app, tools, plug-ins: more #pragma once, and formatting cleanup where
I noticed the need.
2025-08-13 01:48:40 +02:00
Jordi Mas
6124b56b3e Update Catalan translation 2025-08-12 23:29:41 +02:00
Bruno Lopes
839064a6c6 build, gitlab-ci: Drop last ccache shenanigans
Let's prioritize reproducibility over small performance gains,
specially when we have too many packages do deal with.
2025-08-12 16:33:32 -03:00
Bruno Lopes
56cc7e363b build/linux, gitlab-ci: Change .flatpak-builder artifact naming to be more consistent 2025-08-12 16:25:31 -03:00
Bruno Lopes
aee3bd23d6 build/linux: Restore comment of '--destructive-mode'/host mode on Snap script
It was on the env section before the remote-build drop. Let's restore it and
move to the build section which is more appropriate.
2025-08-12 16:07:16 -03:00
Gabriele Barbero
c3d01854b3 dialogs: use core actions for opening images and new files
This commit changes the welcome dialog to use core actions for opening
images and new file. This allows to avoid code duplication.
2025-08-12 18:03:54 +00:00
Gabriele Barbero
d932d02fbe dialogs: implement shortcuts in the Welcome Dialog
This commit adds support for activating user-defined keyboard shortcuts in the Welcome Dialog to:
- Create a new file
- Open a file
- Open one of the 10 most recent files
2025-08-12 18:03:54 +00:00
Kolbjørn Stuestøl
4255227fff Update Norwegian Nynorsk translation 2025-08-12 16:01:37 +00:00
Bruno Lopes
a87ee3c241 build/linux: Add check to ensure we use the right 'snapcraft-rocks' image
If the container image don't have the base snap required by
snapcraft.yaml, it will naturally fail.
2025-08-12 12:21:40 -03:00
Michael Natterer
124993d770 app: GimpRow: don't ref the viewable, use a weak ref instead. 2025-08-12 15:45:16 +02:00
Michael Natterer
ff9a14b7d0 app: fix gimp_viewable_has_preview() to look at both the get_preview()
*and* get_pixbuf() methods. Fixes #14657.
2025-08-12 15:01:39 +02:00
Michael Natterer
f96a7192cd app: add GimpRowFilter and GimpRowDrawableFilter and port the filters
popover to GimpContainerListView.
2025-08-12 11:58:29 +02:00
Bruno Lopes
d4aac4a3e5 build/linux: Rework deps installation message on Snap script
The new text is more alike to the flatpak one, which
should make easier to understand both scripts.
2025-08-11 22:20:51 -03:00
Bruno Lopes
5da4b89002 build/linux: Make Snap on GNOME runners (not on Launchpad)
Now can make snaps 3x faster on CI without snapcraft remote-build.
2025-08-11 22:13:23 -03:00
Bruno Lopes
b960be9735 build/linux: Remove redundant plugs: in favor of 'gnome' Snap extension
See: https://documentation.ubuntu.com/snapcraft/stable/reference/extensions/gnome-extension/
2025-08-11 13:11:45 -03:00
Michael Natterer
2d57b1764d app: GimpRowSettings: forgot to remove some junk. 2025-08-11 16:39:30 +02:00
Michael Natterer
6651d4eb7f app: GimpRow's icon always exists, no need for if (priv->icon). 2025-08-11 16:23:54 +02:00
Michael Natterer
795cf081cc app: use a GimpContainerListView in the layer options dialog. 2025-08-11 16:09:35 +02:00
Michael Natterer
7fad4ad323 app: remove some #if 0'ed junk from GimpContainerListView, but leave
some there as a reminder.
2025-08-11 14:47:18 +02:00
Michael Natterer
9e2b378414 app: remove unused member from struct GimpContainerIconView 2025-08-11 14:41:23 +02:00
Michael Natterer
92e68453df app: set the container last in all GimpContainerView constructors, to
avoid traversing the just-filled view when "context" or "view-size"
changes.
2025-08-11 14:38:02 +02:00
Michael Natterer
c114e96096 app: gimp_container_view_set_container(): standardize a g_return_if_fail() 2025-08-11 14:37:25 +02:00
Michael Natterer
b4e27fbf83 app: create GimpRow with the view size of its GimpContainerView 2025-08-11 12:13:58 +02:00
Michael Natterer
33dfccde51 app: add GimpRowSeparator and GimpRowSettings and port
GimpSettingsEditor to GimpContainerListView.

The separator currently doesn't draw anything, maybe it needs some
CSS.
2025-08-11 12:07:11 +02:00
Michael Natterer
2f87f8e51e app: GimpRowDeviceInfo: add missing dot in comment 2025-08-11 12:06:00 +02:00
Gabriele Barbero
6574f6ff30 display: avoid critical on master devices
When the device is of type GDK_DEVICE_TYPE_MASTER, calling
gdk_device_get_vendor_id() and gdk_device_get_product_id() fails and
triggers a CRITICAL warning. This commit avoids invoking these functions
on master devices, where failure is guaranteed.
See #14219
2025-08-11 09:55:17 +02:00
Cristian Secară
92150e07ba Update Romanian translation 2025-08-10 19:23:19 +00:00
Cristian Secară
37ff61d0ac Update Romanian translation 2025-08-10 19:10:22 +00:00
Cristian Secară
d0d4c769e3 Update Romanian translation 2025-08-10 18:57:29 +00:00
Cristian Secară
aa0a25d82a Update Romanian translation 2025-08-10 18:44:49 +00:00
Cristian Secară
cb13ce0da3 Update Romanian translation 2025-08-10 17:45:05 +00:00
Yuri Chornoivan
f520df6f4a Update Ukrainian translation 2025-08-10 14:25:42 +00:00
Alx Sa
3a2d9c477e core: Set alpha value for image palette imports
Resolves #14649
After the Color Space Invasion, we retrieve the color format
from the palette when creating palettes from images. However,
gimp_palette_import_create_image_palette () still only receives
RGB values. Thus, the palette can store RGBA values without the
alpha, thus defaulting it to a random alpha value. This can cause
issues when using the palette to make a gradient or other instances
where the alpha value is reintroduced.
This patch checks if the format has an alpha channel, and if so, sets
the alpha to 255. Future work can be done to make the image palette
conversion less RGB-specific.
2025-08-10 13:58:25 +00:00
Cristian Secară
261f407008 Update Romanian translation 2025-08-10 13:53:12 +00:00
Cristian Secară
d9b9a7f8bd Update Romanian translation 2025-08-10 13:48:38 +00:00
Cristian Secară
4514e61fd1 Update Romanian translation 2025-08-10 13:33:35 +00:00
Luming Zh
e3b58d5180 Update Chinese (China) translation 2025-08-10 11:16:42 +00:00
Luming Zh
67dcac45ef Update Chinese (China) translation 2025-08-10 11:11:07 +00:00
941 changed files with 130194 additions and 99581 deletions

View File

@@ -13,7 +13,7 @@ spec:
test_pipeline:
description: 'Pipelines used only for testing'
options:
- GIMP_CI_MESON_GCC #trigger the Debian GCC build (rare usefulness)
- GIMP_CI_MESON_CLANG #trigger the Debian Clang build (rare usefulness)
- GIMP_CI_RASTER_ICONS #trigger the Debian Clang build without vector icons (rare usefulness)
- GIMP_CI_CPPCHECK #trigger cppcheck (static code analysis)
- none
@@ -30,7 +30,8 @@ workflow:
##################################################
## 1. On MERGE REQUESTS, the following are triggered:
## - Abbreviated Linux Clang build (base & fast)
## - Abbreviated Linux build
## - Building quality tests (static code analysis)
## - clang-format (static code analysis)
## - Execution tests (dynamic code analysis)
.pipeline_merge: &CI_MERGE
@@ -43,20 +44,22 @@ workflow:
# GitLab is quite sensitive about rules 'if' order so be careful
## 3. On COMMITS except tags.
## - Linux Clang build (base & fast)
## - Linux build
## - Building quality tests (static code analysis)
## - Execution tests (dynamic code analysis)
## - Source tarball (base & fast)
## - Developer documentation (base & fast)
## - Source tarball
## - Developer documentation
.pipeline_commit: &CI_COMMIT
if: '$CI_PIPELINE_SOURCE == "push" && $CI_OPEN_MERGE_REQUESTS == null && $CI_COMMIT_TAG == null'
interruptible: true
variables: {}
## 4. RELEASES.
## - Source tarball (base & fast)
## - Developer documentation (base & fast)
## - Inno Windows installer (base but slow)
## - MS Store .msixupload (base but slow)
## - Source tarball
## - Developer documentation
## - Linux .appimage
## - Inno Windows installer
## - MS Store .msixupload
.pipeline_release: &CI_RELEASE
if: '$CI_COMMIT_TAG != null'
interruptible: false
@@ -77,10 +80,12 @@ workflow:
- 'runner_system_failure'
- 'scheduler_failure'
needs: []
# Default Docker image (unless otherwise defined)
image: debian:${DEB_VERSION}
# Default Docker image (keep variables: DEB_VERSION: consistent with devel-docs/os-support.txt)
image: $CI_REGISTRY_IMAGE:build-debian-${DEB_VERSION}-${RUNNER}
variables:
DEB_VERSION: "bookworm"
UMFPACK: libumfpack5
RUNNER: "x86_64_v3"
# Common cloning procedure
GIT_DEPTH: "1"
GIT_SUBMODULE_STRATEGY: none
@@ -98,28 +103,30 @@ stages:
- analysis
- distribution
## AppImage CI (Debian) ##
.debian:
## Common GNU/Linux 64-bit CI (Debian) ##
.debian-nonreloc:
extends: .default
rules:
- if: '$CI_MERGE_REQUEST_LABELS =~ /.*Package:AppImage.*/'
interruptible: true
- if: '$GIMP_CI_APPIMAGE != null || "$[[ inputs.distribution_pipeline ]]" =~ /.*GIMP_CI_APPIMAGE.*/'
- <<: *CI_MERGE
- <<: *CI_COMMIT
variables: {}
- if: '$GIMP_CI_MESON_CLANG != null || "$[[ inputs.test_pipeline ]]" =~ /.*GIMP_CI_MESON_CLANG.*/'
variables:
CC: clang
CXX: clang++
CC_LD: lld
CXX_LD: lld
TOOLCHAIN: "clang lld"
VARIANT: -clang
- if: '$GIMP_CI_RASTER_ICONS != null || "$[[ inputs.test_pipeline ]]" =~ /.*GIMP_CI_RASTER_ICONS.*/'
variables:
MESON_OPTIONS: "-Dvector-icons=false"
VARIANT: "-raster"
- <<: *CI_RELEASE
parallel:
matrix:
- RUNNER: [aarch64, x86_64_v3]
tags:
- $RUNNER
image: $CI_REGISTRY_IMAGE:build-debian-${DEB_VERSION}-${RUNNER}
variables:
CC: "clang"
CXX: "clang++"
CC_LD: lld
CXX_LD: lld
before_script:
- export GIMP_PREFIX="${CI_PROJECT_DIR}/_install-${RUNNER}"
timeout: 20m
timeout: 30m
.debian_environ: &ENVIRON
# See: https://testing.developer.gimp.org/core/setup/build/#preparing-for-building
@@ -135,39 +142,34 @@ stages:
- export GI_TYPELIB_PATH="${GIMP_PREFIX}/${LIB_DIR}/${LIB_SUBDIR}girepository-1.0${GI_TYPELIB_PATH:+:$GI_TYPELIB_PATH}"
- printf "\e[0Ksection_end:`date +%s`:environ\r\e[0K\n"
deps-debian:
extends: .debian
deps-debian-nonreloc:
extends: .debian-nonreloc
stage: dependencies
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
image: quay.io/buildah/stable
variables:
GIT_STRATEGY: none
UMFPACK: libumfpack5
PKGCONF_RELOCATABLE_OPTION: '-Dpkgconfig.relocatable=true'
script:
- export container=docker
- mkdir -p /kaniko/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
- export BUILDAH_FORMAT=docker
- export STORAGE_DRIVER=vfs
- echo "$CI_REGISTRY_PASSWORD" | buildah login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
# Install deps
- echo "FROM debian:${DEB_VERSION}" > Dockerfile
- echo "WORKDIR $CI_PROJECT_DIR" >> Dockerfile
- echo "RUN printf \"\e[0Ksection_start:0000000001:deps_install[collapsed=true]\r\e[0KInstalling dependencies provided by Debian $DEB_VERSION\n\"" >> Dockerfile
- echo "RUN apt-get update -qq" >> Dockerfile
## 'ca-certificates' is NOT a gimp dep, it is installed only to our Docker image work
- echo "RUN apt-get install -qq -y --no-install-recommends ca-certificates" >> Dockerfile
## Build-time only dependencies
- echo "RUN apt-get install -qq -y --no-install-recommends \\" >> Dockerfile
- echo "appstream
- echo "${TOOLCHAIN:-build-essential}
appstream
bison
ccache
clang
desktop-file-utils
flex
gi-docgen
git
gobject-introspection
libgtk-3-bin
lld
meson
valac
xsltproc" >> Dockerfile
@@ -180,6 +182,7 @@ deps-debian:
glib-networking
graphviz
graphviz-dev
gvfs
iso-codes
libaa1-dev
libappstream-dev
@@ -193,6 +196,7 @@ deps-debian:
libgtk-3-dev
libgudev-1.0-dev
libheif-dev
$LIBHEIF_PLUGINS
libjson-glib-dev
libjxl-dev
liblcms2-dev
@@ -223,33 +227,34 @@ deps-debian:
# Prepare environ
- echo "FROM $CI_REGISTRY_IMAGE:build-debian-${DEB_VERSION}-${RUNNER}" > Dockerfile2;
- echo "RUN printf \"\e[0Ksection_start:`date +%s`:environ[collapsed=true]\r\e[0KPreparing build environment\n\"" >> Dockerfile2;
- export LIB_DIR="lib";
- export LIB_SUBDIR=$([ "$(uname -m)" = 'aarch64' ] && echo "aarch64-linux-gnu/" || echo "x86_64-linux-gnu/");
- echo "ENV PKG_CONFIG_PATH=\"${GIMP_PREFIX}/${LIB_DIR}/${LIB_SUBDIR}pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}\"" >> Dockerfile2;
- echo "ENV PKG_CONFIG_PATH=\"${GIMP_PREFIX}/lib/$([ "$(uname -m)" = 'aarch64' ] && echo "aarch64-linux-gnu/" || echo "x86_64-linux-gnu/")pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}\"" >> Dockerfile2;
- echo "ENV XDG_DATA_DIRS=\"${GIMP_PREFIX}/share:/usr/share${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}\"" >> Dockerfile2;
- echo "ENV CC=\"$CC\"" >> Dockerfile2;
- echo "ENV CXX=\"$CXX\"" >> Dockerfile2;
- echo "ENV CC_LD=\"$CC_LD\"" >> Dockerfile2;
- echo "ENV CXX_LD=\"$CXX_LD\"" >> Dockerfile2;
- if [ "$VARIANT" = "-clang" ]; then
echo "ENV CC=\"$CC\"" >> Dockerfile2;
echo "ENV CXX=\"$CXX\"" >> Dockerfile2;
echo "ENV CC_LD=\"$CC_LD\"" >> Dockerfile2;
echo "ENV CXX_LD=\"$CXX_LD\"" >> Dockerfile2;
fi
- echo "ENV CLICOLOR_FORCE=\"1\"" >> Dockerfile2;
- echo "RUN printf \"\e[0Ksection_end:`date +%s`:environ\r\e[0K\n\"" >> Dockerfile2;
# Build some dependencies
## Build babl
- echo "RUN printf \"\e[0Ksection_start:`date +%s`:babl_build[collapsed=true]\r\e[0KBuilding babl\n\"" >> Dockerfile2;
- echo "RUN git clone --branch \"\$([ \"$CI_COMMIT_TAG\" ] && echo \"\$(git ls-remote --tags --exit-code --refs https://gitlab.gnome.org/GNOME/babl.git | grep -oi \"BABL_[0-9]*_[0-9]*_[0-9]*\" | sort --version-sort | tail -1)\" || echo \"master\")\" --depth=${GIT_DEPTH} https://gitlab.gnome.org/GNOME/babl.git" $CI_PROJECT_DIR/babl >> Dockerfile2;
- echo "RUN meson setup $CI_PROJECT_DIR/babl/_build-${RUNNER} $CI_PROJECT_DIR/babl -Dprefix=\"${GIMP_PREFIX}\" $PKGCONF_RELOCATABLE_OPTION" >> Dockerfile2;
- echo "RUN ninja -C $CI_PROJECT_DIR/babl/_build-${RUNNER}" >> Dockerfile2;
- echo "RUN ninja -C $CI_PROJECT_DIR/babl/_build-${RUNNER} install" >> Dockerfile2;
- echo "RUN git clone --branch \"\$([ \"$CI_COMMIT_TAG\" ] && echo \"\$(git ls-remote --tags --exit-code --refs https://gitlab.gnome.org/GNOME/babl.git | grep -oi \"BABL_[0-9]*_[0-9]*_[0-9]*\" | sort --version-sort | tail -1)\" || echo \"master\")\" --depth=${GIT_DEPTH} https://gitlab.gnome.org/GNOME/babl.git" babl >> Dockerfile2;
- echo "RUN meson setup babl/_build-${RUNNER} babl -Dprefix=\"${GIMP_PREFIX}\" $PKGCONF_RELOCATABLE_OPTION" >> Dockerfile2;
- echo "RUN ninja -C babl/_build-${RUNNER}" >> Dockerfile2;
- echo "RUN ninja -C babl/_build-${RUNNER} install" >> Dockerfile2;
- echo "RUN printf \"\e[0Ksection_end:`date +%s`:babl_build\r\e[0K\n\"" >> Dockerfile2;
## Build GEGL
- echo "RUN printf \"\e[0Ksection_start:`date +%s`:gegl_build[collapsed=true]\r\e[0KBuilding gegl\n\"" >> Dockerfile2;
- echo "RUN git clone --branch \"\$([ \"$CI_COMMIT_TAG\" ] && echo \"\$(git ls-remote --tags --exit-code --refs https://gitlab.gnome.org/GNOME/gegl.git | grep -oi \"GEGL_[0-9]*_[0-9]*_[0-9]*\" | sort --version-sort | tail -1)\" || echo \"master\")\" --depth=${GIT_DEPTH} https://gitlab.gnome.org/GNOME/gegl.git" $CI_PROJECT_DIR/gegl >> Dockerfile2;
- echo "RUN meson setup $CI_PROJECT_DIR/gegl/_build-${RUNNER} $CI_PROJECT_DIR/gegl -Dprefix=\"${GIMP_PREFIX}\" $PKGCONF_RELOCATABLE_OPTION $WORKSHOP_OPTION" >> Dockerfile2;
- echo "RUN ninja -C $CI_PROJECT_DIR/gegl/_build-${RUNNER}" >> Dockerfile2;
- echo "RUN ninja -C $CI_PROJECT_DIR/gegl/_build-${RUNNER} install" >> Dockerfile2;
- echo "RUN git clone --branch \"\$([ \"$CI_COMMIT_TAG\" ] && echo \"\$(git ls-remote --tags --exit-code --refs https://gitlab.gnome.org/GNOME/gegl.git | grep -oi \"GEGL_[0-9]*_[0-9]*_[0-9]*\" | sort --version-sort | tail -1)\" || echo \"master\")\" --depth=${GIT_DEPTH} https://gitlab.gnome.org/GNOME/gegl.git" gegl >> Dockerfile2;
- echo "RUN meson setup gegl/_build-${RUNNER} gegl -Dprefix=\"${GIMP_PREFIX}\" $PKGCONF_RELOCATABLE_OPTION -Dworkshop=true" >> Dockerfile2;
- echo "RUN ninja -C gegl/_build-${RUNNER}" >> Dockerfile2;
- echo "RUN ninja -C gegl/_build-${RUNNER} install" >> Dockerfile2;
- echo "RUN printf \"\e[0Ksection_end:`date +%s`:gegl_build\r\e[0K\n\"" >> Dockerfile2;
- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:build-debian-${DEB_VERSION}-${RUNNER} --cache=true --cache-ttl=120h --image-fs-extract-retry 1 --verbosity=warn
- if [ -f 'Dockerfile2' ]; then /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile2 --destination build-debian-${DEB_VERSION}-${RUNNER}-temp --cache=false --no-push --verbosity=warn; fi
#FIXME: '2>&1 | grep -v STEP' since buildah is too verbose. See: https://github.com/containers/buildah/issues/6362
- buildah build --log-level error --volume $CI_PROJECT_DIR:$CI_PROJECT_DIR:Z --file $CI_PROJECT_DIR/Dockerfile --tag $CI_REGISTRY_IMAGE:build-debian-${DEB_VERSION}-${RUNNER} --layers --cache-from $CI_REGISTRY_IMAGE/cache --cache-to $CI_REGISTRY_IMAGE/cache --cache-ttl=120h 2>&1 | grep -v STEP && buildah push --log-level error $CI_REGISTRY_IMAGE:build-debian-${DEB_VERSION}-${RUNNER} 2>&1 | grep -v STEP
- buildah build --log-level error --volume $CI_PROJECT_DIR:$CI_PROJECT_DIR:Z --file $CI_PROJECT_DIR/Dockerfile2 --no-cache 2>&1 | grep -v STEP
artifacts:
paths:
- _install-${RUNNER}/
@@ -259,81 +264,12 @@ deps-debian:
- gegl/_build-${RUNNER}/config.h
expire_in: 2 hours
gimp-debian:
extends: .debian
needs: ["deps-debian"]
gimp-debian-nonreloc:
extends: .debian-nonreloc
needs: ["deps-debian-nonreloc"]
stage: build
variables:
GIT_SUBMODULE_STRATEGY: recursive
script:
- *ENVIRON
# Build GIMP
- printf "\e[0Ksection_start:`date +%s`:gimp_build[collapsed=true]\r\e[0KBuilding GIMP\n"
- meson setup _build-${RUNNER} -Dprefix="${GIMP_PREFIX}"
-Dpkgconfig.relocatable=true
-Drelocatable-bundle=yes
-Dcheck-update=yes
-Dbuild-id=org.gimp.GIMP_official.AppImage.$(uname -m)
- cd _build-${RUNNER}
- ninja
- printf "\e[0Ksection_end:`date +%s`:gimp_build\r\e[0K\n"
# Create bundle
- printf "\e[0Ksection_start:`date +%s`:gimp_bundle[collapsed=true]\r\e[0KCreating bundle\n"
- ninja install > ninja_install.log 2>&1 || { cat ninja_install.log; exit 1; }
- cd ..
- sh build/linux/appimage/3_dist-gimp-goappimage.sh --bundle-only > goappimage.log 2>&1 || { cat goappimage.log; exit 1; }
- printf "\e[0Ksection_end:`date +%s`:gimp_bundle\r\e[0K\n"
artifacts:
paths:
- AppDir*/
- appimageignore*
- _build-${RUNNER}/meson-logs/meson-log.txt
- _build-${RUNNER}/config.h
expire_in: 2 days
## GNU/Linux 64-bit CIs (Debian) ##
.debian-x64:
extends: .debian
rules:
- <<: *CI_MERGE
- <<: *CI_COMMIT
- if: '$GIMP_CI_MESON_CLANG != null'
variables: {}
- if: '$GIMP_CI_MESON_GCC != null || "$[[ inputs.test_pipeline ]]" =~ /.*GIMP_CI_MESON_GCC.*/'
variables:
CC: "cc"
CXX: "c++"
CC_LD: bfd
CXX_LD: bfd
VARIANT: "-gcc"
- if: '$GIMP_CI_RASTER_ICONS != null || "$[[ inputs.test_pipeline ]]" =~ /.*GIMP_CI_RASTER_ICONS.*/'
variables:
MESON_OPTIONS: "-Dvector-icons=false"
VARIANT: "-raster"
- if: '$GIMP_CI_SOURCES != null'
- <<: *CI_RELEASE
parallel:
matrix:
- RUNNER: x86_64_v3
tags: []
deps-debian-x64:
extends: .debian-x64
stage: !reference [deps-debian, stage]
image: !reference [deps-debian, image]
variables:
GIT_STRATEGY: none
WORKSHOP_OPTION: '-Dworkshop=true'
script:
- !reference [deps-debian, script]
artifacts: !reference [deps-debian, artifacts]
gimp-debian-x64:
extends: .debian-x64
needs: ["deps-debian-x64"]
stage: !reference [gimp-debian, stage]
variables: !reference [gimp-debian, variables]
script:
- *ENVIRON
# Check building
@@ -355,7 +291,7 @@ gimp-debian-x64:
git diff;
exit 1;
fi
- if [ "$VARIANT" != "-gcc" ] && [ "$VARIANT" != "-raster" ] && [ "$CI_PIPELINE_SOURCE" != "merge_request_event" ]; then
- if [ "$VARIANT" != "-clang" ] && [ "$VARIANT" != "-raster" ] && [ "$CI_PIPELINE_SOURCE" != "merge_request_event" ]; then
ninja dist > ninja_dist.log 2>&1 || { cat ninja_dist.log; exit 1; };
fi
- printf "\e[0Ksection_end:`date +%s`:gimp_tar\r\e[0K\n"
@@ -374,6 +310,71 @@ gimp-debian-x64:
expire_in: 2 days
## AppImage CI (Debian) ##
.debian:
extends: .debian-nonreloc
rules:
- if: '$CI_MERGE_REQUEST_LABELS =~ /.*Package:AppImage.*/'
interruptible: true
- if: '$GIMP_CI_APPIMAGE != null || "$[[ inputs.distribution_pipeline ]]" =~ /.*GIMP_CI_APPIMAGE.*/'
- <<: *CI_RELEASE
parallel:
matrix:
- RUNNER: [aarch64, x86_64_v3]
tags:
- $RUNNER
variables:
#FIXME: remove this variables: key and go back to relying on .default DEB_VERSION on GIMP 3.3/3.4
DEB_VERSION: "trixie"
UMFPACK: libumfpack6
LIBHEIF_PLUGINS: "libheif-plugin-dav1d libheif-plugin-aomenc libheif-plugin-libde265 libheif-plugin-x265 libheif-plugin-j2kdec libheif-plugin-j2kenc"
deps-debian:
extends: .debian
stage: !reference [deps-debian-nonreloc, stage]
image: !reference [deps-debian-nonreloc, image]
variables:
GIT_STRATEGY: none
PKGCONF_RELOCATABLE_OPTION: '-Dpkgconfig.relocatable=true'
script:
- !reference [deps-debian-nonreloc, script]
artifacts: !reference [deps-debian-nonreloc, artifacts]
gimp-debian:
extends: .debian
needs: ["deps-debian"]
stage: !reference [gimp-debian-nonreloc, stage]
variables:
#FIXME: remove this variables: key and go back to relying on gimp-debian-nonreloc variables: on GIMP 3.3/3.4
GIT_SUBMODULE_STRATEGY: recursive
script:
- *ENVIRON
# Build GIMP
- printf "\e[0Ksection_start:`date +%s`:gimp_build[collapsed=true]\r\e[0KBuilding GIMP\n"
- meson setup _build-${RUNNER} -Dprefix="${GIMP_PREFIX}"
-Dgi-docgen=disabled
-Dpkgconfig.relocatable=true
-Drelocatable-bundle=yes
-Dcheck-update=yes
-Dbuild-id=org.gimp.GIMP_official.AppImage.$(uname -m)
- cd _build-${RUNNER}
- ninja
- printf "\e[0Ksection_end:`date +%s`:gimp_build\r\e[0K\n"
# Create bundle
- printf "\e[0Ksection_start:`date +%s`:gimp_bundle[collapsed=true]\r\e[0KCreating bundle\n"
- ninja install > ninja_install.log 2>&1 || { cat ninja_install.log; exit 1; }
- cd ..
- sh build/linux/appimage/3_dist-gimp-goappimage.sh --bundle-only > goappimage.log 2>&1 || { cat goappimage.log; exit 1; }
- printf "\e[0Ksection_end:`date +%s`:gimp_bundle\r\e[0K\n"
artifacts:
paths:
- AppDir*/
- appimageignore*
- _build-${RUNNER}/meson-logs/meson-log.txt
- _build-${RUNNER}/config.h
expire_in: 2 days
## Flatpak CI (Fedora) ##
.flatpak:
extends: .default
@@ -394,22 +395,17 @@ gimp-debian-x64:
MESON_DIST: 0
before_script:
- export GIMP_PREFIX="${CI_PROJECT_DIR}/_install"
#30min is enough only if no module was updated/rebuilt, we need more time in case of module bumps
timeout: 90m
deps-flatpak:
extends: .flatpak
stage: dependencies
#https://gitlab.gnome.org/Infrastructure/Infrastructure/-/issues/1502
#cache:
#key: ${CI_JOB_NAME_SLUG}
#paths:
#- .flatpak-builder/
script:
- sh build/linux/flatpak/1_build-deps-flatpakbuilder.sh
artifacts:
paths:
- .flatpak-builder-$RUNNER.tar
- flatpak-builder.log
- _build-$RUNNER.tar.zst
- babl-meson-log.tar
- gegl-meson-log.tar
expire_in: 2 hours
@@ -426,6 +422,7 @@ gimp-flatpak:
paths:
- temp*.flatpak
- repo*.tar
- gimp-flatpak-builder.log
- gimp-meson-log.tar
expire_in: 2 days
@@ -439,43 +436,63 @@ gimp-flatpak:
- if: '$GIMP_CI_SNAP != null || "$[[ inputs.distribution_pipeline ]]" =~ /.*GIMP_CI_SNAP.*/'
parallel:
matrix:
- DPKG_ARCH: [arm64, amd64]
- RUNNER: [aarch64, x86_64_v3]
tags:
- x86_64_v2
image:
name: $CI_REGISTRY_IMAGE:build-snap-${SNAPCRAFT_CORE_VERSION}
entrypoint: [""]
- $RUNNER
image: $CI_REGISTRY_IMAGE:build-snap-${SNAPCRAFT_BASE_VERSION}-${RUNNER}
variables:
SNAPCRAFT_CORE_VERSION: "8_core24"
#@brunvonlope private credentials. We are using these for now
#until we don't get acess to 'gimp' entry on Snap Store: https://github.com/snapcrafters/gimp/issues/447
LAUNCHPAD_CREDENTIALS_ACCESS_TOKEN: pPs367Km5glpfXXK9BQl
LAUNCHPAD_CREDENTIALS_ACCESS_SECRET: PQ0r1JGdHQRWQCS255jNZdglCcK4KDmsGRSZxl4CZwWvMF00GLRFbz1185L08cjh5zWqhQddsvmgLg7l
timeout: 120m
SNAPCRAFT_BASE_VERSION: "8_core24"
RUNNER: x86_64_v3
timeout: 30m
deps-snap:
extends: .snap
stage: dependencies
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
image: quay.io/buildah/stable
script:
- sh build/linux/snap/1_build-deps-snapcraft.sh
- export BUILDAH_FORMAT=docker
- export STORAGE_DRIVER=vfs
- echo "$CI_REGISTRY_PASSWORD" | buildah login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
# Install deps
- echo "FROM ghcr.io/canonical/snapcraft:${SNAPCRAFT_BASE_VERSION}" > Dockerfile
- echo "ENTRYPOINT [\"\"]" >> Dockerfile
- echo "WORKDIR $CI_PROJECT_DIR" >> Dockerfile
- echo "ENV GITLAB_CI=1" >> Dockerfile
- echo "ENV RUNNER=$RUNNER" >> Dockerfile
- echo "RUN apt-get update -y" >> Dockerfile
- echo "RUN apt-get install -y curl jq squashfs-tools sudo" >> Dockerfile
# https://github.com/canonical/snapcraft-rocks/issues/37
- echo "RUN cp -r /usr/lib/python3.*/site-packages/extensions/* /usr/share/snapcraft/extensions/" >> Dockerfile
# https://github.com/canonical/snapcraft-rocks/issues/33
- echo "RUN ln -s /usr/libexec/snapcraft/craftctl /usr/bin/craftctl" >> Dockerfile
- echo "RUN sh build/linux/snap/1_build-deps-snapcraft.sh --install-snaps" >> Dockerfile;
# Build babl and GEGL
- echo "FROM $CI_REGISTRY_IMAGE:build-snap-${SNAPCRAFT_BASE_VERSION}-${RUNNER}" > Dockerfile2;
- echo "RUN sh build/linux/snap/1_build-deps-snapcraft.sh" >> Dockerfile2;
#FIXME: '2>&1 | grep -v STEP' since buildah is too verbose. See: https://github.com/containers/buildah/issues/6362
- buildah build --log-level error --volume $CI_PROJECT_DIR:$CI_PROJECT_DIR:Z --file $CI_PROJECT_DIR/Dockerfile --tag $CI_REGISTRY_IMAGE:build-snap-${SNAPCRAFT_BASE_VERSION}-${RUNNER} --layers --cache-from $CI_REGISTRY_IMAGE/cache --cache-to $CI_REGISTRY_IMAGE/cache --cache-ttl=120h 2>&1 | grep -v STEP && buildah push --log-level error $CI_REGISTRY_IMAGE:build-snap-${SNAPCRAFT_BASE_VERSION}-${RUNNER} 2>&1 | grep -v STEP
- buildah build --log-level error --volume $CI_PROJECT_DIR:$CI_PROJECT_DIR:Z --file $CI_PROJECT_DIR/Dockerfile2 --no-cache 2>&1 | grep -v STEP
artifacts:
paths:
- _install-$RUNNER.tar
- _build-$RUNNER.tar
- babl-meson-log.tar
- gegl-meson-log.tar
expire_in: 2 hours
gimp-snap:
extends: .snap
needs: ["deps-snap"]
stage: build
variables:
#Snapcraft/launchpad does not allow shallow clones
GIT_DEPTH: 0
GIT_SUBMODULE_STRATEGY: recursive
script:
- sh build/linux/snap/2_build-gimp-snapcraft.sh
artifacts:
paths:
- temp*.snap
- snapcraft*.txt
- gimp-snapcraft.log
- gimp-meson-log.tar
expire_in: 2 days
@@ -483,16 +500,20 @@ gimp-snap:
.win:
extends: .default
rules:
#Developers (on GNOME/gimp namespace) can create multi-arch installers (.exe or .msixbundle)
#Non developers (e.g. on MRs), however, can create x64-only installers (.exe or .msix)
- if: '$RUNNER == "windows-aarch64" && $CI_PROJECT_NAMESPACE != "GNOME"'
when: never
- if: '$CI_MERGE_REQUEST_LABELS =~ /.*Package:Windows Installer.*/ && $CI_MERGE_REQUEST_LABELS =~ /.*Package:Microsoft Store.*/'
interruptible: true
variables:
INSTALLER_OPTION: '-Dwindows-installer=true'
STORE_OPTION: '-Dms-store=true'
- if: '$CI_MERGE_REQUEST_LABELS =~ /.*Package:Windows Installer.*/'
- if: '$CI_MERGE_REQUEST_LABELS =~ /.*Package:Windows Installer.*/ && $CI_JOB_NAME !~ /.*store.*/'
interruptible: true
variables:
INSTALLER_OPTION: '-Dwindows-installer=true'
- if: '$CI_MERGE_REQUEST_LABELS =~ /.*Package:Microsoft Store.*/ && $CI_JOB_NAME =~ /.*64.*/ && $CI_JOB_NAME !~ /.*installer.*/'
- if: '$CI_MERGE_REQUEST_LABELS =~ /.*Package:Microsoft Store.*/ && $CI_JOB_NAME !~ /.*mingw32.*/ && $CI_JOB_NAME !~ /.*installer.*/'
interruptible: true
variables:
STORE_OPTION: '-Dms-store=true'
@@ -500,10 +521,10 @@ gimp-snap:
variables:
INSTALLER_OPTION: '-Dwindows-installer=true'
STORE_OPTION: '-Dms-store=true'
- if: '$GIMP_CI_WIN_INSTALLER != null || "$[[ inputs.distribution_pipeline ]]" =~ /.*GIMP_CI_WIN_INSTALLER.*/'
- if: '($GIMP_CI_WIN_INSTALLER != null || "$[[ inputs.distribution_pipeline ]]" =~ /.*GIMP_CI_WIN_INSTALLER.*/) && $CI_JOB_NAME !~ /.*store.*/'
variables:
INSTALLER_OPTION: '-Dwindows-installer=true'
- if: '$GIMP_CI_MS_STORE != null || "$[[ inputs.distribution_pipeline ]]" =~ /.*GIMP_CI_MS_STORE.*/ && $CI_JOB_NAME =~ /.*64.*/ && $CI_JOB_NAME !~ /.*installer.*/'
- if: '($GIMP_CI_MS_STORE != null || "$[[ inputs.distribution_pipeline ]]" =~ /.*GIMP_CI_MS_STORE.*/) && $CI_JOB_NAME !~ /.*mingw32.*/ && $CI_JOB_NAME !~ /.*installer.*/'
variables:
STORE_OPTION: '-Dms-store=true'
- <<: *CI_RELEASE
@@ -512,32 +533,27 @@ gimp-snap:
STORE_OPTION: '-Dms-store=true'
parallel:
matrix:
- RUNNER: windows-aarch64
MSYSTEM_PREFIX: clangarm64
- RUNNER: win32-ps
MSYSTEM_PREFIX: clang64
- RUNNER: [windows-aarch64, win32-ps]
tags:
- $RUNNER
variables:
MSYS_ROOT: 'C:/msys64'
CC: cc
CXX: c++
#meson.build forces non-relocatable .pc. See: https://github.com/mesonbuild/meson/issues/14346
PKGCONF_RELOCATABLE_OPTION: '-Dpkgconfig.relocatable=true'
before_script:
# FIXME:'gimpenv' have buggy code about Windows paths. See: https://gitlab.gnome.org/GNOME/gimp/-/issues/12284
- $GIMP_PREFIX = "$PWD\_install-$MSYSTEM_PREFIX".Replace('\', '/')
timeout: 40m
- if (-not $env:MSYSTEM_PREFIX) { $env:MSYSTEM_PREFIX = if ((Get-WmiObject Win32_ComputerSystem).SystemType -like 'ARM64*') { 'clangarm64' } else { 'clang64' }}
- $GIMP_PREFIX = "$PWD\_install-$env:MSYSTEM_PREFIX"
timeout: 30m
.win_environ: &WIN_ENVIRON
# See: https://testing.developer.gimp.org/core/setup/build/windows/#prepare-for-building
- Write-Output "$([char]27)[0Ksection_start:$(Get-Date -UFormat %s -Millisecond 0):win_environ[collapsed=true]$([char]13)$([char]27)[0KPreparing build environment"
## Build-time vars
- $env:PKG_CONFIG_PATH = "$GIMP_PREFIX/lib/pkgconfig;$MSYS_ROOT/$MSYSTEM_PREFIX/lib/pkgconfig;$MSYS_ROOT/$MSYSTEM_PREFIX/share/pkgconfig"
- $env:XDG_DATA_DIRS = "$GIMP_PREFIX/share;$MSYS_ROOT/$MSYSTEM_PREFIX/share"
- $env:PKG_CONFIG_PATH = "$GIMP_PREFIX/lib/pkgconfig;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/lib/pkgconfig;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/share/pkgconfig"
- $env:XDG_DATA_DIRS = "$GIMP_PREFIX/share;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/share"
## Runtime vars
- $env:PATH = "$GIMP_PREFIX/bin;$MSYS_ROOT/$MSYSTEM_PREFIX/bin;" + $env:PATH
- $env:GI_TYPELIB_PATH = "$GIMP_PREFIX/lib/girepository-1.0;$MSYS_ROOT/$MSYSTEM_PREFIX/lib/girepository-1.0"
- $env:PATH = "$GIMP_PREFIX/bin;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/bin;$env:PATH"
- $env:GI_TYPELIB_PATH = "$GIMP_PREFIX/lib/girepository-1.0;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/lib/girepository-1.0"
- Write-Output "$([char]27)[0Ksection_end:$(Get-Date -UFormat %s -Millisecond 0):win_environ$([char]13)$([char]27)[0K"
deps-win:
@@ -547,14 +563,17 @@ deps-win:
- build\windows\1_build-deps-msys2.ps1
artifacts:
paths:
- _install-$MSYSTEM_PREFIX/
- babl/_build-$MSYSTEM_PREFIX/meson-logs/meson-log.txt
- gegl/_build-$MSYSTEM_PREFIX/meson-logs/meson-log.txt
- _install-*/
- babl/_build-*/meson-logs/meson-log.txt
- gegl/_build-*/meson-logs/meson-log.txt
expire_in: 2 hours
gimp-win:
extends: .win
needs: ["deps-win"]
needs:
- job: deps-win
#to allow running outside 'GNOME/gimp' namespace (on MRs)
optional: true
stage: build
variables:
GIT_SUBMODULE_STRATEGY: recursive
@@ -562,42 +581,37 @@ gimp-win:
- build\windows\2_build-gimp-msys2.ps1
artifacts:
paths:
- gimp-$MSYSTEM_PREFIX/
- _build-$MSYSTEM_PREFIX/meson-logs/meson-log.txt
- _build-$MSYSTEM_PREFIX/done-dll.list
- gimp-*/
- _build-*/meson-logs/meson-log.txt
- _build-*/done-dll.list
# Needed by dist-installer-weekly and dist-store-weekly
- _build-$MSYSTEM_PREFIX/config.h
- _build-$MSYSTEM_PREFIX/plug-ins/file_associations.list
- _build-$MSYSTEM_PREFIX/build/windows/installer/
- _build-$MSYSTEM_PREFIX/build/windows/store/
- _build-*/config.h
- _build-*/plug-ins/file_associations.list
- _build-*/build/windows/installer/
- _build-*/build/windows/store/
expire_in: 2 days
## WINDOWS x86 legacy CI (native MSYS2) ##
.win-x86:
.win-eol:
extends: .win
rules:
- !reference [.win, rules]
- if: '$GIMP_CI_MSYS2_WIN32 != null'
parallel:
matrix:
- RUNNER: win32-ps
MSYSTEM_PREFIX: mingw32
- RUNNER: [win32-ps]
variables:
MSYSTEM_PREFIX: mingw32
MINGW_PACKAGE_PREFIX: mingw-w64-i686
CC: cc
CXX: c++
deps-win-x86:
extends: .win-x86
deps-win-eol:
extends: .win-eol
stage: !reference [deps-win, stage]
script:
- !reference [deps-win, script]
artifacts: !reference [deps-win, artifacts]
gimp-win-x86:
extends: .win-x86
needs: ["deps-win-x86"]
gimp-win-eol:
extends: .win-eol
needs: ["deps-win-eol"]
stage: !reference [gimp-win, stage]
variables:
GIT_SUBMODULE_STRATEGY: recursive
@@ -612,22 +626,18 @@ gimp-win-x86:
file-plug-in-tests:
# FIXME: Do we need another job testing this under Windows? MSYS2 usually has
# the latest deps. It might be a good idea to test that too, maybe weekly?
extends: .debian-x64
extends: .debian-nonreloc
rules:
# Don't run on release since the plug-in doesn't get installed in releases
- <<: *CI_MERGE
- <<: *CI_COMMIT
needs: ["gimp-debian-x64"]
needs: ["gimp-debian-nonreloc"]
stage: analysis
variables:
GIT_STRATEGY: none
GIMP_TESTS_DATA_FOLDER: "$CI_PROJECT_DIR/_data/gimp-test-images/"
GIMP_TESTS_LOG_FILE: "$CI_PROJECT_DIR/_log/import-tests.log"
REGRESSION_STRING: "Total number of regressions: 0"
cache:
key: $CI_JOB_NAME
paths:
- _data
script:
- API_VER=$(grep GIMP_PKGCONFIG_VERSION _build*/config.h | head -1 | sed 's/^.*"\([^"]*\)"$/\1/')
- APP_VER=$(grep GIMP_APP_VERSION _build*/config.h | head -1 | sed 's/^.*"\([^"]*\)"$/\1/')
@@ -660,6 +670,8 @@ meson-health:
- <<: *CI_MERGE
- <<: *CI_COMMIT
stage: analysis
variables:
GIT_SUBMODULE_STRATEGY: recursive
script:
- apt-get update -qq
- apt-get install -qq -y --no-install-recommends git shellcheck devscripts
@@ -684,6 +696,19 @@ clang-format:
- fetch_origin.log
expire_in: 2 days
branches-check:
extends: .default
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_OPEN_MERGE_REQUESTS == null && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
stage: analysis
variables:
GIT_DEPTH: "0"
script:
- apt-get update -qq
- apt-get install -qq -y --no-install-recommends git
- sh .gitlab/check_dead_branches.sh
allow_failure: true
cppcheck:
extends: .default
rules:
@@ -693,7 +718,7 @@ cppcheck:
- apt-get update
- apt-get install -y cppcheck
- cppcheck -q -j8 --enable=all --force --output-file=cppcheck.xml --xml --xml-version=2
-i _build -i babl -i gegl -i _install -i .local -i .cache -i gimp-x64 .
-i _build -i babl -i gegl -i _install .
- mkdir report
- cppcheck-htmlreport --source-dir=. --title=gimp --file=cppcheck.xml --report-dir=report
artifacts:
@@ -707,10 +732,10 @@ cppcheck:
sources-debian:
extends: .default
rules:
# Don't run on MRs since non-merged/non-upstream code can't be distributed by us
- <<: *CI_COMMIT
- if: '$GIMP_CI_SOURCES != null'
- <<: *CI_RELEASE
needs: ["gimp-debian-x64"]
needs: ["gimp-debian-nonreloc"]
stage: distribution
variables:
GIT_STRATEGY: none
@@ -729,10 +754,10 @@ sources-debian:
dev-docs:
extends: .default
rules:
# Don't run on MRs since non-merged/non-upstream code can't be distributed by us
- <<: *CI_COMMIT
- if: '$GIMP_CI_SOURCES != null'
- <<: *CI_RELEASE
needs: ["deps-debian-x64", "gimp-debian-x64"]
needs: ["deps-debian-nonreloc", "gimp-debian-nonreloc"]
stage: distribution
variables:
GIT_STRATEGY: none
@@ -800,15 +825,14 @@ dist-appimage-weekly:
include:
project: GNOME/citemplates
file: flatpak/flatpak_ci_initiative.yml
ref: 42fbc2526a7680b6a4f284a210e63e3973ea6dae
dist-flatpak-weekly:
extends:
- .default
- .publish_nightly
rules:
- if: '$CI_MERGE_REQUEST_LABELS =~ /.*Package:Flatpak.*/'
interruptible: true
- if: '$GIMP_CI_FLATPAK != null || "$[[ inputs.distribution_pipeline ]]" =~ /.*GIMP_CI_FLATPAK.*/'
- !reference [.flatpak, rules]
needs: ["gimp-flatpak"]
stage: distribution
script:
@@ -839,10 +863,14 @@ dist-installer-weekly:
extends: .default
rules:
- !reference [.win, rules]
needs: ["gimp-win", "gimp-win-x86"]
needs:
- job: gimp-win
#to allow running outside 'GNOME/gimp' namespace (on MRs)
optional: true
- job: gimp-win-eol
stage: distribution
tags:
- windows-aarch64
- win32-ps
variables:
MSYS_ROOT: 'C:/msys64'
script:
@@ -857,11 +885,11 @@ dist-installer-weekly:
dist-store-weekly:
extends: .default
rules:
- if: '$CI_MERGE_REQUEST_LABELS =~ /.*Package:Microsoft Store.*/'
interruptible: true
- if: '$GIMP_CI_MS_STORE != null || "$[[ inputs.distribution_pipeline ]]" =~ /.*GIMP_CI_MS_STORE.*/'
- <<: *CI_RELEASE
needs: ["gimp-win"]
- !reference [.win, rules]
needs:
- job: gimp-win
#to allow running outside 'GNOME/gimp' namespace (on MRs)
optional: true
stage: distribution
tags:
- win32-ps

View File

@@ -0,0 +1,42 @@
#!/bin/sh
printf "\e[0Ksection_start:`date +%s`:branch_check[collapsed=false]\r\e[0KChecking for dead branches\n"
git branch -r | grep -v 'origin/HEAD' | grep -v "origin/$CI_DEFAULT_BRANCH" | while IFS= read remote_branch; do
remote_branch=$(printf "%s\n" "$remote_branch" | sed 's/^ *//;s/ *$//')
branch_name=$(printf "%s\n" "$remote_branch" | sed 's|origin/||')
# NOT CHECKING
## Skip old stable branches
if echo "$branch_name" | grep -q "^gimp-[0-9]-" || [ "$branch_name" = "gnome-2-2" ] || [ "$branch_name" = "gnome-2-4" ]; then
printf "\033[33m(SKIP)\033[0m: $branch_name is a snapshot of $CI_DEFAULT_BRANCH but no problem\n"
continue
fi
## Skip recently created branches
if [ "$(git rev-parse "$remote_branch")" = "$(git rev-parse "$CI_COMMIT_SHA")" ]; then
printf "\033[33m(SKIP)\033[0m: $branch_name is identical to $CI_DEFAULT_BRANCH but no problem\n"
continue
fi
# CHECKING
## Check: merge-base
if git merge-base --is-ancestor "$remote_branch" "$CI_COMMIT_SHA"; then
printf "\033[31m(ERROR)\033[0m: $branch_name is fully merged into $CI_DEFAULT_BRANCH (via git merge-base)\n"
touch 'dead_branch'
continue
fi
## Fallback check: cherry
cherry_output=$(git cherry "$CI_COMMIT_SHA" "$remote_branch")
if [ -z "$(printf "%s\n" "$cherry_output" | grep '^+')" ]; then
printf "\033[31m(ERROR)\033[0m: $branch_name is fully merged into $CI_DEFAULT_BRANCH (via git cherry)\n"
touch 'dead_branch'
continue
fi
done
if [ -f "dead_branch" ]; then
printf " Please delete the merged branches\n"
exit 1
else
printf '(INFO): All branches are organized.\n'
fi
printf "\e[0Ksection_end:`date +%s`:branch_check\r\e[0K\n"

View File

@@ -24,7 +24,7 @@ https://gitlab.gnome.org/GNOME/gimp/-/issues/?sort=updated_desc&state=all&label_
- "Be considerate and respectful". This is our main rule.
E.g. avoid negative emotional writing which only generates more upsetting
interactions.
- Stay on topic by writting only one bug per report created.
- Stay on topic by writing only one bug per report created.
- Add full (not cropped) screenshots or other files using the clip button on GitLab. -->
### Reproduction

View File

@@ -9,4 +9,7 @@
"*Allow commits from members who can merge to the target branch.*"
- No AI-generated contents allowed (neither code nor text, images…).
Only human created works please! -->
Only human created works please!
- You can request the devs to allow installable packages to be
generated from this MR by writing ~Package: in the comments -->

View File

@@ -5,7 +5,18 @@
# CHECK SCRIPTS RUNNED BY MESON (ALL OSes)
printf "\e[0Ksection_start:`date +%s`:nonunix_test[collapsed=false]\r\e[0KChecking for non-Unix compatibility\n"
diff=$(git diff -U0 --no-color "${newest_common_ancestor_sha}" -- '*.build' '*.py' | grep -E '^\+[^+]' | sed 's/^+//')
diff=$(git diff -U0 --no-color --submodule=diff "${newest_common_ancestor_sha}" \
| awk '
/^diff --git a\/.*\.(build|py)/ {
sub(/^diff --git a\//, "", $0)
sub(/ b\/.*$/, "", $0)
file = $0
next
}
/^\+[^+]/ && file != "" {
print file ":" substr($0, 2)
}
')
## List of commonly used utilities on Unix world
## See the context: https://gitlab.gnome.org/GNOME/gimp/-/issues/11385
@@ -168,10 +179,21 @@ printf "\e[0Ksection_end:`date +%s`:nonunix_test\r\e[0K\n"
# 1) contain bash shebang or are called by bash;
# 2) contain bashisms.
printf "\e[0Ksection_start:`date +%s`:unix_test[collapsed=false]\r\e[0KChecking for Unix portability (optional)\n"
diff=$(git diff -U0 --no-color "${newest_common_ancestor_sha}" | grep -E '^\+[^+]' | sed 's/^+//')
diff=$(git diff -U0 --no-color --submodule=diff "${newest_common_ancestor_sha}" \
| awk '
/^diff --git a\// {
sub(/^diff --git a\//, "", $0)
sub(/ b\/.*$/, "", $0)
file = $0
next
}
/^\+[^+]/ && file != "" {
print file ":" substr($0, 2)
}
')
## Check shebang and external call (1)
echo "$diff" | grep -E '^#!\s*/usr/bin/env\s+bash|^#!\s*/(usr/bin|bin)/bash(\s|$)' && found_bashism='extrinsic_bashism'
echo "$diff" | grep -E '#!\s*/usr/bin/env\s+bash|#!\s*/(usr/bin|bin)/bash(\s|$)' && found_bashism='extrinsic_bashism'
echo "$diff" | grep -E "bash\s+.*\.sh" && found_bashism='extrinsic_bashism'
## Check content with shellcheck and checkbashisms (2)

View File

@@ -23,6 +23,7 @@ The following people have contributed code to GIMP:
Rob Antonishen
Nicola Archibald
Timm Bäder
Gabriele Barbero
Luis Barrancos
Jerry Baker
John Beale
@@ -204,6 +205,7 @@ The following people have contributed code to GIMP:
Federico Mena Quintero
Loren Merritt
Jim Meyer
Ondřej Míchal
James Mitchell
Hirotsuna Mizuno
Chris Mohler

View File

@@ -201,7 +201,7 @@ help in that regard:
* HEIC: e.g. libde265 and libx265 support (for
respectively decoding and encoding of HEVC).
* AVIF: e.g. libaom decoder and encoder (for AV1 encoding and
decoding), prefered over rav1e.
decoding), preferred over rav1e.
* HEJ2: OpenJPEG (for JPEG2000 inside HEIF).
If you don't compile libheif with the correct flags (see libheif
@@ -489,5 +489,5 @@ reconfiguration:
% ninja reconfigure
Verify that the optional features you wanted are now shown as `true`,
otherwise follow similar advices than above to make sure they are
otherwise follow similar advice as above to make sure they are
visible to your setup.

171
NEWS
View File

@@ -6,6 +6,82 @@
This is the development branch of GIMP.
Overview of Changes from GIMP 3.1.4 to GIMP 3.2-RC1
===================================================
Core:
- macOS: "Quit" from the dock's right-click menu will now follow our
standard Quit procedure, by intercepting the
applicationShouldTerminate signal, instead of forcing the
application to close (hence losing unsaved changes).
- "Add Layer Mask" will now have an "Edit mask immediately" checkbox
allowing to decide whether to go into Edit Mask state or not. This
setting is saved across repetitive actions, as all other settings in
this dialog.
Graphical User Interface:
- "Monitor Linked Image" and "Discard Link Information" menu items
added to Layer menu when the selected layer is a link layer.
- The GimpColorHexEntry will now update the chosen color as you type.
- Use a standard, yet extended, AppMenu on macOS.
Plug-Ins:
- file-compressor: add zip decompression support. This allows support
for .hgt.zip files, as well as other formats compressed with zip.
API:
- The following libgimpbase API are now deprecated:
* gimp_pixpipe_params_init
* gimp_pixpipe_params_parse
* gimp_pixpipe_params_build
* gimp_pixpipe_params_free
- New libgimp functions:
* gimp_vector_layer_get_enable_fill
* gimp_vector_layer_get_enable_stroke
* gimp_vector_layer_get_fill_color
* gimp_vector_layer_get_path
* gimp_vector_layer_get_stroke_cap_style
* gimp_vector_layer_get_stroke_color
* gimp_vector_layer_get_stroke_dash_offset
* gimp_vector_layer_get_stroke_dash_pattern
* gimp_vector_layer_get_stroke_join_style
* gimp_vector_layer_get_stroke_miter_limit
* gimp_vector_layer_get_stroke_width
* gimp_vector_layer_get_stroke_width_unit
* gimp_vector_layer_set_enable_fill
* gimp_vector_layer_set_enable_stroke
* gimp_vector_layer_set_fill_color
* gimp_vector_layer_set_stroke_cap_style
* gimp_vector_layer_set_stroke_color
* gimp_vector_layer_set_stroke_dash_offset
* gimp_vector_layer_set_stroke_dash_pattern
* gimp_vector_layer_set_stroke_join_style
* gimp_vector_layer_set_stroke_miter_limit
* gimp_vector_layer_set_stroke_width
* gimp_vector_layer_set_stroke_width_unit
* gimp_item_is_vector_layer
* gimp_item_id_is_link_layer
* gimp_item_is_link_layer
* gimp_link_layer_discard
* gimp_link_layer_get_by_id
* gimp_link_layer_get_file
* gimp_link_layer_get_type
* gimp_link_layer_monitor
* gimp_link_layer_new
* gimp_link_layer_set_file
* gimp_param_link_layer_get_type
* gimp_param_spec_link_layer
* gimp_procedure_add_link_layer_argument
* gimp_procedure_add_link_layer_aux_argument
* gimp_procedure_add_link_layer_return_value
* gimp_link_layer_get_mime_type
- New libgimp class: GimpLinkLayer
Overview of Changes from GIMP 3.1.2 to GIMP 3.1.4
=================================================
@@ -21,8 +97,31 @@ Core:
- Some cleanup of outdated disabled unit tests and other warnings.
- Restructuration of internal GimpControllerManager and
GimpContainerView API.
- GimpContainerListView now uses a GtkListBox. A Playground switch was
added to use the new widgets in all views that can be switched
between list and grid view (brushes, patterns etc.). This won't
likely get out of Playground before GIMP 4 because it is far too
slow right now (and apparently we'll need GTK4 for making it fast as
our current lists).
- Various code have been moving away from GtkTreeView and some new
internal classes were added as a preparation for GTK4 port.
- GEX format updated to use standard <custom/> instead of <metadata/>
per update in the AppStream specs in the last few years. This
doesn't make any compatibility issue since this format is purely
internal only for now, not public.
- New setting "Update metadata automatically" in Preferences > Image
Import & Export > Export Policies. When enabled, add and update
metadata automatically. When disabled, only the minimum necessary
metadata changes are made, without changing modification date,
synchronizing tags, or updating the software and change history
metadata. This new setting is enabled by default.
- Fix palette import to properly import colors with alpha values from
palettes.
- New layer types:
* vector layers
* link layers
- Fill/Stroke editor are now live-previewing color changes for vector
layer fill/stroke and text layer outlines.
Tools:
@@ -31,6 +130,12 @@ Tools:
mypaint-brushes-1.0.
- Seamless Clone (Playground): made to work again, but is still too
slow to move out of Playground.
- The Paths tool has updated UI to create vector layers.
- Text tool: bold, italic and underline can now be applied with
commonly used shortcuts (Ctrl+b, i and u respectively).
- Vector and Link layers cannot be painted on, and filters cannot be
merged on them. They now need to be explicitly downgraded to raster
layers.
Graphical User Interface:
@@ -43,6 +148,11 @@ Graphical User Interface:
Preferences dialogue, and Welcome dialogue), we now turn off
animations when it is set OFF system-wide.
- "System" color scheme now also works on macOS.
- GimpSpinScale cursors now changed to "pointer" when hovering the
slider area and "col-resize" when actually grabbing the cursor.
- The Welcome dialog will now recognize your standard shortcuts to
create a new file, open a file or open one of the 10 most recent
files.
Plug-Ins:
@@ -61,19 +171,70 @@ Plug-Ins:
playback UIs. The redesign also changes the progress bar to a
GtkScale, so users can more easily move to different frames on the
timeline.
- PAA textures: initial import support (includes RGBA 4444, 5551,
8888, and Grayscale with Alpha channel. It does not yet cover DXT1 -
5 texture import support).
- New GEGL Filter Browser plug-in to list and inspect all available
filters for development purpose.
- New import support:
* PAA textures: initial import support (includes RGBA 4444, 5551,
8888, and Grayscale with Alpha channel. It does not yet cover DXT1
- 5 texture import support).
* Seattle Filmworks photos (earliest format SFW93A, and the most
common format SFW94A). Both formats are essentially mangled JPEGs,
though mangled in different ways.
* HRZ Slow Scan Television Images (restored, as it used to be
implemented and removed in 2004).
- Raw Image data plug-in dialog redesigned to be on a two-column
layout to avoid over-high dialog.
- Print: in sandboxed environments (Flatpak, Snap), the print Settings
are now displayed as a second dialog after the portal print dialog.
This 2-step workflow is a work-around to the inability to tweak the
print dialog when the print portal is in use.
API:
PDB:
- GimpTRCType enum type made available in libgimp and PDB.
- gimp-file-save properly sets associated save or exported files.
- New PDB/libgimp functions:
* gimp_drawable_filter_operation_get_available()
* gimp_drawable_filter_operation_get_details()
* gimp_drawable_filter_operation_get_pspecs()
* gimp_context_get_paint_fade_length()
* gimp_context_get_paint_fade_repeat()
* gimp_context_set_paint_fade_length()
* gimp_context_set_paint_fade_repeat()
* gimp_item_id_is_vector_layer()
* gimp_param_spec_vector_layer()
* gimp_procedure_add_vector_layer_argument()
* gimp_procedure_add_vector_layer_aux_argument()
* gimp_procedure_add_vector_layer_return_value()
* gimp_vector_layer_discard()
* gimp_vector_layer_get_by_id()
* gimp_vector_layer_new()
* gimp_vector_layer_refresh()
- GimpSizeEntry (libgimpwidget) can now parse mathematical expressions
in their reference value spin buttons too.
- GimpColorScales (libgimpwidget) will now set its decimals to 0 when
creating u8 RGB color selectors. This change will help further
distinguish between the 0...00 and 0..255 views in the Color
Selectors. It will also better convey to users that u8 is an integer
value rather than a floating point.
- Favor existing image comment instead of always loading comment from
metadata.
- Improve handling of comment metadata with
"charset=[ascii|InvalidCharsetId]" prefixes.
- New GIMP_METADATA_SAVE_UPDATE value in enum type
GimpMetadataSaveFlags (libgimpbase).
- Modernize setting "Exif.Image.DateTime" metadata by setting the
timezone additionally.
Build:
- Add nightly Snap package.
- Add nightly Aarch64 flatpak.
- appstream-glib dependency replaced with libappstream
- Installer uses latest InnoSetup now.
- New configure option -Dwin-debugging allowing to choose DWARF debug
symbols on Windows instead of the native (CodeView) symbols. This
will be useful for people wishing to debug with GDB in particular.
Overview of Changes from GIMP 3.0.4 to GIMP 3.1.2

View File

@@ -104,6 +104,7 @@
/* global variables */
GimpActionFactory *global_action_factory = NULL;
GHashTable *aux_filter_hash_table = NULL;
/* private variables */
@@ -270,6 +271,8 @@ actions_init (Gimp *gimp)
action_groups[i].icon_name,
action_groups[i].setup_func,
action_groups[i].update_func);
aux_filter_hash_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
}
void
@@ -280,6 +283,23 @@ actions_exit (Gimp *gimp)
g_return_if_fail (global_action_factory->gimp == gimp);
g_clear_object (&global_action_factory);
g_hash_table_unref (aux_filter_hash_table);
}
/* XXX Temporary code to store the list of filter operations with an
* "aux" input. This won't be necessary anymore once these filters can
* be applied non-destructively too in the future.
*/
void
actions_filter_set_aux (const gchar *action_name)
{
g_hash_table_add (aux_filter_hash_table, (gpointer) g_strdup (action_name));
}
gboolean
actions_filter_get_aux (const gchar *action_name)
{
return g_hash_table_lookup (aux_filter_hash_table, action_name) != NULL;
}
Gimp *

View File

@@ -24,6 +24,9 @@ extern GimpActionFactory *global_action_factory;
void actions_init (Gimp *gimp);
void actions_exit (Gimp *gimp);
void actions_filter_set_aux (const gchar *action_name);
gboolean actions_filter_get_aux (const gchar *action_name);
Gimp * action_data_get_gimp (gpointer data);
GimpContext * action_data_get_context (gpointer data);
GimpImage * action_data_get_image (gpointer data);

View File

@@ -307,13 +307,8 @@ gint n_dialogs_dockable_actions = G_N_ELEMENTS (dialogs_dockable_actions);
static const GimpStringActionEntry dialogs_toplevel_actions[] =
{
{ "dialogs-preferences", GIMP_ICON_PREFERENCES_SYSTEM,
#if defined(PLATFORM_OSX)
NC_("dialogs-action", "_Settings..."),
NC_("dialogs-action", "_Settings..."),
#else
NC_("dialogs-action", "_Preferences"),
NC_("dialogs-action", "_Preferences"),
#endif
{ NULL },
NC_("dialogs-action", "Open the preferences dialog"),
"gimp-preferences-dialog",
@@ -360,8 +355,6 @@ static const GimpStringActionEntry dialogs_toplevel_actions[] =
{ "dialogs-about", GIMP_ICON_HELP_ABOUT,
#if defined(G_OS_WIN32)
NC_("dialogs-action", "About GIMP"),
#elif defined(PLATFORM_OSX)
NC_("dialogs-action", "About"),
#else /* UNIX: use GNOME HIG */
NC_("dialogs-action", "_About"),
#endif

View File

@@ -82,6 +82,12 @@ static const GimpActionEntry file_actions[] =
file_open_as_layers_cmd_callback,
GIMP_HELP_FILE_OPEN_AS_LAYER },
{ "file-open-as-link-layers", GIMP_ICON_LAYER,
NC_("file-action", "Op_en as Link Layer..."), NULL, { "<primary><alt><shift>O", NULL },
NC_("file-action", "Open an image file as Link layer"),
file_open_as_link_layer_cmd_callback,
GIMP_HELP_FILE_OPEN_AS_LINK_LAYER },
{ "file-open-location", GIMP_ICON_WEB,
NC_("file-action", "Open _Location..."), NULL, { NULL },
NC_("file-action", "Open an image file from a specified location"),

View File

@@ -73,7 +73,8 @@ static void file_open_dialog_show (Gimp *gimp,
const gchar *title,
GimpImage *image,
GFile *file,
gboolean open_as_layers);
gboolean open_as_layers,
gboolean open_as_link);
static GtkWidget * file_save_dialog_show (Gimp *gimp,
GimpImage *image,
GtkWidget *parent,
@@ -118,7 +119,7 @@ file_open_cmd_callback (GimpAction *action,
file_open_dialog_show (gimp, widget,
_("Open Image"),
image, NULL, FALSE);
image, NULL, FALSE, FALSE);
}
void
@@ -140,7 +141,29 @@ file_open_as_layers_cmd_callback (GimpAction *action,
file_open_dialog_show (gimp, widget,
_("Open Image as Layers"),
image, NULL, TRUE);
image, NULL, TRUE, FALSE);
}
void
file_open_as_link_layer_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
Gimp *gimp;
GtkWidget *widget;
GimpDisplay *display;
GimpImage *image = NULL;
return_if_no_gimp (gimp, data);
return_if_no_widget (widget, data);
display = action_data_get_display (data);
if (display)
image = gimp_display_get_image (display);
file_open_dialog_show (gimp, widget,
_("Open Image as Link Layer"),
image, NULL, TRUE, TRUE);
}
void
@@ -577,7 +600,7 @@ file_file_open_dialog (Gimp *gimp,
{
file_open_dialog_show (gimp, parent,
_("Open Image"),
NULL, file, FALSE);
NULL, file, FALSE, FALSE);
}
@@ -589,7 +612,8 @@ file_open_dialog_show (Gimp *gimp,
const gchar *title,
GimpImage *image,
GFile *file,
gboolean open_as_layers)
gboolean open_as_layers,
gboolean open_as_link)
{
GtkWidget *dialog;
@@ -621,7 +645,7 @@ file_open_dialog_show (Gimp *gimp,
gtk_window_set_title (GTK_WINDOW (dialog), title);
gimp_open_dialog_set_image (GIMP_OPEN_DIALOG (dialog),
image, open_as_layers);
image, open_as_layers, open_as_link);
gtk_window_set_transient_for (GTK_WINDOW (dialog),
GTK_WINDOW (gtk_widget_get_toplevel (parent)));
@@ -841,9 +865,9 @@ file_revert_confirm_response (GtkWidget *dialog,
new_image = file_open_image (gimp, gimp_get_user_context (gimp),
GIMP_PROGRESS (display),
file, 0, 0, FALSE, NULL,
file, 0, 0, TRUE, FALSE, NULL,
GIMP_RUN_INTERACTIVE,
&status, NULL, &error);
NULL, &status, NULL, &error);
if (new_image)
{

View File

@@ -24,6 +24,9 @@ void file_open_cmd_callback (GimpAction *action,
void file_open_as_layers_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void file_open_as_link_layer_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void file_open_location_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);

View File

@@ -29,13 +29,18 @@
#include "core/gimp-filter-history.h"
#include "core/gimpimage.h"
#include "core/gimpgrouplayer.h"
#include "core/gimplinklayer.h"
#include "core/gimplayermask.h"
#include "path/gimpvectorlayer.h"
#include "pdb/gimpprocedure.h"
#include "widgets/gimpaction.h"
#include "widgets/gimpactiongroup.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpstringaction.h"
#include "widgets/gimpuimanager.h"
#include "widgets/gimpwidgets-utils.h"
@@ -48,11 +53,12 @@
/* local function prototypes */
static void filters_actions_set_tooltips (GimpActionGroup *group,
const GimpStringActionEntry *entries,
gint n_entries);
static void filters_actions_history_changed (Gimp *gimp,
GimpActionGroup *group);
static void filters_actions_set_tooltips (GimpActionGroup *group,
const GimpStringActionEntry *entries,
gint n_entries);
static void filters_actions_history_changed (Gimp *gimp,
GimpActionGroup *group);
static gboolean filters_is_non_interactive (const gchar *action_name);
/* private variables */
@@ -748,6 +754,7 @@ static const GimpEnumActionEntry filters_repeat_actions[] =
void
filters_actions_setup (GimpActionGroup *group)
{
static gboolean first_setup = TRUE;
GimpProcedureActionEntry *entries;
gint n_entries;
gint i;
@@ -776,6 +783,21 @@ filters_actions_setup (GimpActionGroup *group)
filters_actions_set_tooltips (group, filters_interactive_actions,
G_N_ELEMENTS (filters_interactive_actions));
/* XXX Hardcoded list to prevent expensive node/graph creation of a
* well-known list of operations.
* This whole code will disappear when we'll support filters with aux
* input non-destructively anyway.
*/
if (first_setup)
{
actions_filter_set_aux ("filters-variable-blur");
actions_filter_set_aux ("filters-oilify");
actions_filter_set_aux ("filters-lens-blur");
actions_filter_set_aux ("filters-gaussian-blur-selective");
actions_filter_set_aux ("filters-displace");
actions_filter_set_aux ("filters-bump-map");
}
gegl_actions = g_strv_builder_new ();
op_classes = gimp_gegl_get_op_classes (TRUE);
@@ -802,7 +824,7 @@ filters_actions_setup (GimpActionGroup *group)
* operations end up generating the same action name. Typically we
* don't want a third-party operation called "my-op" to have the same
* action name than "my_op" (which is to say that one will be
* overrided by the other).
* overridden by the other).
*/
g_free (action_name);
action_name = g_strdup_printf ("filters-%s-%d", formatted_op_name, i++);
@@ -861,6 +883,23 @@ filters_actions_setup (GimpActionGroup *group)
g_free (short_label);
}
/* Identify third-party filters based on operations with an
* auxiliary pad in first setup because of slowness on Windows.
* See #14781.
*/
if (first_setup)
{
GeglNode *node = gegl_node_new ();
gegl_node_set (node,
"operation", op_class->name,
NULL);
if (gegl_node_has_pad (node, "aux"))
actions_filter_set_aux (action_name);
g_clear_object (&node);
}
g_strv_builder_add (gegl_actions, action_name);
g_free (label);
@@ -910,6 +949,8 @@ filters_actions_setup (GimpActionGroup *group)
group, 0);
filters_actions_history_changed (group->gimp, group);
first_setup = FALSE;
}
void
@@ -917,11 +958,14 @@ filters_actions_update (GimpActionGroup *group,
gpointer data)
{
GimpImage *image;
GList *actions;
GList *iter;
gboolean writable = FALSE;
gboolean gray = FALSE;
gboolean alpha = FALSE;
gboolean supports_alpha = FALSE;
gboolean is_group = FALSE;
gboolean force_nde = FALSE;
image = action_data_get_image (data);
@@ -949,6 +993,11 @@ filters_actions_update (GimpActionGroup *group,
if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
is_group = TRUE;
if (GIMP_IS_GROUP_LAYER (drawable) ||
gimp_item_is_vector_layer (GIMP_ITEM (drawable)) ||
gimp_item_is_link_layer (GIMP_ITEM (drawable)))
force_nde = TRUE;
}
g_list_free (drawables);
@@ -957,134 +1006,82 @@ filters_actions_update (GimpActionGroup *group,
#define SET_SENSITIVE(action,condition) \
gimp_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
SET_SENSITIVE ("filters-alien-map", writable);
SET_SENSITIVE ("filters-antialias", writable && !is_group);
SET_SENSITIVE ("filters-apply-canvas", writable);
SET_SENSITIVE ("filters-apply-lens", writable);
SET_SENSITIVE ("filters-bayer-matrix", writable);
SET_SENSITIVE ("filters-bloom", writable);
SET_SENSITIVE ("filters-brightness-contrast", writable);
SET_SENSITIVE ("filters-bump-map", writable && !is_group);
actions = gimp_action_group_list_actions (group);
for (iter = actions; iter; iter = iter->next)
{
GimpAction *action = iter->data;
const gchar *action_name;
action_name = gimp_action_get_name (action);
if (filters_is_non_interactive (action_name))
{
/* Even I'm not sure they should, right now non-interactive
* actions are always applied destructively. So these filters
* are incompatible with layers where non-destructivity is
* mandatory.
*/
SET_SENSITIVE (action_name, writable && ! force_nde);
}
else if (GIMP_IS_STRING_ACTION (action))
{
const gchar *opname;
opname = GIMP_STRING_ACTION (action)->value;
if (opname == NULL)
/* These are the filters-recent-*, repeat and reshow handled
* below.
*/
continue;
if (g_strcmp0 (opname, "gegl:gegl") == 0)
{
/* GEGL graph filter can only be run destructively, unless
* the GIMP_ALLOW_GEGL_GRAPH_LAYER_EFFECT environment
* variable is set.
*/
SET_SENSITIVE (gimp_action_get_name (action), writable &&
(g_getenv ("GIMP_ALLOW_GEGL_GRAPH_LAYER_EFFECT") != NULL || ! force_nde));
}
else if (gegl_has_operation (opname))
{
gboolean sensitive = writable;
if (sensitive && force_nde)
/* Operations with auxiliary inputs can only be applied
* destructively. Therefore they must be deactivated on
* types of layers where filters can only be applied
* non-destructively.
*/
sensitive = ! actions_filter_get_aux (action_name);
SET_SENSITIVE (gimp_action_get_name (action), sensitive);
}
}
}
g_list_free (actions);
/* Special-cased filters */
SET_SENSITIVE ("filters-c2g", writable && !gray);
SET_SENSITIVE ("filters-cartoon", writable);
SET_SENSITIVE ("filters-channel-mixer", writable);
SET_SENSITIVE ("filters-checkerboard", writable);
SET_SENSITIVE ("filters-color-balance", writable && !gray);
SET_SENSITIVE ("filters-color-enhance", writable && !gray);
SET_SENSITIVE ("filters-color-exchange", writable);
SET_SENSITIVE ("filters-color-enhance", writable && !force_nde && !gray);
SET_SENSITIVE ("filters-colorize", writable && !gray);
SET_SENSITIVE ("filters-dither", writable);
SET_SENSITIVE ("filters-color-rotate", writable);
SET_SENSITIVE ("filters-color-temperature", writable && !gray);
SET_SENSITIVE ("filters-color-to-alpha", writable && supports_alpha);
SET_SENSITIVE ("filters-component-extract", writable);
SET_SENSITIVE ("filters-convolution-matrix", writable);
SET_SENSITIVE ("filters-cubism", writable);
SET_SENSITIVE ("filters-curves", writable);
SET_SENSITIVE ("filters-deinterlace", writable);
SET_SENSITIVE ("filters-desaturate", writable && !gray);
SET_SENSITIVE ("filters-difference-of-gaussians", writable);
SET_SENSITIVE ("filters-diffraction-patterns", writable);
SET_SENSITIVE ("filters-dilate", writable && !is_group);
SET_SENSITIVE ("filters-displace", writable && !is_group);
SET_SENSITIVE ("filters-distance-map", writable);
SET_SENSITIVE ("filters-dropshadow", writable && alpha);
SET_SENSITIVE ("filters-edge", writable && !is_group);
SET_SENSITIVE ("filters-edge-laplace", writable);
SET_SENSITIVE ("filters-edge-neon", writable);
SET_SENSITIVE ("filters-edge-sobel", writable);
SET_SENSITIVE ("filters-emboss", writable);
SET_SENSITIVE ("filters-engrave", writable);
SET_SENSITIVE ("filters-erode", writable);
SET_SENSITIVE ("filters-exposure", writable);
SET_SENSITIVE ("filters-fattal-2002", writable);
SET_SENSITIVE ("filters-focus-blur", writable);
SET_SENSITIVE ("filters-fractal-trace", writable);
SET_SENSITIVE ("filters-gaussian-blur", writable);
SET_SENSITIVE ("filters-gaussian-blur-selective", writable && !is_group);
SET_SENSITIVE ("filters-gegl-graph", writable && !is_group);
SET_SENSITIVE ("filters-grid", writable);
SET_SENSITIVE ("filters-high-pass", writable);
SET_SENSITIVE ("filters-hue-chroma", writable);
SET_SENSITIVE ("filters-hue-saturation", writable && !gray);
SET_SENSITIVE ("filters-illusion", writable);
SET_SENSITIVE ("filters-invert-linear", writable && !is_group);
SET_SENSITIVE ("filters-invert-perceptual", writable && !is_group);
SET_SENSITIVE ("filters-invert-value", writable && !is_group);
SET_SENSITIVE ("filters-image-gradient", writable);
SET_SENSITIVE ("filters-kaleidoscope", writable);
SET_SENSITIVE ("filters-lens-blur", writable && !is_group);
SET_SENSITIVE ("filters-lens-distortion", writable);
SET_SENSITIVE ("filters-lens-flare", writable);
SET_SENSITIVE ("filters-levels", writable);
SET_SENSITIVE ("filters-linear-sinusoid", writable);
SET_SENSITIVE ("filters-little-planet", writable);
SET_SENSITIVE ("filters-long-shadow", writable && alpha);
SET_SENSITIVE ("filters-mantiuk-2006", writable);
SET_SENSITIVE ("filters-maze", writable);
SET_SENSITIVE ("filters-mean-curvature-blur", writable);
SET_SENSITIVE ("filters-median-blur", writable);
SET_SENSITIVE ("filters-mono-mixer", writable && !gray);
SET_SENSITIVE ("filters-mosaic", writable);
SET_SENSITIVE ("filters-motion-blur-circular", writable);
SET_SENSITIVE ("filters-motion-blur-linear", writable);
SET_SENSITIVE ("filters-motion-blur-zoom", writable);
SET_SENSITIVE ("filters-newsprint", writable);
SET_SENSITIVE ("filters-noise-cell", writable);
SET_SENSITIVE ("filters-noise-cie-lch", writable);
SET_SENSITIVE ("filters-noise-hsv", writable && !gray);
SET_SENSITIVE ("filters-noise-hurl", writable);
SET_SENSITIVE ("filters-noise-perlin", writable);
SET_SENSITIVE ("filters-noise-pick", writable);
SET_SENSITIVE ("filters-noise-reduction", writable);
SET_SENSITIVE ("filters-noise-rgb", writable);
SET_SENSITIVE ("filters-noise-simplex", writable);
SET_SENSITIVE ("filters-noise-slur", writable);
SET_SENSITIVE ("filters-noise-solid", writable);
SET_SENSITIVE ("filters-noise-spread", writable);
SET_SENSITIVE ("filters-normal-map", writable);
SET_SENSITIVE ("filters-offset", writable);
SET_SENSITIVE ("filters-oilify", writable && !is_group);
SET_SENSITIVE ("filters-panorama-projection", writable);
SET_SENSITIVE ("filters-photocopy", writable);
SET_SENSITIVE ("filters-pixelize", writable);
SET_SENSITIVE ("filters-plasma", writable);
SET_SENSITIVE ("filters-polar-coordinates", writable);
SET_SENSITIVE ("filters-posterize", writable);
SET_SENSITIVE ("filters-recursive-transform", writable);
SET_SENSITIVE ("filters-red-eye-removal", writable && !gray);
SET_SENSITIVE ("filters-reinhard-2005", writable);
SET_SENSITIVE ("filters-rgb-clip", writable);
SET_SENSITIVE ("filters-ripple", writable);
SET_SENSITIVE ("filters-saturation", writable && !gray);
SET_SENSITIVE ("filters-semi-flatten", writable && alpha);
SET_SENSITIVE ("filters-sepia", writable && !gray);
SET_SENSITIVE ("filters-shadows-highlights", writable);
SET_SENSITIVE ("filters-shift", writable);
SET_SENSITIVE ("filters-sinus", writable);
SET_SENSITIVE ("filters-slic", writable);
SET_SENSITIVE ("filters-snn-mean", writable);
SET_SENSITIVE ("filters-softglow", writable);
SET_SENSITIVE ("filters-spherize", writable);
SET_SENSITIVE ("filters-spiral", writable);
SET_SENSITIVE ("filters-stretch-contrast", writable);
SET_SENSITIVE ("filters-stretch-contrast-hsv", writable);
SET_SENSITIVE ("filters-stress", writable);
SET_SENSITIVE ("filters-supernova", writable);
SET_SENSITIVE ("filters-threshold", writable);
SET_SENSITIVE ("filters-threshold-alpha", writable && alpha);
SET_SENSITIVE ("filters-tile-glass", writable);
SET_SENSITIVE ("filters-tile-paper", writable);
SET_SENSITIVE ("filters-tile-seamless", writable);
SET_SENSITIVE ("filters-unsharp-mask", writable);
SET_SENSITIVE ("filters-value-propagate", writable);
SET_SENSITIVE ("filters-variable-blur", writable && !is_group);
SET_SENSITIVE ("filters-video-degradation", writable);
SET_SENSITIVE ("filters-vignette", writable);
SET_SENSITIVE ("filters-waterpixels", writable);
SET_SENSITIVE ("filters-waves", writable);
SET_SENSITIVE ("filters-whirl-pinch", writable);
SET_SENSITIVE ("filters-wind", writable);
#undef SET_SENSITIVE
@@ -1336,3 +1333,19 @@ filters_actions_history_changed (Gimp *gimp,
NULL);
}
}
static gboolean
filters_is_non_interactive (const gchar *action_name)
{
gint i;
for (i = 0; i < G_N_ELEMENTS (filters_actions); i++)
if (g_strcmp0 (filters_actions[i].name, action_name) == 0)
return TRUE;
for (i = 0; i < G_N_ELEMENTS (filters_settings_actions); i++)
if (g_strcmp0 (filters_settings_actions[i].name, action_name) == 0)
return TRUE;
return FALSE;
}

View File

@@ -30,9 +30,12 @@
#include "core/gimpimage.h"
#include "core/gimplayer.h"
#include "core/gimplayer-floating-selection.h"
#include "core/gimplinklayer.h"
#include "text/gimptextlayer.h"
#include "path/gimpvectorlayer.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpactiongroup.h"
#include "widgets/gimpwidgets-utils.h"
@@ -60,6 +63,12 @@ static const GimpActionEntry layers_actions[] =
layers_edit_text_cmd_callback,
GIMP_HELP_LAYER_EDIT },
{ "layers-edit-vector", GIMP_ICON_TOOL_PATH,
NC_("layers-action", "Path Tool"), NULL, { NULL },
NC_("layers-action", "Activate the path tool on this vector layer's path"),
layers_edit_vector_cmd_callback,
GIMP_HELP_TOOL_PATH },
{ "layers-edit-attributes", GIMP_ICON_EDIT,
NC_("layers-action", "_Edit Layer Attributes..."), NULL, { NULL },
NC_("layers-action", "Edit the layer's name"),
@@ -173,6 +182,18 @@ static const GimpActionEntry layers_actions[] =
image_flatten_image_cmd_callback,
GIMP_HELP_IMAGE_FLATTEN },
{ "layers-link-discard", GIMP_ICON_TOOL_TEXT,
NC_("layers-action", "_Discard Link Information"), NULL, { NULL },
NC_("layers-action", "Turn this link layer into a normal layer"),
layers_link_discard_cmd_callback,
GIMP_HELP_LAYER_TEXT_DISCARD },
{ "layers-link-monitor", GIMP_ICON_TOOL_TEXT,
NC_("layers-action", "_Monitor Linked Image"), NULL, { NULL },
NC_("layers-action", "Discard any transformation and monitor the linked file again"),
layers_link_monitor_cmd_callback,
GIMP_HELP_LAYER_TEXT_DISCARD },
{ "layers-text-discard", GIMP_ICON_TOOL_TEXT,
NC_("layers-action", "_Discard Text Information"), NULL, { NULL },
NC_("layers-action", "Turn these text layers into normal layers"),
@@ -191,6 +212,18 @@ static const GimpActionEntry layers_actions[] =
layers_text_along_path_cmd_callback,
GIMP_HELP_LAYER_TEXT_ALONG_PATH },
{ "layers-vector-fill-stroke", NULL,
NC_("layers-action", "Fill / Stroke..."), NULL, { NULL },
NC_("layers-action", "Edit the fill and stroke of this vector layer"),
layers_vector_fill_stroke_cmd_callback,
GIMP_HELP_LAYER_VECTOR_FILL_STROKE },
{ "layers-vector-discard", NULL,
NC_("layers-action", "Discard Vector Information"), NULL, { NULL },
NC_("layers-action", "Turn this vector layer into a normal layer"),
layers_vector_discard_cmd_callback,
GIMP_HELP_LAYER_VECTOR_DISCARD },
{ "layers-resize", GIMP_ICON_OBJECT_RESIZE,
NC_("layers-action", "Layer B_oundary Size..."), NULL, { NULL },
NC_("layers-action", "Adjust the layer dimensions"),
@@ -757,6 +790,8 @@ layers_actions_update (GimpActionGroup *group,
gboolean lock_alpha = TRUE;
gboolean can_lock_alpha = FALSE;
gboolean text_layer = FALSE;
gboolean vector_layer = FALSE;
gboolean link_layer = FALSE;
gboolean bs_mutable = FALSE; /* At least 1 selected layers' blend space is mutable. */
gboolean cs_mutable = FALSE; /* At least 1 selected layers' composite space is mutable. */
gboolean cm_mutable = FALSE; /* At least 1 selected layers' composite mode is mutable. */
@@ -977,7 +1012,10 @@ layers_actions_update (GimpActionGroup *group,
gimp_action_group_set_action_active (group, action, TRUE);
text_layer = gimp_item_is_text_layer (GIMP_ITEM (layer));
text_layer = gimp_item_is_text_layer (GIMP_ITEM (layer));
vector_layer = gimp_item_is_vector_layer (GIMP_ITEM (layer));
if (GIMP_IS_LINK_LAYER (layer))
link_layer = gimp_link_layer_is_monitored (GIMP_LINK_LAYER (layer));
}
}
@@ -993,6 +1031,7 @@ layers_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("layers-edit", !ac && ((layer && !fs) || text_layer));
SET_VISIBLE ("layers-edit-text", text_layer && !ac);
SET_SENSITIVE ("layers-edit-text", text_layer && !ac);
SET_VISIBLE ("layers-edit-vector", vector_layer && !ac);
SET_SENSITIVE ("layers-edit-attributes", layer && !fs && !ac);
if (layer && gimp_layer_is_floating_sel (layer))
@@ -1042,6 +1081,12 @@ layers_actions_update (GimpActionGroup *group,
SET_VISIBLE ("layers-text-to-path", n_text_layers > 0 && !ac);
SET_VISIBLE ("layers-text-along-path", text_layer && !ac);
SET_VISIBLE ("layers-vector-fill-stroke", vector_layer && !ac);
SET_VISIBLE ("layers-vector-discard", vector_layer && !ac);
SET_VISIBLE ("layers-link-discard", link_layer && !ac);
SET_VISIBLE ("layers-link-monitor", GIMP_IS_LINK_LAYER (layer) && ! link_layer && !ac);
SET_SENSITIVE ("layers-resize", n_selected_layers == 1 && all_writable && all_movable && !ac);
SET_SENSITIVE ("layers-resize-to-image", all_writable && all_movable && !ac);
SET_SENSITIVE ("layers-scale", n_selected_layers == 1 && all_writable && all_movable && !ac);

View File

@@ -48,6 +48,8 @@
#include "core/gimplayerpropundo.h"
#include "core/gimplayer-floating-selection.h"
#include "core/gimplayer-new.h"
#include "core/gimplink.h"
#include "core/gimplinklayer.h"
#include "core/gimplist.h"
#include "core/gimppickable.h"
#include "core/gimppickable-auto-shrink.h"
@@ -58,6 +60,8 @@
#include "path/gimppath.h"
#include "path/gimppath-warp.h"
#include "path/gimpstroke.h"
#include "path/gimpvectorlayer.h"
#include "path/gimpvectorlayeroptions.h"
#include "text/gimptext.h"
#include "text/gimptext-path.h"
@@ -66,12 +70,14 @@
#include "widgets/gimpaction.h"
#include "widgets/gimpdock.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpopendialog.h"
#include "widgets/gimpprogressdialog.h"
#include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.h"
#include "display/gimpimagewindow.h"
#include "tools/gimppathtool.h"
#include "tools/gimptexttool.h"
#include "tools/tool_manager.h"
@@ -80,6 +86,7 @@
#include "dialogs/layer-options-dialog.h"
#include "dialogs/resize-dialog.h"
#include "dialogs/scale-dialog.h"
#include "dialogs/vector-layer-options-dialog.h"
#include "actions.h"
#include "items-commands.h"
@@ -101,6 +108,7 @@ static void layers_new_callback (GtkWidget *dialog,
GimpLayerCompositeMode layer_composite_mode,
gdouble layer_opacity,
GimpFillType layer_fill_type,
GimpLink *link,
gint layer_width,
gint layer_height,
gint layer_offset_x,
@@ -124,6 +132,7 @@ static void layers_edit_attributes_callback (GtkWidget *dialog,
GimpLayerCompositeMode layer_composite_mode,
gdouble layer_opacity,
GimpFillType layer_fill_type,
GimpLink *link,
gint layer_width,
gint layer_height,
gint layer_offset_x,
@@ -141,6 +150,7 @@ static void layers_add_mask_callback (GtkWidget *dialog,
GimpAddMaskType add_mask_type,
GimpChannel *channel,
gboolean invert,
gboolean edit_mask,
gpointer user_data);
static void layers_scale_callback (GtkWidget *dialog,
GimpViewable *viewable,
@@ -200,6 +210,10 @@ layers_edit_cmd_callback (GimpAction *action,
{
layers_edit_text_cmd_callback (action, value, data);
}
else if (gimp_item_is_vector_layer (GIMP_ITEM (layers->data)))
{
layers_vector_fill_stroke_cmd_callback (action, value, data);
}
else
{
layers_edit_attributes_cmd_callback (action, value, data);
@@ -251,6 +265,52 @@ layers_edit_text_cmd_callback (GimpAction *action,
}
}
void
layers_edit_vector_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GimpLayer *layer;
GList *layers;
GtkWidget *widget;
GimpTool *active_tool;
return_if_no_layers (image, layers, data);
return_if_no_widget (widget, data);
if (g_list_length (layers) != 1)
return;
layer = layers->data;
if (! gimp_item_is_vector_layer (GIMP_ITEM (layer)))
{
layers_edit_attributes_cmd_callback (action, value, data);
return;
}
active_tool = tool_manager_get_active (image->gimp);
if (! GIMP_IS_PATH_TOOL (active_tool))
{
GimpToolInfo *tool_info;
tool_info = (GimpToolInfo *)
gimp_container_get_child_by_name (image->gimp->tool_info_list,
"gimp-path-tool");
if (GIMP_IS_TOOL_INFO (tool_info))
{
gimp_context_set_tool (action_data_get_context (data), tool_info);
active_tool = tool_manager_get_active (image->gimp);
}
}
if (GIMP_IS_PATH_TOOL (active_tool))
gimp_path_tool_set_path (GIMP_PATH_TOOL (active_tool),
GIMP_VECTOR_LAYER (layer)->options->path);
}
void
layers_edit_attributes_cmd_callback (GimpAction *action,
GVariant *value,
@@ -1045,6 +1105,42 @@ layers_delete_cmd_callback (GimpAction *action,
gimp_image_flush (image);
}
void
layers_link_discard_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GList *layers;
GList *iter;
return_if_no_layers (image, layers, data);
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_PROPERTIES,
_("Discard Links"));
for (iter = layers; iter; iter = iter->next)
if (GIMP_IS_LINK_LAYER (iter->data))
gimp_link_layer_discard (GIMP_LINK_LAYER (iter->data));
gimp_image_undo_group_end (image);
}
void
layers_link_monitor_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GList *layers;
GList *iter;
return_if_no_layers (image, layers, data);
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_PROPERTIES,
_("Monitor Links"));
for (iter = layers; iter; iter = iter->next)
if (GIMP_IS_LINK_LAYER (iter->data))
gimp_link_layer_monitor (GIMP_LINK_LAYER (iter->data));
gimp_image_undo_group_end (image);
}
void
layers_text_discard_cmd_callback (GimpAction *action,
GVariant *value,
@@ -1473,6 +1569,7 @@ layers_mask_add_cmd_callback (GimpAction *action,
widget,
config->layer_add_mask_type,
config->layer_add_mask_invert,
config->layer_add_mask_edit_mask,
layers_add_mask_callback,
NULL);
@@ -1548,7 +1645,9 @@ layers_mask_add_last_vals_cmd_callback (GimpAction *action,
if (config->layer_add_mask_invert)
gimp_channel_invert (GIMP_CHANNEL (mask), FALSE);
gimp_layer_add_mask (iter->data, mask, TRUE, NULL);
gimp_layer_add_mask (iter->data, mask,
config->layer_add_mask_edit_mask,
TRUE, NULL);
}
gimp_image_undo_group_end (image);
@@ -1665,7 +1764,7 @@ layers_mask_show_cmd_callback (GimpAction *action,
{
/* if switching "show mask" on, and any selected layer's
* mask is already visible, bail out because that's
* exactly the logic we use in the ui for multile
* exactly the logic we use in the ui for multiple
* visible layer masks.
*/
return;
@@ -1716,7 +1815,7 @@ layers_mask_disable_cmd_callback (GimpAction *action,
{
/* if switching "disable mask" on, and any selected
* layer's mask is already disabled, bail out because
* that's exactly the logic we use in the ui for multile
* that's exactly the logic we use in the ui for multiple
* disabled layer masks.
*/
return;
@@ -2263,6 +2362,7 @@ layers_new_callback (GtkWidget *dialog,
GimpLayerCompositeMode layer_composite_mode,
gdouble layer_opacity,
GimpFillType layer_fill_type,
GimpLink *link,
gint layer_width,
gint layer_height,
gint layer_offset_x,
@@ -2283,6 +2383,8 @@ layers_new_callback (GtkWidget *dialog,
gint n_layers = g_list_length (layers);
gboolean run_once = (n_layers == 0);
g_return_if_fail (link == NULL);
g_object_set (config,
"layer-new-name", layer_name,
"layer-new-mode", layer_mode,
@@ -2379,6 +2481,7 @@ layers_edit_attributes_callback (GtkWidget *dialog,
GimpLayerCompositeMode layer_composite_mode,
gdouble layer_opacity,
GimpFillType unused1,
GimpLink *link,
gint unused2,
gint unused3,
gint layer_offset_x,
@@ -2407,7 +2510,8 @@ layers_edit_attributes_callback (GtkWidget *dialog,
layer_lock_pixels != gimp_item_get_lock_content (item) ||
layer_lock_position != gimp_item_get_lock_position (item) ||
layer_lock_visibility != gimp_item_get_lock_visibility (item) ||
layer_lock_alpha != gimp_layer_get_lock_alpha (layer))
layer_lock_alpha != gimp_layer_get_lock_alpha (layer) ||
link)
{
gimp_image_undo_group_start (image,
GIMP_UNDO_GROUP_ITEM_PROPERTIES,
@@ -2468,6 +2572,9 @@ layers_edit_attributes_callback (GtkWidget *dialog,
if (layer_lock_alpha != gimp_layer_get_lock_alpha (layer))
gimp_layer_set_lock_alpha (layer, layer_lock_alpha, TRUE);
if (GIMP_IS_LINK_LAYER (layer) && link)
gimp_link_layer_set_link (GIMP_LINK_LAYER (layer), link, TRUE);
gimp_image_undo_group_end (image);
gimp_image_flush (image);
}
@@ -2488,6 +2595,7 @@ layers_add_mask_callback (GtkWidget *dialog,
GimpAddMaskType add_mask_type,
GimpChannel *channel,
gboolean invert,
gboolean edit_mask,
gpointer user_data)
{
GimpImage *image = gimp_item_get_image (GIMP_ITEM (layers->data));
@@ -2497,8 +2605,9 @@ layers_add_mask_callback (GtkWidget *dialog,
GError *error = NULL;
g_object_set (config,
"layer-add-mask-type", add_mask_type,
"layer-add-mask-invert", invert,
"layer-add-mask-type", add_mask_type,
"layer-add-mask-invert", invert,
"layer-add-mask-edit-mask", edit_mask,
NULL);
gimp_image_undo_group_start (image,
@@ -2514,7 +2623,7 @@ layers_add_mask_callback (GtkWidget *dialog,
if (config->layer_add_mask_invert)
gimp_channel_invert (GIMP_CHANNEL (mask), FALSE);
if (! gimp_layer_add_mask (iter->data, mask, TRUE, &error))
if (! gimp_layer_add_mask (iter->data, mask, edit_mask, TRUE, &error))
{
gimp_message_literal (image->gimp,
G_OBJECT (dialog), GIMP_MESSAGE_WARNING,
@@ -2591,6 +2700,56 @@ layers_scale_callback (GtkWidget *dialog,
}
}
void
layers_vector_fill_stroke_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GimpLayer *layer;
GList *layers;
GtkWidget *widget;
return_if_no_layers (image, layers, data);
return_if_no_widget (widget, data);
if (g_list_length (layers) != 1)
return;
layer = layers->data;
if (GIMP_IS_VECTOR_LAYER (layer))
{
GtkWidget *dialog;
dialog = vector_layer_options_dialog_new (GIMP_VECTOR_LAYER (layer),
action_data_get_context (data),
_("Fill / Stroke"),
"gimp-vector-layer-stroke",
GIMP_HELP_LAYER_VECTOR_FILL_STROKE,
widget);
gtk_widget_show (dialog);
}
}
void
layers_vector_discard_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GimpLayer *layer;
GList *layers;
return_if_no_layers (image, layers, data);
if (g_list_length (layers) != 1)
return;
layer = layers->data;
if (GIMP_IS_VECTOR_LAYER (layer))
gimp_vector_layer_discard (GIMP_VECTOR_LAYER (layer));
}
static void
layers_resize_callback (GtkWidget *dialog,
GimpViewable *viewable,

View File

@@ -24,6 +24,9 @@ void layers_edit_cmd_callback (GimpAction *action,
void layers_edit_text_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_edit_vector_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_edit_attributes_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
@@ -74,6 +77,12 @@ void layers_merge_group_cmd_callback (GimpAction *action,
void layers_delete_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_link_discard_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_link_monitor_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_text_discard_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
@@ -83,6 +92,12 @@ void layers_text_to_path_cmd_callback (GimpAction *action,
void layers_text_along_path_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_vector_fill_stroke_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_vector_discard_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_resize_cmd_callback (GimpAction *action,
GVariant *value,

View File

@@ -101,6 +101,6 @@ libappactions = static_library('appactions',
include_directories: [ rootInclude, rootAppInclude, ],
c_args: '-DG_LOG_DOMAIN="Gimp-Actions"',
dependencies: [
gegl, gdk_pixbuf, gtk3,
gegl, gdk_pixbuf, gtk3, gexiv2,
],
)

View File

@@ -149,7 +149,12 @@ static const GimpActionEntry paths_actions[] =
{ "paths-import", GIMP_ICON_DOCUMENT_OPEN,
NC_("paths-action", "I_mport Path..."), NULL, { NULL }, NULL,
paths_import_cmd_callback,
GIMP_HELP_PATH_IMPORT }
GIMP_HELP_PATH_IMPORT },
{ "paths-to-vector-layer", NULL,
NC_("paths-action", "Path to Vector Layer"), NULL, { NULL }, NULL,
path_to_vector_layer_cmd_callback,
GIMP_HELP_PATH_TO_VECTOR_LAYER },
};
static const GimpToggleActionEntry paths_toggle_actions[] =
@@ -429,6 +434,8 @@ paths_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("paths-export", n_selected_paths > 0);
SET_SENSITIVE ("paths-import", image);
SET_SENSITIVE ("paths-to-vector-layer", n_selected_paths == 1);
SET_SENSITIVE ("paths-selection-to-path", image && !mask_empty);
SET_SENSITIVE ("paths-selection-to-path-advanced", image && !mask_empty);
SET_SENSITIVE ("paths-fill", n_selected_paths > 0 &&

View File

@@ -47,6 +47,7 @@
#include "path/gimppath.h"
#include "path/gimppath-export.h"
#include "path/gimppath-import.h"
#include "path/gimpvectorlayer.h"
#include "widgets/gimpaction.h"
#include "widgets/gimpclipboard.h"
@@ -469,6 +470,7 @@ paths_delete_cmd_callback (GimpAction *action,
{
GimpImage *image;
GList *paths;
gboolean attached_to_vector_layer = FALSE;
return_if_no_paths (image, paths, data);
paths = g_list_copy (paths);
@@ -478,11 +480,21 @@ paths_delete_cmd_callback (GimpAction *action,
_("Remove Paths"));
for (GList *iter = paths; iter; iter = iter->next)
gimp_image_remove_path (image, iter->data, TRUE, NULL);
{
/* Verify path is not attached to vector layer */
if (! gimp_path_attached_to_vector_layer (GIMP_PATH (iter->data), image))
gimp_image_remove_path (image, iter->data, TRUE, NULL);
else
attached_to_vector_layer = TRUE;
}
gimp_image_undo_group_end (image);
gimp_image_flush (image);
g_list_free (paths);
if (attached_to_vector_layer)
gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_WARNING,
_("Paths attached to vector layers weren't deleted"));
}
void
@@ -509,6 +521,28 @@ paths_merge_visible_cmd_callback (GimpAction *action,
gimp_image_flush (image);
}
void
path_to_vector_layer_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GList *paths;
GimpVectorLayer *layer;
return_if_no_paths (image, paths, data);
layer = gimp_vector_layer_new (image, paths->data,
gimp_get_user_context (image->gimp));
gimp_image_add_layer (image,
GIMP_LAYER (layer),
GIMP_IMAGE_ACTIVE_PARENT,
-1,
TRUE);
gimp_vector_layer_refresh (layer);
gimp_image_flush (image);
}
void
paths_to_selection_cmd_callback (GimpAction *action,
GVariant *value,

View File

@@ -50,6 +50,9 @@ void paths_duplicate_cmd_callback (GimpAction *action,
void paths_delete_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void path_to_vector_layer_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void paths_merge_visible_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);

View File

@@ -61,6 +61,21 @@ static const GimpActionEntry text_tool_actions[] =
text_tool_paste_cmd_callback,
GIMP_HELP_TEXT_TOOL_PASTE },
{ "text-tool-toggle-bold", GIMP_ICON_FORMAT_TEXT_BOLD,
NC_("text-tool-action", "_Bold"), NULL, { "<primary>B", NULL }, NULL,
text_tool_toggle_bold_cmd_callback,
NULL },
{ "text-tool-toggle-italic", GIMP_ICON_FORMAT_TEXT_ITALIC,
NC_("text-tool-action", "_Italic"), NULL, { "<primary>I", NULL }, NULL,
text_tool_toggle_italic_cmd_callback,
NULL },
{ "text-tool-toggle-underline", GIMP_ICON_FORMAT_TEXT_UNDERLINE,
NC_("text-tool-action", "_Underline"), NULL, { "<primary>U", NULL }, NULL,
text_tool_toggle_underline_cmd_callback,
NULL },
{ "text-tool-delete", GIMP_ICON_EDIT_DELETE,
NC_("text-tool-action", "_Delete"), NULL, { NULL }, NULL,
text_tool_delete_cmd_callback,
@@ -189,14 +204,17 @@ text_tool_actions_update (GimpActionGroup *group,
#define SET_ACTIVE(action,condition) \
gimp_action_group_set_action_active (group, action, (condition) != 0)
SET_SENSITIVE ("text-tool-cut", text_sel);
SET_SENSITIVE ("text-tool-copy", text_sel);
SET_SENSITIVE ("text-tool-paste", clip);
SET_SENSITIVE ("text-tool-delete", text_sel);
SET_SENSITIVE ("text-tool-clear", text_layer);
SET_SENSITIVE ("text-tool-load", image);
SET_SENSITIVE ("text-tool-text-to-path", text_layer);
SET_SENSITIVE ("text-tool-text-along-path", text_layer && g_list_length (paths) == 1);
SET_SENSITIVE ("text-tool-cut", text_sel);
SET_SENSITIVE ("text-tool-copy", text_sel);
SET_SENSITIVE ("text-tool-paste", clip);
SET_SENSITIVE ("text-tool-toggle-bold", text_sel);
SET_SENSITIVE ("text-tool-toggle-italic", text_sel);
SET_SENSITIVE ("text-tool-toggle-underline", text_sel);
SET_SENSITIVE ("text-tool-delete", text_sel);
SET_SENSITIVE ("text-tool-clear", text_layer);
SET_SENSITIVE ("text-tool-load", image);
SET_SENSITIVE ("text-tool-text-to-path", text_layer);
SET_SENSITIVE ("text-tool-text-along-path", text_layer && g_list_length (paths) == 1);
direction = gimp_text_tool_get_direction (text_tool);
for (i = 0; i < G_N_ELEMENTS (text_tool_direction_actions); i++)

View File

@@ -84,6 +84,36 @@ text_tool_paste_cmd_callback (GimpAction *action,
gimp_text_tool_paste_clipboard (text_tool);
}
void
text_tool_toggle_bold_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpTextTool *text_tool = GIMP_TEXT_TOOL (data);
gimp_text_tool_toggle_tag (text_tool, text_tool->buffer->bold_tag);
}
void
text_tool_toggle_italic_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpTextTool *text_tool = GIMP_TEXT_TOOL (data);
gimp_text_tool_toggle_tag (text_tool, text_tool->buffer->italic_tag);
}
void
text_tool_toggle_underline_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpTextTool *text_tool = GIMP_TEXT_TOOL (data);
gimp_text_tool_toggle_tag (text_tool, text_tool->buffer->underline_tag);
}
void
text_tool_delete_cmd_callback (GimpAction *action,
GVariant *value,

View File

@@ -27,6 +27,16 @@ void text_tool_copy_cmd_callback (GimpAction *action,
void text_tool_paste_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void text_tool_toggle_bold_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void text_tool_toggle_italic_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void text_tool_toggle_underline_cmd_callback
(GimpAction *action,
GVariant *value,
gpointer data);
void text_tool_delete_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);

View File

@@ -81,6 +81,7 @@ enum
PROP_LAYER_ADD_MASK_TYPE,
PROP_LAYER_ADD_MASK_INVERT,
PROP_LAYER_ADD_MASK_EDIT_MASK,
PROP_LAYER_MERGE_TYPE,
PROP_LAYER_MERGE_ACTIVE_GROUP_ONLY,
@@ -389,6 +390,13 @@ gimp_dialog_config_class_init (GimpDialogConfigClass *klass)
FALSE,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_LAYER_ADD_MASK_EDIT_MASK,
"layer-add-mask-edit-mask",
"Default layer mask: edit mask immediately",
LAYER_ADD_MASK_EDIT_MASK,
TRUE,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_ENUM (object_class, PROP_LAYER_MERGE_TYPE,
"layer-merge-type",
"Default layer merge type",
@@ -716,6 +724,9 @@ gimp_dialog_config_set_property (GObject *object,
case PROP_LAYER_ADD_MASK_INVERT:
config->layer_add_mask_invert = g_value_get_boolean (value);
break;
case PROP_LAYER_ADD_MASK_EDIT_MASK:
config->layer_add_mask_edit_mask = g_value_get_boolean (value);
break;
case PROP_LAYER_MERGE_TYPE:
config->layer_merge_type = g_value_get_enum (value);
@@ -908,6 +919,9 @@ gimp_dialog_config_get_property (GObject *object,
case PROP_LAYER_ADD_MASK_INVERT:
g_value_set_boolean (value, config->layer_add_mask_invert);
break;
case PROP_LAYER_ADD_MASK_EDIT_MASK:
g_value_set_boolean (value, config->layer_add_mask_edit_mask);
break;
case PROP_LAYER_MERGE_TYPE:
g_value_set_enum (value, config->layer_merge_type);

View File

@@ -78,6 +78,7 @@ struct _GimpDialogConfig
GimpAddMaskType layer_add_mask_type;
gboolean layer_add_mask_invert;
gboolean layer_add_mask_edit_mask;
GimpMergeType layer_merge_type;
gboolean layer_merge_active_group_only;

View File

@@ -659,6 +659,9 @@ _("Sets the default mask for the 'Add Layer Mask' dialog.")
#define LAYER_ADD_MASK_INVERT_BLURB \
_("Sets the default 'invert mask' state for the 'Add Layer Mask' dialog.")
#define LAYER_ADD_MASK_EDIT_MASK \
_("Sets the default 'edit mask' state for the 'Add Layer Mask' dialog.")
#define LAYER_MERGE_TYPE_BLURB \
_("Sets the default merge type for the 'Merge Visible Layers' dialog.")

View File

@@ -44,7 +44,7 @@ libappconfig = static_library('appconfig',
include_directories: [ rootInclude, rootAppInclude, ],
c_args: '-DG_LOG_DOMAIN="Gimp-Config"',
dependencies: [
cairo, gegl, gdk_pixbuf, gio, gio_specific, libmypaint,
cairo, gegl, gdk_pixbuf, gexiv2, gio, gio_specific, libmypaint,
],
)

View File

@@ -1257,6 +1257,7 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_LAYER_MODE, "GIMP_UNDO_LAYER_MODE", "layer-mode" },
{ GIMP_UNDO_LAYER_OPACITY, "GIMP_UNDO_LAYER_OPACITY", "layer-opacity" },
{ GIMP_UNDO_LAYER_LOCK_ALPHA, "GIMP_UNDO_LAYER_LOCK_ALPHA", "layer-lock-alpha" },
{ GIMP_UNDO_LINK_LAYER, "GIMP_UNDO_LINK_LAYER", "link-layer" },
{ GIMP_UNDO_GROUP_LAYER_SUSPEND_RESIZE, "GIMP_UNDO_GROUP_LAYER_SUSPEND_RESIZE", "group-layer-suspend-resize" },
{ GIMP_UNDO_GROUP_LAYER_RESUME_RESIZE, "GIMP_UNDO_GROUP_LAYER_RESUME_RESIZE", "group-layer-resume-resize" },
{ GIMP_UNDO_GROUP_LAYER_SUSPEND_MASK, "GIMP_UNDO_GROUP_LAYER_SUSPEND_MASK", "group-layer-suspend-mask" },
@@ -1267,6 +1268,8 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_TEXT_LAYER, "GIMP_UNDO_TEXT_LAYER", "text-layer" },
{ GIMP_UNDO_TEXT_LAYER_MODIFIED, "GIMP_UNDO_TEXT_LAYER_MODIFIED", "text-layer-modified" },
{ GIMP_UNDO_TEXT_LAYER_CONVERT, "GIMP_UNDO_TEXT_LAYER_CONVERT", "text-layer-convert" },
{ GIMP_UNDO_VECTOR_LAYER, "GIMP_UNDO_VECTOR_LAYER", "vector-layer" },
{ GIMP_UNDO_VECTOR_LAYER_MODIFIED, "GIMP_UNDO_VECTOR_LAYER_MODIFIED", "vector-layer-modified" },
{ GIMP_UNDO_LAYER_MASK_ADD, "GIMP_UNDO_LAYER_MASK_ADD", "layer-mask-add" },
{ GIMP_UNDO_LAYER_MASK_REMOVE, "GIMP_UNDO_LAYER_MASK_REMOVE", "layer-mask-remove" },
{ GIMP_UNDO_LAYER_MASK_APPLY, "GIMP_UNDO_LAYER_MASK_APPLY", "layer-mask-apply" },
@@ -1370,6 +1373,7 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_LAYER_MODE, NC_("undo-type", "Set layer mode"), NULL },
{ GIMP_UNDO_LAYER_OPACITY, NC_("undo-type", "Set layer opacity"), NULL },
{ GIMP_UNDO_LAYER_LOCK_ALPHA, NC_("undo-type", "Lock/Unlock alpha channel"), NULL },
{ GIMP_UNDO_LINK_LAYER, NC_("undo-type", "Link layer"), NULL },
{ GIMP_UNDO_GROUP_LAYER_SUSPEND_RESIZE, NC_("undo-type", "Suspend group layer resize"), NULL },
{ GIMP_UNDO_GROUP_LAYER_RESUME_RESIZE, NC_("undo-type", "Resume group layer resize"), NULL },
{ GIMP_UNDO_GROUP_LAYER_SUSPEND_MASK, NC_("undo-type", "Suspend group layer mask"), NULL },
@@ -1380,6 +1384,8 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_TEXT_LAYER, NC_("undo-type", "Text layer"), NULL },
{ GIMP_UNDO_TEXT_LAYER_MODIFIED, NC_("undo-type", "Text layer modification"), NULL },
{ GIMP_UNDO_TEXT_LAYER_CONVERT, NC_("undo-type", "Convert text layer"), NULL },
{ GIMP_UNDO_VECTOR_LAYER, NC_("undo-type", "Vector layer"), NULL },
{ GIMP_UNDO_VECTOR_LAYER_MODIFIED, NC_("undo-type", "Vector layer modification"), NULL },
{ GIMP_UNDO_LAYER_MASK_ADD, NC_("undo-type", "Add layer masks"), NULL },
{ GIMP_UNDO_LAYER_MASK_REMOVE, NC_("undo-type", "Delete layer masks"), NULL },
{ GIMP_UNDO_LAYER_MASK_APPLY, NC_("undo-type", "Apply layer masks"), NULL },

View File

@@ -609,6 +609,7 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_LAYER_MODE, /*< desc="Set layer mode" >*/
GIMP_UNDO_LAYER_OPACITY, /*< desc="Set layer opacity" >*/
GIMP_UNDO_LAYER_LOCK_ALPHA, /*< desc="Lock/Unlock alpha channel" >*/
GIMP_UNDO_LINK_LAYER, /*< desc="Link layer" >*/
GIMP_UNDO_GROUP_LAYER_SUSPEND_RESIZE, /*< desc="Suspend group layer resize" >*/
GIMP_UNDO_GROUP_LAYER_RESUME_RESIZE, /*< desc="Resume group layer resize" >*/
GIMP_UNDO_GROUP_LAYER_SUSPEND_MASK, /*< desc="Suspend group layer mask" >*/
@@ -619,6 +620,8 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_TEXT_LAYER, /*< desc="Text layer" >*/
GIMP_UNDO_TEXT_LAYER_MODIFIED, /*< desc="Text layer modification" >*/
GIMP_UNDO_TEXT_LAYER_CONVERT, /*< desc="Convert text layer" >*/
GIMP_UNDO_VECTOR_LAYER, /*< desc="Vector layer" >*/
GIMP_UNDO_VECTOR_LAYER_MODIFIED, /*< desc="Vector layer modification" >*/
GIMP_UNDO_LAYER_MASK_ADD, /*< desc="Add layer masks" >*/
GIMP_UNDO_LAYER_MASK_REMOVE, /*< desc="Delete layer masks" >*/
GIMP_UNDO_LAYER_MASK_APPLY, /*< desc="Apply layer masks" >*/

View File

@@ -90,6 +90,7 @@ typedef struct _GimpViewable GimpViewable;
typedef struct _GimpFilter GimpFilter;
typedef struct _GimpItem GimpItem;
typedef struct _GimpAuxItem GimpAuxItem;
typedef struct _GimpLink GimpLink;
typedef struct _Gimp Gimp;
typedef struct _GimpImage GimpImage;
@@ -167,6 +168,7 @@ typedef struct _GimpLayerMask GimpLayerMask;
typedef struct _GimpSelection GimpSelection;
typedef struct _GimpLayer GimpLayer;
typedef struct _GimpGroupLayer GimpGroupLayer;
typedef struct _GimpLinkLayer GimpLinkLayer;
/* auxiliary image items */

View File

@@ -353,7 +353,7 @@ gimp_transform_resize_crop (const GimpVector2 *orig_points,
if (r.area == 0)
{
/* saveguard if something went wrong, adjust and give warning */
/* safeguard if something went wrong, adjust and give warning */
gimp_transform_resize_adjust (orig_points, n_points,
x1, y1, x2, y2);
g_printerr ("no rectangle found by algorithm, no cropping done\n");

View File

@@ -224,18 +224,14 @@ gimp_user_install_run (GimpUserInstall *install,
if (install->migrate)
{
gchar *verstring;
/* TODO: these 2 strings should be merged into one, but it was not
* possible to do it at implementation time, in order not to break
* string freeze.
*/
verstring = g_strdup_printf ("%d.%d", install->old_major, install->old_minor);
user_install_log (install,
_("It seems you have used GIMP %s before. "
/* TRANSLATORS: the %d.%d replacement strings
* will be a series version (e.g. 2.10). The %s
* replacement will be a directory.
*/
_("It seems you have used GIMP %d.%d before. "
"GIMP will now migrate your user settings to '%s'."),
verstring, dirname);
g_free (verstring);
install->old_major, install->old_minor, dirname);
}
else
{

View File

@@ -605,7 +605,7 @@ gimp_get_fill_params (GimpContext *context,
* @start_y:
* @end_x:
* @end_y:
* @n_snap_lines: Number evenly disributed lines to snap to.
* @n_snap_lines: Number evenly distributed lines to snap to.
* @offset_angle: The angle by which to offset the lines, in degrees.
* @xres: The horizontal resolution.
* @yres: The vertical resolution.

View File

@@ -55,6 +55,7 @@
#include "gimp-units.h"
#include "gimp-utils.h"
#include "gimpbrush.h"
#include "gimpbrushgenerated.h"
#include "gimpbuffer.h"
#include "gimpcontext.h"
#include "gimpdynamics.h"
@@ -75,6 +76,8 @@
#include "gimptoolinfo.h"
#include "gimptreeproxy.h"
#include "text/gimpfont.h"
#include "gimp-intl.h"
@@ -1269,6 +1272,34 @@ gimp_get_temp_file (Gimp *gimp,
return file;
}
GimpDataFactory *
gimp_get_data_factory (Gimp *gimp,
GType data_type)
{
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (g_type_is_a (data_type, GIMP_TYPE_DATA), NULL);
if (g_type_is_a (data_type, GIMP_TYPE_BRUSH_GENERATED))
return gimp->brush_factory;
else if (g_type_is_a (data_type, GIMP_TYPE_BRUSH))
return gimp->brush_factory;
else if (g_type_is_a (data_type, GIMP_TYPE_PATTERN))
return gimp->pattern_factory;
else if (g_type_is_a (data_type, GIMP_TYPE_GRADIENT))
return gimp->gradient_factory;
else if (g_type_is_a (data_type, GIMP_TYPE_PALETTE))
return gimp->palette_factory;
else if (g_type_is_a (data_type, GIMP_TYPE_FONT))
return gimp->font_factory;
else if (g_type_is_a (data_type, GIMP_TYPE_DYNAMICS))
return gimp->dynamics_factory;
else if (g_type_is_a (data_type, GIMP_TYPE_MYBRUSH))
return gimp->mybrush_factory;
/* If we reach this, it means we forgot a data factory in our list! */
g_return_val_if_reached (NULL);
}
static gboolean
gimp_exit_idle_cleanup_stray_images (Gimp *gimp)
{

View File

@@ -251,3 +251,7 @@ void gimp_image_opened (Gimp *gimp,
GFile * gimp_get_temp_file (Gimp *gimp,
const gchar *extension);
GimpDataFactory *
gimp_get_data_factory (Gimp *gimp,
GType data_type);

View File

@@ -80,8 +80,7 @@ static GimpTempBuf * gimp_brush_get_new_preview (GimpViewable *vie
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
static gchar * gimp_brush_get_description (GimpViewable *viewable,
gchar **tooltip);
@@ -276,8 +275,7 @@ gimp_brush_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background)
GeglColor *fg_color)
{
GimpBrush *brush = GIMP_BRUSH (viewable);
const GimpTempBuf *mask_buf = brush->priv->mask;
@@ -373,10 +371,10 @@ gimp_brush_get_new_preview (GimpViewable *viewable,
}
else
{
guint8 rgb[3] = {0, 0, 0};
guint8 rgb[3] = { 0, 0, 0 };
if (color != NULL)
gegl_color_get_pixel (color, babl_format ("R'G'B' u8"), rgb);
if (fg_color)
gegl_color_get_pixel (fg_color, babl_format ("R'G'B' u8"), rgb);
for (y = 0; y < mask_height; y++)
{

View File

@@ -271,7 +271,7 @@ gimp_brush_pipe_select_brush (GimpBrush *brush,
break;
case PIPE_SELECT_ANGULAR:
/* Coords angle is already nomalized,
/* Coords angle is already normalized,
* offset by 90 degrees is still needed
* because hoses were made PS compatible*/
ix = (gint) RINT ((1.0 - current_coords->direction + 0.25) * pipe->rank[i]) % pipe->rank[i];
@@ -351,8 +351,10 @@ gimp_brush_pipe_set_params (GimpBrushPipe *pipe,
{
GimpPixPipeParams params;
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gimp_pixpipe_params_init (&params);
gimp_pixpipe_params_parse (paramstring, &params);
G_GNUC_END_IGNORE_DEPRECATIONS
pipe->dimension = params.dim;
pipe->rank = g_new0 (gint, pipe->dimension);
@@ -384,7 +386,9 @@ gimp_brush_pipe_set_params (GimpBrushPipe *pipe,
pipe->index[i] = 0;
}
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gimp_pixpipe_params_free (&params);
G_GNUC_END_IGNORE_DEPRECATIONS
pipe->params = g_strdup (paramstring);
}

View File

@@ -64,14 +64,12 @@ static GimpTempBuf * gimp_buffer_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
static GdkPixbuf * gimp_buffer_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
static gchar * gimp_buffer_get_description (GimpViewable *viewable,
gchar **tooltip);
@@ -232,8 +230,7 @@ gimp_buffer_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
GimpBuffer *buffer = GIMP_BUFFER (viewable);
const Babl *format = gimp_buffer_get_format (buffer);
@@ -268,8 +265,7 @@ gimp_buffer_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
GimpBuffer *buffer = GIMP_BUFFER (viewable);
GdkPixbuf *pixbuf;

View File

@@ -87,8 +87,7 @@ static GimpTempBuf * gimp_curve_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
static gchar * gimp_curve_get_description (GimpViewable *viewable,
gchar **tooltip);
@@ -524,8 +523,7 @@ gimp_curve_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
return NULL;
}

View File

@@ -77,6 +77,14 @@ struct _GimpDataFactoryPrivate
GimpAsyncSet *async_set;
};
typedef struct
{
const gchar *name;
const gchar *collection;
gboolean is_internal;
} SearchData;
#define GET_PRIVATE(obj) (((GimpDataFactory *) (obj))->priv)
@@ -109,6 +117,9 @@ static void gimp_data_factory_path_notify (GObject *ob
static GFile * gimp_data_factory_get_save_dir (GimpDataFactory *factory,
GError **error);
static gboolean gimp_data_factory_search_in_container (GimpData *data,
SearchData *search_data);
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GimpDataFactory, gimp_data_factory,
GIMP_TYPE_OBJECT)
@@ -650,6 +661,47 @@ gimp_data_factory_data_cancel (GimpDataFactory *factory)
GIMP_DATA_FACTORY_GET_CLASS (factory)->data_cancel (factory);
}
GimpData *
gimp_data_factory_get_data (GimpDataFactory *factory,
const gchar *name,
const gchar *collection,
gboolean is_internal)
{
GimpContainer *container;
GimpObject *data;
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
container = gimp_data_factory_get_container (factory);
if (collection == NULL)
{
data = gimp_container_get_child_by_name (container, name);
}
else
{
SearchData *search_data = g_new (SearchData, 1);
search_data->name = name;
search_data->collection = collection;
search_data->is_internal = is_internal;
data = gimp_container_search (container,
(GimpContainerSearchFunc) gimp_data_factory_search_in_container,
search_data);
g_free (search_data);
}
if (! data)
data = gimp_container_get_child_by_name (gimp_data_factory_get_container_obsolete (factory),
name);
if (! data && ! strcmp (name, "Standard"))
data = (GimpObject *) gimp_data_factory_data_get_standard (factory,
gimp_get_user_context (factory->priv->gimp));
return (GimpData *) data;
}
gboolean
gimp_data_factory_has_data_new_func (GimpDataFactory *factory)
{
@@ -1038,3 +1090,10 @@ gimp_data_factory_get_save_dir (GimpDataFactory *factory,
return writable_dir;
}
static gboolean
gimp_data_factory_search_in_container (GimpData *data,
SearchData *search_data)
{
return gimp_data_identify (data, search_data->name, search_data->collection, search_data->is_internal);
}

View File

@@ -87,6 +87,11 @@ GimpAsyncSet * gimp_data_factory_get_async_set (GimpDataFactory *factory);
gboolean gimp_data_factory_data_wait (GimpDataFactory *factory);
void gimp_data_factory_data_cancel (GimpDataFactory *factory);
GimpData * gimp_data_factory_get_data (GimpDataFactory *factory,
const gchar *name,
const gchar *collection,
gboolean is_internal);
gboolean gimp_data_factory_has_data_new_func (GimpDataFactory *factory);
GimpData * gimp_data_factory_data_new (GimpDataFactory *factory,
GimpContext *context,

View File

@@ -113,8 +113,7 @@ gimp_drawable_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
GimpItem *item = GIMP_ITEM (viewable);
GimpImage *image = gimp_item_get_image (item);
@@ -135,8 +134,7 @@ gimp_drawable_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
GimpItem *item = GIMP_ITEM (viewable);
GimpImage *image = gimp_item_get_image (item);

View File

@@ -25,14 +25,12 @@ GimpTempBuf * gimp_drawable_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
GdkPixbuf * gimp_drawable_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
/*
* normal functions (no virtuals)

View File

@@ -766,7 +766,7 @@ gimp_drawable_transform_affine (GimpDrawable *drawable,
{
result = gimp_drawable_transform_paste (drawable, new_buffer, profile,
new_offset_x, new_offset_y,
new_layer);
new_layer, TRUE);
g_object_unref (new_buffer);
}
}
@@ -848,7 +848,7 @@ gimp_drawable_transform_flip (GimpDrawable *drawable,
{
result = gimp_drawable_transform_paste (drawable, new_buffer, profile,
new_offset_x, new_offset_y,
new_layer);
new_layer, TRUE);
g_object_unref (new_buffer);
}
}
@@ -933,7 +933,7 @@ gimp_drawable_transform_rotate (GimpDrawable *drawable,
{
result = gimp_drawable_transform_paste (drawable, new_buffer, profile,
new_offset_x, new_offset_y,
new_layer);
new_layer, TRUE);
g_object_unref (new_buffer);
}
}
@@ -1026,11 +1026,11 @@ gimp_drawable_transform_paste (GimpDrawable *drawable,
GimpColorProfile *buffer_profile,
gint offset_x,
gint offset_y,
gboolean new_layer)
gboolean new_layer,
gboolean push_undo)
{
GimpImage *image;
GimpLayer *layer = NULL;
const gchar *undo_desc = NULL;
GimpImage *image;
GimpLayer *layer = NULL;
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
@@ -1039,14 +1039,19 @@ gimp_drawable_transform_paste (GimpDrawable *drawable,
image = gimp_item_get_image (GIMP_ITEM (drawable));
if (GIMP_IS_LAYER (drawable))
undo_desc = C_("undo-type", "Transform Layer");
else if (GIMP_IS_CHANNEL (drawable))
undo_desc = C_("undo-type", "Transform Channel");
else
return NULL;
if (push_undo)
{
const gchar *undo_desc = NULL;
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE, undo_desc);
if (GIMP_IS_LAYER (drawable))
undo_desc = C_("undo-type", "Transform Layer");
else if (GIMP_IS_CHANNEL (drawable))
undo_desc = C_("undo-type", "Transform Channel");
else
return NULL;
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE, undo_desc);
}
if (new_layer)
{
@@ -1066,13 +1071,14 @@ gimp_drawable_transform_paste (GimpDrawable *drawable,
}
else
{
gimp_drawable_set_buffer_full (drawable, TRUE, NULL,
gimp_drawable_set_buffer_full (drawable, push_undo, NULL,
buffer,
GEGL_RECTANGLE (offset_x, offset_y, 0, 0),
TRUE);
}
gimp_image_undo_group_end (image);
if (push_undo)
gimp_image_undo_group_end (image);
return drawable;
}

View File

@@ -87,4 +87,5 @@ GimpDrawable * gimp_drawable_transform_paste (GimpDrawable
GimpColorProfile *buffer_profile,
gint offset_x,
gint offset_y,
gboolean new_layer);
gboolean new_layer,
gboolean push_undo);

View File

@@ -142,7 +142,8 @@ static void gimp_drawable_transform (GimpItem *item,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
GimpProgress *progress);
GimpProgress *progress,
gboolean push_undo);
static const guint8 *
gimp_drawable_get_icc_profile (GimpColorManaged *managed,
@@ -583,7 +584,7 @@ gimp_drawable_duplicate (GimpItem *item,
new_filter = gimp_drawable_filter_duplicate (new_drawable,
filter);
if (filter)
if (new_filter)
{
gimp_drawable_filter_apply (new_filter, NULL);
gimp_drawable_filter_commit (new_filter, TRUE, NULL, FALSE);
@@ -742,7 +743,7 @@ gimp_drawable_flip (GimpItem *item,
if (buffer)
{
gimp_drawable_transform_paste (drawable, buffer, buffer_profile,
new_off_x, new_off_y, FALSE);
new_off_x, new_off_y, FALSE, TRUE);
g_object_unref (buffer);
}
}
@@ -774,7 +775,7 @@ gimp_drawable_rotate (GimpItem *item,
if (buffer)
{
gimp_drawable_transform_paste (drawable, buffer, buffer_profile,
new_off_x, new_off_y, FALSE);
new_off_x, new_off_y, FALSE, TRUE);
g_object_unref (buffer);
}
}
@@ -786,7 +787,8 @@ gimp_drawable_transform (GimpItem *item,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
GimpProgress *progress)
GimpProgress *progress,
gboolean push_undo)
{
GimpDrawable *drawable = GIMP_DRAWABLE (item);
GeglBuffer *buffer;
@@ -809,7 +811,7 @@ gimp_drawable_transform (GimpItem *item,
if (buffer)
{
gimp_drawable_transform_paste (drawable, buffer, buffer_profile,
new_off_x, new_off_y, FALSE);
new_off_x, new_off_y, FALSE, push_undo);
g_object_unref (buffer);
}
}

View File

@@ -56,6 +56,8 @@
#include "gimplist.h"
#include "gimpprogress.h"
#include "gimp-intl.h"
enum
{
@@ -954,9 +956,8 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
* directly with bad data.
*/
g_set_error (error, GIMP_ERROR, GIMP_FAILED,
/* TODO: localize after string freeze. */
"GEGL operation '%s' has been called with a "
"non-existent argument name '%s' (#%d).",
_("GEGL operation '%s' has been called with a "
"non-existent argument name '%s' (#%d)."),
opname, pspec->name, i);
break;
}
@@ -1019,10 +1020,9 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
else if (! G_TYPE_CHECK_VALUE_TYPE (new_value, G_PARAM_SPEC_VALUE_TYPE (pspec)))
{
g_set_error (error, GIMP_ERROR, GIMP_FAILED,
/* TODO: localize after string freeze. */
"GEGL operation '%s' has been called with a "
"wrong value type for argument '%s' (#%d). "
"Expected %s, got %s.",
_("GEGL operation '%s' has been called with a "
"wrong value type for argument '%s' (#%d). "
"Expected %s, got %s."),
opname, pspec->name, i,
g_type_name (pspec->value_type),
g_type_name (G_VALUE_TYPE (new_value)));
@@ -1095,9 +1095,8 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
if (! gegl_node_has_pad (node, auxinputnames[i]))
{
g_set_error (error, GIMP_ERROR, GIMP_FAILED,
/* TODO: localize after string freeze. */
"GEGL operation '%s' has been called with an "
"invalid aux input name '%s'.",
_("GEGL operation '%s' has been called with an "
"invalid aux input name '%s'."),
opname, auxinputnames[i]);
break;
}

View File

@@ -108,8 +108,7 @@ gimp_drawable_filter_mask_rename (GimpItem *item,
GError **error)
{
g_set_error (error, GIMP_ERROR, GIMP_FAILED,
/* TODO: localized after string freeze. */
"Cannot rename effect masks.");
_("Cannot rename effect masks."));
return FALSE;
}

View File

@@ -406,17 +406,26 @@ gimp_extension_load (GimpExtension *extension,
metadata = as_metadata_new ();
success = as_metadata_parse_file (metadata, file, AS_FORMAT_KIND_XML, error);
if (success)
{
#if AS_CHECK_VERSION(1, 0, 0)
components = as_metadata_get_components (metadata);
component = as_component_box_index (components, 0);
components = as_metadata_get_components (metadata);
component = as_component_box_index (components, 0);
#else
components = as_metadata_get_components (metadata);
component = g_ptr_array_index (components, 0);
components = as_metadata_get_components (metadata);
component = g_ptr_array_index (components, 0);
#endif
}
g_object_unref (file);
g_free (path);
if (!success)
{
return success;
}
if (success && as_component_get_kind (component) != AS_COMPONENT_KIND_ADDON)
{
/* Properly setting the type will allow extensions to be

View File

@@ -63,8 +63,7 @@ static GimpTempBuf * gimp_gradient_get_new_preview (GimpViewable *viewa
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
static const gchar * gimp_gradient_get_extension (GimpData *data);
static void gimp_gradient_copy (GimpData *data,
@@ -219,8 +218,7 @@ gimp_gradient_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
GimpGradient *gradient = GIMP_GRADIENT (viewable);
GimpGradientSegment *seg = NULL;

View File

@@ -159,7 +159,8 @@ static void gimp_group_layer_transform (GimpLayer *layer,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
GimpProgress *progress);
GimpProgress *progress,
gboolean push_undo);
static void gimp_group_layer_convert_type (GimpLayer *layer,
GimpImage *dest_image,
const Babl *new_format,
@@ -1016,7 +1017,8 @@ gimp_group_layer_transform (GimpLayer *layer,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
GimpProgress *progress)
GimpProgress *progress,
gboolean push_undo)
{
GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
GimpGroupLayerPrivate *private = GET_PRIVATE (layer);

View File

@@ -152,7 +152,7 @@ gimp_id_table_insert (GimpIdTable *id_table, gpointer data)
* @data: The data to associate with the id
*
* Insert data in the id table with a specific ID. If data already
* exsts with the given ID, this function fails.
* exists with the given ID, this function fails.
*
* Returns: The used ID if successful, -1 if it was already in use.
**/

View File

@@ -2361,6 +2361,8 @@ select_colors_gray (QuantizeObj *quantobj,
/* Compute the representative color for each box, fill colormap */
for (i = 0; i < numboxes; i++)
compute_color_gray (quantobj, histogram, boxlist + i, i);
g_free (boxlist);
}

View File

@@ -122,8 +122,7 @@ gimp_image_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
GimpImage *image = GIMP_IMAGE (viewable);
const Babl *format;
@@ -153,8 +152,7 @@ gimp_image_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
GimpImage *image = GIMP_IMAGE (viewable);
GdkPixbuf *pixbuf;

View File

@@ -41,11 +41,9 @@ GimpTempBuf * gimp_image_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
GdkPixbuf * gimp_image_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);

View File

@@ -48,6 +48,8 @@
#include "gimplayermaskundo.h"
#include "gimplayerpropundo.h"
#include "gimplayerundo.h"
#include "gimplinklayer.h"
#include "gimplinklayerundo.h"
#include "gimpmaskundo.h"
#include "gimpsamplepoint.h"
#include "gimpsamplepointundo.h"
@@ -57,6 +59,8 @@
#include "path/gimppathmodundo.h"
#include "path/gimppathpropundo.h"
#include "path/gimppathundo.h"
#include "path/gimpvectorlayer.h"
#include "path/gimpvectorlayerundo.h"
#include "text/gimptextlayer.h"
#include "text/gimptextundo.h"
@@ -876,6 +880,64 @@ gimp_image_undo_push_text_layer_convert (GimpImage *image,
NULL);
}
/**********************/
/* Link Layer Undos */
/**********************/
GimpUndo *
gimp_image_undo_push_link_layer (GimpImage *image,
const gchar *undo_desc,
GimpLinkLayer *layer)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_LINK_LAYER (layer), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_LINK_LAYER_UNDO,
GIMP_UNDO_LINK_LAYER, undo_desc,
GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE,
"item", layer,
NULL);
}
/************************/
/* Vector Layer Undos */
/************************/
GimpUndo *
gimp_image_undo_push_vector_layer (GimpImage *image,
const gchar *undo_desc,
GimpVectorLayer *layer,
const GParamSpec *pspec)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_VECTOR_LAYER (layer), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_VECTOR_LAYER_UNDO,
GIMP_UNDO_VECTOR_LAYER, undo_desc,
GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE,
"item", layer,
"param", pspec,
NULL);
}
GimpUndo *
gimp_image_undo_push_vector_layer_modified (GimpImage *image,
const gchar *undo_desc,
GimpVectorLayer *layer)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_VECTOR_LAYER (layer), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_VECTOR_LAYER_UNDO,
GIMP_UNDO_VECTOR_LAYER_MODIFIED, undo_desc,
GIMP_DIRTY_ITEM_META,
"item", layer,
NULL);
}
/**********************/
/* Layer Mask Undos */
@@ -898,6 +960,7 @@ gimp_image_undo_push_layer_mask_add (GimpImage *image,
GIMP_DIRTY_IMAGE_STRUCTURE,
"item", layer,
"layer-mask", mask,
"edit-mask", FALSE,
NULL);
}
@@ -920,6 +983,7 @@ gimp_image_undo_push_layer_mask_remove (GimpImage *image,
GIMP_DIRTY_IMAGE_STRUCTURE,
"item", layer,
"layer-mask", mask,
"edit-mask", gimp_layer_get_edit_mask (layer),
NULL);
}

View File

@@ -214,6 +214,22 @@ GimpUndo * gimp_image_undo_push_text_layer_convert (GimpImage *image,
const gchar *undo_desc,
GimpTextLayer *layer);
/* link layer undos */
GimpUndo * gimp_image_undo_push_link_layer (GimpImage *image,
const gchar *undo_desc,
GimpLinkLayer *layer);
/* vector layer undos */
GimpUndo * gimp_image_undo_push_vector_layer (GimpImage *image,
const gchar *undo_desc,
GimpVectorLayer *layer,
const GParamSpec *pspec);
GimpUndo * gimp_image_undo_push_vector_layer_modified
(GimpImage *image,
const gchar *undo_desc,
GimpVectorLayer *layer);
/* layer mask undos */

View File

@@ -71,6 +71,7 @@
#include "gimplayer-floating-selection.h"
#include "gimplayermask.h"
#include "gimplayerstack.h"
#include "gimplinklayer.h"
#include "gimpmarshal.h"
#include "gimppalette.h"
#include "gimpparasitelist.h"
@@ -87,6 +88,7 @@
#include "text/gimptextlayer.h"
#include "path/gimppath.h"
#include "path/gimpvectorlayer.h"
#include "gimp-log.h"
#include "gimp-intl.h"
@@ -3010,11 +3012,27 @@ gimp_image_get_xcf_version (GimpImage *image,
/* The blending space variant corresponding to SPACE_RGB_PERCEPTUAL in <3.0
* corresponds to R'G'B'A which is NON_LINEAR in babl. Perceptual in babl is
* R~G~B~A, >= 3.0 the code, comments and usage matches the existing enum value
* as being NON_LINEAR and new layers created use the new interger value for
* as being NON_LINEAR and new layers created use the new integer value for
* PERCEPTUAL.
*/
version = MAX (23, version);
}
/* Need version 24 for vector layers. */
if (GIMP_IS_VECTOR_LAYER (layer))
{
ADD_REASON (g_strdup_printf (_("Vector layers were added in %s"),
"GIMP 3.2"));
version = MAX (24, version);
}
/* Need version 25 for link layers. */
if (GIMP_IS_LINK_LAYER (layer))
{
ADD_REASON (g_strdup_printf (_("Link layers were added in %s"),
"GIMP 3.2"));
version = MAX (25, version);
}
}
g_list_free (items);
@@ -3148,7 +3166,7 @@ gimp_image_get_xcf_version (GimpImage *image,
/* Note: user unit storage was changed in XCF 21, but we can still
* easily save older XCF (we use the unit name for both singular and
* plural forms). Therefore we don't bump the XCF version unecessarily
* plural forms). Therefore we don't bump the XCF version unnecessarily
* and don't add any test.
*/
@@ -3194,6 +3212,11 @@ gimp_image_get_xcf_version (GimpImage *image,
if (gimp_version) *gimp_version = 300;
if (version_string) *version_string = "GIMP 3.0";
break;
case 24:
case 25:
if (gimp_version) *gimp_version = 320;
if (version_string) *version_string = "GIMP 3.2";
break;
}
if (version_reason && reasons)
@@ -5457,6 +5480,17 @@ gimp_image_add_layer (GimpImage *image,
gimp_drawable_attach_floating_sel (gimp_layer_get_floating_sel_drawable (layer),
layer);
/* If the layer is a vector layer, also add its path to the image */
if (gimp_item_is_vector_layer (GIMP_ITEM (layer)))
{
GimpPath *path = gimp_vector_layer_get_path (GIMP_VECTOR_LAYER (layer));
if (path &&
(! gimp_item_is_attached (GIMP_ITEM (path))) &&
gimp_item_get_image (GIMP_ITEM (path)) == image)
gimp_image_add_path (image, path, NULL, -1, FALSE);
}
if (old_has_alpha != gimp_image_has_alpha (image))
private->flush_accum.alpha_changed = TRUE;

View File

@@ -71,6 +71,10 @@ struct _GimpImagefilePrivate
gchar *description;
gboolean static_desc;
gint popup_size;
gint popup_width;
gint popup_height;
};
#define GET_PRIVATE(imagefile) ((GimpImagefilePrivate *) gimp_imagefile_get_instance_private ((GimpImagefile *) (imagefile)))
@@ -81,12 +85,17 @@ static void gimp_imagefile_finalize (GObject *object);
static void gimp_imagefile_name_changed (GimpObject *object);
static gboolean gimp_imagefile_get_popup_size (GimpViewable *viewable,
gint width,
gint height,
gboolean dot_for_dot,
gint *popup_width,
gint *popup_height);
static GdkPixbuf * gimp_imagefile_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
static gchar * gimp_imagefile_get_description (GimpViewable *viewable,
gchar **tooltip);
@@ -147,6 +156,7 @@ gimp_imagefile_class_init (GimpImagefileClass *klass)
gimp_object_class->name_changed = gimp_imagefile_name_changed;
viewable_class->name_changed_signal = "info-changed";
viewable_class->get_popup_size = gimp_imagefile_get_popup_size;
viewable_class->get_new_pixbuf = gimp_imagefile_get_new_pixbuf;
viewable_class->get_description = gimp_imagefile_get_description;
@@ -222,13 +232,34 @@ gimp_imagefile_name_changed (GimpObject *object)
private->file = g_file_new_for_uri (gimp_object_get_name (object));
}
static gboolean
gimp_imagefile_get_popup_size (GimpViewable *viewable,
gint width,
gint height,
gboolean dot_for_dot,
gint *popup_width,
gint *popup_height)
{
GimpImagefilePrivate *private = GET_PRIVATE (viewable);
if (width < private->popup_width ||
height < private->popup_height)
{
*popup_width = private->popup_width;
*popup_height = private->popup_height;
return TRUE;
}
return FALSE;
}
static GdkPixbuf *
gimp_imagefile_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
GimpImagefile *imagefile = GIMP_IMAGEFILE (viewable);
@@ -517,10 +548,10 @@ gimp_imagefile_create_thumbnail (GimpImagefile *imagefile,
}
image = file_open_image (private->gimp, context, progress,
private->file, size, size,
private->file, size, size, TRUE,
FALSE, NULL,
GIMP_RUN_NONINTERACTIVE,
&status, &mime_type, error);
NULL, &status, &mime_type, error);
if (image)
gimp_thumbnail_set_info_from_image (private->thumbnail,
@@ -931,11 +962,9 @@ gimp_imagefile_load_thumb (GimpImagefile *imagefile,
gchar *image_uri;
gint image_width;
gint image_height;
GdkPixbuf *pixbuf = NULL;
GError *error = NULL;
gint size = MAX (width, height);
gint pixbuf_width;
gint pixbuf_height;
GdkPixbuf *pixbuf = NULL;
GError *error = NULL;
gint size;
gint preview_width;
gint preview_height;
@@ -946,6 +975,19 @@ gimp_imagefile_load_thumb (GimpImagefile *imagefile,
"image-height", &image_height,
NULL);
/* use the size remembered below if a pixbuf of the remembered
* dimensions is requested
*/
if (width == private->popup_width &&
height == private->popup_height)
{
size = private->popup_size;
}
else
{
size = MAX (width, height);
}
if (gimp_thumbnail_peek_thumb (thumbnail, size) < GIMP_THUMB_STATE_EXISTS)
return NULL;
@@ -975,11 +1017,16 @@ gimp_imagefile_load_thumb (GimpImagefile *imagefile,
return NULL;
}
pixbuf_width = gdk_pixbuf_get_width (pixbuf);
pixbuf_height = gdk_pixbuf_get_height (pixbuf);
/* remember the actual dimensions of the returned pixbuf, and the
* size used to request it, so we can later use that size to get a
* popup.
*/
private->popup_size = size;
private->popup_width = gdk_pixbuf_get_width (pixbuf);
private->popup_height = gdk_pixbuf_get_height (pixbuf);
gimp_viewable_calc_preview_size (pixbuf_width,
pixbuf_height,
gimp_viewable_calc_preview_size (private->popup_width,
private->popup_height,
width,
height,
TRUE, 1.0, 1.0,
@@ -987,7 +1034,8 @@ gimp_imagefile_load_thumb (GimpImagefile *imagefile,
&preview_height,
NULL);
if (preview_width < pixbuf_width || preview_height < pixbuf_height)
if (preview_width != private->popup_width ||
preview_height != private->popup_height)
{
GdkPixbuf *scaled = gdk_pixbuf_scale_simple (pixbuf,
preview_width,
@@ -995,18 +1043,15 @@ gimp_imagefile_load_thumb (GimpImagefile *imagefile,
GDK_INTERP_BILINEAR);
g_object_unref (pixbuf);
pixbuf = scaled;
pixbuf_width = preview_width;
pixbuf_height = preview_height;
}
if (gdk_pixbuf_get_n_channels (pixbuf) != 3)
{
GdkPixbuf *tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
pixbuf_width, pixbuf_height);
preview_width, preview_height);
gdk_pixbuf_composite_color (pixbuf, tmp,
0, 0, pixbuf_width, pixbuf_height,
0, 0, preview_width, preview_height,
0.0, 0.0, 1.0, 1.0,
GDK_INTERP_NEAREST, 255,
0, 0, GIMP_CHECK_SIZE_SM,
@@ -1065,7 +1110,7 @@ gimp_imagefile_save_thumb (GimpImagefile *imagefile,
pixbuf = gimp_viewable_get_new_pixbuf (GIMP_VIEWABLE (image),
/* random context, unused */
gimp_get_user_context (image->gimp),
width, height, NULL, NULL);
width, height, NULL);
/* when layer previews are disabled, we won't get a pixbuf */
if (! pixbuf)

View File

@@ -94,14 +94,12 @@ static GimpTempBuf * gimp_image_proxy_get_new_preview (GimpViewabl
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
static GdkPixbuf * gimp_image_proxy_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
static gchar * gimp_image_proxy_get_description (GimpViewable *viewable,
gchar **tooltip);
@@ -378,8 +376,7 @@ gimp_image_proxy_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (viewable);
GimpImage *image = image_proxy->priv->image;
@@ -421,8 +418,7 @@ gimp_image_proxy_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
GimpImageProxy *image_proxy = GIMP_IMAGE_PROXY (viewable);
GimpImage *image = image_proxy->priv->image;

View File

@@ -1777,7 +1777,7 @@ gimp_item_transform (GimpItem *item,
g_object_freeze_notify (G_OBJECT (item));
item_class->transform (item, context, matrix, direction, interpolation,
clip_result, progress);
clip_result, progress, TRUE);
g_object_thaw_notify (G_OBJECT (item));
@@ -2650,7 +2650,8 @@ gimp_item_mask_bounds (GimpItem *item,
! gimp_channel_is_empty (selection) &&
gimp_item_bounds (GIMP_ITEM (selection), &x, &y, &width, &height))
{
gint off_x, off_y;
gint off_x = 0;
gint off_y = 0;
gint x2, y2;
gimp_item_get_offset (item, &off_x, &off_y);
@@ -2724,7 +2725,8 @@ gimp_item_mask_intersect (GimpItem *item,
gimp_item_bounds (GIMP_ITEM (selection),
&tmp_x, &tmp_y, &tmp_width, &tmp_height))
{
gint off_x, off_y;
gint off_x = 0;
gint off_y = 0;
gimp_item_get_offset (item, &off_x, &off_y);

View File

@@ -107,7 +107,8 @@ struct _GimpItemClass
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
GimpProgress *progress);
GimpProgress *progress,
gboolean push_undo);
GimpTransformResize (* get_clip) (GimpItem *item,
GimpTransformResize clip_result);
gboolean (* fill) (GimpItem *item,

111
app/core/gimplayer-xcf.c Normal file
View File

@@ -0,0 +1,111 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimplayer-xcf.c
*
* Copyright 2003 Sven Neumann <sven@gimp.org>
* Copyright 2025 Jehan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "core-types.h"
#include "gimpimage.h"
#include "gimplayer.h"
#include "gimplayer-xcf.h"
/**
* gimp_layer_from_layer:
* @layer: a #GimpLayer object
* @options: a #GimpVectorLayerOptions object
*
* Converts a standard #GimpLayer into a more specific type of
* #GimpLayer. The new layer takes ownership of properties of @layer.
* The @layer object is rendered unusable by this function. Don't even
* try to use it afterwards!
*
* This is a gross hack that is needed in order to load text or vector
* layers from XCF files in a backwards-compatible way, or as a
* secondary step (after more data has been loaded). Please don't use it
* for anything else!
*
* The variable list of arguments will be the properties which will be
* used to create the new layer of type @new_layer_type. Note that the
* "image" property needs to be set at the minimum.
*
* Return value: a newly allocated object of a subtype of #GimpLayer.
**/
GimpLayer *
gimp_layer_from_layer (GimpLayer *layer,
GType new_layer_type,
...)
{
GimpLayer *new_layer;
GimpDrawable *drawable;
GimpImage *image;
gboolean attached;
GimpLayer *parent = NULL;
gint position = 0;
va_list args;
const gchar *first_prop;
g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL);
g_return_val_if_fail (g_type_is_a (new_layer_type, GIMP_TYPE_LAYER), NULL);
image = gimp_item_get_image (GIMP_ITEM (layer));
if ((attached = gimp_item_is_attached (GIMP_ITEM (layer))))
{
parent = gimp_layer_get_parent (layer);
position = gimp_item_get_index (GIMP_ITEM (layer));
g_object_ref (layer);
gimp_image_remove_layer (image, layer, FALSE, NULL);
}
va_start (args, new_layer_type);
first_prop = va_arg (args, gchar *);
new_layer = GIMP_LAYER (g_object_new_valist (new_layer_type, first_prop, args));
va_end (args);
gimp_item_replace_item (GIMP_ITEM (new_layer), GIMP_ITEM (layer));
drawable = GIMP_DRAWABLE (new_layer);
gimp_drawable_steal_buffer (drawable, GIMP_DRAWABLE (layer));
gimp_layer_set_opacity (GIMP_LAYER (new_layer),
gimp_layer_get_opacity (layer), FALSE);
gimp_layer_set_mode (GIMP_LAYER (new_layer),
gimp_layer_get_mode (layer), FALSE);
gimp_layer_set_blend_space (GIMP_LAYER (new_layer),
gimp_layer_get_blend_space (layer), FALSE);
gimp_layer_set_composite_space (GIMP_LAYER (new_layer),
gimp_layer_get_composite_space (layer), FALSE);
gimp_layer_set_composite_mode (GIMP_LAYER (new_layer),
gimp_layer_get_composite_mode (layer), FALSE);
gimp_layer_set_lock_alpha (GIMP_LAYER (new_layer),
gimp_layer_get_lock_alpha (layer), FALSE);
g_object_unref (layer);
if (attached)
gimp_image_add_layer (image, new_layer, parent, position, FALSE);
return new_layer;
}

27
app/core/gimplayer-xcf.h Normal file
View File

@@ -0,0 +1,27 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimplayer-xcf.h
*
* Copyright 2003 Sven Neumann <sven@gimp.org>
* Copyright 2025 Jehan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
GimpLayer * gimp_layer_from_layer (GimpLayer *layer,
GType new_layer_type,
...) G_GNUC_NULL_TERMINATED;

View File

@@ -169,7 +169,8 @@ static void gimp_layer_transform (GimpItem *item,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
GimpProgress *progress);
GimpProgress *progress,
gboolean push_undo);
static void gimp_layer_to_selection (GimpItem *item,
GimpChannelOps op,
gboolean antialias,
@@ -248,7 +249,8 @@ static void gimp_layer_real_transform (GimpLayer *layer,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
GimpProgress *progress);
GimpProgress *progress,
gboolean push_undo);
static void gimp_layer_real_convert_type (GimpLayer *layer,
GimpImage *dest_image,
const Babl *new_format,
@@ -989,10 +991,10 @@ gimp_layer_duplicate (GimpItem *item,
mask = gimp_item_duplicate (GIMP_ITEM (layer->mask),
G_TYPE_FROM_INSTANCE (layer->mask));
gimp_layer_add_mask (new_layer, GIMP_LAYER_MASK (mask), FALSE, NULL);
gimp_layer_add_mask (new_layer, GIMP_LAYER_MASK (mask),
layer->edit_mask, FALSE, NULL);
new_layer->apply_mask = layer->apply_mask;
new_layer->edit_mask = layer->edit_mask;
new_layer->show_mask = layer->show_mask;
}
}
@@ -1298,7 +1300,8 @@ gimp_layer_transform (GimpItem *item,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
GimpProgress *progress)
GimpProgress *progress,
gboolean push_undo)
{
GimpLayer *layer = GIMP_LAYER (item);
GimpObjectQueue *queue = NULL;
@@ -1328,7 +1331,7 @@ gimp_layer_transform (GimpItem *item,
GIMP_LAYER_GET_CLASS (layer)->transform (layer, context, matrix, direction,
interpolation_type,
clip_result,
progress);
progress, push_undo);
if (layer->mask)
{
@@ -1743,7 +1746,8 @@ gimp_layer_real_transform (GimpLayer *layer,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
GimpProgress *progress)
GimpProgress *progress,
gboolean push_undo)
{
if (! gimp_matrix3_is_simple (matrix) &&
! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
@@ -1753,7 +1757,7 @@ gimp_layer_real_transform (GimpLayer *layer,
context, matrix, direction,
interpolation_type,
clip_result,
progress);
progress, push_undo);
}
static void
@@ -1913,6 +1917,7 @@ gimp_layer_get_mask (GimpLayer *layer)
GimpLayerMask *
gimp_layer_add_mask (GimpLayer *layer,
GimpLayerMask *mask,
gboolean edit_mask,
gboolean push_undo,
GError **error)
{
@@ -1954,7 +1959,7 @@ gimp_layer_add_mask (GimpLayer *layer,
layer->mask = g_object_ref_sink (mask);
layer->apply_mask = TRUE;
layer->edit_mask = TRUE;
layer->edit_mask = edit_mask;
layer->show_mask = FALSE;
gimp_layer_mask_set_layer (mask, layer);

View File

@@ -122,7 +122,8 @@ struct _GimpLayerClass
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
GimpProgress *progress);
GimpProgress *progress,
gboolean push_undo);
void (* convert_type) (GimpLayer *layer,
GimpImage *dest_image,
const Babl *new_format,
@@ -158,6 +159,7 @@ GimpLayerMask * gimp_layer_create_mask (GimpLayer *layer,
GimpChannel *channel);
GimpLayerMask * gimp_layer_add_mask (GimpLayer *layer,
GimpLayerMask *mask,
gboolean edit_mask,
gboolean push_undo,
GError **error);
void gimp_layer_apply_mask (GimpLayer *layer,

View File

@@ -33,7 +33,8 @@
enum
{
PROP_0,
PROP_LAYER_MASK
PROP_LAYER_MASK,
PROP_EDIT_MASK
};
@@ -83,6 +84,11 @@ gimp_layer_mask_undo_class_init (GimpLayerMaskUndoClass *klass)
GIMP_TYPE_LAYER_MASK,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_EDIT_MASK,
g_param_spec_boolean ("edit-mask", NULL, NULL,
FALSE,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
@@ -114,6 +120,9 @@ gimp_layer_mask_undo_set_property (GObject *object,
case PROP_LAYER_MASK:
layer_mask_undo->layer_mask = g_value_dup_object (value);
break;
case PROP_EDIT_MASK:
layer_mask_undo->edit_mask = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -134,6 +143,9 @@ gimp_layer_mask_undo_get_property (GObject *object,
case PROP_LAYER_MASK:
g_value_set_object (value, layer_mask_undo->layer_mask);
break;
case PROP_EDIT_MASK:
g_value_set_boolean (value, layer_mask_undo->edit_mask);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -175,13 +187,15 @@ gimp_layer_mask_undo_pop (GimpUndo *undo,
{
/* remove layer mask */
layer_mask_undo->edit_mask = gimp_layer_get_edit_mask (layer);
gimp_layer_apply_mask (layer, GIMP_MASK_DISCARD, FALSE);
}
else
{
/* restore layer mask */
gimp_layer_add_mask (layer, layer_mask_undo->layer_mask, FALSE, NULL);
gimp_layer_add_mask (layer, layer_mask_undo->layer_mask,
layer_mask_undo->edit_mask, FALSE, NULL);
}
}

View File

@@ -36,6 +36,7 @@ struct _GimpLayerMaskUndo
GimpItemUndo parent_instance;
GimpLayerMask *layer_mask;
gboolean edit_mask;
};
struct _GimpLayerMaskUndoClass

748
app/core/gimplink.c Normal file
View File

@@ -0,0 +1,748 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpLink
* Copyright (C) 2019 Jehan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <cairo.h>
#include <gegl.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "libgimpbase/gimpbase.h"
#include "core-types.h"
#include "gimp.h"
#include "gimpimage.h"
#include "gimplink.h"
#include "gimpmarshal.h"
#include "gimppickable.h"
#include "gimpprojection.h"
#include "file/file-open.h"
#include "gimp-intl.h"
enum
{
PROP_0,
PROP_GIMP,
PROP_FILE,
PROP_ABSOLUTE_PATH,
N_PROPS
};
enum
{
CHANGED,
LAST_SIGNAL
};
struct _GimpLinkPrivate
{
Gimp *gimp;
GFile *file;
GFileMonitor *monitor;
gboolean absolute_path;
GeglBuffer *buffer;
gboolean broken;
GError *error;
guint idle_changed_source;
gboolean is_vector;
gint width;
gint height;
gboolean keep_ratio;
GimpImageBaseType base_type;
GimpPrecision precision;
GimpPlugInProcedure *load_proc;
const gchar *mime_type;
};
static void gimp_link_finalize (GObject *object);
static void gimp_link_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_link_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_link_file_changed (GFileMonitor *monitor,
GFile *file,
GFile *other_file,
GFileMonitorEvent event_type,
GimpLink *link);
static gboolean gimp_link_emit_changed (gpointer data);
static void gimp_link_update_buffer (GimpLink *link,
GimpProgress *progress,
GError **error);
static void gimp_link_start_monitoring (GimpLink *link);
static gchar * gimp_link_get_relative_path (GimpLink *link,
GFile *parent,
gint n_back);
G_DEFINE_TYPE_WITH_PRIVATE (GimpLink, gimp_link, GIMP_TYPE_OBJECT)
#define parent_class gimp_link_parent_class
static guint link_signals[LAST_SIGNAL] = { 0 };
static GParamSpec *link_props[N_PROPS] = { NULL, };
static void
gimp_link_class_init (GimpLinkClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
link_signals[CHANGED] =
g_signal_new ("changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpLinkClass, changed),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
object_class->finalize = gimp_link_finalize;
object_class->get_property = gimp_link_get_property;
object_class->set_property = gimp_link_set_property;
link_props[PROP_GIMP] = g_param_spec_object ("gimp", NULL, NULL,
GIMP_TYPE_GIMP,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY);
link_props[PROP_FILE] = g_param_spec_object ("file", NULL, NULL,
G_TYPE_FILE,
GIMP_PARAM_READWRITE |
G_PARAM_EXPLICIT_NOTIFY);
link_props[PROP_ABSOLUTE_PATH] = g_param_spec_boolean ("absolute-path", NULL, NULL,
FALSE,
GIMP_PARAM_READWRITE);
g_object_class_install_properties (object_class, N_PROPS, link_props);
}
static void
gimp_link_init (GimpLink *link)
{
link->p = gimp_link_get_instance_private (link);
link->p->gimp = NULL;
link->p->file = NULL;
link->p->monitor = NULL;
link->p->buffer = NULL;
link->p->broken = TRUE;
link->p->error = NULL;
link->p->width = 0;
link->p->height = 0;
link->p->base_type = GIMP_RGB;
link->p->precision = GIMP_PRECISION_U8_PERCEPTUAL;
link->p->load_proc = NULL;
link->p->idle_changed_source = 0;
}
static void
gimp_link_finalize (GObject *object)
{
GimpLink *link = GIMP_LINK (object);
g_clear_object (&link->p->file);
g_clear_object (&link->p->monitor);
g_clear_object (&link->p->buffer);
g_clear_error (&link->p->error);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_link_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpLink *link = GIMP_LINK (object);
switch (property_id)
{
case PROP_GIMP:
g_value_set_object (value, link->p->gimp);
break;
case PROP_FILE:
g_value_set_object (value, link->p->file);
break;
case PROP_ABSOLUTE_PATH:
g_value_set_boolean (value, link->p->absolute_path);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_link_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpLink *link = GIMP_LINK (object);
switch (property_id)
{
case PROP_GIMP:
link->p->gimp = g_value_get_object (value);
break;
case PROP_FILE:
gimp_link_set_file (link, g_value_get_object (value), 0, 0, FALSE, NULL, NULL);
break;
case PROP_ABSOLUTE_PATH:
link->p->absolute_path = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_link_file_changed (GFileMonitor *monitor,
GFile *file,
GFile *other_file,
GFileMonitorEvent event_type,
GimpLink *link)
{
switch (event_type)
{
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
if (link->p->idle_changed_source == 0)
link->p->idle_changed_source = g_idle_add_full (G_PRIORITY_LOW,
gimp_link_emit_changed,
link, NULL);
break;
case G_FILE_MONITOR_EVENT_CREATED:
g_signal_emit (link, link_signals[CHANGED], 0);
break;
case G_FILE_MONITOR_EVENT_DELETED:
link->p->broken = TRUE;
g_clear_error (&link->p->error);
g_set_error_literal (&link->p->error,
G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("The file got deleted"));
break;
default:
/* No need to signal for changes where nothing can be done anyway.
* In particular a file deletion, the link is broken, yet we don't
* want to re-render.
* Don't emit either on G_FILE_MONITOR_EVENT_CHANGED because too
* many such events may be emitted for a single file writing.
*/
break;
}
}
static gboolean
gimp_link_emit_changed (gpointer data)
{
GimpLink *link = GIMP_LINK (data);
gimp_link_update_buffer (link, NULL, NULL);
g_signal_emit (link, link_signals[CHANGED], 0);
link->p->idle_changed_source = 0;
return G_SOURCE_REMOVE;
}
static void
gimp_link_update_buffer (GimpLink *link,
GimpProgress *progress,
GError **error)
{
GeglBuffer *buffer = NULL;
GError *real_error = NULL;
g_return_if_fail (GIMP_IS_LINK (link));
g_return_if_fail (error == NULL || *error == NULL);
link->p->is_vector = FALSE;
g_clear_error (&link->p->error);
if (link->p->file)
{
GimpImage *image;
GimpPDBStatusType status;
link->p->mime_type = NULL;
image = file_open_image (link->p->gimp,
gimp_get_user_context (link->p->gimp),
progress,
link->p->file,
link->p->width, link->p->height,
link->p->keep_ratio,
FALSE, NULL,
/* XXX We might want interactive opening
* for a first opening (when done through
* GUI), but not for every re-render.
*/
GIMP_RUN_NONINTERACTIVE,
&link->p->is_vector,
&status, &link->p->mime_type,
&real_error);
if (image && status == GIMP_PDB_SUCCESS)
{
/* If we don't flush the projection first, the buffer may be empty.
* I do wonder if the flushing and updating of the link could
* not be multi-threaded with gimp_projection_flush() instead,
* then notifying the update through signals. For very heavy
* images, would it be a better UX? XXX
*/
gimp_projection_flush_now (gimp_image_get_projection (image), TRUE);
buffer = gimp_pickable_get_buffer (GIMP_PICKABLE (image));
g_object_ref (buffer);
link->p->base_type = gimp_image_get_base_type (image);
link->p->precision = gimp_image_get_precision (image);
link->p->width = gimp_image_get_width (image);
link->p->height = gimp_image_get_height (image);
link->p->load_proc = gimp_image_get_load_proc (image);
}
/* Only keep the buffer, free the rest. */
g_clear_object (&image);
}
link->p->broken = (buffer == NULL);
if (link->p->broken)
{
if (real_error)
link->p->error = g_error_copy (real_error);
else
g_set_error_literal (&link->p->error,
G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("No file was set"));
}
if (error)
*error = real_error;
else
g_clear_error (&real_error);
if (buffer)
{
/* Keep the old buffer if the link is broken (outdated image is
* better than none).
*/
g_clear_object (&link->p->buffer);
link->p->buffer = buffer;
}
}
static void
gimp_link_start_monitoring (GimpLink *link)
{
link->p->monitor = g_file_monitor_file (link->p->file,
G_FILE_MONITOR_WATCH_HARD_LINKS,
NULL, NULL);
g_signal_connect (link->p->monitor, "changed",
G_CALLBACK (gimp_link_file_changed),
link);
}
/**
* gimp_link_get_relative_path:
* @link: the image this link is associated with.
* @parent: (transfer full): a #GFile object.
* @n_back: set it to 0 when calling it initially.
*
* This is a variant of g_file_get_relative_path() which will work even
* when the @link file is not a child of @parent. In this case, the
* relative link will use "../" as many times as necessary until a
* common parent folder is found.
*
* In case no parent is found (it may happen for instance on Windows,
* with various file system roots), an absolute path is returned
* instead, ensuring that we never return %NULL.
*
* Note that this function takes ownership of @parent and will take care
* of freeing it. This allows for tail recursion.
*
* Returns: a path from @link relatively to @parent, falling back
* to an absolute path if a relative path cannot be constructed.
**/
static gchar *
gimp_link_get_relative_path (GimpLink *link,
GFile *parent,
gint n_back)
{
gchar *relative_path;
g_return_val_if_fail (GIMP_IS_LINK (link), NULL);
g_return_val_if_fail (parent != NULL && n_back >= 0, NULL);
relative_path = g_file_get_relative_path (parent, link->p->file);
if (relative_path == NULL)
{
GFile *grand_parent = g_file_get_parent (parent);
g_object_unref (parent);
if (grand_parent == NULL)
/* This may happen e.g. on Windows where there are several roots
* so it is not always possible to make a relative path.
*/
return g_file_get_path (link->p->file);
else
return gimp_link_get_relative_path (link, grand_parent, n_back + 1);
}
else
{
g_object_unref (parent);
if (n_back > 0)
{
GStrvBuilder *builder;
gchar **array;
gchar *dots;
gchar *relpath;
builder = g_strv_builder_new ();
for (gint i = 0; i < n_back; i++)
g_strv_builder_add (builder, "..");
array = g_strv_builder_end (builder);
dots = g_strjoinv (G_DIR_SEPARATOR_S, array);
relpath = g_build_filename (dots, relative_path, NULL);
g_free (relative_path);
g_free (dots);
g_strfreev (array);
g_strv_builder_unref (builder);
relative_path = relpath;
}
return relative_path;
}
}
/* public functions */
/**
* gimp_link_new:
* @gimp: #Gimp object.
* @file: a #GFile object.
*
* Creates a new link object. By default, all link objects are created
* as being relative to the path of the image they will be associated
* with.
*
* Return value: a new #GimpLink or %NULL in case of a problem
**/
GimpLink *
gimp_link_new (Gimp *gimp,
GFile *file,
gint vector_width,
gint vector_height,
gboolean keep_ratio,
GimpProgress *progress,
GError **error)
{
GimpLink *link;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (G_IS_FILE (file), NULL);
link = g_object_new (GIMP_TYPE_LINK,
"gimp", gimp,
"absolute-path", FALSE,
NULL);
gimp_link_set_file (link, file, vector_width, vector_height, keep_ratio, progress, error);
return GIMP_LINK (link);
}
GimpLink *
gimp_link_duplicate (GimpLink *link)
{
GimpLink *new_link;
g_return_val_if_fail (GIMP_IS_LINK (link), NULL);
new_link = g_object_new (GIMP_TYPE_LINK,
"gimp", link->p->gimp,
"absolute-path", gimp_link_get_absolute_path (link),
NULL);
/* Copy things manually as we do not need to trigger a load. */
new_link->p->file = link->p->file ? g_object_ref (link->p->file) : NULL;
new_link->p->buffer = link->p->buffer ? gegl_buffer_dup (link->p->buffer) : NULL;
new_link->p->broken = link->p->broken;
new_link->p->error = link->p->error ? g_error_copy (link->p->error) : NULL;
new_link->p->is_vector = link->p->is_vector;
new_link->p->width = link->p->width;
new_link->p->height = link->p->height;
new_link->p->base_type = link->p->base_type;
new_link->p->precision = link->p->precision;
new_link->p->load_proc = link->p->load_proc;
if (new_link->p->file)
{
gchar *basename;
basename = g_file_get_basename (new_link->p->file);
gimp_object_set_name_safe (GIMP_OBJECT (new_link), basename);
g_free (basename);
if (gimp_link_is_monitored (link))
gimp_link_start_monitoring (new_link);
}
return new_link;
}
/*
* gimp_link_get_file:
* @link: the #GimpLink object.
* @xcf_file: optional XCF file from which @path will be relative to.
* @path: optional returned path of the returned file.
*
* If @path is non-%NULL, it will be set to the file system path for the
* returned %GFile, either as an absolute or relative path, depending on
* how @link was set.
* Note that it is possible for @path to be absolute even when it is set
* to be a relative path, in cases where no relative path can be
* constructed from @xcf_file.
*
* Returns: the %GFile which %link is syncing too.
*/
GFile *
gimp_link_get_file (GimpLink *link,
GFile *xcf_file,
gchar **path)
{
g_return_val_if_fail (GIMP_IS_LINK (link), NULL);
g_return_val_if_fail ((path == NULL && xcf_file == NULL) ||
(*path == NULL && xcf_file != NULL &&
g_file_has_parent (xcf_file, NULL)), NULL);
if (path != NULL)
{
if (link->p->absolute_path)
*path = g_file_get_path (link->p->file);
else
*path = gimp_link_get_relative_path (link,
g_file_get_parent (xcf_file),
0);
}
return link->p->file;
}
void
gimp_link_set_file (GimpLink *link,
GFile *file,
gint vector_width,
gint vector_height,
gboolean keep_ratio,
GimpProgress *progress,
GError **error)
{
g_return_if_fail (GIMP_IS_LINK (link));
g_return_if_fail (G_IS_FILE (file) || file == NULL);
g_return_if_fail (error == NULL || *error == NULL);
if (file == link->p->file ||
(file && link->p->file && g_file_equal (file, link->p->file)))
{
if (link->p->width != vector_width ||
link->p->height != vector_height ||
link->p->keep_ratio != keep_ratio)
gimp_link_set_size (link, vector_width, vector_height, keep_ratio);
return;
}
link->p->width = vector_width;
link->p->height = vector_height;
link->p->keep_ratio = keep_ratio;
g_clear_object (&link->p->monitor);
g_set_object (&link->p->file, file);
gimp_link_update_buffer (link, progress, error);
if (link->p->file)
{
gchar *basename;
basename = g_file_get_basename (link->p->file);
gimp_object_set_name_safe (GIMP_OBJECT (link), basename);
g_free (basename);
gimp_link_start_monitoring (link);
}
g_object_notify_by_pspec (G_OBJECT (link), link_props[PROP_FILE]);
}
gboolean
gimp_link_get_absolute_path (GimpLink *link)
{
g_return_val_if_fail (GIMP_IS_LINK (link), FALSE);
return link->p->absolute_path;
}
void
gimp_link_set_absolute_path (GimpLink *link,
gboolean absolute_path)
{
g_return_if_fail (GIMP_IS_LINK (link));
link->p->absolute_path = absolute_path;
}
const gchar *
gimp_link_get_mime_type (GimpLink *link)
{
g_return_val_if_fail (GIMP_IS_LINK (link), NULL);
return link->p->mime_type;
}
void
gimp_link_freeze (GimpLink *link)
{
g_return_if_fail (GIMP_IS_LINK (link));
g_return_if_fail (link->p->monitor != NULL);
g_clear_object (&link->p->monitor);
}
void
gimp_link_thaw (GimpLink *link)
{
g_return_if_fail (GIMP_IS_LINK (link));
g_return_if_fail (G_IS_FILE (link->p->file) && link->p->monitor == NULL);
gimp_link_update_buffer (link, NULL, NULL);
gimp_link_start_monitoring (link);
}
gboolean
gimp_link_is_monitored (GimpLink *link)
{
g_return_val_if_fail (GIMP_IS_LINK (link), FALSE);
return (link->p->monitor != NULL);
}
gboolean
gimp_link_is_broken (GimpLink *link)
{
g_return_val_if_fail (GIMP_IS_LINK (link), TRUE);
return link->p->broken;
}
void
gimp_link_set_size (GimpLink *link,
gint width,
gint height,
gboolean keep_ratio)
{
g_return_if_fail (GIMP_IS_LINK (link));
link->p->width = width;
link->p->height = height;
link->p->keep_ratio = keep_ratio;
if (link->p->monitor && link->p->is_vector)
gimp_link_update_buffer (link, NULL, NULL);
}
void
gimp_link_get_size (GimpLink *link,
gint *width,
gint *height)
{
g_return_if_fail (GIMP_IS_LINK (link));
*width = link->p->width;
*height = link->p->height;
}
GimpImageBaseType
gimp_link_get_base_type (GimpLink *link)
{
g_return_val_if_fail (GIMP_IS_LINK (link) && ! link->p->broken, GIMP_RGB);
return link->p->base_type;
}
GimpPrecision
gimp_link_get_precision (GimpLink *link)
{
g_return_val_if_fail (GIMP_IS_LINK (link) && ! link->p->broken, GIMP_PRECISION_U8_PERCEPTUAL);
return link->p->precision;
}
GimpPlugInProcedure *
gimp_link_get_load_proc (GimpLink *link)
{
g_return_val_if_fail (GIMP_IS_LINK (link) && ! link->p->broken, NULL);
return link->p->load_proc;
}
gboolean
gimp_link_is_vector (GimpLink *link)
{
g_return_val_if_fail (GIMP_IS_LINK (link), FALSE);
return link->p->is_vector;
}
GeglBuffer *
gimp_link_get_buffer (GimpLink *link)
{
g_return_val_if_fail (GIMP_IS_LINK (link), NULL);
return link->p->buffer;
}

98
app/core/gimplink.h Normal file
View File

@@ -0,0 +1,98 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpLink
* Copyright (C) 2019 Jehan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "gimpitem.h"
#define GIMP_TYPE_LINK (gimp_link_get_type ())
#define GIMP_LINK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_LINK, GimpLink))
#define GIMP_LINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_LINK, GimpLinkClass))
#define GIMP_IS_LINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_LINK))
#define GIMP_IS_LINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_LINK))
#define GIMP_LINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_LINK, GimpLinkClass))
typedef struct _GimpLinkClass GimpLinkClass;
typedef struct _GimpLinkPrivate GimpLinkPrivate;
struct _GimpLink
{
GimpObject parent_instance;
GimpLinkPrivate *p;
};
struct _GimpLinkClass
{
GimpObjectClass parent_class;
void (* changed) (GimpLink *link);
};
GType gimp_link_get_type (void) G_GNUC_CONST;
GimpLink * gimp_link_new (Gimp *gimp,
GFile *file,
gint vector_width,
gint vector_height,
gboolean keep_ratio,
GimpProgress *progress,
GError **error);
GimpLink * gimp_link_duplicate (GimpLink *link);
GFile * gimp_link_get_file (GimpLink *link,
GFile *parent,
gchar **path);
void gimp_link_set_file (GimpLink *layer,
GFile *file,
gint vector_width,
gint vector_height,
gboolean keep_ratio,
GimpProgress *progress,
GError **error);
gboolean gimp_link_get_absolute_path (GimpLink *link);
void gimp_link_set_absolute_path (GimpLink *link,
gboolean absolute_path);
const gchar * gimp_link_get_mime_type (GimpLink *link);
void gimp_link_freeze (GimpLink *link);
void gimp_link_thaw (GimpLink *link);
gboolean gimp_link_is_monitored (GimpLink *link);
gboolean gimp_link_is_broken (GimpLink *link);
void gimp_link_set_size (GimpLink *link,
gint width,
gint height,
gboolean keep_ratio);
void gimp_link_get_size (GimpLink *link,
gint *width,
gint *height);
GimpImageBaseType gimp_link_get_base_type (GimpLink *link);
GimpPrecision gimp_link_get_precision (GimpLink *link);
GimpPlugInProcedure * gimp_link_get_load_proc (GimpLink *link);
gboolean gimp_link_is_vector (GimpLink *link);
GeglBuffer * gimp_link_get_buffer (GimpLink *link);

1137
app/core/gimplinklayer.c Normal file

File diff suppressed because it is too large Load Diff

87
app/core/gimplinklayer.h Normal file
View File

@@ -0,0 +1,87 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpLinkLayer
* Copyright (C) 2019 Jehan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "gimplayer.h"
#define GIMP_TYPE_LINK_LAYER (gimp_link_layer_get_type ())
#define GIMP_LINK_LAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_LINK_LAYER, GimpLinkLayer))
#define GIMP_LINK_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_LINK_LAYER, GimpLinkLayerClass))
#define GIMP_IS_LINK_LAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_LINK_LAYER))
#define GIMP_IS_LINK_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_LINK_LAYER))
#define GIMP_LINK_LAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_LINK_LAYER, GimpLinkLayerClass))
typedef struct _GimpLinkLayerClass GimpLinkLayerClass;
typedef struct _GimpLinkLayerPrivate GimpLinkLayerPrivate;
struct _GimpLinkLayer
{
GimpLayer layer;
GimpLinkLayerPrivate *p;
};
struct _GimpLinkLayerClass
{
GimpLayerClass parent_class;
};
GType gimp_link_layer_get_type (void) G_GNUC_CONST;
GimpLayer * gimp_link_layer_new (GimpImage *image,
GimpLink *link);
GimpLink * gimp_link_layer_get_link (GimpLinkLayer *layer);
gboolean gimp_link_layer_set_link (GimpLinkLayer *layer,
GimpLink *link,
gboolean push_undo);
gboolean gimp_link_layer_set_link_with_matrix (GimpLinkLayer *layer,
GimpLink *link,
GimpMatrix3 *matrix,
GimpInterpolationType interpolation_type,
gint offset_x,
gint offset_y,
gboolean push_undo);
void gimp_link_layer_discard (GimpLinkLayer *layer);
void gimp_link_layer_monitor (GimpLinkLayer *layer);
gboolean gimp_link_layer_is_monitored (GimpLinkLayer *layer);
gboolean gimp_link_layer_get_transform (GimpLinkLayer *layer,
GimpMatrix3 *matrix,
gint *offset_x,
gint *offset_y,
GimpInterpolationType *interpolation);
gboolean gimp_link_layer_set_transform (GimpLinkLayer *layer,
GimpMatrix3 *matrix,
GimpInterpolationType interpolation_type,
gboolean push_undo);
gboolean gimp_item_is_link_layer (GimpItem *item);
/* Only to be used for XCF loading/saving. */
guint32 gimp_link_layer_get_xcf_flags (GimpLinkLayer *layer);
void gimp_link_layer_set_xcf_flags (GimpLinkLayer *layer,
guint32 flags);

View File

@@ -0,0 +1,218 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* Copyright (C) 2019 Jehan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gegl.h>
#include "libgimpbase/gimpbase.h"
#include "core-types.h"
#include "gimpimage.h"
#include "gimplayer.h"
#include "gimplink.h"
#include "gimplinklayer.h"
#include "gimplinklayerundo.h"
enum
{
PROP_0,
PROP_PREV_LINK
};
static void gimp_link_layer_undo_constructed (GObject *object);
static void gimp_link_layer_undo_finalize (GObject *object);
static void gimp_link_layer_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_link_layer_undo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static gint64 gimp_link_layer_undo_get_memsize (GimpObject *object,
gint64 *gui_size);
static void gimp_link_layer_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
G_DEFINE_TYPE (GimpLinkLayerUndo, gimp_link_layer_undo, GIMP_TYPE_ITEM_UNDO)
#define parent_class gimp_link_layer_undo_parent_class
static void
gimp_link_layer_undo_class_init (GimpLinkLayerUndoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass);
object_class->constructed = gimp_link_layer_undo_constructed;
object_class->finalize = gimp_link_layer_undo_finalize;
object_class->set_property = gimp_link_layer_undo_set_property;
object_class->get_property = gimp_link_layer_undo_get_property;
gimp_object_class->get_memsize = gimp_link_layer_undo_get_memsize;
undo_class->pop = gimp_link_layer_undo_pop;
g_object_class_install_property (object_class, PROP_PREV_LINK,
g_param_spec_object ("prev-link",
NULL, NULL,
GIMP_TYPE_LINK,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
gimp_link_layer_undo_init (GimpLinkLayerUndo *undo)
{
}
static void
gimp_link_layer_undo_constructed (GObject *object)
{
GimpLinkLayerUndo *undo = GIMP_LINK_LAYER_UNDO (object);
GimpLinkLayer *layer;
GimpLink *link;
G_OBJECT_CLASS (parent_class)->constructed (object);
gimp_assert (GIMP_IS_LINK_LAYER (GIMP_ITEM_UNDO (object)->item));
layer = GIMP_LINK_LAYER (GIMP_ITEM_UNDO (undo)->item);
link = gimp_link_layer_get_link (layer);
undo->link = link ? gimp_link_duplicate (link) : NULL;
gimp_link_layer_get_transform (layer,
&undo->matrix,
&undo->offset_x,
&undo->offset_y,
&undo->interpolation);
}
static void
gimp_link_layer_undo_finalize (GObject *object)
{
GimpLinkLayerUndo *undo = GIMP_LINK_LAYER_UNDO (object);
g_clear_object (&undo->link);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_link_layer_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpLinkLayerUndo *undo = GIMP_LINK_LAYER_UNDO (object);
switch (property_id)
{
case PROP_PREV_LINK:
g_clear_object (&undo->link);
undo->link = g_value_get_object (value) ? gimp_link_duplicate (g_value_get_object (value)) : NULL;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_link_layer_undo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpLinkLayerUndo *undo = GIMP_LINK_LAYER_UNDO (object);
switch (property_id)
{
case PROP_PREV_LINK:
g_value_set_object (value, undo->link);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static gint64
gimp_link_layer_undo_get_memsize (GimpObject *object,
gint64 *gui_size)
{
GimpItemUndo *item_undo = GIMP_ITEM_UNDO (object);
gint64 memsize = 0;
if (! gimp_item_is_attached (item_undo->item))
memsize += gimp_object_get_memsize (GIMP_OBJECT (item_undo->item),
gui_size);
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
gui_size);
}
static void
gimp_link_layer_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
GimpLinkLayerUndo *layer_undo = GIMP_LINK_LAYER_UNDO (undo);
GimpLinkLayer *layer = GIMP_LINK_LAYER (GIMP_ITEM_UNDO (undo)->item);
GimpLink *link;
GimpMatrix3 matrix;
gint offset_x;
gint offset_y;
GimpInterpolationType interpolation;
GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);
link = gimp_link_layer_get_link (layer);
link = link ? g_object_ref (link) : NULL;
gimp_link_layer_get_transform (layer, &matrix, &offset_x, &offset_y, &interpolation);
gimp_link_layer_set_link_with_matrix (layer, layer_undo->link,
&layer_undo->matrix,
layer_undo->interpolation,
layer_undo->offset_x,
layer_undo->offset_y,
FALSE);
layer_undo->matrix = matrix;
layer_undo->interpolation = interpolation;
layer_undo->offset_x = offset_x;
layer_undo->offset_y = offset_y;
g_clear_object (&layer_undo->link);
layer_undo->link = link;
}

View File

@@ -0,0 +1,53 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* Copyright (C) 2019 Jehan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "gimpitemundo.h"
#define GIMP_TYPE_LINK_LAYER_UNDO (gimp_link_layer_undo_get_type ())
#define GIMP_LINK_LAYER_UNDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_LINK_LAYER_UNDO, GimpLinkLayerUndo))
#define GIMP_LINK_LAYER_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_LINK_LAYER_UNDO, GimpLinkLayerUndoClass))
#define GIMP_IS_LINK_LAYER_UNDO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_LINK_LAYER_UNDO))
#define GIMP_IS_LINK_LAYER_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_LINK_LAYER_UNDO))
#define GIMP_LINK_LAYER_UNDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_LINK_LAYER_UNDO, GimpLinkLayerUndoClass))
typedef struct _GimpLinkLayerUndo GimpLinkLayerUndo;
typedef struct _GimpLinkLayerUndoClass GimpLinkLayerUndoClass;
struct _GimpLinkLayerUndo
{
GimpItemUndo parent_instance;
GimpLink *link;
GimpMatrix3 matrix;
gint offset_x;
gint offset_y;
GimpInterpolationType interpolation;
};
struct _GimpLinkLayerUndoClass
{
GimpItemUndoClass parent_class;
};
GType gimp_link_layer_undo_get_type (void) G_GNUC_CONST;

View File

@@ -207,7 +207,7 @@ gimp_palette_import_create_image_palette (gpointer data,
gint n_colors;
gchar *lab;
GeglColor *color;
guint8 rgb[3];
guint8 rgb[4];
n_colors = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (palette),
"import-n-colors"));
@@ -228,6 +228,12 @@ gimp_palette_import_create_image_palette (gpointer data,
rgb[0] = (guchar) color_tab->r + (color_tab->r_adj / color_tab->count);
rgb[1] = (guchar) color_tab->g + (color_tab->g_adj / color_tab->count);
rgb[2] = (guchar) color_tab->b + (color_tab->b_adj / color_tab->count);
/* TODO: We only receive the RGB values, so if the format has alpha, it
* becomes transparent when used outside of a palette. For now, we'll set
* alpha to 255, but in the future, a less RGB-specific implementation
* would be ideal */
if (babl_format_has_alpha (format))
rgb[3] = 255;
gegl_color_set_pixel (color, format, rgb);

View File

@@ -872,7 +872,7 @@ gimp_palette_load_acb (GimpContext *context,
{
g_free (palette_entry);
g_free (full_palette_name);
g_object_unref (color);
g_clear_object (&color);
g_printerr ("Invalid ACB palette color code");
break;
@@ -880,63 +880,65 @@ gimp_palette_load_acb (GimpContext *context,
if (color_space == 0)
{
gchar rgb[3];
guchar rgb[3];
if (! g_input_stream_read_all (input, rgb, sizeof (rgb),
&bytes_read, NULL, error))
{
g_free (palette_entry);
g_free (full_palette_name);
g_object_unref (color);
g_clear_object (&color);
g_printerr ("Invalid ACB palette colors");
break;
}
gegl_color_set_pixel (color, babl_format ("R'G'B u8"), rgb);
gegl_color_set_pixel (color, babl_format ("R'G'B' u8"), rgb);
color_ok = TRUE;
}
else if (color_space == 2)
{
gchar cmyk[4];
guchar cmyk[4];
gfloat cmyk_f[4];
if (! g_input_stream_read_all (input, cmyk, sizeof (cmyk),
&bytes_read, NULL, error))
{
g_free (palette_entry);
g_free (full_palette_name);
g_object_unref (color);
g_clear_object (&color);
g_printerr ("Invalid ACB palette colors");
break;
}
for (gint j = 0; j < 4; j++)
cmyk[j] = ((255 - cmyk[j]) / 2.55f) + 0.5f;
cmyk_f[j] = (((255 - cmyk[j]) / 2.55f) + 0.5f) / 100.0f;
gegl_color_set_pixel (color, babl_format ("cmyk u8"), cmyk);
gegl_color_set_pixel (color, babl_format ("CMYK float"), cmyk_f);
color_ok = TRUE;
}
else if (color_space == 7)
{
gchar lab[3];
guchar lab[3];
gfloat lab_f[3];
if (! g_input_stream_read_all (input, lab, sizeof (lab),
&bytes_read, NULL, error))
{
g_free (palette_entry);
g_free (full_palette_name);
g_object_unref (color);
g_clear_object (&color);
g_printerr ("Invalid ACB palette colors");
break;
}
lab[0] = (lab[0] / 2.55f) + 0.5f;
lab[1] = lab[1] - 128;
lab[2] = lab[2] - 128;
lab_f[0] = (lab[0] / 2.55f) + 0.5f;
lab_f[1] = ((gfloat) lab[1]) - 128;
lab_f[2] = ((gfloat) lab[2]) - 128;
gegl_color_set_pixel (color, babl_format ("CIE Lab u8"), lab);
gegl_color_set_pixel (color, babl_format ("CIE Lab float"), lab_f);
color_ok = TRUE;
}
@@ -945,7 +947,7 @@ gimp_palette_load_acb (GimpContext *context,
g_free (palette_entry);
g_free (full_palette_name);
g_object_unref (color);
g_clear_object (&color);
if (! color_ok)
{

View File

@@ -76,8 +76,7 @@ static GimpTempBuf * gimp_palette_get_new_preview (GimpViewable *vie
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
static gchar * gimp_palette_get_description (GimpViewable *viewable,
gchar **tooltip);
static const gchar * gimp_palette_get_extension (GimpData *data);
@@ -243,8 +242,7 @@ gimp_palette_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
GimpPalette *palette = GIMP_PALETTE (viewable);
GimpTempBuf *temp_buf;
@@ -498,11 +496,7 @@ gimp_palette_restrict_format (GimpPalette *palette,
if (push_undo_if_image && gimp_data_get_image (GIMP_DATA (palette)))
gimp_image_undo_push_image_colormap (gimp_data_get_image (GIMP_DATA (palette)),
/* TODO: use localized string
* after string freeze.
*/
/*C_("undo-type", "Change Colormap format restriction"));*/
"Change Colormap format restriction");
C_("undo-type", "Change Colormap format restriction"));
palette->format = format;
if (palette->format == NULL)

View File

@@ -36,12 +36,14 @@
#include "gimpimage.h"
#include "gimplayer.h"
#include "gimplayermask.h"
#include "gimplinklayer.h"
#include "gimppalette.h"
#include "gimpparamspecs.h"
#include "gimppattern.h"
#include "gimpselection.h"
#include "path/gimppath.h"
#include "path/gimpvectorlayer.h"
#include "text/gimpfont.h"
#include "text/gimptextlayer.h"

View File

@@ -50,8 +50,7 @@ static GimpTempBuf * gimp_pattern_get_new_preview (GimpViewable *viewa
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
static gchar * gimp_pattern_get_description (GimpViewable *viewable,
gchar **tooltip);
@@ -145,8 +144,7 @@ gimp_pattern_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
GimpPattern *pattern = GIMP_PATTERN (viewable);
GimpTempBuf *temp_buf;

View File

@@ -83,8 +83,7 @@ static GimpTempBuf * gimp_undo_get_new_preview (GimpViewable *viewabl
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
static void gimp_undo_real_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
@@ -304,8 +303,7 @@ gimp_undo_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color G_GNUC_UNUSED,
GeglColor *background G_GNUC_UNUSED)
GeglColor *fg_color G_GNUC_UNUSED)
{
GimpUndo *undo = GIMP_UNDO (viewable);
@@ -495,7 +493,7 @@ gimp_undo_create_preview_private (GimpUndo *undo,
}
undo->preview = gimp_viewable_get_new_preview (preview_viewable, context,
width, height, NULL, NULL);
width, height, NULL);
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (undo));
}

View File

@@ -75,11 +75,10 @@ struct _GimpViewablePrivate
gint depth;
GimpTempBuf *preview_temp_buf;
GeglColor *preview_temp_buf_color;
GdkPixbuf *preview_pixbuf;
GeglColor *preview_pixbuf_color;
GeglColor *preview_pixbuf_background;
GeglColor *preview_temp_buf_color;
GeglColor *preview_temp_buf_background;
};
#define GET_PRIVATE(viewable) \
@@ -108,8 +107,7 @@ static GdkPixbuf * gimp_viewable_real_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
static void gimp_viewable_real_get_preview_size (GimpViewable *viewable,
gint size,
gboolean popup,
@@ -255,13 +253,11 @@ gimp_viewable_finalize (GObject *object)
GimpViewablePrivate *private = GET_PRIVATE (object);
g_clear_pointer (&private->icon_name, g_free);
g_clear_object (&private->icon_pixbuf);
g_clear_object (&private->icon_pixbuf);
g_clear_pointer (&private->preview_temp_buf, gimp_temp_buf_unref);
g_clear_object (&private->preview_pixbuf);
g_clear_object (&private->preview_pixbuf_color);
g_clear_object (&private->preview_pixbuf_background);
g_clear_object (&private->preview_temp_buf_color);
g_clear_object (&private->preview_temp_buf_background);
g_clear_object (&private->preview_temp_buf_color);
g_clear_object (&private->preview_pixbuf);
g_clear_object (&private->preview_pixbuf_color);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -345,11 +341,9 @@ gimp_viewable_real_invalidate_preview (GimpViewable *viewable)
GimpViewablePrivate *private = GET_PRIVATE (viewable);
g_clear_pointer (&private->preview_temp_buf, gimp_temp_buf_unref);
g_clear_object (&private->preview_pixbuf);
g_clear_object (&private->preview_pixbuf_color);
g_clear_object (&private->preview_pixbuf_background);
g_clear_object (&private->preview_temp_buf_color);
g_clear_object (&private->preview_temp_buf_background);
g_clear_object (&private->preview_temp_buf_color);
g_clear_object (&private->preview_pixbuf);
g_clear_object (&private->preview_pixbuf_color);
}
static void
@@ -419,14 +413,15 @@ gimp_viewable_real_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background)
GeglColor *fg_color)
{
GimpViewablePrivate *private = GET_PRIVATE (viewable);
GdkPixbuf *pixbuf = NULL;
GimpTempBuf *temp_buf;
temp_buf = gimp_viewable_get_preview (viewable, context, width, height, color, background);
temp_buf = gimp_viewable_get_preview (viewable, context,
width, height,
fg_color);
if (temp_buf)
{
@@ -697,12 +692,18 @@ gimp_viewable_calc_preview_size (gint aspect_width,
}
gboolean
gimp_viewable_has_preview (GimpViewable *viewable)
gimp_viewable_has_preview (GimpViewable *viewable)
{
GimpViewableClass *viewable_class;
g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), FALSE);
return (GIMP_VIEWABLE_GET_CLASS (viewable)->get_preview != NULL ||
GIMP_VIEWABLE_GET_CLASS (viewable)->get_new_preview != NULL);
viewable_class = GIMP_VIEWABLE_GET_CLASS (viewable);
return (viewable_class->get_preview ||
viewable_class->get_new_preview ||
viewable_class->get_pixbuf ||
viewable_class->get_new_pixbuf);
}
gboolean
@@ -853,10 +854,8 @@ gimp_viewable_get_popup_size (GimpViewable *viewable,
* @context: The context to render the preview for.
* @width: desired width for the preview
* @height: desired height for the preview
* @color: desired foreground color for the preview when the type of
* @fg_color :desired foreground color for the preview when the type of
* @viewable support recolorization.
* @background: desired background color for the preview when the type
* of @viewable supports recolorization.
*
* Gets a preview for a viewable object, by running through a variety
* of methods until it finds one that works. First, if an
@@ -882,8 +881,7 @@ gimp_viewable_get_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background)
GeglColor *fg_color)
{
GimpViewablePrivate *private = GET_PRIVATE (viewable);
GimpViewableClass *viewable_class;
@@ -893,8 +891,6 @@ gimp_viewable_get_preview (GimpViewable *viewable,
g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);
g_return_val_if_fail (width > 0, NULL);
g_return_val_if_fail (height > 0, NULL);
g_return_val_if_fail ((color == NULL && background == NULL) ||
(color != NULL && background != NULL), NULL);
if (G_UNLIKELY (context == NULL))
g_warning ("%s: context is NULL", G_STRFUNC);
@@ -902,21 +898,23 @@ gimp_viewable_get_preview (GimpViewable *viewable,
viewable_class = GIMP_VIEWABLE_GET_CLASS (viewable);
if (viewable_class->get_preview)
temp_buf = viewable_class->get_preview (viewable, context, width, height, color, background);
temp_buf = viewable_class->get_preview (viewable, context,
width, height,
fg_color);
if (temp_buf)
return temp_buf;
if (private->preview_temp_buf &&
((color == NULL && private->preview_temp_buf_color == NULL) ||
(color != NULL && private->preview_temp_buf_color != NULL)))
((fg_color == NULL && private->preview_temp_buf_color == NULL) ||
(fg_color != NULL && private->preview_temp_buf_color != NULL)))
{
if (gimp_temp_buf_get_width (private->preview_temp_buf) == width &&
gimp_temp_buf_get_height (private->preview_temp_buf) == height)
{
gboolean same_colors = TRUE;
if (color != NULL)
if (fg_color)
{
gdouble r1, g1, b1, a1;
gdouble r2, g2, b2, a2;
@@ -924,18 +922,12 @@ gimp_viewable_get_preview (GimpViewable *viewable,
/* Don't use gimp_color_is_perceptually_identical(). Exact
* comparison is fine for this use case.
*/
gegl_color_get_rgba (color, &r1, &g1, &b1, &a1);
gegl_color_get_rgba (private->preview_temp_buf_color, &r2, &g2, &b2, &a2);
gegl_color_get_rgba (fg_color,
&r1, &g1, &b1, &a1);
gegl_color_get_rgba (private->preview_temp_buf_color,
&r2, &g2, &b2, &a2);
same_colors = (r1 == r2 && g1 == g2 && b1 == b2 && a1 == a2);
if (same_colors)
{
gegl_color_get_rgba (background, &r1, &g1, &b1, &a1);
gegl_color_get_rgba (private->preview_temp_buf_background, &r2, &g2, &b2, &a2);
same_colors = (r1 == r2 && g1 == g2 && b1 == b2 && a1 == a2);
}
}
if (same_colors)
@@ -945,15 +937,15 @@ gimp_viewable_get_preview (GimpViewable *viewable,
g_clear_pointer (&private->preview_temp_buf, gimp_temp_buf_unref);
g_clear_object (&private->preview_temp_buf_color);
g_clear_object (&private->preview_temp_buf_background);
if (viewable_class->get_new_preview)
temp_buf = viewable_class->get_new_preview (viewable, context,
width, height, color, background);
width, height,
fg_color);
private->preview_temp_buf = temp_buf;
private->preview_temp_buf_color = color ? gegl_color_duplicate (color) : NULL;
private->preview_temp_buf_background = background ? gegl_color_duplicate (background) : NULL;
private->preview_temp_buf = temp_buf;
private->preview_temp_buf_color = fg_color ?
gegl_color_duplicate (fg_color) : NULL;
return temp_buf;
}
@@ -963,10 +955,8 @@ gimp_viewable_get_preview (GimpViewable *viewable,
* @viewable: The viewable object to get a preview for.
* @width: desired width for the preview
* @height: desired height for the preview
* @color: desired foreground color for the preview when the type of
* @fg_color: desired foreground color for the preview when the type of
* @viewable support recolorization.
* @background: desired background color for the preview when the type
* of @viewable supports recolorization.
*
* Gets a new preview for a viewable object. Similar to
* gimp_viewable_get_preview(), except that it tries things in a
@@ -982,8 +972,7 @@ gimp_viewable_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background)
GeglColor *fg_color)
{
GimpViewableClass *viewable_class;
GimpTempBuf *temp_buf = NULL;
@@ -1000,14 +989,16 @@ gimp_viewable_get_new_preview (GimpViewable *viewable,
if (viewable_class->get_new_preview)
temp_buf = viewable_class->get_new_preview (viewable, context,
width, height, color, background);
width, height,
fg_color);
if (temp_buf)
return temp_buf;
if (viewable_class->get_preview)
temp_buf = viewable_class->get_preview (viewable, context,
width, height, color, background);
width, height,
fg_color);
if (temp_buf)
return gimp_temp_buf_copy (temp_buf);
@@ -1059,10 +1050,8 @@ gimp_viewable_get_dummy_preview (GimpViewable *viewable,
* @context: The context to render the preview for.
* @width: desired width for the preview
* @height: desired height for the preview
* @color: desired foreground color for the preview when the type of
* @fg_color: desired foreground color for the preview when the type of
* @viewable supports recolorization.
* @background: desired background color for the preview when the type
* of @viewable supports recolorization.
*
* Gets a preview for a viewable object, by running through a variety
* of methods until it finds one that works. First, if an
@@ -1082,8 +1071,7 @@ gimp_viewable_get_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background)
GeglColor *fg_color)
{
GimpViewablePrivate *private = GET_PRIVATE (viewable);
GimpViewableClass *viewable_class;
@@ -1093,8 +1081,6 @@ gimp_viewable_get_pixbuf (GimpViewable *viewable,
g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);
g_return_val_if_fail (width > 0, NULL);
g_return_val_if_fail (height > 0, NULL);
g_return_val_if_fail ((color == NULL && background == NULL) ||
(color != NULL && background != NULL), NULL);
if (G_UNLIKELY (context == NULL))
g_warning ("%s: context is NULL", G_STRFUNC);
@@ -1102,21 +1088,23 @@ gimp_viewable_get_pixbuf (GimpViewable *viewable,
viewable_class = GIMP_VIEWABLE_GET_CLASS (viewable);
if (viewable_class->get_pixbuf)
pixbuf = viewable_class->get_pixbuf (viewable, context, width, height, color, background);
pixbuf = viewable_class->get_pixbuf (viewable, context,
width, height,
fg_color);
if (pixbuf)
return pixbuf;
if (private->preview_pixbuf &&
((color == NULL && private->preview_pixbuf_color == NULL) ||
(color != NULL && private->preview_pixbuf_color != NULL)))
((fg_color == NULL && private->preview_pixbuf_color == NULL) ||
(fg_color != NULL && private->preview_pixbuf_color != NULL)))
{
if (gdk_pixbuf_get_width (private->preview_pixbuf) == width &&
gdk_pixbuf_get_height (private->preview_pixbuf) == height)
{
gboolean same_colors = TRUE;
if (color != NULL)
if (fg_color)
{
gdouble r1, g1, b1, a1;
gdouble r2, g2, b2, a2;
@@ -1124,18 +1112,12 @@ gimp_viewable_get_pixbuf (GimpViewable *viewable,
/* Don't use gimp_color_is_perceptually_identical(). Exact
* comparison is fine for this use case.
*/
gegl_color_get_rgba (color, &r1, &g1, &b1, &a1);
gegl_color_get_rgba (private->preview_pixbuf_color, &r2, &g2, &b2, &a2);
gegl_color_get_rgba (fg_color,
&r1, &g1, &b1, &a1);
gegl_color_get_rgba (private->preview_pixbuf_color,
&r2, &g2, &b2, &a2);
same_colors = (r1 == r2 && g1 == g2 && b1 == b2 && a1 == a2);
if (same_colors)
{
gegl_color_get_rgba (background, &r1, &g1, &b1, &a1);
gegl_color_get_rgba (private->preview_pixbuf_background, &r2, &g2, &b2, &a2);
same_colors = (r1 == r2 && g1 == g2 && b1 == b2 && a1 == a2);
}
}
if (same_colors)
@@ -1145,14 +1127,15 @@ gimp_viewable_get_pixbuf (GimpViewable *viewable,
g_clear_object (&private->preview_pixbuf);
g_clear_object (&private->preview_pixbuf_color);
g_clear_object (&private->preview_pixbuf_background);
if (viewable_class->get_new_pixbuf)
pixbuf = viewable_class->get_new_pixbuf (viewable, context, width, height, color, background);
pixbuf = viewable_class->get_new_pixbuf (viewable, context,
width, height,
fg_color);
private->preview_pixbuf = pixbuf;
private->preview_pixbuf_color = color ? gegl_color_duplicate (color) : NULL;
private->preview_pixbuf_background = background ? gegl_color_duplicate (background) : NULL;
private->preview_pixbuf = pixbuf;
private->preview_pixbuf_color = fg_color ?
gegl_color_duplicate (fg_color) : NULL;
return pixbuf;
}
@@ -1163,7 +1146,7 @@ gimp_viewable_get_pixbuf (GimpViewable *viewable,
* @context: The context to render the preview for.
* @width: desired width for the pixbuf
* @height: desired height for the pixbuf
* @color: desired foreground color for the preview when the type of
* @fg_color: desired foreground color for the preview when the type of
* @viewable support recolorization.
*
* Gets a new preview for a viewable object. Similar to
@@ -1180,8 +1163,7 @@ gimp_viewable_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background)
GeglColor *fg_color)
{
GimpViewableClass *viewable_class;
GdkPixbuf *pixbuf = NULL;
@@ -1197,13 +1179,17 @@ gimp_viewable_get_new_pixbuf (GimpViewable *viewable,
viewable_class = GIMP_VIEWABLE_GET_CLASS (viewable);
if (viewable_class->get_new_pixbuf)
pixbuf = viewable_class->get_new_pixbuf (viewable, context, width, height, color, background);
pixbuf = viewable_class->get_new_pixbuf (viewable, context,
width, height,
fg_color);
if (pixbuf)
return pixbuf;
if (viewable_class->get_pixbuf)
pixbuf = viewable_class->get_pixbuf (viewable, context, width, height, color, background);
pixbuf = viewable_class->get_pixbuf (viewable, context,
width, height,
fg_color);
if (pixbuf)
return gdk_pixbuf_copy (pixbuf);

View File

@@ -71,26 +71,22 @@ struct _GimpViewableClass
GimpContext *context,
gint width,
gint height,
GeglColor *fg_color,
GeglColor *background);
GeglColor *fg_color);
GimpTempBuf * (* get_new_preview) (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *fg_color,
GeglColor *background);
GeglColor *fg_color);
GdkPixbuf * (* get_pixbuf) (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *fg_color,
GeglColor *background);
GeglColor *fg_color);
GdkPixbuf * (* get_new_pixbuf) (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *fg_color,
GeglColor *background);
GeglColor *fg_color);
gchar * (* get_description) (GimpViewable *viewable,
gchar **tooltip);
@@ -145,14 +141,12 @@ GimpTempBuf * gimp_viewable_get_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *fg_color,
GeglColor *bg_color);
GeglColor *fg_color);
GimpTempBuf * gimp_viewable_get_new_preview (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *fg_color,
GeglColor *bg_color);
GeglColor *fg_color);
GimpTempBuf * gimp_viewable_get_dummy_preview (GimpViewable *viewable,
gint width,
@@ -163,14 +157,12 @@ GdkPixbuf * gimp_viewable_get_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
GdkPixbuf * gimp_viewable_get_new_pixbuf (GimpViewable *viewable,
GimpContext *context,
gint width,
gint height,
GeglColor *color,
GeglColor *background);
GeglColor *fg_color);
GdkPixbuf * gimp_viewable_get_dummy_pixbuf (GimpViewable *viewable,
gint width,

View File

@@ -185,6 +185,7 @@ libappcore_sources = [
'gimpitemundo.c',
'gimplayer-floating-selection.c',
'gimplayer-new.c',
'gimplayer-xcf.c',
'gimplayer.c',
'gimplayermask.c',
'gimplayermaskpropundo.c',
@@ -193,6 +194,9 @@ libappcore_sources = [
'gimplayerstack.c',
'gimplayerundo.c',
'gimplineart.c',
'gimplink.c',
'gimplinklayer.c',
'gimplinklayerundo.c',
'gimplist.c',
'gimpmaskundo.c',
'gimpmybrush-load.c',
@@ -273,6 +277,7 @@ libappcore = static_library('appcore',
cairo,
gegl,
gdk_pixbuf,
libarchive,
libmypaint,
gexiv2,
appstream,

View File

@@ -512,17 +512,24 @@ about_dialog_add_update (GimpAboutDialog *dialog,
if (config->check_update_timestamp > 0)
{
gchar *subtext;
gchar *time;
datetime = g_date_time_new_from_unix_local (config->check_update_timestamp);
gchar *subtext;
gchar *time;
#if defined(PLATFORM_OSX)
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
NSDate *current_date = [NSDate date];
NSString *formatted_date;
NSString *formatted_time;
#elif defined(G_OS_WIN32)
SYSTEMTIME st;
int date_len, time_len;
wchar_t *date_buf = NULL;
wchar_t *time_buf = NULL;
#endif
datetime = g_date_time_new_from_unix_local (config->check_update_timestamp);
#if defined(PLATFORM_OSX)
formatter.locale = [NSLocale currentLocale];
formatter.dateStyle = NSDateFormatterShortStyle;
@@ -546,11 +553,6 @@ about_dialog_add_update (GimpAboutDialog *dialog,
[formatter release];
[pool drain];
#elif defined(G_OS_WIN32)
SYSTEMTIME st;
int date_len, time_len;
wchar_t *date_buf = NULL;
wchar_t *time_buf = NULL;
GetLocalTime (&st);
date_len = GetDateFormatEx (LOCALE_NAME_USER_DEFAULT, 0, &st,

View File

@@ -73,7 +73,7 @@ extensions_dialog_new (Gimp *gimp)
GtkWidget *widget;
GtkTreeIter top_iter;
dialog = gimp_dialog_new (_("Extensions"), "gimp-extensions",
dialog = gimp_dialog_new (C_("GIMP extensions", "Extensions"), "gimp-extensions",
NULL, 0, NULL,
GIMP_HELP_EXTENSIONS_DIALOG,
_("_OK"), GTK_RESPONSE_OK,

View File

@@ -55,11 +55,13 @@ static void file_open_dialog_response (GtkWidget *dialog,
static GimpImage *file_open_dialog_open_image (GtkWidget *dialog,
Gimp *gimp,
GFile *file,
GimpPlugInProcedure *load_proc);
GimpPlugInProcedure *load_proc,
gboolean as_link);
static gboolean file_open_dialog_open_layers (GtkWidget *dialog,
GimpImage *image,
GFile *file,
GimpPlugInProcedure *load_proc);
GimpPlugInProcedure *load_proc,
gboolean as_link);
/* public functions */
@@ -147,13 +149,14 @@ file_open_dialog_response (GtkWidget *dialog,
{
if (! file_dialog->image)
{
gimp_open_dialog_set_image (
open_dialog,
file_open_dialog_open_image (dialog,
gimp,
file,
file_dialog->file_proc),
TRUE);
gimp_open_dialog_set_image (open_dialog,
file_open_dialog_open_image (dialog,
gimp,
file,
file_dialog->file_proc,
open_dialog->open_as_link),
TRUE,
open_dialog->open_as_link);
if (file_dialog->image)
{
@@ -170,7 +173,8 @@ file_open_dialog_response (GtkWidget *dialog,
else if (file_open_dialog_open_layers (dialog,
file_dialog->image,
file,
file_dialog->file_proc))
file_dialog->file_proc,
open_dialog->open_as_link))
{
success = TRUE;
}
@@ -180,7 +184,8 @@ file_open_dialog_response (GtkWidget *dialog,
if (file_open_dialog_open_image (dialog,
gimp,
file,
file_dialog->file_proc))
file_dialog->file_proc,
open_dialog->open_as_link))
{
success = TRUE;
@@ -227,7 +232,8 @@ static GimpImage *
file_open_dialog_open_image (GtkWidget *dialog,
Gimp *gimp,
GFile *file,
GimpPlugInProcedure *load_proc)
GimpPlugInProcedure *load_proc,
gboolean as_link)
{
GimpImage *image;
GimpPDBStatusType status;
@@ -236,16 +242,21 @@ file_open_dialog_open_image (GtkWidget *dialog,
image = file_open_with_proc_and_display (gimp,
gimp_get_user_context (gimp),
GIMP_PROGRESS (dialog),
file, FALSE,
file, FALSE, as_link,
load_proc,
G_OBJECT (gimp_widget_get_monitor (dialog)),
&status, &error);
if (! image && status != GIMP_PDB_SUCCESS && status != GIMP_PDB_CANCEL)
{
gimp_message (gimp, G_OBJECT (dialog), GIMP_MESSAGE_ERROR,
_("Opening '%s' failed:\n\n%s"),
gimp_file_get_utf8_name (file), error->message);
if (error)
gimp_message (gimp, G_OBJECT (dialog), GIMP_MESSAGE_ERROR,
_("Opening '%s' failed:\n\n%s"),
gimp_file_get_utf8_name (file), error->message);
else
gimp_message (gimp, G_OBJECT (dialog), GIMP_MESSAGE_ERROR,
_("Opening '%s' failed."),
gimp_file_get_utf8_name (file));
g_clear_error (&error);
}
@@ -256,7 +267,8 @@ static gboolean
file_open_dialog_open_layers (GtkWidget *dialog,
GimpImage *image,
GFile *file,
GimpPlugInProcedure *load_proc)
GimpPlugInProcedure *load_proc,
gboolean as_link)
{
GList *new_layers;
GimpPDBStatusType status;
@@ -265,7 +277,7 @@ file_open_dialog_open_layers (GtkWidget *dialog,
new_layers = file_open_layers (image->gimp,
gimp_get_user_context (image->gimp),
GIMP_PROGRESS (dialog),
image, FALSE,
image, FALSE, as_link,
file, GIMP_RUN_INTERACTIVE, load_proc,
&status, &error);

View File

@@ -204,7 +204,7 @@ file_open_location_response (GtkDialog *dialog,
image = file_open_with_proc_and_display (gimp,
gimp_get_user_context (gimp),
GIMP_PROGRESS (box),
file, FALSE, NULL,
file, FALSE, FALSE, NULL,
G_OBJECT (gimp_widget_get_monitor (entry)),
&status, &error);

View File

@@ -322,6 +322,21 @@ item_options_dialog_get_vbox (GtkWidget *dialog)
return private->left_vbox;
}
GtkWidget *
item_options_dialog_get_right_vbox (GtkWidget *dialog)
{
ItemOptionsDialog *private;
g_return_val_if_fail (GIMP_IS_VIEWABLE_DIALOG (dialog), NULL);
private = g_object_get_data (G_OBJECT (dialog),
"item-options-dialog-private");
g_return_val_if_fail (private != NULL, NULL);
return private->right_vbox;
}
GtkWidget *
item_options_dialog_get_grid (GtkWidget *dialog,
gint *next_row)

View File

@@ -55,6 +55,7 @@ GtkWidget * item_options_dialog_new (GimpImage *image,
gpointer user_data);
GtkWidget * item_options_dialog_get_vbox (GtkWidget *dialog);
GtkWidget * item_options_dialog_get_right_vbox (GtkWidget *dialog);
GtkWidget * item_options_dialog_get_grid (GtkWidget *dialog,
gint *next_row);
GtkWidget * item_options_dialog_get_name_entry (GtkWidget *dialog);

View File

@@ -50,6 +50,7 @@ struct _LayerAddMaskDialog
GimpAddMaskType add_mask_type;
GimpChannel *channel;
gboolean invert;
gboolean edit_mask;
GimpAddMaskCallback callback;
gpointer user_data;
};
@@ -73,12 +74,14 @@ layer_add_mask_dialog_new (GList *layers,
GtkWidget *parent,
GimpAddMaskType add_mask_type,
gboolean invert,
gboolean edit_mask,
GimpAddMaskCallback callback,
gpointer user_data)
{
LayerAddMaskDialog *private;
GtkWidget *dialog;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *frame;
GtkWidget *combo;
GtkWidget *button;
@@ -98,6 +101,7 @@ layer_add_mask_dialog_new (GList *layers,
private->layers = layers;
private->add_mask_type = add_mask_type;
private->invert = invert;
private->edit_mask = edit_mask;
private->callback = callback;
private->user_data = user_data;
@@ -180,15 +184,28 @@ layer_add_mask_dialog_new (GList *layers,
gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (combo),
GIMP_VIEWABLE (channel));
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1);
gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
button = gtk_check_button_new_with_mnemonic (_("In_vert mask"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), private->invert);
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
g_signal_connect (button, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&private->invert);
button = gtk_check_button_new_with_mnemonic (_("_Edit mask immediately"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), private->edit_mask);
gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
g_signal_connect (button, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&private->edit_mask);
return dialog;
}
@@ -224,6 +241,7 @@ layer_add_mask_dialog_response (GtkWidget *dialog,
private->add_mask_type,
private->channel,
private->invert,
private->edit_mask,
private->user_data);
}
else

View File

@@ -23,6 +23,7 @@ typedef void (* GimpAddMaskCallback) (GtkWidget *dialog,
GimpAddMaskType add_mask_type,
GimpChannel *channel,
gboolean invert,
gboolean edit_mask,
gpointer user_data);
@@ -31,5 +32,6 @@ GtkWidget * layer_add_mask_dialog_new (GList *layers,
GtkWidget *parent,
GimpAddMaskType add_mask_type,
gboolean invert,
gboolean edit_mask,
GimpAddMaskCallback callback,
gpointer user_data);

View File

@@ -32,12 +32,15 @@
#include "core/gimpdrawable-filters.h"
#include "core/gimpimage.h"
#include "core/gimplayer.h"
#include "core/gimplink.h"
#include "core/gimplinklayer.h"
#include "text/gimptext.h"
#include "text/gimptextlayer.h"
#include "widgets/gimpcontainertreeview.h"
#include "widgets/gimpcontainerlistview.h"
#include "widgets/gimplayermodebox.h"
#include "widgets/gimpopendialog.h"
#include "widgets/gimpviewabledialog.h"
#include "item-options-dialog.h"
@@ -50,6 +53,7 @@ typedef struct _LayerOptionsDialog LayerOptionsDialog;
struct _LayerOptionsDialog
{
Gimp *gimp;
GimpLayer *layer;
GimpLayerMode mode;
GimpLayerColorSpace blend_space;
@@ -68,6 +72,8 @@ struct _LayerOptionsDialog
GtkWidget *composite_mode_combo;
GtkWidget *size_se;
GtkWidget *offset_se;
GimpLink *link;
};
@@ -93,6 +99,9 @@ static void layer_options_dialog_mode_notify (GtkWidget *widget,
static void layer_options_dialog_rename_toggled (GtkWidget *widget,
LayerOptionsDialog *private);
static void layer_options_file_set (GtkFileChooserButton *widget,
LayerOptionsDialog *private);
/* public functions */
@@ -127,6 +136,7 @@ layer_options_dialog_new (GimpImage *image,
GtkWidget *grid;
GtkListStore *space_model;
GtkWidget *combo;
GtkWidget *file_select;
GtkWidget *scale;
GtkWidget *label;
GtkAdjustment *adjustment;
@@ -144,6 +154,7 @@ layer_options_dialog_new (GimpImage *image,
private = g_slice_new0 (LayerOptionsDialog);
private->gimp = image->gimp;
private->layer = layer;
private->mode = layer_mode;
private->blend_space = layer_blend_space;
@@ -156,6 +167,8 @@ layer_options_dialog_new (GimpImage *image,
private->callback = callback;
private->user_data = user_data;
private->link = NULL;
if (layer && gimp_item_is_text_layer (GIMP_ITEM (layer)))
private->rename_text_layers = GIMP_TEXT_LAYER (layer)->auto_rename;
@@ -372,19 +385,6 @@ layer_options_dialog_new (GimpImage *image,
row += 2;
if (! layer)
{
/* The fill type */
combo = gimp_enum_combo_box_new (GIMP_TYPE_FILL_TYPE);
gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
_("_Fill with:"), 0.0, 0.5,
combo, 1);
gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo),
private->fill_type,
G_CALLBACK (gimp_int_combo_box_get_active),
&private->fill_type, NULL);
}
if (layer)
{
GtkWidget *left_vbox = item_options_dialog_get_vbox (dialog);
@@ -398,10 +398,61 @@ layer_options_dialog_new (GimpImage *image,
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (layer));
view = gimp_container_tree_view_new (filters, context,
view = gimp_container_list_view_new (filters, context,
GIMP_VIEW_SIZE_SMALL, 0);
gtk_container_add (GTK_CONTAINER (frame), view);
gtk_widget_show (view);
if (GIMP_IS_LINK_LAYER (layer))
{
GtkWidget *open_dialog;
GimpLink *link;
/* File chooser dialog. */
open_dialog = gimp_open_dialog_new (private->gimp);
gtk_window_set_title (GTK_WINDOW (open_dialog),
_("Select Linked Image"));
/* File chooser button. */
file_select = gtk_file_chooser_button_new_with_dialog (open_dialog);
link = gimp_link_layer_get_link (GIMP_LINK_LAYER (layer));
gtk_file_chooser_set_file (GTK_FILE_CHOOSER (file_select),
gimp_link_get_file (link, NULL, NULL),
NULL);
gtk_widget_show (file_select);
gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
_("_Linked image:"), 0.0, 0.5,
file_select, 1);
g_signal_connect (file_select, "file-set",
G_CALLBACK (layer_options_file_set),
private);
private->link = gimp_link_duplicate (link);
/* Absolute path checkbox. */
button = gtk_check_button_new_with_mnemonic (_("S_tore with absolute path"));
gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
NULL, 0.0, 0.5,
button, 2);
g_object_bind_property (G_OBJECT (private->link), "absolute-path",
G_OBJECT (button), "active",
G_BINDING_SYNC_CREATE |
G_BINDING_BIDIRECTIONAL);
gtk_widget_set_visible (button, TRUE);
}
}
else
{
/* The fill type */
combo = gimp_enum_combo_box_new (GIMP_TYPE_FILL_TYPE);
gimp_grid_attach_aligned (GTK_GRID (grid), 0, row,
_("_Fill with:"), 0.0, 0.5,
combo, 1);
gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo),
private->fill_type,
G_CALLBACK (gimp_int_combo_box_get_active),
&private->fill_type, NULL);
}
button = item_options_dialog_get_lock_position (dialog);
@@ -502,6 +553,7 @@ layer_options_dialog_callback (GtkWidget *dialog,
private->composite_mode,
private->opacity / 100.0,
private->fill_type,
private->link,
width,
height,
offset_x,
@@ -574,3 +626,45 @@ layer_options_dialog_rename_toggled (GtkWidget *widget,
}
}
}
static void
layer_options_file_set (GtkFileChooserButton *widget,
LayerOptionsDialog *private)
{
GFile *file;
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (widget));
if (file)
{
gint width = 0;
gint height = 0;
if (private->layer)
{
width = gimp_item_get_width (GIMP_ITEM (private->layer));
height = gimp_item_get_height (GIMP_ITEM (private->layer));
if (width == 0 || height == 0)
{
GimpImage *image = gimp_item_get_image (GIMP_ITEM (private->layer));
width = gimp_image_get_width (image);
height = gimp_image_get_height (image);
}
}
gimp_link_set_file (private->link, file, width, height, TRUE, NULL, NULL);
if (gimp_link_is_broken (private->link))
{
gimp_link_set_file (private->link, NULL, width, height, TRUE, NULL, NULL);
g_signal_handlers_block_by_func (widget,
G_CALLBACK (layer_options_file_set),
private);
gtk_file_chooser_unselect_file (GTK_FILE_CHOOSER (widget), file);
g_signal_handlers_unblock_by_func (widget,
G_CALLBACK (layer_options_file_set),
private);
}
}
g_clear_object (&file);
}

View File

@@ -29,6 +29,7 @@ typedef void (* GimpLayerOptionsCallback) (GtkWidget *dialog,
GimpLayerCompositeMode layer_composite_mode,
gdouble layer_opacity,
GimpFillType layer_fill_type,
GimpLink *link,
gint layer_width,
gint layer_height,
gint layer_offset_x,

View File

@@ -56,6 +56,7 @@ libappdialogs_sources = [
'tips-dialog.c',
'tips-parser.c',
'user-install-dialog.c',
'vector-layer-options-dialog.c',
'welcome-dialog.c',
gitversion_h,
welcome_dialog_data_c,

View File

@@ -163,7 +163,7 @@ gimp_image_metadata_rotate_dialog (GimpImage *image,
gimp_pickable_flush (GIMP_PICKABLE (image));
pixbuf = gimp_viewable_get_pixbuf (GIMP_VIEWABLE (image), context,
width, height, NULL, NULL);
width, height, NULL);
if (pixbuf)
{
GdkPixbuf *rotated;

View File

@@ -125,7 +125,7 @@ static void palette_import_image_remove (GimpContainer *container,
GimpImage *image,
ImportDialog *private);
static void palette_import_make_palette (ImportDialog *private);
static void palette_import_file_set_filters (GtkFileChooser *file_chooser);
/* public functions */
@@ -282,13 +282,15 @@ palette_import_dialog_new (GimpContext *context)
/* Palette file name entry */
private->file_chooser = gtk_file_chooser_button_new (_("Select Palette File"),
GTK_FILE_CHOOSER_ACTION_OPEN);
GTK_FILE_CHOOSER_ACTION_OPEN);
gimp_grid_attach_aligned (GTK_GRID (grid), 0, 4,
NULL, 0.0, 0.5, private->file_chooser, 1);
gtk_size_group_add_widget (size_group, private->file_chooser);
g_object_unref (size_group);
/* Set valid palette files filters */
palette_import_file_set_filters (GTK_FILE_CHOOSER (private->file_chooser));
g_object_unref (size_group);
/* The "Import" frame */
@@ -893,3 +895,62 @@ palette_import_make_palette (ImportDialog *private)
! (palette &&
gimp_palette_get_n_colors (palette) > 0));
}
static void
palette_import_file_set_filters (GtkFileChooser *file_chooser)
{
GtkFileFilter *filter;
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("All palette files (*.*)"));
gtk_file_filter_add_pattern (filter, "*");
gtk_file_chooser_add_filter (file_chooser, filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("GIMP Palette (*.gpl)"));
gtk_file_filter_add_pattern (filter, "*.gpl");
gtk_file_filter_add_pattern (filter, "*.GPL");
gtk_file_chooser_add_filter (file_chooser, filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("Adobe Color Table (*.act)"));
gtk_file_filter_add_pattern (filter, "*.act");
gtk_file_filter_add_pattern (filter, "*.ACT");
gtk_file_chooser_add_filter (file_chooser, filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("Adobe Color Swatch (*.aco)"));
gtk_file_filter_add_pattern (filter, "*.aco");
gtk_file_filter_add_pattern (filter, "*.ACO");
gtk_file_chooser_add_filter (file_chooser, filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("Adobe Color Book (*.acb)"));
gtk_file_filter_add_pattern (filter, "*.acb");
gtk_file_filter_add_pattern (filter, "*.ACB");
gtk_file_chooser_add_filter (file_chooser, filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("Adobe Swatch Exchange (*.ase)"));
gtk_file_filter_add_pattern (filter, "*.ase");
gtk_file_filter_add_pattern (filter, "*.ASE");
gtk_file_chooser_add_filter (file_chooser, filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("Cascading Style Sheet (*.css)"));
gtk_file_filter_add_pattern (filter, "*.css");
gtk_file_filter_add_pattern (filter, "*.CSS");
gtk_file_chooser_add_filter (file_chooser, filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("JASC or RIFF Palette (*.pal)"));
gtk_file_filter_add_pattern (filter, "*.pal");
gtk_file_filter_add_pattern (filter, "*.PAL");
gtk_file_chooser_add_filter (file_chooser, filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("SwatchBooker (*.sbz)"));
gtk_file_filter_add_pattern (filter, "*.sbz");
gtk_file_filter_add_pattern (filter, "*.SBZ");
gtk_file_chooser_add_filter (file_chooser, filter);
}

View File

@@ -2476,6 +2476,9 @@ prefs_dialog_new (Gimp *gimp,
prefs_check_button_add (object, "layer-add-mask-invert",
_("Invert mask"),
GTK_BOX (vbox2));
prefs_check_button_add (object, "layer-add-mask-edit-mask",
_("Edit mask immediately"),
GTK_BOX (vbox2));
/* Merge Layers Dialog */
vbox2 = prefs_frame_new (_("Merge Layers Dialog"),

View File

@@ -429,7 +429,7 @@ resize_dialog_new (GimpViewable *viewable,
gimp_viewable_get_preview_size (viewable, 200, TRUE, TRUE, &width, &height);
pixbuf = gimp_viewable_get_pixbuf (viewable, context,
width, height, NULL, NULL);
width, height, NULL);
if (pixbuf)
gimp_offset_area_set_pixbuf (GIMP_OFFSET_AREA (private->area), pixbuf);

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