devel-docs: Move advanced concepts to gimp-web-devel
See: Infrastructure/gimp-web-devel#9 Also, drop interpreters.txt since we have an example file.
This commit is contained in:
parent
d997fd39a6
commit
21044e61f2
8 changed files with 0 additions and 1011 deletions
|
|
@ -75,7 +75,6 @@ When writing code, any core developer is expected to follow:
|
|||
|
||||
- GIMP's [coding style](https://developer.gimp.org/core/coding_style/);
|
||||
- the [directory structure](#directory-structure-of-gimp-source-tree)
|
||||
- our [header file inclusion policy](includes.txt)
|
||||
|
||||
[GIMP's developer site](https://developer.gimp.org/) contain various valuable resources.
|
||||
|
||||
|
|
@ -181,69 +180,3 @@ You should also check out [gimp-module-dependencies.svg](gimp-module-dependencie
|
|||
**TODO**: this SVG file is interesting yet very outdated. It should not
|
||||
be considered as some kind dependency rule and should be updated.
|
||||
|
||||
### Advanced concepts
|
||||
|
||||
#### XCF
|
||||
|
||||
The `XCF` format is the core image format of GIMP, which mirrors
|
||||
features made available in GIMP. More than an image format, you may
|
||||
consider it as a work or project format, as it is not made for finale
|
||||
presentation of an artwork but for the work-in-progress process.
|
||||
|
||||
Developers are welcome to read the [specifications of XCF](https://developer.gimp.org/core/standards/xcf/).
|
||||
|
||||
#### Locks
|
||||
|
||||
Items in an image can be locked in various ways to prevent different
|
||||
types of edits.
|
||||
|
||||
This is further explained in [the specifications of locks](https://developer.gimp.org/core/specifications/locks/).
|
||||
|
||||
#### UI Framework
|
||||
|
||||
GIMP has an evolved GUI framework, with a toolbox, dockables, menus…
|
||||
|
||||
This document describing how the GIMP UI framework functions and how it
|
||||
is [implemented](ui-framework.txt) might be of interest.
|
||||
|
||||
#### Contexts
|
||||
|
||||
GIMP uses a lot a concept of "contexts". We recommend reading more about
|
||||
[how GimpContexts are used in GIMP](contexts.txt).
|
||||
|
||||
#### Undo
|
||||
|
||||
GIMP undo system can be challenging at times. This [quick overview of
|
||||
the undo system](undo.txt) can be of interest as a first introduction.
|
||||
|
||||
#### Parasites
|
||||
|
||||
GIMP has a concept of "parasite" data which basically correspond to
|
||||
persistent or semi-persistent data which can be attached to images or
|
||||
items (layers, channels, paths) within an image. These parasites are
|
||||
saved in the XCF format.
|
||||
|
||||
Parasites can also be attached globally to the GIMP session.
|
||||
|
||||
Parasite contents is format-free and you can use any parasite name,
|
||||
nevertheless GIMP itself uses parasite so you should read the
|
||||
[descriptions of known parasites](parasites.txt).
|
||||
|
||||
#### Metadata
|
||||
|
||||
GIMP supports Exif, IPTC and XMP metadata as well as various image
|
||||
format-specific metadata. The topic is quite huge and complex, if not
|
||||
overwhelming.
|
||||
|
||||
This [old document](https://developer.gimp.org/core/specifications/exif_handling/)
|
||||
might be of interest (or maybe not, it has not been recently reviewed and might
|
||||
be widely outdated; in any case, it is not a complete document at all as we
|
||||
definitely do a lot more nowadays). **TODO**: review this document and delete or
|
||||
update it depending of whether it still makes sense.
|
||||
|
||||
#### Tagging
|
||||
|
||||
Various data in GIMP can be tagged across sessions.
|
||||
|
||||
This document on [how resource tagging in GIMP works](tagging.txt) may
|
||||
be of interest.
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
contexts.txt
|
||||
============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This file describes how GimpContexts are used in GIMP.
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
One important context is the so called "user context",
|
||||
gimp_get_user_context(). This context keeps track on what image the
|
||||
user currently has active, for example. Dock windows have their own
|
||||
context which does not necessarily mirror the user context. A dock
|
||||
window can be set to show information for a specific image. Plug-ins
|
||||
also have their own context.
|
||||
|
||||
|
||||
Communication between contexts
|
||||
------------------------------
|
||||
|
||||
So how do the various contexts synchronize and propagate changes?
|
||||
This is most easily explained by a sequence diagram. Let's say there
|
||||
are two image windows with different images opened in GIMP. Call them
|
||||
A and B. Let's say A is currently active. When the user activates B,
|
||||
this is the sequence of events from the focus event to the layers
|
||||
dockable have been updated with the new image. To understand the
|
||||
diagram, you have to know that the dock window has connected signal
|
||||
handlers to image changes in the user context (through a dialog
|
||||
factory getter), and the layer dockable have connected a signal
|
||||
handler to image changes in the dock window context. The sequence of
|
||||
events is as follows:
|
||||
|
||||
GimpContext GimpContext GimpItemTreeView,
|
||||
GimpDisplayShell user GimpDockWindow dock window GimpLayerTreeView
|
||||
|
||||
| | | | |
|
||||
focus event | | | |
|
||||
------->| | | | |
|
||||
| gimp_context_set_display() | | |
|
||||
|--------------->|----------+ | | |
|
||||
| | | | | |
|
||||
| gimp_context_set_image() | | | |
|
||||
| |<---------+ | | |
|
||||
| | | | |
|
||||
| | "image-changed" | |
|
||||
| |------------->| | |
|
||||
| | | gimp_context_set_image() |
|
||||
| | |------------->| |
|
||||
| | | | "image-changed" /
|
||||
| | | | set_image()
|
||||
| | | |------------>|
|
||||
| | | | |
|
||||
|
||||
In single-window mode, the dockables listen directly to the user
|
||||
context. When switching between single-window and multi-window modes,
|
||||
the dockables are updated with their new context, just as when moving
|
||||
a dockable between different dock windows and thus also different
|
||||
contexts. The sequence diagram for single-window mode is:
|
||||
|
||||
GimpContext GimpItemTreeView
|
||||
GimpDisplayShell user GimpLayerTreeView
|
||||
|
||||
| | |
|
||||
focus event | |
|
||||
------->| | |
|
||||
| gimp_context_set_display() |
|
||||
|--------------->|----------+ |
|
||||
| | | |
|
||||
| gimp_context_set_image() | |
|
||||
| |<---------+ |
|
||||
| | |
|
||||
| | "image-changed" /
|
||||
| | set_image()
|
||||
| |------------->|
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
|
||||
|
||||
Parent/child relationships
|
||||
--------------------------
|
||||
|
||||
TODO
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
includes.txt
|
||||
============
|
||||
|
||||
The include policy for the files in app/ is as follows:
|
||||
|
||||
Each subdirectory has a <module>-types.h file which defines the type
|
||||
space known to this module. All .c files in the directory include this
|
||||
(and only this) <module>-types.h file. <foo>-types.h files from other
|
||||
modules are included from the <module>-types.h file only. This way
|
||||
<module>-types.h becomes the only place where the namespace known to a
|
||||
module is defined.
|
||||
|
||||
|
||||
***** .h files *****
|
||||
|
||||
No .h file includes anything, with two exceptions:
|
||||
|
||||
- objects include their immediate parent class
|
||||
- if the header uses stuff like time_t (or off_t), it includes
|
||||
<time.h> (or <sys/types.h>). This only applies to system stuff!
|
||||
|
||||
|
||||
***** .c files *****
|
||||
|
||||
The include order of all .c files of a module is as follows:
|
||||
|
||||
/* example of a .c file from app/core */
|
||||
|
||||
#include "config.h" /* always and first */
|
||||
|
||||
#include <glib.h> /* *only* needed if the file needs stuff */
|
||||
/* like G_OS_WIN32 for conditional inclusion */
|
||||
/* of system headers */
|
||||
|
||||
#include <system headers> /* like <stdio.h> */
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "libgimpfoo/gimpfoo.h" /* as needed, e.g. "libgimpbase/gimpbase.h" */
|
||||
#include "libgimpbar/gimpbar.h"
|
||||
|
||||
#include "core-types.h" /* and _no_ other foo-types.h file */
|
||||
|
||||
#include "base/foo.h" /* files from modules below this one */
|
||||
#include "base/bar.h"
|
||||
|
||||
#include "gimp.h" /* files from this module */
|
||||
#include "gimpimage.h"
|
||||
#include "gimpwhatever.h"
|
||||
|
||||
#include "gimp-intl.h" /* if needed, *must* be the last include */
|
||||
|
|
@ -1,210 +0,0 @@
|
|||
# Interpreters for GIMP plugins
|
||||
|
||||
|
||||
|
||||
## About this document
|
||||
|
||||
This describes how GIMP invokes interpreters for GIMP plugin files.
|
||||
|
||||
This doesn't discuss the architecture of GIMP's interpreters,
|
||||
or how to write an interpreted plugin.
|
||||
|
||||
The audience is mainly GIMP developers.
|
||||
This may also interest users who want to use different interpreters.
|
||||
|
||||
|
||||
## Brief summary
|
||||
|
||||
On Linux (except for Lua) and MacOS, a shebang in a GIMP plugin
|
||||
text file is enough to indicate what interpreter to start.
|
||||
On Windows (and Linux for Lua), you also need an .interp file installed with GIMP.
|
||||
|
||||
It can get complicated;
|
||||
there are many combinations of environment variables, shebangs, file suffixes, and .interp files that can work.
|
||||
|
||||
*To insure a GIMP interpreted plugin works across platforms,
|
||||
it should have a shebang.*
|
||||
|
||||
*Except that ScriptFu plugin files installed to /scripts do not need a shebang
|
||||
since the ScriptFu extension reads them.*
|
||||
|
||||
## Partial history of interpreters in GIMP
|
||||
|
||||
Rarely are interpreters added to GIMP.
|
||||
GIMP 2 offers Perl, Scheme, and Python2 interpreters.
|
||||
GIMP 3 offers Python3, lua, javascript, and the gimp-script-fu-interpreter interpreters.
|
||||
|
||||
|
||||
## Background
|
||||
|
||||
An interpreter usually reads a text file.
|
||||
A user often launches an interpreter and passes a text file.
|
||||
But users can also double-click on a text file to launch the corresponding interpreter.
|
||||
|
||||
Similarly, GIMP launches an interpreter on GIMP plugin text files.
|
||||
GIMP must figure out the "corresponding" interpreter.
|
||||
|
||||
The general mechanism for launching interpreters from their text files is built into the operating system.
|
||||
On Linux and MacOS, the mechanism is called a shebang or sh-bang.
|
||||
On Windows, the mechanism "associates" file extensions with programs.
|
||||
|
||||
GIMP uses similar mechanisms to launch interpreters.
|
||||
See the code in /app/plug-ins/gimpinterpreterdb.c .
|
||||
*The exception is the ScriptFu extension.
|
||||
GIMP starts it when GIMP starts and it reads its ".scm" plugin files from the /scripts directory without benefit
|
||||
of the shebang mechanism.*
|
||||
|
||||
GIMP uses the mechanism when it queries plugin files at startup.
|
||||
Subsequently, GIMP knows the interpreter to launch,
|
||||
for example when a user clicks on a menu item implemented by an interpreter.
|
||||
A user should not click on a GIMP plugin file in a file browser;
|
||||
only one of the GIMP apps should launch interpreted GIMP plugin files.
|
||||
|
||||
|
||||
## Platform differences
|
||||
|
||||
On Linux (except for Lua) and MacOS, you simply need a shebang in a plugin text file.
|
||||
|
||||
On Windows (and Linux, at least for Lua), you must also define an .interp file.
|
||||
The .interp files are part of GIMP's installation on Windows (and Linux for Lua)
|
||||
(in both installer and Microsoft Store versions).
|
||||
The .interp files are built when the Windows installer is built.
|
||||
See the source file: /build/windows/installer/base_gimp3264.iss .
|
||||
|
||||
A user can optionally create .interp files on Linux and MacOS.
|
||||
But they are not usually part of a Linux installation.
|
||||
Sophisticated users can edit .interp files to change which interpreters GIMP launches.
|
||||
|
||||
|
||||
## shebangs
|
||||
|
||||
A shebang is text in the first line of a text file to be interpreted.
|
||||
A shebang starts with "#!",
|
||||
followed by the name or path of an interpreter,
|
||||
or followed by "/usr/bin/env", a space, and the name or path of an interpreter.
|
||||
|
||||
!!! Shebangs for GIMP plugins always use UNIX notation, i.e. forward slashes in path strings.
|
||||
Even on Windows, the shebangs are in UNIX notation.
|
||||
|
||||
Recommended examples for GIMP 3 (see repo directory /extensions/goat-exercises):
|
||||
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env lua
|
||||
#!/usr/bin/env gjs
|
||||
#!/usr/bin/env gimp-script-fu-interpreter-3.0
|
||||
|
||||
Other examples:
|
||||
|
||||
#!python
|
||||
#!/usr/bin/python
|
||||
#!/usr/bin/env python
|
||||
|
||||
Whether the other examples actually work depends on:
|
||||
|
||||
- the platform
|
||||
- the user's environment, namely search PATH's
|
||||
- any .interp files
|
||||
|
||||
|
||||
## .interp files
|
||||
|
||||
Again, .interp files are necessary on Windows (and Linux, at least for Lua).
|
||||
They tell GIMP which executable interpreter to launch for a GIMP plugin text file.
|
||||
|
||||
You usually have one .interp file for each interpreter.
|
||||
For example:
|
||||
- python.interp
|
||||
- lua.interp
|
||||
- gimp-script-fu-interpreter.interp
|
||||
|
||||
The repo file /data/interpreters/default.interp is a non-functioning template
|
||||
for a <foo>.interp file.
|
||||
|
||||
.interp files are installed on Windows to, for example:
|
||||
|
||||
C:\Users\foo\AppData\Programs\GIMP 3.0\lib\gimp\3.0\interpreters
|
||||
|
||||
|
||||
interp files have three kinds of lines:
|
||||
- "program" in the form lhs=rhs
|
||||
- "extension" in the "binfmt" format
|
||||
- "magic" in the "binfmt" format
|
||||
|
||||
### "program" lines in an .interp file
|
||||
|
||||
These lines associate a shebang with a path to an executable.
|
||||
|
||||
These are in the form: "lhs=rhs"
|
||||
where lhs/rhs denotes "left hand side" and "right hand side."
|
||||
|
||||
The lhs matches the full text of a shebang after the "#!"
|
||||
For example, the lhs can be "/usr/bin/env python", having a space.
|
||||
Since a shebang is always in UNIX notation, any slashes are forward.
|
||||
|
||||
The rhs specifies a path to an interpreter.
|
||||
The rhs on the Windows platform is in Windows notation, using back slashes.
|
||||
For example, the rhs can be "C:\Users\foo\AppData\Programs\GIMP 3.0\bin\python"
|
||||
|
||||
|
||||
### "extension" lines in an .interp file
|
||||
|
||||
These lines associate a three-letter (sic) file extension (suffix) with a path to an executable.
|
||||
|
||||
These lines are in binfmt format.
|
||||
See https://en.wikipedia.org/wiki/Binfmt_misc.
|
||||
|
||||
Informally the format is: ":name:type:offset:magic: mask:interpreter:flags"
|
||||
!!! Note the field delimiter is usually ":" but can be another character.
|
||||
GIMP parses the binfmt using the first character as the delimiter.
|
||||
The first field is a name or identifier and has little significance.
|
||||
The second field is an "E".
|
||||
The third, fifth, and seventh fields are usually empty.
|
||||
The fourth field is an up-to-three letter suffix.
|
||||
The sixth field "interpreter" is a name or path to an executable interpreter.
|
||||
|
||||
If the sixth field is a Windows path that has a ":"
|
||||
then the fields must be delimited with another character, say a ",".
|
||||
|
||||
Examples:
|
||||
|
||||
:python:E::py::python3:
|
||||
:luajit:E::lua::luajit:
|
||||
,python,E,,py,,C:\Users\foo\AppData\GIMP 3.0\bin\python3,
|
||||
|
||||
Note the examples are not necessarily working examples.
|
||||
They might not work if the name or path is not found,
|
||||
for example if luajit was not installed to the Windows system directory of executables.
|
||||
|
||||
Note one example shows a path in Windows notation,
|
||||
having a ":", back slashes, and a space in the path.
|
||||
|
||||
|
||||
### "magic" lines in an .interp file
|
||||
|
||||
These lines associate "magic" bytes (inside a binary file) with a path to an executable.
|
||||
|
||||
These lines are in binfmt format.
|
||||
The second field is an "M".
|
||||
|
||||
We won't discuss these further, since they are little used.
|
||||
Binary files on Windows might not have "magic" bytes.
|
||||
Usually interpreters read text files, and rarely binary files.
|
||||
|
||||
|
||||
## Building .interp files for windows
|
||||
|
||||
If a GIMP developer adds an interpreter to the GIMP package,
|
||||
they must modify GIMP's build for Windows
|
||||
to ensure proper .interp files are installed.
|
||||
|
||||
See the repo file: /build/windows/installer/base_gimp3264.iss .
|
||||
|
||||
For the convenience of users, we usually install an .interp file having many lines.
|
||||
Only one "program" line is needed if users only install canonical plugin text files
|
||||
having a recommended shebang
|
||||
using the actual filename of the target interpreter.
|
||||
But since users may install non-canonical plugin text files by copying files,
|
||||
for convenience we have more lines in the .interp file.
|
||||
An extra "extension" line allows plugin text files without any shebang but a proper extension.
|
||||
An extra "program" line allows plugin text files
|
||||
having shebangs with alternate names for an interpreter.
|
||||
|
|
@ -1,316 +0,0 @@
|
|||
|
||||
PARASITE REGISTRY
|
||||
=================
|
||||
|
||||
This document describes parasites in GIMP.
|
||||
|
||||
|
||||
Table of contents
|
||||
-----------------
|
||||
Parasite registry
|
||||
Table of contents
|
||||
Audience
|
||||
|
||||
1. Namespace
|
||||
|
||||
2. Known prefixes
|
||||
|
||||
3. Known global parasites
|
||||
|
||||
4. Known image parasites
|
||||
|
||||
5. Known layer/drawable parasites
|
||||
|
||||
6. Parasite format
|
||||
|
||||
|
||||
Audience
|
||||
--------
|
||||
This document is designed for the convenience of GIMP developers.
|
||||
It does not need to concern users.
|
||||
|
||||
>>>> If your plug-in or script writes parasites, please
|
||||
>>>> amend this file in the Git repository or submit patches to
|
||||
>>>> gimp-developer-list@gnome.org
|
||||
|
||||
|
||||
1. NAMESPACE
|
||||
============
|
||||
|
||||
Plug-in-specific data should be prefixed by the plug-in function name and
|
||||
a slash, i.e. private data of plug_in_displace should be named like:
|
||||
|
||||
plug_in_displace/data1
|
||||
plug_in_displace/data2
|
||||
etc.
|
||||
|
||||
Global data follows no strict rules.
|
||||
|
||||
|
||||
2. KNOWN PREFIXES
|
||||
=================
|
||||
|
||||
"tiff" : The standard GIMP TIFF plugin
|
||||
"jpeg" : The standard GIMP JPEG plugin
|
||||
"png" : The standard GIMP PNG plugin
|
||||
"dcm" : The standard GIMP DICOM plugin
|
||||
"gimp" : For common and standard parasites
|
||||
|
||||
|
||||
3. KNOWN GLOBAL PARASITES
|
||||
=========================
|
||||
|
||||
"jpeg-save-defaults" (GLOBAL, PERSISTENT)
|
||||
Default save parameters used by the JPEG plug-in.
|
||||
|
||||
"png-save-defaults" (GLOBAL, PERSISTENT)
|
||||
Default save parameters used by the PNG plug-in.
|
||||
|
||||
"<plug-in>/_fu_data" (GLOBAL, IMAGE, DRAWABLE, PERSISTENT)
|
||||
The Gimp::Fu module (Perl) might store the arguments of the
|
||||
last plug-in invocation. It is usually attached to images,
|
||||
but might also be found globally. The data format is either
|
||||
pure character data (Data::Dumper) or a serialized data
|
||||
stream created by Storable::nfreeze.
|
||||
|
||||
"exif-orientation-rotate" (GLOBAL, PERSISTENT)
|
||||
Whether a load plug-in should automatically rotate the image
|
||||
according to the orientation specified in the EXIF data. This
|
||||
has values "yes" or "no". If the parasite is not set, the
|
||||
plug-in should ask the user what to do. This parasite may be
|
||||
removed in a future version (assuming always yes).
|
||||
|
||||
|
||||
4. KNOWN IMAGE PARASITES
|
||||
========================
|
||||
|
||||
"gimp-comment" (IMAGE, PERSISTENT)
|
||||
Standard GIF-style image comments. This parasite should be
|
||||
human-readable text in UTF-8 encoding. A trailing \0 might
|
||||
be included and is not part of the comment. Note that image
|
||||
comments may also be present in the "gimp-metadata" parasite.
|
||||
|
||||
"gimp-brush-name" (IMAGE, PERSISTENT)
|
||||
A string in UTF-8 encoding specifying the name of a GIMP brush.
|
||||
Currently, the gbr plug-in uses this parasite when loading and
|
||||
saving .gbr files. A trailing \0 might be included and is not
|
||||
part of the name.
|
||||
|
||||
"gimp-brush-pipe-name" (IMAGE, PERSISTENT)
|
||||
A string in UTF-8 encoding specifying the name of a GIMP brush
|
||||
pipe. Currently, the gih plug-in uses this parasite when loading and
|
||||
saving .gih files. A trailing \0 might be included and is not
|
||||
part of the name.
|
||||
|
||||
"gimp-brush-pipe-parameters" (IMAGE, PERSISTENT)
|
||||
This is all very preliminary:
|
||||
|
||||
A string, containing parameters describing how an brush pipe
|
||||
should be used. The contents is a space-separated list of
|
||||
keywords and values. The keyword and value are separated by a
|
||||
colon.
|
||||
|
||||
This parasite is currently attached to an image by the psp
|
||||
plug-in when it loads a .tub file (Paint Shop Pro picture
|
||||
tube). It is used (first attached with values asked from the
|
||||
user, if nonexistent) by the gpb plug-in when it saves a .gih
|
||||
file. The .gih file contains the same text in it.
|
||||
|
||||
The keywords are:
|
||||
ncells: the number of brushes in the brush pipe
|
||||
step: the default spacing for the pipe
|
||||
dim: the dimension of the pipe. The number of cells
|
||||
in the pipe should be equal to the product
|
||||
of the ranks of each dimension.
|
||||
cols: number of columns in each layer of the image,
|
||||
to be used when editing the pipe as a GIMP image
|
||||
rows: ditto for rows. Note that the number of columns and rows
|
||||
not necessarily are identical to the ranks of the
|
||||
dimensions of a pipe, but in the case of two-
|
||||
and three-dimensional pipes, it probably is.
|
||||
rank0, rank1, ...: (one for each dimension): the index range
|
||||
for that dimension
|
||||
placement: "default", "constant" or "random". "constant" means
|
||||
use the spacing in the first brush in the pipe.
|
||||
"random" means perturb that with some suitable
|
||||
random number function. (Hmm, would it be overdoing it
|
||||
if the pipe also could specify what random function
|
||||
and its parameters...?)
|
||||
sel0, sel1, ...: "default", "random", "incremental", "angular",
|
||||
"pressure", "velocity", and whatever else suitable we might
|
||||
think of ;-) Determines how one index from each dimension is
|
||||
selected (until we have pinpointed the brush to use).
|
||||
|
||||
"gimp-image-grid" (IMAGE, PERSISTENT)
|
||||
The GimpGrid object serialized to a string. Saved as parasite
|
||||
to keep the XCF files backwards compatible. Although gimp-1.2
|
||||
does not know how to handle the image grid, it keeps the grid
|
||||
information intact.
|
||||
|
||||
"gimp-pattern-name" (IMAGE, PERSISTENT)
|
||||
A string in UTF-8 encoding specifying the name of a GIMP pattern.
|
||||
Currently, the pat plug-in uses this parasite when loading and
|
||||
saving .pat files. A trailing \0 might be included and is not
|
||||
part of the name.
|
||||
|
||||
"tiff-save-options" (IMAGE)
|
||||
The TiffSaveVals structure from the TIFF plugin.
|
||||
|
||||
"jpeg-save-options" (IMAGE)
|
||||
The JpegSaveVals structure from the JPEG plugin.
|
||||
|
||||
"jpeg-exif-data" (IMAGE) (deprecated)
|
||||
The ExifData structure serialized into a uchar* blob from
|
||||
libexif. This is deprecated in favor of "exif-data".
|
||||
|
||||
"jpeg-original-settings" (IMAGE, PERSISTENT)
|
||||
The settings found in the original JPEG image: quality (IJG),
|
||||
color space, component subsampling and quantization tables.
|
||||
These can be reused when saving the image in order to minimize
|
||||
quantization losses and keep the same size/quality ratio.
|
||||
|
||||
"gamma" (IMAGE, PERSISTENT)
|
||||
The original gamma this image was created/saved. For JPEG; this is
|
||||
always one, for PNG it's usually taken from the image data. GIMP
|
||||
might use and modify this. The format is an ascii string with the
|
||||
gamma exponent as a flotingpoint value.
|
||||
|
||||
Example: for sRGB images this might contain "0.45454545"
|
||||
|
||||
"chromaticity" (IMAGE, PERSISTENT)
|
||||
This parasite contains 8 floatingpoint values (ascii, separated by
|
||||
whitespace) specifying the x and y coordinates of the whitepoint, the
|
||||
red, green and blue primaries, in this order.
|
||||
|
||||
Example: for sRGB images this might contain
|
||||
"0.3127 0.329 0.64 0.33 0.3 0.6 0.15 0.06"
|
||||
wx wy rx ry gx gy bx by
|
||||
|
||||
"rendering-intent" (IMAGE, PERSISTENT)
|
||||
This specifies the rendering intent of the image. It's a value
|
||||
between 0 and 3, again in ascii:
|
||||
|
||||
0 - perceptual (e.g. for photographs)
|
||||
1 - relative colorimetric (e.g. for logos)
|
||||
2 - saturation-preserving (e.g. for business charts)
|
||||
3 - absolute colorimetric
|
||||
|
||||
"hot-spot" (IMAGE, PERSISTENT)
|
||||
Use this parasite to store an image's "hot spot". Currently
|
||||
used by the XBM plugin to store mouse cursor hot spots.
|
||||
|
||||
Example: a hot spot at coordinates (5,5) is stored as "5 5"
|
||||
|
||||
"exif-data" (IMAGE, PERSISTENT)
|
||||
The ExifData structure serialized into a character array by
|
||||
libexif (using exif_data_save_data). If a "gimp-metadata"
|
||||
parasite is present, it should take precedence over this one.
|
||||
|
||||
"gimp-metadata" (IMAGE, PERSISTENT)
|
||||
The metadata associated with the image, serialized as one XMP
|
||||
packet. This metadata includes the contents of any XMP, EXIF
|
||||
and IPTC blocks from the original image, as well as
|
||||
user-specified values such as image comment, copyright,
|
||||
license, etc.
|
||||
|
||||
"icc-profile" (IMAGE, PERSISTENT | UNDOABLE)
|
||||
This contains an ICC profile describing the color space the
|
||||
image was produced in. TIFF images stored in PhotoShop do
|
||||
oftentimes contain embedded profiles. An experimental color
|
||||
manager exists to use this parasite, and it will be used
|
||||
for interchange between TIFF and PNG (identical profiles)
|
||||
|
||||
"icc-profile-name" (IMAGE, PERSISTENT | UNDOABLE)
|
||||
The profile name is a convenient name for referring to the
|
||||
profile. It is for example used in the PNG file format. The
|
||||
name must be stored in UTF-8 encoding. If a file format uses
|
||||
a different character encoding, it must be converted to UTF-8
|
||||
for use as a parasite.
|
||||
|
||||
"decompose-data" (IMAGE, NONPERSISTENT)
|
||||
Starting with GIMP 2.4, this is added to images produced by
|
||||
the decompose plug-in, and contains information necessary to
|
||||
recompose the original source RGB layer from the resulting
|
||||
grayscale layers. It is ascii; a typical example would be
|
||||
"source=2 type=RGBA 4 5 6 7". This means that layer 2 was
|
||||
decomposed in RGBA mode, giving rise to layers 4, 5, 6, and 7.
|
||||
|
||||
"print-settings" (IMAGE, NONPERSISTENT)
|
||||
This parasite is stored by the Print plug-in and holds settings
|
||||
done in the Print dialog. It also has a version field so that
|
||||
changes to the parasite can be done. GIMP 2.4 used version 0.3.
|
||||
The format is GKeyFile. A lot of the contents are identical to
|
||||
what is stored in ~/.gimp-2.x/print-settings but the parasite
|
||||
has some additional image-related fields.
|
||||
|
||||
"print-page-setup" (IMAGE, NONPERSISTENT)
|
||||
This parasite is stored by the Print plug-in and holds settings
|
||||
done in the Page Setup dialog. The format is GKeyFile as created
|
||||
from GtkPageSetup. The content is identical to what is stored in
|
||||
~/.gimp-2.x/print-page-setup.
|
||||
|
||||
"dcm/XXXX-XXXX-AA" (IMAGE, PERSISTENT)
|
||||
These parasites are stored by the Dicom plug-in and hold the DICOM
|
||||
element information for that image. The format is raw binary data
|
||||
as read from the original image.
|
||||
where: XXXX is a 4-digit ascii encoded hexadecimal number
|
||||
AA is a two character ascii value representing the Dicom
|
||||
element's Value Representation (VR)
|
||||
|
||||
|
||||
5. KNOWN LAYER/DRAWABLE PARASITES
|
||||
=================================
|
||||
|
||||
"gimp-text-layer" (LAYER, PERSISTENT)
|
||||
The associated GimpText object serialized to a string. For
|
||||
convenience the string is terminated by a trailing '\0'.
|
||||
The idea of using a parasite for text layers is to keep the XCF
|
||||
files backward compatible. Although gimp-1.2 doesn't know how
|
||||
to handle the text layer, it keeps the parasite intact.
|
||||
|
||||
"gfig" (LAYER, PERSISTENT)
|
||||
As of GIMP 2.2, the gfig plug-in creates its own layers, and
|
||||
stores a representation of the figure as a layer parasite.
|
||||
The parasite contains a GFig save file, in an ascii format.
|
||||
If gfig is started while the active layer contains a "gfig"
|
||||
parasite, the contents of the parasite are loaded at startup.
|
||||
|
||||
|
||||
6. PARASITE FORMAT
|
||||
==================
|
||||
|
||||
The parasite data format is not rigidly specified. For non-persistent
|
||||
parasites you are entirely free, as the parasite data does not survive the
|
||||
current gimp session. If you need persistent data, you basically have to
|
||||
choose between the following alternatives (also, having some standard for
|
||||
non-persistent data might be fine as well):
|
||||
|
||||
- Cook your own binary data format
|
||||
|
||||
You can invent your own data format. This means that you will either
|
||||
loose totally (consider endian-ness or version-ness issues) or you will
|
||||
get yourself into deep trouble to get it "right" in all cases.
|
||||
|
||||
- Use character (string) data
|
||||
|
||||
Obvious to Perl people but less so to C programmers: just sprintf your
|
||||
data into a string (e.g. "SIZE 100x200 XRES 300 YRES 300") and store
|
||||
that in the parasite, and later sscanf it again. This often solves most
|
||||
of the problems you might encounter, makes for easier debugging and
|
||||
more robustness (consider the case when you add more entries to your
|
||||
persistent data: older plug-ins might be able to read the relevant
|
||||
parts and your application can detect missing fields easily). The
|
||||
drawback is that your data is likely to be larger than a compact binary
|
||||
representation would be. Not much a problem for most applications,
|
||||
though.
|
||||
|
||||
You could also use one parasite per field you store, i.e. foo-size,
|
||||
foo-offset-x, foo-offset-y etc...
|
||||
|
||||
- Use the libgimpconfig serialize functions
|
||||
|
||||
This is a special case of the previous one, using the convenience
|
||||
functions provided by libgimpconfig. If you are not concerned about
|
||||
the size of the string representation of your data, you can use
|
||||
gimp_config_serialize_to_string() and other functions to easily
|
||||
convert your data to/from a character string.
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
=============================================================
|
||||
How does resource tagging in Gimp work?
|
||||
=============================================================
|
||||
|
||||
|
||||
GimpTagged
|
||||
|
||||
Tagging is not limited to a concrete class hierarchy, but any class
|
||||
implementing the GimpTagged interface can be tagged. In addition to
|
||||
methods for adding/removing/enumerating tags it also requires
|
||||
GimpTagged objects to identify themselves:
|
||||
|
||||
* gimp_tagged_get_identifier: used to get a unique identifier of a
|
||||
GimpTagged object. For objects which are stored in a file it will
|
||||
usually be a filename.
|
||||
|
||||
* gimp_tagged_get_checksum: the identifier mentioned above has the problem
|
||||
that it can change during sessions (for example, user moves or renames
|
||||
a resource file). Therefore, there needs to be a way to get another
|
||||
identifier from the data of the tagged object, so that tags stored between
|
||||
session can be remapped properly.
|
||||
|
||||
|
||||
GimpTag
|
||||
|
||||
Tags are represented by a GimpTag object. There are no limitations for
|
||||
tag names except that they cannot contain a selected set of terminal
|
||||
punctuation characters (used to separate tags), leading or trailing
|
||||
whitespace and cannot begin with a reserved prefix for internal tags
|
||||
('gimp:'). These conditions are enforced when creating a tag object from a
|
||||
tag string. The only reason for tag creation to fail is if there are
|
||||
no characters left after trying to fix a tag according to the
|
||||
rules above. Tag names are displayed as the user typed them (case
|
||||
sensitive), but tag comparison is done case-insensitively.
|
||||
|
||||
Tags are immutable, i.e. when a tag is created with one name string, it
|
||||
cannot be changed, but a new tag has to be created instead.
|
||||
|
||||
There are methods provided for convenient use with glib, a comparison
|
||||
function which can be used to sort tag lists and functions for storing
|
||||
tags in a GHashTable.
|
||||
|
||||
|
||||
GimpTagCache
|
||||
|
||||
Between sessions, tags assigned to objects are stored in a cache
|
||||
file. The cache file is a simple XML file, which lists all resources and
|
||||
tags which are added to them. Resources which have no tags assigned
|
||||
are listed here too, so that when we check the cache we know that they
|
||||
have no tags assigned instead of trying to find out if the resource file
|
||||
has been renamed.
|
||||
|
||||
When the session ends, a list of all resources and their tags
|
||||
is constructed. Resources which were not loaded during this session,
|
||||
but had tags assigned are also added to the list (they are saved
|
||||
because they could be useful in the next session, for example, when
|
||||
a temporarily disconnected network directory is reconnected). The list
|
||||
is then written to a tag cache file in the user's home directory.
|
||||
|
||||
When the session starts, the previously saved resource and tag mapping has to
|
||||
be loaded and assigned to GimpTagged objects. First the tag cache is
|
||||
loaded from file, and then containers are added (GimpContainer objects
|
||||
which contain items implementing the GimpTagged interface). After that,
|
||||
loaded resources are assigned tags:
|
||||
|
||||
If a resource identifier matches an identifier in the cache,
|
||||
corresponding tags are assigned to the GimpTagged object.
|
||||
Else, if the identifier is not found in the tag cache,
|
||||
an attempt is made to check if the resource file has been
|
||||
moved/renamed. In such case the checksum is used to match the
|
||||
GimpTagged object with all of the records in the tag cache.
|
||||
If a match is found,
|
||||
the identifier is updated in the tag cache.
|
||||
Otherwise,
|
||||
the loaded GimpTagged object is considered to be a newly
|
||||
added resource.
|
||||
|
||||
|
||||
GimpFilteredContainer
|
||||
|
||||
A GimpFilteredContainer is a "view" (representation) of a
|
||||
GimpContainer. It is related to tagging in that it can be used to
|
||||
filter a GimpContainer to contain only GimpTagged objects which have
|
||||
certain tags assigned. It is automatically updated with any changes in
|
||||
the GimpContainer it wraps. However, items should not be added or removed
|
||||
from this container manually as changes do not affect the original
|
||||
container and would be lost when the GimpFilteredContainer is
|
||||
updated. Instead, the contents should be changed by setting a tag list
|
||||
which would be used to filter GimpTagged objects containing all of the
|
||||
given GimpTags.
|
||||
|
||||
GimpFilteredContainer can use any GimpContainer as a source
|
||||
container. Therefore, it is possible to use the decorator design pattern
|
||||
to implement additional container views, such as a view combining items
|
||||
from multiple containers.
|
||||
|
||||
|
||||
GimpTagEntry widget
|
||||
|
||||
The GimpTagEntry widget extends GtkEntry and is used to either assign or
|
||||
query tags depending on the selected mode. The widget support various
|
||||
usability features:
|
||||
|
||||
* Jellybeans: When a tag is entered and confirmed by either separator,
|
||||
pressing return or otherwise, it becomes a jellybean, i.e. a single
|
||||
unit, not a bunch of characters. Navigating in a GimpTagEntry,
|
||||
deleting tags, etc. can be performed much faster. However, while a tag
|
||||
is just being entered (not yet confirmed), all actions operate on
|
||||
characters as usual.
|
||||
|
||||
* Custom auto completion is implemented in the GimpTagEntry widget which
|
||||
allows to complete tags in the middle of a tag list, doesn't offer
|
||||
already completed tags, tab cycles all possible completions, etc.
|
||||
|
||||
* If the GimpTagEntry is empty and unused it displays a description for
|
||||
the user regarding its purpose.
|
||||
|
||||
When operating in tag assignment mode, tags are assigned only when
|
||||
the user hits the return key.
|
||||
|
||||
When operating in tag query mode, the given GimpFilteredContainer is
|
||||
filtered as the user types. The GimpTagEntry also remembers recently used
|
||||
configurations, which can be cycled using up and down arrow keys.
|
||||
|
||||
|
||||
GimpComboTagEntry widget
|
||||
|
||||
The GimpComboTagEntry widget extends GimpTagEntry and adds the ability to pick
|
||||
tags from a menu-like list (using the GimpTagPopup widget).
|
||||
|
||||
|
||||
GimpTagPopup widget
|
||||
|
||||
The GimpTagPopup widget is used as a tag list menu from the GimpComboTagEntry
|
||||
widget. It is not designed to be used with any other widget.
|
||||
|
||||
GimpTagPopup has many visual and behavioral similarities to GtkMenu.
|
||||
In particular, it uses menu-like scrolling.
|
||||
|
||||
GimpTagPopup implements various usability features, some of which are:
|
||||
|
||||
* Tags which would result in an empty selection of resources are made
|
||||
insensitive.
|
||||
|
||||
* Closing either with the keyboard or by clicking outside the popup area.
|
||||
|
||||
* Underlining of highlighted (hovered) tags.
|
||||
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
GIMP UI Framework
|
||||
=================
|
||||
|
||||
This document describes how the GIMP UI framework functions and is
|
||||
implemented. Here, "UI framework" refers to the system that saves the
|
||||
UI layout between GIMP sessions, i.e. how docks, dockable dialogs etc
|
||||
are setup.
|
||||
|
||||
|
||||
Key Classes
|
||||
-----------
|
||||
|
||||
GimpDockable - Represents a dockable dialog.
|
||||
GimpDockbook - A GtkNotebook of GimpDockables
|
||||
GimpDock - A columns of GimpDockbooks
|
||||
GimpToolbox - Subclasses GimpDock, contains the toolbox.
|
||||
Dockables are added at the bottom
|
||||
GimpMenuDock - Subclasses GimpDock, contains dockables, should
|
||||
probably be merged with GimpDock. The name
|
||||
contains "menu" from the time when it hosted the
|
||||
Image Selection Menu that is now in the
|
||||
GimpDockWindow
|
||||
GimpDockColumns - A set of GimpDocks arranged side by side.
|
||||
GimpDockWindow - A toplevel window containing a GimpDockColumns.
|
||||
GimpImageWindow - A toplevel window containing images and one
|
||||
GimpDockColumns to the left and to the right.
|
||||
GimpDialogFactory - A factory to create and position toplevel windows
|
||||
GimpSessionInfo - Contains session info for one toplevel
|
||||
GimpUIConfigurer - Configures the UI when switching between
|
||||
single-window and multi-window mode
|
||||
|
||||
|
||||
GimpDialogFactory
|
||||
-----------------
|
||||
|
||||
The GimpDialogFactory can be considered to solve two distinct
|
||||
problems:
|
||||
|
||||
1. Create widgets from text, in particular from text in sessionrc
|
||||
2. Session manage toplevel windows so their position is remembered
|
||||
across GIMP sessions
|
||||
|
||||
One possible design adjustment would be to have GimpWidgetFactory that
|
||||
takes care of 1), and then have GimpDialogFactory inherit from
|
||||
GtkWidgetFactory and implementing 2). GimpWidgetFactory could possibly
|
||||
use GtkBuilder.
|
||||
|
||||
|
||||
sessionrc
|
||||
---------
|
||||
When GIMP starts, the sessionrc file is parsed. This step puts
|
||||
GimpSessionInfo:s into GimpDialogFactories. Later when dialogs are
|
||||
created, the dialog factory looks up existing session info entries. If
|
||||
one exists, it uses the session info to set e.g. the position of the
|
||||
created dialog. If it doesn't exist, it creates a new session info
|
||||
object for the dialog. When GIMP exists, the current session infos are
|
||||
then written back to sessionrc.
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
A quick overview of the undo system
|
||||
-----------------------------------
|
||||
|
||||
Actions on the image by the user are pushed onto an undo stack. Each
|
||||
action object includes all the information needed to undo or redo an
|
||||
operation, plus an UndoType. The type can be converted to text to
|
||||
show to the user. Actions may be run forwards (UndoState == REDO) or
|
||||
backwards (UndoState == UNDO). As the action is run, it swaps the
|
||||
image's current state and the recorded state. A run action is moved
|
||||
from the undo stack to the redo stack (or vice-versa if UndoState ==
|
||||
REDO). Pushing something onto the undo stack causes the redo stack to
|
||||
be cleared, since the actions on the redo stack may depend on the
|
||||
image being in a particular state (eg consider: layer add, rename,
|
||||
undo rename, layer delete. If the redo stack weren't cleared on undo,
|
||||
then there would still be a "rename" operation on the redo stack which
|
||||
could be run on a non-existent layer. Bad news.)
|
||||
|
||||
Undo groups
|
||||
-----------
|
||||
In order to group many basic operations together into a more useful
|
||||
whole, code can push group start and end markers. A group is treated
|
||||
as a single action for the purposes of the undo and redo user
|
||||
commands. It is legal to nest groups, in which case the outermost
|
||||
group is the only user-visible one.
|
||||
|
||||
Groups boundaries used to be implemented by pushing a NULL pointer on
|
||||
the undo (or redo) stack. Now they are a special action which has the
|
||||
"group_boundary" bit set. This allows the group boundaries to include
|
||||
the undo type associated with the whole group. The individual actions
|
||||
need to preserve their own undo type since the undo_free_* functions
|
||||
sometimes need to know which action is being freed.
|
||||
|
||||
Undo events
|
||||
-----------
|
||||
Images emit UNDO_EVENT signals, to say that the user has performed an
|
||||
undo or redo action on that image. This allows interested parties to
|
||||
track image mutation actions. So far, only the undo history dialog
|
||||
uses this feature. The other way to discover the undo status of an
|
||||
image is to use the iterator functions undo_map_over_undo_stack() and
|
||||
undo_map_over_redo_stack(). These call your function on each action
|
||||
(or group) on the stack. There is also undo_get_undo_name() and
|
||||
undo_get_redo_name() to peek at the top items on each stack. This
|
||||
could be used (eg) to change the undo/redo menu strings to something
|
||||
more meaningful, but currently lack synchronisation.
|
||||
|
||||
Dirtying images
|
||||
---------------
|
||||
NOTE about the gimage->dirty counter:
|
||||
If 0, then the image is clean (ie, copy on disk is the same as the one
|
||||
in memory).
|
||||
If positive, then that's the number of dirtying operations done
|
||||
on the image since the last save.
|
||||
If negative, then user has hit undo and gone back in time prior
|
||||
to the saved copy. Hitting redo will eventually come back to
|
||||
the saved copy.
|
||||
The image is dirty (ie, needs saving) if counter is non-zero.
|
||||
If the counter is around 10000, this is due to undo-ing back
|
||||
before a saved version, then mutating the image (thus destroying
|
||||
the redo stack). Once this has happened, it's impossible to get
|
||||
the image back to the state on disk, since the redo info has been
|
||||
freed. See undo.c for the gorey details.
|
||||
|
||||
NEVER CALL gimp_image_dirty() directly!
|
||||
|
||||
If your code has just dirtied the image, push an undo instead.
|
||||
Failing that, push the trivial undo which tells the user the
|
||||
command is not undoable: undo_push_cantundo() (But really, it would
|
||||
be best to push a proper undo). If you just dirty the image
|
||||
without pushing an undo then the dirty count is increased, but
|
||||
popping that many undo actions won't lead to a clean image.
|
||||
|
||||
Austin
|
||||
|
||||
Loading…
Reference in a new issue