mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-10-06 01:12:40 +02:00
Compare commits
315 Commits
9cc7ebba01
...
GIMP_2_2_8
Author | SHA1 | Date | |
---|---|---|---|
|
193fbc4e80 | ||
|
1293e78a67 | ||
|
8c7fdf2157 | ||
|
3aedadf462 | ||
|
8938c3737d | ||
|
87cdf69786 | ||
|
7c19fa6e74 | ||
|
5bf6c3c1bf | ||
|
9cc952baac | ||
|
ea74d83f19 | ||
|
770f4a3b84 | ||
|
d1c1a93a0b | ||
|
f59b6fe473 | ||
|
7b2276fb8d | ||
|
ceba721eb3 | ||
|
d2a3278827 | ||
|
7baebf7ec2 | ||
|
86d34fabf3 | ||
|
507faf7f28 | ||
|
e8bc9214f8 | ||
|
c33624d86c | ||
|
b355ab7008 | ||
|
09b663fe70 | ||
|
b082f3197e | ||
|
88a3456a29 | ||
|
0579d2d361 | ||
|
efc1b54727 | ||
|
b42c67d06f | ||
|
ca2dbf109f | ||
|
f286de2805 | ||
|
641fea3772 | ||
|
cdbd8ca5d7 | ||
|
48c653540c | ||
|
7d53336fe9 | ||
|
afbf378c73 | ||
|
437ede8ff9 | ||
|
9a35cd912e | ||
|
21e090f63c | ||
|
22e8d1543d | ||
|
845226cc89 | ||
|
2363344318 | ||
|
1e44e2326f | ||
|
51cb989c4c | ||
|
d84bcaca4a | ||
|
3c1154f835 | ||
|
494750b815 | ||
|
c459becec8 | ||
|
2a8e4a82e8 | ||
|
c994a08843 | ||
|
4510e68102 | ||
|
90f232fe51 | ||
|
6ddeff0a80 | ||
|
97c5038054 | ||
|
0fbbed49a6 | ||
|
75149a0294 | ||
|
6cbdd96808 | ||
|
2f334ee42f | ||
|
d0d63c11d2 | ||
|
3445cc286d | ||
|
6720b00204 | ||
|
376de4b173 | ||
|
0662242ae1 | ||
|
3f9e165696 | ||
|
79a36287bf | ||
|
268c18fd3e | ||
|
9cf0604d13 | ||
|
7a307cd5a3 | ||
|
df9333eb76 | ||
|
90f6cdbce7 | ||
|
643b13587a | ||
|
c1490f8c03 | ||
|
1cc7eb4845 | ||
|
c761756217 | ||
|
7b64d714e0 | ||
|
eb8cb546ae | ||
|
5da54083fb | ||
|
ae93b75e62 | ||
|
9a490d3da2 | ||
|
c174fb5a70 | ||
|
f6ebde014a | ||
|
e15d500ba4 | ||
|
8c6622bbf2 | ||
|
7464438741 | ||
|
fbd577183a | ||
|
11f28c93bc | ||
|
809dfc1843 | ||
|
4ebab399d0 | ||
|
3005882fd7 | ||
|
3f4e0df0ad | ||
|
d924f29ef5 | ||
|
6db0bb625e | ||
|
709f665d51 | ||
|
1fb0435c1a | ||
|
38bc647197 | ||
|
28ecf7836e | ||
|
e1e7925488 | ||
|
17b50156aa | ||
|
206cbc2c25 | ||
|
f1cacf9768 | ||
|
e39744aa34 | ||
|
87f015c15c | ||
|
a612da1b47 | ||
|
700aa7c92e | ||
|
b050836771 | ||
|
b301460d65 | ||
|
597d9acb96 | ||
|
9233bb583b | ||
|
2e9c8b04de | ||
|
78121d58ee | ||
|
9ea19ebcc9 | ||
|
115c09babf | ||
|
5fcd8a7261 | ||
|
75f6abacc6 | ||
|
ffc8cfd045 | ||
|
db6db434e5 | ||
|
c666e6b4b5 | ||
|
2b5f5714a8 | ||
|
6d31dc8775 | ||
|
f9f8a487fe | ||
|
15825d2c81 | ||
|
7e453190bd | ||
|
1653f48a12 | ||
|
00e50e205a | ||
|
d6ed244cc2 | ||
|
caba2acb9b | ||
|
8d704378ac | ||
|
45efa2f7c6 | ||
|
6b864723fe | ||
|
a2895970bd | ||
|
e447e75534 | ||
|
1888463bef | ||
|
d5187fa597 | ||
|
7dc9f9dcbc | ||
|
13d610f856 | ||
|
20c51fdcdb | ||
|
33bf5e0975 | ||
|
b91bc5a0f7 | ||
|
79d07f84fd | ||
|
e53e635980 | ||
|
431f958947 | ||
|
58af5fc180 | ||
|
d268151bc5 | ||
|
53ff3cf688 | ||
|
b6fe96abb0 | ||
|
ce2dffe141 | ||
|
d1fd07e56e | ||
|
4b0ad1f4b3 | ||
|
2ef770cd52 | ||
|
6012ff2305 | ||
|
a926121565 | ||
|
a7d8d18868 | ||
|
1220aa81b6 | ||
|
0070785231 | ||
|
60aeab1caa | ||
|
ead788d9b2 | ||
|
39bb0a38bc | ||
|
0f2cd40231 | ||
|
ae63be0ac4 | ||
|
ca8bf21fde | ||
|
a62680c81f | ||
|
b2b9401dd6 | ||
|
94649fd797 | ||
|
65b129df03 | ||
|
2d619f35ba | ||
|
9029ff4415 | ||
|
1e13246362 | ||
|
a91c39aca1 | ||
|
78632aac86 | ||
|
3721aea58f | ||
|
b5f8c129ae | ||
|
f11458f8c1 | ||
|
0c9292b1fc | ||
|
7bdc0b80e6 | ||
|
f77110641a | ||
|
a72c45efd4 | ||
|
fd9f144e4d | ||
|
6af024fba3 | ||
|
784ce7d0ac | ||
|
242e3fae17 | ||
|
90a4f52d55 | ||
|
2f4d16375e | ||
|
aa3befd64a | ||
|
708a48c867 | ||
|
866399971f | ||
|
63e9531f58 | ||
|
2b20e93df7 | ||
|
a7f409861b | ||
|
12a7391ae6 | ||
|
464f1423fa | ||
|
df50486006 | ||
|
3dd780ab7e | ||
|
19fae8c649 | ||
|
18b3f4e4bd | ||
|
36eaa88a6d | ||
|
a86ac2b129 | ||
|
202b370725 | ||
|
40080b1d3f | ||
|
9e93d1e605 | ||
|
7bd30e4c80 | ||
|
b7a1d41ec6 | ||
|
d31b2e20ee | ||
|
d5274aea23 | ||
|
149c283f95 | ||
|
3b64bbb975 | ||
|
41c698c54a | ||
|
450706b482 | ||
|
9d2b5bcaab | ||
|
16d22f4f47 | ||
|
8fc277d64f | ||
|
dfc4c296b7 | ||
|
77b6a8c5f4 | ||
|
133e350ec6 | ||
|
93cb959bfc | ||
|
b82de8ac7e | ||
|
9041299076 | ||
|
cdf7d54387 | ||
|
db01595cf2 | ||
|
1a6cb99eb0 | ||
|
1dec77ca31 | ||
|
cd021f711d | ||
|
e5b9d8d53a | ||
|
eeae809f5d | ||
|
507a009407 | ||
|
9d44271641 | ||
|
4269faf530 | ||
|
93effa0cca | ||
|
aa0054bc22 | ||
|
20bb067bbe | ||
|
1155c5004a | ||
|
c9aec80db6 | ||
|
3635296719 | ||
|
0fa8c4534a | ||
|
e9118bde0e | ||
|
902621e3ab | ||
|
726b0699a9 | ||
|
9d770f7051 | ||
|
afd6c2b469 | ||
|
0ea8fcf76b | ||
|
c4bc54c68c | ||
|
32440eccfb | ||
|
a413f3fa31 | ||
|
a02db2c7b8 | ||
|
6685a80479 | ||
|
e8c9656440 | ||
|
cc599127a7 | ||
|
cc37cf78ff | ||
|
99ddaf298c | ||
|
008966460f | ||
|
49ef8d8b83 | ||
|
d405dba237 | ||
|
5a7a02974f | ||
|
3db9509c12 | ||
|
53af771197 | ||
|
8632c4e9f4 | ||
|
5649dd557e | ||
|
77b2a421f0 | ||
|
20986ef746 | ||
|
f023a087f4 | ||
|
8af216e31d | ||
|
8c96fff260 | ||
|
62fa2b0dcc | ||
|
559276d4af | ||
|
f386036463 | ||
|
58b4220bf0 | ||
|
34bf50b054 | ||
|
11fd2a9817 | ||
|
285dbd9a79 | ||
|
a5bd90afe4 | ||
|
75497a88ae | ||
|
26bfc70adb | ||
|
cf4743c86d | ||
|
d5063b7381 | ||
|
11e5748a54 | ||
|
2e9dfbf497 | ||
|
da082212d4 | ||
|
529baa0319 | ||
|
2ba3f403fb | ||
|
59454ab882 | ||
|
c662d931f7 | ||
|
e53c1dc594 | ||
|
79112fe5dd | ||
|
8b0cc5afb5 | ||
|
2961ab77cf | ||
|
5957e9af2a | ||
|
54483737a0 | ||
|
b279dbc156 | ||
|
d7ea29d9b5 | ||
|
816939aa13 | ||
|
f9dfa75b05 | ||
|
91321ad40f | ||
|
088954fbc8 | ||
|
d03384998c | ||
|
f1779c533a | ||
|
ca7786e2e2 | ||
|
0269a53089 | ||
|
8beb39c8fa | ||
|
74f7135459 | ||
|
42438ec11e | ||
|
97e044f0e0 | ||
|
e635e7b7a4 | ||
|
57cc047fec | ||
|
b8eca42f07 | ||
|
7058dd5bfe | ||
|
8880c9ac1e | ||
|
b0710f76a5 | ||
|
f9c6c6f0c1 | ||
|
f50e63cac4 | ||
|
c6254ce51e | ||
|
0dbdc65494 | ||
|
e1dfff940e | ||
|
a23a0ab740 | ||
|
8fea4ec817 | ||
|
b30989c334 | ||
|
cc2eaae6f6 | ||
|
dfa016b6a3 |
5
HACKING
5
HACKING
@@ -63,6 +63,11 @@ the GIMP API reference manuals, you can set AUTOGEN_CONFIGURE_ARGS to
|
||||
"--enable-gtk-doc". Please note that you will then need a recent
|
||||
version of gtk-doc as well as a working setup for handling DocBook/XML.
|
||||
|
||||
If you do not have a recent version of gtk-doc, you can pass the
|
||||
option "--disable-gtk-doc" to autogen.sh. This will completely
|
||||
disable the support for gtk-doc so you will not be able to generate
|
||||
the API documentation.
|
||||
|
||||
|
||||
CVS
|
||||
---
|
||||
|
48
Makefile.am
48
Makefile.am
@@ -1,30 +1,30 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = \
|
||||
m4macros \
|
||||
tools \
|
||||
regexrepl \
|
||||
cursors \
|
||||
themes \
|
||||
po \
|
||||
po-libgimp \
|
||||
po-plug-ins \
|
||||
po-script-fu \
|
||||
data \
|
||||
menus \
|
||||
tips \
|
||||
libgimpbase \
|
||||
libgimpcolor \
|
||||
libgimpmath \
|
||||
libgimpmodule \
|
||||
libgimpthumb \
|
||||
libgimpwidgets \
|
||||
libgimp \
|
||||
app \
|
||||
$(GIMP_MODULES) \
|
||||
$(GIMP_PLUGINS) \
|
||||
etc \
|
||||
$(GIMP_DEVEL_DOCS) \
|
||||
m4macros \
|
||||
tools \
|
||||
regexrepl \
|
||||
cursors \
|
||||
themes \
|
||||
po \
|
||||
po-libgimp \
|
||||
po-plug-ins \
|
||||
po-script-fu \
|
||||
data \
|
||||
menus \
|
||||
tips \
|
||||
libgimpbase \
|
||||
libgimpcolor \
|
||||
libgimpmath \
|
||||
libgimpmodule \
|
||||
libgimpthumb \
|
||||
libgimpwidgets \
|
||||
libgimp \
|
||||
app \
|
||||
$(GIMP_MODULES) \
|
||||
$(GIMP_PLUGINS) \
|
||||
etc \
|
||||
devel-docs \
|
||||
docs
|
||||
|
||||
bin_SCRIPTS = gimptool-@GIMP_TOOL_VERSION@ @GIMPINSTALL@
|
||||
|
158
NEWS
158
NEWS
@@ -2,8 +2,162 @@ The GNU Image Manipulation Program Version 2.2
|
||||
----------------------------------------------
|
||||
|
||||
This is the stable branch of GIMP 2.2. Only bug-fixes are applied
|
||||
here. New features are being added in the HEAD branch that will lead
|
||||
to GIMP version 2.4.
|
||||
here. New features are being added in the HEAD branch that will be
|
||||
released as GIMP version 2.4.
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.8
|
||||
========================
|
||||
- fixed possible crash in plug-ins-query PDB function
|
||||
- fixes to Script-Fu server mode on Win32
|
||||
- fixed possible crash in win32 gimptool variant
|
||||
- plugged a tiny memleak in the image display code
|
||||
- plugged a tiny memleak in libgimpwidgets
|
||||
- attempt to fix calling the web-browser on win32 (bug #171200)
|
||||
- fixed loading of images in help-browser plug-in on win32
|
||||
- fixed zoom offsets if dot-for-dot mode is disabled (bug #306476)
|
||||
- fixes to Gfig parasite loading
|
||||
- disabled buggy gimprc option stingy-memory-use (bug #306617)
|
||||
- don't try to create a preview for a non-existant image file (bug #307672)
|
||||
- fixed bug in Retinex plug-in (bug #157915)
|
||||
- fixed bug in Newsprint plug-in (bug #161573)
|
||||
- fixed bug in Shift plug-in (bug #308748)
|
||||
- fixed bug in Grid plug-in (bug #308754)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.7
|
||||
========================
|
||||
- update layer previews on colormap changes (bug #301033)
|
||||
- fixed loading of text layers from XCF files (bug #301028)
|
||||
- when loading a PDF, honor CropBox over MediaBox (bug #301432)
|
||||
- fixed incompatibility of GimpIntStore with GTK+ 2.6 (bug #301524)
|
||||
- fixed navigation popup in plug-in previews (bug #301523)
|
||||
- fixed handling of compression types in TIFF plug-in (bug #301557)
|
||||
- fixed bug in Lighting Effects plug-in (bug #302075)
|
||||
- fixed focus issues in message dialogs (bug #302400)
|
||||
- fixed bug in SSE2 assembly for Lighten Only layer mode (bug #164061)
|
||||
- fixed resize-window-on-zoom feature (bug #164281)
|
||||
- corrected upper limit of tile-cache-size (bug #303371)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.6
|
||||
========================
|
||||
- reverted change to the print plug-in (see bug #169909)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.5
|
||||
========================
|
||||
- fixed double-click behaviour of GimpButton
|
||||
- properly handle 302 redirect output from wget in URL plug-in (bug #168322)
|
||||
- fixed loading of layer masks in PSD plug-in (bug #166976)
|
||||
- fixed bugs in PSD save plug-in (bugs #167139 and #121871)
|
||||
- fixed Reset in Scale and Resize dialogs (bug #169011)
|
||||
- fixed filename encoding issues when loading Script-Fu scripts (bug #165002)
|
||||
- fixed i18n build quirks (bug #169274)
|
||||
- improve autoscrolling with tablets in Windows (bug #167960)
|
||||
- fixed setup of size entries in tool-options (bug #169066)
|
||||
- when opening images as layers, do it interactively (bug #168936)
|
||||
- fixed precondition checks in gimp_drawable_transform_scale (bug #170195)
|
||||
- fixed handling of resolution unit in Print Size dialog (bug #170200)
|
||||
- disable "gtk-alternative-button-order" setting because our code
|
||||
doesn't honor it (bug #170543)
|
||||
- fixed behaviour of selection tool when dragging from top-right (bug #143887)
|
||||
- speed up conversion of grayscale images to indexed colors (bug #170801)
|
||||
- fixed bug in grayscale to indexed color conversion (bug #170825)
|
||||
- don't offer empty palettes for conversion to indexed color (bug #170973)
|
||||
- disable search in container tree-views since it interferes with global
|
||||
accelerators (bug #169339)
|
||||
- corrected mousewheel section of default controllerrc (bug #171083)
|
||||
- fixed build on amd64/gcc-4.0 (bug #300227)
|
||||
- unset Keep Transparency from Color to Alpha plug-in.
|
||||
- fixed crash caused by Histogram dockable in RGB mode (bug #170116)
|
||||
- fixed statusbar display for negative moves (bug #171497)
|
||||
- fixed a couple of problems in the BMP plug-in (bug #171306, bug #171453
|
||||
and bug #171562)
|
||||
- fixed bug in Resize dialog if previews are turned off (bug #171827)
|
||||
- fixed disappearing previews in Rotate Colormap plug-in (bug #172284)
|
||||
- fixed deletion of fractals in Fractal Explorer plug-in (bug #172347)
|
||||
- fixed preview in Deinterlace plug-in (bug #172589)
|
||||
- fixed crashes on exit in some locales (bug #172581)
|
||||
- fixed installation directories for message catalogs (bug #169274)
|
||||
- handle deletion of layers and channels that have a floating selection
|
||||
attached (bug #168582)
|
||||
- plugged some smaller memory leaks
|
||||
- fixed preview in Gaussian Blur plug-in for zero radii (bug #173039)
|
||||
- fixed a couple of problems in the Winicon plug-in
|
||||
- fixed bug in GIF loader that was triggered with a broken GIF (bug #173119)
|
||||
- fixed crash in Ink tool (bug #164272)
|
||||
- let the text tool remember the last-used font (bug #171024)
|
||||
- quote the print command used in the Print plug-in (bug #169909)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.4
|
||||
========================
|
||||
- fixed an out-of-bounds read access in the Edge plug-in (bug #164963)
|
||||
- limit aspect ratio in crop tool to sane values (bug #164827)
|
||||
- fixed indexed conversion on floating selections (bug #165342)
|
||||
- fixed button order in resize and scale dialogs
|
||||
- improved handling of UNC paths on Windows
|
||||
- fixed crash in winicon save plug-in (bug #162742)
|
||||
- fixed image types registration for some python plug-ins (bug #1666650)
|
||||
- workaround problems with font names ending in numbers (bug #166540)
|
||||
- show clone source when cloning from a different image (bug #167002)
|
||||
- corrected coordinate limits in New Guide script (bug #167529)
|
||||
- fixed crash in gradient editor (bug #167604)
|
||||
- don't give keyboard focus to combo boxes in image window (bug #167809)
|
||||
- fixed saving of MNG files with negative layer offsets (bug #166059)
|
||||
- fixed use of the text tool on floating selections (bug #166829)
|
||||
- don't create duplicate templates when migrating user settings (bug #167893)
|
||||
- let the py-slice script ignore out-of-bounds guides (bug #167843)
|
||||
- store thumbnails in temporary folder if no valid home directory exists
|
||||
(bug #167973)
|
||||
- fixed Emboss plug-in for small images (bug #168022)
|
||||
- avoid crashes in toolbox size allocation code (bug #162500)
|
||||
- switch from display-wide grab to application-wide grab while tool
|
||||
actions are being performed (bug #162823)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.3
|
||||
========================
|
||||
- fixed build problem in MIDI input controller (bug #163593)
|
||||
- remember last used directory in file open and save dialogs (bug #162385)
|
||||
- fixed crashed in DND of indexed drawables (bug #163879)
|
||||
- removed bumpmap artifacts in Lighting Effects plug-in (bug #163877)
|
||||
- fixed non-interactive mode of Retinex plug-in
|
||||
- fixed undo of ink strokes (bug #163670)
|
||||
- fixed expose event handling in Curve Bend plug-in (bug #164207)
|
||||
- added a missing pressure sensitivity toggle to Airbrush tool (bug #164237)
|
||||
- fixed loading of XJT images files from read-only folders (bug #164116)
|
||||
- fixed bug in the Info dialog that crashed the Crop tool (bug #163617)
|
||||
- fixed yet another entry problem in the Scale Image dialog (bug #163951)
|
||||
- fixed serialization of binary parasites (bug #163131)
|
||||
- correctly initialize the preview in the Bumpmap plug-in (bug #162285)
|
||||
- give visual feedback if a dialog is already opened (bug #164156)
|
||||
- fixed saving of JPEG images with large quality settings (bug #164087)
|
||||
- update the menus when selecting a component in the Channels dialog
|
||||
(bug #164195)
|
||||
- fixed issues with the save dialog in the Imagemap plug-in (bug #164864)
|
||||
- update filesize in JPEG dialog if size of EXIF data changes (bug #164914)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.2
|
||||
========================
|
||||
- let Decompose plug-in create layers with alpha channel
|
||||
- fixed crash in save dialog (bug #162443)
|
||||
- fixed misbehaviour in Scale and Resize dialogs (bug #162387)
|
||||
- fixed preview in Imagemap plug-in (bug #162592)
|
||||
- fixed handling of broken menu path translations (bug #162590)
|
||||
- fixed bugs in the Sparkle plug-in and the Frosty Logo script (bug #132145)
|
||||
- fixed two broken Python scripts (bug #162707)
|
||||
- changed default response in Close dialog (bug #162872)
|
||||
- flush the display when plug-in dialogs are disposed (bug #163084)
|
||||
- fixed build problem on amd64 with gcc-4.0 (bug #163041)
|
||||
- fixed problem in locales that are rendered right-to-left (bug #162663)
|
||||
- fixed bug in Frosty Logo Script-Fu (bug #132145)
|
||||
- raise the toolbox when it is selected from the Tools menu (bug #163381)
|
||||
- improved usability of Keyboard Shortcuts editor (bug #163385)
|
||||
- fixed gradient selection widget in libgimpui (bug #163427)
|
||||
- workaround a problem in the MMX code (bug #162778)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.1
|
||||
|
7
README
7
README
@@ -87,10 +87,13 @@ end. But if you are absolutely allergic to ads, don't subscribe.
|
||||
======
|
||||
|
||||
And finally, for the real junkies, there is an IRC channel devoted to
|
||||
the GIMP. On Byxnet (a private mostly-GIMP network) there is #gimp.
|
||||
Many of the developers hang out there. One of the Byxnet servers are:
|
||||
the GIMP. On GIMPNet (a private free software oriented network) there is
|
||||
#gimp. Many of the developers hang out there. Some of the GIMPNet
|
||||
servers are:
|
||||
|
||||
irc.gimp.org:6667
|
||||
irc.us.gimp.org:6667
|
||||
irc.eu.gimp.org:6667
|
||||
|
||||
|
||||
4. Customizing
|
||||
|
52
acinclude.m4
52
acinclude.m4
@@ -364,3 +364,55 @@ dnl That should be it. Now just export out symbols:
|
||||
AC_SUBST(ALSA_CFLAGS)
|
||||
AC_SUBST(ALSA_LIBS)
|
||||
])
|
||||
|
||||
dnl The following lines were copied from gtk-doc.m4
|
||||
|
||||
dnl Usage:
|
||||
dnl GTK_DOC_CHECK([minimum-gtk-doc-version])
|
||||
AC_DEFUN([GTK_DOC_CHECK],
|
||||
[
|
||||
AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first
|
||||
AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first
|
||||
dnl for overriding the documentation installation directory
|
||||
AC_ARG_WITH(html-dir,
|
||||
AC_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),,
|
||||
[with_html_dir='${datadir}/gtk-doc/html'])
|
||||
HTML_DIR="$with_html_dir"
|
||||
AC_SUBST(HTML_DIR)
|
||||
|
||||
dnl enable/disable documentation building
|
||||
AC_ARG_ENABLE(gtk-doc,
|
||||
AC_HELP_STRING([--enable-gtk-doc],
|
||||
[use gtk-doc to build documentation (default=no)]),,
|
||||
enable_gtk_doc=no)
|
||||
|
||||
have_gtk_doc=no
|
||||
if test x$enable_gtk_doc = xyes; then
|
||||
if test -z "$PKG_CONFIG"; then
|
||||
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
|
||||
fi
|
||||
if test "$PKG_CONFIG" != "no" && $PKG_CONFIG --exists gtk-doc; then
|
||||
have_gtk_doc=yes
|
||||
fi
|
||||
|
||||
dnl do we want to do a version check?
|
||||
ifelse([$1],[],,
|
||||
[gtk_doc_min_version=$1
|
||||
if test "$have_gtk_doc" = yes; then
|
||||
AC_MSG_CHECKING([gtk-doc version >= $gtk_doc_min_version])
|
||||
if $PKG_CONFIG --atleast-version $gtk_doc_min_version gtk-doc; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
have_gtk_doc=no
|
||||
fi
|
||||
fi
|
||||
])
|
||||
if test "$have_gtk_doc" != yes; then
|
||||
enable_gtk_doc=no
|
||||
fi
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(ENABLE_GTK_DOC, test x$enable_gtk_doc = xyes)
|
||||
AM_CONDITIONAL(GTK_DOC_USE_LIBTOOL, test -n "$LIBTOOL")
|
||||
])
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include "core/gimpimage.h"
|
||||
|
||||
#include "widgets/gimpactionfactory.h"
|
||||
#include "widgets/gimpactiongroup.h"
|
||||
#include "widgets/gimpcontainereditor.h"
|
||||
#include "widgets/gimpcontainerview.h"
|
||||
#include "widgets/gimpdock.h"
|
||||
|
@@ -20,6 +20,11 @@
|
||||
#define __DIALOGS_ACTIONS_H__
|
||||
|
||||
|
||||
/* this check is needed for the extern declaration below to be correct */
|
||||
#ifndef __GIMP_ACTION_GROUP_H__
|
||||
#error "widgets/gimpactiongroup.h must be included prior to dialog-actions.h"
|
||||
#endif
|
||||
|
||||
extern GimpStringActionEntry dialogs_dockable_actions[];
|
||||
extern gint n_dialogs_dockable_actions;
|
||||
|
||||
|
@@ -253,6 +253,8 @@ dockable_actions_update (GimpActionGroup *group,
|
||||
#define SET_SENSITIVE(action,sensitive) \
|
||||
gimp_action_group_set_action_sensitive (group, action, (sensitive) != 0)
|
||||
|
||||
SET_SENSITIVE ("dockable-detach-tab", n_pages > 1);
|
||||
|
||||
SET_VISIBLE ("dockable-preview-size-menu", preview_size != -1);
|
||||
|
||||
if (preview_size != -1)
|
||||
|
@@ -94,10 +94,17 @@ void
|
||||
file_open_from_image_cmd_callback (GtkAction *action,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GimpImage *image;
|
||||
GtkWidget *widget;
|
||||
const gchar *uri = NULL;
|
||||
return_if_no_widget (widget, data);
|
||||
|
||||
file_open_dialog_show (widget, action_data_get_image (data), NULL, FALSE);
|
||||
image = action_data_get_image (data);
|
||||
|
||||
if (image)
|
||||
uri = gimp_object_get_name (GIMP_OBJECT (image));
|
||||
|
||||
file_open_dialog_show (widget, NULL, uri, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -365,7 +372,8 @@ file_open_dialog_show (GtkWidget *parent,
|
||||
|
||||
if (dialog)
|
||||
{
|
||||
gimp_file_dialog_set_uri (GIMP_FILE_DIALOG (dialog), gimage, uri);
|
||||
if (uri)
|
||||
gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (dialog), uri);
|
||||
|
||||
if (open_as_layer)
|
||||
{
|
||||
@@ -410,7 +418,6 @@ file_save_dialog_show (GimpImage *gimage,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (dialog)
|
||||
{
|
||||
gtk_window_set_title (GTK_WINDOW (dialog), title);
|
||||
|
@@ -219,11 +219,12 @@ plug_in_actions_add_proc (GimpActionGroup *group,
|
||||
path_original = proc_def->menu_paths->data;
|
||||
path_translated = dgettext (locale_domain, path_original);
|
||||
|
||||
if (! plug_in_actions_check_translation (path_original, path_translated))
|
||||
return;
|
||||
path_original = g_strdup (path_original);
|
||||
|
||||
path_original = g_strdup (path_original);
|
||||
path_translated = g_strdup (path_translated);
|
||||
if (plug_in_actions_check_translation (path_original, path_translated))
|
||||
path_translated = g_strdup (path_translated);
|
||||
else
|
||||
path_translated = g_strdup (path_original);
|
||||
|
||||
p1 = strrchr (path_original, '/');
|
||||
p2 = strrchr (path_translated, '/');
|
||||
@@ -263,6 +264,8 @@ plug_in_actions_add_proc (GimpActionGroup *group,
|
||||
|
||||
if (plug_in_actions_check_translation (original, translated))
|
||||
plug_in_actions_build_path (group, original, translated);
|
||||
else
|
||||
plug_in_actions_build_path (group, original, original);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -295,6 +298,8 @@ plug_in_actions_add_path (GimpActionGroup *group,
|
||||
|
||||
if (plug_in_actions_check_translation (menu_path, path_translated))
|
||||
plug_in_actions_build_path (group, menu_path, path_translated);
|
||||
else
|
||||
plug_in_actions_build_path (group, menu_path, menu_path);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -61,14 +61,13 @@ plug_in_run_cmd_callback (GtkAction *action,
|
||||
PlugInProcDef *proc_def,
|
||||
gpointer data)
|
||||
{
|
||||
Gimp *gimp;
|
||||
ProcRecord *proc_rec;
|
||||
Argument *args;
|
||||
GimpDisplay *gdisp = NULL;
|
||||
gint gdisp_ID = -1;
|
||||
gint i;
|
||||
gint argc;
|
||||
GimpImageType drawable_type = GIMP_RGB_IMAGE;
|
||||
Gimp *gimp;
|
||||
ProcRecord *proc_rec;
|
||||
Argument *args;
|
||||
GimpDisplay *gdisp = NULL;
|
||||
gint gdisp_ID = -1;
|
||||
gint i;
|
||||
gint argc;
|
||||
|
||||
gimp = action_data_get_gimp (data);
|
||||
if (! gimp)
|
||||
@@ -115,8 +114,6 @@ plug_in_run_cmd_callback (GtkAction *action,
|
||||
|
||||
if (drawable)
|
||||
{
|
||||
drawable_type = gimp_drawable_type (drawable);
|
||||
|
||||
args[2].value.pdb_int =
|
||||
gimp_item_get_ID (GIMP_ITEM (drawable));
|
||||
argc++;
|
||||
@@ -145,7 +142,7 @@ plug_in_run_cmd_callback (GtkAction *action,
|
||||
|
||||
/* remember only "standard" plug-ins */
|
||||
if (proc_rec->proc_type == GIMP_PLUGIN &&
|
||||
proc_rec->num_args >= 2 &&
|
||||
proc_rec->num_args >= 3 &&
|
||||
proc_rec->args[1].arg_type == GIMP_PDB_IMAGE &&
|
||||
proc_rec->args[2].arg_type == GIMP_PDB_DRAWABLE)
|
||||
{
|
||||
|
440
app/airbrush.c
440
app/airbrush.c
@@ -1,440 +0,0 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "appenv.h"
|
||||
#include "airbrush.h"
|
||||
#include "drawable.h"
|
||||
#include "gdisplay.h"
|
||||
#include "gradient.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimpbrush.h"
|
||||
#include "gimpcontext.h"
|
||||
#include "gimpui.h"
|
||||
#include "paint_funcs.h"
|
||||
#include "paint_core.h"
|
||||
#include "paint_options.h"
|
||||
#include "selection.h"
|
||||
#include "temp_buf.h"
|
||||
#include "tool.h"
|
||||
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
|
||||
/* The maximum amount of pressure that can be exerted */
|
||||
#define MAX_PRESSURE 0.075
|
||||
|
||||
/* Default pressure setting */
|
||||
#define AIRBRUSH_PRESSURE_DEFAULT 10.0
|
||||
#define AIRBRUSH_INCREMENTAL_DEFAULT FALSE
|
||||
|
||||
#define OFF 0
|
||||
#define ON 1
|
||||
|
||||
/* the airbrush structures */
|
||||
|
||||
typedef struct _AirbrushTimeout AirbrushTimeout;
|
||||
|
||||
struct _AirbrushTimeout
|
||||
{
|
||||
PaintCore *paint_core;
|
||||
GimpDrawable *drawable;
|
||||
};
|
||||
|
||||
typedef struct _AirbrushOptions AirbrushOptions;
|
||||
|
||||
struct _AirbrushOptions
|
||||
{
|
||||
PaintOptions paint_options;
|
||||
|
||||
gdouble rate;
|
||||
gdouble rate_d;
|
||||
GtkObject *rate_w;
|
||||
|
||||
gdouble pressure;
|
||||
gdouble pressure_d;
|
||||
GtkObject *pressure_w;
|
||||
};
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static gpointer airbrush_paint_func (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
PaintState state);
|
||||
static gpointer airbrush_non_gui_paint_func (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
PaintState state);
|
||||
|
||||
|
||||
/* the airbrush tool options */
|
||||
static AirbrushOptions *airbrush_options = NULL;
|
||||
|
||||
/* local variables */
|
||||
static gint timer; /* timer for successive paint applications */
|
||||
static gint timer_state = OFF; /* state of airbrush tool */
|
||||
static AirbrushTimeout airbrush_timeout;
|
||||
|
||||
static gdouble non_gui_pressure;
|
||||
static gboolean non_gui_incremental;
|
||||
|
||||
/* forward function declarations */
|
||||
static void airbrush_motion (PaintCore *, GimpDrawable *,
|
||||
PaintPressureOptions *,
|
||||
gdouble, PaintApplicationMode);
|
||||
static gint airbrush_time_out (gpointer);
|
||||
|
||||
|
||||
/* functions */
|
||||
|
||||
static void
|
||||
airbrush_options_reset (void)
|
||||
{
|
||||
AirbrushOptions *options = airbrush_options;
|
||||
|
||||
paint_options_reset ((PaintOptions *) options);
|
||||
|
||||
gtk_adjustment_set_value (GTK_ADJUSTMENT (options->rate_w),
|
||||
options->rate_d);
|
||||
gtk_adjustment_set_value (GTK_ADJUSTMENT (options->pressure_w),
|
||||
options->pressure_d);
|
||||
}
|
||||
|
||||
static AirbrushOptions *
|
||||
airbrush_options_new (void)
|
||||
{
|
||||
AirbrushOptions *options;
|
||||
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *table;
|
||||
GtkWidget *scale;
|
||||
|
||||
/* the new airbrush tool options structure */
|
||||
options = g_new (AirbrushOptions, 1);
|
||||
paint_options_init ((PaintOptions *) options,
|
||||
AIRBRUSH,
|
||||
airbrush_options_reset);
|
||||
options->rate = options->rate_d = 80.0;
|
||||
options->pressure = options->pressure_d = AIRBRUSH_PRESSURE_DEFAULT;
|
||||
|
||||
/* the main vbox */
|
||||
vbox = ((ToolOptions *) options)->main_vbox;
|
||||
|
||||
/* the rate scale */
|
||||
table = gtk_table_new (2, 2, FALSE);
|
||||
gtk_table_set_col_spacing (GTK_TABLE (table), 0, 4);
|
||||
gtk_table_set_row_spacings (GTK_TABLE (table), 1);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
|
||||
|
||||
options->rate_w =
|
||||
gtk_adjustment_new (options->rate_d, 0.0, 150.0, 1.0, 1.0, 0.0);
|
||||
scale = gtk_hscale_new (GTK_ADJUSTMENT (options->rate_w));
|
||||
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
|
||||
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
|
||||
gtk_signal_connect (GTK_OBJECT (options->rate_w), "value_changed",
|
||||
GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
|
||||
&options->rate);
|
||||
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
|
||||
_("Rate:"), 1.0, 1.0,
|
||||
scale, 1, FALSE);
|
||||
|
||||
/* the pressure scale */
|
||||
options->pressure_w =
|
||||
gtk_adjustment_new (options->pressure_d, 0.0, 100.0, 1.0, 1.0, 0.0);
|
||||
scale = gtk_hscale_new (GTK_ADJUSTMENT (options->pressure_w));
|
||||
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
|
||||
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
|
||||
gtk_signal_connect (GTK_OBJECT (options->pressure_w), "value_changed",
|
||||
GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
|
||||
&options->pressure);
|
||||
gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
|
||||
_("Pressure:"), 1.0, 1.0,
|
||||
scale, 1, FALSE);
|
||||
|
||||
gtk_widget_show (table);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
Tool *
|
||||
tools_new_airbrush (void)
|
||||
{
|
||||
Tool * tool;
|
||||
PaintCore * private;
|
||||
|
||||
/* The tool options */
|
||||
if (! airbrush_options)
|
||||
{
|
||||
airbrush_options = airbrush_options_new ();
|
||||
tools_register (AIRBRUSH, (ToolOptions *) airbrush_options);
|
||||
}
|
||||
|
||||
tool = paint_core_new (AIRBRUSH);
|
||||
|
||||
private = (PaintCore *) tool->private;
|
||||
private->paint_func = airbrush_paint_func;
|
||||
private->pick_colors = TRUE;
|
||||
private->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
|
||||
|
||||
return tool;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
airbrush_paint_func (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
PaintState state)
|
||||
{
|
||||
GimpBrush *brush;
|
||||
gdouble rate;
|
||||
|
||||
if (!drawable)
|
||||
return NULL;
|
||||
|
||||
brush = gimp_context_get_brush (NULL);
|
||||
switch (state)
|
||||
{
|
||||
case INIT_PAINT :
|
||||
/* timer_state = OFF; */
|
||||
if (timer_state == ON)
|
||||
{
|
||||
g_warning ("killing stray timer, please report to lewing@gimp.org");
|
||||
gtk_timeout_remove (timer);
|
||||
}
|
||||
timer_state = OFF;
|
||||
break;
|
||||
|
||||
case MOTION_PAINT :
|
||||
if (timer_state == ON)
|
||||
gtk_timeout_remove (timer);
|
||||
timer_state = OFF;
|
||||
|
||||
airbrush_motion (paint_core, drawable,
|
||||
airbrush_options->paint_options.pressure_options,
|
||||
airbrush_options->pressure,
|
||||
airbrush_options->paint_options.incremental ?
|
||||
INCREMENTAL : CONSTANT);
|
||||
|
||||
if (airbrush_options->rate != 0.0)
|
||||
{
|
||||
airbrush_timeout.paint_core = paint_core;
|
||||
airbrush_timeout.drawable = drawable;
|
||||
rate = airbrush_options->paint_options.pressure_options->rate ?
|
||||
(10000 / (airbrush_options->rate * 2.0 * paint_core->curpressure)) :
|
||||
(10000 / airbrush_options->rate);
|
||||
timer = gtk_timeout_add (rate, airbrush_time_out, NULL);
|
||||
timer_state = ON;
|
||||
}
|
||||
break;
|
||||
|
||||
case FINISH_PAINT :
|
||||
if (timer_state == ON)
|
||||
gtk_timeout_remove (timer);
|
||||
timer_state = OFF;
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tools_free_airbrush (Tool *tool)
|
||||
{
|
||||
if (timer_state == ON)
|
||||
gtk_timeout_remove (timer);
|
||||
timer_state = OFF;
|
||||
|
||||
paint_core_free (tool);
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
airbrush_time_out (gpointer client_data)
|
||||
{
|
||||
/* service the timer */
|
||||
airbrush_motion (airbrush_timeout.paint_core,
|
||||
airbrush_timeout.drawable,
|
||||
airbrush_options->paint_options.pressure_options,
|
||||
airbrush_options->pressure,
|
||||
airbrush_options->paint_options.incremental ?
|
||||
INCREMENTAL : CONSTANT);
|
||||
gdisplays_flush ();
|
||||
|
||||
/* restart the timer */
|
||||
if (airbrush_options->rate != 0.0)
|
||||
{
|
||||
if (airbrush_options->paint_options.pressure_options->rate)
|
||||
{
|
||||
/* set a new timer */
|
||||
timer = gtk_timeout_add ((10000 / (airbrush_options->rate * 2.0 * airbrush_timeout.paint_core->curpressure)),
|
||||
airbrush_time_out, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
airbrush_motion (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
PaintPressureOptions *pressure_options,
|
||||
double pressure,
|
||||
PaintApplicationMode mode)
|
||||
{
|
||||
GImage *gimage;
|
||||
TempBuf *area;
|
||||
guchar col[MAX_CHANNELS];
|
||||
gdouble scale;
|
||||
|
||||
if (!drawable)
|
||||
return;
|
||||
|
||||
if (! (gimage = gimp_drawable_gimage (drawable)))
|
||||
return;
|
||||
|
||||
if (pressure_options->size)
|
||||
scale = paint_core->curpressure;
|
||||
else
|
||||
scale = 1.0;
|
||||
|
||||
if (! (area = paint_core_get_paint_area (paint_core, drawable, scale)))
|
||||
return;
|
||||
|
||||
/* color the pixels */
|
||||
if (pressure_options->color)
|
||||
{
|
||||
GimpRGB color;
|
||||
|
||||
gradient_get_color_at (gimp_context_get_gradient (NULL),
|
||||
paint_core->curpressure, &color);
|
||||
|
||||
gimp_rgba_get_uchar (&color,
|
||||
&col[RED_PIX],
|
||||
&col[GREEN_PIX],
|
||||
&col[BLUE_PIX],
|
||||
&col[ALPHA_PIX]);
|
||||
|
||||
mode = INCREMENTAL;
|
||||
color_pixels (temp_buf_data (area), col,
|
||||
area->width * area->height, area->bytes);
|
||||
}
|
||||
else if (paint_core->brush && paint_core->brush->pixmap)
|
||||
{
|
||||
mode = INCREMENTAL;
|
||||
paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area,
|
||||
scale, SOFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_image_get_foreground (gimage, drawable, col);
|
||||
col[area->bytes - 1] = OPAQUE_OPACITY;
|
||||
color_pixels (temp_buf_data (area), col,
|
||||
area->width * area->height, area->bytes);
|
||||
}
|
||||
|
||||
if (pressure_options->pressure)
|
||||
pressure = pressure * 2.0 * paint_core->curpressure;
|
||||
|
||||
/* paste the newly painted area to the image */
|
||||
paint_core_paste_canvas (paint_core, drawable,
|
||||
MIN (pressure, 255),
|
||||
(gint) (gimp_context_get_opacity (NULL) * 255),
|
||||
gimp_context_get_paint_mode (NULL),
|
||||
SOFT, scale, mode);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
airbrush_non_gui_paint_func (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
PaintState state)
|
||||
{
|
||||
airbrush_motion (paint_core, drawable, &non_gui_pressure_options,
|
||||
non_gui_pressure, non_gui_incremental);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
airbrush_non_gui_default (GimpDrawable *drawable,
|
||||
gint num_strokes,
|
||||
gdouble *stroke_array)
|
||||
{
|
||||
AirbrushOptions *options = airbrush_options;
|
||||
gdouble pressure = AIRBRUSH_PRESSURE_DEFAULT;
|
||||
|
||||
if(options)
|
||||
pressure = options->pressure;
|
||||
|
||||
return airbrush_non_gui (drawable, pressure, num_strokes, stroke_array);
|
||||
}
|
||||
|
||||
gboolean
|
||||
airbrush_non_gui (GimpDrawable *drawable,
|
||||
gdouble pressure,
|
||||
gint num_strokes,
|
||||
gdouble *stroke_array)
|
||||
{
|
||||
gint i;
|
||||
|
||||
if (paint_core_init (&non_gui_paint_core, drawable,
|
||||
stroke_array[0], stroke_array[1]))
|
||||
{
|
||||
/* Set the paint core's paint func */
|
||||
non_gui_paint_core.paint_func = airbrush_non_gui_paint_func;
|
||||
|
||||
non_gui_pressure = pressure;
|
||||
|
||||
non_gui_paint_core.startx = non_gui_paint_core.lastx = stroke_array[0];
|
||||
non_gui_paint_core.starty = non_gui_paint_core.lasty = stroke_array[1];
|
||||
|
||||
airbrush_non_gui_paint_func (&non_gui_paint_core, drawable, 0);
|
||||
|
||||
for (i = 1; i < num_strokes; i++)
|
||||
{
|
||||
non_gui_paint_core.curx = stroke_array[i * 2 + 0];
|
||||
non_gui_paint_core.cury = stroke_array[i * 2 + 1];
|
||||
|
||||
paint_core_interpolate (&non_gui_paint_core, drawable);
|
||||
|
||||
non_gui_paint_core.lastx = non_gui_paint_core.curx;
|
||||
non_gui_paint_core.lasty = non_gui_paint_core.cury;
|
||||
}
|
||||
|
||||
/* Finish the painting */
|
||||
paint_core_finish (&non_gui_paint_core, drawable, -1);
|
||||
|
||||
/* Cleanup */
|
||||
paint_core_cleanup ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
@@ -189,6 +189,7 @@ app_run (const gchar *full_prog_name,
|
||||
"Gimp-GUI",
|
||||
"Gimp-Menus",
|
||||
"Gimp-PDB",
|
||||
"Gimp-Paint",
|
||||
"Gimp-Paint-Funcs",
|
||||
"Gimp-Plug-In",
|
||||
"Gimp-Text",
|
||||
|
@@ -19,8 +19,10 @@ static struct install_table {
|
||||
#if defined(COMPILE_MMX_IS_OKAY)
|
||||
{ GIMP_COMPOSITE_MULTIPLY, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_multiply_rgba8_rgba8_rgba8_mmx },
|
||||
{ GIMP_COMPOSITE_SCREEN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_screen_rgba8_rgba8_rgba8_mmx },
|
||||
{ GIMP_COMPOSITE_DIFFERENCE, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_difference_rgba8_rgba8_rgba8_mmx },
|
||||
{ GIMP_COMPOSITE_ADDITION, GIMP_PIXELFORMAT_VA8, GIMP_PIXELFORMAT_VA8, GIMP_PIXELFORMAT_VA8, gimp_composite_addition_va8_va8_va8_mmx },
|
||||
{ GIMP_COMPOSITE_DIFFERENCE, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_difference_rgba8_rgba8_rgba8_mmx },
|
||||
#if 0
|
||||
{ GIMP_COMPOSITE_ADDITION, GIMP_PIXELFORMAT_VA8, GIMP_PIXELFORMAT_VA8, GIMP_PIXELFORMAT_VA8, gimp_composite_addition_va8_va8_va8_mmx },
|
||||
#endif
|
||||
{ GIMP_COMPOSITE_ADDITION, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_addition_rgba8_rgba8_rgba8_mmx },
|
||||
{ GIMP_COMPOSITE_SUBTRACT, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_subtract_rgba8_rgba8_rgba8_mmx },
|
||||
{ GIMP_COMPOSITE_DARKEN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_darken_rgba8_rgba8_rgba8_mmx },
|
||||
|
@@ -64,7 +64,7 @@ gimp_composite_mmx_test (int iterations, int n_pixels)
|
||||
va8M[i].a = i;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
gimp_composite_context_init (&special_ctx, GIMP_COMPOSITE_ADDITION, GIMP_PIXELFORMAT_VA8, GIMP_PIXELFORMAT_VA8, GIMP_PIXELFORMAT_VA8, GIMP_PIXELFORMAT_VA8, n_pixels, (unsigned char *) va8A, (unsigned char *) va8B, (unsigned char *) va8B, (unsigned char *) va8D2);
|
||||
gimp_composite_context_init (&generic_ctx, GIMP_COMPOSITE_ADDITION, GIMP_PIXELFORMAT_VA8, GIMP_PIXELFORMAT_VA8, GIMP_PIXELFORMAT_VA8, GIMP_PIXELFORMAT_VA8, n_pixels, (unsigned char *) va8A, (unsigned char *) va8B, (unsigned char *) va8B, (unsigned char *) va8D1);
|
||||
ft0 = gimp_composite_regression_time_function (iterations, gimp_composite_dispatch, &generic_ctx);
|
||||
@@ -75,6 +75,7 @@ gimp_composite_mmx_test (int iterations, int n_pixels)
|
||||
return (1);
|
||||
}
|
||||
gimp_composite_regression_timer_report ("addition_va8_va8_va8", ft0, ft1);
|
||||
#endif
|
||||
|
||||
gimp_composite_context_init (&special_ctx, GIMP_COMPOSITE_ADDITION, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, n_pixels, (unsigned char *) rgba8A, (unsigned char *) rgba8B, (unsigned char *) rgba8B, (unsigned char *) rgba8D2);
|
||||
gimp_composite_context_init (&generic_ctx, GIMP_COMPOSITE_ADDITION, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, n_pixels, (unsigned char *) rgba8A, (unsigned char *) rgba8B, (unsigned char *) rgba8B, (unsigned char *) rgba8D1);
|
||||
|
@@ -1289,7 +1289,7 @@ gimp_composite_swap_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
void
|
||||
gimp_composite_addition_va8_va8_va8_mmx (GimpCompositeContext *_op)
|
||||
{
|
||||
@@ -1379,6 +1379,7 @@ gimp_composite_addition_va8_va8_va8_mmx (GimpCompositeContext *_op)
|
||||
|
||||
asm("emms");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
void
|
||||
|
@@ -55,7 +55,8 @@ extern void gimp_composite_softlight_rgba8_rgba8_rgba8_mmx (GimpCompositeContext
|
||||
extern void gimp_composite_subtract_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *ctx);
|
||||
extern void gimp_composite_swap_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *ctx);
|
||||
extern void gimp_composite_valueonly_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *ctx);
|
||||
|
||||
#if 0
|
||||
extern void gimp_composite_addition_va8_va8_va8_mmx (GimpCompositeContext *ctx);
|
||||
#endif
|
||||
#endif /* COMPILE_IS_OKAY */
|
||||
#endif
|
||||
|
@@ -48,6 +48,16 @@
|
||||
#define pminub(src,dst,tmp) "pminub " "%%" #src ", %%" #dst
|
||||
#define pmaxub(src,dst,tmp) "pmaxub " "%%" #src ", %%" #dst
|
||||
|
||||
extern const guint32 rgba8_alpha_mask_64[2];
|
||||
extern const guint32 rgba8_b1_64[2];
|
||||
extern const guint32 rgba8_b255_64[2];
|
||||
extern const guint32 rgba8_w1_64[2];
|
||||
extern const guint32 rgba8_w2_64[2];
|
||||
extern const guint32 rgba8_w128_64[2];
|
||||
extern const guint32 rgba8_w256_64[2];
|
||||
extern const guint32 rgba8_w255_64[2];
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
@@ -590,7 +590,7 @@ gimp_composite_lighten_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
uint128 *B = (uint128 *) _op->B;
|
||||
gulong n_pixels = _op->n_pixels;
|
||||
|
||||
asm volatile ("movq %0,%%mm0" : : "m" (*rgba8_alpha_mask_64) : "%mm0");
|
||||
asm volatile ("movdqu %0,%%xmm0" : : "m" (*rgba8_alpha_mask_64) : "%xmm0");
|
||||
|
||||
for (; n_pixels >= 4; n_pixels -= 4)
|
||||
{
|
||||
|
@@ -241,15 +241,6 @@ typedef unsigned long uint32;
|
||||
typedef unsigned long long uint64;
|
||||
typedef struct { uint64 __uint64[2]; } uint128;
|
||||
|
||||
extern const guint32 rgba8_alpha_mask_64[2];
|
||||
extern const guint32 rgba8_b1_64[2];
|
||||
extern const guint32 rgba8_b255_64[2];
|
||||
extern const guint32 rgba8_w1_64[2];
|
||||
extern const guint32 rgba8_w2_64[2];
|
||||
extern const guint32 rgba8_w128_64[2];
|
||||
extern const guint32 rgba8_w256_64[2];
|
||||
extern const guint32 rgba8_w255_64[2];
|
||||
|
||||
extern const guint32 va8_alpha_mask[2];
|
||||
extern const guint32 va8_b255[2];
|
||||
extern const guint32 va8_w1[2];
|
||||
|
@@ -114,14 +114,15 @@ gimp_base_config_class_init (GimpBaseConfigClass *klass)
|
||||
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_STINGY_MEMORY_USE,
|
||||
"stingy-memory-use", STINGY_MEMORY_USE_BLURB,
|
||||
FALSE,
|
||||
GIMP_PARAM_RESTART);
|
||||
GIMP_PARAM_IGNORE);
|
||||
GIMP_CONFIG_INSTALL_PROP_UINT (object_class, PROP_NUM_PROCESSORS,
|
||||
"num-processors", NUM_PROCESSORS_BLURB,
|
||||
1, 30, 1,
|
||||
0);
|
||||
GIMP_CONFIG_INSTALL_PROP_MEMSIZE (object_class, PROP_TILE_CACHE_SIZE,
|
||||
"tile-cache-size", TILE_CACHE_SIZE_BLURB,
|
||||
0, GIMP_MAX_MEMSIZE, 1 << 27, /* 128MB */
|
||||
0, MIN (G_MAXULONG, GIMP_MAX_MEMSIZE),
|
||||
1 << 27, /* 128MB */
|
||||
GIMP_PARAM_CONFIRM);
|
||||
}
|
||||
|
||||
|
@@ -136,6 +136,9 @@ dump_gimprc_system (GimpConfig *rc,
|
||||
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
|
||||
continue;
|
||||
|
||||
if (prop_spec->flags & GIMP_PARAM_IGNORE)
|
||||
continue;
|
||||
|
||||
comment = dump_describe_param (prop_spec);
|
||||
if (comment)
|
||||
{
|
||||
@@ -265,6 +268,9 @@ dump_gimprc_manpage (GimpConfig *rc,
|
||||
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
|
||||
continue;
|
||||
|
||||
if (prop_spec->flags & GIMP_PARAM_IGNORE)
|
||||
continue;
|
||||
|
||||
write (fd, ".TP\n", strlen (".TP\n"));
|
||||
|
||||
if (gimp_config_serialize_property (rc, prop_spec, writer))
|
||||
|
@@ -952,6 +952,7 @@ gimp_undo_type_get_type (void)
|
||||
{ GIMP_UNDO_GROUP_IMAGE_ROTATE, "GIMP_UNDO_GROUP_IMAGE_ROTATE", "group-image-rotate" },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_CROP, "GIMP_UNDO_GROUP_IMAGE_CROP", "group-image-crop" },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_CONVERT, "GIMP_UNDO_GROUP_IMAGE_CONVERT", "group-image-convert" },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE, "GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE", "group-image-item-remove" },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, "GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE", "group-image-layers-merge" },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_VECTORS_MERGE, "GIMP_UNDO_GROUP_IMAGE_VECTORS_MERGE", "group-image-vectors-merge" },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_QMASK, "GIMP_UNDO_GROUP_IMAGE_QMASK", "group-image-qmask" },
|
||||
@@ -1017,6 +1018,7 @@ gimp_undo_type_get_type (void)
|
||||
{ GIMP_UNDO_FS_RELAX, "GIMP_UNDO_FS_RELAX", "fs-relax" },
|
||||
{ GIMP_UNDO_TRANSFORM, "GIMP_UNDO_TRANSFORM", "transform" },
|
||||
{ GIMP_UNDO_PAINT, "GIMP_UNDO_PAINT", "paint" },
|
||||
{ GIMP_UNDO_INK, "GIMP_UNDO_INK", "ink" },
|
||||
{ GIMP_UNDO_PARASITE_ATTACH, "GIMP_UNDO_PARASITE_ATTACH", "parasite-attach" },
|
||||
{ GIMP_UNDO_PARASITE_REMOVE, "GIMP_UNDO_PARASITE_REMOVE", "parasite-remove" },
|
||||
{ GIMP_UNDO_CANT, "GIMP_UNDO_CANT", "cant" },
|
||||
@@ -1032,6 +1034,7 @@ gimp_undo_type_get_type (void)
|
||||
{ GIMP_UNDO_GROUP_IMAGE_ROTATE, N_("Rotate image"), NULL },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_CROP, N_("Crop image"), NULL },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_CONVERT, N_("Convert image"), NULL },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE, N_("Remove item"), NULL },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, N_("Merge layers"), NULL },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_VECTORS_MERGE, N_("Merge vectors"), NULL },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_QMASK, N_("Quick Mask"), NULL },
|
||||
@@ -1097,6 +1100,7 @@ gimp_undo_type_get_type (void)
|
||||
{ GIMP_UNDO_FS_RELAX, N_("FS relax"), NULL },
|
||||
{ GIMP_UNDO_TRANSFORM, N_("Transform"), NULL },
|
||||
{ GIMP_UNDO_PAINT, N_("Paint"), NULL },
|
||||
{ GIMP_UNDO_INK, N_("Ink"), NULL },
|
||||
{ GIMP_UNDO_PARASITE_ATTACH, N_("Attach parasite"), NULL },
|
||||
{ GIMP_UNDO_PARASITE_REMOVE, N_("Remove parasite"), NULL },
|
||||
{ GIMP_UNDO_CANT, N_("EEK: can't undo"), NULL },
|
||||
|
@@ -439,6 +439,7 @@ typedef enum /*< pdb-skip >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_ROTATE, /*< desc="Rotate image" >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_CROP, /*< desc="Crop image" >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_CONVERT, /*< desc="Convert image" >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE, /*< desc="Remove item" >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, /*< desc="Merge layers" >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_VECTORS_MERGE,/*< desc="Merge vectors" >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_QMASK, /*< desc="Quick Mask" >*/
|
||||
@@ -509,6 +510,7 @@ typedef enum /*< pdb-skip >*/
|
||||
GIMP_UNDO_FS_RELAX, /*< desc="FS relax" >*/
|
||||
GIMP_UNDO_TRANSFORM, /*< desc="Transform" >*/
|
||||
GIMP_UNDO_PAINT, /*< desc="Paint" >*/
|
||||
GIMP_UNDO_INK, /*< desc="Ink" >*/
|
||||
GIMP_UNDO_PARASITE_ATTACH, /*< desc="Attach parasite" >*/
|
||||
GIMP_UNDO_PARASITE_REMOVE, /*< desc="Remove parasite" >*/
|
||||
|
||||
|
@@ -18,6 +18,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
@@ -107,8 +109,28 @@ gimp_templates_save (Gimp *gimp)
|
||||
}
|
||||
|
||||
|
||||
/* just like gimp_list_get_child_by_name() but matches case-insensitive */
|
||||
static GimpObject *
|
||||
gimp_templates_migrate_get_child_by_name (const GimpContainer *container,
|
||||
const gchar *name)
|
||||
{
|
||||
GimpList *list = GIMP_LIST (container);
|
||||
GList *glist;
|
||||
|
||||
for (glist = list->list; glist; glist = g_list_next (glist))
|
||||
{
|
||||
GimpObject *object = glist->data;
|
||||
|
||||
if (! g_ascii_strcasecmp (object->name, name))
|
||||
return object;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_templates_migrate:
|
||||
* @olddir: the old user directory
|
||||
*
|
||||
* Migrating the templaterc from GIMP 2.0 to GIMP 2.2 needs this special
|
||||
* hack since we changed the way that units are handled. This function
|
||||
@@ -116,7 +138,7 @@ gimp_templates_save (Gimp *gimp)
|
||||
* is to replace the unit for a couple of default templates with "pixels".
|
||||
**/
|
||||
void
|
||||
gimp_templates_migrate (void)
|
||||
gimp_templates_migrate (const gchar *olddir)
|
||||
{
|
||||
GimpContainer *templates = gimp_list_new (GIMP_TYPE_TEMPLATE, TRUE);
|
||||
gchar *filename = gimp_personal_rc_file ("templaterc");
|
||||
@@ -127,7 +149,26 @@ gimp_templates_migrate (void)
|
||||
gchar *tmp = g_build_filename (gimp_sysconf_directory (),
|
||||
"templaterc", NULL);
|
||||
|
||||
gimp_config_deserialize_file (GIMP_CONFIG (templates), tmp, NULL, NULL);
|
||||
if (olddir && strstr (olddir, "2.0"))
|
||||
{
|
||||
/* We changed the spelling of a couple of template names
|
||||
* from upper to lower case between 2.0 and 2.2.
|
||||
*/
|
||||
GimpContainerClass *class = GIMP_CONTAINER_GET_CLASS (templates);
|
||||
gpointer func = class->get_child_by_name;
|
||||
|
||||
class->get_child_by_name = gimp_templates_migrate_get_child_by_name;
|
||||
|
||||
gimp_config_deserialize_file (GIMP_CONFIG (templates),
|
||||
tmp, NULL, NULL);
|
||||
|
||||
class->get_child_by_name = func;
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_config_deserialize_file (GIMP_CONFIG (templates),
|
||||
tmp, NULL, NULL);
|
||||
}
|
||||
|
||||
g_free (tmp);
|
||||
|
||||
|
@@ -20,10 +20,10 @@
|
||||
#define __GIMP_TEMPLATES_H__
|
||||
|
||||
|
||||
void gimp_templates_load (Gimp *gimp);
|
||||
void gimp_templates_save (Gimp *gimp);
|
||||
void gimp_templates_load (Gimp *gimp);
|
||||
void gimp_templates_save (Gimp *gimp);
|
||||
|
||||
void gimp_templates_migrate (void);
|
||||
void gimp_templates_migrate (const gchar *olddir);
|
||||
|
||||
|
||||
#endif /* __GIMP_TEMPLATES_H__ */
|
||||
|
@@ -1,758 +0,0 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#ifdef G_OS_WIN32 /* gets defined by glib.h */
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifndef _O_BINARY
|
||||
#define _O_BINARY 0
|
||||
#endif
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
|
||||
#include "core-types.h"
|
||||
|
||||
#include "base/brush-scale.h"
|
||||
#include "base/temp-buf.h"
|
||||
|
||||
#include "config/gimpbaseconfig.h"
|
||||
|
||||
#include "gimpbrush.h"
|
||||
#include "gimpbrush-header.h"
|
||||
#include "gimpbrushgenerated.h"
|
||||
#include "gimpmarshal.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
SPACING_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
||||
static void gimp_brush_class_init (GimpBrushClass *klass);
|
||||
static void gimp_brush_init (GimpBrush *brush);
|
||||
|
||||
static void gimp_brush_finalize (GObject *object);
|
||||
|
||||
static gint64 gimp_brush_get_memsize (GimpObject *object,
|
||||
gint64 *gui_size);
|
||||
|
||||
static gboolean gimp_brush_get_popup_size (GimpViewable *viewable,
|
||||
gint width,
|
||||
gint height,
|
||||
gboolean dot_for_dot,
|
||||
gint *popup_width,
|
||||
gint *popup_height);
|
||||
static TempBuf * gimp_brush_get_new_preview (GimpViewable *viewable,
|
||||
gint width,
|
||||
gint height);
|
||||
static gchar * gimp_brush_get_description (GimpViewable *viewable,
|
||||
gchar **tooltip);
|
||||
static gchar * gimp_brush_get_extension (GimpData *data);
|
||||
|
||||
static GimpBrush * gimp_brush_real_select_brush (GimpBrush *brush,
|
||||
GimpCoords *last_coords,
|
||||
GimpCoords *cur_coords);
|
||||
static gboolean gimp_brush_real_want_null_motion (GimpBrush *brush,
|
||||
GimpCoords *last_coords,
|
||||
GimpCoords *cur_coords);
|
||||
|
||||
|
||||
static guint brush_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static GimpDataClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
gimp_brush_get_type (void)
|
||||
{
|
||||
static GType brush_type = 0;
|
||||
|
||||
if (! brush_type)
|
||||
{
|
||||
static const GTypeInfo brush_info =
|
||||
{
|
||||
sizeof (GimpBrushClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
(GClassInitFunc) gimp_brush_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (GimpBrush),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) gimp_brush_init,
|
||||
};
|
||||
|
||||
brush_type = g_type_register_static (GIMP_TYPE_DATA,
|
||||
"GimpBrush",
|
||||
&brush_info, 0);
|
||||
}
|
||||
|
||||
return brush_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_brush_class_init (GimpBrushClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
|
||||
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
|
||||
GimpDataClass *data_class = GIMP_DATA_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
brush_signals[SPACING_CHANGED] =
|
||||
g_signal_new ("spacing_changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GimpBrushClass, spacing_changed),
|
||||
NULL, NULL,
|
||||
gimp_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
object_class->finalize = gimp_brush_finalize;
|
||||
|
||||
gimp_object_class->get_memsize = gimp_brush_get_memsize;
|
||||
|
||||
viewable_class->default_stock_id = "gimp-tool-paintbrush";
|
||||
viewable_class->get_popup_size = gimp_brush_get_popup_size;
|
||||
viewable_class->get_new_preview = gimp_brush_get_new_preview;
|
||||
viewable_class->get_description = gimp_brush_get_description;
|
||||
|
||||
data_class->get_extension = gimp_brush_get_extension;
|
||||
|
||||
klass->select_brush = gimp_brush_real_select_brush;
|
||||
klass->want_null_motion = gimp_brush_real_want_null_motion;
|
||||
klass->spacing_changed = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_brush_init (GimpBrush *brush)
|
||||
{
|
||||
brush->mask = NULL;
|
||||
brush->pixmap = NULL;
|
||||
|
||||
brush->spacing = 20;
|
||||
brush->x_axis.x = 15.0;
|
||||
brush->x_axis.y = 0.0;
|
||||
brush->y_axis.x = 0.0;
|
||||
brush->y_axis.y = 15.0;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_brush_finalize (GObject *object)
|
||||
{
|
||||
GimpBrush *brush = GIMP_BRUSH (object);
|
||||
|
||||
if (brush->mask)
|
||||
{
|
||||
temp_buf_free (brush->mask);
|
||||
brush->mask = NULL;
|
||||
}
|
||||
|
||||
if (brush->pixmap)
|
||||
{
|
||||
temp_buf_free (brush->pixmap);
|
||||
brush->pixmap = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gint64
|
||||
gimp_brush_get_memsize (GimpObject *object,
|
||||
gint64 *gui_size)
|
||||
{
|
||||
GimpBrush *brush = GIMP_BRUSH (object);
|
||||
gint64 memsize = 0;
|
||||
|
||||
if (brush->mask)
|
||||
memsize += temp_buf_get_memsize (brush->mask);
|
||||
|
||||
if (brush->pixmap)
|
||||
memsize += temp_buf_get_memsize (brush->pixmap);
|
||||
|
||||
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
|
||||
gui_size);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_brush_get_popup_size (GimpViewable *viewable,
|
||||
gint width,
|
||||
gint height,
|
||||
gboolean dot_for_dot,
|
||||
gint *popup_width,
|
||||
gint *popup_height)
|
||||
{
|
||||
GimpBrush *brush = GIMP_BRUSH (viewable);
|
||||
|
||||
if (brush->mask->width > width || brush->mask->height > height)
|
||||
{
|
||||
*popup_width = brush->mask->width;
|
||||
*popup_height = brush->mask->height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static TempBuf *
|
||||
gimp_brush_get_new_preview (GimpViewable *viewable,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GimpBrush *brush = GIMP_BRUSH (viewable);
|
||||
gint brush_width;
|
||||
gint brush_height;
|
||||
TempBuf *mask_buf = NULL;
|
||||
TempBuf *pixmap_buf = NULL;
|
||||
TempBuf *return_buf = NULL;
|
||||
guchar transp[4] = { 0, 0, 0, 0 };
|
||||
guchar *mask;
|
||||
guchar *buf;
|
||||
gint x, y;
|
||||
gboolean scale = FALSE;
|
||||
|
||||
mask_buf = gimp_brush_get_mask (brush);
|
||||
pixmap_buf = gimp_brush_get_pixmap (brush);
|
||||
|
||||
brush_width = mask_buf->width;
|
||||
brush_height = mask_buf->height;
|
||||
|
||||
if (brush_width > width || brush_height > height)
|
||||
{
|
||||
gdouble ratio_x = (gdouble) brush_width / width;
|
||||
gdouble ratio_y = (gdouble) brush_height / height;
|
||||
|
||||
brush_width = (gdouble) brush_width / MAX (ratio_x, ratio_y) + 0.5;
|
||||
brush_height = (gdouble) brush_height / MAX (ratio_x, ratio_y) + 0.5;
|
||||
|
||||
if (brush_width <= 0) brush_width = 1;
|
||||
if (brush_height <= 0) brush_height = 1;
|
||||
|
||||
mask_buf = brush_scale_mask (mask_buf, brush_width, brush_height);
|
||||
|
||||
if (pixmap_buf)
|
||||
{
|
||||
/* TODO: the scale function should scale the pixmap and the
|
||||
* mask in one run
|
||||
*/
|
||||
pixmap_buf =
|
||||
brush_scale_pixmap (pixmap_buf, brush_width, brush_height);
|
||||
}
|
||||
|
||||
scale = TRUE;
|
||||
}
|
||||
|
||||
return_buf = temp_buf_new (brush_width, brush_height, 4, 0, 0, transp);
|
||||
|
||||
mask = temp_buf_data (mask_buf);
|
||||
buf = temp_buf_data (return_buf);
|
||||
|
||||
if (pixmap_buf)
|
||||
{
|
||||
guchar *pixmap = temp_buf_data (pixmap_buf);
|
||||
|
||||
for (y = 0; y < brush_height; y++)
|
||||
{
|
||||
for (x = 0; x < brush_width ; x++)
|
||||
{
|
||||
*buf++ = *pixmap++;
|
||||
*buf++ = *pixmap++;
|
||||
*buf++ = *pixmap++;
|
||||
*buf++ = *mask++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < brush_height; y++)
|
||||
{
|
||||
for (x = 0; x < brush_width ; x++)
|
||||
{
|
||||
*buf++ = 0;
|
||||
*buf++ = 0;
|
||||
*buf++ = 0;
|
||||
*buf++ = *mask++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scale)
|
||||
{
|
||||
temp_buf_free (mask_buf);
|
||||
|
||||
if (pixmap_buf)
|
||||
temp_buf_free (pixmap_buf);
|
||||
}
|
||||
|
||||
return return_buf;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gimp_brush_get_description (GimpViewable *viewable,
|
||||
gchar **tooltip)
|
||||
{
|
||||
GimpBrush *brush = GIMP_BRUSH (viewable);
|
||||
|
||||
if (tooltip)
|
||||
*tooltip = NULL;
|
||||
|
||||
return g_strdup_printf ("%s (%d x %d)",
|
||||
GIMP_OBJECT (brush)->name,
|
||||
brush->mask->width,
|
||||
brush->mask->height);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gimp_brush_get_extension (GimpData *data)
|
||||
{
|
||||
return GIMP_BRUSH_FILE_EXTENSION;
|
||||
}
|
||||
|
||||
GimpData *
|
||||
gimp_brush_new (const gchar *name,
|
||||
gboolean stingy_memory_use)
|
||||
{
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
return gimp_brush_generated_new (name,
|
||||
GIMP_BRUSH_GENERATED_CIRCLE,
|
||||
5.0, 2, 0.5, 1.0, 0.0,
|
||||
stingy_memory_use);
|
||||
}
|
||||
|
||||
GimpData *
|
||||
gimp_brush_get_standard (void)
|
||||
{
|
||||
static GimpData *standard_brush = NULL;
|
||||
|
||||
if (! standard_brush)
|
||||
{
|
||||
standard_brush = gimp_brush_new ("Standard", FALSE);
|
||||
|
||||
standard_brush->dirty = FALSE;
|
||||
gimp_data_make_internal (standard_brush);
|
||||
|
||||
/* set ref_count to 2 --> never swap the standard brush */
|
||||
g_object_ref (standard_brush);
|
||||
}
|
||||
|
||||
return standard_brush;
|
||||
}
|
||||
|
||||
GList *
|
||||
gimp_brush_load (const gchar *filename,
|
||||
gboolean stingy_memory_use,
|
||||
GError **error)
|
||||
{
|
||||
GimpBrush *brush;
|
||||
gint fd;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
g_return_val_if_fail (g_path_is_absolute (filename), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
fd = open (filename, O_RDONLY | _O_BINARY);
|
||||
if (fd == -1)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_OPEN,
|
||||
_("Could not open '%s' for reading: %s"),
|
||||
gimp_filename_to_utf8 (filename), g_strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
brush = gimp_brush_load_brush (fd, filename, error);
|
||||
|
||||
close (fd);
|
||||
|
||||
if (! brush)
|
||||
return NULL;
|
||||
|
||||
/* Swap the brush to disk (if we're being stingy with memory) */
|
||||
if (stingy_memory_use)
|
||||
{
|
||||
temp_buf_swap (brush->mask);
|
||||
|
||||
if (brush->pixmap)
|
||||
temp_buf_swap (brush->pixmap);
|
||||
}
|
||||
|
||||
return g_list_prepend (NULL, brush);
|
||||
}
|
||||
|
||||
GimpBrush *
|
||||
gimp_brush_select_brush (GimpBrush *brush,
|
||||
GimpCoords *last_coords,
|
||||
GimpCoords *cur_coords)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
|
||||
g_return_val_if_fail (last_coords != NULL, NULL);
|
||||
g_return_val_if_fail (cur_coords != NULL, NULL);
|
||||
|
||||
return GIMP_BRUSH_GET_CLASS (brush)->select_brush (brush,
|
||||
last_coords,
|
||||
cur_coords);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_brush_want_null_motion (GimpBrush *brush,
|
||||
GimpCoords *last_coords,
|
||||
GimpCoords *cur_coords)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_BRUSH (brush), FALSE);
|
||||
g_return_val_if_fail (last_coords != NULL, FALSE);
|
||||
g_return_val_if_fail (cur_coords != NULL, FALSE);
|
||||
|
||||
return GIMP_BRUSH_GET_CLASS (brush)->want_null_motion (brush,
|
||||
last_coords,
|
||||
cur_coords);
|
||||
}
|
||||
|
||||
static GimpBrush *
|
||||
gimp_brush_real_select_brush (GimpBrush *brush,
|
||||
GimpCoords *last_coords,
|
||||
GimpCoords *cur_coords)
|
||||
{
|
||||
return brush;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_brush_real_want_null_motion (GimpBrush *brush,
|
||||
GimpCoords *last_coords,
|
||||
GimpCoords *cur_coords)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TempBuf *
|
||||
gimp_brush_get_mask (const GimpBrush *brush)
|
||||
{
|
||||
g_return_val_if_fail (brush != NULL, NULL);
|
||||
g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
|
||||
|
||||
return brush->mask;
|
||||
}
|
||||
|
||||
TempBuf *
|
||||
gimp_brush_get_pixmap (const GimpBrush *brush)
|
||||
{
|
||||
g_return_val_if_fail (brush != NULL, NULL);
|
||||
g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
|
||||
|
||||
return brush->pixmap;
|
||||
}
|
||||
|
||||
gint
|
||||
gimp_brush_get_spacing (const GimpBrush *brush)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_BRUSH (brush), 0);
|
||||
|
||||
return brush->spacing;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_brush_set_spacing (GimpBrush *brush,
|
||||
gint spacing)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_BRUSH (brush));
|
||||
|
||||
if (brush->spacing != spacing)
|
||||
{
|
||||
brush->spacing = spacing;
|
||||
|
||||
gimp_brush_spacing_changed (brush);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimp_brush_spacing_changed (GimpBrush *brush)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_BRUSH (brush));
|
||||
|
||||
g_signal_emit (brush, brush_signals[SPACING_CHANGED], 0);
|
||||
}
|
||||
|
||||
GimpBrush *
|
||||
gimp_brush_load_brush (gint fd,
|
||||
const gchar *filename,
|
||||
GError **error)
|
||||
{
|
||||
GimpBrush *brush;
|
||||
gint bn_size;
|
||||
BrushHeader header;
|
||||
gchar *name = NULL;
|
||||
guchar *pixmap;
|
||||
guchar *mask;
|
||||
gssize i, size;
|
||||
gboolean success = TRUE;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
g_return_val_if_fail (fd != -1, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
/* Read in the header size */
|
||||
if (read (fd, &header, sizeof (header)) != sizeof (header))
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Could not read %d bytes from '%s': %s"),
|
||||
(gint) sizeof (header),
|
||||
gimp_filename_to_utf8 (filename), g_strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* rearrange the bytes in each unsigned int */
|
||||
header.header_size = g_ntohl (header.header_size);
|
||||
header.version = g_ntohl (header.version);
|
||||
header.width = g_ntohl (header.width);
|
||||
header.height = g_ntohl (header.height);
|
||||
header.bytes = g_ntohl (header.bytes);
|
||||
header.magic_number = g_ntohl (header.magic_number);
|
||||
header.spacing = g_ntohl (header.spacing);
|
||||
|
||||
/* Check for correct file format */
|
||||
|
||||
if (header.width == 0)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"Width = 0."),
|
||||
gimp_filename_to_utf8 (filename));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (header.height == 0)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"Height = 0."),
|
||||
gimp_filename_to_utf8 (filename));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (header.bytes == 0)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"Bytes = 0."),
|
||||
gimp_filename_to_utf8 (filename));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (header.version)
|
||||
{
|
||||
case 1:
|
||||
/* If this is a version 1 brush, set the fp back 8 bytes */
|
||||
lseek (fd, -8, SEEK_CUR);
|
||||
header.header_size += 8;
|
||||
/* spacing is not defined in version 1 */
|
||||
header.spacing = 25;
|
||||
break;
|
||||
|
||||
case 3: /* cinepaint brush */
|
||||
if (header.bytes == 18 /* FLOAT16_GRAY_GIMAGE */)
|
||||
{
|
||||
header.bytes = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"Unknown depth %d."),
|
||||
gimp_filename_to_utf8 (filename), header.bytes);
|
||||
return NULL;
|
||||
}
|
||||
/* fallthrough */
|
||||
|
||||
case 2:
|
||||
if (header.magic_number == GBRUSH_MAGIC)
|
||||
break;
|
||||
|
||||
default:
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"Unknown version %d."),
|
||||
gimp_filename_to_utf8 (filename), header.version);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Read in the brush name */
|
||||
if ((bn_size = (header.header_size - sizeof (header))))
|
||||
{
|
||||
gchar *utf8;
|
||||
|
||||
name = g_new (gchar, bn_size);
|
||||
|
||||
if ((read (fd, name, bn_size)) < bn_size)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"File appears truncated."),
|
||||
gimp_filename_to_utf8 (filename));
|
||||
g_free (name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
utf8 = gimp_any_to_utf8 (name, -1,
|
||||
_("Invalid UTF-8 string in brush file '%s'."),
|
||||
gimp_filename_to_utf8 (filename));
|
||||
g_free (name);
|
||||
name = utf8;
|
||||
}
|
||||
|
||||
if (!name)
|
||||
name = g_strdup (_("Unnamed"));
|
||||
|
||||
brush = g_object_new (GIMP_TYPE_BRUSH,
|
||||
"name", name,
|
||||
NULL);
|
||||
|
||||
g_free (name);
|
||||
|
||||
brush->mask = temp_buf_new (header.width, header.height, 1, 0, 0, NULL);
|
||||
|
||||
mask = temp_buf_data (brush->mask);
|
||||
size = header.width * header.height * header.bytes;
|
||||
|
||||
switch (header.bytes)
|
||||
{
|
||||
case 1:
|
||||
success = (read (fd, mask, size) == size);
|
||||
break;
|
||||
|
||||
case 2: /* cinepaint brush, 16 bit floats */
|
||||
{
|
||||
guchar buf[8 * 1024];
|
||||
|
||||
for (i = 0; success && i < size;)
|
||||
{
|
||||
gssize bytes = MIN (size - i, sizeof (buf));
|
||||
|
||||
success = (read (fd, buf, bytes) == bytes);
|
||||
|
||||
if (success)
|
||||
{
|
||||
guint16 *b = (guint16 *) buf;
|
||||
|
||||
i += bytes;
|
||||
|
||||
for (; bytes > 0; bytes -= 2, mask++, b++)
|
||||
{
|
||||
union
|
||||
{
|
||||
guint16 u[2];
|
||||
gfloat f;
|
||||
} short_float;
|
||||
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
short_float.u[0] = 0;
|
||||
short_float.u[1] = GUINT16_FROM_BE (*b);
|
||||
#else
|
||||
short_float.u[0] = GUINT16_FROM_BE (*b);
|
||||
short_float.u[1] = 0;
|
||||
#endif
|
||||
|
||||
*mask = (guchar) (short_float.f * 255.0 + 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
guchar buf[8 * 1024];
|
||||
|
||||
brush->pixmap = temp_buf_new (header.width, header.height,
|
||||
3, 0, 0, NULL);
|
||||
pixmap = temp_buf_data (brush->pixmap);
|
||||
|
||||
for (i = 0; success && i < size;)
|
||||
{
|
||||
gssize bytes = MIN (size - i, sizeof (buf));
|
||||
|
||||
success = (read (fd, buf, bytes) == bytes);
|
||||
|
||||
if (success)
|
||||
{
|
||||
guchar *b = buf;
|
||||
|
||||
i += bytes;
|
||||
|
||||
for (; bytes > 0; bytes -= 4, pixmap += 3, mask++, b += 4)
|
||||
{
|
||||
pixmap[0] = b[0];
|
||||
pixmap[1] = b[1];
|
||||
pixmap[2] = b[2];
|
||||
|
||||
mask[0] = b[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_object_unref (brush);
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"Unsupported brush depth %d\n"
|
||||
"GIMP brushes must be GRAY or RGBA."),
|
||||
gimp_filename_to_utf8 (filename), header.bytes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (! success)
|
||||
{
|
||||
g_object_unref (brush);
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"File appears truncated."),
|
||||
gimp_filename_to_utf8 (filename));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
brush->spacing = header.spacing;
|
||||
brush->x_axis.x = header.width / 2.0;
|
||||
brush->x_axis.y = 0.0;
|
||||
brush->y_axis.x = 0.0;
|
||||
brush->y_axis.y = header.height / 2.0;
|
||||
|
||||
return brush;
|
||||
}
|
@@ -402,18 +402,30 @@ void
|
||||
gimp_data_create_filename (GimpData *data,
|
||||
const gchar *dest_dir)
|
||||
{
|
||||
gchar *safename;
|
||||
gchar *filename;
|
||||
gchar *fullpath;
|
||||
gint i;
|
||||
gint unum = 1;
|
||||
gchar *safename;
|
||||
gchar *filename;
|
||||
gchar *fullpath;
|
||||
gint i;
|
||||
gint unum = 1;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (GIMP_IS_DATA (data));
|
||||
g_return_if_fail (dest_dir != NULL);
|
||||
g_return_if_fail (g_path_is_absolute (dest_dir));
|
||||
|
||||
if (data->internal)
|
||||
return;
|
||||
|
||||
safename = g_filename_from_utf8 (gimp_object_get_name (GIMP_OBJECT (data)),
|
||||
-1, NULL, NULL, NULL);
|
||||
-1, NULL, NULL, &error);
|
||||
if (! safename)
|
||||
{
|
||||
g_warning ("gimp_data_create_filename:\n"
|
||||
"g_filename_from_utf8() failed for '%s': %s",
|
||||
gimp_object_get_name (GIMP_OBJECT (data)), error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (safename[0] == '.')
|
||||
safename[0] = '-';
|
||||
|
@@ -147,6 +147,7 @@
|
||||
#include "gimpimage-undo-push.h"
|
||||
#include "gimplist.h"
|
||||
#include "gimplayer.h"
|
||||
#include "gimplayer-floating-sel.h"
|
||||
#include "gimppalette.h"
|
||||
#include "gimpprogress.h"
|
||||
|
||||
@@ -802,6 +803,9 @@ gimp_image_convert (GimpImage *gimage,
|
||||
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_CONVERT,
|
||||
undo_desc);
|
||||
|
||||
if (gimp_image_floating_sel (gimage))
|
||||
floating_sel_relax (gimp_image_floating_sel (gimage), TRUE);
|
||||
|
||||
/* Push the image type to the stack */
|
||||
gimp_image_undo_push_image_type (gimage, NULL);
|
||||
|
||||
@@ -1058,6 +1062,9 @@ gimp_image_convert (GimpImage *gimage,
|
||||
if (quantobj)
|
||||
quantobj->delete_func (quantobj);
|
||||
|
||||
if (gimp_image_floating_sel (gimage))
|
||||
floating_sel_rigor (gimp_image_floating_sel (gimage), TRUE);
|
||||
|
||||
gimp_image_undo_group_end (gimage);
|
||||
|
||||
gimp_image_invalidate_layer_previews (gimage);
|
||||
@@ -2202,9 +2209,9 @@ compute_color_gray (QuantizeObj *quantobj,
|
||||
/* Compute representative color for a box, put it in colormap[icolor] */
|
||||
{
|
||||
int i, min, max;
|
||||
long count;
|
||||
long total;
|
||||
long gtotal;
|
||||
guint64 count;
|
||||
guint64 total;
|
||||
guint64 gtotal;
|
||||
|
||||
min = boxp->Rmin;
|
||||
max = boxp->Rmax;
|
||||
@@ -2224,9 +2231,9 @@ compute_color_gray (QuantizeObj *quantobj,
|
||||
|
||||
if (total != 0)
|
||||
{
|
||||
quantobj->cmap[icolor].red = (gtotal + (total >> 1)) / total;
|
||||
quantobj->cmap[icolor].green = quantobj->cmap[icolor].red;
|
||||
quantobj->cmap[icolor].blue = quantobj->cmap[icolor].red;
|
||||
quantobj->cmap[icolor].red =
|
||||
quantobj->cmap[icolor].green =
|
||||
quantobj->cmap[icolor].blue = (gtotal + (total >> 1)) / total;
|
||||
}
|
||||
else /* The only situation where total==0 is if the image was null or
|
||||
* all-transparent. In that case we just put a dummy value in
|
||||
@@ -2755,8 +2762,7 @@ fill_inverse_cmap_gray (QuantizeObj *quantobj,
|
||||
|
||||
for (i = 0; i < quantobj->actual_number_of_colors; i++)
|
||||
{
|
||||
dist = pixel - cmap[i].red;
|
||||
dist *= dist;
|
||||
dist = ABS(pixel - cmap[i].red);
|
||||
|
||||
if (dist < mindist)
|
||||
{
|
||||
@@ -4201,7 +4207,6 @@ initialize_median_cut (GimpImageBaseType type,
|
||||
}
|
||||
|
||||
if (palette_type == GIMP_WEB_PALETTE ||
|
||||
palette_type == GIMP_MONO_PALETTE ||
|
||||
palette_type == GIMP_CUSTOM_PALETTE)
|
||||
{
|
||||
switch (dither_type)
|
||||
|
@@ -1023,11 +1023,13 @@ gimp_image_real_colormap_changed (GimpImage *gimage,
|
||||
{
|
||||
if (gimp_image_base_type (gimage) == GIMP_INDEXED)
|
||||
{
|
||||
gimp_image_color_hash_invalidate (gimage, color_index);
|
||||
|
||||
/* A colormap alteration affects the whole image */
|
||||
gimp_image_update (gimage, 0, 0, gimage->width, gimage->height);
|
||||
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (gimage));
|
||||
|
||||
gimp_image_color_hash_invalidate (gimage, color_index);
|
||||
gimp_image_invalidate_layer_previews (gimage);
|
||||
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (gimage));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2729,12 +2731,22 @@ gimp_image_remove_layer (GimpImage *gimage,
|
||||
GimpLayer *active_layer;
|
||||
gint index;
|
||||
gboolean old_has_alpha;
|
||||
gboolean undo_group = FALSE;
|
||||
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
g_return_if_fail (GIMP_IS_LAYER (layer));
|
||||
g_return_if_fail (gimp_container_have (gimage->layers,
|
||||
GIMP_OBJECT (layer)));
|
||||
|
||||
if (gimp_drawable_has_floating_sel (GIMP_DRAWABLE (layer)))
|
||||
{
|
||||
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE,
|
||||
_("Remove Layer"));
|
||||
undo_group = TRUE;
|
||||
|
||||
floating_sel_remove (gimp_image_floating_sel (gimage));
|
||||
}
|
||||
|
||||
active_layer = gimp_image_get_active_layer (gimage);
|
||||
|
||||
index = gimp_container_get_child_index (gimage->layers,
|
||||
@@ -2797,6 +2809,9 @@ gimp_image_remove_layer (GimpImage *gimage,
|
||||
|
||||
if (old_has_alpha != gimp_image_has_alpha (gimage))
|
||||
gimp_image_alpha_changed (gimage);
|
||||
|
||||
if (undo_group)
|
||||
gimp_image_undo_group_end (gimage);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -3024,12 +3039,22 @@ gimp_image_remove_channel (GimpImage *gimage,
|
||||
{
|
||||
GimpChannel *active_channel;
|
||||
gint index;
|
||||
gboolean undo_group = FALSE;
|
||||
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
||||
g_return_if_fail (gimp_container_have (gimage->channels,
|
||||
GIMP_OBJECT (channel)));
|
||||
|
||||
if (gimp_drawable_has_floating_sel (GIMP_DRAWABLE (channel)))
|
||||
{
|
||||
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE,
|
||||
_("Remove Channel"));
|
||||
undo_group = TRUE;
|
||||
|
||||
floating_sel_remove (gimp_image_floating_sel (gimage));
|
||||
}
|
||||
|
||||
active_channel = gimp_image_get_active_channel (gimage);
|
||||
|
||||
index = gimp_container_get_child_index (gimage->channels,
|
||||
@@ -3063,6 +3088,9 @@ gimp_image_remove_channel (GimpImage *gimage,
|
||||
}
|
||||
|
||||
g_object_unref (channel);
|
||||
|
||||
if (undo_group)
|
||||
gimp_image_undo_group_end (gimage);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@@ -673,6 +673,9 @@ gimp_imagefile_load_thumb (GimpImagefile *imagefile,
|
||||
if (gimp_thumbnail_peek_thumb (thumbnail, size) < GIMP_THUMB_STATE_EXISTS)
|
||||
return NULL;
|
||||
|
||||
if (thumbnail->image_state == GIMP_THUMB_STATE_NOT_FOUND)
|
||||
return NULL;
|
||||
|
||||
pixbuf = gimp_thumbnail_load_thumb (thumbnail, size, &error);
|
||||
|
||||
if (! pixbuf)
|
||||
|
@@ -66,10 +66,8 @@ static gint64 gimp_item_get_memsize (GimpObject *object,
|
||||
static GimpItem * gimp_item_real_duplicate (GimpItem *item,
|
||||
GType new_type,
|
||||
gboolean add_alpha);
|
||||
static GimpItem * gimp_item_real_convert_from (GimpItem *item,
|
||||
GimpImage *dest_image,
|
||||
GType new_type,
|
||||
gboolean add_alpha);
|
||||
static void gimp_item_real_convert (GimpItem *item,
|
||||
GimpImage *dest_image);
|
||||
static gboolean gimp_item_real_rename (GimpItem *item,
|
||||
const gchar *new_name,
|
||||
const gchar *undo_desc);
|
||||
@@ -176,8 +174,7 @@ gimp_item_class_init (GimpItemClass *klass)
|
||||
|
||||
klass->is_attached = NULL;
|
||||
klass->duplicate = gimp_item_real_duplicate;
|
||||
klass->convert_from = gimp_item_real_convert_from;
|
||||
klass->convert_to = NULL;
|
||||
klass->convert = gimp_item_real_convert;
|
||||
klass->rename = gimp_item_real_rename;
|
||||
klass->translate = gimp_item_real_translate;
|
||||
klass->scale = gimp_item_real_scale;
|
||||
@@ -306,13 +303,11 @@ gimp_item_real_duplicate (GimpItem *item,
|
||||
return new_item;
|
||||
}
|
||||
|
||||
static GimpItem *
|
||||
gimp_item_real_convert_from (GimpItem *item,
|
||||
GimpImage *dest_image,
|
||||
GType new_type,
|
||||
gboolean add_alpha)
|
||||
static void
|
||||
gimp_item_real_convert (GimpItem *item,
|
||||
GimpImage *dest_image)
|
||||
{
|
||||
return gimp_item_duplicate (item, new_type, add_alpha);
|
||||
gimp_item_set_image (item, dest_image);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -536,17 +531,10 @@ gimp_item_convert (GimpItem *item,
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL);
|
||||
g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_ITEM), NULL);
|
||||
|
||||
new_item = GIMP_ITEM_GET_CLASS (item)->convert_from (item, dest_image,
|
||||
new_type, add_alpha);
|
||||
new_item = gimp_item_duplicate (item, new_type, add_alpha);
|
||||
|
||||
if (new_item)
|
||||
{
|
||||
if (dest_image != item->gimage)
|
||||
gimp_item_set_image (new_item, dest_image);
|
||||
|
||||
if (GIMP_ITEM_GET_CLASS (new_item)->convert_to)
|
||||
GIMP_ITEM_GET_CLASS (new_item)->convert_to (new_item, item);
|
||||
}
|
||||
GIMP_ITEM_GET_CLASS (new_item)->convert (new_item, dest_image);
|
||||
|
||||
return new_item;
|
||||
}
|
||||
|
@@ -68,12 +68,8 @@ struct _GimpItemClass
|
||||
GimpItem * (* duplicate) (GimpItem *item,
|
||||
GType new_type,
|
||||
gboolean add_alpha);
|
||||
GimpItem * (* convert_from) (GimpItem *item,
|
||||
GimpImage *dest_image,
|
||||
GType new_type,
|
||||
gboolean add_alpha);
|
||||
void (* convert_to) (GimpItem *item,
|
||||
GimpItem *src_item);
|
||||
void (* convert) (GimpItem *item,
|
||||
GimpImage *dest_image);
|
||||
gboolean (* rename) (GimpItem *item,
|
||||
const gchar *new_name,
|
||||
const gchar *undo_desc);
|
||||
|
@@ -79,8 +79,8 @@ static gboolean gimp_layer_is_attached (GimpItem *item);
|
||||
static GimpItem * gimp_layer_duplicate (GimpItem *item,
|
||||
GType new_type,
|
||||
gboolean add_alpha);
|
||||
static void gimp_layer_convert_to (GimpItem *item,
|
||||
GimpItem *src_item);
|
||||
static void gimp_layer_convert (GimpItem *item,
|
||||
GimpImage *dest_image);
|
||||
static gboolean gimp_layer_rename (GimpItem *item,
|
||||
const gchar *new_name,
|
||||
const gchar *undo_desc);
|
||||
@@ -239,7 +239,7 @@ gimp_layer_class_init (GimpLayerClass *klass)
|
||||
item_class->removed = gimp_layer_removed;
|
||||
item_class->is_attached = gimp_layer_is_attached;
|
||||
item_class->duplicate = gimp_layer_duplicate;
|
||||
item_class->convert_to = gimp_layer_convert_to;
|
||||
item_class->convert = gimp_layer_convert;
|
||||
item_class->rename = gimp_layer_rename;
|
||||
item_class->translate = gimp_layer_translate;
|
||||
item_class->scale = gimp_layer_scale;
|
||||
@@ -487,19 +487,16 @@ gimp_layer_duplicate (GimpItem *item,
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_layer_convert_to (GimpItem *item,
|
||||
GimpItem *src_item)
|
||||
gimp_layer_convert (GimpItem *item,
|
||||
GimpImage *dest_image)
|
||||
{
|
||||
GimpLayer *layer = GIMP_LAYER (item);
|
||||
GimpDrawable *drawable = GIMP_DRAWABLE (item);
|
||||
GimpImageBaseType old_base_type;
|
||||
GimpImageBaseType new_base_type;
|
||||
|
||||
if (GIMP_ITEM_CLASS (parent_class)->convert_to)
|
||||
GIMP_ITEM_CLASS (parent_class)->convert_to (item, src_item);
|
||||
|
||||
old_base_type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (drawable));
|
||||
new_base_type = gimp_image_base_type (gimp_item_get_image (item));
|
||||
new_base_type = gimp_image_base_type (dest_image);
|
||||
|
||||
if (old_base_type != new_base_type)
|
||||
{
|
||||
@@ -560,8 +557,10 @@ gimp_layer_convert_to (GimpItem *item,
|
||||
tile_manager_unref (new_tiles);
|
||||
}
|
||||
|
||||
if (layer->mask && item->gimage != src_item->gimage)
|
||||
gimp_item_set_image (GIMP_ITEM (layer->mask), item->gimage);
|
||||
if (layer->mask)
|
||||
gimp_item_set_image (GIMP_ITEM (layer->mask), dest_image);
|
||||
|
||||
GIMP_ITEM_CLASS (parent_class)->convert (item, dest_image);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@@ -261,9 +261,10 @@ gimp_parasite_list_deserialize (GimpConfig *list,
|
||||
case G_TOKEN_SYMBOL:
|
||||
if (scanner->value.v_symbol == parasite_symbol)
|
||||
{
|
||||
gchar *parasite_name = NULL;
|
||||
gint parasite_flags = 0;
|
||||
gchar *parasite_data = NULL;
|
||||
gchar *parasite_name = NULL;
|
||||
gint parasite_flags = 0;
|
||||
guint8 *parasite_data = NULL;
|
||||
gint parasite_data_size = 0;
|
||||
GimpParasite *parasite;
|
||||
|
||||
token = G_TOKEN_STRING;
|
||||
@@ -282,17 +283,43 @@ gimp_parasite_list_deserialize (GimpConfig *list,
|
||||
if (! gimp_scanner_parse_int (scanner, ¶site_flags))
|
||||
goto cleanup;
|
||||
|
||||
token = G_TOKEN_STRING;
|
||||
token = G_TOKEN_INT;
|
||||
|
||||
if (g_scanner_peek_next_token (scanner) != token)
|
||||
goto cleanup;
|
||||
{
|
||||
/* old format -- plain string */
|
||||
|
||||
if (! gimp_scanner_parse_string (scanner, ¶site_data))
|
||||
goto cleanup;
|
||||
gchar *str;
|
||||
|
||||
if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING)
|
||||
goto cleanup;
|
||||
|
||||
if (! gimp_scanner_parse_string (scanner, &str))
|
||||
goto cleanup;
|
||||
|
||||
parasite_data_size = strlen (str);
|
||||
parasite_data = str;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* new format -- properly encoded binary data */
|
||||
|
||||
if (! gimp_scanner_parse_int (scanner, ¶site_data_size))
|
||||
goto cleanup;
|
||||
|
||||
token = G_TOKEN_STRING;
|
||||
|
||||
if (g_scanner_peek_next_token (scanner) != token)
|
||||
goto cleanup;
|
||||
|
||||
if (! gimp_scanner_parse_data (scanner, parasite_data_size,
|
||||
¶site_data))
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
parasite = gimp_parasite_new (parasite_name,
|
||||
parasite_flags,
|
||||
strlen (parasite_data),
|
||||
parasite_data_size,
|
||||
parasite_data);
|
||||
gimp_parasite_list_add (GIMP_PARASITE_LIST (list),
|
||||
parasite); /* adds a copy */
|
||||
@@ -301,7 +328,7 @@ gimp_parasite_list_deserialize (GimpConfig *list,
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
|
||||
g_free (parasite_data);
|
||||
cleanup:
|
||||
cleanup:
|
||||
g_free (parasite_name);
|
||||
}
|
||||
break;
|
||||
@@ -442,51 +469,19 @@ parasite_serialize (const gchar *key,
|
||||
GimpParasite *parasite,
|
||||
GimpConfigWriter *writer)
|
||||
{
|
||||
GString *str;
|
||||
const gchar *data;
|
||||
guint32 len;
|
||||
|
||||
if (! gimp_parasite_is_persistent (parasite))
|
||||
return;
|
||||
|
||||
gimp_config_writer_open (writer, parasite_symbol);
|
||||
|
||||
str = g_string_sized_new (64);
|
||||
gimp_config_writer_printf (writer, "\"%s\" %lu %lu",
|
||||
gimp_parasite_name (parasite),
|
||||
gimp_parasite_flags (parasite),
|
||||
gimp_parasite_data_size (parasite));
|
||||
|
||||
g_string_printf (str, "\"%s\" %lu \"",
|
||||
gimp_parasite_name (parasite),
|
||||
gimp_parasite_flags (parasite));
|
||||
|
||||
/* the current methodology is: never move the parasiterc from one
|
||||
* system to another. If you want to do this you should probably
|
||||
* write out parasites which contain any non-alphanumeric(+some)
|
||||
* characters as \xHH sequences altogether.
|
||||
*/
|
||||
|
||||
data = (const gchar *) gimp_parasite_data (parasite);
|
||||
|
||||
for (len = gimp_parasite_data_size (parasite); len > 0; len--, data++)
|
||||
{
|
||||
switch (*data)
|
||||
{
|
||||
case '\\': g_string_append_len (str, "\\\\", 2); break;
|
||||
case '\0': g_string_append_len (str, "\\0" , 2); break;
|
||||
case '"' : g_string_append_len (str, "\\\"", 2); break;
|
||||
/* disabled, not portable! */
|
||||
/* case '\n': fputs ("\\n", fp); break;*/
|
||||
/* case '\r': fputs ("\\r", fp); break;*/
|
||||
case 26 : g_string_append_len (str, "\\z", 2); break;
|
||||
|
||||
default : g_string_append_c (str, *data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_string_append (str, "\"");
|
||||
|
||||
gimp_config_writer_print (writer, str->str, str->len);
|
||||
|
||||
g_string_free (str, TRUE);
|
||||
gimp_config_writer_data (writer,
|
||||
gimp_parasite_data_size (parasite),
|
||||
gimp_parasite_data (parasite));
|
||||
|
||||
gimp_config_writer_close (writer);
|
||||
gimp_config_writer_linefeed (writer);
|
||||
|
@@ -366,7 +366,9 @@ static gboolean
|
||||
convert_dialog_palette_filter (const GimpObject *object,
|
||||
gpointer user_data)
|
||||
{
|
||||
return GIMP_PALETTE (object)->n_colors <= 256;
|
||||
GimpPalette *palette = GIMP_PALETTE (object);
|
||||
|
||||
return palette->n_colors > 0 && palette->n_colors <= 256;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -117,7 +117,7 @@ file_open_dialog_response (GtkWidget *open_dialog,
|
||||
|
||||
for (list = uris; list; list = g_slist_next (list))
|
||||
{
|
||||
gchar *filename = g_filename_from_uri (list->data, NULL, NULL);
|
||||
gchar *filename = file_utils_filename_from_uri (list->data);
|
||||
|
||||
if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
|
@@ -158,14 +158,16 @@ file_open_location_response (GtkDialog *dialog,
|
||||
GimpImage *image;
|
||||
gchar *uri;
|
||||
gchar *filename;
|
||||
gchar *hostname;
|
||||
GError *error = NULL;
|
||||
GimpPDBStatusType status;
|
||||
|
||||
filename = g_filename_from_uri (text, NULL, NULL);
|
||||
filename = g_filename_from_uri (text, &hostname, NULL);
|
||||
|
||||
if (filename)
|
||||
{
|
||||
uri = g_filename_to_uri (filename, NULL, NULL);
|
||||
uri = g_filename_to_uri (filename, hostname, NULL);
|
||||
g_free (hostname);
|
||||
g_free (filename);
|
||||
}
|
||||
else
|
||||
|
@@ -68,7 +68,8 @@ static gboolean file_save_dialog_save_image (GtkWidget *save_dialog,
|
||||
GtkWidget *
|
||||
file_save_dialog_new (Gimp *gimp)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *dialog;
|
||||
const gchar *uri;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
|
||||
|
||||
@@ -78,6 +79,26 @@ file_save_dialog_new (Gimp *gimp)
|
||||
GTK_STOCK_SAVE,
|
||||
GIMP_HELP_FILE_SAVE);
|
||||
|
||||
uri = g_object_get_data (G_OBJECT (gimp), "gimp-file-save-last-uri");
|
||||
|
||||
if (uri)
|
||||
{
|
||||
gchar *folder_uri = g_path_get_dirname (uri);
|
||||
|
||||
#ifdef __GNUC__
|
||||
#warning: FIXME: should use set_uri() but idle stuff in the file chooser seems to override set_current_name() when called immediately after set_uri()
|
||||
#endif
|
||||
|
||||
if (folder_uri)
|
||||
{
|
||||
gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog),
|
||||
folder_uri);
|
||||
g_free (folder_uri);
|
||||
}
|
||||
|
||||
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "");
|
||||
}
|
||||
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (file_save_dialog_response),
|
||||
gimp);
|
||||
@@ -95,7 +116,6 @@ file_save_dialog_response (GtkWidget *save_dialog,
|
||||
{
|
||||
GimpFileDialog *dialog = GIMP_FILE_DIALOG (save_dialog);
|
||||
gchar *uri;
|
||||
gchar *filename;
|
||||
|
||||
if (response_id != GTK_RESPONSE_OK)
|
||||
{
|
||||
@@ -107,31 +127,36 @@ file_save_dialog_response (GtkWidget *save_dialog,
|
||||
|
||||
uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (save_dialog));
|
||||
|
||||
filename = g_filename_from_uri (uri, NULL, NULL);
|
||||
|
||||
if (g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||
if (uri && strlen (uri))
|
||||
{
|
||||
file_save_overwrite (save_dialog, uri, uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_file_dialog_set_sensitive (dialog, FALSE);
|
||||
gchar *filename = file_utils_filename_from_uri (uri);
|
||||
|
||||
if (file_save_dialog_save_image (save_dialog,
|
||||
dialog->gimage,
|
||||
uri,
|
||||
uri,
|
||||
dialog->file_proc,
|
||||
dialog->save_a_copy))
|
||||
g_return_if_fail (filename != NULL);
|
||||
|
||||
if (g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
gtk_widget_hide (save_dialog);
|
||||
file_save_overwrite (save_dialog, uri, uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_file_dialog_set_sensitive (dialog, FALSE);
|
||||
|
||||
if (file_save_dialog_save_image (save_dialog,
|
||||
dialog->gimage,
|
||||
uri,
|
||||
uri,
|
||||
dialog->file_proc,
|
||||
dialog->save_a_copy))
|
||||
{
|
||||
gtk_widget_hide (save_dialog);
|
||||
}
|
||||
|
||||
gimp_file_dialog_set_sensitive (dialog, TRUE);
|
||||
}
|
||||
|
||||
gimp_file_dialog_set_sensitive (dialog, TRUE);
|
||||
g_free (filename);
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
g_free (uri);
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
typedef struct _OverwriteData OverwriteData;
|
||||
@@ -231,6 +256,8 @@ file_save_dialog_save_image (GtkWidget *save_dialog,
|
||||
GimpPDBStatusType status;
|
||||
GError *error = NULL;
|
||||
|
||||
g_object_ref (gimage);
|
||||
|
||||
status = file_save_as (gimage,
|
||||
gimp_get_user_context (gimage->gimp),
|
||||
GIMP_PROGRESS (save_dialog),
|
||||
@@ -241,6 +268,12 @@ file_save_dialog_save_image (GtkWidget *save_dialog,
|
||||
save_a_copy,
|
||||
&error);
|
||||
|
||||
if (status == GIMP_PDB_SUCCESS)
|
||||
g_object_set_data_full (G_OBJECT (gimage->gimp), "gimp-file-save-last-uri",
|
||||
g_strdup (uri), (GDestroyNotify) g_free);
|
||||
|
||||
g_object_unref (gimage);
|
||||
|
||||
if (status != GIMP_PDB_SUCCESS &&
|
||||
status != GIMP_PDB_CANCEL)
|
||||
{
|
||||
|
@@ -89,7 +89,7 @@ image_scale_dialog_new (GimpImage *image,
|
||||
dialog->context = context;
|
||||
dialog->dialog = scale_dialog_new (GIMP_VIEWABLE (display->gimage),
|
||||
_("Scale Image"), "gimp-image-scale",
|
||||
display->shell,
|
||||
parent,
|
||||
gimp_standard_help_func,
|
||||
GIMP_HELP_IMAGE_SCALE,
|
||||
GIMP_DISPLAY_SHELL (display->shell)->unit,
|
||||
|
@@ -56,6 +56,8 @@ static void info_dialog_field_new (InfoDialog *idialog,
|
||||
GCallback callback,
|
||||
gpointer callback_data);
|
||||
static void info_dialog_update_field (InfoField *info_field);
|
||||
static void info_dialog_field_free (gpointer data,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
/* public functions */
|
||||
@@ -92,12 +94,24 @@ info_dialog_notebook_new (GimpViewable *viewable,
|
||||
help_func, help_data, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
info_dialog_field_free (gpointer data,
|
||||
gpointer user_data)
|
||||
{
|
||||
InfoField *field = data;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (field->obj,
|
||||
field->callback,
|
||||
field->callback_data);
|
||||
g_free (field);
|
||||
}
|
||||
|
||||
void
|
||||
info_dialog_free (InfoDialog *idialog)
|
||||
{
|
||||
g_return_if_fail (idialog != NULL);
|
||||
|
||||
g_slist_foreach (idialog->field_list, (GFunc) g_free, NULL);
|
||||
g_slist_foreach (idialog->field_list, (GFunc) info_dialog_field_free, NULL);
|
||||
g_slist_free (idialog->field_list);
|
||||
|
||||
gtk_widget_destroy (idialog->shell);
|
||||
|
@@ -103,8 +103,8 @@ print_size_dialog_new (GimpImage *image,
|
||||
parent,
|
||||
help_func, help_id,
|
||||
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GIMP_STOCK_RESET, RESPONSE_RESET,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
||||
|
||||
NULL);
|
||||
@@ -298,8 +298,8 @@ print_size_dialog_response (GtkWidget *dialog,
|
||||
case GTK_RESPONSE_OK:
|
||||
private->callback (dialog,
|
||||
private->image,
|
||||
gimp_size_entry_get_value (entry, 0),
|
||||
gimp_size_entry_get_value (entry, 1),
|
||||
gimp_size_entry_get_refval (entry, 0),
|
||||
gimp_size_entry_get_refval (entry, 1),
|
||||
gimp_size_entry_get_unit (entry),
|
||||
private->user_data);
|
||||
break;
|
||||
|
@@ -135,8 +135,8 @@ resize_dialog_new (GimpViewable *viewable,
|
||||
parent,
|
||||
help_func, help_id,
|
||||
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GIMP_STOCK_RESET, RESPONSE_RESET,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GIMP_STOCK_RESIZE, GTK_RESPONSE_OK,
|
||||
|
||||
NULL);
|
||||
@@ -253,7 +253,8 @@ resize_dialog_new (GimpViewable *viewable,
|
||||
gimp_viewable_get_preview_size (viewable, 200, FALSE, TRUE, &width, &height);
|
||||
pixbuf = gimp_viewable_get_pixbuf (viewable, width, height);
|
||||
|
||||
gimp_offset_area_set_pixbuf (GIMP_OFFSET_AREA (private->area), pixbuf);
|
||||
if (pixbuf)
|
||||
gimp_offset_area_set_pixbuf (GIMP_OFFSET_AREA (private->area), pixbuf);
|
||||
|
||||
g_signal_connect (private->area, "offsets_changed",
|
||||
G_CALLBACK (offsets_changed),
|
||||
@@ -307,9 +308,15 @@ resize_dialog_reset (ResizeDialog *private)
|
||||
{
|
||||
g_object_set (private->box,
|
||||
"keep-aspect", FALSE,
|
||||
NULL);
|
||||
|
||||
g_object_set (private->box,
|
||||
"width", private->old_width,
|
||||
"height", private->old_height,
|
||||
"unit", private->old_unit,
|
||||
NULL);
|
||||
|
||||
g_object_set (private->box,
|
||||
"keep-aspect", TRUE,
|
||||
NULL);
|
||||
}
|
||||
|
@@ -116,8 +116,8 @@ scale_dialog_new (GimpViewable *viewable,
|
||||
parent,
|
||||
help_func, help_id,
|
||||
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GIMP_STOCK_RESET, RESPONSE_RESET,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GIMP_STOCK_SCALE, GTK_RESPONSE_OK,
|
||||
|
||||
NULL);
|
||||
@@ -279,9 +279,15 @@ scale_dialog_reset (ScaleDialog *private)
|
||||
|
||||
g_object_set (private->box,
|
||||
"keep-aspect", FALSE,
|
||||
NULL);
|
||||
|
||||
g_object_set (private->box,
|
||||
"width", width,
|
||||
"height", height,
|
||||
"unit", private->unit,
|
||||
NULL);
|
||||
|
||||
g_object_set (private->box,
|
||||
"keep-aspect", TRUE,
|
||||
"xresolution", xres,
|
||||
"yresolution", yres,
|
||||
|
@@ -1294,7 +1294,7 @@ user_install_migrate_files (const gchar *oldgimp,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gimp_templates_migrate ();
|
||||
gimp_templates_migrate (oldgimp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -106,7 +106,7 @@ static void gimp_display_shell_get_device_state (GimpDisplayShell *shell,
|
||||
static GdkModifierType
|
||||
gimp_display_shell_key_to_state (gint key);
|
||||
|
||||
GdkEvent * gimp_display_shell_compress_motion (GimpDisplayShell *shell);
|
||||
static GdkEvent * gimp_display_shell_compress_motion (GimpDisplayShell *shell);
|
||||
|
||||
|
||||
/* public functions */
|
||||
@@ -785,6 +785,13 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
|
||||
case 1:
|
||||
state &= ~GDK_BUTTON1_MASK;
|
||||
|
||||
if (! shell->space_pressed && ! shell->space_release_pending)
|
||||
gdk_display_keyboard_ungrab (gdk_display, time);
|
||||
|
||||
gdk_display_pointer_ungrab (gdk_display, time);
|
||||
|
||||
gtk_grab_add (canvas);
|
||||
|
||||
if (active_tool &&
|
||||
(! gimp_image_is_empty (gimage) ||
|
||||
gimp_tool_control_handles_empty_image (active_tool->control)))
|
||||
@@ -808,10 +815,7 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
|
||||
&image_coords, state,
|
||||
gdisp);
|
||||
|
||||
if (! shell->space_pressed && ! shell->space_release_pending)
|
||||
gdk_display_keyboard_ungrab (gdk_display, time);
|
||||
|
||||
gdk_display_pointer_ungrab (gdk_display, time);
|
||||
gtk_grab_remove (canvas);
|
||||
|
||||
if (shell->space_release_pending)
|
||||
{
|
||||
@@ -1064,8 +1068,19 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
|
||||
&device_coords);
|
||||
|
||||
if (device_coords.x == mevent->x &&
|
||||
device_coords.y == mevent->y)
|
||||
{
|
||||
device_coords.y == mevent->y
|
||||
#ifdef G_OS_WIN32
|
||||
/* The Win32 backend for GDK just returns the
|
||||
* coordinates from the last motion/button event
|
||||
* for extended input devices, so if the event is
|
||||
* put back in the queue, this will keep scrolling
|
||||
* until the edge of the image is reached (bug
|
||||
* #167960) */
|
||||
&& mevent->device == gdk_display_get_core_pointer (
|
||||
gdk_display_get_default ())
|
||||
#endif /* G_OS_WIN32 */
|
||||
)
|
||||
{
|
||||
/* Put this event back on the queue
|
||||
* so it keeps scrolling
|
||||
*/
|
||||
@@ -1738,7 +1753,7 @@ gimp_display_shell_key_to_state (gint key)
|
||||
* The gimp_display_shell_compress_motion function source may be re-used under
|
||||
* the XFree86-style license. <adam@gimp.org>
|
||||
*/
|
||||
GdkEvent *
|
||||
static GdkEvent *
|
||||
gimp_display_shell_compress_motion (GimpDisplayShell *shell)
|
||||
{
|
||||
GdkEvent *event;
|
||||
|
@@ -135,7 +135,7 @@ gimp_display_shell_close_dialog (GimpDisplayShell *shell,
|
||||
NULL);
|
||||
g_free (title);
|
||||
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), RESPONSE_SAVE);
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
|
||||
|
||||
g_signal_connect (dialog, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed),
|
||||
|
@@ -456,11 +456,15 @@ gimp_display_shell_scale_by_values (GimpDisplayShell *shell,
|
||||
gint offset_y,
|
||||
gboolean resize_window)
|
||||
{
|
||||
Gimp *gimp;
|
||||
|
||||
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
||||
|
||||
gimp = shell->gdisp->gimage->gimp;
|
||||
/* Abort early if the values are all setup already. We don't
|
||||
* want to inadvertently resize the window (bug #164281).
|
||||
*/
|
||||
if (shell->scale == scale &&
|
||||
shell->offset_x == offset_x &&
|
||||
shell->offset_y == offset_y)
|
||||
return;
|
||||
|
||||
/* freeze the active tool */
|
||||
gimp_display_shell_pause (shell);
|
||||
|
@@ -1533,6 +1533,9 @@ gimp_display_shell_set_highlight (GimpDisplayShell *shell,
|
||||
|
||||
gdk_region_get_rectangles (old, &rects, &num_rects);
|
||||
|
||||
gdk_region_destroy (old);
|
||||
gdk_region_destroy (new);
|
||||
|
||||
for (i = 0; i < num_rects; i++)
|
||||
gimp_display_update_area (shell->gdisp, TRUE,
|
||||
rects[i].x,
|
||||
|
@@ -252,7 +252,7 @@ gimp_scale_combo_box_set_scale (GimpScaleComboBox *combo_box,
|
||||
SCALE, &this,
|
||||
-1);
|
||||
|
||||
if (this == scale)
|
||||
if (fabs (this - scale) < 0.01)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -154,6 +154,7 @@ gimp_statusbar_init (GimpStatusbar *statusbar)
|
||||
GtkWidget *frame;
|
||||
GimpUnitStore *store;
|
||||
GtkShadowType shadow_type;
|
||||
gboolean has_focus_on_click;
|
||||
|
||||
box->spacing = 2;
|
||||
box->homogeneous = FALSE;
|
||||
@@ -188,6 +189,13 @@ gimp_statusbar_init (GimpStatusbar *statusbar)
|
||||
statusbar->unit_combo = gimp_unit_combo_box_new_with_model (store);
|
||||
g_object_unref (store);
|
||||
|
||||
has_focus_on_click =
|
||||
g_object_class_find_property (G_OBJECT_GET_CLASS (statusbar->unit_combo),
|
||||
"focus-on-click") != NULL;
|
||||
|
||||
GTK_WIDGET_UNSET_FLAGS (statusbar->unit_combo, GTK_CAN_FOCUS);
|
||||
if (has_focus_on_click)
|
||||
g_object_set (statusbar->unit_combo, "focus-on-click", FALSE, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), statusbar->unit_combo);
|
||||
gtk_widget_show (statusbar->unit_combo);
|
||||
|
||||
@@ -201,6 +209,9 @@ gimp_statusbar_init (GimpStatusbar *statusbar)
|
||||
gtk_widget_show (frame);
|
||||
|
||||
statusbar->scale_combo = gimp_scale_combo_box_new ();
|
||||
GTK_WIDGET_UNSET_FLAGS (statusbar->scale_combo, GTK_CAN_FOCUS);
|
||||
if (has_focus_on_click)
|
||||
g_object_set (statusbar->scale_combo, "focus-on-click", FALSE, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (frame), statusbar->scale_combo);
|
||||
gtk_widget_show (statusbar->scale_combo);
|
||||
|
||||
@@ -218,6 +229,7 @@ gimp_statusbar_init (GimpStatusbar *statusbar)
|
||||
statusbar->cancel_button = gtk_button_new_with_label (_("Cancel"));
|
||||
gtk_widget_set_sensitive (statusbar->cancel_button, FALSE);
|
||||
gtk_box_pack_start (box, statusbar->cancel_button, FALSE, FALSE, 0);
|
||||
GTK_WIDGET_UNSET_FLAGS (statusbar->cancel_button, GTK_CAN_FOCUS);
|
||||
gtk_widget_show (statusbar->cancel_button);
|
||||
|
||||
g_signal_connect (statusbar->cancel_button, "clicked",
|
||||
@@ -479,9 +491,9 @@ gimp_statusbar_push_coords (GimpStatusbar *statusbar,
|
||||
{
|
||||
g_snprintf (buf, sizeof (buf), statusbar->cursor_format_str,
|
||||
title,
|
||||
ROUND (x),
|
||||
(gint) RINT (x),
|
||||
separator,
|
||||
ROUND (y));
|
||||
(gint) RINT (y));
|
||||
}
|
||||
else /* show real world units */
|
||||
{
|
||||
@@ -518,7 +530,7 @@ gimp_statusbar_push_length (GimpStatusbar *statusbar,
|
||||
{
|
||||
g_snprintf (buf, sizeof (buf), statusbar->length_format_str,
|
||||
title,
|
||||
ROUND (value));
|
||||
(gint) RINT (value));
|
||||
}
|
||||
else /* show real world units */
|
||||
{
|
||||
@@ -654,7 +666,7 @@ gimp_statusbar_set_cursor (GimpStatusbar *statusbar,
|
||||
{
|
||||
g_snprintf (buffer, sizeof (buffer),
|
||||
statusbar->cursor_format_str,
|
||||
"", ROUND (x), ", ", ROUND (y));
|
||||
"", (gint) RINT (x), ", ", (gint) RINT (y));
|
||||
}
|
||||
else /* show real world units */
|
||||
{
|
||||
|
@@ -106,7 +106,7 @@ file_open_image (Gimp *gimp,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
filename = g_filename_from_uri (uri, NULL, NULL);
|
||||
filename = file_utils_filename_from_uri (uri);
|
||||
|
||||
if (filename)
|
||||
{
|
||||
@@ -224,7 +224,7 @@ file_open_thumbnail (Gimp *gimp,
|
||||
gint image_id;
|
||||
gint i;
|
||||
|
||||
filename = g_filename_from_uri (uri, NULL, NULL);
|
||||
filename = file_utils_filename_from_uri (uri);
|
||||
|
||||
args = g_new0 (Argument, proc->num_args);
|
||||
|
||||
@@ -362,7 +362,7 @@ file_open_layer (Gimp *gimp,
|
||||
|
||||
new_image = file_open_image (gimp, context, progress,
|
||||
uri, uri,
|
||||
NULL, GIMP_RUN_NONINTERACTIVE,
|
||||
NULL, GIMP_RUN_INTERACTIVE,
|
||||
status, &mime_type, error);
|
||||
|
||||
if (new_image)
|
||||
|
@@ -133,7 +133,7 @@ file_save_as (GimpImage *gimage,
|
||||
return GIMP_PDB_CALLING_ERROR;
|
||||
}
|
||||
|
||||
filename = g_filename_from_uri (uri, NULL, NULL);
|
||||
filename = file_utils_filename_from_uri (uri);
|
||||
|
||||
if (filename)
|
||||
{
|
||||
|
@@ -129,6 +129,53 @@ file_utils_filename_to_uri (GSList *procs,
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* file_utils_filename_from_uri:
|
||||
* @uri: a URI
|
||||
*
|
||||
* A utility function to be used as a replacement for
|
||||
* g_filename_from_uri(). It deals with file: URIs with hostname in a
|
||||
* platform-specific way. On Win32, a UNC path is created and
|
||||
* returned, on other platforms the URI is detected as non-local and
|
||||
* NULL is returned.
|
||||
*
|
||||
* Returns: newly allocated filename or %NULL if @uri is a remote file
|
||||
**/
|
||||
gchar *
|
||||
file_utils_filename_from_uri (const gchar *uri)
|
||||
{
|
||||
gchar *filename;
|
||||
gchar *hostname;
|
||||
|
||||
g_return_val_if_fail (uri != NULL, NULL);
|
||||
|
||||
filename = g_filename_from_uri (uri, &hostname, NULL);
|
||||
|
||||
if (!filename)
|
||||
return NULL;
|
||||
|
||||
if (hostname)
|
||||
{
|
||||
/* we have a file: URI with a hostname */
|
||||
#ifdef G_OS_WIN32
|
||||
/* on Win32, create a valid UNC path and use it as the filename */
|
||||
|
||||
gchar *tmp = g_build_filename ("//", hostname, filename, NULL);
|
||||
|
||||
g_free (filename);
|
||||
filename = tmp;
|
||||
#else
|
||||
/* otherwise return NULL, caller should use URI then */
|
||||
g_free (filename);
|
||||
filename = NULL;
|
||||
#endif
|
||||
|
||||
g_free (hostname);
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
PlugInProcDef *
|
||||
file_utils_find_proc (GSList *procs,
|
||||
const gchar *uri)
|
||||
@@ -146,7 +193,7 @@ file_utils_find_proc (GSList *procs,
|
||||
if (file_proc)
|
||||
return file_proc;
|
||||
|
||||
filename = g_filename_from_uri (uri, NULL, NULL);
|
||||
filename = file_utils_filename_from_uri (uri);
|
||||
|
||||
/* Then look for magics */
|
||||
if (filename)
|
||||
@@ -254,9 +301,10 @@ file_utils_uri_to_utf8_filename (const gchar *uri)
|
||||
{
|
||||
g_return_val_if_fail (uri != NULL, NULL);
|
||||
|
||||
if (! strncmp (uri, "file:", strlen ("file:")))
|
||||
if (g_str_has_prefix (uri, "file:"))
|
||||
{
|
||||
gchar *filename = g_filename_from_uri (uri, NULL, NULL);
|
||||
gchar *filename = file_utils_filename_from_uri (uri);
|
||||
|
||||
if (filename)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
@@ -25,6 +25,7 @@
|
||||
gchar * file_utils_filename_to_uri (GSList *procs,
|
||||
const gchar *filename,
|
||||
GError **error);
|
||||
gchar * file_utils_filename_from_uri (const gchar *uri);
|
||||
|
||||
gchar * file_utils_uri_to_utf8_basename (const gchar *uri);
|
||||
gchar * file_utils_uri_to_utf8_filename (const gchar *uri);
|
||||
|
@@ -578,6 +578,7 @@ gimp_recent_list_add_item (GimpRecentItem *item)
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to lock: %s", g_strerror (errno));
|
||||
close (fd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@@ -218,7 +218,8 @@ splash_update (const gchar *text1,
|
||||
gdouble percentage)
|
||||
{
|
||||
GdkRectangle expose = { 0, 0, 0, 0 };
|
||||
PangoRectangle rect;
|
||||
PangoRectangle ink;
|
||||
PangoRectangle logical;
|
||||
gint width;
|
||||
gint height;
|
||||
|
||||
@@ -230,30 +231,30 @@ splash_update (const gchar *text1,
|
||||
|
||||
if (text1)
|
||||
{
|
||||
pango_layout_get_pixel_extents (splash->upper, NULL, &rect);
|
||||
splash_rectangle_union (&expose, &rect, splash->upper_x, splash->upper_y);
|
||||
pango_layout_get_pixel_extents (splash->upper, &ink, NULL);
|
||||
splash_rectangle_union (&expose, &ink, splash->upper_x, splash->upper_y);
|
||||
|
||||
pango_layout_set_text (splash->upper, text1, -1);
|
||||
pango_layout_get_pixel_extents (splash->upper, NULL, &rect);
|
||||
pango_layout_get_pixel_extents (splash->upper, &ink, &logical);
|
||||
|
||||
splash->upper_x = (width - rect.width) / 2;
|
||||
splash->upper_y = height - 2 * (rect.height + 6);
|
||||
splash->upper_x = (width - logical.width) / 2;
|
||||
splash->upper_y = height - 2 * (logical.height + 6);
|
||||
|
||||
splash_rectangle_union (&expose, &rect, splash->upper_x, splash->upper_y);
|
||||
splash_rectangle_union (&expose, &ink, splash->upper_x, splash->upper_y);
|
||||
}
|
||||
|
||||
if (text2)
|
||||
{
|
||||
pango_layout_get_pixel_extents (splash->lower, NULL, &rect);
|
||||
splash_rectangle_union (&expose, &rect, splash->lower_x, splash->lower_y);
|
||||
pango_layout_get_pixel_extents (splash->lower, &ink, NULL);
|
||||
splash_rectangle_union (&expose, &ink, splash->lower_x, splash->lower_y);
|
||||
|
||||
pango_layout_set_text (splash->lower, text2, -1);
|
||||
pango_layout_get_pixel_extents (splash->lower, NULL, &rect);
|
||||
pango_layout_get_pixel_extents (splash->lower, &ink, &logical);
|
||||
|
||||
splash->lower_x = (width - rect.width) / 2;
|
||||
splash->lower_y = height - (rect.height + 6);
|
||||
splash->lower_x = (width - logical.width) / 2;
|
||||
splash->lower_y = height - (logical.height + 6);
|
||||
|
||||
splash_rectangle_union (&expose, &rect, splash->lower_x, splash->lower_y);
|
||||
splash_rectangle_union (&expose, &ink, splash->lower_x, splash->lower_y);
|
||||
}
|
||||
|
||||
if (expose.width > 0 && expose.height > 0)
|
||||
|
@@ -47,6 +47,8 @@ libapppaint_a_sources = \
|
||||
gimpink.h \
|
||||
gimpink-blob.c \
|
||||
gimpink-blob.h \
|
||||
gimpink-undo.c \
|
||||
gimpink-undo.h \
|
||||
gimpinkoptions.c \
|
||||
gimpinkoptions.h \
|
||||
gimppaintcore.c \
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#define KERNEL_WIDTH 3
|
||||
#define KERNEL_HEIGHT 3
|
||||
#define KERNEL_SUBSAMPLE 4
|
||||
#define KERNEL_SUM 256
|
||||
|
||||
|
||||
/* Brush pixel subsampling kernels */
|
||||
@@ -17,37 +18,37 @@ static const int subsample[5][5][9] =
|
||||
{
|
||||
{
|
||||
{ 64, 64, 0, 64, 64, 0, 0, 0, 0, },
|
||||
{ 25, 102, 0, 25, 102, 0, 0, 0, 0, },
|
||||
{ 25, 103, 0, 25, 103, 0, 0, 0, 0, },
|
||||
{ 0, 128, 0, 0, 128, 0, 0, 0, 0, },
|
||||
{ 0, 102, 25, 0, 102, 25, 0, 0, 0, },
|
||||
{ 0, 103, 25, 0, 103, 25, 0, 0, 0, },
|
||||
{ 0, 64, 64, 0, 64, 64, 0, 0, 0, }
|
||||
},
|
||||
{
|
||||
{ 25, 25, 0, 102, 102, 0, 0, 0, 0, },
|
||||
{ 6, 43, 0, 43, 162, 0, 0, 0, 0, },
|
||||
{ 0, 50, 0, 0, 205, 0, 0, 0, 0, },
|
||||
{ 0, 43, 6, 0, 162, 43, 0, 0, 0, },
|
||||
{ 0, 25, 25, 0, 102, 102, 0, 0, 0, }
|
||||
{ 25, 25, 0, 103, 103, 0, 0, 0, 0, },
|
||||
{ 6, 44, 0, 44, 162, 0, 0, 0, 0, },
|
||||
{ 0, 50, 0, 0, 206, 0, 0, 0, 0, },
|
||||
{ 0, 44, 6, 0, 162, 44, 0, 0, 0, },
|
||||
{ 0, 25, 25, 0, 103, 103, 0, 0, 0, }
|
||||
},
|
||||
{
|
||||
{ 0, 0, 0, 128, 128, 0, 0, 0, 0, },
|
||||
{ 0, 0, 0, 50, 205, 0, 0, 0, 0, },
|
||||
{ 0, 0, 0, 50, 206, 0, 0, 0, 0, },
|
||||
{ 0, 0, 0, 0, 256, 0, 0, 0, 0, },
|
||||
{ 0, 0, 0, 0, 205, 50, 0, 0, 0, },
|
||||
{ 0, 0, 0, 0, 206, 50, 0, 0, 0, },
|
||||
{ 0, 0, 0, 0, 128, 128, 0, 0, 0, }
|
||||
},
|
||||
{
|
||||
{ 0, 0, 0, 102, 102, 0, 25, 25, 0, },
|
||||
{ 0, 0, 0, 43, 162, 0, 6, 43, 0, },
|
||||
{ 0, 0, 0, 0, 205, 0, 0, 50, 0, },
|
||||
{ 0, 0, 0, 0, 162, 43, 0, 43, 6, },
|
||||
{ 0, 0, 0, 0, 102, 102, 0, 25, 25, }
|
||||
{ 0, 0, 0, 103, 103, 0, 25, 25, 0, },
|
||||
{ 0, 0, 0, 44, 162, 0, 6, 44, 0, },
|
||||
{ 0, 0, 0, 0, 206, 0, 0, 50, 0, },
|
||||
{ 0, 0, 0, 0, 162, 44, 0, 44, 6, },
|
||||
{ 0, 0, 0, 0, 103, 103, 0, 25, 25, }
|
||||
},
|
||||
{
|
||||
{ 0, 0, 0, 64, 64, 0, 64, 64, 0, },
|
||||
{ 0, 0, 0, 25, 102, 0, 25, 102, 0, },
|
||||
{ 0, 0, 0, 25, 103, 0, 25, 103, 0, },
|
||||
{ 0, 0, 0, 0, 128, 0, 0, 128, 0, },
|
||||
{ 0, 0, 0, 0, 102, 25, 0, 102, 25, },
|
||||
{ 0, 0, 0, 0, 103, 25, 0, 103, 25, },
|
||||
{ 0, 0, 0, 0, 64, 64, 0, 64, 64, }
|
||||
}
|
||||
};
|
||||
|
@@ -909,13 +909,16 @@ gimp_brush_core_subsample_mask (GimpBrushCore *core,
|
||||
gint r, s;
|
||||
gulong *accum[KERNEL_HEIGHT];
|
||||
gint offs;
|
||||
gint kernel_sum;
|
||||
|
||||
while (x < 0) x += mask->width;
|
||||
while (x < 0)
|
||||
x += mask->width;
|
||||
|
||||
left = x - floor (x);
|
||||
index1 = (gint) (left * (gdouble) (KERNEL_SUBSAMPLE + 1));
|
||||
|
||||
while (y < 0) y += mask->height;
|
||||
while (y < 0)
|
||||
y += mask->height;
|
||||
|
||||
left = y - floor (y);
|
||||
index2 = (gint) (left * (gdouble) (KERNEL_SUBSAMPLE + 1));
|
||||
|
||||
@@ -971,15 +974,6 @@ gimp_brush_core_subsample_mask (GimpBrushCore *core,
|
||||
for (i = 0; i < KERNEL_HEIGHT ; i++)
|
||||
accum[i] = g_new0 (gulong, dest->width + 1);
|
||||
|
||||
/* Investigate modifiying kernelgen to make the sum the same
|
||||
* for all kernels. That way kernal_sum becomes a constant
|
||||
*/
|
||||
kernel_sum = 0;
|
||||
for (i = 0; i < KERNEL_HEIGHT * KERNEL_WIDTH; i++)
|
||||
{
|
||||
kernel_sum += kernel[i];
|
||||
}
|
||||
|
||||
core->kernel_brushes[index2][index1] = dest;
|
||||
|
||||
m = mask_buf_data (mask);
|
||||
@@ -993,9 +987,7 @@ gimp_brush_core_subsample_mask (GimpBrushCore *core,
|
||||
offs = j + dest_offset_x;
|
||||
s = KERNEL_WIDTH;
|
||||
while (s--)
|
||||
{
|
||||
accum[r][offs++] += *m * *k++;
|
||||
}
|
||||
accum[r][offs++] += *m * *k++;
|
||||
}
|
||||
m++;
|
||||
}
|
||||
@@ -1003,7 +995,7 @@ gimp_brush_core_subsample_mask (GimpBrushCore *core,
|
||||
/* store the accum buffer into the destination mask */
|
||||
d = mask_buf_data (dest) + (i + dest_offset_y) * dest->width;
|
||||
for (j = 0; j < dest->width; j++)
|
||||
*d++ = (accum[0][j] + 127) / kernel_sum;
|
||||
*d++ = (accum[0][j] + 127) / KERNEL_SUM;
|
||||
|
||||
rotate_pointers (accum, KERNEL_HEIGHT);
|
||||
|
||||
@@ -1015,7 +1007,7 @@ gimp_brush_core_subsample_mask (GimpBrushCore *core,
|
||||
{
|
||||
d = mask_buf_data (dest) + (i + dest_offset_y) * dest->width;
|
||||
for (j = 0; j < dest->width; j++)
|
||||
*d++ = (accum[0][j] + (kernel_sum / 2)) / kernel_sum;
|
||||
*d++ = (accum[0][j] + (KERNEL_SUM / 2)) / KERNEL_SUM;
|
||||
|
||||
rotate_pointers (accum, KERNEL_HEIGHT);
|
||||
i++;
|
||||
@@ -1113,7 +1105,7 @@ gimp_brush_core_pressurize_mask (GimpBrushCore *core,
|
||||
|
||||
j = pressure + pressure;
|
||||
k = 0;
|
||||
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if (k > 255)
|
||||
@@ -1134,9 +1126,7 @@ gimp_brush_core_pressurize_mask (GimpBrushCore *core,
|
||||
|
||||
i = subsample_mask->width * subsample_mask->height;
|
||||
while (i--)
|
||||
{
|
||||
*dest++ = mapi[(*source++)];
|
||||
}
|
||||
*dest++ = mapi[(*source++)];
|
||||
|
||||
return core->pressure_brush;
|
||||
}
|
||||
@@ -1156,7 +1146,8 @@ gimp_brush_core_solidify_mask (GimpBrushCore *core,
|
||||
|
||||
if ((brush_mask->width % 2) == 0)
|
||||
{
|
||||
while (x < 0) x += brush_mask->width;
|
||||
while (x < 0)
|
||||
x += brush_mask->width;
|
||||
|
||||
if ((x - floor (x)) >= 0.5)
|
||||
dest_offset_x++;
|
||||
@@ -1164,7 +1155,8 @@ gimp_brush_core_solidify_mask (GimpBrushCore *core,
|
||||
|
||||
if ((brush_mask->height % 2) == 0)
|
||||
{
|
||||
while (y < 0) y += brush_mask->height;
|
||||
while (y < 0)
|
||||
y += brush_mask->height;
|
||||
|
||||
if ((y - floor (y)) >= 0.5)
|
||||
dest_offset_y++;
|
||||
@@ -1203,9 +1195,7 @@ gimp_brush_core_solidify_mask (GimpBrushCore *core,
|
||||
for (i = 0; i < brush_mask->height; i++)
|
||||
{
|
||||
for (j = 0; j < brush_mask->width; j++)
|
||||
{
|
||||
*d++ = (*m++) ? OPAQUE_OPACITY : TRANSPARENT_OPACITY;
|
||||
}
|
||||
*d++ = (*m++) ? OPAQUE_OPACITY : TRANSPARENT_OPACITY;
|
||||
|
||||
d += 2;
|
||||
}
|
||||
@@ -1478,7 +1468,6 @@ paint_line_pixmap_mask (GimpImage *dest,
|
||||
for (byte_loop = 0; byte_loop < bytes - 1; byte_loop++)
|
||||
d[byte_loop] *= alpha;
|
||||
|
||||
/* printf("i: %i d->r: %i d->g: %i d->b: %i d->a: %i\n",i,(int)d[0], (int)d[1], (int)d[2], (int)d[3]); */
|
||||
gimp_image_transform_color (dest, drawable, d, GIMP_RGB, p);
|
||||
d += bytes;
|
||||
}
|
||||
|
@@ -448,6 +448,14 @@ blob_convex_union (Blob *b1,
|
||||
return result;
|
||||
}
|
||||
|
||||
Blob *
|
||||
blob_duplicate (Blob *b)
|
||||
{
|
||||
g_return_val_if_fail (b != NULL, NULL);
|
||||
|
||||
return g_memdup (b, sizeof (Blob) + sizeof (BlobSpan) * (b->height - 1));
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
blob_dump (Blob *b)
|
||||
|
@@ -84,6 +84,7 @@ void blob_bounds (Blob *b,
|
||||
gint *height);
|
||||
Blob * blob_convex_union (Blob *b1,
|
||||
Blob *b2);
|
||||
Blob * blob_duplicate (Blob *b);
|
||||
|
||||
|
||||
#endif /* __GIMP_INK_BLOB_H__ */
|
||||
|
187
app/paint/gimpink-undo.c
Normal file
187
app/paint/gimpink-undo.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "paint-types.h"
|
||||
|
||||
#include "core/gimpimage-undo.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpundo.h"
|
||||
|
||||
#include "gimpink.h"
|
||||
#include "gimpink-blob.h"
|
||||
#include "gimpink-undo.h"
|
||||
|
||||
|
||||
/**************/
|
||||
/* Ink Undo */
|
||||
/**************/
|
||||
|
||||
typedef struct _InkUndo InkUndo;
|
||||
|
||||
struct _InkUndo
|
||||
{
|
||||
GimpInk *ink;
|
||||
|
||||
Blob *last_blob;
|
||||
|
||||
gdouble dt_buffer[DIST_SMOOTHER_BUFFER];
|
||||
gint dt_index;
|
||||
|
||||
guint32 ts_buffer[TIME_SMOOTHER_BUFFER];
|
||||
gint ts_index;
|
||||
|
||||
gdouble last_time;
|
||||
|
||||
gboolean init_velocity;
|
||||
};
|
||||
|
||||
|
||||
static gboolean undo_pop_ink (GimpUndo *undo,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum);
|
||||
static void undo_free_ink (GimpUndo *undo,
|
||||
GimpUndoMode undo_mode);
|
||||
|
||||
|
||||
gboolean
|
||||
gimp_ink_push_undo (GimpPaintCore *core,
|
||||
GimpImage *gimage,
|
||||
const gchar *undo_desc)
|
||||
{
|
||||
GimpUndo *new;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_INK (core), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
|
||||
|
||||
if (! GIMP_PAINT_CORE_CLASS (g_type_class_peek_parent (GIMP_INK_GET_CLASS (core)))->push_undo (core, gimage, undo_desc))
|
||||
return FALSE;
|
||||
|
||||
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_UNDO,
|
||||
sizeof (InkUndo),
|
||||
sizeof (InkUndo),
|
||||
GIMP_UNDO_INK, undo_desc,
|
||||
FALSE,
|
||||
undo_pop_ink,
|
||||
undo_free_ink,
|
||||
NULL)))
|
||||
{
|
||||
GimpInk *ink = GIMP_INK (core);
|
||||
InkUndo *ink_undo = new->data;
|
||||
|
||||
ink_undo->ink = ink;
|
||||
|
||||
if (ink->start_blob)
|
||||
ink_undo->last_blob = blob_duplicate (ink->start_blob);
|
||||
|
||||
memcpy (ink_undo->dt_buffer, ink->dt_buffer,
|
||||
sizeof (ink_undo->dt_buffer));
|
||||
|
||||
ink_undo->dt_index = ink->dt_index;
|
||||
|
||||
memcpy (ink_undo->ts_buffer, ink->ts_buffer,
|
||||
sizeof (ink_undo->ts_buffer));
|
||||
|
||||
ink_undo->ts_index = ink->ts_index;
|
||||
|
||||
ink_undo->last_time = ink->last_time;
|
||||
|
||||
ink_undo->init_velocity = ink->init_velocity;
|
||||
|
||||
g_object_add_weak_pointer (G_OBJECT (ink), (gpointer) &ink_undo->ink);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
undo_pop_ink (GimpUndo *undo,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum)
|
||||
{
|
||||
InkUndo *ink_undo = undo->data;
|
||||
|
||||
/* only pop if the core still exists */
|
||||
if (ink_undo->ink)
|
||||
{
|
||||
Blob *tmp_blob;
|
||||
gint tmp_int;
|
||||
gdouble tmp_double;
|
||||
guint32 tmp_int_buf[DIST_SMOOTHER_BUFFER];
|
||||
gdouble tmp_double_buf[DIST_SMOOTHER_BUFFER];
|
||||
|
||||
tmp_blob = ink_undo->ink->last_blob;
|
||||
ink_undo->ink->last_blob = ink_undo->last_blob;
|
||||
ink_undo->last_blob = tmp_blob;
|
||||
|
||||
memcpy (tmp_double_buf, ink_undo->ink->dt_buffer,
|
||||
sizeof (tmp_double_buf));
|
||||
memcpy (ink_undo->ink->dt_buffer, ink_undo->dt_buffer,
|
||||
sizeof (tmp_double_buf));
|
||||
memcpy (ink_undo->dt_buffer, tmp_double_buf,
|
||||
sizeof (tmp_double_buf));
|
||||
|
||||
tmp_int = ink_undo->ink->dt_index;
|
||||
ink_undo->ink->dt_index = ink_undo->dt_index;
|
||||
ink_undo->dt_index = tmp_int;
|
||||
|
||||
memcpy (tmp_int_buf, ink_undo->ink->ts_buffer,
|
||||
sizeof (tmp_int_buf));
|
||||
memcpy (ink_undo->ink->ts_buffer, ink_undo->ts_buffer,
|
||||
sizeof (tmp_int_buf));
|
||||
memcpy (ink_undo->ts_buffer, tmp_int_buf,
|
||||
sizeof (tmp_int_buf));
|
||||
|
||||
tmp_int = ink_undo->ink->ts_index;
|
||||
ink_undo->ink->ts_index = ink_undo->ts_index;
|
||||
ink_undo->ts_index = tmp_int;
|
||||
|
||||
tmp_double = ink_undo->ink->last_time;
|
||||
ink_undo->ink->last_time = ink_undo->last_time;
|
||||
ink_undo->last_time = tmp_double;
|
||||
|
||||
tmp_int = ink_undo->ink->init_velocity;
|
||||
ink_undo->ink->init_velocity = ink_undo->init_velocity;
|
||||
ink_undo->init_velocity = tmp_int;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
undo_free_ink (GimpUndo *undo,
|
||||
GimpUndoMode undo_mode)
|
||||
{
|
||||
InkUndo *ink_undo = undo->data;
|
||||
|
||||
if (ink_undo->ink)
|
||||
g_object_remove_weak_pointer (G_OBJECT (ink_undo->ink),
|
||||
(gpointer) &ink_undo->ink);
|
||||
|
||||
if (ink_undo->last_blob)
|
||||
g_free (ink_undo->last_blob);
|
||||
|
||||
g_free (ink_undo);
|
||||
}
|
@@ -1,9 +1,6 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpconfig-path.h
|
||||
* Copyright (C) 2001-2002 Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
@@ -19,13 +16,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GIMP_CONFIG_PATH_H__
|
||||
#define __GIMP_CONFIG_PATH_H__
|
||||
#ifndef __GIMP_INK_UNDO_H__
|
||||
#define __GIMP_INK_UNDO_H__
|
||||
|
||||
|
||||
gchar * gimp_config_path_expand (const gchar *path,
|
||||
gboolean recode,
|
||||
GError **error);
|
||||
gboolean gimp_ink_push_undo (GimpPaintCore *core,
|
||||
GimpImage *gimage,
|
||||
const gchar *undo_desc);
|
||||
|
||||
|
||||
#endif /* __GIMP_CONFIG_PATH_H__ */
|
||||
#endif /* __GIMP_INK_UNDO_H__ */
|
@@ -37,6 +37,7 @@
|
||||
#include "gimpinkoptions.h"
|
||||
#include "gimpink.h"
|
||||
#include "gimpink-blob.h"
|
||||
#include "gimpink-undo.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
@@ -75,9 +76,10 @@ static Blob * ink_pen_ellipse (GimpInkOptions *options,
|
||||
|
||||
static void time_smoother_add (GimpInk *ink,
|
||||
guint32 value);
|
||||
static gdouble time_smoother_result (GimpInk *ink);
|
||||
static guint32 time_smoother_result (GimpInk *ink);
|
||||
static void time_smoother_init (GimpInk *ink,
|
||||
guint32 initval);
|
||||
|
||||
static void dist_smoother_add (GimpInk *ink,
|
||||
gdouble value);
|
||||
static gdouble dist_smoother_result (GimpInk *ink);
|
||||
@@ -141,6 +143,7 @@ gimp_ink_class_init (GimpInkClass *klass)
|
||||
|
||||
paint_core_class->paint = gimp_ink_paint;
|
||||
paint_core_class->get_paint_area = gimp_ink_get_paint_area;
|
||||
paint_core_class->push_undo = gimp_ink_push_undo;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -153,6 +156,12 @@ gimp_ink_finalize (GObject *object)
|
||||
{
|
||||
GimpInk *ink = GIMP_INK (object);
|
||||
|
||||
if (ink->start_blob)
|
||||
{
|
||||
g_free (ink->start_blob);
|
||||
ink->start_blob = NULL;
|
||||
}
|
||||
|
||||
if (ink->last_blob)
|
||||
{
|
||||
g_free (ink->last_blob);
|
||||
@@ -174,13 +183,31 @@ gimp_ink_paint (GimpPaintCore *paint_core,
|
||||
switch (paint_state)
|
||||
{
|
||||
case GIMP_PAINT_STATE_INIT:
|
||||
if (ink->last_blob &&
|
||||
paint_core->cur_coords.x == paint_core->last_coords.x &&
|
||||
if (paint_core->cur_coords.x == paint_core->last_coords.x &&
|
||||
paint_core->cur_coords.y == paint_core->last_coords.y)
|
||||
{
|
||||
/* start with a new blob if we're not interpolating */
|
||||
g_free (ink->last_blob);
|
||||
ink->last_blob = NULL;
|
||||
/* start with new blobs if we're not interpolating */
|
||||
|
||||
if (ink->start_blob)
|
||||
{
|
||||
g_free (ink->start_blob);
|
||||
ink->start_blob = NULL;
|
||||
}
|
||||
|
||||
if (ink->last_blob)
|
||||
{
|
||||
g_free (ink->last_blob);
|
||||
ink->last_blob = NULL;
|
||||
}
|
||||
}
|
||||
else if (ink->last_blob)
|
||||
{
|
||||
/* save the start blob of the line for undo otherwise */
|
||||
|
||||
if (ink->start_blob)
|
||||
g_free (ink->start_blob);
|
||||
|
||||
ink->start_blob = blob_duplicate (ink->last_blob);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -207,7 +234,7 @@ gimp_ink_get_paint_area (GimpPaintCore *paint_core,
|
||||
|
||||
bytes = gimp_drawable_bytes_with_alpha (drawable);
|
||||
|
||||
blob_bounds (ink->blob, &x, &y, &width, &height);
|
||||
blob_bounds (ink->cur_blob, &x, &y, &width, &height);
|
||||
|
||||
dwidth = gimp_item_width (GIMP_ITEM (drawable));
|
||||
dheight = gimp_item_height (GIMP_ITEM (drawable));
|
||||
@@ -256,25 +283,26 @@ gimp_ink_motion (GimpPaintCore *paint_core,
|
||||
paint_core->cur_coords.ytilt,
|
||||
10.0);
|
||||
|
||||
if (ink->start_blob)
|
||||
g_free (ink->start_blob);
|
||||
|
||||
ink->start_blob = blob_duplicate (ink->last_blob);
|
||||
|
||||
time_smoother_init (ink, time);
|
||||
ink->last_time = time;
|
||||
|
||||
dist_smoother_init (ink, 0.0);
|
||||
ink->init_velocity = TRUE;
|
||||
|
||||
ink->lastx = paint_core->cur_coords.x;
|
||||
ink->lasty = paint_core->cur_coords.y;
|
||||
|
||||
blob_to_render = ink->last_blob;
|
||||
}
|
||||
else
|
||||
{
|
||||
Blob *blob;
|
||||
gdouble lasttime, thistime;
|
||||
gdouble dist;
|
||||
gdouble velocity;
|
||||
|
||||
lasttime = ink->last_time;
|
||||
guint32 lasttime = ink->last_time;
|
||||
guint32 thistime;
|
||||
|
||||
time_smoother_add (ink, time);
|
||||
thistime = ink->last_time = time_smoother_result (ink);
|
||||
@@ -289,10 +317,10 @@ gimp_ink_motion (GimpPaintCore *paint_core,
|
||||
if (thistime == lasttime)
|
||||
thistime = lasttime + 1;
|
||||
|
||||
dist = sqrt ((ink->lastx - paint_core->cur_coords.x) *
|
||||
(ink->lastx - paint_core->cur_coords.x) +
|
||||
(ink->lasty - paint_core->cur_coords.y) *
|
||||
(ink->lasty - paint_core->cur_coords.y));
|
||||
dist = sqrt ((paint_core->last_coords.x - paint_core->cur_coords.x) *
|
||||
(paint_core->last_coords.x - paint_core->cur_coords.x) +
|
||||
(paint_core->last_coords.y - paint_core->cur_coords.y) *
|
||||
(paint_core->last_coords.y - paint_core->cur_coords.y));
|
||||
|
||||
if (ink->init_velocity)
|
||||
{
|
||||
@@ -305,9 +333,6 @@ gimp_ink_motion (GimpPaintCore *paint_core,
|
||||
dist = dist_smoother_result (ink);
|
||||
}
|
||||
|
||||
ink->lastx = paint_core->cur_coords.x;
|
||||
ink->lasty = paint_core->cur_coords.y;
|
||||
|
||||
velocity = 10.0 * sqrt ((dist) / (gdouble) (thistime - lasttime));
|
||||
|
||||
blob = ink_pen_ellipse (options,
|
||||
@@ -326,9 +351,10 @@ gimp_ink_motion (GimpPaintCore *paint_core,
|
||||
}
|
||||
|
||||
/* Get the the buffer */
|
||||
ink->blob = blob_to_render;
|
||||
|
||||
ink->cur_blob = blob_to_render;
|
||||
area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options);
|
||||
ink->cur_blob = NULL;
|
||||
|
||||
if (! area)
|
||||
return;
|
||||
|
||||
@@ -493,43 +519,6 @@ ink_pen_ellipse (GimpInkOptions *options,
|
||||
radmin * tcos);
|
||||
}
|
||||
|
||||
static void
|
||||
dist_smoother_init (GimpInk *ink,
|
||||
gdouble initval)
|
||||
{
|
||||
gint i;
|
||||
|
||||
ink->dt_index = 0;
|
||||
|
||||
for (i = 0; i < DIST_SMOOTHER_BUFFER; i++)
|
||||
{
|
||||
ink->dt_buffer[i] = initval;
|
||||
}
|
||||
}
|
||||
|
||||
static gdouble
|
||||
dist_smoother_result (GimpInk *ink)
|
||||
{
|
||||
gint i;
|
||||
gdouble result = 0.0;
|
||||
|
||||
for (i = 0; i < DIST_SMOOTHER_BUFFER; i++)
|
||||
{
|
||||
result += ink->dt_buffer[i];
|
||||
}
|
||||
|
||||
return (result / (gdouble) DIST_SMOOTHER_BUFFER);
|
||||
}
|
||||
|
||||
static void
|
||||
dist_smoother_add (GimpInk *ink,
|
||||
gdouble value)
|
||||
{
|
||||
ink->dt_buffer[ink->dt_index] = value;
|
||||
|
||||
if ((++ink->dt_index) == DIST_SMOOTHER_BUFFER)
|
||||
ink->dt_index = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
time_smoother_init (GimpInk *ink,
|
||||
@@ -540,40 +529,75 @@ time_smoother_init (GimpInk *ink,
|
||||
ink->ts_index = 0;
|
||||
|
||||
for (i = 0; i < TIME_SMOOTHER_BUFFER; i++)
|
||||
{
|
||||
ink->ts_buffer[i] = initval;
|
||||
}
|
||||
ink->ts_buffer[i] = initval;
|
||||
}
|
||||
|
||||
static gdouble
|
||||
static guint32
|
||||
time_smoother_result (GimpInk *ink)
|
||||
{
|
||||
gint i;
|
||||
guint64 result = 0;
|
||||
|
||||
for (i = 0; i < TIME_SMOOTHER_BUFFER; i++)
|
||||
{
|
||||
result += ink->ts_buffer[i];
|
||||
}
|
||||
result += ink->ts_buffer[i];
|
||||
|
||||
#ifdef _MSC_VER
|
||||
return (gdouble) (gint64) (result / TIME_SMOOTHER_BUFFER);
|
||||
#else
|
||||
return (result / TIME_SMOOTHER_BUFFER);
|
||||
#endif
|
||||
return (result / (guint64) TIME_SMOOTHER_BUFFER);
|
||||
}
|
||||
|
||||
static void
|
||||
time_smoother_add (GimpInk *ink,
|
||||
guint32 value)
|
||||
{
|
||||
ink->ts_buffer[ink->ts_index] = value;
|
||||
guint64 long_value = (guint64) value;
|
||||
|
||||
if ((++ink->ts_index) == TIME_SMOOTHER_BUFFER)
|
||||
/* handle wrap-around of time values */
|
||||
if (long_value < ink->ts_buffer[ink->ts_index])
|
||||
long_value += (guint64) + G_MAXUINT32;
|
||||
|
||||
ink->ts_buffer[ink->ts_index++] = long_value;
|
||||
|
||||
ink->ts_buffer[ink->ts_index++] = value;
|
||||
|
||||
if (ink->ts_index == TIME_SMOOTHER_BUFFER)
|
||||
ink->ts_index = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dist_smoother_init (GimpInk *ink,
|
||||
gdouble initval)
|
||||
{
|
||||
gint i;
|
||||
|
||||
ink->dt_index = 0;
|
||||
|
||||
for (i = 0; i < DIST_SMOOTHER_BUFFER; i++)
|
||||
ink->dt_buffer[i] = initval;
|
||||
}
|
||||
|
||||
static gdouble
|
||||
dist_smoother_result (GimpInk *ink)
|
||||
{
|
||||
gint i;
|
||||
gdouble result = 0.0;
|
||||
|
||||
for (i = 0; i < DIST_SMOOTHER_BUFFER; i++)
|
||||
result += ink->dt_buffer[i];
|
||||
|
||||
return (result / (gdouble) DIST_SMOOTHER_BUFFER);
|
||||
}
|
||||
|
||||
static void
|
||||
dist_smoother_add (GimpInk *ink,
|
||||
gdouble value)
|
||||
{
|
||||
ink->dt_buffer[ink->dt_index++] = value;
|
||||
|
||||
if (ink->dt_index == DIST_SMOOTHER_BUFFER)
|
||||
ink->dt_index = 0;
|
||||
}
|
||||
|
||||
|
||||
/*********************************/
|
||||
/* Rendering functions */
|
||||
/*********************************/
|
||||
|
@@ -43,7 +43,9 @@ struct _GimpInk
|
||||
{
|
||||
GimpPaintCore parent_instance;
|
||||
|
||||
Blob *blob; /* current blob */
|
||||
Blob *start_blob; /* starting blob (for undo) */
|
||||
|
||||
Blob *cur_blob; /* current blob */
|
||||
Blob *last_blob; /* blob for last cursor position */
|
||||
|
||||
/* circular distance history buffer */
|
||||
@@ -55,7 +57,6 @@ struct _GimpInk
|
||||
gint ts_index;
|
||||
|
||||
gdouble last_time; /* previous time of a motion event */
|
||||
gdouble lastx, lasty; /* previous position of a motion event */
|
||||
|
||||
gboolean init_velocity;
|
||||
};
|
||||
|
@@ -50,14 +50,14 @@ static void undo_free_paint (GimpUndo *undo,
|
||||
GimpUndoMode undo_mode);
|
||||
|
||||
gboolean
|
||||
gimp_paint_core_push_undo (GimpImage *gimage,
|
||||
const gchar *undo_desc,
|
||||
GimpPaintCore *core)
|
||||
gimp_paint_core_real_push_undo (GimpPaintCore *core,
|
||||
GimpImage *gimage,
|
||||
const gchar *undo_desc)
|
||||
{
|
||||
GimpUndo *new;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_PAINT_CORE (core), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
|
||||
|
||||
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_UNDO,
|
||||
sizeof (PaintUndo),
|
||||
|
@@ -20,9 +20,9 @@
|
||||
#define __GIMP_PAINT_CORE_UNDO_H__
|
||||
|
||||
|
||||
gboolean gimp_paint_core_push_undo (GimpImage *gimage,
|
||||
const gchar *undo_desc,
|
||||
GimpPaintCore *core);
|
||||
gboolean gimp_paint_core_real_push_undo (GimpPaintCore *core,
|
||||
GimpImage *gimage,
|
||||
const gchar *undo_desc);
|
||||
|
||||
|
||||
#endif /* __GIMP_PAINT_CORE_UNDO_H__ */
|
||||
|
@@ -138,6 +138,7 @@ gimp_paint_core_class_init (GimpPaintCoreClass *klass)
|
||||
klass->post_paint = gimp_paint_core_real_post_paint;
|
||||
klass->interpolate = gimp_paint_core_real_interpolate;
|
||||
klass->get_paint_area = gimp_paint_core_real_get_paint_area;
|
||||
klass->push_undo = gimp_paint_core_real_push_undo;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -343,7 +344,7 @@ gimp_paint_core_finish (GimpPaintCore *core,
|
||||
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_PAINT,
|
||||
paint_info ? paint_info->blurb : _("Paint"));
|
||||
|
||||
gimp_paint_core_push_undo (gimage, NULL, core);
|
||||
GIMP_PAINT_CORE_GET_CLASS (core)->push_undo (core, gimage, NULL);
|
||||
|
||||
gimp_drawable_push_undo (drawable, NULL,
|
||||
core->x1, core->y1,
|
||||
|
@@ -96,6 +96,10 @@ struct _GimpPaintCoreClass
|
||||
TempBuf * (* get_paint_area) (GimpPaintCore *core,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintOptions *paint_options);
|
||||
|
||||
gboolean (* push_undo) (GimpPaintCore *core,
|
||||
GimpImage *gimage,
|
||||
const gchar *undo_desc);
|
||||
};
|
||||
|
||||
|
||||
|
194
app/paint_core.h
194
app/paint_core.h
@@ -1,194 +0,0 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PAINT_CORE_H__
|
||||
#define __PAINT_CORE_H__
|
||||
|
||||
#include "tool.h"
|
||||
/* the different states that the painting function can be called with */
|
||||
|
||||
typedef enum /*< skip >*/
|
||||
{
|
||||
INIT_PAINT, /* Setup PaintFunc internals */
|
||||
MOTION_PAINT, /* PaintFunc performs motion-related rendering */
|
||||
PAUSE_PAINT, /* Unused. Reserved */
|
||||
RESUME_PAINT, /* Unused. Reserved */
|
||||
FINISH_PAINT, /* Cleanup and/or reset PaintFunc operation */
|
||||
PRETRACE_PAINT, /* PaintFunc performs window tracing activity prior to rendering */
|
||||
POSTTRACE_PAINT /* PaintFunc performs window tracing activity following rendering */
|
||||
} PaintState;
|
||||
|
||||
typedef enum /*< skip >*/
|
||||
{
|
||||
TOOL_CAN_HANDLE_CHANGING_BRUSH = 0x0001, /* Set for tools that don't mind
|
||||
* if the brush changes while
|
||||
* painting.
|
||||
*/
|
||||
|
||||
TOOL_TRACES_ON_WINDOW /* Set for tools that perform temporary
|
||||
* rendering directly to the window. These
|
||||
* require sequencing with gdisplay_flush()
|
||||
* routines. See clone.c for example.
|
||||
*/
|
||||
} ToolFlags;
|
||||
|
||||
typedef gpointer (* PaintFunc) (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
PaintState paint_state);
|
||||
|
||||
struct _PaintCore
|
||||
{
|
||||
DrawCore * core; /* Core select object */
|
||||
|
||||
gdouble startx; /* starting x coord */
|
||||
gdouble starty; /* starting y coord */
|
||||
gdouble startpressure; /* starting pressure */
|
||||
gdouble startxtilt; /* starting xtilt */
|
||||
gdouble startytilt; /* starting ytilt */
|
||||
#ifdef GTK_HAVE_SIX_VALUATORS
|
||||
gdouble startwheel; /* starting wheel */
|
||||
#endif /* GTK_HAVE_SIX_VALUATORS */
|
||||
|
||||
gdouble curx; /* current x coord */
|
||||
gdouble cury; /* current y coord */
|
||||
gdouble curpressure; /* current pressure */
|
||||
gdouble curxtilt; /* current xtilt */
|
||||
gdouble curytilt; /* current ytilt */
|
||||
#ifdef GTK_HAVE_SIX_VALUATORS
|
||||
gdouble curwheel; /* current wheel */
|
||||
#endif /* GTK_HAVE_SIX_VALUATORS */
|
||||
|
||||
gdouble lastx; /* last x coord */
|
||||
gdouble lasty; /* last y coord */
|
||||
gdouble lastpressure; /* last pressure */
|
||||
gdouble lastxtilt; /* last xtilt */
|
||||
gdouble lastytilt; /* last ytilt */
|
||||
#ifdef GTK_HAVE_SIX_VALUATORS
|
||||
gdouble lastwheel; /* last wheel */
|
||||
#endif /* GTK_HAVE_SIX_VALUATORS */
|
||||
|
||||
gint state; /* state of buttons and keys */
|
||||
|
||||
gdouble distance; /* distance traveled by brush */
|
||||
gdouble pixel_dist; /* distance in pixels */
|
||||
gdouble spacing; /* spacing */
|
||||
|
||||
gint x1, y1; /* image space coordinate */
|
||||
gint x2, y2; /* image space coords */
|
||||
|
||||
GimpBrush * brush; /* current brush */
|
||||
|
||||
PaintFunc paint_func; /* painting function */
|
||||
|
||||
gboolean pick_colors; /* pick color if ctrl or alt is pressed */
|
||||
gboolean pick_state; /* was ctrl or alt pressed when clicked? */
|
||||
ToolFlags flags; /* tool flags, see ToolFlags above */
|
||||
|
||||
guint context_id; /* for the statusbar */
|
||||
};
|
||||
|
||||
extern PaintCore non_gui_paint_core;
|
||||
|
||||
/* Special undo type */
|
||||
typedef struct _PaintUndo PaintUndo;
|
||||
|
||||
struct _PaintUndo
|
||||
{
|
||||
gint tool_ID;
|
||||
gdouble lastx;
|
||||
gdouble lasty;
|
||||
gdouble lastpressure;
|
||||
gdouble lastxtilt;
|
||||
gdouble lastytilt;
|
||||
#ifdef GTK_HAVE_SIX_VALUATORS
|
||||
gdouble lastwheel;
|
||||
#endif /* GTK_HAVE_SIX_VALUATORS */
|
||||
};
|
||||
|
||||
/* paint tool action functions */
|
||||
void paint_core_button_press (GimpTool *tool,
|
||||
GdkEventButton *bevent,
|
||||
GDisplay *gdisp);
|
||||
void paint_core_button_release (GimpTool *tool,
|
||||
GdkEventButton *bevent,
|
||||
GDisplay *gdisp);
|
||||
void paint_core_motion (GimpTool *tool,
|
||||
GdkEventMotion *mevent,
|
||||
GDisplay *gdisp);
|
||||
void paint_core_cursor_update (GimpTool *tool,
|
||||
GdkEventMotion *mevent,
|
||||
GDisplay *gdisp);
|
||||
|
||||
void paint_core_control (GimpTool *tool,
|
||||
ToolAction action,
|
||||
GDisplay *gdisp);
|
||||
|
||||
/* paint tool functions */
|
||||
void paint_core_no_draw (GimpTool *tool);
|
||||
GimpTool * paint_core_new (GimpToolClass *type);
|
||||
void paint_core_free (GimpTool *tool);
|
||||
int paint_core_init (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
void paint_core_interpolate (PaintCore *paint_core,
|
||||
GimpDrawable *drawable);
|
||||
void paint_core_finish (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint tool_ID);
|
||||
void paint_core_cleanup (void);
|
||||
|
||||
void paint_core_get_color_from_gradient (PaintCore *paint_core,
|
||||
gdouble gradient_length,
|
||||
GimpRGB *color,
|
||||
GradientPaintMode mode);
|
||||
|
||||
/* paint tool painting functions */
|
||||
TempBuf * paint_core_get_paint_area (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gdouble scale);
|
||||
TempBuf * paint_core_get_orig_image (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint x1,
|
||||
gint y1,
|
||||
gint x2,
|
||||
gint y2);
|
||||
void paint_core_paste_canvas (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint brush_opacity,
|
||||
gint image_opacity,
|
||||
LayerModeEffects paint_mode,
|
||||
BrushApplicationMode brush_hardness,
|
||||
gdouble brush_scale,
|
||||
PaintApplicationMode mode);
|
||||
void paint_core_replace_canvas (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint brush_opacity,
|
||||
gint image_opacity,
|
||||
BrushApplicationMode brush_hardness,
|
||||
gdouble brush_scale,
|
||||
PaintApplicationMode mode);
|
||||
void paint_core_color_area_with_pixmap (PaintCore *paint_core,
|
||||
GimpImage *dest,
|
||||
GimpDrawable *drawable,
|
||||
TempBuf *area,
|
||||
gdouble scale,
|
||||
BrushApplicationMode mode);
|
||||
|
||||
|
||||
#endif /* __PAINT_CORE_H__ */
|
@@ -1,108 +0,0 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef __PAINT_OPTIONS_H__
|
||||
#define __PAINT_OPTIONS_H__
|
||||
|
||||
#include "tool.h"
|
||||
#include "tool_options.h"
|
||||
|
||||
/* the paint options structures */
|
||||
typedef struct _PaintPressureOptions PaintPressureOptions;
|
||||
struct _PaintPressureOptions
|
||||
{
|
||||
GtkWidget *frame;
|
||||
|
||||
gboolean opacity;
|
||||
gboolean opacity_d;
|
||||
GtkWidget *opacity_w;
|
||||
|
||||
gboolean pressure;
|
||||
gboolean pressure_d;
|
||||
GtkWidget *pressure_w;
|
||||
|
||||
gboolean rate;
|
||||
gboolean rate_d;
|
||||
GtkWidget *rate_w;
|
||||
|
||||
gboolean size;
|
||||
gboolean size_d;
|
||||
GtkWidget *size_w;
|
||||
|
||||
gboolean color;
|
||||
gboolean color_d;
|
||||
GtkWidget *color_w;
|
||||
};
|
||||
|
||||
/* the paint options structures */
|
||||
typedef struct _PaintOptions PaintOptions;
|
||||
struct _PaintOptions
|
||||
{
|
||||
ToolOptions tool_options;
|
||||
|
||||
/* vbox for the common paint options */
|
||||
GtkWidget *paint_vbox;
|
||||
|
||||
/* a widget to be shown if we are in global mode */
|
||||
GtkWidget *global;
|
||||
|
||||
/* options used by all paint tools */
|
||||
GtkObject *opacity_w;
|
||||
GtkWidget *paint_mode_w;
|
||||
|
||||
/* this tool's private context */
|
||||
GimpContext *context;
|
||||
|
||||
/* the incremental toggle */
|
||||
gboolean incremental;
|
||||
gboolean incremental_d;
|
||||
GtkWidget *incremental_w;
|
||||
|
||||
/* the pressure-sensitivity options */
|
||||
PaintPressureOptions *pressure_options;
|
||||
};
|
||||
|
||||
|
||||
/* the default pressure_options for non_gui use */
|
||||
extern PaintPressureOptions non_gui_pressure_options;
|
||||
|
||||
|
||||
/* paint tool options functions */
|
||||
|
||||
PaintOptions *paint_options_new (ToolType tool_type,
|
||||
ToolOptionsResetFunc reset_func);
|
||||
|
||||
void paint_options_reset (PaintOptions *options);
|
||||
|
||||
/* to be used by "derived" paint options only */
|
||||
void paint_options_init (PaintOptions *options,
|
||||
ToolType tool_type,
|
||||
ToolOptionsResetFunc reset_func);
|
||||
|
||||
|
||||
/* functions for the global paint options */
|
||||
|
||||
/* switch between global and per-tool paint options */
|
||||
void paint_options_set_global (gboolean global);
|
||||
|
||||
|
||||
/* a utility function which returns a paint mode menu */
|
||||
GtkWidget * paint_mode_menu_new (GtkSignalFunc callback,
|
||||
gpointer data,
|
||||
LayerModeEffects initial);
|
||||
|
||||
#endif /* __PAINT_OPTIONS_H__ */
|
@@ -1327,7 +1327,7 @@ drawable_transform_scale_invoker (Gimp *gimp,
|
||||
|
||||
success = (gimp_item_is_attached (GIMP_ITEM (drawable)) &&
|
||||
trans_info[X0] < trans_info[X1] &&
|
||||
trans_info[Y0] < trans_info[X1]);
|
||||
trans_info[Y0] < trans_info[Y1]);
|
||||
|
||||
if (success &&
|
||||
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
|
||||
@@ -1480,7 +1480,7 @@ drawable_transform_scale_default_invoker (Gimp *gimp,
|
||||
|
||||
success = (gimp_item_is_attached (GIMP_ITEM (drawable)) &&
|
||||
trans_info[X0] < trans_info[X1] &&
|
||||
trans_info[Y0] < trans_info[X1]);
|
||||
trans_info[Y0] < trans_info[Y1]);
|
||||
|
||||
if (success &&
|
||||
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
|
||||
|
@@ -302,7 +302,12 @@ procedural_db_execute (Gimp *gimp,
|
||||
return_args = plug_in_run (gimp, context, progress, procedure,
|
||||
args, procedure->num_args,
|
||||
TRUE, FALSE, -1);
|
||||
break;
|
||||
|
||||
/* If there are no return arguments, assume
|
||||
* an execution error and fall through.
|
||||
*/
|
||||
if (return_args)
|
||||
break;
|
||||
|
||||
default:
|
||||
return_args = g_new (Argument, 1);
|
||||
|
@@ -302,7 +302,12 @@ procedural_db_execute (Gimp *gimp,
|
||||
return_args = plug_in_run (gimp, context, progress, procedure,
|
||||
args, procedure->num_args,
|
||||
TRUE, FALSE, -1);
|
||||
break;
|
||||
|
||||
/* If there are no return arguments, assume
|
||||
* an execution error and fall through.
|
||||
*/
|
||||
if (return_args)
|
||||
break;
|
||||
|
||||
default:
|
||||
return_args = g_new (Argument, 1);
|
||||
|
@@ -302,7 +302,12 @@ procedural_db_execute (Gimp *gimp,
|
||||
return_args = plug_in_run (gimp, context, progress, procedure,
|
||||
args, procedure->num_args,
|
||||
TRUE, FALSE, -1);
|
||||
break;
|
||||
|
||||
/* If there are no return arguments, assume
|
||||
* an execution error and fall through.
|
||||
*/
|
||||
if (return_args)
|
||||
break;
|
||||
|
||||
default:
|
||||
return_args = g_new (Argument, 1);
|
||||
|
@@ -854,7 +854,7 @@ static ProcRecord image_scale_proc =
|
||||
{
|
||||
"gimp_image_scale",
|
||||
"Scale the image to the specified extents.",
|
||||
"This procedure scales the image so that it's new width and height are equal to the supplied parameters. Offsets are also provided which describe the position of the previous image's content. No bounds checking is currently provided, so don't supply parameters that are out of bounds. All channels within the image are scaled according to the specified parameters; this includes the image selection mask. All layers within the image are repositioned according to the specified offsets.",
|
||||
"This procedure scales the image so that its new width and height are equal to the supplied parameters. Offsets are also provided which describe the position of the previous image's content. No bounds checking is currently provided, so don't supply parameters that are out of bounds. All channels within the image are scaled according to the specified parameters; this includes the image selection mask. All layers within the image are repositioned according to the specified offsets.",
|
||||
"Spencer Kimball & Peter Mattis",
|
||||
"Spencer Kimball & Peter Mattis",
|
||||
"1995-1996",
|
||||
@@ -3684,6 +3684,8 @@ image_set_filename_invoker (Gimp *gimp,
|
||||
g_free (tmp);
|
||||
else
|
||||
success = FALSE;
|
||||
|
||||
g_free (utf8);
|
||||
}
|
||||
else
|
||||
success = FALSE;
|
||||
|
@@ -76,91 +76,76 @@ plugins_query_invoker (Gimp *gimp,
|
||||
Argument *return_args;
|
||||
gchar *search_str;
|
||||
gint32 num_plugins = 0;
|
||||
gchar **menu_strs;
|
||||
gchar **accel_strs;
|
||||
gchar **prog_strs;
|
||||
gchar **types_strs;
|
||||
gint32 *time_ints;
|
||||
gchar **realname_strs;
|
||||
gchar **menu_strs = NULL;
|
||||
gchar **accel_strs = NULL;
|
||||
gchar **prog_strs = NULL;
|
||||
gchar **types_strs = NULL;
|
||||
gint32 *time_ints = NULL;
|
||||
gchar **realname_strs = NULL;
|
||||
GSList *list;
|
||||
GSList *matched = NULL;
|
||||
gint i = 0;
|
||||
regex_t sregex;
|
||||
|
||||
search_str = (gchar *) args[0].value.pdb_pointer;
|
||||
|
||||
if (search_str && strlen (search_str))
|
||||
regcomp (&sregex, search_str, REG_ICASE);
|
||||
else
|
||||
if (search_str && ! strlen (search_str))
|
||||
search_str = NULL;
|
||||
|
||||
/* count number of plugin entries, then allocate arrays of correct size
|
||||
* where we can store the strings.
|
||||
*/
|
||||
|
||||
for (list = gimp->plug_in_proc_defs; list; list = g_slist_next (list))
|
||||
if (! (search_str && regcomp (&sregex, search_str, REG_ICASE)))
|
||||
{
|
||||
PlugInProcDef *proc_def = list->data;
|
||||
/* count number of plugin entries, then allocate arrays of correct size
|
||||
* where we can store the strings.
|
||||
*/
|
||||
|
||||
if (proc_def->prog && proc_def->menu_paths)
|
||||
for (list = gimp->plug_in_proc_defs; list; list = g_slist_next (list))
|
||||
{
|
||||
gchar *name;
|
||||
PlugInProcDef *proc_def = list->data;
|
||||
|
||||
if (proc_def->menu_label)
|
||||
{
|
||||
name = proc_def->menu_label;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = strrchr (proc_def->menu_paths->data, '/');
|
||||
if (proc_def->prog && proc_def->menu_paths)
|
||||
{
|
||||
gchar *name;
|
||||
|
||||
if (name)
|
||||
name = name + 1;
|
||||
if (proc_def->menu_label)
|
||||
{
|
||||
name = proc_def->menu_label;
|
||||
}
|
||||
else
|
||||
name = proc_def->menu_paths->data;
|
||||
{
|
||||
name = strrchr (proc_def->menu_paths->data, '/');
|
||||
|
||||
if (name)
|
||||
name = name + 1;
|
||||
else
|
||||
name = proc_def->menu_paths->data;
|
||||
}
|
||||
|
||||
name = gimp_strip_uline (name);
|
||||
|
||||
if (! search_str || ! match_strings (&sregex, name))
|
||||
{
|
||||
num_plugins++;
|
||||
matched = g_slist_prepend (matched, proc_def);
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
if (search_str && match_strings (&sregex, name))
|
||||
continue;
|
||||
|
||||
num_plugins++;
|
||||
}
|
||||
}
|
||||
|
||||
menu_strs = g_new (gchar *, num_plugins);
|
||||
accel_strs = g_new (gchar *, num_plugins);
|
||||
prog_strs = g_new (gchar *, num_plugins);
|
||||
types_strs = g_new (gchar *, num_plugins);
|
||||
realname_strs = g_new (gchar *, num_plugins);
|
||||
time_ints = g_new (gint , num_plugins);
|
||||
menu_strs = g_new (gchar *, num_plugins);
|
||||
accel_strs = g_new (gchar *, num_plugins);
|
||||
prog_strs = g_new (gchar *, num_plugins);
|
||||
types_strs = g_new (gchar *, num_plugins);
|
||||
realname_strs = g_new (gchar *, num_plugins);
|
||||
time_ints = g_new (gint , num_plugins);
|
||||
|
||||
for (list = gimp->plug_in_proc_defs; list; list = g_slist_next (list))
|
||||
{
|
||||
PlugInProcDef *proc_def = list->data;
|
||||
matched = g_slist_reverse (matched);
|
||||
|
||||
if (i > num_plugins)
|
||||
g_error ("Internal error counting plugins");
|
||||
|
||||
if (proc_def->prog && proc_def->menu_paths)
|
||||
for (list = matched; list; list = g_slist_next (list))
|
||||
{
|
||||
ProcRecord *pr = &proc_def->db_info;
|
||||
gchar *name;
|
||||
|
||||
if (proc_def->menu_label)
|
||||
{
|
||||
name = proc_def->menu_label;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = strrchr (proc_def->menu_paths->data, '/');
|
||||
|
||||
if (name)
|
||||
name = name + 1;
|
||||
else
|
||||
name = proc_def->menu_paths->data;
|
||||
}
|
||||
|
||||
if (search_str && match_strings (&sregex, name))
|
||||
continue;
|
||||
PlugInProcDef *proc_def = list->data;
|
||||
ProcRecord *proc_rec = &proc_def->db_info;
|
||||
gchar *name;
|
||||
|
||||
if (proc_def->menu_label)
|
||||
name = g_strdup_printf ("%s/%s",
|
||||
@@ -173,17 +158,19 @@ plugins_query_invoker (Gimp *gimp,
|
||||
accel_strs[i] = NULL;
|
||||
prog_strs[i] = g_strdup (proc_def->prog);
|
||||
types_strs[i] = g_strdup (proc_def->image_types);
|
||||
realname_strs[i] = g_strdup (pr->name);
|
||||
realname_strs[i] = g_strdup (proc_rec->name);
|
||||
time_ints[i] = proc_def->mtime;
|
||||
|
||||
g_free (name);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (search_str)
|
||||
regfree (&sregex);
|
||||
g_slist_free (matched);
|
||||
|
||||
if (search_str)
|
||||
regfree (&sregex);
|
||||
}
|
||||
|
||||
return_args = procedural_db_return_args (&plugins_query_proc, TRUE);
|
||||
|
||||
|
@@ -302,7 +302,12 @@ procedural_db_execute (Gimp *gimp,
|
||||
return_args = plug_in_run (gimp, context, progress, procedure,
|
||||
args, procedure->num_args,
|
||||
TRUE, FALSE, -1);
|
||||
break;
|
||||
|
||||
/* If there are no return arguments, assume
|
||||
* an execution error and fall through.
|
||||
*/
|
||||
if (return_args)
|
||||
break;
|
||||
|
||||
default:
|
||||
return_args = g_new (Argument, 1);
|
||||
|
@@ -478,13 +478,24 @@ procedural_db_query_invoker (Gimp *gimp,
|
||||
|
||||
if (success)
|
||||
{
|
||||
regcomp (&pdb_query.name_regex, name, 0);
|
||||
regcomp (&pdb_query.blurb_regex, blurb, 0);
|
||||
regcomp (&pdb_query.help_regex, help, 0);
|
||||
regcomp (&pdb_query.author_regex, author, 0);
|
||||
regcomp (&pdb_query.copyright_regex, copyright, 0);
|
||||
regcomp (&pdb_query.date_regex, date, 0);
|
||||
regcomp (&pdb_query.proc_type_regex, proc_type, 0);
|
||||
success = FALSE;
|
||||
|
||||
if (regcomp (&pdb_query.name_regex, name, 0))
|
||||
goto free_name;
|
||||
if (regcomp (&pdb_query.blurb_regex, blurb, 0))
|
||||
goto free_blurb;
|
||||
if (regcomp (&pdb_query.help_regex, help, 0))
|
||||
goto free_help;
|
||||
if (regcomp (&pdb_query.author_regex, author, 0))
|
||||
goto free_author;
|
||||
if (regcomp (&pdb_query.copyright_regex, copyright, 0))
|
||||
goto free_copyright;
|
||||
if (regcomp (&pdb_query.date_regex, date, 0))
|
||||
goto free_date;
|
||||
if (regcomp (&pdb_query.proc_type_regex, proc_type, 0))
|
||||
goto free_proc_type;
|
||||
|
||||
success = TRUE;
|
||||
|
||||
pdb_query.gimp = gimp;
|
||||
pdb_query.list_of_procs = NULL;
|
||||
@@ -499,13 +510,20 @@ procedural_db_query_invoker (Gimp *gimp,
|
||||
g_hash_table_foreach (gimp->procedural_compat_ht,
|
||||
procedural_db_query_entry, &pdb_query);
|
||||
|
||||
regfree (&pdb_query.name_regex);
|
||||
regfree (&pdb_query.blurb_regex);
|
||||
regfree (&pdb_query.help_regex);
|
||||
regfree (&pdb_query.author_regex);
|
||||
regfree (&pdb_query.copyright_regex);
|
||||
regfree (&pdb_query.date_regex);
|
||||
regfree (&pdb_query.proc_type_regex);
|
||||
free_proc_type:
|
||||
regfree (&pdb_query.proc_type_regex);
|
||||
free_date:
|
||||
regfree (&pdb_query.date_regex);
|
||||
free_copyright:
|
||||
regfree (&pdb_query.copyright_regex);
|
||||
free_author:
|
||||
regfree (&pdb_query.author_regex);
|
||||
free_help:
|
||||
regfree (&pdb_query.help_regex);
|
||||
free_blurb:
|
||||
regfree (&pdb_query.blurb_regex);
|
||||
free_name:
|
||||
regfree (&pdb_query.name_regex);
|
||||
}
|
||||
|
||||
return_args = procedural_db_return_args (&procedural_db_query_proc, success);
|
||||
|
@@ -149,7 +149,7 @@ static ProcArg text_fontname_inargs[] =
|
||||
{
|
||||
GIMP_PDB_STRING,
|
||||
"text",
|
||||
"The text to generate"
|
||||
"The text to generate (in UTF-8 encoding)"
|
||||
},
|
||||
{
|
||||
GIMP_PDB_INT32,
|
||||
@@ -267,7 +267,7 @@ static ProcArg text_get_extents_fontname_inargs[] =
|
||||
{
|
||||
GIMP_PDB_STRING,
|
||||
"text",
|
||||
"The text to generate"
|
||||
"The text to generate (in UTF-8 encoding)"
|
||||
},
|
||||
{
|
||||
GIMP_PDB_FLOAT,
|
||||
@@ -464,7 +464,7 @@ static ProcArg text_inargs[] =
|
||||
{
|
||||
GIMP_PDB_STRING,
|
||||
"text",
|
||||
"The text to generate"
|
||||
"The text to generate (in UTF-8 encoding)"
|
||||
},
|
||||
{
|
||||
GIMP_PDB_INT32,
|
||||
@@ -652,7 +652,7 @@ static ProcArg text_get_extents_inargs[] =
|
||||
{
|
||||
GIMP_PDB_STRING,
|
||||
"text",
|
||||
"The text to generate"
|
||||
"The text to generate (in UTF-8 encoding)"
|
||||
},
|
||||
{
|
||||
GIMP_PDB_FLOAT,
|
||||
|
@@ -435,7 +435,7 @@ scale_invoker (Gimp *gimp,
|
||||
|
||||
success = (gimp_item_is_attached (GIMP_ITEM (drawable)) &&
|
||||
trans_info[X0] < trans_info[X1] &&
|
||||
trans_info[Y0] < trans_info[X1]);
|
||||
trans_info[Y0] < trans_info[Y1]);
|
||||
|
||||
if (success &&
|
||||
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
|
||||
|
@@ -1,514 +0,0 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995-2000 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* NOTE: This file is autogenerated by pdbgen.pl. */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "apptypes.h"
|
||||
#include "procedural_db.h"
|
||||
|
||||
#include "appenv.h"
|
||||
#include "plug_in.h"
|
||||
|
||||
#ifdef HAVE_GLIBC_REGEX
|
||||
#include <regex.h>
|
||||
#else
|
||||
#include "regexrepl.h"
|
||||
#endif
|
||||
|
||||
|
||||
static ProcRecord progress_init_proc;
|
||||
static ProcRecord progress_update_proc;
|
||||
static ProcRecord temp_PDB_name_proc;
|
||||
static ProcRecord plugins_query_proc;
|
||||
static ProcRecord plugin_domain_register_proc;
|
||||
static ProcRecord plugin_help_register_proc;
|
||||
|
||||
void
|
||||
register_plug_in_procs (void)
|
||||
{
|
||||
procedural_db_register (&progress_init_proc);
|
||||
procedural_db_register (&progress_update_proc);
|
||||
procedural_db_register (&temp_PDB_name_proc);
|
||||
procedural_db_register (&plugins_query_proc);
|
||||
procedural_db_register (&plugin_domain_register_proc);
|
||||
procedural_db_register (&plugin_help_register_proc);
|
||||
}
|
||||
|
||||
static int
|
||||
match_strings (regex_t *preg,
|
||||
gchar *a)
|
||||
{
|
||||
return regexec (preg, a, 0, NULL, 0);
|
||||
}
|
||||
|
||||
static Argument *
|
||||
progress_init_invoker (Argument *args)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
gchar *message;
|
||||
gint32 gdisplay;
|
||||
|
||||
message = (gchar *) args[0].value.pdb_pointer;
|
||||
|
||||
gdisplay = args[1].value.pdb_int;
|
||||
|
||||
if (current_plug_in && current_plug_in->open)
|
||||
{
|
||||
success = TRUE;
|
||||
if (!no_interface)
|
||||
plug_in_progress_init (current_plug_in, message, gdisplay);
|
||||
}
|
||||
|
||||
return procedural_db_return_args (&progress_init_proc, success);
|
||||
}
|
||||
|
||||
static ProcArg progress_init_inargs[] =
|
||||
{
|
||||
{
|
||||
PDB_STRING,
|
||||
"message",
|
||||
"Message to use in the progress dialog"
|
||||
},
|
||||
{
|
||||
PDB_INT32,
|
||||
"gdisplay",
|
||||
"GDisplay to update progressbar in, or -1 for a seperate window"
|
||||
}
|
||||
};
|
||||
|
||||
static ProcRecord progress_init_proc =
|
||||
{
|
||||
"gimp_progress_init",
|
||||
"Initializes the progress bar for the current plug-in.",
|
||||
"Initializes the progress bar for the current plug-in. It is only valid to call this procedure from a plug-in.",
|
||||
"Spencer Kimball & Peter Mattis",
|
||||
"Spencer Kimball & Peter Mattis",
|
||||
"1995-1996",
|
||||
PDB_INTERNAL,
|
||||
2,
|
||||
progress_init_inargs,
|
||||
0,
|
||||
NULL,
|
||||
{ { progress_init_invoker } }
|
||||
};
|
||||
|
||||
static Argument *
|
||||
progress_update_invoker (Argument *args)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
gdouble percentage;
|
||||
|
||||
percentage = args[0].value.pdb_float;
|
||||
|
||||
if (current_plug_in && current_plug_in->open)
|
||||
{
|
||||
success = TRUE;
|
||||
if (!no_interface)
|
||||
plug_in_progress_update (current_plug_in, percentage);
|
||||
}
|
||||
|
||||
return procedural_db_return_args (&progress_update_proc, success);
|
||||
}
|
||||
|
||||
static ProcArg progress_update_inargs[] =
|
||||
{
|
||||
{
|
||||
PDB_FLOAT,
|
||||
"percentage",
|
||||
"Percentage of progress completed"
|
||||
}
|
||||
};
|
||||
|
||||
static ProcRecord progress_update_proc =
|
||||
{
|
||||
"gimp_progress_update",
|
||||
"Updates the progress bar for the current plug-in.",
|
||||
"Updates the progress bar for the current plug-in. It is only valid to call this procedure from a plug-in.",
|
||||
"Spencer Kimball & Peter Mattis",
|
||||
"Spencer Kimball & Peter Mattis",
|
||||
"1995-1996",
|
||||
PDB_INTERNAL,
|
||||
1,
|
||||
progress_update_inargs,
|
||||
0,
|
||||
NULL,
|
||||
{ { progress_update_invoker } }
|
||||
};
|
||||
|
||||
static Argument *
|
||||
temp_PDB_name_invoker (Argument *args)
|
||||
{
|
||||
Argument *return_args;
|
||||
gchar *temp_name;
|
||||
static gint proc_number = 0;
|
||||
|
||||
temp_name = g_strdup_printf ("temp_plugin_number_%d", proc_number++);
|
||||
|
||||
return_args = procedural_db_return_args (&temp_PDB_name_proc, TRUE);
|
||||
return_args[1].value.pdb_pointer = temp_name;
|
||||
|
||||
return return_args;
|
||||
}
|
||||
|
||||
static ProcArg temp_PDB_name_outargs[] =
|
||||
{
|
||||
{
|
||||
PDB_STRING,
|
||||
"temp_name",
|
||||
"A unique temporary name for a temporary PDB entry"
|
||||
}
|
||||
};
|
||||
|
||||
static ProcRecord temp_PDB_name_proc =
|
||||
{
|
||||
"gimp_temp_PDB_name",
|
||||
"Generates a unique temporary PDB name.",
|
||||
"This procedure generates a temporary PDB entry name that is guaranteed to be unique. It is many used by the interactive popup dialogs to generate a PDB entry name.",
|
||||
"Andy Thomas",
|
||||
"Andy Thomas",
|
||||
"1998",
|
||||
PDB_INTERNAL,
|
||||
0,
|
||||
NULL,
|
||||
1,
|
||||
temp_PDB_name_outargs,
|
||||
{ { temp_PDB_name_invoker } }
|
||||
};
|
||||
|
||||
static Argument *
|
||||
plugins_query_invoker (Argument *args)
|
||||
{
|
||||
Argument *return_args;
|
||||
gchar *search_str;
|
||||
gint32 num_plugins = 0;
|
||||
gchar **menu_strs;
|
||||
gchar **accel_strs;
|
||||
gchar **prog_strs;
|
||||
gchar **types_strs;
|
||||
gint32 *time_ints;
|
||||
gchar **realname_strs;
|
||||
PlugInProcDef *proc_def;
|
||||
GSList *tmp = NULL;
|
||||
gint i = 0;
|
||||
regex_t sregex;
|
||||
|
||||
search_str = (gchar *) args[0].value.pdb_pointer;
|
||||
|
||||
if (search_str && strlen (search_str))
|
||||
regcomp (&sregex, search_str, REG_ICASE);
|
||||
else
|
||||
search_str = NULL;
|
||||
|
||||
/* count number of plugin entries, then allocate 4 arrays of correct size
|
||||
* where we can store the strings.
|
||||
*/
|
||||
|
||||
tmp = proc_defs;
|
||||
while (tmp)
|
||||
{
|
||||
proc_def = tmp->data;
|
||||
tmp = tmp->next;
|
||||
|
||||
if (proc_def->prog && proc_def->menu_path)
|
||||
{
|
||||
gchar *name = strrchr (proc_def->menu_path, '/');
|
||||
|
||||
if (name)
|
||||
name = name + 1;
|
||||
else
|
||||
name = proc_def->menu_path;
|
||||
|
||||
if (search_str && match_strings (&sregex, name))
|
||||
continue;
|
||||
|
||||
num_plugins++;
|
||||
}
|
||||
}
|
||||
|
||||
menu_strs = g_new (gchar *, num_plugins);
|
||||
accel_strs = g_new (gchar *, num_plugins);
|
||||
prog_strs = g_new (gchar *, num_plugins);
|
||||
types_strs = g_new (gchar *, num_plugins);
|
||||
realname_strs = g_new (gchar *, num_plugins);
|
||||
time_ints = g_new (gint , num_plugins);
|
||||
|
||||
tmp = proc_defs;
|
||||
while (tmp)
|
||||
{
|
||||
if (i > num_plugins)
|
||||
g_error ("Internal error counting plugins");
|
||||
|
||||
proc_def = tmp->data;
|
||||
tmp = tmp->next;
|
||||
|
||||
if (proc_def->prog && proc_def->menu_path)
|
||||
{
|
||||
ProcRecord *pr = &proc_def->db_info;
|
||||
|
||||
gchar *name = strrchr (proc_def->menu_path, '/');
|
||||
|
||||
if (name)
|
||||
name = name + 1;
|
||||
else
|
||||
name = proc_def->menu_path;
|
||||
|
||||
if (search_str && match_strings(&sregex,name))
|
||||
continue;
|
||||
|
||||
menu_strs[i] = g_strdup (proc_def->menu_path);
|
||||
accel_strs[i] = g_strdup (proc_def->accelerator);
|
||||
prog_strs[i] = g_strdup (proc_def->prog);
|
||||
types_strs[i] = g_strdup (proc_def->image_types);
|
||||
realname_strs[i] = g_strdup (pr->name);
|
||||
time_ints[i] = proc_def->mtime;
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* This I hope frees up internal stuff */
|
||||
if (search_str)
|
||||
free (sregex.buffer);
|
||||
|
||||
return_args = procedural_db_return_args (&plugins_query_proc, TRUE);
|
||||
|
||||
return_args[1].value.pdb_int = num_plugins;
|
||||
return_args[2].value.pdb_pointer = menu_strs;
|
||||
return_args[3].value.pdb_int = num_plugins;
|
||||
return_args[4].value.pdb_pointer = accel_strs;
|
||||
return_args[5].value.pdb_int = num_plugins;
|
||||
return_args[6].value.pdb_pointer = prog_strs;
|
||||
return_args[7].value.pdb_int = num_plugins;
|
||||
return_args[8].value.pdb_pointer = types_strs;
|
||||
return_args[9].value.pdb_int = num_plugins;
|
||||
return_args[10].value.pdb_pointer = time_ints;
|
||||
return_args[11].value.pdb_int = num_plugins;
|
||||
return_args[12].value.pdb_pointer = realname_strs;
|
||||
|
||||
return return_args;
|
||||
}
|
||||
|
||||
static ProcArg plugins_query_inargs[] =
|
||||
{
|
||||
{
|
||||
PDB_STRING,
|
||||
"search_string",
|
||||
"If not an empty string then use this as a search pattern"
|
||||
}
|
||||
};
|
||||
|
||||
static ProcArg plugins_query_outargs[] =
|
||||
{
|
||||
{
|
||||
PDB_INT32,
|
||||
"num_plugins",
|
||||
"The number of plugins"
|
||||
},
|
||||
{
|
||||
PDB_STRINGARRAY,
|
||||
"menu_path",
|
||||
"The menu path of the plugin"
|
||||
},
|
||||
{
|
||||
PDB_INT32,
|
||||
"num_plugins",
|
||||
"The number of plugins"
|
||||
},
|
||||
{
|
||||
PDB_STRINGARRAY,
|
||||
"plugin_accelerator",
|
||||
"String representing keyboard accelerator (could be empty string)"
|
||||
},
|
||||
{
|
||||
PDB_INT32,
|
||||
"num_plugins",
|
||||
"The number of plugins"
|
||||
},
|
||||
{
|
||||
PDB_STRINGARRAY,
|
||||
"plugin_location",
|
||||
"Location of the plugin program"
|
||||
},
|
||||
{
|
||||
PDB_INT32,
|
||||
"num_plugins",
|
||||
"The number of plugins"
|
||||
},
|
||||
{
|
||||
PDB_STRINGARRAY,
|
||||
"plugin_image_type",
|
||||
"Type of image that this plugin will work on"
|
||||
},
|
||||
{
|
||||
PDB_INT32,
|
||||
"num_plugins",
|
||||
"The number of plugins"
|
||||
},
|
||||
{
|
||||
PDB_INT32ARRAY,
|
||||
"plugin_install_time",
|
||||
"Time that the plugin was installed"
|
||||
},
|
||||
{
|
||||
PDB_INT32,
|
||||
"num_plugins",
|
||||
"The number of plugins"
|
||||
},
|
||||
{
|
||||
PDB_STRINGARRAY,
|
||||
"plugin_real_name",
|
||||
"The internal name of the plugin"
|
||||
}
|
||||
};
|
||||
|
||||
static ProcRecord plugins_query_proc =
|
||||
{
|
||||
"gimp_plugins_query",
|
||||
"Queries the plugin database for its contents.",
|
||||
"This procedure queries the contents of the plugin database.",
|
||||
"Andy Thomas",
|
||||
"Andy Thomas",
|
||||
"1998",
|
||||
PDB_INTERNAL,
|
||||
1,
|
||||
plugins_query_inargs,
|
||||
12,
|
||||
plugins_query_outargs,
|
||||
{ { plugins_query_invoker } }
|
||||
};
|
||||
|
||||
static Argument *
|
||||
plugin_domain_register_invoker (Argument *args)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
gchar *domain_name;
|
||||
gchar *domain_path;
|
||||
PlugInDef *plug_in_def;
|
||||
|
||||
domain_name = (gchar *) args[0].value.pdb_pointer;
|
||||
if (domain_name == NULL)
|
||||
success = FALSE;
|
||||
|
||||
domain_path = (gchar *) args[1].value.pdb_pointer;
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (current_plug_in && current_plug_in->query)
|
||||
{
|
||||
plug_in_def = current_plug_in->user_data;
|
||||
|
||||
if (plug_in_def->locale_domain)
|
||||
g_free (plug_in_def->locale_domain);
|
||||
plug_in_def->locale_domain = g_strdup (domain_name);
|
||||
|
||||
if (plug_in_def->locale_path);
|
||||
g_free (plug_in_def->locale_path);
|
||||
plug_in_def->locale_path = domain_path ? g_strdup (domain_path) : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return procedural_db_return_args (&plugin_domain_register_proc, success);
|
||||
}
|
||||
|
||||
static ProcArg plugin_domain_register_inargs[] =
|
||||
{
|
||||
{
|
||||
PDB_STRING,
|
||||
"domain_name",
|
||||
"The name of the textdomain (must be unique)."
|
||||
},
|
||||
{
|
||||
PDB_STRING,
|
||||
"domain_path",
|
||||
"The absolute path to the compiled message catalog (may be NULL)."
|
||||
}
|
||||
};
|
||||
|
||||
static ProcRecord plugin_domain_register_proc =
|
||||
{
|
||||
"gimp_plugin_domain_register",
|
||||
"Registers a textdomain for localisation.",
|
||||
"This procedure adds a textdomain to the list of domains Gimp searches for strings when translating its menu entries. There is no need to call this function for plug-ins that have their strings included in the gimp-std-plugins domain as that is used by default. If the compiled message catalog is not in the standard location, you may specify an absolute path to another location. This procedure can only be called in the query function of a plug-in and it has to be called before any procedure is installed.",
|
||||
"Sven Neumann",
|
||||
"Sven Neumann",
|
||||
"2000",
|
||||
PDB_INTERNAL,
|
||||
2,
|
||||
plugin_domain_register_inargs,
|
||||
0,
|
||||
NULL,
|
||||
{ { plugin_domain_register_invoker } }
|
||||
};
|
||||
|
||||
static Argument *
|
||||
plugin_help_register_invoker (Argument *args)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
gchar *help_path;
|
||||
PlugInDef *plug_in_def;
|
||||
|
||||
help_path = (gchar *) args[0].value.pdb_pointer;
|
||||
if (help_path == NULL)
|
||||
success = FALSE;
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (current_plug_in && current_plug_in->query)
|
||||
{
|
||||
plug_in_def = current_plug_in->user_data;
|
||||
|
||||
if (plug_in_def->help_path)
|
||||
g_free (plug_in_def->help_path);
|
||||
plug_in_def->help_path = g_strdup (help_path);
|
||||
}
|
||||
}
|
||||
|
||||
return procedural_db_return_args (&plugin_help_register_proc, success);
|
||||
}
|
||||
|
||||
static ProcArg plugin_help_register_inargs[] =
|
||||
{
|
||||
{
|
||||
PDB_STRING,
|
||||
"help_path",
|
||||
"The rootdir of the plug-in's help pages"
|
||||
}
|
||||
};
|
||||
|
||||
static ProcRecord plugin_help_register_proc =
|
||||
{
|
||||
"gimp_plugin_help_register",
|
||||
"Register a help path for a plug-in.",
|
||||
"This procedure changes the help rootdir for the plug-in which calls it. All subsequent calls of gimp_help from this plug-in will be interpreted relative to this rootdir. This procedure can only be called in the query function of a plug-in and it has to be called before any procedure is installed.",
|
||||
"Michael Natterer <mitch@gimp.org>",
|
||||
"Michael Natterer <mitch@gimp.org>",
|
||||
"2000",
|
||||
PDB_INTERNAL,
|
||||
1,
|
||||
plugin_help_register_inargs,
|
||||
0,
|
||||
NULL,
|
||||
{ { plugin_help_register_invoker } }
|
||||
};
|
@@ -21,6 +21,8 @@ libapptext_a_sources = \
|
||||
gimp-fonts.h \
|
||||
gimpfont.c \
|
||||
gimpfont.h \
|
||||
gimpfont-utils.c \
|
||||
gimpfont-utils.h \
|
||||
gimpfontlist.c \
|
||||
gimpfontlist.h \
|
||||
gimptext.c \
|
||||
|
82
app/text/gimpfont-utils.c
Normal file
82
app/text/gimpfont-utils.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpfontlist.c
|
||||
* Copyright (C) 2005 Manish Singh <yosh@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <pango/pangoft2.h>
|
||||
|
||||
#include "gimpfont-utils.h"
|
||||
|
||||
/* Workaround pango bug #166540 */
|
||||
|
||||
static const char *
|
||||
getword (const char *str, const char *last, size_t *wordlen)
|
||||
{
|
||||
const char *result;
|
||||
|
||||
while (last > str && g_ascii_isspace (*(last - 1)))
|
||||
last--;
|
||||
|
||||
result = last;
|
||||
while (result > str && !g_ascii_isspace (*(result - 1)))
|
||||
result--;
|
||||
|
||||
*wordlen = last - result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gimp_font_util_pango_font_description_to_string (const PangoFontDescription *desc)
|
||||
{
|
||||
gchar *name;
|
||||
size_t wordlen;
|
||||
const gchar *p;
|
||||
|
||||
g_return_val_if_fail (desc != NULL, NULL);
|
||||
|
||||
name = pango_font_description_to_string (desc);
|
||||
|
||||
p = getword (name, name + strlen (name), &wordlen);
|
||||
|
||||
if (wordlen)
|
||||
{
|
||||
gchar *end;
|
||||
gdouble size;
|
||||
|
||||
size = g_ascii_strtod (p, &end);
|
||||
|
||||
if (end - p == wordlen)
|
||||
{
|
||||
gchar *new_name;
|
||||
|
||||
new_name = g_strconcat (name, ",", NULL);
|
||||
g_free (name);
|
||||
|
||||
name = new_name;
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* Object properties deserialization routines
|
||||
* Copyright (C) 2001-2002 Sven Neumann <sven@gimp.org>
|
||||
* gimpfont-utils.h
|
||||
* Copyright (C) 2005 Manish Singh <yosh@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,14 +19,18 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GIMP_CONFIG_DESERIALIZE_H__
|
||||
#define __GIMP_CONFIG_DESERIALIZE_H__
|
||||
#ifndef __GIMP_FONT_UTILS_H__
|
||||
#define __GIMP_FONT_UTILS_H__
|
||||
|
||||
|
||||
gboolean gimp_config_deserialize_properties (GimpConfig *config,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gboolean store_unknown_tokens);
|
||||
/* This is solely to workaround pango bug #166540, by tacking on a ',' to
|
||||
* font names that end in numbers, so pango_font_description_from_string
|
||||
* doesn't interpret it as a size. Note that this doesn't fully workaround
|
||||
* problems pango has with font name serialization, just only the bad size
|
||||
* interpretation. Family names that end with style names are still
|
||||
* processed wrongly.
|
||||
*/
|
||||
gchar * gimp_font_util_pango_font_description_to_string (const PangoFontDescription *desc);
|
||||
|
||||
|
||||
#endif /* __GIMP_CONFIG_DESERIALIZE_H__ */
|
||||
#endif /* __GIMP_FONT_UTILS_H__ */
|
@@ -233,8 +233,7 @@ gimp_font_get_popup_size (GimpViewable *viewable,
|
||||
name = gimp_object_get_name (GIMP_OBJECT (font));
|
||||
|
||||
font_desc = pango_font_description_from_string (name);
|
||||
if (!font_desc)
|
||||
return FALSE;
|
||||
g_return_val_if_fail (font_desc != NULL, FALSE);
|
||||
|
||||
pango_font_description_set_size (font_desc, GIMP_FONT_POPUP_SIZE);
|
||||
|
||||
@@ -291,8 +290,6 @@ gimp_font_get_new_preview (GimpViewable *viewable,
|
||||
|
||||
font_desc = pango_font_description_from_string (name);
|
||||
g_return_val_if_fail (font_desc != NULL, NULL);
|
||||
if (!font_desc)
|
||||
return NULL;
|
||||
|
||||
pango_font_description_set_size (font_desc,
|
||||
PANGO_SCALE * height * 2.0 / 3.0);
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include "text-types.h"
|
||||
|
||||
#include "gimpfont.h"
|
||||
#include "gimpfont-utils.h"
|
||||
#include "gimpfontlist.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
@@ -48,6 +49,9 @@
|
||||
#endif
|
||||
|
||||
|
||||
typedef char * (* GimpFontDescToStringFunc) (const PangoFontDescription *desc);
|
||||
|
||||
|
||||
static void gimp_font_list_class_init (GimpFontListClass *klass);
|
||||
static void gimp_font_list_init (GimpFontList *list);
|
||||
|
||||
@@ -62,6 +66,8 @@ static void gimp_font_list_load_names (GimpFontList *list,
|
||||
|
||||
static GimpListClass *parent_class = NULL;
|
||||
|
||||
static GimpFontDescToStringFunc font_desc_to_string = NULL;
|
||||
|
||||
|
||||
GType
|
||||
gimp_font_list_get_type (void)
|
||||
@@ -125,11 +131,32 @@ gimp_font_list_new (gdouble xresolution,
|
||||
void
|
||||
gimp_font_list_restore (GimpFontList *list)
|
||||
{
|
||||
PangoFontMap *fontmap;
|
||||
PangoContext *context;
|
||||
PangoFontMap *fontmap;
|
||||
PangoContext *context;
|
||||
|
||||
g_return_if_fail (GIMP_IS_FONT_LIST (list));
|
||||
|
||||
if (font_desc_to_string == NULL)
|
||||
{
|
||||
PangoFontDescription *desc;
|
||||
gchar *name;
|
||||
gchar last_char;
|
||||
|
||||
desc = pango_font_description_new ();
|
||||
pango_font_description_set_family (desc, "Wilber 12");
|
||||
|
||||
name = pango_font_description_to_string (desc);
|
||||
last_char = name[strlen (name) - 1];
|
||||
|
||||
g_free (name);
|
||||
pango_font_description_free (desc);
|
||||
|
||||
if (last_char != ',')
|
||||
font_desc_to_string = &gimp_font_util_pango_font_description_to_string;
|
||||
else
|
||||
font_desc_to_string = &pango_font_description_to_string;
|
||||
}
|
||||
|
||||
fontmap = pango_ft2_font_map_new ();
|
||||
pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (fontmap),
|
||||
list->xresolution, list->yresolution);
|
||||
@@ -158,7 +185,7 @@ gimp_font_list_add_font (GimpFontList *list,
|
||||
if (! desc)
|
||||
return;
|
||||
|
||||
name = pango_font_description_to_string (desc);
|
||||
name = font_desc_to_string (desc);
|
||||
|
||||
if (! g_utf8_validate (name, -1, NULL))
|
||||
{
|
||||
@@ -260,7 +287,7 @@ gimp_font_list_load_names (GimpFontList *list,
|
||||
FcFontSetDestroy (fontset);
|
||||
}
|
||||
|
||||
#else /* ! USE_FONTCONFIG_DIRECTLY */
|
||||
#else /* ! USE_FONTCONFIG_DIRECTLY */
|
||||
|
||||
static void
|
||||
gimp_font_list_load_names (GimpFontList *list,
|
||||
@@ -292,4 +319,4 @@ gimp_font_list_load_names (GimpFontList *list,
|
||||
g_free (families);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* USE_FONTCONFIG_DIRECTLY */
|
||||
|
@@ -37,6 +37,8 @@
|
||||
#include "core/gimpimage-undo.h"
|
||||
#include "core/gimplayer-floating-sel.h"
|
||||
|
||||
#include "gimpfont-utils.h"
|
||||
|
||||
#include "gimptext.h"
|
||||
#include "gimptext-compat.h"
|
||||
#include "gimptextlayer.h"
|
||||
@@ -77,7 +79,7 @@ text_render (GimpImage *gimage,
|
||||
size = PANGO_PIXELS (pango_font_description_get_size (desc));
|
||||
|
||||
pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE);
|
||||
font = pango_font_description_to_string (desc);
|
||||
font = gimp_font_util_pango_font_description_to_string (desc);
|
||||
|
||||
pango_font_description_free (desc);
|
||||
|
||||
|
@@ -62,6 +62,7 @@ enum
|
||||
static gchar * gimp_text_get_xlfd_field (const gchar *fontname,
|
||||
gint field_num,
|
||||
gchar *buffer);
|
||||
static gchar * launder_font_name (gchar *name);
|
||||
|
||||
|
||||
/**
|
||||
@@ -118,10 +119,10 @@ gimp_text_font_name_from_xlfd (const gchar *xlfd)
|
||||
if (i < 4)
|
||||
fields[i] = NULL;
|
||||
|
||||
return g_strconcat (fields[0], " ",
|
||||
fields[1], " ",
|
||||
fields[2], " ",
|
||||
fields[3], NULL);
|
||||
return launder_font_name (g_strconcat (fields[0], " ",
|
||||
fields[1], " ",
|
||||
fields[2], " ",
|
||||
fields[3], NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,7 +251,7 @@ gimp_text_get_xlfd_field (const gchar *fontname,
|
||||
for (t2 = t1; *t2; t2++)
|
||||
{
|
||||
if (*t2 == '-' && --num_dashes == 0)
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (t2 > t1)
|
||||
@@ -258,7 +259,7 @@ gimp_text_get_xlfd_field (const gchar *fontname,
|
||||
/* Check we don't overflow the buffer */
|
||||
len = (gsize) t2 - (gsize) t1;
|
||||
if (len > XLFD_MAX_FIELD_LEN - 1)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
if (*t1 == '*')
|
||||
return NULL;
|
||||
@@ -268,7 +269,7 @@ gimp_text_get_xlfd_field (const gchar *fontname,
|
||||
|
||||
/* Convert to lower case. */
|
||||
for (p = buffer; *p; p++)
|
||||
*p = g_ascii_tolower (*p);
|
||||
*p = g_ascii_tolower (*p);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -277,3 +278,25 @@ gimp_text_get_xlfd_field (const gchar *fontname,
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* Guard against font names that end in numbers being interpreted as a
|
||||
* font size in pango font descriptions
|
||||
*/
|
||||
static gchar *
|
||||
launder_font_name (gchar *name)
|
||||
{
|
||||
gchar *laundered_name;
|
||||
gchar last_char;
|
||||
|
||||
last_char = name[strlen (name) - 1];
|
||||
|
||||
if (g_ascii_isdigit (last_char) || last_char == '.')
|
||||
{
|
||||
laundered_name = g_strconcat (name, ",", NULL);
|
||||
g_free (name);
|
||||
|
||||
return laundered_name;
|
||||
}
|
||||
else
|
||||
return name;
|
||||
}
|
||||
|
@@ -142,8 +142,6 @@ gimp_text_layout_new (GimpText *text,
|
||||
|
||||
font_desc = pango_font_description_from_string (text->font);
|
||||
g_return_val_if_fail (font_desc != NULL, NULL);
|
||||
if (!font_desc)
|
||||
return NULL;
|
||||
|
||||
gimp_image_get_resolution (image, &xres, &yres);
|
||||
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "tools-types.h"
|
||||
|
||||
#include "config/gimpconfig.h"
|
||||
#include "config/gimpconfig-utils.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimplist.h"
|
||||
@@ -455,6 +456,11 @@ gimp_tools_register (GType tool_type,
|
||||
paint_core_name,
|
||||
stock_id);
|
||||
|
||||
if (tool_type == GIMP_TYPE_TEXT_TOOL)
|
||||
gimp_config_connect (G_OBJECT (tool_info->tool_options),
|
||||
G_OBJECT (gimp_get_user_context (gimp)),
|
||||
"font");
|
||||
|
||||
if (g_type_is_a (tool_type, GIMP_TYPE_IMAGE_MAP_TOOL))
|
||||
g_object_set (tool_info, "visible", FALSE, NULL);
|
||||
|
||||
|
@@ -153,9 +153,23 @@ gimp_clone_tool_button_press (GimpTool *tool,
|
||||
GimpDisplay *gdisp)
|
||||
{
|
||||
GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool);
|
||||
GimpCloneTool *clone_tool = GIMP_CLONE_TOOL (tool);
|
||||
|
||||
if ((state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) == GDK_CONTROL_MASK)
|
||||
GIMP_CLONE (paint_tool->core)->set_source = TRUE;
|
||||
{
|
||||
GIMP_CLONE (paint_tool->core)->set_source = TRUE;
|
||||
|
||||
if (gdisp != clone_tool->src_gdisp)
|
||||
{
|
||||
if (clone_tool->src_gdisp)
|
||||
g_object_remove_weak_pointer (G_OBJECT (clone_tool->src_gdisp),
|
||||
(gpointer *) &clone_tool->src_gdisp);
|
||||
|
||||
clone_tool->src_gdisp = gdisp;
|
||||
g_object_add_weak_pointer (G_OBJECT (gdisp),
|
||||
(gpointer *) &clone_tool->src_gdisp);
|
||||
}
|
||||
}
|
||||
else
|
||||
GIMP_CLONE (paint_tool->core)->set_source = FALSE;
|
||||
|
||||
@@ -231,18 +245,26 @@ gimp_clone_tool_draw (GimpDrawTool *draw_tool)
|
||||
|
||||
if (options->clone_type == GIMP_IMAGE_CLONE && clone->src_drawable)
|
||||
{
|
||||
gint off_x;
|
||||
gint off_y;
|
||||
gint off_x;
|
||||
gint off_y;
|
||||
GimpDisplay *tmp_gdisp;
|
||||
GimpCloneTool *clone_tool = GIMP_CLONE_TOOL (draw_tool);
|
||||
|
||||
gimp_item_offsets (GIMP_ITEM (clone->src_drawable), &off_x, &off_y);
|
||||
|
||||
gimp_draw_tool_draw_handle (draw_tool,
|
||||
GIMP_HANDLE_CROSS,
|
||||
clone->src_x + off_x,
|
||||
clone->src_y + off_y,
|
||||
TARGET_WIDTH, TARGET_WIDTH,
|
||||
GTK_ANCHOR_CENTER,
|
||||
FALSE);
|
||||
tmp_gdisp = draw_tool->gdisp;
|
||||
draw_tool->gdisp = clone_tool->src_gdisp;
|
||||
|
||||
if (draw_tool->gdisp)
|
||||
gimp_draw_tool_draw_handle (draw_tool,
|
||||
GIMP_HANDLE_CROSS,
|
||||
clone->src_x + off_x,
|
||||
clone->src_y + off_y,
|
||||
TARGET_WIDTH, TARGET_WIDTH,
|
||||
GTK_ANCHOR_CENTER,
|
||||
FALSE);
|
||||
|
||||
draw_tool->gdisp = tmp_gdisp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -37,6 +37,7 @@ typedef struct _GimpCloneToolClass GimpCloneToolClass;
|
||||
struct _GimpCloneTool
|
||||
{
|
||||
GimpPaintTool parent_instance;
|
||||
GimpDisplay *src_gdisp;
|
||||
};
|
||||
|
||||
struct _GimpCloneToolClass
|
||||
|
@@ -1339,7 +1339,14 @@ crop_aspect_changed (GtkWidget *widget,
|
||||
|
||||
crop->y2 = crop->y1 + ((gdouble) (crop->x2 - crop->x1) / crop->aspect_ratio);
|
||||
|
||||
crop->change_aspect_ratio = FALSE;
|
||||
if (crop->y2 >= crop->y1 + 1)
|
||||
crop->change_aspect_ratio = FALSE;
|
||||
else
|
||||
{
|
||||
crop->change_aspect_ratio = TRUE;
|
||||
crop->y2 = crop->y1 + 1;
|
||||
}
|
||||
|
||||
crop_recalc (crop, TRUE);
|
||||
crop->change_aspect_ratio = TRUE;
|
||||
|
||||
|
@@ -136,18 +136,11 @@ static void
|
||||
gimp_ellipse_select_tool_draw (GimpDrawTool *draw_tool)
|
||||
{
|
||||
GimpRectSelectTool *rect_sel = GIMP_RECT_SELECT_TOOL (draw_tool);
|
||||
gint ix, iy;
|
||||
gint iw, ih;
|
||||
|
||||
gimp_rect_select_tool_coords_to_integer (draw_tool->gdisp,
|
||||
rect_sel->x, rect_sel->y,
|
||||
rect_sel->w, rect_sel->h,
|
||||
&ix, &iy,
|
||||
&iw, &ih);
|
||||
gimp_draw_tool_draw_arc (draw_tool,
|
||||
FALSE,
|
||||
ix, iy,
|
||||
iw, ih,
|
||||
rect_sel->x, rect_sel->y,
|
||||
rect_sel->w, rect_sel->h,
|
||||
0, 23040,
|
||||
FALSE);
|
||||
}
|
||||
|
@@ -267,8 +267,13 @@ gimp_magnify_tool_button_release (GimpTool *tool,
|
||||
new_scale = shell->scale * scale;
|
||||
}
|
||||
|
||||
offset_x = (new_scale * (x1 + x2) / 2) - (win_width / 2);
|
||||
offset_y = (new_scale * (y1 + y2) / 2) - (win_height / 2);
|
||||
offset_x = (new_scale * ((x1 + x2) / 2)
|
||||
* SCREEN_XRES (shell) / gdisp->gimage->xresolution
|
||||
- (win_width / 2));
|
||||
|
||||
offset_y = (new_scale * ((y1 + y2) / 2)
|
||||
* SCREEN_YRES (shell) / gdisp->gimage->yresolution
|
||||
- (win_height / 2));
|
||||
|
||||
gimp_display_shell_scale_by_values (shell,
|
||||
new_scale,
|
||||
|
@@ -227,11 +227,10 @@ pressure_options_gui (GimpPressureOptions *pressure,
|
||||
}
|
||||
|
||||
/* the opacity toggle */
|
||||
if (tool_type == GIMP_TYPE_CLONE_TOOL ||
|
||||
tool_type == GIMP_TYPE_DODGE_BURN_TOOL ||
|
||||
tool_type == GIMP_TYPE_ERASER_TOOL ||
|
||||
tool_type == GIMP_TYPE_PAINTBRUSH_TOOL ||
|
||||
tool_type == GIMP_TYPE_PENCIL_TOOL)
|
||||
if (g_type_is_a (tool_type, GIMP_TYPE_PAINTBRUSH_TOOL) ||
|
||||
tool_type == GIMP_TYPE_CLONE_TOOL ||
|
||||
tool_type == GIMP_TYPE_DODGE_BURN_TOOL ||
|
||||
tool_type == GIMP_TYPE_ERASER_TOOL)
|
||||
{
|
||||
button = gimp_prop_check_button_new (config, "pressure-opacity",
|
||||
_("Opacity"));
|
||||
@@ -299,7 +298,7 @@ fade_options_gui (GimpFadeOptions *fade,
|
||||
GtkWidget *table;
|
||||
GtkWidget *spinbutton;
|
||||
GtkWidget *button;
|
||||
GtkWidget *unitmenu;
|
||||
GtkWidget *menu;
|
||||
|
||||
if (g_type_is_a (tool_type, GIMP_TYPE_PAINTBRUSH_TOOL) ||
|
||||
tool_type == GIMP_TYPE_CLONE_TOOL ||
|
||||
@@ -335,12 +334,13 @@ fade_options_gui (GimpFadeOptions *fade,
|
||||
spinbutton, 1, FALSE);
|
||||
|
||||
/* the fade-out unitmenu */
|
||||
unitmenu = gimp_prop_unit_menu_new (config, "fade-unit", "%a");
|
||||
gtk_table_attach (GTK_TABLE (table), unitmenu, 2, 3, 0, 1,
|
||||
menu = gimp_prop_unit_menu_new (config, "fade-unit", "%a");
|
||||
gtk_table_attach (GTK_TABLE (table), menu, 2, 3, 0, 1,
|
||||
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
|
||||
gtk_widget_show (unitmenu);
|
||||
gtk_widget_show (menu);
|
||||
|
||||
g_object_set_data (G_OBJECT (unitmenu), "set_digits", spinbutton);
|
||||
g_object_set_data (G_OBJECT (menu), "set_digits", spinbutton);
|
||||
gimp_unit_menu_set_pixel_digits (GIMP_UNIT_MENU (menu), 0);
|
||||
}
|
||||
|
||||
return frame;
|
||||
@@ -357,7 +357,7 @@ gradient_options_gui (GimpGradientOptions *gradient,
|
||||
GtkWidget *table;
|
||||
GtkWidget *spinbutton;
|
||||
GtkWidget *button;
|
||||
GtkWidget *unitmenu;
|
||||
GtkWidget *menu;
|
||||
GtkWidget *combo;
|
||||
|
||||
if (g_type_is_a (tool_type, GIMP_TYPE_PAINTBRUSH_TOOL))
|
||||
@@ -405,12 +405,13 @@ gradient_options_gui (GimpGradientOptions *gradient,
|
||||
spinbutton, 1, FALSE);
|
||||
|
||||
/* the gradient unitmenu */
|
||||
unitmenu = gimp_prop_unit_menu_new (config, "gradient-unit", "%a");
|
||||
gtk_table_attach (GTK_TABLE (table), unitmenu, 2, 3, 1, 2,
|
||||
menu = gimp_prop_unit_menu_new (config, "gradient-unit", "%a");
|
||||
gtk_table_attach (GTK_TABLE (table), menu, 2, 3, 1, 2,
|
||||
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
|
||||
gtk_widget_show (unitmenu);
|
||||
gtk_widget_show (menu);
|
||||
|
||||
g_object_set_data (G_OBJECT (unitmenu), "set_digits", spinbutton);
|
||||
g_object_set_data (G_OBJECT (menu), "set_digits", spinbutton);
|
||||
gimp_unit_menu_set_pixel_digits (GIMP_UNIT_MENU (menu), 0);
|
||||
|
||||
/* the repeat type */
|
||||
combo = gimp_prop_enum_combo_box_new (config, "gradient-repeat", 0, 0);
|
||||
|
@@ -157,8 +157,9 @@ gimp_rect_select_tool_init (GimpRectSelectTool *rect_select)
|
||||
gimp_tool_control_set_tool_cursor (tool->control,
|
||||
GIMP_TOOL_CURSOR_RECT_SELECT);
|
||||
|
||||
rect_select->x = rect_select->y = 0.0;
|
||||
rect_select->w = rect_select->h = 0.0;
|
||||
rect_select->sx = rect_select->sy = 0;
|
||||
rect_select->x = rect_select->y = 0;
|
||||
rect_select->w = rect_select->h = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -176,14 +177,15 @@ gimp_rect_select_tool_button_press (GimpTool *tool,
|
||||
|
||||
options = GIMP_SELECTION_OPTIONS (tool->tool_info->tool_options);
|
||||
|
||||
rect_sel->x = coords->x;
|
||||
rect_sel->y = coords->y;
|
||||
rect_sel->w = 0.0;
|
||||
rect_sel->h = 0.0;
|
||||
rect_sel->sx = RINT(coords->x);
|
||||
rect_sel->sy = RINT(coords->y);
|
||||
rect_sel->x = 0;
|
||||
rect_sel->y = 0;
|
||||
rect_sel->w = 0;
|
||||
rect_sel->h = 0;
|
||||
rect_sel->lx = RINT(coords->x);
|
||||
rect_sel->ly = RINT(coords->y);
|
||||
rect_sel->center = FALSE;
|
||||
rect_sel->moved = FALSE;
|
||||
|
||||
rect_sel->last_coords = *coords;
|
||||
|
||||
rect_sel->fixed_mode = options->fixed_mode;
|
||||
rect_sel->fixed_width = options->fixed_width;
|
||||
@@ -247,10 +249,6 @@ gimp_rect_select_tool_button_release (GimpTool *tool,
|
||||
GimpDisplay *gdisp)
|
||||
{
|
||||
GimpRectSelectTool *rect_sel = GIMP_RECT_SELECT_TOOL (tool);
|
||||
gdouble x, y;
|
||||
gdouble w, h;
|
||||
gint ix, iy;
|
||||
gint iw, ih;
|
||||
|
||||
gimp_tool_pop_status (tool);
|
||||
|
||||
@@ -260,19 +258,8 @@ gimp_rect_select_tool_button_release (GimpTool *tool,
|
||||
|
||||
/* First take care of the case where the user "cancels" the action */
|
||||
if (! (state & GDK_BUTTON3_MASK))
|
||||
{
|
||||
x = (rect_sel->w < 0) ? rect_sel->x + rect_sel->w : rect_sel->x;
|
||||
y = (rect_sel->h < 0) ? rect_sel->y + rect_sel->h : rect_sel->y;
|
||||
|
||||
w = ABS (rect_sel->w);
|
||||
h = ABS (rect_sel->h);
|
||||
|
||||
gimp_rect_select_tool_coords_to_integer (gdisp,
|
||||
x, y, w, h,
|
||||
&ix, &iy, &iw, &ih);
|
||||
|
||||
if ((!rect_sel->moved || !iw || !ih)
|
||||
&& rect_sel->fixed_mode == GIMP_RECT_SELECT_MODE_FREE)
|
||||
{
|
||||
if (rect_sel->w == 0 || rect_sel->h == 0)
|
||||
{
|
||||
/* If there is a floating selection, anchor it */
|
||||
if (gimp_image_floating_sel (gdisp->gimage))
|
||||
@@ -287,8 +274,9 @@ gimp_rect_select_tool_button_release (GimpTool *tool,
|
||||
}
|
||||
|
||||
gimp_rect_select_tool_rect_select (rect_sel,
|
||||
ix, iy, iw, ih);
|
||||
|
||||
rect_sel->x, rect_sel->y,
|
||||
rect_sel->w, rect_sel->h);
|
||||
|
||||
/* show selection on all views */
|
||||
gimp_image_flush (gdisp->gimage);
|
||||
}
|
||||
@@ -303,15 +291,8 @@ gimp_rect_select_tool_motion (GimpTool *tool,
|
||||
{
|
||||
GimpRectSelectTool *rect_sel = GIMP_RECT_SELECT_TOOL (tool);
|
||||
GimpSelectionTool *sel_tool = GIMP_SELECTION_TOOL (tool);
|
||||
gdouble ox, oy;
|
||||
gdouble w, h;
|
||||
gdouble tw, th;
|
||||
gint mx, my;
|
||||
gdouble ratio;
|
||||
gint ix, iy;
|
||||
gint iw, ih;
|
||||
|
||||
if (coords->x != rect_sel->x || coords->y != rect_sel->y)
|
||||
rect_sel->moved = TRUE;
|
||||
|
||||
if (sel_tool->op == SELECTION_ANCHOR)
|
||||
{
|
||||
@@ -322,73 +303,49 @@ gimp_rect_select_tool_motion (GimpTool *tool,
|
||||
|
||||
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
|
||||
|
||||
|
||||
if (state & GDK_MOD1_MASK)
|
||||
{
|
||||
/* Just move the selection rectangle around */
|
||||
|
||||
mx = RINT(coords->x) - rect_sel->lx;
|
||||
my = RINT(coords->y) - rect_sel->ly;
|
||||
|
||||
rect_sel->x += coords->x - rect_sel->last_coords.x;
|
||||
rect_sel->y += coords->y - rect_sel->last_coords.y;
|
||||
rect_sel->sx += mx;
|
||||
rect_sel->sy += my;
|
||||
rect_sel->x += mx;
|
||||
rect_sel->y += my;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Change the selection rectangle's size */
|
||||
/* Change the selection rectangle's size, first calculate absolute
|
||||
* width and height, then take care of quadrants.
|
||||
*/
|
||||
|
||||
/* Calculate starting point */
|
||||
|
||||
if (rect_sel->center)
|
||||
if (rect_sel->fixed_mode == GIMP_RECT_SELECT_MODE_FIXED_SIZE)
|
||||
{
|
||||
ox = rect_sel->x + rect_sel->w / 2.0;
|
||||
oy = rect_sel->y + rect_sel->h / 2.0;
|
||||
rect_sel->w = RINT(rect_sel->fixed_width);
|
||||
rect_sel->h = RINT(rect_sel->fixed_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
ox = rect_sel->x;
|
||||
oy = rect_sel->y;
|
||||
rect_sel->w = abs(RINT(coords->x) - rect_sel->sx);
|
||||
rect_sel->h = abs(RINT(coords->y) - rect_sel->sy);
|
||||
}
|
||||
|
||||
switch (rect_sel->fixed_mode)
|
||||
|
||||
if (rect_sel->fixed_mode == GIMP_RECT_SELECT_MODE_FIXED_RATIO)
|
||||
{
|
||||
case GIMP_RECT_SELECT_MODE_FIXED_SIZE:
|
||||
w = ((coords->x - ox) > 0 ?
|
||||
rect_sel->fixed_width : -rect_sel->fixed_width);
|
||||
|
||||
h = ((coords->y - oy) > 0 ?
|
||||
rect_sel->fixed_height : -rect_sel->fixed_height);
|
||||
break;
|
||||
|
||||
case GIMP_RECT_SELECT_MODE_FIXED_RATIO:
|
||||
ratio = ((gdouble) rect_sel->fixed_height /
|
||||
(gdouble) rect_sel->fixed_width);
|
||||
tw = (coords->x - ox);
|
||||
th = (coords->y - oy);
|
||||
|
||||
/* This is probably an inefficient way to do it, but it gives
|
||||
* nicer, more predictable results than the original algorithm
|
||||
*/
|
||||
if ((abs (th) < (ratio * abs (tw))) &&
|
||||
(abs (tw) > (abs (th) / ratio)))
|
||||
ratio = rect_sel->fixed_height / rect_sel->fixed_width;
|
||||
if ( ( (gdouble) rect_sel->h) / ( (gdouble) rect_sel->w ) > ratio)
|
||||
{
|
||||
w = tw;
|
||||
h = (tw * ratio);
|
||||
/* h should have the sign of th */
|
||||
if ((th < 0 && h > 0) || (th > 0 && h < 0))
|
||||
h = -h;
|
||||
rect_sel->w = RINT(rect_sel->h / ratio);
|
||||
}
|
||||
else
|
||||
{
|
||||
h = th;
|
||||
w = (th / ratio);
|
||||
/* w should have the sign of tw */
|
||||
if ((tw < 0 && w > 0) || (tw > 0 && w < 0))
|
||||
w = -w;
|
||||
rect_sel->h = RINT(rect_sel->w * ratio);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
w = (coords->x - ox);
|
||||
h = (coords->y - oy);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* If the shift key is down, then make the rectangle square (or
|
||||
* ellipse circular)
|
||||
@@ -396,79 +353,68 @@ gimp_rect_select_tool_motion (GimpTool *tool,
|
||||
if ((state & GDK_SHIFT_MASK) &&
|
||||
rect_sel->fixed_mode == GIMP_RECT_SELECT_MODE_FREE)
|
||||
{
|
||||
gint s = MAX (abs (w), abs (h));
|
||||
|
||||
if (w < 0)
|
||||
w = -s;
|
||||
if (rect_sel->w > rect_sel->h)
|
||||
{
|
||||
rect_sel->h = rect_sel->w;
|
||||
}
|
||||
else
|
||||
w = s;
|
||||
|
||||
if (h < 0)
|
||||
h = -s;
|
||||
else
|
||||
h = s;
|
||||
{
|
||||
rect_sel->w = rect_sel->h;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the control key is down, create the selection from the center out
|
||||
*/
|
||||
if (state & GDK_CONTROL_MASK)
|
||||
{
|
||||
rect_sel->center = TRUE;
|
||||
|
||||
switch (rect_sel->fixed_mode)
|
||||
/* If the control key is down, create the selection from the center out */
|
||||
if (rect_sel->fixed_mode == GIMP_RECT_SELECT_MODE_FIXED_SIZE)
|
||||
{
|
||||
case GIMP_RECT_SELECT_MODE_FIXED_SIZE:
|
||||
rect_sel->x = ox - w / 2.0;
|
||||
rect_sel->y = oy - h / 2.0;
|
||||
rect_sel->w = w;
|
||||
rect_sel->h = h;
|
||||
break;
|
||||
|
||||
case GIMP_RECT_SELECT_MODE_FIXED_RATIO:
|
||||
rect_sel->x = ox - w;
|
||||
rect_sel->y = oy - h;
|
||||
rect_sel->w = w * 2.0;
|
||||
rect_sel->h = h * 2.0;
|
||||
break;
|
||||
|
||||
default:
|
||||
w = abs (w);
|
||||
h = abs (h);
|
||||
|
||||
rect_sel->x = ox - w;
|
||||
rect_sel->y = oy - h;
|
||||
rect_sel->w = 2.0 * w;
|
||||
rect_sel->h = 2.0 * h;
|
||||
break;
|
||||
/* Fixed size selection is simply centered over start point */
|
||||
rect_sel->x = RINT(rect_sel->sx - rect_sel->w / 2.0);
|
||||
rect_sel->y = RINT(rect_sel->sy - rect_sel->h / 2.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Non-fixed size is mirrored over starting point */
|
||||
rect_sel->x = rect_sel->sx - rect_sel->w;
|
||||
rect_sel->y = rect_sel->sy - rect_sel->h;
|
||||
rect_sel->w = rect_sel->w * 2;
|
||||
rect_sel->h = rect_sel->h * 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rect_sel->center = FALSE;
|
||||
|
||||
rect_sel->x = ox;
|
||||
rect_sel->y = oy;
|
||||
rect_sel->w = w;
|
||||
rect_sel->h = h;
|
||||
/* Make (rect->x, rect->y) upper left hand point of selection */
|
||||
if (coords->x > rect_sel->sx)
|
||||
{
|
||||
rect_sel->x = rect_sel->sx;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect_sel->x = rect_sel->sx - rect_sel->w;
|
||||
}
|
||||
if (coords->y > rect_sel->sy)
|
||||
{
|
||||
rect_sel->y = rect_sel->sy;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect_sel->y = rect_sel->sy - rect_sel->h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rect_sel->last_coords = *coords;
|
||||
|
||||
rect_sel->lx = RINT(coords->x);
|
||||
rect_sel->ly = RINT(coords->y);
|
||||
|
||||
gimp_rect_select_tool_update_options (rect_sel, gdisp);
|
||||
|
||||
gimp_tool_pop_status (tool);
|
||||
|
||||
gimp_rect_select_tool_coords_to_integer (gdisp,
|
||||
rect_sel->x, rect_sel->y,
|
||||
rect_sel->w, rect_sel->h,
|
||||
&ix, &iy,
|
||||
&iw, &ih);
|
||||
gimp_tool_push_status_coords (tool,
|
||||
_("Selection: "),
|
||||
iw,
|
||||
rect_sel->w,
|
||||
" x ",
|
||||
ih);
|
||||
rect_sel->h);
|
||||
|
||||
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
|
||||
}
|
||||
@@ -477,17 +423,11 @@ static void
|
||||
gimp_rect_select_tool_draw (GimpDrawTool *draw_tool)
|
||||
{
|
||||
GimpRectSelectTool *rect_sel = GIMP_RECT_SELECT_TOOL (draw_tool);
|
||||
gint ix, iy;
|
||||
gint iw, ih;
|
||||
|
||||
gimp_rect_select_tool_coords_to_integer (draw_tool->gdisp,
|
||||
rect_sel->x, rect_sel->y,
|
||||
rect_sel->w, rect_sel->h,
|
||||
&ix, &iy,
|
||||
&iw, &ih);
|
||||
gimp_draw_tool_draw_rectangle (draw_tool,
|
||||
FALSE,
|
||||
ix, iy, iw, ih,
|
||||
rect_sel->x, rect_sel->y,
|
||||
rect_sel->w, rect_sel->h,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
@@ -598,17 +538,17 @@ gimp_rect_select_tool_update_options (GimpRectSelectTool *rect_sel,
|
||||
|
||||
if (shell->unit == GIMP_UNIT_PIXEL)
|
||||
{
|
||||
width = fabs (rect_sel->w);
|
||||
height = fabs (rect_sel->h);
|
||||
width = rect_sel->w;
|
||||
height = rect_sel->h;
|
||||
}
|
||||
else
|
||||
{
|
||||
GimpImage *image = gdisp->gimage;
|
||||
|
||||
width = (fabs (rect_sel->w) *
|
||||
width = (rect_sel->w *
|
||||
_gimp_unit_get_factor (image->gimp,
|
||||
shell->unit) / image->xresolution);
|
||||
height = (fabs (rect_sel->h) *
|
||||
height = (rect_sel->h *
|
||||
_gimp_unit_get_factor (image->gimp,
|
||||
shell->unit) / image->yresolution);
|
||||
}
|
||||
@@ -619,25 +559,3 @@ gimp_rect_select_tool_update_options (GimpRectSelectTool *rect_sel,
|
||||
"fixed-unit", shell->unit,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_rect_select_tool_coords_to_integer (GimpDisplay *gdisp,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gdouble w,
|
||||
gdouble h,
|
||||
gint *ix,
|
||||
gint *iy,
|
||||
gint *iw,
|
||||
gint *ih)
|
||||
{
|
||||
x = MIN (x, x + w);
|
||||
y = MIN (y, y + h);
|
||||
w = ABS (w);
|
||||
h = ABS (h);
|
||||
|
||||
*ix = RINT (x);
|
||||
*iy = RINT (y);
|
||||
*iw = RINT (w + (x - *ix));
|
||||
*ih = RINT (h + (y - *iy));
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user