mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-10-06 01:12:40 +02:00
Compare commits
798 Commits
9c74e2fc00
...
gimp-3-0
Author | SHA1 | Date | |
---|---|---|---|
|
6e69dd3aaa | ||
|
8082e58981 | ||
|
a77e8fd05d | ||
|
4646a57a2d | ||
|
99aea0682c | ||
|
6e4fd33341 | ||
|
35311e3147 | ||
|
73b82cd306 | ||
|
3d3b4dee1a | ||
|
5969c2bf99 | ||
|
d81cfcc325 | ||
|
24aef543eb | ||
|
cfeec87ee6 | ||
|
25c9fcf382 | ||
|
5edbb073e2 | ||
|
65d51a7e22 | ||
|
a105f91292 | ||
|
52d95d3397 | ||
|
e9bade2792 | ||
|
b5c70171b4 | ||
|
5e9cb28a92 | ||
|
14d65c8984 | ||
|
b8fde036d4 | ||
|
1c178fb775 | ||
|
51d754c6d0 | ||
|
c9bb07858a | ||
|
f28ae86274 | ||
|
e49458b07b | ||
|
f2c13d319e | ||
|
8d9b12acef | ||
|
68235861da | ||
|
865360ee8e | ||
|
abaa5a5184 | ||
|
d89cee9d1b | ||
|
c7c4c44f79 | ||
|
fa3b9f897b | ||
|
5c40ba81f6 | ||
|
30baa23c65 | ||
|
5c5c692214 | ||
|
00a181f885 | ||
|
086bc2effc | ||
|
660ec0be61 | ||
|
de3aeddbf0 | ||
|
b0a197f826 | ||
|
da2f91bc22 | ||
|
6596b97c96 | ||
|
f31642a419 | ||
|
a9ead55147 | ||
|
9d3baeff2b | ||
|
50fda1d013 | ||
|
38bacb232e | ||
|
ab538eb732 | ||
|
b5a4acdf43 | ||
|
a640adf781 | ||
|
9227c02a2f | ||
|
3493f49292 | ||
|
d1c6584cbb | ||
|
d572c4bd25 | ||
|
f031436de1 | ||
|
e3e1c491cb | ||
|
b250472f2e | ||
|
66cc2e2173 | ||
|
95582ad439 | ||
|
ce26064aa2 | ||
|
8eeebed5fb | ||
|
a2586af9e0 | ||
|
386b50fdf2 | ||
|
a69e8671dc | ||
|
543808b723 | ||
|
a8b7011577 | ||
|
dfb1a7a06b | ||
|
26a9de0743 | ||
|
c02401b2a7 | ||
|
2aa6214272 | ||
|
a0cee0001a | ||
|
83b568db2c | ||
|
25791641fe | ||
|
aaf02143fd | ||
|
f6db0b0c1d | ||
|
0c1015294b | ||
|
3e5c4341e1 | ||
|
2d075cac99 | ||
|
3425bd852e | ||
|
39546bae9b | ||
|
df8b16ddb4 | ||
|
453ce7e31f | ||
|
55b96b64df | ||
|
003a9fcbc7 | ||
|
12aa79d695 | ||
|
fb6105a91f | ||
|
95c9121c69 | ||
|
eb691a9cdd | ||
|
99b236ccdb | ||
|
d090c56b3c | ||
|
ba828074bc | ||
|
746a7d22fe | ||
|
9d83052173 | ||
|
f7086295b2 | ||
|
44b368ab15 | ||
|
db609889e7 | ||
|
4fb7c882f2 | ||
|
031e41d4b5 | ||
|
2cb2b0deda | ||
|
4ad758e41a | ||
|
e9038b6c1b | ||
|
1a85761705 | ||
|
63704d59f8 | ||
|
20eac401a7 | ||
|
faf0c82e59 | ||
|
d4c9d53ddd | ||
|
87f97e043c | ||
|
4c5211aeaa | ||
|
b0c2d15e28 | ||
|
6998e09f12 | ||
|
6886329ffc | ||
|
39e7cb593e | ||
|
0c82d21473 | ||
|
819a9944de | ||
|
e75970cd9f | ||
|
2170e57ac5 | ||
|
1b702c6cf9 | ||
|
ec27a8a335 | ||
|
ceb44e7fab | ||
|
293f8dcc3b | ||
|
2aea04dccc | ||
|
fd0f495392 | ||
|
89c01638ca | ||
|
60d66a435b | ||
|
aed9cecd58 | ||
|
6cfac3aab3 | ||
|
2c484d70e7 | ||
|
c9e52916e9 | ||
|
cf20027c42 | ||
|
1ee540e2b7 | ||
|
36f3e78e20 | ||
|
aa50232b48 | ||
|
19a4c5cc70 | ||
|
7df5b399ab | ||
|
00590cd9f1 | ||
|
a9efbd33ac | ||
|
2dc831542a | ||
|
547bd9f630 | ||
|
4480cd19aa | ||
|
129c896183 | ||
|
42f2f5b200 | ||
|
22c2d6b2f0 | ||
|
c63c4d5446 | ||
|
7d86007f8f | ||
|
3e00d8b051 | ||
|
a604a8e4a6 | ||
|
fad0334dc2 | ||
|
56c495ec4b | ||
|
f18a1d54e4 | ||
|
cddfaef2a6 | ||
|
2692ba9793 | ||
|
6f9ad5adef | ||
|
38eec6a0a6 | ||
|
4d73d78c25 | ||
|
8796816094 | ||
|
62b2d78ce9 | ||
|
8b892f47b2 | ||
|
923777d63f | ||
|
e91da8d63d | ||
|
d07216de20 | ||
|
e7ade9dd6f | ||
|
0cdcbab01b | ||
|
851c1e2e1d | ||
|
fb529e56e7 | ||
|
16fc70d694 | ||
|
34a43d3c08 | ||
|
6c3c99d96a | ||
|
d97514a743 | ||
|
5c3e2122d5 | ||
|
3385862d8b | ||
|
7c24ee750d | ||
|
2d2d39f3da | ||
|
3d90916646 | ||
|
2884141dbb | ||
|
200397b5db | ||
|
29e1724501 | ||
|
f520f4c268 | ||
|
7422e66a50 | ||
|
78486fd460 | ||
|
cb96b02bdc | ||
|
d71e8ffa00 | ||
|
a31d0243f1 | ||
|
69691a99fe | ||
|
8f48d0b9aa | ||
|
cc02900d30 | ||
|
30debd889a | ||
|
3485ec68f9 | ||
|
d255161d40 | ||
|
8a1f13d838 | ||
|
43b3091756 | ||
|
5cf0f58b49 | ||
|
bfb5b9f22b | ||
|
6f1c2e0609 | ||
|
e42e46d7d9 | ||
|
7b6150134c | ||
|
b99b56cc44 | ||
|
e0fafcfda0 | ||
|
65fd742117 | ||
|
e73dfeb65c | ||
|
f90d572bb0 | ||
|
ed36d91e47 | ||
|
8bec5e0910 | ||
|
627eb7eac9 | ||
|
0b1836cbfc | ||
|
51336c251c | ||
|
dd370e5dd0 | ||
|
c52b339d93 | ||
|
4256945b48 | ||
|
68ac609295 | ||
|
e0ede3fea5 | ||
|
e1df31ce2e | ||
|
03986f8644 | ||
|
75c89cc35d | ||
|
e15a2b360a | ||
|
c0f4a47d2a | ||
|
f1bf235818 | ||
|
dd2dc14ebc | ||
|
71f88dc598 | ||
|
3d8dc28f81 | ||
|
bb041398ec | ||
|
1c50d3637c | ||
|
db481eff60 | ||
|
27aed674aa | ||
|
7df17bfff2 | ||
|
93f9f77cda | ||
|
76fe5fdb55 | ||
|
0810d21006 | ||
|
065a2137e9 | ||
|
c34718ec1a | ||
|
1b46f9919a | ||
|
c85ed3a831 | ||
|
a301edcaa6 | ||
|
ff52288279 | ||
|
6e9d42f6ed | ||
|
ea9a889560 | ||
|
dc105fced1 | ||
|
0442aaba18 | ||
|
6c3d75f2d2 | ||
|
dbefff4066 | ||
|
9206bd1eb0 | ||
|
af4fb0c736 | ||
|
e5f24a9009 | ||
|
ae69624488 | ||
|
519b2a21e0 | ||
|
b9627f313e | ||
|
d90852aa55 | ||
|
7507df7923 | ||
|
af3b5cba29 | ||
|
bd5c1abf62 | ||
|
dd8673bc79 | ||
|
120098fd1f | ||
|
f4629bae43 | ||
|
868bd52608 | ||
|
05001a0963 | ||
|
0b03537534 | ||
|
fde94e3b6a | ||
|
23ee091011 | ||
|
f83d93f24b | ||
|
b3604bb864 | ||
|
198b08dc2f | ||
|
70652c0a8f | ||
|
a20d8fa561 | ||
|
d57fb16c2d | ||
|
0079ca3db2 | ||
|
51ec493554 | ||
|
c9bbeed48a | ||
|
5d3049c29d | ||
|
eaa43858d3 | ||
|
1cd9e8ca89 | ||
|
2c16fb989b | ||
|
41689ef2e2 | ||
|
ff48f18f8a | ||
|
f6c1b2682e | ||
|
fc9014c0ed | ||
|
65b354d1b7 | ||
|
35e46412da | ||
|
364083a2b7 | ||
|
08216b96c0 | ||
|
bf29ced257 | ||
|
4aa9d4adb6 | ||
|
62ff5c1375 | ||
|
00657b7efb | ||
|
70524615a3 | ||
|
5efc38a22b | ||
|
92bf5af6d5 | ||
|
ae5774f9b0 | ||
|
630b1a2e4b | ||
|
370e79457f | ||
|
3c09a8fbf6 | ||
|
6a0d699d91 | ||
|
dcdaa47938 | ||
|
2b06439488 | ||
|
264bb8185e | ||
|
b3aaae6b46 | ||
|
c5b03588ad | ||
|
06caf0f336 | ||
|
33754b9732 | ||
|
2f0fcbf0f7 | ||
|
62734b98a5 | ||
|
b1397d782f | ||
|
14a90bc49d | ||
|
8fc0bca456 | ||
|
353e4e1b4b | ||
|
750b25e89a | ||
|
42ece88151 | ||
|
344ff82a2d | ||
|
9d094a26f2 | ||
|
03ae50a4f6 | ||
|
3594b6497e | ||
|
22e725c129 | ||
|
5bfca496fc | ||
|
e262f7f07f | ||
|
48548ab742 | ||
|
75c036b6c1 | ||
|
f4ab1beb55 | ||
|
0d6175e2a5 | ||
|
30691c39f0 | ||
|
97f473aa3f | ||
|
378f990fe9 | ||
|
ff4e58b89c | ||
|
b2357ffe26 | ||
|
862bbe0014 | ||
|
f02ed53502 | ||
|
64a23d0799 | ||
|
a8f194d6c1 | ||
|
251870ade6 | ||
|
3b72778d76 | ||
|
2d8e3a2523 | ||
|
170d676a22 | ||
|
638b706371 | ||
|
0b8b40fcda | ||
|
6fb6835412 | ||
|
f170eaa493 | ||
|
cd178cb6e0 | ||
|
8a928fb48c | ||
|
343613c2e1 | ||
|
cf8ccde824 | ||
|
40a2ffc0ab | ||
|
0756e9eb29 | ||
|
0d6332db4f | ||
|
ccff32ce25 | ||
|
4cc43207bd | ||
|
f322a862e2 | ||
|
75a3035e9e | ||
|
1a60da1540 | ||
|
62ebacbca3 | ||
|
9a76ae6f22 | ||
|
8601b86229 | ||
|
e942a9889e | ||
|
f3f5545b64 | ||
|
204c45a24b | ||
|
bce3c8a91d | ||
|
adf3ec5b3a | ||
|
7eb3b86a6f | ||
|
52e4751ed8 | ||
|
8b151b07b6 | ||
|
0765b43dc5 | ||
|
e5d39aca31 | ||
|
a1662b354e | ||
|
ab32b16854 | ||
|
7d72a31431 | ||
|
634a983d3c | ||
|
1dd58f6084 | ||
|
fb4a3c6f9a | ||
|
55f890976c | ||
|
368a9dd9b0 | ||
|
3975bc4f76 | ||
|
860c1e1b3d | ||
|
8ff11234f5 | ||
|
aea5e7ec9e | ||
|
2a1b2050bb | ||
|
226e79ee26 | ||
|
c27096db9e | ||
|
5367af70ca | ||
|
c871ae4e22 | ||
|
8ac7a0737c | ||
|
23e083b03d | ||
|
160e78061a | ||
|
7d5c644e67 | ||
|
075a57c9f4 | ||
|
9ab2174138 | ||
|
a6669446ab | ||
|
a1faa99245 | ||
|
c838b0c869 | ||
|
bebb00b5d9 | ||
|
c72644797a | ||
|
69d3170bb9 | ||
|
f48b81560e | ||
|
2349b7fe05 | ||
|
c88a3895ae | ||
|
c69fccd7eb | ||
|
de44a35e2d | ||
|
be00573373 | ||
|
df4cab222e | ||
|
4fdecfa6e3 | ||
|
ac2d3abd8f | ||
|
7271f5dd79 | ||
|
e9460c2953 | ||
|
c7da856096 | ||
|
a108153fb2 | ||
|
ea038ba54f | ||
|
b31e1ce1f9 | ||
|
d575dda062 | ||
|
7f89dc042d | ||
|
7d924ab1d0 | ||
|
ad0dd37e61 | ||
|
16a9c521a4 | ||
|
c40e0509b1 | ||
|
ebc2715cb7 | ||
|
c519df8efd | ||
|
6667ae9614 | ||
|
b046c86891 | ||
|
acfc1d4c59 | ||
|
7304dde26f | ||
|
c06b863036 | ||
|
4e54e65615 | ||
|
d0afcb2513 | ||
|
74588ed328 | ||
|
bb49cb4244 | ||
|
9167ba0801 | ||
|
dd4e1c9bcb | ||
|
ff80f51cca | ||
|
e3a016621f | ||
|
be4286878f | ||
|
221f9cde04 | ||
|
62d806a2a5 | ||
|
73e4246c80 | ||
|
fea9cc2a0f | ||
|
3635a7cba1 | ||
|
e64b528cd4 | ||
|
40a3b28895 | ||
|
b24bc16230 | ||
|
8746cc20d8 | ||
|
f4184fb9a1 | ||
|
450ffa522f | ||
|
68253fbcd6 | ||
|
59d9736ae7 | ||
|
684355e776 | ||
|
7f25157cbd | ||
|
0ad20e9978 | ||
|
31d48d5a6c | ||
|
fef770abc3 | ||
|
3a7d5b1502 | ||
|
2b4b5ebec0 | ||
|
f7167bfad7 | ||
|
8818507dd2 | ||
|
45ab5b7396 | ||
|
44ca94a234 | ||
|
dba32330ad | ||
|
d428b513a4 | ||
|
7f9a7b26b7 | ||
|
ee7ef712ac | ||
|
cbe63bb8ca | ||
|
2010ded65e | ||
|
56d4da4860 | ||
|
cf18bb04ae | ||
|
e0798f7d13 | ||
|
7c6a666403 | ||
|
2d1f64c21e | ||
|
bfc1f6c828 | ||
|
6129ad10cb | ||
|
fd4d87e2c5 | ||
|
cabb091b91 | ||
|
97e044c1da | ||
|
917a6a1fd6 | ||
|
e3d5999dc1 | ||
|
a7e473095c | ||
|
0e517c4d0a | ||
|
4d434a8e94 | ||
|
be388e755f | ||
|
00199fe4a2 | ||
|
8396636b98 | ||
|
3d30184897 | ||
|
ab4bb47e25 | ||
|
f2af098ef7 | ||
|
9c1548bb44 | ||
|
8df143b112 | ||
|
d172f61651 | ||
|
d2dfe35e68 | ||
|
4d949bf907 | ||
|
97cd0a547e | ||
|
2f90972e62 | ||
|
541291ad6f | ||
|
98eda40dcc | ||
|
490ef967e8 | ||
|
4f1a42dc67 | ||
|
fff2650d0e | ||
|
744b46a460 | ||
|
6669c8de07 | ||
|
c360b6e7f0 | ||
|
03e048fdbd | ||
|
28a3a2d5e3 | ||
|
88091b3796 | ||
|
a4e722e831 | ||
|
37db40df0a | ||
|
7eff9e5d6c | ||
|
ea8e4ee902 | ||
|
f79f9cd015 | ||
|
466b6f8a39 | ||
|
a02a9adc74 | ||
|
2e4f1f1beb | ||
|
a0af5873b2 | ||
|
f8748991cf | ||
|
79f68e2ba4 | ||
|
acc89a47d1 | ||
|
4cd077b848 | ||
|
a97024be42 | ||
|
c8c1b71451 | ||
|
2ab734cf78 | ||
|
8ed3889f24 | ||
|
1bc9190a60 | ||
|
85e9b4e80e | ||
|
89cc277fed | ||
|
685d230a09 | ||
|
b394428d5c | ||
|
b1e5e4166d | ||
|
dd3333260f | ||
|
b78dfda746 | ||
|
d8dacb36ed | ||
|
bddeb457e2 | ||
|
f90b934f15 | ||
|
e9f5ff23ec | ||
|
12f06fd84d | ||
|
25c8fe150e | ||
|
006e9a1871 | ||
|
a9bc3f68ba | ||
|
3130c4f527 | ||
|
689b7ab191 | ||
|
3dec3da781 | ||
|
fd3d4a900c | ||
|
29d8994a06 | ||
|
26813b0700 | ||
|
67c50a87d1 | ||
|
0205a29603 | ||
|
af4591f409 | ||
|
a5be286f1c | ||
|
c31176da28 | ||
|
ad0e1a2e2b | ||
|
0c863016f3 | ||
|
fa2d998b6f | ||
|
d702705aa1 | ||
|
bc1ee83a9c | ||
|
0028c81db1 | ||
|
bf4ae28ac0 | ||
|
e6e669d28a | ||
|
97455b62b6 | ||
|
b97ca8aab4 | ||
|
7295447e6b | ||
|
a932e1913e | ||
|
654ad4d77b | ||
|
d99bb22c95 | ||
|
758d4852d5 | ||
|
abf32e2842 | ||
|
159d8b0fdf | ||
|
2af072d247 | ||
|
f45742928c | ||
|
5094a5dbe9 | ||
|
bb0198552d | ||
|
93a9501797 | ||
|
ea98cea0b7 | ||
|
385a70016c | ||
|
b6f434d63f | ||
|
5fb338865f | ||
|
03703151a7 | ||
|
891ade751a | ||
|
c40c8a805e | ||
|
1ed34ab5f5 | ||
|
e702c8adae | ||
|
f2f8cd6b51 | ||
|
4787c8c807 | ||
|
fe62c2c497 | ||
|
7e0b321917 | ||
|
395e65fff3 | ||
|
b11ad046b0 | ||
|
1e7b0a05b3 | ||
|
e37b0051d4 | ||
|
23d325f75e | ||
|
0211b1d8ad | ||
|
08514ea908 | ||
|
cbd12eb252 | ||
|
35aac2071a | ||
|
6012696e92 | ||
|
f1c8146817 | ||
|
8a539e995c | ||
|
0a5b3adce0 | ||
|
b717a7f040 | ||
|
ae8167a661 | ||
|
6c7ec3a697 | ||
|
1f2187cfa4 | ||
|
1e7a1fdae4 | ||
|
96c448c9a5 | ||
|
2a43d1e195 | ||
|
ada93d7e5a | ||
|
5f49716379 | ||
|
0a127bd895 | ||
|
923d19fc15 | ||
|
65955e46c8 | ||
|
e99294f683 | ||
|
2d558d8ea0 | ||
|
a32e01e738 | ||
|
26e5e8f3df | ||
|
e6fe57371d | ||
|
aa66ec06b3 | ||
|
218e7642be | ||
|
d4f6b77c14 | ||
|
1b1d905e65 | ||
|
20ce3f87fd | ||
|
ac42bed7b2 | ||
|
dfedd5875c | ||
|
6400ff65d1 | ||
|
055aae53f7 | ||
|
f7cc3a78c1 | ||
|
c776e02ef5 | ||
|
939d77c281 | ||
|
9baf9dbdca | ||
|
523f100656 | ||
|
4c17447abd | ||
|
0133a0b811 | ||
|
7a82e2d436 | ||
|
2188e05f59 | ||
|
6409076d50 | ||
|
59a07dffb3 | ||
|
d89d471908 | ||
|
2c730a5517 | ||
|
b8c8c9ac38 | ||
|
059cf39ffa | ||
|
e16b928638 | ||
|
20909283d8 | ||
|
b7701910df | ||
|
a499cf5635 | ||
|
e22d1c4590 | ||
|
fb5dc5f119 | ||
|
9c150a7a85 | ||
|
c289689659 | ||
|
972206d08c | ||
|
38b5a53783 | ||
|
f36640f22e | ||
|
08d81f2176 | ||
|
aa5c751542 | ||
|
e2d5e56c8d | ||
|
f0e8f72885 | ||
|
4c179d5192 | ||
|
1bb8672d76 | ||
|
d4acc18911 | ||
|
1cf9950d4b | ||
|
b02d4f8619 | ||
|
aac1224b03 | ||
|
9e13a3e4ad | ||
|
ddb1569d0e | ||
|
54e9058e3a | ||
|
c01459af11 | ||
|
6ce9f6c90e | ||
|
204aa6685a | ||
|
bafc6efb6e | ||
|
bc1f8cfd17 | ||
|
ee555b9e0c | ||
|
8787704034 | ||
|
a31852237a | ||
|
0be6e7a718 | ||
|
9960603571 | ||
|
b43e5382cf | ||
|
4004cae28c | ||
|
3fdd3d385d | ||
|
7e6b319616 | ||
|
dcf130df14 | ||
|
bf2a49e394 | ||
|
01f29debf2 | ||
|
88fbc7be2f | ||
|
4d2b8b94da | ||
|
62703353e7 | ||
|
9ccd191ab0 | ||
|
c393e5ce7a | ||
|
c45c03ffda | ||
|
a117810670 | ||
|
35d502edd2 | ||
|
cc2a306354 | ||
|
a140c181d1 | ||
|
77c7124612 | ||
|
f9055788d2 | ||
|
abcd1c5cee | ||
|
4f13a6c4a9 | ||
|
f322f1d8fb | ||
|
7abafcc462 | ||
|
84614a3683 | ||
|
86a2fc685e | ||
|
b9af5f4868 | ||
|
26862cea6e | ||
|
045c23f982 | ||
|
187846f05a | ||
|
90b8991995 | ||
|
5f9b7370ff | ||
|
0741f7fc72 | ||
|
8774f46c3d | ||
|
4e01949adb | ||
|
87c090e829 | ||
|
8f67090536 | ||
|
047b6dcadb | ||
|
a38d25886b | ||
|
fa70c3e547 | ||
|
ae3a3db048 | ||
|
de06f2260e | ||
|
2e94d5228f | ||
|
2fb7e8afdc | ||
|
f73854a0ef | ||
|
1c10963a6e | ||
|
f4013972fe | ||
|
c78650b5c4 | ||
|
5f379ff45b | ||
|
2e7782ae13 | ||
|
6069d81807 | ||
|
d67c859711 | ||
|
3ad84e955f | ||
|
ec1d626330 | ||
|
96beda2ae5 | ||
|
26c21c534f | ||
|
66d05121af | ||
|
04e2d0016f | ||
|
44bed73c6b | ||
|
8993293996 | ||
|
fd450f07f9 | ||
|
e7f033ac67 | ||
|
5ac4cc3a0e | ||
|
c480a66187 | ||
|
eceef8dbc0 | ||
|
832363c0f0 | ||
|
cf129ed0a5 | ||
|
08dd69d5f6 | ||
|
47405bd97f | ||
|
6eca9ebe51 | ||
|
1e0879e0da | ||
|
7d4d967972 | ||
|
e565a5594f | ||
|
647d3a0222 | ||
|
efcdcb7009 | ||
|
ba55fd716c | ||
|
9f5521b52a | ||
|
129d499698 | ||
|
afa454398f | ||
|
34dc46f892 | ||
|
8f078f45a9 | ||
|
efa673b796 | ||
|
6486f908c4 | ||
|
6fb91fea86 | ||
|
c9788ceeb8 | ||
|
a7cff72eaf | ||
|
81f9026b16 | ||
|
fb12d2d1fe | ||
|
5d261000a8 | ||
|
cb11675766 | ||
|
3eca7cea89 | ||
|
6eaf61b86b | ||
|
00b59dbcc8 | ||
|
ecb25b5ba3 | ||
|
c937ff855f | ||
|
aaca92f96a | ||
|
e229a04170 | ||
|
8fcb7ad303 | ||
|
fb95bc93bc | ||
|
48a5479232 | ||
|
b89771ed27 | ||
|
98d123b3df | ||
|
d14c8d7f2b | ||
|
17f3956343 | ||
|
9c76d5dee7 | ||
|
eb55331c93 | ||
|
3c3768586c | ||
|
71fb2fbe85 | ||
|
725e8367f7 | ||
|
dd712a7ac6 | ||
|
f7224b0d35 | ||
|
caa9d8a799 | ||
|
25f7863bef | ||
|
d202119b9b | ||
|
06de383c37 | ||
|
263b8e17c7 | ||
|
579f45e5ad | ||
|
8c0b6bf814 | ||
|
952cc59544 | ||
|
920278029e | ||
|
fa0a9f395c | ||
|
dfe09f2e5d | ||
|
3ecb537537 | ||
|
c8ab50fe57 | ||
|
d0bce08dc3 | ||
|
4feb016009 | ||
|
b097f2baae | ||
|
4742e81c67 | ||
|
55c41c7617 | ||
|
0a12e66709 | ||
|
cabb14cdd4 | ||
|
941ecc6c9e | ||
|
70864ff1a1 | ||
|
b3b111a3ab | ||
|
31a39392aa |
626
.gitlab-ci.yml
626
.gitlab-ci.yml
@@ -3,8 +3,9 @@ spec:
|
||||
distribution_pipeline:
|
||||
description: 'Pipelines that creates installable GIMP'
|
||||
options:
|
||||
- GIMP_CI_APPIMAGE #trigger the appimage making.
|
||||
- GIMP_CI_APPIMAGE #trigger the appimage making (base & fast).
|
||||
- GIMP_CI_FLATPAK #trigger the flatpak build and publishing (base but slow)
|
||||
- GIMP_CI_SNAP #trigger the snap build (base but slow)
|
||||
- GIMP_CI_WIN_INSTALLER #trigger all native MSYS2 builds then creates Inno Windows installer (base but slow)
|
||||
- GIMP_CI_MS_STORE #trigger arm64 and x64 native MSYS2 builds then creates a .msixbundle (base but slow)
|
||||
- none
|
||||
@@ -12,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
|
||||
@@ -29,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
|
||||
@@ -42,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
|
||||
@@ -76,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
|
||||
@@ -93,37 +99,40 @@ workflow:
|
||||
|
||||
stages:
|
||||
- dependencies
|
||||
- gimp
|
||||
- build
|
||||
- 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_v2]
|
||||
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
|
||||
- echo -e "\e[0Ksection_start:`date +%s`:environ[collapsed=true]\r\e[0KPreparing build environment"
|
||||
- gcc -print-multi-os-directory 2>/dev/null | grep ./ && export LIB_DIR=$(gcc -print-multi-os-directory | sed 's/\.\.\///g') || export LIB_DIR="lib"
|
||||
- gcc -print-multiarch 2>/dev/null | grep . && export LIB_SUBDIR=$(echo $(gcc -print-multiarch)'/')
|
||||
# See: https://testing.developer.gimp.org/core/setup/build/#preparing-for-building
|
||||
- printf "\e[0Ksection_start:`date +%s`:environ[collapsed=true]\r\e[0KPreparing build environment\n"
|
||||
- gcc -print-multi-os-directory 2>/dev/null | grep -q ./ && export LIB_DIR=$(gcc -print-multi-os-directory | sed 's/\.\.\///g') || export LIB_DIR="lib"
|
||||
- gcc -print-multiarch 2>/dev/null | grep -q . && export LIB_SUBDIR=$(echo $(gcc -print-multiarch)'/') || export LIB_SUBDIR=
|
||||
## Build-time vars
|
||||
- export PKG_CONFIG_PATH="${GIMP_PREFIX}/${LIB_DIR}/${LIB_SUBDIR}pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
|
||||
- export XDG_DATA_DIRS="${GIMP_PREFIX}/share:/usr/share${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}"
|
||||
@@ -131,44 +140,39 @@ stages:
|
||||
- export PATH="${GIMP_PREFIX}/bin:$PATH"
|
||||
- export LD_LIBRARY_PATH="${GIMP_PREFIX}/${LIB_DIR}/${LIB_SUBDIR}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
||||
- export GI_TYPELIB_PATH="${GIMP_PREFIX}/${LIB_DIR}/${LIB_SUBDIR}girepository-1.0${GI_TYPELIB_PATH:+:$GI_TYPELIB_PATH}"
|
||||
- echo -e "\e[0Ksection_end:`date +%s`:environ\r\e[0K"
|
||||
- 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 "RUN echo -e \"\e[0Ksection_start:0000000001:deps_install[collapsed=true]\r\e[0KInstalling dependencies provided by 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
|
||||
ccache
|
||||
clang
|
||||
- echo "${TOOLCHAIN:-build-essential}
|
||||
appstream
|
||||
bison
|
||||
desktop-file-utils
|
||||
flex
|
||||
gi-docgen
|
||||
git
|
||||
gobject-introspection
|
||||
libgtk-3-bin
|
||||
lld
|
||||
meson
|
||||
valac
|
||||
xauth
|
||||
xsltproc
|
||||
xvfb" >> Dockerfile
|
||||
xsltproc" >> Dockerfile
|
||||
## Runtime dependencies
|
||||
- echo "RUN apt-get install -qq -y --no-install-recommends \\" >> Dockerfile
|
||||
- echo "at-spi2-core
|
||||
@@ -178,9 +182,10 @@ deps-debian:
|
||||
glib-networking
|
||||
graphviz
|
||||
graphviz-dev
|
||||
gvfs
|
||||
iso-codes
|
||||
libaa1-dev
|
||||
libappstream-glib-dev
|
||||
libappstream-dev
|
||||
libarchive-dev
|
||||
libbz2-dev
|
||||
libcfitsio-dev
|
||||
@@ -191,6 +196,7 @@ deps-debian:
|
||||
libgtk-3-dev
|
||||
libgudev-1.0-dev
|
||||
libheif-dev
|
||||
$LIBHEIF_PLUGINS
|
||||
libjson-glib-dev
|
||||
libjxl-dev
|
||||
liblcms2-dev
|
||||
@@ -203,9 +209,7 @@ deps-debian:
|
||||
libopenjp2-7-dev
|
||||
libpoppler-glib-dev
|
||||
libqoi-dev
|
||||
libraw-dev
|
||||
librsvg2-dev
|
||||
libspiro-dev
|
||||
libsuitesparse-dev
|
||||
libtiff-dev
|
||||
$UMFPACK
|
||||
@@ -219,37 +223,38 @@ deps-debian:
|
||||
python3
|
||||
python3-gi
|
||||
python3-gi-cairo" >> Dockerfile
|
||||
- echo "RUN echo -e \"\e[0Ksection_end:0000000002:deps_install\r\e[0K\"" >> Dockerfile
|
||||
- echo "RUN printf \"\e[0Ksection_end:0000000002:deps_install\r\e[0K\n\"" >> Dockerfile
|
||||
# Prepare environ
|
||||
- echo "FROM $CI_REGISTRY_IMAGE:build-debian-${DEB_VERSION}-${RUNNER}" > Dockerfile2;
|
||||
- echo "RUN echo -e \"\e[0Ksection_start:`date +%s`:environ[collapsed=true]\r\e[0KPreparing build environment\"" >> 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 "RUN printf \"\e[0Ksection_start:`date +%s`:environ[collapsed=true]\r\e[0KPreparing build environment\n\"" >> 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 echo -e \"\e[0Ksection_end:`date +%s`:environ\r\e[0K\"" >> Dockerfile2;
|
||||
- echo "RUN printf \"\e[0Ksection_end:`date +%s`:environ\r\e[0K\n\"" >> Dockerfile2;
|
||||
# Build some dependencies
|
||||
## Build babl
|
||||
- echo "RUN echo -e \"\e[0Ksection_start:`date +%s`:babl_build[collapsed=true]\r\e[0KBuilding babl\"" >> 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 echo -e \"\e[0Ksection_end:`date +%s`:babl_build\r\e[0K\"" >> Dockerfile2;
|
||||
- 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" 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 echo -e \"\e[0Ksection_start:`date +%s`:gegl_build[collapsed=true]\r\e[0KBuilding gegl\"" >> 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 echo -e \"\e[0Ksection_end:`date +%s`:gegl_build\r\e[0K\"" >> 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
|
||||
- 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" 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;
|
||||
#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,110 +264,41 @@ deps-debian:
|
||||
- gegl/_build-${RUNNER}/config.h
|
||||
expire_in: 2 hours
|
||||
|
||||
gimp-debian:
|
||||
extends: .debian
|
||||
needs: ["deps-debian"]
|
||||
stage: gimp
|
||||
gimp-debian-nonreloc:
|
||||
extends: .debian-nonreloc
|
||||
needs: ["deps-debian-nonreloc"]
|
||||
stage: build
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
script:
|
||||
- *ENVIRON
|
||||
# Build GIMP
|
||||
- echo -e "\e[0Ksection_start:`date +%s`:gimp_build[collapsed=true]\r\e[0KBuilding GIMP"
|
||||
- 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
|
||||
- echo -e "\e[0Ksection_end:`date +%s`:gimp_build\r\e[0K"
|
||||
# Create bundle
|
||||
- echo -e "\e[0Ksection_start:`date +%s`:gimp_bundle[collapsed=true]\r\e[0KCreating bundle"
|
||||
- ninja install &> ninja_install.log || cat ninja_install.log
|
||||
- cd ..
|
||||
- bash build/linux/appimage/3_dist-gimp-goappimage.sh --bundle-only &> goappimage.log || cat goappimage.log
|
||||
- echo -e "\e[0Ksection_end:`date +%s`:gimp_bundle\r\e[0K"
|
||||
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_v2
|
||||
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
|
||||
- echo -e "\e[0Ksection_start:`date +%s`:gimp_build[collapsed=true]\r\e[0KBuilding GIMP"
|
||||
- printf "\e[0Ksection_start:`date +%s`:gimp_build[collapsed=true]\r\e[0KBuilding GIMP\n"
|
||||
- meson setup _build-${RUNNER} -Dprefix="${GIMP_PREFIX}"
|
||||
-Dfile-plug-ins-test=true
|
||||
$MESON_OPTIONS
|
||||
- cd _build-${RUNNER}
|
||||
- ninja
|
||||
- echo -e "\e[0Ksection_end:`date +%s`:gimp_build\r\e[0K"
|
||||
- printf "\e[0Ksection_end:`date +%s`:gimp_build\r\e[0K\n"
|
||||
# Check execution
|
||||
- echo -e "\e[0Ksection_start:`date +%s`:gimp_test[collapsed=true]\r\e[0KTesting GIMP execution"
|
||||
- printf "\e[0Ksection_start:`date +%s`:gimp_test[collapsed=true]\r\e[0KTesting GIMP execution\n"
|
||||
- ninja test
|
||||
- echo -e "\e[0Ksection_end:`date +%s`:gimp_test\r\e[0K"
|
||||
- printf "\e[0Ksection_end:`date +%s`:gimp_test\r\e[0K\n"
|
||||
# Check source
|
||||
- echo -e "\e[0Ksection_start:`date +%s`:gimp_tar[collapsed=true]\r\e[0KChecking GIMP source"
|
||||
- printf "\e[0Ksection_start:`date +%s`:gimp_tar[collapsed=true]\r\e[0KChecking GIMP source\n"
|
||||
- if [ $(git diff |wc -l) -ne 0 ]; then
|
||||
echo "ERROR. A generated file was updated without the source:";
|
||||
printf "ERROR. A generated file was updated without the source:\n";
|
||||
git diff;
|
||||
exit 1;
|
||||
fi
|
||||
- if [ "$VARIANT" != "-gcc" ] && [ "$VARIANT" != "-raster" ] && [ "$CI_PIPELINE_SOURCE" != "merge_request_event" ]; then
|
||||
ninja dist &> ninja_dist.txt || cat ninja_dist.txt;
|
||||
- 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
|
||||
- echo -e "\e[0Ksection_end:`date +%s`:gimp_tar\r\e[0K"
|
||||
- printf "\e[0Ksection_end:`date +%s`:gimp_tar\r\e[0K\n"
|
||||
# Check install
|
||||
- echo -e "\e[0Ksection_start:`date +%s`:gimp_install[collapsed=true]\r\e[0KChecking GIMP installation"
|
||||
- ninja install &> ninja_install.txt || cat ninja_install.txt;
|
||||
- echo -e "\e[0Ksection_end:`date +%s`:gimp_install\r\e[0K"
|
||||
- printf "\e[0Ksection_start:`date +%s`:gimp_install[collapsed=true]\r\e[0KChecking GIMP installation\n"
|
||||
- ninja install > ninja_install.log 2>&1 || { cat ninja_install.log; exit 1; };
|
||||
- printf "\e[0Ksection_end:`date +%s`:gimp_install\r\e[0K\n"
|
||||
artifacts:
|
||||
paths:
|
||||
- _install-${RUNNER}/
|
||||
@@ -374,49 +310,188 @@ gimp-debian-x64:
|
||||
expire_in: 2 days
|
||||
|
||||
|
||||
## Flatpak CI ##
|
||||
.flatpak-x64:
|
||||
## 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
|
||||
#We need to specify this since .flatpak from flatpak_ci_initiative.yml sets to true
|
||||
interruptible: false
|
||||
rules:
|
||||
- if: '$CI_MERGE_REQUEST_LABELS =~ /.*Package:Flatpak.*/'
|
||||
interruptible: true
|
||||
- if: '$GIMP_CI_FLATPAK != null || "$[[ inputs.distribution_pipeline ]]" =~ /.*GIMP_CI_FLATPAK.*/'
|
||||
parallel:
|
||||
matrix:
|
||||
- RUNNER: [flatpak-aarch64, flatpak-x86_64]
|
||||
tags:
|
||||
- flatpak
|
||||
image: 'quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master'
|
||||
- $RUNNER
|
||||
image: quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master
|
||||
variables:
|
||||
RUN_TESTS: 0
|
||||
MESON_DIST: 0
|
||||
before_script:
|
||||
- export GIMP_PREFIX="${CI_PROJECT_DIR}/_install"
|
||||
timeout: 40m
|
||||
#30min is enough only if no module was updated/rebuilt, we need more time in case of module bumps
|
||||
timeout: 90m
|
||||
|
||||
deps-flatpak-x64:
|
||||
extends: .flatpak-x64
|
||||
deps-flatpak:
|
||||
extends: .flatpak
|
||||
stage: dependencies
|
||||
#https://gitlab.gnome.org/Infrastructure/Infrastructure/-/issues/1502
|
||||
#cache:
|
||||
#key: ${CI_JOB_NAME_SLUG}
|
||||
#paths:
|
||||
#- .flatpak-builder/
|
||||
script:
|
||||
- bash build/linux/flatpak/1_build-deps-flatpak.sh
|
||||
- sh build/linux/flatpak/1_build-deps-flatpakbuilder.sh
|
||||
artifacts:
|
||||
paths:
|
||||
- .flatpak-builder.tar
|
||||
- flatpak-builder.log
|
||||
- _build-$RUNNER.tar.zst
|
||||
- babl-meson-log.tar
|
||||
- gegl-meson-log.tar
|
||||
expire_in: 2 hours
|
||||
|
||||
gimp-flatpak-x64:
|
||||
extends: .flatpak-x64
|
||||
needs: ["deps-flatpak-x64"]
|
||||
stage: gimp
|
||||
gimp-flatpak:
|
||||
extends: .flatpak
|
||||
needs: ["deps-flatpak"]
|
||||
stage: build
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
script:
|
||||
- bash build/linux/flatpak/2_build-gimp-flatpak.sh
|
||||
- sh build/linux/flatpak/2_build-gimp-flatpakbuilder.sh
|
||||
artifacts:
|
||||
paths:
|
||||
- repo.tar
|
||||
- temp*.flatpak
|
||||
- repo*.tar
|
||||
- gimp-flatpak-builder.log
|
||||
- gimp-meson-log.tar
|
||||
expire_in: 2 days
|
||||
|
||||
|
||||
## Snap CI (Ubuntu) ##
|
||||
.snap:
|
||||
extends: .default
|
||||
rules:
|
||||
- if: '$CI_MERGE_REQUEST_LABELS =~ /.*Package:Snap.*/'
|
||||
interruptible: true
|
||||
- if: '$GIMP_CI_SNAP != null || "$[[ inputs.distribution_pipeline ]]" =~ /.*GIMP_CI_SNAP.*/'
|
||||
parallel:
|
||||
matrix:
|
||||
- RUNNER: [aarch64, x86_64_v3]
|
||||
tags:
|
||||
- $RUNNER
|
||||
image: $CI_REGISTRY_IMAGE:build-snap-${SNAPCRAFT_BASE_VERSION}-${RUNNER}
|
||||
variables:
|
||||
SNAPCRAFT_BASE_VERSION: "8_core24"
|
||||
RUNNER: x86_64_v3
|
||||
timeout: 30m
|
||||
|
||||
deps-snap:
|
||||
extends: .snap
|
||||
stage: dependencies
|
||||
image: quay.io/buildah/stable
|
||||
script:
|
||||
- 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:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
script:
|
||||
- sh build/linux/snap/2_build-gimp-snapcraft.sh
|
||||
artifacts:
|
||||
paths:
|
||||
- temp*.snap
|
||||
- gimp-snapcraft.log
|
||||
- gimp-meson-log.tar
|
||||
expire_in: 2 days
|
||||
|
||||
@@ -425,16 +500,20 @@ gimp-flatpak-x64:
|
||||
.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'
|
||||
@@ -442,10 +521,10 @@ gimp-flatpak-x64:
|
||||
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
|
||||
@@ -454,90 +533,85 @@ gimp-flatpak-x64:
|
||||
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:
|
||||
extends: .win
|
||||
stage: dependencies
|
||||
script:
|
||||
- build/windows/1_build-deps-msys2.ps1
|
||||
- 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"]
|
||||
stage: gimp
|
||||
needs:
|
||||
- job: deps-win
|
||||
#to allow running outside 'GNOME/gimp' namespace (on MRs)
|
||||
optional: true
|
||||
stage: build
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
script:
|
||||
- build/windows/2_build-gimp-msys2.ps1
|
||||
- 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/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
|
||||
@@ -552,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/')
|
||||
@@ -581,7 +651,7 @@ file-plug-in-tests:
|
||||
- cd ..
|
||||
- cat ${PLUG_IN_DIR}test-file-plug-ins/batch-import-tests.py | gimp-console-${APP_VER} -idf --batch-interpreter python-fu-eval -b - --quit
|
||||
- if [ $(grep -c "${REGRESSION_STRING}" "${GIMP_TESTS_LOG_FILE}") -ne 1 ]; then
|
||||
echo "There are file import regressions. Check the log at ${GIMP_TESTS_LOG_FILE}!";
|
||||
printf "There are file import regressions. Check the log at ${GIMP_TESTS_LOG_FILE}!\n";
|
||||
exit 1;
|
||||
fi
|
||||
# FIXME No export testing for now until it's more developed. A limited test
|
||||
@@ -592,6 +662,7 @@ file-plug-in-tests:
|
||||
reports:
|
||||
junit: "_log/import-tests.xml"
|
||||
expire_in: 2 days
|
||||
timeout: 30m
|
||||
|
||||
meson-health:
|
||||
extends: .default
|
||||
@@ -599,10 +670,13 @@ meson-health:
|
||||
- <<: *CI_MERGE
|
||||
- <<: *CI_COMMIT
|
||||
stage: analysis
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
script:
|
||||
- apt-get update
|
||||
- apt-get install -y git
|
||||
- bash .gitlab/run_meson_health_diff.sh
|
||||
- apt-get update -qq
|
||||
- apt-get install -qq -y --no-install-recommends git shellcheck devscripts
|
||||
- sh .gitlab/run_meson_health_diff.sh
|
||||
allow_failure: true
|
||||
|
||||
clang-format:
|
||||
extends: .default
|
||||
@@ -613,7 +687,7 @@ clang-format:
|
||||
- apt-get update
|
||||
- apt-get install -y clang-format
|
||||
git
|
||||
- .gitlab/run_style_check_diff.sh
|
||||
- sh .gitlab/run_style_check_diff.sh
|
||||
allow_failure: true
|
||||
artifacts:
|
||||
when: on_failure
|
||||
@@ -622,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:
|
||||
@@ -631,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:
|
||||
@@ -645,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
|
||||
@@ -667,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
|
||||
@@ -728,7 +815,7 @@ dist-appimage-weekly:
|
||||
needs: ["gimp-debian"]
|
||||
stage: distribution
|
||||
script:
|
||||
- bash build/linux/appimage/3_dist-gimp-goappimage.sh
|
||||
- sh build/linux/appimage/3_dist-gimp-goappimage.sh
|
||||
artifacts:
|
||||
expose_as: 'Linux appimage'
|
||||
paths:
|
||||
@@ -736,39 +823,58 @@ dist-appimage-weekly:
|
||||
expire_in: 8 days
|
||||
|
||||
include:
|
||||
project: 'GNOME/citemplates'
|
||||
file: 'flatpak/flatpak_ci_initiative.yml'
|
||||
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.*/'
|
||||
needs: ["gimp-flatpak-x64"]
|
||||
- !reference [.flatpak, rules]
|
||||
needs: ["gimp-flatpak"]
|
||||
stage: distribution
|
||||
script:
|
||||
- bash build/linux/flatpak/3_dist-gimp-flatpak.sh
|
||||
- sh build/linux/flatpak/3_dist-gimp-flatpakbuilder.sh
|
||||
artifacts:
|
||||
expose_as: 'Linux flatpak'
|
||||
paths:
|
||||
- build/linux/flatpak/_Output/
|
||||
expire_in: 8 days
|
||||
|
||||
dist-snap-weekly:
|
||||
extends: .default
|
||||
rules:
|
||||
- !reference [.snap, rules]
|
||||
needs: ["gimp-snap"]
|
||||
stage: distribution
|
||||
image: !reference [.snap, image]
|
||||
variables: !reference [.snap, variables]
|
||||
script:
|
||||
- sh build/linux/snap/3_dist-gimp-snapcraft.sh
|
||||
artifacts:
|
||||
expose_as: 'Linux snap'
|
||||
paths:
|
||||
- build/linux/snap/_Output/
|
||||
expire_in: 8 days
|
||||
|
||||
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:
|
||||
- build/windows/installer/3_dist-gimp-inno.ps1
|
||||
- build\windows\installer\3_dist-gimp-inno.ps1
|
||||
artifacts:
|
||||
expose_as: 'Windows exe'
|
||||
paths:
|
||||
@@ -779,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
|
||||
|
42
.gitlab/check_dead_branches.sh
Normal file
42
.gitlab/check_dead_branches.sh
Normal 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"
|
@@ -1,16 +1,8 @@
|
||||
<!-- ⚠️ IMPORTANT: READ ME! ⚠️
|
||||
This is the default template for bug reports.
|
||||
For feature requests or performance issues, please switch instead to the appropriate template in the "Choose a template" list.
|
||||
For feature requests, performance issues and security reports, please switch instead to the appropriate template in the "Choose a template" list.
|
||||
|
||||
It is important that you fill all the fields of the template.
|
||||
|
||||
There are a few issues we get reports about quite frequently. If you want to check if what you have encountered is among these, please see:
|
||||
https://gitlab.gnome.org/GNOME/gimp/-/issues/?sort=updated_desc&state=all&label_name%5B%5D=Duplication%20target&first_page_size=100
|
||||
|
||||
**Code of Conduct**: "Be considerate and respectful" is our main rule.
|
||||
E.g. avoid negative emotional writing which only generates more upsetting
|
||||
interactions. Thanks!
|
||||
-->
|
||||
It is important that you fill all the fields of the template. -->
|
||||
|
||||
### Environment/Versions
|
||||
|
||||
@@ -19,14 +11,21 @@ interactions. Thanks!
|
||||
- Operating System: <!--[Windows? macOS? Linux? All? Add OS versions too] (write it after the > symbol) -->
|
||||
- (if Linux) Display system: <!--[X11? Wayland? Which compositor and version?] (write it after the > symbol) -->
|
||||
|
||||
<!--Note: bug reporters are expected to have verified the bug still exists
|
||||
<!-- Note: you are expected to have verified the bug still exists
|
||||
either in the last stable version of GIMP or on updated development code
|
||||
(master branch).-->
|
||||
(master branch).
|
||||
|
||||
There are a few issues we get reports about quite frequently. If you want to check if what you have encountered is among these, please see:
|
||||
https://gitlab.gnome.org/GNOME/gimp/-/issues/?sort=updated_desc&state=all&label_name%5B%5D=Duplication%20target&first_page_size=100 -->
|
||||
|
||||
### Description of the bug
|
||||
|
||||
<!--Please describe your issue with details.
|
||||
Add full (not cropped) screenshots or other files if needed.(write it after the > symbol)-->
|
||||
<!-- Please describe your issue with details. By "details" we mean:
|
||||
- "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 writing only one bug per report created.
|
||||
- Add full (not cropped) screenshots or other files using the clip button on GitLab. -->
|
||||
|
||||
### Reproduction
|
||||
|
||||
|
@@ -1,4 +1,8 @@
|
||||
**Operating System:** <!--[Windows? macOS? Linux? All?] (write it after the > symbol) -->
|
||||
<!-- ⚠️ IMPORTANT: READ ME! ⚠️
|
||||
This is the template for feature requests.
|
||||
For bug reports, performance issues and security reports, please switch instead to the appropriate template in the "Choose a template" list.
|
||||
|
||||
It is important that you fill all the fields of the template. -->
|
||||
|
||||
### Description of the feature
|
||||
|
||||
@@ -15,3 +19,5 @@
|
||||
<!-- Explain the use cases or problems to solve.
|
||||
If you are unsure, you should first discuss with the community in the forums
|
||||
or talk with the developers on IRC: https://www.gimp.org/discuss.html -->
|
||||
|
||||
/label ~"1. Feature"
|
||||
|
@@ -1,14 +1,21 @@
|
||||
<!-- ⚠️ IMPORTANT: READ ME! ⚠️
|
||||
This is the template for performance issues.
|
||||
For bug reports, feature requests and security reports, please switch instead to the appropriate template in the "Choose a template" list.
|
||||
|
||||
It is important that you fill all the fields of the template. -->
|
||||
|
||||
### Environment/Versions
|
||||
|
||||
- GIMP Version:
|
||||
- GIMP version number:
|
||||
- Package: <!--[flatpak? Installer from gimp.org? If another installer, tell us where from] (write it after the > symbol)-->
|
||||
- Operating System: <!--[Windows? macOS? Linux? All?] (write it after the > symbol) -->
|
||||
- Operating System: <!--[Windows? macOS? Linux? All? Add OS versions too] (write it after the > symbol) -->
|
||||
- (if Linux) Display system: <!--[X11? Wayland? Which compositor and version?] (write it after the > symbol) -->
|
||||
|
||||
<!-- Note: bug reporters are expected to have verified the bug still exists
|
||||
<!-- Note: you are expected to have verified the performance issue still exists
|
||||
either in the last stable version of GIMP or on updated development code
|
||||
(master branch). -->
|
||||
|
||||
### Issue Description
|
||||
### Description of the performance issue
|
||||
|
||||
<!-- Please provide a general description of the issue. -->
|
||||
|
||||
@@ -25,9 +32,9 @@ For more information, see
|
||||
|
||||
<!-- Please describe in detail the actions performed in the performance log.
|
||||
If you added empty event markers to the log, please provide a description for them here.
|
||||
If you recorded a screencast while recording the log, please attach it here. -->
|
||||
If you recorded a screencast while recording the log, please attach it here. -->
|
||||
|
||||
### Additional Information
|
||||
### Additional information
|
||||
|
||||
<!-- If there is any additional information, please provide it here. -->
|
||||
|
||||
|
31
.gitlab/issue_templates/security.md
Normal file
31
.gitlab/issue_templates/security.md
Normal file
@@ -0,0 +1,31 @@
|
||||
<!-- ⚠️ IMPORTANT: READ ME! ⚠️
|
||||
This is the template for security reports.
|
||||
For bug reports, feature requests and performance issues, please switch instead to the appropriate template in the "Choose a template" list.
|
||||
|
||||
It is important that you fill all the fields of the template. -->
|
||||
|
||||
### Environment/Versions
|
||||
|
||||
- GIMP version number:
|
||||
- Package: <!--[flatpak? Installer from gimp.org? If another installer, tell us where from] (write it after the > symbol)-->
|
||||
- Operating System: <!--[Windows? macOS? Linux? All? Add OS versions too] (write it after the > symbol) -->
|
||||
- (if Linux) Display system: <!--[X11? Wayland? Which compositor and version?] (write it after the > symbol) -->
|
||||
|
||||
<!-- Note: you are expected to have verified the security issue still exists
|
||||
either in the last stable version of GIMP or on updated development code
|
||||
(master branch). -->
|
||||
|
||||
### Description of the security report
|
||||
|
||||
<!-- Please provide a general description of the security issue (with CVE code if possible). -->
|
||||
|
||||
### Antivirus Log
|
||||
|
||||
<!-- Please attach a antivirus log or other file detailing the issue, and attach it to the report.
|
||||
If you have none, at least report GIMP as false positive to the antivirus before continuing. -->
|
||||
|
||||
### Additional information
|
||||
|
||||
<!-- If there you know the culprit code, please link it here. -->
|
||||
|
||||
/label ~"1. Security"
|
@@ -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 -->
|
||||
|
@@ -1,167 +1,218 @@
|
||||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
|
||||
source .gitlab/search-common-ancestor.sh
|
||||
|
||||
diff=$(git diff -U0 --no-color "${newest_common_ancestor_sha}" -- '*.build' '*.py' | grep -E '^\+[^+]' | sed 's/^+//')
|
||||
. .gitlab/search-common-ancestor.sh
|
||||
|
||||
|
||||
#List of commonly used utilities on Unix world
|
||||
#See the context: https://gitlab.gnome.org/GNOME/gimp/-/issues/11385
|
||||
coreutils_array=(
|
||||
".sh"
|
||||
"'sh'"
|
||||
"'bash'"
|
||||
"'\['"
|
||||
"'arch'"
|
||||
"'awk'"
|
||||
"'b2sum'"
|
||||
"'base32'"
|
||||
"'base64'"
|
||||
"'basename'"
|
||||
"'basenc'"
|
||||
"'cat'"
|
||||
"'chcon'"
|
||||
"'chgrp'"
|
||||
"'chmod'"
|
||||
"'chown'"
|
||||
"'chroot'"
|
||||
"'cksum'"
|
||||
"'cmp'"
|
||||
"'comm'"
|
||||
"'cp'"
|
||||
"'csplit'"
|
||||
"'cut'"
|
||||
"'date'"
|
||||
"'dd'"
|
||||
"'df'"
|
||||
"'diff'"
|
||||
"'dir'"
|
||||
"'dircolors'"
|
||||
"'dirname'"
|
||||
"'du'"
|
||||
"'echo'"
|
||||
"'env'"
|
||||
"'expand'"
|
||||
"'expr'"
|
||||
"'factor'"
|
||||
"'false'"
|
||||
"'find'"
|
||||
"'fmt'"
|
||||
"'fold'"
|
||||
"'gkill'"
|
||||
"'grep'"
|
||||
"'groups'"
|
||||
"'head'"
|
||||
"'hostid'"
|
||||
"'hostname'"
|
||||
"'id'"
|
||||
"'install'"
|
||||
"'join'"
|
||||
"'link'"
|
||||
"'ln'"
|
||||
"'logname'"
|
||||
"'ls'"
|
||||
"'md5sum'"
|
||||
"'mkdir'"
|
||||
"'mkfifo'"
|
||||
"'mknod'"
|
||||
"'mktemp'"
|
||||
"'mv'"
|
||||
"'nice'"
|
||||
"'nl'"
|
||||
"'nohup'"
|
||||
"'nproc'"
|
||||
"'numfmt'"
|
||||
"'od'"
|
||||
"'paste'"
|
||||
"'pathchk'"
|
||||
"'pinky'"
|
||||
"'pr'"
|
||||
"'printenv'"
|
||||
"'printf'"
|
||||
"'ptx'"
|
||||
"'pwd'"
|
||||
"'readlink'"
|
||||
"'realpath'"
|
||||
"'rm'"
|
||||
"'rmdir'"
|
||||
"'runcon'"
|
||||
"'sed'"
|
||||
"'seq'"
|
||||
"'sha1sum'"
|
||||
"'sha224sum'"
|
||||
"'sha256sum'"
|
||||
"'sha384sum'"
|
||||
"'sha512sum'"
|
||||
"'shred'"
|
||||
"'shuf'"
|
||||
"'sleep'"
|
||||
"'sort'"
|
||||
"'split'"
|
||||
"'stat'"
|
||||
"'stdbuf'"
|
||||
"'stty'"
|
||||
"'sum'"
|
||||
"'sync'"
|
||||
"'tac'"
|
||||
"'tail'"
|
||||
"'tee'"
|
||||
"'test'"
|
||||
"'timeout'"
|
||||
"'touch'"
|
||||
"'tr'"
|
||||
"'true'"
|
||||
"'truncate'"
|
||||
"'tsort'"
|
||||
"'tty'"
|
||||
"'uname'"
|
||||
"'unexpand'"
|
||||
"'uniq'"
|
||||
"'unlink'"
|
||||
"'users'"
|
||||
"'vdir'"
|
||||
"'wc'"
|
||||
"'who'"
|
||||
"'whoami'"
|
||||
"'yes'"
|
||||
)
|
||||
# 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 --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)
|
||||
}
|
||||
')
|
||||
|
||||
for coreutil in "${coreutils_array[@]}"; do
|
||||
## List of commonly used utilities on Unix world
|
||||
## See the context: https://gitlab.gnome.org/GNOME/gimp/-/issues/11385
|
||||
coreutils_list="
|
||||
\.sh \
|
||||
'sh' \
|
||||
'bash' \
|
||||
'\[' \
|
||||
'arch' \
|
||||
'awk' \
|
||||
'b2sum' \
|
||||
'base32' \
|
||||
'base64' \
|
||||
'basename' \
|
||||
'basenc' \
|
||||
'cat' \
|
||||
'chcon' \
|
||||
'chgrp' \
|
||||
'chmod' \
|
||||
'chown' \
|
||||
'chroot' \
|
||||
'cksum' \
|
||||
'cmp' \
|
||||
'comm' \
|
||||
'cp' \
|
||||
'csplit' \
|
||||
'cut' \
|
||||
'date' \
|
||||
'dd' \
|
||||
'df' \
|
||||
'diff' \
|
||||
'dir' \
|
||||
'dircolors' \
|
||||
'dirname' \
|
||||
'du' \
|
||||
'echo' \
|
||||
'env' \
|
||||
'expand' \
|
||||
'expr' \
|
||||
'factor' \
|
||||
'false' \
|
||||
'find' \
|
||||
'fmt' \
|
||||
'fold' \
|
||||
'gkill' \
|
||||
'grep' \
|
||||
'groups' \
|
||||
'head' \
|
||||
'hostid' \
|
||||
'hostname' \
|
||||
'id' \
|
||||
'install' \
|
||||
'join' \
|
||||
'link' \
|
||||
'ln' \
|
||||
'logname' \
|
||||
'ls' \
|
||||
'md5sum' \
|
||||
'mkdir' \
|
||||
'mkfifo' \
|
||||
'mknod' \
|
||||
'mktemp' \
|
||||
'mv' \
|
||||
'nice' \
|
||||
'nl' \
|
||||
'nohup' \
|
||||
'nproc' \
|
||||
'numfmt' \
|
||||
'od' \
|
||||
'paste' \
|
||||
'pathchk' \
|
||||
'pinky' \
|
||||
'pr' \
|
||||
'printenv' \
|
||||
'printf' \
|
||||
'ptx' \
|
||||
'pwd' \
|
||||
'readlink' \
|
||||
'realpath' \
|
||||
'rm' \
|
||||
'rmdir' \
|
||||
'runcon' \
|
||||
'sed' \
|
||||
'seq' \
|
||||
'sha1sum' \
|
||||
'sha224sum' \
|
||||
'sha256sum' \
|
||||
'sha384sum' \
|
||||
'sha512sum' \
|
||||
'shred' \
|
||||
'shuf' \
|
||||
'sleep' \
|
||||
'sort' \
|
||||
'split' \
|
||||
'stat' \
|
||||
'stdbuf' \
|
||||
'stty' \
|
||||
'sum' \
|
||||
'sync' \
|
||||
'tac' \
|
||||
'tail' \
|
||||
'tee' \
|
||||
'test' \
|
||||
'timeout' \
|
||||
'touch' \
|
||||
'tr' \
|
||||
'true' \
|
||||
'truncate' \
|
||||
'tsort' \
|
||||
'tty' \
|
||||
'uname' \
|
||||
'unexpand' \
|
||||
'uniq' \
|
||||
'unlink' \
|
||||
'users' \
|
||||
'vdir' \
|
||||
'wc' \
|
||||
'who' \
|
||||
'whoami' \
|
||||
'yes'
|
||||
"
|
||||
for coreutil in $coreutils_list; do
|
||||
if echo "$diff" | grep -q "$coreutil"; then
|
||||
found_coreutils+=" $coreutil"
|
||||
found_coreutils="$(echo "$found_coreutils $coreutil" | sed 's|\\||g')"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$found_coreutils" ]; then
|
||||
echo -e '\033[31m(ERROR)\033[0m: Seems that you are trying to add an Unix-specific dependency to be called by Meson.'
|
||||
echo " Please, port to Python (which is crossplatform), your use of:${found_coreutils}."
|
||||
printf "$diff\n"
|
||||
printf '\033[31m(ERROR)\033[0m: Seems that you are trying to add an Unix-specific dependency to be called by Meson.\n'
|
||||
printf " Please, port to Python (which is crossplatform), your use of:${found_coreutils}.\n"
|
||||
fi
|
||||
|
||||
|
||||
#Limited list of commonly used utilities on Windows world
|
||||
ntutils_array=(
|
||||
".bat"
|
||||
".cmd"
|
||||
".ps1"
|
||||
"'cmd'"
|
||||
"'powershell'"
|
||||
)
|
||||
|
||||
for ntutil in "${ntutils_array[@]}"; do
|
||||
## Limited list of commonly used utilities on Windows world
|
||||
ntutils_list="
|
||||
\.bat \
|
||||
\.cmd \
|
||||
\.ps1 \
|
||||
'cmd' \
|
||||
'powershell'
|
||||
"
|
||||
for ntutil in $ntutils_list; do
|
||||
if echo "$diff" | grep -q "$ntutil"; then
|
||||
found_ntutils+=" $ntutil"
|
||||
found_ntutils="$(echo "$found_ntutils $ntutil" | sed 's|\\||g')"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$found_ntutils" ]; then
|
||||
echo -e '\033[31m(ERROR)\033[0m: Seems that you are trying to add a NT-specific dependency to be called by Meson.'
|
||||
echo " Please, port to Python (which is crossplatform), your use of:${found_ntutils}."
|
||||
printf "$diff\n"
|
||||
printf '\033[31m(ERROR)\033[0m: Seems that you are trying to add a NT-specific dependency to be called by Meson.\n'
|
||||
printf " Please, port to Python (which is crossplatform), your use of:${found_ntutils}.\n"
|
||||
fi
|
||||
|
||||
if [ -z "$found_coreutils" ] && [ -z "$found_ntutils" ]; then
|
||||
printf '(INFO): Meson .build and .py files are alright regarding being crossplatform.\n'
|
||||
fi
|
||||
printf "\e[0Ksection_end:`date +%s`:nonunix_test\r\e[0K\n"
|
||||
|
||||
if [ "$found_coreutils" ] || [ "$found_ntutils" ]; then
|
||||
|
||||
# CHECK SCRIPTS NOT RUN BY MESON (UNIX ONLY)
|
||||
# Shell scripts have potential portability issues if:
|
||||
# 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 --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 "bash\s+.*\.sh" && found_bashism='extrinsic_bashism'
|
||||
|
||||
## Check content with shellcheck and checkbashisms (2)
|
||||
for sh_script in $(find "$CI_PROJECT_DIR" -type d -name .git -prune -o -type f \( ! -name '*.ps1' ! -name '*.c' -exec grep -lE '^#!\s*/usr/bin/env\s+(sh|bash)|^#!\s*/(usr/bin|bin)/(sh|bash)(\s|$)' {} \; -o -name '*.sh' ! -exec grep -q '^#!' {} \; -print \)); do
|
||||
shellcheck --severity=warning --shell=sh -x "$sh_script" | grep -v 'set option posix is' | grep -vE '.*http.*SC[0-9]+.*POSIX' | grep --color=always -B 2 -E 'SC[0-9]+.*POSIX' && found_bashism='intrinsic_bashism'
|
||||
checkbashisms -f $sh_script || found_bashism='intrinsic_bashism'
|
||||
done
|
||||
|
||||
if [ "$found_bashism" ]; then
|
||||
printf '\033[33m(WARNING)\033[0m: Seems that you added a Bash-specific code (aka "bashism").\n'
|
||||
printf " It is recommended to make it POSIX-compliant (which is portable).\n"
|
||||
else
|
||||
printf '(INFO): Shell .sh files are alright regarding being portable.\n'
|
||||
fi
|
||||
printf "\e[0Ksection_end:`date +%s`:unix_test\r\e[0K\n"
|
||||
|
||||
|
||||
if [ "$found_coreutils" ] || [ "$found_ntutils" ] || [ "$found_bashism" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 'Meson .build files are alright regarding crossplatform.'
|
||||
exit 0
|
||||
|
@@ -1,27 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
#!/bin/sh
|
||||
|
||||
ancestor_horizon=28 # days (4 weeks)
|
||||
|
||||
echo ""
|
||||
echo "This script may be wrong. You may disregard it if it conflicts with"
|
||||
echo "https://gitlab.gnome.org/GNOME/gimp/-/blob/master/CODING_STYLE.md"
|
||||
echo "https://developer.gimp.org/core/coding_style/"
|
||||
|
||||
clang-format --version
|
||||
|
||||
# Wrap everything in a subshell so we can propagate the exit status.
|
||||
(
|
||||
|
||||
source .gitlab/search-common-ancestor.sh
|
||||
. .gitlab/search-common-ancestor.sh
|
||||
|
||||
git diff -U0 --no-color "${newest_common_ancestor_sha}" | clang-format-diff -p1 > format-diff.log
|
||||
)
|
||||
exit_status=$?
|
||||
|
||||
[ ${exit_status} == 0 ] || exit ${exit_status}
|
||||
[ ${exit_status} = 0 ] || exit ${exit_status}
|
||||
|
||||
format_diff="$(<format-diff.log)"
|
||||
format_diff="$(cat format-diff.log)"
|
||||
|
||||
if [ -n "${format_diff}" ]; then
|
||||
cat format-diff.log
|
||||
|
@@ -1,6 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
#!/bin/sh
|
||||
|
||||
ancestor_horizon=28 # days (4 weeks)
|
||||
|
||||
@@ -14,7 +12,7 @@ ancestor_horizon=28 # days (4 weeks)
|
||||
if ! git ls-remote --exit-code upstream >/dev/null 2>&1 ; then
|
||||
git remote add upstream https://gitlab.gnome.org/GNOME/gimp.git
|
||||
fi
|
||||
git fetch --shallow-since="$(date --date="${ancestor_horizon} days ago" +%Y-%m-%d)" upstream &> ./fetch_upstream.log
|
||||
git fetch --shallow-since="$(date --date="${ancestor_horizon} days ago" +%Y-%m-%d)" upstream > ./fetch_upstream.log 2>&1
|
||||
|
||||
# Work out the newest common ancestor between the detached HEAD that this CI job
|
||||
# has checked out, and the upstream target branch (which will typically be
|
||||
@@ -28,10 +26,12 @@ git fetch --shallow-since="$(date --date="${ancestor_horizon} days ago" +%Y-%m-%
|
||||
git remote add patch-origin ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL:-${CI_PROJECT_URL}}
|
||||
|
||||
source_branch="${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:-${CI_COMMIT_BRANCH}}"
|
||||
git fetch --shallow-since="$(date --date="${ancestor_horizon} days ago" +%Y-%m-%d)" patch-origin "${source_branch}" &> ./fetch_origin.log
|
||||
git fetch --shallow-since="$(date --date="${ancestor_horizon} days ago" +%Y-%m-%d)" patch-origin "${source_branch}" > ./fetch_origin.log 2>&1
|
||||
|
||||
newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "upstream/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}") <(git rev-list --first-parent "patch-origin/${source_branch}") | head -1)
|
||||
if [ -z "${newest_common_ancestor_sha}" ]; then
|
||||
git rev-list --first-parent "upstream/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-gimp-3-0}" > "temp_upstream" 2>&1
|
||||
git rev-list --first-parent "patch-origin/${source_branch}" > "temp_patch-origin" 2>&1
|
||||
newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' "temp_upstream" "temp_patch-origin" | head -n 1)
|
||||
if [ -z "${newest_common_ancestor_sha}" ] || [ "${newest_common_ancestor_sha}" = '' ]; then
|
||||
echo "Couldn’t find common ancestor with upstream main branch. This typically"
|
||||
echo "happens if you branched from main a long time ago. Please update"
|
||||
echo "your clone, rebase, and re-push your branch."
|
||||
|
@@ -244,7 +244,7 @@ help in that regard:
|
||||
|
||||
Package Name Version
|
||||
|
||||
appstream-glib @APPSTREAM_GLIB_REQUIRED_VERSION@
|
||||
appstream @APPSTREAM_REQUIRED_VERSION@
|
||||
ATK @ATK_REQUIRED_VERSION@
|
||||
babl @BABL_REQUIRED_VERSION@
|
||||
cairo @CAIRO_REQUIRED_VERSION@
|
||||
@@ -281,10 +281,12 @@ help in that regard:
|
||||
|
||||
Package Name Version Feature
|
||||
|
||||
bison - Image Map plug-in
|
||||
cairo-pdf @CAIRO_PDF_REQUIRED_VERSION@ PDF export
|
||||
cfitsio - FITS
|
||||
iso-codes - Language selection
|
||||
ExcHndl - Crash logs on Windows with Dr. MinGW
|
||||
flex - Image Map plug-in
|
||||
gs - ghostscript
|
||||
libaa - ASCII art
|
||||
libheif @LIBHEIF_REQUIRED_VERSION@ HEIF (HEIC, AVIF)
|
||||
|
233
NEWS
233
NEWS
@@ -6,6 +6,239 @@
|
||||
This is the development branch of GIMP.
|
||||
|
||||
|
||||
Overview of Changes from GIMP 3.0.4 to GIMP 3.0.6
|
||||
=================================================
|
||||
|
||||
This is a mostly bug-fix release.
|
||||
|
||||
Core:
|
||||
|
||||
- Many false-positive build warnings have been cleaned out (and proper
|
||||
issues fixed).
|
||||
- Various crashes fixed.
|
||||
- When creating a layer mask from the layer's alpha, but the layer has
|
||||
no alpha, simply fill the mask with complete opacity instead of
|
||||
a completely transparent layer.
|
||||
- Various core infrastructure code reviewed, cleaned up, refactored
|
||||
and improved, in drawable, layer and filter handling code, tree view
|
||||
code, and more.
|
||||
- GIMP_ICONS_LIKE_A_BOSS environment variable is not working anymore
|
||||
(because "gtk-menu-images" and "gtk-button-images" have been
|
||||
deprecated in GTK3 and removed in GTK4) and was therefore removed.
|
||||
- Lock Content now shows as an undo step.
|
||||
- Add alpha channel for certain transforms.
|
||||
- Add alpha channel on filter merge, when necessary.
|
||||
- Filters can now be applied non-destructively on channels.
|
||||
- Improved Photoshop brush support.
|
||||
- After deleting a palette entry, the next entry is automatically
|
||||
selected. This allows easily deleting several entries in a row,
|
||||
among other usage.
|
||||
- Resize image to layers irrespective to selections.
|
||||
- Improved in-GUI release notes' demo script language:
|
||||
* We can now set a button value to click it:
|
||||
"toolbox:text,
|
||||
tool-options:outline=1,
|
||||
tool-options:outline-direction"
|
||||
* Color selector's module names can be used as identifiers:
|
||||
"color-editor,color-editor:CMYK=1,color-editor:total-ink-coverage"
|
||||
- Fixed Alpha to Selection on single layers with no transparency.
|
||||
- Various code is slowly ported to newer code, preparing for GTK4 port
|
||||
(in an unplanned future step):
|
||||
* Using g_set_str() (optionally redefining it in our core code to
|
||||
avoid bumping the GLib minimum requirement).
|
||||
* Start using GListModel in various pieces of code, in particular
|
||||
getting rid of more and more usage of GtkTreeView when possible
|
||||
(as it will be deprecated with GTK4).
|
||||
* New GimpRow class for all future row widgets.
|
||||
* Use more of G_DECLARE_DERIVABLE_TYPE and G_DECLARE_FINAL_TYPE
|
||||
where relevant.
|
||||
* New GimpContainerListView using a GtkListBox.
|
||||
* New GimpRowSeparator, GimpRowSettings, GimpRowFilter and
|
||||
GimpRowDrawableFilter widgets.
|
||||
- (Experimental) GEX Format was updated.
|
||||
- Palette import:
|
||||
* Set alpha value for image palette imports.
|
||||
* Fix Lab & CMYK ACB palette import.
|
||||
* Add palette format filters to import dialog, making it more
|
||||
apparent what palette formats are supported, and giving the
|
||||
ability to hide irrelevant files.
|
||||
- Improved filter actions' sensitivity to make sure they are set
|
||||
insensitive when relevant. In particular filters which cannot be run
|
||||
non-destructively (e.g. filters with aux inputs, non-interactive
|
||||
filters and GEGL Graph) must be insensitive when trying to run them
|
||||
on group layers.
|
||||
- Fix bad axis centering on zoom out.
|
||||
- Export better SVG when exporting paths.
|
||||
|
||||
Tools:
|
||||
|
||||
- Text tool: make sure the default color is only changed when the user
|
||||
confirms the color change.
|
||||
- Foreground Selection tool: do not create a selection when no strokes
|
||||
has been made. In particular this removes the unnecessary delay
|
||||
which happened when switching to another tool without actually
|
||||
stroking anything.
|
||||
- All Transform tools: transform boundaries for preview is now
|
||||
multi-layers aware.
|
||||
- (Experimental) Seamless Clone tool: made to work again, though it is
|
||||
still too slow to get out of Playground.
|
||||
|
||||
Graphical User Interface:
|
||||
|
||||
- Various improvements to window management:
|
||||
* Keep-Above windows are set with the Utility hint.
|
||||
* Utility windows are not made transient to a parent.
|
||||
* Transient factory dialogs follow the active display, ensuring that
|
||||
new image windows would not hide your toolbox and dock windows.
|
||||
- Various CSS improvements for styling of the interface. Some theme
|
||||
leaks were also fixed.
|
||||
- New toggle button in Brushes and Fonts dockable, allowing brush and
|
||||
font previews to optionally follow the color theme. For instance,
|
||||
when using a dark theme, the brush and font previews could be drawn
|
||||
on the theme background, using the theme foreground colors. By
|
||||
default, these data previews are still drawn as black on white.
|
||||
- Palette grid is now drawn with the theme's background color.
|
||||
- Consistent naming patterns on human-facing options (first word only
|
||||
capitalized).
|
||||
- About dialog:
|
||||
* We will now display the date and time of the last
|
||||
check in a "Up to date as of <date> at <time>" string, differing
|
||||
from the "Last checked on <date> at <time>" string. The former
|
||||
will be used to indicate that GIMP is indeed up-to-date whereas
|
||||
the latter when a new version was released and that you should
|
||||
update.
|
||||
* We now respect the system time/date format on macOS and Windows.
|
||||
- The search popup won't pop up without an image.
|
||||
- Better zoom step algorithm for data previews in container popup
|
||||
(e.g. the brush popup in paint Tool Options).
|
||||
- Disable animation in the Input Controller, Preferences and Welcome
|
||||
dialogs for stack transition when animation are disabled in system
|
||||
settings.
|
||||
- Fixed crosshair hotspot on Windows (crosshair cursor for brushes was
|
||||
offset with a non-100% display scale factor).
|
||||
- Debug/CRITICAL dialog:
|
||||
* Make sure it is non-modal.
|
||||
* Follow the theme mode under Windows.
|
||||
- While loading images, all widgets in the file dialog are made
|
||||
insensitive, except for the Cancel button and the progress bar.
|
||||
- Both grid and list views can now zoom via scroll and zoom gestures
|
||||
(it used to only work in list views).
|
||||
- Pop an error message up on startup when GIO modules to read HTTPS
|
||||
links are not found and that we therefore fail to load the remote
|
||||
gimp_versions.json file. With the AppImage package in particular, we
|
||||
depend on an environment daemon which cannot be shipped in the
|
||||
package. So the next best thing is to warn people and tell them what
|
||||
they should install to get version checks.
|
||||
- Welcome dialog:
|
||||
* The "Community Tutorials" link is now shown after the
|
||||
"Documentation" link.
|
||||
* The "Learn more" link in Release Notes tab leads to the actual
|
||||
release news for this version.
|
||||
|
||||
Plug-ins:
|
||||
|
||||
- PDF export: do not draw disabled layer masks.
|
||||
- Jigsaw: the plug-in can now draw on transparent layers.
|
||||
- Various file format fixes and improvements: JPEG 2000 import, TIFF
|
||||
import, DDS import, SVG import, PSP import, FITS export, ICNS
|
||||
import, Dicom import, WBMP import, Farbfeld import, XWD import, ILBM
|
||||
import.
|
||||
- Sphere Designer: use spin scale instead of spin entries (the latter
|
||||
is unusable with little horizontal space).
|
||||
- Animation Play: frames are shown again in the playback progress bar.
|
||||
- Vala Goat Exercise: ignoring C warning in this Vala plug-in as it is
|
||||
generated code and we cannot control it.
|
||||
- file-gih: brush pipe selection modes now have nice, translatable
|
||||
names.
|
||||
- Metadata viewer: port from GtkTreeView to GtkListBox.
|
||||
- File Raw Data: reduce Raw Data load dialogue height by moving to a
|
||||
2-column layout.
|
||||
- SVG import: it is now possible to break aspect ratio with specific
|
||||
width/height arguments, when calling the PDB procedure
|
||||
non-interactively (from other plug-ins).
|
||||
- Print: when run through a portal print dialog, the "Image Settings"
|
||||
will be exposed as a secondary dialog, outputted after the portal
|
||||
dialog, instead of a tab on the main print dialog (because it is not
|
||||
possible to tweak the print dialog when it is created by a portal).
|
||||
This will bring back usable workflow of printing with GIMP when run
|
||||
in a sandbox (e.g. Flatpak or Snap).
|
||||
- Recompose: fixed for YCbCr decomposed images.
|
||||
- Fixed vulnerabilities: ZDI-CAN-27684, ZDI-CAN-27863, ZDI-CAN-27878,
|
||||
ZDI-CAN-27836, ZDI-CAN-27823, ZDI-CAN-27793.
|
||||
- C Source and HTML export can now be run non-interactively too (e.g.
|
||||
from other plug-ins).
|
||||
- Map Object: fix missing spin boxes.
|
||||
- Small Tiles: fix display lag.
|
||||
|
||||
API:
|
||||
|
||||
- libgimpui:
|
||||
* new function: gimp_prop_toggle_new()
|
||||
* updated widget default for GimpChoice in GimpProcedureDialog: when
|
||||
the number of choices is below 3, a radio frame is used, and a
|
||||
combo box otherwise (it used to always be a combo box).
|
||||
* GimpExportProcedureDialog: comment text area will be made
|
||||
(in)sensitive depending on the checked state of "Save Comment"
|
||||
option.
|
||||
* Use arrows for GimpSpinScale cursors.
|
||||
* GimpColorScales: no decimal for u8 RGB color selector. This change
|
||||
will help further distinguish between the 0...100 and 0..255 views
|
||||
in the Color Selectors.
|
||||
* Internal color drags now use a "application/x-geglcolor" target
|
||||
since "application/x-color" is standard and should not be used for
|
||||
our more powerful color formats.
|
||||
- libgimp:
|
||||
* new enum type: GimpTRCType
|
||||
* gimp_file_save() sets the XCF or exported files accordingly.
|
||||
* Metadata:
|
||||
+ Favor existing image comment instead of always loading comment
|
||||
from metadata.
|
||||
+ Fix handling of "charset=" in comments.
|
||||
+ Better heuristic to choose the comment to export, especially
|
||||
when it has been edited in the export dialog comment field.
|
||||
+ XMP modification date format fix and Exif.Image.DateTime
|
||||
metadata has been modernized, also adding the timezone.
|
||||
- PDB/libgimp:
|
||||
* Allow nullable sample points and guide types for some
|
||||
functions.
|
||||
* GeglParamFilePath can now be passed across the wire.
|
||||
- macOS: improve dock icon flashing issue.
|
||||
|
||||
Build:
|
||||
|
||||
- CI scripts synced to latest `master` state.
|
||||
- Windows file format association list is now generated at build time,
|
||||
avoiding discrepancies.
|
||||
- Build scripts are made POSIX-compliant for better portability across
|
||||
platforms.
|
||||
- New nightly Snap package.
|
||||
- New nightly Aarch64 flatpak.
|
||||
- Core code ported from appstream-glib to libappstream.
|
||||
- Windows installer now uses the latest InnoSetup again.
|
||||
- New option -Dwin-debugging=dwarf to generate DWARF symbols on
|
||||
Windows (defaults to CodeView symbols).
|
||||
- Compilation should work again fine with older librsvg (before the
|
||||
Rust port).
|
||||
- release-stats.sh script updated to generate text directly pastable
|
||||
into our release news.
|
||||
- CI:
|
||||
* Linux builds ported from unmaintained Kaniko to Buildah.
|
||||
* Colored output and .pdb support for builds of dependency using
|
||||
CMake.
|
||||
* Ability to apply remote patches on dependency builds.
|
||||
* New job "branches-check" to warn about dead branches.
|
||||
* Our Debian jobs are now built with GCC again (the CLang builds are
|
||||
switched to weekly scheduled jobs).
|
||||
- Clean out deprecation warnings on GLib and GTK/GDK based on our
|
||||
minimum requirement of these dependencies thanks to
|
||||
GLIB_VERSION_MIN_REQUIRED() and GLIB_VERSION_MAX_ALLOWED() macros
|
||||
(and equivalent GDK macros).
|
||||
- We now build Exiv2 ourselves on Windows as a temporary workaround to
|
||||
issue #12626.
|
||||
- Improved packages binary caching with ORAS for Flatpak.
|
||||
- AppImage: we now depend on Debian Trixie.
|
||||
|
||||
|
||||
Overview of Changes from GIMP 3.0.2 to GIMP 3.0.4
|
||||
=================================================
|
||||
|
||||
|
@@ -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 *
|
||||
@@ -490,10 +510,9 @@ action_data_sel_count (gpointer data)
|
||||
{
|
||||
if (GIMP_IS_CONTAINER_EDITOR (data))
|
||||
{
|
||||
GimpContainerEditor *editor;
|
||||
GimpContainerEditor *editor = GIMP_CONTAINER_EDITOR (data);
|
||||
|
||||
editor = GIMP_CONTAINER_EDITOR (data);
|
||||
return gimp_container_view_get_selected (editor->view, NULL, NULL);
|
||||
return gimp_container_view_get_selected (editor->view, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -25,6 +25,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);
|
||||
|
@@ -895,17 +895,16 @@ context_select_object (GimpActionSelectType select_type,
|
||||
GimpContainer *container)
|
||||
{
|
||||
GimpObject *current;
|
||||
GType child_type;
|
||||
|
||||
current =
|
||||
gimp_context_get_by_type (context,
|
||||
gimp_container_get_children_type (container));
|
||||
child_type = gimp_container_get_child_type (container);
|
||||
|
||||
current = gimp_context_get_by_type (context, child_type);
|
||||
|
||||
current = action_select_object (select_type, container, current);
|
||||
|
||||
if (current)
|
||||
gimp_context_set_by_type (context,
|
||||
gimp_container_get_children_type (container),
|
||||
current);
|
||||
gimp_context_set_by_type (context, child_type, current);
|
||||
}
|
||||
|
||||
static gint
|
||||
|
@@ -68,7 +68,7 @@ data_open_as_image_cmd_callback (GimpAction *action,
|
||||
|
||||
data = (GimpData *)
|
||||
gimp_context_get_by_type (context,
|
||||
gimp_data_factory_view_get_children_type (view));
|
||||
gimp_data_factory_view_get_child_type (view));
|
||||
|
||||
if (data && gimp_data_get_file (data))
|
||||
{
|
||||
@@ -119,7 +119,7 @@ data_new_cmd_callback (GimpAction *action,
|
||||
GtkWidget *edit_button;
|
||||
|
||||
gimp_context_set_by_type (context,
|
||||
gimp_data_factory_view_get_children_type (view),
|
||||
gimp_data_factory_view_get_child_type (view),
|
||||
GIMP_OBJECT (data));
|
||||
|
||||
edit_button = gimp_data_factory_view_get_edit_button (view);
|
||||
@@ -142,7 +142,7 @@ data_duplicate_cmd_callback (GimpAction *action,
|
||||
|
||||
data = (GimpData *)
|
||||
gimp_context_get_by_type (context,
|
||||
gimp_data_factory_view_get_children_type (view));
|
||||
gimp_data_factory_view_get_child_type (view));
|
||||
|
||||
if (data && gimp_data_factory_view_have (view, GIMP_OBJECT (data)))
|
||||
{
|
||||
@@ -155,7 +155,7 @@ data_duplicate_cmd_callback (GimpAction *action,
|
||||
GtkWidget *edit_button;
|
||||
|
||||
gimp_context_set_by_type (context,
|
||||
gimp_data_factory_view_get_children_type (view),
|
||||
gimp_data_factory_view_get_child_type (view),
|
||||
GIMP_OBJECT (new_data));
|
||||
|
||||
edit_button = gimp_data_factory_view_get_edit_button (view);
|
||||
@@ -178,7 +178,7 @@ data_copy_location_cmd_callback (GimpAction *action,
|
||||
|
||||
data = (GimpData *)
|
||||
gimp_context_get_by_type (context,
|
||||
gimp_data_factory_view_get_children_type (view));
|
||||
gimp_data_factory_view_get_child_type (view));
|
||||
|
||||
if (data)
|
||||
{
|
||||
@@ -207,7 +207,7 @@ data_show_in_file_manager_cmd_callback (GimpAction *action,
|
||||
|
||||
data = (GimpData *)
|
||||
gimp_context_get_by_type (context,
|
||||
gimp_data_factory_view_get_children_type (view));
|
||||
gimp_data_factory_view_get_child_type (view));
|
||||
|
||||
if (data)
|
||||
{
|
||||
@@ -243,7 +243,7 @@ data_delete_cmd_callback (GimpAction *action,
|
||||
|
||||
data = (GimpData *)
|
||||
gimp_context_get_by_type (context,
|
||||
gimp_data_factory_view_get_children_type (view));
|
||||
gimp_data_factory_view_get_child_type (view));
|
||||
|
||||
if (data &&
|
||||
gimp_data_is_deletable (data) &&
|
||||
@@ -288,7 +288,7 @@ data_edit_cmd_callback (GimpAction *action,
|
||||
|
||||
data = (GimpData *)
|
||||
gimp_context_get_by_type (context,
|
||||
gimp_data_factory_view_get_children_type (view));
|
||||
gimp_data_factory_view_get_child_type (view));
|
||||
|
||||
if (data && gimp_data_factory_view_have (view, GIMP_OBJECT (data)))
|
||||
{
|
||||
|
@@ -174,34 +174,34 @@ drawable_actions_update (GimpActionGroup *group,
|
||||
{
|
||||
GimpItem *item;
|
||||
|
||||
if (gimp_item_get_visible (iter->data))
|
||||
has_visible = TRUE;
|
||||
|
||||
if (gimp_item_can_lock_content (iter->data))
|
||||
{
|
||||
if (! gimp_item_get_lock_content (iter->data))
|
||||
locked = FALSE;
|
||||
can_lock = TRUE;
|
||||
}
|
||||
|
||||
if (gimp_item_can_lock_position (iter->data))
|
||||
{
|
||||
if (! gimp_item_get_lock_position (iter->data))
|
||||
locked_pos = FALSE;
|
||||
can_lock_pos = TRUE;
|
||||
}
|
||||
|
||||
if (gimp_viewable_get_children (GIMP_VIEWABLE (iter->data)))
|
||||
none_children = FALSE;
|
||||
|
||||
if (! gimp_drawable_is_rgb (iter->data))
|
||||
all_rgb = FALSE;
|
||||
|
||||
if (GIMP_IS_LAYER_MASK (iter->data))
|
||||
item = GIMP_ITEM (gimp_layer_mask_get_layer (GIMP_LAYER_MASK (iter->data)));
|
||||
else
|
||||
item = GIMP_ITEM (iter->data);
|
||||
|
||||
if (gimp_item_get_visible (item))
|
||||
has_visible = TRUE;
|
||||
|
||||
if (gimp_item_can_lock_content (item))
|
||||
{
|
||||
if (! gimp_item_get_lock_content (item))
|
||||
locked = FALSE;
|
||||
can_lock = TRUE;
|
||||
}
|
||||
|
||||
if (gimp_item_can_lock_position (item))
|
||||
{
|
||||
if (! gimp_item_get_lock_position (item))
|
||||
locked_pos = FALSE;
|
||||
can_lock_pos = TRUE;
|
||||
}
|
||||
|
||||
if (gimp_viewable_get_children (GIMP_VIEWABLE (item)))
|
||||
none_children = FALSE;
|
||||
|
||||
if (! gimp_drawable_is_rgb (iter->data))
|
||||
all_rgb = FALSE;
|
||||
|
||||
if (gimp_item_is_content_locked (item, NULL))
|
||||
all_writable = FALSE;
|
||||
|
||||
|
@@ -59,6 +59,7 @@ static void file_actions_last_opened_update (GimpContainer *container,
|
||||
static void file_actions_last_opened_reorder (GimpContainer *container,
|
||||
GimpImagefile *unused1,
|
||||
gint unused2,
|
||||
gint unused3,
|
||||
GimpActionGroup *group);
|
||||
static void file_actions_close_all_update (GimpContainer *images,
|
||||
GimpObject *unused,
|
||||
@@ -434,6 +435,7 @@ static void
|
||||
file_actions_last_opened_reorder (GimpContainer *container,
|
||||
GimpImagefile *unused1,
|
||||
gint unused2,
|
||||
gint unused3,
|
||||
GimpActionGroup *group)
|
||||
{
|
||||
file_actions_last_opened_update (container, unused1, group);
|
||||
|
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "core/gimp-filter-history.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpgrouplayer.h"
|
||||
#include "core/gimplayermask.h"
|
||||
|
||||
#include "pdb/gimpprocedure.h"
|
||||
@@ -36,6 +37,7 @@
|
||||
#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 +50,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 +751,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 +780,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 ();
|
||||
|
||||
@@ -858,6 +877,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);
|
||||
@@ -907,6 +943,8 @@ filters_actions_setup (GimpActionGroup *group)
|
||||
group, 0);
|
||||
|
||||
filters_actions_history_changed (group->gimp, group);
|
||||
|
||||
first_setup = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -914,11 +952,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);
|
||||
|
||||
@@ -946,6 +987,9 @@ filters_actions_update (GimpActionGroup *group,
|
||||
|
||||
if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
|
||||
is_group = TRUE;
|
||||
|
||||
if (GIMP_IS_GROUP_LAYER (drawable))
|
||||
force_nde = TRUE;
|
||||
}
|
||||
|
||||
g_list_free (drawables);
|
||||
@@ -954,134 +998,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
|
||||
|
||||
@@ -1303,3 +1295,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;
|
||||
}
|
||||
|
@@ -182,13 +182,13 @@ static const GimpActionEntry layers_actions[] =
|
||||
{ "layers-text-to-vectors", GIMP_ICON_TOOL_TEXT,
|
||||
NC_("layers-action", "Text to _Path"), NULL, { NULL },
|
||||
NC_("layers-action", "Create paths from text layers"),
|
||||
layers_text_to_vectors_cmd_callback,
|
||||
layers_text_to_path_cmd_callback,
|
||||
GIMP_HELP_LAYER_TEXT_TO_PATH },
|
||||
|
||||
{ "layers-text-along-vectors", GIMP_ICON_TOOL_TEXT,
|
||||
NC_("layers-action", "Text alon_g Path"), NULL, { NULL },
|
||||
NC_("layers-action", "Warp this layer's text along the current path"),
|
||||
layers_text_along_vectors_cmd_callback,
|
||||
layers_text_along_path_cmd_callback,
|
||||
GIMP_HELP_LAYER_TEXT_ALONG_PATH },
|
||||
|
||||
{ "layers-resize", GIMP_ICON_OBJECT_RESIZE,
|
||||
@@ -780,8 +780,8 @@ layers_actions_update (GimpActionGroup *group,
|
||||
|
||||
gboolean all_visible = TRUE;
|
||||
gboolean all_next_visible = TRUE;
|
||||
gboolean all_masks_shown = TRUE;
|
||||
gboolean all_masks_disabled = TRUE;
|
||||
gboolean any_mask_shown = FALSE;
|
||||
gboolean any_mask_disabled = FALSE;
|
||||
gboolean all_writable = TRUE;
|
||||
gboolean all_movable = TRUE;
|
||||
|
||||
@@ -816,10 +816,11 @@ layers_actions_update (GimpActionGroup *group,
|
||||
if (gimp_layer_get_mask (iter->data))
|
||||
{
|
||||
have_masks = TRUE;
|
||||
if (! gimp_layer_get_show_mask (iter->data))
|
||||
all_masks_shown = FALSE;
|
||||
if (gimp_layer_get_apply_mask (iter->data))
|
||||
all_masks_disabled = FALSE;
|
||||
|
||||
if (gimp_layer_get_show_mask (iter->data))
|
||||
any_mask_shown = TRUE;
|
||||
if (! gimp_layer_get_apply_mask (iter->data))
|
||||
any_mask_disabled = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1082,8 +1083,8 @@ layers_actions_update (GimpActionGroup *group,
|
||||
SET_SENSITIVE ("layers-mask-disable", n_selected_layers > 0 && !fs && !ac && have_masks);
|
||||
|
||||
SET_ACTIVE ("layers-mask-edit", n_selected_layers == 1 && have_masks && gimp_layer_get_edit_mask (layers->data));
|
||||
SET_ACTIVE ("layers-mask-show", all_masks_shown);
|
||||
SET_ACTIVE ("layers-mask-disable", all_masks_disabled);
|
||||
SET_ACTIVE ("layers-mask-show", any_mask_shown);
|
||||
SET_ACTIVE ("layers-mask-disable", any_mask_disabled);
|
||||
|
||||
SET_SENSITIVE ("layers-mask-selection-replace", n_selected_layers && !fs && !ac && have_masks);
|
||||
SET_SENSITIVE ("layers-mask-selection-add", n_selected_layers && !fs && !ac && have_masks);
|
||||
|
@@ -39,8 +39,6 @@
|
||||
#include "core/gimpcontainer.h"
|
||||
#include "core/gimpcontext.h"
|
||||
#include "core/gimpdrawable-fill.h"
|
||||
#include "core/gimpdrawable-filters.h"
|
||||
#include "core/gimpdrawablefilter.h"
|
||||
#include "core/gimpgrouplayer.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-merge.h"
|
||||
@@ -447,6 +445,7 @@ layers_new_last_vals_cmd_callback (GimpAction *action,
|
||||
ngettext ("New layer",
|
||||
"New layers",
|
||||
n_layers > 0 ? n_layers : 1));
|
||||
|
||||
for (iter = layers; iter || run_once ; iter = iter ? iter->next : NULL)
|
||||
{
|
||||
GimpLayer *parent;
|
||||
@@ -492,11 +491,13 @@ layers_new_last_vals_cmd_callback (GimpAction *action,
|
||||
gimp_image_add_layer (image, layer, parent, position, TRUE);
|
||||
new_layers = g_list_prepend (new_layers, layer);
|
||||
}
|
||||
|
||||
gimp_image_set_selected_layers (image, new_layers);
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
g_list_free (layers);
|
||||
g_list_free (new_layers);
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
@@ -550,6 +551,7 @@ layers_new_group_cmd_callback (GimpAction *action,
|
||||
layers = g_list_copy (layers);
|
||||
n_layers = g_list_length (layers);
|
||||
run_once = (n_layers == 0);
|
||||
|
||||
gimp_image_undo_group_start (image,
|
||||
GIMP_UNDO_GROUP_LAYER_ADD,
|
||||
ngettext ("New layer group",
|
||||
@@ -588,11 +590,13 @@ layers_new_group_cmd_callback (GimpAction *action,
|
||||
}
|
||||
|
||||
gimp_image_set_selected_layers (image, new_layers);
|
||||
gimp_image_undo_group_end (image);
|
||||
gimp_image_flush (image);
|
||||
|
||||
g_list_free (layers);
|
||||
g_list_free (new_layers);
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
gimp_image_flush (image);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -665,7 +669,6 @@ layers_raise_cmd_callback (GimpAction *action,
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_image_flush (image);
|
||||
g_list_free (raised_layers);
|
||||
return;
|
||||
}
|
||||
@@ -680,11 +683,10 @@ layers_raise_cmd_callback (GimpAction *action,
|
||||
raised_layers = g_list_reverse (raised_layers);
|
||||
for (iter = raised_layers; iter; iter = iter->next)
|
||||
gimp_image_raise_item (image, iter->data, NULL);
|
||||
|
||||
gimp_image_flush (image);
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
g_list_free (raised_layers);
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -716,10 +718,10 @@ layers_raise_to_top_cmd_callback (GimpAction *action,
|
||||
for (iter = raised_layers; iter; iter = iter->next)
|
||||
gimp_image_raise_item_to_top (image, iter->data);
|
||||
|
||||
gimp_image_flush (image);
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
g_list_free (raised_layers);
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -746,7 +748,6 @@ layers_lower_cmd_callback (GimpAction *action,
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_image_flush (image);
|
||||
g_list_free (lowered_layers);
|
||||
return;
|
||||
}
|
||||
@@ -761,10 +762,10 @@ layers_lower_cmd_callback (GimpAction *action,
|
||||
for (iter = lowered_layers; iter; iter = iter->next)
|
||||
gimp_image_lower_item (image, iter->data, NULL);
|
||||
|
||||
gimp_image_flush (image);
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
g_list_free (lowered_layers);
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -798,10 +799,10 @@ layers_lower_to_bottom_cmd_callback (GimpAction *action,
|
||||
for (iter = lowered_layers; iter; iter = iter->next)
|
||||
gimp_image_lower_item_to_bottom (image, iter->data);
|
||||
|
||||
gimp_image_flush (image);
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
g_list_free (lowered_layers);
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -821,8 +822,7 @@ layers_duplicate_cmd_callback (GimpAction *action,
|
||||
_("Duplicate layers"));
|
||||
for (iter = layers; iter; iter = iter->next)
|
||||
{
|
||||
GimpLayer *new_layer;
|
||||
GimpContainer *filters;
|
||||
GimpLayer *new_layer;
|
||||
|
||||
new_layer = GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (iter->data),
|
||||
G_TYPE_FROM_INSTANCE (iter->data)));
|
||||
@@ -837,39 +837,6 @@ layers_duplicate_cmd_callback (GimpAction *action,
|
||||
TRUE);
|
||||
gimp_drawable_enable_resize_undo (GIMP_DRAWABLE (new_layer));
|
||||
new_layers = g_list_prepend (new_layers, new_layer);
|
||||
|
||||
/* Import any attached layer effects */
|
||||
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (iter->data));
|
||||
if (gimp_container_get_n_children (filters) > 0)
|
||||
{
|
||||
GList *filter_list;
|
||||
GimpContainer *filters;
|
||||
|
||||
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (iter->data));
|
||||
|
||||
for (filter_list = GIMP_LIST (filters)->queue->tail; filter_list;
|
||||
filter_list = g_list_previous (filter_list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (filter_list->data))
|
||||
{
|
||||
GimpDrawableFilter *old_filter = filter_list->data;
|
||||
GimpDrawableFilter *filter;
|
||||
|
||||
filter =
|
||||
gimp_drawable_filter_duplicate (GIMP_DRAWABLE (new_layer),
|
||||
old_filter);
|
||||
|
||||
if (filter != NULL)
|
||||
{
|
||||
gimp_drawable_filter_apply (filter, NULL);
|
||||
gimp_drawable_filter_commit (filter, TRUE, NULL, FALSE);
|
||||
|
||||
gimp_drawable_filter_layer_mask_freeze (filter);
|
||||
g_object_unref (filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gimp_image_set_selected_layers (image, new_layers);
|
||||
@@ -922,6 +889,7 @@ layers_merge_down_cmd_callback (GimpAction *action,
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
gimp_image_set_selected_layers (image, layers);
|
||||
g_list_free (layers);
|
||||
|
||||
@@ -1013,6 +981,7 @@ layers_merge_group_cmd_callback (GimpAction *action,
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
g_list_free (merge_layers);
|
||||
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
@@ -1072,6 +1041,7 @@ layers_delete_cmd_callback (GimpAction *action,
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
g_list_free (removed_layers);
|
||||
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
@@ -1094,18 +1064,20 @@ layers_text_discard_cmd_callback (GimpAction *action,
|
||||
}
|
||||
|
||||
void
|
||||
layers_text_to_vectors_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data)
|
||||
layers_text_to_path_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data)
|
||||
{
|
||||
GimpImage *image;
|
||||
GList *layers;
|
||||
GList *iter;
|
||||
gboolean path_added = FALSE;
|
||||
return_if_no_layers (image, layers, data);
|
||||
|
||||
/* TODO: have the proper undo group. */
|
||||
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_PATHS_IMPORT,
|
||||
_("Add Paths"));
|
||||
|
||||
for (iter = layers; iter; iter = iter->next)
|
||||
{
|
||||
GimpLayer *layer = iter->data;
|
||||
@@ -1122,16 +1094,20 @@ layers_text_to_vectors_cmd_callback (GimpAction *action,
|
||||
|
||||
gimp_image_add_path (image, path,
|
||||
GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
|
||||
gimp_image_flush (image);
|
||||
path_added = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
if (path_added)
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
void
|
||||
layers_text_along_vectors_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data)
|
||||
layers_text_along_path_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data)
|
||||
{
|
||||
GimpImage *image;
|
||||
GList *layers;
|
||||
@@ -1260,6 +1236,7 @@ layers_resize_to_image_cmd_callback (GimpAction *action,
|
||||
if (g_list_length (layers) > 1)
|
||||
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_RESIZE,
|
||||
_("Layers to Image Size"));
|
||||
|
||||
for (iter = layers; iter; iter = iter->next)
|
||||
gimp_layer_resize_to_image (iter->data,
|
||||
action_data_get_context (data),
|
||||
@@ -1445,8 +1422,9 @@ layers_crop_to_content_cmd_callback (GimpAction *action,
|
||||
break;
|
||||
}
|
||||
}
|
||||
gimp_image_flush (image);
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1574,7 +1552,6 @@ layers_mask_add_last_vals_cmd_callback (GimpAction *action,
|
||||
}
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
@@ -1601,6 +1578,7 @@ layers_mask_apply_cmd_callback (GimpAction *action,
|
||||
! gimp_item_is_content_locked (GIMP_ITEM (iter->data), NULL))))
|
||||
break;
|
||||
}
|
||||
|
||||
if (iter == NULL)
|
||||
/* No layers or none have applicable masks. */
|
||||
return;
|
||||
@@ -1675,43 +1653,47 @@ layers_mask_show_cmd_callback (GimpAction *action,
|
||||
GimpImage *image;
|
||||
GList *layers;
|
||||
GList *iter;
|
||||
gboolean active = g_variant_get_boolean (value);
|
||||
gboolean have_masks = FALSE;
|
||||
gboolean active = g_variant_get_boolean (value);
|
||||
gint n_masks = 0;
|
||||
return_if_no_layers (image, layers, data);
|
||||
|
||||
for (iter = layers; iter; iter = iter->next)
|
||||
{
|
||||
if (gimp_layer_get_mask (iter->data))
|
||||
{
|
||||
have_masks = TRUE;
|
||||
/* A bit of tricky to handle multiple and diverse layers with
|
||||
* a toggle action (with only binary state).
|
||||
* In non-active state, we will consider sets of both shown
|
||||
* and hidden masks as ok and exits. This allows us to switch
|
||||
* the action "active" state without actually changing
|
||||
* individual masks state without explicit user request.
|
||||
*/
|
||||
if (! active && ! gimp_layer_get_show_mask (iter->data))
|
||||
return;
|
||||
if (active && gimp_layer_get_show_mask (iter->data))
|
||||
{
|
||||
/* 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
|
||||
* visible layer masks.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (gimp_layer_get_show_mask (iter->data) != active)
|
||||
n_masks++;
|
||||
}
|
||||
}
|
||||
if (! have_masks)
|
||||
|
||||
if (n_masks == 0)
|
||||
return;
|
||||
|
||||
gimp_image_undo_group_start (image,
|
||||
GIMP_UNDO_GROUP_LAYER_ADD,
|
||||
_("Show Layer Masks"));
|
||||
if (n_masks > 1)
|
||||
gimp_image_undo_group_start (image,
|
||||
GIMP_UNDO_GROUP_LAYER_ADD,
|
||||
_("Show Layer Masks"));
|
||||
|
||||
for (iter = layers; iter; iter = iter->next)
|
||||
{
|
||||
if (gimp_layer_get_mask (iter->data))
|
||||
{
|
||||
gimp_layer_set_show_mask (iter->data, active, TRUE);
|
||||
}
|
||||
gimp_layer_set_show_mask (iter->data, active, TRUE);
|
||||
}
|
||||
|
||||
if (n_masks > 1)
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
gimp_image_flush (image);
|
||||
gimp_image_undo_group_end (image);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1722,43 +1704,47 @@ layers_mask_disable_cmd_callback (GimpAction *action,
|
||||
GimpImage *image;
|
||||
GList *layers;
|
||||
GList *iter;
|
||||
gboolean active = g_variant_get_boolean (value);
|
||||
gboolean have_masks = FALSE;
|
||||
gboolean active = g_variant_get_boolean (value);
|
||||
gint n_masks = 0;
|
||||
return_if_no_layers (image, layers, data);
|
||||
|
||||
for (iter = layers; iter; iter = iter->next)
|
||||
{
|
||||
if (gimp_layer_get_mask (iter->data))
|
||||
{
|
||||
have_masks = TRUE;
|
||||
/* A bit of tricky to handle multiple and diverse layers with
|
||||
* a toggle action (with only binary state).
|
||||
* In non-active state, we will consider sets of both enabled
|
||||
* and disabled masks as ok and exits. This allows us to
|
||||
* switch the action "active" state without actually changing
|
||||
* individual masks state without explicit user request.
|
||||
*/
|
||||
if (! active && gimp_layer_get_apply_mask (iter->data))
|
||||
return;
|
||||
if (active && ! gimp_layer_get_apply_mask (iter->data))
|
||||
{
|
||||
/* 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
|
||||
* disabled layer masks.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if ((! gimp_layer_get_apply_mask (iter->data)) != active)
|
||||
n_masks++;
|
||||
}
|
||||
}
|
||||
if (! have_masks)
|
||||
|
||||
if (n_masks == 0)
|
||||
return;
|
||||
|
||||
gimp_image_undo_group_start (image,
|
||||
GIMP_UNDO_GROUP_LAYER_ADD,
|
||||
_("Disable Layer Masks"));
|
||||
if (n_masks > 1)
|
||||
gimp_image_undo_group_start (image,
|
||||
GIMP_UNDO_GROUP_LAYER_ADD,
|
||||
_("Disable Layer Masks"));
|
||||
|
||||
for (iter = layers; iter; iter = iter->next)
|
||||
{
|
||||
if (gimp_layer_get_mask (iter->data))
|
||||
{
|
||||
gimp_layer_set_apply_mask (iter->data, ! active, TRUE);
|
||||
}
|
||||
gimp_layer_set_apply_mask (iter->data, ! active, TRUE);
|
||||
}
|
||||
|
||||
if (n_masks > 1)
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
gimp_image_flush (image);
|
||||
gimp_image_undo_group_end (image);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1801,10 +1787,12 @@ layers_mask_to_selection_cmd_callback (GimpAction *action,
|
||||
C_("undo-type", "Intersect Masks with Selection"));
|
||||
break;
|
||||
}
|
||||
|
||||
gimp_channel_combine_items (gimp_image_get_mask (image),
|
||||
masks, operation);
|
||||
gimp_image_flush (image);
|
||||
g_list_free (masks);
|
||||
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1883,8 +1871,10 @@ layers_alpha_to_selection_cmd_callback (GimpAction *action,
|
||||
C_("undo-type", "Intersect Alpha with Selection"));
|
||||
break;
|
||||
}
|
||||
|
||||
gimp_channel_combine_items (gimp_image_get_mask (image),
|
||||
layers, operation);
|
||||
|
||||
gimp_image_flush (image);
|
||||
|
||||
if (gimp_channel_is_empty (gimp_image_get_mask (image)))
|
||||
@@ -2044,6 +2034,7 @@ layers_blend_space_cmd_callback (GimpAction *action,
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
g_list_free (update_layers);
|
||||
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
}
|
||||
@@ -2097,6 +2088,7 @@ layers_composite_space_cmd_callback (GimpAction *action,
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
g_list_free (update_layers);
|
||||
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
}
|
||||
@@ -2150,6 +2142,7 @@ layers_composite_mode_cmd_callback (GimpAction *action,
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
g_list_free (update_layers);
|
||||
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
}
|
||||
@@ -2226,6 +2219,7 @@ layers_lock_alpha_cmd_callback (GimpAction *action,
|
||||
gimp_image_undo_group_start (image,
|
||||
GIMP_UNDO_GROUP_LAYER_LOCK_ALPHA,
|
||||
lock_alpha ? _("Lock alpha channels") : _("Unlock alpha channels"));
|
||||
|
||||
for (iter = layers; iter; iter = iter->next)
|
||||
{
|
||||
if (gimp_layer_can_lock_alpha (iter->data))
|
||||
@@ -2234,6 +2228,7 @@ layers_lock_alpha_cmd_callback (GimpAction *action,
|
||||
gimp_layer_set_lock_alpha (iter->data, lock_alpha, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
@@ -2474,7 +2469,6 @@ layers_edit_attributes_callback (GtkWidget *dialog,
|
||||
gimp_layer_set_lock_alpha (layer, layer_lock_alpha, TRUE);
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
@@ -2510,6 +2504,7 @@ layers_add_mask_callback (GtkWidget *dialog,
|
||||
gimp_image_undo_group_start (image,
|
||||
GIMP_UNDO_GROUP_LAYER_ADD,
|
||||
_("Add Layer Masks"));
|
||||
|
||||
for (iter = layers; iter; iter = iter->next)
|
||||
{
|
||||
mask = gimp_layer_create_mask (iter->data,
|
||||
@@ -2532,6 +2527,7 @@ layers_add_mask_callback (GtkWidget *dialog,
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
gimp_image_flush (image);
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
|
@@ -78,10 +78,10 @@ void layers_delete_cmd_callback (GimpAction *action,
|
||||
void layers_text_discard_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data);
|
||||
void layers_text_to_vectors_cmd_callback (GimpAction *action,
|
||||
void layers_text_to_path_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data);
|
||||
void layers_text_along_vectors_cmd_callback (GimpAction *action,
|
||||
void layers_text_along_path_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data);
|
||||
|
||||
|
@@ -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,
|
||||
],
|
||||
)
|
||||
|
@@ -79,8 +79,17 @@ palette_editor_delete_color_cmd_callback (GimpAction *action,
|
||||
if (data_editor->data_editable && editor->color)
|
||||
{
|
||||
GimpPalette *palette = GIMP_PALETTE (data_editor->data);
|
||||
gint index;
|
||||
|
||||
index = gimp_palette_get_entry_position (palette, editor->color);
|
||||
|
||||
gimp_palette_delete_entry (palette, editor->color);
|
||||
|
||||
if (index >= gimp_palette_get_n_colors (palette))
|
||||
index = gimp_palette_get_n_colors (palette) - 1;
|
||||
|
||||
gimp_palette_view_select_entry (GIMP_PALETTE_VIEW (editor->view),
|
||||
gimp_palette_get_entry (palette, index));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -117,9 +117,7 @@ palettes_merge_callback (GtkWidget *widget,
|
||||
context = gimp_container_view_get_context (editor->view);
|
||||
factory = gimp_data_factory_view_get_data_factory (view);
|
||||
|
||||
gimp_container_view_get_selected (editor->view, &selected, NULL);
|
||||
|
||||
if (g_list_length (selected) < 2)
|
||||
if (gimp_container_view_get_selected (editor->view, &selected) < 2)
|
||||
{
|
||||
gimp_message_literal (context->gimp,
|
||||
G_OBJECT (editor), GIMP_MESSAGE_WARNING,
|
||||
|
@@ -46,7 +46,7 @@ static const GimpActionEntry paths_actions[] =
|
||||
NC_("paths-action", "Edit Pa_th"), NULL, { NULL },
|
||||
NC_("paths-action", "Edit the active path"),
|
||||
paths_edit_cmd_callback,
|
||||
GIMP_HELP_TOOL_VECTORS },
|
||||
GIMP_HELP_TOOL_PATH },
|
||||
|
||||
{ "paths-edit-attributes", GIMP_ICON_EDIT,
|
||||
NC_("paths-action", "_Edit Path Attributes..."), NULL, { NULL },
|
||||
|
@@ -138,7 +138,7 @@ paths_edit_cmd_callback (GimpAction *action,
|
||||
}
|
||||
|
||||
if (GIMP_IS_VECTOR_TOOL (active_tool))
|
||||
gimp_vector_tool_set_vectors (GIMP_VECTOR_TOOL (active_tool), paths->data);
|
||||
gimp_vector_tool_set_path (GIMP_VECTOR_TOOL (active_tool), paths->data);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -924,8 +924,8 @@ paths_import_callback (GtkWidget *dialog,
|
||||
GimpImage *image,
|
||||
GFile *file,
|
||||
GFile *import_folder,
|
||||
gboolean merge_vectors,
|
||||
gboolean scale_vectors,
|
||||
gboolean merge_paths,
|
||||
gboolean scale_paths,
|
||||
gpointer user_data)
|
||||
{
|
||||
GimpDialogConfig *config = GIMP_DIALOG_CONFIG (image->gimp->config);
|
||||
@@ -937,8 +937,8 @@ paths_import_callback (GtkWidget *dialog,
|
||||
|
||||
g_object_set (config,
|
||||
"path-import-path", path,
|
||||
"path-import-merge", merge_vectors,
|
||||
"path-import-scale", scale_vectors,
|
||||
"path-import-merge", merge_paths,
|
||||
"path-import-scale", scale_paths,
|
||||
NULL);
|
||||
|
||||
if (path)
|
||||
|
@@ -57,9 +57,9 @@ void paths_merge_visible_cmd_callback (GimpAction *action,
|
||||
void paths_to_selection_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data);
|
||||
void paths_selection_to_paths_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data);
|
||||
void paths_selection_to_paths_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data);
|
||||
|
||||
void paths_fill_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
|
@@ -102,7 +102,7 @@ plug_in_run_cmd_callback (GimpAction *action,
|
||||
context = gimp_container_view_get_context (editor->view);
|
||||
|
||||
object = gimp_context_get_by_type (context,
|
||||
gimp_container_get_children_type (container));
|
||||
gimp_container_get_child_type (container));
|
||||
|
||||
args = procedure_commands_get_data_args (procedure, object);
|
||||
}
|
||||
@@ -119,14 +119,16 @@ plug_in_run_cmd_callback (GimpAction *action,
|
||||
{
|
||||
GimpItemTreeView *view = GIMP_ITEM_TREE_VIEW (data);
|
||||
GimpImage *image;
|
||||
GList *items;
|
||||
GList *items = NULL;
|
||||
|
||||
image = gimp_item_tree_view_get_image (view);
|
||||
|
||||
if (image)
|
||||
items = GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->get_selected_items (image);
|
||||
else
|
||||
items = NULL;
|
||||
{
|
||||
GType item_type = GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->item_type;
|
||||
|
||||
items = gimp_image_get_selected_items (image, item_type);
|
||||
}
|
||||
|
||||
args = procedure_commands_get_items_args (procedure, image, items);
|
||||
}
|
||||
|
@@ -289,14 +289,14 @@ procedure_commands_get_display_args (GimpProcedure *procedure,
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (GIMP_IS_PARAM_SPEC_CORE_OBJECT_ARRAY (procedure->args[n_args]))
|
||||
else if (gimp_value_array_length (args) > n_args &&
|
||||
GIMP_IS_PARAM_SPEC_CORE_OBJECT_ARRAY (procedure->args[n_args]))
|
||||
{
|
||||
GimpDrawable **drawables = NULL;
|
||||
gint n_drawables;
|
||||
GList *iter;
|
||||
gint i;
|
||||
|
||||
|
||||
n_drawables = g_list_length (drawables_list);
|
||||
|
||||
drawables = g_new0 (GimpDrawable *, n_drawables + 1);
|
||||
|
@@ -166,7 +166,7 @@ templates_duplicate_cmd_callback (GimpAction *action,
|
||||
|
||||
gimp_container_add (container, GIMP_OBJECT (new_template));
|
||||
gimp_context_set_by_type (context,
|
||||
gimp_container_get_children_type (container),
|
||||
gimp_container_get_child_type (container),
|
||||
GIMP_OBJECT (new_template));
|
||||
g_object_unref (new_template);
|
||||
|
||||
@@ -326,7 +326,7 @@ templates_delete_response (GtkWidget *dialog,
|
||||
{
|
||||
if (new_active)
|
||||
gimp_context_set_by_type (delete_data->context,
|
||||
gimp_container_get_children_type (delete_data->container),
|
||||
gimp_container_get_child_type (delete_data->container),
|
||||
new_active);
|
||||
|
||||
gimp_container_remove (delete_data->container,
|
||||
|
@@ -170,7 +170,7 @@ text_tool_text_to_path_cmd_callback (GimpAction *action,
|
||||
{
|
||||
GimpTextTool *text_tool = GIMP_TEXT_TOOL (data);
|
||||
|
||||
gimp_text_tool_create_vectors (text_tool);
|
||||
gimp_text_tool_create_path (text_tool);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -181,7 +181,7 @@ text_tool_text_along_path_cmd_callback (GimpAction *action,
|
||||
GimpTextTool *text_tool = GIMP_TEXT_TOOL (data);
|
||||
GError *error = NULL;
|
||||
|
||||
if (! gimp_text_tool_create_vectors_warped (text_tool, &error))
|
||||
if (! gimp_text_tool_create_path_warped (text_tool, &error))
|
||||
{
|
||||
gimp_message (text_tool->image->gimp, G_OBJECT (text_tool),
|
||||
GIMP_MESSAGE_ERROR,
|
||||
|
@@ -87,7 +87,8 @@ vector_toolpath_actions_update (GimpActionGroup *group,
|
||||
gpointer data)
|
||||
{
|
||||
GimpToolPath *toolpath = GIMP_TOOL_PATH (data);
|
||||
gboolean on_handle, on_curve;
|
||||
gboolean on_handle;
|
||||
gboolean on_curve;
|
||||
|
||||
gimp_tool_path_get_popup_state (toolpath, &on_handle, &on_curve);
|
||||
|
||||
|
@@ -36,4 +36,5 @@ void vector_toolpath_reverse_stroke_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data);
|
||||
|
||||
|
||||
#endif /* __VECTOR_TOOLPATH_COMMANDS_H__ */
|
||||
|
@@ -273,9 +273,9 @@ static const GimpToggleActionEntry view_toggle_actions[] =
|
||||
{ "view-snap-to-vectors", NULL,
|
||||
NC_("view-action", "Snap t_o Active Path"), NULL, { NULL },
|
||||
NC_("view-action", "Tool operations snap to the active path"),
|
||||
view_snap_to_vectors_cmd_callback,
|
||||
view_snap_to_path_cmd_callback,
|
||||
FALSE,
|
||||
GIMP_HELP_VIEW_SNAP_TO_VECTORS },
|
||||
GIMP_HELP_VIEW_SNAP_TO_PATH },
|
||||
|
||||
{ "view-snap-to-bbox", NULL,
|
||||
NC_("view-action", "Snap to _Bounding Boxes"), NULL, { NULL },
|
||||
|
@@ -963,9 +963,9 @@ view_snap_to_canvas_cmd_callback (GimpAction *action,
|
||||
}
|
||||
|
||||
void
|
||||
view_snap_to_vectors_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data)
|
||||
view_snap_to_path_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data)
|
||||
{
|
||||
GimpDisplayShell *shell;
|
||||
gboolean active;
|
||||
@@ -973,9 +973,9 @@ view_snap_to_vectors_cmd_callback (GimpAction *action,
|
||||
|
||||
active = g_variant_get_boolean (value);
|
||||
|
||||
if (active != gimp_display_shell_get_snap_to_vectors (shell))
|
||||
if (active != gimp_display_shell_get_snap_to_path (shell))
|
||||
{
|
||||
gimp_display_shell_set_snap_to_vectors (shell, active);
|
||||
gimp_display_shell_set_snap_to_path (shell, active);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -154,7 +154,7 @@ void view_snap_to_grid_cmd_callback (GimpAction *action,
|
||||
void view_snap_to_canvas_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data);
|
||||
void view_snap_to_vectors_cmd_callback (GimpAction *action,
|
||||
void view_snap_to_path_cmd_callback (GimpAction *action,
|
||||
GVariant *value,
|
||||
gpointer data);
|
||||
void view_snap_to_bbox_cmd_callback (GimpAction *action,
|
||||
|
@@ -59,7 +59,8 @@ static void windows_actions_display_remove (GimpContainer *conta
|
||||
GimpActionGroup *group);
|
||||
static void windows_actions_display_reorder (GimpContainer *container,
|
||||
GimpDisplay *display,
|
||||
gint position,
|
||||
gint old_index,
|
||||
gint new_index,
|
||||
GimpActionGroup *group);
|
||||
static void windows_actions_image_notify (GimpDisplay *display,
|
||||
const GParamSpec *unused,
|
||||
@@ -336,6 +337,7 @@ windows_actions_display_remove (GimpContainer *container,
|
||||
static void
|
||||
windows_actions_display_reorder (GimpContainer *container,
|
||||
GimpDisplay *display,
|
||||
gint old_index,
|
||||
gint new_index,
|
||||
GimpActionGroup *group)
|
||||
{
|
||||
|
12
app/app.c
12
app/app.c
@@ -530,11 +530,13 @@ app_activate_callback (GimpCoreApp *app,
|
||||
gimp_signal_private (SIGINT, app_quit_on_ctrl_c, 0);
|
||||
#endif
|
||||
g_printf ("\n== %s ==\n%s\n\n%s\n",
|
||||
/* TODO: localize when string freeze is over. */
|
||||
"INFO",
|
||||
"GIMP is now running as a background process. "
|
||||
"You can quit anytime with Ctrl-C (SIGINT).",
|
||||
"If you wanted to quit immediately instead, call GIMP with --quit.");
|
||||
/* TRANSLATORS: title for info message in terminal window */
|
||||
_("INFO"),
|
||||
/* TRANSLATORS: info message displayed in terminal window. */
|
||||
_("GIMP is now running as a background process. "
|
||||
"You can quit anytime with Ctrl-C (SIGINT)."),
|
||||
/* TRANSLATORS: info message displayed in terminal window. */
|
||||
_("If you wanted to quit immediately instead, call GIMP with --quit."));
|
||||
g_application_hold (G_APPLICATION (app));
|
||||
}
|
||||
}
|
||||
|
@@ -56,4 +56,32 @@ typedef struct _GimpTemplate GimpTemplate;
|
||||
#define gimp_assert_not_reached g_assert_not_reached
|
||||
|
||||
|
||||
#if ! GLIB_CHECK_VERSION(2, 76, 0)
|
||||
/* Function copied from GLib 2.76.0 and made available privately so that
|
||||
* we don't have to bump our dependency requirement.
|
||||
*
|
||||
* TODO: remove this when GLib requirement moves over 2.76.
|
||||
*/
|
||||
static inline gboolean g_set_str (char **str_pointer,
|
||||
const char *new_str);
|
||||
|
||||
static inline gboolean
|
||||
g_set_str (char **str_pointer,
|
||||
const char *new_str)
|
||||
{
|
||||
char *copy;
|
||||
|
||||
if (*str_pointer == new_str ||
|
||||
(*str_pointer && new_str && strcmp (*str_pointer, new_str) == 0))
|
||||
return FALSE;
|
||||
|
||||
copy = g_strdup (new_str);
|
||||
g_free (*str_pointer);
|
||||
*str_pointer = copy;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __CONFIG_TYPES_H__ */
|
||||
|
@@ -909,9 +909,9 @@ gimp_core_config_finalize (GObject *object)
|
||||
g_free (core_config->plug_in_rc_path);
|
||||
g_free (core_config->import_raw_plug_in);
|
||||
|
||||
g_clear_pointer (&core_config->last_known_release, g_free);
|
||||
g_clear_pointer (&core_config->last_known_release, g_free);
|
||||
g_clear_pointer (&core_config->last_release_comment, g_free);
|
||||
g_clear_pointer (&core_config->config_version, g_free);
|
||||
g_clear_pointer (&core_config->config_version, g_free);
|
||||
|
||||
g_clear_object (&core_config->default_image);
|
||||
g_clear_object (&core_config->default_grid);
|
||||
@@ -932,12 +932,12 @@ gimp_core_config_set_property (GObject *object,
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_LANGUAGE:
|
||||
g_free (core_config->language);
|
||||
core_config->language = g_value_dup_string (value);
|
||||
g_set_str (&core_config->language,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_PREV_LANGUAGE:
|
||||
g_free (core_config->prev_language);
|
||||
core_config->prev_language = g_value_dup_string (value);
|
||||
g_set_str (&core_config->prev_language,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_INTERPOLATION_TYPE:
|
||||
core_config->interpolation_type = g_value_get_enum (value);
|
||||
@@ -946,116 +946,116 @@ gimp_core_config_set_property (GObject *object,
|
||||
core_config->default_threshold = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_PLUG_IN_PATH:
|
||||
g_free (core_config->plug_in_path);
|
||||
core_config->plug_in_path = g_value_dup_string (value);
|
||||
g_set_str (&core_config->plug_in_path,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_MODULE_PATH:
|
||||
g_free (core_config->module_path);
|
||||
core_config->module_path = g_value_dup_string (value);
|
||||
g_set_str (&core_config->module_path,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_INTERPRETER_PATH:
|
||||
g_free (core_config->interpreter_path);
|
||||
core_config->interpreter_path = g_value_dup_string (value);
|
||||
g_set_str (&core_config->interpreter_path,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_ENVIRON_PATH:
|
||||
g_free (core_config->environ_path);
|
||||
core_config->environ_path = g_value_dup_string (value);
|
||||
g_set_str (&core_config->environ_path,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_BRUSH_PATH:
|
||||
g_free (core_config->brush_path);
|
||||
core_config->brush_path = g_value_dup_string (value);
|
||||
g_set_str (&core_config->brush_path,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_BRUSH_PATH_WRITABLE:
|
||||
g_free (core_config->brush_path_writable);
|
||||
core_config->brush_path_writable = g_value_dup_string (value);
|
||||
g_set_str (&core_config->brush_path_writable,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DYNAMICS_PATH:
|
||||
g_free (core_config->dynamics_path);
|
||||
core_config->dynamics_path = g_value_dup_string (value);
|
||||
g_set_str (&core_config->dynamics_path,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DYNAMICS_PATH_WRITABLE:
|
||||
g_free (core_config->dynamics_path_writable);
|
||||
core_config->dynamics_path_writable = g_value_dup_string (value);
|
||||
g_set_str (&core_config->dynamics_path_writable,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_MYPAINT_BRUSH_PATH:
|
||||
g_free (core_config->mypaint_brush_path);
|
||||
core_config->mypaint_brush_path = g_value_dup_string (value);
|
||||
g_set_str (&core_config->mypaint_brush_path,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_MYPAINT_BRUSH_PATH_WRITABLE:
|
||||
g_free (core_config->mypaint_brush_path_writable);
|
||||
core_config->mypaint_brush_path_writable = g_value_dup_string (value);
|
||||
g_set_str (&core_config->mypaint_brush_path_writable,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_PATTERN_PATH:
|
||||
g_free (core_config->pattern_path);
|
||||
core_config->pattern_path = g_value_dup_string (value);
|
||||
g_set_str (&core_config->pattern_path,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_PATTERN_PATH_WRITABLE:
|
||||
g_free (core_config->pattern_path_writable);
|
||||
core_config->pattern_path_writable = g_value_dup_string (value);
|
||||
g_set_str (&core_config->pattern_path_writable,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_PALETTE_PATH:
|
||||
g_free (core_config->palette_path);
|
||||
core_config->palette_path = g_value_dup_string (value);
|
||||
g_set_str (&core_config->palette_path,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_PALETTE_PATH_WRITABLE:
|
||||
g_free (core_config->palette_path_writable);
|
||||
core_config->palette_path_writable = g_value_dup_string (value);
|
||||
g_set_str (&core_config->palette_path_writable,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_GRADIENT_PATH:
|
||||
g_free (core_config->gradient_path);
|
||||
core_config->gradient_path = g_value_dup_string (value);
|
||||
g_set_str (&core_config->gradient_path,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_GRADIENT_PATH_WRITABLE:
|
||||
g_free (core_config->gradient_path_writable);
|
||||
core_config->gradient_path_writable = g_value_dup_string (value);
|
||||
g_set_str (&core_config->gradient_path_writable,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_TOOL_PRESET_PATH:
|
||||
g_free (core_config->tool_preset_path);
|
||||
core_config->tool_preset_path = g_value_dup_string (value);
|
||||
g_set_str (&core_config->tool_preset_path,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_TOOL_PRESET_PATH_WRITABLE:
|
||||
g_free (core_config->tool_preset_path_writable);
|
||||
core_config->tool_preset_path_writable = g_value_dup_string (value);
|
||||
g_set_str (&core_config->tool_preset_path_writable,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_FONT_PATH:
|
||||
g_free (core_config->font_path);
|
||||
core_config->font_path = g_value_dup_string (value);
|
||||
g_set_str (&core_config->font_path,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_FONT_PATH_WRITABLE:
|
||||
g_free (core_config->font_path_writable);
|
||||
core_config->font_path_writable = g_value_dup_string (value);
|
||||
g_set_str (&core_config->font_path_writable,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DEFAULT_BRUSH:
|
||||
g_free (core_config->default_brush);
|
||||
core_config->default_brush = g_value_dup_string (value);
|
||||
g_set_str (&core_config->default_brush,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DEFAULT_DYNAMICS:
|
||||
g_free (core_config->default_dynamics);
|
||||
core_config->default_dynamics = g_value_dup_string (value);
|
||||
g_set_str (&core_config->default_dynamics,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DEFAULT_MYPAINT_BRUSH:
|
||||
g_free (core_config->default_mypaint_brush);
|
||||
core_config->default_mypaint_brush = g_value_dup_string (value);
|
||||
g_set_str (&core_config->default_mypaint_brush,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DEFAULT_PATTERN:
|
||||
g_free (core_config->default_pattern);
|
||||
core_config->default_pattern = g_value_dup_string (value);
|
||||
g_set_str (&core_config->default_pattern,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DEFAULT_PALETTE:
|
||||
g_free (core_config->default_palette);
|
||||
core_config->default_palette = g_value_dup_string (value);
|
||||
g_set_str (&core_config->default_palette,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DEFAULT_GRADIENT:
|
||||
g_free (core_config->default_gradient);
|
||||
core_config->default_gradient = g_value_dup_string (value);
|
||||
g_set_str (&core_config->default_gradient,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DEFAULT_TOOL_PRESET:
|
||||
g_free (core_config->default_tool_preset);
|
||||
core_config->default_tool_preset = g_value_dup_string (value);
|
||||
g_set_str (&core_config->default_tool_preset,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DEFAULT_FONT:
|
||||
g_free (core_config->default_font);
|
||||
core_config->default_font = g_value_dup_string (value);
|
||||
g_set_str (&core_config->default_font,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_GLOBAL_BRUSH:
|
||||
core_config->global_brush = g_value_get_boolean (value);
|
||||
@@ -1101,8 +1101,8 @@ gimp_core_config_set_property (GObject *object,
|
||||
core_config->undo_preview_size = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_PLUGINRC_PATH:
|
||||
g_free (core_config->plug_in_rc_path);
|
||||
core_config->plug_in_rc_path = g_value_dup_string (value);
|
||||
g_set_str (&core_config->plug_in_rc_path,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_LAYER_PREVIEWS:
|
||||
core_config->layer_previews = g_value_get_boolean (value);
|
||||
@@ -1134,8 +1134,8 @@ gimp_core_config_set_property (GObject *object,
|
||||
core_config->last_release_timestamp = g_value_get_int64 (value);
|
||||
break;
|
||||
case PROP_LAST_RELEASE_COMMENT:
|
||||
g_clear_pointer (&core_config->last_release_comment, g_free);
|
||||
core_config->last_release_comment = g_value_dup_string (value);
|
||||
g_set_str (&core_config->last_release_comment,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_LAST_REVISION:
|
||||
core_config->last_revision = g_value_get_int (value);
|
||||
@@ -1143,13 +1143,13 @@ gimp_core_config_set_property (GObject *object,
|
||||
case PROP_LAST_KNOWN_RELEASE:
|
||||
if (core_config->last_known_release != g_value_get_string (value))
|
||||
{
|
||||
g_clear_pointer (&core_config->last_known_release, g_free);
|
||||
core_config->last_known_release = g_value_dup_string (value);
|
||||
g_set_str (&core_config->last_known_release,
|
||||
g_value_get_string (value));
|
||||
}
|
||||
break;
|
||||
case PROP_CONFIG_VERSION:
|
||||
g_clear_pointer (&core_config->config_version, g_free);
|
||||
core_config->config_version = g_value_dup_string (value);
|
||||
g_set_str (&core_config->config_version,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_SAVE_DOCUMENT_HISTORY:
|
||||
core_config->save_document_history = g_value_get_boolean (value);
|
||||
@@ -1168,8 +1168,8 @@ gimp_core_config_set_property (GObject *object,
|
||||
core_config->import_add_alpha = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_IMPORT_RAW_PLUG_IN:
|
||||
g_free (core_config->import_raw_plug_in);
|
||||
core_config->import_raw_plug_in = g_value_dup_string (value);
|
||||
g_set_str (&core_config->import_raw_plug_in,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_EXPORT_FILE_TYPE:
|
||||
core_config->export_file_type = g_value_get_enum (value);
|
||||
|
@@ -89,14 +89,14 @@ enum
|
||||
PROP_CHANNEL_NEW_NAME,
|
||||
PROP_CHANNEL_NEW_COLOR,
|
||||
|
||||
PROP_VECTORS_NEW_NAME,
|
||||
PROP_PATH_NEW_NAME,
|
||||
|
||||
PROP_VECTORS_EXPORT_PATH,
|
||||
PROP_VECTORS_EXPORT_ACTIVE_ONLY,
|
||||
PROP_PATH_EXPORT_PATH,
|
||||
PROP_PATH_EXPORT_ACTIVE_ONLY,
|
||||
|
||||
PROP_VECTORS_IMPORT_PATH,
|
||||
PROP_VECTORS_IMPORT_MERGE,
|
||||
PROP_VECTORS_IMPORT_SCALE,
|
||||
PROP_PATH_IMPORT_PATH,
|
||||
PROP_PATH_IMPORT_MERGE,
|
||||
PROP_PATH_IMPORT_SCALE,
|
||||
|
||||
PROP_SELECTION_FEATHER_RADIUS,
|
||||
PROP_SELECTION_FEATHER_EDGE_LOCK,
|
||||
@@ -425,47 +425,47 @@ gimp_dialog_config_class_init (GimpDialogConfigClass *klass)
|
||||
TRUE, half_transparent,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_STRING (object_class, PROP_VECTORS_NEW_NAME,
|
||||
GIMP_CONFIG_PROP_STRING (object_class, PROP_PATH_NEW_NAME,
|
||||
"path-new-name",
|
||||
"Default new path name",
|
||||
VECTORS_NEW_NAME_BLURB,
|
||||
PATH_NEW_NAME_BLURB,
|
||||
_("Path"),
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_PATH (object_class, PROP_VECTORS_EXPORT_PATH,
|
||||
GIMP_CONFIG_PROP_PATH (object_class, PROP_PATH_EXPORT_PATH,
|
||||
"path-export-path",
|
||||
"Default path export folder path",
|
||||
VECTORS_EXPORT_PATH_BLURB,
|
||||
PATH_EXPORT_PATH_BLURB,
|
||||
GIMP_CONFIG_PATH_FILE,
|
||||
NULL,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_VECTORS_EXPORT_ACTIVE_ONLY,
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_PATH_EXPORT_ACTIVE_ONLY,
|
||||
"path-export-active-only",
|
||||
"Default export only the selected paths",
|
||||
VECTORS_EXPORT_ACTIVE_ONLY_BLURB,
|
||||
PATH_EXPORT_ACTIVE_ONLY_BLURB,
|
||||
TRUE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_PATH (object_class, PROP_VECTORS_IMPORT_PATH,
|
||||
GIMP_CONFIG_PROP_PATH (object_class, PROP_PATH_IMPORT_PATH,
|
||||
"path-import-path",
|
||||
"Default path import folder path",
|
||||
VECTORS_IMPORT_PATH_BLURB,
|
||||
PATH_IMPORT_PATH_BLURB,
|
||||
GIMP_CONFIG_PATH_FILE,
|
||||
NULL,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_VECTORS_IMPORT_MERGE,
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_PATH_IMPORT_MERGE,
|
||||
"path-import-merge",
|
||||
"Default merge imported path",
|
||||
VECTORS_IMPORT_MERGE_BLURB,
|
||||
PATH_IMPORT_MERGE_BLURB,
|
||||
FALSE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_VECTORS_IMPORT_SCALE,
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_PATH_IMPORT_SCALE,
|
||||
"path-import-scale",
|
||||
"Default scale imported path",
|
||||
VECTORS_IMPORT_SCALE_BLURB,
|
||||
PATH_IMPORT_SCALE_BLURB,
|
||||
FALSE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
@@ -598,9 +598,9 @@ gimp_dialog_config_finalize (GObject *object)
|
||||
g_clear_pointer (&config->color_profile_path, g_free);
|
||||
g_clear_pointer (&config->layer_new_name, g_free);
|
||||
g_clear_pointer (&config->channel_new_name, g_free);
|
||||
g_clear_pointer (&config->path_new_name, g_free);
|
||||
g_clear_pointer (&config->path_export_path, g_free);
|
||||
g_clear_pointer (&config->path_import_path, g_free);
|
||||
g_clear_pointer (&config->path_new_name, g_free);
|
||||
g_clear_pointer (&config->path_export_path, g_free);
|
||||
g_clear_pointer (&config->path_import_path, g_free);
|
||||
|
||||
g_clear_object (&config->fill_options);
|
||||
g_clear_object (&config->stroke_options);
|
||||
@@ -632,9 +632,7 @@ gimp_dialog_config_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_COLOR_PROFILE_PATH:
|
||||
if (config->color_profile_path)
|
||||
g_free (config->color_profile_path);
|
||||
config->color_profile_path = g_value_dup_string (value);
|
||||
g_set_str (&config->color_profile_path, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_IMAGE_CONVERT_PROFILE_INTENT:
|
||||
@@ -687,9 +685,7 @@ gimp_dialog_config_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_LAYER_NEW_NAME:
|
||||
if (config->layer_new_name)
|
||||
g_free (config->layer_new_name);
|
||||
config->layer_new_name = g_value_dup_string (value);
|
||||
g_set_str (&config->layer_new_name, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_LAYER_NEW_MODE:
|
||||
config->layer_new_mode = g_value_get_enum (value);
|
||||
@@ -732,39 +728,31 @@ gimp_dialog_config_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_CHANNEL_NEW_NAME:
|
||||
if (config->channel_new_name)
|
||||
g_free (config->channel_new_name);
|
||||
config->channel_new_name = g_value_dup_string (value);
|
||||
g_set_str (&config->channel_new_name, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_CHANNEL_NEW_COLOR:
|
||||
g_clear_object (&config->channel_new_color);
|
||||
config->channel_new_color = gegl_color_duplicate (g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_VECTORS_NEW_NAME:
|
||||
if (config->path_new_name)
|
||||
g_free (config->path_new_name);
|
||||
config->path_new_name = g_value_dup_string (value);
|
||||
case PROP_PATH_NEW_NAME:
|
||||
g_set_str (&config->path_new_name, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_VECTORS_EXPORT_PATH:
|
||||
if (config->path_export_path)
|
||||
g_free (config->path_export_path);
|
||||
config->path_export_path = g_value_dup_string (value);
|
||||
case PROP_PATH_EXPORT_PATH:
|
||||
g_set_str (&config->path_export_path, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_VECTORS_EXPORT_ACTIVE_ONLY:
|
||||
case PROP_PATH_EXPORT_ACTIVE_ONLY:
|
||||
config->path_export_active_only = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_VECTORS_IMPORT_PATH:
|
||||
if (config->path_import_path)
|
||||
g_free (config->path_import_path);
|
||||
config->path_import_path = g_value_dup_string (value);
|
||||
case PROP_PATH_IMPORT_PATH:
|
||||
g_set_str (&config->path_import_path, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_VECTORS_IMPORT_MERGE:
|
||||
case PROP_PATH_IMPORT_MERGE:
|
||||
config->path_import_merge = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_VECTORS_IMPORT_SCALE:
|
||||
case PROP_PATH_IMPORT_SCALE:
|
||||
config->path_import_scale = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
@@ -938,24 +926,24 @@ gimp_dialog_config_get_property (GObject *object,
|
||||
g_value_set_object (value, config->channel_new_color);
|
||||
break;
|
||||
|
||||
case PROP_VECTORS_NEW_NAME:
|
||||
case PROP_PATH_NEW_NAME:
|
||||
g_value_set_string (value, config->path_new_name);
|
||||
break;
|
||||
|
||||
case PROP_VECTORS_EXPORT_PATH:
|
||||
case PROP_PATH_EXPORT_PATH:
|
||||
g_value_set_string (value, config->path_export_path);
|
||||
break;
|
||||
case PROP_VECTORS_EXPORT_ACTIVE_ONLY:
|
||||
case PROP_PATH_EXPORT_ACTIVE_ONLY:
|
||||
g_value_set_boolean (value, config->path_export_active_only);
|
||||
break;
|
||||
|
||||
case PROP_VECTORS_IMPORT_PATH:
|
||||
case PROP_PATH_IMPORT_PATH:
|
||||
g_value_set_string (value, config->path_import_path);
|
||||
break;
|
||||
case PROP_VECTORS_IMPORT_MERGE:
|
||||
case PROP_PATH_IMPORT_MERGE:
|
||||
g_value_set_boolean (value, config->path_import_merge);
|
||||
break;
|
||||
case PROP_VECTORS_IMPORT_SCALE:
|
||||
case PROP_PATH_IMPORT_SCALE:
|
||||
g_value_set_boolean (value, config->path_import_scale);
|
||||
break;
|
||||
|
||||
|
@@ -439,8 +439,8 @@ gimp_display_config_finalize (GObject *object)
|
||||
{
|
||||
GimpDisplayConfig *display_config = GIMP_DISPLAY_CONFIG (object);
|
||||
|
||||
g_free (display_config->image_title_format);
|
||||
g_free (display_config->image_status_format);
|
||||
g_clear_pointer (&display_config->image_title_format, g_free);
|
||||
g_clear_pointer (&display_config->image_status_format, g_free);
|
||||
|
||||
g_clear_object (&display_config->default_view);
|
||||
g_clear_object (&display_config->default_fullscreen_view);
|
||||
@@ -518,12 +518,10 @@ gimp_display_config_set_property (GObject *object,
|
||||
display_config->show_paint_tool_cursor = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_IMAGE_TITLE_FORMAT:
|
||||
g_free (display_config->image_title_format);
|
||||
display_config->image_title_format = g_value_dup_string (value);
|
||||
g_set_str (&display_config->image_title_format, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_IMAGE_STATUS_FORMAT:
|
||||
g_free (display_config->image_status_format);
|
||||
display_config->image_status_format = g_value_dup_string (value);
|
||||
g_set_str (&display_config->image_status_format, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_MONITOR_XRESOLUTION:
|
||||
display_config->monitor_xres = g_value_get_double (value);
|
||||
|
@@ -47,16 +47,16 @@ enum
|
||||
};
|
||||
|
||||
|
||||
static void gimp_early_rc_constructed (GObject *object);
|
||||
static void gimp_early_rc_finalize (GObject *object);
|
||||
static void gimp_early_rc_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_early_rc_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_early_rc_constructed (GObject *object);
|
||||
static void gimp_early_rc_finalize (GObject *object);
|
||||
static void gimp_early_rc_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_early_rc_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
|
||||
/* Just use GimpConfig interface's default implementation which will
|
||||
@@ -206,9 +206,7 @@ gimp_early_rc_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_LANGUAGE:
|
||||
if (rc->language)
|
||||
g_free (rc->language);
|
||||
rc->language = g_value_dup_string (value);
|
||||
g_set_str (&rc->language, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
@@ -255,12 +253,15 @@ gimp_early_rc_get_property (GObject *object,
|
||||
case PROP_VERBOSE:
|
||||
g_value_set_boolean (value, rc->verbose);
|
||||
break;
|
||||
|
||||
case PROP_SYSTEM_GIMPRC:
|
||||
g_value_set_object (value, rc->system_gimprc);
|
||||
break;
|
||||
|
||||
case PROP_USER_GIMPRC:
|
||||
g_value_set_object (value, rc->user_gimprc);
|
||||
break;
|
||||
|
||||
case PROP_LANGUAGE:
|
||||
g_value_set_string (value, rc->language);
|
||||
break;
|
||||
|
@@ -182,9 +182,9 @@ gimp_gegl_config_finalize (GObject *object)
|
||||
{
|
||||
GimpGeglConfig *gegl_config = GIMP_GEGL_CONFIG (object);
|
||||
|
||||
g_free (gegl_config->temp_path);
|
||||
g_free (gegl_config->swap_path);
|
||||
g_free (gegl_config->swap_compression);
|
||||
g_clear_pointer (&gegl_config->temp_path, g_free);
|
||||
g_clear_pointer (&gegl_config->swap_path, g_free);
|
||||
g_clear_pointer (&gegl_config->swap_compression, g_free);
|
||||
|
||||
gimp_debug_remove_instance (object);
|
||||
|
||||
@@ -202,23 +202,25 @@ gimp_gegl_config_set_property (GObject *object,
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_TEMP_PATH:
|
||||
g_free (gegl_config->temp_path);
|
||||
gegl_config->temp_path = g_value_dup_string (value);
|
||||
g_set_str (&gegl_config->temp_path, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_SWAP_PATH:
|
||||
g_free (gegl_config->swap_path);
|
||||
gegl_config->swap_path = g_value_dup_string (value);
|
||||
g_set_str (&gegl_config->swap_path, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_SWAP_COMPRESSION:
|
||||
g_free (gegl_config->swap_compression);
|
||||
gegl_config->swap_compression = g_value_dup_string (value);
|
||||
g_set_str (&gegl_config->swap_compression, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_NUM_PROCESSORS:
|
||||
gegl_config->num_processors = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_TILE_CACHE_SIZE:
|
||||
gegl_config->tile_cache_size = g_value_get_uint64 (value);
|
||||
break;
|
||||
|
||||
case PROP_USE_OPENCL:
|
||||
gegl_config->use_opencl = g_value_get_boolean (value);
|
||||
break;
|
||||
@@ -246,18 +248,23 @@ gimp_gegl_config_get_property (GObject *object,
|
||||
case PROP_TEMP_PATH:
|
||||
g_value_set_string (value, gegl_config->temp_path);
|
||||
break;
|
||||
|
||||
case PROP_SWAP_PATH:
|
||||
g_value_set_string (value, gegl_config->swap_path);
|
||||
break;
|
||||
|
||||
case PROP_SWAP_COMPRESSION:
|
||||
g_value_set_string (value, gegl_config->swap_compression);
|
||||
break;
|
||||
|
||||
case PROP_NUM_PROCESSORS:
|
||||
g_value_set_int (value, gegl_config->num_processors);
|
||||
break;
|
||||
|
||||
case PROP_TILE_CACHE_SIZE:
|
||||
g_value_set_uint64 (value, gegl_config->tile_cache_size);
|
||||
break;
|
||||
|
||||
case PROP_USE_OPENCL:
|
||||
g_value_set_boolean (value, gegl_config->use_opencl);
|
||||
break;
|
||||
|
@@ -73,6 +73,7 @@ enum
|
||||
PROP_THEME_SCHEME,
|
||||
PROP_OVERRIDE_THEME_ICON_SIZE,
|
||||
PROP_CUSTOM_ICON_SIZE,
|
||||
PROP_VIEWABLES_FOLLOW_THEME,
|
||||
PROP_ICON_THEME_PATH,
|
||||
PROP_ICON_THEME,
|
||||
PROP_PREFER_SYMBOLIC_ICONS,
|
||||
@@ -91,6 +92,7 @@ enum
|
||||
PROP_PLAYGROUND_NPD_TOOL,
|
||||
PROP_PLAYGROUND_SEAMLESS_CLONE_TOOL,
|
||||
PROP_PLAYGROUND_PAINT_SELECT_TOOL,
|
||||
PROP_PLAYGROUND_USE_LIST_BOX,
|
||||
|
||||
PROP_HIDE_DOCKS,
|
||||
PROP_SINGLE_WINDOW_MODE,
|
||||
@@ -329,6 +331,13 @@ gimp_gui_config_class_init (GimpGuiConfigClass *klass)
|
||||
GIMP_TYPE_ICON_SIZE,
|
||||
GIMP_ICON_SIZE_MEDIUM,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_VIEWABLES_FOLLOW_THEME,
|
||||
"viewables-follow-theme",
|
||||
"Preview of viewables follow the theme style when relevant",
|
||||
VIEWABLES_FOLLOW_THEME_BLURB,
|
||||
FALSE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
|
||||
path = gimp_config_build_data_path ("icons");
|
||||
GIMP_CONFIG_PROP_PATH (object_class, PROP_ICON_THEME_PATH,
|
||||
@@ -462,6 +471,14 @@ gimp_gui_config_class_init (GimpGuiConfigClass *klass)
|
||||
GIMP_PARAM_STATIC_STRINGS |
|
||||
GIMP_CONFIG_PARAM_RESTART);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class,
|
||||
PROP_PLAYGROUND_USE_LIST_BOX,
|
||||
"playground-use-list-box",
|
||||
"Playground Use List Box",
|
||||
PLAYGROUND_USE_LIST_BOX_BLURB,
|
||||
FALSE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_property (object_class, PROP_HIDE_DOCKS,
|
||||
g_param_spec_boolean ("hide-docks",
|
||||
NULL,
|
||||
@@ -591,12 +608,12 @@ gimp_gui_config_finalize (GObject *object)
|
||||
{
|
||||
GimpGuiConfig *gui_config = GIMP_GUI_CONFIG (object);
|
||||
|
||||
g_free (gui_config->theme_path);
|
||||
g_free (gui_config->theme);
|
||||
g_free (gui_config->icon_theme_path);
|
||||
g_free (gui_config->icon_theme);
|
||||
g_free (gui_config->help_locales);
|
||||
g_free (gui_config->user_manual_online_uri);
|
||||
g_clear_pointer (&gui_config->theme_path, g_free);
|
||||
g_clear_pointer (&gui_config->theme, g_free);
|
||||
g_clear_pointer (&gui_config->icon_theme_path, g_free);
|
||||
g_clear_pointer (&gui_config->icon_theme, g_free);
|
||||
g_clear_pointer (&gui_config->help_locales, g_free);
|
||||
g_clear_pointer (&gui_config->user_manual_online_uri, g_free);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
@@ -675,13 +692,11 @@ gimp_gui_config_set_property (GObject *object,
|
||||
case PROP_TOOLBOX_GROUPS:
|
||||
gui_config->toolbox_groups = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_THEME_PATH:
|
||||
g_free (gui_config->theme_path);
|
||||
gui_config->theme_path = g_value_dup_string (value);
|
||||
case PROP_THEME_PATH:
|
||||
g_set_str (&gui_config->theme_path, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_THEME:
|
||||
g_free (gui_config->theme);
|
||||
gui_config->theme = g_value_dup_string (value);
|
||||
g_set_str (&gui_config->theme, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_THEME_SCHEME:
|
||||
gui_config->theme_scheme = g_value_get_enum (value);
|
||||
@@ -692,13 +707,14 @@ gimp_gui_config_set_property (GObject *object,
|
||||
case PROP_CUSTOM_ICON_SIZE:
|
||||
gui_config->custom_icon_size = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_ICON_THEME_PATH:
|
||||
g_free (gui_config->icon_theme_path);
|
||||
gui_config->icon_theme_path = g_value_dup_string (value);
|
||||
case PROP_VIEWABLES_FOLLOW_THEME:
|
||||
gui_config->viewables_follow_theme = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_ICON_THEME_PATH:
|
||||
g_set_str (&gui_config->icon_theme_path, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_ICON_THEME:
|
||||
g_free (gui_config->icon_theme);
|
||||
gui_config->icon_theme = g_value_dup_string (value);
|
||||
g_set_str (&gui_config->icon_theme, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_PREFER_SYMBOLIC_ICONS:
|
||||
gui_config->prefer_symbolic_icons = g_value_get_boolean (value);
|
||||
@@ -713,8 +729,7 @@ gimp_gui_config_set_property (GObject *object,
|
||||
gui_config->show_help_button = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_HELP_LOCALES:
|
||||
g_free (gui_config->help_locales);
|
||||
gui_config->help_locales = g_value_dup_string (value);
|
||||
g_set_str (&gui_config->help_locales, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_HELP_BROWSER:
|
||||
gui_config->help_browser = g_value_get_enum (value);
|
||||
@@ -723,8 +738,7 @@ gimp_gui_config_set_property (GObject *object,
|
||||
gui_config->user_manual_online = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_USER_MANUAL_ONLINE_URI:
|
||||
g_free (gui_config->user_manual_online_uri);
|
||||
gui_config->user_manual_online_uri = g_value_dup_string (value);
|
||||
g_set_str (&gui_config->user_manual_online_uri, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_ACTION_HISTORY_SIZE:
|
||||
gui_config->action_history_size = g_value_get_int (value);
|
||||
@@ -748,6 +762,9 @@ gimp_gui_config_set_property (GObject *object,
|
||||
case PROP_PLAYGROUND_PAINT_SELECT_TOOL:
|
||||
gui_config->playground_paint_select_tool = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_PLAYGROUND_USE_LIST_BOX:
|
||||
gui_config->playground_use_list_box = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_HIDE_DOCKS:
|
||||
gui_config->hide_docks = g_value_get_boolean (value);
|
||||
@@ -874,6 +891,9 @@ gimp_gui_config_get_property (GObject *object,
|
||||
case PROP_CUSTOM_ICON_SIZE:
|
||||
g_value_set_enum (value, gui_config->custom_icon_size);
|
||||
break;
|
||||
case PROP_VIEWABLES_FOLLOW_THEME:
|
||||
g_value_set_boolean (value, gui_config->viewables_follow_theme);
|
||||
break;
|
||||
case PROP_ICON_THEME_PATH:
|
||||
g_value_set_string (value, gui_config->icon_theme_path);
|
||||
break;
|
||||
@@ -926,6 +946,9 @@ gimp_gui_config_get_property (GObject *object,
|
||||
case PROP_PLAYGROUND_PAINT_SELECT_TOOL:
|
||||
g_value_set_boolean (value, gui_config->playground_paint_select_tool);
|
||||
break;
|
||||
case PROP_PLAYGROUND_USE_LIST_BOX:
|
||||
g_value_set_boolean (value, gui_config->playground_use_list_box);
|
||||
break;
|
||||
|
||||
case PROP_HIDE_DOCKS:
|
||||
g_value_set_boolean (value, gui_config->hide_docks);
|
||||
|
@@ -70,6 +70,7 @@ struct _GimpGuiConfig
|
||||
gdouble font_relative_size;
|
||||
gboolean override_icon_size;
|
||||
GimpIconSize custom_icon_size;
|
||||
gboolean viewables_follow_theme;
|
||||
gboolean use_help;
|
||||
gboolean show_help_button;
|
||||
gchar *help_locales;
|
||||
@@ -86,6 +87,7 @@ struct _GimpGuiConfig
|
||||
gboolean playground_npd_tool;
|
||||
gboolean playground_seamless_clone_tool;
|
||||
gboolean playground_paint_select_tool;
|
||||
gboolean playground_use_list_box;
|
||||
|
||||
/* saved in sessionrc */
|
||||
gboolean hide_docks;
|
||||
|
@@ -130,11 +130,11 @@ gimp_plugin_config_finalize (GObject *object)
|
||||
{
|
||||
GimpPluginConfig *plugin_config = GIMP_PLUGIN_CONFIG (object);
|
||||
|
||||
g_free (plugin_config->fractalexplorer_path);
|
||||
g_free (plugin_config->gfig_path);
|
||||
g_free (plugin_config->gflare_path);
|
||||
g_free (plugin_config->gimpressionist_path);
|
||||
g_free (plugin_config->script_fu_path);
|
||||
g_clear_pointer (&plugin_config->fractalexplorer_path, g_free);
|
||||
g_clear_pointer (&plugin_config->gfig_path, g_free);
|
||||
g_clear_pointer (&plugin_config->gflare_path, g_free);
|
||||
g_clear_pointer (&plugin_config->gimpressionist_path, g_free);
|
||||
g_clear_pointer (&plugin_config->script_fu_path, g_free);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
@@ -150,28 +150,19 @@ gimp_plugin_config_set_property (GObject *object,
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_FRACTALEXPLORER_PATH:
|
||||
g_free (plugin_config->fractalexplorer_path);
|
||||
plugin_config->fractalexplorer_path = g_value_dup_string (value);
|
||||
g_set_str (&plugin_config->fractalexplorer_path, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_GFIG_PATH:
|
||||
g_free (plugin_config->gfig_path);
|
||||
plugin_config->gfig_path = g_value_dup_string (value);
|
||||
g_set_str (&plugin_config->gfig_path, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_GFLARE_PATH:
|
||||
g_free (plugin_config->gflare_path);
|
||||
plugin_config->gflare_path = g_value_dup_string (value);
|
||||
g_set_str (&plugin_config->gflare_path, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_GIMPRESSIONIST_PATH:
|
||||
g_free (plugin_config->gimpressionist_path);
|
||||
plugin_config->gimpressionist_path = g_value_dup_string (value);
|
||||
g_set_str (&plugin_config->gimpressionist_path, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_SCRIPT_FU_PATH:
|
||||
g_free (plugin_config->script_fu_path);
|
||||
plugin_config->script_fu_path = g_value_dup_string (value);
|
||||
g_set_str (&plugin_config->script_fu_path, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -193,19 +184,15 @@ gimp_plugin_config_get_property (GObject *object,
|
||||
case PROP_FRACTALEXPLORER_PATH:
|
||||
g_value_set_string (value, plugin_config->fractalexplorer_path);
|
||||
break;
|
||||
|
||||
case PROP_GFIG_PATH:
|
||||
g_value_set_string (value, plugin_config->gfig_path);
|
||||
break;
|
||||
|
||||
case PROP_GFLARE_PATH:
|
||||
g_value_set_string (value, plugin_config->gflare_path);
|
||||
break;
|
||||
|
||||
case PROP_GIMPRESSIONIST_PATH:
|
||||
g_value_set_string (value, plugin_config->gimpressionist_path);
|
||||
break;
|
||||
|
||||
case PROP_SCRIPT_FU_PATH:
|
||||
g_value_set_string (value, plugin_config->script_fu_path);
|
||||
break;
|
||||
|
@@ -512,6 +512,9 @@ _("Enable the Seamless Clone tool.")
|
||||
#define PLAYGROUND_PAINT_SELECT_TOOL_BLURB \
|
||||
_("Enable the Paint Select tool.")
|
||||
|
||||
#define PLAYGROUND_USE_LIST_BOX_BLURB \
|
||||
_("Use the new GtkListBox widget for simple lists.")
|
||||
|
||||
#define SPACE_BAR_ACTION_BLURB \
|
||||
_("What to do when the space bar is pressed in the image window.")
|
||||
|
||||
@@ -558,6 +561,9 @@ _("The name of the icon theme to use.")
|
||||
#define OVERRIDE_THEME_ICON_SIZE_BLURB \
|
||||
_("Override theme-set icon sizes.")
|
||||
|
||||
#define VIEWABLES_FOLLOW_THEME_BLURB \
|
||||
_("Use theme colors for preview")
|
||||
|
||||
#define ICON_SIZE_BLURB \
|
||||
_("The size of the icons to use.")
|
||||
|
||||
@@ -661,22 +667,22 @@ _("Sets the default channel name for the 'New Channel' dialog.")
|
||||
#define CHANNEL_NEW_COLOR_BLURB \
|
||||
_("Sets the default color and opacity for the 'New Channel' dialog.")
|
||||
|
||||
#define VECTORS_NEW_NAME_BLURB \
|
||||
#define PATH_NEW_NAME_BLURB \
|
||||
_("Sets the default path name for the 'New Path' dialog.")
|
||||
|
||||
#define VECTORS_EXPORT_PATH_BLURB \
|
||||
#define PATH_EXPORT_PATH_BLURB \
|
||||
_("Sets the default folder path for the 'Export Path' dialog.")
|
||||
|
||||
#define VECTORS_EXPORT_ACTIVE_ONLY_BLURB \
|
||||
#define PATH_EXPORT_ACTIVE_ONLY_BLURB \
|
||||
_("Sets the default 'Export the selected paths' state for the 'Export Path' dialog.")
|
||||
|
||||
#define VECTORS_IMPORT_PATH_BLURB \
|
||||
#define PATH_IMPORT_PATH_BLURB \
|
||||
_("Sets the default folder path for the 'Import Path' dialog.")
|
||||
|
||||
#define VECTORS_IMPORT_MERGE_BLURB \
|
||||
#define PATH_IMPORT_MERGE_BLURB \
|
||||
_("Sets the default 'Merge imported paths' state for the 'Import Path' dialog.")
|
||||
|
||||
#define VECTORS_IMPORT_SCALE_BLURB \
|
||||
#define PATH_IMPORT_SCALE_BLURB \
|
||||
_("Sets the default 'Scale imported paths to fit size' state for the 'Import Path' dialog.")
|
||||
|
||||
#define SELECTION_FEATHER_RADIUS_BLURB \
|
||||
|
@@ -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,
|
||||
],
|
||||
)
|
||||
|
||||
@@ -53,7 +53,7 @@ test('app-config',
|
||||
[ 'test-config.c', app_debug_files, ],
|
||||
|
||||
dependencies: [
|
||||
appstream_glib,
|
||||
appstream,
|
||||
libapp_dep,
|
||||
],
|
||||
link_with: [
|
||||
|
@@ -482,7 +482,7 @@ typedef enum /*< pdb-skip >*/
|
||||
|
||||
GType gimp_trc_type_get_type (void) G_GNUC_CONST;
|
||||
|
||||
typedef enum /*< pdb-skip >*/
|
||||
typedef enum
|
||||
{
|
||||
GIMP_TRC_LINEAR, /*< desc="Linear" >*/
|
||||
GIMP_TRC_NON_LINEAR, /*< desc="Non-Linear" >*/
|
||||
|
@@ -31,8 +31,6 @@
|
||||
#include "gimpbuffer.h"
|
||||
#include "gimpcontext.h"
|
||||
#include "gimpdrawable-edit.h"
|
||||
#include "gimpdrawable-filters.h"
|
||||
#include "gimpdrawablefilter.h"
|
||||
#include "gimperror.h"
|
||||
#include "gimpgrouplayer.h"
|
||||
#include "gimpimage.h"
|
||||
@@ -286,7 +284,6 @@ gimp_edit_copy (GimpImage *image,
|
||||
clip_image = gimp_image_new_from_drawables (image->gimp, drawables, TRUE, TRUE);
|
||||
gimp_container_remove (image->gimp->images, GIMP_OBJECT (clip_image));
|
||||
gimp_set_clipboard_image (image->gimp, clip_image);
|
||||
g_list_free (drawables);
|
||||
|
||||
clip_selection = gimp_image_get_mask (clip_image);
|
||||
if (! gimp_channel_is_empty (clip_selection))
|
||||
@@ -339,11 +336,6 @@ gimp_edit_copy (GimpImage *image,
|
||||
}
|
||||
g_list_free (all_items);
|
||||
|
||||
gimp_image_undo_disable (clip_image);
|
||||
gimp_image_resize_to_layers (clip_image, context, NULL, NULL, NULL,
|
||||
NULL, NULL);
|
||||
gimp_image_undo_enable (clip_image);
|
||||
|
||||
/* We need to store the original offsets before the image was
|
||||
* resized, in order to move it into the correct location for
|
||||
* in-place pasting.
|
||||
@@ -355,6 +347,42 @@ gimp_edit_copy (GimpImage *image,
|
||||
"gimp-edit-new-image-y",
|
||||
GINT_TO_POINTER (selection_bounds.y));
|
||||
}
|
||||
else
|
||||
{
|
||||
gint offset_x;
|
||||
gint offset_y;
|
||||
|
||||
/* We need to store the minimum offset from the selected layers
|
||||
* in order to move it into the correct location for
|
||||
* in-place pasting.
|
||||
*/
|
||||
gimp_item_get_offset (GIMP_ITEM (drawables->data), &offset_x, &offset_y);
|
||||
|
||||
for (iter = g_list_next (drawables); iter; iter = iter->next)
|
||||
{
|
||||
gint item_x;
|
||||
gint item_y;
|
||||
|
||||
gimp_item_get_offset (GIMP_ITEM (iter->data), &item_x, &item_y);
|
||||
|
||||
offset_x = MIN (item_x, offset_x);
|
||||
offset_y = MIN (item_y, offset_y);
|
||||
}
|
||||
|
||||
g_object_set_data (G_OBJECT (clip_image),
|
||||
"gimp-edit-new-image-x",
|
||||
GINT_TO_POINTER (offset_x));
|
||||
g_object_set_data (G_OBJECT (clip_image),
|
||||
"gimp-edit-new-image-y",
|
||||
GINT_TO_POINTER (offset_y));
|
||||
}
|
||||
g_list_free (drawables);
|
||||
|
||||
gimp_image_undo_disable (clip_image);
|
||||
gimp_image_resize_to_layers (clip_image, context, NULL, NULL, NULL,
|
||||
NULL, NULL);
|
||||
gimp_image_undo_enable (clip_image);
|
||||
|
||||
/* Remove selection from the clipboard image. */
|
||||
gimp_channel_clear (clip_selection, NULL, FALSE);
|
||||
g_object_unref (clip_image);
|
||||
@@ -506,38 +534,9 @@ gimp_edit_paste_get_tagged_layers (GimpImage *image,
|
||||
"gimp-image-copied-layer"));
|
||||
if (copied)
|
||||
{
|
||||
GimpContainer *filters;
|
||||
|
||||
layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (iter->data),
|
||||
image, layer_type));
|
||||
|
||||
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (iter->data));
|
||||
if (gimp_container_get_n_children (filters) > 0)
|
||||
{
|
||||
GList *filter_list;
|
||||
|
||||
for (filter_list = GIMP_LIST (filters)->queue->tail;
|
||||
filter_list;
|
||||
filter_list = g_list_previous (filter_list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (filter_list->data))
|
||||
{
|
||||
GimpDrawableFilter *old_filter = filter_list->data;
|
||||
GimpDrawableFilter *filter;
|
||||
|
||||
filter = gimp_drawable_filter_duplicate (GIMP_DRAWABLE (layer), old_filter);
|
||||
|
||||
if (filter != NULL)
|
||||
{
|
||||
gimp_drawable_filter_apply (filter, NULL);
|
||||
gimp_drawable_filter_commit (filter, TRUE, NULL, FALSE);
|
||||
|
||||
gimp_drawable_filter_layer_mask_freeze (filter);
|
||||
g_object_unref (filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
returned_layers = g_list_prepend (returned_layers, layer);
|
||||
|
||||
switch (paste_type)
|
||||
|
@@ -121,7 +121,10 @@ gimp_user_install_items[] =
|
||||
static gboolean user_install_detect_old (GimpUserInstall *install,
|
||||
const gchar *gimp_dir);
|
||||
static gchar * user_install_old_style_gimpdir (void);
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
static gchar * user_install_flatpak_gimpdir (gint minor);
|
||||
#endif
|
||||
|
||||
static void user_install_log (GimpUserInstall *install,
|
||||
const gchar *format,
|
||||
@@ -297,7 +300,7 @@ user_install_detect_old (GimpUserInstall *install,
|
||||
gint major;
|
||||
gint minor;
|
||||
|
||||
for (major = 3; major >= 2; major--)
|
||||
for (major = GIMP_MAJOR_VERSION; major >= 2; major--)
|
||||
{
|
||||
gint max_minor;
|
||||
|
||||
@@ -324,14 +327,14 @@ user_install_detect_old (GimpUserInstall *install,
|
||||
|
||||
if (migrate)
|
||||
{
|
||||
install->old_major = 2;
|
||||
install->old_major = major;
|
||||
install->old_minor = minor;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
if (minor == 10)
|
||||
if (major == 2 && minor == 10)
|
||||
{
|
||||
/* This is special-casing for GIMP 2.10 as flatpak where
|
||||
* we had this weird inconsistency: depending on whether a
|
||||
@@ -381,6 +384,8 @@ user_install_detect_old (GimpUserInstall *install,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (migrate)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,6 +451,7 @@ user_install_old_style_gimpdir (void)
|
||||
return gimp_dir;
|
||||
}
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
static gchar *
|
||||
user_install_flatpak_gimpdir (gint minor)
|
||||
{
|
||||
@@ -466,6 +472,7 @@ user_install_flatpak_gimpdir (gint minor)
|
||||
|
||||
return gimp_dir;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
user_install_log (GimpUserInstall *install,
|
||||
@@ -758,7 +765,7 @@ user_update_menurc_over20 (const GMatchInfo *matched_value,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gchar *
|
||||
static gchar *
|
||||
user_update_post_process_menurc_over20 (gpointer user_data)
|
||||
{
|
||||
GString *string = g_string_new (NULL);
|
||||
|
@@ -53,6 +53,7 @@
|
||||
#include "gimp-utils.h"
|
||||
#include "gimpasync.h"
|
||||
#include "gimpcontext.h"
|
||||
#include "gimpdata.h"
|
||||
#include "gimperror.h"
|
||||
#include "gimpimage.h"
|
||||
|
||||
@@ -933,6 +934,195 @@ gimp_data_input_stream_read_line_always (GDataInputStream *stream,
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_data_input_stream_read_char (GDataInputStream *input,
|
||||
gchar *value,
|
||||
GError **error)
|
||||
{
|
||||
gchar result;
|
||||
|
||||
result = g_data_input_stream_read_byte (input, NULL, error);
|
||||
if (error && *error)
|
||||
return FALSE;
|
||||
|
||||
*value = result;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_data_input_stream_read_short (GDataInputStream *input,
|
||||
gint16 *value,
|
||||
GError **error)
|
||||
{
|
||||
gint16 result;
|
||||
|
||||
result = g_data_input_stream_read_int16 (input, NULL, error);
|
||||
if (error && *error)
|
||||
return FALSE;
|
||||
|
||||
*value = result;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_data_input_stream_read_long (GDataInputStream *input,
|
||||
gint32 *value,
|
||||
GError **error)
|
||||
{
|
||||
gint32 result;
|
||||
|
||||
result = g_data_input_stream_read_int32 (input, NULL, error);
|
||||
if (error && *error)
|
||||
return FALSE;
|
||||
|
||||
*value = result;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_data_input_stream_read_ucs2_text (GDataInputStream *input,
|
||||
gchar **value,
|
||||
GError **error)
|
||||
{
|
||||
gchar *name_ucs2;
|
||||
gint32 pslen = 0;
|
||||
gint len;
|
||||
gint i;
|
||||
|
||||
/* two-bytes characters encoded (UCS-2)
|
||||
* format:
|
||||
* long : number of characters in string
|
||||
* data : zero terminated UCS-2 string
|
||||
*/
|
||||
|
||||
if (! gimp_data_input_stream_read_long (input, &pslen, error) || pslen <= 0)
|
||||
return FALSE;
|
||||
|
||||
len = 2 * pslen;
|
||||
|
||||
name_ucs2 = g_new (gchar, len);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
gchar mychar;
|
||||
|
||||
if (! gimp_data_input_stream_read_char (input, &mychar, error))
|
||||
{
|
||||
g_free (name_ucs2);
|
||||
return FALSE;
|
||||
}
|
||||
name_ucs2[i] = mychar;
|
||||
}
|
||||
|
||||
*value = g_convert (name_ucs2, len,
|
||||
"UTF-8", "UCS-2BE",
|
||||
NULL, NULL, NULL);
|
||||
|
||||
g_free (name_ucs2);
|
||||
|
||||
return (*value != NULL);
|
||||
}
|
||||
|
||||
/* Photoshop resource (brush, pattern) rle decode */
|
||||
gboolean
|
||||
gimp_data_input_stream_rle_decode (GDataInputStream *input,
|
||||
gchar *buffer,
|
||||
gsize buffer_size,
|
||||
gint32 height,
|
||||
GError **error)
|
||||
{
|
||||
gint i, j;
|
||||
gshort *cscanline_len = NULL;
|
||||
gchar *cdata = NULL;
|
||||
gchar *data = buffer;
|
||||
gboolean result;
|
||||
|
||||
/* read compressed size foreach scanline */
|
||||
cscanline_len = gegl_scratch_new (gshort, height);
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
result = gimp_data_input_stream_read_short (input, &cscanline_len[i], error);
|
||||
if (! result || cscanline_len[i] <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* unpack each scanline data */
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
gint len;
|
||||
gsize bytes_read;
|
||||
|
||||
len = cscanline_len[i];
|
||||
|
||||
cdata = gegl_scratch_alloc (len);
|
||||
|
||||
if (! g_input_stream_read_all (G_INPUT_STREAM (input),
|
||||
cdata, len,
|
||||
&bytes_read, NULL, error) ||
|
||||
bytes_read != len)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (j = 0; j < len;)
|
||||
{
|
||||
gint32 n = cdata[j++];
|
||||
|
||||
if (n >= 128) /* force sign */
|
||||
n -= 256;
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
/* copy the following char -n + 1 times */
|
||||
|
||||
if (n == -128) /* it's a nop */
|
||||
continue;
|
||||
|
||||
n = -n + 1;
|
||||
|
||||
if (j + 1 > len || (data - buffer) + n > buffer_size)
|
||||
goto err;
|
||||
|
||||
memset (data, cdata[j], n);
|
||||
|
||||
j += 1;
|
||||
data += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* read the following n + 1 chars (no compr) */
|
||||
|
||||
n = n + 1;
|
||||
|
||||
if (j + n > len || (data - buffer) + n > buffer_size)
|
||||
goto err;
|
||||
|
||||
memcpy (data, &cdata[j], n);
|
||||
|
||||
j += n;
|
||||
data += n;
|
||||
}
|
||||
}
|
||||
|
||||
g_clear_pointer (&cdata, gegl_scratch_free);
|
||||
}
|
||||
|
||||
g_clear_pointer (&cscanline_len, gegl_scratch_free);
|
||||
|
||||
return TRUE;
|
||||
|
||||
err:
|
||||
g_clear_pointer (&cdata, gegl_scratch_free);
|
||||
g_clear_pointer (&cscanline_len, gegl_scratch_free);
|
||||
if (error && ! *error)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in Photoshop resource file: "
|
||||
"RLE compressed data is corrupt."));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_ascii_strtoi (const gchar *nptr,
|
||||
gchar **endptr,
|
||||
|
@@ -98,6 +98,24 @@ gchar * gimp_data_input_stream_read_line_always
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean gimp_data_input_stream_read_char (GDataInputStream *input,
|
||||
gchar *value,
|
||||
GError **error);
|
||||
gboolean gimp_data_input_stream_read_short (GDataInputStream *input,
|
||||
gint16 *value,
|
||||
GError **error);
|
||||
gboolean gimp_data_input_stream_read_long (GDataInputStream *input,
|
||||
gint32 *value,
|
||||
GError **error);
|
||||
gboolean gimp_data_input_stream_read_ucs2_text (GDataInputStream *input,
|
||||
gchar **value,
|
||||
GError **error);
|
||||
gboolean gimp_data_input_stream_rle_decode (GDataInputStream *input,
|
||||
gchar *buffer,
|
||||
gsize buffer_size,
|
||||
gint32 height,
|
||||
GError **error);
|
||||
|
||||
gboolean gimp_ascii_strtoi (const gchar *nptr,
|
||||
gchar **endptr,
|
||||
gint base,
|
||||
|
@@ -254,9 +254,9 @@ gimp_init (Gimp *gimp)
|
||||
gimp->drawable_filter_table = gimp_id_table_new ();
|
||||
|
||||
gimp->displays = g_object_new (GIMP_TYPE_LIST,
|
||||
"children-type", GIMP_TYPE_OBJECT,
|
||||
"policy", GIMP_CONTAINER_POLICY_WEAK,
|
||||
"append", TRUE,
|
||||
"child-type", GIMP_TYPE_OBJECT,
|
||||
"policy", GIMP_CONTAINER_POLICY_WEAK,
|
||||
"append", TRUE,
|
||||
NULL);
|
||||
gimp_object_set_static_name (GIMP_OBJECT (gimp->displays), "displays");
|
||||
gimp->next_display_id = 1;
|
||||
@@ -268,15 +268,15 @@ gimp_init (Gimp *gimp)
|
||||
gimp_data_factories_init (gimp);
|
||||
|
||||
gimp->tool_info_list = g_object_new (GIMP_TYPE_LIST,
|
||||
"children-type", GIMP_TYPE_TOOL_INFO,
|
||||
"append", TRUE,
|
||||
"child-type", GIMP_TYPE_TOOL_INFO,
|
||||
"append", TRUE,
|
||||
NULL);
|
||||
gimp_object_set_static_name (GIMP_OBJECT (gimp->tool_info_list),
|
||||
"tool infos");
|
||||
|
||||
gimp->tool_item_list = g_object_new (GIMP_TYPE_LIST,
|
||||
"children-type", GIMP_TYPE_TOOL_ITEM,
|
||||
"append", TRUE,
|
||||
"child-type", GIMP_TYPE_TOOL_ITEM,
|
||||
"append", TRUE,
|
||||
NULL);
|
||||
gimp_object_set_static_name (GIMP_OBJECT (gimp->tool_item_list),
|
||||
"tool items");
|
||||
@@ -540,10 +540,6 @@ gimp_real_initialize (Gimp *gimp,
|
||||
|
||||
status_callback (_("Initialization"), NULL, 0.0);
|
||||
|
||||
/* set the last values used to default values */
|
||||
gimp->image_new_last_template =
|
||||
gimp_config_duplicate (GIMP_CONFIG (gimp->config->default_image));
|
||||
|
||||
/* add data objects that need the user context */
|
||||
gimp_data_factories_add_builtin (gimp);
|
||||
|
||||
@@ -1118,6 +1114,37 @@ gimp_get_tool_info (Gimp *gimp,
|
||||
return (GimpToolInfo *) info;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_set_last_template (Gimp *gimp,
|
||||
GimpTemplate *template)
|
||||
{
|
||||
GimpTemplate *last_template;
|
||||
|
||||
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
||||
g_return_if_fail (GIMP_IS_TEMPLATE (template));
|
||||
|
||||
last_template = gimp_get_last_template (gimp);
|
||||
|
||||
gimp_config_sync (G_OBJECT (template),
|
||||
G_OBJECT (last_template), 0);
|
||||
}
|
||||
|
||||
GimpTemplate *
|
||||
gimp_get_last_template (Gimp *gimp)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
|
||||
|
||||
if (! gimp->image_new_last_template)
|
||||
{
|
||||
/* set the last values used to default values */
|
||||
gimp->image_new_last_template =
|
||||
gimp_config_duplicate (GIMP_CONFIG (gimp->config->default_image));
|
||||
}
|
||||
|
||||
return gimp->image_new_last_template;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gimp_message:
|
||||
* @gimp: a pointer to the %Gimp object
|
||||
|
@@ -95,6 +95,8 @@ struct _Gimp
|
||||
|
||||
GList *image_windows;
|
||||
|
||||
GObject *controller_manager;
|
||||
|
||||
GimpImage *clipboard_image;
|
||||
GimpBuffer *clipboard_buffer;
|
||||
GimpContainer *named_buffers;
|
||||
@@ -225,6 +227,10 @@ GimpContext * gimp_get_user_context (Gimp *gimp);
|
||||
GimpToolInfo * gimp_get_tool_info (Gimp *gimp,
|
||||
const gchar *tool_name);
|
||||
|
||||
void gimp_set_last_template (Gimp *gimp,
|
||||
GimpTemplate *_template);
|
||||
GimpTemplate * gimp_get_last_template (Gimp *gimp);
|
||||
|
||||
void gimp_message (Gimp *gimp,
|
||||
GObject *handler,
|
||||
GimpMessageSeverity severity,
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include "gimpbrush-private.h"
|
||||
#include "gimppattern-header.h"
|
||||
#include "gimptempbuf.h"
|
||||
#include "gimp-utils.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
@@ -87,26 +88,11 @@ static GimpBrush * gimp_brush_load_abr_brush_v6 (GDataInputStream *input,
|
||||
gint index,
|
||||
GFile *file,
|
||||
GError **error);
|
||||
|
||||
static gchar abr_read_char (GDataInputStream *input,
|
||||
GError **error);
|
||||
static gint16 abr_read_short (GDataInputStream *input,
|
||||
GError **error);
|
||||
static gint32 abr_read_long (GDataInputStream *input,
|
||||
GError **error);
|
||||
static gchar * abr_read_ucs2_text (GDataInputStream *input,
|
||||
GError **error);
|
||||
static gboolean abr_supported (AbrHeader *abr_hdr,
|
||||
GError **error);
|
||||
static gboolean abr_reach_8bim_section (GDataInputStream *input,
|
||||
const gchar *name,
|
||||
GError **error);
|
||||
static gboolean abr_rle_decode (GDataInputStream *input,
|
||||
gchar *buffer,
|
||||
gsize buffer_size,
|
||||
gint32 height,
|
||||
GError **error);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
@@ -481,13 +467,11 @@ gimp_brush_load_abr (GimpContext *context,
|
||||
g_data_input_stream_set_byte_order (data_input,
|
||||
G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
|
||||
|
||||
abr_hdr.version = abr_read_short (data_input, &my_error);
|
||||
if (my_error)
|
||||
if (! gimp_data_input_stream_read_short (data_input, &abr_hdr.version, &my_error))
|
||||
goto done;
|
||||
|
||||
/* sub-version for ABR v6 */
|
||||
abr_hdr.count = abr_read_short (data_input, &my_error);
|
||||
if (my_error)
|
||||
if (! gimp_data_input_stream_read_short (data_input, &abr_hdr.count, &my_error))
|
||||
goto done;
|
||||
|
||||
if (abr_supported (&abr_hdr, &my_error))
|
||||
@@ -578,8 +562,7 @@ gimp_brush_load_abr_v6 (GDataInputStream *input,
|
||||
if (! abr_reach_8bim_section (input, "samp", error))
|
||||
return brush_list;
|
||||
|
||||
sample_section_size = abr_read_long (input, error);
|
||||
if (error && *error)
|
||||
if (! gimp_data_input_stream_read_long (input, &sample_section_size, error))
|
||||
return brush_list;
|
||||
|
||||
sample_section_end = (sample_section_size +
|
||||
@@ -623,12 +606,10 @@ gimp_brush_load_abr_brush_v12 (GDataInputStream *input,
|
||||
GimpBrush *brush = NULL;
|
||||
AbrBrushHeader abr_brush_hdr;
|
||||
|
||||
abr_brush_hdr.type = abr_read_short (input, error);
|
||||
if (error && *error)
|
||||
if (! gimp_data_input_stream_read_short (input, &abr_brush_hdr.type, error))
|
||||
return NULL;
|
||||
|
||||
abr_brush_hdr.size = abr_read_long (input, error);
|
||||
if (error && *error)
|
||||
if (! gimp_data_input_stream_read_long (input, &abr_brush_hdr.size, error))
|
||||
return NULL;
|
||||
|
||||
if (abr_brush_hdr.size < 0)
|
||||
@@ -668,43 +649,34 @@ gimp_brush_load_abr_brush_v12 (GDataInputStream *input,
|
||||
gchar *name;
|
||||
gchar *sample_name = NULL;
|
||||
gchar *tmp;
|
||||
gshort compress;
|
||||
gchar compress;
|
||||
|
||||
abr_sampled_brush_hdr.misc = abr_read_long (input, error);
|
||||
if (error && *error)
|
||||
break;
|
||||
|
||||
abr_sampled_brush_hdr.spacing = abr_read_short (input, error);
|
||||
if (error && *error)
|
||||
if (! gimp_data_input_stream_read_long (input, &abr_sampled_brush_hdr.misc, error) ||
|
||||
! gimp_data_input_stream_read_short (input, &abr_sampled_brush_hdr.spacing, error))
|
||||
break;
|
||||
|
||||
if (abr_hdr->version == 2)
|
||||
{
|
||||
sample_name = abr_read_ucs2_text (input, error);
|
||||
if (error && *error)
|
||||
if (! gimp_data_input_stream_read_ucs2_text (input, &sample_name, error))
|
||||
break;
|
||||
}
|
||||
|
||||
abr_sampled_brush_hdr.antialiasing = abr_read_char (input, error);
|
||||
if (error && *error)
|
||||
if (! gimp_data_input_stream_read_char (input, &abr_sampled_brush_hdr.antialiasing, error))
|
||||
break;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
abr_sampled_brush_hdr.bounds[i] = abr_read_short (input, error);
|
||||
if (error && *error)
|
||||
if (! gimp_data_input_stream_read_short (input, &abr_sampled_brush_hdr.bounds[i], error))
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
abr_sampled_brush_hdr.bounds_long[i] = abr_read_long (input, error);
|
||||
if (error && *error)
|
||||
if (! gimp_data_input_stream_read_long (input, &abr_sampled_brush_hdr.bounds_long[i], error))
|
||||
break;
|
||||
}
|
||||
|
||||
abr_sampled_brush_hdr.depth = abr_read_short (input, error);
|
||||
if (error && *error)
|
||||
if (! gimp_data_input_stream_read_short (input, &abr_sampled_brush_hdr.depth, error))
|
||||
break;
|
||||
|
||||
height = (abr_sampled_brush_hdr.bounds_long[2] -
|
||||
@@ -715,9 +687,9 @@ gimp_brush_load_abr_brush_v12 (GDataInputStream *input,
|
||||
|
||||
/* g_print ("width %i height %i bytes %i\n", width, height, bytes); */
|
||||
|
||||
if (width < 1 || width > 10000 ||
|
||||
height < 1 || height > 10000 ||
|
||||
bytes < 1 || bytes > 1 ||
|
||||
if (width < 1 || width > GIMP_BRUSH_MAX_SIZE ||
|
||||
height < 1 || height > GIMP_BRUSH_MAX_SIZE ||
|
||||
bytes < 1 || bytes > 1 ||
|
||||
G_MAXSIZE / width / height / bytes < 1)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
@@ -771,8 +743,7 @@ gimp_brush_load_abr_brush_v12 (GDataInputStream *input,
|
||||
mask = gimp_temp_buf_get_data (brush->priv->mask);
|
||||
size = width * height * bytes;
|
||||
|
||||
compress = abr_read_char (input, error);
|
||||
if (error && *error)
|
||||
if (! gimp_data_input_stream_read_char (input, &compress, error))
|
||||
{
|
||||
g_object_unref (brush);
|
||||
brush = NULL;
|
||||
@@ -800,7 +771,7 @@ gimp_brush_load_abr_brush_v12 (GDataInputStream *input,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! abr_rle_decode (input, (gchar *) mask, size, height, error))
|
||||
if (! gimp_data_input_stream_rle_decode (input, (gchar *) mask, size, height, error))
|
||||
{
|
||||
g_object_unref (brush);
|
||||
brush = NULL;
|
||||
@@ -846,8 +817,7 @@ gimp_brush_load_abr_brush_v6 (GDataInputStream *input,
|
||||
gchar *name;
|
||||
gboolean r;
|
||||
|
||||
brush_size = abr_read_long (input, error);
|
||||
if (error && *error)
|
||||
if (! gimp_data_input_stream_read_long (input, &brush_size, error))
|
||||
return NULL;
|
||||
|
||||
if (brush_size < 0)
|
||||
@@ -887,12 +857,13 @@ gimp_brush_load_abr_brush_v6 (GDataInputStream *input,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
top = abr_read_long (input, error); if (error && *error) return NULL;
|
||||
left = abr_read_long (input, error); if (error && *error) return NULL;
|
||||
bottom = abr_read_long (input, error); if (error && *error) return NULL;
|
||||
right = abr_read_long (input, error); if (error && *error) return NULL;
|
||||
depth = abr_read_short (input, error); if (error && *error) return NULL;
|
||||
compress = abr_read_char (input, error); if (error && *error) return NULL;
|
||||
if (! gimp_data_input_stream_read_long (input, &top, error) ||
|
||||
! gimp_data_input_stream_read_long (input, &left, error) ||
|
||||
! gimp_data_input_stream_read_long (input, &bottom, error) ||
|
||||
! gimp_data_input_stream_read_long (input, &right, error) ||
|
||||
! gimp_data_input_stream_read_short (input, &depth, error) ||
|
||||
! gimp_data_input_stream_read_char (input, &compress, error))
|
||||
return NULL;
|
||||
|
||||
depth = depth >> 3;
|
||||
|
||||
@@ -905,10 +876,10 @@ gimp_brush_load_abr_brush_v6 (GDataInputStream *input,
|
||||
width, height, depth, compress);
|
||||
#endif
|
||||
|
||||
if (width < 1 || width > 10000 ||
|
||||
height < 1 || height > 10000 ||
|
||||
(compress && depth != 1) ||
|
||||
(! compress && (depth < 1 || depth > 2)) ||
|
||||
if (width < 1 || width > GIMP_BRUSH_MAX_SIZE ||
|
||||
height < 1 || height > GIMP_BRUSH_MAX_SIZE ||
|
||||
(compress && depth != 1) ||
|
||||
(! compress && (depth < 1 || depth > 2)) ||
|
||||
G_MAXSIZE / width / height / depth < 1)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
@@ -994,7 +965,7 @@ gimp_brush_load_abr_brush_v6 (GDataInputStream *input,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! abr_rle_decode (input, (gchar *) mask, size, height, error))
|
||||
if (! gimp_data_input_stream_rle_decode (input, (gchar *) mask, size, height, error))
|
||||
{
|
||||
g_object_unref (brush);
|
||||
return NULL;
|
||||
@@ -1008,67 +979,6 @@ gimp_brush_load_abr_brush_v6 (GDataInputStream *input,
|
||||
return brush;
|
||||
}
|
||||
|
||||
static gchar
|
||||
abr_read_char (GDataInputStream *input,
|
||||
GError **error)
|
||||
{
|
||||
return g_data_input_stream_read_byte (input, NULL, error);
|
||||
}
|
||||
|
||||
static gint16
|
||||
abr_read_short (GDataInputStream *input,
|
||||
GError **error)
|
||||
{
|
||||
return g_data_input_stream_read_int16 (input, NULL, error);
|
||||
}
|
||||
|
||||
static gint32
|
||||
abr_read_long (GDataInputStream *input,
|
||||
GError **error)
|
||||
{
|
||||
return g_data_input_stream_read_int32 (input, NULL, error);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
abr_read_ucs2_text (GDataInputStream *input,
|
||||
GError **error)
|
||||
{
|
||||
gchar *name_ucs2;
|
||||
gchar *name_utf8;
|
||||
gint len;
|
||||
gint i;
|
||||
|
||||
/* two-bytes characters encoded (UCS-2)
|
||||
* format:
|
||||
* long : number of characters in string
|
||||
* data : zero terminated UCS-2 string
|
||||
*/
|
||||
|
||||
len = 2 * abr_read_long (input, error);
|
||||
if (len <= 0)
|
||||
return NULL;
|
||||
|
||||
name_ucs2 = g_new (gchar, len);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
name_ucs2[i] = abr_read_char (input, error);
|
||||
if (error && *error)
|
||||
{
|
||||
g_free (name_ucs2);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
name_utf8 = g_convert (name_ucs2, len,
|
||||
"UTF-8", "UCS-2BE",
|
||||
NULL, NULL, NULL);
|
||||
|
||||
g_free (name_ucs2);
|
||||
|
||||
return name_utf8;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
abr_supported (AbrHeader *abr_hdr,
|
||||
GError **error)
|
||||
@@ -1110,7 +1020,7 @@ abr_reach_8bim_section (GDataInputStream *input,
|
||||
{
|
||||
gchar tag[4];
|
||||
gchar tagname[5];
|
||||
guint32 section_size;
|
||||
gint32 section_size;
|
||||
gsize bytes_read;
|
||||
|
||||
if (! g_input_stream_read_all (G_INPUT_STREAM (input),
|
||||
@@ -1133,8 +1043,7 @@ abr_reach_8bim_section (GDataInputStream *input,
|
||||
if (! strncmp (tagname, name, 4))
|
||||
return TRUE;
|
||||
|
||||
section_size = abr_read_long (input, error);
|
||||
if (error && *error)
|
||||
if (! gimp_data_input_stream_read_long (input, §ion_size, error))
|
||||
return FALSE;
|
||||
|
||||
if (! g_seekable_seek (G_SEEKABLE (input), section_size, G_SEEK_CUR,
|
||||
@@ -1144,101 +1053,3 @@ abr_reach_8bim_section (GDataInputStream *input,
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
abr_rle_decode (GDataInputStream *input,
|
||||
gchar *buffer,
|
||||
gsize buffer_size,
|
||||
gint32 height,
|
||||
GError **error)
|
||||
{
|
||||
gint i, j;
|
||||
gshort *cscanline_len = NULL;
|
||||
gchar *cdata = NULL;
|
||||
gchar *data = buffer;
|
||||
|
||||
/* read compressed size foreach scanline */
|
||||
cscanline_len = gegl_scratch_new (gshort, height);
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
cscanline_len[i] = abr_read_short (input, error);
|
||||
if ((error && *error) || cscanline_len[i] <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* unpack each scanline data */
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
gint len;
|
||||
gsize bytes_read;
|
||||
|
||||
len = cscanline_len[i];
|
||||
|
||||
cdata = gegl_scratch_alloc (len);
|
||||
|
||||
if (! g_input_stream_read_all (G_INPUT_STREAM (input),
|
||||
cdata, len,
|
||||
&bytes_read, NULL, error) ||
|
||||
bytes_read != len)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (j = 0; j < len;)
|
||||
{
|
||||
gint32 n = cdata[j++];
|
||||
|
||||
if (n >= 128) /* force sign */
|
||||
n -= 256;
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
/* copy the following char -n + 1 times */
|
||||
|
||||
if (n == -128) /* it's a nop */
|
||||
continue;
|
||||
|
||||
n = -n + 1;
|
||||
|
||||
if (j + 1 > len || (data - buffer) + n > buffer_size)
|
||||
goto err;
|
||||
|
||||
memset (data, cdata[j], n);
|
||||
|
||||
j += 1;
|
||||
data += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* read the following n + 1 chars (no compr) */
|
||||
|
||||
n = n + 1;
|
||||
|
||||
if (j + n > len || (data - buffer) + n > buffer_size)
|
||||
goto err;
|
||||
|
||||
memcpy (data, &cdata[j], n);
|
||||
|
||||
j += n;
|
||||
data += n;
|
||||
}
|
||||
}
|
||||
|
||||
g_clear_pointer (&cdata, gegl_scratch_free);
|
||||
}
|
||||
|
||||
g_clear_pointer (&cscanline_len, gegl_scratch_free);
|
||||
|
||||
return TRUE;
|
||||
|
||||
err:
|
||||
g_clear_pointer (&cdata, gegl_scratch_free);
|
||||
g_clear_pointer (&cscanline_len, gegl_scratch_free);
|
||||
if (error && ! *error)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file: "
|
||||
"RLE compressed brush data corrupt."));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "core-types.h"
|
||||
|
||||
#include "gimp.h"
|
||||
#include "gimpbezierdesc.h"
|
||||
#include "gimpbrush.h"
|
||||
#include "gimpbrush-boundary.h"
|
||||
@@ -37,6 +38,7 @@
|
||||
#include "gimpbrushcache.h"
|
||||
#include "gimpbrushgenerated.h"
|
||||
#include "gimpbrushpipe.h"
|
||||
#include "gimpcontext.h"
|
||||
#include "gimptagged.h"
|
||||
#include "gimptempbuf.h"
|
||||
|
||||
@@ -77,7 +79,8 @@ static gboolean gimp_brush_get_size (GimpViewable *vie
|
||||
static GimpTempBuf * gimp_brush_get_new_preview (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height);
|
||||
gint height,
|
||||
GeglColor *fg_color);
|
||||
static gchar * gimp_brush_get_description (GimpViewable *viewable,
|
||||
gchar **tooltip);
|
||||
|
||||
@@ -131,6 +134,7 @@ gimp_brush_class_init (GimpBrushClass *klass)
|
||||
gimp_object_class->get_memsize = gimp_brush_get_memsize;
|
||||
|
||||
viewable_class->default_icon_name = "gimp-tool-paintbrush";
|
||||
viewable_class->default_name = _("Brush");
|
||||
viewable_class->get_size = gimp_brush_get_size;
|
||||
viewable_class->get_new_preview = gimp_brush_get_new_preview;
|
||||
viewable_class->get_description = gimp_brush_get_description;
|
||||
@@ -270,7 +274,8 @@ static GimpTempBuf *
|
||||
gimp_brush_get_new_preview (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height)
|
||||
gint height,
|
||||
GeglColor *fg_color)
|
||||
{
|
||||
GimpBrush *brush = GIMP_BRUSH (viewable);
|
||||
const GimpTempBuf *mask_buf = brush->priv->mask;
|
||||
@@ -366,13 +371,18 @@ gimp_brush_get_new_preview (GimpViewable *viewable,
|
||||
}
|
||||
else
|
||||
{
|
||||
guint8 rgb[3] = { 0, 0, 0 };
|
||||
|
||||
if (fg_color)
|
||||
gegl_color_get_pixel (fg_color, babl_format ("R'G'B' u8"), rgb);
|
||||
|
||||
for (y = 0; y < mask_height; y++)
|
||||
{
|
||||
for (x = 0; x < mask_width ; x++)
|
||||
{
|
||||
*buf++ = 0;
|
||||
*buf++ = 0;
|
||||
*buf++ = 0;
|
||||
*buf++ = rgb[0];
|
||||
*buf++ = rgb[1];
|
||||
*buf++ = rgb[2];
|
||||
*buf++ = *mask++;
|
||||
}
|
||||
}
|
||||
|
@@ -35,6 +35,8 @@
|
||||
#include "gimpimage.h"
|
||||
#include "gimptempbuf.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
static void gimp_color_managed_iface_init (GimpColorManagedInterface *iface);
|
||||
|
||||
@@ -61,11 +63,13 @@ static gboolean gimp_buffer_get_popup_size (GimpViewable *viewable,
|
||||
static GimpTempBuf * gimp_buffer_get_new_preview (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height);
|
||||
gint height,
|
||||
GeglColor *fg_color);
|
||||
static GdkPixbuf * gimp_buffer_get_new_pixbuf (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height);
|
||||
gint height,
|
||||
GeglColor *fg_color);
|
||||
static gchar * gimp_buffer_get_description (GimpViewable *viewable,
|
||||
gchar **tooltip);
|
||||
|
||||
@@ -97,6 +101,7 @@ gimp_buffer_class_init (GimpBufferClass *klass)
|
||||
gimp_object_class->get_memsize = gimp_buffer_get_memsize;
|
||||
|
||||
viewable_class->default_icon_name = "edit-paste";
|
||||
viewable_class->default_name = _("Buffer");
|
||||
viewable_class->name_editable = TRUE;
|
||||
viewable_class->get_size = gimp_buffer_get_size;
|
||||
viewable_class->get_preview_size = gimp_buffer_get_preview_size;
|
||||
@@ -224,7 +229,8 @@ static GimpTempBuf *
|
||||
gimp_buffer_get_new_preview (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height)
|
||||
gint height,
|
||||
GeglColor *fg_color G_GNUC_UNUSED)
|
||||
{
|
||||
GimpBuffer *buffer = GIMP_BUFFER (viewable);
|
||||
const Babl *format = gimp_buffer_get_format (buffer);
|
||||
@@ -258,7 +264,8 @@ static GdkPixbuf *
|
||||
gimp_buffer_get_new_pixbuf (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height)
|
||||
gint height,
|
||||
GeglColor *fg_color G_GNUC_UNUSED)
|
||||
{
|
||||
GimpBuffer *buffer = GIMP_BUFFER (viewable);
|
||||
GdkPixbuf *pixbuf;
|
||||
|
@@ -556,24 +556,28 @@ gimp_channel_combine_items (GimpChannel *mask,
|
||||
|
||||
if (g_list_length (layers) == 1)
|
||||
{
|
||||
GimpChannel *alpha;
|
||||
gint offset_x;
|
||||
gint offset_y;
|
||||
|
||||
if (gimp_drawable_has_alpha (layers->data))
|
||||
{
|
||||
GimpChannel *alpha;
|
||||
gint offset_x;
|
||||
gint offset_y;
|
||||
|
||||
alpha = gimp_channel_new_from_alpha (image,
|
||||
layers->data, NULL, NULL);
|
||||
gimp_item_get_offset (layers->data, &offset_x, &offset_y);
|
||||
gimp_channel_combine_mask (channel, alpha,
|
||||
GIMP_CHANNEL_OP_REPLACE,
|
||||
offset_x, offset_y);
|
||||
g_object_unref (alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_channel_all (channel, FALSE);
|
||||
alpha = gimp_channel_new (image,
|
||||
gimp_item_get_width (layers->data),
|
||||
gimp_item_get_height (layers->data),
|
||||
NULL, NULL);
|
||||
gimp_channel_all (alpha, FALSE);
|
||||
}
|
||||
gimp_item_get_offset (layers->data, &offset_x, &offset_y);
|
||||
gimp_channel_combine_mask (channel, alpha,
|
||||
GIMP_CHANNEL_OP_REPLACE,
|
||||
offset_x, offset_y);
|
||||
g_object_unref (alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -281,7 +281,7 @@ gimp_channel_select_polygon (GimpChannel *channel,
|
||||
void
|
||||
gimp_channel_select_path (GimpChannel *channel,
|
||||
const gchar *undo_desc,
|
||||
GimpPath *vectors,
|
||||
GimpPath *path,
|
||||
GimpChannelOps op,
|
||||
gboolean antialias,
|
||||
gboolean feather,
|
||||
@@ -294,9 +294,9 @@ gimp_channel_select_path (GimpChannel *channel,
|
||||
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
||||
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (channel)));
|
||||
g_return_if_fail (undo_desc != NULL);
|
||||
g_return_if_fail (GIMP_IS_PATH (vectors));
|
||||
g_return_if_fail (GIMP_IS_PATH (path));
|
||||
|
||||
bezier = gimp_path_get_bezier (vectors);
|
||||
bezier = gimp_path_get_bezier (path);
|
||||
|
||||
if (bezier && bezier->num_data > 4)
|
||||
{
|
||||
|
@@ -81,7 +81,7 @@ void gimp_channel_select_polygon (GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_select_path (GimpChannel *channel,
|
||||
const gchar *undo_desc,
|
||||
GimpPath *vectors,
|
||||
GimpPath *path,
|
||||
GimpChannelOps op,
|
||||
gboolean antialias,
|
||||
gboolean feather,
|
||||
|
@@ -236,8 +236,9 @@ gimp_channel_class_init (GimpChannelClass *klass)
|
||||
|
||||
gimp_object_class->get_memsize = gimp_channel_get_memsize;
|
||||
|
||||
viewable_class->get_description = gimp_channel_get_description;
|
||||
viewable_class->default_icon_name = "gimp-channel";
|
||||
viewable_class->default_name = _("Channel");
|
||||
viewable_class->get_description = gimp_channel_get_description;
|
||||
|
||||
filter_class->get_node = gimp_channel_get_node;
|
||||
|
||||
@@ -253,7 +254,6 @@ gimp_channel_class_init (GimpChannelClass *klass)
|
||||
item_class->fill = gimp_channel_fill;
|
||||
item_class->stroke = gimp_channel_stroke;
|
||||
item_class->to_selection = gimp_channel_to_selection;
|
||||
item_class->default_name = _("Channel");
|
||||
item_class->rename_desc = C_("undo-type", "Rename Channel");
|
||||
item_class->translate_desc = C_("undo-type", "Move Channel");
|
||||
item_class->scale_desc = C_("undo-type", "Scale Channel");
|
||||
@@ -315,6 +315,7 @@ gimp_channel_init (GimpChannel *channel)
|
||||
channel->num_segs_in = 0;
|
||||
channel->num_segs_out = 0;
|
||||
channel->empty = FALSE;
|
||||
channel->full = FALSE;
|
||||
channel->bounds_known = FALSE;
|
||||
channel->x1 = 0;
|
||||
channel->y1 = 0;
|
||||
@@ -469,7 +470,7 @@ gimp_channel_bounds (GimpItem *item,
|
||||
&channel->y1,
|
||||
&channel->x2,
|
||||
&channel->y2);
|
||||
|
||||
channel->full = FALSE;
|
||||
channel->bounds_known = TRUE;
|
||||
}
|
||||
|
||||
@@ -503,6 +504,7 @@ gimp_channel_duplicate (GimpItem *item,
|
||||
/* selection mask variables */
|
||||
new_channel->bounds_known = channel->bounds_known;
|
||||
new_channel->empty = channel->empty;
|
||||
new_channel->full = channel->full;
|
||||
new_channel->x1 = channel->x1;
|
||||
new_channel->y1 = channel->y1;
|
||||
new_channel->x2 = channel->x2;
|
||||
@@ -706,8 +708,8 @@ gimp_channel_scale (GimpItem *item,
|
||||
new_offset_y = 0;
|
||||
}
|
||||
|
||||
/* don't waste CPU cycles scaling an empty channel */
|
||||
if (channel->bounds_known && channel->empty)
|
||||
/* don't waste CPU cycles scaling an empty or full channel */
|
||||
if (channel->bounds_known && (channel->empty || channel->full))
|
||||
{
|
||||
GimpDrawable *drawable = GIMP_DRAWABLE (item);
|
||||
GeglBuffer *new_buffer;
|
||||
@@ -724,7 +726,10 @@ gimp_channel_scale (GimpItem *item,
|
||||
TRUE);
|
||||
g_object_unref (new_buffer);
|
||||
|
||||
gimp_channel_clear (GIMP_CHANNEL (item), NULL, FALSE);
|
||||
if (channel->empty)
|
||||
gimp_channel_clear (GIMP_CHANNEL (item), NULL, FALSE);
|
||||
else
|
||||
gimp_channel_all (GIMP_CHANNEL (item), FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1105,6 +1110,7 @@ gimp_channel_real_is_empty (GimpChannel *channel)
|
||||
g_clear_pointer (&channel->segs_out, g_free);
|
||||
|
||||
channel->empty = TRUE;
|
||||
channel->full = FALSE;
|
||||
channel->num_segs_in = 0;
|
||||
channel->num_segs_out = 0;
|
||||
channel->bounds_known = TRUE;
|
||||
@@ -1120,11 +1126,10 @@ gimp_channel_real_is_empty (GimpChannel *channel)
|
||||
static gboolean
|
||||
gimp_channel_real_is_full (GimpChannel *channel)
|
||||
{
|
||||
return ! gimp_channel_is_empty (channel) &&
|
||||
channel->x1 == 0 &&
|
||||
channel->y1 == 0 &&
|
||||
channel->x2 == gimp_item_get_width (GIMP_ITEM (channel)) &&
|
||||
channel->y2 == gimp_item_get_height (GIMP_ITEM (channel));
|
||||
if (channel->bounds_known)
|
||||
return channel->full;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1232,6 +1237,7 @@ gimp_channel_real_clear (GimpChannel *channel,
|
||||
/* we know the bounds */
|
||||
channel->bounds_known = TRUE;
|
||||
channel->empty = TRUE;
|
||||
channel->full = FALSE;
|
||||
channel->x1 = 0;
|
||||
channel->y1 = 0;
|
||||
channel->x2 = gimp_item_get_width (GIMP_ITEM (channel));
|
||||
@@ -1260,6 +1266,7 @@ gimp_channel_real_all (GimpChannel *channel,
|
||||
/* we know the bounds */
|
||||
channel->bounds_known = TRUE;
|
||||
channel->empty = FALSE;
|
||||
channel->full = TRUE;
|
||||
channel->x1 = 0;
|
||||
channel->y1 = 0;
|
||||
channel->x2 = gimp_item_get_width (GIMP_ITEM (channel));
|
||||
@@ -1282,6 +1289,10 @@ gimp_channel_real_invert (GimpChannel *channel,
|
||||
{
|
||||
gimp_channel_all (channel, FALSE);
|
||||
}
|
||||
else if (channel->bounds_known && channel->full)
|
||||
{
|
||||
gimp_channel_clear (channel, NULL, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_gegl_apply_invert_linear (gimp_drawable_get_buffer (drawable),
|
||||
@@ -1389,7 +1400,8 @@ gimp_channel_real_grow (GimpChannel *channel,
|
||||
x2 += x1;
|
||||
y2 += y1;
|
||||
|
||||
if (gimp_channel_is_empty (channel))
|
||||
if (gimp_channel_is_empty (channel) ||
|
||||
gimp_channel_is_full (channel))
|
||||
return;
|
||||
|
||||
if (x1 - radius_x > 0)
|
||||
@@ -1486,7 +1498,8 @@ gimp_channel_real_flood (GimpChannel *channel,
|
||||
if (! gimp_item_bounds (GIMP_ITEM (channel), &x, &y, &width, &height))
|
||||
return;
|
||||
|
||||
if (gimp_channel_is_empty (channel))
|
||||
if (gimp_channel_is_empty (channel) ||
|
||||
gimp_channel_is_full (channel))
|
||||
return;
|
||||
|
||||
if (push_undo)
|
||||
|
@@ -50,6 +50,7 @@ struct _GimpChannel
|
||||
gint num_segs_in; /* number of lines in boundary */
|
||||
gint num_segs_out; /* number of lines in boundary */
|
||||
gboolean empty; /* is the region empty? */
|
||||
gboolean full; /* is the region completely full? */
|
||||
gboolean bounds_known; /* recalculate the bounds? */
|
||||
gint x1, y1; /* coordinates for bounding box */
|
||||
gint x2, y2; /* lower right hand coordinate */
|
||||
|
@@ -71,8 +71,8 @@ gimp_container_filter (GimpContainer *container,
|
||||
|
||||
result =
|
||||
g_object_new (G_TYPE_FROM_INSTANCE (container),
|
||||
"children-type", gimp_container_get_children_type (container),
|
||||
"policy", GIMP_CONTAINER_POLICY_WEAK,
|
||||
"child-type", gimp_container_get_child_type (container),
|
||||
"policy", GIMP_CONTAINER_POLICY_WEAK,
|
||||
NULL);
|
||||
|
||||
context.filter = filter;
|
||||
|
@@ -56,7 +56,7 @@ enum
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_CHILDREN_TYPE,
|
||||
PROP_CHILD_TYPE,
|
||||
PROP_POLICY
|
||||
};
|
||||
|
||||
@@ -72,18 +72,21 @@ typedef struct
|
||||
|
||||
struct _GimpContainerPrivate
|
||||
{
|
||||
GType children_type;
|
||||
GType child_type;
|
||||
GimpContainerPolicy policy;
|
||||
gint n_children;
|
||||
|
||||
GList *handlers;
|
||||
gint freeze_count;
|
||||
gint n_children_before_freeze;
|
||||
gint suspend_items_changed;
|
||||
};
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static void gimp_container_config_iface_init (GimpConfigInterface *iface);
|
||||
static void gimp_container_list_model_iface_init (GListModelInterface *iface);
|
||||
static void gimp_container_config_iface_init (GimpConfigInterface *iface);
|
||||
|
||||
static void gimp_container_dispose (GObject *object);
|
||||
|
||||
@@ -103,6 +106,15 @@ static void gimp_container_real_add (GimpContainer *container,
|
||||
GimpObject *object);
|
||||
static void gimp_container_real_remove (GimpContainer *container,
|
||||
GimpObject *object);
|
||||
static void gimp_container_real_reorder (GimpContainer *container,
|
||||
GimpObject *object,
|
||||
gint old_index,
|
||||
gint new_index);
|
||||
|
||||
static GType gimp_container_get_item_type (GListModel *list);
|
||||
static guint gimp_container_get_n_items (GListModel *list);
|
||||
static gpointer gimp_container_get_item (GListModel *list,
|
||||
guint index);
|
||||
|
||||
static gboolean gimp_container_serialize (GimpConfig *config,
|
||||
GimpConfigWriter *writer,
|
||||
@@ -121,6 +133,8 @@ static void gimp_container_free_handler (GimpContainer *container,
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GimpContainer, gimp_container, GIMP_TYPE_OBJECT,
|
||||
G_ADD_PRIVATE (GimpContainer)
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
|
||||
gimp_container_list_model_iface_init)
|
||||
G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG,
|
||||
gimp_container_config_iface_init))
|
||||
|
||||
@@ -159,9 +173,10 @@ gimp_container_class_init (GimpContainerClass *klass)
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GimpContainerClass, reorder),
|
||||
NULL, NULL,
|
||||
gimp_marshal_VOID__OBJECT_INT,
|
||||
G_TYPE_NONE, 2,
|
||||
gimp_marshal_VOID__OBJECT_INT_INT,
|
||||
G_TYPE_NONE, 3,
|
||||
GIMP_TYPE_OBJECT,
|
||||
G_TYPE_INT,
|
||||
G_TYPE_INT);
|
||||
|
||||
container_signals[FREEZE] =
|
||||
@@ -188,7 +203,7 @@ gimp_container_class_init (GimpContainerClass *klass)
|
||||
|
||||
klass->add = gimp_container_real_add;
|
||||
klass->remove = gimp_container_real_remove;
|
||||
klass->reorder = NULL;
|
||||
klass->reorder = gimp_container_real_reorder;
|
||||
klass->freeze = NULL;
|
||||
klass->thaw = NULL;
|
||||
|
||||
@@ -202,8 +217,8 @@ gimp_container_class_init (GimpContainerClass *klass)
|
||||
klass->get_child_by_index = NULL;
|
||||
klass->get_child_index = NULL;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_CHILDREN_TYPE,
|
||||
g_param_spec_gtype ("children-type",
|
||||
g_object_class_install_property (object_class, PROP_CHILD_TYPE,
|
||||
g_param_spec_gtype ("child-type",
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_OBJECT,
|
||||
GIMP_PARAM_READWRITE |
|
||||
@@ -218,6 +233,14 @@ gimp_container_class_init (GimpContainerClass *klass)
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_container_list_model_iface_init (GListModelInterface *iface)
|
||||
{
|
||||
iface->get_item_type = gimp_container_get_item_type;
|
||||
iface->get_n_items = gimp_container_get_n_items;
|
||||
iface->get_item = gimp_container_get_item;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_container_config_iface_init (GimpConfigInterface *iface)
|
||||
{
|
||||
@@ -229,12 +252,13 @@ static void
|
||||
gimp_container_init (GimpContainer *container)
|
||||
{
|
||||
container->priv = gimp_container_get_instance_private (container);
|
||||
container->priv->handlers = NULL;
|
||||
container->priv->freeze_count = 0;
|
||||
|
||||
container->priv->children_type = G_TYPE_NONE;
|
||||
container->priv->policy = GIMP_CONTAINER_POLICY_STRONG;
|
||||
container->priv->n_children = 0;
|
||||
container->priv->handlers = NULL;
|
||||
container->priv->freeze_count = 0;
|
||||
|
||||
container->priv->child_type = G_TYPE_NONE;
|
||||
container->priv->policy = GIMP_CONTAINER_POLICY_STRONG;
|
||||
container->priv->n_children = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -249,10 +273,10 @@ gimp_container_dispose (GObject *object)
|
||||
((GimpContainerHandler *)
|
||||
container->priv->handlers->data)->quark);
|
||||
|
||||
if (container->priv->children_type != G_TYPE_NONE)
|
||||
if (container->priv->child_type != G_TYPE_NONE)
|
||||
{
|
||||
g_type_class_unref (g_type_class_peek (container->priv->children_type));
|
||||
container->priv->children_type = G_TYPE_NONE;
|
||||
g_type_class_unref (g_type_class_peek (container->priv->child_type));
|
||||
container->priv->child_type = G_TYPE_NONE;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
@@ -268,9 +292,9 @@ gimp_container_set_property (GObject *object,
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_CHILDREN_TYPE:
|
||||
container->priv->children_type = g_value_get_gtype (value);
|
||||
g_type_class_ref (container->priv->children_type);
|
||||
case PROP_CHILD_TYPE:
|
||||
container->priv->child_type = g_value_get_gtype (value);
|
||||
g_type_class_ref (container->priv->child_type);
|
||||
break;
|
||||
case PROP_POLICY:
|
||||
container->priv->policy = g_value_get_enum (value);
|
||||
@@ -291,8 +315,8 @@ gimp_container_get_property (GObject *object,
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_CHILDREN_TYPE:
|
||||
g_value_set_gtype (value, container->priv->children_type);
|
||||
case PROP_CHILD_TYPE:
|
||||
g_value_set_gtype (value, container->priv->child_type);
|
||||
break;
|
||||
case PROP_POLICY:
|
||||
g_value_set_enum (value, container->priv->policy);
|
||||
@@ -338,6 +362,43 @@ gimp_container_real_remove (GimpContainer *container,
|
||||
container->priv->n_children--;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_container_real_reorder (GimpContainer *container,
|
||||
GimpObject *object,
|
||||
gint old_index,
|
||||
gint new_index)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* GListModel functions */
|
||||
|
||||
static GType
|
||||
gimp_container_get_item_type (GListModel *list)
|
||||
{
|
||||
return gimp_container_get_child_type (GIMP_CONTAINER (list));
|
||||
}
|
||||
|
||||
static guint
|
||||
gimp_container_get_n_items (GListModel *list)
|
||||
{
|
||||
return gimp_container_get_n_children (GIMP_CONTAINER (list));
|
||||
}
|
||||
|
||||
static void *
|
||||
gimp_container_get_item (GListModel *list,
|
||||
guint index)
|
||||
{
|
||||
GimpContainer *self = GIMP_CONTAINER (list);
|
||||
|
||||
if (index >= gimp_container_get_n_children (self))
|
||||
return NULL;
|
||||
|
||||
return g_object_ref (gimp_container_get_child_by_index (self, index));
|
||||
}
|
||||
|
||||
|
||||
/* GimpConfig functions */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -434,12 +495,12 @@ gimp_container_deserialize (GimpConfig *config,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (! g_type_is_a (type, container->priv->children_type))
|
||||
if (! g_type_is_a (type, container->priv->child_type))
|
||||
{
|
||||
g_scanner_error (scanner,
|
||||
"'%s' is not a subclass of '%s'",
|
||||
scanner->value.v_identifier,
|
||||
g_type_name (container->priv->children_type));
|
||||
g_type_name (container->priv->child_type));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -555,11 +616,11 @@ gimp_container_free_handler (GimpContainer *container,
|
||||
}
|
||||
|
||||
GType
|
||||
gimp_container_get_children_type (GimpContainer *container)
|
||||
gimp_container_get_child_type (GimpContainer *container)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_CONTAINER (container), G_TYPE_NONE);
|
||||
|
||||
return container->priv->children_type;
|
||||
return container->priv->child_type;
|
||||
}
|
||||
|
||||
GimpContainerPolicy
|
||||
@@ -588,7 +649,7 @@ gimp_container_add (GimpContainer *container,
|
||||
g_return_val_if_fail (GIMP_IS_CONTAINER (container), FALSE);
|
||||
g_return_val_if_fail (object != NULL, FALSE);
|
||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (object,
|
||||
container->priv->children_type),
|
||||
container->priv->child_type),
|
||||
FALSE);
|
||||
|
||||
if (gimp_container_have (container, object))
|
||||
@@ -638,6 +699,14 @@ gimp_container_add (GimpContainer *container,
|
||||
container->priv->n_children++;
|
||||
}
|
||||
|
||||
if (container->priv->freeze_count == 0 &&
|
||||
container->priv->suspend_items_changed == 0)
|
||||
{
|
||||
gint index = gimp_container_get_child_index (container, object);
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (container), index, 0, 1);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -647,11 +716,12 @@ gimp_container_remove (GimpContainer *container,
|
||||
{
|
||||
GList *list;
|
||||
gint n_children;
|
||||
gint index;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_CONTAINER (container), FALSE);
|
||||
g_return_val_if_fail (object != NULL, FALSE);
|
||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (object,
|
||||
container->priv->children_type),
|
||||
container->priv->child_type),
|
||||
FALSE);
|
||||
|
||||
if (! gimp_container_have (container, object))
|
||||
@@ -678,6 +748,7 @@ gimp_container_remove (GimpContainer *container,
|
||||
}
|
||||
|
||||
n_children = container->priv->n_children;
|
||||
index = gimp_container_get_child_index (container, object);
|
||||
|
||||
g_signal_emit (container, container_signals[REMOVE], 0, object);
|
||||
|
||||
@@ -703,6 +774,12 @@ gimp_container_remove (GimpContainer *container,
|
||||
break;
|
||||
}
|
||||
|
||||
if (container->priv->freeze_count == 0 &&
|
||||
container->priv->suspend_items_changed == 0)
|
||||
{
|
||||
g_list_model_items_changed (G_LIST_MODEL (container), index, 1, 0);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -711,10 +788,12 @@ gimp_container_insert (GimpContainer *container,
|
||||
GimpObject *object,
|
||||
gint index)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_CONTAINER (container), FALSE);
|
||||
g_return_val_if_fail (object != NULL, FALSE);
|
||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (object,
|
||||
container->priv->children_type),
|
||||
container->priv->child_type),
|
||||
FALSE);
|
||||
|
||||
g_return_val_if_fail (index >= -1 &&
|
||||
@@ -727,12 +806,30 @@ gimp_container_insert (GimpContainer *container,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
container->priv->suspend_items_changed++;
|
||||
|
||||
if (gimp_container_add (container, object))
|
||||
{
|
||||
return gimp_container_reorder (container, object, index);
|
||||
/* set success to TRUE even if reorder() fails, because the
|
||||
* object has in fact been added
|
||||
*/
|
||||
success = TRUE;
|
||||
|
||||
gimp_container_reorder (container, object, index);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
container->priv->suspend_items_changed--;
|
||||
|
||||
if (success &&
|
||||
container->priv->freeze_count == 0 &&
|
||||
container->priv->suspend_items_changed == 0)
|
||||
{
|
||||
gint index = gimp_container_get_child_index (container, object);
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (container), index, 0, 1);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -740,12 +837,12 @@ gimp_container_reorder (GimpContainer *container,
|
||||
GimpObject *object,
|
||||
gint new_index)
|
||||
{
|
||||
gint index;
|
||||
gint old_index;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_CONTAINER (container), FALSE);
|
||||
g_return_val_if_fail (object != NULL, FALSE);
|
||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (object,
|
||||
container->priv->children_type),
|
||||
container->priv->child_type),
|
||||
FALSE);
|
||||
|
||||
g_return_val_if_fail (new_index >= -1 &&
|
||||
@@ -754,18 +851,31 @@ gimp_container_reorder (GimpContainer *container,
|
||||
if (new_index == -1)
|
||||
new_index = container->priv->n_children - 1;
|
||||
|
||||
index = gimp_container_get_child_index (container, object);
|
||||
old_index = gimp_container_get_child_index (container, object);
|
||||
|
||||
if (index == -1)
|
||||
if (old_index == -1)
|
||||
{
|
||||
g_warning ("%s: container %p does not contain object %p",
|
||||
G_STRFUNC, container, object);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (index != new_index)
|
||||
g_signal_emit (container, container_signals[REORDER], 0,
|
||||
object, new_index);
|
||||
if (old_index != new_index)
|
||||
{
|
||||
g_signal_emit (container, container_signals[REORDER], 0,
|
||||
object, old_index, new_index);
|
||||
|
||||
if (container->priv->freeze_count == 0 &&
|
||||
container->priv->suspend_items_changed == 0)
|
||||
{
|
||||
gint new_index = gimp_container_get_child_index (container, object);
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (container),
|
||||
MIN (old_index, new_index),
|
||||
ABS (old_index - new_index) + 1,
|
||||
ABS (old_index - new_index) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -778,19 +888,30 @@ gimp_container_freeze (GimpContainer *container)
|
||||
container->priv->freeze_count++;
|
||||
|
||||
if (container->priv->freeze_count == 1)
|
||||
g_signal_emit (container, container_signals[FREEZE], 0);
|
||||
{
|
||||
container->priv->n_children_before_freeze = container->priv->n_children;
|
||||
|
||||
g_signal_emit (container, container_signals[FREEZE], 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimp_container_thaw (GimpContainer *container)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_CONTAINER (container));
|
||||
g_return_if_fail (container->priv->freeze_count > 0);
|
||||
|
||||
if (container->priv->freeze_count > 0)
|
||||
container->priv->freeze_count--;
|
||||
container->priv->freeze_count--;
|
||||
|
||||
if (container->priv->freeze_count == 0)
|
||||
g_signal_emit (container, container_signals[THAW], 0);
|
||||
{
|
||||
g_list_model_items_changed (G_LIST_MODEL (container), 0,
|
||||
container->priv->n_children_before_freeze,
|
||||
container->priv->n_children);
|
||||
container->priv->n_children_before_freeze = 0;
|
||||
|
||||
g_signal_emit (container, container_signals[THAW], 0);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -981,7 +1102,7 @@ gimp_container_get_child_index (GimpContainer *container,
|
||||
g_return_val_if_fail (GIMP_IS_CONTAINER (container), -1);
|
||||
g_return_val_if_fail (object != NULL, -1);
|
||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (object,
|
||||
container->priv->children_type),
|
||||
container->priv->child_type),
|
||||
-1);
|
||||
|
||||
return GIMP_CONTAINER_GET_CLASS (container)->get_child_index (container,
|
||||
@@ -1076,7 +1197,7 @@ gimp_container_add_handler (GimpContainer *container,
|
||||
|
||||
if (! g_str_has_prefix (signame, "notify::"))
|
||||
g_return_val_if_fail (g_signal_lookup (signame,
|
||||
container->priv->children_type), 0);
|
||||
container->priv->child_type), 0);
|
||||
|
||||
handler = g_slice_new0 (GimpContainerHandler);
|
||||
|
||||
@@ -1154,8 +1275,8 @@ gimp_container_remove_handlers_by_func (GimpContainer *container,
|
||||
{
|
||||
gimp_container_free_handler (container, handler);
|
||||
|
||||
container->priv->handlers = g_list_delete_link (
|
||||
container->priv->handlers, list);
|
||||
container->priv->handlers =
|
||||
g_list_delete_link (container->priv->handlers, list);
|
||||
}
|
||||
|
||||
list = next;
|
||||
@@ -1181,8 +1302,8 @@ gimp_container_remove_handlers_by_data (GimpContainer *container,
|
||||
{
|
||||
gimp_container_free_handler (container, handler);
|
||||
|
||||
container->priv->handlers = g_list_delete_link (
|
||||
container->priv->handlers, list);
|
||||
container->priv->handlers =
|
||||
g_list_delete_link (container->priv->handlers, list);
|
||||
}
|
||||
|
||||
list = next;
|
||||
|
@@ -58,6 +58,7 @@ struct _GimpContainerClass
|
||||
GimpObject *object);
|
||||
void (* reorder) (GimpContainer *container,
|
||||
GimpObject *object,
|
||||
gint old_index,
|
||||
gint new_index);
|
||||
void (* freeze) (GimpContainer *container);
|
||||
void (* thaw) (GimpContainer *container);
|
||||
@@ -86,7 +87,7 @@ struct _GimpContainerClass
|
||||
|
||||
GType gimp_container_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GType gimp_container_get_children_type (GimpContainer *container);
|
||||
GType gimp_container_get_child_type (GimpContainer *container);
|
||||
GimpContainerPolicy gimp_container_get_policy (GimpContainer *container);
|
||||
gint gimp_container_get_n_children (GimpContainer *container);
|
||||
|
||||
@@ -149,5 +150,7 @@ void gimp_container_remove_handlers_by_data
|
||||
(GimpContainer *container,
|
||||
gpointer callback_data);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GimpContainer, g_object_unref);
|
||||
|
||||
|
||||
#endif /* __GIMP_CONTAINER_H__ */
|
||||
|
@@ -2296,8 +2296,7 @@ static void
|
||||
gimp_context_paint_info_dirty (GimpPaintInfo *paint_info,
|
||||
GimpContext *context)
|
||||
{
|
||||
g_free (context->paint_name);
|
||||
context->paint_name = g_strdup (gimp_object_get_name (paint_info));
|
||||
g_set_str (&context->paint_name, gimp_object_get_name (paint_info));
|
||||
|
||||
g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
|
||||
GIMP_CONTEXT_PROP_PAINT_INFO);
|
||||
@@ -2646,8 +2645,7 @@ static void
|
||||
gimp_context_brush_dirty (GimpBrush *brush,
|
||||
GimpContext *context)
|
||||
{
|
||||
g_free (context->brush_name);
|
||||
context->brush_name = g_strdup (gimp_object_get_name (brush));
|
||||
g_set_str (&context->brush_name, gimp_object_get_name (brush));
|
||||
|
||||
g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
|
||||
GIMP_CONTEXT_PROP_BRUSH);
|
||||
@@ -2760,8 +2758,7 @@ static void
|
||||
gimp_context_dynamics_dirty (GimpDynamics *dynamics,
|
||||
GimpContext *context)
|
||||
{
|
||||
g_free (context->dynamics_name);
|
||||
context->dynamics_name = g_strdup (gimp_object_get_name (dynamics));
|
||||
g_set_str (&context->dynamics_name, gimp_object_get_name (dynamics));
|
||||
|
||||
g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
|
||||
GIMP_CONTEXT_PROP_DYNAMICS);
|
||||
@@ -2873,8 +2870,7 @@ static void
|
||||
gimp_context_mybrush_dirty (GimpMybrush *brush,
|
||||
GimpContext *context)
|
||||
{
|
||||
g_free (context->mybrush_name);
|
||||
context->mybrush_name = g_strdup (gimp_object_get_name (brush));
|
||||
g_set_str (&context->mybrush_name, gimp_object_get_name (brush));
|
||||
|
||||
g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
|
||||
GIMP_CONTEXT_PROP_MYBRUSH);
|
||||
@@ -2986,8 +2982,7 @@ static void
|
||||
gimp_context_pattern_dirty (GimpPattern *pattern,
|
||||
GimpContext *context)
|
||||
{
|
||||
g_free (context->pattern_name);
|
||||
context->pattern_name = g_strdup (gimp_object_get_name (pattern));
|
||||
g_set_str (&context->pattern_name, gimp_object_get_name (pattern));
|
||||
|
||||
g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
|
||||
GIMP_CONTEXT_PROP_PATTERN);
|
||||
@@ -3099,8 +3094,7 @@ static void
|
||||
gimp_context_gradient_dirty (GimpGradient *gradient,
|
||||
GimpContext *context)
|
||||
{
|
||||
g_free (context->gradient_name);
|
||||
context->gradient_name = g_strdup (gimp_object_get_name (gradient));
|
||||
g_set_str (&context->gradient_name, gimp_object_get_name (gradient));
|
||||
|
||||
g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
|
||||
GIMP_CONTEXT_PROP_GRADIENT);
|
||||
@@ -3212,8 +3206,7 @@ static void
|
||||
gimp_context_palette_dirty (GimpPalette *palette,
|
||||
GimpContext *context)
|
||||
{
|
||||
g_free (context->palette_name);
|
||||
context->palette_name = g_strdup (gimp_object_get_name (palette));
|
||||
g_set_str (&context->palette_name, gimp_object_get_name (palette));
|
||||
|
||||
g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
|
||||
GIMP_CONTEXT_PROP_PALETTE);
|
||||
@@ -3344,8 +3337,7 @@ gimp_context_set_font_name (GimpContext *context,
|
||||
*/
|
||||
gimp_context_set_font (context, GIMP_FONT (gimp_font_get_standard ()));
|
||||
|
||||
g_free (context->font_name);
|
||||
context->font_name = g_strdup (name);
|
||||
g_set_str (&context->font_name, name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3363,8 +3355,8 @@ static void
|
||||
gimp_context_font_dirty (GimpFont *font,
|
||||
GimpContext *context)
|
||||
{
|
||||
g_free (context->font_name);
|
||||
context->font_name = g_strdup (gimp_object_get_name (font));
|
||||
g_set_str (&context->font_name,
|
||||
gimp_object_get_name (font));
|
||||
|
||||
g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
|
||||
GIMP_CONTEXT_PROP_FONT);
|
||||
@@ -3476,8 +3468,7 @@ static void
|
||||
gimp_context_tool_preset_dirty (GimpToolPreset *tool_preset,
|
||||
GimpContext *context)
|
||||
{
|
||||
g_free (context->tool_preset_name);
|
||||
context->tool_preset_name = g_strdup (gimp_object_get_name (tool_preset));
|
||||
g_set_str (&context->tool_preset_name, gimp_object_get_name (tool_preset));
|
||||
|
||||
g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
|
||||
GIMP_CONTEXT_PROP_TOOL_PRESET);
|
||||
@@ -3584,8 +3575,7 @@ static void
|
||||
gimp_context_buffer_dirty (GimpBuffer *buffer,
|
||||
GimpContext *context)
|
||||
{
|
||||
g_free (context->buffer_name);
|
||||
context->buffer_name = g_strdup (gimp_object_get_name (buffer));
|
||||
g_set_str (&context->buffer_name, gimp_object_get_name (buffer));
|
||||
|
||||
g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
|
||||
GIMP_CONTEXT_PROP_BUFFER);
|
||||
@@ -3700,8 +3690,7 @@ static void
|
||||
gimp_context_imagefile_dirty (GimpImagefile *imagefile,
|
||||
GimpContext *context)
|
||||
{
|
||||
g_free (context->imagefile_name);
|
||||
context->imagefile_name = g_strdup (gimp_object_get_name (imagefile));
|
||||
g_set_str (&context->imagefile_name, gimp_object_get_name (imagefile));
|
||||
|
||||
g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
|
||||
GIMP_CONTEXT_PROP_IMAGEFILE);
|
||||
@@ -3816,8 +3805,7 @@ static void
|
||||
gimp_context_template_dirty (GimpTemplate *template,
|
||||
GimpContext *context)
|
||||
{
|
||||
g_free (context->template_name);
|
||||
context->template_name = g_strdup (gimp_object_get_name (template));
|
||||
g_set_str (&context->template_name, gimp_object_get_name (template));
|
||||
|
||||
g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
|
||||
GIMP_CONTEXT_PROP_TEMPLATE);
|
||||
|
@@ -86,7 +86,8 @@ static gboolean gimp_curve_get_popup_size (GimpViewable *viewable,
|
||||
static GimpTempBuf * gimp_curve_get_new_preview (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height);
|
||||
gint height,
|
||||
GeglColor *fg_color);
|
||||
static gchar * gimp_curve_get_description (GimpViewable *viewable,
|
||||
gchar **tooltip);
|
||||
|
||||
@@ -521,7 +522,8 @@ static GimpTempBuf *
|
||||
gimp_curve_get_new_preview (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height)
|
||||
gint height,
|
||||
GeglColor *fg_color G_GNUC_UNUSED)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -850,7 +850,7 @@ gimp_data_factory_get_data_type (GimpDataFactory *factory)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), G_TYPE_NONE);
|
||||
|
||||
return gimp_container_get_children_type (factory->priv->container);
|
||||
return gimp_container_get_child_type (factory->priv->container);
|
||||
}
|
||||
|
||||
GimpContainer *
|
||||
|
@@ -52,9 +52,9 @@ gimp_document_list_new (Gimp *gimp)
|
||||
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
|
||||
|
||||
document_list = g_object_new (GIMP_TYPE_DOCUMENT_LIST,
|
||||
"name", "document-list",
|
||||
"children-type", GIMP_TYPE_IMAGEFILE,
|
||||
"policy", GIMP_CONTAINER_POLICY_STRONG,
|
||||
"name", "document-list",
|
||||
"child-type", GIMP_TYPE_IMAGEFILE,
|
||||
"policy", GIMP_CONTAINER_POLICY_STRONG,
|
||||
NULL);
|
||||
|
||||
document_list->gimp = gimp;
|
||||
|
@@ -179,7 +179,7 @@ gimp_drawable_fill_boundary (GimpDrawable *drawable,
|
||||
gboolean
|
||||
gimp_drawable_fill_path (GimpDrawable *drawable,
|
||||
GimpFillOptions *options,
|
||||
GimpPath *vectors,
|
||||
GimpPath *path,
|
||||
gboolean push_undo,
|
||||
GError **error)
|
||||
{
|
||||
@@ -188,14 +188,14 @@ gimp_drawable_fill_path (GimpDrawable *drawable,
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
|
||||
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_FILL_OPTIONS (options), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_PATH (vectors), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_PATH (path), FALSE);
|
||||
g_return_val_if_fail (gimp_fill_options_get_style (options) !=
|
||||
GIMP_FILL_STYLE_PATTERN ||
|
||||
gimp_context_get_pattern (GIMP_CONTEXT (options)) != NULL,
|
||||
FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
bezier = gimp_path_get_bezier (vectors);
|
||||
bezier = gimp_path_get_bezier (path);
|
||||
|
||||
if (bezier && bezier->num_data > 4)
|
||||
{
|
||||
|
@@ -47,7 +47,7 @@ void gimp_drawable_fill_boundary (GimpDrawable *drawable,
|
||||
|
||||
gboolean gimp_drawable_fill_path (GimpDrawable *drawable,
|
||||
GimpFillOptions *options,
|
||||
GimpPath *vectors,
|
||||
GimpPath *path,
|
||||
gboolean push_undo,
|
||||
GError **error);
|
||||
|
||||
|
@@ -49,6 +49,19 @@
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
void
|
||||
_gimp_drawable_filters_init (GimpDrawable *drawable)
|
||||
{
|
||||
drawable->private->filter_stack = gimp_filter_stack_new (GIMP_TYPE_FILTER);
|
||||
}
|
||||
|
||||
void
|
||||
_gimp_drawable_filters_finalize (GimpDrawable *drawable)
|
||||
{
|
||||
g_clear_object (&drawable->private->filter_stack);
|
||||
}
|
||||
|
||||
GimpContainer *
|
||||
gimp_drawable_get_filters (GimpDrawable *drawable)
|
||||
{
|
||||
@@ -77,6 +90,58 @@ gimp_drawable_has_visible_filters (GimpDrawable *drawable)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_drawable_n_editable_filters (GimpDrawable *drawable,
|
||||
gint *n_editable,
|
||||
gint *first,
|
||||
gint *last)
|
||||
{
|
||||
GList *list;
|
||||
gboolean editing_blocked = FALSE;
|
||||
gint index = 0;
|
||||
gint n = 0;
|
||||
gint first_editable = -1;
|
||||
gint last_editable = -1;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
|
||||
|
||||
for (list = GIMP_LIST (drawable->private->filter_stack)->queue->head;
|
||||
list;
|
||||
list = g_list_next (list), index++)
|
||||
{
|
||||
GimpFilter *filter = list->data;
|
||||
gboolean editable = FALSE;
|
||||
|
||||
if (GIMP_IS_DRAWABLE_FILTER (filter))
|
||||
{
|
||||
if (gimp_drawable_filter_get_temporary (GIMP_DRAWABLE_FILTER (filter)))
|
||||
{
|
||||
editing_blocked = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
editable = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (editable)
|
||||
{
|
||||
n++;
|
||||
|
||||
if (first_editable == -1)
|
||||
first_editable = index;
|
||||
|
||||
last_editable = index;
|
||||
}
|
||||
}
|
||||
|
||||
if (n_editable) *n_editable = n;
|
||||
if (first) *first = first_editable;
|
||||
if (last) *last = last_editable;
|
||||
|
||||
return ! editing_blocked;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_add_filter (GimpDrawable *drawable,
|
||||
GimpFilter *filter)
|
||||
@@ -115,16 +180,105 @@ gimp_drawable_clear_filters (GimpDrawable *drawable)
|
||||
gimp_drawable_filters_changed (drawable);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_drawable_has_filter (GimpDrawable *drawable,
|
||||
GimpFilter *filter)
|
||||
{
|
||||
gboolean filter_exists = FALSE;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_FILTER (filter), FALSE);
|
||||
|
||||
filter_exists = gimp_container_have (drawable->private->filter_stack,
|
||||
GIMP_OBJECT (filter));
|
||||
|
||||
return filter_exists;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_drawable_raise_filter (GimpDrawable *drawable,
|
||||
GimpFilter *filter)
|
||||
{
|
||||
gint index;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE_FILTER (filter), FALSE);
|
||||
g_return_val_if_fail (gimp_drawable_has_filter (drawable, filter), FALSE);
|
||||
|
||||
if (gimp_drawable_filter_get_mask (GIMP_DRAWABLE_FILTER (filter)) == NULL)
|
||||
return FALSE;
|
||||
|
||||
index = gimp_container_get_child_index (drawable->private->filter_stack,
|
||||
GIMP_OBJECT (filter));
|
||||
index--;
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
gimp_image_undo_push_filter_reorder (gimp_item_get_image (GIMP_ITEM (drawable)),
|
||||
_("Reorder filter"),
|
||||
drawable,
|
||||
GIMP_DRAWABLE_FILTER (filter));
|
||||
|
||||
gimp_container_reorder (drawable->private->filter_stack,
|
||||
GIMP_OBJECT (filter), index);
|
||||
|
||||
gimp_drawable_update (drawable, 0, 0, -1, -1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_drawable_lower_filter (GimpDrawable *drawable,
|
||||
GimpFilter *filter)
|
||||
{
|
||||
gint index;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE_FILTER (filter), FALSE);
|
||||
g_return_val_if_fail (gimp_drawable_has_filter (drawable, filter), FALSE);
|
||||
|
||||
if (gimp_drawable_filter_get_mask (GIMP_DRAWABLE_FILTER (filter)) == NULL)
|
||||
return FALSE;
|
||||
|
||||
index = gimp_container_get_child_index (drawable->private->filter_stack,
|
||||
GIMP_OBJECT (filter));
|
||||
index++;
|
||||
|
||||
if (index < gimp_container_get_n_children (drawable->private->filter_stack))
|
||||
{
|
||||
/* Don't rearrange filters with floating selection */
|
||||
if (! GIMP_IS_DRAWABLE_FILTER (gimp_container_get_child_by_index (drawable->private->filter_stack,
|
||||
index)))
|
||||
return FALSE;
|
||||
|
||||
gimp_image_undo_push_filter_reorder (gimp_item_get_image (GIMP_ITEM (drawable)),
|
||||
_("Reorder filter"),
|
||||
drawable,
|
||||
GIMP_DRAWABLE_FILTER (filter));
|
||||
|
||||
gimp_container_reorder (drawable->private->filter_stack,
|
||||
GIMP_OBJECT (filter), index);
|
||||
|
||||
gimp_drawable_update (drawable, 0, 0, -1, -1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_merge_filters (GimpDrawable *drawable)
|
||||
{
|
||||
GList *list;
|
||||
GimpImage *image;
|
||||
GimpChannel *selection = NULL;
|
||||
GeglBuffer *buffer = NULL;
|
||||
GimpChannel *selection;
|
||||
GeglBuffer *buffer;
|
||||
GList *list;
|
||||
|
||||
if (! GIMP_IS_DRAWABLE (drawable))
|
||||
return;
|
||||
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
|
||||
|
||||
image = gimp_item_get_image (GIMP_ITEM (drawable));
|
||||
|
||||
@@ -145,7 +299,8 @@ gimp_drawable_merge_filters (GimpDrawable *drawable)
|
||||
*/
|
||||
if (GIMP_LIST (drawable->private->filter_stack)->queue->head)
|
||||
{
|
||||
GimpDrawableFilter *top_filter = NULL;
|
||||
GimpDrawableFilter *filter = NULL;
|
||||
gboolean add_alpha = FALSE;
|
||||
|
||||
for (list = GIMP_LIST (drawable->private->filter_stack)->queue->tail;
|
||||
list;
|
||||
@@ -153,34 +308,55 @@ gimp_drawable_merge_filters (GimpDrawable *drawable)
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (list->data) &&
|
||||
gimp_filter_get_active (GIMP_FILTER (list->data)))
|
||||
top_filter = list->data;
|
||||
{
|
||||
filter = list->data;
|
||||
|
||||
if (! add_alpha)
|
||||
add_alpha = gimp_drawable_filter_get_add_alpha (filter);
|
||||
}
|
||||
}
|
||||
|
||||
if (top_filter)
|
||||
if (filter)
|
||||
{
|
||||
GimpApplicator *applicator;
|
||||
GeglNode *graph;
|
||||
GeglNode *output;
|
||||
GeglRectangle output_rect;
|
||||
|
||||
if (GIMP_IS_LAYER (drawable) && add_alpha)
|
||||
gimp_layer_add_alpha (GIMP_LAYER (drawable));
|
||||
|
||||
graph = gimp_filter_stack_get_graph (GIMP_FILTER_STACK (drawable->private->filter_stack));
|
||||
output = gegl_node_get_output_proxy (graph, "output");
|
||||
output_rect = gegl_node_get_bounding_box (output);
|
||||
buffer = gegl_buffer_new (&output_rect, gimp_drawable_get_format (drawable));
|
||||
|
||||
applicator = gimp_filter_get_applicator (GIMP_FILTER (top_filter));
|
||||
applicator = gimp_filter_get_applicator (GIMP_FILTER (filter));
|
||||
gimp_applicator_set_dest_buffer (applicator, buffer);
|
||||
gimp_applicator_blit (applicator, gegl_buffer_get_extent (buffer));
|
||||
gimp_drawable_set_buffer (drawable, TRUE, NULL, buffer);
|
||||
g_clear_object (&buffer);
|
||||
}
|
||||
|
||||
while ((list = GIMP_LIST (drawable->private->filter_stack)->queue->tail))
|
||||
/* don't use a for() loop because we are deleting the list
|
||||
* under our feet
|
||||
*/
|
||||
list = GIMP_LIST (drawable->private->filter_stack)->queue->head;
|
||||
while (list)
|
||||
{
|
||||
gimp_image_undo_push_filter_remove (gimp_item_get_image (GIMP_ITEM (drawable)),
|
||||
_("Merge filter"), drawable, list->data);
|
||||
filter = list->data;
|
||||
|
||||
gimp_drawable_remove_filter (drawable, GIMP_FILTER (list->data));
|
||||
list = list->next;
|
||||
|
||||
if (GIMP_IS_DRAWABLE_FILTER (filter) &&
|
||||
! gimp_drawable_filter_get_temporary (filter))
|
||||
|
||||
{
|
||||
gimp_image_undo_push_filter_remove (gimp_item_get_image (GIMP_ITEM (drawable)),
|
||||
_("Merge filter"),
|
||||
drawable, filter);
|
||||
gimp_drawable_remove_filter (drawable, GIMP_FILTER (filter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,21 +373,6 @@ gimp_drawable_merge_filters (GimpDrawable *drawable)
|
||||
gimp_drawable_filters_changed (drawable);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_drawable_has_filter (GimpDrawable *drawable,
|
||||
GimpFilter *filter)
|
||||
{
|
||||
gboolean filter_exists = FALSE;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_FILTER (filter), FALSE);
|
||||
|
||||
filter_exists = gimp_container_have (drawable->private->filter_stack,
|
||||
GIMP_OBJECT (filter));
|
||||
|
||||
return filter_exists;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_drawable_merge_filter (GimpDrawable *drawable,
|
||||
GimpFilter *filter,
|
||||
|
@@ -21,21 +21,38 @@
|
||||
#define __GIMP_DRAWABLE_FILTERS_H__
|
||||
|
||||
|
||||
/* internal functions */
|
||||
|
||||
void _gimp_drawable_filters_init (GimpDrawable *drawable);
|
||||
void _gimp_drawable_filters_finalize (GimpDrawable *drawable);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
GimpContainer * gimp_drawable_get_filters (GimpDrawable *drawable);
|
||||
|
||||
gboolean gimp_drawable_has_visible_filters (GimpDrawable *drawable);
|
||||
|
||||
gboolean gimp_drawable_n_editable_filters (GimpDrawable *drawable,
|
||||
gint *n_editable,
|
||||
gint *first,
|
||||
gint *last);
|
||||
|
||||
void gimp_drawable_add_filter (GimpDrawable *drawable,
|
||||
GimpFilter *filter);
|
||||
void gimp_drawable_remove_filter (GimpDrawable *drawable,
|
||||
GimpFilter *filter);
|
||||
void gimp_drawable_clear_filters (GimpDrawable *drawable);
|
||||
|
||||
void gimp_drawable_merge_filters (GimpDrawable *drawable);
|
||||
|
||||
gboolean gimp_drawable_has_filter (GimpDrawable *drawable,
|
||||
GimpFilter *filter);
|
||||
|
||||
gboolean gimp_drawable_raise_filter (GimpDrawable *drawable,
|
||||
GimpFilter *filter);
|
||||
gboolean gimp_drawable_lower_filter (GimpDrawable *drawable,
|
||||
GimpFilter *filter);
|
||||
|
||||
void gimp_drawable_merge_filters (GimpDrawable *drawable);
|
||||
gboolean gimp_drawable_merge_filter (GimpDrawable *drawable,
|
||||
GimpFilter *filter,
|
||||
GimpProgress *progress,
|
||||
|
@@ -112,7 +112,8 @@ GimpTempBuf *
|
||||
gimp_drawable_get_new_preview (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height)
|
||||
gint height,
|
||||
GeglColor *fg_color G_GNUC_UNUSED)
|
||||
{
|
||||
GimpItem *item = GIMP_ITEM (viewable);
|
||||
GimpImage *image = gimp_item_get_image (item);
|
||||
@@ -132,7 +133,8 @@ GdkPixbuf *
|
||||
gimp_drawable_get_new_pixbuf (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height)
|
||||
gint height,
|
||||
GeglColor *fg_color G_GNUC_UNUSED)
|
||||
{
|
||||
GimpItem *item = GIMP_ITEM (viewable);
|
||||
GimpImage *image = gimp_item_get_image (item);
|
||||
|
@@ -25,11 +25,13 @@
|
||||
GimpTempBuf * gimp_drawable_get_new_preview (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height);
|
||||
gint height,
|
||||
GeglColor *fg_color);
|
||||
GdkPixbuf * gimp_drawable_get_new_pixbuf (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height);
|
||||
gint height,
|
||||
GeglColor *fg_color);
|
||||
|
||||
/*
|
||||
* normal functions (no virtuals)
|
||||
|
@@ -76,7 +76,7 @@ gimp_drawable_stroke_boundary (GimpDrawable *drawable,
|
||||
gboolean
|
||||
gimp_drawable_stroke_path (GimpDrawable *drawable,
|
||||
GimpStrokeOptions *options,
|
||||
GimpPath *vectors,
|
||||
GimpPath *path,
|
||||
gboolean push_undo,
|
||||
GError **error)
|
||||
{
|
||||
@@ -85,14 +85,14 @@ gimp_drawable_stroke_path (GimpDrawable *drawable,
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
|
||||
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_STROKE_OPTIONS (options), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_PATH (vectors), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_PATH (path), FALSE);
|
||||
g_return_val_if_fail (gimp_fill_options_get_style (GIMP_FILL_OPTIONS (options)) !=
|
||||
GIMP_FILL_STYLE_PATTERN ||
|
||||
gimp_context_get_pattern (GIMP_CONTEXT (options)) != NULL,
|
||||
FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
bezier = gimp_path_get_bezier (vectors);
|
||||
bezier = gimp_path_get_bezier (path);
|
||||
|
||||
if (bezier && bezier->num_data >= 2)
|
||||
{
|
||||
|
@@ -32,7 +32,7 @@ void gimp_drawable_stroke_boundary (GimpDrawable *drawable,
|
||||
|
||||
gboolean gimp_drawable_stroke_path (GimpDrawable *drawable,
|
||||
GimpStrokeOptions *options,
|
||||
GimpPath *vectors,
|
||||
GimpPath *path,
|
||||
gboolean push_undo,
|
||||
GError **error);
|
||||
|
||||
|
@@ -50,7 +50,6 @@
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-colormap.h"
|
||||
#include "gimpimage-undo-push.h"
|
||||
#include "gimplayer.h"
|
||||
#include "gimpmarshal.h"
|
||||
#include "gimppickable.h"
|
||||
#include "gimpprogress.h"
|
||||
@@ -100,6 +99,7 @@ static void gimp_drawable_get_property (GObject *object,
|
||||
static gint64 gimp_drawable_get_memsize (GimpObject *object,
|
||||
gint64 *gui_size);
|
||||
|
||||
static void gimp_drawable_size_changed (GimpViewable *viewable);
|
||||
static gboolean gimp_drawable_get_size (GimpViewable *viewable,
|
||||
gint *width,
|
||||
gint *height);
|
||||
@@ -291,6 +291,7 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
|
||||
|
||||
gimp_object_class->get_memsize = gimp_drawable_get_memsize;
|
||||
|
||||
viewable_class->size_changed = gimp_drawable_size_changed;
|
||||
viewable_class->get_size = gimp_drawable_get_size;
|
||||
viewable_class->get_new_preview = gimp_drawable_get_new_preview;
|
||||
viewable_class->get_new_pixbuf = gimp_drawable_get_new_pixbuf;
|
||||
@@ -335,7 +336,7 @@ gimp_drawable_init (GimpDrawable *drawable)
|
||||
{
|
||||
drawable->private = gimp_drawable_get_instance_private (drawable);
|
||||
|
||||
drawable->private->filter_stack = gimp_filter_stack_new (GIMP_TYPE_FILTER);
|
||||
_gimp_drawable_filters_init (drawable);
|
||||
}
|
||||
|
||||
/* sorry for the evil casts */
|
||||
@@ -386,7 +387,8 @@ gimp_drawable_finalize (GObject *object)
|
||||
|
||||
g_clear_object (&drawable->private->source_node);
|
||||
g_clear_object (&drawable->private->buffer_source_node);
|
||||
g_clear_object (&drawable->private->filter_stack);
|
||||
|
||||
_gimp_drawable_filters_finalize (drawable);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
@@ -440,6 +442,36 @@ gimp_drawable_get_memsize (GimpObject *object,
|
||||
gui_size);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_drawable_size_changed (GimpViewable *viewable)
|
||||
{
|
||||
GList *list;
|
||||
gint width;
|
||||
gint height;
|
||||
|
||||
if (GIMP_VIEWABLE_CLASS (parent_class)->size_changed)
|
||||
GIMP_VIEWABLE_CLASS (parent_class)->size_changed (viewable);
|
||||
|
||||
width = gimp_item_get_width (GIMP_ITEM (viewable));
|
||||
height = gimp_item_get_height (GIMP_ITEM (viewable));
|
||||
|
||||
for (list = GIMP_LIST (GIMP_DRAWABLE (viewable)->private->filter_stack)->queue->tail;
|
||||
list;
|
||||
list = g_list_previous (list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (list->data))
|
||||
{
|
||||
GimpDrawableFilter *filter = list->data;
|
||||
GimpChannel *mask = GIMP_CHANNEL (gimp_drawable_filter_get_mask (filter));
|
||||
GeglRectangle rect = { 0, 0, width, height };
|
||||
|
||||
/* Don't resize partial layer effects */
|
||||
if (gimp_channel_is_empty (mask))
|
||||
gimp_drawable_filter_refresh_crop (filter, &rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_drawable_get_size (GimpViewable *viewable,
|
||||
gint *width,
|
||||
@@ -529,11 +561,38 @@ gimp_drawable_duplicate (GimpItem *item,
|
||||
GimpDrawable *drawable = GIMP_DRAWABLE (item);
|
||||
GimpDrawable *new_drawable = GIMP_DRAWABLE (new_item);
|
||||
GeglBuffer *new_buffer;
|
||||
GimpContainer *filters;
|
||||
GList *list;
|
||||
|
||||
new_buffer = gimp_gegl_buffer_dup (gimp_drawable_get_buffer (drawable));
|
||||
|
||||
gimp_drawable_set_buffer (new_drawable, FALSE, NULL, new_buffer);
|
||||
g_object_unref (new_buffer);
|
||||
|
||||
filters = gimp_drawable_get_filters (drawable);
|
||||
|
||||
for (list = GIMP_LIST (filters)->queue->tail;
|
||||
list;
|
||||
list = g_list_previous (list))
|
||||
{
|
||||
GimpDrawableFilter *filter = list->data;
|
||||
|
||||
if (GIMP_IS_DRAWABLE_FILTER (filter))
|
||||
{
|
||||
GimpDrawableFilter *new_filter;
|
||||
|
||||
new_filter = gimp_drawable_filter_duplicate (new_drawable,
|
||||
filter);
|
||||
if (new_filter)
|
||||
{
|
||||
gimp_drawable_filter_apply (new_filter, NULL);
|
||||
gimp_drawable_filter_commit (new_filter, TRUE, NULL, FALSE);
|
||||
|
||||
gimp_drawable_filter_layer_mask_freeze (new_filter);
|
||||
g_object_unref (new_filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new_item;
|
||||
@@ -570,30 +629,6 @@ gimp_drawable_scale (GimpItem *item,
|
||||
0, 0),
|
||||
TRUE);
|
||||
g_object_unref (new_buffer);
|
||||
|
||||
if (GIMP_IS_LAYER (drawable))
|
||||
{
|
||||
GList *list;
|
||||
|
||||
for (list = GIMP_LIST (drawable->private->filter_stack)->queue->tail;
|
||||
list; list = g_list_previous (list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (list->data))
|
||||
{
|
||||
GimpDrawableFilter *filter = list->data;
|
||||
GimpChannel *mask = GIMP_CHANNEL (gimp_drawable_filter_get_mask (filter));
|
||||
GeglRectangle *rect = GEGL_RECTANGLE (0, 0,
|
||||
new_width,
|
||||
new_height);
|
||||
|
||||
/* Don't resize partial layer effects */
|
||||
if (gimp_channel_is_empty (mask))
|
||||
gimp_drawable_filter_refresh_crop (filter, rect);
|
||||
}
|
||||
}
|
||||
if (list)
|
||||
g_list_free (list);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -679,28 +714,6 @@ gimp_drawable_resize (GimpItem *item,
|
||||
0, 0),
|
||||
TRUE);
|
||||
g_object_unref (new_buffer);
|
||||
|
||||
if (GIMP_IS_LAYER (drawable))
|
||||
{
|
||||
GList *list;
|
||||
|
||||
for (list = GIMP_LIST (drawable->private->filter_stack)->queue->tail;
|
||||
list; list = g_list_previous (list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (list->data))
|
||||
{
|
||||
GimpDrawableFilter *filter = list->data;
|
||||
GimpChannel *mask = GIMP_CHANNEL (gimp_drawable_filter_get_mask (filter));
|
||||
GeglRectangle rect = {0, 0, new_width, new_height};
|
||||
|
||||
/* Don't resize partial layer effects */
|
||||
if (gimp_channel_is_empty (mask))
|
||||
gimp_drawable_filter_refresh_crop (filter, &rect);
|
||||
}
|
||||
}
|
||||
if (list)
|
||||
g_list_free (list);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -764,30 +777,6 @@ gimp_drawable_rotate (GimpItem *item,
|
||||
new_off_x, new_off_y, FALSE);
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
|
||||
if (GIMP_IS_LAYER (drawable))
|
||||
{
|
||||
GList *list;
|
||||
gint width = gimp_item_get_width (GIMP_ITEM (drawable));
|
||||
gint height = gimp_item_get_height (GIMP_ITEM (drawable));
|
||||
|
||||
for (list = GIMP_LIST (drawable->private->filter_stack)->queue->tail;
|
||||
list; list = g_list_previous (list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (list->data))
|
||||
{
|
||||
GimpDrawableFilter *filter = list->data;
|
||||
GimpChannel *mask = GIMP_CHANNEL (gimp_drawable_filter_get_mask (filter));
|
||||
GeglRectangle rect = {0, 0, width, height};
|
||||
|
||||
/* Don't resize partial layer effects */
|
||||
if (gimp_channel_is_empty (mask))
|
||||
gimp_drawable_filter_refresh_crop (filter, &rect);
|
||||
}
|
||||
}
|
||||
if (list)
|
||||
g_list_free (list);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1200,24 +1189,23 @@ gimp_drawable_update (GimpDrawable *drawable,
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
|
||||
|
||||
if (width < 0)
|
||||
if (width < 0 || height < 0)
|
||||
{
|
||||
GeglRectangle bounding_box;
|
||||
|
||||
bounding_box = gimp_drawable_get_bounding_box (drawable);
|
||||
|
||||
x = bounding_box.x;
|
||||
width = bounding_box.width;
|
||||
}
|
||||
if (width < 0)
|
||||
{
|
||||
x = bounding_box.x;
|
||||
width = bounding_box.width;
|
||||
}
|
||||
|
||||
if (height < 0)
|
||||
{
|
||||
GeglRectangle bounding_box;
|
||||
|
||||
bounding_box = gimp_drawable_get_bounding_box (drawable);
|
||||
|
||||
y = bounding_box.y;
|
||||
height = bounding_box.height;
|
||||
if (height < 0)
|
||||
{
|
||||
y = bounding_box.y;
|
||||
height = bounding_box.height;
|
||||
}
|
||||
}
|
||||
|
||||
if (drawable->private->paint_count == 0)
|
||||
@@ -1285,6 +1273,14 @@ gimp_drawable_update_all (GimpDrawable *drawable)
|
||||
GIMP_DRAWABLE_GET_CLASS (drawable)->update_all (drawable);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_filters_changed (GimpDrawable *drawable)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
|
||||
|
||||
g_signal_emit (drawable, gimp_drawable_signals[FILTERS_CHANGED], 0);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_invalidate_boundary (GimpDrawable *drawable)
|
||||
{
|
||||
@@ -2110,10 +2106,7 @@ gimp_drawable_end_paint (GimpDrawable *drawable)
|
||||
if (gimp_drawable_has_visible_filters (drawable) &&
|
||||
drawable->private->paint_count == 0)
|
||||
{
|
||||
gimp_item_set_visible (GIMP_ITEM (drawable), FALSE, FALSE);
|
||||
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (drawable)));
|
||||
gimp_item_set_visible (GIMP_ITEM (drawable),TRUE, FALSE);
|
||||
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (drawable)));
|
||||
gimp_drawable_update (drawable, 0, 0, -1, -1);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -2184,9 +2177,3 @@ gimp_drawable_is_painting (GimpDrawable *drawable)
|
||||
|
||||
return drawable->private->paint_count > 0;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_filters_changed (GimpDrawable *drawable)
|
||||
{
|
||||
g_signal_emit (drawable, gimp_drawable_signals[FILTERS_CHANGED], 0);
|
||||
}
|
||||
|
@@ -134,6 +134,8 @@ void gimp_drawable_update (GimpDrawable *drawa
|
||||
gint height);
|
||||
void gimp_drawable_update_all (GimpDrawable *drawable);
|
||||
|
||||
void gimp_drawable_filters_changed (GimpDrawable *drawable);
|
||||
|
||||
void gimp_drawable_invalidate_boundary (GimpDrawable *drawable);
|
||||
void gimp_drawable_get_active_components (GimpDrawable *drawable,
|
||||
gboolean *active);
|
||||
@@ -235,7 +237,5 @@ gboolean gimp_drawable_end_paint (GimpDrawable *drawable)
|
||||
gboolean gimp_drawable_flush_paint (GimpDrawable *drawable);
|
||||
gboolean gimp_drawable_is_painting (GimpDrawable *drawable);
|
||||
|
||||
void gimp_drawable_filters_changed (GimpDrawable *drawable);
|
||||
|
||||
|
||||
#endif /* __GIMP_DRAWABLE_H__ */
|
||||
|
@@ -115,7 +115,7 @@ struct _GimpDrawableFilter
|
||||
GeglNode *crop_after;
|
||||
GimpApplicator *applicator;
|
||||
|
||||
gboolean is_temporary;
|
||||
gboolean temporary;
|
||||
/* This is mirroring merge_filter option of GimpFilterOptions. */
|
||||
gboolean to_be_merged;
|
||||
};
|
||||
@@ -173,6 +173,7 @@ static void gimp_drawable_filter_lock_alpha_changed (GimpLayer
|
||||
|
||||
static void gimp_drawable_filter_reorder (GimpFilterStack *stack,
|
||||
GimpDrawableFilter *reordered_filter,
|
||||
gint old_index,
|
||||
gint new_index,
|
||||
GimpDrawableFilter *filter);
|
||||
|
||||
@@ -291,7 +292,7 @@ gimp_drawable_filter_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_TEMPORARY:
|
||||
filter->is_temporary = g_value_get_boolean (value);
|
||||
filter->temporary = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_TO_BE_MERGED:
|
||||
@@ -325,7 +326,7 @@ gimp_drawable_filter_get_property (GObject *object,
|
||||
g_value_set_boolean (value, filter->has_custom_name);
|
||||
break;
|
||||
case PROP_TEMPORARY:
|
||||
g_value_set_boolean (value, filter->is_temporary);
|
||||
g_value_set_boolean (value, filter->temporary);
|
||||
break;
|
||||
case PROP_TO_BE_MERGED:
|
||||
g_value_set_boolean (value, filter->to_be_merged);
|
||||
@@ -530,6 +531,8 @@ gimp_drawable_filter_duplicate (GimpDrawable *drawable,
|
||||
prior_filter->composite_mode);
|
||||
gimp_drawable_filter_set_region (filter,
|
||||
prior_filter->region);
|
||||
gimp_drawable_filter_set_add_alpha (filter,
|
||||
prior_filter->add_alpha);
|
||||
gimp_filter_set_active (GIMP_FILTER (filter),
|
||||
gimp_filter_get_active (GIMP_FILTER (prior_filter)));
|
||||
gimp_filter_set_is_last_node (GIMP_FILTER (filter),
|
||||
@@ -590,6 +593,47 @@ gimp_drawable_filter_get_mask (GimpDrawableFilter *filter)
|
||||
return filter->mask;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_filter_set_temporary (GimpDrawableFilter *filter,
|
||||
gboolean temporary)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_DRAWABLE_FILTER (filter));
|
||||
|
||||
temporary = temporary ? TRUE : FALSE;
|
||||
|
||||
if (temporary != filter->temporary)
|
||||
{
|
||||
g_object_set (filter,
|
||||
"temporary", temporary,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_drawable_filter_get_temporary (GimpDrawableFilter *filter)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE_FILTER (filter), FALSE);
|
||||
|
||||
return filter->temporary;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_filter_set_opacity (GimpDrawableFilter *filter,
|
||||
gdouble opacity)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_DRAWABLE_FILTER (filter));
|
||||
|
||||
if (opacity != filter->opacity)
|
||||
{
|
||||
filter->opacity = opacity;
|
||||
|
||||
gimp_drawable_filter_sync_opacity (filter);
|
||||
|
||||
if (gimp_drawable_filter_is_active (filter))
|
||||
gimp_drawable_filter_update_drawable (filter, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
gdouble
|
||||
gimp_drawable_filter_get_opacity (GimpDrawableFilter *filter)
|
||||
{
|
||||
@@ -598,6 +642,32 @@ gimp_drawable_filter_get_opacity (GimpDrawableFilter *filter)
|
||||
return filter->opacity;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_filter_set_mode (GimpDrawableFilter *filter,
|
||||
GimpLayerMode paint_mode,
|
||||
GimpLayerColorSpace blend_space,
|
||||
GimpLayerColorSpace composite_space,
|
||||
GimpLayerCompositeMode composite_mode)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_DRAWABLE_FILTER (filter));
|
||||
|
||||
if (paint_mode != filter->paint_mode ||
|
||||
blend_space != filter->blend_space ||
|
||||
composite_space != filter->composite_space ||
|
||||
composite_mode != filter->composite_mode)
|
||||
{
|
||||
filter->paint_mode = paint_mode;
|
||||
filter->blend_space = blend_space;
|
||||
filter->composite_space = composite_space;
|
||||
filter->composite_mode = composite_mode;
|
||||
|
||||
gimp_drawable_filter_sync_mode (filter);
|
||||
|
||||
if (gimp_drawable_filter_is_active (filter))
|
||||
gimp_drawable_filter_update_drawable (filter, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
GimpLayerMode
|
||||
gimp_drawable_filter_get_paint_mode (GimpDrawableFilter *filter)
|
||||
{
|
||||
@@ -630,22 +700,6 @@ gimp_drawable_filter_get_composite_mode (GimpDrawableFilter *filter)
|
||||
return filter->composite_mode;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_drawable_filter_get_clip (GimpDrawableFilter *filter)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE_FILTER (filter), FALSE);
|
||||
|
||||
return filter->clip;
|
||||
}
|
||||
|
||||
GimpFilterRegion
|
||||
gimp_drawable_filter_get_region (GimpDrawableFilter *filter)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE_FILTER (filter), 0);
|
||||
|
||||
return filter->region;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_filter_set_clip (GimpDrawableFilter *filter,
|
||||
gboolean clip)
|
||||
@@ -661,6 +715,14 @@ gimp_drawable_filter_set_clip (GimpDrawableFilter *filter,
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_drawable_filter_get_clip (GimpDrawableFilter *filter)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE_FILTER (filter), FALSE);
|
||||
|
||||
return filter->clip;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_filter_set_region (GimpDrawableFilter *filter,
|
||||
GimpFilterRegion region)
|
||||
@@ -678,6 +740,14 @@ gimp_drawable_filter_set_region (GimpDrawableFilter *filter,
|
||||
}
|
||||
}
|
||||
|
||||
GimpFilterRegion
|
||||
gimp_drawable_filter_get_region (GimpDrawableFilter *filter)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE_FILTER (filter), 0);
|
||||
|
||||
return filter->region;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_filter_set_crop (GimpDrawableFilter *filter,
|
||||
const GeglRectangle *rect,
|
||||
@@ -803,7 +873,7 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
|
||||
GimpLayerColorSpace composite_space,
|
||||
GimpLayerCompositeMode composite_mode,
|
||||
const gchar **auxinputnames,
|
||||
const GimpDrawable **auxinputs,
|
||||
GimpDrawable **auxinputs,
|
||||
GError **error)
|
||||
{
|
||||
GimpImage *image;
|
||||
@@ -1060,47 +1130,12 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter,
|
||||
return (*error != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_filter_set_opacity (GimpDrawableFilter *filter,
|
||||
gdouble opacity)
|
||||
gboolean
|
||||
gimp_drawable_filter_get_add_alpha (GimpDrawableFilter *filter)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_DRAWABLE_FILTER (filter));
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE_FILTER (filter), FALSE);
|
||||
|
||||
if (opacity != filter->opacity)
|
||||
{
|
||||
filter->opacity = opacity;
|
||||
|
||||
gimp_drawable_filter_sync_opacity (filter);
|
||||
|
||||
if (gimp_drawable_filter_is_active (filter))
|
||||
gimp_drawable_filter_update_drawable (filter, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_filter_set_mode (GimpDrawableFilter *filter,
|
||||
GimpLayerMode paint_mode,
|
||||
GimpLayerColorSpace blend_space,
|
||||
GimpLayerColorSpace composite_space,
|
||||
GimpLayerCompositeMode composite_mode)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_DRAWABLE_FILTER (filter));
|
||||
|
||||
if (paint_mode != filter->paint_mode ||
|
||||
blend_space != filter->blend_space ||
|
||||
composite_space != filter->composite_space ||
|
||||
composite_mode != filter->composite_mode)
|
||||
{
|
||||
filter->paint_mode = paint_mode;
|
||||
filter->blend_space = blend_space;
|
||||
filter->composite_space = composite_space;
|
||||
filter->composite_mode = composite_mode;
|
||||
|
||||
gimp_drawable_filter_sync_mode (filter);
|
||||
|
||||
if (gimp_drawable_filter_is_active (filter))
|
||||
gimp_drawable_filter_update_drawable (filter, NULL);
|
||||
}
|
||||
return filter->add_alpha;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1981,6 +2016,7 @@ gimp_drawable_filter_lock_alpha_changed (GimpLayer *layer,
|
||||
static void
|
||||
gimp_drawable_filter_reorder (GimpFilterStack *stack,
|
||||
GimpDrawableFilter *reordered_filter,
|
||||
gint old_index,
|
||||
gint new_index,
|
||||
GimpDrawableFilter *filter)
|
||||
{
|
||||
@@ -1998,6 +2034,8 @@ gimp_drawable_filter_reorder (GimpFilterStack *stack,
|
||||
* it's organized.
|
||||
*/
|
||||
GIMP_IS_DRAWABLE_FILTER (GIMP_LIST (stack)->queue->head->data))
|
||||
gimp_drawable_filter_sync_format (GIMP_LIST (stack)->queue->head->data);
|
||||
{
|
||||
gimp_drawable_filter_sync_format (GIMP_LIST (stack)->queue->head->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -68,7 +68,20 @@ GimpDrawable *
|
||||
GeglNode * gimp_drawable_filter_get_operation (GimpDrawableFilter *filter);
|
||||
GimpDrawableFilterMask *
|
||||
gimp_drawable_filter_get_mask (GimpDrawableFilter *filter);
|
||||
|
||||
void gimp_drawable_filter_set_temporary (GimpDrawableFilter *filter,
|
||||
gboolean temporary);
|
||||
gboolean gimp_drawable_filter_get_temporary (GimpDrawableFilter *filter);
|
||||
|
||||
void gimp_drawable_filter_set_opacity (GimpDrawableFilter *filter,
|
||||
gdouble opacity);
|
||||
gdouble gimp_drawable_filter_get_opacity (GimpDrawableFilter *filter);
|
||||
|
||||
void gimp_drawable_filter_set_mode (GimpDrawableFilter *filter,
|
||||
GimpLayerMode paint_mode,
|
||||
GimpLayerColorSpace blend_space,
|
||||
GimpLayerColorSpace composite_space,
|
||||
GimpLayerCompositeMode composite_mode);
|
||||
GimpLayerMode
|
||||
gimp_drawable_filter_get_paint_mode (GimpDrawableFilter *filter);
|
||||
GimpLayerColorSpace
|
||||
@@ -80,17 +93,20 @@ GimpLayerColorSpace
|
||||
GimpLayerCompositeMode
|
||||
gimp_drawable_filter_get_composite_mode
|
||||
(GimpDrawableFilter *filter);
|
||||
gboolean gimp_drawable_filter_get_clip (GimpDrawableFilter *filter);
|
||||
GimpFilterRegion
|
||||
gimp_drawable_filter_get_region (GimpDrawableFilter *filter);
|
||||
|
||||
void gimp_drawable_filter_set_clip (GimpDrawableFilter *filter,
|
||||
gboolean clip);
|
||||
gboolean gimp_drawable_filter_get_clip (GimpDrawableFilter *filter);
|
||||
|
||||
void gimp_drawable_filter_set_region (GimpDrawableFilter *filter,
|
||||
GimpFilterRegion region);
|
||||
GimpFilterRegion
|
||||
gimp_drawable_filter_get_region (GimpDrawableFilter *filter);
|
||||
|
||||
void gimp_drawable_filter_set_crop (GimpDrawableFilter *filter,
|
||||
const GeglRectangle *rect,
|
||||
gboolean update);
|
||||
|
||||
void gimp_drawable_filter_set_preview (GimpDrawableFilter *filter,
|
||||
gboolean enabled);
|
||||
void gimp_drawable_filter_set_preview_split
|
||||
@@ -108,15 +124,9 @@ gboolean gimp_drawable_filter_update (GimpDrawableFilter *filter,
|
||||
GimpLayerColorSpace composite_space,
|
||||
GimpLayerCompositeMode composite_mode,
|
||||
const gchar **auxinputnames,
|
||||
const GimpDrawable **auxinputs,
|
||||
GimpDrawable **auxinputs,
|
||||
GError **error);
|
||||
void gimp_drawable_filter_set_opacity (GimpDrawableFilter *filter,
|
||||
gdouble opacity);
|
||||
void gimp_drawable_filter_set_mode (GimpDrawableFilter *filter,
|
||||
GimpLayerMode paint_mode,
|
||||
GimpLayerColorSpace blend_space,
|
||||
GimpLayerColorSpace composite_space,
|
||||
GimpLayerCompositeMode composite_mode);
|
||||
gboolean gimp_drawable_filter_get_add_alpha (GimpDrawableFilter *filter);
|
||||
void gimp_drawable_filter_set_add_alpha (GimpDrawableFilter *filter,
|
||||
gboolean add_alpha);
|
||||
|
||||
|
@@ -106,7 +106,8 @@ gimp_drawable_filter_undo_constructed (GObject *object)
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
|
||||
gimp_assert (GIMP_IS_DRAWABLE_FILTER (df_undo->filter));
|
||||
gimp_assert (GIMP_IS_DRAWABLE_FILTER (df_undo->filter) &&
|
||||
! gimp_drawable_filter_get_temporary (df_undo->filter));
|
||||
|
||||
drawable = gimp_drawable_filter_get_drawable (df_undo->filter);
|
||||
if (drawable)
|
||||
@@ -242,10 +243,7 @@ gimp_drawable_filter_undo_pop (GimpUndo *undo,
|
||||
{
|
||||
gimp_drawable_remove_filter (drawable, GIMP_FILTER (filter));
|
||||
|
||||
gimp_item_set_visible (GIMP_ITEM (drawable), FALSE, FALSE);
|
||||
gimp_image_flush (undo->image);
|
||||
gimp_item_set_visible (GIMP_ITEM (drawable), TRUE, FALSE);
|
||||
gimp_image_flush (undo->image);
|
||||
gimp_drawable_update (drawable, 0, 0, -1, -1);
|
||||
}
|
||||
}
|
||||
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
|
||||
@@ -267,7 +265,7 @@ gimp_drawable_filter_undo_pop (GimpUndo *undo,
|
||||
{
|
||||
gimp_container_reorder (filter_stack, GIMP_OBJECT (filter),
|
||||
df_undo->row_index);
|
||||
gimp_drawable_filter_apply (filter, NULL);
|
||||
gimp_drawable_update (drawable, 0, 0, -1, -1);
|
||||
}
|
||||
else if (undo->undo_type == GIMP_UNDO_FILTER_MODIFIED)
|
||||
{
|
||||
@@ -354,11 +352,8 @@ gimp_drawable_filter_undo_free (GimpUndo *undo,
|
||||
{
|
||||
GimpDrawableFilterUndo *drawable_filter_undo = GIMP_DRAWABLE_FILTER_UNDO (undo);
|
||||
|
||||
if (drawable_filter_undo->filter)
|
||||
g_clear_object (&drawable_filter_undo->filter);
|
||||
|
||||
if (drawable_filter_undo->node)
|
||||
g_object_unref (drawable_filter_undo->node);
|
||||
g_clear_object (&drawable_filter_undo->filter);
|
||||
g_clear_object (&drawable_filter_undo->node);
|
||||
|
||||
GIMP_UNDO_CLASS (parent_class)->free (undo, undo_mode);
|
||||
}
|
||||
|
@@ -38,7 +38,7 @@ struct _GimpDrawableFilterUndo
|
||||
GimpUndo parent_instance;
|
||||
|
||||
GimpDrawableFilter *filter;
|
||||
guint32 row_index;
|
||||
gint row_index;
|
||||
|
||||
GeglNode *node;
|
||||
gdouble opacity;
|
||||
|
@@ -47,6 +47,7 @@ static void gimp_drawable_stack_remove (GimpContainer *container
|
||||
GimpObject *object);
|
||||
static void gimp_drawable_stack_reorder (GimpContainer *container,
|
||||
GimpObject *object,
|
||||
gint old_index,
|
||||
gint new_index);
|
||||
|
||||
static void gimp_drawable_stack_drawable_update (GimpItem *item,
|
||||
@@ -104,7 +105,7 @@ gimp_drawable_stack_constructed (GObject *object)
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
|
||||
gimp_assert (g_type_is_a (gimp_container_get_children_type (container),
|
||||
gimp_assert (g_type_is_a (gimp_container_get_child_type (container),
|
||||
GIMP_TYPE_DRAWABLE));
|
||||
|
||||
gimp_container_add_handler (container, "update",
|
||||
@@ -142,11 +143,13 @@ gimp_drawable_stack_remove (GimpContainer *container,
|
||||
static void
|
||||
gimp_drawable_stack_reorder (GimpContainer *container,
|
||||
GimpObject *object,
|
||||
gint old_index,
|
||||
gint new_index)
|
||||
{
|
||||
GimpDrawableStack *stack = GIMP_DRAWABLE_STACK (container);
|
||||
|
||||
GIMP_CONTAINER_CLASS (parent_class)->reorder (container, object, new_index);
|
||||
GIMP_CONTAINER_CLASS (parent_class)->reorder (container, object,
|
||||
old_index, new_index);
|
||||
|
||||
if (gimp_filter_get_active (GIMP_FILTER (object)))
|
||||
gimp_drawable_stack_drawable_active (GIMP_ITEM (object), stack);
|
||||
@@ -161,9 +164,9 @@ gimp_drawable_stack_new (GType drawable_type)
|
||||
g_return_val_if_fail (g_type_is_a (drawable_type, GIMP_TYPE_DRAWABLE), NULL);
|
||||
|
||||
return g_object_new (GIMP_TYPE_DRAWABLE_STACK,
|
||||
"name", g_type_name (drawable_type),
|
||||
"children-type", drawable_type,
|
||||
"policy", GIMP_CONTAINER_POLICY_STRONG,
|
||||
"name", g_type_name (drawable_type),
|
||||
"child-type", drawable_type,
|
||||
"policy", GIMP_CONTAINER_POLICY_STRONG,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@@ -20,7 +20,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <appstream-glib.h>
|
||||
#include <appstream.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gegl.h>
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
@@ -45,11 +46,12 @@ enum
|
||||
|
||||
struct _GimpExtensionPrivate
|
||||
{
|
||||
gchar *path;
|
||||
gchar *path;
|
||||
|
||||
AsApp *app;
|
||||
gboolean writable;
|
||||
gboolean running;
|
||||
AsMetadata *metadata;
|
||||
AsComponent *component;
|
||||
gboolean writable;
|
||||
gboolean running;
|
||||
|
||||
/* Extension metadata: directories. */
|
||||
GList *brush_paths;
|
||||
@@ -144,8 +146,7 @@ gimp_extension_finalize (GObject *object)
|
||||
gimp_extension_clean (extension);
|
||||
|
||||
g_free (extension->p->path);
|
||||
if (extension->p->app)
|
||||
g_object_unref (extension->p->app);
|
||||
g_clear_object (&extension->p->metadata);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
@@ -222,31 +223,26 @@ gimp_extension_new (const gchar *dir,
|
||||
const gchar *
|
||||
gimp_extension_get_name (GimpExtension *extension)
|
||||
{
|
||||
g_return_val_if_fail (extension->p->app != NULL, NULL);
|
||||
g_return_val_if_fail (extension->p->component != NULL, NULL);
|
||||
|
||||
return as_app_get_name (extension->p->app, g_getenv ("LANGUAGE")) ?
|
||||
as_app_get_name (extension->p->app, g_getenv ("LANGUAGE")) :
|
||||
as_app_get_name (extension->p->app, NULL);
|
||||
return as_component_get_name (extension->p->component);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
gimp_extension_get_comment (GimpExtension *extension)
|
||||
{
|
||||
g_return_val_if_fail (extension->p->app != NULL, NULL);
|
||||
|
||||
return as_app_get_comment (extension->p->app, g_getenv ("LANGUAGE")) ?
|
||||
as_app_get_comment (extension->p->app, g_getenv ("LANGUAGE")) :
|
||||
as_app_get_comment (extension->p->app, NULL);
|
||||
g_return_val_if_fail (extension->p->component != NULL, NULL);
|
||||
|
||||
return as_component_get_summary (extension->p->component);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
gimp_extension_get_description (GimpExtension *extension)
|
||||
{
|
||||
g_return_val_if_fail (extension->p->app != NULL, NULL);
|
||||
g_return_val_if_fail (extension->p->component != NULL, NULL);
|
||||
|
||||
return as_app_get_description (extension->p->app, g_getenv ("LANGUAGE")) ?
|
||||
as_app_get_description (extension->p->app, g_getenv ("LANGUAGE")) :
|
||||
as_app_get_description (extension->p->app, NULL);
|
||||
return as_component_get_description (extension->p->component);
|
||||
}
|
||||
|
||||
GdkPixbuf *
|
||||
@@ -255,30 +251,74 @@ gimp_extension_get_screenshot (GimpExtension *extension,
|
||||
gint height,
|
||||
const gchar **caption)
|
||||
{
|
||||
GdkPixbuf *pixbuf = NULL;
|
||||
AsScreenshot *screenshot;
|
||||
GdkPixbuf *pixbuf = NULL;
|
||||
AsScreenshot *screenshot = NULL;
|
||||
const GPtrArray *screenshots;
|
||||
|
||||
g_return_val_if_fail (extension->p->app != NULL, NULL);
|
||||
g_return_val_if_fail (extension->p->component != NULL, NULL);
|
||||
|
||||
#if AS_CHECK_VERSION(1, 0, 0)
|
||||
screenshots = as_component_get_screenshots_all (extension->p->component);
|
||||
#else
|
||||
screenshots = as_component_get_screenshots (extension->p->component);
|
||||
#endif
|
||||
|
||||
if (screenshots == NULL || screenshots->len == 0)
|
||||
{
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
/* Look for the screenshot marked as default */
|
||||
for (guint i = 0; i < screenshots->len; i++)
|
||||
{
|
||||
AsScreenshot *ss = g_ptr_array_index (screenshots, i);
|
||||
if (as_screenshot_get_kind (ss) == AS_SCREENSHOT_KIND_DEFAULT)
|
||||
{
|
||||
screenshot = ss;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (screenshot == NULL)
|
||||
{
|
||||
g_printerr (_("Invalid AppStream metadata: failed to find default screenshot for extension \"%s\""),
|
||||
as_component_get_id (extension->p->component));
|
||||
}
|
||||
|
||||
screenshot = as_app_get_screenshot_default (extension->p->app);
|
||||
if (screenshot)
|
||||
{
|
||||
AsImage *image;
|
||||
AsImage *image = NULL;
|
||||
GFile *file = NULL;
|
||||
GFileInputStream *istream = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
image = as_screenshot_get_image_for_locale (screenshot, g_getenv ("LANGUAGE"), width, height);
|
||||
if (! image)
|
||||
image = as_screenshot_get_image_for_locale (screenshot, NULL, width, height);
|
||||
#if AS_CHECK_VERSION(1, 0, 0)
|
||||
image = as_screenshot_get_image (screenshot, width, height, 1);
|
||||
#else
|
||||
image = as_screenshot_get_image (screenshot, width, height);
|
||||
#endif
|
||||
|
||||
file = g_file_new_for_uri (as_image_get_url (image));
|
||||
istream = g_file_read (file, NULL, &error);
|
||||
if (istream != NULL)
|
||||
{
|
||||
pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (istream), NULL, &error);
|
||||
}
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
g_printerr (_("Invalid AppStream metadata: Error loading image: \"%s\""), error->message);
|
||||
}
|
||||
|
||||
pixbuf = as_image_get_pixbuf (image);
|
||||
if (pixbuf)
|
||||
{
|
||||
g_object_ref (pixbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *file;
|
||||
GFileInputStream *istream;
|
||||
GError *error = NULL;
|
||||
GFile *file = NULL;
|
||||
GFileInputStream *istream = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
file = g_file_new_for_uri (as_image_get_url (image));
|
||||
istream = g_file_read (file, NULL, &error);
|
||||
@@ -298,9 +338,7 @@ gimp_extension_get_screenshot (GimpExtension *extension,
|
||||
|
||||
if (caption)
|
||||
{
|
||||
*caption = as_screenshot_get_caption (screenshot, g_getenv ("LANGUAGE"));
|
||||
if (*caption == NULL)
|
||||
*caption = as_screenshot_get_caption (screenshot, NULL);
|
||||
*caption = as_screenshot_get_caption (screenshot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,16 +369,29 @@ gboolean
|
||||
gimp_extension_load (GimpExtension *extension,
|
||||
GError **error)
|
||||
{
|
||||
AsApp *app;
|
||||
GPtrArray *extends;
|
||||
GPtrArray *requires;
|
||||
AsRelease *release;
|
||||
gchar *appdata_name;
|
||||
gchar *path;
|
||||
gboolean success = FALSE;
|
||||
gboolean has_require = FALSE;
|
||||
AsMetadata *metadata;
|
||||
AsComponent *component;
|
||||
#if AS_CHECK_VERSION(1, 0, 0)
|
||||
AsComponentBox *components = NULL;
|
||||
#else
|
||||
GPtrArray *components = NULL;
|
||||
#endif
|
||||
GPtrArray *extends;
|
||||
GPtrArray *relations;
|
||||
AsRelease *release = NULL;
|
||||
#if AS_CHECK_VERSION(1, 0, 0)
|
||||
AsReleaseList *rlist = NULL;
|
||||
#else
|
||||
GPtrArray *rlist = NULL;
|
||||
#endif
|
||||
gchar *appdata_name;
|
||||
gchar *path;
|
||||
GFile *file;
|
||||
gboolean success = FALSE;
|
||||
gboolean has_require = FALSE;
|
||||
|
||||
g_clear_object (&extension->p->app);
|
||||
g_clear_object (&extension->p->metadata);
|
||||
extension->p->component = NULL;
|
||||
|
||||
/* Search in subdirectory if a file with the same name as
|
||||
* directory and ending with ".metainfo.xml" exists.
|
||||
@@ -350,12 +401,32 @@ gimp_extension_load (GimpExtension *extension,
|
||||
path = g_build_filename (extension->p->path, appdata_name, NULL);
|
||||
g_free (appdata_name);
|
||||
|
||||
app = as_app_new ();
|
||||
success = as_app_parse_file (app, path,
|
||||
AS_APP_PARSE_FLAG_USE_HEURISTICS,
|
||||
error);
|
||||
file = g_file_new_for_path (path);
|
||||
|
||||
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);
|
||||
#else
|
||||
components = as_metadata_get_components (metadata);
|
||||
component = g_ptr_array_index (components, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
g_free (path);
|
||||
if (success && as_app_get_kind (app) != AS_APP_KIND_ADDON)
|
||||
|
||||
if (!success)
|
||||
{
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
if (success && as_component_get_kind (component) != AS_COMPONENT_KIND_ADDON)
|
||||
{
|
||||
/* Properly setting the type will allow extensions to be
|
||||
* distributed appropriately through other means.
|
||||
@@ -364,11 +435,11 @@ gimp_extension_load (GimpExtension *extension,
|
||||
*error = g_error_new (GIMP_EXTENSION_ERROR,
|
||||
GIMP_EXTENSION_BAD_APPDATA,
|
||||
_("Extension AppData must be of type \"addon\", found \"%s\" instead."),
|
||||
as_app_kind_to_string (as_app_get_kind (app)));
|
||||
as_component_kind_to_string (as_component_get_kind (component)));
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
extends = as_app_get_extends (app);
|
||||
extends = as_component_get_extends (component);
|
||||
if (success &&
|
||||
! g_ptr_array_find_with_equal_func (extends, "org.gimp.GIMP",
|
||||
g_str_equal, NULL))
|
||||
@@ -384,7 +455,7 @@ gimp_extension_load (GimpExtension *extension,
|
||||
}
|
||||
|
||||
if (success &&
|
||||
g_strcmp0 (as_app_get_id (app),
|
||||
g_strcmp0 (as_component_get_id (component),
|
||||
gimp_object_get_name (extension)) != 0)
|
||||
{
|
||||
/* Extension IDs will be unique and we want therefore the
|
||||
@@ -394,11 +465,24 @@ gimp_extension_load (GimpExtension *extension,
|
||||
*error = g_error_new (GIMP_EXTENSION_ERROR,
|
||||
GIMP_EXTENSION_FAILED,
|
||||
_("Extension AppData id (\"%s\") and directory (\"%s\") must be the same."),
|
||||
as_app_get_id (app), gimp_object_get_name (extension));
|
||||
as_component_get_id (component), gimp_object_get_name (extension));
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
release = as_app_get_release_default (app);
|
||||
#if AS_CHECK_VERSION(1, 0, 0)
|
||||
rlist = as_component_get_releases_plain (component);
|
||||
if (rlist != NULL && !as_release_list_is_empty (rlist))
|
||||
{
|
||||
release = as_release_list_index (rlist, 0);
|
||||
}
|
||||
#else
|
||||
rlist = as_component_get_releases (component);
|
||||
if (rlist != NULL && rlist->len > 0)
|
||||
{
|
||||
release = g_ptr_array_index (rlist, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (success && (! release || ! as_release_get_version (release)))
|
||||
{
|
||||
/* We don't need the detail, just to know that the extension has a
|
||||
@@ -412,24 +496,19 @@ gimp_extension_load (GimpExtension *extension,
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
requires = as_app_get_requires (app);
|
||||
if (success && requires)
|
||||
relations = as_component_get_requires (component);
|
||||
if (success && relations != NULL)
|
||||
{
|
||||
gint i;
|
||||
|
||||
/* An extension could set requirements, in particular a range of
|
||||
* supported version of GIMP, but also other extensions.
|
||||
*/
|
||||
|
||||
for (i = 0; i < requires->len; i++)
|
||||
for (guint i = 0; i < relations->len; i++)
|
||||
{
|
||||
AsRequire *require = g_ptr_array_index (requires, i);
|
||||
AsRelation *relation = g_ptr_array_index(relations, i);
|
||||
|
||||
if (as_require_get_kind (require) == AS_REQUIRE_KIND_ID &&
|
||||
g_strcmp0 (as_require_get_value (require), "org.gimp.GIMP") == 0)
|
||||
if (as_relation_get_item_kind(relation) == AS_RELATION_ITEM_KIND_ID &&
|
||||
g_strcmp0(as_relation_get_value_str(relation), "org.gimp.GIMP") == 0)
|
||||
{
|
||||
has_require = TRUE;
|
||||
if (! as_require_version_compare (require, GIMP_VERSION, error))
|
||||
|
||||
if (! as_relation_version_compare (relation, GIMP_VERSION, error))
|
||||
{
|
||||
success = FALSE;
|
||||
break;
|
||||
@@ -437,14 +516,11 @@ gimp_extension_load (GimpExtension *extension,
|
||||
}
|
||||
else if (error && *error == NULL)
|
||||
{
|
||||
/* Right now we only support requirement relative to GIMP
|
||||
* version.
|
||||
*/
|
||||
*error = g_error_new (GIMP_EXTENSION_ERROR,
|
||||
GIMP_EXTENSION_FAILED,
|
||||
_("Unsupported <requires> \"%s\" (type %s)."),
|
||||
as_require_get_value (require),
|
||||
as_require_kind_to_string (as_require_get_kind (require)));
|
||||
_("Unsupported <relation> \"%s\" (type %s)."),
|
||||
as_relation_get_value_str(relation),
|
||||
as_relation_item_kind_to_string(as_relation_get_item_kind(relation)));
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
@@ -462,9 +538,14 @@ gimp_extension_load (GimpExtension *extension,
|
||||
}
|
||||
|
||||
if (success)
|
||||
extension->p->app = app;
|
||||
{
|
||||
extension->p->metadata = metadata;
|
||||
extension->p->component = component;
|
||||
}
|
||||
else
|
||||
g_object_unref (app);
|
||||
{
|
||||
g_clear_object (&metadata);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
@@ -476,11 +557,11 @@ gimp_extension_run (GimpExtension *extension,
|
||||
GHashTable *metadata;
|
||||
gchar *value;
|
||||
|
||||
g_return_val_if_fail (extension->p->app != NULL, FALSE);
|
||||
g_return_val_if_fail (extension->p->component != NULL, FALSE);
|
||||
g_return_val_if_fail (error && *error == NULL, FALSE);
|
||||
|
||||
gimp_extension_clean (extension);
|
||||
metadata = as_app_get_metadata (extension->p->app);
|
||||
metadata = as_component_get_custom (extension->p->component);
|
||||
|
||||
value = g_hash_table_lookup (metadata, "GIMP::brush-path");
|
||||
extension->p->brush_paths = gimp_extension_validate_paths (extension,
|
||||
@@ -738,7 +819,7 @@ gimp_extension_validate_paths (GimpExtension *extension,
|
||||
|
||||
for (i = 0; patharray[i]; i++)
|
||||
{
|
||||
/* Note: appstream-glib is supposed to return everything as UTF-8,
|
||||
/* Note: appstream is supposed to return everything as UTF-8,
|
||||
* so we should not have to bother about this. */
|
||||
gchar *path;
|
||||
GFile *file;
|
||||
|
@@ -56,8 +56,7 @@ GimpFillStyle gimp_fill_options_get_style (GimpFillOptions *optio
|
||||
void gimp_fill_options_set_style (GimpFillOptions *options,
|
||||
GimpFillStyle style);
|
||||
|
||||
GimpCustomStyle gimp_fill_options_get_custom_style
|
||||
(GimpFillOptions *options);
|
||||
GimpCustomStyle gimp_fill_options_get_custom_style (GimpFillOptions *options);
|
||||
void gimp_fill_options_set_custom_style (GimpFillOptions *options,
|
||||
GimpCustomStyle custom_style);
|
||||
|
||||
|
@@ -57,7 +57,8 @@ struct _GimpFilterPrivate
|
||||
GimpApplicator *applicator;
|
||||
};
|
||||
|
||||
#define GET_PRIVATE(filter) ((GimpFilterPrivate *) gimp_filter_get_instance_private ((GimpFilter *) (filter)))
|
||||
#define GET_PRIVATE(filter) \
|
||||
((GimpFilterPrivate *) gimp_filter_get_instance_private ((GimpFilter *) (filter)))
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
@@ -223,12 +224,10 @@ gimp_filter_new (const gchar *name)
|
||||
GeglNode *
|
||||
gimp_filter_get_node (GimpFilter *filter)
|
||||
{
|
||||
GimpFilterPrivate *private;
|
||||
GimpFilterPrivate *private = GET_PRIVATE (filter);
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_FILTER (filter), NULL);
|
||||
|
||||
private = GET_PRIVATE (filter);
|
||||
|
||||
if (private->node)
|
||||
return private->node;
|
||||
|
||||
@@ -297,12 +296,10 @@ void
|
||||
gimp_filter_set_applicator (GimpFilter *filter,
|
||||
GimpApplicator *applicator)
|
||||
{
|
||||
GimpFilterPrivate *private;
|
||||
GimpFilterPrivate *private = GET_PRIVATE (filter);
|
||||
|
||||
g_return_if_fail (GIMP_IS_FILTER (filter));
|
||||
|
||||
private = GET_PRIVATE (filter);
|
||||
|
||||
private->applicator = applicator;
|
||||
}
|
||||
|
||||
|
@@ -24,21 +24,13 @@
|
||||
#include "gimpviewable.h"
|
||||
|
||||
|
||||
#define GIMP_TYPE_FILTER (gimp_filter_get_type ())
|
||||
#define GIMP_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_FILTER, GimpFilter))
|
||||
#define GIMP_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_FILTER, GimpFilterClass))
|
||||
#define GIMP_IS_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_FILTER))
|
||||
#define GIMP_IS_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_FILTER))
|
||||
#define GIMP_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_FILTER, GimpFilterClass))
|
||||
#define GIMP_TYPE_FILTER (gimp_filter_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (GimpFilter,
|
||||
gimp_filter,
|
||||
GIMP, FILTER,
|
||||
GimpViewable)
|
||||
|
||||
|
||||
typedef struct _GimpFilterClass GimpFilterClass;
|
||||
|
||||
struct _GimpFilter
|
||||
{
|
||||
GimpViewable parent_instance;
|
||||
};
|
||||
|
||||
struct _GimpFilterClass
|
||||
{
|
||||
GimpViewableClass parent_class;
|
||||
|
@@ -60,6 +60,9 @@ static void gimp_filtered_container_real_src_thaw (GimpFilteredContainer *
|
||||
|
||||
static gboolean gimp_filtered_container_object_matches (GimpFilteredContainer *filtered_container,
|
||||
GimpObject *object);
|
||||
static void gimp_filtered_container_src_sort_func (GimpContainer *src,
|
||||
GParamSpec *pspec,
|
||||
GimpFilteredContainer *filtered_container);
|
||||
static void gimp_filtered_container_src_add (GimpContainer *src_container,
|
||||
GimpObject *obj,
|
||||
GimpFilteredContainer *filtered_container);
|
||||
@@ -148,6 +151,9 @@ gimp_filtered_container_dispose (GObject *object)
|
||||
|
||||
if (filtered_container->src_container)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (filtered_container->src_container,
|
||||
gimp_filtered_container_src_sort_func,
|
||||
filtered_container);
|
||||
g_signal_handlers_disconnect_by_func (filtered_container->src_container,
|
||||
gimp_filtered_container_src_add,
|
||||
filtered_container);
|
||||
@@ -188,6 +194,9 @@ gimp_filtered_container_set_property (GObject *object,
|
||||
case PROP_SRC_CONTAINER:
|
||||
filtered_container->src_container = g_value_dup_object (value);
|
||||
|
||||
g_signal_connect (filtered_container->src_container, "notify::sort-func",
|
||||
G_CALLBACK (gimp_filtered_container_src_sort_func),
|
||||
filtered_container);
|
||||
g_signal_connect (filtered_container->src_container, "add",
|
||||
G_CALLBACK (gimp_filtered_container_src_add),
|
||||
filtered_container);
|
||||
@@ -304,17 +313,17 @@ gimp_filtered_container_new (GimpContainer *src_container,
|
||||
GimpObjectFilterFunc filter_func,
|
||||
gpointer filter_data)
|
||||
{
|
||||
GType children_type;
|
||||
GType child_type;
|
||||
GCompareFunc sort_func;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_LIST (src_container), NULL);
|
||||
|
||||
children_type = gimp_container_get_children_type (src_container);
|
||||
sort_func = gimp_list_get_sort_func (GIMP_LIST (src_container));
|
||||
child_type = gimp_container_get_child_type (src_container);
|
||||
sort_func = gimp_list_get_sort_func (GIMP_LIST (src_container));
|
||||
|
||||
return g_object_new (GIMP_TYPE_FILTERED_CONTAINER,
|
||||
"sort-func", sort_func,
|
||||
"children-type", children_type,
|
||||
"child-type", child_type,
|
||||
"policy", GIMP_CONTAINER_POLICY_WEAK,
|
||||
"unique-names", FALSE,
|
||||
"src-container", src_container,
|
||||
@@ -332,6 +341,16 @@ gimp_filtered_container_object_matches (GimpFilteredContainer *filtered_containe
|
||||
filtered_container->filter_data));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_filtered_container_src_sort_func (GimpContainer *src,
|
||||
GParamSpec *pspec,
|
||||
GimpFilteredContainer *filtered_container)
|
||||
{
|
||||
GCompareFunc sort_func = gimp_list_get_sort_func (GIMP_LIST (src));
|
||||
|
||||
gimp_list_set_sort_func (GIMP_LIST (filtered_container), sort_func);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_filtered_container_src_add (GimpContainer *src_container,
|
||||
GimpObject *object,
|
||||
|
@@ -40,6 +40,7 @@ static void gimp_filter_stack_remove (GimpContainer *container,
|
||||
GimpObject *object);
|
||||
static void gimp_filter_stack_reorder (GimpContainer *container,
|
||||
GimpObject *object,
|
||||
gint old_index,
|
||||
gint new_index);
|
||||
|
||||
static void gimp_filter_stack_add_node (GimpFilterStack *stack,
|
||||
@@ -83,7 +84,7 @@ gimp_filter_stack_constructed (GObject *object)
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
|
||||
gimp_assert (g_type_is_a (gimp_container_get_children_type (container),
|
||||
gimp_assert (g_type_is_a (gimp_container_get_child_type (container),
|
||||
GIMP_TYPE_FILTER));
|
||||
|
||||
gimp_container_add_handler (container, "active-changed",
|
||||
@@ -147,6 +148,7 @@ gimp_filter_stack_remove (GimpContainer *container,
|
||||
static void
|
||||
gimp_filter_stack_reorder (GimpContainer *container,
|
||||
GimpObject *object,
|
||||
gint old_index,
|
||||
gint new_index)
|
||||
{
|
||||
GimpFilterStack *stack = GIMP_FILTER_STACK (container);
|
||||
@@ -155,7 +157,8 @@ gimp_filter_stack_reorder (GimpContainer *container,
|
||||
if (stack->graph && gimp_filter_get_active (filter))
|
||||
gimp_filter_stack_remove_node (stack, filter);
|
||||
|
||||
GIMP_CONTAINER_CLASS (parent_class)->reorder (container, object, new_index);
|
||||
GIMP_CONTAINER_CLASS (parent_class)->reorder (container, object,
|
||||
old_index, new_index);
|
||||
|
||||
if (gimp_filter_get_active (filter))
|
||||
{
|
||||
@@ -175,9 +178,9 @@ gimp_filter_stack_new (GType filter_type)
|
||||
g_return_val_if_fail (g_type_is_a (filter_type, GIMP_TYPE_FILTER), NULL);
|
||||
|
||||
return g_object_new (GIMP_TYPE_FILTER_STACK,
|
||||
"name", g_type_name (filter_type),
|
||||
"children-type", filter_type,
|
||||
"policy", GIMP_CONTAINER_POLICY_STRONG,
|
||||
"name", g_type_name (filter_type),
|
||||
"child-type", filter_type,
|
||||
"policy", GIMP_CONTAINER_POLICY_STRONG,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@@ -35,6 +35,8 @@
|
||||
#include "gimptagged.h"
|
||||
#include "gimptempbuf.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
#define EPSILON 1e-10
|
||||
|
||||
@@ -60,7 +62,8 @@ static gboolean gimp_gradient_get_popup_size (GimpViewable *viewa
|
||||
static GimpTempBuf * gimp_gradient_get_new_preview (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height);
|
||||
gint height,
|
||||
GeglColor *fg_color);
|
||||
|
||||
static const gchar * gimp_gradient_get_extension (GimpData *data);
|
||||
static void gimp_gradient_copy (GimpData *data,
|
||||
@@ -118,6 +121,7 @@ gimp_gradient_class_init (GimpGradientClass *klass)
|
||||
gimp_object_class->get_memsize = gimp_gradient_get_memsize;
|
||||
|
||||
viewable_class->default_icon_name = "gimp-tool-gradient";
|
||||
viewable_class->default_name = _("Gradient");
|
||||
viewable_class->get_preview_size = gimp_gradient_get_preview_size;
|
||||
viewable_class->get_popup_size = gimp_gradient_get_popup_size;
|
||||
viewable_class->get_new_preview = gimp_gradient_get_new_preview;
|
||||
@@ -213,7 +217,8 @@ static GimpTempBuf *
|
||||
gimp_gradient_get_new_preview (GimpViewable *viewable,
|
||||
GimpContext *context,
|
||||
gint width,
|
||||
gint height)
|
||||
gint height,
|
||||
GeglColor *fg_color G_GNUC_UNUSED)
|
||||
{
|
||||
GimpGradient *gradient = GIMP_GRADIENT (viewable);
|
||||
GimpGradientSegment *seg = NULL;
|
||||
|
@@ -33,9 +33,7 @@
|
||||
#include "gegl/gimp-babl.h"
|
||||
#include "gegl/gimp-gegl-loops.h"
|
||||
|
||||
#include "gimpchannel.h"
|
||||
#include "gimpdrawable-filters.h"
|
||||
#include "gimpdrawablefilter.h"
|
||||
#include "gimpgrouplayer.h"
|
||||
#include "gimpgrouplayerundo.h"
|
||||
#include "gimpimage.h"
|
||||
@@ -277,6 +275,7 @@ gimp_group_layer_class_init (GimpGroupLayerClass *klass)
|
||||
gimp_object_class->get_memsize = gimp_group_layer_get_memsize;
|
||||
|
||||
viewable_class->default_icon_name = "gimp-group-layer";
|
||||
viewable_class->default_name = _("Layer Group");
|
||||
viewable_class->ancestry_changed = gimp_group_layer_ancestry_changed;
|
||||
viewable_class->get_size = gimp_group_layer_get_size;
|
||||
viewable_class->get_children = gimp_group_layer_get_children;
|
||||
@@ -291,7 +290,6 @@ gimp_group_layer_class_init (GimpGroupLayerClass *klass)
|
||||
item_class->resize = gimp_group_layer_resize;
|
||||
item_class->get_clip = gimp_group_layer_get_clip;
|
||||
|
||||
item_class->default_name = _("Layer Group");
|
||||
item_class->rename_desc = C_("undo-type", "Rename Layer Group");
|
||||
item_class->translate_desc = C_("undo-type", "Move Layer Group");
|
||||
item_class->scale_desc = C_("undo-type", "Scale Layer Group");
|
||||
@@ -594,7 +592,6 @@ gimp_group_layer_duplicate (GimpItem *item,
|
||||
GimpItem *child = list->data;
|
||||
GimpItem *new_child;
|
||||
GimpLayerMask *mask;
|
||||
GimpContainer *filters;
|
||||
|
||||
new_child = gimp_item_duplicate (child, G_TYPE_FROM_INSTANCE (child));
|
||||
|
||||
@@ -619,36 +616,6 @@ gimp_group_layer_duplicate (GimpItem *item,
|
||||
gimp_container_insert (new_private->children,
|
||||
GIMP_OBJECT (new_child),
|
||||
position++);
|
||||
|
||||
/* Copy any attached layer effects */
|
||||
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (child));
|
||||
if (gimp_container_get_n_children (filters) > 0)
|
||||
{
|
||||
GList *filter_list;
|
||||
|
||||
for (filter_list = GIMP_LIST (filters)->queue->tail; filter_list;
|
||||
filter_list = g_list_previous (filter_list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (filter_list->data))
|
||||
{
|
||||
GimpDrawableFilter *old_filter = filter_list->data;
|
||||
GimpDrawableFilter *filter;
|
||||
|
||||
filter =
|
||||
gimp_drawable_filter_duplicate (GIMP_DRAWABLE (new_child),
|
||||
old_filter);
|
||||
|
||||
if (filter != NULL)
|
||||
{
|
||||
gimp_drawable_filter_apply (filter, NULL);
|
||||
gimp_drawable_filter_commit (filter, TRUE, NULL, FALSE);
|
||||
|
||||
gimp_drawable_filter_layer_mask_freeze (filter);
|
||||
g_object_unref (filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* force the projection to reallocate itself */
|
||||
@@ -2002,7 +1969,6 @@ gimp_group_layer_update_size (GimpGroupLayer *group)
|
||||
gboolean size_changed;
|
||||
gboolean resize_mask;
|
||||
GList *list;
|
||||
GimpContainer *filters;
|
||||
|
||||
old_bounds.x = gimp_item_get_offset_x (item);
|
||||
old_bounds.y = gimp_item_get_offset_y (item);
|
||||
@@ -2137,29 +2103,6 @@ gimp_group_layer_update_size (GimpGroupLayer *group)
|
||||
if (resize_mask && ! private->transforming)
|
||||
gimp_group_layer_update_mask_size (group);
|
||||
|
||||
/* Update the crop of any filters */
|
||||
if (size_changed)
|
||||
{
|
||||
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (group));
|
||||
for (list = GIMP_LIST (filters)->queue->tail;
|
||||
list; list = g_list_previous (list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (list->data))
|
||||
{
|
||||
GimpDrawableFilter *filter = list->data;
|
||||
GimpChannel *filter_mask;
|
||||
|
||||
filter_mask = GIMP_CHANNEL (gimp_drawable_filter_get_mask (filter));
|
||||
|
||||
/* Don't resize partial layer effects */
|
||||
if (gimp_channel_is_empty (filter_mask))
|
||||
gimp_drawable_filter_refresh_crop (filter, &bounding_box);
|
||||
}
|
||||
}
|
||||
if (list)
|
||||
g_list_free (list);
|
||||
}
|
||||
|
||||
/* if we show the mask, invalidate the new mask area */
|
||||
if (resize_mask && gimp_layer_get_show_mask (layer))
|
||||
{
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -95,7 +95,7 @@ gimp_image_crop (GimpImage *image,
|
||||
width, height, -x, -y);
|
||||
}
|
||||
|
||||
/* Resize all vectors */
|
||||
/* Resize all paths */
|
||||
for (list = gimp_image_get_path_iter (image);
|
||||
list;
|
||||
list = g_list_next (list))
|
||||
|
@@ -30,8 +30,6 @@
|
||||
|
||||
#include "gimp.h"
|
||||
#include "gimpchannel.h"
|
||||
#include "gimpdrawable-filters.h"
|
||||
#include "gimpdrawablefilter.h"
|
||||
#include "gimpguide.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-color-profile.h"
|
||||
@@ -259,9 +257,8 @@ gimp_image_duplicate_layers (GimpImage *image,
|
||||
list;
|
||||
list = g_list_next (list))
|
||||
{
|
||||
GimpLayer *layer = list->data;
|
||||
GimpLayer *new_layer;
|
||||
GimpContainer *filters;
|
||||
GimpLayer *layer = list->data;
|
||||
GimpLayer *new_layer;
|
||||
|
||||
if (gimp_layer_is_floating_sel (layer))
|
||||
continue;
|
||||
@@ -278,36 +275,6 @@ gimp_image_duplicate_layers (GimpImage *image,
|
||||
|
||||
gimp_image_add_layer (new_image, new_layer,
|
||||
NULL, count++, FALSE);
|
||||
|
||||
/* Import any attached layer effects */
|
||||
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (layer));
|
||||
if (gimp_container_get_n_children (filters) > 0)
|
||||
{
|
||||
GList *filter_list;
|
||||
|
||||
for (filter_list = GIMP_LIST (filters)->queue->tail; filter_list;
|
||||
filter_list = g_list_previous (filter_list))
|
||||
{
|
||||
if (GIMP_IS_DRAWABLE_FILTER (filter_list->data))
|
||||
{
|
||||
GimpDrawableFilter *old_filter = filter_list->data;
|
||||
GimpDrawableFilter *filter;
|
||||
|
||||
filter =
|
||||
gimp_drawable_filter_duplicate (GIMP_DRAWABLE (new_layer),
|
||||
old_filter);
|
||||
|
||||
if (filter != NULL)
|
||||
{
|
||||
gimp_drawable_filter_apply (filter, NULL);
|
||||
gimp_drawable_filter_commit (filter, TRUE, NULL, FALSE);
|
||||
|
||||
gimp_drawable_filter_layer_mask_freeze (filter);
|
||||
g_object_unref (filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new_item_stack = GIMP_ITEM_STACK (gimp_image_get_layers (new_image));
|
||||
|
@@ -230,7 +230,7 @@ gimp_image_flip_full (GimpImage *image,
|
||||
|
||||
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_FLIP, NULL);
|
||||
|
||||
/* Flip all layers, channels (including selection mask), and vectors */
|
||||
/* Flip all layers, channels (including selection mask), and paths */
|
||||
while ((item = gimp_object_queue_pop (queue)))
|
||||
{
|
||||
gboolean clip = FALSE;
|
||||
|
@@ -361,8 +361,8 @@ gimp_image_item_list_get_list (GimpImage *image,
|
||||
}
|
||||
|
||||
static GList *
|
||||
gimp_image_item_list_remove_children (GList *list,
|
||||
const GimpItem *parent)
|
||||
gimp_image_item_list_remove_children (GList *list,
|
||||
GimpItem *parent)
|
||||
{
|
||||
GList *l = list;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user