                   ------------------------------
                   GNU Image Manipulation Program
                         Development Branch
                   ------------------------------

This is the unstable branch of GIMP.


Overview of Changes from GIMP 2.10.x to GIMP 2.99.2
===================================================

Core:

  - Improved "space invasion".
  - New extension format support (.gex a.k.a. GIMP Extension) which is
    an archive containing various supported data. So far, it can
    package: brushes, MyPaint brushes, dynamics, patterns, gradients,
    palettes, tool presets, plug-ins, splash images and themes.
  - New extension manager allowing to enable, disable or uninstall
    installed extensions, with a dialog available in `Edit > Manage
    Extensions`.
  - Multi selection of layers now possible. Various tools and features
    are now multi-selection aware.
  - XCF format bumped to version 14 with awareness of multiple layer
    selection.
  - All code is year-2038-safe with deprecated time API replaced.
  - "Alpha to Selection" various actions warn when the result selection
    is empty.
  - Color Profile Policy (import) now exposes a "Convert to Preferred
    Profile" (fourth) choice and the import dialog default "Convert"
    action will convert the image to the preferred profile (if any was
    set, otherwise it falls back to the built-in profile). Converting to
    the built-in profile will be still available as secondary action.
  - A new "Metadata Rotation Policy" is now exposed in the Preferences
    dialog, next to the "Color Profile Policy" (in page `Preferences >
    Image Import & Export`) with 3 options: "Ask what to do", "Discard
    metadata without rotating" and "Rotate the image then discard
    metadata".
    This policy used to be handled API-size, with a dialog generated by
    libgimpui gimp_image_metadata_load_finish(), and saved in a global
    parasite. The whole logics and GUI has been moved as core logics,
    similar to the "Color Profile Policy".

User Interface:

  - Whole interface ported to GTK+3:
    * Proper HiDPI support, which will follow the system's scale factor
      for all widgets. This is a core toolkit support, unlike the basic
      better-than-nothing hacks from GIMP 2.10.x.
    * GTK+3 CSS-like support. All themes for former versions are
      therefore not working anymore.
    * GTK+3 themes have the concept of "dark variant", so a same theme
      may propose both a light and a dark versions. Preference for dark
      variants can now be checked in `Preferences > Themes > Use dark
      theme variant if available` checkbox, allowing for instance to use
      your system theme in its light variant everywhere except in GIMP.
      This option is checked by default as graphics software are often
      prefered in dark modes.
    * Symbolic icon themes are now recolored automatically according to
      the theme colors (no theme and icon theme tweaking anymore to end
      up with dark on dark or light on light interfaces), except for
      color elements whose SVG style is marked as "!important".
    * Native Wayland support.
    * Various dialogs now use Client-Side decorations and modern GTK+
      widgets are being used when relevant (e.g. GtkSwitch which gives a
      better feeling of a general "ON/OFF state").
  - Image display rendered faster with a render cache that keeps the
    result of scaling, color management, display filters and shell mask
    (for tools like fuzzy select).
  - Shift-click on layer GimpContainerTreeView (typically the Layers
    dockable) allows to expand/collapse all item groups but the clicked
    one.
  - Compact GimpSpinScale is now the only available version.

Devices:

  - Device hotplug supported (thanks to GTK+3). In particular:
    * you don't need to have your tablets and other devices plugged
      before you start GIMP anymore;
    * enabling your devices in the "Configure Input Devices" dialog is
      not needed anymore. Tablets will work out-of-the box;
    * you can safely unplug and replug the same or other input devices
      while GIMP is running.
  - "Input Devices" dialog improved:
    * "Save" and "Close" buttons replaced by "OK" (save and exit),
      "Cancel" (reset and exit) and "Reset" (reset to previous settings
      but keep the dialog open).
    * "Keys" list has been discontinued. The "key" concept is
      associated to "keyboard" devices (a tablet being a "pointing
      device" with buttons, not keys) so this list was actually useless
      and only confusing.

Plug-ins:

  - Major rewrite of the API (see below). So GIMP 2.10.x plug-ins and
    below must be ported to the new API.
  - Every introspected binding which we test comes with a "Goat
    Exercise", which is a demo plug-in popping a dialog and showing its
    own source code. It processes a simple "gegl:invert" operation on a
    drawable. All "Goat Exercises" must do the same thing in the same
    way, simply in their respective languages, as documentation/example
    code for a language binding.
  - The Goat Exercise plug-ins are themselves installed as a GIMP
    Extension, as a demo for extension creation.
  - Plug-ins must be installed in their own subdirectory in
    `$XDG_CONFIG_HOME/GIMP/2.99/plug-ins/`, thus preventing data mess
    (with plug-ins coming with data and installing it all in the root
    plug-ins/ directory) and DLL hell. The main plug-in executable must
    be named the same as the directory (possibly with an added
    extension).
    E.g.: `plug-ins/my-cool-plug-in/my-cool-plug-in.py`
  - HEIF export allows selecting color subsampling/pixel format (YUV444,
    YUV420, RGB) and encoder speed (Slow, Balanced, Fast).
    Lossless option delivers visually lossless output.
  - New "file-heif-av1-load" procedure separate from "file-heif-load"
    for AVIF only.

API:

  - `GimpPDB` is now a class to represent the PDB communication channel
    with GIMP. It is a singleton which exist exactly once per running
    plug-in, hence it is not meant to be manually instanciated and can
    only be returned by gimp_get_pdb(). It is mostly used to look up
    procedures declared by other plug-ins or by GIMP core, check if a
    given procedure exist and run the procedures.
  - `GimpPlugIn` is a class which every plug-in should now subclass as a
    way to create their plug-in, and override at least the methods
    query_procedures() and create_procedure(). Two other methods
    (init_procedures() and quit()) can be optionally overrided.
    The new subclass must be declared to gimp by calling gimp_main() to
    make it available to the core (PDB procedure, menu items, etc.).
    A plug-in can obtain its own GimpPlugIn instance with
    gimp_get_plug_in(). This is a singleton object which belongs to
    libgimp.
  - Plug-In procedures are now represented by a class `GimpProcedure`.
    * The subclass `GimpFileProcedure` handles file-related procedures,
      and its own subclasses `GimpLoadProcedure` and `GimpSaveProcedure`
      handle load/export procedures (file format support).
    * The subclass `GimpThumbnailProcedure` for procedures run during
      the lifetime of the GIMP session each time a plug-in thumbnail
      procedure is called.
    * The subclass `GimpImageProcedure` handles `GimpImage`-related
      procedures, i.e. any procedure which want to work on the opened
      image (GIMP core will pass through the active image and selected
      drawables to the plug-in procedure).
    * Objects of the subclass `GimpPDBProcedure` are not meant to be
      created or freed by plug-ins, they represent any `GimpProcedure`
      and are returned by `gimp_pdb_lookup_procedure()` by looking it up
      by name on the singleton `GimpPDB` object.
  - `GimpProcedureConfig` is the base class to represent the arguments
    when running a `GimpProcedure`. It implements the `GimpConfig`
    interface and will provide proper management of saved settings
    (including the last used values) and generated GUI using
    prop_widgets to plug-ins. This is still a work-in-progress.
    Currently `GimpProcedure` run function is called with a
    `GimpValueArray` whose values can be transfered into a
    `GimpProcedureConfig` by calling `gimp_procedure_config_begin_run()`
    or `gimp_procedure_config_begin_export()`.
  - `GimpDisplay` is now a class of its own.
  - `GimpImage` is now a class to represent an opened image.
  - `GimpItem` is now a class to represent various `GimpImage` items.
    * `GimpVectors` subclass represents an image path.
    * `GimpDrawable` subclass represents drawable object but is a
      simili-abstract class as it won't be a finale object class, which
      can be so far either a:
      + `GimpLayer` represents image layers.
      + `GimpChannel` represents a `GimpImage` channel which is
         typically in GIMP a named channel which can be added into a
         `GimpImage` channel stack (the "Channels" dockable in the GUI)
         with `gimp_image_insert_channel()`. This class is not really
         used to represent a color space component though this is
         conceptually the same thing (so maybe some day) and named
         channel can actually be created from an image color component
         with `gimp_channel_new_from_component()`.
         Some other specific usages have their own subclasses:
        - `GimpLayerMask` subclass is used for a `GimpLayer` mask.
        - `GimpSelection` subclass is used for a `GimpImage` selection.
  - GimpImage, GimpItem and GimpDisplay (and their various subclasses)
    represent objects which can be passed through the PDB. They are
    managed by libgimp and should not be freed by plug-ins.
  - The PDB-passing classes still have IDs which can be obtained with
    gimp_image_get_id(), gimp_item_get_id() and gimp_display_get_id()
    respectively. Conversely you can get back the object with
    gimp_image_get_by_id(), gimp_item_get_by_id() and
    gimp_display_get_by_id().
    Specific variants exist to get back an item object from its ID, such
    as gimp_layer_get_by_id(), which do additional class verification
    (other than this, they are similar to gimp_item_get_by_id()).
    **NOTE**: since objects are managed by libgimp, you are ensured that
    a `*_get_by_id()` call returns you exactly the same object you had
    previously for a given object. Consequently you can do pointer
    comparison of objects to compare images, items or displays during a
    given run. This will work because objects are unique (these are not
    several object copies representing the same remote object).
  - Type validation function which used to work on IDs now work directly
    with object arguments while new function with added `*_id*` have
    been created to validate from an object ID instead, GIMP 2.10-style.
    To verify if an ID exist:
    * gimp_image_is_valid() / gimp_image_id_is_valid()
    * gimp_item_is_valid() / gimp_item_id_is_valid()
    * gimp_display_is_valid() / gimp_display_id_is_valid()
    To check if GimpItem are from specific subclasses:
    * gimp_item_is_drawable() / gimp_item_id_is_drawable()
    * gimp_item_is_layer() / gimp_item_id_is_layer()
    * gimp_item_is_text_layer() / gimp_item_id_is_text_layer()
    * gimp_item_is_channel() / gimp_item_id_is_channel()
    * gimp_item_is_layer_mask() / gimp_item_id_is_layer_mask()
    * gimp_item_is_selection() / gimp_item_id_is_selection()
    * gimp_item_is_vectors() / gimp_item_id_is_vectors()

    **NOTE**: since these are GObject classes, you can also use the
    GObject style macros such as GIMP_IS_LAYER(). Yet these macros do
    not do any ID verification (which is not a problem anyway in most
    cases as you got the object from API calls) and will not exist in
    bindings.

    **IMPORTANT**: using IDs is mostly for internal usage and actually
    there are very few reasons to ever need to get an object ID from a
    plug-in. Usually you should rather just work only with the unique
    object pointers returned by the API.
  - The whole API has been updated to use objects instead of object IDs
    when relevant. For instance all existing libgimp functions from 2.10
    which were called on an image ID are now called on a GimpImage
    object instead.
  - All file paths procedure parameters are now handled by GIO's `GFile`
    which simplify various file handling issues (path formats, encoding,
    etc.) and brings new features (remote access, secure protocol
    support, etc.). We also got rid of the "filename" vs "raw_filename"
    differenciation in parameters. Hence all libgimp* functions with
    these parameters have been updated as well.
  - gimp_image_metadata_load_finish() is now fully GUI/GTK-code free.
    The first consequence is that it is not in libgimpui anymore, but in
    libgimp, as it should. The second consequence is that the boolean
    `interactive` argument has been removed. Now all image rotation
    logics (the part which needed a GUI) has been moved into core and
    will be automatically run when normally loading images from GIMP's
    interface, similarly as to how color profiles was already handled.
  - 2 new libgimp functions: gimp_image_policy_rotate() and
    gimp_image_policy_color_profile() are now available to explicitly
    call the Preferences-set policy on an image. This may result in a
    dialog being presented to the user if `interactive` is TRUE and
    settings is "Ask what to do".
    It is unecessary to call these functions when developing a new
    GimpLoadProcedure because the core will automatically do the right
    thing and call these on normal image loading workflow.
    Instead if a plug-in calls such GimpLoadProcedure through the PDB,
    no such functions will be run automatically. It is up to the plug-in
    to decide what to do (no conversion, mandatory conversion, or using
    user settings, possibly with a dialog to decide, hence calling these
    functions explicitly).
  - New function gimp_export_comment() to query the user settings (as
    set in Preferences) on whether or not a file plug-in should export
    the image's comment.
  - Several functions which are returning C-array of objects with a size
    output argument now also have a GList counterpart (not as
    replacement, but as additional API):
    * gimp_get_images() -> gimp_list_images()
    * gimp_image_get_layers() -> gimp_image_list_layers()
    * gimp_image_get_selected_layers() -> gimp_image_list_selected_layers()
    * gimp_image_get_channels() -> gimp_image_list_channels()
    * gimp_image_get_vectors() -> gimp_image_list_vectors()
    * gimp_item_get_children() -> gimp_item_list_children()
  - New function gimp_vectors_stroke_reverse() to reverse a specified
    stroke in a given GimpVectors.
  - Function gimp_zoom_preview_get_drawable() which got deprecated since
    GIMP 2.10.0 and replaced by gimp_zoom_preview_get_drawable_id() is
    reinstated with the new GimpDrawable class, whereas the newer
    function got removed.
    Similarly gimp_zoom_preview_new_from_drawable_id() is replaced by
    gimp_zoom_preview_new_from_drawable().
  - Note: there are likely more API changes, unfortunately we haven't
    kept the NEWS file up-to-start from scratch. The best is to look at
    the API generated documentation.
  - The full API is GObject Introspected into 2 modules: Gimp and
    GimpUi. This means plug-ins can be written in various non-C
    languages. So far the following languages have been tested and work
    well: Python 3, Lua, Javascript and Vala.
    (Note: Python 2 is also working, but considering that this language
    is end-of-life since 2020, we don't really care).
  - All pygimp specific Python API does not exist anymore. Python will
    use the same API as C plug-ins, introspected through GObject
    Introspection.

Documentation:

  - `devel-docs/xcf.txt` updated to handle XCF 14.

Build:

  - New meson build system. Still deemed "experimental" for the time
    being. Packagers are recommended to continue using the autotools
    build system in order to avoid build system-specific bugs.
  - Continuous integration in Gitlab with:
    - an autotools build with GCC on a Debian/testing runner
    - an autotools distcheck build on a Debian/testing runner
    - a meson build with GCC on a Debian/testing runner
    - a meson build with Clang on a Debian/testing runner
    - a meson cross-build with Mingw-w64 for Windows 32-bit
    - a meson cross-build with Mingw-w64 for Windows 64-bit
    - static code analysis with cppcheck
    - a source tarball distribution job (tar.bz2 and tar.xz)
    - a ready-to-run Windows 64-bit test archive
    - a ready-to-run Windows 32-bit test archive

Known blocker issues:

  - GTK+3 port is functional but not complete as some deprecated APIs
    are still being used.
  - Space invasion is still a work-in-progress.
  - Plug-ins API update is still a work-in-progress.
  - GIMP extensions are still a work-in-progress.
  - Multiple layer selection is still work-in-progress. Some issues are
    expected, and possibly even some crashes in code paths which were
    not updated yet.
  - No custom theme yet, in particular we want a neutral gray theme with
    light/dark variants, and a middle-gray theme too.
  - We probably want to revive a "Small" theme as well with smaller
    icons (useful on smaller displays, or mid-high density displays or
    simply depending on tastes).
  - Various blocking bugs happen on Wayland only.
