[gimp-gap] support acceleration charactersitics for Storyboard and animated filter apply



commit 626b3f04c1ecfa0395ca7adf7e7ea198eb9a7e2b
Author: Wolfgang Hofer <wolfgangh svn gnome org>
Date:   Mon Feb 15 18:58:06 2010 +0100

    support acceleration charactersitics for Storyboard and animated filter apply

 ChangeLog                                          |   61 ++
 NEWS                                               |   28 +-
 docs/reference/txt/STORYBOARD_FILE_DOC.txt         |   72 ++-
 docs/reference/txt/gap-filterall-db-browser.txt    |   85 ++-
 docs/reference/txt/plug-in-gap-move-path.txt       |  144 ++++-
 .../txt/plug-in-gap-storyboard-attr-prop.txt       |   15 +-
 .../txt/plug-in-gap-storyboard-clip-prop.txt       |  101 +++
 gap/gap_accel_char.c                               |   39 +-
 gap/gap_accel_char.h                               |   18 +-
 gap/gap_accel_da.c                                 |  263 ++++++--
 gap/gap_accel_da.h                                 |   10 +-
 gap/gap_dbbrowser_utils.c                          |  236 +++++--
 gap/gap_dbbrowser_utils.h                          |    7 +-
 gap/gap_filter.h                                   |    2 +-
 gap/gap_filter_foreach.c                           |   44 +-
 gap/gap_filter_main.c                              |   11 +-
 gap/gap_filter_pdb.h                               |    5 -
 gap/gap_fmac_main.c                                |    4 +-
 gap/gap_mod_layer.c                                |   71 ++-
 gap/gap_morph_exec.c                               |    3 +-
 gap/gap_mov_dialog.c                               |   73 +--
 gap/gap_mov_exec.c                                 |   66 +-
 gap/gap_story_att_trans_dlg.c                      |  104 +++-
 gap/gap_story_file.c                               |  300 ++++++---
 gap/gap_story_file.h                               |    5 +
 gap/gap_story_main.h                               |    8 +
 gap/gap_story_properties.c                         |  149 ++++-
 gap/gap_story_render_processor.c                   |  731 +++++++++++++-------
 gap/gap_story_render_types.h                       |   25 +-
 gap/gap_story_syntax.c                             |   14 +-
 libgapbase/gap_libgapbase.h                        |    9 +
 31 files changed, 2021 insertions(+), 682 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 04095be..a789b42 100755
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,64 @@
+2010-02-15 Wolfgang Hofer <hof gimp org>
+
+- acceleration graph widget changed. Now the widget knows the connected adjustment
+  and can handle refresh on changed value internally.
+  further provides setting the value with the mouse by click on the graph
+    Button 1 (LEFT):   sets value dependent from y position
+    Button 2 (MIDDLE): sets value 0 (acceleration OFF)
+    Button 3 (RIGHT):  sets value 1 (constant speed)
+
+- implementation for acceleration characteristic support im
+  storyboard transitions.
+
+- refactoring: moved multiple local definitions of the same macro MIX_VALUE
+  to one central module libgapbase/gap_libgapbase.h
+  (and renamed as GAP_BASE_MIX_VALUE)
+
+
+- alternative Rendering algorithm for STORYBOARD processing
+  scale, move operations where the result is larger than the frame in the composite image
+  are now handled by computing the affected (clipped) rectangle that will be visible on frame
+  after scale/move. Only this smaller part is copied, scaled and moved.
+  This shall use less resources and speeds up processing when scrolling or zooming images
+  that are larger than the resulting video frame size.
+
+   a first test, a zoom into a 1200 x 900 imgae rendered
+   to 110 frames of size 640 x 480 showed that render time of 1 min 30 sec
+   was nearly the same with or without that optimize feature .....
+   TODO ... further testing
+
+  * NEWS
+  * docs/reference/txt/gap-filterall-db-browser.txt
+  * docs/reference/txt/plug-in-gap-move-path.txt
+  * docs/reference/txt/plug-in-gap-storyboard-attr-prop.txt
+  * docs/reference/txt/plug-in-gap-storyboard-clip-prop.txt
+  * docs/reference/txt/STORYBOARD_FILE_DOC.txt
+
+  * libgapbase/gap_libgapbase.h
+
+  * gap/gap_accel_char.c [.h]
+  * gap/gap_accel_da.c [.h]
+  * gap/gap_dbbrowser_utils.c [.h]
+  * gap/gap_filter_foreach.c
+  * gap/gap_filter.h
+  * gap/gap_filter_main.c
+  * gap/gap_filter_pdb.h
+  * gap/gap_fmac_main.c
+  * gap/gap_mod_layer.c
+  * gap/gap_morph_exec.c
+  * gap/gap_mov_dialog.c
+  * gap/gap_mov_exec.c
+
+  * gap/gap_story_att_trans_dlg.c
+  * gap/gap_story_file.c [.h]
+  * gap/gap_story_main.h
+  * gap/gap_story_properties.c
+  * gap/gap_story_render_processor.c
+  * gap/gap_story_render_types.h.
+  * gap/gap_story_syntax.c
+
+
+
 2010-02-08 Wolfgang Hofer <hof gimp org>
 
 - the GIMP-GAP libavformat(libavcodec based video encoder
diff --git a/NEWS b/NEWS
index 75ada93..d395b06 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,28 @@
-Here is a short overview whats new in GIMP-GAP-2.5.0:
+Here is a short overview whats new in GIMP-GAP-2.7.0:
+-----------------------------------------------------
+(compared to gimp-gap release 2.6.0)
+
+- fixed a bug in the GAP ffmpeg encoder that resulted in lower quality
+  of the encoded video.
+  (disabled buggy pre conversion to yuv420P colormodel for the ffmpeg encoder.
+  now feeding RGB to the codec or convert with functions of the encoding engine)
+
+- GIMP-GAP now supports speed control of movements and other transitions
+  via Acceleation characteristic presets. Those presets are available
+  - in the MovePath tool
+  - in Storyboard transitions
+    and Storyboard filtemacro pair calls when applied with varying values.
+  - in animated filter calls with varying values.
+    relevant in Filter All Layers
+    and Modify Drames feature when applying a filter
+    
+    Th GAP dbbrowser now supports acceleration characteristic graph and spinbutton
+    (that replaces the "Apply Varying" button of older GIMP_GAP releases)
+
+- some other bugfixes (See ChangeLog for details)
+
+
+Here is a short overview whats new in GIMP-GAP-2.6.0:
 -----------------------------------------------------
 (compared to gimp-gap release 2.4.0)
 
@@ -52,7 +76,7 @@ Here is a short overview whats new in GIMP-GAP-2.5.0:
 - added wrapper for the resynthesizer
   (provides support for animated apply of the 3rd party plug-in resynthesizer)
 
-- external libs for vidoe read and write access
+- external libs for video read and write access
   were updated to ffmpeg-0.5 and libmpeg3-1.8
 
 - bugfixes and updates for the use with GIMP-2.6.x releases.(see ChangeLog for details)
diff --git a/docs/reference/txt/STORYBOARD_FILE_DOC.txt b/docs/reference/txt/STORYBOARD_FILE_DOC.txt
old mode 100644
new mode 100755
index f966cde..654d8cb
--- a/docs/reference/txt/STORYBOARD_FILE_DOC.txt
+++ b/docs/reference/txt/STORYBOARD_FILE_DOC.txt
@@ -1,4 +1,4 @@
-STORYBOARD_FILES           2007.09.05:
+STORYBOARD_FILES           2010.02.15:
 
 
 General
@@ -59,6 +59,8 @@ in the style:
 if no parametername key prefix is specified the fixed order of items
 is assumed. items must not contain blanks. (except blanks in "quoted strings")
 
+Note: you should not use this style without key that is just supported
+for backwards compatibility with old GIMP-GAP versions)
 
 
 Overview of supported RECORD TYPES:
@@ -90,7 +92,8 @@ VID_PLAY_MOVIE     track:1  file:"movie_filename"     from:0001  to:0099 \
 			     mask_anchor:clip \
 			     mask_stepsize:1.0 \
 			     mask_disable:n \
-			     macsteps:1
+			     macsteps:1 \
+			     macaccel
 
 VID_PLAY_ANIMIMAGE track:1  file:"image_filename"     from:0001 to:0099  \
                              mode:{pingpong|normal} \
@@ -102,7 +105,8 @@ VID_PLAY_ANIMIMAGE track:1  file:"image_filename"     from:0001 to:0099  \
 			     mask_anchor:clip \
 			     mask_stepsize:1.0 \
 			     mask_disable:n \
-			     macsteps:1
+			     macsteps:1 \
+			     macaccel
 
 VID_PLAY_FRAMES    track:1  base:"basename" ext:.jpg  from:0001 to:0099  \
                              mode:{pingpong|normal} \
@@ -114,7 +118,8 @@ VID_PLAY_FRAMES    track:1  base:"basename" ext:.jpg  from:0001 to:0099  \
 			     mask_anchor:clip \
 			     mask_stepsize:1.0 \
 			     mask_disable:n \
-			     macsteps:1
+			     macsteps:1 \
+			     macaccel
 
 VID_PLAY_IMAGE     track:1  file:"image_filename"    nloops:1 \
                              macro:"macro_filename"
@@ -123,7 +128,8 @@ VID_PLAY_IMAGE     track:1  file:"image_filename"    nloops:1 \
 			     mask_anchor:clip \
 			     mask_stepsize:1.0 \
 			     mask_disable:n \
-			     macsteps:1
+			     macsteps:1 \
+			     macaccel
 
 VID_PLAY_COLOR     track:1  red:0.0 green:1.0 blue:0.0 alpha:1.0   nloops:1 \
                              flip:n \
@@ -131,7 +137,8 @@ VID_PLAY_COLOR     track:1  red:0.0 green:1.0 blue:0.0 alpha:1.0   nloops:1 \
 			     mask_anchor:clip \
 			     mask_stepsize:1.0 \
 			     mask_disable:n \
-			     macsteps:1
+			     macsteps:1 \
+			     macaccel
 
 VID_SILENCE        track:1                                         nloops:1  wait_until_sec:0.0
 
@@ -322,7 +329,11 @@ VID_PLAY_MOVIE
  [19] macsteps:         ... an integer value greater or equal than 1.
                             Defines the (maximal) duration in number of frames
                             for applying filtermacros with varying values.
-                            Default: 1
+ [20] macaccel:         ... an integer value specifiying acceleration characteristic
+                            for applying filtermacros with varying values.
+                            where 1 changes filtersettings with constant speed.
+                            other positive values result in increasing speed, negative values
+                            result in decreasing speed.
 
 
 
@@ -355,6 +366,7 @@ VID_PLAY_ANIMIMAGE
  [13] mask_stepsize:    ... Same as described for VID_PLAY_MOVIE (see above)
  [14] mask_disable:     ... Same as described for VID_PLAY_MOVIE (see above)
  [15] macsteps:         ... Same as described for VID_PLAY_MOVIE (see above)
+ [16] macaccel:         ... Same as described for VID_PLAY_MOVIE (see above)
 
 
 
@@ -390,6 +402,7 @@ VID_PLAY_FRAMES
  [14] mask_stepsize:    ... Same as described for VID_PLAY_MOVIE (see above)
  [15] mask_disable:     ... Same as described for VID_PLAY_MOVIE (see above)
  [16] macsteps:         ... Same as described for VID_PLAY_MOVIE (see above)
+ [17] macaccel:         ... Same as described for VID_PLAY_MOVIE (see above)
 
 VID_PLAY_IMAGE
   fetch frame from a single imagefile. (Multilayer Images are handled as
@@ -408,6 +421,7 @@ VID_PLAY_IMAGE
   [9] mask_stepsize:    ... Same as described for VID_PLAY_MOVIE (see above)
  [10] mask_disable:     ... Same as described for VID_PLAY_MOVIE (see above)
  [11] macsteps:         ... Same as described for VID_PLAY_MOVIE (see above)
+ [12] macaccel:         ... Same as described for VID_PLAY_MOVIE (see above)
 
 
 
@@ -430,6 +444,7 @@ VID_PLAY_COLOR
  [10] mask_stepsize:    ... Same as described for VID_PLAY_MOVIE (see above)
  [11] mask_disable:     ... Same as described for VID_PLAY_MOVIE (see above)
  [12] macsteps:         ... Same as described for VID_PLAY_MOVIE (see above)
+ [13] macaccel:         ... Same as described for VID_PLAY_MOVIE (see above)
 
 VID_SILENCE
   This record is used to define Pauses in a videotrack. 
@@ -459,6 +474,13 @@ VID_OPACITY
                             in number of frames (integer) or seconds (float) 
                             The duration Value 0 applies the TO value immediate.
                             DEFAULT: 0
+  [6] accel             ... an integer value specifiying acceleration characteristic
+                            for speed behavior of opacity changes.
+                            where 1 (and 0) changes opacity with constant speed.
+                            other positive values result in increasing speed, negative values
+                            result in decreasing speed.
+                            DEFAULT: 0
+
 
 VID_ZOOM_X and VID_ZOOM_Y
   These records are used to define Zooming Effects
@@ -476,6 +498,12 @@ VID_ZOOM_X and VID_ZOOM_Y
                             in number of frames (integer 10) or seconds (float) 
                             The duration Value 0 applies the TO value immediate.
                             DEFAULT: 0
+  [6] accel             ... an integer value specifiying acceleration characteristic
+                            for speed behavior of zoom changes.
+                            where 1 (and 0) changes size with constant speed.
+                            other positive values result in increasing speed, negative values
+                            result in decreasing speed.
+                            DEFAULT: 0
 
 
 VID_MOVE_X and VID_MOVE_Y
@@ -496,6 +524,12 @@ VID_MOVE_X and VID_MOVE_Y
                             in number of frames (integer 10) or seconds (float) 
                             The duration Value 0 applies the TO value immediate.
                             DEFAULT: 0
+  [6] accel             ... an integer value specifiying acceleration characteristic
+                            for speed behavior of movents.
+                            where 1 (and 0) changes positions with constant speed.
+                            other positive values result in increasing speed, negative values
+                            result in decreasing speed.
+                            DEFAULT: 0
 
   Example:
     Assume we have video master size 320x200 pixels,
@@ -888,7 +922,7 @@ Audiorange:
 Macrofiles:
 ------------
   Macros can be used to perform a user defineable set of
-  one or more gimp procedures, such as 
+  one or more gimp procedures (plug-ins), such as 
     - color correction
     - sharpen / blur
     - transformations
@@ -917,7 +951,8 @@ Macrofiles:
   example:
   VID_PLAY_MOVIE track:1 file:"/vol1/videos/A.mpg" from:000001 to:000500 \
               macro:"/vol1/fmac/my_blur_macro.fmac" \
-              macsteps:200
+              macsteps:200 \
+              macaccel:10
               
   This example implicite referes to a second macrofile:
   
@@ -932,10 +967,14 @@ Macrofiles:
   Procesing for frame 000001 of the input video clip A.mpg 
   will apply the parameter values of the 1st macrofile.
   As processing continues, the influence of
-  the values defined in the 2nd macrofile grows. At fame 000200
-  (macsteps:200) the final value as defined in the 2nd macrofile
+  the values defined in the 2nd macrofile grows.
+  At fame 000200 (macsteps:200) the final value, as defined in the 2nd macrofile
   is reached, and will be used for all further frames of this video clip too
   (201 upto 500).
+  The speed of the change from settings in the 1st and the 2nd
+  macrofile depends on the specified acceleration characteristic
+  (macaccel:10) where 10 defines increasing speed.
+  Use value 1 for constant speed (e.g linear changing settings)
   
   Filtercalls in the 2nd macrofile that have no correlating pendent
   in the 1st macrofile are ignored. Filtercalls of the 1st
@@ -964,9 +1003,14 @@ Macrofiles:
    *   macrofile2:line 3.) correlates with macrofile1:line 4.)
 
   RESTRICTION:
-   - Applying filters with varying values is restricted
-     to filters that provide an iterator procedure
-     that handles the mix of filter specific prameter values.
+   - Applying filters (e.g plug-ins) with varying values is restricted
+     to filters that provide the capability to access
+     the filter specific prameter settings (typically stored as last values buffer in memory)
+     by either implementing an iterator procedure or registering
+     the structure of this last values buffer in the
+     configuration file lastval_descriptions.txt
+     
+     This allows GIMP-GAP to handles the mix of filter specific prameter values.
      (see also Filter->Filter all Layers)
      
   
diff --git a/docs/reference/txt/gap-filterall-db-browser.txt b/docs/reference/txt/gap-filterall-db-browser.txt
old mode 100644
new mode 100755
index 12965de..80e4f52
--- a/docs/reference/txt/gap-filterall-db-browser.txt
+++ b/docs/reference/txt/gap-filterall-db-browser.txt
@@ -18,26 +18,47 @@ Animated calls of plug-in filters:
   all available plug-ins in a listbox (and informations about
   the selected plug-in on the right side).
 
+
+  Select one of the listed plug-ins, then select acceleration characteristic
+  and press the Apply button to continue with the next dialog step.
+
   Note: The listbox does not show the full PDB, but
         only those plug-ins that are capable to run under control
 	of the "Filter all Layers" plug-in.
   
-  Select one of the listed plug-ins and press one of the buttons:
+        some of them are restricted for apply with a fixed setting
+        on all handled layers. for Those plug-ins the
+        Acceleration Characteristic spnbutton widget is disabled.
+        The other plug-ins are capable to be applied
+        with varying values and enable the spinbutton.
+
+  
+  "Acceleration Characteristic"
+      can be set with a spinbutton where you can enter a value.
+      A graph next to the spinbutton shows the selected characteristic.
+      The acceleration characteristic can also be changed by
+      clicking on th graph and dragging vertically with the mouse.
+
+      A straight line from left bottom to right top corner of the graph
+      is drawn for value 1 that represents constant speed.
+      (This is the same behavior as the "Apply Varying" button
+      worked in older GIMP-GAP releases 2.6 and earlier)
+      Positive values greater than 1 result in an accelerated
+      change of the settings, negative values result in decelerated
+      change of the settings.
 
-  "Apply Varying":
-      The selected plug-in is called 2 times in interactive mode,
+      With Acceleration Characteristic value other than 0
+      the selected plug-in is called 2 times in interactive mode,
       1. for the backround layer
       2. for the top layer.
+      This defines the settings at begin and at end.
       
       For all further layers, the plug-in will work non-interactive
-      with the iterated inbetween values.
-      Therefore the plug-in must have an "_Iterator" or "_Iterator_ALT"
-      procedure, to modify the "last stored values"
-       
-      (GIMP-GAP provides such procedures for more than 50 existing plug-ins)
+      with the iterated inbetween values that were internally stored in memory
+      as settings for begin and end, respecting the acceleration characteristic.
+      (constant speed, acceleration or deceleration) 
+      
       
-      If the iterator procedure is not available, the
-      "Apply Varying" button is set insensitive on the selected procedure.
       
       Note:
             It is possible to iterate values of the type PARAM_DRAWABLE,
@@ -48,11 +69,18 @@ Animated calls of plug-in filters:
             and the inbetween values for the non-interactive filtercalls
             will be the layers between the from and to layerstackindex.
             (an animation sequence as the user might expect)             
-  
-  "Apply Constant":
-      The selected plug-in is called only once in interactive mode,
+
+      
+      
+      With Acceleration Characteristic value 0 varying feature
+      is turned off, and the graph is rendered as empty rectangle.
+      In this case selected plug-in is called only once in interactive mode,
       For all further layers, the plug-in will work non-interactive
       using the last stored values.
+      (This is the same behavior as the "Apply Constant" button
+      worked in older GIMP-GAP releases 2.6 and earlier)
+      
+      
 
 
   The script sel-to-anim-img.scm simplifies the creation of animated
@@ -65,6 +93,33 @@ Animated calls of plug-in filters:
   on the generated new image.
 
   Notes:
+    - when new plug-ins are installed, they are
+      not automatically capable to be applying with varying values,
+      unless the plug-in implements an "_Iterator" procedure,
+      (see docs/howto/HOWTO-write-animated-plug-ins.txt)
+      or registers in the GIMP_GAP configuration file
+      
+        lastval_descriptions.txt 
+      
+      located in the gimp configuration directory
+      in your $HOME (uniX) or Documents and Settings (WindowsXP)
+
+      Here is an example entry for the wideangle 3rd party plug-in:      
+
+
+      # --------------------- 
+      "plug_in_wideangle" #- added manually 
+      STRUCT_BEGIN;0;48;1;
+        gdouble;0;8;1;centre_x
+        gdouble;8;8;1;centre_y
+        gdouble;16;8;1;square_a
+        gdouble;24;8;1;quad_a
+        gdouble;32;8;1;scale_a
+        gdouble;40;8;1;brighten
+      STRUCT_END;0;4;1;
+
+
+
     - Some plug-ins may not work correct or crash when called
       in NON_INTERACTIVE mode. (see TESTPROT_iter_ALT)
 
@@ -84,3 +139,7 @@ Animated calls of plug-in filters:
       In that case you can try to generate the needed _Iterator procedure
       for your plug-ins current interface by yourself.
       (see file: README_devlopers)
+
+
+
+
diff --git a/docs/reference/txt/plug-in-gap-move-path.txt b/docs/reference/txt/plug-in-gap-move-path.txt
old mode 100644
new mode 100755
index f90de81..6481f6f
--- a/docs/reference/txt/plug-in-gap-move-path.txt
+++ b/docs/reference/txt/plug-in-gap-move-path.txt
@@ -293,13 +293,13 @@ Move Path (make things move)
            
          
          - Speed:
-	   If no keyframes are set,
+	   If no keyframes are set, and acceleration characteristic value 0 is specified
            the "Move Path" plug-in alternates the settings linear from
            controlpoint to controlpoint, so things move (or happen) in constant speed
            between 2 controlpoints.
            
-           If you want to make accelerated moving obcets, you'll
-           have to set more controlpoints with growing distances.
+           If you want to make accelerated moving obcets, you
+           can set more controlpoints with growing distances.
            
            Example:
            
@@ -313,7 +313,93 @@ Move Path (make things move)
            but each part has another length. This results in different
            (growing) speeds for each part of the path.
            
+      Acceleration characteristic:
+      ---------------------------
            
+        Since GIMP-GAP-2.7 speed can be controled with acceleration
+        characteristic presets. Those presets are integer values
+        where value 1 defines constant speed along a path segment,
+        indepent to the distance between the controlpoints of the path segment.
+        (How to define path segments see chapter Keyframes below)
+        positive values result in acceleration, negative values in deceleration.
+        
+
+	        
+	0 ... implicite speed control, compatible to GAP 2.6.x and older releases
+	      (This is the default setting for all acceleration characteristic values)
+	      Each line between 2 contolpoints gets an equal time slot (e.g number of frames)
+	      The speed between 2 controlpoints is constant, but depends on the length of the line,
+	      where short lines result in low speed and long lines result in high speed.
+
+
+        For all other Acceleration characteristic values than 0
+        the line length between controlpoints does not affect
+        the speed of the moving object.
+
+
+        1        ... Constant Speed 
+                     object moves through a path segment with constant speed.
+                     A path segment includes all path lines beween two keyframes
+                     (note that first and last controlpoint are considered as keyframes
+                     without explicite keyframe value)
+                     
+                     In this mode the line length between controlpoints does not affect
+                     the speed of the moving object.
+
+        positive value ...Acceleration                 
+                     object moves through a path segment with increasing speed.
+                     higher values result in slower speed at start and higher speed at end
+                     of the path segment
+
+        positive value  ...Deceleration
+                     object moves through a path segment with decreasing speed.
+
+
+        Acceleration characteristic values can be specified independent for
+        o) Movement     ... Movent of the object
+        o) Opacity      ... To control speed of the opacity changes
+        o) Size         ... To control speed of size changes (e.g. zooming)
+        o) Rotation     ... To control speed of object rotation
+        o) Perspective  ... To control speed of object perspective transformations
+        o) FeatherRadius... To control speed of selection fether radius changes
+
+        Each of those values can be changed in the Acceleration Tab
+        with a spinbutton where you can enter a value.
+        A graph next to the spinbutton shows the selected acceleration characteristic curve.
+        The acceleration characteristic can also be changed by
+        clicking on th graph and dragging vertically with the mouse.
+	
+	A straight line from left bottom to right top corner of the graph
+	is drawn for value 1 that represents constant speed.
+        
+
+
+        Acceleration characteristics are only relevant on the 1st controlpoint, 
+        and controlpoints that are marked as KEYFRAME but not on other controlpoints.
+        For controlpoints that are not relevant, the spinbutton widgets in the
+        acceleration characteristic tab are disabled.
+
+        In case acceleration characteristic values != 0 are used for any other settings than movement
+        all controlpoint settings other than positionm (X/Y) of NON-keyframes are ignored.
+        (note that first and last controlpoint are
+         implicite keyframes and therefore always relevant)
+         
+        Example:
+           have a path with 10 controlpoints, none of them marked as keyframe
+           specifiy rotation 0 for first controlpoint, rotation 180 for the last
+           controlpoint and select both Acceleration characteristic for Movement
+           and Rotation value 1 (for constant speed)
+           
+           This settings move the object along the path of 10 points and rotate it
+           with constant speed from 0 to 180 degree, regardless what rotation settings
+           are define in controlpoints 2,3,4,5,6,7,8,9.
+
+        
+        Speed of the moving object can be controled for each segment of the path,
+        where a segment is the distance to the next KEYFRAME. In case there are no
+        explicite Keyframes the path has only one segment with full length
+        from the firtst to the last controlpoint.
+
            
     - Keyframes
         
@@ -331,11 +417,59 @@ Move Path (make things move)
 	Keyframes are shown as absolute frame number
 	in the "Move Path" dialog window, but they
 	are saved as relative values in the
-	pointfile.
+	controlpointfile.
 	(if start frame = 5
 	 and a keyframe is displayed as 7
 	 the keyframe is internally stored as 2 (7 - 5)
 	 
+	Keyframes are also used to define path segments.
+	Where a Path segment includes all followin controlpoints
+        until the next Keyframe.
+        
+        Independent acceleration characteristics can be set at
+        those controlpoints that are the begin of a path segment.
+        (e.g the 1st controlpoint and all keyframes)
+        
+        Example:
+          You have 500 frames and want to render an object
+          that stands still at coordinate 320/200 in the 1st 50 frames,
+          than accelerates until frame 150, moves with constant speed
+          until frame 400, decelerates until frame 450 and stays still
+          at coordinate 470/150 until the end frame 500.
+          
+          
+        
+        #Segment A  (standstill)
+        [ 0]  x:320 y:200
+
+        #Segment B  (increasing speed due to acceleration value 20 for Movement)
+        [ 1]  x:320 y:200  keyframe:50    acceleration Movement: 20
+        [ 2]  x:330 y:210
+        [ 3]  x:350 y:200
+        [ 4]  x:360 y:190
+
+        #Segment C  (move with constant speed due to acceleration value 1 for Movement)
+        [ 5]  x:362 y:170  keyframe:150   acceleration Movement: 1
+	[ 6]  ...
+	[ 7]  ...
+	[ 8]  ...
+	[ 9]  ...
+	[10]  ...       
+	
+        #Segment D  (decreasing speed due to acceleration value -15 for Movement)
+        [11]  x:500 y:150  keyframe:400   acceleration Movement: -15
+        [12]  x:490 y:160
+        [13]  x:475 y:155
+        [14]  x:475 y:155
+
+        #Segment D  (standstill)
+        [15]  x:470 y:150  keyframe:450
+        [16]  x:470 y:150
+
+
+
+	 
+	 
      - Checking Controlpoints
         - The check is done at "OK", and "Anim Preview"
 	  button,
@@ -387,7 +521,7 @@ Move Path (make things move)
 
 
     "Move Path" advanced settings
-    --------------------------
+    -----------------------------
     
     - Bluebox
          With the bluebox check_button you can apply the bluebox filter effect
diff --git a/docs/reference/txt/plug-in-gap-storyboard-attr-prop.txt b/docs/reference/txt/plug-in-gap-storyboard-attr-prop.txt
old mode 100644
new mode 100755
index 932a3bc..48bd195
--- a/docs/reference/txt/plug-in-gap-storyboard-attr-prop.txt
+++ b/docs/reference/txt/plug-in-gap-storyboard-attr-prop.txt
@@ -55,7 +55,20 @@ Transition Attributes (Storyboard)
      
     Frames:
       Duration of the transition effect measured in frames.
-      
+
+    Acceleration Characteristic:
+      A Spinbutton and a graph widget
+      is available to enter and display the acceleration characteristc value
+      in each row (for Opacity, MoveX, MoveY, ScaleWidht and ScaleHeight)
+      The graph next to the spinbutton shows the selected acceleration characteristic curve.
+      The acceleration characteristic can also be changed by
+      clicking on th graph and dragging vertically with the mouse.
+      	
+      A straight line from left bottom to right top corner of the graph
+      is drawn for value 1 that represents constant speed.
+      other positive values result in increasing speed of the transition,
+      negative values result in decreasing speed.
+
       
     Comment:
       An optional comment text on the transition.
diff --git a/docs/reference/txt/plug-in-gap-storyboard-clip-prop.txt b/docs/reference/txt/plug-in-gap-storyboard-clip-prop.txt
old mode 100644
new mode 100755
index 624c540..19da3fa
--- a/docs/reference/txt/plug-in-gap-storyboard-clip-prop.txt
+++ b/docs/reference/txt/plug-in-gap-storyboard-clip-prop.txt
@@ -89,10 +89,111 @@ Clip Properties (Storyboard)
         the deinterlace filter is only available for clip type
         MOVIE.
 
+    Transform:
+      Provides frame orientation transformations that are applied on frames
+      of this clip.
+      
+      The transform radio buttons are:
+      
+      "None"
+         keep the original frame orientation
+      
+      "Rotate 180"
+         rotate the frames of this clip by 180 degree
+      
+      "Flip Horizontally"
+         horizontally mirror the frames of this clip
+      
+      "Flip Vertically"
+         vertically mirror the frames of this clip
+      
+
+
     Duration:
       Information about the duration of the clip in frames
       and playtime in format mm:ss:msec
       
+
+
+    Mask:
+      Individual transparency foreach frame of the clip
+      can be added by selecting a mask.
+      Important:
+      You must define (at least one) Mask clip in the Mask Section of the Storyboard
+      before you can assign a mask to a clip.
+      
+      The mask can be assigned to clip or master.
+      
+      o) Clip    ... the mask is scaled to the size of the fetched frame of the clip
+                     and attached as additional transparency
+                     before transitions (move and scale) are applied.
+                     Eg. the mask moves and scales with the clip.
+      
+      o) Master ... the mask is scaled to the size of the resulting frame
+                    and attached after transitions (move and scale) were already applied.
+                    E.g the mask is fixed in size and position.
+
+
+      Mask Stepsize:
+        In case the assigned mask clip is an animation (and not a sinle image),
+        the mask stepsize controls how to advance to the next mask frame.
+        Where a value of 2.0 speeds up the mask effect (by skipping
+        every 2nd frame in the assigned mask clip)
+        A value of 0.5 will slow down the mask effect.
+        Use value 1.0 for normal speed for mask effect.
+
+
+    Filtermacro:
+       Here you can specify the filename of a GIMP-GAP filtermacro
+       that shall be applied for each frame of this clip.
+       
+       see plug-in-filter-macro.txt how to record filtermacros
+       and STORYBOARD_FILE_DOC.txt chapter Macrofiles for more details.
+    
+       Filtermacro Steps:
+         Here you can enter the duration in number of frames for the transition
+         of settings from filtermacro to settings of a 2nd filtermacro
+         (in case a 2nd filtermacro is available)
+       
+         Use value 1 to apply just constant settings of the 1st filtermacro
+         (if a 2nd filtermacro is available it will be ignored
+         and its name will be displayed with the prefix "OFF")
+
+       Note that filtermacro effects are not automatically visible
+       in standard playback of the Storyboard dialog.
+       You must use the playback based on full rendering
+       to preview those effects.
+      
+       
+
+    Filtermacro2:
+       For applying filtermacros with varing values you need a 2nd
+       filtermacro file.
+       The 2nd filtermacro file is automatically identified via naming convention
+       and can NOT be specified explicite. Its name is diplayed read only
+       when such a file is available, and prefixed with "ON" when active
+       or "OFF" when disabled (e.g duration of 1 frame is specified)
+       
+       
+       see STORYBOARD_FILE_DOC.txt chapter Macrofiles for details
+       about applying filtermacros with varying values.
+
+       Acceleration Characteristic for applying filtermacro with varying values:
+       A Spinbutton and a graph widget
+       is available to enter and display the acceleration characteristc value
+       The graph next to the spinbutton shows the selected acceleration characteristic curve.
+       The acceleration characteristic can also be changed by
+       clicking on th graph and dragging vertically with the mouse.
+      	
+       A straight line from left bottom to right top corner of the graph
+       is drawn for value 1 that represents constant speed.
+       other positive values result in increasing speed of the transition,
+       negative values result in decreasing speed.
+
+
+
+
+
     Comment:
       An optional comment text on the clip.
 
diff --git a/gap/gap_accel_char.c b/gap/gap_accel_char.c
old mode 100644
new mode 100755
index 9ff6fe9..ef4cdfb
--- a/gap/gap_accel_char.c
+++ b/gap/gap_accel_char.c
@@ -45,7 +45,7 @@
  *  1 specified constant speed
  *
  * positive values > 1 represent acceleration, 
- + negative values < -1  for deceleration
+ * negative values < -1  for deceleration
  *
  * orig_factor: a positive gdouble in the range 0.0 to 1.0
  * returns modified mix_factor in the range 0.0 to 1.0 according to specified accelCharacteristic
@@ -80,3 +80,40 @@ gap_accelMixFactor(gdouble orig_factor, gint accelCharacteristic)
 
   return (mix);  
 }  /* end gap_accelMixFactor */
+
+
+/* ---------------------------------------
+ * gap_accel_calculate_current_step
+ * ---------------------------------------
+ * calculate current step respecting the specified accelration characteristic
+ */
+gdouble
+gap_calculate_current_step_with_acceleration(gdouble current_step, gint32 total_steps, gint accelCharacteristic)
+{
+  gdouble currentStepClamped;
+  gdouble accelStep;
+
+  if (total_steps <= 0)
+  {
+    return (current_step);
+  }
+  currentStepClamped = CLAMP(current_step, 0.0, (gdouble)total_steps);
+  
+  switch (accelCharacteristic)
+  {
+    case 0:
+    case 1:
+    case -1:
+      return (currentStepClamped);
+      break;
+    default:
+      accelStep = gap_accelMixFactor(currentStepClamped / (gdouble)total_steps, accelCharacteristic);
+      break;
+  }
+
+  return (accelStep * (gdouble)total_steps);
+
+}  /* end gap_calculate_current_step_with_acceleration */
+
+
+
diff --git a/gap/gap_accel_char.h b/gap/gap_accel_char.h
old mode 100644
new mode 100755
index 5249748..4604ee5
--- a/gap/gap_accel_char.h
+++ b/gap/gap_accel_char.h
@@ -31,18 +31,30 @@
 #include <libgimp/gimp.h>
 
 
+#define GAP_ACCEL_CHAR_NONE     0
+#define GAP_ACCEL_CHAR_LINEAR   1
+#define GAP_ACCEL_CHAR_MIN     -100
+#define GAP_ACCEL_CHAR_MAX      100
+
+
 /* ---------------------------------------
  * gap_accelMixFactor
  * ---------------------------------------
  * this proecdure implements hardcoded acceleration characteristics.
- *     
+ *
  * accelCharacteristic: 0 and 1 for linear, positive values for acceleration, negative values for deceleration
  *
  * orig_factor: a positive gdouble in the range 0.0 to 1.0
  * returns modified mix_factor in the range 0.0 to 1.0 according to specified accelCharacteristic
  */
-gdouble 
-gap_accelMixFactor(gdouble orig_factor, gint accelCharacteristic);
+gdouble   gap_accelMixFactor(gdouble orig_factor, gint accelCharacteristic);
+
+/* ---------------------------------------
+ * gap_accel_calculate_current_step
+ * ---------------------------------------
+ * calculate current step respecting the specified accelration characteristic
+ */
+gdouble   gap_calculate_current_step_with_acceleration(gdouble current_step, gint32 total_steps, gint accelCharacteristic);
 
 
 #endif
diff --git a/gap/gap_accel_da.c b/gap/gap_accel_da.c
index 54d1281..72699b1 100644
--- a/gap/gap_accel_da.c
+++ b/gap/gap_accel_da.c
@@ -50,9 +50,19 @@ extern int gap_debug;  /* 1 == print debug infos , 0 dont print debug infos */
 
 
 #define GRAPH_RADIUS           3
-
-
-static gint  gap_accel_repaint (GtkWidget *, GdkEvent *,
+#define GRAPH_MASK  GDK_EXPOSURE_MASK | \
+                    GDK_POINTER_MOTION_MASK | \
+                    GDK_POINTER_MOTION_HINT_MASK | \
+                    GDK_ENTER_NOTIFY_MASK | \
+                    GDK_BUTTON_PRESS_MASK | \
+                    GDK_BUTTON_RELEASE_MASK | \
+                    GDK_BUTTON1_MOTION_MASK
+
+
+static void    p_accel_value_changed_cb(GtkObject *obj, GapAccelWidget *accel_wgt);
+static gfloat  p_calculate_accelCharacteristic_from_Position(GapAccelWidget *accel_wgt);
+static gint    p_accel_event_callback(GtkWidget *wgt, GdkEvent *evt,  GapAccelWidget *accel_wgt);
+static gint    gap_accel_repaint (GtkWidget *, GdkEvent *,
                                 GapAccelWidget *);
 
 /* ------------------------------
@@ -62,68 +72,216 @@ static gint  gap_accel_repaint (GtkWidget *, GdkEvent *,
  * (for transparent pixels)
  */
 GapAccelWidget *
-gap_accel_new(gint width, gint height, gint accelerationCharacteristic)
+gap_accel_new(gint width, gint height, gint32 accelerationCharacteristic)
 {
-  GapAccelWidget *accel_ptr;
-  
+  return (gap_accel_new_with_adj(width, height, accelerationCharacteristic, NULL));
+}  /* end gap_accel_new */
+
+/* ------------------------------
+ * gap_pview_new
+ * ------------------------------
+ * pv_check_size is checkboard size in pixels
+ * (for transparent pixels)
+ */
+GapAccelWidget *
+gap_accel_new_with_adj(gint width, gint height, gint32 accelerationCharacteristic, GtkObject *adj)
+{
+  GapAccelWidget *accel_wgt;
  
-  accel_ptr = g_malloc0(sizeof(GapAccelWidget));
+  accel_wgt = g_malloc0(sizeof(GapAccelWidget));
 
-  accel_ptr->accelerationCharacteristic = accelerationCharacteristic;
-  accel_ptr->width = width;
-  accel_ptr->height = height;
-  accel_ptr->pixWidth = accel_ptr->width + GRAPH_RADIUS * 4;
-  accel_ptr->pixHeight = accel_ptr->height+ GRAPH_RADIUS * 4;
+  accel_wgt->accelerationCharacteristic = accelerationCharacteristic;
+  accel_wgt->width = width;
+  accel_wgt->height = height;
+  accel_wgt->pixWidth = accel_wgt->width + GRAPH_RADIUS * 4;
+  accel_wgt->pixHeight = accel_wgt->height+ GRAPH_RADIUS * 4;
+  accel_wgt->isButton1Pressed = FALSE;
 
+  if (adj == NULL)
+  {
+    adj = gtk_adjustment_new ( accelerationCharacteristic
+                           , GAP_ACCEL_CHAR_MIN
+                           , GAP_ACCEL_CHAR_MAX
+                           , 1
+                           , 10
+                           , 0
+                           );
+  }
+  accel_wgt->adj = adj;
 
-  accel_ptr->da_widget = gtk_drawing_area_new ();
-  gtk_widget_set_size_request (accel_ptr->da_widget
-                              , accel_ptr->pixWidth
-                              , accel_ptr->pixHeight
+  accel_wgt->da_widget = gtk_drawing_area_new ();
+  gtk_widget_set_size_request (accel_wgt->da_widget
+                              , accel_wgt->pixWidth
+                              , accel_wgt->pixHeight
                               );
 
-  gtk_widget_set_events (accel_ptr->da_widget, GDK_EXPOSURE_MASK);
+  gtk_widget_set_events (accel_wgt->da_widget, GRAPH_MASK);
+  gtk_widget_show (accel_wgt->da_widget);
 
-/*
-  gtk_container_add (GTK_CONTAINER (abox), accel_ptr->da_widget);
-  gtk_widget_show (accel_ptr->da_widget);
-*/
+  g_signal_connect (accel_wgt->da_widget, "event",
+                    G_CALLBACK (p_accel_event_callback),
+                    accel_wgt);
 
-  g_signal_connect (accel_ptr->da_widget, "event",
-                    G_CALLBACK (gap_accel_repaint),
-                    accel_ptr);
+  g_signal_connect (G_OBJECT (adj), "value_changed",
+                      G_CALLBACK (p_accel_value_changed_cb),
+                      accel_wgt);
 
+  return(accel_wgt);
+}  /* end gap_pview_new */
 
 
+/* ---------------------------------------------
+ * p_calculate_accelCharacteristic_from_Position
+ * ---------------------------------------------
+ */
+static gfloat
+p_calculate_accelCharacteristic_from_Position(GapAccelWidget *accel_wgt)
+{
+  int tx, ty;
+  gdouble  x, y;
+  gfloat   accelValueFlt;
 
-  return(accel_ptr);
-}  /* end gap_pview_new */
+  /* init with current value as default */
+  accelValueFlt = (gfloat)accel_wgt->accelerationCharacteristic;
+  
+  if(accel_wgt->da_widget != NULL)
+  {
+    if(accel_wgt->da_widget->window != NULL)
+    {
+        /*  get the pointer position  */
+        gdk_window_get_pointer (accel_wgt->da_widget->window, &tx, &ty, NULL);
+
+        x = CLAMP ((tx - GRAPH_RADIUS), 0, accel_wgt->width);
+        y = CLAMP ((ty - GRAPH_RADIUS), 0, accel_wgt->height);
+
+
+        accelValueFlt = y / (MAX(1.0, accel_wgt->height));
+        accelValueFlt = (accelValueFlt * 200) - 100;
+        if((accelValueFlt < 1.0) && (accelValueFlt > -1.0))
+        {
+          /* value 0 is replaced by 1 (because 0 turns off acceleration completely
+           * and this shall not happen when picking the value)
+           */
+          accelValueFlt = 1.0;
+        }
+    }
+  }
 
+  
+  return (accelValueFlt);
+}  /* end p_calculate_accelCharacteristic_from_Position */
+
+
+/* -------------------------------
+ * p_accel_value_changed_cb
+ * -------------------------------
+ */
+static void
+p_accel_value_changed_cb(GtkObject *obj, GapAccelWidget *accel_wgt)
+{
+  gint32 accelerationCharacteristic;
 
+  if(obj)
+  {
+    accelerationCharacteristic = (GTK_ADJUSTMENT(obj)->value);
 
+    /* refresh the acceleration graph */
+    if(accel_wgt == NULL)
+    {
+      if(gap_debug)
+      {
+        printf("p_accel_value_changed_cb: accel_wgt is NULL\n");
+      }
+    }
+    else
+    {
+      gap_accel_render (accel_wgt, accelerationCharacteristic);
+    }
+
+  }
+}  /* end p_accel_value_changed_cb */
+
+   
+    
 /* ------------------------------
  * gap_accel_render
  * ------------------------------
  */
 void
-gap_accel_render (GapAccelWidget *accel_ptr, gint accelerationCharacteristic)
+gap_accel_render (GapAccelWidget *accel_wgt, gint32 accelerationCharacteristic)
 {
-  accel_ptr->accelerationCharacteristic = accelerationCharacteristic;
-  gap_accel_repaint(NULL, NULL, accel_ptr);
+  accel_wgt->accelerationCharacteristic = accelerationCharacteristic;
+  gap_accel_repaint(NULL, NULL, accel_wgt);
 }
 
 /* ------------------------------
+ * p_accel_event_callback
+ * ------------------------------
+ */
+static gint
+p_accel_event_callback(GtkWidget *wgt, GdkEvent *event,
+  GapAccelWidget *accel_wgt)
+{
+  GdkEventButton *bevent;
+
+  switch (event->type)
+  {
+    case GDK_EXPOSE:
+      gap_accel_repaint(wgt, event, accel_wgt);
+      break;
+
+    case GDK_BUTTON_PRESS:
+      bevent = (GdkEventButton *) event;
+      if ((bevent != NULL) && (accel_wgt->adj != NULL))
+      {
+        switch (bevent->button)
+        {
+          case 1:
+            accel_wgt->isButton1Pressed = TRUE;
+            gtk_adjustment_set_value(accel_wgt->adj, p_calculate_accelCharacteristic_from_Position(accel_wgt));
+            break;
+          case 2:
+            gtk_adjustment_set_value(accel_wgt->adj, (gfloat)0.0);
+            break;
+          case 3:
+            gtk_adjustment_set_value(accel_wgt->adj, (gfloat)1.0);
+            break;
+        }
+      }
+      break;
+
+    case GDK_BUTTON_RELEASE:
+      accel_wgt->isButton1Pressed = FALSE;
+      break;
+
+    case GDK_MOTION_NOTIFY:
+      if(accel_wgt->isButton1Pressed == TRUE)
+      {
+        gtk_adjustment_set_value(accel_wgt->adj, p_calculate_accelCharacteristic_from_Position(accel_wgt));
+      }
+      break;
+
+    default:
+      break;
+  }
+
+  return FALSE;
+}  /* end p_accel_event_callback */
+
+
+/* ------------------------------
  * gap_accel_repaint
  * ------------------------------
  */
 static gint
 gap_accel_repaint(GtkWidget *wgt, GdkEvent *evt,
-  GapAccelWidget *accel_ptr)
+  GapAccelWidget *accel_wgt)
 {
   GtkStyle *graph_style;
+  gint32    accelerationCharacteristic;
   gint      i;
 
-  if(accel_ptr->da_widget == NULL)
+  if(accel_wgt->da_widget == NULL)
   {
      if(gap_debug)
      {
@@ -131,7 +289,7 @@ gap_accel_repaint(GtkWidget *wgt, GdkEvent *evt,
      }
      return (FALSE);
   }
-  if(accel_ptr->da_widget->window == NULL)
+  if(accel_wgt->da_widget->window == NULL)
   {
      if(gap_debug)
      {
@@ -140,36 +298,37 @@ gap_accel_repaint(GtkWidget *wgt, GdkEvent *evt,
      return (FALSE);
   }
 
+  accelerationCharacteristic = accel_wgt->accelerationCharacteristic;
   
-  graph_style = gtk_widget_get_style (accel_ptr->da_widget);
+  graph_style = gtk_widget_get_style (accel_wgt->da_widget);
   
   
   /*  Clear the pixmap  */
-  gdk_draw_rectangle (accel_ptr->da_widget->window, graph_style->bg_gc[GTK_STATE_NORMAL],
-                      TRUE, 0, 0, accel_ptr->pixWidth, accel_ptr->pixHeight);
+  gdk_draw_rectangle (accel_wgt->da_widget->window, graph_style->bg_gc[GTK_STATE_NORMAL],
+                      TRUE, 0, 0, accel_wgt->pixWidth, accel_wgt->pixHeight);
 
 
   /*  Draw the grid lines (or just outline if acceleration is not active */
   for (i = 0; i < 5; i++)
   {
-      if ((i == 0) || (i==4) || (accel_ptr->accelerationCharacteristic != 0))
+      if ((i == 0) || (i==4) || (accelerationCharacteristic != 0))
       {
         gdouble xf;
         gdouble yf;
         gint    xi;
         gint    yi;
         
-        xf = (gdouble)i * ((gdouble)accel_ptr->width / 4.0);
-        yf = (gdouble)i * ((gdouble)accel_ptr->height / 4.0);
+        xf = (gdouble)i * ((gdouble)accel_wgt->width / 4.0);
+        yf = (gdouble)i * ((gdouble)accel_wgt->height / 4.0);
         xi = xf;
         yi = yf;
         
-        gdk_draw_line (accel_ptr->da_widget->window, graph_style->dark_gc[GTK_STATE_NORMAL],
+        gdk_draw_line (accel_wgt->da_widget->window, graph_style->dark_gc[GTK_STATE_NORMAL],
                      GRAPH_RADIUS, yi + GRAPH_RADIUS,
-                     accel_ptr->width + GRAPH_RADIUS, yi + GRAPH_RADIUS);
-        gdk_draw_line (accel_ptr->da_widget->window, graph_style->dark_gc[GTK_STATE_NORMAL],
+                     accel_wgt->width + GRAPH_RADIUS, yi + GRAPH_RADIUS);
+        gdk_draw_line (accel_wgt->da_widget->window, graph_style->dark_gc[GTK_STATE_NORMAL],
                      xi + GRAPH_RADIUS, GRAPH_RADIUS,
-                     xi + GRAPH_RADIUS, accel_ptr->height + GRAPH_RADIUS);
+                     xi + GRAPH_RADIUS, accel_wgt->height + GRAPH_RADIUS);
 
       }
   }
@@ -178,24 +337,27 @@ gap_accel_repaint(GtkWidget *wgt, GdkEvent *evt,
   /*  Draw the the acceleration curve according to accelerationCharacteristic
    *  when acceleration is active 
    */
-  if(accel_ptr->accelerationCharacteristic != 0)
+  if(accelerationCharacteristic != 0)
   {
        gdouble xFactor;
        gdouble yFactor;
        gdouble yF;
+       gint px, py;
        
+       px = 0;
+       py = 0;
        /*  Draw the active curve  */
-       for (i = 0; i < accel_ptr->width; i++)
+       for (i = 0; i < accel_wgt->width; i++)
        {
-           gint cx, cy, px, py;
+           gint cx, cy;
          
-           xFactor = (gdouble)i / (MAX(1.0, (gdouble)accel_ptr->width));
-           yFactor = gap_accelMixFactor(xFactor,  accel_ptr->accelerationCharacteristic);
-           yF = (gdouble)accel_ptr->height * yFactor;
+           xFactor = (gdouble)i / (MAX(1.0, (gdouble)accel_wgt->width));
+           yFactor = gap_accelMixFactor(xFactor,  accelerationCharacteristic);
+           yF = (gdouble)accel_wgt->height * yFactor;
 
 
            cx = i + GRAPH_RADIUS;
-           cy = (accel_ptr->height) - yF  + GRAPH_RADIUS;
+           cy = (accel_wgt->height) - yF  + GRAPH_RADIUS;
            
            if(gap_debug)
            {
@@ -209,7 +371,7 @@ gap_accel_repaint(GtkWidget *wgt, GdkEvent *evt,
            }
            if(i>0)
            {
-              gdk_draw_line (accel_ptr->da_widget->window, graph_style->black_gc,
+              gdk_draw_line (accel_wgt->da_widget->window, graph_style->black_gc,
                      px, py,
                      cx, cy
                      );
@@ -217,6 +379,7 @@ gap_accel_repaint(GtkWidget *wgt, GdkEvent *evt,
            px = cx;
            py = cy;
        }
+
   }
 
   return FALSE;
diff --git a/gap/gap_accel_da.h b/gap/gap_accel_da.h
index 546da08..a3cf53a 100644
--- a/gap/gap_accel_da.h
+++ b/gap/gap_accel_da.h
@@ -34,17 +34,19 @@
 
 typedef struct GapAccelWidget
 {
+  GtkObject *adj;
   GtkWidget *da_widget;                    /* the graph drawing_area */
-  gint       accelerationCharacteristic;
+  gint32     accelerationCharacteristic;
   gint       width;
   gint       height;
   gint       pixWidth;
   gint       pixHeight;
+  gboolean   isButton1Pressed;
   
 } GapAccelWidget;
 
-GapAccelWidget   *gap_accel_new(gint width, gint height, gint accelerationCharacteristic);
-
-void       gap_accel_render (GapAccelWidget *accel_ptr, gint accelerationCharacteristic);
+GapAccelWidget   *gap_accel_new(gint width, gint height, gint32 accelerationCharacteristic);
+GapAccelWidget   *gap_accel_new_with_adj(gint width, gint height, gint32 accelerationCharacteristic, GtkObject *adj);
+void              gap_accel_render (GapAccelWidget *accel_wgt, gint32 accelerationCharacteristic);
 
 #endif
diff --git a/gap/gap_dbbrowser_utils.c b/gap/gap_dbbrowser_utils.c
old mode 100644
new mode 100755
index 2ff23be..6839a36
--- a/gap/gap_dbbrowser_utils.c
+++ b/gap/gap_dbbrowser_utils.c
@@ -57,6 +57,8 @@
 #include "gap_match.h"
 #include "gap_pdb_calls.h"
 #include "gap_dbbrowser_utils.h"
+#include "gap_accel_char.h"
+#include "gap_accel_da.h"
 #include "gap-intl.h"
 
 
@@ -98,8 +100,13 @@ typedef struct
 
   /* GAP DB-Browser specific items */
   gchar            *selected_menu_path;
-  GtkWidget* app_const_button;
-  GtkWidget* app_vary_button;
+  GtkWidget        *app_const_button;
+  GapAccelWidget   *accel_wgt;
+  GtkObject        *accel_adj;
+  GtkWidget        *accel_spinbutton;
+  GtkWidget        *accel_hbox;
+
+
   GtkWidget* menupath_button;
 
   t_constraint_func      constraint_func;
@@ -114,8 +121,8 @@ typedef struct
 
 /* local functions */
 
-static const gchar * GParamType_to_string         (GimpPDBArgType   type);
-static const gchar * GimpPDBProcType_to_string    (GimpPDBProcType  type);
+//static const gchar * GParamType_to_string         (GimpPDBArgType   type);
+//static const gchar * GimpPDBProcType_to_string    (GimpPDBProcType  type);
 
 
 static void         procedure_select_callback    (GtkTreeSelection  *sel,
@@ -135,13 +142,13 @@ static void         dialog_num_button_callback   (dbbrowser_t* dbbrowser,
                                                   gint button_nr);
 static void         dialog_button_1_callback     (GtkWidget *widget,
                                                   dbbrowser_t* dbbrowser);
-static void         dialog_button_2_callback     (GtkWidget *widget,
-                                                  dbbrowser_t* dbbrowser);
 static void         dialog_button_3_callback     (GtkWidget *widget,
                                                   dbbrowser_t* dbbrowser);
+static void         p_accel_spinbutton_callback  (GtkObject *obj, dbbrowser_t* dbbrowser);
+
 static void         p_create_action_area_buttons (dbbrowser_t *dbbrowser,
                                                   char *button_1_txt,
-                                                  char *button_2_txt,
+                                                  gboolean showAccelerationCharacteristic,
                                                   const char *help_id
                                                 );
 
@@ -149,7 +156,7 @@ static void         p_create_action_area_buttons (dbbrowser_t *dbbrowser,
 int 
 gap_db_browser_dialog(char *title_txt,
                       char *button_1_txt,
-                      char *button_2_txt,
+                      gboolean                 showAccelerationCharacteristic,
                       t_constraint_func        constraint_func,
                       t_constraint_func        constraint_func_sel1,
                       t_constraint_func        constraint_func_sel2,
@@ -271,7 +278,7 @@ gap_db_browser_dialog(char *title_txt,
 
 
   /* GAP specific buttons in dialog->action_aera */
-  p_create_action_area_buttons(dbbrowser, button_1_txt, button_2_txt, help_id);
+  p_create_action_area_buttons(dbbrowser, button_1_txt, showAccelerationCharacteristic, help_id);
 
 
   /* now build the list */
@@ -305,6 +312,14 @@ gap_db_browser_dialog(char *title_txt,
   gtk_main ();
   gdk_flush ();
 
+
+  if(gap_debug)
+  {
+    printf("gap_db_browser_dialog: result accelCharacteristic:%d\n"
+       , (int)dbbrowser->result->accelCharacteristic
+       );
+  }
+
   return  (dbbrowser->result->button_nr);
 } /* end gap_db_browser_dialog */
 
@@ -312,7 +327,7 @@ gap_db_browser_dialog(char *title_txt,
 static void
 p_create_action_area_buttons(dbbrowser_t *dbbrowser,
                              char *button_1_txt,
-                             char *button_2_txt,
+                             gboolean  showAccelerationCharacteristic,
                              const char *help_id
                             )
 {
@@ -379,6 +394,67 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
 
 
   row++;
+
+  /* the Acceleration characteristic value spinbutton and graph */
+  if (showAccelerationCharacteristic) 
+  {
+    GapAccelWidget  *accel_wgt;
+    GtkObject       *adj;
+    GtkWidget       *spinbutton;
+    gint32           accelerationCharacteristic;
+
+#define ACC_WGT_WIDTH 34
+#define ACC_WGT_HEIGHT 30
+
+    dbbrowser->accel_hbox = gtk_hbox_new (FALSE, 1);
+    gtk_widget_show (dbbrowser->accel_hbox);
+    gtk_table_attach_defaults (GTK_TABLE(table), dbbrowser->accel_hbox, cof, cof+1, row, row + 1);
+
+    accelerationCharacteristic = 0;
+    if(dbbrowser->result != NULL)
+    {
+      accelerationCharacteristic = dbbrowser->result->accelCharacteristic;
+    }
+
+    /* the acceleration characteristic graph display widget */
+
+    accel_wgt = gap_accel_new(ACC_WGT_WIDTH, ACC_WGT_HEIGHT, accelerationCharacteristic);
+    gtk_box_pack_start (GTK_BOX (dbbrowser->accel_hbox), accel_wgt->da_widget, FALSE, FALSE, 1);
+    gtk_widget_show (accel_wgt->da_widget);
+  
+    adj = accel_wgt->adj;
+
+    /* the Acceleration characteristic value spinbutton */
+    spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
+    dbbrowser->accel_adj = adj;
+    dbbrowser->accel_spinbutton = spinbutton;
+
+    gtk_widget_show (spinbutton);
+    
+    gtk_box_pack_start (GTK_BOX (dbbrowser->accel_hbox), spinbutton, TRUE, TRUE, 1);
+    gtk_widget_set_size_request (spinbutton, 50, -1);
+    gimp_help_set_help_data (spinbutton, _("acceleration characteristic for filter apply 0=constant, 1 varying with constant speed, positive accelerate, negative decelerate"), NULL);
+
+    g_object_set_data(G_OBJECT(adj), "dbbrowser", dbbrowser);
+
+    g_signal_connect (G_OBJECT (dbbrowser->accel_adj), "value_changed",
+                      G_CALLBACK (p_accel_spinbutton_callback),
+                      dbbrowser);
+
+
+    dbbrowser->accel_wgt = accel_wgt;
+  } 
+  else
+  { 
+    dbbrowser->accel_adj = NULL;
+    dbbrowser->accel_spinbutton = NULL;
+  
+    dbbrowser->accel_hbox = gtk_hbox_new (FALSE, 1);
+    gtk_widget_show (dbbrowser->accel_hbox);
+    gtk_table_attach_defaults (GTK_TABLE(table), dbbrowser->accel_hbox, cof, cof+1, row, row + 1);
+  
+  }
+
   /* Button1 (Apply Constant) */
   if (button_1_txt) {
     dbbrowser->app_const_button = gtk_button_new_with_label (button_1_txt);
@@ -386,24 +462,12 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
     g_signal_connect (G_OBJECT (dbbrowser->app_const_button), "clicked",
                         G_CALLBACK (dialog_button_1_callback), dbbrowser );
     gtk_table_attach (GTK_TABLE (table), dbbrowser->app_const_button,
-                      cof, cof+1, row, row + 1, 
+                      cof+1, cof+2, row, row + 1, 
                       GTK_FILL, 0, 0, 0);
     gtk_widget_set_sensitive (dbbrowser->app_const_button, FALSE);
     gtk_widget_show (dbbrowser->app_const_button);
   } else dbbrowser->app_const_button = NULL;
 
-  /* Button1 (Apply Varying) */
-  if (button_2_txt) {
-    dbbrowser->app_vary_button = gtk_button_new_with_label (button_2_txt);
-    GTK_WIDGET_SET_FLAGS (dbbrowser->app_vary_button, GTK_CAN_DEFAULT);
-    g_signal_connect (G_OBJECT (dbbrowser->app_vary_button), "clicked",
-                        G_CALLBACK (dialog_button_2_callback), dbbrowser );
-    gtk_table_attach (GTK_TABLE (table), dbbrowser->app_vary_button,
-                      cof+1, cof+2, row, row + 1, 
-                      GTK_FILL, 0, 0, 0);
-    gtk_widget_set_sensitive (dbbrowser->app_vary_button, FALSE);
-    gtk_widget_show (dbbrowser->app_vary_button);
-  } else dbbrowser->app_vary_button = NULL;
 
   /* Button Cancel */
   button = gtk_button_new_from_stock ( GTK_STOCK_CANCEL);
@@ -542,15 +606,15 @@ dialog_select (dbbrowser_t *dbbrowser,
        gtk_widget_set_sensitive (dbbrowser->app_const_button, FALSE);
      }
   }
-  if(dbbrowser->app_vary_button != NULL)
+  if(dbbrowser->accel_spinbutton != NULL)
   {
      if(0 != (dbbrowser->constraint_func_sel2)(dbbrowser->selected_proc_name, dbbrowser->current_image_id))
      { 
-        gtk_widget_set_sensitive (dbbrowser->app_vary_button, TRUE);
+        gtk_widget_set_sensitive (dbbrowser->accel_spinbutton, TRUE);
      }
      else
      {
-        gtk_widget_set_sensitive (dbbrowser->app_vary_button, FALSE);
+        gtk_widget_set_sensitive (dbbrowser->accel_spinbutton, FALSE);
      }
   }
   
@@ -643,12 +707,6 @@ dialog_button_1_callback (GtkWidget *widget, dbbrowser_t* dbbrowser)
   dialog_num_button_callback(dbbrowser, 0);
 }
 
-/* GAP APPLY varying callback */
-static void 
-dialog_button_2_callback (GtkWidget *widget, dbbrowser_t* dbbrowser)
-{
-  dialog_num_button_callback(dbbrowser, 1);
-}
 
 /* CODEGEN callback (does not close the dialog) */
 static void 
@@ -661,6 +719,30 @@ dialog_button_3_callback (GtkWidget *widget, dbbrowser_t* dbbrowser)
 }  /* end dialog_button_3_callback */
 
 
+/* -------------------------------
+ * p_accel_spinbutton_callback
+ * -------------------------------
+ */
+static void
+p_accel_spinbutton_callback(GtkObject *obj, dbbrowser_t* dbbrowser)
+{
+  gint32 l_val;
+
+  if(dbbrowser)
+  {
+    l_val = (GTK_ADJUSTMENT(dbbrowser->accel_adj)->value);
+    if(dbbrowser->result)
+    {
+      if(dbbrowser->result->accelCharacteristic != l_val)
+      {
+        dbbrowser->result->accelCharacteristic = l_val;
+      }
+    }
+  }
+}  /* end p_accel_spinbutton_callback */
+
+
+
 /* search in the whole db */
 static void 
 dialog_search_callback (GtkWidget   *widget, 
@@ -839,51 +921,51 @@ convert_string (gchar *str)
 }
 
 
-static const gchar *
-GParamType_to_string (GimpPDBArgType type)
-{
-  switch (type)
-    {
-    case GIMP_PDB_INT32:       return "INT32";
-    case GIMP_PDB_INT16:       return "INT16";
-    case GIMP_PDB_INT8:        return "INT8";
-    case GIMP_PDB_FLOAT:       return "FLOAT";
-    case GIMP_PDB_STRING:      return "STRING";
-    case GIMP_PDB_INT32ARRAY:  return "INT32ARRAY";
-    case GIMP_PDB_INT16ARRAY:  return "INT16ARRAY";
-    case GIMP_PDB_INT8ARRAY:   return "INT8ARRAY";
-    case GIMP_PDB_FLOATARRAY:  return "FLOATARRAY";
-    case GIMP_PDB_STRINGARRAY: return "STRINGARRAY";
-    case GIMP_PDB_COLOR:       return "COLOR";
-    case GIMP_PDB_REGION:      return "REGION";
-    case GIMP_PDB_DISPLAY:     return "DISPLAY";
-    case GIMP_PDB_IMAGE:       return "IMAGE";
-    case GIMP_PDB_LAYER:       return "LAYER";
-    case GIMP_PDB_CHANNEL:     return "CHANNEL";
-    case GIMP_PDB_DRAWABLE:    return "DRAWABLE";
-    case GIMP_PDB_SELECTION:   return "SELECTION";
-    case GIMP_PDB_BOUNDARY:    return "BOUNDARY";
-    case GIMP_PDB_PATH:        return "PATH";
-    case GIMP_PDB_PARASITE:    return "PARASITE";
-    case GIMP_PDB_STATUS:      return "STATUS";
-    case GIMP_PDB_END:         return "END";
-    default:                   return "UNKNOWN?";
-    }
-}
-
-
-static const gchar *
-GimpPDBProcType_to_string (GimpPDBProcType type)
-{
-  switch (type)
-    {
-    case GIMP_INTERNAL:  return _("Internal GIMP procedure");
-    case GIMP_PLUGIN:    return _("GIMP Plug-In");
-    case GIMP_EXTENSION: return _("GIMP Extension");
-    case GIMP_TEMPORARY: return _("Temporary Procedure");
-    default:             return "UNKNOWN";
-    }
-}
+// static const gchar *
+// GParamType_to_string (GimpPDBArgType type)
+// {
+//   switch (type)
+//     {
+//     case GIMP_PDB_INT32:       return "INT32";
+//     case GIMP_PDB_INT16:       return "INT16";
+//     case GIMP_PDB_INT8:        return "INT8";
+//     case GIMP_PDB_FLOAT:       return "FLOAT";
+//     case GIMP_PDB_STRING:      return "STRING";
+//     case GIMP_PDB_INT32ARRAY:  return "INT32ARRAY";
+//     case GIMP_PDB_INT16ARRAY:  return "INT16ARRAY";
+//     case GIMP_PDB_INT8ARRAY:   return "INT8ARRAY";
+//     case GIMP_PDB_FLOATARRAY:  return "FLOATARRAY";
+//     case GIMP_PDB_STRINGARRAY: return "STRINGARRAY";
+//     case GIMP_PDB_COLOR:       return "COLOR";
+//     case GIMP_PDB_REGION:      return "REGION";
+//     case GIMP_PDB_DISPLAY:     return "DISPLAY";
+//     case GIMP_PDB_IMAGE:       return "IMAGE";
+//     case GIMP_PDB_LAYER:       return "LAYER";
+//     case GIMP_PDB_CHANNEL:     return "CHANNEL";
+//     case GIMP_PDB_DRAWABLE:    return "DRAWABLE";
+//     case GIMP_PDB_SELECTION:   return "SELECTION";
+//     case GIMP_PDB_BOUNDARY:    return "BOUNDARY";
+//     case GIMP_PDB_PATH:        return "PATH";
+//     case GIMP_PDB_PARASITE:    return "PARASITE";
+//     case GIMP_PDB_STATUS:      return "STATUS";
+//     case GIMP_PDB_END:         return "END";
+//     default:                   return "UNKNOWN?";
+//     }
+// }
+// 
+// 
+// static const gchar *
+// GimpPDBProcType_to_string (GimpPDBProcType type)
+// {
+//   switch (type)
+//     {
+//     case GIMP_INTERNAL:  return _("Internal GIMP procedure");
+//     case GIMP_PLUGIN:    return _("GIMP Plug-In");
+//     case GIMP_EXTENSION: return _("GIMP Extension");
+//     case GIMP_TEMPORARY: return _("Temporary Procedure");
+//     default:             return "UNKNOWN";
+//     }
+// }
 
 /* search for menupath
  *  return NULL if menupath for plugin name was not found.
diff --git a/gap/gap_dbbrowser_utils.h b/gap/gap_dbbrowser_utils.h
old mode 100644
new mode 100755
index 0fc591c..913609b
--- a/gap/gap_dbbrowser_utils.h
+++ b/gap/gap_dbbrowser_utils.h
@@ -36,8 +36,9 @@
 #include "libgimp/gimp.h"
 
 typedef struct {
-   char selected_proc_name[256];
-   int  button_nr;               /* -1 on cancel, 0 .. n */
+   char   selected_proc_name[256];
+   int    button_nr;               /* -1 on cancel, 0 .. n */
+   gint32 accelCharacteristic;
 } GapDbBrowserResult;
 
 /* proc to check if to add or not to add the procedure to the browsers listbox
@@ -50,7 +51,7 @@ typedef int (*t_constraint_func) (gchar *proc_name, gint32 image_id);
 int
 gap_db_browser_dialog (char *title_txt,
                        char *button_1_txt,
-                       char *button_2_txt,
+                       gboolean                 showAccelerationCharacteristic,
                        t_constraint_func        constraint_func,
                        t_constraint_func        constraint_func_sel1,
                        t_constraint_func        constraint_func_sel2,
diff --git a/gap/gap_filter.h b/gap/gap_filter.h
old mode 100644
new mode 100755
index fcce08a..5f09faa
--- a/gap/gap_filter.h
+++ b/gap/gap_filter.h
@@ -59,7 +59,7 @@
  */
 
 gint gap_proc_anim_apply(GimpRunMode run_mode, gint32 image_id, char *l_plugin_name
-    , GapFiltPdbApplyMode apply_mode);
+    , gint32 accelCharacteristic);
 
 
 /* ------------------------
diff --git a/gap/gap_filter_foreach.c b/gap/gap_filter_foreach.c
old mode 100644
new mode 100755
index 6fbf41a..9cd02f6
--- a/gap/gap_filter_foreach.c
+++ b/gap/gap_filter_foreach.c
@@ -71,6 +71,7 @@
 #include "gap_filter_pdb.h"
 #include "gap_dbbrowser_utils.h"
 #include "gap_lib.h"
+#include "gap_accel_char.h"
 
 #define GAP_DB_BROWSER_FILTERALL_HELP_ID  "gap-filterall-db-browser"
 
@@ -93,9 +94,9 @@ static gint p_pitstop(GimpRunMode run_mode, char *plugin_name, gint text_flag,
 static void p_visibilty_restore(gint32 image_id, gint nlayers, int *visible_tab, char *plugin_name);
 static gint32 p_get_indexed_layerid(gint32 image_id, gint *nlayers, gint32 idx, char *plugin_name);
 static int p_foreach_multilayer(GimpRunMode run_mode, gint32 image_id,
-                         const char *plugin_name, GapFiltPdbApplyMode apply_mode);
+                         const char *plugin_name, gint32 accelCharacteristic);
 static int p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
-                         char *canonical_plugin_name, GapFiltPdbApplyMode apply_mode);
+                         char *canonical_plugin_name, gint32 accelCharacteristic);
 
 /* ------------------------
  * p_gdisplays_update_full
@@ -250,13 +251,13 @@ p_get_indexed_layerid(gint32 image_id, gint *nlayers, gint32 idx, char *plugin_n
  */
 static int
 p_foreach_multilayer(GimpRunMode run_mode, gint32 image_id,
-                     const char *plugin_name, GapFiltPdbApplyMode apply_mode)
+                     const char *plugin_name, gint32 accelCharacteristic)
 {
   char *canonical_plugin_name;
   int rc;
   
   canonical_plugin_name = gimp_canonicalize_identifier(plugin_name);
-  rc = p_foreach_multilayer2(run_mode, image_id, canonical_plugin_name, apply_mode);
+  rc = p_foreach_multilayer2(run_mode, image_id, canonical_plugin_name, accelCharacteristic);
   
   g_free(canonical_plugin_name);
 
@@ -274,7 +275,7 @@ p_foreach_multilayer(GimpRunMode run_mode, gint32 image_id,
  */
 static int
 p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
-                         char *canonical_plugin_name, GapFiltPdbApplyMode apply_mode)
+                         char *canonical_plugin_name, gint32 accelCharacteristic)
 {
   static char l_key_from[512];
   static char l_key_to[512];
@@ -347,7 +348,7 @@ p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
 
       l_percentage_step = 1.0 / l_nlayers;
 
-      if((l_plugin_iterator != NULL)  && (l_nlayers > 1) && (apply_mode == GAP_PAPP_VARYING_LINEAR ))
+      if((l_plugin_iterator != NULL)  && (l_nlayers > 1) && (accelCharacteristic != GAP_ACCEL_CHAR_NONE ))
       {
         l_child_pid = 0; /* fork(); */
         if(l_child_pid < 0)
@@ -519,14 +520,18 @@ p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
           }
 
 
-          if((l_plugin_iterator != NULL) && (apply_mode == GAP_PAPP_VARYING_LINEAR ))
+          if((l_plugin_iterator != NULL) && (accelCharacteristic != GAP_ACCEL_CHAR_NONE ))
           {
+            gdouble accelStep;
+       
+       
+            accelStep = gap_calculate_current_step_with_acceleration((gdouble)l_idx, l_nlayers -1, accelCharacteristic);
             /* call plugin-specific iterator (or the common iterator), to modify
              * the plugin's last_values
              */
             if(!gap_filter_iterator_call(l_plugin_iterator
                  , l_nlayers -1      /* total steps  */
-                 , (gdouble)l_idx    /* current step */
+                 , accelStep         /* current step according to acceleration characteristic */
                  , canonical_plugin_name
                  , l_plugin_data_len
                  ))
@@ -581,16 +586,17 @@ p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
  */
 gint
 gap_proc_anim_apply(GimpRunMode run_mode, gint32 image_id, char *plugin_name
-  , GapFiltPdbApplyMode apply_mode)
+  , gint32 accelCharacteristic)
 {
   GapDbBrowserResult  l_browser_result;
+  l_browser_result.accelCharacteristic = GAP_ACCEL_CHAR_LINEAR;
 
   if(run_mode == GIMP_RUN_INTERACTIVE)
   {
 
     if(gap_db_browser_dialog( _("Select Filter for Animated Apply"),
-                                 _("Apply Constant"),
-                                 _("Apply Varying"),
+                                 _("Apply"),
+                                 TRUE,                                  /* showAccelerationCharacteristic */
                                  gap_filt_pdb_constraint_proc,
                                  gap_filt_pdb_constraint_proc_sel1,
                                  gap_filt_pdb_constraint_proc_sel2,
@@ -604,15 +610,25 @@ gap_proc_anim_apply(GimpRunMode run_mode, gint32 image_id, char *plugin_name
     }
 
     strcpy(plugin_name, l_browser_result.selected_proc_name);
-    if(l_browser_result.button_nr == 1) apply_mode = GAP_PAPP_VARYING_LINEAR;
+    
+    /* invert acceleration to deceleration and vice versa
+     * (because processing layer indexes is done from high to low values) 
+     */
+    accelCharacteristic = (-1 * l_browser_result.accelCharacteristic);
 
-    if(gap_debug) printf("DEBUG: gap_db_browser_dialog SELECTED:%s\n", plugin_name);
+    if(gap_debug) 
+    {
+      printf("DEBUG: gap_db_browser_dialog SELECTED:%s accelCharacteristic:%d\n"
+           , plugin_name
+           , (int)accelCharacteristic
+           );
+    }
 
   }
 
   return(p_foreach_multilayer(run_mode,
                               image_id,
                               plugin_name,
-                              apply_mode ));
+                              accelCharacteristic ));
 
 }
diff --git a/gap/gap_filter_main.c b/gap/gap_filter_main.c
old mode 100644
new mode 100755
index 3457719..658e0e0
--- a/gap/gap_filter_main.c
+++ b/gap/gap_filter_main.c
@@ -50,6 +50,7 @@
 #include "gap_filter.h"
 #include "gap_filter_iterators.h"
 #include "gap_dbbrowser_utils.h"
+#include "gap_accel_char.h"
 
 /* revision history:
  * gimp   1.3.20b;  2003/09/20  hof: update version, minor cleanup
@@ -98,7 +99,7 @@ query ()
     {GIMP_PDB_IMAGE, "image", "Input image"},
     {GIMP_PDB_DRAWABLE, "drawable", "Input drawable (unused)"},
     {GIMP_PDB_STRING, "proc_name", "name of plugin procedure to run for each layer"},
-    {GIMP_PDB_INT32, "varying", "0 .. apply constant, 1..apply varying"},
+    {GIMP_PDB_INT32, "acceleration", "0 .. apply constant, 1..apply varying constant speed, positive accelerate, nagative decelerate"},
   };
 
   static GimpParamDef *return_vals = NULL;
@@ -203,9 +204,9 @@ run(const gchar *name
   
   if (strcmp (name, PLUG_IN_NAME_ANIMFILTER) == 0)
   {
-      GapFiltPdbApplyMode apply_mode;
+      gint32 accelCharacteristic;
 
-      apply_mode = GAP_PAPP_CONSTANT;
+      accelCharacteristic = GAP_ACCEL_CHAR_NONE;
       if (run_mode == GIMP_RUN_NONINTERACTIVE)
       {
         if (n_params != 5)
@@ -219,7 +220,7 @@ run(const gchar *name
         }
         if( param[4].data.d_int32 != 0)
         {
-          apply_mode = GAP_PAPP_VARYING_LINEAR;
+          accelCharacteristic = param[4].data.d_int32;
         }
       }
       else if(run_mode == GIMP_RUN_WITH_LAST_VALS)
@@ -233,7 +234,7 @@ run(const gchar *name
 
         image_id    = param[1].data.d_image;
 
-        l_rc = gap_proc_anim_apply(run_mode, image_id, l_plugin_name, apply_mode);
+        l_rc = gap_proc_anim_apply(run_mode, image_id, l_plugin_name, accelCharacteristic);
         gimp_set_data(PLUG_IN_NAME_ANIMFILTER,
                       l_plugin_name, sizeof(l_plugin_name));
       }
diff --git a/gap/gap_filter_pdb.h b/gap/gap_filter_pdb.h
old mode 100644
new mode 100755
index c75a214..5fe6b69
--- a/gap/gap_filter_pdb.h
+++ b/gap/gap_filter_pdb.h
@@ -33,11 +33,6 @@ typedef enum
 } GapFiltPdbProcType;
 
 
-typedef enum
-{  GAP_PAPP_CONSTANT                = 0,
-   GAP_PAPP_VARYING_LINEAR          = 1
-} GapFiltPdbApplyMode;
-
 
 /* ------------------------
  * gap_filter_pdb.h
diff --git a/gap/gap_fmac_main.c b/gap/gap_fmac_main.c
index 7a4ac3f..34961cc 100644
--- a/gap/gap_fmac_main.c
+++ b/gap/gap_fmac_main.c
@@ -59,6 +59,7 @@
 #include "gap_dbbrowser_utils.h"
 #include "gap_lastvaldesc.h"
 #include "gap_fmac_context.h"
+#include "gap_accel_char.h"
 
 /* revision history:
  * gimp   1.3.26b;  2004/02/29  hof: bugfix NONINTERACTIVE call did crash
@@ -626,10 +627,11 @@ static gint
 p_fmac_add_filter(const char *filtermacro_file, gint32 image_id)
 {
   GapDbBrowserResult   l_browser_result;
+  l_browser_result.accelCharacteristic = GAP_ACCEL_CHAR_NONE;
 
   if(gap_db_browser_dialog( _("Select Filtercalls of Current GIMP Session")
-                          , NULL            /* dont use the 1.st action button at all */
                           , _("Add Filter")
+                          , FALSE                                /* FALSE disables acceleration characteristic */
                           , p_fmac_pdb_constraint_proc
                           , p_fmac_pdb_constraint_proc_sel1
                           , p_fmac_pdb_constraint_proc_sel2
diff --git a/gap/gap_mod_layer.c b/gap/gap_mod_layer.c
old mode 100644
new mode 100755
index bfb0ec8..ccb7c7d
--- a/gap/gap_mod_layer.c
+++ b/gap/gap_mod_layer.c
@@ -77,6 +77,7 @@
 #include "gap_range_ops.h"
 #include "gap_mod_layer.h"
 #include "gap_mod_layer_dialog.h"
+#include "gap_accel_char.h"
 
 
 extern      int gap_debug; /* ==0  ... dont print debug infos */
@@ -990,7 +991,7 @@ p_do_filter_dialogs(GapAnimInfo *ainfo_ptr,
                     GapModLayliElem * layli_ptr, gint nlayers ,
                     char *filter_procname, int filt_len,
                     gint *plugin_data_len,
-                    GapFiltPdbApplyMode *apply_mode,
+                    gint32 *accelCharacteristic,
                     gboolean operate_on_layermask
                     )
 {
@@ -1001,11 +1002,13 @@ p_do_filter_dialogs(GapAnimInfo *ainfo_ptr,
   static char l_key_from[512];
   static char *canonical_proc_name;
 
+  l_browser_result.accelCharacteristic = GAP_ACCEL_CHAR_LINEAR;
+  
   /* GAP-PDB-Browser Dialog */
   /* ---------------------- */
   if(gap_db_browser_dialog( _("Select Filter for Animated Apply on Frames"),
-                            _("Apply Constant"),
-                            _("Apply Varying"),
+                            _("Apply"),
+                            TRUE, /* showAccelerationCharacteristic */
                             gap_filt_pdb_constraint_proc,
                             gap_filt_pdb_constraint_proc_sel1,
                             gap_filt_pdb_constraint_proc_sel2,
@@ -1023,8 +1026,10 @@ p_do_filter_dialogs(GapAnimInfo *ainfo_ptr,
   filter_procname[filt_len-1] = '\0';
   g_free(canonical_proc_name);
   
-  if(l_browser_result.button_nr == 1) *apply_mode = GAP_PAPP_VARYING_LINEAR;
-  else                                *apply_mode = GAP_PAPP_CONSTANT;
+  /* invert acceleration to deceleration and vice versa
+   * (because processing runs backwards from total_frames down to 0) 
+   */
+  *accelCharacteristic = (-1 * l_browser_result.accelCharacteristic);
 
   /* 1.st INTERACTIV Filtercall dialog */
   /* --------------------------------- */
@@ -1080,7 +1085,7 @@ p_do_filter_dialogs(GapAnimInfo *ainfo_ptr,
     return (-1);
   }
 
-  if(*apply_mode != GAP_PAPP_VARYING_LINEAR)
+  if(*accelCharacteristic == GAP_ACCEL_CHAR_NONE)
   {
     return (p_pitstop_dialog(1, filter_procname));
   }
@@ -1104,7 +1109,7 @@ p_do_filter_dialogs(GapAnimInfo *ainfo_ptr,
  */
 static gint
 p_do_2nd_filter_dialogs(char *filter_procname,
-                        GapFiltPdbApplyMode  l_apply_mode,
+                        gint32  accelCharacteristic,
                         char *last_frame_filename,
                         gint32 sel_mode, gint32 sel_case,
                         gint32 sel_invert, char *sel_pattern,
@@ -1248,7 +1253,7 @@ p_frames_modify(GapAnimInfo *ainfo_ptr,
   char      *l_plugin_iterator;
   gdouble    l_cur_step;
   gint       l_total_steps;
-  GapFiltPdbApplyMode  l_apply_mode;
+  gint32        accelCharacteristic;
   char         *l_last_frame_filename;
   gint          l_count;
   gboolean      l_operating_on_current_image;
@@ -1257,9 +1262,12 @@ p_frames_modify(GapAnimInfo *ainfo_ptr,
 
 
 
-  if(gap_debug) printf("gap: p_frames_modify START, action_mode=%d  sel_mode=%d case=%d, invert=%d patt:%s:\n",
+  if(gap_debug)
+  { 
+    printf("gap: p_frames_modify START, action_mode=%d  sel_mode=%d case=%d, invert=%d patt:%s:\n",
         (int)action_mode, (int)sel_mode, (int)sel_case, (int)sel_invert, sel_pattern);
-
+  }
+  
   l_operate_on_layermask = FALSE;
   l_percentage = 0.0;
   if(ainfo_ptr->run_mode == GIMP_RUN_INTERACTIVE)
@@ -1275,7 +1283,7 @@ p_frames_modify(GapAnimInfo *ainfo_ptr,
   l_rc = 0;
   l_plugin_iterator = NULL;
   l_plugin_data_len = 0;
-  l_apply_mode = GAP_PAPP_CONSTANT;
+  accelCharacteristic = GAP_ACCEL_CHAR_NONE;
   l_dpy_id = -1;
   l_last_frame_filename = NULL;
 
@@ -1314,7 +1322,10 @@ p_frames_modify(GapAnimInfo *ainfo_ptr,
   l_cur_frame_nr = l_begin;
   while(1)              /* loop foreach frame in range */
   {
-    if(gap_debug) printf("p_frames_modify While l_cur_frame_nr = %d\n", (int)l_cur_frame_nr);
+    if(gap_debug)
+    {
+      printf("p_frames_modify While l_cur_frame_nr = %d\n", (int)l_cur_frame_nr);
+    }
 
     /* build the frame name */
     if(ainfo_ptr->new_filename != NULL) g_free(ainfo_ptr->new_filename);
@@ -1394,16 +1405,16 @@ p_frames_modify(GapAnimInfo *ainfo_ptr,
                                  l_layli_ptr, l_nlayers,
                                 &l_filter_procname[0], sizeof(l_filter_procname),
                                 &l_plugin_data_len,
-                                &l_apply_mode,
+                                &accelCharacteristic,
                                  l_operate_on_layermask
                                  );
 
       if(l_last_frame_filename != NULL)
       {
-        if((l_rc == 0) && (l_apply_mode == GAP_PAPP_VARYING_LINEAR))
+        if((l_rc == 0) && (accelCharacteristic != GAP_ACCEL_CHAR_NONE))
         {
           l_rc = p_do_2nd_filter_dialogs(&l_filter_procname[0],
-                                   l_apply_mode,
+                                   accelCharacteristic,
                                    l_last_frame_filename,
                                    sel_mode, sel_case, sel_invert, sel_pattern,
                                    l_operate_on_layermask
@@ -1427,7 +1438,7 @@ p_frames_modify(GapAnimInfo *ainfo_ptr,
       }
 
       /* check for matching Iterator PluginProcedures */
-      if(l_apply_mode == GAP_PAPP_VARYING_LINEAR )
+      if(accelCharacteristic != GAP_ACCEL_CHAR_NONE )
       {
         l_plugin_iterator =  gap_filt_pdb_get_iterator_proc(&l_filter_procname[0], &l_count);
       }
@@ -1474,22 +1485,34 @@ p_frames_modify(GapAnimInfo *ainfo_ptr,
 
     /* iterator call (for filter apply with varying values) */
     if((action_mode == GAP_MOD_ACM_APPLY_FILTER)
-    && (l_plugin_iterator != NULL) && (l_apply_mode == GAP_PAPP_VARYING_LINEAR ))
+    && (l_plugin_iterator != NULL) && (accelCharacteristic != GAP_ACCEL_CHAR_NONE ))
     {
+       gdouble accelStep;
+       
        l_cur_step -= 1.0;
+       
+       accelStep = gap_calculate_current_step_with_acceleration(l_cur_step, l_total_steps, accelCharacteristic);
+       if(gap_debug) 
+       {
+         printf("DEBUG: calling iterator %s  current frame:%d  accelStep:%f\n"
+                               ,l_plugin_iterator
+                               , (int)l_cur_frame_nr
+                               , (float)accelStep
+                               );
+       }
+
         /* call plugin-specific iterator, to modify
          * the plugin's last_values
          */
-       if(gap_debug) printf("DEBUG: calling iterator %s  current frame:%d\n",
-                               l_plugin_iterator, (int)l_cur_frame_nr);
+
        if(strcmp(l_plugin_iterator, GIMP_PLUGIN_GAP_COMMON_ITER) == 0)
        {
          l_params = gimp_run_procedure (l_plugin_iterator,
                            &l_retvals,
                            GIMP_PDB_INT32,   GIMP_RUN_NONINTERACTIVE,
                            GIMP_PDB_INT32,   l_total_steps,      /* total steps  */
-                           GIMP_PDB_FLOAT,   (gdouble)l_cur_step,    /* current step */
-                           GIMP_PDB_INT32,   l_plugin_data_len, /* length of stored data struct */
+                           GIMP_PDB_FLOAT,   accelStep,          /* current step respecting acceleration characteristic */
+                           GIMP_PDB_INT32,   l_plugin_data_len,  /* length of stored data struct */
                            GIMP_PDB_STRING,  &l_filter_procname[0],       /* the common iterator needs the plugin name as additional param */
                            GIMP_PDB_END);
        }
@@ -1498,9 +1521,9 @@ p_frames_modify(GapAnimInfo *ainfo_ptr,
          l_params = gimp_run_procedure (l_plugin_iterator,
                              &l_retvals,
                              GIMP_PDB_INT32,   GIMP_RUN_NONINTERACTIVE,
-                             GIMP_PDB_INT32,   l_total_steps,          /* total steps  */
-                             GIMP_PDB_FLOAT,   (gdouble)l_cur_step,    /* current step */
-                             GIMP_PDB_INT32,   l_plugin_data_len, /* length of stored data struct */
+                             GIMP_PDB_INT32,   l_total_steps,       /* total steps  */
+                             GIMP_PDB_FLOAT,   accelStep,           /* current step respecting acceleration characteristic */
+                             GIMP_PDB_INT32,   l_plugin_data_len,   /* length of stored data struct */
                              GIMP_PDB_END);
        }
        if (l_params[0].data.d_status != GIMP_PDB_SUCCESS)
diff --git a/gap/gap_morph_exec.c b/gap/gap_morph_exec.c
index b1e6453..cc4969a 100644
--- a/gap/gap_morph_exec.c
+++ b/gap/gap_morph_exec.c
@@ -77,7 +77,6 @@
 #define GAP_MORPH_MIN_TOL_FAKTOR 4.5
 #define GAP_MORPH_XY_REL_FAKTOR 5
 
-#define MIX_VALUE(factor, a, b) ((a * (1.0 - factor)) +  (b * factor))
 
 typedef struct GapMorphExeLayerstack
 {
@@ -2163,7 +2162,7 @@ p_mix_layers (gint32  curr_image_id
         {
            gdouble val;
            
-           val = MIX_VALUE(curr_mix_factor, (gdouble)(*bg_ptr), (gdouble)(*top_ptr));
+           val = GAP_BASE_MIX_VALUE(curr_mix_factor, (gdouble)(*bg_ptr), (gdouble)(*top_ptr));
            *pixel_ptr = (guchar)val;
            
            pixel_ptr++;
diff --git a/gap/gap_mov_dialog.c b/gap/gap_mov_dialog.c
index 675ba49..c71b2e1 100755
--- a/gap/gap_mov_dialog.c
+++ b/gap/gap_mov_dialog.c
@@ -126,6 +126,7 @@
 
 #include "gap_pview_da.h"
 #include "gap_accel_da.h"
+#include "gap_accel_char.h"
 #include "gap_stock.h"
 
 
@@ -652,7 +653,7 @@ mov_dialog ( GimpDrawable *drawable, t_mov_gui_stuff *mgp,
 #endif
   /* dialog */
   dlg = gtk_dialog_new ();
-  gtk_window_set_type_hint (dlg, GDK_WINDOW_TYPE_HINT_NORMAL);
+  gtk_window_set_type_hint (GTK_WINDOW (dlg), GDK_WINDOW_TYPE_HINT_NORMAL);
   mgp->shell = dlg;
   mgp->first_nr = first_nr;
   mgp->last_nr = last_nr;
@@ -2741,7 +2742,6 @@ p_clear_one_point(gint idx)
 void
 p_mix_one_point(gint idx, gint ref1, gint ref2, gdouble mix_factor)
 {
-#define MIX_VALUE(factor, a, b) ((a * (1.0 - factor)) +  (b * factor))
 
   if((idx >= 0)
   && (idx <= pvals->point_idx_max)
@@ -2751,29 +2751,29 @@ p_mix_one_point(gint idx, gint ref1, gint ref2, gdouble mix_factor)
   && (ref2 <= pvals->point_idx_max)
   )
   {
-    pvals->point[idx].opacity  = MIX_VALUE(mix_factor, pvals->point[ref1].opacity,   pvals->point[ref2].opacity);
-    pvals->point[idx].w_resize = MIX_VALUE(mix_factor, pvals->point[ref1].w_resize,  pvals->point[ref2].w_resize);
-    pvals->point[idx].h_resize = MIX_VALUE(mix_factor, pvals->point[ref1].h_resize,  pvals->point[ref2].h_resize);
-    pvals->point[idx].rotation = MIX_VALUE(mix_factor, pvals->point[ref1].rotation,  pvals->point[ref2].rotation);
+    pvals->point[idx].opacity  = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].opacity,   pvals->point[ref2].opacity);
+    pvals->point[idx].w_resize = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].w_resize,  pvals->point[ref2].w_resize);
+    pvals->point[idx].h_resize = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].h_resize,  pvals->point[ref2].h_resize);
+    pvals->point[idx].rotation = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].rotation,  pvals->point[ref2].rotation);
 
-    pvals->point[idx].ttlx      = MIX_VALUE(mix_factor, pvals->point[ref1].ttlx,  pvals->point[ref2].ttlx);
-    pvals->point[idx].ttly      = MIX_VALUE(mix_factor, pvals->point[ref1].ttly,  pvals->point[ref2].ttly);
-    pvals->point[idx].ttrx      = MIX_VALUE(mix_factor, pvals->point[ref1].ttrx,  pvals->point[ref2].ttrx);
-    pvals->point[idx].ttry      = MIX_VALUE(mix_factor, pvals->point[ref1].ttry,  pvals->point[ref2].ttry);
-    pvals->point[idx].tblx      = MIX_VALUE(mix_factor, pvals->point[ref1].tblx,  pvals->point[ref2].tblx);
-    pvals->point[idx].tbly      = MIX_VALUE(mix_factor, pvals->point[ref1].tbly,  pvals->point[ref2].tbly);
-    pvals->point[idx].tbrx      = MIX_VALUE(mix_factor, pvals->point[ref1].tbrx,  pvals->point[ref2].tbrx);
-    pvals->point[idx].tbry      = MIX_VALUE(mix_factor, pvals->point[ref1].tbry,  pvals->point[ref2].tbry);
+    pvals->point[idx].ttlx      = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].ttlx,  pvals->point[ref2].ttlx);
+    pvals->point[idx].ttly      = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].ttly,  pvals->point[ref2].ttly);
+    pvals->point[idx].ttrx      = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].ttrx,  pvals->point[ref2].ttrx);
+    pvals->point[idx].ttry      = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].ttry,  pvals->point[ref2].ttry);
+    pvals->point[idx].tblx      = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].tblx,  pvals->point[ref2].tblx);
+    pvals->point[idx].tbly      = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].tbly,  pvals->point[ref2].tbly);
+    pvals->point[idx].tbrx      = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].tbrx,  pvals->point[ref2].tbrx);
+    pvals->point[idx].tbry      = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].tbry,  pvals->point[ref2].tbry);
 
-    pvals->point[idx].sel_feather_radius = MIX_VALUE(mix_factor, pvals->point[ref1].sel_feather_radius,  pvals->point[ref2].sel_feather_radius);
+    pvals->point[idx].sel_feather_radius = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].sel_feather_radius,  pvals->point[ref2].sel_feather_radius);
 
 
-    pvals->point[idx].accPosition         = MIX_VALUE(mix_factor, pvals->point[ref1].accPosition,          pvals->point[ref2].accPosition);
-    pvals->point[idx].accOpacity          = MIX_VALUE(mix_factor, pvals->point[ref1].accOpacity,           pvals->point[ref2].accOpacity);
-    pvals->point[idx].accSize             = MIX_VALUE(mix_factor, pvals->point[ref1].accSize,              pvals->point[ref2].accSize);
-    pvals->point[idx].accRotation         = MIX_VALUE(mix_factor, pvals->point[ref1].accRotation,          pvals->point[ref2].accRotation);
-    pvals->point[idx].accPerspective      = MIX_VALUE(mix_factor, pvals->point[ref1].accPerspective,       pvals->point[ref2].accPerspective);
-    pvals->point[idx].accSelFeatherRadius = MIX_VALUE(mix_factor, pvals->point[ref1].accSelFeatherRadius,  pvals->point[ref2].accSelFeatherRadius);
+    pvals->point[idx].accPosition         = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].accPosition,          pvals->point[ref2].accPosition);
+    pvals->point[idx].accOpacity          = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].accOpacity,           pvals->point[ref2].accOpacity);
+    pvals->point[idx].accSize             = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].accSize,              pvals->point[ref2].accSize);
+    pvals->point[idx].accRotation         = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].accRotation,          pvals->point[ref2].accRotation);
+    pvals->point[idx].accPerspective      = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].accPerspective,       pvals->point[ref2].accPerspective);
+    pvals->point[idx].accSelFeatherRadius = GAP_BASE_MIX_VALUE(mix_factor, pvals->point[ref1].accSelFeatherRadius,  pvals->point[ref2].accSelFeatherRadius);
 
 
 
@@ -4031,8 +4031,8 @@ mov_acc_tab_create (t_mov_gui_stuff *mgp)
   GtkWidget      *table;
   GtkObject      *adj;
 
-#define ACC_MIN -100
-#define ACC_MAX  100
+#define ACC_MIN  GAP_ACCEL_CHAR_MIN
+#define ACC_MAX  GAP_ACCEL_CHAR_MAX
 
   /* the vbox */
   vbox = gtk_vbox_new (FALSE, 3);
@@ -5088,7 +5088,6 @@ mov_path_acceleration_adjustment_update(GtkWidget *widget,
 {
   gint old_val;
   t_mov_gui_stuff *mgp;
-  GapAccelWidget  *accel_ptr;
 
   mgp = g_object_get_data( G_OBJECT(widget), "mgp" );
 
@@ -5096,18 +5095,6 @@ mov_path_acceleration_adjustment_update(GtkWidget *widget,
   old_val = *val;
   gimp_int_adjustment_update(GTK_ADJUSTMENT(widget), (gpointer)val);
 
-  accel_ptr = g_object_get_data ( G_OBJECT(widget), "accel_ptr" );
-
-  if(accel_ptr == NULL)
-  {
-    if(gap_debug)
-    {
-      printf("accel_ptr is NULL\n");
-    }
-  }
-  
-  gap_accel_render (accel_ptr, *val);
-
   return;
 
 }  /* end mov_path_acceleration_adjustment_update */
@@ -5653,8 +5640,8 @@ p_mov_acc_spinbutton_new(GtkTable *table
                     )
 {
   GtkObject       *adj;
-  GapAccelWidget  *accel_ptr;
-  gint accelerationCharacteristic;
+  GapAccelWidget  *accel_wgt;
+  gint32           accelerationCharacteristic;
   
 #define ACC_WGT_WIDTH 28
 #define ACC_WGT_HEIGHT 26
@@ -5678,15 +5665,13 @@ p_mov_acc_spinbutton_new(GtkTable *table
                     ,privatetip
                     );
 
-  accelerationCharacteristic = (int)initial_val;
-  accel_ptr = gap_accel_new(ACC_WGT_WIDTH, ACC_WGT_HEIGHT, accelerationCharacteristic);
+  accelerationCharacteristic = (gint32)initial_val;
+  accel_wgt = gap_accel_new_with_adj(ACC_WGT_WIDTH, ACC_WGT_HEIGHT, accelerationCharacteristic, adj);
 
 
-  gtk_table_attach( GTK_TABLE(table), accel_ptr->da_widget, col+2, col+3, row, row+1,
+  gtk_table_attach( GTK_TABLE(table), accel_wgt->da_widget, col+2, col+3, row, row+1,
                     GTK_FILL, 0, 4, 0 );
-  gtk_widget_show (accel_ptr->da_widget);
-
-  g_object_set_data (G_OBJECT (adj), "accel_ptr", accel_ptr);
+  gtk_widget_show (accel_wgt->da_widget);
 
   return(adj);
 }  /* end p_mov_acc_spinbutton_new */
diff --git a/gap/gap_mov_exec.c b/gap/gap_mov_exec.c
index 22275f7..e86d5fb 100755
--- a/gap/gap_mov_exec.c
+++ b/gap/gap_mov_exec.c
@@ -937,12 +937,6 @@ p_calculate_settings_for_current_FrameTween(
    , gint     endOfSegmentIndex
   )
 {
-/* MIX_VALUE  0.0 <= factor <= 1.0
- *  result is a  for factor 0.0
- *            b  for factor 1.0
- *            mix for factors inbetween
- */
-#define MIX_VALUE(factor, a, b) ((a * (1.0 - factor)) +  (b * factor))
 
   gdouble tweenMultiplicator;
   gint frameNrAtEndOfSegment;
@@ -998,8 +992,8 @@ p_calculate_settings_for_current_FrameTween(
          , &posFactor
          );
 
-    cur_ptr->currX  =       MIX_VALUE(posFactor, (gdouble)val_ptr->point[segmPtidx].p_x,      (gdouble)val_ptr->point[segmPtidx +1].p_x);
-    cur_ptr->currY  =       MIX_VALUE(posFactor, (gdouble)val_ptr->point[segmPtidx].p_y,      (gdouble)val_ptr->point[segmPtidx +1].p_y);
+    cur_ptr->currX  =       GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[segmPtidx].p_x,      (gdouble)val_ptr->point[segmPtidx +1].p_x);
+    cur_ptr->currY  =       GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[segmPtidx].p_y,      (gdouble)val_ptr->point[segmPtidx +1].p_y);
 
 
     if(gap_debug)
@@ -1032,8 +1026,8 @@ p_calculate_settings_for_current_FrameTween(
     }
 
 
-    cur_ptr->currX  =       MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].p_x,      (gdouble)val_ptr->point[currPtidx].p_x);
-    cur_ptr->currY  =       MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].p_y,      (gdouble)val_ptr->point[currPtidx].p_y);
+    cur_ptr->currX  =       GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].p_x,      (gdouble)val_ptr->point[currPtidx].p_x);
+    cur_ptr->currY  =       GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].p_y,      (gdouble)val_ptr->point[currPtidx].p_y);
   }
 
 
@@ -1046,12 +1040,12 @@ p_calculate_settings_for_current_FrameTween(
                                                       , currFrameTweenInSegment
                                                       , val_ptr->point[startOfSegmentIndex].accOpacity
                                                       );
-    cur_ptr->currOpacity  = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].opacity,  (gdouble)val_ptr->point[endOfSegmentIndex].opacity);
+    cur_ptr->currOpacity  = GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].opacity,  (gdouble)val_ptr->point[endOfSegmentIndex].opacity);
   }
   else
   {
     /* No acceleration characteristic specified for opacity (compatible to GAP 2.6.x release behavior) */
-    cur_ptr->currOpacity  = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].opacity,  (gdouble)val_ptr->point[currPtidx].opacity);
+    cur_ptr->currOpacity  = GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].opacity,  (gdouble)val_ptr->point[currPtidx].opacity);
   }
 
 
@@ -1064,13 +1058,13 @@ p_calculate_settings_for_current_FrameTween(
                                                       , currFrameTweenInSegment
                                                       , val_ptr->point[startOfSegmentIndex].accSize
                                                       );
-    cur_ptr->currWidth    = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].w_resize, (gdouble)val_ptr->point[endOfSegmentIndex].w_resize);
-    cur_ptr->currHeight   = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].h_resize, (gdouble)val_ptr->point[endOfSegmentIndex].h_resize);
+    cur_ptr->currWidth    = GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].w_resize, (gdouble)val_ptr->point[endOfSegmentIndex].w_resize);
+    cur_ptr->currHeight   = GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].h_resize, (gdouble)val_ptr->point[endOfSegmentIndex].h_resize);
   }
   else
   {
-    cur_ptr->currWidth    = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].w_resize, (gdouble)val_ptr->point[currPtidx].w_resize);
-    cur_ptr->currHeight   = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].h_resize, (gdouble)val_ptr->point[currPtidx].h_resize);
+    cur_ptr->currWidth    = GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].w_resize, (gdouble)val_ptr->point[currPtidx].w_resize);
+    cur_ptr->currHeight   = GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].h_resize, (gdouble)val_ptr->point[currPtidx].h_resize);
   }
 
 
@@ -1083,11 +1077,11 @@ p_calculate_settings_for_current_FrameTween(
                                                       , currFrameTweenInSegment
                                                       , val_ptr->point[startOfSegmentIndex].accRotation
                                                       );
-    cur_ptr->currRotation = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].rotation, (gdouble)val_ptr->point[endOfSegmentIndex].rotation);
+    cur_ptr->currRotation = GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].rotation, (gdouble)val_ptr->point[endOfSegmentIndex].rotation);
   }
   else
   {
-    cur_ptr->currRotation = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].rotation, (gdouble)val_ptr->point[currPtidx].rotation);
+    cur_ptr->currRotation = GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].rotation, (gdouble)val_ptr->point[currPtidx].rotation);
  
     if(gap_debug)
     {
@@ -1112,25 +1106,25 @@ p_calculate_settings_for_current_FrameTween(
                                                       , currFrameTweenInSegment
                                                       , val_ptr->point[startOfSegmentIndex].accPerspective
                                                       );
-    cur_ptr->currTTLX     = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].ttlx,     (gdouble)val_ptr->point[endOfSegmentIndex].ttlx);
-    cur_ptr->currTTLY     = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].ttly,     (gdouble)val_ptr->point[endOfSegmentIndex].ttly);
-    cur_ptr->currTTRX     = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].ttrx,     (gdouble)val_ptr->point[endOfSegmentIndex].ttrx);
-    cur_ptr->currTTRY     = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].ttry,     (gdouble)val_ptr->point[endOfSegmentIndex].ttry);
-    cur_ptr->currTBLX     = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].tblx,     (gdouble)val_ptr->point[endOfSegmentIndex].tblx);
-    cur_ptr->currTBLY     = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].tbly,     (gdouble)val_ptr->point[endOfSegmentIndex].tbly);
-    cur_ptr->currTBRX     = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].tbrx,     (gdouble)val_ptr->point[endOfSegmentIndex].tbrx);
-    cur_ptr->currTBRY     = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].tbry,     (gdouble)val_ptr->point[endOfSegmentIndex].tbry);
+    cur_ptr->currTTLX     = GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].ttlx,     (gdouble)val_ptr->point[endOfSegmentIndex].ttlx);
+    cur_ptr->currTTLY     = GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].ttly,     (gdouble)val_ptr->point[endOfSegmentIndex].ttly);
+    cur_ptr->currTTRX     = GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].ttrx,     (gdouble)val_ptr->point[endOfSegmentIndex].ttrx);
+    cur_ptr->currTTRY     = GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].ttry,     (gdouble)val_ptr->point[endOfSegmentIndex].ttry);
+    cur_ptr->currTBLX     = GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].tblx,     (gdouble)val_ptr->point[endOfSegmentIndex].tblx);
+    cur_ptr->currTBLY     = GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].tbly,     (gdouble)val_ptr->point[endOfSegmentIndex].tbly);
+    cur_ptr->currTBRX     = GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].tbrx,     (gdouble)val_ptr->point[endOfSegmentIndex].tbrx);
+    cur_ptr->currTBRY     = GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].tbry,     (gdouble)val_ptr->point[endOfSegmentIndex].tbry);
   }
   else
   {
-    cur_ptr->currTTLX     = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].ttlx,     (gdouble)val_ptr->point[currPtidx].ttlx);
-    cur_ptr->currTTLY     = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].ttly,     (gdouble)val_ptr->point[currPtidx].ttly);
-    cur_ptr->currTTRX     = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].ttrx,     (gdouble)val_ptr->point[currPtidx].ttrx);
-    cur_ptr->currTTRY     = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].ttry,     (gdouble)val_ptr->point[currPtidx].ttry);
-    cur_ptr->currTBLX     = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].tblx,     (gdouble)val_ptr->point[currPtidx].tblx);
-    cur_ptr->currTBLY     = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].tbly,     (gdouble)val_ptr->point[currPtidx].tbly);
-    cur_ptr->currTBRX     = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].tbrx,     (gdouble)val_ptr->point[currPtidx].tbrx);
-    cur_ptr->currTBRY     = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].tbry,     (gdouble)val_ptr->point[currPtidx].tbry);
+    cur_ptr->currTTLX     = GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].ttlx,     (gdouble)val_ptr->point[currPtidx].ttlx);
+    cur_ptr->currTTLY     = GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].ttly,     (gdouble)val_ptr->point[currPtidx].ttly);
+    cur_ptr->currTTRX     = GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].ttrx,     (gdouble)val_ptr->point[currPtidx].ttrx);
+    cur_ptr->currTTRY     = GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].ttry,     (gdouble)val_ptr->point[currPtidx].ttry);
+    cur_ptr->currTBLX     = GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].tblx,     (gdouble)val_ptr->point[currPtidx].tblx);
+    cur_ptr->currTBLY     = GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].tbly,     (gdouble)val_ptr->point[currPtidx].tbly);
+    cur_ptr->currTBRX     = GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].tbrx,     (gdouble)val_ptr->point[currPtidx].tbrx);
+    cur_ptr->currTBRY     = GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].tbry,     (gdouble)val_ptr->point[currPtidx].tbry);
   }
 
   /* calculate Selection Feather Radius settings for the currently processed Frame (or tween) */
@@ -1142,11 +1136,11 @@ p_calculate_settings_for_current_FrameTween(
                                                       , currFrameTweenInSegment
                                                       , val_ptr->point[startOfSegmentIndex].accSelFeatherRadius
                                                       );
-    cur_ptr->currSelFeatherRadius = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].sel_feather_radius,     (gdouble)val_ptr->point[endOfSegmentIndex].sel_feather_radius);
+    cur_ptr->currSelFeatherRadius = GAP_BASE_MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].sel_feather_radius,     (gdouble)val_ptr->point[endOfSegmentIndex].sel_feather_radius);
   }
   else
   {
-    cur_ptr->currSelFeatherRadius = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].sel_feather_radius,     (gdouble)val_ptr->point[currPtidx].sel_feather_radius);
+    cur_ptr->currSelFeatherRadius = GAP_BASE_MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].sel_feather_radius,     (gdouble)val_ptr->point[currPtidx].sel_feather_radius);
   }
 
   return(frameNrAtEndOfSegment);
diff --git a/gap/gap_story_att_trans_dlg.c b/gap/gap_story_att_trans_dlg.c
old mode 100644
new mode 100755
index 5d11ffa..3171627
--- a/gap/gap_story_att_trans_dlg.c
+++ b/gap/gap_story_att_trans_dlg.c
@@ -50,6 +50,7 @@
 #include "gap_vin.h"
 #include "gap_timeconv.h"
 #include "gap_layer_copy.h"
+#include "gap_accel_da.h"
 
 
 #include "gap-intl.h"
@@ -117,6 +118,7 @@ static void     p_attw_dur_button_clicked_callback(GtkWidget *widget
 static void     p_attw_gdouble_adjustment_callback(GtkObject *obj, gdouble *val);
 static void     p_duration_dependent_refresh(GapStbAttrWidget *attw);
 static void     p_attw_duration_adjustment_callback(GtkObject *obj, gint32 *val);
+static void     p_attw_accel_adjustment_callback(GtkObject *obj, gint32 *val);
 static void     p_attw_enable_toggle_update_callback(GtkWidget *widget, gboolean *val);
 
 static void     p_attw_auto_update_toggle_update_callback(GtkWidget *widget, gboolean *val);
@@ -226,6 +228,8 @@ static void     p_create_and_attach_att_arr_widgets(const char *row_title
                  , gdouble    *att_arr_value_to_ptr
                  , const char *dur_tooltip
                  , gint32     *att_arr_value_dur_ptr
+                 , const char *accel_tooltip
+                 , gint32     *att_arr_value_accel_ptr
                  );
 
 /* ---------------------------------
@@ -349,6 +353,8 @@ p_attw_prop_reset_all(GapStbAttrWidget *attw)
         gtk_adjustment_set_value(GTK_ADJUSTMENT(attw->att_rows[ii].spinbutton_dur_adj)
                                 , attw->stb_elem_refptr->att_arr_value_dur[ii]);
 
+        gtk_adjustment_set_value(GTK_ADJUSTMENT(attw->att_rows[ii].spinbutton_accel_adj)
+                                , attw->stb_elem_refptr->att_arr_value_accel[ii]);
       }
       gtk_adjustment_set_value(GTK_ADJUSTMENT(attw->spinbutton_overlap_dur_adj)
                                 , attw->stb_elem_refptr->att_overlap);
@@ -491,6 +497,7 @@ p_attw_update_sensitivity(GapStbAttrWidget *attw)
     gtk_widget_set_sensitive(attw->att_rows[ii].button_from, sensitive);
     gtk_widget_set_sensitive(attw->att_rows[ii].button_to, sensitive);
     gtk_widget_set_sensitive(attw->att_rows[ii].button_dur, sensitive);
+    gtk_widget_set_sensitive(attw->att_rows[ii].spinbutton_accel, sensitive);
 
   }
 
@@ -800,6 +807,42 @@ p_attw_duration_adjustment_callback(GtkObject *obj, gint32 *val)
 }  /* end p_attw_duration_adjustment_callback */
 
 
+/* -----------------------------------
+ * p_attw_accel_adjustment_callback
+ * -----------------------------------
+ */
+static void
+p_attw_accel_adjustment_callback(GtkObject *obj, gint32 *val)
+{
+  GapStbAttrWidget *attw;
+  gint32 l_val;
+
+
+  attw = g_object_get_data( G_OBJECT(obj), OBJ_DATA_KEY_ATTW );
+  if(attw)
+  {
+    if(attw->stb_elem_refptr)
+    {
+      l_val = RINT (GTK_ADJUSTMENT(obj)->value);
+      if(gap_debug)
+      {
+        printf("accel gint32_adjustment_callback: obj:%d old_val:%d val:%d\n"
+             ,(int)obj
+             ,(int)*val
+             ,(int)l_val
+             );
+      }
+      if(l_val != *val)
+      {
+        p_attw_push_undo_and_set_unsaved_changes(attw);
+        *val = l_val;
+        
+      }
+    }
+  }
+
+}  /* end p_attw_accel_adjustment_callback */
+
 /* ------------------------------------
  * p_attw_enable_toggle_update_callback
  * ------------------------------------
@@ -2357,6 +2400,8 @@ p_create_and_attach_att_arr_widgets(const char *row_title
    , gdouble    *att_arr_value_to_ptr
    , const char *dur_tooltip
    , gint32     *att_arr_value_dur_ptr
+   , const char *accel_tooltip
+   , gint32     *att_arr_value_accel_ptr
   )
 {
   GtkWidget *label;
@@ -2511,7 +2556,7 @@ p_create_and_attach_att_arr_widgets(const char *row_title
   gtk_table_attach (GTK_TABLE (table), spinbutton, col, col+1, row, row+1,
                     (GtkAttachOptions) (0),
                     (GtkAttachOptions) (0), 0, 0);
-  gtk_widget_set_size_request (spinbutton, 80, -1);
+  gtk_widget_set_size_request (spinbutton, 60, -1);
   gimp_help_set_help_data (spinbutton, _("Number of frames (duration of transition from start to end value)"), NULL);
 
   g_object_set_data(G_OBJECT(adj), OBJ_DATA_KEY_ATTW, attw);
@@ -2528,6 +2573,51 @@ p_create_and_attach_att_arr_widgets(const char *row_title
   gtk_widget_show (label);
   attw->att_rows[att_type_idx].dur_time_label = label;
 
+  col++;
+
+
+  /* the acceleration characteristic graph display widget */
+  {
+#define ACC_WGT_WIDTH 32
+#define ACC_WGT_HEIGHT 22
+
+    gint32           accelerationCharacteristic;
+    GapAccelWidget  *accel_wgt;
+
+    accelerationCharacteristic = *att_arr_value_accel_ptr;
+    accel_wgt = gap_accel_new(ACC_WGT_WIDTH, ACC_WGT_HEIGHT, accelerationCharacteristic);
+    
+    /* the Acceleration characteristic value spinbutton */
+    adj = accel_wgt->adj;
+    
+    spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
+    attw->att_rows[att_type_idx].spinbutton_accel_adj = adj;
+    attw->att_rows[att_type_idx].spinbutton_accel = spinbutton;
+
+    gtk_widget_show (spinbutton);
+    gtk_table_attach (GTK_TABLE (table), spinbutton, col+1, col+2, row, row+1,
+                    (GtkAttachOptions) (0),
+                    (GtkAttachOptions) (0), 0, 0);
+    gtk_widget_set_size_request (spinbutton, 50, -1);
+    gimp_help_set_help_data (spinbutton, accel_tooltip, NULL);
+
+    g_object_set_data(G_OBJECT(adj), OBJ_DATA_KEY_ATTW, attw);
+    
+    gtk_table_attach( GTK_TABLE(table), accel_wgt->da_widget, col, col+1, row, row+1,
+                        GTK_FILL, 0, 4, 0 );
+    gtk_widget_show (accel_wgt->da_widget);
+    
+    
+    
+    g_signal_connect (G_OBJECT (adj), "value_changed",
+                      G_CALLBACK (p_attw_accel_adjustment_callback),
+                      att_arr_value_accel_ptr);
+ 
+  }
+
+
+
+
 }  /* end p_create_and_attach_att_arr_widgets */
 
 
@@ -2709,7 +2799,7 @@ gap_story_attw_properties_dialog (GapStbAttrWidget *attw)
     gtk_table_attach (GTK_TABLE (table), spinbutton, 7, 8, row, row+1,
                       (GtkAttachOptions) (0),
                       (GtkAttachOptions) (0), 0, 0);
-    gtk_widget_set_size_request (spinbutton, 80, -1);
+    gtk_widget_set_size_request (spinbutton, 60, -1);
     gimp_help_set_help_data (spinbutton, _("Number of overlapping frames within this track"), NULL);
 
     g_object_set_data(G_OBJECT(adj), OBJ_DATA_KEY_ATTW, attw);
@@ -2747,6 +2837,8 @@ gap_story_attw_properties_dialog (GapStbAttrWidget *attw)
       , &attw->stb_elem_refptr->att_arr_value_to[att_type_idx]
       , _("number of frames")
       , &attw->stb_elem_refptr->att_arr_value_dur[att_type_idx]
+      , _("acceleration characteristic for opacity (1 for constant speed, positive: acceleration, negative: deceleration)")
+      , &attw->stb_elem_refptr->att_arr_value_accel[att_type_idx]
       );
 
     row++;
@@ -2773,6 +2865,8 @@ gap_story_attw_properties_dialog (GapStbAttrWidget *attw)
       , &attw->stb_elem_refptr->att_arr_value_to[att_type_idx]
       , _("number of frames")
       , &attw->stb_elem_refptr->att_arr_value_dur[att_type_idx]
+      , _("acceleration characteristic for horizontal move (1 for constant speed, positive: acceleration, negative: deceleration)")
+      , &attw->stb_elem_refptr->att_arr_value_accel[att_type_idx]
       );
 
 
@@ -2800,6 +2894,8 @@ gap_story_attw_properties_dialog (GapStbAttrWidget *attw)
       , &attw->stb_elem_refptr->att_arr_value_to[att_type_idx]
       , _("number of frames")
       , &attw->stb_elem_refptr->att_arr_value_dur[att_type_idx]
+      , _("acceleration characteristic for vertical move (1 for constant speed, positive: acceleration, negative: deceleration)")
+      , &attw->stb_elem_refptr->att_arr_value_accel[att_type_idx]
       );
 
     row++;
@@ -2826,6 +2922,8 @@ gap_story_attw_properties_dialog (GapStbAttrWidget *attw)
       , &attw->stb_elem_refptr->att_arr_value_to[att_type_idx]
       , _("number of frames")
       , &attw->stb_elem_refptr->att_arr_value_dur[att_type_idx]
+      , _("acceleration characteristic for scale width (1 for constant speed, positive: acceleration, negative: deceleration)")
+      , &attw->stb_elem_refptr->att_arr_value_accel[att_type_idx]
       );
 
     row++;
@@ -2852,6 +2950,8 @@ gap_story_attw_properties_dialog (GapStbAttrWidget *attw)
       , &attw->stb_elem_refptr->att_arr_value_to[att_type_idx]
       , _("number of frames")
       , &attw->stb_elem_refptr->att_arr_value_dur[att_type_idx]
+      , _("acceleration characteristic for scale height (1 for constant speed, positive: acceleration, negative: deceleration)")
+      , &attw->stb_elem_refptr->att_arr_value_accel[att_type_idx]
       );
 
   }
diff --git a/gap/gap_story_file.c b/gap/gap_story_file.c
old mode 100644
new mode 100755
index 58183d0..4bf1869
--- a/gap/gap_story_file.c
+++ b/gap/gap_story_file.c
@@ -235,6 +235,7 @@ gap_story_debug_print_elem(GapStoryElem *stb_elem)
       printf("  filtermacro_file: (NULL)\n");
     }
     printf("  fmac_total_steps: %d\n", (int)stb_elem->fmac_total_steps);
+    printf("  fmac_accel:       %d\n", (int)stb_elem->fmac_accel);
 
     if(stb_elem->preferred_decoder)
     {
@@ -252,12 +253,13 @@ gap_story_debug_print_elem(GapStoryElem *stb_elem)
       {
         if(stb_elem->att_arr_enable[ii])
         {
-          printf("  [%d] %s  from: %f  to: %f   dur: %d\n"
+          printf("  [%d] %s  from: %f  to: %f   dur: %d  accel: %d\n"
             , (int)ii
             , gtab_att_transition_key_words[ii]
             , (float)stb_elem->att_arr_value_from[ii]
             , (float)stb_elem->att_arr_value_to[ii]
             , (int)stb_elem->att_arr_value_dur[ii]
+            , (int)stb_elem->att_arr_value_accel[ii]
             );
         }
       }
@@ -701,6 +703,7 @@ gap_story_new_elem(GapStoryRecordType record_type)
     stb_elem->delace = 0.0;
     stb_elem->filtermacro_file = NULL;
     stb_elem->fmac_total_steps = 1;
+    stb_elem->fmac_accel = 0;              /* default: use no acceleration */
     stb_elem->preferred_decoder = NULL;
     stb_elem->from_frame = 1;
     stb_elem->to_frame = 1;
@@ -736,6 +739,7 @@ gap_story_new_elem(GapStoryRecordType record_type)
         stb_elem->att_arr_value_from[ii] = gap_story_get_default_attribute(ii);
         stb_elem->att_arr_value_to[ii] = gap_story_get_default_attribute(ii);
         stb_elem->att_arr_value_dur[ii] = 1;        /* number of frames to change from -> to value */
+        stb_elem->att_arr_value_accel[ii] = 0;      /* per default use no acceleration characteristic */
       }
     }
 
@@ -2818,6 +2822,7 @@ p_assign_parsed_video_values(GapStoryElem *stb_elem
   , char *mask_stepsize_ptr
   , char *mask_disable_ptr
   , char *fmac_total_steps_ptr
+  , char *fmac_accel_ptr
   )
 {
   if(nloops_ptr)
@@ -2920,8 +2925,42 @@ p_assign_parsed_video_values(GapStoryElem *stb_elem
     }
   }
 
+  if(fmac_accel_ptr)
+  {
+    if (*fmac_accel_ptr)
+    {
+      stb_elem->fmac_accel = p_scan_gint32(fmac_accel_ptr,  -1000, 1000, stb);
+    }
+  }
+
+
 }  /* end p_assign_parsed_video_values */
 
+
+/* ------------------------------
+ * p_assign_accel_attr
+ * ------------------------------
+ * assign acceleration characteristic for the transition attribute [ii]
+ * if information is present (e.g accel_ptr is not null and points to a value)
+ */
+static void
+p_assign_accel_attr(GapStoryElem *stb_elem
+  , GapStoryBoard *stb
+  , char *accel_ptr
+  , gint ii
+  )
+{
+  if(accel_ptr)
+  {
+    if(*accel_ptr)
+    {
+      stb_elem->att_arr_value_accel[ii] = p_scan_gint32(accel_ptr,  -1000, 1000, stb);
+    }
+  }
+}  /* end p_assign_accel_attr */
+
+
+
 /* ------------------------------
  * p_story_parse_line
  * ------------------------------
@@ -2945,7 +2984,7 @@ static void
 p_story_parse_line(GapStoryBoard *stb, char *longline
    , gint32 longlinenr, char *multi_lines)
 {
-#define GAP_MAX_STB_PARAMS_PER_LINE 19
+#define GAP_MAX_STB_PARAMS_PER_LINE 20
   char *l_scan_ptr;
   char *l_record_key;
   char *l_parname;
@@ -3246,6 +3285,7 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
     char *l_from_ptr       = l_wordval[2];
     char *l_to_ptr         = l_wordval[3];
     char *l_dur_ptr        = l_wordval[4];
+    char *l_accel_ptr      = l_wordval[5];
 
     gint32 l_track_nr;
 
@@ -3296,10 +3336,12 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
         stb_elem->file_line_nr = longlinenr;
         stb_elem->orig_src_line = g_strdup(multi_lines);
         stb_elem->track = l_track_nr;
-        if(*l_from_ptr)     { stb_elem->att_arr_value_from[ii] = p_scan_gdouble(l_from_ptr, 0.0, 1.0, stb); }
-        if(*l_to_ptr)       { stb_elem->att_arr_value_to[ii]   = p_scan_gdouble(l_to_ptr,   0.0, 1.0, stb); }
-        else                { stb_elem->att_arr_value_to[ii]   = stb_elem->att_arr_value_from[ii]; }
-        if(*l_dur_ptr)      { stb_elem->att_arr_value_dur[ii]  = p_scan_gint32(l_dur_ptr,  0, 999, stb); }
+        if(*l_from_ptr)     { stb_elem->att_arr_value_from[ii]  = p_scan_gdouble(l_from_ptr, 0.0, 1.0, stb); }
+        if(*l_to_ptr)       { stb_elem->att_arr_value_to[ii]    = p_scan_gdouble(l_to_ptr,   0.0, 1.0, stb); }
+        else                { stb_elem->att_arr_value_to[ii]    = stb_elem->att_arr_value_from[ii]; }
+        if(*l_dur_ptr)      { stb_elem->att_arr_value_dur[ii]   = p_scan_gint32(l_dur_ptr,  0, 999, stb); }
+        
+        p_assign_accel_attr(stb_elem, stb, l_accel_ptr, ii);
 
         if(elem_already_in_the_list != TRUE)
         {
@@ -3322,10 +3364,12 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
         stb_elem->file_line_nr = longlinenr;
         stb_elem->orig_src_line = g_strdup(multi_lines);
         stb_elem->track = l_track_nr;
-        if(*l_from_ptr)     { stb_elem->att_arr_value_from[ii] = p_scan_gdouble(l_from_ptr, 0.0001, 999.9, stb); }
-        if(*l_to_ptr)       { stb_elem->att_arr_value_to[ii]   = p_scan_gdouble(l_to_ptr,   0.0001, 999.9, stb); }
-        else                { stb_elem->att_arr_value_to[ii]   = stb_elem->att_arr_value_from[ii]; }
-        if(*l_dur_ptr)      { stb_elem->att_arr_value_dur[ii]  = p_scan_gint32(l_dur_ptr,  0, 999, stb); }
+        if(*l_from_ptr)     { stb_elem->att_arr_value_from[ii]  = p_scan_gdouble(l_from_ptr, 0.0001, 999.9, stb); }
+        if(*l_to_ptr)       { stb_elem->att_arr_value_to[ii]    = p_scan_gdouble(l_to_ptr,   0.0001, 999.9, stb); }
+        else                { stb_elem->att_arr_value_to[ii]    = stb_elem->att_arr_value_from[ii]; }
+        if(*l_dur_ptr)      { stb_elem->att_arr_value_dur[ii]   = p_scan_gint32(l_dur_ptr,  0, 999, stb); }
+        
+        p_assign_accel_attr(stb_elem, stb, l_accel_ptr, ii);
 
         if(elem_already_in_the_list != TRUE)
         {
@@ -3348,10 +3392,12 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
         stb_elem->file_line_nr = longlinenr;
         stb_elem->orig_src_line = g_strdup(multi_lines);
         stb_elem->track = l_track_nr;
-        if(*l_from_ptr)     { stb_elem->att_arr_value_from[ii] = p_scan_gdouble(l_from_ptr, 0.0001, 999.9, stb); }
-        if(*l_to_ptr)       { stb_elem->att_arr_value_to[ii]   = p_scan_gdouble(l_to_ptr,   0.0001, 999.9, stb); }
-        else                { stb_elem->att_arr_value_to[ii]   = stb_elem->att_arr_value_from[ii]; }
-        if(*l_dur_ptr)      { stb_elem->att_arr_value_dur[ii]  = p_scan_gint32(l_dur_ptr,  0, 999, stb); }
+        if(*l_from_ptr)     { stb_elem->att_arr_value_from[ii]  = p_scan_gdouble(l_from_ptr, 0.0001, 999.9, stb); }
+        if(*l_to_ptr)       { stb_elem->att_arr_value_to[ii]    = p_scan_gdouble(l_to_ptr,   0.0001, 999.9, stb); }
+        else                { stb_elem->att_arr_value_to[ii]    = stb_elem->att_arr_value_from[ii]; }
+        if(*l_dur_ptr)      { stb_elem->att_arr_value_dur[ii]   = p_scan_gint32(l_dur_ptr,  0, 999, stb); }
+        
+        p_assign_accel_attr(stb_elem, stb, l_accel_ptr, ii);
 
         if(elem_already_in_the_list != TRUE)
         {
@@ -3374,10 +3420,12 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
         stb_elem->file_line_nr = longlinenr;
         stb_elem->orig_src_line = g_strdup(multi_lines);
         stb_elem->track = l_track_nr;
-        if(*l_from_ptr)     { stb_elem->att_arr_value_from[ii] = p_scan_gdouble(l_from_ptr, -99999.9, 99999.9, stb); }
-        if(*l_to_ptr)       { stb_elem->att_arr_value_to[ii]   = p_scan_gdouble(l_to_ptr,   -99999.9, 99999.9, stb); }
-        else                { stb_elem->att_arr_value_to[ii]   = stb_elem->att_arr_value_from[ii]; }
-        if(*l_dur_ptr)      { stb_elem->att_arr_value_dur[ii]  = p_scan_gint32(l_dur_ptr,  0, 999, stb); }
+        if(*l_from_ptr)     { stb_elem->att_arr_value_from[ii]  = p_scan_gdouble(l_from_ptr, -99999.9, 99999.9, stb); }
+        if(*l_to_ptr)       { stb_elem->att_arr_value_to[ii]    = p_scan_gdouble(l_to_ptr,   -99999.9, 99999.9, stb); }
+        else                { stb_elem->att_arr_value_to[ii]    = stb_elem->att_arr_value_from[ii]; }
+        if(*l_dur_ptr)      { stb_elem->att_arr_value_dur[ii]   = p_scan_gint32(l_dur_ptr,  0, 999, stb); }
+        
+        p_assign_accel_attr(stb_elem, stb, l_accel_ptr, ii);
 
         if(elem_already_in_the_list != TRUE)
         {
@@ -3400,10 +3448,12 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
         stb_elem->file_line_nr = longlinenr;
         stb_elem->orig_src_line = g_strdup(multi_lines);
         stb_elem->track = l_track_nr;
-        if(*l_from_ptr)     { stb_elem->att_arr_value_from[ii] = p_scan_gdouble(l_from_ptr, -99999.9, 99999.9, stb); }
-        if(*l_to_ptr)       { stb_elem->att_arr_value_to[ii]   = p_scan_gdouble(l_to_ptr,   -99999.9, 99999.9, stb); }
-        else                { stb_elem->att_arr_value_to[ii]   = stb_elem->att_arr_value_from[ii]; }
-        if(*l_dur_ptr)      { stb_elem->att_arr_value_dur[ii]  = p_scan_gint32(l_dur_ptr,  0, 999, stb); }
+        if(*l_from_ptr)     { stb_elem->att_arr_value_from[ii]  = p_scan_gdouble(l_from_ptr, -99999.9, 99999.9, stb); }
+        if(*l_to_ptr)       { stb_elem->att_arr_value_to[ii]    = p_scan_gdouble(l_to_ptr,   -99999.9, 99999.9, stb); }
+        else                { stb_elem->att_arr_value_to[ii]    = stb_elem->att_arr_value_from[ii]; }
+        if(*l_dur_ptr)      { stb_elem->att_arr_value_dur[ii]   = p_scan_gint32(l_dur_ptr,  0, 999, stb); }
+        
+        p_assign_accel_attr(stb_elem, stb, l_accel_ptr, ii);
 
         if(elem_already_in_the_list != TRUE)
         {
@@ -3527,6 +3577,7 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
     char *l_mask_stepsize_ptr = l_wordval[8];
     char *l_mask_disable_ptr  = l_wordval[9];
     char *l_fmac_total_steps_ptr  = l_wordval[10];
+    char *l_fmac_accel_ptr        = l_wordval[11];
 
 
     stb_elem = gap_story_new_elem(GAP_STBREC_VID_IMAGE);
@@ -3550,6 +3601,7 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
           , l_mask_stepsize_ptr
           , l_mask_disable_ptr
           , l_fmac_total_steps_ptr
+          , l_fmac_accel_ptr
           );
 
       p_check_image_numpart(stb_elem, l_filename_ptr);
@@ -3579,6 +3631,7 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
     char *l_mask_stepsize_ptr = l_wordval[13];
     char *l_mask_disable_ptr  = l_wordval[14];
     char *l_fmac_total_steps_ptr  = l_wordval[15];
+    char *l_fmac_accel_ptr        = l_wordval[16];
 
     stb_elem = gap_story_new_elem(GAP_STBREC_VID_FRAMES);
     if(stb_elem)
@@ -3607,6 +3660,7 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
           , l_mask_stepsize_ptr
           , l_mask_disable_ptr
           , l_fmac_total_steps_ptr
+          , l_fmac_accel_ptr
           );
 
       if((*l_basename_ptr)
@@ -3647,6 +3701,7 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
     char *l_mask_stepsize_ptr = l_wordval[16];
     char *l_mask_disable_ptr  = l_wordval[17];
     char *l_fmac_total_steps_ptr  = l_wordval[18];
+    char *l_fmac_accel_ptr        = l_wordval[19];
 
     stb_elem = gap_story_new_elem(GAP_STBREC_VID_MOVIE);
     if(stb_elem)
@@ -3678,6 +3733,7 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
           , l_mask_stepsize_ptr
           , l_mask_disable_ptr
           , l_fmac_total_steps_ptr
+          , l_fmac_accel_ptr
           );
 
 
@@ -3709,6 +3765,7 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
     char *l_mask_stepsize_ptr = l_wordval[12];
     char *l_mask_disable_ptr  = l_wordval[13];
     char *l_fmac_total_steps_ptr  = l_wordval[14];
+    char *l_fmac_accel_ptr        = l_wordval[15];
     GapStorySection *l_main_section;
     
     l_main_section = gap_story_find_main_section(stb);
@@ -3749,6 +3806,7 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
           , l_mask_stepsize_ptr
           , l_mask_disable_ptr
           , l_fmac_total_steps_ptr
+          , l_fmac_accel_ptr
           );
 
       gap_story_list_append_elem(stb, stb_elem);
@@ -3775,6 +3833,7 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
     char *l_mask_stepsize_ptr = l_wordval[11];
     char *l_mask_disable_ptr  = l_wordval[12];
     char *l_fmac_total_steps_ptr  = l_wordval[13];
+    char *l_fmac_accel_ptr        = l_wordval[14];
 
     stb_elem = gap_story_new_elem(GAP_STBREC_VID_COLOR);
     if(stb_elem)
@@ -3799,6 +3858,7 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
           , l_mask_stepsize_ptr
           , l_mask_disable_ptr
           , l_fmac_total_steps_ptr
+          , l_fmac_accel_ptr
           );
 
       gap_story_list_append_elem(stb, stb_elem);
@@ -3825,6 +3885,7 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
     char *l_mask_stepsize_ptr = l_wordval[12];
     char *l_mask_disable_ptr  = l_wordval[13];
     char *l_fmac_total_steps_ptr  = l_wordval[14];
+    char *l_fmac_accel_ptr        = l_wordval[15];
 
     stb_elem = gap_story_new_elem(GAP_STBREC_VID_ANIMIMAGE);
     if(stb_elem)
@@ -3849,6 +3910,7 @@ p_story_parse_line(GapStoryBoard *stb, char *longline
           , l_mask_stepsize_ptr
           , l_mask_disable_ptr
           , l_fmac_total_steps_ptr
+          , l_fmac_accel_ptr
           );
 
       gap_story_list_append_elem(stb, stb_elem);
@@ -4728,12 +4790,19 @@ p_story_save_att_transition(FILE *fp, GapStoryElem *stb_elem)
         fprintf(fp, " ");
       }
 
-      fprintf(fp, "%s:%d %s:%s %s:%s %s:%d\n"
+      fprintf(fp, "%s:%d %s:%s %s:%s %s:%d"
                  , l_parnam_tab.parname[1]              , (int)stb_elem->track
                  , l_parnam_tab.parname[2]              , l_from_str
                  , l_parnam_tab.parname[3]              , l_to_str
                  , l_parnam_tab.parname[4]              , stb_elem->att_arr_value_dur[ii]
                  );
+      if(stb_elem->att_arr_value_accel[ii] != 0)
+      {
+        fprintf(fp, " %s:%d"
+                 , l_parnam_tab.parname[5]              , stb_elem->att_arr_value_accel[ii]
+                 );
+      }
+      fprintf(fp, "\n");
     }
   }
 
@@ -5460,6 +5529,42 @@ p_story_save_flip_and_mask_params(FILE *fp, GapStoryElem *stb_elem
 
 }  /* end p_story_save_flip_and_mask_params */
 
+/* ---------------------------------
+ * p_story_save_filtermacro_params
+ * ---------------------------------
+ * print the optional filtermacro parameters
+ * to file (only in case where specified and necessary)
+ */
+static void
+p_story_save_filtermacro_params(FILE *fp, GapStoryElem *stb_elem
+  , const char *parname_fmac_file
+  , const char *parname_fmac_steps
+  , const char *parname_fmac_accel
+  )
+{
+  if(stb_elem->filtermacro_file)
+  {
+    fprintf(fp, " %s:\"%s\""
+       , parname_fmac_file
+       , stb_elem->filtermacro_file
+       );
+    if(stb_elem->fmac_total_steps > 1)
+    {
+      fprintf(fp, " %s:%d"
+         , parname_fmac_steps
+         , (int)stb_elem->fmac_total_steps
+         );
+    }
+    if(stb_elem->fmac_accel != 0)
+    {
+      fprintf(fp, " %s:%d"
+         , parname_fmac_accel
+         , (int)stb_elem->fmac_accel
+         );
+    }
+  }
+
+}  /* end p_story_save_filtermacro_params */
 
 /* ------------------------------
  * p_story_save_video_list
@@ -5565,20 +5670,11 @@ p_story_save_video_list(GapStoryBoard *stb, FILE *fp, gint32 save_track
                , l_parnam_tab.parname[8], l_dbl_str_step_density
                );
 
-          if(stb_elem->filtermacro_file)
-          {
-            fprintf(fp, " %s:\"%s\""
-               , l_parnam_tab.parname[9]
-               , stb_elem->filtermacro_file
-               );
-            if(stb_elem->fmac_total_steps > 1)
-            {
-              fprintf(fp, " %s:%d"
-                 , l_parnam_tab.parname[15]
-                 , stb_elem->fmac_total_steps
-                 );
-            }
-          }
+          p_story_save_filtermacro_params(fp, stb_elem
+	      , l_parnam_tab.parname[9]   /* parname_fmac_file */
+	      , l_parnam_tab.parname[15]  /* parname_fmac_steps */
+	      , l_parnam_tab.parname[16]  /* parname_fmac_accel */
+              );
 
           p_story_save_flip_and_mask_params(fp, stb_elem
                   , l_parnam_tab.parname[10]  /* parname_flip  */
@@ -5607,20 +5703,12 @@ p_story_save_video_list(GapStoryBoard *stb, FILE *fp, gint32 save_track
                , l_parnam_tab.parname[2], stb_elem->orig_filename
                , l_parnam_tab.parname[3], (int)stb_elem->nloop
                );
-        if(stb_elem->filtermacro_file)
-        {
-          fprintf(fp, " %s:\"%s\""
-               , l_parnam_tab.parname[4]
-               , stb_elem->filtermacro_file
-               );
-          if(stb_elem->fmac_total_steps > 1)
-          {
-              fprintf(fp, " %s:%d"
-                 , l_parnam_tab.parname[10]
-                 , stb_elem->fmac_total_steps
-                 );
-          }
-        }
+
+        p_story_save_filtermacro_params(fp, stb_elem
+	      , l_parnam_tab.parname[4]   /* parname_fmac_file */
+	      , l_parnam_tab.parname[10]  /* parname_fmac_steps */
+	      , l_parnam_tab.parname[11]  /* parname_fmac_accel */
+              );
 
         p_story_save_flip_and_mask_params(fp, stb_elem
                   , l_parnam_tab.parname[5]  /* parname_flip  */
@@ -5661,20 +5749,12 @@ p_story_save_video_list(GapStoryBoard *stb, FILE *fp, gint32 save_track
                , l_parnam_tab.parname[10], l_dbl_str_step_density
                );
 
-          if(stb_elem->filtermacro_file)
-          {
-            fprintf(fp, " %s:\"%s\""
-               , l_parnam_tab.parname[11]
-               , stb_elem->filtermacro_file
-               );
-            if(stb_elem->fmac_total_steps > 1)
-            {
-              fprintf(fp, " %s:%d"
-                 , l_parnam_tab.parname[18]
-                 , stb_elem->fmac_total_steps
-                 );
-            }
-          }
+          p_story_save_filtermacro_params(fp, stb_elem
+	      , l_parnam_tab.parname[11]  /* parname_fmac_file */
+	      , l_parnam_tab.parname[18]  /* parname_fmac_steps */
+	      , l_parnam_tab.parname[19]  /* parname_fmac_accel */
+              );
+
           if(stb_elem->preferred_decoder)
           {
             fprintf(fp, " %s:\"%s\""
@@ -5734,20 +5814,11 @@ p_story_save_video_list(GapStoryBoard *stb, FILE *fp, gint32 save_track
                , l_parnam_tab.parname[7], l_dbl_str_step_density
                );
 
-          if(stb_elem->filtermacro_file)
-          {
-            fprintf(fp, " %s:\"%s\""
-               , l_parnam_tab.parname[8]
-               , stb_elem->filtermacro_file
-               );
-            if(stb_elem->fmac_total_steps > 1)
-            {
-              fprintf(fp, " %s:%d"
-                 , l_parnam_tab.parname[14]
-                 , stb_elem->fmac_total_steps
-                 );
-            }
-          }
+          p_story_save_filtermacro_params(fp, stb_elem
+	      , l_parnam_tab.parname[8]   /* parname_fmac_file */
+	      , l_parnam_tab.parname[14]  /* parname_fmac_steps */
+	      , l_parnam_tab.parname[15]  /* parname_fmac_accel */
+              );
 
           p_story_save_flip_and_mask_params(fp, stb_elem
                   , l_parnam_tab.parname[9]  /* parname_flip  */
@@ -5782,23 +5853,14 @@ p_story_save_video_list(GapStoryBoard *stb, FILE *fp, gint32 save_track
                , l_parnam_tab.parname[7], l_dbl_str_step_density
                );
 
-          if(stb_elem->filtermacro_file)
-          {
-            fprintf(fp, " %s:\"%s\""
-               , l_parnam_tab.parname[8]
-               , stb_elem->filtermacro_file
-               );
-            if(stb_elem->fmac_total_steps > 1)
-            {
-              fprintf(fp, " %s:%d"
-                 , l_parnam_tab.parname[14]
-                 , stb_elem->fmac_total_steps
-                 );
-            }
-          }
+          p_story_save_filtermacro_params(fp, stb_elem
+	      , l_parnam_tab.parname[8]   /* parname_fmac_file */
+	      , l_parnam_tab.parname[14]  /* parname_fmac_steps */
+	      , l_parnam_tab.parname[15]  /* parname_fmac_accel */
+              );
 
           p_story_save_flip_and_mask_params(fp, stb_elem
-                  , l_parnam_tab.parname[9]  /* parname_flip  */
+                  , l_parnam_tab.parname[9]   /* parname_flip  */
                   , l_parnam_tab.parname[10]  /* parname_mask_name */
                   , l_parnam_tab.parname[11]  /* parname_mask_anchor */
                   , l_parnam_tab.parname[12]  /* parname_mask_stepsize */
@@ -6701,6 +6763,7 @@ gap_story_elem_duplicate(GapStoryElem      *stb_elem)
     stb_elem_dup->file_line_nr    = stb_elem->file_line_nr;
 
     stb_elem_dup->fmac_total_steps        = stb_elem->fmac_total_steps;
+    stb_elem_dup->fmac_accel              = stb_elem->fmac_accel;
 
     stb_elem_dup->vid_wait_untiltime_sec  = stb_elem->vid_wait_untiltime_sec;
     stb_elem_dup->color_red               = stb_elem->color_red;
@@ -6717,10 +6780,11 @@ gap_story_elem_duplicate(GapStoryElem      *stb_elem)
       gint ii;
       for(ii=0; ii < GAP_STB_ATT_TYPES_ARRAY_MAX; ii++)
       {
-        stb_elem_dup->att_arr_enable[ii]     = stb_elem->att_arr_enable[ii];
-        stb_elem_dup->att_arr_value_from[ii] = stb_elem->att_arr_value_from[ii];
-        stb_elem_dup->att_arr_value_to[ii]   = stb_elem->att_arr_value_to[ii];
-        stb_elem_dup->att_arr_value_dur[ii]  = stb_elem->att_arr_value_dur[ii];
+        stb_elem_dup->att_arr_enable[ii]      = stb_elem->att_arr_enable[ii];
+        stb_elem_dup->att_arr_value_from[ii]  = stb_elem->att_arr_value_from[ii];
+        stb_elem_dup->att_arr_value_to[ii]    = stb_elem->att_arr_value_to[ii];
+        stb_elem_dup->att_arr_value_dur[ii]   = stb_elem->att_arr_value_dur[ii];
+        stb_elem_dup->att_arr_value_accel[ii] = stb_elem->att_arr_value_accel[ii];
       }
     }
     stb_elem_dup->flip_request            = stb_elem->flip_request;
@@ -6815,6 +6879,9 @@ gap_story_elem_copy(GapStoryElem *stb_elem_dst, GapStoryElem *stb_elem)
     stb_elem_dst->step_density    = stb_elem->step_density;
     stb_elem_dst->file_line_nr    = stb_elem->file_line_nr;
 
+    stb_elem_dst->fmac_total_steps        = stb_elem->fmac_total_steps;
+    stb_elem_dst->fmac_accel              = stb_elem->fmac_accel;
+
 
     stb_elem_dst->vid_wait_untiltime_sec  = stb_elem->vid_wait_untiltime_sec;
     stb_elem_dst->color_red               = stb_elem->color_red;
@@ -6830,10 +6897,11 @@ gap_story_elem_copy(GapStoryElem *stb_elem_dst, GapStoryElem *stb_elem)
       gint ii;
       for(ii=0; ii < GAP_STB_ATT_TYPES_ARRAY_MAX; ii++)
       {
-        stb_elem_dst->att_arr_enable[ii]     = stb_elem->att_arr_enable[ii];
-        stb_elem_dst->att_arr_value_from[ii] = stb_elem->att_arr_value_from[ii];
-        stb_elem_dst->att_arr_value_to[ii]   = stb_elem->att_arr_value_to[ii];
-        stb_elem_dst->att_arr_value_dur[ii]  = stb_elem->att_arr_value_dur[ii];
+        stb_elem_dst->att_arr_enable[ii]      = stb_elem->att_arr_enable[ii];
+        stb_elem_dst->att_arr_value_from[ii]  = stb_elem->att_arr_value_from[ii];
+        stb_elem_dst->att_arr_value_to[ii]    = stb_elem->att_arr_value_to[ii];
+        stb_elem_dst->att_arr_value_dur[ii]   = stb_elem->att_arr_value_dur[ii];
+        stb_elem_dst->att_arr_value_accel[ii] = stb_elem->att_arr_value_accel[ii];
       }
     }
 
@@ -8726,7 +8794,7 @@ gap_story_get_default_attribute(gint att_typ_idx)
  * gap_story_file_calculate_render_attributes
  * ------------------------------------------
  * perform calculations for rendering a layer or image (specified by frame_width, frame_height)
- * onto a destination image (specified by vid_width, vid_height)
+ * onto a destination image (specified by vid_width, vid_height e.g. composite image size)
  *
  * according to storyboard attribute settings
  * (specified by
@@ -8861,6 +8929,28 @@ gap_story_file_calculate_render_attributes(GapStoryCalcAttr *result_attr
   result_attr->x_offs = result_ofsx + ((view_vid_width - vid_width) / 2);
   result_attr->y_offs = result_ofsy + ((view_vid_height - vid_height) / 2);
 
+
+  /* calculate visble rectangle size after clipping */
+  if (result_attr->x_offs < 0)
+  {
+    result_attr->visible_width = MIN((result_attr->width + result_attr->x_offs) , vid_width);
+  }
+  else
+  {
+    result_attr->visible_width = MIN((vid_width - result_attr->x_offs), result_attr->width);
+  }
+
+  if (result_attr->y_offs < 0)
+  {
+    result_attr->visible_height = MIN((result_attr->height + result_attr->y_offs) , vid_height);
+  }
+  else
+  {
+    result_attr->visible_height = MIN((vid_height - result_attr->y_offs), result_attr->height);
+  }
+
+
+
   /* debug output */
   if(gap_debug)
   {
@@ -8875,13 +8965,15 @@ gap_story_file_calculate_render_attributes(GapStoryCalcAttr *result_attr
       if (keep_proportions) { printf ("ON "); } else  { printf ("OFF "); }
       printf ("\n");
     }
-    printf (" view: (%d x %d) master: (%d x %d) frame: (%d x %d)\n"
+    printf (" view: (%d x %d) master: (%d x %d) frame: (%d x %d) visible (%d x %d)\n"
               ,(int)view_vid_width
               ,(int)view_vid_height
               ,(int)vid_width
               ,(int)vid_height
               ,(int)frame_width
               ,(int)frame_height
+              ,(int)result_attr->visible_width
+              ,(int)result_attr->visible_height
               );
     printf (" scale_x:%.3f scale_y:%.3f\n", (float)scale_x , (float) scale_y);
     printf (" move_x:%.3f move_y:%.3f\n", (float)move_x , (float) move_y);
diff --git a/gap/gap_story_file.h b/gap/gap_story_file.h
old mode 100644
new mode 100755
index 4e2f845..3534641
--- a/gap/gap_story_file.h
+++ b/gap/gap_story_file.h
@@ -137,6 +137,7 @@
     gchar *preferred_decoder;
     gchar *filtermacro_file;
     gint32 fmac_total_steps;
+    gint32 fmac_accel;
     
     gint32 from_frame;
     gint32 to_frame;
@@ -170,6 +171,7 @@
     gdouble  att_arr_value_from[GAP_STB_ATT_TYPES_ARRAY_MAX];
     gdouble  att_arr_value_to[GAP_STB_ATT_TYPES_ARRAY_MAX];
     gint32   att_arr_value_dur[GAP_STB_ATT_TYPES_ARRAY_MAX];        /* number of frames to change from -> to value */
+    gint32   att_arr_value_accel[GAP_STB_ATT_TYPES_ARRAY_MAX];      /* acceleration characteristics */
     gint32   att_overlap;  /* number of overlapping frames (value > 0 will generate a shadow track) */
 
     /* new members for Audio Record types */
@@ -294,6 +296,9 @@
     gint32  x_offs;
     gint32  y_offs;
     gdouble opacity;
+    
+    gint32  visible_width;
+    gint32  visible_height;
   } GapStoryCalcAttr;
 
   typedef struct GapStoryVideoFileRef
diff --git a/gap/gap_story_main.h b/gap/gap_story_main.h
old mode 100644
new mode 100755
index db3a6fd..a59a528
--- a/gap/gap_story_main.h
+++ b/gap/gap_story_main.h
@@ -199,9 +199,14 @@ typedef struct GapStbPropWidget  /* nickname: pw */
   GtkWidget  *pw_mask_anchor_radio_button_arr[2];
   GtkObject  *pw_spinbutton_mask_stepsize_adj;
   
+  /* for filermacro handling */
+  GtkObject  *pw_spinbutton_fmac_accel_adj;
+  GtkWidget  *pw_spinbutton_fmac_accel;
   GtkWidget  *pw_spinbutton_fmac_steps;
   GtkObject  *pw_spinbutton_fmac_steps_adj;
+  GtkWidget  *pw_label_alternate_fmac2;
   GtkWidget  *pw_label_alternate_fmac_file;
+  GtkWidget  *pw_hbox_fmac2;
   
 
   struct GapStbPropWidget *next;
@@ -272,15 +277,18 @@ typedef struct GapStbAttRow
   GtkObject  *spinbutton_from_adj;
   GtkObject  *spinbutton_to_adj;
   GtkObject  *spinbutton_dur_adj;
+  GtkObject  *spinbutton_accel_adj;
   GtkWidget  *dur_time_label;
 
   GtkWidget  *spinbutton_from;
   GtkWidget  *spinbutton_to;
   GtkWidget  *spinbutton_dur;
+  GtkWidget  *spinbutton_accel;
 
   GtkWidget  *button_from;
   GtkWidget  *button_to;
   GtkWidget  *button_dur;
+
 } GapStbAttRow;
 
 typedef struct GapStbAttrWidget  /* nickname: attw */
diff --git a/gap/gap_story_properties.c b/gap/gap_story_properties.c
old mode 100644
new mode 100755
index c3e2d6a..0d032e1
--- a/gap/gap_story_properties.c
+++ b/gap/gap_story_properties.c
@@ -57,6 +57,8 @@
 #include "gap_fmac_base.h"
 #include "gap_fmac_name.h"
 #include "gap_story_vthumb.h"
+#include "gap_accel_char.h"
+#include "gap_accel_da.h"
 
 
 #include "gap-intl.h"
@@ -177,6 +179,7 @@ static void     p_delace_spinbutton_cb(GtkObject *obj, GapStbPropWidget *pw);
 static void     p_maskstep_density_spinbutton_cb(GtkObject *obj, GapStbPropWidget *pw);
 static void     p_step_density_spinbutton_cb(GtkObject *obj, GapStbPropWidget *pw);
 static void     p_fmac_steps_spinbutton_cb(GtkObject *obj, GapStbPropWidget *pw);
+static void     p_fmac_accel_spinbutton_cb(GtkObject *obj, GapStbPropWidget *pw);
 
 static void     p_radio_flip_update(GapStbPropWidget *pw, gint32 flip_request);
 static void     p_radio_flip_none_callback(GtkWidget *widget, GapStbPropWidget *pw);
@@ -3039,6 +3042,30 @@ p_fmac_steps_spinbutton_cb(GtkObject *obj, GapStbPropWidget *pw)
   }
 }  /* end p_fmac_steps_spinbutton_cb */
 
+/* -------------------------------
+ * p_fmac_accel_spinbutton_cb
+ * -------------------------------
+ */
+static void
+p_fmac_accel_spinbutton_cb(GtkObject *obj, GapStbPropWidget *pw)
+{
+  gint32 l_val;
+
+  if(pw)
+  {
+    l_val = (GTK_ADJUSTMENT(pw->pw_spinbutton_fmac_accel_adj)->value);
+    if(pw->stb_elem_refptr)
+    {
+      if(pw->stb_elem_refptr->fmac_accel != l_val)
+      {
+        p_pw_push_undo_and_set_unsaved_changes(pw);
+        pw->stb_elem_refptr->fmac_accel = l_val;
+
+      }
+    }
+  }
+}  /* end p_fmac_accel_spinbutton_cb */
+
 
 /* ---------------------------------
  * p_radio_flip_update
@@ -3333,10 +3360,11 @@ static void
 p_pw_check_fmac_sensitivity(GapStbPropWidget *pw)
 {
   gboolean sensitive;
+  gboolean accelSensitive;
   char *alt_fmac_name;
   char *lbl_text;
   
-    
+  accelSensitive = FALSE;
   sensitive = FALSE;
   lbl_text = NULL;
   if(pw->stb_elem_refptr)
@@ -3353,18 +3381,19 @@ p_pw_check_fmac_sensitivity(GapStbPropWidget *pw)
              sensitive = TRUE;
              if(pw->stb_elem_refptr->fmac_total_steps > 1)
              {
-               lbl_text = gap_base_shorten_filename(_("Filtermacro2: ")   /* prefix */
-                                     ,alt_fmac_name   /* filenamepart */
-                                     ,_(" (ON)")      /* suffix */
-                                     ,90              /* max_chars */
+               lbl_text = gap_base_shorten_filename(_("ON:") /* prefix */
+                                     ,alt_fmac_name            /* filenamepart */
+                                     ,""                       /* suffix */
+                                     ,52                       /* max_chars */
                                      );
+                accelSensitive = TRUE;
              }
              else
              {
-               lbl_text = gap_base_shorten_filename(_("Filtermacro2: ")   /* prefix */
-                                     ,alt_fmac_name   /* filenamepart */
-                                     ,_(" (OFF)")     /* suffix */
-                                     ,90              /* max_chars */
+               lbl_text = gap_base_shorten_filename(_("OFF:") /* prefix */
+                                     ,alt_fmac_name             /* filenamepart */
+                                     ,""                        /* suffix */
+                                     ,52                        /* max_chars */
                                      );
              }
                         
@@ -3377,10 +3406,20 @@ p_pw_check_fmac_sensitivity(GapStbPropWidget *pw)
   if (lbl_text == NULL)
   {
     lbl_text = g_strdup(" ");
+    gtk_label_set_text ( GTK_LABEL(pw->pw_label_alternate_fmac2), "" );
+    gtk_widget_hide (pw->pw_hbox_fmac2);
+    gtk_widget_hide (pw->pw_spinbutton_fmac_accel);
+  }
+  else
+  {
+    gtk_widget_show (pw->pw_hbox_fmac2);
+    gtk_widget_show (pw->pw_spinbutton_fmac_accel);
+    gtk_label_set_text ( GTK_LABEL(pw->pw_label_alternate_fmac2), _("Filtermacro2: ") );
   }
   
   gtk_label_set_text ( GTK_LABEL(pw->pw_label_alternate_fmac_file), lbl_text );
   gtk_widget_set_sensitive(pw->pw_spinbutton_fmac_steps, sensitive);
+  gtk_widget_set_sensitive(pw->pw_spinbutton_fmac_accel, accelSensitive);
   p_pw_update_properties(pw);
 
   g_free(lbl_text);
@@ -3630,7 +3669,7 @@ p_pw_clear_widgets(GapStbPropWidget *pw)
   pw->mask_pv_container = NULL;
   pw->typ_icon_pv_ptr = NULL;
 
-  pw->pw_prop_dialog;
+  pw->pw_prop_dialog = NULL;
   pw->pw_filesel = NULL;
   pw->pw_filename_entry = NULL;
   pw->master_table = NULL;
@@ -3900,6 +3939,18 @@ gap_story_pw_properties_dialog (GapStbPropWidget *pw)
         /* movies and section always start at frame 1 */
         l_lower_limit = 1.0;
         break;
+      case GAP_STBREC_VID_SILENCE:
+      case GAP_STBREC_VID_COLOR:
+      case GAP_STBREC_VID_IMAGE:
+      case GAP_STBREC_VID_ANIMIMAGE:
+      case GAP_STBREC_VID_FRAMES:
+      case GAP_STBREC_VID_COMMENT:
+      case GAP_STBREC_VID_UNKNOWN:
+      case GAP_STBREC_AUD_SILENCE:
+      case GAP_STBREC_AUD_SOUND:
+      case GAP_STBREC_AUD_MOVIE:
+      case GAP_STBREC_ATT_TRANSITION:
+        break;
     }
   }
     
@@ -4616,14 +4667,80 @@ gap_story_pw_properties_dialog (GapStbPropWidget *pw)
                       pw);
   }
 
+
   row++;
 
-  /* the alternate filtermacro_file label */
-  label = gtk_label_new ("");
-  pw->pw_label_alternate_fmac_file = label;
-  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-  gtk_table_attach_defaults (GTK_TABLE(table), label, 0, 4, row, row+1);
-  gtk_widget_show (label);
+
+
+
+  /* 2nd row alternative filtermacro (VARYING) */
+  {
+    GtkWidget       *hbox_fmac;
+    GtkWidget       *spinbutton;
+    GapAccelWidget  *accel_wgt;
+    gint32           accelerationCharacteristic;
+
+#define ACC_WGT_WIDTH 32
+#define ACC_WGT_HEIGHT 22
+
+    hbox_fmac = gtk_hbox_new (FALSE, 1);
+    gtk_widget_show (hbox_fmac);
+    gtk_table_attach_defaults (GTK_TABLE(table), hbox_fmac, 1, 2, row, row+1);
+
+    pw->pw_hbox_fmac2 = hbox_fmac;
+
+    /* the alternate filtermacro 2 label (prefix) */
+    label = gtk_label_new ("");
+    pw->pw_label_alternate_fmac2 = label;
+    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+    gtk_table_attach_defaults (GTK_TABLE(table), label, 0, 1, row, row+1);
+    gtk_widget_show (label);
+
+
+
+    /* the alternate filtermacro_file label */
+    label = gtk_label_new ("");
+    pw->pw_label_alternate_fmac_file = label;
+    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+    gtk_widget_set_size_request(label, PW_ENTRY_WIDTH, -1);
+    gtk_widget_show (label);
+    gtk_box_pack_start (GTK_BOX (hbox_fmac), label, TRUE, TRUE, 1);
+
+    
+    /* the Acceleration characteristic value spinbutton */
+    accelerationCharacteristic = 0;
+    if(pw->stb_elem_refptr)
+    {
+      accelerationCharacteristic = pw->stb_elem_refptr->fmac_accel;
+    }
+
+    /* the acceleration characteristic graph display widget */
+    accel_wgt = gap_accel_new(ACC_WGT_WIDTH, ACC_WGT_HEIGHT, accelerationCharacteristic);
+    
+    adj = accel_wgt->adj;
+    spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
+    pw->pw_spinbutton_fmac_accel_adj = adj;
+    pw->pw_spinbutton_fmac_accel = spinbutton;
+
+    gtk_widget_show (spinbutton);
+    gtk_table_attach (GTK_TABLE (table), spinbutton, 2, 3, row, row+1,
+                    (GtkAttachOptions) (0),
+                    (GtkAttachOptions) (0), 0, 0);
+    gtk_widget_set_size_request (spinbutton, PW_SPIN_BUTTON_WIDTH, -1);
+    gimp_help_set_help_data (spinbutton, _("acceleration characteristic for filtermacro 0=off positive accelerate, negative decelerate"), NULL);
+
+    g_object_set_data(G_OBJECT(adj), "pw", pw);
+    
+    
+    gtk_box_pack_start (GTK_BOX (hbox_fmac), accel_wgt->da_widget, FALSE, FALSE, 1);
+    gtk_widget_show (accel_wgt->da_widget);
+  
+    g_signal_connect (G_OBJECT (pw->pw_spinbutton_fmac_accel_adj), "value_changed",
+                      G_CALLBACK (p_fmac_accel_spinbutton_cb),
+                      pw);
+
+  }
+
   
   p_pw_check_fmac_sensitivity(pw);
   
diff --git a/gap/gap_story_render_processor.c b/gap/gap_story_render_processor.c
old mode 100644
new mode 100755
index 850c465..05b02c0
--- a/gap/gap_story_render_processor.c
+++ b/gap/gap_story_render_processor.c
@@ -78,6 +78,7 @@
 #include "gap_story_render_processor.h"
 #include "gap_fmac_name.h"
 #include "gap_frame_fetcher.h"
+#include "gap_accel_char.h"
 
 /* data for the storyboard proceesor frame fetching
  */
@@ -140,20 +141,13 @@ static void     p_find_min_max_vid_tracknumbers(GapStoryRenderFrameRangeElem *fr
                              , gint32 *lowest_tracknr
                              , gint32 *highest_tracknr
                              );
-static void     p_step_attribute(gint32 frames_handled
-                 ,gdouble *from_val
-                 ,gdouble *to_val
-                 ,gint32  *dur
-                 );
-static gdouble  p_step_attribute_read(gint32 frame_step
-                 ,gdouble from_val
-                 ,gdouble to_val
-                 ,gint32  dur
-                 );
-static gdouble  p_step_attribute_read(gint32 frame_step
+
+static gdouble  p_attribute__at_step(gint32 frame_step /* current frame (since start of current processed clip */
                  ,gdouble from_val
                  ,gdouble to_val
-                 ,gint32  dur
+                 ,gint32  frames_dur        /* duration of the complete transition in frames */
+                 ,gint32  frames_done       /* already handled steps in previous clips */
+                 ,gint    accel             /* acceleration characteristic for the transition */
                  );
 
 static void     p_select_section_by_name(GapStoryRenderVidHandle *vidhand
@@ -205,6 +199,7 @@ static GapStoryRenderFrameRangeElem *  p_new_framerange_element(
                           ,GapStoryMaskAnchormode mask_anchor  /* how to apply the layer mask */
                           ,gboolean mask_disable
                           ,gint32 fmac_total_steps
+                          ,gint32 fmac_accel
                           );
 static void       p_add_frn_list(GapStoryRenderVidHandle *vidhand, GapStoryRenderFrameRangeElem *frn_elem);
 static void       p_step_all_vtrack_attributes(gint32 track, gint32 frames_to_handle
@@ -314,6 +309,11 @@ static gint32     p_exec_filtermacro(gint32 image_id
                          , const char *filtermacro_file_to
                          , gdouble current_step
                          , gint32 total_steps
+                         , gint accelerationCharacteristic
+                         );
+static gboolean p_transform_operate_on_full_layer(GapStoryCalcAttr *calculated
+                         , gint32 comp_image_id, gint32 tmp_image_id
+                         , GapStoryRenderFrameRangeElem *frn_elem
                          );
 static gint32     p_transform_and_add_layer( gint32 comp_image_id
                          , gint32 tmp_image_id
@@ -481,6 +481,7 @@ gap_story_render_debug_print_frame_elem(GapStoryRenderFrameRangeElem *frn_elem,
       printf("  [%d] filtermacro_file  : ", (int)l_idx); if(frn_elem->filtermacro_file) { printf("%s\n", frn_elem->filtermacro_file );} else { printf ("(null)\n"); }
       printf("  [%d] f.macro_file_to   : ", (int)l_idx); if(frn_elem->filtermacro_file_to) { printf("%s\n", frn_elem->filtermacro_file_to );} else { printf ("(null)\n"); }
       printf("  [%d] fmac_total_steps  : %d\n", (int)l_idx, (int)frn_elem->fmac_total_steps );
+      printf("  [%d] fmac_accel        : %d\n", (int)l_idx, (int)frn_elem->fmac_accel );
 
       printf("  [%d] frame_from        : %.4f\n", (int)l_idx, (float)frn_elem->frame_from );
       printf("  [%d] frame_to          : %.4f\n", (int)l_idx, (float)frn_elem->frame_to );
@@ -523,25 +524,35 @@ gap_story_render_debug_print_frame_elem(GapStoryRenderFrameRangeElem *frn_elem,
       printf("  [%d] wait_untilframes   : %d\n", (int)l_idx, (int)frn_elem->wait_untilframes );
 
 
-      printf("  [%d] opacity_from      : %f\n", (int)l_idx, (float)frn_elem->opacity_from );
-      printf("  [%d] opacity_to        : %f\n", (int)l_idx, (float)frn_elem->opacity_to );
-      printf("  [%d] opacity_dur       : %d\n", (int)l_idx, (int)frn_elem->opacity_dur );
-
-      printf("  [%d] scale_x_from      : %f\n", (int)l_idx, (float)frn_elem->scale_x_from );
-      printf("  [%d] scale_x_to        : %f\n", (int)l_idx, (float)frn_elem->scale_x_to );
-      printf("  [%d] scale_x_dur       : %d\n", (int)l_idx, frn_elem->scale_x_dur );
-
-      printf("  [%d] scale_y_from      : %f\n", (int)l_idx, (float)frn_elem->scale_y_from );
-      printf("  [%d] scale_y_to        : %f\n", (int)l_idx, (float)frn_elem->scale_y_to );
-      printf("  [%d] scale_y_dur       : %d\n", (int)l_idx, (int)frn_elem->scale_y_dur );
-
-      printf("  [%d] move_x_from       : %f\n", (int)l_idx, (float)frn_elem->move_x_from );
-      printf("  [%d] move_x_to         : %f\n", (int)l_idx, (float)frn_elem->move_x_to );
-      printf("  [%d] move_x_dur        : %d\n", (int)l_idx, (int)frn_elem->move_x_dur );
-
-      printf("  [%d] move_y_from       : %f\n", (int)l_idx, (float)frn_elem->move_y_from );
-      printf("  [%d] move_y_to         : %f\n", (int)l_idx, (float)frn_elem->move_y_to );
-      printf("  [%d] move_y_dur        : %d\n", (int)l_idx, (int)frn_elem->move_y_dur );
+      printf("  [%d] opacity_from         : %f\n", (int)l_idx, (float)frn_elem->opacity_from );
+      printf("  [%d] opacity_to           : %f\n", (int)l_idx, (float)frn_elem->opacity_to );
+      printf("  [%d] opacity_dur          : %d\n", (int)l_idx, (int)frn_elem->opacity_dur );
+      printf("  [%d] opacity_accel        : %d\n", (int)l_idx, (int)frn_elem->opacity_accel );
+      printf("  [%d] opacity_frames_done  : %d\n", (int)l_idx, (int)frn_elem->opacity_frames_done );
+
+      printf("  [%d] scale_x_from         : %f\n", (int)l_idx, (float)frn_elem->scale_x_from );
+      printf("  [%d] scale_x_to           : %f\n", (int)l_idx, (float)frn_elem->scale_x_to );
+      printf("  [%d] scale_x_dur          : %d\n", (int)l_idx, frn_elem->scale_x_dur );
+      printf("  [%d] scale_x_accel        : %d\n", (int)l_idx, frn_elem->scale_x_accel );
+      printf("  [%d] scale_x_frames_done  : %d\n", (int)l_idx, frn_elem->scale_x_frames_done );
+
+      printf("  [%d] scale_y_from         : %f\n", (int)l_idx, (float)frn_elem->scale_y_from );
+      printf("  [%d] scale_y_to           : %f\n", (int)l_idx, (float)frn_elem->scale_y_to );
+      printf("  [%d] scale_y_dur          : %d\n", (int)l_idx, (int)frn_elem->scale_y_dur );
+      printf("  [%d] scale_y_accel        : %d\n", (int)l_idx, frn_elem->scale_y_accel );
+      printf("  [%d] scale_y_frames_done  : %d\n", (int)l_idx, frn_elem->scale_y_frames_done );
+
+      printf("  [%d] move_x_from          : %f\n", (int)l_idx, (float)frn_elem->move_x_from );
+      printf("  [%d] move_x_to            : %f\n", (int)l_idx, (float)frn_elem->move_x_to );
+      printf("  [%d] move_x_dur           : %d\n", (int)l_idx, (int)frn_elem->move_x_dur );
+      printf("  [%d] move_x_accel         : %d\n", (int)l_idx, (int)frn_elem->move_x_accel );
+      printf("  [%d] move_x_frames_done   : %d\n", (int)l_idx, (int)frn_elem->move_x_frames_done );
+
+      printf("  [%d] move_y_from          : %f\n", (int)l_idx, (float)frn_elem->move_y_from );
+      printf("  [%d] move_y_to            : %f\n", (int)l_idx, (float)frn_elem->move_y_to );
+      printf("  [%d] move_y_dur           : %d\n", (int)l_idx, (int)frn_elem->move_y_dur );
+      printf("  [%d] move_y_accel         : %d\n", (int)l_idx, (int)frn_elem->move_y_accel );
+      printf("  [%d] move_y_frames_done   : %d\n", (int)l_idx, (int)frn_elem->move_y_frames_done );
   }
 }  /* end gap_story_render_debug_print_frame_elem */
 
@@ -943,68 +954,50 @@ p_find_min_max_vid_tracknumbers(GapStoryRenderFrameRangeElem *frn_list
 }  /* end p_find_min_max_vid_tracknumbers */
 
 
-/* ---------------------------------------
- * p_step_attribute
- * ---------------------------------------
- * calculate remaining attribute value after N frames_handled
- * and change *from_val and *dur accordingly
+/* --------------------------------
+ * p_attribute_query_at_step
+ * --------------------------------
+ * return 
+ *  o) from_val (before and at start of transition) or 
+ *  o) to_val (at end and after transition) or
+ *  o) a mixed value according to frame_step progress and acceleratin characteristics 
+ *     when frame_step is a frame number within the transition.
  */
-static void
-p_step_attribute(gint32 frames_handled
-                ,gdouble *from_val
-                ,gdouble *to_val
-                ,gint32  *dur
+static gdouble
+p_attribute_query_at_step(gint32 frame_step /* current frame (since start of current processed clip */
+                ,gdouble from_val
+                ,gdouble to_val
+                ,gint32  frames_dur        /* duration of the complete transition in frames */
+                ,gint32  frames_done       /* already handled steps in previous clips */
+                ,gint    accel             /* acceleration characteristic for the transition */
                 )
 {
-  gint32 l_rest_steps;
-  gdouble step_delta_val;
+  gdouble l_mixed_val;
+  gdouble l_mixed_factor;
+  gint32  l_steps_since_transition_start;
+  
 
-  l_rest_steps =  *dur  - frames_handled;
-  if((l_rest_steps <= 0) || (*dur <= 0))
+  l_steps_since_transition_start = frames_done + frame_step;
+  
+  if (l_steps_since_transition_start <= 0)
   {
-    *from_val = *to_val;
-    *dur = 0;
+    return (from_val);
   }
-  else
+  
+  if (l_steps_since_transition_start >= frames_dur)
   {
-    step_delta_val =  (*to_val - *from_val) / (gdouble)(*dur);
-
-    *from_val = *to_val - (step_delta_val * l_rest_steps) ;
-    *dur = l_rest_steps;
+    return (to_val);
   }
-}  /* end p_step_attribute */
 
+  l_mixed_factor = (gdouble)l_steps_since_transition_start  / (gdouble)frames_dur;
+  l_mixed_factor = gap_accelMixFactor(l_mixed_factor, accel);
 
+  l_mixed_val = GAP_BASE_MIX_VALUE(l_mixed_factor, from_val, to_val);
 
-/* --------------------------------
- * p_step_attribute_read
- * --------------------------------
- * return attribute value after N frame steps
- */
-static gdouble
-p_step_attribute_read(gint32 frame_step
-                ,gdouble from_val
-                ,gdouble to_val
-                ,gint32  dur
-                )
-{
-  gdouble l_from_val;
-  gdouble l_to_val;
-  gint32  l_dur;
-
-  l_from_val    = from_val;
-  l_to_val      = to_val;
-  l_dur         = dur;
-
-  p_step_attribute( frame_step
-                  , &l_from_val
-                  , &l_to_val
-                  , &l_dur
-                  );
+  return(l_mixed_val);
 
-  return(l_from_val);
+}  /* end p_attribute_query_at_step */
 
-}  /* end p_step_attribute */
 
 
 /* ----------------------------------------------------
@@ -1239,31 +1232,40 @@ p_fetch_framename(GapStoryRenderFrameRangeElem *frn_list
          l_step = (master_frame_nr - 1) - l_frame_group_count;
 
 
-
-         *opacity = p_step_attribute_read(l_step
+         *opacity = p_attribute_query_at_step(l_step
                                     , frn_elem->opacity_from
                                     , frn_elem->opacity_to
                                     , frn_elem->opacity_dur
+                                    , frn_elem->opacity_frames_done
+                                    , frn_elem->opacity_accel
                                     );
-         *scale_x = p_step_attribute_read(l_step
+         *scale_x = p_attribute_query_at_step(l_step
                                     , frn_elem->scale_x_from
                                     , frn_elem->scale_x_to
                                     , frn_elem->scale_x_dur
+                                    , frn_elem->scale_x_frames_done
+                                    , frn_elem->scale_x_accel
                                     );
-         *scale_y = p_step_attribute_read(l_step
+         *scale_y = p_attribute_query_at_step(l_step
                                     , frn_elem->scale_y_from
                                     , frn_elem->scale_y_to
                                     , frn_elem->scale_y_dur
+                                    , frn_elem->scale_y_frames_done
+                                    , frn_elem->scale_y_accel
                                     );
-         *move_x  = p_step_attribute_read(l_step
+         *move_x  = p_attribute_query_at_step(l_step
                                     , frn_elem->move_x_from
                                     , frn_elem->move_x_to
                                     , frn_elem->move_x_dur
+                                    , frn_elem->move_x_frames_done
+                                    , frn_elem->move_x_accel
                                     );
-         *move_y  = p_step_attribute_read(l_step
+         *move_y  = p_attribute_query_at_step(l_step
                                     , frn_elem->move_y_from
                                     , frn_elem->move_y_to
                                     , frn_elem->move_y_dur
+                                    , frn_elem->move_y_frames_done
+                                    , frn_elem->move_y_accel
                                     );
         break;
       }
@@ -1274,11 +1276,11 @@ p_fetch_framename(GapStoryRenderFrameRangeElem *frn_list
 
   if(gap_debug)
   {
-   printf("p_fetch_framename: track:%d master_frame_nr:%d framename:%s: found_at_idx:%d opa:%f scale:%f %f move:%f %f layerstack_idx:%d\n"
-       ,(int)track
-       ,(int)master_frame_nr
+    printf("p_fetch_framename: track:%d master_frame_nr:%d framename:%s: found_at_idx:%d opa:%f scale:%f %f move:%f %f layerstack_idx:%d\n"
+       , (int)track
+       , (int)master_frame_nr
        , l_framename
-       ,(int)l_found_at_idx
+       , (int)l_found_at_idx
        , (float)*opacity
        , (float)*scale_x
        , (float)*scale_y
@@ -1351,6 +1353,7 @@ p_new_framerange_element(GapStoryRenderFrameType  frn_type
                       ,GapStoryMaskAnchormode mask_anchor  /* how to apply the layer mask */
                       ,gboolean mask_disable
                       ,gint32 fmac_total_steps
+                      ,gint32 fmac_accel
                       )
 {
   GapStoryRenderFrameRangeElem *frn_elem;
@@ -1424,6 +1427,7 @@ p_new_framerange_element(GapStoryRenderFrameType  frn_type
   frn_elem->filtermacro_file   = NULL;
   frn_elem->filtermacro_file_to = NULL;
   frn_elem->fmac_total_steps   = 1;
+  frn_elem->fmac_accel         = 0;
   frn_elem->gvahand            = NULL;
   frn_elem->seltrack           = seltrack;
   frn_elem->exact_seek         = exact_seek;
@@ -1461,6 +1465,7 @@ p_new_framerange_element(GapStoryRenderFrameType  frn_type
 
   /* check filtermacro_file for absolute pathname */
   frn_elem->fmac_total_steps = fmac_total_steps;
+  frn_elem->fmac_accel = fmac_accel;
   frn_elem->filtermacro_file      = NULL;
   if(filtermacro_file)
   {
@@ -1573,35 +1578,12 @@ p_step_all_vtrack_attributes(gint32 track
                        , GapStoryRenderVTrackArray *vtarr
                       )
 {
-  p_step_attribute( frames_to_handle
-                  , &vtarr->attr[track].opacity_from
-                  , &vtarr->attr[track].opacity_to
-                  , &vtarr->attr[track].opacity_dur
-                  );
+  vtarr->attr[track].opacity_frames_done += frames_to_handle;
+  vtarr->attr[track].scale_x_frames_done += frames_to_handle;
+  vtarr->attr[track].scale_y_frames_done += frames_to_handle;
+  vtarr->attr[track].move_x_frames_done += frames_to_handle;
+  vtarr->attr[track].move_y_frames_done += frames_to_handle;
 
-  p_step_attribute( frames_to_handle
-                  , &vtarr->attr[track].scale_x_from
-                  , &vtarr->attr[track].scale_x_to
-                  , &vtarr->attr[track].scale_x_dur
-                  );
-
-  p_step_attribute( frames_to_handle
-                  , &vtarr->attr[track].scale_y_from
-                  , &vtarr->attr[track].scale_y_to
-                  , &vtarr->attr[track].scale_y_dur
-                  );
-
-  p_step_attribute( frames_to_handle
-                  , &vtarr->attr[track].move_x_from
-                  , &vtarr->attr[track].move_x_to
-                  , &vtarr->attr[track].move_x_dur
-                  );
-
-  p_step_attribute( frames_to_handle
-                  , &vtarr->attr[track].move_y_from
-                  , &vtarr->attr[track].move_y_to
-                  , &vtarr->attr[track].move_y_dur
-                  );
 }  /* end p_step_all_vtrack_attributes */
 
 
@@ -1609,23 +1591,24 @@ p_step_all_vtrack_attributes(gint32 track
  * p_set_vtrack_attributes
  * ----------------------------------------------------
  * set current video track attributes for the
- * Framerange_Element. from the current attribute array.
+ * Framerange_Element. from the current attribute array that represents
+ * the video track context.
  *
  * attribute array is changed to the state after
  * the playback of the Framerange_element.
+ * since GAP-2.7.x this just affects the new attributes *_frames_done
+ * the other settings *_from, *_to, *_dur and *_accel are copied
+ * unchanged, the current mixed value(s) are calculated later
+ * (see p_attribute_query_at_step) based on the complete transition.
  *
  * Example for fade_in Attribute settings:
  *    IN:    opacity_from: 0.0   opacity_to: 1.0  opacity_dur: 50 frames
  *    if the range has 50 or more frames
  *    the fade_in can be handled fully within the range,
- *    the result will be:
- *       OUT:  opacity_from: 1.0   opacity_to: 1.0  opacity_dur: 0 frames
- *
- *    if the range is for example 25 frames (smaller than the duration 50)
- *    the result will be:
- *       OUT:  opacity_from: 0.5   opacity_to: 1.0  opacity_dur: 25 frames
- *       because there are 25 rest frames to complete the fade in action
- *       in the next range (if there will be any)
+ *    if the range is for example 20 frames (smaller than the duration 50)
+ *       the opacity_frames_done is increased by 20 frames
+ *       and the rest of 30 frames to complete the fade-in action
+ *       will be handled in the next frame range element (if there is any)
  *
  */
 static void
@@ -1643,21 +1626,35 @@ p_set_vtrack_attributes(GapStoryRenderFrameRangeElem *frn_elem
   frn_elem->mask_framecount       = vtarr->attr[track].mask_framecount;
 
 
-  frn_elem->opacity_from     = vtarr->attr[track].opacity_from;
-  frn_elem->opacity_to       = vtarr->attr[track].opacity_to;
-  frn_elem->opacity_dur      = vtarr->attr[track].opacity_dur;
-  frn_elem->scale_x_from     = vtarr->attr[track].scale_x_from;
-  frn_elem->scale_x_to       = vtarr->attr[track].scale_x_to;
-  frn_elem->scale_x_dur      = vtarr->attr[track].scale_x_dur;
-  frn_elem->scale_y_from     = vtarr->attr[track].scale_y_from;
-  frn_elem->scale_y_to       = vtarr->attr[track].scale_y_to;
-  frn_elem->scale_y_dur      = vtarr->attr[track].scale_y_dur;
-  frn_elem->move_x_from      = vtarr->attr[track].move_x_from;
-  frn_elem->move_x_to        = vtarr->attr[track].move_x_to;
-  frn_elem->move_x_dur       = vtarr->attr[track].move_x_dur;
-  frn_elem->move_y_from      = vtarr->attr[track].move_y_from;
-  frn_elem->move_y_to        = vtarr->attr[track].move_y_to;
-  frn_elem->move_y_dur       = vtarr->attr[track].move_y_dur;
+  frn_elem->opacity_from         = vtarr->attr[track].opacity_from;
+  frn_elem->opacity_to           = vtarr->attr[track].opacity_to;
+  frn_elem->opacity_dur          = vtarr->attr[track].opacity_dur;
+  frn_elem->opacity_accel        = vtarr->attr[track].opacity_accel;
+  frn_elem->opacity_frames_done  = vtarr->attr[track].opacity_frames_done;
+  
+  frn_elem->scale_x_from         = vtarr->attr[track].scale_x_from;
+  frn_elem->scale_x_to           = vtarr->attr[track].scale_x_to;
+  frn_elem->scale_x_dur          = vtarr->attr[track].scale_x_dur;
+  frn_elem->scale_x_accel        = vtarr->attr[track].scale_x_accel;
+  frn_elem->scale_x_frames_done  = vtarr->attr[track].scale_x_frames_done;
+  
+  frn_elem->scale_y_from         = vtarr->attr[track].scale_y_from;
+  frn_elem->scale_y_to           = vtarr->attr[track].scale_y_to;
+  frn_elem->scale_y_dur          = vtarr->attr[track].scale_y_dur;
+  frn_elem->scale_y_accel        = vtarr->attr[track].scale_y_accel;
+  frn_elem->scale_y_frames_done  = vtarr->attr[track].scale_y_frames_done;
+  
+  frn_elem->move_x_from          = vtarr->attr[track].move_x_from;
+  frn_elem->move_x_to            = vtarr->attr[track].move_x_to;
+  frn_elem->move_x_dur           = vtarr->attr[track].move_x_dur;
+  frn_elem->move_x_accel         = vtarr->attr[track].move_x_accel;
+  frn_elem->move_x_frames_done   = vtarr->attr[track].move_x_frames_done;
+  
+  frn_elem->move_y_from          = vtarr->attr[track].move_y_from;
+  frn_elem->move_y_to            = vtarr->attr[track].move_y_to;
+  frn_elem->move_y_dur           = vtarr->attr[track].move_y_dur;
+  frn_elem->move_y_accel         = vtarr->attr[track].move_y_accel;
+  frn_elem->move_y_frames_done   = vtarr->attr[track].move_y_frames_done;
 
 
   /* advance mask_framecount */
@@ -1666,12 +1663,9 @@ p_set_vtrack_attributes(GapStoryRenderFrameRangeElem *frn_elem
 
   p_step_all_vtrack_attributes(track, frn_elem->frames_to_handle, vtarr);
 
-
 }  /* end p_set_vtrack_attributes  */
 
 
-
-
 /* ---------------------------------
  * p_vidclip_add_as_is
  * ---------------------------------
@@ -1735,6 +1729,7 @@ p_vidclip_shadow_add_silence(gint32 shadow_track
                                      , GAP_MSK_ANCHOR_CLIP  /* mask_anchor */
                                      , TRUE                 /* mask_disable */
                                      , 1                    /* fmac_total_steps */
+                                     , 0                    /* fmac_accel */
                                      );
   if(frn_elem)
   {
@@ -1876,21 +1871,35 @@ p_copy_vattr_values(gint32 src_track
   vtarr->attr[dst_track].fit_height        = vtarr->attr[src_track].fit_height;
 
 
-  vtarr->attr[dst_track].opacity_from      = vtarr->attr[src_track].opacity_from;
-  vtarr->attr[dst_track].opacity_to        = vtarr->attr[src_track].opacity_to;
-  vtarr->attr[dst_track].opacity_dur       = vtarr->attr[src_track].opacity_dur;
-  vtarr->attr[dst_track].scale_x_from      = vtarr->attr[src_track].scale_x_from;
-  vtarr->attr[dst_track].scale_x_to        = vtarr->attr[src_track].scale_x_to;
-  vtarr->attr[dst_track].scale_x_dur       = vtarr->attr[src_track].scale_x_dur;
-  vtarr->attr[dst_track].scale_y_from      = vtarr->attr[src_track].scale_y_from;
-  vtarr->attr[dst_track].scale_y_to        = vtarr->attr[src_track].scale_y_to;
-  vtarr->attr[dst_track].scale_y_dur       = vtarr->attr[src_track].scale_y_dur;
-  vtarr->attr[dst_track].move_x_from       = vtarr->attr[src_track].move_x_from;
-  vtarr->attr[dst_track].move_x_to         = vtarr->attr[src_track].move_x_to;
-  vtarr->attr[dst_track].move_x_dur        = vtarr->attr[src_track].move_x_dur;
-  vtarr->attr[dst_track].move_y_from       = vtarr->attr[src_track].move_y_from;
-  vtarr->attr[dst_track].move_y_to         = vtarr->attr[src_track].move_y_to;
-  vtarr->attr[dst_track].move_y_dur        = vtarr->attr[src_track].move_y_dur;
+  vtarr->attr[dst_track].opacity_from        = vtarr->attr[src_track].opacity_from;
+  vtarr->attr[dst_track].opacity_to          = vtarr->attr[src_track].opacity_to;
+  vtarr->attr[dst_track].opacity_dur         = vtarr->attr[src_track].opacity_dur;
+  vtarr->attr[dst_track].opacity_accel       = vtarr->attr[src_track].opacity_accel;
+  vtarr->attr[dst_track].opacity_frames_done = vtarr->attr[src_track].opacity_frames_done;
+  
+  vtarr->attr[dst_track].scale_x_from        = vtarr->attr[src_track].scale_x_from;
+  vtarr->attr[dst_track].scale_x_to          = vtarr->attr[src_track].scale_x_to;
+  vtarr->attr[dst_track].scale_x_dur         = vtarr->attr[src_track].scale_x_dur;
+  vtarr->attr[dst_track].scale_x_accel       = vtarr->attr[src_track].scale_x_accel;
+  vtarr->attr[dst_track].scale_x_frames_done = vtarr->attr[src_track].scale_x_frames_done;
+  
+  vtarr->attr[dst_track].scale_y_from        = vtarr->attr[src_track].scale_y_from;
+  vtarr->attr[dst_track].scale_y_to          = vtarr->attr[src_track].scale_y_to;
+  vtarr->attr[dst_track].scale_y_dur         = vtarr->attr[src_track].scale_y_dur;
+  vtarr->attr[dst_track].scale_y_accel       = vtarr->attr[src_track].scale_y_accel;
+  vtarr->attr[dst_track].scale_y_frames_done = vtarr->attr[src_track].scale_y_frames_done;
+  
+  vtarr->attr[dst_track].move_x_from         = vtarr->attr[src_track].move_x_from;
+  vtarr->attr[dst_track].move_x_to           = vtarr->attr[src_track].move_x_to;
+  vtarr->attr[dst_track].move_x_dur          = vtarr->attr[src_track].move_x_dur;
+  vtarr->attr[dst_track].move_x_accel        = vtarr->attr[src_track].move_x_accel;
+  vtarr->attr[dst_track].move_x_frames_done  = vtarr->attr[src_track].move_x_frames_done;
+  
+  vtarr->attr[dst_track].move_y_from         = vtarr->attr[src_track].move_y_from;
+  vtarr->attr[dst_track].move_y_to           = vtarr->attr[src_track].move_y_to;
+  vtarr->attr[dst_track].move_y_dur          = vtarr->attr[src_track].move_y_dur;
+  vtarr->attr[dst_track].move_y_accel        = vtarr->attr[src_track].move_y_accel;
+  vtarr->attr[dst_track].move_y_frames_done  = vtarr->attr[src_track].move_y_frames_done;
 
 }  /* end p_copy_vattr_values */
 
@@ -2007,6 +2016,7 @@ p_vidclip_split_and_add_frn_list(GapStoryRenderFrameRangeElem *frn_elem
                       ,frn_elem->mask_anchor
                       ,FALSE     /* keep mask enabled if the element has one */
                       ,frn_elem->fmac_total_steps
+                      ,frn_elem->fmac_accel
                       );
 
 
@@ -2124,24 +2134,39 @@ p_clear_vattr_array(GapStoryRenderVTrackArray *vtarr)
     vtarr->attr[l_idx].overlap_count = 0;
     vtarr->attr[l_idx].mask_framecount = 0;
 
-    vtarr->attr[l_idx].keep_proportions   = FALSE;
-    vtarr->attr[l_idx].fit_width          = TRUE;
-    vtarr->attr[l_idx].fit_height         = TRUE;
-    vtarr->attr[l_idx].opacity_from  = 1.0;
-    vtarr->attr[l_idx].opacity_to    = 1.0;
-    vtarr->attr[l_idx].opacity_dur   = 0;
-    vtarr->attr[l_idx].scale_x_from  = 1.0;
-    vtarr->attr[l_idx].scale_x_to    = 1.0;
-    vtarr->attr[l_idx].scale_x_dur   = 0;
-    vtarr->attr[l_idx].scale_y_from  = 1.0;
-    vtarr->attr[l_idx].scale_y_to    = 1.0;
-    vtarr->attr[l_idx].scale_y_dur   = 0;
-    vtarr->attr[l_idx].move_x_from   = 0.0;
-    vtarr->attr[l_idx].move_x_to     = 0.0;
-    vtarr->attr[l_idx].move_x_dur    = 0;
-    vtarr->attr[l_idx].move_y_from   = 0.0;
-    vtarr->attr[l_idx].move_y_to     = 0.0;
-    vtarr->attr[l_idx].move_y_dur    = 0;
+    vtarr->attr[l_idx].keep_proportions     = FALSE;
+    vtarr->attr[l_idx].fit_width            = TRUE;
+    vtarr->attr[l_idx].fit_height           = TRUE;
+    
+    vtarr->attr[l_idx].opacity_from         = 1.0;
+    vtarr->attr[l_idx].opacity_to           = 1.0;
+    vtarr->attr[l_idx].opacity_dur          = 0;
+    vtarr->attr[l_idx].opacity_accel        = 0;
+    vtarr->attr[l_idx].opacity_frames_done  = 0;
+        
+    vtarr->attr[l_idx].scale_x_from         = 1.0;
+    vtarr->attr[l_idx].scale_x_to           = 1.0;
+    vtarr->attr[l_idx].scale_x_dur          = 0;
+    vtarr->attr[l_idx].scale_x_accel        = 0;
+    vtarr->attr[l_idx].scale_x_frames_done  = 0;
+    
+    vtarr->attr[l_idx].scale_y_from         = 1.0;
+    vtarr->attr[l_idx].scale_y_to           = 1.0;
+    vtarr->attr[l_idx].scale_y_dur          = 0;
+    vtarr->attr[l_idx].scale_y_accel        = 0;
+    vtarr->attr[l_idx].scale_y_frames_done  = 0;
+    
+    vtarr->attr[l_idx].move_x_from          = 0.0;
+    vtarr->attr[l_idx].move_x_to            = 0.0;
+    vtarr->attr[l_idx].move_x_dur           = 0;
+    vtarr->attr[l_idx].move_x_accel         = 0;
+    vtarr->attr[l_idx].move_x_frames_done   = 0;
+    
+    vtarr->attr[l_idx].move_y_from          = 0.0;
+    vtarr->attr[l_idx].move_y_to            = 0.0;
+    vtarr->attr[l_idx].move_y_dur           = 0;
+    vtarr->attr[l_idx].move_y_accel         = 0;
+    vtarr->attr[l_idx].move_y_frames_done   = 0;
   }
 }  /* end p_clear_vattr_array */
 
@@ -2265,6 +2290,8 @@ p_storyboard_analyze(GapStoryBoard *stb
   frn_list = NULL;
   vtarr = &vtarray;
 
+  p_clear_vattr_array(vtarr);
+
   storyboard_file = stb->storyboardfile;
 
   /* copy Master informations: */
@@ -2321,13 +2348,11 @@ p_storyboard_analyze(GapStoryBoard *stb
     p_append_render_section_to_vidhand(vidhand, vidhand->parsing_section);
 
     /* clear video track attribute settings for all tracks.
-     * video attribute array holds current transition values (opacity, move and scale)
+     * video attribute array holds current transition value context (opacity, move and scale)
      * of all tracks and is updated at parsing of the the current clip.
-     * each processed clip gets its start values from the array, and modifies the values
-     * according to the amount of framesteps of a transition that can be handled
-     * by processing the clip.
-     * processing of a transition attribute element explicite sets the specified
-     * number of framesteps, and from_ and to values for the next transition.
+     * each processed clip gets its start and end values (_from _to) from the array,
+     * and gets the information how many frames of the transition are already handled in previous
+     * clips (_frames_done) as start value.
      *
      * The video attribute array must be cleared at start of each section.
      */
@@ -2425,29 +2450,39 @@ p_storyboard_analyze(GapStoryBoard *stb
                 switch(ii)
                 {
                   case GAP_STB_ATT_TYPE_OPACITY:
-                    vtarr->attr[l_track].opacity_from = stb_elem->att_arr_value_from[ii];
-                    vtarr->attr[l_track].opacity_to   = stb_elem->att_arr_value_to[ii];
-                    vtarr->attr[l_track].opacity_dur  = stb_elem->att_arr_value_dur[ii];
+                    vtarr->attr[l_track].opacity_from  = stb_elem->att_arr_value_from[ii];
+                    vtarr->attr[l_track].opacity_to    = stb_elem->att_arr_value_to[ii];
+                    vtarr->attr[l_track].opacity_dur   = stb_elem->att_arr_value_dur[ii];
+                    vtarr->attr[l_track].opacity_accel = stb_elem->att_arr_value_accel[ii];
+                    vtarr->attr[l_track].opacity_frames_done  = 0;
                     break;
                   case GAP_STB_ATT_TYPE_MOVE_X:
-                    vtarr->attr[l_track].move_x_from  = stb_elem->att_arr_value_from[ii];
-                    vtarr->attr[l_track].move_x_to    = stb_elem->att_arr_value_to[ii];
-                    vtarr->attr[l_track].move_x_dur   = stb_elem->att_arr_value_dur[ii];
+                    vtarr->attr[l_track].move_x_from   = stb_elem->att_arr_value_from[ii];
+                    vtarr->attr[l_track].move_x_to     = stb_elem->att_arr_value_to[ii];
+                    vtarr->attr[l_track].move_x_dur    = stb_elem->att_arr_value_dur[ii];
+                    vtarr->attr[l_track].move_x_accel  = stb_elem->att_arr_value_accel[ii];
+                    vtarr->attr[l_track].move_x_frames_done = 0;
                     break;
                   case GAP_STB_ATT_TYPE_MOVE_Y:
-                    vtarr->attr[l_track].move_y_from  = stb_elem->att_arr_value_from[ii];
-                    vtarr->attr[l_track].move_y_to    = stb_elem->att_arr_value_to[ii];
-                    vtarr->attr[l_track].move_y_dur   = stb_elem->att_arr_value_dur[ii];
+                    vtarr->attr[l_track].move_y_from   = stb_elem->att_arr_value_from[ii];
+                    vtarr->attr[l_track].move_y_to     = stb_elem->att_arr_value_to[ii];
+                    vtarr->attr[l_track].move_y_dur    = stb_elem->att_arr_value_dur[ii];
+                    vtarr->attr[l_track].move_y_accel  = stb_elem->att_arr_value_accel[ii];
+                    vtarr->attr[l_track].move_y_frames_done = 0;
                     break;
                   case GAP_STB_ATT_TYPE_ZOOM_X:
-                    vtarr->attr[l_track].scale_x_from = stb_elem->att_arr_value_from[ii];
-                    vtarr->attr[l_track].scale_x_to   = stb_elem->att_arr_value_to[ii];
-                    vtarr->attr[l_track].scale_x_dur  = stb_elem->att_arr_value_dur[ii];
+                    vtarr->attr[l_track].scale_x_from  = stb_elem->att_arr_value_from[ii];
+                    vtarr->attr[l_track].scale_x_to    = stb_elem->att_arr_value_to[ii];
+                    vtarr->attr[l_track].scale_x_dur   = stb_elem->att_arr_value_dur[ii];
+                    vtarr->attr[l_track].scale_x_accel = stb_elem->att_arr_value_accel[ii];
+                    vtarr->attr[l_track].scale_x_frames_done = 0;
                     break;
                   case GAP_STB_ATT_TYPE_ZOOM_Y:
-                    vtarr->attr[l_track].scale_y_from = stb_elem->att_arr_value_from[ii];
-                    vtarr->attr[l_track].scale_y_to   = stb_elem->att_arr_value_to[ii];
-                    vtarr->attr[l_track].scale_y_dur  = stb_elem->att_arr_value_dur[ii];
+                    vtarr->attr[l_track].scale_y_from  = stb_elem->att_arr_value_from[ii];
+                    vtarr->attr[l_track].scale_y_to    = stb_elem->att_arr_value_to[ii];
+                    vtarr->attr[l_track].scale_y_dur   = stb_elem->att_arr_value_dur[ii];
+                    vtarr->attr[l_track].scale_y_accel = stb_elem->att_arr_value_accel[ii];
+                    vtarr->attr[l_track].scale_y_frames_done = 0;
                     break;
                 }
               }
@@ -2480,6 +2515,7 @@ p_storyboard_analyze(GapStoryBoard *stb
                                                , GAP_MSK_ANCHOR_CLIP  /* mask_anchor */
                                                , TRUE                 /* mask_disable */
                                                , 1                    /* fmac_total_steps */
+                                               , 0                    /* fmac_accel */
                                                );
             if(frn_elem)
             {
@@ -2515,6 +2551,7 @@ p_storyboard_analyze(GapStoryBoard *stb
                                                , GAP_MSK_ANCHOR_CLIP  /* mask_anchor */
                                                , TRUE                 /* mask_disable */
                                                , 1                    /* fmac_total_steps */
+                                               , 0                    /* fmac_accel */
                                                );
             if(frn_elem)
             {
@@ -2547,6 +2584,7 @@ p_storyboard_analyze(GapStoryBoard *stb
                                                , stb_elem->mask_anchor
                                                , stb_elem->mask_disable
                                                , stb_elem->fmac_total_steps
+                                               , stb_elem->fmac_accel
                                                );
             if(frn_elem)
             {
@@ -2584,6 +2622,7 @@ p_storyboard_analyze(GapStoryBoard *stb
                                                , stb_elem->mask_anchor
                                                , stb_elem->mask_disable
                                                , stb_elem->fmac_total_steps
+                                               , stb_elem->fmac_accel
                                                );
             if(frn_elem)
             {
@@ -2669,6 +2708,7 @@ p_storyboard_analyze(GapStoryBoard *stb
                                                     , stb_elem->mask_anchor
                                                     , stb_elem->mask_disable
                                                     , stb_elem->fmac_total_steps
+                                                    , stb_elem->fmac_accel
                                                     );
                  if(frn_elem)
                  {
@@ -3681,6 +3721,7 @@ p_open_video_handle_private(    gboolean ignore_audio
                                          , GAP_MSK_ANCHOR_CLIP  /* mask_anchor */
                                          , TRUE                 /* mask_disable */
                                          , 1                    /* fmac_total_steps */
+                                         , 0                    /* fmac_accel */
                                          );
       if(frn_elem)
       {
@@ -3713,6 +3754,7 @@ p_open_video_handle_private(    gboolean ignore_audio
                                          , GAP_MSK_ANCHOR_CLIP  /* mask_anchor */
                                          , TRUE                 /* mask_disable */
                                          , 1                    /* fmac_total_steps */
+                                         , 0                    /* fmac_accel */
                                          );
         render_section->frn_list->frames_to_handle = l_from -1;
         render_section->frn_list->next = frn_elem;
@@ -3772,6 +3814,7 @@ p_open_video_handle_private(    gboolean ignore_audio
                                          , GAP_MSK_ANCHOR_CLIP  /* mask_anchor */
                                          , TRUE                 /* mask_disable */
                                          , 1                    /* fmac_total_steps */
+                                         , 0                    /* fmac_accel */
                                          );
       if(frn_elem) *frame_count = frn_elem->frames_to_handle;
 
@@ -3802,6 +3845,7 @@ p_open_video_handle_private(    gboolean ignore_audio
                                            , GAP_MSK_ANCHOR_CLIP  /* mask_anchor */
                                            , TRUE                 /* mask_disable */
                                            , 1                    /* fmac_total_steps */
+                                           , 0                    /* fmac_accel */
                                            );
         render_section->frn_list->frames_to_handle = l_from -1;
         render_section->frn_list->next = frn_elem;
@@ -3849,6 +3893,7 @@ p_open_video_handle_private(    gboolean ignore_audio
                                          , GAP_MSK_ANCHOR_CLIP  /* mask_anchor */
                                          , TRUE                 /* mask_disable */
                                          , 1                    /* fmac_total_steps */
+                                         , 0                    /* fmac_accel */
                                          );
       if(frn_elem)
       {
@@ -3886,6 +3931,7 @@ p_open_video_handle_private(    gboolean ignore_audio
                                          , GAP_MSK_ANCHOR_CLIP  /* mask_anchor */
                                          , TRUE                 /* mask_disable */
                                          , 1                    /* fmac_total_steps */
+                                         , 0                    /* fmac_accel */
                                          );
       if(frn_elem)
       {
@@ -4094,6 +4140,7 @@ p_exec_filtermacro(gint32 image_id, gint32 layer_id, const char *filtermacro_fil
     , const char *filtermacro_file_to
     , gdouble current_step
     , gint32 total_steps
+    , gint accelerationCharacteristic
 )
 {
   GimpParam* l_params;
@@ -4127,7 +4174,7 @@ p_exec_filtermacro(gint32 image_id, gint32 layer_id, const char *filtermacro_fil
           * in this situation GIMP displays the error message
           *    "expected tile ack and received: 5"
           *    and causes the called plug-in to exit immediate without success
-          * Therfore always add an alpha channel before calling a filtermacro.
+          * Therefore always add an alpha channel before calling a filtermacro.
           */
           gimp_layer_add_alpha(layer_id);
        }
@@ -4146,14 +4193,13 @@ p_exec_filtermacro(gint32 image_id, gint32 layer_id, const char *filtermacro_fil
        }
        else
        {
-           if(current_step > total_steps)
-           {
-             current_step = total_steps;
-           }
-           if(current_step < 0.0)
-           {
-             current_step = 0.0;
-           }
+           gdouble   current_accel_step;
+           
+           current_accel_step = gap_calculate_current_step_with_acceleration(current_step
+                                   , total_steps
+                                   , accelerationCharacteristic
+                                   );
+
            /* execute varying value mix of 2 GAP Filtermacro_files */
            l_params = gimp_run_procedure (GAP_FMACNAME_PLUG_IN_NAME_FMAC_VARYING,
                      &l_retvals,
@@ -4162,7 +4208,7 @@ p_exec_filtermacro(gint32 image_id, gint32 layer_id, const char *filtermacro_fil
                      GIMP_PDB_DRAWABLE, layer_id,
                      GIMP_PDB_STRING,   filtermacro_file,
                      GIMP_PDB_STRING,   filtermacro_file_to,
-                     GIMP_PDB_FLOAT,    current_step,  /* 0.0 upto 1.0 */
+                     GIMP_PDB_FLOAT,    current_accel_step,
                      GIMP_PDB_INT32,    total_steps,
                      GIMP_PDB_END);
        }
@@ -4192,12 +4238,74 @@ p_exec_filtermacro(gint32 image_id, gint32 layer_id, const char *filtermacro_fil
 
 
 /* ----------------------------------------------------
+ * p_transform_operate_on_full_layer
+ * ----------------------------------------------------
+ * check if it is required to operate on the full calculated resulting layer (return TRUE)
+ * or if we can operate on a smaller clipped rectangle (return FALSE)
+ */
+static gboolean
+p_transform_operate_on_full_layer(GapStoryCalcAttr *calculated, gint32 comp_image_id, gint32 tmp_image_id
+  , GapStoryRenderFrameRangeElem *frn_elem)
+{
+  gint32 calculated_area;
+  gint32 visible_on_composite_area;
+  gint32 composite_img_area;
+  gint32 tmp_image_area;
+  gboolean l_ret;
+
+  l_ret = TRUE;
+  
+  calculated_area = calculated->width * calculated->height;
+  visible_on_composite_area = calculated->visible_width * calculated->visible_height;
+  composite_img_area = gimp_image_width(comp_image_id) * gimp_image_height(comp_image_id);
+ 
+  if(gap_debug)
+  {
+      tmp_image_area = gimp_image_width(tmp_image_id) * gimp_image_height(tmp_image_id);
+      printf("p_transform_operate_on_full_layer areasize tmp:%d, calc:%d, visble:%d, composite:%d\n"
+         , (int)tmp_image_area
+         , (int)calculated_area
+         , (int)visible_on_composite_area
+         , (int)composite_img_area
+         );
+  }
+  
+  if ((calculated_area > composite_img_area)
+  ||  (visible_on_composite_area < composite_img_area))
+  {
+    if((frn_elem->mask_name != NULL)
+    && (frn_elem->mask_anchor == GAP_MSK_ANCHOR_CLIP))
+    {
+      tmp_image_area = gimp_image_width(tmp_image_id) * gimp_image_height(tmp_image_id);
+      
+      /* operation on clipped rectangle requires creation of the mask already at
+       * tmp_image_area size. in case the calculated area
+       * is smaller than the original tmp image, it will be
+       * more efficient to operate with the complete layer at calculated_area size
+       */
+      if (tmp_image_area < calculated_area)
+      {
+        l_ret = FALSE; /* operate on visble rectanngle only */
+      }
+    }
+    else
+    {
+      l_ret = FALSE; /* operate on visble rectanngle only */
+    }
+  }
+  
+  return (l_ret);
+
+}  /* end p_transform_operate_on_full_layer */
+
+/* ----------------------------------------------------
  * p_transform_and_add_layer
  * ----------------------------------------------------
- * - copy the layer (layer_id) to the composite image
+ * - copy the layer (layer_id) from tmp_image to the composite image
  *   using copy/paste
  * - the source Layer (layer_id) must be part of tmp_image_id
  * - set opacity, scale and move layer_id according to video attributes
+ * - optional apply transparency in case mask is attached (anchored to clip or master)
  *
  * return the new created layer id in the comp_image_id
  *   (that is already added to the composte image on top of layerstack)
@@ -4247,6 +4355,7 @@ p_transform_and_add_layer( gint32 comp_image_id
                       , frn_elem->filtermacro_file_to
                       , (gdouble)(local_stepcount) /* fmac_current_step */
                       , frn_elem->fmac_total_steps
+                      , frn_elem->fmac_accel
                     );
 
   if(gap_debug)
@@ -4286,68 +4395,186 @@ p_transform_and_add_layer( gint32 comp_image_id
   calculated = &calculate_attributes;
 
 
-  /* check size and scale source layer_id to calculated size
-   */
-  if ((gimp_image_width(tmp_image_id) != calculated->width)
-  ||  (gimp_image_height(tmp_image_id) != calculated->height) )
+  /* add a new transparent layer to composite image */
+  l_new_layer_id = gimp_layer_new(comp_image_id
+                              , "pasted_track"
+                              , vid_width
+                              , vid_height
+                              , GIMP_RGBA_IMAGE
+                              , 0.0         /* Opacity full transparent */
+                              ,GIMP_NORMAL_MODE);
+  gimp_image_add_layer(comp_image_id, l_new_layer_id, 0);
+  gap_layer_clear_to_color(l_new_layer_id, 0.0, 0.0, 0.0, 0.0);
+
+
+  if(TRUE == p_transform_operate_on_full_layer(calculated, comp_image_id, tmp_image_id, frn_elem))
   {
+    /* operate on layer in full calculated size */
     if(gap_debug)
     {
-      printf("DEBUG: p_transform_and_add_layer scaling layer from %dx%d to %dx%d\n"
+      printf("p_transform operate on FULL size layer\n");
+    }
+    /* check size and scale source layer_id to calculated size
+     */
+    if ((gimp_image_width(tmp_image_id) != calculated->width)
+    ||  (gimp_image_height(tmp_image_id) != calculated->height) )
+    {
+      if(gap_debug)
+      {
+        printf("DEBUG: p_transform_and_add_layer scaling layer from %dx%d to %dx%d\n"
                             , (int)gimp_image_width(tmp_image_id)
                             , (int)gimp_image_height(tmp_image_id)
                             , (int)calculated->width
                             , (int)calculated->height
                             );
 
+      }
+      gimp_layer_scale(layer_id, calculated->width, calculated->height
+                      , FALSE  /* FALSE: centered at image TRUE: centered local on layer */
+                      );
+
     }
-    gimp_layer_scale(layer_id, calculated->width, calculated->height
-                    , FALSE  /* FALSE: centered at image TRUE: centered local on layer */
-                    );
 
-  }
 
 
-  /* add a new layer to composite image */
-  l_new_layer_id = gimp_layer_new(comp_image_id
-                              , "pasted_track"
-                              , vid_width
-                              , vid_height
-                              , GIMP_RGBA_IMAGE
-                              , 0.0         /* Opacity full transparent */
-                              ,GIMP_NORMAL_MODE);
-  gimp_image_add_layer(comp_image_id, l_new_layer_id, 0);
-  gap_layer_clear_to_color(l_new_layer_id, 0.0, 0.0, 0.0, 0.0);
-
-  if((frn_elem->mask_name != NULL)
-  && (frn_elem->mask_anchor == GAP_MSK_ANCHOR_CLIP))
-  {
-     p_fetch_and_add_layermask(vidhand
+    if((frn_elem->mask_name != NULL)
+    && (frn_elem->mask_anchor == GAP_MSK_ANCHOR_CLIP))
+    {
+       /* fetch and add mask at calculated scaled size of layer_id */
+       p_fetch_and_add_layermask(vidhand
                   , frn_elem
                   , local_stepcount
                   , tmp_image_id
                   , layer_id
                   );
-     /* apply the mask (necessary because the following copy with this layer
-      * as source would ignore the layer mask)
-      */
-     gimp_layer_remove_mask(layer_id, GIMP_MASK_APPLY);
+       /* apply the mask (necessary because the following copy with this layer
+        * as source would ignore the layer mask)
+        */
+       gimp_layer_remove_mask(layer_id, GIMP_MASK_APPLY);
 
-  }
+    }
 
-  /* copy from tmp_image and paste to composite_image
-   * force copying of the complete layer by clearing the selection
-   */
-  gimp_selection_none(tmp_image_id);
-  gimp_edit_copy(layer_id);
-  l_fsel_layer_id = gimp_edit_paste(l_new_layer_id, FALSE);  /* FALSE paste clear selection */
+    /* copy from tmp_image and paste to composite_image
+     * force copying of the complete layer by clearing the selection
+     */
+    gimp_selection_none(tmp_image_id);
+    gimp_edit_copy(layer_id);
+    l_fsel_layer_id = gimp_edit_paste(l_new_layer_id, FALSE);  /* FALSE paste clear selection */
 
-  gimp_layer_set_offsets(l_fsel_layer_id
+    gimp_layer_set_offsets(l_fsel_layer_id
                         , calculated->x_offs
                         , calculated->y_offs
                         );
 
-  gimp_floating_sel_anchor(l_fsel_layer_id);
+    gimp_floating_sel_anchor(l_fsel_layer_id);
+  }
+  else
+  {
+    /* operate on clipped rectangle size */
+    if(gap_debug)
+    {
+      printf("p_transform operate on CLIPPED RECTANGLE\n");
+    }
+    
+    if ((calculated->visible_width <= 0) || (calculated->visible_height <= 0))
+    {
+      /* nothing will be visible (width or height is 0), so we can skip copying and scaling */
+      return (l_new_layer_id);  /* that is still fully transparent */
+    }
+         
+    if((frn_elem->mask_name != NULL)
+    && (frn_elem->mask_anchor == GAP_MSK_ANCHOR_CLIP))
+    {
+      /* add and apply layermask at original unscaled tmp_image size */
+      p_fetch_and_add_layermask(vidhand
+                  , frn_elem
+                  , local_stepcount
+                  , tmp_image_id
+                  , layer_id
+                  );
+      /* apply the mask (necessary because the following copy with this layer
+       * as source would ignore the layer mask)
+       */
+      gimp_layer_remove_mask(layer_id, GIMP_MASK_APPLY);
+    }
+
+
+         
+    /* copy selected clipped source rectangle from tmp_image to composite image 
+     * as floating selection attached to l_new_layer_id (visble part at source size)
+     */
+    {
+      gdouble sx;
+      gdouble sy;
+      gdouble swidth;
+      gdouble sheight;
+      
+      sx = 0;
+      if (calculated->x_offs < 0)
+      {
+        sx = (0 - calculated->x_offs) * 
+            ((gdouble)gimp_image_width(tmp_image_id) / MAX((gdouble)calculated->width, 1.0));
+      }
+      
+      sy = 0;
+      if (calculated->y_offs < 0)
+      {
+        sy = (0 - calculated->y_offs) * 
+            ((gdouble)gimp_image_height(tmp_image_id) / MAX((gdouble)calculated->height, 1.0));
+      }
+      
+      swidth = calculated->visible_width * gimp_image_width(tmp_image_id) / MAX(calculated->width, 1);
+      sheight = calculated->visible_height * gimp_image_height(tmp_image_id) / MAX(calculated->height, 1);
+
+      if(gap_debug)
+      {
+        printf("p_transform source rectangle offset sx:%.4f, sy:%.4f, swidth:%.4f, sheight:%.4f\n"
+           , (float)sx
+           , (float)sy
+           , (float)swidth
+           , (float)sheight
+           );
+      }
+
+      gimp_rect_select(tmp_image_id
+                      , sx, sy
+                      , swidth, sheight
+                      , GIMP_CHANNEL_OP_REPLACE
+                      , FALSE  /* feather flag */
+                      , 0.0    /* feather_radius */
+                      );
+    }
+
+    gimp_edit_copy(layer_id);
+    l_fsel_layer_id = gimp_edit_paste(l_new_layer_id, FALSE);  /* FALSE paste clear selection */
+
+
+    /* scale floating selection to visible target size */
+    if ((gimp_drawable_width(l_fsel_layer_id) != calculated->visible_width)
+    ||  (gimp_drawable_height(l_fsel_layer_id) != calculated->visible_height) )
+    {
+      gimp_layer_scale(l_fsel_layer_id, calculated->visible_width, calculated->visible_height
+                      , FALSE  /* FALSE: centered at image TRUE: centered local on layer */
+                      );
+    }
+
+    /* move floating selection according to target offsets
+     * (negative offsets are truncated to 0
+     * because this case is already handled by selecting only the visible clipped rectangle)
+     */
+    gimp_layer_set_offsets(l_fsel_layer_id
+                        , MAX(0, calculated->x_offs)
+                        , MAX(0, calculated->y_offs)
+                        );
+
+    gimp_floating_sel_anchor(l_fsel_layer_id);
+
+    
+  }
+
+
+
+
 
   if((frn_elem->mask_name != NULL)
   && (frn_elem->mask_anchor == GAP_MSK_ANCHOR_MASTER))
@@ -4367,9 +4594,6 @@ p_transform_and_add_layer( gint32 comp_image_id
 }   /* end p_transform_and_add_layer */
 
 
-
-
-
 /* ----------------------------------------------------
  * p_create_unicolor_image
  * ----------------------------------------------------
@@ -5310,9 +5534,10 @@ p_stb_render_composite_image_postprocessing(GapStbFetchData *gfd
   p_exec_filtermacro(gfd->comp_image_id
                     , gfd->layer_id
                     , filtermacro_file
-                    , NULL /* have no 2nd filtermacro_file_to for varying parametersets */
+                    , NULL /* have no 2nd filtermacro_file_to for varying parameter sets */
                     , 0.0  /* current_step */
                     , 1    /* total_steps */
+                    , 0    /* accelerationCharacteristic 0 = off */
                     );
 
   /* check again size and scale image to desired Videosize if needed */
@@ -5530,7 +5755,7 @@ p_do_insert_area_processing(GapStbFetchData *gfd
 /* --------------------------------------------
  * p_story_render_fetch_composite_image_private
  * --------------------------------------------
- * this procedure builds the composite image for the fram number specified by master_frame_nr.
+ * this procedure builds the composite image for the frame number specified by master_frame_nr.
  * Therefore all videotracks of the storyboard (specified via an already opened handle vidhand)
  * are fetched as layers. The track number is the layerstack index.
  * optional filtermacro processing is done for the separate layers (clip specific filtermacre)
@@ -5675,7 +5900,7 @@ p_story_render_fetch_composite_image_private(GapStoryRenderVidHandle *vidhand
            {
               printf("\n** ERROR fetching master_frame_nr:%d, from framename:%s Current CLIP was:\n"
                  , (int)master_frame_nr
-                 , (int)gfd->framename
+                 , gfd->framename
                  );
               gap_story_render_debug_print_frame_elem(gfd->frn_elem, -1);
               printf("\n** storyboard render processing failed\n");
diff --git a/gap/gap_story_render_types.h b/gap/gap_story_render_types.h
old mode 100644
new mode 100755
index 367ec69..80d6fa6
--- a/gap/gap_story_render_types.h
+++ b/gap/gap_story_render_types.h
@@ -136,7 +136,7 @@ typedef struct GapStoryRenderFrameRangeElem   /* nick: frn_elem */
    char   *filtermacro_file;
    char   *filtermacro_file_to;  /* additional macro with 2nd parameterset(s) for varying apply */
    gint32  fmac_total_steps;     /* total steps for varying filtermacro apply */
-
+   gint32  fmac_accel;           /* acceleration characteristic for filtermacro apply with varying values */
    
    gdouble  frame_from;       /* internal frame number that is 1.st of range (float due to internal clip splitting) */
    gdouble  frame_to;         /* internal frame number that is the last handled frame of the range */
@@ -182,6 +182,18 @@ typedef struct GapStoryRenderFrameRangeElem   /* nick: frn_elem */
    gdouble move_y_to;          /* -1.0 upto 1.0 where 0 is center and -1.0 up outside */
    gint32  move_y_dur;         /* number of frames to change from -> to value */
 
+   gint    opacity_accel;        /* acceleration characteristic for opacity transformation */
+   gint32  opacity_frames_done;  /* already processed frames since begin of transition */ 
+   gint    move_x_accel;
+   gint32  move_x_frames_done;
+   gint    move_y_accel;
+   gint32  move_y_frames_done;
+   gint    scale_x_accel;
+   gint32  scale_x_frames_done;
+   gint    scale_y_accel;
+   gint32  scale_y_frames_done;
+
+
    void   *next;
 } GapStoryRenderFrameRangeElem;  /* used for storyboard processing */
 
@@ -259,6 +271,17 @@ typedef struct GapStoryRenderVTrackAttrElem
    gdouble move_y_to;          /* -1.0 upto 1.0 where 0 is center and -1.0 up outside */
    gint32  move_y_dur;         /* number of frames to change from -> to value */
 
+   gint    opacity_accel;        /* acceleration characteristic for opacity transformation */
+   gint32  opacity_frames_done;  /* already processed frames since begin of transition */ 
+   gint    move_x_accel;
+   gint32  move_x_frames_done;
+   gint    move_y_accel;
+   gint32  move_y_frames_done;
+   gint    scale_x_accel;
+   gint32  scale_x_frames_done;
+   gint    scale_y_accel;
+   gint32  scale_y_frames_done;
+
 } GapStoryRenderVTrackAttrElem;  /* Video track attributes used for storyboard processing */
 
 typedef struct GapStoryRenderVTrackArray
diff --git a/gap/gap_story_syntax.c b/gap/gap_story_syntax.c
old mode 100644
new mode 100755
index 7c93707..2936b02
--- a/gap/gap_story_syntax.c
+++ b/gap/gap_story_syntax.c
@@ -272,7 +272,7 @@ p_create_syntax_list(void)
                ,NULL
                );
   p_add_keyword(GAP_STBKEY_VID_MASTER_FRAME_ASPECT
-           ,"width"
+               ,"width"
                ,"height"
                ,NULL
                );
@@ -306,6 +306,7 @@ p_create_syntax_list(void)
                ,"mask_stepsize"
                ,"mask_disable"
                ,"macsteps"
+               ,"macaccel"
                ,NULL
                );
   p_add_keyword(GAP_STBKEY_VID_PLAY_BLACKSECTION
@@ -323,6 +324,7 @@ p_create_syntax_list(void)
                ,"mask_stepsize"
                ,"mask_disable"
                ,"macsteps"
+               ,"macaccel"
                ,NULL
                );
   p_add_keyword(GAP_STBKEY_VID_PLAY_MOVIE
@@ -344,6 +346,7 @@ p_create_syntax_list(void)
                ,"mask_stepsize"
                ,"mask_disable"
                ,"macsteps"
+               ,"macaccel"
                ,NULL
                );
   p_add_keyword(GAP_STBKEY_VID_PLAY_FRAMES
@@ -362,6 +365,7 @@ p_create_syntax_list(void)
                ,"mask_stepsize"
                ,"mask_disable"
                ,"macsteps"
+               ,"macaccel"
                ,NULL
                );
   p_add_keyword(GAP_STBKEY_VID_PLAY_ANIMIMAGE
@@ -379,6 +383,7 @@ p_create_syntax_list(void)
                ,"mask_stepsize"
                ,"mask_disable"
                ,"macsteps"
+               ,"macaccel"
                ,NULL
                );
 
@@ -393,6 +398,7 @@ p_create_syntax_list(void)
                ,"mask_stepsize"
                ,"mask_disable"
                ,"macsteps"
+               ,"macaccel"
                ,NULL
                );
   p_add_keyword(GAP_STBKEY_VID_PLAY_COLOR
@@ -409,6 +415,7 @@ p_create_syntax_list(void)
                ,"mask_stepsize"
                ,"mask_disable"
                ,"macsteps"
+               ,"macaccel"
                ,NULL
                );
   p_add_keyword(GAP_STBKEY_VID_SILENCE
@@ -422,6 +429,7 @@ p_create_syntax_list(void)
                ,"opacity_from"
                ,"opacity_to"
                ,"nframes"
+               ,"accel"
                ,NULL
                );
   p_add_keyword(GAP_STBKEY_VID_ZOOM_X
@@ -429,6 +437,7 @@ p_create_syntax_list(void)
                ,"zoom_x_from"
                ,"zoom_x_to"
                ,"nframes"
+               ,"accel"
                ,NULL
                );
   p_add_keyword(GAP_STBKEY_VID_ZOOM_Y
@@ -436,6 +445,7 @@ p_create_syntax_list(void)
                ,"zoom_y_from"
                ,"zoom_y_to"
                ,"nframes"
+               ,"accel"
                ,NULL
                );
   p_add_keyword(GAP_STBKEY_VID_MOVE_X
@@ -443,6 +453,7 @@ p_create_syntax_list(void)
                ,"move_x_from"
                ,"move_x_to"
                ,"nframes"
+               ,"accel"
                ,NULL
                );
   p_add_keyword(GAP_STBKEY_VID_MOVE_Y
@@ -450,6 +461,7 @@ p_create_syntax_list(void)
                ,"move_y_from"
                ,"move_y_to"
                ,"nframes"
+               ,"accel"
                ,NULL
                );
   p_add_keyword(GAP_STBKEY_VID_FIT_SIZE
diff --git a/libgapbase/gap_libgapbase.h b/libgapbase/gap_libgapbase.h
index 87cafd7..90a818e 100644
--- a/libgapbase/gap_libgapbase.h
+++ b/libgapbase/gap_libgapbase.h
@@ -37,4 +37,13 @@
 #include "gap_file_util.h"
 #include "gap_base.h"
 
+
+/* GAP_BASE_MIX_VALUE  0.0 <= factor <= 1.0
+ *  result is a  for factor 0.0
+ *            b  for factor 1.0
+ *            mix for factors inbetween
+ */
+#define GAP_BASE_MIX_VALUE(factor, a, b) ((a * (1.0 - factor)) +  (b * factor))
+
+
 #endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]