--- /dev/null
+Developers:
+
+Robert B. Quattlebaum Jr (darco)
+Adrian Bentley
+
+Contributors:
+
+Paul Wise (pabs)
+Dmitriy Pomerantsev (Atrus)
+Daniel Fort
+Luka Pravica
+Andreas Jochens
+Chris Moore (dooglus)
+Martin Michlmayr
--- /dev/null
+2005-11-28 Robert Quattlebaum <darco@deepdarc.com>
+ * src/modules/lyr_std/sphere_distort.cpp/h: Clarified namespace issues
+2005-11-08 Robert Quattlebaum <darco@deepdarc.com>
+ * src/modules/lyr_std/stretch.cpp/h: Clarified namespace issues
+2005-11-03 Robert Quattlebaum <darco@deepdarc.com>
+ * src/synfig/savecanvas.cpp: added #include <sys/errorno.h>
+ * src/synfig/value.cpp: Various GCC 4.0 fixes
+ * src/modules/mod_bmp/trgt_bmp.cpp: The BMP target was broken. It's now fixed.
+ * examples: Removed SFAutomaton font due to licensing issues.
+ * All: Updated copyright notice to reflect new license
+
+2004-04-07 (darco): Foldy... Powers?
+2004-03-30 (darco): Fix for weird keyframe problem
+2004-03-24 (darco): Speed improvements for both the pastecanvas layer and the checkerboard layer
+2004-03-15 (darco): "Noise" layer split into two different layers: NoiseGradient, and NoiseDistort, which can be found in the Gradients and Distortions categories respectively.
+2004-03-05 (darco): New stuff tangents should interpolate using polar coordinates. Awesome.
+2004-03-05 (darco): Added "Bevel" Layer
+2004-03-05 (darco): Added "Shade" Layer
+2004-03-04 (darco): Fixed problem with tangents not animating correctly
+2004-02-25 (darco): Added the "time_offset" parameter to the Paste Canvas layer
+2004-02-20 (darco): Significantly improved the BLine (which will be later called "outline") layer
+2004-02-16 (darco): Added some under-the-hood-updates
+2004-02-16 (darco): Improved renddesc editing slightly
+2004-02-16 (darco): fixed the hit checks for the gradient layers. You can now more easily click on layers under them
+2004-02-11 (darco): fixed a memory leak in the freetype layer
+2004-02-11 (darco): fixed the onto blend method
+2004-02-10 (adruab): Added shape specific blurs
+2004-01-23 (darco) : Fixed minor loop problem
+2004-01-23 (darco) : Added "Cosine" falloff to circle. (should be better than sigmond)
+2004-01-21 (darco) : Support for paletted PNG files added
+2004-01-15 (darco) : BLine Layer: Added "width" parameter, removed "width_list" parameter
+2004-01-13 (darco) : Font layer largely re-written--now supports multiple lines. Also much more consistent.
+2004-01-09 (darco) : fixed all the loose ends with the rectangle layer
+2004-01-09 (darco) : Added expand parameter to rectangle layer
+2004-01-09 (darco) : Adjusted the rectangle layer -- you can now invert it
+2004-01-09 (darco) : You can now duplicate inline canvases
+2004-01-05 (darco) : Both ends of a BLine can now have round edges (which are now on by default)
+2004-01-05 (darco) : Increased threshold for cusp cut-off of tangents are too sharp
+2003-12-29 (darco) : Added support for sharp cusp points (on by default now)
+2003-12-24 (darco) : Adjusted Copyright Notice
+2003-12-24 (darco) : Improved the horizontal placement consistancy of the Text layer.
+2003-12-24 (darco) : Fix for obscure bug in scale valuenode that would cause a failure to load a saved file
+2003-11-25 (darco) : Improved the Text layer again. *sigh*
+2003-11-20 (darco) : Improved the consistancy of the Text layer again. :P
+2003-11-18 (darco) : Improved the consistancy of the Text layer. You should be able to use it without worrying about the layout going weird anymore.
+2003-11-12 (darco) : Added "--dpi", "--dpi-x", and "--dpi-y" arguments to the SINFG command line tool. these allow you to change the DPI of what you are rendering.
+2003-11-10 (darco) : Fixed odd animation behavior
+2003-11-10 (darco) : Fixed a bug in the PasteCanvas layer where mouse clicks wouldn't match up if the "origin" was changed from 0,0.
+2003-11-04 (darco) : Inserting points into a polygon is now smarter -- puts the new point between the original two
+2003-10-28 (darco) : Added support for physical dimension information in file format (xres/yres)
+2003-10-20 (adruab) : Added support for video encoding through use of FFMPEG (avi,mpg,asf,rm,wmv)
+2003-10-07 (darco) : Changed dynamic list/bline pad the index with zeros (001, 002, etc.)
+2003-10-06 (darco) : Added Red-Blue color-corection adjustment to gamma
+2003-10-06 (darco) : Added "displacement" mode for noise
+2003-10-06 (darco) : The "scale" valuenode will now NOT scale the alpha channel of a color. (Otherwise, it's kinda useless)
+2003-10-05 (darco) : The noise layer is now... Animated!
+2003-10-05 (darco) : Added new layer... Noise!
+2003-10-04 (darco) : You should now be able to create polygons layers without crashing. (Regions and BLines are another story though...)
+2003-10-03 (darco) : Implemented layer descriptions
+2003-09-30 (darco) : Fixed bug where BLine would "warp" when introducing new vertices.
+2003-09-30 (darco) : Editing stuff while the work area refreshes in SINFG Studio should now be smoother
+2003-09-24 (darco) : Adjusted the hit check in PasteCanvas layer to support inline canvases
+2003-09-23 (darco) : ConicalGradient had incorrect angle, it was 90 degrees off. Fixed.
+2003-09-17 (darco) : Fixed bewildering "wobble" animation bug
+2003-09-02 (darco) : Added antialiasing to the gradient layers
+2003-09-01 (darco) : Added Twirl Layer
+2003-09-01 (darco) : Added Star Layer
+2003-08-31 (darco) : Negative values are now clamped to the black point rather than having some kind of visualization.
+2003-08-13 (darco) : Fixed some gamma issues on the PNG and ImageMagick image importers
+2003-08-13 (darco) : Again, Improved support for clickable layers
+2003-08-12 (darco) : Improved support for clickable layers
+2003-08-06 (darco) : Added accelerated renderer for all gradient layers, they are now much faster. (Needs adaptive supersampling though...)
+2003-07-31 (darco) : Added support for black level adjustment in gamma correction
+2003-07-30 (darco) : Added support for gamma correction
+2003-07-30 (darco) : Adjusted the mandelbrot layer to support gradients
+2003-07-29 (darco) : Improved blend methods: Brighten, Darken
+2003-07-29 (darco) : Added new blend methods: Screen, Overlay, and Difference
+2003-07-24 (darco) : Added gradients!!!
+2003-07-16 (darco) : Tiled Renderer now implemented
+2003-07-14 (darco) : TCB controls now implemented
+2003-05-05 (darco) : Dynamic List entries can now have multiple start times and end times
+2003-05-05 (darco) : Phasing out Timed Stamp Value Node, because the animated value node is now capable.
+2003-05-05 (darco) : The Animated Value Node can now use exported values in waypoints.
+2003-04-23 (darco) : Added "stretch" layer. (Allows distortions to things like circles)
+2003-04-18 (darco) : Added "exposure" parameter to color correct layer
+2003-04-17 (darco) : Added native suport for JPEG files
+2003-04-15 (darco) : The parametric renderer is now multi-threaded, meaning it can take advantage of multiple processors. Doesn't work in Win32.
+2003-04-14 (darco) : Added "ColorCorrect" layer
+2003-04-14 (darco) : Added "bailout" parameter to Mandelbrot and Julia layers. Use larger values to improve smoothing.
+2003-04-14 (darco) : Improved clamp layer
+2003-04-14 (darco) : Fix a bug with the "Color" blend method
+2003-04-11 (darco) : Added "XORPattern" layer
+2003-04-11 (darco) : Added "clamp" layer for clamping colors
+2003-04-10 (darco) : Fixed a bug with the "smooth outside" parameter of the Julia and Mandelbrot layers
+2003-04-10 (darco) : Major under-the-hood changes
+2003-04-07 (darco) : Implemented support for inline (nested) canvases in parameters
+2003-04-07 (darco) : Removed "time blur" option from "blur" layer
+2003-04-07 (darco) : Created "motion blur" layer
+2003-04-04 (darco) : Added layer "julia"
+2003-04-04 (darco) : Added layer "inside out"
+2003-04-03 (darco) : Fixed some minor issues with the polygon layer
+2003-04-03 (darco) : Improvements to the way that time is handed
+2003-04-02 (darco) : Added "offset" parameter to polygon layer
+
+2003-04-01 (darco) : Added a new value type, "Time"
+2003-04-01 (darco) : Fixed a bug where values were not getting clamped
+2003-03-31 (darco) : Tons of under-the-hood changes
+2003-03-27 (darco) : Added "-c" argument to sinfg tool.
+2003-03-26 (darco) : Added "antialias" attribute to <canvas> in SIF file format.
+2003-03-26 (darco) : Fixed bug #0000010 ("DataNode_Subtract always reverts 'scalar' to constant after save/load")
+2003-03-25 (darco) : Added support for linking to DataNodes/Canvases in other Compositions.
+2003-03-24 (darco) : Added support for linking to DataNodes in different Canvases.
+
+2003-03-23 (darco) : Fixed a small bug in circle layer that caused inconsistant results when the feather was set to zero and the parametric renderer used.
+2003-03-23 (darco) : Added "zoom" parameter to PasteCanvas layer
+
+2003-03-22 (darco) : Fixed color-order bug in ImageMagick importer
+2003-03-22 (darco) : Fixed a layer-cloning bug (For example, attempting to clone the Import layer would crash SINFG Studio)
+
+2003-03-20 (darco) : Fixed bug where numbers would be appended to filename when using bitmap target
+2003-03-20 (darco) : PPM Module wasn't being loaded. Fixed.
+2003-03-20 (darco) : Version Increment
+
+2003-03-19 (darco) : Added BMP importer
+2003-03-19 (darco) : Added PNG importer
+
+2003-03-19 (darco) : Added "--importers" option to sinfg tool, for listing loaded importers
+
+2003-03-17 (darco) : Slight optimization to Region layer
+2003-03-17 (darco) : Slight optimization to BLine layer
+
+2003-03-04 (darco) : Improved some layers to improve responsiveness during rendering.
+2003-03-04 (darco) : Added rotate layer.
+2003-03-04 (darco) : Fully implemented the "angle" type in loading and saving.
+
+2003-03-01 (darco) : Changed the default zoom amount from 1.0 to 0.0
--- /dev/null
+# $Id$
+
+MAINTAINERCLEANFILES=COPYING INSTALL @PACKAGE_TARNAME@.pc.in @PACKAGE_TARNAME@.tar.gz doxygen.cfg config/config.guess config/config.sub config/ltmain.sh config/ltmain.sh.orig config/ltmain.sh.rej config/install-sh config/mkinstalldirs config/aclocal.m4 config/missing config/texinfo.tex config/depcomp aclocal.m4 config.h.in configure stamp-h.in Makefile.in config.log config.status .doc_stamp .DS_Store @PACKAGE_TARNAME@.spec include/etl_profile.h.in libltdl/COPYING.LIB libltdl/Makefile.in libltdl/acinclude.m4 libltdl/config-h.in libltdl/configure.in libltdl/ltdl.h libltdl/Makefile.am libltdl/README libltdl/aclocal.m4 libltdl/configure libltdl/ltdl.c libltdl/stamp-h.in
+
+
+SUBDIRS=libltdl src examples
+
+# Install the pkg-config file:
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = @PACKAGE_TARNAME@.pc
+
+bin_SCRIPTS=synfig-config
+
+EXTRA_DIST=ChangeLog.old TODO config/subs.m4 bootstrap config/package doc/hw-gfx-mapping.txt win32build.sh macosxbuild.sh win32inst.nsi.in COPYING config/depcomp config/synfig.m4 config/cxx_macros.m4 @PACKAGE_TARNAME@.spec config/project.spec.in config/build.cfg synfig.kdevprj synfig-config.in config/ETL.m4 config/doxygen.cfg.in doxygen.cfg config/pkgconfig.pc.in config/pkgconfig.m4 config/libxml++.m4 @PACKAGE_TARNAME@.pc.in pkg-info/macosx/core-resources/ReadMe.txt pkg-info/macosx/core-resources/Welcome.txt pkg-info/macosx/core-resources/install.sh
+
+CVS=cvs
+GREP=grep
+PRINTF=printf
+SH=sh
+DOXYGEN=doxygen
+
+SVN=svn
+TAG=@PACKAGE_TARNAME@_@VERSION_MAJ@_@VERSION_MIN@_@VERSION_REV@
+
+
+tagstable:
+ -$(SVN) delete $(SVN_REPOSITORY)/tags/stable -m "Stable Tag: Removing old tag"
+ $(SVN) copy $(top_srcdir) $(SVN_REPOSITORY)/tags/stable -m "Stable Tag: Copying everything over"
+
+tagrelease:
+ $(SVN) copy $(top_srcdir) $(SVN_REPOSITORY)/tags/$(TAG) -m "Release $(TAG)"
+
+stats:
+ -@echo
+ -@echo -- Stats
+ -@echo
+ -@$(PRINTF) "Total lines: "
+ -@wc -l $(shell find $(top_srcdir)/src -name '*.[ch]*') | $(GREP) total
+ -@$(PRINTF) "Total size: "
+ -@du -hcs $(shell find $(top_srcdir)/src -name '*.[ch]*') | $(GREP) total
+ -@echo
+
+ChangeLog:
+ -svn update
+ svn2cl --include-rev || touch ChangeLog
+
+#tagstable:
+# $(CVS) tag -F stable
+
+#tagrelease:
+# $(CVS) tag -F @PACKAGE_TARNAME@_@VERSION_MAJ@_@VERSION_MIN@_@VERSION_REV@
+
+
+listfixmes:
+ -@echo
+ -@echo -- List of pending FIXMEs
+ -@echo
+ -@$(GREP) -e FIXME -e "\\fixme" -n $(shell find $(top_srcdir) -name '*.[ch]*')
+ -@echo
+
+listhacks:
+ -@echo
+ -@echo -- List of pending HACKs
+ -@echo
+ -@$(GREP) -e HACK -e "\\hack" -n $(shell find $(top_srcdir) -name '*.[ch]*')
+ -@echo
+
+listtodos:
+ -@echo
+ -@echo -- List of pending TODOs
+ -@echo
+ -@$(GREP) -e TODO -e "\\todo" -n $(shell find $(top_srcdir) -name '*.[ch]*')
+ -@echo
+
+listoptimizes:
+ -@echo
+ -@echo -- List of pending optimizations
+ -@echo
+ -@$(GREP) -e OPTIMIZE -e "\\optimize" -n $(shell find $(top_srcdir) -name '*.[ch]*')
+ -@echo
+
+listwritemes:
+ -@echo
+ -@echo -- List of pending WRITEMEs
+ -@echo
+ -@$(GREP) -e WRITEME -e "\\writeme" -n $(shell find $(top_srcdir) -name '*.[ch]*')
+ -@echo
+
+install-bin:
+ make -C src/synfig install-libLTLIBRARIES
+
+win32inst.nsi: $(srcdir)/win32inst.nsi.in
+ ./config.status win32inst.nsi
+
+pkg-info/macosx/synfig-core.info: $(srcdir)/pkg-info/macosx/synfig-core.info.in
+ ./config.status pkg-info/macosx/synfig-core.info
+
+RMDIR=rm -fr
+
+if WIN32_PKG
+package: all win32inst.nsi
+ cp -fu `which libHalf-4.dll` src/modules/mod_openexr/.libs/
+ cp -fu `which libIlmImf-4.dll` src/modules/mod_openexr/.libs/
+ cp -fu `which libIlmThread-4.dll` src/modules/mod_openexr/.libs/
+ cp -fu `which libIex-4.dll` src/modules/mod_openexr/.libs/
+ makensis win32inst.nsi
+else
+if MACOSX_PKG
+package: all pkg-info/macosx/synfig-core.info
+ [ -d pkg_root ] && $(RMDIR) pkg_root || true
+ make install-strip prefix="`pwd`/pkg_root"
+ $(srcdir)/config/package pkg_root pkg-info/macosx/synfig-core.info -r $(srcdir)/pkg-info/macosx/core-resources
+endif
+endif
+
+run: check
+
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ $(srcdir)/bootstrap
+
+.doc_stamp: doxygen.cfg
+ $(DOXYGEN) doxygen.cfg
+ touch .doc_stamp
+
+benchmark:
+ synfig -b -t null -q --time 0 $(srcdir)/examples/*.sif
+
+html: .doc_stamp
+
+rtf: .doc_stamp
+
+docs: html
+
+.PHONY: stats tagstable tagrelease listfixmes listhacks check docs pdf html rtf
--- /dev/null
+ synfig releases
+
+ 0.61.07 (SVN 878) - October 10, 2007 - Bug fixes
+
+ * Fix importing on amd64 (#1692825)
+ * Fixes for the PasteCanvas layer (#1356449)
+ * Clean up Layer menu and displayed layer names
+ * Allow exported canvases to be used in more than one place within a canvas (#1785296)
+ * Fix, extend, and enable the 'XOR Pattern' layer
+ * Fix and extend the 'Plant' layer (#1790903)
+ * Turn on plant layer (gunsmoke) in macwolfen.sifz example
+ * Use 'fast gaussian' rather than 'gaussian' for blurs in pirates.sifz - it's faster!
+ * Fix and enable the 'Timed Swap' valuenode conversion
+ * Extend the 'Linear' valuenode conversion to work with colors and integers.
+ * Enable basic motion blur display at all qualities
+ * Fix an artifact on the curve gradient layer (#1792063, r663)
+ * Add the 'Range', 'Repeat Gradient', 'Add', 'Exponent' valuenode conversions
+ * Add the 'BLine Vector', and 'BLine Tangent' valuenode conversions (#1781903)
+ * Fix problems with valuenode conversion (#1794374, #1795913, #1795922, #1796068, #1797488)
+ * Allow gradients to be animated (#1568818, #1795802)
+ * Stop TCB angle waypoints changing to type Linear on load (#1778930)
+ * Use compression when saving to files with .sifz extension
+ * Compressed example .sif files to .sifz to save space
+ * Fixed Motion Blur layer (#1800783)
+ * Allow building studio with gcc -O2 (#1509627)
+ * Allow encapsulated layers to animate their z-depth, even when time-shifted (#1806852)
+ * Fixed the Radial Blur layer when zooming in on the canvas (#1807709)
+ * Fix several other bugs and crashes
+
+ 0.61.06 (SVN 536) - June 20, 2007 - Bug fixes
+
+ * Add fontconfig support
+ * Fix amd64 issue
+ * Fix ffmpeg, gif, libav targets
+ * Include more target modules in the Win32 package
+ * Fix some crashes in synfigstudio
+ * Fix some render artifacts
+ * Fix some doxygen warnings
+ * Some MacOS fixes
+ * Misc bug fixes
+ * Fix random number generation for 64 bit CPUs (#1698604)
+ * Add parameter 'fast' to curve gradients to choose fast or accurate rendering (#1672033)
+ * Add new odd/even winding style for regions
+
+ 0.61.05 (SVN 126) - February 27, 2005 - Misc fixes
+
+ * Use system libltdl when available (#1423944)
+ * Update doxygen config file (#1402909)
+ * Fix fontconfig/xft FTBFS
+ * Misc fix (#1414370)
+
+ 0.61.04 (SVN 102) - January 10, 2005 - Misc fixes
+
+ * Check for imagemagick at build time
+ * Clarify mod_openexr copyright
+ * Fix mod_openexr building
+ * Don't add 'Copyright Voria' to PNG output
+ * Don't write localised numbers when generating SIF files
+
+ 0.61.03 - December 8, 2005 - Copyright update
+
+ * Update more old copyright and licence notices
+ * Remove broken walk example
+ * Misc code fixes
+
+ 0.61.02 - November 26, 2005 - Misc fixes
+
+ * Small cygwin/optimization/code fixes
+
+ 0.61.01 - November 3, 2005 - Copyright update
+
+ * Update old copyright and licence notices
+ * Fix some GCC 4.0 build issues
+ * Include errno.h where needed
+ * Add ./configure options for debug, warnings, optimisation, profiling
+ * Add about_dialog.sif as another example
+ * Remove SFAutomaton.ttf due to licence issues
+ * Fix BMP rendering target
+
+ 0.61.00-39 - November 1, 2005 - Developer preview
+
+ * First public release!
+
--- /dev/null
+ synfig -- vector animation renderer
+
+synfig is a vector based 2D animation package. It is designed to be
+capable of producing feature-film quality animation. It eliminates the
+need for tweening, preventing the need to hand-draw each frame. synfig
+features spatial and temporal resolution independence (sharp and smooth
+at any resolution or framerate), high dynamic range images, and a
+flexible plugin system.
+
+This package contains the renderer used to convert synfig .sif files to
+raster images, videos and other formats. Layer types include geometric,
+gradient, filter, distortion, transformation, fractal and others. Output
+targets include JPEG, PNG, GIF, BMP, PPM, DV, OpenEXR, ffmpeg (MPEG1),
+libavcodec (AVI), imagemagick (MIFF), yuv420p and others.
+
+Links
+
+Web: http://www.synfig.com/
+Wiki: http://wiki.synfig.com/
+SVN: http://svn.voria.com/code/synfig/
+Proj: http://sf.net/projects/synfig/
+IRC: irc://irc.freenode.net/synfig
+
+Please use the IRC channel and the sf.net tracker to get support and
+report bugs, request features and submit patches.
+
+Copyright
+
+Copyright 2002 Robert B. Quattlebaum Jr.
+Copyright 2002 Adrian Bentley
+Copyright 2006 Paul Wise
+Copyright 2007 Chris Moore
+
+Licence
+
+This package is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of
+the License, or (at your option) any later version.
+
+This package is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+or visit http://www.gnu.org/licenses/gpl.html
--- /dev/null
+
+## General ##
+
+* Re-write font system. (The "simple text" layer is a dirty,dirty hack)
+* Use pre-multiplied alpha to speed up compositing
+* Solidify plug in system to be more robust (Auto-detect and load?)
+* Solidify and codify XML file format into XML schema
+* Make layer and value-node parameters handled in the same way. (currently different)
+* Move to a garbage-collected system rather than reference counted
+* Integrate a scripting language (Possibly better suited for libsynfigapp?)
+* Finish and migrate to a new surface layer class
+ - Arbitrary color/alpha channels
+ - Surface locking/unlocking
+ - Copy-on-write
+* Make the "Value" class extendable by plug-ins
+* Add parameter mechanism to render target class to allow user to control things like:
+ - Color depth
+ - Codec
+ - etc.
+* Review/rewrite error-handling and reporting mechanism
+* Migrate public API to be more language agnostic in nature
+* Network-distributed rendering
+* Solid multi-threaded rendering
+* mod_png: 16-bit pixel support
+
+
+## Wanted Plug-Ins ##
+
+* mod_svg: SVG Import/Export
+* mod_quicktime: Support for importing/rendering-to quicktime movies (MacOS X and Windows Only)
+* mod_imageio: Support for Apple's ImageIO framework (MacOS X Only)
+* mod_tiff: Using libtiff
+* mod_wmv: Support for Windows Media for importing/rendering-to wmv/avi movies (Windows only)
+
+## User-requested features ##
+
+http://wiki.synfig.com/Wish_list
+http://sf.net/tracker/?group_id=144022&atid=757419
--- /dev/null
+#! /bin/sh
+#
+# Synfig Bootstrap Script
+# $Id$
+#
+# This script creates the configure script and Makefile.in files,
+# and also fixes a few things in both to ensure a smooth build
+# on all compilers and platforms.
+#
+
+# Grab the current directory and move to our own
+CURR_DIR="$(pwd)"
+cd "$(dirname $0)"
+
+# Environment Variables
+BOOTSTRAP_NAME="$(basename $0)"
+CONFIG_DIR="config"
+
+[ -x /bin/cygpath ] && CONFIG_DIR="`cygpath -m -s "$CONFIG_DIR"`"
+[ -x /bin/cygpath ] && CONFIG_DIR="`cygpath -u "$CONFIG_DIR"`"
+[ -x /bin/cygpath ] && CURR_DIR="`cygpath -m -s "$CURR_DIR"`"
+[ -x /bin/cygpath ] && CURR_DIR="`cygpath -u "$CURR_DIR"`"
+# Automake,Autoconf, and Libtool versions that we require
+#AUTOCONF_VERSION=2.5
+#AUTOMAKE_VERSION=1.6
+#LIBTOOL_VERSION=1.4
+export WANT_AUTOMAKE=1.8
+#export WANT_LIBTOOL_VER=1.5
+export WANT_AUTOCONF_2_5=1
+export WANT_AUTOCONF=2.5
+
+. "$CONFIG_DIR/build.cfg"
+
+SED_SCRIPT="
+s/@PACKAGE@/$PACKAGE/g;
+s/@PACKAGE_NAME@/$PACKAGE_NAME/g;
+s/@PACKAGE_BUGREPORT@/$PACKAGE_BUGREPORT/g;
+s/@PACKAGE_TARNAME@/$PACKAGE_TARNAME/g;
+s/@PACKAGE_VERSION@/$PACKAGE_VERSION/g;
+s|@SVN_REPOSITORY@|$SVN_REPOSITORY|g;
+s/@VERSION@/$VERSION/g;
+s/@API_VERSION@/$API_VERSION/g;
+s/@VERSION_MAJ@/$VERSION_MAJ/g;
+s/@VERSION_MIN@/$VERSION_MIN/g;
+s/@VERSION_REV@/$VERSION_REV/g;
+s/@VERSION_REL@/$VERSION_REL/g;
+s/@CFLAGS@//g;
+"
+
+# Define the output function
+output () {
+ echo $BOOTSTRAP_NAME: $*
+}
+
+# Define the cleanup function
+cleanup () {
+ output Cleaning up...
+ rm -fr config.cache autom4te*.cache configure.in $TEMPFILE
+}
+
+output Preparing build environment for $PACKAGE-$VERSION...
+
+# Look for the CVS directory. If we don't find it, we need to
+# ask the user if they know what they are doing.
+( test -d CVS || test -d .svn ) ||
+{
+ output warning: This shell script is intended for those
+ output warning: who either know what they are doing or
+ output warning: or downloaded this program from the CVS
+ output warning: repository. See README for more details.
+ output warning: To avoid seeing this message in the future,
+ output warning: create an empty directory called 'CVS'.
+ output Waiting for 15 seconds...
+ sleep 15
+}
+
+# Create the temporary file
+output Creating temporary file...
+TEMPFILE=`mktemp /tmp/$BOOTSTRAP_NAME.XXXXXX` ||
+{
+ output ERROR: Unable to create temporary file!
+ exit 1
+}
+
+# Check for autoconf
+(which autoconf > /dev/null 2>&1 ) ||
+{
+ output error: 'Could not find GNU autoconf!'
+ output You need to download and install GNU autoconf v2.52 or higher.
+ output '<ftp://ftp.gnu.org/gnu/autoconf/>'
+ cleanup;
+ exit 1
+}
+
+# Check autoconf version
+output Using $(autoconf --version | grep utoconf)
+autoconf --version | grep -q "$AUTOCONF_VERSION" ||
+{
+ output warning: Unexpected version of GNU Autoconf "(expected $AUTOCONF_VERSION)"
+ output warning: *** Bootstrap process may fail!
+}
+
+# Check for automake
+(which automake > /dev/null 2>&1 ) ||
+{
+ output error: 'Could not find GNU automake!'
+ output You need to download and install GNU automake v1.5 or higher.
+ output '<ftp://ftp.gnu.org/gnu/automake/>'
+ cleanup;
+ exit 1
+}
+
+# Check automake version
+output Using $(automake --version | grep utomake)
+automake --version | grep -q "$AUTOMAKE_VERSION" ||
+{
+ output warning: Unexpected version of GNU Automake "(expected $AUTOMAKE_VERSION)"
+ output warning: *** Bootstrap process may fail!
+}
+
+# Check for libtool
+(which libtool > /dev/null 2>&1 ) ||
+{
+ output error: 'Could not find GNU libtool!'
+ output You need to download and install GNU libtool v1.4 or higher.
+ output '<ftp://ftp.gnu.org/gnu/libtool/>'
+ exit 1
+}
+
+# Check libtool version
+echo $BOOTSTRAP_NAME: Using $(libtoolize --version | grep ibtool)
+libtoolize --version | grep -q "$LIBTOOL_VERSION" ||
+{
+ output warning: Unexpected version of GNU Libtool "(expected $LIBTOOL_VERSION)"
+ output warning: *** Bootstrap process may fail!
+}
+
+# Versions of libtool prior to 1.4.2 have a seriously broken libltdl.
+# If we are using this broken version, we need to patch it.
+libtoolize --version | grep -q -e "1.4.2" -e "1.4.1" -e "1.4 " && PATCH_LTDL=1
+
+RECONFIG_LTDL=1
+
+for FILENAME in doxygen.cfg pkgconfig.pc project.spec ; do {
+output Creating $FILENAME...
+sed "$SED_SCRIPT" < "$CONFIG_DIR/$FILENAME.in" > $FILENAME;
+} ; done
+
+output Renaming pkgconfig.pc to $PACKAGE_TARNAME.pc.in...
+mv pkgconfig.pc "$PACKAGE_TARNAME.pc.in"
+
+output Renaming project.spec to $PACKAGE.spec...
+mv project.spec "$PACKAGE.spec"
+
+output Finishing up $PACKAGE.spec...
+echo %changelog >> "$PACKAGE.spec"
+cat NEWS >> "$PACKAGE.spec"
+
+output Creating configure.in from configure.ac...
+sed "$SED_SCRIPT" < "$CONFIG_DIR/configure.ac" > configure.in;
+
+output Generating ChangeLog from SVN
+if test x != "x$VERSION_REL" ; then export REVISION="--revision $VERSION_REL" ; fi
+test -f ChangeLog || svn2cl --include-rev $REVISION $SVN_REPOSITORY/trunk/ || touch ChangeLog
+
+output Setting up build environment...
+
+# Set the shell to output what we are doing
+set -x
+
+# Create all of the build environment files
+(
+ libtoolize -c -f --ltdl &&
+ aclocal -I "$CONFIG_DIR" $ACLOCAL_FLAGS &&
+ autoheader &&
+ autoconf -o configure &&
+ automake --force-missing --add-missing --include-deps &&
+ true
+) ||
+{
+ # Something went wrong...
+ set +x
+ output Failure.
+ cleanup;
+ exit 1
+}
+
+# Turn off echoing of commands
+set +x
+
+# Reconfigure the LTDL, if necessary
+[ $RECONFIG_LTDL"x" != "x" ] && (
+ output Reconfiguring LTDL...
+ set -x
+ (
+ cd libltdl &&
+ ( echo "AC_CONFIG_AUX_DIR(../config)" >> configure.* ) &&
+ aclocal -I "../$CONFIG_DIR" &&
+ autoheader &&
+ autoconf &&
+ automake --force-missing --add-missing --include-deps
+ ) ||
+ {
+ # Something went wrong...
+ set +x
+ output Failure.
+ cleanup;
+ exit 1
+ }
+ set +x
+)
+
+# If this is the broken version of LTDL, then patch it
+[ $PATCH_LTDL"x" != "x" ] && (
+ output Patching LTDL...
+ sed "
+ s/handle || /(handle \&\& handle->loader) || /;
+ s/errors > 0) \&\& file_not_found ())/errors > 0) \&\& !file_not_found ())/;
+ s/(!handle)/(!handle || !handle->loader)/;
+ s/ access (filename, R_OK)/ !access (filename, R_OK)/;
+ " < libltdl/ltdl.c > $TEMPFILE && cp $TEMPFILE libltdl/ltdl.c
+ sed "
+ s/DLL_EXPORT/LTDL_DLL_EXPORT/;
+ " < libltdl/ltdl.h > $TEMPFILE && cp $TEMPFILE libltdl/ltdl.h
+)
+
+(
+output Patching libtool...
+patch config/ltmain.sh config/ltmain.patch
+) || true
+false && {
+ # Something went wrong...
+ set +x
+ output Failure.
+ cleanup;
+ exit 1
+}
+
+#echo '#define LTDL_SHLIB_EXT ".so"' >> libltdl/config-h.in
+#echo '
+#ifdef WIN32
+#define LTDL_SHLIB_EXT ".dll"
+#else
+#if __APPLE__
+#define LTDL_SHLIB_EXT ".so"
+#else
+#define LTDL_SHLIB_EXT ".la"
+#endif
+#endif ' >> libltdl/config-h.in
+
+# output Patching configure script to look for gcc3...
+# sed "
+# s/g++ c++/g++3 g++ c++/;
+# s/gcc cc/gcc3 gcc cc/;
+# s:"'${prefix}/include'":"'${prefix}/include/synfig'":;
+# s:PREFIX/include:PREFIX/include/ETL:;
+# " < configure > $TEMPFILE
+# cp $TEMPFILE configure
+
+# Patch the Makefile.in files
+for filename in $(find Makefile.in src -name Makefile.in) ; do {
+ echo $BOOTSTRAP_NAME: Patching $filename
+ (
+ cp $filename $TEMPFILE &&
+ sed "
+ # Remove brain-dead include path
+ s;-I. ;;
+
+ # Gosh... I can't remember why I did this one...
+ # Everything seems to work, so I'll leave it in.
+ s;-I"'$(srcdir)'" ;-I"'$(top_srcdir)'" ;
+
+ # Tell the configure script where it's origin realy is
+ s;configure.in;config/configure.ac;
+ " < $TEMPFILE > $filename
+ ) ||
+ {
+ # Patch failure
+ output Failure. Unable to patch $filename.
+ cleanup;
+ exit 1
+ }
+}; done
+
+output Creating Makefile...
+( echo "
+all:
+ ./configure --enable-maintainer-mode
+ make all
+
+install:
+ ./configure --enable-maintainer-mode
+ make install
+
+check:
+ ./configure --enable-maintainer-mode
+ make check
+
+distcheck:
+ ./configure --enable-maintainer-mode
+ make check
+
+dist:
+ ./configure --enable-maintainer-mode
+ make dist
+
+docs: doxygen.cfg
+ doxygen doxygen.cfg
+
+" ) > Makefile
+
+output Complete.
+
+cleanup;
+
+# Move back to the current directory
+cd "$CURR_DIR"
+
+make -C src/synfig/proto
--- /dev/null
+# ETL M4 Macro
+# For GNU Autotools
+# $Id$
+#
+# By Robert B. Quattlebaum Jr. <darco@users.sf.net>
+#
+
+AC_DEFUN([ETL_DEPS],
+[
+ AC_C_BIGENDIAN
+
+ AC_CHECK_LIB(user32, main)
+ AC_CHECK_LIB(kernel32, main)
+ AC_CHECK_LIB(pthread, main)
+
+ AC_HEADER_STDC
+
+ AC_CHECK_HEADERS(pthread.h)
+ AC_CHECK_HEADERS(sched.h)
+ AC_CHECK_HEADERS(sys/times.h)
+ AC_CHECK_HEADERS(sys/time.h)
+ AC_CHECK_HEADERS(unistd.h)
+ AC_CHECK_HEADERS(windows.h)
+ AC_CHECK_FUNCS([pthread_create])
+ AC_CHECK_FUNCS([pthread_rwlock_init])
+ AC_CHECK_FUNCS([pthread_yield])
+ AC_CHECK_FUNCS([sched_yield])
+ AC_CHECK_FUNCS([CreateThread])
+ AC_CHECK_FUNCS([__clone])
+ AC_CHECK_FUNCS([QueryPerformanceCounter])
+
+ AC_CHECK_FUNCS([gettimeofday])
+ AC_CHECK_FUNCS([vsscanf])
+ AC_CHECK_FUNCS([vsprintf])
+ AC_CHECK_FUNCS([vasprintf])
+ AC_CHECK_FUNCS([vsnprintf],[],[
+ AC_CHECK_FUNC([_vsnprintf],[
+ AC_DEFINE(vsnprintf,_vsnprintf,[define if the vsnprintf function is mangled])
+ AC_DEFINE(HAVE_VSNPRINTF,1)
+ ])
+ ])
+
+ $1
+])
+
+AC_DEFUN([USING_ETL],
+[
+ AC_ARG_WITH(ETL-includes,
+ [ --with-ETL-includes Specify location of ETL headers],[
+ CXXFLAGS="$CXXFLAGS -I$withval"
+ ])
+
+ AC_PATH_PROG(ETL_CONFIG,ETL-config,no)
+
+ if test "$ETL_CONFIG" = "no"; then
+ no_ETL_config="yes"
+ $2
+ else
+ AC_MSG_CHECKING([if $ETL_CONFIG works])
+ if $ETL_CONFIG --libs >/dev/null 2>&1; then
+ ETL_VERSION="`$ETL_CONFIG --version`"
+ AC_MSG_RESULT([yes, $ETL_VERSION])
+ CXXFLAGS="$CXXFLAGS `$ETL_CONFIG --cxxflags`"
+ $1
+ else
+ AC_MSG_RESULT(no)
+ no_ETL_config="yes"
+ $2
+ fi
+ fi
+
+ ETL_DEPS($1,$2)
+])
+
+
--- /dev/null
+
+PACKAGE_NAME="Synfig Core"
+PACKAGE_BUGREPORT="darco@deepdarc.com"
+PACKAGE_TARNAME=synfig
+VERSION_MAJ="0"
+VERSION_MIN="61"
+VERSION_REV="07"
+[ -d ".svn" ] && VERSION_REL=`svn info | grep Revision | sed "s/.* \([0123456789]*\)/\1/"`
+SVN_REPOSITORY="http://svn.voria.com/code/synfig-core"
+
+[ -d CVS ] && VERSION_REL="CVS"
+
+if [ x$VERSION_REL = "x" ] ; then {
+ VERSION=$VERSION_MAJ.$VERSION_MIN.$VERSION_REV
+} else {
+ VERSION=$VERSION_MAJ.$VERSION_MIN.$VERSION_REV-$VERSION_REL
+} ; fi
+
+API_VERSION="0.0"
+
+PACKAGE_VERSION=$VERSION
+PACKAGE=$PACKAGE_TARNAME
--- /dev/null
+# $Id$
+
+# -- I N I T --------------------------------------------------
+
+. $srcdir/config/build.cfg
+
+AC_INIT(@PACKAGE_NAME@,@PACKAGE_VERSION@,@PACKAGE_BUGREPORT@,@PACKAGE_TARNAME@)
+AC_REVISION
+
+AC_CONFIG_AUX_DIR(config)
+AM_CONFIG_HEADER(config.h)
+AC_CANONICAL_HOST
+dnl AC_CANONICAL_TARGET
+
+AM_INIT_AUTOMAKE
+AM_MAINTAINER_MODE
+
+AC_LIBLTDL_INSTALLABLE
+AC_SUBST(INCLTDL)
+AC_SUBST(LIBLTDL)
+
+API_VERSION=@API_VERSION@
+
+
+AC_DEFINE(LT_SCOPE,[extern],[LibLTDL is linked staticly])
+
+
+
+
+# -- V A R I A B L E S ----------------------------------------
+
+SVN_REPOSITORY=@SVN_REPOSITORY@
+AC_SUBST(SVN_REPOSITORY)
+
+# -- P R O G R A M S ------------------------------------------
+
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_CPP
+AC_PROG_CXXCPP
+AC_PROG_INSTALL
+
+AC_LANG_CPLUSPLUS
+
+
+# -- A R G U M E N T S ----------------------------------------
+
+
+AC_ARG_TIMELIMIT
+AC_ARG_DEBUG
+AC_ARG_OPTIMIZATION
+AC_ARG_WARNINGS
+AC_ARG_PROFILING
+AC_ARG_PROFILE_ARCS
+AC_ARG_BRANCH_PROBABILITIES
+dnl AC_ARG_LICENSE_KEY
+
+AC_ARG_ENABLE(g5opt,[
+ --enable-g5opt enable optimizations specific to G5 proc],[
+# CXXFLAGS="$CXXFLAGS -fastf -fPIC"
+# CFLAGS="$CFLAGS -fastf -fPIC"
+ CXXFLAGS="$CXXFLAGS -mtune=G5 -falign-loops=32"
+ CFLAGS="$CFLAGS -mtune=G5"
+],
+[
+ true
+])
+
+#MINGW_FLAGS="-mno-cygwin"
+
+AC_WIN32_QUIRKS
+
+# If we are in debug mode, use the debugging version of the
+# Microsoft Visual C Runtime Library
+#if [[ $debug = "yes" ]] ; then {
+# WIN32_DEBUG_LIBRARY="msvcr70d"
+# WIN32_DEBUG_LIBRARY="msvcrtd"
+# LIBTOOL_PATCH_SED="$LIBTOOL_PATCH_SED
+# s/-lmsvcrt/-l$WIN32_DEBUG_LIBRARY/g;
+# ";
+#} ; fi
+
+AC_LIBTOOL_WIN32_DLL
+AC_LIBTOOL_DLOPEN
+AC_DISABLE_STATIC
+AC_ENABLE_SHARED
+AC_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+AC_LIBTOOL_PATCH
+
+#if [[ "$LIBTOOL_PATCH_SED""x" != "x" ]] ; then {
+# printf "Patching libtool... "
+# cat libtool | sed "$LIBTOOL_PATCH_SED" > libtool2
+# rm libtool
+# mv libtool2 libtool
+# chmod +x libtool
+# AC_MSG_RESULT([patched])
+#} fi ;
+
+
+dnl
+dnl dynamic linker
+dnl
+AC_CHECK_LIB(c, dlopen,
+ DYNAMIC_LD_LIBS="",
+ AC_CHECK_LIB(
+ dl,
+ dlopen,
+ DYNAMIC_LD_LIBS="-ldl",
+ DYNAMIC_LD_LIBS=""
+ )
+)
+
+AC_SUBST(DYNAMIC_LD_LIBS)
+
+AC_ARG_ENABLE(half,[
+ --enable-half Use OpenEXR's "half" type for color],[
+ use_openexr_half=$enableval
+],
+[
+ use_openexr_half="no"
+])
+
+
+
+AC_ARG_ENABLE(layer-profiling,[
+ --enable-layer-profiling Enable layer profiling],[
+ use_layerprofiling=$enableval
+],
+[
+ use_layerprofiling="no"
+])
+if test $use_layerprofiling = "yes" ; then {
+ AC_DEFINE(SYNFIG_PROFILE_LAYERS,[1],[enable layer profiling])
+} ; fi
+
+
+
+
+AC_ARG_WITH(imagemagick,[
+ --without-imagemagick Disable support for ImageMagick],[
+],[
+ AC_CHECK_PROG([imagemagick_convert],[convert],[yes],[no])
+ with_imagemagick=$imagemagick_convert
+])
+if test $with_imagemagick = "no" ; then {
+ AM_CONDITIONAL(WITH_IMAGEMAGICK,false)
+} else {
+ AM_CONDITIONAL(WITH_IMAGEMAGICK,true)
+} ; fi
+
+
+
+
+
+AC_ARG_WITH(ffmpeg,[
+ --without-ffmpeg Disable support for FFMPEG],[
+],[
+ with_ffmpeg="yes"
+])
+if test $with_ffmpeg = "no" ; then {
+ AM_CONDITIONAL(WITH_FFMPEG,false)
+} else {
+ AM_CONDITIONAL(WITH_FFMPEG,true)
+} ; fi
+
+
+
+
+AC_ARG_WITH(vimage,[
+ --with-vimage Enable support for apple vImage],[
+],[
+ with_vimage="no"
+])
+if test $with_vimage = "no" ; then {
+ AM_CONDITIONAL(WITH_VIMAGE,false)
+} else {
+ AM_CONDITIONAL(WITH_VIMAGE,true)
+ AC_DEFINE(HAS_VIMAGE,[1],[enable apple vImage])
+ VIMAGE_LIBS="-Wc,-framework -Wc,Accelerate"
+
+} ; fi
+
+
+
+AC_ARG_WITH(libdv,[
+ --without-libdv Disable support for libdv],[
+],[
+ with_libdv="yes"
+])
+if test $with_libdv = "no" ; then {
+ AM_CONDITIONAL(WITH_LIBDV,false)
+} else {
+ AM_CONDITIONAL(WITH_LIBDV,true)
+} ; fi
+
+
+
+
+# LIBAVCODEC CHECK--------------------
+
+AC_ARG_WITH(libavcodec,[
+ --without-libavcodec disable support for libavcodec (Default=auto)],[
+],[
+ with_libavcodec="yes"
+])
+
+if test $with_libavcodec != "no" ; then {
+ PKG_CHECK_MODULES(LIBAVCODEC, [libavcodec libavformat],[],[echo no; with_libavcodec="no"])
+} ; fi
+if test $with_libavcodec = "yes" ; then {
+ AC_DEFINE(WITH_LIBAVCODEC,[],[enable libavcodec support])
+ AM_CONDITIONAL(WITH_LIBAVCODEC,true)
+} else {
+ AM_CONDITIONAL(WITH_LIBAVCODEC,false)
+} ; fi
+
+
+
+# FREETYPE2 CHECK--------------------
+
+AC_ARG_WITH(freetype,[
+ --without-freetype disable support for freetype (Default=auto)],[
+],[
+ with_freetype="yes"
+])
+
+if test $with_freetype != "no" ; then {
+ PKG_CHECK_MODULES(FREETYPE, freetype2,[
+ with_freetype="yes"
+ ],[
+ PKG_CHECK_MODULES(FREETYPE, xft,[
+ with_freetype="yes"
+ ],[
+ with_freetype="no"
+ ])
+ ])
+} ; fi
+
+if test $with_freetype = "no" ; then {
+ AM_CONDITIONAL(WITH_FREETYPE,false)
+} else {
+ AM_CONDITIONAL(WITH_FREETYPE,true)
+} ; fi
+
+
+# FONTCONFIG CHECK--------------------
+
+AC_ARG_WITH(fontconfig,[
+ --without-fontconfig disable support for fontconfig (Default=auto)],[
+],[
+ with_fontconfig="yes"
+])
+
+if test $with_fontconfig != "no" ; then {
+ PKG_CHECK_MODULES(FONTCONFIG, fontconfig,[
+ with_fontconfig="yes"
+ ],[
+ with_fontconfig="no"
+ ])
+} ; fi
+
+if test $with_fontconfig = "yes" ; then {
+ AC_DEFINE(WITH_FONTCONFIG,[],[enable fontconfig support])
+ AM_CONDITIONAL(WITH_FONTCONFIG,true)
+} else {
+ AM_CONDITIONAL(WITH_FONTCONFIG,false)
+} ; fi
+
+
+# OPENEXR CHECK------------------------
+AC_ARG_WITH(openexr,[
+ --without-openexr Disable support for ILM's OpenEXR],[
+],[
+ with_openexr="yes"
+])
+if test $with_openexr = "yes" ; then {
+ PKG_CHECK_MODULES(OPENEXR, OpenEXR,[
+ CONFIG_DEPS="$CONFIG_DEPS OpenEXR"
+
+ AC_DEFINE(HAVE_OPENEXR,[], [ Define if OpenEXR is available ] )
+ AM_CONDITIONAL(WITH_OPENEXR,true)
+ ],
+ [
+ with_openexr="no"
+ ])
+} ; fi
+if test $with_openexr = "no" ; then {
+ AM_CONDITIONAL(WITH_OPENEXR,false)
+ use_openexr_half="no"
+} ; fi
+if test $use_openexr_half = yes ; then {
+ AC_MSG_RESULT([ ** Using OpenEXR Half.])
+ CONFIG_CFLAGS="$CONFIG_CFLAGS -DUSE_HALF_TYPE"
+ OPENEXR_HALF_LIBS="-lHalf"
+} else {
+ OPENEXR_HALF_LIBS=""
+} ; fi
+
+
+
+
+
+# -- L I B R A R I E S ----------------------------------------
+
+AC_LIB_LTDL
+
+PKG_CHECK_MODULES(ETL, [ETL >= 0.04.10],,[
+ AC_MSG_ERROR([ ** You need to install the ETL (version 0.04.10 or greater).])
+])
+CONFIG_DEPS="$CONFIG_DEPS ETL"
+
+
+PKG_CHECK_MODULES(LIBXMLPP, libxml++-2.6,[
+ CONFIG_DEPS="$CONFIG_DEPS libxml++-2.6"
+],[
+ PKG_CHECK_MODULES(LIBXMLPP, libxml++-1.0,[
+ CONFIG_DEPS="$CONFIG_DEPS libxml++-1.0"
+ ],[
+ AC_MSG_ERROR([ ** You need to install libxml++, either verison 2.6 or 1.0.])
+ ])
+])
+
+PKG_CHECK_MODULES(LIBSIGC, [sigc++-2.0],,[
+ AC_MSG_ERROR([ ** libsigc++-2.0 not found. It is required. You should really install it.])
+dnl PKG_CHECK_MODULES(LIBSIGC, [sigc++-1.2],,[
+dnl AC_MSG_ERROR([ ** At least libsigc++-1.2 is required.])
+dnl ])
+])
+CONFIG_DEPS="$CONFIG_DEPS sigc++-2.0"
+
+dnl PKG_CHECK_MODULES(GLIB, glib-2.0,[GLIB="yes"],[GLIB="no"])
+
+
+
+
+
+TARGET_TIF="yes"
+TARGET_PNG="yes"
+TARGET_MNG="no"
+TARGET_JPEG="yes"
+
+if test "$TARGET_TIF" != "disabled" ; then
+AC_CHECK_LIB(tiff, TIFFClose,[
+ TIF_LIBS="-ltiff"
+ AC_DEFINE(HAVE_LIBTIFF,[], [ Define if TIFF library is available ] )
+ AC_SUBST(TIF_LIBS)
+ AM_CONDITIONAL(HAVE_LIBTIFF,true)
+],[
+ AC_MSG_RESULT([ *** TIFF Output target disabled])
+ TARGET_TIF="no"
+ AM_CONDITIONAL(HAVE_LIBTIFF,false)
+])
+fi
+
+AC_CHECK_LIB(png, png_write_row,[
+ PNG_LIBS="-lpng"
+ AC_DEFINE(HAVE_LIBPNG,[], [ Define if PNG library is available ] )
+ AC_SUBST(PNG_LIBS)
+ AM_CONDITIONAL(HAVE_LIBPNG,true)
+],[
+ AC_CHECK_LIB(png12, png_write_row,[
+ PNG_LIBS="-lpng12"
+ AC_DEFINE(HAVE_LIBPNG,[])
+ AC_SUBST(PNG_LIBS)
+ AM_CONDITIONAL(HAVE_LIBPNG,true)
+ ],[
+ AC_MSG_RESULT([ *** PNG Output target disabled])
+ TARGET_PNG="no"
+ AM_CONDITIONAL(HAVE_LIBPNG,false)
+ ],[-lz -L${exec_prefix}/lib])
+],[-lz -L${exec_prefix}/lib])
+
+#AC_CHECK_LIB(mng, mng_initialize,[
+# MNG_LIBS="-lmng -lz"
+# AC_DEFINE(HAVE_LIBMNG,[], [ Define if MNG library is available ] )
+# AC_SUBST(MNG_LIBS)
+# AM_CONDITIONAL(HAVE_LIBMNG,true)
+#],[
+# AC_MSG_RESULT([ *** MNG Output target disabled])
+# TARGET_MNG="no"
+# AM_CONDITIONAL(HAVE_LIBMNG,false)
+#],[-lz -L${exec_prefix}/lib])
+
+AC_CHECK_LIB(jpeg, main,[
+ JPEG_LIBS="-ljpeg"
+ AC_DEFINE(HAVE_LIBJPEG,[], [ Define if JPEG library is available ] )
+ AC_SUBST(JPEG_LIBS)
+ AM_CONDITIONAL(HAVE_LIBJPEG,true)
+],[
+ AC_MSG_RESULT([ *** JPEG Output target disabled])
+ TARGET_JPEG="no"
+ AM_CONDITIONAL(HAVE_LIBJPEG,false)
+],[-L${exec_prefix}/lib])
+
+
+dnl AC_CHECK_HEADERS(jpeglib.h,[],[
+dnl AC_MSG_RESULT([ *** JPEG Output target disabled])
+dnl TARGET_JPEG="no"
+dnl AM_CONDITIONAL(HAVE_LIBJPEG,false)
+dnl ])
+
+
+
+MODULE_DIR='${libdir}/synfig/modules'
+moduledir=$libdir/synfig/modules
+AC_SUBST(MODULE_DIR)
+SYNFIGLIB_DIR=$libdir/synfig
+AC_SUBST(SYNFIGLIB_DIR)
+
+
+
+
+
+CXXFLAGS="$CXXFLAGS -fpermissive"
+
+AC_CHECK_HEADERS(signal.h termios.h sys/errno.h)
+
+
+case "$host" in
+ *mingw* | *cygwin*)
+ AM_CONDITIONAL(WIN32_PKG, true)
+ AM_CONDITIONAL(MACOSX_PKG, false)
+ ;;
+ *darwin*)
+ AM_CONDITIONAL(WIN32_PKG, false)
+ AM_CONDITIONAL(MACOSX_PKG, true)
+ ;;
+ *)
+ AM_CONDITIONAL(WIN32_PKG, false)
+ AM_CONDITIONAL(MACOSX_PKG, false)
+ ;;
+esac
+
+
+
+# -- H E A D E R S --------------------------------------------
+
+# -- T Y P E S & S T R U C T S --------------------------------
+
+# -- F U N C T I O N S ----------------------------------------
+
+dnl AC_CHECK_FUNCS([floor pow sqrt],[],[
+dnl AC_MSG_ERROR([ ** Could not find proper math functions.])
+dnl ])
+
+AC_CHECK_FUNCS([fork])
+AC_CHECK_FUNCS([kill])
+AC_CHECK_FUNCS([pipe])
+
+AC_CHECK_FUNCS(
+ [isnan],
+ [],
+ [
+ AC_CHECK_FUNCS(
+ [_isnan]
+ )
+ ]
+)
+
+AC_CHECK_FUNCS(
+ [isnanf],
+ [],
+ [
+ AC_CHECK_FUNCS(
+ [_isnanf]
+ )
+ ]
+)
+
+AC_CHECK_FUNCS(
+ [floorl],
+ [],
+ [
+ AC_CHECK_FUNCS(
+ [_floorl]
+ )
+ ]
+)
+
+AC_CHECK_LIB([pthread],[pthread_create])
+
+# -- O U T P U T ----------------------------------------------
+
+AC_SUBST(CFLAGS)
+AC_SUBST(CXXFLAGS)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(LDFLAGS)
+
+VERSION_MAJ=@VERSION_MAJ@
+VERSION_MIN=@VERSION_MIN@
+VERSION_REV=@VERSION_REV@
+AC_SUBST(VERSION_MAJ)
+AC_SUBST(VERSION_MIN)
+AC_SUBST(VERSION_REV)
+
+dnl AC_CONFIG_SUBDIRS(libltdl)
+
+CONFIG_LIBS="-lsynfig"
+CONFIG_CFLAGS="$CONFIG_CFLAGS"
+AC_SUBST(CONFIG_LIBS)
+AC_SUBST(CONFIG_CFLAGS)
+AC_SUBST(CONFIG_DEPS)
+AC_SUBST(ETL_CFLAGS)
+
+SYNFIG_LIBS="$VIMAGE_LIBS $LIBXMLPP_LIBS $ETL_LIBS $LIBSIGC_LIBS"
+SYNFIG_CFLAGS="$LIBXMLPP_CFLAGS $ETL_CFLAGS $LIBSIGC_CFLAGS $CONFIG_CFLAGS -DSYNFIG_NO_DEPRECATED"
+
+CONFIG_CFLAGS="`echo $CONFIG_CFLAGS | sed s/-mno-cygwin//g | sed s/-mwindows//g`"
+SYNFIG_CFLAGS="`echo $SYNFIG_CFLAGS | sed s/-mno-cygwin//g | sed s/-mwindows//g`"
+SYNFIG_LIBS="`echo $SYNFIG_LIBS | sed s/-mno-cygwin//g | sed s/-mwindows//g`"
+
+AC_SUBST(LIBADD_DL)
+
+AC_SUBST(SYNFIG_LIBS)
+AC_SUBST(SYNFIG_CFLAGS)
+AC_SUBST(OPENEXR_HALF_LIBS)
+
+AC_SUBST(API_VERSION)
+
+synfigincludedir=$includedir/synfig-@API_VERSION@
+AC_SUBST(synfigincludedir)
+
+[(
+ [ -d libltdl ] || mkdir libltdl;
+ cd libltdl;
+
+ echo
+ echo pwd: `pwd`
+ echo ../$srcdir/libltdl/configure $ac_configure_args "'--srcdir="../$srcdir/libltdl"'" --with-auxdir=../$srcdir/config "'CFLAGS=$CFLAGS'" "'LDFLAGS=$LDFLAGS'" "'CC=$CC'" "'CPP=$CPP'" "'CPPFLAGS=$CPPFLAGS'" --disable-shared --enable-static
+ echo ../$srcdir/libltdl/configure $ac_configure_args "'--srcdir="../$srcdir/libltdl"'" --with-auxdir=../$srcdir/config "'CFLAGS=$CFLAGS'" "'LDFLAGS=$LDFLAGS'" "'CC=$CC'" "'CPP=$CPP'" "'CPPFLAGS=$CPPFLAGS'" --disable-shared --enable-static | sh
+
+)]
+
+# src/modules/mod_mng/Makefile
+
+AC_OUTPUT(
+synfig-config
+@PACKAGE_TARNAME@.pc
+Makefile
+src/Makefile
+src/synfig/Makefile
+src/modules/Makefile
+src/modules/mod_filter/Makefile
+src/modules/mod_bmp/Makefile
+src/modules/mod_gif/Makefile
+src/modules/mod_ppm/Makefile
+src/modules/mod_png/Makefile
+src/modules/mod_jpeg/Makefile
+src/modules/lyr_std/Makefile
+src/modules/mod_geometry/Makefile
+src/modules/mod_gradient/Makefile
+src/modules/mod_noise/Makefile
+src/modules/lyr_freetype/Makefile
+src/modules/mod_ffmpeg/Makefile
+src/modules/mod_dv/Makefile
+src/modules/mod_imagemagick/Makefile
+src/modules/mod_openexr/Makefile
+src/modules/mod_libavcodec/Makefile
+src/modules/mod_yuv420p/Makefile
+src/modules/mod_particle/Makefile
+src/tool/Makefile
+src/modules/synfig_modules.cfg
+examples/walk/Makefile
+examples/Makefile
+win32inst.nsi
+pkg-info/macosx/synfig-core.info
+dnl src/modules/trgt_mpg/Makefile
+dnl src/modules/mptr_mplayer/Makefile
+)
+
+# -- S U M M A R Y --------------------------------------------
+
+echo "
+$PACKAGE_NAME v.$VERSION
+Configuration Summary
+- - - - - -
+
+Install Prefix -------------------> $prefix
+Module directory -----------------> $moduledir
+Build Platform -------------------> $build
+Host Platform --------------------> $host
+Time Limit -----------------------> $death_time
+Arc Profiling --------------------> $profile_arcs
+GProf Profiling ------------------> $profiling
+Debug Mode -----------------------> $debug ($debug_flags)
+Optimization ---------------------> $optimization
+PNG output target support --------> $TARGET_PNG
+MNG output target support --------> $TARGET_MNG
+TIFF output target support -------> $TARGET_TIF
+JPEG output target support -------> $TARGET_JPEG
+ETL_CFLAGS -----------------------> $ETL_CFLAGS
+FreeType2 ------------------------> $with_freetype
+fontconfig -----------------------> $with_fontconfig
+libavcodec -----------------------> $with_libavcodec
+vImage ---------------------------> $with_vimage
+ImageMagick ----------------------> $with_imagemagick
+FFMPEG ---------------------------> $with_ffmpeg
+libdv ----------------------------> $with_libdv
+OpenEXR --------------------------> $with_openexr
+Using OpenEXR's \"half\" type ------> $use_openexr_half
+
+"'$'"CXX -----------------------------> '$CXX'
+"'$'"CXXFLAGS ------------------------> '$CXXFLAGS'
+"'$'"SYNFIG_LIBS ---------------------> '$SYNFIG_LIBS'
+"'$'"LIBXMLPP_LIBS -------------------> '$LIBXMLPP_LIBS'
+"'$'"ETL_LIBS ------------------------> '$ETL_LIBS'
+"'$'"LIBSIGC_LIBS --------------------> '$LIBSIGC_LIBS'
+"'$'"SYNFIG_CFLAGS -------------------> '$SYNFIG_CFLAGS'
+"'$'"LIBADD_DL -----------------------> '$LIBADD_DL'
+"
--- /dev/null
+AC_DEFUN([AC_CXX_FUNCTION_NONTYPE_PARAMETERS],
+[AC_CACHE_CHECK(whether the compiler supports function templates with non-type parameters,
+ac_cv_cxx_function_nontype_parameters,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([
+template<class T, int N> class A {};
+template<class T, int N> int f(const A<T,N>& x) { return 0; }
+],[A<double, 17> z; return f(z);],
+ ac_cv_cxx_function_nontype_parameters=yes, ac_cv_cxx_function_nontype_parameters=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_function_nontype_parameters" = yes; then
+ AC_DEFINE(HAVE_FUNCTION_NONTYPE_PARAMETERS,,
+ [define if the compiler supports function templates with non-type parameters])
+fi
+])
+
+AC_DEFUN([AC_CXX_NAMESPACES],
+[AC_CACHE_CHECK(whether the compiler implements namespaces,
+ac_cv_cxx_namespaces,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([namespace Outer { namespace Inner { int i = 0; }}],
+ [using namespace Outer::Inner; return i;],
+ ac_cv_cxx_namespaces=yes, ac_cv_cxx_namespaces=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_namespaces" = yes; then
+ AC_DEFINE(HAVE_NAMESPACES,,[define if the compiler implements namespaces])
+fi
+])
+
+AC_DEFUN([AC_CXX_HAVE_COMPLEX],
+[AC_CACHE_CHECK(whether the compiler has complex<T>,
+ac_cv_cxx_have_complex,
+[AC_REQUIRE([AC_CXX_NAMESPACES])
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <complex>
+#ifdef HAVE_NAMESPACES
+using namespace std;
+#endif],[complex<float> a; complex<double> b; return 0;],
+ ac_cv_cxx_have_complex=yes, ac_cv_cxx_have_complex=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_have_complex" = yes; then
+ AC_DEFINE(HAVE_COMPLEX,,[define if the compiler has complex<T>])
+fi
+])
+
+AC_DEFUN([AC_CXX_HAVE_SSTREAM],
+[AC_CACHE_CHECK(whether the compiler has stringstream,
+ac_cv_cxx_have_sstream,
+[AC_REQUIRE([AC_CXX_NAMESPACES])
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <sstream>
+#ifdef HAVE_NAMESPACES
+using namespace std;
+#endif],[stringstream message; message << "Hello"; return 0;],
+ ac_cv_cxx_have_sstream=yes, ac_cv_cxx_have_sstream=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_have_sstream" = yes; then
+ AC_DEFINE(HAVE_SSTREAM,,[define if the compiler has stringstream])
+fi
+])
+
+AC_DEFUN([AC_CXX_MUTABLE],
+[AC_CACHE_CHECK(whether the compiler supports the mutable keyword,
+ac_cv_cxx_mutable,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([
+class A { mutable int i;
+ public:
+ int f (int n) const { i = n; return i; }
+ };
+],[A a; return a.f (1);],
+ ac_cv_cxx_mutable=yes, ac_cv_cxx_mutable=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_mutable" = yes; then
+ AC_DEFINE(HAVE_MUTABLE,,[define if the compiler supports the mutable keyword])
+fi
+])
+
--- /dev/null
+# Doxyfile 1.4.6
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = @PACKAGE@
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = @VERSION@
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = doc
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES = "legal=\if legal" \
+ endlegal=\endif \
+ "writeme=\todo This needs to be documented further." \
+ "stub=\todo This is a non-functional stub." \
+ "optimize=\todo This needs to be optimized further."
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
+# include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = YES
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = NO
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = src/synfig
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS = *.h \
+ *.hxx \
+ *.hpp \
+ *.cpp \
+ *.cxx
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = SYNFIG_NO_DEPRECATED \
+ DOXYGEN_SKIP
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = gif
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that a graph may be further truncated if the graph's
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default),
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
--- /dev/null
+# Configure paths for FreeType2
+# Marcelo Magallon 2001-10-26, based on gtk.m4 by Owen Taylor
+
+dnl AC_CHECK_FT2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for FreeType2, and define FT2_CFLAGS and FT2_LIBS
+dnl
+AC_DEFUN([AC_CHECK_FT2],
+[dnl
+dnl Get the cflags and libraries from the freetype-config script
+dnl
+AC_ARG_WITH(ft-prefix,
+[ --with-ft-prefix=PREFIX
+ Prefix where FreeType is installed (optional)],
+ ft_config_prefix="$withval", ft_config_prefix="")
+AC_ARG_WITH(ft-exec-prefix,
+[ --with-ft-exec-prefix=PREFIX
+ Exec prefix where FreeType is installed (optional)],
+ ft_config_exec_prefix="$withval", ft_config_exec_prefix="")
+AC_ARG_ENABLE(freetypetest,
+[ --disable-freetypetest Do not try to compile and run
+ a test FreeType program],
+ [], enable_fttest=yes)
+
+if test x$ft_config_exec_prefix != x ; then
+ ft_config_args="$ft_config_args --exec-prefix=$ft_config_exec_prefix"
+ if test x${FT2_CONFIG+set} != xset ; then
+ FT2_CONFIG=$ft_config_exec_prefix/bin/freetype-config
+ fi
+fi
+if test x$ft_config_prefix != x ; then
+ ft_config_args="$ft_config_args --prefix=$ft_config_prefix"
+ if test x${FT2_CONFIG+set} != xset ; then
+ FT2_CONFIG=$ft_config_prefix/bin/freetype-config
+ fi
+fi
+AC_PATH_PROG(FT2_CONFIG, freetype-config, no)
+
+min_ft_version=ifelse([$1], ,6.1.0,$1)
+AC_MSG_CHECKING(for FreeType - version >= $min_ft_version)
+no_ft=""
+if test "$FT2_CONFIG" = "no" ; then
+ no_ft=yes
+else
+ FT2_CFLAGS=`$FT2_CONFIG $ft_config_args --cflags`
+ FT2_LIBS=`$FT2_CONFIG $ft_config_args --libs`
+ ft_config_major_version=`$FT2_CONFIG $ft_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+ ft_config_minor_version=`$FT2_CONFIG $ft_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+ ft_config_micro_version=`$FT2_CONFIG $ft_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+ ft_min_major_version=`echo $min_ft_version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+ ft_min_minor_version=`echo $min_ft_version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+ ft_min_micro_version=`echo $min_ft_version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+ if test x$enable_fttest = xyes ; then
+ ft_config_is_lt=""
+ if test $ft_config_major_version -lt $ft_min_major_version ; then
+ ft_config_is_lt=yes
+ else
+ if test $ft_config_major_version -eq $ft_min_major_version ; then
+ if test $ft_config_minor_version -lt $ft_min_minor_version ; then
+ ft_config_is_lt=yes
+ else
+ if test $ft_config_minor_version -eq $ft_min_minor_version ; then
+ if test $ft_config_micro_version -lt $ft_min_micro_version ; then
+ ft_config_is_lt=yes
+ fi
+ fi
+ fi
+ fi
+ fi
+ if test x$ft_config_is_lt = xyes ; then
+ no_ft=yes
+ else
+ ac_save_CFLAGS="$CFLAGS"
+ ac_save_CXXFLAGS="$CFLAGS"
+ ac_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $FT2_CFLAGS"
+ CXXFLAGS="$CXXFLAGS $FT2_CFLAGS"
+ LIBS="$FT2_LIBS $LIBS"
+dnl
+dnl Sanity checks for the results of freetype-config to some extent
+dnl
+ AC_TRY_RUN([
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main()
+{
+ FT_Library library;
+ FT_Error error;
+
+ error = FT_Init_FreeType(&library);
+
+ if (error)
+ return 1;
+ else
+ {
+ FT_Done_FreeType(library);
+ return 0;
+ }
+}
+],, no_ft=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+ CFLAGS="$ac_save_CFLAGS"
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi # test $ft_config_version -lt $ft_min_version
+ fi # test x$enable_fttest = xyes
+fi # test "$FT2_CONFIG" = "no"
+if test x$no_ft = x ; then
+ AC_MSG_RESULT(yes)
+ ifelse([$2], , :, [$2])
+else
+ AC_MSG_RESULT(no)
+ if test "$FT2_CONFIG" = "no" ; then
+ echo "*** The freetype-config script installed by FreeType 2 could not be found."
+ echo "*** If FreeType 2 was installed in PREFIX, make sure PREFIX/bin is in"
+ echo "*** your path, or set the FT2_CONFIG environment variable to the"
+ echo "*** full path to freetype-config."
+ else
+ if test x$ft_config_is_lt = xyes ; then
+ echo "*** Your installed version of the FreeType 2 library is too old."
+ echo "*** If you have different versions of FreeType 2, make sure that"
+ echo "*** correct values for --with-ft-prefix or --with-ft-exec-prefix"
+ echo "*** are used, or set the FT2_CONFIG environment variable to the"
+ echo "*** full path to freetype-config."
+ else
+ echo "*** The FreeType test program failed to run. If your system uses"
+ echo "*** shared libraries and they are installed outside the normal"
+ echo "*** system library path, make sure the variable LD_LIBRARY_PATH"
+ echo "*** (or whatever is appropiate for your system) is correctly set."
+ fi
+ fi
+ FT2_CFLAGS=""
+ FT2_LIBS=""
+ ifelse([$3], , :, [$3])
+fi
+AC_SUBST(FT2_CFLAGS)
+AC_SUBST(FT2_LIBS)
+])
--- /dev/null
+dnl AC_LIBXMLPP([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+
+AC_DEFUN([AM_LIBXMLPP],
+[
+
+AC_PATH_PROG(XMLPP_CONFIG,xml++-config,no)
+
+AC_MSG_CHECKING(for libxml++)
+
+if $XMLPP_CONFIG --libs print > /dev/null 2>&1; then
+ AC_MSG_RESULT(yes)
+ LIBXMLPP_CFLAGS=`xml++-config --cflags`
+ LIBXMLPP_LIBS=`xml++-config --libs`
+ AC_SUBST(LIBXMLPP_CFLAGS)
+ AC_SUBST(LIBXMLPP_LIBS)
+ ifelse([$1], , :, [$1])
+else
+ AC_MSG_RESULT(no)
+ ifelse([$2], , , [$2])
+fi
+
+])
+
--- /dev/null
+# Configure paths for LIBXML2
+# Toshio Kuratomi 2001-04-21
+# Adapted from:
+# Configure paths for GLIB
+# Owen Taylor 97-11-3
+
+dnl AM_PATH_XML([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for XML, and define XML_CFLAGS and XML_LIBS
+dnl
+AC_DEFUN([AM_PATH_XML],[
+AC_ARG_WITH(xml-prefix,
+ [ --with-xml-prefix=PFX Prefix where libxml is installed (optional)],
+ xml_config_prefix="$withval", xml_config_prefix="")
+AC_ARG_WITH(xml-exec-prefix,
+ [ --with-xml-exec-prefix=PFX Exec prefix where libxml is installed (optional)],
+ xml_config_exec_prefix="$withval", xml_config_exec_prefix="")
+AC_ARG_ENABLE(xmltest,
+ [ --disable-xmltest Do not try to compile and run a test LIBXML program],,
+ enable_xmltest=yes)
+
+ if test x$xml_config_exec_prefix != x ; then
+ xml_config_args="$xml_config_args --exec-prefix=$xml_config_exec_prefix"
+ if test x${XML_CONFIG+set} != xset ; then
+ XML_CONFIG=$xml_config_exec_prefix/bin/xml-config
+ fi
+ fi
+ if test x$xml_config_prefix != x ; then
+ xml_config_args="$xml_config_args --prefix=$xml_config_prefix"
+ if test x${XML_CONFIG+set} != xset ; then
+ XML_CONFIG=$xml_config_prefix/bin/xml-config
+ fi
+ fi
+
+ AC_PATH_PROG(XML_CONFIG, xml-config, no)
+ min_xml_version=ifelse([$1], ,1.0.0,[$1])
+ AC_MSG_CHECKING(for libxml - version >= $min_xml_version)
+ no_xml=""
+ if test "$XML_CONFIG" = "no" ; then
+ no_xml=yes
+ else
+ XML_CFLAGS=`$XML_CONFIG $xml_config_args --cflags`
+ XML_LIBS=`$XML_CONFIG $xml_config_args --libs`
+ xml_config_major_version=`$XML_CONFIG $xml_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+ xml_config_minor_version=`$XML_CONFIG $xml_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+ xml_config_micro_version=`$XML_CONFIG $xml_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+ if test "x$enable_xmltest" = "xyes" ; then
+ ac_save_CFLAGS="$CFLAGS"
+ ac_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $XML_CFLAGS"
+ LIBS="$XML_LIBS $LIBS"
+dnl
+dnl Now check if the installed libxml is sufficiently new.
+dnl (Also sanity checks the results of xml-config to some extent)
+dnl
+ rm -f conf.xmltest
+ AC_TRY_RUN([
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <libxml/tree.h>
+
+int
+main()
+{
+ int xml_major_version, xml_minor_version, xml_micro_version;
+ int major, minor, micro;
+ char *tmp_version;
+ int tmp_int_version;
+
+ system("touch conf.xmltest");
+
+ /* Capture xml-config output via autoconf/configure variables */
+ /* HP/UX 9 (%@#!) writes to sscanf strings */
+ tmp_version = (char *)strdup("$min_xml_version");
+ if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) {
+ printf("%s, bad version string from xml-config\n", "$min_xml_version");
+ exit(1);
+ }
+ free(tmp_version);
+
+ /* Capture the version information from the header files */
+ tmp_int_version = LIBXML_VERSION;
+ xml_major_version=tmp_int_version / 10000;
+ xml_minor_version=(tmp_int_version - xml_major_version * 10000) / 100;
+ xml_micro_version=(tmp_int_version - xml_minor_version * 100 - xml_major_version * 10000);
+
+ /* Compare xml-config output to the libxml headers */
+ if ((xml_major_version != $xml_config_major_version) ||
+ (xml_minor_version != $xml_config_minor_version)
+#if 0
+ ||
+/* The last released version of libxml-1.x has an incorrect micro version in
+ * the header file so neither the includes nor the library will match the
+ * micro_version to the output of xml-config
+ */
+ (xml_micro_version != $xml_config_micro_version)
+#endif
+ )
+
+ {
+ printf("*** libxml header files (version %d.%d.%d) do not match\n",
+ xml_major_version, xml_minor_version, xml_micro_version);
+ printf("*** xml-config (version %d.%d.%d)\n",
+ $xml_config_major_version, $xml_config_minor_version, $xml_config_micro_version);
+ return 1;
+ }
+/* Compare the headers to the library to make sure we match */
+ /* Less than ideal -- doesn't provide us with return value feedback,
+ * only exits if there's a serious mismatch between header and library.
+ */
+ LIBXML_TEST_VERSION;
+
+ /* Test that the library is greater than our minimum version */
+ if (($xml_config_major_version > major) ||
+ (($xml_config_major_version == major) && ($xml_config_minor_version > minor)) ||
+ (($xml_config_major_version == major) && ($xml_config_minor_version == minor) &&
+ ($xml_config_micro_version >= micro)))
+ {
+ return 0;
+ }
+ else
+ {
+ printf("\n*** An old version of libxml (%d.%d.%d) was found.\n",
+ xml_major_version, xml_minor_version, xml_micro_version);
+ printf("*** You need a version of libxml newer than %d.%d.%d. The latest version of\n",
+ major, minor, micro);
+ printf("*** libxml is always available from ftp://ftp.xmlsoft.org.\n");
+ printf("***\n");
+ printf("*** If you have already installed a sufficiently new version, this error\n");
+ printf("*** probably means that the wrong copy of the xml-config shell script is\n");
+ printf("*** being found. The easiest way to fix this is to remove the old version\n");
+ printf("*** of LIBXML, but you can also set the XML_CONFIG environment to point to the\n");
+ printf("*** correct copy of xml-config. (In this case, you will have to\n");
+ printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+ printf("*** so that the correct libraries are found at run-time))\n");
+ }
+ return 1;
+}
+],, no_xml=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+
+ if test "x$no_xml" = x ; then
+ AC_MSG_RESULT(yes (version $xml_config_major_version.$xml_config_minor_version.$xml_config_micro_version))
+ ifelse([$2], , :, [$2])
+ else
+ AC_MSG_RESULT(no)
+ if test "$XML_CONFIG" = "no" ; then
+ echo "*** The xml-config script installed by LIBXML could not be found"
+ echo "*** If libxml was installed in PREFIX, make sure PREFIX/bin is in"
+ echo "*** your path, or set the XML_CONFIG environment variable to the"
+ echo "*** full path to xml-config."
+ else
+ if test -f conf.xmltest ; then
+ :
+ else
+ echo "*** Could not run libxml test program, checking why..."
+ CFLAGS="$CFLAGS $XML_CFLAGS"
+ LIBS="$LIBS $XML_LIBS"
+ AC_TRY_LINK([
+#include <libxml/tree.h>
+#include <stdio.h>
+], [ LIBXML_TEST_VERSION; return 0;],
+ [ echo "*** The test program compiled, but did not run. This usually means"
+ echo "*** that the run-time linker is not finding LIBXML or finding the wrong"
+ echo "*** version of LIBXML. If it is not finding LIBXML, you'll need to set your"
+ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+ echo "*** to the installed location Also, make sure you have run ldconfig if that"
+ echo "*** is required on your system"
+ echo "***"
+ echo "*** If you have an old version installed, it is best to remove it, although"
+ echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ],
+ [ echo "*** The test program failed to compile or link. See the file config.log for the"
+ echo "*** exact error that occured. This usually means LIBXML was incorrectly installed"
+ echo "*** or that you have moved LIBXML since it was installed. In the latter case, you"
+ echo "*** may want to edit the xml-config script: $XML_CONFIG" ])
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+
+ XML_CFLAGS=""
+ XML_LIBS=""
+ ifelse([$3], , :, [$3])
+ fi
+ AC_SUBST(XML_CFLAGS)
+ AC_SUBST(XML_LIBS)
+ rm -f conf.xmltest
+])
+
+# Configure paths for LIBXML2
+# Toshio Kuratomi 2001-04-21
+# Adapted from:
+# Configure paths for GLIB
+# Owen Taylor 97-11-3
+
+dnl AM_PATH_XML2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for XML, and define XML_CFLAGS and XML_LIBS
+dnl
+AC_DEFUN([AM_PATH_XML2],[
+AC_ARG_WITH(xml-prefix,
+ [ --with-xml-prefix=PFX Prefix where libxml is installed (optional)],
+ xml_config_prefix="$withval", xml_config_prefix="")
+AC_ARG_WITH(xml-exec-prefix,
+ [ --with-xml-exec-prefix=PFX Exec prefix where libxml is installed (optional)],
+ xml_config_exec_prefix="$withval", xml_config_exec_prefix="")
+AC_ARG_ENABLE(xmltest,
+ [ --disable-xmltest Do not try to compile and run a test LIBXML program],,
+ enable_xmltest=yes)
+
+ if test x$xml_config_exec_prefix != x ; then
+ xml_config_args="$xml_config_args --exec-prefix=$xml_config_exec_prefix"
+ if test x${XML2_CONFIG+set} != xset ; then
+ XML2_CONFIG=$xml_config_exec_prefix/bin/xml2-config
+ fi
+ fi
+ if test x$xml_config_prefix != x ; then
+ xml_config_args="$xml_config_args --prefix=$xml_config_prefix"
+ if test x${XML2_CONFIG+set} != xset ; then
+ XML2_CONFIG=$xml_config_prefix/bin/xml2-config
+ fi
+ fi
+
+ AC_PATH_PROG(XML2_CONFIG, xml2-config, no)
+ min_xml_version=ifelse([$1], ,2.0.0,[$1])
+ AC_MSG_CHECKING(for libxml - version >= $min_xml_version)
+ no_xml=""
+ if test "$XML2_CONFIG" = "no" ; then
+ no_xml=yes
+ else
+ XML_CFLAGS=`$XML2_CONFIG $xml_config_args --cflags`
+ XML_LIBS=`$XML2_CONFIG $xml_config_args --libs`
+ xml_config_major_version=`$XML2_CONFIG $xml_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+ xml_config_minor_version=`$XML2_CONFIG $xml_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+ xml_config_micro_version=`$XML2_CONFIG $xml_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+ if test "x$enable_xmltest" = "xyes" ; then
+ ac_save_CFLAGS="$CFLAGS"
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ ac_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $XML_CFLAGS"
+ CXXFLAGS="$CXXFLAGS $XML_CFLAGS"
+ LIBS="$XML_LIBS $LIBS"
+dnl
+dnl Now check if the installed libxml is sufficiently new.
+dnl (Also sanity checks the results of xml2-config to some extent)
+dnl
+ rm -f conf.xmltest
+ AC_TRY_RUN([
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <libxml/xmlversion.h>
+
+int
+main()
+{
+ int xml_major_version, xml_minor_version, xml_micro_version;
+ int major, minor, micro;
+ char *tmp_version;
+
+ system("touch conf.xmltest");
+
+ /* Capture xml2-config output via autoconf/configure variables */
+ /* HP/UX 9 (%@#!) writes to sscanf strings */
+ tmp_version = (char *)strdup("$min_xml_version");
+ if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) {
+ printf("%s, bad version string from xml2-config\n", "$min_xml_version");
+ exit(1);
+ }
+ free(tmp_version);
+
+ /* Capture the version information from the header files */
+ tmp_version = (char *)strdup(LIBXML_DOTTED_VERSION);
+ if (sscanf(tmp_version, "%d.%d.%d", &xml_major_version, &xml_minor_version, &xml_micro_version) != 3) {
+ printf("%s, bad version string from libxml includes\n", "LIBXML_DOTTED_VERSION");
+ exit(1);
+ }
+ free(tmp_version);
+
+ /* Compare xml2-config output to the libxml headers */
+ if ((xml_major_version != $xml_config_major_version) ||
+ (xml_minor_version != $xml_config_minor_version) ||
+ (xml_micro_version != $xml_config_micro_version))
+ {
+ printf("*** libxml header files (version %d.%d.%d) do not match\n",
+ xml_major_version, xml_minor_version, xml_micro_version);
+ printf("*** xml2-config (version %d.%d.%d)\n",
+ $xml_config_major_version, $xml_config_minor_version, $xml_config_micro_version);
+ return 1;
+ }
+/* Compare the headers to the library to make sure we match */
+ /* Less than ideal -- doesn't provide us with return value feedback,
+ * only exits if there's a serious mismatch between header and library.
+ */
+ LIBXML_TEST_VERSION;
+
+ /* Test that the library is greater than our minimum version */
+ if ((xml_major_version > major) ||
+ ((xml_major_version == major) && (xml_minor_version > minor)) ||
+ ((xml_major_version == major) && (xml_minor_version == minor) &&
+ (xml_micro_version >= micro)))
+ {
+ return 0;
+ }
+ else
+ {
+ printf("\n*** An old version of libxml (%d.%d.%d) was found.\n",
+ xml_major_version, xml_minor_version, xml_micro_version);
+ printf("*** You need a version of libxml newer than %d.%d.%d. The latest version of\n",
+ major, minor, micro);
+ printf("*** libxml is always available from ftp://ftp.xmlsoft.org.\n");
+ printf("***\n");
+ printf("*** If you have already installed a sufficiently new version, this error\n");
+ printf("*** probably means that the wrong copy of the xml2-config shell script is\n");
+ printf("*** being found. The easiest way to fix this is to remove the old version\n");
+ printf("*** of LIBXML, but you can also set the XML2_CONFIG environment to point to the\n");
+ printf("*** correct copy of xml2-config. (In this case, you will have to\n");
+ printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+ printf("*** so that the correct libraries are found at run-time))\n");
+ }
+ return 1;
+}
+],, no_xml=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+ CFLAGS="$ac_save_CFLAGS"
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+
+ if test "x$no_xml" = x ; then
+ AC_MSG_RESULT(yes (version $xml_config_major_version.$xml_config_minor_version.$xml_config_micro_version))
+ ifelse([$2], , :, [$2])
+ else
+ AC_MSG_RESULT(no)
+ if test "$XML2_CONFIG" = "no" ; then
+ echo "*** The xml2-config script installed by LIBXML could not be found"
+ echo "*** If libxml was installed in PREFIX, make sure PREFIX/bin is in"
+ echo "*** your path, or set the XML2_CONFIG environment variable to the"
+ echo "*** full path to xml2-config."
+ else
+ if test -f conf.xmltest ; then
+ :
+ else
+ echo "*** Could not run libxml test program, checking why..."
+ CFLAGS="$CFLAGS $XML_CFLAGS"
+ CXXFLAGS="$CXXFLAGS $XML_CFLAGS"
+ LIBS="$LIBS $XML_LIBS"
+ AC_TRY_LINK([
+#include <libxml/xmlversion.h>
+#include <stdio.h>
+], [ LIBXML_TEST_VERSION; return 0;],
+ [ echo "*** The test program compiled, but did not run. This usually means"
+ echo "*** that the run-time linker is not finding LIBXML or finding the wrong"
+ echo "*** version of LIBXML. If it is not finding LIBXML, you'll need to set your"
+ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+ echo "*** to the installed location Also, make sure you have run ldconfig if that"
+ echo "*** is required on your system"
+ echo "***"
+ echo "*** If you have an old version installed, it is best to remove it, although"
+ echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ],
+ [ echo "*** The test program failed to compile or link. See the file config.log for the"
+ echo "*** exact error that occured. This usually means LIBXML was incorrectly installed"
+ echo "*** or that you have moved LIBXML since it was installed. In the latter case, you"
+ echo "*** may want to edit the xml2-config script: $XML2_CONFIG" ])
+ CFLAGS="$ac_save_CFLAGS"
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+
+ XML_CFLAGS=""
+ XML_LIBS=""
+ $3
+
+
+ ifelse([$3], , :, [$3])
+ fi
+ AC_SUBST(XML_CFLAGS)
+ AC_SUBST(XML_LIBS)
+ rm -f conf.xmltest
+])
--- /dev/null
+--- ltmain.bak Thu Apr 7 19:12:55 2005
++++ ltmain.sh Thu Apr 7 19:20:28 2005
+@@ -5362,10 +5362,10 @@
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+- if test "$inst_prefix_dir" = "$destdir"; then
+- $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
+- exit 1
+- fi
++# if test "$inst_prefix_dir" = "$destdir"; then
++# $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
++# exit 1
++# fi
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
--- /dev/null
+#! /bin/csh -ef
+# this file was orignally distributed by Apple in the Developer Tools package
+#it is distributed under the Apple Open Source License
+set version=0.2
+set prog = `/usr/bin/basename $0`
+set usage = "Usage: $prog [-f] root-dir info-file [tiff-file] [-d dest-dir] [-r resource-dir] [-traditional | -gnutar] [-bzip]"
+set noglob
+
+if (-x /usr/bin/mkbom) then
+ set mkbom=/usr/bin/mkbom
+ set lsbom=/usr/bin/lsbom
+else
+ set mkbom=/usr/etc/mkbom
+ set lsbom=/usr/etc/lsbom
+endif
+
+if (-x /usr/bin/awk) then
+ set awk=/usr/bin/awk
+else
+ set awk=/bin/awk
+endif
+set bzip2=`which bzip2`
+set gnutar=/usr/bin/gnutar
+set tar=/usr/bin/tar
+set pax=/bin/pax
+
+# gather parameters
+if ($#argv == 0) then
+ echo $usage
+ exit(1)
+endif
+unset usebzip
+while ( $#argv > 0 )
+ switch ( $argv[1] )
+ case -d:
+ if ( $?destDir ) then
+ echo ${prog}: dest-dir parameter already set to ${destDir}.
+ echo $usage
+ exit(1)
+ else if ( $#argv < 2 ) then
+ echo ${prog}: -d option requires destination directory.
+ echo $usage
+ exit(1)
+ else
+ set destDir = $argv[2]
+ shift; shift
+ breaksw
+ endif
+ case -f:
+ if ( $?rootDir ) then
+ echo ${prog}: root-dir parameter already set to ${rootDir}.
+ echo $usage
+ exit(1)
+ else if ( $#argv < 2 ) then
+ echo ${prog}: -f option requires package root directory.
+ echo $usage
+ exit(1)
+ else
+ set rootDir = $argv[2]
+ set fflag
+ shift; shift
+ breaksw
+ endif
+ case -r:
+ if ( $?resDir ) then
+ echo ${prog}: resource-dir parameter already set to ${resDir}.
+ echo $usage
+ exit(1)
+ else if ( $#argv < 2 ) then
+ echo ${prog}: -r option requires package resource directory.
+ echo $usage
+ exit(1)
+ else
+ set resDir = $argv[2]
+ shift; shift
+ breaksw
+ endif
+ case -traditional:
+ echo useing standard tar
+ set usetar
+ unset usegnutar
+ unset usepax
+ breaksw
+ case -gnutar:
+ echo using gnutar
+ set usegnutar
+ unset usepax
+ unset usetar
+ shift
+ case -bzip:
+ if (-x $bzip2) then
+ set usebzip
+ echo using bzip compression
+ else
+ echo COMPRESSION ERROR: You can not use BZIP2 you do not have it installed
+ exit(1)
+ endif
+ shift
+ breaksw
+ case -*:
+ echo ${prog}: Unknown option: $argv[1]
+ echo $usage
+ exit(1)
+ case *.info:
+ if ( $?info ) then
+ echo ${prog}: info-file parameter already set to ${info}.
+ echo $usage
+ exit(1)
+ else
+ set info = "$argv[1]"
+ shift
+ breaksw
+ endif
+ case *.tiff:
+ if ( $?tiff ) then
+ echo ${prog}: tiff-file parameter already set to ${tiff}.
+ echo $usage
+ exit(1)
+ else
+ set tiff = "$argv[1]"
+ shift
+ breaksw
+ endif
+ default:
+ if ( $?rootDir ) then
+ echo ${prog}: unrecognized parameter: $argv[1]
+ echo $usage
+ exit(1)
+ else
+ set rootDir = "$argv[1]"
+ shift
+ breaksw
+ endif
+ endsw
+end
+
+# check for mandatory parameters
+if ( ! $?rootDir ) then
+ echo ${prog}: missing root-dir parameter.
+ echo $usage
+ exit(1)
+else if ( ! $?info) then
+ echo ${prog}: missing info-file parameter.
+ echo $usage
+ exit(1)
+endif
+
+# destDir gets default value if unset on command line
+if ( $?destDir ) then
+ /bin/mkdir -p $destDir
+else
+ set destDir = .
+endif
+
+# derive the root name for the package from the root name of the info file
+set root = `/usr/bin/basename $info .info`
+
+# create package directory
+set pkg = ${destDir}/${root}.pkg
+echo Generating Installer package $pkg ...
+if ( -e $pkg ) /bin/rm -rf $pkg
+/bin/mkdir -p -m 755 $pkg
+/bin/mkdir -p -m 755 $pkg/Contents
+/bin/mkdir -p -m 755 $pkg/Contents/Resources
+/bin/mkdir -p -m 755 $pkg/Contents/Resources/English.lproj/
+echo "gxpmpkg2" >$pkg/Contents/PkgInfo
+chmod 755 $pkg/Contents/PkgInfo
+# (gnu)tar/pax and compress root directory to package archive
+echo -n " creating package archive ... "
+if ( $?fflag ) then
+ set pkgTop = ${rootDir:t}
+ set parent = ${rootDir:h}
+ if ( "$parent" == "$pkgTop" ) set parent = "."
+else
+ set parent = $rootDir
+ set pkgTop = .
+endif
+if ( $?usetar ) then
+ set pkgArchive = $pkg/Contents/Resources/$root.tar.Z
+ (cd $parent; $tar -w $pkgTop) | /usr/bin/tar -f -c > $pkgArchive
+else if ( $?usegnutar ) then
+ if ( $?usebzip ) then
+ set pkgArchive = $pkg/Contents/Resources/$root.tar.bz2
+ (cd $parent; $gnutar c $pkgTop) | $bzip2 -f -c > $pkgArchive
+ else
+ set pkgArchive = $pkg/Contents/Resources/$root.tar.gz
+ (cd $parent; $gnutar zcf $pkgArchive $pkgTop)
+ endif
+else
+ set pkgArchive = $pkg/Contents/Resources/$root.pax.gz
+ (cd $parent; $pax -w -z -x cpio $pkgTop) > $pkgArchive
+endif
+/bin/chmod 755 $pkgArchive
+echo done.
+
+# copy info file to package
+set pkgInfo = $pkg/Contents/Resources/English.lproj/$root.info
+echo -n " copying ${info:t} ... "
+/bin/cp $info $pkgInfo
+/bin/chmod 755 $pkgInfo
+echo done.
+
+# copy tiff file to package
+if ( $?tiff ) then
+ set pkgTiff = $pkg/$root.tiff
+ echo -n " copying ${tiff:t} ... "
+ /bin/cp $tiff $pkgTiff
+ /bin/chmod 444 $pkgTiff
+ echo done.
+endif
+
+# copy resources to package
+if ( $?resDir ) then
+ echo -n " copying ${resDir:t} ... "
+
+ # don't want to see push/pop output
+ pushd $resDir > /dev/null
+ # get lists of resources. We'll want to change
+ # permissions on just these things later.
+ set directoriesInResDir = `find . -type d | grep -v -e .svn -e CVS`
+ set filesInResDir = `find . -type f`
+ popd > /dev/null
+
+ # copy the resource directory contents into the package directory
+ foreach resFile (`cd $resDir && find . | grep -v -e .svn -e CVS`)
+ cp -r "$resDir/$resFile" "$pkg/Contents/Resources"
+ end
+
+ pushd $pkg/Contents/Resources > /dev/null
+ # Change all directories to +r+x, except the package
+ # directory itself
+ foreach resFileItem ($directoriesInResDir)
+ if ( $resFileItem != "." ) then
+ chmod 755 "$resFileItem"
+ endif
+ end
+ # change all flat files to read only
+ foreach resFileItem ($filesInResDir)
+ if ( $resFileItem != "./.DS_Store" ) then
+ chmod 755 "$resFileItem"
+ endif
+ end
+ popd > /dev/null
+
+ echo done.
+endif
+
+# generate bom file
+set pkgBom = $pkg/Contents/Resources/$root.bom
+echo -n " generating bom file ... "
+/bin/rm -f $pkgBom
+if ( $?fflag ) then
+ $mkbom $parent $pkgBom >& /dev/null
+else
+ $mkbom $rootDir $pkgBom >& /dev/null
+endif
+/bin/chmod 444 $pkgArchive
+echo done.
+
+# generate sizes file
+set pkgSizes = $pkg/Contents/Resources/$root.sizes
+echo -n " generating sizes file ... "
+
+# compute number of files in package
+set numFiles = `$lsbom -s $pkgBom | /usr/bin/wc -l`
+
+# compute package size when compressed
+@ compressedSize = `/usr/bin/du -k -s $pkg | $awk '{print $1}'`
+@ compressedSize += 3 # add 1KB each for sizes, location, status files
+
+@ infoSize = `/bin/ls -s $pkgInfo | $awk '{print $1}'`
+@ bomSize = `/bin/ls -s $pkgBom | $awk '{print $1}'`
+if ( $?tiff ) then
+ @ tiffSize = `/bin/ls -s $pkgTiff | $awk '{print $1}'`
+else
+ @ tiffSize = 0
+endif
+
+@ installedSize = `/usr/bin/du -k -s $rootDir | $awk '{print $1}'`
+@ installedSize += $infoSize + $bomSize + $tiffSize + 3
+
+# echo size parameters to sizes file
+echo NumFiles $numFiles > $pkgSizes
+echo InstalledSize $installedSize >> $pkgSizes
+echo CompressedSize $compressedSize >> $pkgSizes
+echo done.
+echo " ... finished generating $pkg."
+
+exit(0)
+
+# end package
+
--- /dev/null
+
+dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
+dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
+dnl also defines GSTUFF_PKG_ERRORS on error
+AC_DEFUN([PKG_CHECK_MODULES], [
+ succeeded=no
+
+ if test -z "$PKG_CONFIG"; then
+ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+ fi
+
+ if test "$PKG_CONFIG" = "no" ; then
+ echo "*** The pkg-config script could not be found. Make sure it is"
+ echo "*** in your path, or set the PKG_CONFIG environment variable"
+ echo "*** to the full path to pkg-config."
+ echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
+ else
+ PKG_CONFIG_MIN_VERSION=0.9.0
+ if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
+ AC_MSG_CHECKING(for $2)
+
+ if $PKG_CONFIG --exists "$2" ; then
+ AC_MSG_RESULT(yes)
+ succeeded=yes
+
+ AC_MSG_CHECKING($1_CFLAGS)
+ $1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
+ AC_MSG_RESULT($$1_CFLAGS)
+
+ AC_MSG_CHECKING($1_LIBS)
+ $1_LIBS=`$PKG_CONFIG --libs "$2"`
+ AC_MSG_RESULT($$1_LIBS)
+ else
+ $1_CFLAGS=""
+ $1_LIBS=""
+ ## If we have a custom action on failure, don't print errors, but
+ ## do set a variable so people can do so.
+ $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+ ifelse([$4], ,echo $$1_PKG_ERRORS,)
+ fi
+
+ AC_SUBST($1_CFLAGS)
+ AC_SUBST($1_LIBS)
+ else
+ echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
+ echo "*** See http://www.freedesktop.org/software/pkgconfig"
+ fi
+ fi
+
+ if test $succeeded = yes; then
+ ifelse([$3], , :, [$3])
+ else
+ ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
+ fi
+])
+
+
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@synfigincludedir@
+
+Name: @PACKAGE_TARNAME@
+Description: @PACKAGE_NAME@
+Requires: @CONFIG_DEPS@
+Version: @VERSION@
+Libs: -L${libdir} @CONFIG_LIBS@
+Cflags: @CONFIG_CFLAGS@ -I${includedir}
--- /dev/null
+
+Summary: Voria Extented Template Library
+Name: @PACKAGE_TARNAME@-devel
+Version: @VERSION_MAJ@.@VERSION_MIN@.@VERSION_REV@
+Release: @VERSION_REL@
+Copyright: free (see license), see /usr/share/doc/%{name}-%{version}/license.html
+URL: http://www.synfig.com/
+Packager: Robert B. Quattlebaum Jr. <darco@deepdarc.com>
+Group: Development/Languages
+Icon: config/logo.gif
+#Patch0: STLport-rename.patch
+#Patch1: STLport-rules.patch
+#Patch2: STLport-install-dir.patch
+Buildroot: %{_tmppath}/%{name}-%{version}-%(id -u -n)
+
+%description
+VoriaETL is a multiplatform class and template library
+designed to complement and supplement the C++ STL.
+
+%prep
+%setup
+#%patch0 -p1
+#%patch1 -p1
+#%patch2 -p1
+
+%build
+./configure --prefix=$RPM_BUILD_ROOT
+make
+
+%install
+make install
+
+%clean
+make clean
+
+%post -n @PACKAGE@-devel
+/sbin/ldconfig
+
+%postun -n @PACKAGE@-devel
+/sbin/ldconfig
+
+%files
+%defattr(-,root,root)
+%doc INSTALL README doc test
+/usr/include/*
+
--- /dev/null
+
+## AC_ARG_WARNINGS()
+##
+## Provide the --enable-warnings configure argument, set to 'minimum'
+## by default.
+##
+AC_DEFUN([AC_ARG_WARNINGS],
+[
+ AC_ARG_ENABLE([warnings],
+ [ --enable-warnings=[[none|minimum|maximum|hardcore]]
+ Control compiler pickyness. [[default=maximum]]],
+ [gtkmm_enable_warnings="$enableval"],
+ gtkmm_enable_warnings="maximum")
+
+ AC_MSG_CHECKING([for compiler warning flags to use])
+
+ gtkmm_warning_flags=''
+
+ # -W is now known as -Wextra, but that's not known by gcc 2 or 3
+ case "$gtkmm_enable_warnings" in
+ none|no) gtkmm_warning_flags='';;
+ minimum|yes) gtkmm_warning_flags='-Wall -Wno-unused-parameter';;
+ maximum) gtkmm_warning_flags='-W -Wall -Wno-unused-parameter';;
+ hardcore) gtkmm_warning_flags='-W -Wall -Werror -Wno-unused-parameter';;
+ esac
+
+ gtkmm_use_flags=''
+
+ if test "x$gtkmm_warning_flags" != "x"
+ then
+ echo 'int foo() { return 0; }' > conftest.cc
+
+ for flag in $gtkmm_warning_flags
+ do
+ # Test whether the compiler accepts the flag. GCC doesn't bail
+ # out when given an unsupported flag but prints a warning, so
+ # check the compiler output instead.
+ gtkmm_cxx_out="`$CXX $flag -c conftest.cc 2>&1`"
+ rm -f conftest.$OBJEXT
+ test "x${gtkmm_cxx_out}" = "x" && \
+ gtkmm_use_flags="${gtkmm_use_flags:+$gtkmm_use_flags }$flag"
+ done
+
+ rm -f conftest.cc
+ gtkmm_cxx_out=''
+ fi
+
+ if test "x$gtkmm_use_flags" != "x"
+ then
+ for flag in $gtkmm_use_flags
+ do
+ case " $CXXFLAGS " in
+ *" $flag "*) ;; # don't add flags twice
+ *) CXXFLAGS="${CXXFLAGS:+$CXXFLAGS }$flag";;
+ esac
+ done
+ else
+ gtkmm_use_flags='none'
+ fi
+
+ AC_MSG_RESULT([$gtkmm_use_flags])
+])
+
+
+
+
+AC_DEFUN([AC_ARG_DEBUG],
+[
+ AC_MSG_CHECKING([for debug flags])
+
+ AC_ARG_ENABLE(debug,[ --enable-debug Build in debugging mode],[
+ debug=$enableval
+ ],[
+ debug="no"
+ ])
+ debug_flags=''
+
+ case "$debug" in
+ yes)
+ debug_flags="-D_DEBUG -g"
+ ;;
+ half)
+ debug_flags="-DNDEBUG -g"
+ ;;
+ no|*)
+ debug_flags="-DNDEBUG -Wno-deprecated"
+ ;;
+ esac
+
+
+ CXXFLAGS="`echo $CXXFLAGS | sed s:-g::` $debug_flags"
+ CFLAGS="`echo $CFLAGS | sed s:-g::` $debug_flags"
+
+ AC_MSG_RESULT([$debug_flags])
+])
+
+
+
+
+## Optimisation level 2 in g++ 4.1 or g++ 4.2 breaks composition loading in the vector parsing function in loadcanvas.cpp (1509627)
+AC_DEFUN([AC_ARG_OPTIMIZATION],
+[
+ AC_MSG_CHECKING([for optimization flags])
+
+ AC_ARG_ENABLE(optimization,[ --enable-optimization=[[0,1,2,3,4]] Select optimization level (default=2)],[
+ optimization=$enableval
+ ],[
+ optimization="2"
+ ])
+ optimization_flags=''
+ case "$optimization" in
+ 0|no) optimization_flags="-O0";;
+ 1) optimization_flags="-O1";;
+ 2|yes) optimization_flags="-O2";;
+ pass1) optimization_flags="-O2 -fprofile-arcs";;
+ pass2) optimization_flags="-O2 -fbranch-probabilities";;
+ 3) optimization_flags="-O3";;
+ *) optimization_flags="-O4";;
+ esac
+ CXXFLAGS="`echo $CXXFLAGS | sed 's:-O.::g'` $optimization_flags"
+ CFLAGS="`echo $CFLAGS | sed 's:-O.::g'` $optimization_flags"
+ AC_MSG_RESULT([$optimization_flags])
+])
+
+AC_DEFUN([AC_ARG_PROFILE_ARCS],
+[
+ AC_MSG_CHECKING([for arc profiling])
+
+ AC_ARG_ENABLE(profile-arcs,[ --enable-profile-arcs Enable arc profiling],[
+ profile_arcs=$enableval
+ ],[
+ profile_arcs=no
+ ])
+
+ if test $profile_arcs = "yes" ; then {
+ CXXFLAGS="$CXXFLAGS -fprofile-arcs";
+ CFLAGS="$CFLAGS -fprofile-arcs";
+ } ; fi
+
+ AC_MSG_RESULT([$profile_arcs])
+])
+
+AC_DEFUN([AC_ARG_BRANCH_PROBABILITIES],
+[
+ AC_MSG_CHECKING([for branch-probabilities])
+
+ AC_ARG_ENABLE(branch-probabilities,[ --enable-branch-probabilities Enable branch-probabilities],[
+ branch_probabilities=$enableval
+ ],[
+ branch_probabilities=no
+ ])
+
+ if test $branch_probabilities = "yes" ; then {
+ CXXFLAGS="$CXXFLAGS -fbranch-probabilities";
+ CFLAGS="$CFLAGS -fbranch-probabilities";
+ } ; fi
+
+ AC_MSG_RESULT([$branch_probabilities])
+])
+
+AC_DEFUN([AC_ARG_PROFILING],
+[
+ AC_MSG_CHECKING([for profiling])
+
+ AC_ARG_ENABLE(profiling,[ --enable-profiling Enable profiling using gprof],[
+ profiling=$enableval
+ ],[
+ profiling=no
+ ])
+
+ if test $profiling = "yes" ; then {
+ CFLAGS="$CFLAGS -pg";
+ CXXFLAGS="$CXXFLAGS -pg";
+ LDFLAGS="$LDFLAGS -pg";
+ LIBS="$LIBS";
+ } ; fi
+
+ AC_MSG_RESULT([$profiling])
+])
+
+AC_DEFUN([AC_ARG_TIMELIMIT],
+[
+ AC_ARG_ENABLE(timelimit,[ --enable-timelimit=[[days]] Set number of usable days(default=forever)],[
+ death_time=$((`date +%s`+$enableval*60*60*24))
+ AC_DEFINE_UNQUOTED(DEATH_TIME,$death_time, [ Describes the time at which the library will stop working ] )
+ ],
+ [
+ death_time="no"
+ ])
+])
+
+AC_DEFUN([AC_ARG_LICENSE_KEY],
+[
+ AC_ARG_ENABLE(license_key,[ --enable-license-key Turn on license key requirement],[
+ AC_DEFINE(LICENSE_KEY_REQUIRED,, [ Enables license key checks ] )
+ ],
+ [
+ license_key=no
+ ])
+])
+
+AC_DEFUN([AC_ARG_TIMELIMIT],
+[
+ AC_ARG_ENABLE(timelimit,[ --enable-timelimit=[[days]] Set number of usable days(default=forever)],[
+ death_time=$((`date +%s`+$enableval*60*60*24))
+ AC_DEFINE_UNQUOTED(DEATH_TIME,$death_time, [ Describes the time at which the library will stop working ] )
+ ],
+ [
+ death_time="no"
+ ])
+])
+
+MINGW_FLAGS="-mno-cygwin"
+
+
+AC_DEFUN([AC_WIN32_QUIRKS],
+[
+
+case "$host" in
+ *mingw*)
+ AC_MSG_CHECKING([the flavor of the compiler])
+ if ( $CC --version | grep -q mingw ) ; then {
+ AC_MSG_RESULT([compiler is mingw special])
+ LIBTOOL_PATCH_SED="
+ s/dir=\"\$absdir\"/dir=\`cygpath -d -m \"\$absdir\"\`/;
+ s/absdir=\`cd \"\$dir\" && pwd\`/absdir=\`cygpath -d -m \"\$dir\"\`/;
+ s/# We need an absolute path/dir=\`cygpath -d -m \"\$dir\"\` # We need an absolute path/;
+ s- /usr/lib- C:/mingw/lib-g;
+ s-\"/lib -\"C:/mingw/lib -g;
+ s- /lib/ - -g;
+ ";
+ sys_lib_dlsearch_path_spec="C:/mingw/lib"
+ ac_default_prefix=`cygpath -d -m "$ac_default_prefix"`;
+ } else {
+ AC_MSG_RESULT([compiler is cygwin stock, adding -mno-cygwin])
+ CPP="$CPP $MINGW_FLAGS"
+ CC="$CC $MINGW_FLAGS"
+ CXX="$CXX $MINGW_FLAGS -L/usr/$host/lib -I/usr/include/c++/3.3.3/$host"
+ CXXCPP="$CXXCPP $MINGW_FLAGS"
+
+
+} ; fi
+
+ LTCC="gcc"
+ CXXFLAGS="$CXXFLAGS -LC:/GTK/lib"
+ CFLAGS="$CFLAGS -LC:/GTK/lib"
+ LDFLAGS="$LDFLAGS -lole32 -no-undefined -Wl,--export-all-symbols -Wl,--subsystem=console -Wl,--enable-runtime-pseudo-reloc"
+dnl LDFLAGS="$LDFLAGS -lole32 -no-undefined -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--subsystem=console -Wl,--enable-runtime-pseudo-reloc"
+ ;;
+ *cygwin*)
+ LDFLAGS="$LDFLAGS -lole32 -no-undefined -Wl,--export-all-symbols"
+dnl LDFLAGS="$LDFLAGS -lole32 -no-undefined -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--subsystem=console"
+ CXXFLAGS="$CXXFLAGS -I/target/include"
+ CFLAGS="$CFLAGS -I/target/include"
+ ;;
+ powerpc-apple*)
+ echo Adding mac-specific optimization flags. . .
+ CXXFLAGS="$CXXFLAGS $G5OPTFLAGS"
+ ;;
+esac
+
+
+])
+
+AC_DEFUN([AC_LIBTOOL_PATCH],
+[
+
+if [[ "$LIBTOOL_PATCH_SED""x" != "x" ]] ; then {
+ printf "Patching libtool... "
+ cat libtool | sed "$LIBTOOL_PATCH_SED" > libtool2
+ rm libtool
+ mv libtool2 libtool
+ chmod +x libtool
+ AC_MSG_RESULT([patched])
+} fi ;
+
+
+])
--- /dev/null
+# SYNFIG M4 Macro
+# For GNU Autotools
+# $Id$
+#
+# By Robert B. Quattlebaum Jr. <darco@users.sf.net>
+# AM_LIBXMLPP(,$2)
+
+
+AC_DEFUN([SYNFIG_DEPS],
+[
+ USING_ETL(,$2)
+ AM_PATH_XML2(,,$2)
+ AC_CHECK_FUNCS([floor pow sqrt],,$2)
+ AM_LIBXMLPP(,$2)
+
+ CXXFLAGS="$CXXFLAGS $LIBXMLPP_CFLAGS"
+ LIBS="$LIBS $LIBXMLPP_LIBS"
+
+ $1
+])
+
+AC_DEFUN([USING_SYNFIG],
+[
+ AC_ARG_WITH(synfig-includes,
+ [ --with-synfig-includes Specify location of synfig headers],[
+ CXXFLAGS="$CXXFLAGS -I$withval"
+ ])
+
+ AC_PATH_PROG(SYNFIG_CONFIG,synfig-config,no)
+
+ if test "$SYNFIG_CONFIG" = "no"; then
+ no_SYNFIG_config="yes"
+ $2
+ else
+ AC_MSG_CHECKING([if $SYNFIG_CONFIG works])
+ if $SYNFIG_CONFIG --libs >/dev/null 2>&1; then
+ SYNFIG_VERSION="`$SYNFIG_CONFIG --version`"
+ AC_MSG_RESULT([yes, $SYNFIG_VERSION])
+ CXXFLAGS="$CXXFLAGS `$SYNFIG_CONFIG --cxxflags`"
+ $1
+ else
+ AC_MSG_RESULT(no)
+ no_SYNFIG_config="yes"
+ $2
+ fi
+ fi
+
+ SYNFIG_DEPS($1,$2)
+])
+
+
--- /dev/null
+Shader Calculation Model:
+
+inputs - variables that control the object
+shader - joint vertex and pixel shader necessary for calculation
+
+Parameter Types:
+ Uniforms - things that are constant for the entire render setup
+
+Layer render properties:
+
+Blend - blends with layer behind (amount,blend-method), if complicated must use (pixel shader...).
+Algorithmic - gets colors without sampling textures (exception for function look ups...).
+
+Sampling - samples a texture map as part of the color calc process.
+ Behind - use result(s) below to calculate color.
+ Internal -
+ Functions/Inputs - CPU generated internal texture maps (uniform)
+ Dependent - GPU generated texture maps (unknown use...)
+
+Parameters:
+ Uniforms - layer-wide stats (color, blend-mode, amount, below texture, coverage map, etc.)
+ Varying - pixel coordinate (in canv-space), texture coordinates for samplers, etc.
+
+For optimized stuff:
+ For layer constants that aren't simple calculations (i.e. changing the blend type),
+ we can use global constants (however since OpenGL doesn't allow you to define those
+ manually, we can probably do it with #defines or the like)... Just in time compiling
+ (optimized by caching these changes of course) would allow us to operate in an optimal
+ manner (rather than having dynamic branching at run time).
+
+Considerations for Framework:
+
+For truly optimal rendering, caching textures would be great, but it would take up a lot of space. So an intelligent resource system should be implemented. The resource eviction routine should be intelligent and should deal with the resources deepest in the tree (of course this doesn't entirely count for CPU generated stuff). A priority system should be generated, mostly depending on how often it's used and even more, how expensive it is to generate (cpu and gpu side...).
+
+Shader considerations for Operations:
+
+Blend functionality can be done in a separate pass unless the blending shader part is also programmable (requires less JIT compiling).
+
+Sampling function should be abstracted to use different forms of interpolation (for nearest and linear, the built in support is probably plenty).
+
+Iterated calculations: either done using dynamic looping in GLSL or multipass rendering.
+
+
+Shader considerations for layers:
+
+solid_color - just use blend with an input global color parameter
+
+circle - can calculate alpha in falloff based on interpolated pixel values and then use that and the amount... color to blend (must work out whether or not to out put an amount map + color blend, or a color map + amount blend... currently using the first on CPU side).
+
+checker_board - same as circle, but a simpler calculation (antialiasing will require a few calculations using the values of the derivatives of the pixel coordinates)
+
+rectangle - same thing as the checker_board, but only need to worry about 2 edges per dimension.
+
+Coverage Map Based: outline,polygon,region,star,text
+and Internal Samplers: import, noise
+ - would require CPU side computation of the coverage map/color map
+ (tiling would be a little more difficult... we'll see how effective it would be...)
+
+Modifiers (algorithmic w/ direct below sample): clamp,colorcorrect (blend also classifies as this)
+ - modification of the colors underneath using math... easy....
+
+Basic Transform: translate,stretch,zoom (should require no sampling),super_sample (simple down sample)
+ - simply requires the repositioning (and resizing in the case of the super sample) of the window
+
+Behind Samplers:
+ Basic Transform: rotate,twirl,
+ In-place: bevel,blur,halftone2,shade
+ Warpers: inside_out, spherize, noise_distort (internal and behind sampler)
+ - requires access to the background texture (with increased window in order to not find distortions).
+
+Iterated: mandelbrot,julia (used to warp, index into gradient, etc.)
+ - requires iterative refinement of the fractal values (with crazy swapping to consider stopping points)
+
+Gradients (complicated... could require a CPU side color map, unless we have dynamic looping):
+ conical_gradient, linear_gradient, radial_gradient, spiral_gradient
--- /dev/null
+SUBDIRS=walk
+MAINTAINERCLEANFILES=Makefile.in
+EXTRA_DIST= about_dialog.sifz backdrop.sifz business_card.sifz candy.sifz cells.sifz eye.sifz eyes.sifz gamma.sifz gradient.sifz headmo.sifz installer-logo.sifz japan.sifz logo.sifz macwolfen.sifz Makefile.am mandelbrot.sifz newjulia.sifz newjulia2.sifz noise.sifz pirates.sifz preambletaffy.sifz prologue_kid.sifz sparkle.sifz splat.sifz star.sifz wallpaper.sifz warpcube.sifz warptext.sifz z_depth_test.sifz
--- /dev/null
+MAINTAINERCLEANFILES=Makefile.in
+EXTRA_DIST=animation.lst frame_01.jpg frame_02.jpg frame_03.jpg frame_04.jpg walk.sifz
--- /dev/null
+FPS 4
+frame_01.jpg
+frame_02.jpg
+frame_03.jpg
+frame_04.jpg
+frame_01.jpg
+frame_02.jpg
+frame_03.jpg
+frame_04.jpg
+frame_01.jpg
+frame_02.jpg
+frame_03.jpg
+frame_04.jpg
+frame_01.jpg
+frame_02.jpg
+frame_03.jpg
+frame_04.jpg
+frame_01.jpg
+frame_02.jpg
+frame_03.jpg
+frame_04.jpg
+frame_01.jpg
+frame_02.jpg
+frame_03.jpg
+frame_04.jpg
+frame_01.jpg
+frame_02.jpg
+frame_03.jpg
+frame_04.jpg
+frame_01.jpg
+frame_02.jpg
+frame_03.jpg
+frame_04.jpg
+frame_01.jpg
+frame_02.jpg
+frame_03.jpg
+frame_04.jpg
+frame_01.jpg
+frame_02.jpg
+frame_03.jpg
+frame_04.jpg
+frame_01.jpg
+frame_02.jpg
+frame_03.jpg
+frame_04.jpg
+frame_01.jpg
+frame_02.jpg
+frame_03.jpg
+frame_04.jpg
+frame_01.jpg
+frame_02.jpg
+frame_03.jpg
+frame_04.jpg
--- /dev/null
+#!/bin/sh
+
+#OPTIONS="--disable-optimization --enable-debug"
+
+PREFIX=/Users/darco/Projects/Voria/synfig-build
+
+export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig:/usr/lib/pkgconfig:/usr/X11R6/lib/pkgconfig
+OPTIONS="--prefix=$PREFIX"
+#OPTIONS="$OPTIONS --enable-timelimit=120"
+#OPTIONS="$OPTIONS --enable-optimization=2"
+OPTIONS="$OPTIONS --enable-optimization=3"
+#OPTIONS="$OPTIONS --enable-g5opt"
+#OPTIONS="$OPTIONS --disable-optimization"
+OPTIONS="$OPTIONS --disable-debug"
+#OPTIONS="$OPTIONS --with-vimage"
+OPTIONS="$OPTIONS --without-openexr"
+OPTIONS="$OPTIONS --disable-dependency-tracking"
+#OPTIONS="$OPTIONS --enable-universal"
+
+ARCH_FLAGS=""
+#ARCH_FLAGS="$ARCH_FLAGS -arch ppc"
+ARCH_FLAGS="$ARCH_FLAGS -arch i386"
+
+LDFLAGS="-L$PREFIX/lib"
+CFLAGS="-I$PREFIX/include"
+CXXFLAGS="-I$PREFIX/include"
+
+CC="gcc $LDFLAGS $CFLAGS $ARCH_FLAGS"
+CXX="g++ $LDFLAGS $CFLAGS $ARCH_FLAGS"
+CPP="gcc -E"
+CXXCPP="g++ -E"
+
+#distcc --version && {
+# CC=distcc
+# CXX="distcc g++"
+#}
+
+
+BUILDDIR=macosxbuild
+
+[ -e configure ] || ./bootstrap || exit 1
+
+[ -d $BUILDDIR ] && rm -fr $BUILDDIR
+
+mkdir $BUILDDIR
+
+cd $BUILDDIR
+
+echo ../configure $OPTIONS CC=\"$CC\" CXX=\"$CXX\" CPP=\"$CPP\" CXXCPP=\"$CXXCPP\" LDFLAGS=\"$LDFLAGS\" CFLAGS=\"$CFLAGS\" CXXFLAGS=\"$CXXFLAGS\"
+
+../configure $OPTIONS CC="$CC" CXX="$CXX" CPP="$CPP" CXXCPP="$CXXCPP" LDFLAGS="$LDFLAGS" CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" MACOS_DEPLOYMENT_TARGET=10.4 || exit 1
+
+make -j2
+make install-strip
+
+#make package $MAKEFLAGS
+
+#make installer
+
+
--- /dev/null
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+^L
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+^L
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control
+compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+^L
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+^L
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+^L
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+^L
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply, and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License
+may add an explicit geographical distribution limitation excluding those
+countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+^L
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+^L
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey the exclusion of warranty; and each file should
+have at least the "copyright" line and a pointer to where the full
+notice is found.
+
+
+ <one line to give the library's name and a brief idea of what it
+does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper
+mail.
+
+You should also get your employer (if you work as a programmer) or
+your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James
+Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
--- /dev/null
+This is the readme for Synfig Core.
--- /dev/null
+This is the welcome for Synfig.
--- /dev/null
+#!/bin/sh
+# finish up the installation
+# this script should be executed using the sudo command
+# this file is copied to synfig-devel.post_install and synfig-devel.post_upgrade
+# inside the .pkg bundle
+LOGFILE="/synfig_install.log"
+
+exit 0
+
+
+umask 022
+
+RESOURCE_DIR=`dirname $0`
+PREFIX=/usr/local
+
+cd $RESOURCE_DIR
+
+echo "Creating synfig-config script"
+[ -d $PREFIX ] || mkdir $PREFIX
+[ -d $PREFIX/bin ] || mkdir $PREFIX/bin
+[ -d $PREFIX/include ] || mkdir $PREFIX/include
+[ -d $PREFIX/lib ] || mkdir $PREFIX/lib
+[ -d $PREFIX/sbin ] || mkdir $PREFIX/sbin
+
+echo "Cleaning up any previous installation"
+[ -d $PREFIX/include/synfig ] && rm -fr $PREFIX/include/synfig
+ln -s /Library/Frameworks/synfig.framework/Headers $PREFIX/include/synfig
+
+sed '
+s:@exec_prefix@:/usr/local:g;
+s:@prefix@:/usr/local:g;
+s:@bindir@:$exec_prefix/bin:g;
+s:@libdir@:$exec_prefix/lib:g;
+s:@includedir@:$prefix/include:g;
+s:@VERSION@:@_VERSION_@:g;
+s:@PACKAGE@:@_PACKAGE_@:g;
+s:@LIBS@::g;
+s:@VERSION@:@_VERSION_@:;
+s:@PACKAGE@:@_PACKAGE_@:;
+s:@CONFIG_LIBS@:-F/Library/Frameworks/synfig.framework:;
+s:@SYNFIG_LIBS@:-F/Library/Frameworks/synfig.framework:;
+s:@CONFIG_CFLAGS@:-framework synfig:;
+' < $RESOURCE_DIR/synfig-config.in > $PREFIX/bin/synfig-config
+chmod 775 $PREFIX/bin/synfig-config
+
+echo "Precompiling Headers"
+#/usr/bin/c++ -precomp /Library/Frameworks/synfig.framework/Headers/synfig.h -o /Library/Frameworks/synfig.framework/Headers/synfig.p
+
+echo "Moving synfig tool"
+cp $RESOURCE_DIR/synfig $PREFIX/bin || exit 1
+
+echo "Done with shell script"
+
+
+exit 0
+
+
+
--- /dev/null
+#!/bin/sh
+# finish up the installation
+# this script should be executed using the sudo command
+# this file is copied to synfig-devel.post_install and synfig-devel.post_upgrade
+# inside the .pkg bundle
+LOGFILE="/synfig_install.log"
+
+exit 0
+
+
+umask 022
+
+RESOURCE_DIR=`dirname $0`
+PREFIX=/usr/local
+
+cd $RESOURCE_DIR
+
+echo "Creating synfig-config script"
+[ -d $PREFIX ] || mkdir $PREFIX
+[ -d $PREFIX/bin ] || mkdir $PREFIX/bin
+[ -d $PREFIX/include ] || mkdir $PREFIX/include
+[ -d $PREFIX/lib ] || mkdir $PREFIX/lib
+[ -d $PREFIX/sbin ] || mkdir $PREFIX/sbin
+
+echo "Cleaning up any previous installation"
+[ -d $PREFIX/include/synfig ] && rm -fr $PREFIX/include/synfig
+ln -s /Library/Frameworks/synfig.framework/Headers $PREFIX/include/synfig
+
+sed '
+s:@exec_prefix@:/usr/local:g;
+s:@prefix@:/usr/local:g;
+s:@bindir@:$exec_prefix/bin:g;
+s:@libdir@:$exec_prefix/lib:g;
+s:@includedir@:$prefix/include:g;
+s:@VERSION@:@_VERSION_@:g;
+s:@PACKAGE@:@_PACKAGE_@:g;
+s:@LIBS@::g;
+s:@VERSION@:@_VERSION_@:;
+s:@PACKAGE@:@_PACKAGE_@:;
+s:@CONFIG_LIBS@:-F/Library/Frameworks/synfig.framework:;
+s:@SYNFIG_LIBS@:-F/Library/Frameworks/synfig.framework:;
+s:@CONFIG_CFLAGS@:-framework synfig:;
+' < $RESOURCE_DIR/synfig-config.in > $PREFIX/bin/synfig-config
+chmod 775 $PREFIX/bin/synfig-config
+
+echo "Precompiling Headers"
+#/usr/bin/c++ -precomp /Library/Frameworks/synfig.framework/Headers/synfig.h -o /Library/Frameworks/synfig.framework/Headers/synfig.p
+
+echo "Moving synfig tool"
+cp $RESOURCE_DIR/synfig $PREFIX/bin || exit 1
+
+echo "Done with shell script"
+
+
+exit 0
+
+
+
--- /dev/null
+Title @PACKAGE_NAME@ @VERSION@
+Version @VERSION@
+Description @PACKAGE_NAME@
+DefaultLocation /usr/local
+DeleteWarning
+NeedsAuthorization YES
+DisableStop NO
+UseUserMask YES
+Application NO
+Relocatable NO
+Required NO
+InstallOnly NO
+RequiresReboot NO
+InstallFat NO
--- /dev/null
+# $Id$
+
+MAINTAINERCLEANFILES=Makefile.in
+SUBDIRS=synfig modules tool
+EXTRA_DIST=template.cpp template.h
+
--- /dev/null
+# $Id$
+
+synfiglibdir=@SYNFIGLIB_DIR@
+
+MAINTAINERCLEANFILES=Makefile.in
+SUBDIRS=mod_particle mod_filter mod_yuv420p mod_gif mod_gradient mod_geometry mod_noise mod_libavcodec mod_jpeg mod_openexr mod_bmp mod_ppm mod_png mod_dv mod_imagemagick mod_ffmpeg lyr_freetype lyr_std
+EXTRA_DIST=untemplate.nsh template.nsh example/simplecircle.h example/simplecircle.cpp example/filledrect.h example/main.cpp example/Makefile.am example/filledrect.cpp example/metaballs.cpp example/metaballs.h mod_mng/trgt_mng.h mod_mng/unmod_mng.nsh mod_mng/main.cpp mod_mng/Makefile.am mod_mng/mod_mng.nsh mod_mng/trgt_mng.cpp mptr_mplayer/main.cpp mptr_mplayer/mptr_mplayer.h mptr_mplayer/Makefile.am mptr_mplayer/mptr_mplayer.cpp
+
+sysconf_DATA = synfig_modules.cfg
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+module_LTLIBRARIES = libexample.la
+libexample_la_SOURCES = main.cpp simplecircle.cpp simplecircle.h filledrect.h filledrect.cpp metaballs.h metaballs.cpp
+libexample_la_LIBADD = ../../synfig/libsynfig.la @SYNFIG_LIBS@
+libexample_la_LDFLAGS = -module -no-undefined
+libexample_la_CXXFLAGS = @SYNFIG_CFLAGS@
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file filledrect.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <ETL/pen>
+
+#include "filledrect.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(FilledRect);
+SYNFIG_LAYER_SET_NAME(FilledRect,"rectangle");
+SYNFIG_LAYER_SET_LOCAL_NAME(FilledRect,_("Rectangle"));
+SYNFIG_LAYER_SET_CATEGORY(FilledRect,_("Geometry"));
+SYNFIG_LAYER_SET_VERSION(FilledRect,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(FilledRect,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+FilledRect::FilledRect():
+ Layer_Composite(1.0,Color::BLEND_STRAIGHT),
+ color(Color::black()),
+ point1(0,0),
+ point2(1,1),
+ feather_x(0),
+ feather_y(0),
+ bevel(0),
+ bevCircle(0)
+{
+}
+
+bool
+FilledRect::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(color);
+ IMPORT(point1);
+ IMPORT(point2);
+ IMPORT(feather_x);
+ IMPORT(feather_y);
+ IMPORT(bevel);
+ IMPORT(bevCircle);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+FilledRect::get_param(const String ¶m)const
+{
+ EXPORT(color);
+ EXPORT(point1);
+ EXPORT(point2);
+ EXPORT(feather_x);
+ EXPORT(feather_y);
+ EXPORT(bevel);
+ EXPORT(bevCircle);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+FilledRect::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("color")
+ .set_local_name(_("Color"))
+ );
+
+ ret.push_back(ParamDesc("point1")
+ .set_local_name(_("Point 1"))
+ );
+
+ ret.push_back(ParamDesc("point2")
+ .set_local_name(_("Point 2"))
+ );
+
+ ret.push_back(ParamDesc("feather_x")
+ .set_local_name(_("Feather X"))
+ );
+
+ ret.push_back(ParamDesc("feather_y")
+ .set_local_name(_("Feather Y"))
+ );
+
+ ret.push_back(ParamDesc("bevel")
+ .set_local_name(_("Bevel"))
+ );
+
+ ret.push_back(ParamDesc("bevCircle")
+ .set_local_name(_("Keep Bevel Circular"))
+ );
+
+ return ret;
+}
+
+bool
+FilledRect::get_color(const Point &pos, Color &out, Real &outamount) const
+{
+ Point p[2] = {point1,point2};
+ Real swap;
+
+ if(p[0][0] > p[1][0])
+ {
+ swap = p[0][0];
+ p[0][0] = p[1][0];
+ p[1][0] = swap;
+ }
+
+ if(p[0][1] > p[1][1])
+ {
+ swap = p[0][1];
+ p[0][1] = p[1][1];
+ p[1][1] = swap;
+ }
+
+ /*
+ p[0][0] -= feather_x;
+ p[1][0] += feather_x;
+ p[0][1] -= feather_y;
+ p[1][1] += feather_y;*/
+ const Real w = p[1][0] - p[0][0];
+ const Real h = p[1][1] - p[0][1];
+
+ if(pos[0] >= p[0][0] && pos[0] <= p[1][0] && pos[1] >= p[0][1] && pos[1] <= p[1][1])
+ {
+ Real value = 1;
+
+ if(feather_x > 0)
+ {
+ Real xdist = pos[0] - p[0][0];
+ xdist = min(xdist,p[1][0]-pos[0]);
+
+ if(xdist < feather_x)
+ {
+ value = xdist/feather_x;
+ }
+ }
+
+ if(feather_y > 0)
+ {
+ Real ydist = pos[1]-p[0][1];
+ ydist = min(ydist,p[1][1]-pos[1]);
+
+ if(ydist < feather_y)
+ {
+ value = min(value,(ydist/feather_y));
+ }
+ }
+
+ //if we're beveled then check with ellipse code...
+ if(bevel > 0)
+ {
+ const Real bev = (bevel > 1) ? 1 : bevel;
+ const Real bevx = bevCircle ? min(w*bev/2,h*bev/2) : w*bev/2;
+ const Real bevy = bevCircle ? min(w*bev/2,h*bev/2) : h*bev/2;;
+
+ Vector v(0,0);
+ bool in = false;
+
+ //based on which quarter it is in (and because it's x/y symmetric) get a positive vector (x/y)
+ if(pos[0] < p[0][0] + bevx)
+ {
+ if(pos[1] < p[0][1] + bevy)
+ {
+ v[0] = p[0][0] + bevx - pos[0];
+ v[1] = p[0][1] + bevy - pos[1];
+ in = true;
+ }else if(pos[1] > p[1][1] - bevy)
+ {
+ v[0] = p[0][0] + bevx - pos[0];
+ v[1] = pos[1] - (p[1][1] - bevy);
+ in = true;
+ }
+ }
+ else if(pos[0] > p[1][0] - bevx)
+ {
+ if(pos[1] < p[0][1] + bevy)
+ {
+ v[0] = pos[0] - (p[1][0] - bevx);
+ v[1] = p[0][1] + bevy - pos[1];
+ in = true;
+ }else if(pos[1] > p[1][1] - bevy)
+ {
+ v[0] = pos[0] - (p[1][0] - bevx);
+ v[1] = pos[1] - (p[1][1] - bevy);
+ in = true;
+ }
+ }
+
+ //if it's inside a bevelled block
+ if(in)
+ {
+ const Vector scale(bevx,bevy);
+
+ Vector vc(v[0]/scale[0],v[1]/scale[1]);
+ Real d = vc.mag();
+
+ //if it's inside the ellipse
+ if(d < 1)
+ {
+ Real val = atan2(vc[1],vc[0]);
+ val /= (PI/2); //< will always be (0,pi/2) because both components are positive
+
+ Real fthx=1,fthy=1;
+
+ //change d into distance away from edge
+ d = 1 - d;
+
+ if(feather_x > 0)
+ {
+ if(scale[0] < feather_x)
+ {
+ fthy = scale[0]/feather_x;
+ }
+
+ if(d*scale[0] < feather_x)
+ {
+ fthx = d*scale[0]/feather_x;
+ }
+ }
+
+ if(feather_y > 0)
+ {
+ if(scale[1] < feather_y)
+ {
+ fthx = min(fthx,scale[1]/feather_y);
+ }
+
+ if(d*scale[1] < feather_y)
+ {
+ fthy = min(fthy,d*scale[1]/feather_y);
+ }
+ }
+
+ //interpolate
+ outamount = min(value,((1-val)*fthx + val*fthy)) * get_amount();
+ out = color;
+ return true;
+
+ }else return false;
+ }
+ }
+
+ outamount = value * get_amount();
+ out = color;
+
+ return true;
+ }else
+ return false;
+}
+
+Color
+FilledRect::get_color(Context context, const Point &pos)const
+{
+ Color clr;
+ Real amt;
+
+ if(get_color(pos,clr,amt))
+ {
+ if(amt==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return clr;
+ else
+ return Color::blend(clr,context.get_color(pos),amt,get_blend_method());
+ }
+ else
+ return context.get_color(pos);
+}
+
+bool
+FilledRect::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ // Width and Height of a pixel
+ const Point br(renddesc.get_br()), tl(renddesc.get_tl());
+ const int w = renddesc.get_w(), h = renddesc.get_h();
+
+ Real wpp = (br[0]-tl[0])/w;
+ Real hpp = (br[1]-tl[1])/h;
+ //const Real xneg = wpp<0?-1:1;
+ //const Real yneg = hpp<0?-1:1;
+
+ //the bounds of the rectangle
+ Point p[2] = {point1,point2};
+
+ if((p[0][0] > p[1][0]) ^ wpp < 0)
+ {
+ swap(p[0][0],p[1][0]);
+ }
+
+ if((p[0][1] > p[1][1]) ^ hpp < 0)
+ {
+ swap(p[0][1],p[1][1]);
+ }
+
+ /*p[0][0] -= xneg*feather_x;
+ p[1][0] += xneg*feather_x;
+ p[0][1] -= yneg*feather_y;
+ p[1][1] += yneg*feather_y;*/
+
+ //the integer coordinates
+ int y_start = (int)((p[0][1] - tl[1])/hpp +.5); //round start up
+ int x_start = (int)((p[0][0] - tl[0])/wpp +.5);
+ int y_end = (int)((p[1][1] - tl[1])/hpp +.5); //and ends up
+ int x_end = (int)((p[1][0] - tl[0])/wpp +.5);
+
+ y_start = max(0,y_start);
+ x_start = max(0,x_start);
+ y_end = min(h,y_end);
+ x_end = min(w,x_end);
+
+ SuperCallback supercb(cb,0,9000,10000);
+
+ if(y_start >= h || x_start > w || x_end < 0 || y_end < 0)
+ {
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ return true;
+ }
+
+ Real xf_start = tl[0] + x_start*wpp;
+ Point pos(xf_start,tl[1] + y_start*hpp);
+
+ Color clr = Color::black();
+ Real amt;
+
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ for(int y = y_start; y < y_end; y++, pos[1] += hpp)
+ {
+ pos[0] = xf_start;
+ for(int x = x_start; x < x_end; x++, pos[0] += wpp)
+ {
+ if(get_color(pos,clr,amt))
+ {
+ if(amt==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ (*surface)[y][x] = clr;
+ else
+ (*surface)[y][x] = Color::blend(clr,(*surface)[y][x],amt,get_blend_method());
+ }
+ }
+ }
+
+ return true;
+
+#if 0
+ //faster version but much more complex
+ //the floating point
+ Real y1,y2,y3;
+ Real x1,x2,x3;
+ Real dx1,dx2; //reversed in 3rd y section, not used in 2nd
+
+ //the transparent
+ Real fx = 0, fy = 0;
+ Real dfx,dfy;
+
+ //Get the slopes of the lines we need to worry about
+ if(feather_x)
+ {
+ dfx = 1/(fxsize);
+
+ if(fxsize*2 > xfw)
+ {
+ x1 = xfw/2;
+ x2 = 0;
+ x3 = xfw;
+ }else
+ {
+ x1 = fxsize;
+ x2 = xfw - fxsize;
+ x3 = xfw;
+ }
+ }else
+ {
+ fx = 1;
+ dfx = 0;
+ x1=0;
+ x2=xfw;
+ x3=0;
+ }
+
+ if(feather_y)
+ {
+ dfy = 1/(fysize);
+
+ if(fysize*2 > yfh)
+ {
+ y1 = yfh/2;
+ y2 = 0;
+ y3 = yfh;
+ }else
+ {
+ y1 = fysize;
+ y2 = yfh - fysize;
+ y3 = yfh;
+ }
+
+ dx1 = ph*feather_x/feather_y;
+ dx2 = -2*dx1;
+
+ }else
+ {
+ fy = 1;
+ dfy = 0;
+ y1=0;
+ y2=yfh;
+ y3=0;
+ }
+
+ fy = yf*dfy;
+
+ int x,y;
+ Real value = 0;
+ SuperCallback supercb(cb,0,9000,10000);
+ Surface::pen p;
+
+ Real tx1 = 0,tx2 =
+ for(y = y_start;yf < y1; y++,yf++,fy+=dfy, tx1+=dx1)
+ {
+ fx = xf*dfx;
+
+ p = surface->get_pen(x_start,y);
+ for(; xf < x1; xf++,p.inc_x(), fx+=dfx)
+ {
+ //we are in the x portion... use fx
+ value = fx*get_amount();
+ if(value==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ p.put_value(color);
+ else
+ p.put_value(Color::blend(color,p.get_value(),value,get_blend_method()));
+ }
+
+ for(;xf < x2; xf++,p.inc_x())
+ {
+ //we are now in y... use fy
+ value = fy*get_amount();
+ if(value==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ p.put_value(color);
+ else
+ p.put_value(Color::blend(color,p.get_value(),value,get_blend_method()));
+ }
+
+ fx = xfw?(xfw - xf)/xfw:1;
+ for(;xf < x3 && ; xf++,p.inc_x(), fx-=dfx)
+ {
+ //we are in the x portion... use fx
+ value = max(0,fx*get_amount());
+ if(value==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ p.put_value(color);
+ else
+ p.put_value(Color::blend(color,p.get_value(),value,get_blend_method()));
+ }
+ }
+
+ x1 =
+ for(;fy < 1.0; y++,yf++,fy+=dfy)
+ {
+ fx = xf*dfx;
+
+ p = surface->get_pen(x_start,y);
+ for(; xf < x1; xf++,p.inc_x(), fx+=dfx)
+ {
+ //we are in the x portion... use fx
+ value = fx*get_amount();
+ if(value==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ p.put_value(color);
+ else
+ p.put_value(Color::blend(color,p.get_value(),value,get_blend_method()));
+ }
+
+ for(;xf < x2; xf++,p.inc_x())
+ {
+ //we are now in y... use fy
+ value = fy*get_amount();
+ if(value==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ p.put_value(color);
+ else
+ p.put_value(Color::blend(color,p.get_value(),value,get_blend_method()));
+ }
+
+ fx = xfw?(xfw - xf)/xfw:1;
+ for(;xf < x3 && ; xf++,p.inc_x(), fx-=dfx)
+ {
+ //we are in the x portion... use fx
+ value = max(0,fx*get_amount());
+ if(value==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ p.put_value(color);
+ else
+ p.put_value(Color::blend(color,p.get_value(),value,get_blend_method()));
+ }
+ }
+
+ for()
+ {
+ for(int x = x_start; x < x_end; x++)
+ {
+
+ }
+ }
+
+#endif
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file filledrect.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_FILLEDRECT_H
+#define __SYNFIG_FILLEDRECT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+#include <synfig/value.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class FilledRect : public synfig::Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ synfig::Color color;
+
+ synfig::Point point1;
+ synfig::Point point2;
+
+ synfig::Real feather_x;
+ synfig::Real feather_y;
+
+ synfig::Real bevel;
+
+ bool bevCircle;
+
+ bool get_color(const synfig::Point &pos, synfig::Color &out, synfig::Real &outamount)const;
+
+public:
+
+ FilledRect();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+
+ virtual synfig::ValueBase get_param(const synfig::String & param)const;
+
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+
+ virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+
+ virtual Vocab get_param_vocab()const;
+}; // END of class FilledRect
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file example/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include <synfig/canvas.h>
+#include <synfig/string.h>
+#include "simplecircle.h"
+#include "filledrect.h"
+#include "metaballs.h"
+
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(example)
+ MODULE_NAME("Example Module")
+ MODULE_DESCRIPTION("A dummy module that serves as a starting point for writing other modules.")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(example)
+ BEGIN_LAYERS
+ //LAYER(SimpleCircle)
+ //LAYER(FilledRect)
+ //LAYER(Metaballs)
+ END_LAYERS
+MODULE_INVENTORY_END
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file metaballs.cpp
+** \brief Implements metaballs
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <ETL/pen>
+
+#include "metaballs.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Metaballs);
+SYNFIG_LAYER_SET_NAME(Metaballs,"metaballs");
+SYNFIG_LAYER_SET_LOCAL_NAME(Metaballs,_("Metaballs"));
+SYNFIG_LAYER_SET_CATEGORY(Metaballs,_("Default"));
+SYNFIG_LAYER_SET_VERSION(Metaballs,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Metaballs,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Metaballs::Metaballs():
+ Layer_Composite(1.0,Color::BLEND_STRAIGHT),
+ color(Color::black())
+{
+}
+
+bool
+Metaballs::set_param(const String & param, const ValueBase &value)
+{
+ if( param=="centers" && value.same_type_as(centers))
+ {
+ centers = value;
+ return true;
+ }
+
+ if( param=="weights" && value.same_type_as(weights))
+ {
+ weights = value;
+ return true;
+ }
+
+ if( param=="radii" && value.same_type_as(radii))
+ {
+ radii = value;
+ return true;
+ }
+
+ IMPORT(color);
+ IMPORT(threshold);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+Metaballs::get_param(const String ¶m)const
+{
+ EXPORT(color);
+
+ EXPORT(radii);
+ EXPORT(weights);
+ EXPORT(centers);
+ EXPORT(threshold);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+Metaballs::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("color")
+ .set_local_name(_("Color"))
+ );
+
+ ret.push_back(ParamDesc("centers")
+ .set_local_name(_("Points"))
+ );
+
+ ret.push_back(ParamDesc("radii")
+ .set_local_name(_("Radii"))
+ );
+
+ ret.push_back(ParamDesc("weights")
+ .set_local_name(_("Weights"))
+ );
+
+ ret.push_back(ParamDesc("threshold")
+ .set_local_name(_("Threshold"))
+ );
+
+ return ret;
+}
+
+static inline Real densityfunc(const synfig::Point &p, const synfig::Point &c, Real R)
+{
+ const Real dx = p[0] - c[0];
+ const Real dy = p[1] - c[1];
+
+ const Real n = (1 - (dx*dx + dy*dy)/(R*R));
+ return (n*n*n);
+
+ /*
+ f(d) = (1 - d^2)^3
+ f'(d) = -6d * (1 - d^2)^2
+
+ could use this too...
+ f(d) = (1 - d^2)^2
+ f'(d) = -6d * (1 - d^2)
+ */
+}
+
+Real
+Metaballs::totaldensity(const Point &pos) const
+{
+ Real density = 0;
+
+ //sum up weighted functions
+ for(unsigned int i=0;i<centers.size();i++)
+ {
+ density += weights[i] * densityfunc(pos,centers[i], radii[i]);
+ }
+
+ return density;
+}
+
+Color
+Metaballs::get_color(Context context, const Point &pos)const
+{
+ Real dens = totaldensity(pos);
+
+ if(dens >= threshold)
+ return color;
+ else
+ return context.get_color(pos);
+}
+
+bool
+Metaballs::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ // Width and Height of a pixel
+ const Point br(renddesc.get_br()),
+ tl(renddesc.get_tl());
+
+ const int w = renddesc.get_w(),
+ h = renddesc.get_h();
+
+ Real pw = renddesc.get_pw();
+ Real ph = renddesc.get_ph();
+
+ SuperCallback supercb(cb,0,9000,10000);
+
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ Point pos(tl[0],tl[1]);
+
+ Real dens;
+
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ for(int y = 0; y < h; y++, pos[1] += ph)
+ {
+ pos[0] = tl[0];
+ for(int x = 0; x < w; x++, pos[0] += pw)
+ {
+ dens = totaldensity(pos);
+
+ if(dens >= threshold)
+ {
+ (*surface)[y][x] = Color::blend(color,(*surface)[y][x],get_amount(),get_blend_method());
+ }
+ }
+ }
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file metaballs.h
+** \brief Declares information for defining Metaballs.
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_METABALLS_H
+#define __SYNFIG_METABALLS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+#include <synfig/value.h>
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+class Metaballs : public synfig::Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ synfig::Color color;
+
+ std::vector<synfig::Point> centers;
+ std::vector<synfig::Real> radii;
+ std::vector<synfig::Real> weights;
+
+ synfig::Real threshold;
+ //Real threshold2;
+
+ synfig::Real totaldensity(const synfig::Point &pos)const;
+
+public:
+
+ Metaballs();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+
+ virtual synfig::ValueBase get_param(const synfig::String & param)const;
+
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+
+ virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+
+ virtual Vocab get_param_vocab()const;
+}; // END of class Metaballs
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file simplecircle.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#include "simplecircle.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(SimpleCircle);
+SYNFIG_LAYER_SET_NAME(SimpleCircle,"simple_circle");
+SYNFIG_LAYER_SET_LOCAL_NAME(SimpleCircle,_("Simple Circle"));
+SYNFIG_LAYER_SET_CATEGORY(SimpleCircle,_("Do Not Use"));
+SYNFIG_LAYER_SET_VERSION(SimpleCircle,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(SimpleCircle,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+SimpleCircle::SimpleCircle():
+ Layer_Composite(1.0,Color::BLEND_STRAIGHT),
+ color(Color::black()),
+ center(0,0),
+ radius(0.5)
+{
+}
+
+bool
+SimpleCircle::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(color);
+ IMPORT(center);
+ IMPORT(radius);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+SimpleCircle::get_param(const String ¶m)const
+{
+ EXPORT(color);
+ EXPORT(center);
+ EXPORT(radius);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+SimpleCircle::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("color")
+ .set_local_name(_("Color"))
+ );
+
+ ret.push_back(ParamDesc("center")
+ .set_local_name(_("Center"))
+ );
+
+ ret.push_back(ParamDesc("radius")
+ .set_local_name(_("Radius"))
+ .set_description(_("This is the radius of the circle"))
+ .set_origin("center")
+ );
+
+ return ret;
+}
+
+Color
+SimpleCircle::get_color(Context context, const Point &pos)const
+{
+
+ if((pos-center).mag()<radius)
+ {
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,context.get_color(pos),get_amount(),get_blend_method());
+ }
+ else
+ return context.get_color(pos);
+}
+
+synfig::Layer::Handle
+SimpleCircle::hit_check(synfig::Context context, const synfig::Point &pos)const
+{
+ if((pos-center).mag()<radius)
+ return const_cast<SimpleCircle*>(this);
+ else
+ return context.hit_check(pos);
+}
+
+/*
+bool
+SimpleCircle::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ // Mark our progress as starting
+ if(cb && !cb->amount_complete(0,1000))
+ return false;
+
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ surface->fill(color);
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(1000,1000))
+ return false;
+
+ return true;
+ }
+
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+
+ int x,y;
+
+ Surface::alpha_pen apen(surface->begin());
+
+ apen.set_value(color);
+ apen.set_alpha(get_amount());
+ apen.set_blend_method(get_blend_method());
+
+ for(y=0;y<renddesc.get_h();y++,apen.inc_y(),apen.dec_x(x))
+ for(x=0;x<renddesc.get_w();x++,apen.inc_x())
+ apen.put_value();
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
+*/
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file simplecircle.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_SIMPLECIRCLE_H
+#define __SYNFIG_SIMPLECIRCLE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+#include <synfig/layer_composite.h>
+#include <synfig/value.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class SimpleCircle : public synfig::Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ synfig::Color color;
+
+ synfig::Point center;
+
+ synfig::Real radius;
+
+public:
+
+ SimpleCircle();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+
+ virtual synfig::ValueBase get_param(const synfig::String & param)const;
+
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+
+ //virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual Vocab get_param_vocab()const;
+}; // END of class SimpleCircle
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+# $Id$
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+AM_CXXFLAGS=@CXXFLAGS@ @FREETYPE_CFLAGS@
+
+moduledir=@MODULE_DIR@
+
+if WITH_FREETYPE
+module_LTLIBRARIES = liblyr_freetype.la
+liblyr_freetype_la_SOURCES = main.cpp lyr_freetype.cpp lyr_freetype.h
+liblyr_freetype_la_LIBADD = -L../../synfig -lsynfig @FREETYPE_LIBS@ @SYNFIG_LIBS@
+liblyr_freetype_la_LDFLAGS = -module -no-undefined
+liblyr_freetype_la_CXXFLAGS = @SYNFIG_CFLAGS@ @FREETYPE_CFLAGS@
+if WITH_FONTCONFIG
+liblyr_freetype_la_LIBADD += @FONTCONFIG_LIBS@
+liblyr_freetype_la_CXXFLAGS += @FONTCONFIG_CFLAGS@
+else
+endif
+else
+endif
+
+
+EXTRA_DIST= lyr_freetype.nsh unlyr_freetype.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file lyr_freetype.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2006 Paul Wise
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_LAYER
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#ifdef WITH_FONTCONFIG
+#include <fontconfig/fontconfig.h>
+#endif
+
+#include "lyr_freetype.h"
+
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+#define MAX_GLYPHS 2000
+
+#define PANGO_STYLE_NORMAL (0)
+#define PANGO_STYLE_OBLIQUE (1)
+#define PANGO_STYLE_ITALIC (2)
+
+
+#define WEIGHT_NORMAL (400)
+#define WEIGHT_BOLD (700)
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Layer_Freetype);
+SYNFIG_LAYER_SET_NAME(Layer_Freetype,"text");
+SYNFIG_LAYER_SET_LOCAL_NAME(Layer_Freetype,_("Text"));
+SYNFIG_LAYER_SET_CATEGORY(Layer_Freetype,_("Other"));
+SYNFIG_LAYER_SET_VERSION(Layer_Freetype,"0.2");
+SYNFIG_LAYER_SET_CVS_ID(Layer_Freetype,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/*Glyph::~Glyph()
+{
+ if(glyph)FT_Done_Glyph(glyph);
+}
+*/
+void
+TextLine::clear_and_free()
+{
+ std::vector<Glyph>::iterator iter;
+ for(iter=glyph_table.begin();iter!=glyph_table.end();++iter)
+ {
+ if(iter->glyph)FT_Done_Glyph(iter->glyph);
+ iter->glyph=0;
+ }
+ glyph_table.clear();
+}
+
+/* === M E T H O D S ======================================================= */
+
+Layer_Freetype::Layer_Freetype()
+{
+ face=0;
+
+ size=Vector(0.25,0.25);
+ text=_("Text Layer");
+ color=Color::black();
+ pos=Vector(0,0);
+ orient=Vector(0.5,0.5);
+ compress=1.0;
+ vcompress=1.0;
+ weight=WEIGHT_NORMAL;
+ style=PANGO_STYLE_NORMAL;
+ family="Sans Serif";
+ use_kerning=true;
+ grid_fit=false;
+ old_version=false;
+ set_blend_method(Color::BLEND_COMPOSITE);
+ needs_sync_=true;
+
+ new_font(family,style,weight);
+
+ invert=false;
+}
+
+Layer_Freetype::~Layer_Freetype()
+{
+ if(face)
+ FT_Done_Face(face);
+}
+
+void
+Layer_Freetype::new_font(const synfig::String &family, int style, int weight)
+{
+ if(
+ !new_font_(family,style,weight) &&
+ !new_font_(family,style,WEIGHT_NORMAL) &&
+ !new_font_(family,PANGO_STYLE_NORMAL,weight) &&
+ !new_font_(family,PANGO_STYLE_NORMAL,WEIGHT_NORMAL) &&
+ !new_font_("sans serif",style,weight) &&
+ !new_font_("sans serif",style,WEIGHT_NORMAL) &&
+ !new_font_("sans serif",PANGO_STYLE_NORMAL,weight)
+ )
+ new_font_("sans serif",PANGO_STYLE_NORMAL,WEIGHT_NORMAL);
+}
+
+bool
+Layer_Freetype::new_font_(const synfig::String &font_fam_, int style, int weight)
+{
+ synfig::String font_fam(font_fam_);
+
+ if(new_face(font_fam_))
+ return true;
+
+ //start evil hack
+ for(unsigned int i=0;i<font_fam.size();i++)font_fam[i]=tolower(font_fam[i]);
+ //end evil hack
+
+ if(font_fam=="arial black")
+#ifndef __APPLE__
+ if(new_face("ariblk"))
+ return true;
+ else
+#endif
+ font_fam="sans serif";
+
+ if(font_fam=="sans serif" || font_fam=="arial")
+ {
+ String arial("arial");
+ if(weight>WEIGHT_NORMAL)
+ arial+='b';
+ if(style==PANGO_STYLE_ITALIC||style==PANGO_STYLE_OBLIQUE)
+ arial+='i';
+ else
+ if(weight>WEIGHT_NORMAL) arial+='d';
+
+ if(new_face(arial))
+ return true;
+#ifdef __APPLE__
+ if(new_face("Helvetica RO"))
+ return true;
+#endif
+ }
+
+ if(font_fam=="comic" || font_fam=="comic sans")
+ {
+ String filename("comic");
+ if(weight>WEIGHT_NORMAL)
+ filename+='b';
+ if(style==PANGO_STYLE_ITALIC||style==PANGO_STYLE_OBLIQUE)
+ filename+='i';
+ else if(weight>WEIGHT_NORMAL) filename+='d';
+
+ if(new_face(filename))
+ return true;
+ }
+
+ if(font_fam=="courier" || font_fam=="courier new")
+ {
+ String filename("cour");
+ if(weight>WEIGHT_NORMAL)
+ filename+='b';
+ if(style==PANGO_STYLE_ITALIC||style==PANGO_STYLE_OBLIQUE)
+ filename+='i';
+ else if(weight>WEIGHT_NORMAL) filename+='d';
+
+ if(new_face(filename))
+ return true;
+ }
+
+ if(font_fam=="serif" || font_fam=="times" || font_fam=="times new roman")
+ {
+ String filename("times");
+ if(weight>WEIGHT_NORMAL)
+ filename+='b';
+ if(style==PANGO_STYLE_ITALIC||style==PANGO_STYLE_OBLIQUE)
+ filename+='i';
+ else if(weight>WEIGHT_NORMAL) filename+='d';
+
+ if(new_face(filename))
+ return true;
+ }
+
+ if(font_fam=="trebuchet")
+ {
+ String filename("trebuc");
+ if(weight>WEIGHT_NORMAL)
+ filename+='b';
+ if(style==PANGO_STYLE_ITALIC||style==PANGO_STYLE_OBLIQUE)
+ {
+ filename+='i';
+ if(weight<=WEIGHT_NORMAL) filename+='t';
+ }
+ else if(weight>WEIGHT_NORMAL) filename+='d';
+
+ if(new_face(filename))
+ return true;
+ }
+
+
+ if(font_fam=="sans serif" || font_fam=="luxi sans")
+ {
+ {
+ String luxi("luxis");
+ if(weight>WEIGHT_NORMAL)
+ luxi+='b';
+ else
+ luxi+='r';
+ if(style==PANGO_STYLE_ITALIC||style==PANGO_STYLE_OBLIQUE)
+ luxi+='i';
+
+
+ if(new_face(luxi))
+ return true;
+ }
+ if(new_face("arial"))
+ return true;
+ if(new_face("Arial"))
+ return true;
+ }
+ if(font_fam=="serif" || font_fam=="times" || font_fam=="times new roman" || font_fam=="luxi serif")
+ {
+ {
+ String luxi("luxir");
+ if(weight>WEIGHT_NORMAL)
+ luxi+='b';
+ else
+ luxi+='r';
+ if(style==PANGO_STYLE_ITALIC||style==PANGO_STYLE_OBLIQUE)
+ luxi+='i';
+
+ if(new_face(luxi))
+ return true;
+ }
+ if(new_face("Times New Roman"))
+ return true;
+ if(new_face("Times"))
+ return true;
+ }
+ if(font_fam=="luxi")
+ {
+ {
+ String luxi("luxim");
+ if(weight>WEIGHT_NORMAL)
+ luxi+='b';
+ else
+ luxi+='r';
+ if(style==PANGO_STYLE_ITALIC||style==PANGO_STYLE_OBLIQUE)
+ luxi+='i';
+
+ if(new_face(luxi))
+ return true;
+ }
+
+ if(new_face("Times New Roman"))
+ return true;
+ if(new_face("Times"))
+ return true;
+ }
+
+ return new_face(font_fam_) || new_face(font_fam);
+
+ return false;
+}
+
+#ifdef USE_MAC_FT_FUNCS
+void fss2path(char *path, FSSpec *fss)
+{
+ int l; //fss->name contains name of last item in path
+ for(l=0; l<(fss->name[0]); l++) path[l] = fss->name[l + 1];
+ path[l] = 0;
+
+ if(fss->parID != fsRtParID) //path is more than just a volume name
+ {
+ int i, len;
+ CInfoPBRec pb;
+
+ pb.dirInfo.ioNamePtr = fss->name;
+ pb.dirInfo.ioVRefNum = fss->vRefNum;
+ pb.dirInfo.ioDrParID = fss->parID;
+ do
+ {
+ pb.dirInfo.ioFDirIndex = -1; //get parent directory name
+ pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
+ if(PBGetCatInfoSync(&pb) != noErr) break;
+
+ len = fss->name[0] + 1;
+ for(i=l; i>=0; i--) path[i + len] = path[i];
+ for(i=1; i<len; i++) path[i - 1] = fss->name[i]; //add to start of path
+ path[i - 1] = ':';
+ l += len;
+} while(pb.dirInfo.ioDrDirID != fsRtDirID); //while more directory levels
+ }
+}
+#endif
+
+bool
+Layer_Freetype::new_face(const String &newfont)
+{
+ int error;
+ FT_Long face_index=0;
+
+ // If we are already loaded, don't bother reloading.
+ if(face && font==newfont)
+ return true;
+
+ if(face)
+ {
+ FT_Done_Face(face);
+ face=0;
+ }
+
+ error=FT_New_Face(ft_library,newfont.c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,(newfont+".ttf").c_str(),face_index,&face);
+
+ if(get_canvas())
+ {
+ if(error)error=FT_New_Face(ft_library,(get_canvas()->get_file_path()+ETL_DIRECTORY_SEPARATOR+newfont).c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,(get_canvas()->get_file_path()+ETL_DIRECTORY_SEPARATOR+newfont+".ttf").c_str(),face_index,&face);
+ }
+
+#ifdef USE_MAC_FT_FUNCS
+ if(error)
+ {
+ FSSpec fs_spec;
+ error=FT_GetFile_From_Mac_Name(newfont.c_str(),&fs_spec,&face_index);
+ if(!error)
+ {
+ char filename[512];
+ fss2path(filename,&fs_spec);
+ //FSSpecToNativePathName(fs_spec,filename,sizeof(filename)-1, 0);
+
+ error=FT_New_Face(ft_library, filename, face_index,&face);
+ //error=FT_New_Face_From_FSSpec(ft_library, &fs_spec, face_index,&face);
+ synfig::info(__FILE__":%d: \"%s\" (%s) -- ft_error=%d",__LINE__,newfont.c_str(),filename,error);
+ }
+ else
+ {
+ synfig::info(__FILE__":%d: \"%s\" -- ft_error=%d",__LINE__,newfont.c_str(),error);
+ // Unable to generate fs_spec
+ }
+
+ }
+#endif
+
+#ifdef WITH_FONTCONFIG
+ if(error)
+ {
+ FcFontSet *fs;
+ FcResult result;
+ if( !FcInit() )
+ {
+ synfig::warning("Layer_Freetype: fontconfig: %s",_("unable to initialise"));
+ error = 1;
+ } else {
+ FcPattern* pat = FcNameParse((FcChar8 *) newfont.c_str());
+ FcConfigSubstitute(0, pat, FcMatchPattern);
+ FcDefaultSubstitute(pat);
+ FcPattern *match;
+ fs = FcFontSetCreate();
+ match = FcFontMatch(0, pat, &result);
+ if (match)
+ FcFontSetAdd(fs, match);
+ if (pat)
+ FcPatternDestroy(pat);
+ if(fs){
+ FcChar8* file;
+ if( FcPatternGetString (fs->fonts[0], FC_FILE, 0, &file) == FcResultMatch )
+ error=FT_New_Face(ft_library,(const char*)file,face_index,&face);
+ FcFontSetDestroy(fs);
+ } else
+ synfig::warning("Layer_Freetype: fontconfig: %s",_("empty font set"));
+ }
+ }
+#endif
+
+#ifdef WIN32
+ if(error)error=FT_New_Face(ft_library,("C:\\WINDOWS\\FONTS\\"+newfont).c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("C:\\WINDOWS\\FONTS\\"+newfont+".ttf").c_str(),face_index,&face);
+#else
+
+#ifdef __APPLE__
+ if(error)error=FT_New_Face(ft_library,("~/Library/Fonts/"+newfont).c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("~/Library/Fonts/"+newfont+".ttf").c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("~/Library/Fonts/"+newfont+".dfont").c_str(),face_index,&face);
+
+ if(error)error=FT_New_Face(ft_library,("/Library/Fonts/"+newfont).c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("/Library/Fonts/"+newfont+".ttf").c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("/Library/Fonts/"+newfont+".dfont").c_str(),face_index,&face);
+#endif
+
+ if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/type1/"+newfont).c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/type1/"+newfont+".ttf").c_str(),face_index,&face);
+
+ if(error)error=FT_New_Face(ft_library,("/usr/share/fonts/truetype/"+newfont).c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("/usr/share/fonts/truetype/"+newfont+".ttf").c_str(),face_index,&face);
+
+ if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/TTF/"+newfont).c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/TTF/"+newfont+".ttf").c_str(),face_index,&face);
+
+ if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/truetype/"+newfont).c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/truetype/"+newfont+".ttf").c_str(),face_index,&face);
+
+#endif
+ if(error)
+ {
+ //synfig::error(strprintf("Layer_Freetype:%s (err=%d)",_("Unable to open face."),error));
+ return false;
+ }
+
+ font=newfont;
+
+ needs_sync_=true;
+ return true;
+}
+
+bool
+Layer_Freetype::set_param(const String & param, const ValueBase &value)
+{
+ Mutex::Lock lock(mutex);
+/*
+ if(param=="font" && value.same_type_as(font))
+ {
+ new_font(etl::basename(value.get(font)),style,weight);
+ family=etl::basename(value.get(font));
+ return true;
+ }
+*/
+ IMPORT_PLUS(family,new_font(family,style,weight));
+ IMPORT_PLUS(weight,new_font(family,style,weight));
+ IMPORT_PLUS(style,new_font(family,style,weight));
+ IMPORT_PLUS(size, if(old_version){size/=2.0;} needs_sync_=true );
+ IMPORT_PLUS(text,needs_sync_=true);
+ IMPORT_PLUS(pos,needs_sync_=true);
+ IMPORT(color);
+ IMPORT(invert);
+ IMPORT_PLUS(orient,needs_sync_=true);
+ IMPORT_PLUS(compress,needs_sync_=true);
+ IMPORT_PLUS(vcompress,needs_sync_=true);
+ IMPORT_PLUS(use_kerning,needs_sync_=true);
+ IMPORT_PLUS(grid_fit,needs_sync_=true);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+Layer_Freetype::get_param(const String& param)const
+{
+ EXPORT(font);
+ EXPORT(family);
+ EXPORT(style);
+ EXPORT(weight);
+ EXPORT(size);
+ EXPORT(text);
+ EXPORT(color);
+ EXPORT(pos);
+ EXPORT(orient);
+ EXPORT(compress);
+ EXPORT(vcompress);
+ EXPORT(use_kerning);
+ EXPORT(grid_fit);
+ EXPORT(invert);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+Layer_Freetype::get_param_vocab(void)const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("text")
+ .set_local_name(_("Text"))
+ .set_description(_("Text to Render"))
+ .set_hint("paragraph")
+ );
+
+ ret.push_back(ParamDesc("color")
+ .set_local_name(_("Color"))
+ .set_description(_("Color of the text"))
+ );
+
+ ret.push_back(ParamDesc("family")
+ .set_local_name(_("Font Family"))
+ .set_hint("font_family")
+ );
+
+ ret.push_back(ParamDesc("style")
+ .set_local_name(_("Style"))
+ .set_hint("enum")
+ .add_enum_value(PANGO_STYLE_NORMAL, "normal" ,_("Normal"))
+ .add_enum_value(PANGO_STYLE_OBLIQUE, "oblique" ,_("Oblique"))
+ .add_enum_value(PANGO_STYLE_ITALIC, "italic" ,_("Italic"))
+ );
+
+ ret.push_back(ParamDesc("weight")
+ .set_local_name(_("Weight"))
+ .set_hint("enum")
+ .add_enum_value(200, "ultralight" ,_("Ultralight"))
+ .add_enum_value(300, "light" ,_("light"))
+ .add_enum_value(400, "normal" ,_("Normal"))
+ .add_enum_value(700, "bold" ,_("Bold"))
+ .add_enum_value(800, "ultrabold" ,_("Ultrabold"))
+ .add_enum_value(900, "heavy" ,_("Heavy"))
+ );
+ ret.push_back(ParamDesc("compress")
+ .set_local_name(_("Horizontal Spacing"))
+ .set_description(_("Describes how close glyphs are horizontally"))
+ );
+
+ ret.push_back(ParamDesc("vcompress")
+ .set_local_name(_("Vertical Spacing"))
+ .set_description(_("Describes how close lines of text are vertically"))
+ );
+
+ ret.push_back(ParamDesc("size")
+ .set_local_name(_("Size"))
+ .set_description(_("Size of the text"))
+ .set_hint("size")
+ .set_origin("pos")
+ .set_scalar(1)
+ );
+
+ ret.push_back(ParamDesc("orient")
+ .set_local_name(_("Orientation"))
+ .set_description(_("Text Orientation"))
+ .set_invisible_duck()
+ );
+
+ ret.push_back(ParamDesc("pos")
+ .set_local_name(_("Position"))
+ .set_description(_("Text Position"))
+ );
+
+ ret.push_back(ParamDesc("font")
+ .set_local_name(_("Font"))
+ .set_description(_("Filename of the font to use"))
+ .set_hint("filename")
+ .not_critical()
+ .hidden()
+ );
+
+ ret.push_back(ParamDesc("use_kerning")
+ .set_local_name(_("Kerning"))
+ .set_description(_("Enables/Disables font kerning (If the font supports it)"))
+ );
+
+ ret.push_back(ParamDesc("grid_fit")
+ .set_local_name(_("Sharpen Edges"))
+ .set_description(_("Turn this off if you are going to be animating the text"))
+ );
+ ret.push_back(ParamDesc("invert")
+ .set_local_name(_("Invert"))
+ );
+ return ret;
+}
+
+void
+Layer_Freetype::sync()
+{
+ needs_sync_=false;
+
+
+
+
+}
+
+Color
+Layer_Freetype::get_color(Context context, const synfig::Point &pos)const
+{
+ if(needs_sync_)
+ const_cast<Layer_Freetype*>(this)->sync();
+
+ if(!face)
+ return context.get_color(pos);
+ return context.get_color(pos);
+}
+
+bool
+Layer_Freetype::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ static synfig::RecMutex freetype_mutex;
+
+ if(needs_sync_)
+ const_cast<Layer_Freetype*>(this)->sync();
+
+
+
+
+ int error;
+ Vector size(Layer_Freetype::size*2);
+
+ if(!context.accelerated_render(surface,quality,renddesc,cb))
+ return false;
+
+ if(is_disabled() || text.empty())
+ return true;
+
+ // If there is no font loaded, just bail
+ if(!face)
+ {
+ if(cb)cb->warning(string("Layer_Freetype:")+_("No face loaded, no text will be rendered."));
+ return true;
+ }
+
+ String text(Layer_Freetype::text);
+ if(text=="@_FILENAME_@" && get_canvas() && !get_canvas()->get_file_name().empty())
+ {
+ text=basename(get_canvas()->get_file_name());
+ }
+
+ // Width and Height of a pixel
+ Vector::value_type pw=renddesc.get_w()/(renddesc.get_br()[0]-renddesc.get_tl()[0]);
+ Vector::value_type ph=renddesc.get_h()/(renddesc.get_br()[1]-renddesc.get_tl()[1]);
+
+ // Calculate character width and height
+ int w=abs(round_to_int(size[0]*pw));
+ int h=abs(round_to_int(size[1]*ph));
+
+ //int bx=(int)((pos[0]-renddesc.get_tl()[0])*pw*64+0.5);
+ //int by=(int)((pos[1]-renddesc.get_tl()[1])*ph*64+0.5);
+ int bx=0;
+ int by=0;
+
+ // If the font is the size of a pixel, don't bother rendering any text
+ if(w<=1 || h<=1)
+ {
+ if(cb)cb->warning(string("Layer_Freetype:")+_("Text too small, no text will be rendered."));
+ return true;
+ }
+
+ synfig::RecMutex::Lock lock(freetype_mutex);
+
+#define CHAR_RESOLUTION (64)
+ error = FT_Set_Char_Size(
+ face, // handle to face object
+ (int)CHAR_RESOLUTION, // char_width in 1/64th of points
+ (int)CHAR_RESOLUTION, // char_height in 1/64th of points
+ round_to_int(abs(size[0]*pw*CHAR_RESOLUTION)), // horizontal device resolution
+ round_to_int(abs(size[1]*ph*CHAR_RESOLUTION)) ); // vertical device resolution
+
+ // Here is where we can compensate for the
+ // error in freetype's rendering engine.
+ const float xerror(abs(size[0]*pw)/(float)face->size->metrics.x_ppem/1.13f/0.996);
+ const float yerror(abs(size[1]*ph)/(float)face->size->metrics.y_ppem/1.13f/0.996);
+ //synfig::info("xerror=%f, yerror=%f",xerror,yerror);
+ const float compress(Layer_Freetype::compress*xerror);
+ const float vcompress(Layer_Freetype::vcompress*yerror);
+
+ if(error)
+ {
+ if(cb)cb->warning(string("Layer_Freetype:")+_("Unable to set face size.")+strprintf(" (err=%d)",error));
+ }
+
+ FT_GlyphSlot slot = face->glyph; // a small shortcut
+ FT_UInt glyph_index(0);
+ FT_UInt previous(0);
+ int u,v;
+
+ std::list<TextLine> lines;
+
+ /*
+ -- ** -- CREATE GLYPHS -------------------------------------------------------
+ */
+
+ lines.push_front(TextLine());
+ string::const_iterator iter;
+ for (iter=text.begin(); iter!=text.end(); ++iter)
+ {
+ int multiplier(1);
+ if(*iter=='\n')
+ {
+ lines.push_front(TextLine());
+ bx=0;
+ by=0;
+ previous=0;
+ continue;
+ }
+ if(*iter=='\t')
+ {
+ multiplier=8;
+ glyph_index = FT_Get_Char_Index( face, ' ' );
+ }
+ else
+ glyph_index = FT_Get_Char_Index( face, *iter );
+
+ // retrieve kerning distance and move pen position
+ if ( FT_HAS_KERNING(face) && use_kerning && previous && glyph_index )
+ {
+ FT_Vector delta;
+
+ if(grid_fit)
+ FT_Get_Kerning( face, previous, glyph_index, ft_kerning_default, &delta );
+ else
+ FT_Get_Kerning( face, previous, glyph_index, ft_kerning_unfitted, &delta );
+
+ if(compress<1.0f)
+ {
+ bx += round_to_int(delta.x*compress);
+ by += round_to_int(delta.y*compress);
+ }
+ else
+ {
+ bx += delta.x;
+ by += delta.y;
+ }
+ }
+
+ Glyph curr_glyph;
+
+ // store current pen position
+ curr_glyph.pos.x = bx;
+ curr_glyph.pos.y = by;
+
+ // load glyph image into the slot. DO NOT RENDER IT !!
+ if(grid_fit)
+ error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT);
+ else
+ error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT|FT_LOAD_NO_HINTING );
+ if (error) continue; // ignore errors, jump to next glyph
+
+ // extract glyph image and store it in our table
+ error = FT_Get_Glyph( face->glyph, &curr_glyph.glyph );
+ if (error) continue; // ignore errors, jump to next glyph
+
+ // record current glyph index
+ previous = glyph_index;
+
+ // Update the line width
+ lines.front().width=bx+slot->advance.x;
+
+ // increment pen position
+ if(multiplier>1)
+ bx += round_to_int(slot->advance.x*multiplier*compress)-bx%round_to_int(slot->advance.x*multiplier*compress);
+ else
+ bx += round_to_int(slot->advance.x*compress*multiplier);
+
+ //bx += round_to_int(slot->advance.x*compress*multiplier);
+ //by += round_to_int(slot->advance.y*compress);
+ by += slot->advance.y*multiplier;
+
+ lines.front().glyph_table.push_back(curr_glyph);
+
+ }
+
+
+ //float string_height;
+ //string_height=(((lines.size()-1)*face->size->metrics.height+lines.back().actual_height()));
+
+ //int string_height=face->size->metrics.ascender;
+//#define METRICS_SCALE_ONE (65536.0f)
+#define METRICS_SCALE_ONE ((float)(1<<16))
+
+ float line_height;
+ line_height=vcompress*((float)face->height*(((float)face->size->metrics.y_scale/METRICS_SCALE_ONE)));
+
+ int string_height;
+ string_height=round_to_int(((lines.size()-1)*line_height+lines.back().actual_height()));
+ //synfig::info("string_height=%d",string_height);
+ //synfig::info("line_height=%f",line_height);
+
+ /*
+ -- ** -- RENDER THE GLYPHS ---------------------------------------------------
+ */
+
+ Surface src_;
+ Surface *src_surface;
+
+ src_surface=surface;
+
+ if(invert)
+ {
+ src_=*surface;
+ Surface::alpha_pen pen(surface->begin(),get_amount(),get_blend_method());
+
+ surface->fill(color,pen,src_.get_w(),src_.get_h());
+
+ src_surface=&src_;
+ }
+
+ {
+ std::list<TextLine>::iterator iter;
+ int curr_line;
+ for(curr_line=0,iter=lines.begin();iter!=lines.end();++iter,curr_line++)
+ {
+ bx=round_to_int((pos[0]-renddesc.get_tl()[0])*pw*CHAR_RESOLUTION-orient[0]*iter->width);
+ by=round_to_int((pos[1]-renddesc.get_tl()[1])*ph*CHAR_RESOLUTION+(1.0-orient[1])*string_height-line_height*curr_line);
+ //by=round_to_int(vcompress*((pos[1]-renddesc.get_tl()[1])*ph*64+(1.0-orient[1])*string_height-face->size->metrics.height*curr_line));
+ //synfig::info("curr_line=%d, bx=%d, by=%d",curr_line,bx,by);
+
+ std::vector<Glyph>::iterator iter2;
+ for(iter2=iter->glyph_table.begin();iter2!=iter->glyph_table.end();++iter2)
+ {
+ FT_Glyph image(iter2->glyph);
+ FT_Vector pen;
+ FT_BitmapGlyph bit;
+
+ pen.x = bx + iter2->pos.x;
+ pen.y = by + iter2->pos.y;
+
+ //synfig::info("GLYPH: pen.x=%d, pen,y=%d",curr_line,(pen.x+32)>>6,(pen.y+32)>>6);
+
+ error = FT_Glyph_To_Bitmap( &image, ft_render_mode_normal,0/*&pen*/, 1 );
+ if(error) { FT_Done_Glyph( image ); continue; }
+
+ bit = (FT_BitmapGlyph)image;
+
+ for(v=0;v<bit->bitmap.rows;v++)
+ for(u=0;u<bit->bitmap.width;u++)
+ {
+ int x=u+((pen.x+32)>>6)+ bit->left;
+ int y=v+((pen.y+32)>>6)- bit->top;
+ if( y>=0 &&
+ x>=0 &&
+ y<surface->get_h() &&
+ x<surface->get_w())
+ {
+ float myamount=(float)bit->bitmap.buffer[v*bit->bitmap.pitch+u]/255.0f;
+ if(invert)
+ myamount=1.0f-myamount;
+ (*surface)[y][x]=Color::blend(color,(*src_surface)[y][x],myamount*get_amount(),get_blend_method());
+ }
+ }
+
+ FT_Done_Glyph( image );
+ }
+ //iter->clear_and_free();
+ }
+ }
+
+
+ return true;
+}
+
+synfig::Rect
+Layer_Freetype::get_bounding_rect()const
+{
+ if(needs_sync_)
+ const_cast<Layer_Freetype*>(this)->sync();
+// if(!is_disabled())
+ return synfig::Rect::full_plane();
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file lyr_freetype.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LYR_FREETYPE_H
+#define __SYNFIG_LYR_FREETYPE_H
+
+/* === H E A D E R S ======================================================= */
+
+//#ifdef __APPLE__
+//#define USE_MAC_FT_FUNCS (1)
+//#endif
+
+#include <synfig/layer_composite.h>
+#include <synfig/vector.h>
+#include <synfig/color.h>
+#include <synfig/string.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_GLYPH_H
+#include <vector>
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/canvas.h>
+
+
+#include <ETL/misc>
+
+#ifdef USE_MAC_FT_FUNCS
+ #include <CoreServices/CoreServices.h>
+ #include FT_MAC_H
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+
+struct Glyph
+{
+ FT_Glyph glyph;
+ FT_Vector pos;
+ //int width;
+};
+struct TextLine
+{
+ int width;
+ std::vector<Glyph> glyph_table;
+
+ TextLine():width(0) { }
+ void clear_and_free();
+
+ int actual_height()const
+ {
+ int height(0);
+
+ std::vector<Glyph>::const_iterator iter;
+ for(iter=glyph_table.begin();iter!=glyph_table.end();++iter)
+ {
+ FT_BBox glyph_bbox;
+
+ //FT_Glyph_Get_CBox( glyphs[n], ft_glyph_bbox_pixels, &glyph_bbox );
+ FT_Glyph_Get_CBox( iter->glyph, ft_glyph_bbox_subpixels, &glyph_bbox );
+
+ if(glyph_bbox.yMax>height)
+ height=glyph_bbox.yMax;
+ }
+ return height;
+ }
+};
+
+
+class Layer_Freetype : public synfig::Layer_Composite, public synfig::Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+private:
+
+ FT_Face face;
+ synfig::String font;
+ synfig::String family;
+ synfig::String text;
+ synfig::Vector size;
+ synfig::Vector orient;
+ synfig::Color color;
+ synfig::Point pos;
+ synfig::Real compress;
+ synfig::Real vcompress;
+
+ int style;
+ int weight;
+ bool use_kerning;
+ bool grid_fit;
+ bool invert;
+
+ bool old_version;
+ bool needs_sync_;
+
+ void sync();
+
+ mutable synfig::Mutex mutex;
+
+public:
+ Layer_Freetype();
+ virtual ~Layer_Freetype();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+ virtual ValueBase get_param(const String & param)const;
+ virtual Color get_color(Context context, const synfig::Point &pos)const;
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+
+ virtual Vocab get_param_vocab()const;
+
+ virtual bool set_version(const String &ver){if(ver=="0.1")old_version=true;return true;}
+ virtual void reset_version(){old_version=false;}
+
+ virtual synfig::Rect get_bounding_rect()const;
+
+private:
+ void new_font(const synfig::String &family, int style=0, int weight=400);
+ bool new_font_(const synfig::String &family, int style=0, int weight=400);
+ bool new_face(const synfig::String &newfont);
+};
+
+extern FT_Library ft_library;
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+; The stuff to install
+Section "lyr_freetype" Sec_lyr_freetype
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=lyr_freetype.dll "src\modules\lyr_freetype\.libs\liblyr_freetype-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "lyr_freetype"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file lyr_freetype/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <synfig/module.h>
+#include "lyr_freetype.h"
+#include <iostream>
+#include <ETL/stringf>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#endif
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+FT_Library ft_library;
+
+/* === E N T R Y P O I N T ================================================= */
+
+bool freetype_constructor(synfig::ProgressCallback *cb)
+{
+ int error;
+ if(cb)cb->task("Initializing FreeType...");
+ if ( (error = FT_Init_FreeType( &ft_library )) )
+ {
+ if(cb)cb->error(strprintf("Layer_Freetype: FreeType initialization failed. (err=%d)",error));
+ return false;
+ }
+ return true;
+}
+
+void freetype_destructor()
+{
+ std::cerr<<"freetype_destructor()"<<std::endl;
+}
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(liblyr_freetype)
+ MODULE_NAME("FreeType Font Layer")
+ MODULE_DESCRIPTION("Provides a font rendering layer via FreeType")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+
+ MODULE_CONSTRUCTOR(freetype_constructor)
+ MODULE_DESTRUCTOR(freetype_destructor)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(liblyr_freetype)
+ BEGIN_LAYERS
+ LAYER(Layer_Freetype)
+ LAYER_ALIAS(Layer_Freetype,"Text")
+ END_LAYERS
+MODULE_INVENTORY_END
--- /dev/null
+Section "un.lyr_freetype"
+ Delete "$INSTDIR\lib\synfig\modules\lyr_freetype.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+module_LTLIBRARIES = liblyr_std.la
+liblyr_std_la_SOURCES = main.cpp timeloop.cpp timeloop.h warp.cpp warp.h xorpattern.cpp booleancurve.h booleancurve.cpp bevel.cpp bevel.h shade.cpp shade.h twirl.cpp twirl.h stretch.cpp stretch.h xorpattern.h clamp.cpp clamp.h supersample.cpp supersample.h insideout.cpp insideout.h julia.cpp julia.h rotate.cpp rotate.h mandelbrot.cpp mandelbrot.h zoom.h zoom.cpp import.cpp import.h translate.h translate.cpp sphere_distort.h sphere_distort.cpp
+liblyr_std_la_CXXFLAGS = @SYNFIG_CFLAGS@
+liblyr_std_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+liblyr_std_la_LDFLAGS = -module -no-undefined
+EXTRA_DIST= lyr_std.nsh unlyr_std.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file bevel.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "bevel.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/segment.h>
+
+#include <cstring>
+#include <ETL/pen>
+#include <ETL/misc>
+
+#endif
+
+using namespace synfig;
+using namespace etl;
+using namespace std;
+
+/*#define TYPE_BOX 0
+#define TYPE_FASTGUASSIAN 1
+#define TYPE_FASTGAUSSIAN 1
+#define TYPE_CROSS 2
+#define TYPE_GUASSIAN 3
+#define TYPE_GAUSSIAN 3
+#define TYPE_DISC 4
+*/
+
+/* -- G L O B A L S --------------------------------------------------------- */
+
+SYNFIG_LAYER_INIT(Layer_Bevel);
+SYNFIG_LAYER_SET_NAME(Layer_Bevel,"bevel");
+SYNFIG_LAYER_SET_LOCAL_NAME(Layer_Bevel,_("Bevel"));
+SYNFIG_LAYER_SET_CATEGORY(Layer_Bevel,_("Stylize"));
+SYNFIG_LAYER_SET_VERSION(Layer_Bevel,"0.2");
+SYNFIG_LAYER_SET_CVS_ID(Layer_Bevel,"$Id$");
+
+/* -- F U N C T I O N S ----------------------------------------------------- */
+
+inline void clamp(synfig::Vector &v)
+{
+ if(v[0]<0.0)v[0]=0.0;
+ if(v[1]<0.0)v[1]=0.0;
+}
+
+Layer_Bevel::Layer_Bevel():
+ Layer_Composite (0.75,Color::BLEND_ONTO),
+ softness(0.1),
+ type(Blur::FASTGAUSSIAN),
+ color1(Color::white()),
+ color2(Color::black()),
+ depth(0.2)
+{
+ angle=Angle::deg(135);
+ calc_offset();
+ use_luma=false;
+ solid=false;
+}
+
+void
+Layer_Bevel::calc_offset()
+{
+ offset[0]=Angle::cos(angle).get()*depth;
+ offset[1]=Angle::sin(angle).get()*depth;
+
+ offset45[0]=Angle::cos(angle-Angle::deg(45)).get()*depth*0.707106781;
+ offset45[1]=Angle::sin(angle-Angle::deg(45)).get()*depth*0.707106781;
+}
+
+bool
+Layer_Bevel::set_param(const String ¶m, const ValueBase &value)
+{
+ IMPORT_PLUS(softness,softness=softness>0?softness:0);
+ IMPORT(color1);
+ IMPORT(color2);
+ IMPORT_PLUS(depth,calc_offset());
+ IMPORT_PLUS(angle,calc_offset());
+ IMPORT(type);
+ IMPORT(use_luma);
+ IMPORT(solid);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+Layer_Bevel::get_param(const String ¶m)const
+{
+ EXPORT(type);
+ EXPORT(softness);
+ EXPORT(color1);
+ EXPORT(color2);
+ EXPORT(depth);
+ EXPORT(angle);
+ EXPORT(use_luma);
+ EXPORT(solid);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Color
+Layer_Bevel::get_color(Context context, const Point &pos)const
+{
+ const Vector size(softness,softness);
+ Point blurpos = Blur(size,type)(pos);
+
+ if(get_amount()==0.0)
+ return context.get_color(pos);
+
+ Color shade;
+
+ Real hi_alpha(1.0f-context.get_color(blurpos+offset).get_a());
+ Real lo_alpha(1.0f-context.get_color(blurpos-offset).get_a());
+
+ Real shade_alpha(hi_alpha-lo_alpha);
+ if(shade_alpha>0)
+ shade=color1,shade.set_a(shade_alpha);
+ else
+ shade=color2,shade.set_a(-shade_alpha);
+
+ return Color::blend(shade,context.get_color(pos),get_amount(),get_blend_method());
+}
+
+bool
+Layer_Bevel::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ int x,y;
+ SuperCallback stageone(cb,0,5000,10000);
+ SuperCallback stagetwo(cb,5000,10000,10000);
+
+ const int w = renddesc.get_w(),
+ h = renddesc.get_h();
+ const Real pw = renddesc.get_pw(),
+ ph = renddesc.get_ph();
+ const Vector size(softness,softness);
+
+ RendDesc workdesc(renddesc);
+ Surface worksurface;
+ etl::surface<float> blurred;
+
+ //callbacks depend on how long the blur takes
+ if(size[0] || size[1])
+ {
+ if(type == Blur::DISC)
+ {
+ stageone = SuperCallback(cb,0,5000,10000);
+ stagetwo = SuperCallback(cb,5000,10000,10000);
+ }
+ else
+ {
+ stageone = SuperCallback(cb,0,9000,10000);
+ stagetwo = SuperCallback(cb,9000,10000,10000);
+ }
+ }
+ else
+ {
+ stageone = SuperCallback(cb,0,9999,10000);
+ stagetwo = SuperCallback(cb,9999,10000,10000);
+ }
+
+ //expand the working surface to accommodate the blur
+
+ //the expanded size = 1/2 the size in each direction rounded up
+ int halfsizex = (int) (abs(size[0]*.5/pw) + 3),
+ halfsizey = (int) (abs(size[1]*.5/ph) + 3);
+
+ int offset_u(round_to_int(offset[0]/pw)),offset_v(round_to_int(offset[1]/ph));
+ int offset_w(w+abs(offset_u)*2),offset_h(h+abs(offset_v)*2);
+
+ workdesc.set_subwindow(
+ -abs(offset_u),
+ -abs(offset_v),
+ w+abs(offset_u),
+ h+abs(offset_v)
+ );
+
+ //expand by 1/2 size in each direction on either side
+ switch(type)
+ {
+ case Blur::DISC:
+ case Blur::BOX:
+ case Blur::CROSS:
+ {
+ workdesc.set_subwindow(-max(1,halfsizex),-max(1,halfsizey),offset_w+2*max(1,halfsizex),offset_h+2*max(1,halfsizey));
+ break;
+ }
+ case Blur::FASTGAUSSIAN:
+ {
+ if(quality < 4)
+ {
+ halfsizex*=2;
+ halfsizey*=2;
+ }
+ workdesc.set_subwindow(-max(1,halfsizex),-max(1,halfsizey),offset_w+2*max(1,halfsizex),offset_h+2*max(1,halfsizey));
+ break;
+ }
+ case Blur::GAUSSIAN:
+ {
+ #define GAUSSIAN_ADJUSTMENT (0.05)
+ Real pw = (Real)workdesc.get_w()/(workdesc.get_br()[0]-workdesc.get_tl()[0]);
+ Real ph = (Real)workdesc.get_h()/(workdesc.get_br()[1]-workdesc.get_tl()[1]);
+
+ pw=pw*pw;
+ ph=ph*ph;
+
+ halfsizex = (int)(abs(pw)*size[0]*GAUSSIAN_ADJUSTMENT+0.5);
+ halfsizey = (int)(abs(ph)*size[1]*GAUSSIAN_ADJUSTMENT+0.5);
+
+ halfsizex = (halfsizex + 1)/2;
+ halfsizey = (halfsizey + 1)/2;
+ workdesc.set_subwindow( -halfsizex, -halfsizey, offset_w+2*halfsizex, offset_h+2*halfsizey );
+
+ break;
+ }
+ }
+
+ //render the background onto the expanded surface
+ if(!context.accelerated_render(&worksurface,quality,workdesc,&stageone))
+ return false;
+
+ // Copy over the alpha
+ blurred.set_wh(worksurface.get_w(),worksurface.get_h());
+ if(!use_luma)
+ {
+ for(int j=0;j<worksurface.get_h();j++)
+ for(int i=0;i<worksurface.get_w();i++)
+ {
+ blurred[j][i]=worksurface[j][i].get_a();
+ }
+ }
+ else
+ {
+ for(int j=0;j<worksurface.get_h();j++)
+ for(int i=0;i<worksurface.get_w();i++)
+ {
+ blurred[j][i]=worksurface[j][i].get_a()*worksurface[j][i].get_y();
+ }
+ }
+
+ //blur the image
+ Blur(size,type,&stagetwo)(blurred,workdesc.get_br()-workdesc.get_tl(),blurred);
+
+ //be sure the surface is of the correct size
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+
+ int u = halfsizex+abs(offset_u), v = halfsizey+abs(offset_v);
+ for(y=0;y<renddesc.get_h();y++,v++)
+ {
+ u = halfsizex+abs(offset_u);
+ for(x=0;x<renddesc.get_w();x++,u++)
+ {
+ Real alpha(0);
+ Color shade;
+
+ {
+ const float u2(offset[0]/pw),v2(offset[1]/ph);
+ alpha+=1.0f-blurred.linear_sample(u2+u,v2+v);
+ }
+ {
+ const float u2(-offset[0]/pw),v2(-offset[1]/ph);
+ alpha-=1.0f-blurred.linear_sample(u2+u,v2+v);
+ }
+ {
+ const float u2(offset45[0]/pw),v2(offset45[1]/ph);
+ alpha+=1.0f-blurred.linear_sample(u2+u,v2+v)*0.5f;
+ }
+ {
+ const float u2(offset45[1]/ph),v2(-offset45[0]/pw);
+ alpha+=1.0f-blurred.linear_sample(u2+u,v2+v)*0.5f;
+ }
+ {
+ const float u2(-offset45[0]/pw),v2(-offset45[1]/ph);
+ alpha-=1.0f-blurred.linear_sample(u2+u,v2+v)*0.5f;
+ }
+ {
+ const float u2(-offset45[1]/ph),v2(offset45[0]/pw);
+ alpha-=1.0f-blurred.linear_sample(u2+u,v2+v)*0.5f;
+ }
+
+ if(solid)
+ {
+ alpha/=4.0f;
+ alpha+=0.5f;
+ shade=Color::blend(color1,color2,alpha,Color::BLEND_STRAIGHT);
+ }
+ else
+ {
+ alpha/=2;
+ if(alpha>0)
+ shade=color1,shade.set_a(shade.get_a()*alpha);
+ else
+ shade=color2,shade.set_a(shade.get_a()*-alpha);
+ }
+
+
+
+ if(shade.get_a())
+ {
+ (*surface)[y][x]=Color::blend(shade,worksurface[v][u],get_amount(),get_blend_method());
+ }
+ else (*surface)[y][x] = worksurface[v][u];
+ }
+ }
+
+ if(cb && !cb->amount_complete(10000,10000))
+ {
+ //if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ return true;
+}
+
+Layer::Vocab
+Layer_Bevel::get_param_vocab(void)const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("type")
+ .set_local_name(_("Type"))
+ .set_description(_("Type of blur to use"))
+ .set_hint("enum")
+ .add_enum_value(Blur::BOX,"box",_("Box Blur"))
+ .add_enum_value(Blur::FASTGAUSSIAN,"fastgaussian",_("Fast Gaussian Blur"))
+ .add_enum_value(Blur::CROSS,"cross",_("Cross-Hatch Blur"))
+ .add_enum_value(Blur::GAUSSIAN,"gaussian",_("Gaussian Blur"))
+ .add_enum_value(Blur::DISC,"disc",_("Disc Blur"))
+ );
+
+ ret.push_back(ParamDesc("color1")
+ .set_local_name(_("Hi-Color"))
+ );
+ ret.push_back(ParamDesc("color2")
+ .set_local_name(_("Lo-Color"))
+ );
+ ret.push_back(ParamDesc("angle")
+ .set_local_name(_("Light Angle"))
+ );
+ ret.push_back(ParamDesc("depth")
+ .set_is_distance()
+ .set_local_name(_("Depth of Bevel"))
+ );
+ ret.push_back(ParamDesc("softness")
+ .set_is_distance()
+ .set_local_name(_("Softness"))
+ );
+ ret.push_back(ParamDesc("use_luma")
+ .set_local_name(_("Use Luma"))
+ );
+ ret.push_back(ParamDesc("solid")
+ .set_local_name(_("Solid"))
+ );
+
+ return ret;
+}
+
+Rect
+Layer_Bevel::get_full_bounding_rect(Context context)const
+{
+ if(is_disabled())
+ return context.get_full_bounding_rect();
+
+ Rect under(context.get_full_bounding_rect());
+
+ if(Color::is_onto(get_blend_method()))
+ return under;
+
+ Rect bounds(under.expand(softness));
+ bounds.expand_x(abs(depth));
+ bounds.expand_y(abs(depth));
+
+ return bounds;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file bevel.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifndef __SYNFIG_LAYER_BEVEL_H__
+#define __SYNFIG_LAYER_BEVEL_H__
+
+/* -- H E A D E R S --------------------------------------------------------- */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+#include <synfig/blur.h>
+#include <synfig/angle.h>
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class Layer_Bevel : public synfig::Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+private:
+ synfig::Real softness;
+ int type;
+
+ synfig::Color color1;
+ synfig::Color color2;
+
+ synfig::Angle angle;
+ synfig::Real depth;
+
+ synfig::Vector offset;
+ synfig::Vector offset45;
+
+ bool use_luma;
+ bool solid;
+
+ void calc_offset();
+public:
+ Layer_Bevel();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+
+ virtual synfig::Rect get_full_bounding_rect(Context context)const;
+ virtual Vocab get_param_vocab()const;
+}; // END of class Blur
+
+/* -- E X T E R N S --------------------------------------------------------- */
+
+/* -- E N D ----------------------------------------------------------------- */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file booleancurve.cpp
+** \brief Boolean Curve Implementation File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "booleancurve.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+BooleanCurve::BooleanCurve()
+{
+}
+
+BooleanCurve::~BooleanCurve()
+{
+}
+
+bool BooleanCurve::set_param(const String & param, const synfig::ValueBase &value)
+{
+ if(param=="regions" && value.same_type_as(regions))
+ {
+ vector<BLinePoint> bv;
+ int size = value.get_list().size();
+
+ const vector<ValueBase> &vlist = value.get_list();
+
+ regions.clear();
+ for(int i = 0; i < size; ++i)
+ {
+ regions.push_back(vector<BLinePoint>(vlist[i].get_list().begin(),vlist[i].get_list().end()));
+ }
+ return true;
+ }
+
+ return Layer_Shape::set_param(param,value);
+}
+
+ValueBase BooleanCurve::get_param(const String & param)const
+{
+ EXPORT(regions);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Shape::get_param(param);
+}
+
+Layer::Vocab BooleanCurve::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Shape::get_param_vocab());
+
+ ret.push_back(ParamDesc("regions")
+ .set_local_name(_("Region Set"))
+ .set_description(_("Set of regions to combine"))
+ );
+
+ return ret;
+}
+
+Color BooleanCurve::get_color(Context /*context*/, const Point &/*pos*/)const
+{
+ Color c(Color::alpha());
+
+ return c;
+}
+
+bool BooleanCurve::accelerated_render(Context /*context*/,Surface */*surface*/,int /*quality*/, const RendDesc &/*renddesc*/, ProgressCallback */*cb*/)const
+{
+ return false;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file booleancurve.h
+** \brief Boolean Curve Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_BOOLEAN_CURVE_H
+#define __SYNFIG_BOOLEAN_CURVE_H
+
+/* === H E A D E R S ======================================================= */
+#include <synfig/layer_shape.h>
+#include <synfig/blinepoint.h>
+
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+namespace synfig
+{
+
+class BooleanCurve : public Layer_Shape
+{
+ //dynamic list of regions and such
+ typedef std::vector< std::vector<BLinePoint> > region_list_type;
+ region_list_type regions;
+
+ enum BOOLEAN_OP
+ {
+ Union = 0,
+ Intersection,
+ MutualExclude,
+ Num_Boolean_Ops
+ };
+
+ int operation;
+
+public:
+
+ BooleanCurve();
+ ~BooleanCurve();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Vocab get_param_vocab()const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+};
+
+} //end of namespace synfig
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file clamp.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "clamp.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Layer_Clamp);
+SYNFIG_LAYER_SET_NAME(Layer_Clamp,"clamp");
+SYNFIG_LAYER_SET_LOCAL_NAME(Layer_Clamp,_("Clamp"));
+SYNFIG_LAYER_SET_CATEGORY(Layer_Clamp,_("Filters"));
+SYNFIG_LAYER_SET_VERSION(Layer_Clamp,"0.2");
+SYNFIG_LAYER_SET_CVS_ID(Layer_Clamp,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Layer_Clamp::Layer_Clamp():
+ invert_negative(false),
+ clamp_ceiling(true),
+ ceiling(1.0f),
+ floor(0.0f)
+{
+}
+
+inline Color
+Layer_Clamp::clamp_color(const Color &in)const
+{
+ Color ret(in);
+
+ if(ret.get_a()==0)
+ return Color::alpha();
+
+ if(invert_negative)
+ {
+ if(ret.get_a()<floor)
+ ret=-ret;
+
+ if(ret.get_r()<floor)
+ {
+ ret.set_g(ret.get_g()-ret.get_r());
+ ret.set_b(ret.get_b()-ret.get_r());
+ ret.set_r(floor);
+ }
+ if(ret.get_g()<floor)
+ {
+ ret.set_r(ret.get_r()-ret.get_g());
+ ret.set_b(ret.get_b()-ret.get_g());
+ ret.set_g(floor);
+ }
+ if(ret.get_b()<floor)
+ {
+ ret.set_g(ret.get_g()-ret.get_b());
+ ret.set_r(ret.get_r()-ret.get_b());
+ ret.set_b(floor);
+ }
+ }
+ else
+ {
+ if(ret.get_r()<floor) ret.set_r(floor);
+ if(ret.get_g()<floor) ret.set_g(floor);
+ if(ret.get_b()<floor) ret.set_b(floor);
+ if(ret.get_a()<floor) ret.set_a(floor);
+ }
+
+ if(clamp_ceiling)
+ {
+ if(ret.get_r()>ceiling) ret.set_r(ceiling);
+ if(ret.get_g()>ceiling) ret.set_g(ceiling);
+ if(ret.get_b()>ceiling) ret.set_b(ceiling);
+ if(ret.get_a()>ceiling) ret.set_a(ceiling);
+ }
+ return ret;
+}
+
+bool
+Layer_Clamp::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(invert_negative);
+ IMPORT(clamp_ceiling);
+ IMPORT(ceiling);
+ IMPORT(floor);
+
+ return false;
+}
+
+ValueBase
+Layer_Clamp::get_param(const String ¶m)const
+{
+ EXPORT(invert_negative);
+ EXPORT(clamp_ceiling);
+
+ EXPORT(ceiling);
+ EXPORT(floor);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return ValueBase();
+}
+
+Layer::Vocab
+Layer_Clamp::get_param_vocab()const
+{
+ Layer::Vocab ret;
+
+ ret.push_back(ParamDesc("invert_negative")
+ .set_local_name(_("Invert Negative"))
+ );
+
+ ret.push_back(ParamDesc("clamp_ceiling")
+ .set_local_name(_("Clamp Ceiling"))
+ );
+
+ ret.push_back(ParamDesc("ceiling")
+ .set_local_name(_("Ceiling"))
+ );
+
+ ret.push_back(ParamDesc("floor")
+ .set_local_name(_("Floor"))
+ );
+
+ return ret;
+}
+
+Color
+Layer_Clamp::get_color(Context context, const Point &pos)const
+{
+ return clamp_color(context.get_color(pos));
+}
+
+bool
+Layer_Clamp::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+
+ int x,y;
+
+ Surface::pen pen(surface->begin());
+
+ for(y=0;y<renddesc.get_h();y++,pen.inc_y(),pen.dec_x(x))
+ for(x=0;x<renddesc.get_w();x++,pen.inc_x())
+ pen.put_value(clamp_color(pen.get_value()));
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
+
+
+Rect
+Layer_Clamp::get_full_bounding_rect(Context context)const
+{
+ return context.get_full_bounding_rect();
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file clamp.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LAYER_SOLIDCOLOR_H
+#define __SYNFIG_LAYER_SOLIDCOLOR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Layer_Clamp : public Layer
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ bool invert_negative;
+ bool clamp_ceiling;
+
+ float ceiling;
+ float floor;
+
+ Color clamp_color(const Color &in)const;
+
+public:
+
+ Layer_Clamp();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+
+ virtual Rect get_full_bounding_rect(Context context)const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+
+ virtual Vocab get_param_vocab()const;
+}; // END of class Layer_Clamp
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file import.cpp
+** \brief Image Import Layer Implementation
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "import.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/canvas.h>
+
+#endif
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Import);
+SYNFIG_LAYER_SET_NAME(Import,"import");
+SYNFIG_LAYER_SET_LOCAL_NAME(Import,_("Import Image"));
+SYNFIG_LAYER_SET_CATEGORY(Import,_("Other"));
+SYNFIG_LAYER_SET_VERSION(Import,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Import,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Import::Import()
+{
+ time_offset=0;
+}
+
+Import::~Import()
+{
+}
+
+void
+Import::on_canvas_set()
+{
+ if(get_canvas())set_param("filename",filename);
+}
+
+bool
+Import::set_param(const String & param, const ValueBase &value)
+{
+ try{
+ IMPORT(time_offset);
+ if(param=="filename" && value.same_type_as(filename))
+ {
+ if(!get_canvas())
+ {
+ filename=value.get(filename);
+ importer=0;
+ surface.clear();
+ return true;
+ }
+
+ String newfilename=value.get(string());
+ String filename_with_path;
+
+ // Get rid of any %20 crap
+ {
+ String::size_type n;
+ while((n=newfilename.find("%20"))!=String::npos)
+ newfilename.replace(n,3," ");
+ }
+
+ //if(get_canvas()->get_file_path()==dirname(newfilename))
+ //{
+ // synfig::info("Image seems to be in local directory. Adjusting path...");
+ // newfilename=basename(newfilename);
+ //}
+
+#ifndef WIN32
+ if(is_absolute_path(newfilename))
+ {
+ string curpath(cleanup_path(absolute_path(get_canvas()->get_file_path())));
+ while(basename(curpath)==".")curpath=dirname(curpath);
+
+ newfilename=relative_path(curpath,newfilename);
+ synfig::info("basename(curpath)=%s, Path adjusted to %s",basename(curpath).c_str(),newfilename.c_str());
+ }
+#endif
+
+ if(filename.empty())
+ filename=newfilename;
+
+ if(newfilename.empty())
+ {
+ filename=newfilename;
+ importer=0;
+ surface.clear();
+ return true;
+ }
+
+ // If we are already loaded, don't reload
+ if(filename==newfilename && importer)
+ {
+ synfig::warning(strprintf(_("Filename seems to already be set to \"%s\" (%s)"),filename.c_str(),newfilename.c_str()));
+ return true;
+ }
+
+ assert(get_canvas());
+
+ if(is_absolute_path(newfilename))
+ filename_with_path=newfilename;
+ else
+ filename_with_path=get_canvas()->get_file_path()+ETL_DIRECTORY_SEPARATOR+newfilename;
+
+ handle<Importer> newimporter;
+
+ newimporter=Importer::open(absolute_path(filename_with_path));
+
+ if(!newimporter)
+ {
+ newimporter=Importer::open(get_canvas()->get_file_path()+ETL_DIRECTORY_SEPARATOR+basename(newfilename));
+ if(!newimporter)
+ {
+ synfig::error(strprintf("Unable to create an importer object with file \"%s\"",filename_with_path.c_str()));
+ surface.clear();
+ return false;
+ }
+ }
+
+ surface.clear();
+ if(!newimporter->get_frame(surface,Time(0)))
+ {
+ synfig::warning(strprintf("Unable to get frame from \"%s\"",filename_with_path.c_str()));
+ }
+
+ importer=newimporter;
+ filename=newfilename;
+ abs_filename=absolute_path(filename_with_path);
+
+ return true;
+ }
+ } catch(...) { set_amount(0); return false; }
+
+ return Layer_Bitmap::set_param(param,value);
+}
+
+ValueBase
+Import::get_param(const String & param)const
+{
+ EXPORT(time_offset);
+
+ if(get_canvas())
+ {
+ if(param=="filename")
+ {
+ string curpath(cleanup_path(absolute_path(get_canvas()->get_file_path())));
+ return relative_path(curpath,abs_filename);
+ }
+ }
+ else
+ EXPORT(filename);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Bitmap::get_param(param);
+}
+
+Layer::Vocab
+Import::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Bitmap::get_param_vocab());
+
+ ret.push_back(ParamDesc("filename")
+ .set_local_name(_("Filename"))
+ .set_description(_("File to import"))
+ .set_hint("filename")
+ );
+ ret.push_back(ParamDesc("time_offset")
+ .set_local_name(_("Time Offset"))
+ );
+
+ return ret;
+}
+
+void
+Import::set_time(Context context, Time time)const
+{
+ if(get_amount() && importer && importer->is_animated())importer->get_frame(surface,time+time_offset);
+ //else surface.clear();
+ context.set_time(time);
+}
+
+void
+Import::set_time(Context context, Time time, const Point &pos)const
+{
+ if(get_amount() && importer && importer->is_animated())importer->get_frame(surface,time+time_offset);
+ //else surface.clear();
+ context.set_time(time,pos);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file import.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_IMPORT_H
+#define __SYNFIG_IMPORT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_bitmap.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+#include <synfig/importer.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class Import : public synfig::Layer_Bitmap
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+ synfig::String filename;
+ synfig::String abs_filename;
+ synfig::Importer::Handle importer;
+ synfig::Time time_offset;
+
+protected:
+ Import();
+
+public:
+ ~Import();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+
+ virtual synfig::ValueBase get_param(const synfig::String & param)const;
+
+ virtual Vocab get_param_vocab()const;
+
+ virtual void on_canvas_set();
+
+ virtual void set_time(synfig::Context context, synfig::Time time)const;
+
+ virtual void set_time(synfig::Context context, synfig::Time time, const synfig::Point &point)const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file insideout.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "insideout.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/transform.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(InsideOut);
+SYNFIG_LAYER_SET_NAME(InsideOut,"inside_out");
+SYNFIG_LAYER_SET_LOCAL_NAME(InsideOut,_("Inside Out"));
+SYNFIG_LAYER_SET_CATEGORY(InsideOut,_("Distortions"));
+SYNFIG_LAYER_SET_VERSION(InsideOut,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(InsideOut,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+InsideOut::InsideOut():
+ origin(0,0)
+{
+}
+
+bool
+InsideOut::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(origin);
+ return false;
+}
+
+ValueBase
+InsideOut::get_param(const String & param)const
+{
+ EXPORT(origin);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return ValueBase();
+}
+
+synfig::Layer::Handle
+InsideOut::hit_check(synfig::Context context, const synfig::Point &p)const
+{
+ Point pos(p-origin);
+ Real inv_mag=pos.inv_mag();
+ Point invpos(pos*inv_mag*inv_mag);
+ return context.hit_check(invpos+origin);
+}
+
+Color
+InsideOut::get_color(Context context, const Point &p)const
+{
+ Point pos(p-origin);
+ Real inv_mag=pos.inv_mag();
+ Point invpos(pos*inv_mag*inv_mag);
+ return context.get_color(invpos+origin);
+}
+
+class InsideOut_Trans : public Transform
+{
+ etl::handle<const InsideOut> layer;
+public:
+ InsideOut_Trans(const InsideOut* x):layer(x) { }
+
+ synfig::Vector perform(const synfig::Vector& x)const
+ {
+ Point pos(x-layer->origin);
+ Real inv_mag=pos.inv_mag();
+ if(!isnan(inv_mag))
+ return (pos*(inv_mag*inv_mag)+layer->origin);
+ return x;
+ }
+
+ synfig::Vector unperform(const synfig::Vector& x)const
+ {
+ Point pos(x-layer->origin);
+ Real inv_mag=pos.inv_mag();
+ if(!isnan(inv_mag))
+ return (pos*(inv_mag*inv_mag)+layer->origin);
+ return x;
+ }
+};
+etl::handle<Transform>
+InsideOut::get_transform()const
+{
+ return new InsideOut_Trans(this);
+}
+
+Layer::Vocab
+InsideOut::get_param_vocab()const
+{
+ Layer::Vocab ret;
+
+ ret.push_back(ParamDesc("origin")
+ .set_local_name(_("Origin"))
+ .set_description(_("Defines the where the center will be"))
+ );
+
+ return ret;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file insideout.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_INSIDEOUT_H
+#define __SYNFIG_INSIDEOUT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer.h>
+#include <synfig/color.h>
+#include <synfig/context.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+class InsideOut_Trans;
+
+class InsideOut : public Layer
+{
+ SYNFIG_LAYER_MODULE_EXT
+ friend class InsideOut_Trans;
+
+private:
+
+ Point origin;
+
+public:
+ InsideOut();
+
+ virtual bool set_param(const String ¶m, const ValueBase &value);
+ virtual ValueBase get_param(const String ¶m)const;
+ virtual Color get_color(Context context, const Point &pos)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+ virtual Vocab get_param_vocab()const;
+ virtual etl::handle<synfig::Transform> get_transform()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file julia.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "julia.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+#define LOG_OF_2 0.69314718055994528623
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Julia);
+SYNFIG_LAYER_SET_NAME(Julia,"julia");
+SYNFIG_LAYER_SET_LOCAL_NAME(Julia,_("Julia Set"));
+SYNFIG_LAYER_SET_CATEGORY(Julia,_("Fractals"));
+SYNFIG_LAYER_SET_VERSION(Julia,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Julia,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+inline void
+color_neg_flip(Color &color)
+{
+ if(color.get_a()==0)
+ {
+ color=Color::alpha();
+ return;
+ }
+
+ if(color.get_a()<0)
+ color=-color;
+
+ if(color.get_r()<0)
+ {
+ color.set_g(color.get_g()-color.get_r());
+ color.set_b(color.get_b()-color.get_r());
+ color.set_r(0);
+ }
+ if(color.get_g()<0)
+ {
+ color.set_r(color.get_r()-color.get_g());
+ color.set_b(color.get_b()-color.get_g());
+ color.set_g(0);
+ }
+ if(color.get_b()<0)
+ {
+ color.set_r(color.get_r()-color.get_b());
+ color.set_g(color.get_g()-color.get_b());
+ color.set_b(0);
+ }
+}
+
+/* === M E T H O D S ======================================================= */
+
+Julia::Julia():color_shift(angle::degrees(0))
+{
+ icolor=Color::black();
+ ocolor=Color::black();
+ iterations=32;
+ color_shift=Angle::deg(0);
+
+ distort_inside=true;
+ distort_outside=true;
+ shade_inside=true;
+ shade_outside=true;
+ solid_inside=false;
+ solid_outside=false;
+ invert_inside=false;
+ invert_outside=false;
+ color_inside=true;
+ color_outside=false;
+ color_cycle=false;
+ smooth_outside=true;
+ broken=false;
+ seed=Point(0,0);
+
+ bailout=4;
+ lp=log(log(bailout));
+}
+
+bool
+Julia::set_param(const String & param, const ValueBase &value)
+{
+
+ IMPORT(icolor);
+ IMPORT(ocolor);
+ IMPORT(color_shift);
+ IMPORT(seed);
+
+ IMPORT(distort_inside);
+ IMPORT(distort_outside);
+ IMPORT(shade_inside);
+ IMPORT(shade_outside);
+ IMPORT(solid_inside);
+ IMPORT(solid_outside);
+ IMPORT(invert_inside);
+ IMPORT(invert_outside);
+ IMPORT(color_inside);
+ IMPORT(color_outside);
+
+ IMPORT(color_cycle);
+ IMPORT(smooth_outside);
+ IMPORT(broken);
+
+ if(param=="iterations" && value.same_type_as(iterations))
+ {
+ iterations=value.get(iterations);
+ if(iterations<0)
+ iterations=0;
+ if(iterations>500000)
+ iterations=500000;
+ return true;
+ }
+ if(param=="bailout" && value.same_type_as(bailout))
+ {
+ bailout=value.get(bailout);
+ bailout*=bailout;
+ lp=log(log(bailout));
+ return true;
+ }
+
+ return false;
+}
+
+ValueBase
+Julia::get_param(const String & param)const
+{
+ EXPORT(icolor);
+ EXPORT(ocolor);
+ EXPORT(color_shift);
+ EXPORT(iterations);
+ EXPORT(seed);
+
+ EXPORT(distort_inside);
+ EXPORT(distort_outside);
+ EXPORT(shade_inside);
+ EXPORT(shade_outside);
+ EXPORT(solid_inside);
+ EXPORT(solid_outside);
+ EXPORT(invert_inside);
+ EXPORT(invert_outside);
+ EXPORT(color_inside);
+ EXPORT(color_outside);
+ EXPORT(color_cycle);
+ EXPORT(smooth_outside);
+ EXPORT(broken);
+
+ if(param=="bailout")
+ return sqrt(bailout);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return ValueBase();
+}
+
+Color
+Julia::get_color(Context context, const Point &pos)const
+{
+ Real
+ cr, ci,
+ zr, zi,
+ zr_hold;
+
+ ColorReal
+ depth, mag(0);
+
+ Color
+ ret;
+
+ cr=seed[0];
+ ci=seed[1];
+ zr=pos[0];
+ zi=pos[1];
+
+ for(int i=0;i<iterations;i++)
+ {
+ // Perform complex multiplication
+ zr_hold=zr;
+ zr=zr*zr-zi*zi + cr;
+ zi=zr_hold*zi*2 + ci;
+
+ // Use "broken" algorithm, if requested (looks weird)
+ if(broken)zr+=zi;
+
+ // Calculate Magnitude
+ mag=zr*zr+zi*zi;
+
+ if(mag>4)
+ {
+ if(smooth_outside)
+ {
+ // Darco's original mandelbrot smoothing algo
+ // depth=((Point::value_type)i+(2.0-sqrt(mag))/PI);
+
+ // Linas Vepstas algo (Better than darco's)
+ // See (http://linas.org/art-gallery/escape/smooth.html)
+ depth= (ColorReal)i - log(log(sqrt(mag))) / LOG_OF_2;
+
+ // Clamp
+ if(depth<0) depth=0;
+ }
+ else
+ depth=static_cast<ColorReal>(i);
+
+ if(solid_outside)
+ ret=ocolor;
+ else
+ if(distort_outside)
+ ret=context.get_color(Point(zr,zi));
+ else
+ ret=context.get_color(pos);
+
+ if(invert_outside)
+ ret=~ret;
+
+ if(color_outside)
+ ret=ret.set_uv(zr,zi).clamped_negative();
+
+ if(color_cycle)
+ ret=ret.rotate_uv(color_shift.operator*(depth)).clamped_negative();
+
+ if(shade_outside)
+ {
+ ColorReal alpha=depth/static_cast<ColorReal>(iterations);
+ ret=(ocolor-ret)*alpha+ret;
+ }
+ return ret;
+ }
+ }
+
+ if(solid_inside)
+ ret=icolor;
+ else
+ if(distort_inside)
+ ret=context.get_color(Point(zr,zi));
+ else
+ ret=context.get_color(pos);
+
+ if(invert_inside)
+ ret=~ret;
+
+ if(color_inside)
+ ret=ret.set_uv(zr,zi).clamped_negative();
+
+ if(shade_inside)
+ ret=(icolor-ret)*mag+ret;
+
+ return ret;
+}
+
+Layer::Vocab
+Julia::get_param_vocab()const
+{
+ Layer::Vocab ret;
+
+ ret.push_back(ParamDesc("icolor")
+ .set_local_name(_("Inside Color"))
+ .set_description(_("Color of the Set"))
+ );
+ ret.push_back(ParamDesc("ocolor")
+ .set_local_name(_("Outside Color"))
+ .set_description(_("Color outside the Set"))
+ );
+ ret.push_back(ParamDesc("color_shift")
+ .set_local_name(_("Color Shift"))
+ );
+ ret.push_back(ParamDesc("iterations")
+ .set_local_name(_("Iterations"))
+ );
+ ret.push_back(ParamDesc("seed")
+ .set_local_name(_("Seed Point"))
+ );
+ ret.push_back(ParamDesc("bailout")
+ .set_local_name(_("Bailout ValueBase"))
+ );
+
+ ret.push_back(ParamDesc("distort_inside")
+ .set_local_name(_("Distort Inside"))
+ );
+ ret.push_back(ParamDesc("shade_inside")
+ .set_local_name(_("Shade Inside"))
+ );
+ ret.push_back(ParamDesc("solid_inside")
+ .set_local_name(_("Solid Inside"))
+ );
+ ret.push_back(ParamDesc("invert_inside")
+ .set_local_name(_("Invert Inside"))
+ );
+ ret.push_back(ParamDesc("color_inside")
+ .set_local_name(_("Color Inside"))
+ );
+ ret.push_back(ParamDesc("distort_outside")
+ .set_local_name(_("Distort Outside"))
+ );
+ ret.push_back(ParamDesc("shade_outside")
+ .set_local_name(_("Shade Outside"))
+ );
+ ret.push_back(ParamDesc("solid_outside")
+ .set_local_name(_("Solid Outside"))
+ );
+ ret.push_back(ParamDesc("invert_outside")
+ .set_local_name(_("Invert Outside"))
+ );
+ ret.push_back(ParamDesc("color_outside")
+ .set_local_name(_("Color Outside"))
+ );
+
+ ret.push_back(ParamDesc("color_cycle")
+ .set_local_name(_("Color Cycle"))
+ );
+ ret.push_back(ParamDesc("smooth_outside")
+ .set_local_name(_("Smooth Outside"))
+ .set_description(_("Smooth the coloration outside the set"))
+ );
+ ret.push_back(ParamDesc("broken")
+ .set_local_name(_("Break Set"))
+ .set_description(_("Modify equation to achieve interesting results"))
+ );
+
+
+ return ret;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file julia.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_JULIA_H
+#define __SYNFIG_JULIA_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+#include <synfig/angle.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class Julia : public synfig::Layer
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ synfig::Color icolor;
+ synfig::Color ocolor;
+ synfig::Angle color_shift;
+ Real bailout;
+ Real lp;
+ int iterations;
+ synfig::Point seed;
+
+ bool distort_inside;
+ bool distort_outside;
+ bool shade_inside;
+ bool shade_outside;
+ bool solid_inside;
+ bool solid_outside;
+ bool invert_inside;
+ bool invert_outside;
+ bool color_inside;
+ bool color_outside;
+
+ bool color_cycle;
+ bool smooth_outside;
+ bool broken;
+
+public:
+ Julia();
+
+ virtual bool set_param(const synfig::String ¶m, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const synfig::String ¶m)const;
+
+ virtual Color get_color(synfig::Context context, const synfig::Point &pos)const;
+
+ virtual Vocab get_param_vocab()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+; The stuff to install
+Section "lyr_std" Sec_lyr_std
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=lyr_std.dll "src\modules\lyr_std\.libs\liblyr_std-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "lyr_std"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file lyr_std/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include <synfig/string.h>
+
+#include "zoom.h"
+//#include "blur.h"
+#include "import.h"
+#include "translate.h"
+#include "rotate.h"
+#include "clamp.h"
+#include "stretch.h"
+
+//#include "colorcorrect.h"
+
+#include "supersample.h"
+
+#include "mandelbrot.h"
+#include "julia.h"
+#include "insideout.h"
+#include "xorpattern.h"
+#include "twirl.h"
+#include "sphere_distort.h"
+
+
+
+#include "shade.h"
+#include "bevel.h"
+//#include "halftone2.h"
+
+//#include "radialblur.h"
+
+#include "warp.h"
+#include "timeloop.h"
+
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(liblyr_std)
+ MODULE_NAME("Standard Layers")
+ MODULE_DESCRIPTION("Provides a basic set of standard layers")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(liblyr_std)
+ BEGIN_LAYERS
+ LAYER(Zoom) LAYER_ALIAS(Zoom,"Zoom")
+ LAYER(Import) LAYER_ALIAS(Import,"Import")
+ LAYER(Translate) LAYER_ALIAS(Translate,"Translate")
+ LAYER(SuperSample) LAYER_ALIAS(SuperSample,"SuperSample")
+ LAYER(Rotate) LAYER_ALIAS(Rotate,"Rotate")
+ LAYER(Warp)
+ LAYER(Julia)
+ LAYER(InsideOut)
+ LAYER(Mandelbrot)
+ LAYER(Layer_Clamp)
+ LAYER(Layer_Stretch)
+ LAYER(XORPattern) LAYER_ALIAS(XORPattern,"XORPattern")
+ LAYER(Twirl)
+ LAYER(Layer_Shade)
+ LAYER(Layer_Bevel)
+ LAYER(Layer_TimeLoop)
+ LAYER(Layer_SphereDistort)
+ END_LAYERS
+MODULE_INVENTORY_END
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mandelbrot.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "mandelbrot.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+#define LOG_OF_2 0.69314718055994528623
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Mandelbrot);
+SYNFIG_LAYER_SET_NAME(Mandelbrot,"mandelbrot");
+SYNFIG_LAYER_SET_LOCAL_NAME(Mandelbrot,_("Mandelbrot Set"));
+SYNFIG_LAYER_SET_CATEGORY(Mandelbrot,_("Fractals"));
+SYNFIG_LAYER_SET_VERSION(Mandelbrot,"0.2");
+SYNFIG_LAYER_SET_CVS_ID(Mandelbrot,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+inline void
+color_neg_flip(Color &color)
+{
+ if(color.get_a()==0)
+ {
+ color=Color::alpha();
+ return;
+ }
+
+ if(color.get_a()<0)
+ color=-color;
+
+ if(color.get_r()<0)
+ {
+ color.set_g(color.get_g()-color.get_r());
+ color.set_b(color.get_b()-color.get_r());
+ color.set_r(0);
+ }
+ if(color.get_g()<0)
+ {
+ color.set_r(color.get_r()-color.get_g());
+ color.set_b(color.get_b()-color.get_g());
+ color.set_g(0);
+ }
+ if(color.get_b()<0)
+ {
+ color.set_r(color.get_r()-color.get_b());
+ color.set_g(color.get_g()-color.get_b());
+ color.set_b(0);
+ }
+}
+
+/* === M E T H O D S ======================================================= */
+
+Mandelbrot::Mandelbrot():
+ gradient_offset_inside(0.0),
+ gradient_offset_outside(0.0),
+ gradient_loop_inside(true),
+ gradient_scale_outside(1.0),
+ gradient_inside(Color::alpha(),Color::black()),
+ gradient_outside(Color::alpha(),Color::black())
+{
+ iterations=32;
+// color_shift=Angle::deg(0);
+
+ distort_inside=true;
+ distort_outside=true;
+ solid_inside=false;
+ solid_outside=false;
+ invert_inside=false;
+ invert_outside=false;
+ shade_inside=true;
+ shade_outside=true;
+
+ smooth_outside=true;
+ broken=false;
+
+ bailout=4;
+ lp=log(log(bailout));
+}
+
+bool
+Mandelbrot::set_param(const String & param, const ValueBase &value)
+{
+
+// IMPORT(color_shift);
+
+ IMPORT(gradient_offset_inside);
+ IMPORT(gradient_offset_outside);
+ IMPORT(gradient_loop_inside);
+ IMPORT(gradient_scale_outside);
+
+ IMPORT(distort_inside);
+ IMPORT(distort_outside);
+ IMPORT(solid_inside);
+ IMPORT(solid_outside);
+ IMPORT(invert_inside);
+ IMPORT(invert_outside);
+ IMPORT(shade_inside);
+ IMPORT(shade_outside);
+
+ IMPORT(smooth_outside);
+ IMPORT(broken);
+
+ IMPORT(gradient_inside);
+ IMPORT(gradient_outside);
+
+ if(param=="iterations" && value.same_type_as(iterations))
+ {
+ iterations=value.get(iterations);
+ if(iterations<0)
+ iterations=0;
+ if(iterations>500000)
+ iterations=500000;
+ return true;
+ }
+ if(param=="bailout" && value.same_type_as(bailout))
+ {
+ bailout=value.get(bailout);
+ bailout*=bailout;
+ lp=log(log(bailout));
+ return true;
+ }
+
+ return false;
+}
+
+ValueBase
+Mandelbrot::get_param(const String & param)const
+{
+// EXPORT(icolor);
+// EXPORT(ocolor);
+// EXPORT(color_shift);
+ EXPORT(iterations);
+
+ EXPORT(gradient_offset_inside);
+ EXPORT(gradient_offset_outside);
+ EXPORT(gradient_loop_inside);
+ EXPORT(gradient_scale_outside);
+
+ EXPORT(distort_inside);
+ EXPORT(distort_outside);
+ EXPORT(solid_inside);
+ EXPORT(solid_outside);
+ EXPORT(invert_inside);
+ EXPORT(invert_outside);
+ EXPORT(shade_inside);
+ EXPORT(shade_outside);
+ EXPORT(smooth_outside);
+ EXPORT(broken);
+
+ EXPORT(gradient_inside);
+ EXPORT(gradient_outside);
+
+ if(param=="bailout")
+ return sqrt(bailout);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return ValueBase();
+}
+
+Layer::Vocab
+Mandelbrot::get_param_vocab()const
+{
+ Layer::Vocab ret;
+
+
+ ret.push_back(ParamDesc("iterations")
+ .set_local_name(_("Iterations"))
+ );
+ ret.push_back(ParamDesc("bailout")
+ .set_local_name(_("Bailout ValueBase"))
+ );
+
+ ret.push_back(ParamDesc("broken")
+ .set_local_name(_("Break Set"))
+ .set_description(_("Modify equation to achieve interesting results"))
+ );
+
+
+ ret.push_back(ParamDesc("distort_inside")
+ .set_local_name(_("Distort Inside"))
+ .set_group(_("Inside"))
+ );
+ ret.push_back(ParamDesc("shade_inside")
+ .set_local_name(_("Shade Inside"))
+ .set_group(_("Inside"))
+ );
+ ret.push_back(ParamDesc("solid_inside")
+ .set_local_name(_("Solid Inside"))
+ .set_group(_("Inside"))
+ );
+ ret.push_back(ParamDesc("invert_inside")
+ .set_local_name(_("Invert Inside"))
+ .set_group(_("Inside"))
+ );
+ ret.push_back(ParamDesc("gradient_inside")
+ .set_local_name(_("Gradient Inside"))
+ .set_group(_("Inside"))
+ );
+ ret.push_back(ParamDesc("gradient_offset_inside")
+ .set_local_name(_("Offset Inside"))
+ .set_group(_("Inside"))
+ );
+ ret.push_back(ParamDesc("gradient_loop_inside")
+ .set_local_name(_("Loop Inside"))
+ .set_group(_("Inside"))
+ );
+
+ ret.push_back(ParamDesc("distort_outside")
+ .set_local_name(_("Distort Outside"))
+ .set_group(_("Outside"))
+ );
+ ret.push_back(ParamDesc("shade_outside")
+ .set_local_name(_("Shade Outside"))
+ .set_group(_("Outside"))
+ );
+ ret.push_back(ParamDesc("solid_outside")
+ .set_local_name(_("Solid Outside"))
+ .set_group(_("Outside"))
+ );
+ ret.push_back(ParamDesc("invert_outside")
+ .set_local_name(_("Invert Outside"))
+ .set_group(_("Outside"))
+ );
+ ret.push_back(ParamDesc("gradient_outside")
+ .set_local_name(_("Gradient outside"))
+ .set_group(_("Outside"))
+ );
+ ret.push_back(ParamDesc("smooth_outside")
+ .set_local_name(_("Smooth Outside"))
+ .set_description(_("Smooth the coloration outside the set"))
+ .set_group(_("Outside"))
+ );
+ ret.push_back(ParamDesc("gradient_offset_outside")
+ .set_local_name(_("Offset Outside"))
+ .set_group(_("Outside"))
+ );
+ ret.push_back(ParamDesc("gradient_scale_outside")
+ .set_local_name(_("Scale Outside"))
+ .set_group(_("Outside"))
+ );
+
+ return ret;
+}
+
+Color
+Mandelbrot::get_color(Context context, const Point &pos)const
+{
+ Real
+ cr, ci,
+ zr, zi,
+ zr_hold;
+
+ ColorReal
+ depth, mag(0);
+
+ Color
+ ret;
+
+
+ zr=zi=0;
+ cr=pos[0];
+ ci=pos[1];
+
+ for(int i=0;i<iterations;i++)
+ {
+ // Perform complex multiplication
+ zr_hold=zr;
+ zr=zr*zr-zi*zi + cr;
+ if(broken)zr+=zi; // Use "broken" algorithm, if requested (looks weird)
+ zi=zr_hold*zi*2 + ci;
+
+
+ // Calculate Magnitude
+ mag=zr*zr+zi*zi;
+
+ if(mag>bailout)
+ {
+ if(smooth_outside)
+ {
+ // Darco's original mandelbrot smoothing algo
+ // depth=((Point::value_type)i+(2.0-sqrt(mag))/PI);
+
+ // Linas Vepstas algo (Better than darco's)
+ // See (http://linas.org/art-gallery/escape/smooth.html)
+ depth= (ColorReal)i + LOG_OF_2*lp - log(log(sqrt(mag))) / LOG_OF_2;
+
+ // Clamp
+ if(depth<0) depth=0;
+ }
+ else
+ depth=static_cast<ColorReal>(i);
+
+ ColorReal amount(depth/static_cast<ColorReal>(iterations));
+ amount=amount*gradient_scale_outside+gradient_offset_outside;
+ amount-=floor(amount);
+
+ if(solid_outside)
+ ret=gradient_outside(amount);
+ else
+ {
+ if(distort_outside)
+ ret=context.get_color(Point(pos[0]+zr,pos[1]+zi));
+ else
+ ret=context.get_color(pos);
+
+ if(invert_outside)
+ ret=~ret;
+
+ if(shade_outside)
+ ret=Color::blend(gradient_outside(amount), ret, 1.0);
+ }
+
+
+ return ret;
+ }
+ }
+
+ ColorReal amount(abs(mag+gradient_offset_inside));
+ if(gradient_loop_inside)
+ amount-=floor(amount);
+
+ if(solid_inside)
+ ret=gradient_inside(amount);
+ else
+ {
+ if(distort_inside)
+ ret=context.get_color(Point(pos[0]+zr,pos[1]+zi));
+ else
+ ret=context.get_color(pos);
+
+ if(invert_inside)
+ ret=~ret;
+
+ if(shade_inside)
+ ret=Color::blend(gradient_inside(amount), ret, 1.0);
+ }
+
+ return ret;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mandelbrot.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_MANDELBROT_H
+#define __SYNFIG_MANDELBROT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer.h>
+#include <synfig/color.h>
+#include <synfig/angle.h>
+#include <synfig/gradient.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class Mandelbrot : public Layer
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ Real bailout;
+ Real lp;
+ int iterations;
+
+ bool smooth_outside;
+ bool broken;
+
+ bool distort_inside;
+ bool distort_outside;
+ bool solid_inside;
+ bool solid_outside;
+ bool invert_inside;
+ bool invert_outside;
+ bool shade_outside;
+ bool shade_inside;
+ Real gradient_offset_inside;
+ Real gradient_offset_outside;
+ bool gradient_loop_inside;
+ Real gradient_scale_outside;
+ Gradient gradient_inside;
+ Gradient gradient_outside;
+
+public:
+ Mandelbrot();
+
+ virtual bool set_param(const String ¶m, const ValueBase &value);
+ virtual ValueBase get_param(const String ¶m)const;
+ virtual Color get_color(Context context, const Point &pos)const;
+ virtual Vocab get_param_vocab()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file rotate.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "rotate.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/transform.h>
+#include <ETL/misc>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Rotate);
+SYNFIG_LAYER_SET_NAME(Rotate,"rotate");
+SYNFIG_LAYER_SET_LOCAL_NAME(Rotate,_("Rotate"));
+SYNFIG_LAYER_SET_CATEGORY(Rotate,_("Transform"));
+SYNFIG_LAYER_SET_VERSION(Rotate,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Rotate,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Rotate::Rotate():
+ origin (0,0),
+ amount (Angle::deg(0)),
+ sin_val (0),
+ cos_val (1)
+{
+}
+
+Rotate::~Rotate()
+{
+}
+
+bool
+Rotate::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(origin);
+
+ if(param=="amount" && value.same_type_as(amount))
+ {
+ amount=value.get(amount);
+ sin_val=Angle::sin(amount).get();
+ cos_val=Angle::cos(amount).get();
+ return true;
+ }
+
+ return false;
+}
+
+ValueBase
+Rotate::get_param(const String ¶m)const
+{
+ EXPORT(origin);
+ EXPORT(amount);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return ValueBase();
+}
+
+Layer::Vocab
+Rotate::get_param_vocab()const
+{
+ Layer::Vocab ret;
+
+ ret.push_back(ParamDesc("origin")
+ .set_local_name(_("Origin"))
+ .set_description(_("Point where you want the origin to be"))
+ );
+
+ ret.push_back(ParamDesc("amount")
+ .set_local_name(_("Amount"))
+ .set_description(_("Amount of rotation"))
+ .set_origin("origin")
+ );
+
+ return ret;
+}
+
+class Rotate_Trans : public Transform
+{
+ etl::handle<const Rotate> layer;
+public:
+ Rotate_Trans(const Rotate* x):Transform(x->get_guid()),layer(x) { }
+
+ synfig::Vector perform(const synfig::Vector& x)const
+ {
+ Point pos(x-layer->origin);
+ return Point(layer->cos_val*pos[0]-layer->sin_val*pos[1],layer->sin_val*pos[0]+layer->cos_val*pos[1])+layer->origin;
+ }
+
+ synfig::Vector unperform(const synfig::Vector& x)const
+ {
+ Point pos(x-layer->origin);
+ return Point(layer->cos_val*pos[0]+layer->sin_val*pos[1],-layer->sin_val*pos[0]+layer->cos_val*pos[1])+layer->origin;
+ }
+};
+etl::handle<Transform>
+Rotate::get_transform()const
+{
+ return new Rotate_Trans(this);
+}
+
+synfig::Layer::Handle
+Rotate::hit_check(synfig::Context context, const synfig::Point &p)const
+{
+ Point pos(p-origin);
+ Point newpos(cos_val*pos[0]+sin_val*pos[1],-sin_val*pos[0]+cos_val*pos[1]);
+ newpos+=origin;
+ return context.hit_check(newpos);
+}
+
+Color
+Rotate::get_color(Context context, const Point &p)const
+{
+ Point pos(p-origin);
+ Point newpos(cos_val*pos[0]+sin_val*pos[1],-sin_val*pos[0]+cos_val*pos[1]);
+ newpos+=origin;
+ return context.get_color(newpos);
+}
+
+bool
+Rotate::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ if(amount.dist(Angle::deg(0))==Angle::deg(0))
+ return context.accelerated_render(surface,quality,renddesc,cb);
+ if(amount.dist(Angle::deg(180))==Angle::deg(0))
+ {
+ RendDesc desc(renddesc);
+ desc.clear_flags();
+ Point tmp;
+ tmp=renddesc.get_tl()-origin;
+ desc.set_tl(Point(-tmp[0],-tmp[1])+origin);
+ tmp=renddesc.get_br()-origin;
+ desc.set_br(Point(-tmp[0],-tmp[1])+origin);
+ return context.accelerated_render(surface,quality,desc,cb);
+ }
+
+ SuperCallback stageone(cb,0,9000,10000);
+ SuperCallback stagetwo(cb,9000,10000,10000);
+
+ if(cb && !cb->amount_complete(0,10000))
+ return false;
+
+ Point tl(renddesc.get_tl()-origin);
+ Point br(renddesc.get_br()-origin);
+ Point rot_tl(cos_val*tl[0]+sin_val*tl[1],-sin_val*tl[0]+cos_val*tl[1]);
+ Point rot_br(cos_val*br[0]+sin_val*br[1],-sin_val*br[0]+cos_val*br[1]);
+ Point rot_tr(cos_val*br[0]+sin_val*tl[1],-sin_val*br[0]+cos_val*tl[1]);
+ Point rot_bl(cos_val*tl[0]+sin_val*br[1],-sin_val*tl[0]+cos_val*br[1]);
+ rot_tl+=origin;
+ rot_br+=origin;
+ rot_tr+=origin;
+ rot_bl+=origin;
+
+ Point min_point(min(min(min(rot_tl[0],rot_br[0]),rot_tr[0]),rot_bl[0]),min(min(min(rot_tl[1],rot_br[1]),rot_tr[1]),rot_bl[1]));
+ Point max_point(max(max(max(rot_tl[0],rot_br[0]),rot_tr[0]),rot_bl[0]),max(max(max(rot_tl[1],rot_br[1]),rot_tr[1]),rot_bl[1]));
+
+ if(tl[0]>br[0])
+ {
+ tl[0]=max_point[0];
+ br[0]=min_point[0];
+ }
+ else
+ {
+ br[0]=max_point[0];
+ tl[0]=min_point[0];
+ }
+ if(tl[1]>br[1])
+ {
+ tl[1]=max_point[1];
+ br[1]=min_point[1];
+ }
+ else
+ {
+ br[1]=max_point[1];
+ tl[1]=min_point[1];
+ }
+
+ Real pw=(renddesc.get_w())/(renddesc.get_br()[0]-renddesc.get_tl()[0]);
+ Real ph=(renddesc.get_h())/(renddesc.get_br()[1]-renddesc.get_tl()[1]);
+
+ RendDesc desc(renddesc);
+ desc.clear_flags();
+ //desc.set_flags(RendDesc::PX_ASPECT);
+ desc.set_tl(tl);
+ desc.set_br(br);
+ desc.set_wh(round_to_int(pw*(br[0]-tl[0])),round_to_int(ph*(br[1]-tl[1])));
+
+ //synfig::warning("given window: [%f,%f]-[%f,%f] %dx%d",renddesc.get_tl()[0],renddesc.get_tl()[1],renddesc.get_br()[0],renddesc.get_br()[1],renddesc.get_w(),renddesc.get_h());
+ //synfig::warning("surface to render: [%f,%f]-[%f,%f] %dx%d",desc.get_tl()[0],desc.get_tl()[1],desc.get_br()[0],desc.get_br()[1],desc.get_w(),desc.get_h());
+
+ Surface source;
+ source.set_wh(desc.get_w(),desc.get_h());
+
+ if(!context.accelerated_render(&source,quality,desc,&stageone))
+ return false;
+
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+
+ Surface::pen pen(surface->begin());
+
+ if(quality<=4)
+ {
+ // CUBIC
+ int x,y;//,u,v,u2,v2;
+ Point point,tmp;
+ for(y=0,point[1]=renddesc.get_tl()[1];y<surface->get_h();y++,pen.inc_y(),pen.dec_x(x),point[1]+=1.0/ph)
+ {
+ for(x=0,point[0]=renddesc.get_tl()[0];x<surface->get_w();x++,pen.inc_x(),point[0]+=1.0/pw)
+ {
+ tmp=Point(cos_val*(point[0]-origin[0])+sin_val*(point[1]-origin[1]),-sin_val*(point[0]-origin[0])+cos_val*(point[1]-origin[1])) +origin;
+ (*surface)[y][x]=source.cubic_sample((tmp[0]-tl[0])*pw,(tmp[1]-tl[1])*ph);
+ }
+ if(y&31==0 && cb)
+ {
+ if(!stagetwo.amount_complete(y,surface->get_h()))
+ return false;
+ }
+ }
+ }
+ else
+ if(quality<=6)
+ {
+ // INTERPOLATION_LINEAR
+ int x,y;//,u,v,u2,v2;
+ Point point,tmp;
+ for(y=0,point[1]=renddesc.get_tl()[1];y<surface->get_h();y++,pen.inc_y(),pen.dec_x(x),point[1]+=1.0/ph)
+ {
+ for(x=0,point[0]=renddesc.get_tl()[0];x<surface->get_w();x++,pen.inc_x(),point[0]+=1.0/pw)
+ {
+ tmp=Point(cos_val*(point[0]-origin[0])+sin_val*(point[1]-origin[1]),-sin_val*(point[0]-origin[0])+cos_val*(point[1]-origin[1])) +origin;
+ (*surface)[y][x]=source.linear_sample((tmp[0]-tl[0])*pw,(tmp[1]-tl[1])*ph);
+ }
+ if(y&31==0 && cb)
+ {
+ if(!stagetwo.amount_complete(y,surface->get_h()))
+ return false;
+ }
+ }
+ }
+ else
+ {
+ // NEAREST_NEIGHBOR
+ int x,y,u,v;
+ Point point,tmp;
+ for(y=0,point[1]=renddesc.get_tl()[1];y<surface->get_h();y++,pen.inc_y(),pen.dec_x(x),point[1]+=1.0/ph)
+ {
+ for(x=0,point[0]=renddesc.get_tl()[0];x<surface->get_w();x++,pen.inc_x(),point[0]+=1.0/pw)
+ {
+ tmp=Point(cos_val*(point[0]-origin[0])+sin_val*(point[1]-origin[1]),-sin_val*(point[0]-origin[0])+cos_val*(point[1]-origin[1])) +origin;
+ u=int((tmp[0]-tl[0])*pw);
+ v=int((tmp[1]-tl[1])*ph);
+ if(u<0)
+ u=0;
+ if(v<0)
+ v=0;
+ if(u>=source.get_w())
+ u=source.get_w()-1;
+ if(v>=source.get_h())
+ v=source.get_h()-1;
+ //pen.set_value(source[v][u]);
+ (*surface)[y][x]=source[v][u];
+ }
+ if(y&31==0 && cb)
+ {
+ if(!stagetwo.amount_complete(y,surface->get_h()))
+ return false;
+ }
+ }
+ }
+
+ if(cb && !cb->amount_complete(10000,10000)) return false;
+
+ return true;
+}
+
+Rect
+Rotate::get_full_bounding_rect(Context context)const
+{
+ Rect under(context.get_full_bounding_rect());
+ return get_transform()->perform(under);
+}
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file rotate.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_ROTATE_H
+#define __SYNFIG_ROTATE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/vector.h>
+#include <synfig/angle.h>
+#include <synfig/layer.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+class Rotate_Trans;
+
+class Rotate : public Layer
+{
+ SYNFIG_LAYER_MODULE_EXT
+ friend class Rotate_Trans;
+private:
+ Vector origin;
+ Angle amount;
+
+ Real sin_val;
+ Real cos_val;
+public:
+ Rotate();
+ ~Rotate();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+ virtual ValueBase get_param(const synfig::String & param)const;
+ virtual Color get_color(Context context, const Point &pos)const;
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+ virtual Vocab get_param_vocab()const;
+ virtual Rect get_full_bounding_rect(Context context)const;
+
+ virtual etl::handle<synfig::Transform> get_transform()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file shade.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "shade.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/segment.h>
+
+#include <cstring>
+#include <ETL/pen>
+#include <ETL/misc>
+
+#endif
+
+using namespace synfig;
+using namespace etl;
+using namespace std;
+
+/*#define TYPE_BOX 0
+#define TYPE_FASTGUASSIAN 1
+#define TYPE_CROSS 2
+#define TYPE_GAUSSIAN 3
+#define TYPE_DISC 4
+*/
+
+/* -- G L O B A L S --------------------------------------------------------- */
+
+SYNFIG_LAYER_INIT(Layer_Shade);
+SYNFIG_LAYER_SET_NAME(Layer_Shade,"shade");
+SYNFIG_LAYER_SET_LOCAL_NAME(Layer_Shade,_("Shade"));
+SYNFIG_LAYER_SET_CATEGORY(Layer_Shade,_("Stylize"));
+SYNFIG_LAYER_SET_VERSION(Layer_Shade,"0.2");
+SYNFIG_LAYER_SET_CVS_ID(Layer_Shade,"$Id$");
+
+/* -- F U N C T I O N S ----------------------------------------------------- */
+
+inline void clamp(synfig::Vector &v)
+{
+ if(v[0]<0.0)v[0]=0.0;
+ if(v[1]<0.0)v[1]=0.0;
+}
+
+Layer_Shade::Layer_Shade():
+ Layer_Composite (0.75,Color::BLEND_BEHIND),
+ size(0.1,0.1),
+ type(Blur::FASTGAUSSIAN),
+ color(Color::black()),
+ offset(0.2,-0.2),
+ invert(false)
+{
+}
+
+bool
+Layer_Shade::set_param(const String ¶m, const ValueBase &value)
+{
+ IMPORT_PLUS(size,clamp(size));
+ IMPORT(type);
+ IMPORT(color);
+ IMPORT(offset);
+ IMPORT(invert);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+Layer_Shade::get_param(const String ¶m)const
+{
+ EXPORT(size);
+ EXPORT(type);
+ EXPORT(color);
+ EXPORT(offset);
+ EXPORT(invert);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Color
+Layer_Shade::get_color(Context context, const Point &pos)const
+{
+ Point blurpos = Blur(size,type)(pos);
+
+ if(get_amount()==0.0)
+ return context.get_color(pos);
+
+ Color shade(color);
+
+ if(!invert)
+ shade.set_a(context.get_color(blurpos-offset).get_a());
+ else
+ shade.set_a(1.0f-context.get_color(blurpos-offset).get_a());
+
+ return Color::blend(shade,context.get_color(pos),get_amount(),get_blend_method());
+}
+
+bool
+Layer_Shade::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ int x,y;
+
+ const int w = renddesc.get_w(),
+ h = renddesc.get_h();
+ const Real pw = renddesc.get_pw(),
+ ph = renddesc.get_ph();
+
+ RendDesc workdesc(renddesc);
+ Surface worksurface;
+ etl::surface<float> blurred;
+
+ //expand the working surface to accommodate the blur
+
+ //the expanded size = 1/2 the size in each direction rounded up
+ int halfsizex = (int) (abs(size[0]*.5/pw) + 3),
+ halfsizey = (int) (abs(size[1]*.5/ph) + 3);
+
+ int offset_u(-round_to_int(offset[0]/pw)),offset_v(-round_to_int(offset[1]/ph));
+
+ int offset_w(w+abs(offset_u)),offset_h(h+abs(offset_v));
+
+ workdesc.set_subwindow(
+ offset_u<0?offset_u:0,
+ offset_v<0?offset_v:0,
+ (offset_u>0?offset_u:0)+w,
+ (offset_v>0?offset_v:0)+h
+ );
+
+ /*
+ if(quality >=10)
+ {
+ halfsizex=1;
+ halfsizey=1;
+ }else
+ */
+ if(quality == 9)
+ {
+ halfsizex/=4;
+ halfsizey/=4;
+ }
+
+ //expand by 1/2 size in each direction on either side
+ switch(type)
+ {
+ case Blur::DISC:
+ case Blur::BOX:
+ case Blur::CROSS:
+ {
+ workdesc.set_subwindow(-max(1,halfsizex),-max(1,halfsizey),offset_w+2*max(1,halfsizex),offset_h+2*max(1,halfsizey));
+ break;
+ }
+ case Blur::FASTGAUSSIAN:
+ {
+ if(quality < 4)
+ {
+ halfsizex*=2;
+ halfsizey*=2;
+ }
+ workdesc.set_subwindow(-max(1,halfsizex),-max(1,halfsizey),offset_w+2*max(1,halfsizex),offset_h+2*max(1,halfsizey));
+ break;
+ }
+ case Blur::GAUSSIAN:
+ {
+ #define GAUSSIAN_ADJUSTMENT (0.05)
+ Real pw = (Real)workdesc.get_w()/(workdesc.get_br()[0]-workdesc.get_tl()[0]);
+ Real ph = (Real)workdesc.get_h()/(workdesc.get_br()[1]-workdesc.get_tl()[1]);
+
+ pw=pw*pw;
+ ph=ph*ph;
+
+ halfsizex = (int)(abs(pw)*size[0]*GAUSSIAN_ADJUSTMENT+0.5);
+ halfsizey = (int)(abs(ph)*size[1]*GAUSSIAN_ADJUSTMENT+0.5);
+
+ halfsizex = (halfsizex + 1)/2;
+ halfsizey = (halfsizey + 1)/2;
+ workdesc.set_subwindow( -halfsizex, -halfsizey, offset_w+2*halfsizex, offset_h+2*halfsizey );
+
+ break;
+ }
+ }
+#define SCALE_FACTOR (64.0)
+ if(/*quality>9 || */size[0]<=pw*SCALE_FACTOR)
+ {
+ SuperCallback stageone(cb,0,5000,10000);
+ SuperCallback stagetwo(cb,5000,10000,10000);
+
+ //callbacks depend on how long the blur takes
+ if(size[0] || size[1])
+ {
+ if(type == Blur::DISC)
+ {
+ stageone = SuperCallback(cb,0,5000,10000);
+ stagetwo = SuperCallback(cb,5000,10000,10000);
+ }
+ else
+ {
+ stageone = SuperCallback(cb,0,9000,10000);
+ stagetwo = SuperCallback(cb,9000,10000,10000);
+ }
+ }
+ else
+ {
+ stageone = SuperCallback(cb,0,9999,10000);
+ stagetwo = SuperCallback(cb,9999,10000,10000);
+ }
+
+
+
+ //render the background onto the expanded surface
+ if(!context.accelerated_render(&worksurface,quality,workdesc,&stageone))
+ return false;
+
+ // Copy over the alpha
+ blurred.set_wh(worksurface.get_w(),worksurface.get_h());
+ for(int j=0;j<worksurface.get_h();j++)
+ for(int i=0;i<worksurface.get_w();i++)
+ {
+ blurred[j][i]=worksurface[j][i].get_a();
+ }
+
+ //blur the image
+ Blur(size,type,&stagetwo)(blurred,workdesc.get_br()-workdesc.get_tl(),blurred);
+
+ //be sure the surface is of the correct size
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+
+ int u = halfsizex-(offset_u<0?offset_u:0), v = halfsizey-(offset_v<0?offset_v:0);
+ for(y=0;y<renddesc.get_h();y++,v++)
+ {
+ u = halfsizex-(offset_u<0?offset_u:0);
+ for(x=0;x<renddesc.get_w();x++,u++)
+ {
+ Color a(color);
+
+ if(!invert)
+ a.set_a(blurred.linear_sample(offset_u+(float)u,offset_v+(float)v));
+ else
+ a.set_a(1.0f-blurred.linear_sample(offset_u+(float)u,offset_v+(float)v));
+
+ if(a.get_a() || get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ (*surface)[y][x]=Color::blend(a,worksurface[v][u],get_amount(),get_blend_method());
+ }
+ else (*surface)[y][x] = worksurface[v][u];
+ }
+ }
+ }
+ else
+ {
+
+ SuperCallback stageone(cb,0,5000,10000);
+ SuperCallback stagetwo(cb,5000,10000,10000);
+
+ //callbacks depend on how long the blur takes
+ if(size[0] || size[1])
+ {
+ if(type == Blur::DISC)
+ {
+ stageone = SuperCallback(cb,0,5000,10000);
+ stagetwo = SuperCallback(cb,5000,10000,10000);
+ }
+ else
+ {
+ stageone = SuperCallback(cb,0,9000,10000);
+ stagetwo = SuperCallback(cb,9000,10000,10000);
+ }
+ }
+ else
+ {
+ stageone = SuperCallback(cb,0,9999,10000);
+ stagetwo = SuperCallback(cb,9999,10000,10000);
+ }
+
+ int fw(floor_to_int(abs(size[0]/(pw*SCALE_FACTOR)))+1);
+ int fh(floor_to_int(abs(size[1]/(ph*SCALE_FACTOR)))+1);
+ int tmpw(round_to_int((float)workdesc.get_w()/fw)),tmph(round_to_int((float)workdesc.get_h()/fh));
+
+ workdesc.clear_flags();
+ workdesc.set_wh(tmpw,tmph);
+ //synfig::info("fw: %d, fh: %d",fw,fh);
+
+ //render the blur fodder
+ if(!context.accelerated_render(&worksurface,quality,workdesc,&stageone))
+ return false;
+
+ //render the background
+ if(!context.accelerated_render(surface,quality,renddesc,&stageone))
+ return false;
+
+ // Copy over the alpha
+ blurred.set_wh(worksurface.get_w(),worksurface.get_h());
+ for(int j=0;j<worksurface.get_h();j++)
+ for(int i=0;i<worksurface.get_w();i++)
+ blurred[j][i]=worksurface[j][i].get_a();
+
+ //blur the image
+ Blur(size,type,&stagetwo)(blurred,workdesc.get_br()-workdesc.get_tl(),blurred);
+
+
+ int u = halfsizex-(offset_u<0?offset_u:0), v = halfsizey-(offset_v<0?offset_v:0);
+ for(y=0;y<renddesc.get_h();y++,v++)
+ {
+ u = halfsizex-(offset_u<0?offset_u:0);
+ for(x=0;x<renddesc.get_w();x++,u++)
+ {
+ Color a(color);
+
+ if(!invert)
+ a.set_a(blurred.linear_sample(((float)offset_u+(float)u)/(float)fw,((float)offset_v+(float)v)/(float)fh));
+ else
+ a.set_a(1.0f-blurred.linear_sample(((float)offset_u+(float)u)/fw,((float)offset_v+(float)v)/(float)fh));
+
+ if(a.get_a() || get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ (*surface)[y][x]=Color::blend(a,(*surface)[y][x],get_amount(),get_blend_method());
+ }
+ }
+ }
+ }
+
+
+ if(cb && !cb->amount_complete(10000,10000))
+ {
+ //if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ return true;
+}
+
+Layer::Vocab
+Layer_Shade::get_param_vocab(void)const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("color")
+ .set_local_name(_("Color"))
+ );
+ ret.push_back(ParamDesc("offset")
+ .set_local_name(_("Offset"))
+ );
+ ret.push_back(ParamDesc("size")
+ .set_local_name(_("Size"))
+ .set_description(_("Size of Shade"))
+ .set_is_distance()
+ .set_origin("offset")
+ );
+ ret.push_back(ParamDesc("type")
+ .set_local_name(_("Type"))
+ .set_description(_("Type of blur to use"))
+ .set_hint("enum")
+ .add_enum_value(Blur::BOX,"box",_("Box Blur"))
+ .add_enum_value(Blur::FASTGAUSSIAN,"fastgaussian",_("Fast Gaussian Blur"))
+ .add_enum_value(Blur::CROSS,"cross",_("Cross-Hatch Blur"))
+ .add_enum_value(Blur::GAUSSIAN,"gaussian",_("Gaussian Blur"))
+ .add_enum_value(Blur::DISC,"disc",_("Disc Blur"))
+ );
+
+ ret.push_back(ParamDesc("invert")
+ .set_local_name(_("Invert"))
+ );
+
+ return ret;
+}
+
+Rect
+Layer_Shade::get_full_bounding_rect(Context context)const
+{
+ if(is_disabled())
+ return context.get_full_bounding_rect();
+
+ if(invert)
+ return Rect::full_plane();
+
+ Rect under(context.get_full_bounding_rect());
+
+ if(Color::is_onto(get_blend_method()))
+ return under;
+
+ Rect bounds((under+offset).expand_x(size[0]).expand_y(size[1]));
+
+ if(is_solid_color())
+ return bounds;
+
+ return bounds|under;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file shade.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifndef __SYNFIG_LAYER_SHADE_H__
+#define __SYNFIG_LAYER_SHADE_H__
+
+/* -- H E A D E R S --------------------------------------------------------- */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+#include <synfig/blur.h>
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class Layer_Shade : public synfig::Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+private:
+ synfig::Vector size;
+ int type;
+ synfig::Color color;
+ synfig::Vector offset;
+ bool invert;
+
+public:
+ Layer_Shade();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+ virtual Rect get_full_bounding_rect(Context context)const;
+
+ virtual Vocab get_param_vocab()const;
+}; // END of class Blur
+
+/* -- E X T E R N S --------------------------------------------------------- */
+
+/* -- E N D ----------------------------------------------------------------- */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file sphere_distort.cpp
+** \brief Sphere Distort File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "sphere_distort.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/transform.h>
+
+#include <synfig/curve_helper.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+#ifndef PI
+const double PI = 3.14159265;
+#endif
+
+enum
+{
+ TYPE_NORMAL = 0,
+ TYPE_DISTH = 1, //axe the horizontal axis
+ TYPE_DISTV = 2, //axe the vertical axis
+ N_TYPES
+};
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Layer_SphereDistort);
+SYNFIG_LAYER_SET_NAME(Layer_SphereDistort,"spherize");
+SYNFIG_LAYER_SET_LOCAL_NAME(Layer_SphereDistort,_("Spherize"));
+SYNFIG_LAYER_SET_CATEGORY(Layer_SphereDistort,_("Distortions"));
+SYNFIG_LAYER_SET_VERSION(Layer_SphereDistort,"0.2");
+SYNFIG_LAYER_SET_CVS_ID(Layer_SphereDistort,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Layer_SphereDistort::Layer_SphereDistort()
+:Layer_Composite(1.0,Color::BLEND_STRAIGHT),
+center(0,0),
+radius(1),
+percent(1.0),
+type(TYPE_NORMAL),
+clip(false)
+{
+}
+
+
+bool
+Layer_SphereDistort::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT_PLUS(center,sync());
+ IMPORT_PLUS(radius,sync());
+ IMPORT(type);
+ IMPORT_AS(percent,"amount");
+ IMPORT(clip);
+
+ if(param=="percent")
+ {
+ if(dynamic_param_list().count("percent"))
+ {
+ connect_dynamic_param("amount",dynamic_param_list().find("percent")->second);
+ disconnect_dynamic_param("percent");
+ synfig::warning("Layer_SphereDistort::::set_param(): Updated valuenode connection to use the new \"amount\" parameter.");
+ }
+ else
+ synfig::warning("Layer_SphereDistort::::set_param(): The parameter \"segment_list\" is deprecated. Use \"bline\" instead.");
+ }
+
+ return false;
+}
+
+ValueBase
+Layer_SphereDistort::get_param(const String ¶m)const
+{
+ EXPORT(center);
+ EXPORT(radius);
+ EXPORT(type);
+ EXPORT_AS(percent,"amount");
+ EXPORT(clip);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return ValueBase();
+}
+
+void
+Layer_SphereDistort::sync()
+{
+}
+
+Layer::Vocab
+Layer_SphereDistort::get_param_vocab()const
+{
+ Layer::Vocab ret;
+
+ ret.push_back(ParamDesc("center")
+ .set_local_name(_("Position"))
+ );
+
+ ret.push_back(ParamDesc("radius")
+ .set_local_name(_("Radius"))
+ .set_origin("center")
+ .set_is_distance()
+ );
+
+ ret.push_back(ParamDesc("amount")
+ .set_local_name(_("Amount"))
+ .set_is_distance(false)
+ );
+
+ ret.push_back(ParamDesc("clip")
+ .set_local_name(_("Clip"))
+ );
+
+ ret.push_back(ParamDesc("type")
+ .set_local_name(_("Distort Type"))
+ .set_description(_("The direction of the distortion"))
+ .set_hint("enum")
+ .add_enum_value(TYPE_NORMAL,"normal",_("Spherize"))
+ .add_enum_value(TYPE_DISTH,"honly",_("Vertical Bar"))
+ .add_enum_value(TYPE_DISTV,"vonly",_("Horizontal Bar"))
+ );
+
+ return ret;
+}
+
+/*
+ Spherical Distortion: maps an image onto a ellipsoid of some sort
+
+ so the image coordinate (i.e. distance away from the center)
+ will determine how things get mapped
+
+ so with the radius and position the mapping would go as follows
+
+ r = (pos - center) / radius clamped to [-1,1]
+
+ if it's outside of that range then it's not distorted
+ but if it's inside of that range then it goes as follows
+
+ angle = r * pi/2 (-pi/2,pi/2)
+
+ newr = cos(angle)*radius
+
+ the inverse of this is (which is actually what we'd be transforming it from
+
+
+*/
+
+inline float spherify(float f)
+{
+ if(f > -1 && f < 1 && f!=0)
+ return sinf(f*(PI/2));
+ else return f;
+}
+
+inline float unspherify(float f)
+{
+ if(f > -1 && f < 1 && f!=0)
+ return asin(f)/(PI/2);
+ else return f;
+}
+
+Point sphtrans(const Point &p, const Point ¢er, const float &radius,
+ const Real &percent, int type, bool& clipped)
+{
+ const Vector v = (p - center) / radius;
+
+ Point newp = p;
+ const float t = percent;
+
+ clipped=false;
+
+ if(type == TYPE_NORMAL)
+ {
+ const float m = v.mag();
+ float lerp(0);
+
+ if(m <= -1 || m >= 1)
+ {
+ clipped=true;
+ return newp;
+ }else
+ if(m==0)
+ return newp;
+ else
+ if(t > 0)
+ {
+ lerp = (t*unspherify(m) + (1-t)*m);
+ }else if(t < 0)
+ {
+ lerp = ((1+t)*m - t*spherify(m));
+ }else lerp = m;
+
+ const float d = lerp*radius;
+ newp = center + v*(d/m);
+ }
+
+ else if(type == TYPE_DISTH)
+ {
+ float lerp(0);
+ if(v[0] <= -1 || v[0] >= 1)
+ {
+ clipped=true;
+ return newp;
+ }else
+ if(v[0]==0)
+ return newp;
+ else
+ if(t > 0)
+ {
+ lerp = (t*unspherify(v[0]) + (1-t)*v[0]);
+ }else if(t < 0)
+ {
+ lerp = ((1+t)*v[0] - t*spherify(v[0]));
+ }else lerp = v[0];
+
+ newp[0] = center[0] + lerp*radius;
+ }
+
+ else if(type == TYPE_DISTV)
+ {
+ float lerp(0);
+ if(v[1] <= -1 || v[1] >= 1)
+ {
+ clipped=true;
+ return newp;
+ }
+ else
+ if(v[1]==0)
+ return newp;
+ else
+ if(t > 0)
+ {
+ lerp = (t*unspherify(v[1]) + (1-t)*v[1]);
+ }else if(t < 0)
+ {
+ lerp = ((1+t)*v[1] - t*spherify(v[1]));
+ }else lerp = v[1];
+
+ newp[1] = center[1] + lerp*radius;
+ }
+
+ return newp;
+}
+
+inline Point sphtrans(const Point &p, const Point ¢er, const Real &radius,
+ const Real &percent, int type)
+{
+ bool tmp;
+ return sphtrans(p, center, radius, percent, type, tmp);
+}
+
+synfig::Layer::Handle
+Layer_SphereDistort::hit_check(synfig::Context context, const synfig::Point &pos)const
+{
+ bool clipped;
+ Point point(sphtrans(pos,center,radius,percent,type,clipped));
+ if(clip && clipped)
+ return 0;
+ return context.hit_check(point);
+}
+
+Color
+Layer_SphereDistort::get_color(Context context, const Point &pos)const
+{
+ bool clipped;
+ Point point(sphtrans(pos,center,radius,percent,type,clipped));
+ if(clip && clipped)
+ return Color::alpha();
+ return context.get_color(point);
+}
+
+#if 1
+bool Layer_SphereDistort::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ /* Things to consider:
+ 1) Block expansion for distortion (ouch... quality level??)
+ 2) Bounding box clipping
+ 3) Super sampling for better visual quality (based on the quality level?)
+ 4) Interpolation type for sampling (based on quality level?)
+
+ //things to defer until after
+ super sampling, non-linear interpolation
+ */
+
+ //bounding box reject
+ {
+ Rect sphr;
+
+ sphr.set_point(center[0]-radius,center[1]-radius);
+ sphr.expand(center[0]+radius,center[1]+radius);
+
+ //get the bounding box of the transform
+ Rect windr;
+
+ //and the bounding box of the rendering
+ windr.set_point(renddesc.get_tl()[0],renddesc.get_tl()[1]);
+ windr.expand(renddesc.get_br()[0],renddesc.get_br()[1]);
+
+ //test bounding boxes for collision
+ if( (type == TYPE_NORMAL && !intersect(sphr,windr)) ||
+ (type == TYPE_DISTH && (sphr.minx >= windr.maxx || windr.minx >= sphr.maxx)) ||
+ (type == TYPE_DISTV && (sphr.miny >= windr.maxy || windr.miny >= sphr.maxy)) )
+ {
+ //synfig::warning("Spherize: Bounding box reject");
+ return context.accelerated_render(surface,quality,renddesc,cb);
+ }
+
+ //synfig::warning("Spherize: Bounding box accept");
+ }
+
+ //Ok, so we overlap some... now expand the window for rendering
+ RendDesc r = renddesc;
+ Surface background;
+ Real pw = renddesc.get_pw(),ph = renddesc.get_ph();
+
+ int nl=0,nt=0,nr=0,nb=0, nw=0,nh=0;
+ Point tl = renddesc.get_tl(), br = renddesc.get_br();
+
+ {
+ //must enlarge window by pixel coordinates so go!
+
+ //need to figure out closest and farthest point and distort THOSE
+
+ Point origin[4] = {tl,tl,br,br};
+ Vector v[4] = {Vector(0,br[1]-tl[1]),
+ Vector(br[0]-tl[0],0),
+ Vector(0,tl[1]-br[1]),
+ Vector(tl[0]-br[0],0)};
+
+ Point close(0,0);
+ Real t = 0;
+ Rect expandr(tl,br);
+
+ //expandr.set_point(tl[0],tl[1]);
+ //expandr.expand(br[0],br[1]);
+
+ //synfig::warning("Spherize: Loop through lines and stuff");
+ for(int i=0; i<4; ++i)
+ {
+ //synfig::warning("Spherize: %d", i);
+ Vector p_o = center-origin[i];
+
+ //project onto left line
+ t = (p_o*v[i])/v[i].mag_squared();
+
+ //clamp
+ if(t < 0) t = 0; if(t > 1) t = 1;
+
+ close = origin[i] + v[i]*t;
+
+ //now get transforms and expand the rectangle to accomodate
+ Point p = sphtrans(close,center,radius,percent,type);
+ expandr.expand(p[0],p[1]);
+ p = sphtrans(origin[i],center,radius,percent,type);
+ expandr.expand(p[0],p[1]);
+ p = sphtrans(origin[i]+v[i],center,radius,percent,type);
+ expandr.expand(p[0],p[1]);
+ }
+
+ /*synfig::warning("Spherize: Bounding box (%f,%f)-(%f,%f)",
+ expandr.minx,expandr.miny,expandr.maxx,expandr.maxy);*/
+
+ //now that we have the bouding rectangle of ALL the pixels (should be...)
+ //order it so that it's in the same orientation as the tl,br pair
+
+ //synfig::warning("Spherize: Organize like tl,br");
+ Point ntl(0,0),nbr(0,0);
+
+ //sort x
+ if(tl[0] < br[0])
+ {
+ ntl[0] = expandr.minx;
+ nbr[0] = expandr.maxx;
+ }
+ else
+ {
+ ntl[0] = expandr.maxx;
+ nbr[0] = expandr.minx;
+ }
+
+ //sort y
+ if(tl[1] < br[1])
+ {
+ ntl[1] = expandr.miny;
+ nbr[1] = expandr.maxy;
+ }
+ else
+ {
+ ntl[1] = expandr.maxy;
+ nbr[1] = expandr.miny;
+ }
+
+ //now expand the window as needed
+ Vector temp = ntl-tl;
+
+ //pixel offset
+ nl = (int)(temp[0]/pw)-1;
+ nt = (int)(temp[1]/ph)-1;
+
+ temp = nbr - br;
+ nr = (int)(temp[0]/pw)+1;
+ nb = (int)(temp[1]/ph)+1;
+
+ nw = renddesc.get_w() + nr - nl;
+ nh = renddesc.get_h() + nb - nt;
+
+ //synfig::warning("Spherize: Setting subwindow (%d,%d) (%d,%d) (%d,%d)",nl,nt,nr,nb,nw,nh);
+ r.set_subwindow(nl,nt,nw,nh);
+
+ /*r = renddesc;
+ nw = r.get_w(), nh = r.get_h();
+ nl = 0, nt = 0;*/
+ }
+
+ //synfig::warning("Spherize: render background");
+ if(!context.accelerated_render(&background,quality,r,cb))
+ {
+ synfig::warning("SphereDistort: Layer below failed");
+ return false;
+ }
+
+ //now distort and check to make sure we aren't overshooting our bounds here
+ int w = renddesc.get_w(), h = renddesc.get_h();
+ surface->set_wh(w,h);
+
+ Point sample = tl, sub = tl, trans(0,0);
+ float xs = 0,ys = 0;
+ int y=0,x=0;
+ Real invpw = 1/pw, invph = 1/ph;
+ Surface::pen p = surface->begin();
+
+ Point rtl = r.get_tl();
+
+ //synfig::warning("Spherize: About to transform");
+
+ for(y = 0; y < h; ++y, sample[1] += ph, p.inc_y())
+ {
+ sub = sample;
+ for(x = 0; x < w; ++x, sub[0] += pw, p.inc_x())
+ {
+ bool clipped;
+ trans=sphtrans(sub,center,radius,percent,type,clipped);
+ if(clip && clipped)
+ {
+ p.put_value(Color::alpha());
+ continue;
+ }
+
+ xs = (trans[0]-rtl[0])*invpw;
+ ys = (trans[1]-rtl[1])*invph;
+
+ if(!(xs >= 0 && xs < nw && ys >= 0 && ys < nh))
+ {
+ //synfig::warning("Spherize: we failed to account for %f,%f",xs,ys);
+ p.put_value(context.get_color(trans));//Color::alpha());
+ continue;
+ }
+
+ //sample at that pixel location based on the quality
+ if(quality <= 4) // cubic
+ p.put_value(background.cubic_sample(xs,ys));
+ else if(quality <= 5) // cosine
+ p.put_value(background.cosine_sample(xs,ys));
+ else if(quality <= 6) // linear
+ p.put_value(background.linear_sample(xs,ys));
+ else // nearest
+ p.put_value(background[round_to_int(ys)][round_to_int(xs)]);
+ }
+ p.dec_x(w);
+ }
+
+ return true;
+}
+#endif
+
+class synfig::Spherize_Trans : public synfig::Transform
+{
+ etl::handle<const Layer_SphereDistort> layer;
+public:
+ Spherize_Trans(const Layer_SphereDistort* x):Transform(x->get_guid()),layer(x) { }
+
+ synfig::Vector perform(const synfig::Vector& x)const
+ {
+ return sphtrans(x,layer->center,layer->radius,-layer->percent,layer->type);
+ }
+
+ synfig::Vector unperform(const synfig::Vector& x)const
+ {
+ return sphtrans(x,layer->center,layer->radius,layer->percent,layer->type);
+ }
+};
+
+etl::handle<Transform>
+Layer_SphereDistort::get_transform()const
+{
+ return new Spherize_Trans(this);
+}
+
+Rect
+Layer_SphereDistort::get_bounding_rect()const
+{
+ Rect bounds(Rect::full_plane());
+ switch(type)
+ {
+ case TYPE_NORMAL:
+ bounds=Rect(center[0]+radius, center[1]+radius,
+ center[0]-radius, center[1]-radius);
+ break;
+ case TYPE_DISTH:
+ bounds = Rect::vertical_strip(center[0]-radius, center[0]+radius);
+ break;
+ case TYPE_DISTV:
+ bounds = Rect::horizontal_strip(center[1]-radius, center[1]+radius);
+ break;
+ default:
+ break;
+ }
+
+ return bounds;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file sphere_distort.h
+** \brief Sphere Distort Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_SPHERE_DISTORT_H
+#define __SYNFIG_SPHERE_DISTORT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_composite.h>
+#include <synfig/vector.h>
+#include <synfig/rect.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+namespace synfig
+{
+class Spherize_Trans;
+
+class Layer_SphereDistort : public Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+ friend class Spherize_Trans;
+
+private:
+
+ Vector center;
+ double radius;
+
+ double percent;
+
+ int type;
+
+// static Point sphtrans(const Point &xoff, const Point ¢er, const Real &radius, const Real &percent, int type);
+
+// static double spherify(double xoff);
+// static double unspherify(double xoff);
+
+ bool clip;
+
+ synfig::Rect bounds;
+
+ void sync();
+
+public:
+
+ Layer_SphereDistort();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual Rect get_bounding_rect()const;
+
+ virtual Vocab get_param_vocab()const;
+ virtual etl::handle<synfig::Transform> get_transform()const;
+}; // END of class Layer_SphereDistort
+
+}
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file stretch.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "stretch.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/transform.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Layer_Stretch);
+SYNFIG_LAYER_SET_NAME(Layer_Stretch,"stretch");
+SYNFIG_LAYER_SET_LOCAL_NAME(Layer_Stretch,_("Stretch"));
+SYNFIG_LAYER_SET_CATEGORY(Layer_Stretch,_("Distortions"));
+SYNFIG_LAYER_SET_VERSION(Layer_Stretch,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Layer_Stretch,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Layer_Stretch::Layer_Stretch():
+ amount(1,1),
+ center(0,0)
+{
+}
+
+
+bool
+Layer_Stretch::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(amount);
+ IMPORT(center);
+
+ return false;
+}
+
+ValueBase
+Layer_Stretch::get_param(const String ¶m)const
+{
+ EXPORT(amount);
+ EXPORT(center);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return ValueBase();
+}
+
+Layer::Vocab
+Layer_Stretch::get_param_vocab()const
+{
+ Layer::Vocab ret;
+
+ ret.push_back(ParamDesc("amount")
+ .set_local_name(_("Amount"))
+ );
+
+ ret.push_back(ParamDesc("center")
+ .set_local_name(_("Center"))
+ );
+
+ return ret;
+}
+
+synfig::Layer::Handle
+Layer_Stretch::hit_check(synfig::Context context, const synfig::Point &pos)const
+{
+ Point npos(pos);
+ npos[0]=(npos[0]-center[0])/amount[0]+center[0];
+ npos[1]=(npos[1]-center[1])/amount[1]+center[1];
+ return context.hit_check(npos);
+}
+
+Color
+Layer_Stretch::get_color(Context context, const Point &pos)const
+{
+ Point npos(pos);
+ npos[0]=(npos[0]-center[0])/amount[0]+center[0];
+ npos[1]=(npos[1]-center[1])/amount[1]+center[1];
+ return context.get_color(npos);
+}
+
+class Stretch_Trans : public Transform
+{
+ etl::handle<const Layer_Stretch> layer;
+public:
+ Stretch_Trans(const Layer_Stretch* x):Transform(x->get_guid()),layer(x) { }
+
+ synfig::Vector perform(const synfig::Vector& x)const
+ {
+ return Vector((x[0]-layer->center[0])*layer->amount[0]+layer->center[0],
+ (x[1]-layer->center[1])*layer->amount[1]+layer->center[1]);
+ }
+
+ synfig::Vector unperform(const synfig::Vector& x)const
+ {
+ return Vector((x[0]-layer->center[0])/layer->amount[0]+layer->center[0],
+ (x[1]-layer->center[1])/layer->amount[1]+layer->center[1]);
+ }
+};
+etl::handle<Transform>
+Layer_Stretch::get_transform()const
+{
+ return new Stretch_Trans(this);
+}
+
+bool
+Layer_Stretch::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ RendDesc desc(renddesc);
+ desc.clear_flags();
+ // Adjust the top_left and bottom_right points
+ // for our zoom amount
+ Point npos;
+ npos[0]=(desc.get_tl()[0]-center[0])/amount[0]+center[0];
+ npos[1]=(desc.get_tl()[1]-center[1])/amount[1]+center[1];
+ desc.set_tl(npos);
+ npos[0]=(desc.get_br()[0]-center[0])/amount[0]+center[0];
+ npos[1]=(desc.get_br()[1]-center[1])/amount[1]+center[1];
+ desc.set_br(npos);
+
+ // Render the scene
+ return context.accelerated_render(surface,quality,desc,cb);
+}
+
+Rect
+Layer_Stretch::get_full_bounding_rect(Context context)const
+{
+ Rect rect(context.get_full_bounding_rect());
+ Point min(rect.get_min()), max(rect.get_max());
+
+ return Rect(Point((min[0]-center[0])*amount[0]+center[0],
+ (min[1]-center[1])*amount[1]+center[1]),
+ Point((max[0]-center[0])*amount[0]+center[0],
+ (max[1]-center[1])*amount[1]+center[1]));
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file stretch.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LAYER_STRETCH_H
+#define __SYNFIG_LAYER_STRETCH_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer.h>
+#include <synfig/vector.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class Stretch_Trans;
+namespace synfig {
+
+class Layer_Stretch : public Layer
+{
+ SYNFIG_LAYER_MODULE_EXT
+ friend class ::Stretch_Trans;
+
+private:
+
+ Vector amount;
+ Point center;
+
+public:
+
+ Layer_Stretch();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual Vocab get_param_vocab()const;
+ virtual etl::handle<synfig::Transform> get_transform()const;
+ virtual synfig::Rect get_full_bounding_rect(Context context)const;
+}; // END of class Layer_Stretch
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file supersample.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "supersample.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#include <synfig/target.h>
+#include <synfig/render.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(SuperSample);
+SYNFIG_LAYER_SET_NAME(SuperSample,"super_sample");
+SYNFIG_LAYER_SET_LOCAL_NAME(SuperSample,_("Super Sample"));
+SYNFIG_LAYER_SET_CATEGORY(SuperSample,_("Other"));
+SYNFIG_LAYER_SET_VERSION(SuperSample,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(SuperSample,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+SuperSample::SuperSample():width(2),height(2)
+{
+ scanline=false;
+ alpha_aware=true;
+}
+
+bool
+SuperSample::set_param(const String & param, const ValueBase &value)
+{
+
+ IMPORT(width);
+ IMPORT(height);
+ IMPORT(scanline);
+ IMPORT(alpha_aware);
+
+ return false;
+}
+
+ValueBase
+SuperSample::get_param(const String& param)const
+{
+ EXPORT(width);
+ EXPORT(height);
+ EXPORT(scanline);
+ EXPORT(alpha_aware);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return ValueBase();
+}
+
+bool
+SuperSample::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ // don't bother supersampling if our quality is too low.
+ if(quality>=10)
+ return context.accelerated_render(surface,quality,renddesc,cb);
+
+ RendDesc desc(renddesc);
+
+ SuperCallback subcb(cb,1,9000,10000);
+ SuperCallback stagetwo(cb,9000,10000,10000);
+
+ desc.clear_flags();
+ desc.set_wh(desc.get_w()*width,desc.get_h()*height);
+
+ Surface tempsurface;
+
+ // Render the scene
+ if(scanline)
+ {
+ handle<Target> target=surface_target(&tempsurface);
+ if(!target)
+ {
+ if(cb)cb->error(_("Unable to create SurfaceTarget"));
+ return false;
+ }
+ target->set_rend_desc(&desc);
+
+ if(!render(context-1,target,desc,&subcb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Scanline Renderer Failure",__LINE__));
+ return false;
+ }
+ }
+ else
+ if(!context.accelerated_render(&tempsurface,quality,desc,cb))
+ {
+ //if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+
+ Surface::pen pen(surface->begin());
+ Surface::pen temp_pen(tempsurface.begin());
+
+ if(cb && !cb->amount_complete(9001,10000)) return false;
+
+ if(alpha_aware)
+ {
+ int x,y,u,v;
+ float sum;
+ Color pool;
+ for(y=0;y<surface->get_h();y++,pen.inc_y(),pen.dec_x(x),temp_pen.inc_y(height),temp_pen.dec_x(x*width))
+ {
+ for(x=0;x<surface->get_w();x++,pen.inc_x(),temp_pen.inc_x(width))
+ {
+ pool=Color(0,0,0,0);
+ sum=0;
+
+ for(v=0;v<height;v++,temp_pen.inc_y(),temp_pen.dec_x(u))
+ for(u=0;u<width;u++,temp_pen.inc_x())
+ {
+ pool+=temp_pen.get_value()*temp_pen.get_value().get_a();
+ sum+=temp_pen.get_value().get_a();
+ }
+ temp_pen.dec_y(v);
+
+ if(sum)
+ {
+ pool/=sum;
+ pool.set_a(sum/float(width*height));
+ pen.put_value(pool);
+ }
+ else
+ pen.put_value(Color::alpha());
+ }
+ if(y&31==0 && cb)
+ {
+ if(!stagetwo.amount_complete(y,surface->get_h()))
+ return false;
+ }
+ }
+ }
+ else
+ {
+ int x,y,u,v;
+ Color pool;
+ float multiplier=1.0f/float(width*height);
+ for(y=0;y<surface->get_h();y++,pen.inc_y(),pen.dec_x(x),temp_pen.inc_y(height),temp_pen.dec_x(x*width))
+ {
+ for(x=0;x<surface->get_w();x++,pen.inc_x(),temp_pen.inc_x(width))
+ {
+ pool=Color(0,0,0,0);
+ for(v=0;v<height;v++,temp_pen.inc_y(),temp_pen.dec_x(u))
+ for(u=0;u<width;u++,temp_pen.inc_x())
+ pool+=temp_pen.get_value();
+ temp_pen.dec_y(v);
+ pen.put_value(pool*multiplier);
+ }
+ if(y&31==0 && cb)
+ {
+ if(!stagetwo.amount_complete(y,surface->get_h()))
+ return false;
+ }
+ }
+ }
+
+ if(cb && !cb->amount_complete(10000,10000)) return false;
+
+ return true;
+}
+
+Layer::Vocab
+SuperSample::get_param_vocab(void)const
+{
+ Layer::Vocab ret;
+
+ ret.push_back(ParamDesc("width")
+ .set_local_name(_("Width"))
+ .set_description(_("Width of sample area (In pixels)"))
+ );
+ ret.push_back(ParamDesc("height")
+ .set_local_name(_("Height"))
+ .set_description(_("Height of sample area (In pixels)"))
+ );
+ ret.push_back(ParamDesc("scanline")
+ .set_local_name(_("Use Parametric"))
+ .set_description(_("Use the Parametric Renderer"))
+ );
+ ret.push_back(ParamDesc("alpha_aware")
+ .set_local_name(_("Be Alpha Safe"))
+ );
+
+ return ret;
+}
+
+Rect
+SuperSample::get_bounding_rect(Context context)const
+{
+ return context.get_full_bounding_rect();
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file supersample.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_SUPERSAMPLE_H
+#define __SYNFIG_SUPERSAMPLE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class SuperSample : public synfig::Layer
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+ int width, height;
+ bool scanline,alpha_aware;
+public:
+ SuperSample();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+ virtual synfig::Rect get_bounding_rect(Context context)const;
+
+ virtual Vocab get_param_vocab()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file timeloop.cpp
+** \brief Image Layer_TimeLoop Layer Implementation
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "timeloop.h"
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/value.h>
+
+#endif
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Layer_TimeLoop);
+SYNFIG_LAYER_SET_NAME(Layer_TimeLoop,"timeloop");
+SYNFIG_LAYER_SET_LOCAL_NAME(Layer_TimeLoop,_("Time Loop"));
+SYNFIG_LAYER_SET_CATEGORY(Layer_TimeLoop,_("Other"));
+SYNFIG_LAYER_SET_VERSION(Layer_TimeLoop,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Layer_TimeLoop,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Layer_TimeLoop::Layer_TimeLoop()
+{
+ start_time=0;
+ end_time=1;
+}
+
+Layer_TimeLoop::~Layer_TimeLoop()
+{
+}
+
+bool
+Layer_TimeLoop::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(start_time);
+ IMPORT(end_time);
+ return Layer::set_param(param,value);
+}
+
+ValueBase
+Layer_TimeLoop::get_param(const String & param)const
+{
+ EXPORT(start_time);
+ EXPORT(end_time);
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer::get_param(param);
+}
+
+Layer::Vocab
+Layer_TimeLoop::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer::get_param_vocab());
+
+ ret.push_back(ParamDesc("start_time")
+ .set_local_name(_("Start Time"))
+ );
+
+ ret.push_back(ParamDesc("end_time")
+ .set_local_name(_("End Time"))
+ );
+
+ return ret;
+}
+
+void
+Layer_TimeLoop::set_time(Context context, Time time)const
+{
+ Real diff(end_time-start_time);
+ if(diff>0)
+ time-=int(Real(time-start_time)/diff)*diff+start_time;
+ context.set_time(time);
+}
+
+Color
+Layer_TimeLoop::get_color(Context context, const Point &pos)const
+{
+ return context.get_color(pos);
+}
+
+bool
+Layer_TimeLoop::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ return context.accelerated_render(surface,quality,renddesc,cb);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file timeloop.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TIMELOOP_H
+#define __SYNFIG_TIMELOOP_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer.h>
+#include <synfig/color.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class Layer_TimeLoop : public synfig::Layer
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+ synfig::Time start_time;
+ synfig::Time end_time;
+
+protected:
+ Layer_TimeLoop();
+
+public:
+ ~Layer_TimeLoop();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+
+ virtual synfig::ValueBase get_param(const synfig::String & param)const;
+
+ virtual Vocab get_param_vocab()const;
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+
+ virtual void set_time(synfig::Context context, synfig::Time time)const;
+ virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file translate.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "translate.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/canvas.h>
+#include <synfig/transform.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Translate);
+SYNFIG_LAYER_SET_NAME(Translate,"translate");
+SYNFIG_LAYER_SET_LOCAL_NAME(Translate,_("Translate"));
+SYNFIG_LAYER_SET_CATEGORY(Translate,_("Transform"));
+SYNFIG_LAYER_SET_VERSION(Translate,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Translate,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Translate::Translate():origin(0,0)
+{
+}
+
+Translate::~Translate()
+{
+}
+
+bool
+Translate::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(origin);
+
+ return false;
+}
+
+ValueBase
+Translate::get_param(const String& param)const
+{
+ EXPORT(origin);
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return ValueBase();
+}
+
+Layer::Vocab
+Translate::get_param_vocab()const
+{
+ Layer::Vocab ret;
+
+ ret.push_back(ParamDesc("origin")
+ .set_local_name(_("Origin"))
+ .set_description(_("Point where you want the origin to be"))
+ );
+
+ return ret;
+}
+
+synfig::Layer::Handle
+Translate::hit_check(synfig::Context context, const synfig::Point &pos)const
+{
+ return context.hit_check(pos-origin);
+}
+
+Color
+Translate::get_color(Context context, const Point &pos)const
+{
+ return context.get_color(pos-origin);
+}
+
+class Translate_Trans : public Transform
+{
+ etl::handle<const Translate> layer;
+public:
+ Translate_Trans(const Translate* x):Transform(x->get_guid()),layer(x) { }
+
+ synfig::Vector perform(const synfig::Vector& x)const
+ {
+ return x+layer->origin;
+ }
+
+ synfig::Vector unperform(const synfig::Vector& x)const
+ {
+ return x-layer->origin;
+ }
+};
+etl::handle<Transform>
+Translate::get_transform()const
+{
+ return new Translate_Trans(this);
+}
+
+bool
+Translate::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ RendDesc desc(renddesc);
+
+ desc.clear_flags();
+ desc.set_tl(desc.get_tl()-origin);
+ desc.set_br(desc.get_br()-origin);
+
+ // Render the scene
+ if(!context.accelerated_render(surface,quality,desc,cb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ return true;
+}
+
+Rect
+Translate::get_full_bounding_rect(Context context)const
+{
+ return context.get_full_bounding_rect() + origin;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file translate.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRANSLATE_H
+#define __SYNFIG_TRANSLATE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer.h>
+#include <synfig/vector.h>
+#include <synfig/string.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class Translate_Trans;
+
+class Translate : public Layer
+{
+ SYNFIG_LAYER_MODULE_EXT
+ friend class Translate_Trans;
+private:
+ Vector origin;
+public:
+ Translate();
+ ~Translate();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+ virtual ValueBase get_param(const String & param)const;
+ virtual Color get_color(Context context, const Point &pos)const;
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+ virtual Vocab get_param_vocab()const;
+ virtual synfig::Rect get_full_bounding_rect(Context context)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+ virtual etl::handle<synfig::Transform> get_transform()const;
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file twirl.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/transform.h>
+#include "twirl.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Twirl);
+SYNFIG_LAYER_SET_NAME(Twirl,"twirl");
+SYNFIG_LAYER_SET_LOCAL_NAME(Twirl,_("Twirl"));
+SYNFIG_LAYER_SET_CATEGORY(Twirl,_("Distortions"));
+SYNFIG_LAYER_SET_VERSION(Twirl,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Twirl,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Twirl::Twirl():
+ Layer_Composite(1.0,Color::BLEND_STRAIGHT),
+ center(0,0),
+ radius(1.0),
+ rotations(Angle::zero()),
+ distort_inside(true),
+ distort_outside(false)
+{
+}
+
+bool
+Twirl::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(center);
+ IMPORT(radius);
+ IMPORT(rotations);
+ IMPORT(distort_inside);
+ IMPORT(distort_outside);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+Twirl::get_param(const String ¶m)const
+{
+ EXPORT(center);
+ EXPORT(radius);
+ EXPORT(rotations);
+ EXPORT(distort_inside);
+ EXPORT(distort_outside);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return false;
+}
+
+Layer::Vocab
+Twirl::get_param_vocab()const
+{
+ Layer::Vocab ret;
+
+ ret.push_back(ParamDesc("center")
+ .set_local_name(_("Center"))
+ );
+
+ ret.push_back(ParamDesc("radius")
+ .set_local_name(_("Radius"))
+ .set_description(_("This is the radius of the circle"))
+ .set_is_distance()
+ .set_origin("center")
+ );
+
+ ret.push_back(ParamDesc("rotations")
+ .set_local_name(_("Rotations"))
+ .set_origin("center")
+ );
+
+ ret.push_back(ParamDesc("distort_inside")
+ .set_local_name(_("Distort Inside"))
+ );
+
+ ret.push_back(ParamDesc("distort_outside")
+ .set_local_name(_("Distort Outside"))
+ );
+
+ return ret;
+}
+
+synfig::Point
+Twirl::distort(const synfig::Point &pos,bool reverse)const
+{
+ Point centered(pos-center);
+ Real mag(centered.mag());
+
+ Angle a;
+
+ if((distort_inside || mag>radius) && (distort_outside || mag<radius))
+ a=rotations*((centered.mag()-radius)/radius);
+ else
+ return pos;
+
+ if(reverse) a=-a;
+
+ const Real sin(Angle::sin(a).get());
+ const Real cos(Angle::cos(a).get());
+
+ Point twirled;
+ twirled[0]=cos*centered[0]-sin*centered[1];
+ twirled[1]=sin*centered[0]+cos*centered[1];
+
+ return twirled+center;
+}
+
+synfig::Layer::Handle
+Twirl::hit_check(synfig::Context context, const synfig::Point &pos)const
+{
+ return context.hit_check(distort(pos));
+}
+
+Color
+Twirl::get_color(Context context, const Point &pos)const
+{
+ return context.get_color(distort(pos));
+}
+
+class Twirl_Trans : public Transform
+{
+ etl::handle<const Twirl> layer;
+public:
+ Twirl_Trans(const Twirl* x):Transform(x->get_guid()),layer(x) { }
+
+ synfig::Vector perform(const synfig::Vector& x)const
+ {
+ return layer->distort(x,true);
+ }
+
+ synfig::Vector unperform(const synfig::Vector& x)const
+ {
+ return layer->distort(x,false);
+ }
+};
+etl::handle<Transform>
+Twirl::get_transform()const
+{
+ return new Twirl_Trans(this);
+}
+
+/*
+bool
+Twirl::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ }
+ else
+ {
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+ if(get_amount()==0)
+ return true;
+ }
+
+
+ int x,y;
+
+ Surface::pen pen(surface->begin());
+ const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
+ Point pos;
+ Point tl(renddesc.get_tl());
+ const int w(surface->get_w());
+ const int h(surface->get_h());
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(color_func(pos));
+ }
+ else
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(Color::blend(color_func(pos),pen.get_value(),get_amount(),get_blend_method()));
+ }
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
+*/
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file twirl.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TWIRL_H
+#define __SYNFIG_TWIRL_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+#include <synfig/value.h>
+#include <synfig/gradient.h>
+#include <synfig/angle.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+class Twirl_Trans;
+
+class Twirl : public synfig::Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+ friend class Twirl_Trans;
+
+private:
+
+ synfig::Point center;
+
+ synfig::Real radius;
+
+ synfig::Angle rotations;
+
+ bool distort_inside;
+
+ bool distort_outside;
+
+ synfig::Point distort(const synfig::Point &pos, bool reverse=false)const;
+public:
+
+ Twirl();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+
+ virtual synfig::ValueBase get_param(const synfig::String & param)const;
+
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+
+ //virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual Vocab get_param_vocab()const;
+ virtual etl::handle<synfig::Transform> get_transform()const;
+}; // END of class Twirl
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.lyr_std"
+ Delete "$INSTDIR\lib\synfig\modules\lyr_std.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file warp.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "warp.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/transform.h>
+#include <ETL/misc>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Warp);
+SYNFIG_LAYER_SET_NAME(Warp,"warp");
+SYNFIG_LAYER_SET_LOCAL_NAME(Warp,_("Warp"));
+SYNFIG_LAYER_SET_CATEGORY(Warp,_("Distortions"));
+SYNFIG_LAYER_SET_VERSION(Warp,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Warp,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Warp::Warp():
+ src_tl (-2,2),
+ src_br (2,-2),
+ dest_tl (-1.8,2.1),
+ dest_tr (1.8,2.1),
+ dest_bl (-2.2,-2),
+ dest_br (2.2,-2),
+ clip (true)
+{
+ sync();
+ horizon=4;
+}
+
+Warp::~Warp()
+{
+}
+
+inline Point
+Warp::transform_forward(const Point& p)const
+{
+ return Point(
+ (inv_matrix[0][0]*p[0] + inv_matrix[0][1]*p[1] + inv_matrix[0][2])/(inv_matrix[2][0]*p[0] + inv_matrix[2][1]*p[1] + inv_matrix[2][2]),
+ (inv_matrix[1][0]*p[0] + inv_matrix[1][1]*p[1] + inv_matrix[1][2])/(inv_matrix[2][0]*p[0] + inv_matrix[2][1]*p[1] + inv_matrix[2][2])
+ );
+}
+
+inline Point
+Warp::transform_backward(const Point& p)const
+{
+ return Point(
+ (matrix[0][0]*p[0] + matrix[0][1]*p[1] + matrix[0][2])/(matrix[2][0]*p[0] + matrix[2][1]*p[1] + matrix[2][2]),
+ (matrix[1][0]*p[0] + matrix[1][1]*p[1] + matrix[1][2])/(matrix[2][0]*p[0] + matrix[2][1]*p[1] + matrix[2][2])
+ );
+}
+
+inline Real
+Warp::transform_forward_z(const Point& p)const
+{
+ return inv_matrix[2][0]*p[0] + inv_matrix[2][1]*p[1] + inv_matrix[2][2];
+}
+
+inline Real
+Warp::transform_backward_z(const Point& p)const
+{
+ return matrix[2][0]*p[0] + matrix[2][1]*p[1] + matrix[2][2];
+}
+
+/*
+#define transform_forward(p) Point( \
+ cache_a*p[0] + cache_b*p[1] + cache_c*p[0]*p[1] + cache_d, \
+ cache_e*p[0] + cache_f*p[1] + cache_i*p[0]*p[1] + cache_j )
+
+#define transform_backward(p) Point( \
+ cache_a*p[0] + cache_b*p[1] + cache_c*p[0]*p[1] + cache_d, \
+ cache_e*p[0] + cache_f*p[1] + cache_i*p[0]*p[1] + cache_j )
+*/
+
+#define triangle_area(a,b,c) (0.5*(-b[0]*a[1]+c[0]*a[1]+a[0]*b[1]-c[0]*b[1]-a[0]*c[1]+b[0]*c[1]))
+#define quad_area(a,b,c,d) (triangle_area(a,b,c)+triangle_area(a,c,d))
+
+Real mat3_determinant(Real matrix[3][3])
+{
+ Real ret;
+
+ ret = (matrix[0][0] *
+ (matrix[1][1] * matrix[2][2] -
+ matrix[1][2] * matrix[2][1]));
+ ret -= (matrix[1][0] *
+ (matrix[0][1] * matrix[2][2] -
+ matrix[0][2] * matrix[2][1]));
+ ret += (matrix[2][0] *
+ (matrix[0][1] * matrix[1][2] -
+ matrix[0][2] * matrix[1][1]));
+
+return ret;
+}
+
+void mat3_invert(Real in[3][3], Real out[3][3])
+{
+ Real det(mat3_determinant(in));
+
+ if (det == 0.0)
+ return;
+
+ det = 1.0 / det;
+
+ out[0][0] = (in[1][1] * in[2][2] -
+ in[1][2] * in[2][1]) * det;
+
+ out[1][0] = - (in[1][0] * in[2][2] -
+ in[1][2] * in[2][0]) * det;
+
+ out[2][0] = (in[1][0] * in[2][1] -
+ in[1][1] * in[2][0]) * det;
+
+ out[0][1] = - (in[0][1] * in[2][2] -
+ in[0][2] * in[2][1]) * det;
+
+ out[1][1] = (in[0][0] * in[2][2] -
+ in[0][2] * in[2][0]) * det;
+
+ out[2][1] = - (in[0][0] * in[2][1] -
+ in[0][1] * in[2][0]) * det;
+
+ out[0][2] = (in[0][1] * in[1][2] -
+ in[0][2] * in[1][1]) * det;
+
+ out[1][2] = - (in[0][0] * in[1][2] -
+ in[0][2] * in[1][0]) * det;
+
+ out[2][2] = (in[0][0] * in[1][1] -
+ in[0][1] * in[1][0]) * det;
+
+}
+
+void
+Warp::sync()
+{
+/* cache_a=(-dest_tl[0]+dest_tr[0])/(src_br[1]-src_tl[1]);
+ cache_b=(-dest_tl[0]+dest_bl[0])/(src_br[0]-src_tl[0]);
+ cache_c=(dest_tl[0]-dest_tr[0]+dest_br[0]-dest_bl[0])/((src_br[1]-src_tl[1])*(src_br[0]-src_tl[0]));
+ cache_d=dest_tl[0];
+
+ cache_e=(-dest_tl[1]+dest_tr[1])/(src_br[0]-src_tl[0]);
+ cache_f=(-dest_tl[1]+dest_bl[1])/(src_br[1]-src_tl[1]);
+ cache_i=(dest_tl[1]-dest_tr[1]+dest_br[1]-dest_bl[1])/((src_br[1]-src_tl[1])*(src_br[0]-src_tl[0]));
+ cache_j=dest_tl[1];
+*/
+
+/* matrix[2][0]=(dest_tl[0]-dest_tr[0]+dest_br[0]-dest_bl[0])/((src_br[1]-src_tl[1])*(src_br[0]-src_tl[0]));
+ matrix[2][1]=(dest_tl[1]-dest_tr[1]+dest_br[1]-dest_bl[1])/((src_br[1]-src_tl[1])*(src_br[0]-src_tl[0]));
+ matrix[2][2]=quad_area(dest_tl,dest_tr,dest_br,dest_bl)/((src_br[1]-src_tl[1])*(src_br[0]-src_tl[0]));
+
+ matrix[0][0]=-(-dest_tl[1]+dest_tr[1])/(src_br[0]-src_tl[0]);
+ matrix[0][1]=-(-dest_tl[1]+dest_bl[1])/(src_br[1]-src_tl[1]);
+
+ matrix[1][0]=-(-dest_tl[0]+dest_tr[0])/(src_br[1]-src_tl[1]);
+ matrix[1][1]=-(-dest_tl[0]+dest_bl[0])/(src_br[0]-src_tl[0]);
+
+ matrix[0][2]=matrix[0][0]*dest_tl[0] + matrix[0][1]*dest_tl[1];
+ matrix[1][2]=matrix[1][0]*dest_tl[0] + matrix[1][1]*dest_tl[1];
+*/
+
+#define matrix tmp
+ Real tmp[3][3];
+
+ const Real& x1(min(src_br[0],src_tl[0]));
+ const Real& y1(min(src_br[1],src_tl[1]));
+ const Real& x2(max(src_br[0],src_tl[0]));
+ const Real& y2(max(src_br[1],src_tl[1]));
+
+ Real tx1(dest_bl[0]);
+ Real ty1(dest_bl[1]);
+ Real tx2(dest_br[0]);
+ Real ty2(dest_br[1]);
+ Real tx3(dest_tl[0]);
+ Real ty3(dest_tl[1]);
+ Real tx4(dest_tr[0]);
+ Real ty4(dest_tr[1]);
+
+ if(src_br[0]<src_tl[0])
+ swap(tx3,tx4),swap(ty3,ty4),swap(tx1,tx2),swap(ty1,ty2);
+
+ if(src_br[1]>src_tl[1])
+ swap(tx3,tx1),swap(ty3,ty1),swap(tx4,tx2),swap(ty4,ty2);
+
+ Real scalex;
+ Real scaley;
+
+ scalex = scaley = 1.0;
+
+ if ((x2 - x1) > 0)
+ scalex = 1.0 / (Real) (x2 - x1);
+
+ if ((y2 - y1) > 0)
+ scaley = 1.0 / (Real) (y2 - y1);
+
+ /* Determine the perspective transform that maps from
+ * the unit cube to the transformed coordinates
+ */
+ {
+ Real dx1, dx2, dx3, dy1, dy2, dy3;
+
+ dx1 = tx2 - tx4;
+ dx2 = tx3 - tx4;
+ dx3 = tx1 - tx2 + tx4 - tx3;
+
+ dy1 = ty2 - ty4;
+ dy2 = ty3 - ty4;
+ dy3 = ty1 - ty2 + ty4 - ty3;
+
+ /* Is the mapping affine? */
+ if ((dx3 == 0.0) && (dy3 == 0.0))
+ {
+ matrix[0][0] = tx2 - tx1;
+ matrix[0][1] = tx4 - tx2;
+ matrix[0][2] = tx1;
+ matrix[1][0] = ty2 - ty1;
+ matrix[1][1] = ty4 - ty2;
+ matrix[1][2] = ty1;
+ matrix[2][0] = 0.0;
+ matrix[2][1] = 0.0;
+ }
+ else
+ {
+ Real det1, det2;
+
+ det1 = dx3 * dy2 - dy3 * dx2;
+ det2 = dx1 * dy2 - dy1 * dx2;
+
+ if (det1 == 0.0 && det2 == 0.0)
+ matrix[2][0] = 1.0;
+ else
+ matrix[2][0] = det1 / det2;
+
+ det1 = dx1 * dy3 - dy1 * dx3;
+
+ if (det1 == 0.0 && det2 == 0.0)
+ matrix[2][1] = 1.0;
+ else
+ matrix[2][1] = det1 / det2;
+
+ matrix[0][0] = tx2 - tx1 + matrix[2][0] * tx2;
+ matrix[0][1] = tx3 - tx1 + matrix[2][1] * tx3;
+ matrix[0][2] = tx1;
+
+ matrix[1][0] = ty2 - ty1 + matrix[2][0] * ty2;
+ matrix[1][1] = ty3 - ty1 + matrix[2][1] * ty3;
+ matrix[1][2] = ty1;
+ }
+
+ matrix[2][2] = 1.0;
+ }
+#undef matrix
+
+ Real scaletrans[3][3]={
+ { scalex, 0, -x1*scalex },
+ { 0, scaley, -y1*scaley },
+ { 0, 0, 1 }
+ };
+
+ Real t1,t2,t3;
+
+ for (int i = 0; i < 3; i++)
+ {
+ t1 = tmp[i][0];
+ t2 = tmp[i][1];
+ t3 = tmp[i][2];
+
+ for (int j = 0; j < 3; j++)
+ {
+ matrix[i][j] = t1 * scaletrans[0][j];
+ matrix[i][j] += t2 * scaletrans[1][j];
+ matrix[i][j] += t3 * scaletrans[2][j];
+ }
+ }
+
+ mat3_invert(matrix, inv_matrix);
+/*
+ gimp_matrix3_identity (result);
+ gimp_matrix3_translate (result, -x1, -y1);
+ gimp_matrix3_scale (result, scalex, scaley);
+ gimp_matrix3_mult (&matrix, result);
+*/
+}
+
+bool
+Warp::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT_PLUS(src_tl,sync());
+ IMPORT_PLUS(src_br,sync());
+ IMPORT_PLUS(dest_tl,sync());
+ IMPORT_PLUS(dest_tr,sync());
+ IMPORT_PLUS(dest_bl,sync());
+ IMPORT_PLUS(dest_br,sync());
+ IMPORT(clip);
+ IMPORT(horizon);
+
+ return false;
+}
+
+ValueBase
+Warp::get_param(const String ¶m)const
+{
+ EXPORT(src_tl);
+ EXPORT(src_br);
+ EXPORT(dest_tl);
+ EXPORT(dest_tr);
+ EXPORT(dest_bl);
+ EXPORT(dest_br);
+ EXPORT(clip);
+ EXPORT(horizon);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return ValueBase();
+}
+
+Layer::Vocab
+Warp::get_param_vocab()const
+{
+ Layer::Vocab ret;
+
+ ret.push_back(ParamDesc("src_tl")
+ .set_local_name(_("Source TL"))
+ .set_box("src_br")
+ );
+
+ ret.push_back(ParamDesc("src_br")
+ .set_local_name(_("Source BR"))
+ );
+
+ ret.push_back(ParamDesc("dest_tl")
+ .set_local_name(_("Dest TL"))
+ .set_connect("dest_tr")
+ );
+
+ ret.push_back(ParamDesc("dest_tr")
+ .set_local_name(_("Dest TR"))
+ .set_connect("dest_br")
+ );
+
+ ret.push_back(ParamDesc("dest_br")
+ .set_local_name(_("Dest BR"))
+ .set_connect("dest_bl")
+ );
+
+ ret.push_back(ParamDesc("dest_bl")
+ .set_local_name(_("Dest BL"))
+ .set_connect("dest_tl")
+ );
+
+ ret.push_back(ParamDesc("clip")
+ .set_local_name(_("Clip"))
+ );
+
+ ret.push_back(ParamDesc("horizon")
+ .set_local_name(_("Horizon"))
+ );
+
+ return ret;
+}
+
+
+class Warp_Trans : public Transform
+{
+ etl::handle<const Warp> layer;
+public:
+ Warp_Trans(const Warp* x):Transform(x->get_guid()),layer(x) { }
+
+ synfig::Vector perform(const synfig::Vector& x)const
+ {
+ return layer->transform_backward(x);
+ //Point pos(x-layer->origin);
+ //return Point(layer->cos_val*pos[0]-layer->sin_val*pos[1],layer->sin_val*pos[0]+layer->cos_val*pos[1])+layer->origin;
+ }
+
+ synfig::Vector unperform(const synfig::Vector& x)const
+ {
+
+ return layer->transform_forward(x);
+ //Point pos(x-layer->origin);
+ //return Point(layer->cos_val*pos[0]+layer->sin_val*pos[1],-layer->sin_val*pos[0]+layer->cos_val*pos[1])+layer->origin;
+ }
+};
+etl::handle<Transform>
+Warp::get_transform()const
+{
+ return new Warp_Trans(this);
+}
+
+synfig::Layer::Handle
+Warp::hit_check(synfig::Context context, const synfig::Point &p)const
+{
+ Point newpos(transform_forward(p));
+
+ if(clip)
+ {
+ Rect rect(src_tl,src_br);
+ if(!rect.is_inside(newpos))
+ return 0;
+ }
+
+ return context.hit_check(newpos);
+}
+
+Color
+Warp::get_color(Context context, const Point &p)const
+{
+ Point newpos(transform_forward(p));
+
+ if(clip)
+ {
+ Rect rect(src_tl,src_br);
+ if(!rect.is_inside(newpos))
+ return Color::alpha();
+ }
+
+ const float z(transform_backward_z(newpos));
+ if(z>0 && z<horizon)
+ return context.get_color(newpos);
+ else
+ return Color::alpha();
+}
+
+//#define ACCEL_WARP_IS_BROKEN 1
+
+bool
+Warp::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback stageone(cb,0,9000,10000);
+ SuperCallback stagetwo(cb,9000,10000,10000);
+
+ Real pw=(renddesc.get_w())/(renddesc.get_br()[0]-renddesc.get_tl()[0]);
+ Real ph=(renddesc.get_h())/(renddesc.get_br()[1]-renddesc.get_tl()[1]);
+
+ if(cb && !cb->amount_complete(0,10000))
+ return false;
+
+ Point tl(renddesc.get_tl());
+ Point br(renddesc.get_br());
+
+ Rect bounding_rect;
+
+ Rect render_rect(tl,br);
+ Rect clip_rect(Rect::full_plane());
+ Rect dest_rect(dest_tl,dest_br); dest_rect.expand(dest_tr).expand(dest_bl);
+
+ Real zoom_factor(1.0);
+
+ // Quick exclusion clip, if necessary
+ if(clip && !intersect(render_rect,dest_rect))
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ surface->clear();
+ return true;
+ }
+
+ {
+ Rect other(render_rect);
+ if(clip)
+ other&=dest_rect;
+
+ Point min(other.get_min());
+ Point max(other.get_max());
+
+ bool init_point_set=false;
+
+ // Point trans_point[4];
+ Point p;
+ // Real trans_z[4];
+ Real z,minz(10000000000000.0f),maxz(0);
+
+ //! \todo checking the 4 corners for 0<=z<horizon*2 and using
+ //! only 4 corners which satisfy this condition isn't the
+ //! right thing to do. It's possible that none of the 4
+ //! corners fall within that range, and yet content of the
+ //! tile does.
+ p=transform_forward(min);
+ z=transform_backward_z(p);
+ if(z>0 && z<horizon*2)
+ {
+ if(init_point_set)
+ bounding_rect.expand(p);
+ else
+ bounding_rect=Rect(p);
+ init_point_set=true;
+ maxz=std::max(maxz,z);
+ minz=std::min(minz,z);
+ }
+
+ p=transform_forward(max);
+ z=transform_backward_z(p);
+ if(z>0 && z<horizon*2)
+ {
+ if(init_point_set)
+ bounding_rect.expand(p);
+ else
+ bounding_rect=Rect(p);
+ init_point_set=true;
+ maxz=std::max(maxz,z);
+ minz=std::min(minz,z);
+ }
+
+ swap(min[1],max[1]);
+
+ p=transform_forward(min);
+ z=transform_backward_z(p);
+ if(z>0 && z<horizon*2)
+ {
+ if(init_point_set)
+ bounding_rect.expand(p);
+ else
+ bounding_rect=Rect(p);
+ init_point_set=true;
+ maxz=std::max(maxz,z);
+ minz=std::min(minz,z);
+ }
+
+ p=transform_forward(max);
+ z=transform_backward_z(p);
+ if(z>0 && z<horizon*2)
+ {
+ if(init_point_set)
+ bounding_rect.expand(p);
+ else
+ bounding_rect=Rect(p);
+ init_point_set=true;
+ maxz=std::max(maxz,z);
+ minz=std::min(minz,z);
+ }
+
+ if(!init_point_set)
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ surface->clear();
+ return true;
+ }
+ zoom_factor=(1+(maxz-minz));
+
+ }
+
+#ifdef ACCEL_WARP_IS_BROKEN
+ return Layer::accelerated_render(context,surface,quality,renddesc, cb);
+#else
+
+ /*swap(tl[1],br[1]);
+ bounding_rect
+ .expand(transform_forward(tl))
+ .expand(transform_forward(br))
+ ;
+ swap(tl[1],br[1]);*/
+
+ //synfig::warning("given window: [%f,%f]-[%f,%f] %dx%d",tl[0],tl[1],br[0],br[1],renddesc.get_w(),renddesc.get_h());
+ //synfig::warning("Projected: [%f,%f]-[%f,%f]",bounding_rect.get_min()[0],bounding_rect.get_min()[1],bounding_rect.get_max()[0],bounding_rect.get_max()[1]);
+
+ // If we are clipping, then go ahead and clip to the
+ // source rectangle
+ if(clip)
+ clip_rect&=Rect(src_tl,src_br);
+
+ // Bound ourselves to the bounding rectangle of
+ // what is under us
+ clip_rect&=context.get_full_bounding_rect();//.expand_x(abs(zoom_factor/pw)).expand_y(abs(zoom_factor/ph));
+
+ bounding_rect&=clip_rect;
+
+ Point min_point(bounding_rect.get_min());
+ Point max_point(bounding_rect.get_max());
+
+ // we're going to divide by the different of these pairs soon;
+ // if they're the same, we'll be dividing by zero, and we don't
+ // want to do that!
+ // \todo what should we do in this case?
+ if (min_point[0] == max_point[0] || min_point[1] == max_point[1])
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ surface->clear();
+ return true;
+ }
+
+ if(tl[0]>br[0])
+ {
+ tl[0]=max_point[0];
+ br[0]=min_point[0];
+ }
+ else
+ {
+ br[0]=max_point[0];
+ tl[0]=min_point[0];
+ }
+ if(tl[1]>br[1])
+ {
+ tl[1]=max_point[1];
+ br[1]=min_point[1];
+ }
+ else
+ {
+ br[1]=max_point[1];
+ tl[1]=min_point[1];
+ }
+
+
+
+ const int tmp_d(max(renddesc.get_w(),renddesc.get_h()));
+ Real src_pw=(tmp_d*zoom_factor)/(br[0]-tl[0]);
+ Real src_ph=(tmp_d*zoom_factor)/(br[1]-tl[1]);
+
+
+ RendDesc desc(renddesc);
+ desc.clear_flags();
+ //desc.set_flags(RendDesc::PX_ASPECT);
+ desc.set_tl(tl);
+ desc.set_br(br);
+ desc.set_wh(ceil_to_int(src_pw*(br[0]-tl[0])),ceil_to_int(src_ph*(br[1]-tl[1])));
+
+ //synfig::warning("surface to render: [%f,%f]-[%f,%f] %dx%d",desc.get_tl()[0],desc.get_tl()[1],desc.get_br()[0],desc.get_br()[1],desc.get_w(),desc.get_h());
+ if(desc.get_w()==0 && desc.get_h()==0)
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ surface->clear();
+ return true;
+ }
+
+ // Recalculate the pixel widths for the src renddesc
+ src_pw=(desc.get_w())/(desc.get_br()[0]-desc.get_tl()[0]);
+ src_ph=(desc.get_h())/(desc.get_br()[1]-desc.get_tl()[1]);
+
+
+ Surface source;
+ source.set_wh(desc.get_w(),desc.get_h());
+
+ if(!context.accelerated_render(&source,quality,desc,&stageone))
+ return false;
+
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ surface->clear();
+
+ Surface::pen pen(surface->begin());
+
+ if(quality<=4)
+ {
+ // CUBIC
+ int x,y;
+ float u,v;
+ Point point,tmp;
+ for(y=0,point[1]=renddesc.get_tl()[1];y<surface->get_h();y++,pen.inc_y(),pen.dec_x(x),point[1]+=1.0/ph)
+ {
+ for(x=0,point[0]=renddesc.get_tl()[0];x<surface->get_w();x++,pen.inc_x(),point[0]+=1.0/pw)
+ {
+ tmp=transform_forward(point);
+ const float z(transform_backward_z(tmp));
+ if(!clip_rect.is_inside(tmp) || !(z>0 && z<horizon))
+ {
+ (*surface)[y][x]=Color::alpha();
+ continue;
+ }
+
+ u=(tmp[0]-tl[0])*src_pw;
+ v=(tmp[1]-tl[1])*src_ph;
+
+ if(u<0 || v<0 || u>=source.get_w() || v>=source.get_h() || isnan(u) || isnan(v))
+ (*surface)[y][x]=context.get_color(tmp);
+ else
+ (*surface)[y][x]=source.cubic_sample(u,v);
+ }
+ if(y&31==0 && cb)
+ {
+ if(!stagetwo.amount_complete(y,surface->get_h()))
+ return false;
+ }
+ }
+ }
+ else
+ if(quality<=6)
+ {
+ // INTERPOLATION_LINEAR
+ int x,y;
+ float u,v;
+ Point point,tmp;
+ for(y=0,point[1]=renddesc.get_tl()[1];y<surface->get_h();y++,pen.inc_y(),pen.dec_x(x),point[1]+=1.0/ph)
+ {
+ for(x=0,point[0]=renddesc.get_tl()[0];x<surface->get_w();x++,pen.inc_x(),point[0]+=1.0/pw)
+ {
+ tmp=transform_forward(point);
+ const float z(transform_backward_z(tmp));
+ if(!clip_rect.is_inside(tmp) || !(z>0 && z<horizon))
+ {
+ (*surface)[y][x]=Color::alpha();
+ continue;
+ }
+
+ u=(tmp[0]-tl[0])*src_pw;
+ v=(tmp[1]-tl[1])*src_ph;
+
+ if(u<0 || v<0 || u>=source.get_w() || v>=source.get_h() || isnan(u) || isnan(v))
+ (*surface)[y][x]=context.get_color(tmp);
+ else
+ (*surface)[y][x]=source.linear_sample(u,v);
+ }
+ if(y&31==0 && cb)
+ {
+ if(!stagetwo.amount_complete(y,surface->get_h()))
+ return false;
+ }
+ }
+ }
+ else
+ {
+ // NEAREST_NEIGHBOR
+ int x,y;
+ float u,v;
+ Point point,tmp;
+ for(y=0,point[1]=renddesc.get_tl()[1];y<surface->get_h();y++,pen.inc_y(),pen.dec_x(x),point[1]+=1.0/ph)
+ {
+ for(x=0,point[0]=renddesc.get_tl()[0];x<surface->get_w();x++,pen.inc_x(),point[0]+=1.0/pw)
+ {
+ tmp=transform_forward(point);
+ const float z(transform_backward_z(tmp));
+ if(!clip_rect.is_inside(tmp) || !(z>0 && z<horizon))
+ {
+ (*surface)[y][x]=Color::alpha();
+ continue;
+ }
+
+ u=(tmp[0]-tl[0])*src_pw;
+ v=(tmp[1]-tl[1])*src_ph;
+
+ if(u<0 || v<0 || u>=source.get_w() || v>=source.get_h() || isnan(u) || isnan(v))
+ (*surface)[y][x]=context.get_color(tmp);
+ else
+ //pen.set_value(source[v][u]);
+ (*surface)[y][x]=source[floor_to_int(v)][floor_to_int(u)];
+ }
+ if(y&31==0 && cb)
+ {
+ if(!stagetwo.amount_complete(y,surface->get_h()))
+ return false;
+ }
+ }
+ }
+
+#endif
+
+ if(cb && !cb->amount_complete(10000,10000)) return false;
+
+ return true;
+}
+
+synfig::Rect
+Warp::get_bounding_rect()const
+{
+ return Rect::full_plane();
+}
+
+synfig::Rect
+Warp::get_full_bounding_rect(Context context)const
+{
+// return Rect::full_plane();
+
+ Rect under(context.get_full_bounding_rect());
+
+ if(clip)
+ {
+ under&=Rect(src_tl,src_br);
+ }
+
+ return get_transform()->perform(under);
+
+ /*
+ Rect under(context.get_full_bounding_rect());
+ Rect ret(Rect::zero());
+
+ if(under.area()==HUGE_VAL)
+ return Rect::full_plane();
+
+ ret.expand(
+ transform_backward(
+ under.get_min()
+ )
+ );
+ ret.expand(
+ transform_backward(
+ under.get_max()
+ )
+ );
+ ret.expand(
+ transform_backward(
+ Vector(
+ under.get_min()[0],
+ under.get_max()[1]
+ )
+ )
+ );
+ ret.expand(
+ transform_backward(
+ Vector(
+ under.get_max()[0],
+ under.get_min()[1]
+ )
+ )
+ );
+
+ if(ret.area()==HUGE_VAL)
+ return Rect::full_plane();
+
+ return ret;
+ */
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file warp.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_WARP_H
+#define __SYNFIG_WARP_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/vector.h>
+#include <synfig/angle.h>
+#include <synfig/layer.h>
+#include <synfig/rect.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+class Warp_Trans;
+
+class Warp : public Layer
+{
+ SYNFIG_LAYER_MODULE_EXT
+ friend class Warp_Trans;
+private:
+
+ Point src_tl,src_br,dest_tl,dest_tr,dest_bl,dest_br;
+
+ Real horizon;
+
+ Real cache_a,cache_b,cache_c,cache_d,cache_e,cache_f,cache_i,cache_j;
+
+ Real matrix[3][3];
+ Real inv_matrix[3][3];
+
+ Point transform_forward(const Point& p)const;
+ Point transform_backward(const Point& p)const;
+
+ Real transform_forward_z(const Point& p)const;
+ Real transform_backward_z(const Point& p)const;
+
+ bool clip;
+
+public:
+ void sync();
+
+ Warp();
+ ~Warp();
+
+ virtual synfig::Rect get_full_bounding_rect(synfig::Context context)const;
+ virtual synfig::Rect get_bounding_rect()const;
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+ virtual ValueBase get_param(const synfig::String & param)const;
+ virtual Color get_color(Context context, const Point &pos)const;
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+ virtual Vocab get_param_vocab()const;
+ virtual etl::handle<synfig::Transform> get_transform()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file xorpattern.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "xorpattern.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(XORPattern);
+SYNFIG_LAYER_SET_NAME(XORPattern,"xor_pattern");
+SYNFIG_LAYER_SET_LOCAL_NAME(XORPattern,_("XOR Pattern"));
+SYNFIG_LAYER_SET_CATEGORY(XORPattern,_("Other"));
+SYNFIG_LAYER_SET_VERSION(XORPattern,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(XORPattern,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+XORPattern::XORPattern():
+ Layer_Composite (1.0,Color::BLEND_STRAIGHT),
+ pos(0.125,0.125),
+ size(0.25,0.25)
+{
+}
+
+bool
+XORPattern::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(pos);
+ IMPORT(size);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+XORPattern::get_param(const String & param)const
+{
+ EXPORT(pos);
+ EXPORT(size);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Color
+XORPattern::get_color(Context context, const Point &point)const
+{
+ if(get_amount()==0.0)
+ return context.get_color(point);
+
+ unsigned int a=(unsigned int)floor((point[0]-pos[0])/size[0]), b=(unsigned int)floor((point[1]-pos[1])/size[1]);
+ unsigned char rindex=(a^b);
+ unsigned char gindex=(a^(~b))*4;
+ unsigned char bindex=~(a^b)*2;
+
+ Color color((Color::value_type)rindex/(Color::value_type)255.0,
+ (Color::value_type)gindex/(Color::value_type)255.0,
+ (Color::value_type)bindex/(Color::value_type)255.0,
+ 1.0);
+
+ if(get_amount() == 1 && get_blend_method() == Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,context.get_color(point),get_amount(),get_blend_method());
+
+}
+
+Layer::Vocab
+XORPattern::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("pos")
+ .set_local_name(_("Offset"))
+ );
+ ret.push_back(ParamDesc("size")
+ .set_local_name(_("Size"))
+ .set_origin("pos")
+ );
+
+ return ret;
+}
+
+synfig::Layer::Handle
+XORPattern::hit_check(synfig::Context context, const synfig::Point &getpos)const
+{
+ // if we have a zero amount
+ if(get_amount()==0.0)
+ // then the click passes down to our context
+ return context.hit_check(getpos);
+
+ synfig::Layer::Handle tmp;
+ // if we are behind the context, and the click hits something in the context
+ if(get_blend_method()==Color::BLEND_BEHIND && (tmp=context.hit_check(getpos)))
+ // then return the thing it hit in the context
+ return tmp;
+
+ // if we're using an 'onto' blend method and the click missed the context
+ if(Color::is_onto(get_blend_method()) && !(tmp=context.hit_check(getpos)))
+ // then it misses everything
+ return 0;
+
+ // otherwise the click hit us, since we're the size of the whole plane
+ return const_cast<XORPattern*>(this);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file xorpattern.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_XORPATTERN_H
+#define __SYNFIG_XORPATTERN_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/context.h>
+#include <synfig/vector.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class XORPattern : public synfig::Layer_Composite, public synfig::Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ Point pos;
+ Point size;
+
+public:
+ XORPattern();
+
+ virtual bool set_param(const String ¶m, const ValueBase &value);
+ virtual ValueBase get_param(const String ¶m)const;
+ virtual Color get_color(Context context, const Point &pos)const;
+ virtual Vocab get_param_vocab()const;
+ virtual synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file zoom.cpp
+** \brief writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "zoom.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/transform.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Zoom);
+SYNFIG_LAYER_SET_NAME(Zoom,"zoom");
+SYNFIG_LAYER_SET_LOCAL_NAME(Zoom,_("Zoom"));
+SYNFIG_LAYER_SET_CATEGORY(Zoom,_("Transform"));
+SYNFIG_LAYER_SET_VERSION(Zoom,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Zoom,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Zoom::Zoom():
+ center(0,0),
+ amount(0)
+{
+}
+
+bool
+Zoom::set_param(const String & param, const ValueBase &value)
+{
+
+ IMPORT(center);
+ IMPORT(amount);
+
+ return false;
+}
+
+ValueBase
+Zoom::get_param(const String ¶m)const
+{
+ EXPORT(center);
+ EXPORT(amount);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return ValueBase();
+}
+
+Layer::Vocab
+Zoom::get_param_vocab()const
+{
+ Layer::Vocab ret;
+
+ ret.push_back(ParamDesc("amount")
+ .set_local_name(_("Amount"))
+ .set_description(_("Amount to zoom in"))
+ );
+
+ ret.push_back(ParamDesc("center")
+ .set_local_name(_("Center"))
+ .set_description(_("Point to zoom in to"))
+ );
+
+ return ret;
+}
+
+synfig::Layer::Handle
+Zoom::hit_check(synfig::Context context, const synfig::Point &pos)const
+{
+ return context.hit_check((pos-center)/exp(amount)+center);
+}
+
+Color
+Zoom::get_color(Context context, const Point &pos)const
+{
+ return context.get_color((pos-center)/exp(amount)+center);
+}
+
+class Zoom_Trans : public Transform
+{
+ etl::handle<const Zoom> layer;
+public:
+ Zoom_Trans(const Zoom* x):Transform(x->get_guid()),layer(x) { }
+
+ synfig::Vector perform(const synfig::Vector& x)const
+ {
+ return (x-layer->center)*exp(layer->amount)+layer->center;
+ }
+
+ synfig::Vector unperform(const synfig::Vector& x)const
+ {
+ return (x-layer->center)/exp(layer->amount)+layer->center;
+ }
+};
+etl::handle<Transform>
+Zoom::get_transform()const
+{
+ return new Zoom_Trans(this);
+}
+
+bool
+Zoom::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ Vector::value_type zoomfactor=1.0/exp(amount);
+ RendDesc desc(renddesc);
+ desc.clear_flags();
+
+ // Adjust the top_left and bottom_right points
+ // for our zoom amount
+ desc.set_tl((desc.get_tl()-center)*zoomfactor+center);
+ desc.set_br((desc.get_br()-center)*zoomfactor+center);
+
+ // Render the scene
+ return context.accelerated_render(surface,quality,desc,cb);
+}
+
+synfig::Rect
+Zoom::get_full_bounding_rect(synfig::Context context)const
+{
+ return (context.get_full_bounding_rect()-center)*exp(amount)+center;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file zoom.h
+** \brief writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_ZOOM_H
+#define __SYNFIG_ZOOM_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer.h>
+#include <synfig/vector.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class Zoom_Trans;
+
+class Zoom : public Layer
+{
+ SYNFIG_LAYER_MODULE_EXT
+ friend class Zoom_Trans;
+private:
+ Vector center;
+ Real amount;
+public:
+ Zoom();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+ virtual ValueBase get_param(const String & param)const;
+ virtual Color get_color(Context context, const Point &pos)const;
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+ virtual Vocab get_param_vocab()const;
+ virtual synfig::Rect get_full_bounding_rect(synfig::Context context)const;
+ virtual etl::handle<synfig::Transform> get_transform()const;
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+module_LTLIBRARIES = libmod_bmp.la
+libmod_bmp_la_SOURCES = main.cpp trgt_bmp.cpp trgt_bmp.h mptr_bmp.cpp mptr_bmp.h
+libmod_bmp_la_LDFLAGS = -module -no-undefined
+libmod_bmp_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_bmp_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+EXTRA_DIST= mod_bmp.nsh unmod_bmp.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_bmp/main.cpp
+** \brief writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include <synfig/layer.h>
+#include "trgt_bmp.h"
+#include "mptr_bmp.h"
+
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(mod_bmp)
+ MODULE_NAME("Microsoft BMP File Format Module")
+ MODULE_DESCRIPTION("Provides a Microsoft BMP output target and importer")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(mod_bmp)
+ BEGIN_TARGETS
+ TARGET(bmp)
+ END_TARGETS
+ BEGIN_IMPORTERS
+ IMPORTER(bmp_mptr)
+ END_IMPORTERS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_bmp" Sec_mod_bmp
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_bmp.dll "src\modules\mod_bmp\.libs\libmod_bmp-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_bmp"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_bmp.cpp
+** \brief bmp Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "mptr_bmp.h"
+#include <synfig/general.h>
+#include <synfig/surface.h>
+
+#include <algorithm>
+#include <functional>
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_IMPORTER_INIT(bmp_mptr);
+SYNFIG_IMPORTER_SET_NAME(bmp_mptr,"bmp");
+SYNFIG_IMPORTER_SET_EXT(bmp_mptr,"bmp");
+SYNFIG_IMPORTER_SET_VERSION(bmp_mptr,"0.1");
+SYNFIG_IMPORTER_SET_CVS_ID(bmp_mptr,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+struct BITMAPFILEHEADER
+{
+ unsigned char bfType[2];
+ unsigned long bfSize;
+ unsigned short bfReserved1;
+ unsigned short bfReserved2;
+ unsigned long bfOffsetBits;
+};
+
+struct BITMAPINFOHEADER
+{
+ unsigned long biSize;
+ long biWidth;
+ long biHeight;
+ unsigned short biPlanes;
+ unsigned short biBitCount;
+ unsigned long biCompression;
+ unsigned long biSizeImage;
+ long biXPelsPerMeter;
+ long biYPelsPerMeter;
+ unsigned long biClrUsed;
+ unsigned long biClrImportant;
+};
+
+#ifdef WORDS_BIGENDIAN
+inline long little_endian(const long &x)
+{
+ long ret;
+ char *big_e=(char *)&ret;
+ char *lit_e=(char *)&x;
+ big_e[0]=lit_e[3];
+ big_e[1]=lit_e[2];
+ big_e[2]=lit_e[1];
+ big_e[3]=lit_e[0];
+ return ret;
+}
+inline short little_endian_short(const short &x)
+{
+ short ret;
+ char *big_e=(char *)&ret;
+ char *lit_e=(char *)&x;
+ big_e[0]=lit_e[1];
+ big_e[1]=lit_e[0];
+ return ret;
+}
+#else
+#define little_endian(x) (x)
+#define little_endian_short(x) (x)
+#endif
+
+
+
+
+
+
+bmp_mptr::bmp_mptr(const char *file)
+{
+ filename=file;
+}
+
+bmp_mptr::~bmp_mptr()
+{
+}
+
+bool
+bmp_mptr::get_frame(synfig::Surface &surface,Time /*time*/, synfig::ProgressCallback *cb)
+{
+ FILE *file=fopen(filename.c_str(),"rb");
+ if(!file)
+ {
+ if(cb)cb->error("bmp_mptr::GetFrame(): "+strprintf(_("Unable to open %s"),filename.c_str()));
+ else synfig::error("bmp_mptr::GetFrame(): "+strprintf(_("Unable to open %s"),filename.c_str()));
+ return false;
+ }
+
+ BITMAPFILEHEADER fileheader;
+ BITMAPINFOHEADER infoheader;
+ char b_char=fgetc(file);
+ char m_char=fgetc(file);
+
+ if(b_char!='B' || m_char!='M')
+ {
+ if(cb)cb->error("bmp_mptr::GetFrame(): "+strprintf(_("%s is not in BMP format"),filename.c_str()));
+ else synfig::error("bmp_mptr::GetFrame(): "+strprintf(_("%s is not in BMP format"),filename.c_str()));
+ return false;
+ }
+
+ if(fread(&fileheader.bfSize, 1, sizeof(BITMAPFILEHEADER)-4, file)!=sizeof(BITMAPFILEHEADER)-4)
+ {
+ String str("bmp_mptr::get_frame(): "+strprintf(_("Failure while reading BITMAPFILEHEADER from %s"),filename.c_str()));
+ if(cb)cb->error(str);
+ else synfig::error(str);
+ return false;
+ }
+
+ if(fread(&infoheader, 1, sizeof(BITMAPINFOHEADER), file)!=sizeof(BITMAPINFOHEADER))
+ {
+ String str("bmp_mptr::get_frame(): "+strprintf(_("Failure while reading BITMAPINFOHEADER from %s"),filename.c_str()));
+ if(cb)cb->error(str);
+ else synfig::error(str);
+ return false;
+ }
+
+ int offset=little_endian(fileheader.bfOffsetBits);
+
+ if(offset!=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)-2)
+ {
+ String str("bmp_mptr::get_frame(): "+strprintf(_("Bad BITMAPFILEHEADER in %s. (bfOffsetBits=%d, should be %d)"),filename.c_str(),offset,sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)-2));
+ if(cb)cb->error(str);
+ else synfig::error(str);
+ return false;
+ }
+
+ if(little_endian(infoheader.biSize)!=little_endian(40))
+ {
+ String str("bmp_mptr::get_frame(): "+strprintf(_("Bad BITMAPINFOHEADER in %s. (biSize=%d, should be 40)"),filename.c_str(),little_endian(infoheader.biSize)));
+ if(cb)cb->error(str);
+ else synfig::error(str);
+ return false;
+ }
+
+ int w,h,bit_count;
+
+ w=little_endian(infoheader.biWidth);
+ h=little_endian(infoheader.biHeight);
+ bit_count=little_endian_short(infoheader.biBitCount);
+
+ synfig::warning("w:%d\n",w);
+ synfig::warning("h:%d\n",h);
+ synfig::warning("bit_count:%d\n",bit_count);
+
+ if(little_endian(infoheader.biCompression))
+ {
+ if(cb)cb->error("bmp_mptr::GetFrame(): "+string(_("Reading compressed bitmaps is not supported")));
+ else synfig::error("bmp_mptr::GetFrame(): "+string(_("Reading compressed bitmaps is not supported")));
+ return false;
+ }
+
+ if(bit_count!=24 && bit_count!=32)
+ {
+ if(cb)cb->error("bmp_mptr::GetFrame(): "+strprintf(_("Unsupported bit depth (bit_count=%d, should be 24 or 32)"),bit_count));
+ else synfig::error("bmp_mptr::GetFrame(): "+strprintf(_("Unsupported bit depth (bit_count=%d, should be 24 or 32)"),bit_count));
+ return false;
+ }
+
+ int x;
+ int y;
+ surface.set_wh(w,h);
+ for(y=0;y<surface.get_h();y++)
+ for(x=0;x<surface.get_w();x++)
+ {
+// float b=(float)(unsigned char)fgetc(file)*(1.0/255.0);
+// float g=(float)(unsigned char)fgetc(file)*(1.0/255.0);
+// float r=(float)(unsigned char)fgetc(file)*(1.0/255.0);
+ float b=gamma().b_U8_to_F32((unsigned char)fgetc(file));
+ float g=gamma().g_U8_to_F32((unsigned char)fgetc(file));
+ float r=gamma().r_U8_to_F32((unsigned char)fgetc(file));
+
+ surface[h-y-1][x]=Color(
+ r,
+ g,
+ b,
+ 1.0
+ );
+ if(bit_count==32)
+ fgetc(file);
+ }
+
+
+ fclose(file);
+ return true;
+}
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_bmp.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_MPTR_PPM_H
+#define __SYNFIG_MPTR_PPM_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/importer.h>
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <cstdio>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class bmp_mptr : public synfig::Importer
+{
+SYNFIG_IMPORTER_MODULE_EXT
+
+private:
+ synfig::String filename;
+
+public:
+ bmp_mptr(const char *filename);
+ ~bmp_mptr();
+
+ virtual bool get_frame(synfig::Surface &surface,synfig::Time time, synfig::ProgressCallback *callback);
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_bmp.cpp
+** \brief Bitmap Target
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trgt_bmp.h"
+#include <synfig/general.h>
+
+#include <cstdio>
+#include <algorithm>
+#include <functional>
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === I N F O ============================================================= */
+
+SYNFIG_TARGET_INIT(bmp);
+SYNFIG_TARGET_SET_NAME(bmp,"bmp");
+SYNFIG_TARGET_SET_EXT(bmp,"bmp");
+SYNFIG_TARGET_SET_VERSION(bmp,"0.1");
+SYNFIG_TARGET_SET_CVS_ID(bmp,"$Id$");
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+struct BITMAPFILEHEADER
+{
+ unsigned char bfType[2];
+ unsigned long bfSize;
+ unsigned short bfReserved1;
+ unsigned short bfReserved2;
+ unsigned long bfOffsetBits;
+};
+
+struct BITMAPINFOHEADER
+{
+ unsigned long biSize;
+ long biWidth;
+ long biHeight;
+ unsigned short biPlanes;
+ unsigned short biBitCount;
+ unsigned long biCompression;
+ unsigned long biSizeImage;
+ long biXPelsPerMeter;
+ long biYPelsPerMeter;
+ unsigned long biClrUsed;
+ unsigned long biClrImportant;
+};
+
+/* === M E T H O D S ======================================================= */
+
+#ifdef WORDS_BIGENDIAN
+inline long little_endian(const long &x)
+{
+ long ret;
+ char *big_e=(char *)&ret;
+ char *lit_e=(char *)&x;
+ big_e[0]=lit_e[3];
+ big_e[1]=lit_e[2];
+ big_e[2]=lit_e[1];
+ big_e[3]=lit_e[0];
+ return ret;
+}
+inline short little_endian_short(const short &x)
+{
+ short ret;
+ char *big_e=(char *)&ret;
+ char *lit_e=(char *)&x;
+ big_e[0]=lit_e[1];
+ big_e[1]=lit_e[0];
+ return ret;
+}
+#else
+#define little_endian(x) (x)
+#define little_endian_short(x) (x)
+#endif
+
+bmp::bmp(const char *Filename)
+{
+ file=NULL;
+ filename=Filename;
+ multi_image=false;
+ buffer=0;
+ color_buffer=0;
+ set_remove_alpha();
+
+}
+
+bmp::~bmp()
+{
+ if(file)
+ fclose(file);
+ file=NULL;
+ delete [] buffer;
+ delete [] color_buffer;
+}
+
+bool
+bmp::set_rend_desc(RendDesc *given_desc)
+{
+ pf=PF_BGR;
+
+ // Flip the image upside down,
+ // because bitmaps are upside down.
+ given_desc->set_flags(0);
+ Point tl=given_desc->get_tl();
+ Point br=given_desc->get_br();
+ Point::value_type tmp;
+ tmp=tl[1];
+ tl[1]=br[1];
+ br[1]=tmp;
+ given_desc->set_tl(tl);
+ given_desc->set_br(br);
+
+ desc=*given_desc;
+ if(desc.get_frame_end()-desc.get_frame_start()>0)
+ {
+ multi_image=true;
+ imagecount=desc.get_frame_start();
+ }
+ else
+ multi_image=false;
+
+ return true;
+}
+
+void
+bmp::end_frame()
+{
+ if(file)
+ fclose(file);
+ delete [] color_buffer;
+ color_buffer=0;
+ file=NULL;
+ imagecount++;
+}
+
+bool
+bmp::start_frame(synfig::ProgressCallback *callback)
+{
+ int w=desc.get_w(),h=desc.get_h();
+
+ rowspan=4*((w*(channels(pf)*8)+31)/32);
+ if(multi_image)
+ {
+ String
+ newfilename(filename),
+ ext(find(filename.begin(),filename.end(),'.'),filename.end());
+ newfilename.erase(find(newfilename.begin(),newfilename.end(),'.'),newfilename.end());
+
+ newfilename+=etl::strprintf("%04d",imagecount)+ext;
+ file=fopen(newfilename.c_str(),"wb");
+ if(callback)callback->task(newfilename+_(" (animated)"));
+ }
+ else
+ {
+ file=fopen(filename.c_str(),"wb");
+ if(callback)callback->task(filename);
+ }
+
+ if(!file)
+ {
+ if(callback)callback->error(_("Unable to open file"));
+ else synfig::error(_("Unable to open file"));
+ return false;
+ }
+
+ BITMAPFILEHEADER fileheader;
+ BITMAPINFOHEADER infoheader;
+
+ fileheader.bfType[0]='B';
+ fileheader.bfType[1]='M';
+ fileheader.bfSize=little_endian(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+rowspan*h);
+ fileheader.bfReserved1=0;
+ fileheader.bfReserved2=0;
+ fileheader.bfOffsetBits=little_endian(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)-2);
+
+ infoheader.biSize=little_endian(40);
+ infoheader.biWidth=little_endian(w);
+ infoheader.biHeight=little_endian(h);
+ infoheader.biPlanes=little_endian_short((short)1);
+ infoheader.biBitCount=little_endian_short((short)(channels(pf)*8));
+ infoheader.biCompression=little_endian(0);
+ infoheader.biSizeImage=little_endian(0);
+ infoheader.biXPelsPerMeter=little_endian((int)rend_desc().get_x_res());
+ infoheader.biYPelsPerMeter=little_endian((int)rend_desc().get_y_res()); // pels per meter...?
+ infoheader.biClrUsed=little_endian(0);
+ infoheader.biClrImportant=little_endian(0);
+
+ fprintf(file,"BM");
+
+ if(!fwrite(&fileheader.bfSize,sizeof(BITMAPFILEHEADER)-4,1,file))
+ {
+ if(callback)callback->error(_("Unable to write file header to file"));
+ else synfig::error(_("Unable to write file header to file"));
+ return false;
+ }
+
+ if(!fwrite(&infoheader,sizeof(BITMAPINFOHEADER),1,file))
+ {
+ if(callback)callback->error(_("Unable to write info header"));
+ else synfig::error(_("Unable to write info header"));
+ return false;
+ }
+
+ delete [] buffer;
+ buffer=new unsigned char[rowspan];
+
+ delete [] color_buffer;
+ color_buffer=new Color[desc.get_w()];
+
+ return true;
+}
+
+Color *
+bmp::start_scanline(int /*scanline*/)
+{
+ return color_buffer;
+}
+
+bool
+bmp::end_scanline()
+{
+ if(!file)
+ return false;
+
+ convert_color_format(buffer, color_buffer, desc.get_w(), pf, gamma());
+
+ if(!fwrite(buffer,1,rowspan,file))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_bmp.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRGT_BMP_H
+#define __SYNFIG_TRGT_BMP_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/target_scanline.h>
+#include <synfig/string.h>
+#include <cstdio>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class bmp : public synfig::Target_Scanline
+{
+ SYNFIG_TARGET_MODULE_EXT
+private:
+ int rowspan;
+ int imagecount;
+ bool multi_image;
+ FILE *file;
+ synfig::String filename;
+ unsigned char *buffer;
+ synfig::Color *color_buffer;
+ synfig::PixelFormat pf;
+
+public:
+ bmp(const char *filename);
+ virtual ~bmp();
+
+ virtual bool set_rend_desc(synfig::RendDesc *desc);
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+ virtual void end_frame();
+ virtual synfig::Color * start_scanline(int scanline);
+ virtual bool end_scanline();
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_bmp"
+ Delete "$INSTDIR\lib\synfig\modules\mod_bmp.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+if WITH_LIBDV
+module_LTLIBRARIES = libmod_dv.la
+libmod_dv_la_SOURCES = main.cpp trgt_dv.cpp trgt_dv.h
+libmod_dv_la_LDFLAGS = -module -no-undefined
+libmod_dv_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_dv_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+else
+endif
+EXTRA_DIST= mod_dv.nsh unmod_dv.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_dv/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include "trgt_dv.h"
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(mod_dv)
+ MODULE_NAME("DV Target")
+ MODULE_DESCRIPTION("Provides a DV Stream target (ie: for miniDV stuff)")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(mod_dv)
+ BEGIN_TARGETS
+ TARGET(dv_trgt)
+ END_TARGETS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_dv" Sec_mod_dv
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_dv.dll "src\modules\mod_dv\.libs\libmod_dv-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_dv"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_dv.cpp
+** \brief ppm Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_TARGET
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ETL/stringf>
+#include "trgt_dv.h"
+#include <stdio.h>
+#include <algorithm>
+#include <functional>
+#include <ETL/clock>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_TARGET_INIT(dv_trgt);
+SYNFIG_TARGET_SET_NAME(dv_trgt,"dv");
+SYNFIG_TARGET_SET_EXT(dv_trgt,"dv");
+SYNFIG_TARGET_SET_VERSION(dv_trgt,"0.1");
+SYNFIG_TARGET_SET_CVS_ID(dv_trgt,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+
+dv_trgt::dv_trgt(const char *Filename)
+{
+ file=NULL;
+ filename=Filename;
+ buffer=NULL;
+ wide_aspect=false;
+ color_buffer=0;
+ set_remove_alpha();
+
+}
+
+dv_trgt::~dv_trgt()
+{
+ if(file)
+ pclose(file);
+ file=NULL;
+ delete [] buffer;
+ delete [] color_buffer;
+}
+
+bool
+dv_trgt::set_rend_desc(RendDesc *given_desc)
+{
+ // Set the aspect ratio
+ if(wide_aspect)
+ {
+ // 16:9 Aspect
+ given_desc->set_wh(160,90);
+
+ // Widescreen should be progressive scan
+ given_desc->set_interlaced(false);
+ }
+ else
+ {
+ // 4:3 Aspect
+ given_desc->set_wh(400,300);
+
+ // We should be interlaced
+ given_desc->set_interlaced(true);
+ }
+
+ // but the pixel res should be 720x480
+ given_desc->clear_flags(),given_desc->set_wh(720,480);
+
+ // NTSC Frame rate is 29.97
+ given_desc->set_frame_rate(29.97);
+
+ // The pipe to encodedv is PPM, which needs RGB data
+ //given_desc->set_pixel_format(PF_RGB);
+
+ // Set the description
+ desc=*given_desc;
+
+ return true;
+}
+
+bool
+dv_trgt::init()
+{
+ imagecount=desc.get_frame_start();
+
+ string command;
+
+ if(wide_aspect)
+ command=strprintf("encodedv -w 1 - > \"%s\"\n",filename.c_str());
+ else
+ command=strprintf("encodedv - > \"%s\"\n",filename.c_str());
+
+ // Open the pipe to encodedv
+ file=popen(command.c_str(),"w");
+
+ if(!file)
+ {
+ synfig::error(_("Unable to open pipe to encodedv"));
+ return false;
+ }
+
+ // Sleep for a moment to let the pipe catch up
+ etl::clock().sleep(0.25f);
+
+ return true;
+}
+
+void
+dv_trgt::end_frame()
+{
+ fprintf(file, " ");
+ fflush(file);
+ imagecount++;
+}
+
+bool
+dv_trgt::start_frame(synfig::ProgressCallback */*callback*/)
+{
+ int w=desc.get_w(),h=desc.get_h();
+
+ if(!file)
+ return false;
+
+ fprintf(file, "P6\n");
+ fprintf(file, "%d %d\n", w, h);
+ fprintf(file, "%d\n", 255);
+
+ delete [] buffer;
+ buffer=new unsigned char[3*w];
+
+ delete [] color_buffer;
+ color_buffer=new Color[w];
+
+ return true;
+}
+
+Color *
+dv_trgt::start_scanline(int /*scanline*/)
+{
+ return color_buffer;
+}
+
+bool
+dv_trgt::end_scanline()
+{
+ if(!file)
+ return false;
+
+ convert_color_format(buffer, color_buffer, desc.get_w(), PF_RGB, gamma());
+
+ if(!fwrite(buffer,1,desc.get_w()*3,file))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_dv.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRGT_DV_H
+#define __SYNFIG_TRGT_DV_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/target_scanline.h>
+#include <synfig/string.h>
+#include <cstdio>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+
+class dv_trgt : public synfig::Target_Scanline
+{
+ SYNFIG_TARGET_MODULE_EXT
+private:
+ int imagecount;
+ bool wide_aspect;
+ FILE *file;
+ synfig::String filename;
+ unsigned char *buffer;
+ synfig::Color *color_buffer;
+public:
+ dv_trgt(const char *filename);
+ virtual ~dv_trgt();
+
+
+ virtual bool set_rend_desc(synfig::RendDesc *desc);
+ virtual bool init();
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+ virtual void end_frame();
+
+ virtual synfig::Color * start_scanline(int scanline);
+ virtual bool end_scanline();
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_dv"
+ Delete "$INSTDIR\lib\synfig\modules\mod_dv.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+if WITH_FFMPEG
+module_LTLIBRARIES = libmod_ffmpeg.la
+libmod_ffmpeg_la_SOURCES = main.cpp mptr_ffmpeg.cpp mptr_ffmpeg.h trgt_ffmpeg.cpp trgt_ffmpeg.h
+libmod_ffmpeg_la_LDFLAGS = -module -no-undefined
+libmod_ffmpeg_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_ffmpeg_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+else
+endif
+
+
+EXTRA_DIST= mod_ffmpeg.nsh unmod_ffmpeg.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_ffmpeg/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include "mptr_ffmpeg.h"
+#include "trgt_ffmpeg.h"
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(mod_ffmpeg)
+ MODULE_NAME("FFMPEG Module")
+ MODULE_DESCRIPTION("Provides output targets for each format that FFMPEG supports")
+ MODULE_AUTHOR("Robert B. Quattlebaum Jr.")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(mod_ffmpeg)
+ BEGIN_TARGETS
+ TARGET(ffmpeg_trgt)
+ TARGET_EXT(ffmpeg_trgt,"avi")
+ TARGET_EXT(ffmpeg_trgt,"mpg")
+ TARGET_EXT(ffmpeg_trgt,"rm")
+ TARGET_EXT(ffmpeg_trgt,"asf")
+ TARGET_EXT(ffmpeg_trgt,"swf")
+ TARGET_EXT(ffmpeg_trgt,"yuv")
+ TARGET_EXT(ffmpeg_trgt,"rgb")
+ END_TARGETS
+// BEGIN_IMPORTERS
+// IMPORTER_EXT(ffmpeg_mptr,"avi")
+// IMPORTER_EXT(ffmpeg_mptr,"mpg")
+// IMPORTER_EXT(ffmpeg_mptr,"mpeg")
+// IMPORTER_EXT(ffmpeg_mptr,"mov")
+// IMPORTER_EXT(ffmpeg_mptr,"rm")
+// IMPORTER_EXT(ffmpeg_mptr,"dv")
+// END_IMPORTERS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_ffmpeg" Sec_mod_ffmpeg
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_ffmpeg.dll "src\modules\mod_ffmpeg\.libs\libmod_ffmpeg-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_ffmpeg"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_ffmpeg.cpp
+** \brief ppm Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ETL/stringf>
+#include "mptr_ffmpeg.h"
+#include <stdio.h>
+#include <iostream>
+#include <algorithm>
+#include <functional>
+#include <ETL/stringf>
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_IMPORTER_INIT(ffmpeg_mptr);
+SYNFIG_IMPORTER_SET_NAME(ffmpeg_mptr,"ffmpeg");
+SYNFIG_IMPORTER_SET_EXT(ffmpeg_mptr,"avi");
+SYNFIG_IMPORTER_SET_VERSION(ffmpeg_mptr,"0.1");
+SYNFIG_IMPORTER_SET_CVS_ID(ffmpeg_mptr,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+bool
+ffmpeg_mptr::seek_to(int frame)
+{
+ if(frame<cur_frame || !file)
+ {
+ if(file)
+ {
+ pclose(file);
+ }
+
+ string command;
+
+ command=strprintf("ffmpeg -i \"%s\" -an -f image2pipe -vcodec ppm -\n",filename.c_str());
+
+ file=popen(command.c_str(),"r");
+
+ if(!file)
+ {
+ cerr<<"Unable to open pipe to ffmpeg"<<endl;
+ return false;
+ }
+ cur_frame=-1;
+ }
+
+ while(cur_frame<frame-1)
+ {
+ cerr<<"Seeking to..."<<frame<<'('<<cur_frame<<')'<<endl;
+ if(!grab_frame())
+ return false;
+ }
+ return true;
+}
+
+bool
+ffmpeg_mptr::grab_frame(void)
+{
+ if(!file)
+ {
+ cerr<<"unable to open "<<filename<<endl;
+ return false;
+ }
+ int w,h;
+ float divisor;
+ char cookie[2];
+ cookie[0]=fgetc(file);
+ cookie[1]=fgetc(file);
+
+ if(cookie[0]!='P' || cookie[1]!='6')
+ {
+ cerr<<"stream not in PPM format \""<<cookie[0]<<cookie[1]<<'"'<<endl;
+ return false;
+ }
+
+ fgetc(file);
+ fscanf(file,"%d %d\n",&w,&h);
+ fscanf(file,"%f",&divisor);
+ fgetc(file);
+
+ if(feof(file))
+ return false;
+
+ int x;
+ int y;
+ frame.set_wh(w,h);
+ for(y=0;y<frame.get_h();y++)
+ for(x=0;x<frame.get_w();x++)
+ {
+ if(feof(file))
+ return false;
+/*
+ frame[y][x]=Color(
+ (float)(unsigned char)fgetc(file)/divisor,
+ (float)(unsigned char)fgetc(file)/divisor,
+ (float)(unsigned char)fgetc(file)/divisor,
+ 1.0
+*/
+ float r=gamma().r_U8_to_F32((unsigned char)fgetc(file));
+ float g=gamma().g_U8_to_F32((unsigned char)fgetc(file));
+ float b=gamma().b_U8_to_F32((unsigned char)fgetc(file));
+ frame[y][x]=Color(
+ r,
+ g,
+ b,
+ 1.0
+ );
+ }
+ cur_frame++;
+ return true;
+}
+
+ffmpeg_mptr::ffmpeg_mptr(const char *f)
+{
+#ifdef HAVE_TERMIOS_H
+ tcgetattr (0, &oldtty);
+#endif
+ filename=f;
+ file=NULL;
+ fps=23.98;
+ cur_frame=-1;
+}
+
+ffmpeg_mptr::~ffmpeg_mptr()
+{
+ if(file)
+ pclose(file);
+#ifdef HAVE_TERMIOS_H
+ tcsetattr(0,TCSANOW,&oldtty);
+#endif
+}
+
+bool
+ffmpeg_mptr::get_frame(synfig::Surface &surface,Time time, synfig::ProgressCallback *)
+{
+ int i=(int)(time*fps);
+ if(i!=cur_frame)
+ {
+ if(!seek_to(i))
+ return false;
+ if(!grab_frame());
+ return false;
+ }
+
+ surface=frame;
+ return false;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_ffmpeg.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_MPTR_FFMPEG_H
+#define __SYNFIG_MPTR_FFMPEG_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/importer.h>
+#include <stdio.h>
+#include "string.h"
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+
+#endif
+
+#include <synfig/surface.h>
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class ffmpeg_mptr : public synfig::Importer
+{
+ SYNFIG_IMPORTER_MODULE_EXT
+public:
+private:
+ synfig::String filename;
+ FILE *file;
+ int cur_frame;
+ synfig::Surface frame;
+ float fps;
+#ifdef HAVE_TERMIOS_H
+ struct termios oldtty;
+#endif
+
+ bool seek_to(int frame);
+ bool grab_frame(void);
+
+public:
+ ffmpeg_mptr(const char *filename);
+ ~ffmpeg_mptr();
+
+
+ virtual bool get_frame(synfig::Surface &surface,synfig::Time time, synfig::ProgressCallback *callback);
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_ffmpeg.cpp
+** \brief ppm Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_TARGET
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ETL/stringf>
+#include "trgt_ffmpeg.h"
+#include <stdio.h>
+#include <algorithm>
+#include <functional>
+#include <ETL/clock>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_TARGET_INIT(ffmpeg_trgt);
+SYNFIG_TARGET_SET_NAME(ffmpeg_trgt,"ffmpeg");
+SYNFIG_TARGET_SET_EXT(ffmpeg_trgt,"mpg");
+SYNFIG_TARGET_SET_VERSION(ffmpeg_trgt,"0.1");
+SYNFIG_TARGET_SET_CVS_ID(ffmpeg_trgt,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+ffmpeg_trgt::ffmpeg_trgt(const char *Filename)
+{
+ file=NULL;
+ filename=Filename;
+ multi_image=false;
+ buffer=NULL;
+ color_buffer=0;
+ set_remove_alpha();
+}
+
+ffmpeg_trgt::~ffmpeg_trgt()
+{
+ if(file)
+ {
+ etl::yield();
+ sleep(1);
+ pclose(file);
+ }
+ file=NULL;
+ delete [] buffer;
+ delete [] color_buffer;
+}
+
+bool
+ffmpeg_trgt::set_rend_desc(RendDesc *given_desc)
+{
+ //given_desc->set_pixel_format(PF_RGB);
+
+ // Make sure that the width and height
+ // are multiples of 8
+ given_desc->set_w((given_desc->get_w()+4)/8*8);
+ given_desc->set_h((given_desc->get_h()+4)/8*8);
+
+ /*
+ // Valid framerates:
+ // 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60
+ float fps=given_desc->get_frame_rate();
+ if(fps <24.0)
+ given_desc->set_frame_rate(23.976);
+ if(fps>=24.0 && fps <25.0)
+ given_desc->set_frame_rate(24);
+ if(fps>=25.0 && fps <29.97)
+ given_desc->set_frame_rate(25);
+ if(fps>=29.97 && fps <30.0)
+ given_desc->set_frame_rate(29.97);
+ if(fps>=29.97 && fps <30.0)
+ given_desc->set_frame_rate(29.97);
+ if(fps>=30.0 && fps <50.0)
+ given_desc->set_frame_rate(30.0);
+ if(fps>=50.0 && fps <59.94)
+ given_desc->set_frame_rate(50);
+ if(fps>=59.94)
+ given_desc->set_frame_rate(59.94);
+ */
+
+ desc=*given_desc;
+
+ return true;
+}
+
+bool
+ffmpeg_trgt::init()
+{
+ imagecount=desc.get_frame_start();
+ if(desc.get_frame_end()-desc.get_frame_start()>0)
+ multi_image=true;
+ string command;
+
+ command=strprintf("ffmpeg -f image2pipe -vcodec ppm -an -r %f -i pipe: -loop -hq -title \"%s\" -vcodec mpeg1video -y \"%s\"\n",desc.get_frame_rate(),get_canvas()->get_name().c_str(),filename.c_str());
+
+ file=popen(command.c_str(),"w");
+
+ // etl::yield();
+
+ if(!file)
+ {
+ synfig::error(_("Unable to open pipe to ffmpeg"));
+ return false;
+ }
+
+ return true;
+}
+
+void
+ffmpeg_trgt::end_frame()
+{
+ //fprintf(file, " ");
+ fflush(file);
+ imagecount++;
+}
+
+bool
+ffmpeg_trgt::start_frame(synfig::ProgressCallback */*callback*/)
+{
+ int w=desc.get_w(),h=desc.get_h();
+
+ if(!file)
+ return false;
+
+ fprintf(file, "P6\n");
+ fprintf(file, "%d %d\n", w, h);
+ fprintf(file, "%d\n", 255);
+
+ delete [] buffer;
+ buffer=new unsigned char[3*w];
+ delete [] color_buffer;
+ color_buffer=new Color[w];
+
+ return true;
+}
+
+Color *
+ffmpeg_trgt::start_scanline(int /*scanline*/)
+{
+ return color_buffer;
+}
+
+bool
+ffmpeg_trgt::end_scanline()
+{
+ if(!file)
+ return false;
+
+ convert_color_format(buffer, color_buffer, desc.get_w(), PF_RGB, gamma());
+
+ if(!fwrite(buffer,1,desc.get_w()*3,file))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_ffmpeg.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRGT_FFMPEG_H
+#define __SYNFIG_TRGT_FFMPEG_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/target_scanline.h>
+#include <synfig/string.h>
+#include <cstdio>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class ffmpeg_trgt : public synfig::Target_Scanline
+{
+ SYNFIG_TARGET_MODULE_EXT
+private:
+ int imagecount;
+ bool multi_image;
+ FILE *file;
+ synfig::String filename;
+ unsigned char *buffer;
+ synfig::Color *color_buffer;
+public:
+ ffmpeg_trgt(const char *filename);
+
+ virtual bool set_rend_desc(synfig::RendDesc *desc);
+ virtual bool init();
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+ virtual void end_frame();
+
+ virtual ~ffmpeg_trgt();
+
+ virtual synfig::Color * start_scanline(int scanline);
+ virtual bool end_scanline();
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_ffmpeg"
+ Delete "$INSTDIR\lib\synfig\modules\mod_ffmpeg.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+module_LTLIBRARIES = libmod_filter.la
+libmod_filter_la_SOURCES = blur.cpp blur.h colorcorrect.cpp colorcorrect.h halftone2.cpp halftone2.h lumakey.cpp lumakey.h radialblur.cpp radialblur.h main.cpp halftone.cpp halftone.h halftone3.cpp halftone3.h
+libmod_filter_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_filter_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+libmod_filter_la_LDFLAGS = -module -no-undefined
+EXTRA_DIST= mod_filter.nsh unmod_filter.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_filter/blur.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "blur.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/segment.h>
+
+#include <cstring>
+#include <ETL/pen>
+
+#endif
+
+using namespace synfig;
+using namespace etl;
+using namespace std;
+
+/*#define TYPE_BOX 0
+#define TYPE_FASTGUASSIAN 1
+#define TYPE_FASTGAUSSIAN 1
+#define TYPE_CROSS 2
+#define TYPE_GUASSIAN 3
+#define TYPE_GAUSSIAN 3
+#define TYPE_DISC 4
+*/
+
+/* -- G L O B A L S --------------------------------------------------------- */
+
+SYNFIG_LAYER_INIT(Blur_Layer);
+SYNFIG_LAYER_SET_NAME(Blur_Layer,"blur");
+SYNFIG_LAYER_SET_LOCAL_NAME(Blur_Layer,_("Blur"));
+SYNFIG_LAYER_SET_CATEGORY(Blur_Layer,_("Blurs"));
+SYNFIG_LAYER_SET_VERSION(Blur_Layer,"0.2");
+SYNFIG_LAYER_SET_CVS_ID(Blur_Layer,"$Id$");
+
+/* -- F U N C T I O N S ----------------------------------------------------- */
+
+inline void clamp(synfig::Vector &v)
+{
+ if(v[0]<0.0)v[0]=0.0;
+ if(v[1]<0.0)v[1]=0.0;
+}
+
+Blur_Layer::Blur_Layer():
+ Layer_Composite (1.0,Color::BLEND_STRAIGHT),
+ size(0.1,0.1),
+ type(Blur::FASTGAUSSIAN)
+{
+}
+
+bool
+Blur_Layer::set_param(const String ¶m, const ValueBase &value)
+{
+ IMPORT_PLUS(size,clamp(size));
+ IMPORT(type);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+Blur_Layer::get_param(const String ¶m)const
+{
+ EXPORT(size);
+ EXPORT(type);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Color
+Blur_Layer::get_color(Context context, const Point &pos)const
+{
+ Point blurpos = Blur(size,type)(pos);
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return context.get_color(blurpos);
+
+ if(get_amount()==0.0)
+ return context.get_color(pos);
+
+ return Color::blend(context.get_color(blurpos),context.get_color(pos),get_amount(),get_blend_method());
+}
+
+bool
+Blur_Layer::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ // int x,y;
+ SuperCallback stageone(cb,0,5000,10000);
+ SuperCallback stagetwo(cb,5000,10000,10000);
+
+ const int w = renddesc.get_w(),
+ h = renddesc.get_h();
+ const Real pw = renddesc.get_pw(),
+ ph = renddesc.get_ph();
+
+ RendDesc workdesc(renddesc);
+ Surface worksurface,blurred;
+
+ //callbacks depend on how long the blur takes
+ if(size[0] || size[1])
+ {
+ if(type == Blur::DISC)
+ {
+ stageone = SuperCallback(cb,0,5000,10000);
+ stagetwo = SuperCallback(cb,5000,10000,10000);
+ }
+ else
+ {
+ stageone = SuperCallback(cb,0,9000,10000);
+ stagetwo = SuperCallback(cb,9000,10000,10000);
+ }
+ }
+ else
+ {
+ stageone = SuperCallback(cb,0,9999,10000);
+ stagetwo = SuperCallback(cb,9999,10000,10000);
+ }
+
+ //expand the working surface to accommodate the blur
+
+ //the expanded size = 1/2 the size in each direction rounded up
+ int halfsizex = (int) (abs(size[0]*.5/pw) + 3),
+ halfsizey = (int) (abs(size[1]*.5/ph) + 3);
+
+ //expand by 1/2 size in each direction on either side
+ switch(type)
+ {
+ case Blur::DISC:
+ case Blur::BOX:
+ case Blur::CROSS:
+ {
+ workdesc.set_subwindow(-max(1,halfsizex),-max(1,halfsizey),w+2*max(1,halfsizex),h+2*max(1,halfsizey));
+ break;
+ }
+ case Blur::FASTGAUSSIAN:
+ {
+ if(quality < 4)
+ {
+ halfsizex*=2;
+ halfsizey*=2;
+ }
+ workdesc.set_subwindow(-max(1,halfsizex),-max(1,halfsizey),w+2*max(1,halfsizex),h+2*max(1,halfsizey));
+ break;
+ }
+ case Blur::GAUSSIAN:
+ {
+ #define GAUSSIAN_ADJUSTMENT (0.05)
+ Real pw = (Real)workdesc.get_w()/(workdesc.get_br()[0]-workdesc.get_tl()[0]);
+ Real ph = (Real)workdesc.get_h()/(workdesc.get_br()[1]-workdesc.get_tl()[1]);
+
+ pw=pw*pw;
+ ph=ph*ph;
+
+ halfsizex = (int)(abs(pw)*size[0]*GAUSSIAN_ADJUSTMENT+0.5);
+ halfsizey = (int)(abs(ph)*size[1]*GAUSSIAN_ADJUSTMENT+0.5);
+
+ halfsizex = (halfsizex + 1)/2;
+ halfsizey = (halfsizey + 1)/2;
+ workdesc.set_subwindow( -halfsizex, -halfsizey, w+2*halfsizex, h+2*halfsizey );
+
+ break;
+ }
+ }
+
+ //render the background onto the expanded surface
+ if(!context.accelerated_render(&worksurface,quality,workdesc,&stageone))
+ return false;
+
+ //blur the image
+ Blur(size,type,&stagetwo)(worksurface,workdesc.get_br()-workdesc.get_tl(),blurred);
+
+ //be sure the surface is of the correct size
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+
+ {
+ Surface::pen pen(surface->begin());
+ worksurface.blit_to(pen,halfsizex,halfsizey,renddesc.get_w(),renddesc.get_h());
+ }
+ {
+ Surface::alpha_pen pen(surface->begin());
+ pen.set_alpha(get_amount());
+ pen.set_blend_method(get_blend_method());
+ blurred.blit_to(pen,halfsizex,halfsizey,renddesc.get_w(),renddesc.get_h());
+ }
+ if(cb && !cb->amount_complete(10000,10000))
+ {
+ //if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ return true;
+}
+
+Layer::Vocab
+Blur_Layer::get_param_vocab(void)const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("size")
+ .set_local_name(_("Size"))
+ .set_description(_("Size of Blur"))
+ );
+ ret.push_back(ParamDesc("type")
+ .set_local_name(_("Type"))
+ .set_description(_("Type of blur to use"))
+ .set_hint("enum")
+ .add_enum_value(Blur::BOX,"box",_("Box Blur"))
+ .add_enum_value(Blur::FASTGAUSSIAN,"fastgaussian",_("Fast Gaussian Blur"))
+ .add_enum_value(Blur::CROSS,"cross",_("Cross-Hatch Blur"))
+ .add_enum_value(Blur::GAUSSIAN,"gaussian",_("Gaussian Blur"))
+ .add_enum_value(Blur::DISC,"disc",_("Disc Blur"))
+ );
+
+ return ret;
+}
+
+Rect
+Blur_Layer::get_full_bounding_rect(Context context)const
+{
+ if(is_disabled() || Color::is_onto(get_blend_method()))
+ return context.get_full_bounding_rect();
+
+ Rect bounds(context.get_full_bounding_rect().expand_x(size[0]).expand_y(size[1]));
+
+ return bounds;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_filter/blur.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifndef __SYNFIG_LAYER_BLUR_H__
+#define __SYNFIG_LAYER_BLUR_H__
+
+/* -- H E A D E R S --------------------------------------------------------- */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+#include <synfig/blur.h>
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class Blur_Layer : public synfig::Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+private:
+ synfig::Point size;
+ int type;
+
+public:
+ Blur_Layer();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+ virtual synfig::Rect get_full_bounding_rect(Context context)const;
+
+ virtual Vocab get_param_vocab()const;
+}; // END of class Blur
+
+/* -- E X T E R N S --------------------------------------------------------- */
+
+/* -- E N D ----------------------------------------------------------------- */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file colorcorrect.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "colorcorrect.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Layer_ColorCorrect);
+SYNFIG_LAYER_SET_NAME(Layer_ColorCorrect,"colorcorrect");
+SYNFIG_LAYER_SET_LOCAL_NAME(Layer_ColorCorrect,_("Color Correct"));
+SYNFIG_LAYER_SET_CATEGORY(Layer_ColorCorrect,_("Filters"));
+SYNFIG_LAYER_SET_VERSION(Layer_ColorCorrect,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Layer_ColorCorrect,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Layer_ColorCorrect::Layer_ColorCorrect():
+ hue_adjust(Angle::zero()),
+ brightness(0),
+ contrast(1.0),
+ exposure(0.0)
+{
+}
+
+inline Color
+Layer_ColorCorrect::correct_color(const Color &in)const
+{
+ Color ret(in);
+ Real brightness((this->brightness-0.5)*this->contrast+0.5);
+
+ if(gamma.get_gamma_r()!=1.0)
+ {
+ if(ret.get_r() < 0)
+ {
+ ret.set_r(-gamma.r_F32_to_F32(-ret.get_r()));
+ }else
+ {
+ ret.set_r(gamma.r_F32_to_F32(ret.get_r()));
+ }
+ }
+ if(gamma.get_gamma_g()!=1.0)
+ {
+ if(ret.get_g() < 0)
+ {
+ ret.set_g(-gamma.g_F32_to_F32(-ret.get_g()));
+ }else
+ {
+ ret.set_g(gamma.g_F32_to_F32(ret.get_g()));
+ }
+ }
+ if(gamma.get_gamma_b()!=1.0)
+ {
+ if(ret.get_b() < 0)
+ {
+ ret.set_b(-gamma.b_F32_to_F32(-ret.get_b()));
+ }else
+ {
+ ret.set_b(gamma.b_F32_to_F32(ret.get_b()));
+ }
+ }
+
+ assert(!isnan(ret.get_r()));
+ assert(!isnan(ret.get_g()));
+ assert(!isnan(ret.get_b()));
+
+ if(exposure!=0.0)
+ {
+ const float factor(exp(exposure));
+ ret.set_r(ret.get_r()*factor);
+ ret.set_g(ret.get_g()*factor);
+ ret.set_b(ret.get_b()*factor);
+ }
+
+ // Adjust Contrast
+ if(contrast!=1.0)
+ {
+ ret.set_r(ret.get_r()*contrast);
+ ret.set_g(ret.get_g()*contrast);
+ ret.set_b(ret.get_b()*contrast);
+ }
+
+ if(brightness)
+ {
+ // Adjust R Channel Brightness
+ if(ret.get_r()>-brightness)
+ ret.set_r(ret.get_r()+brightness);
+ else if(ret.get_r()<brightness)
+ ret.set_r(ret.get_r()-brightness);
+ else
+ ret.set_r(0);
+
+ // Adjust G Channel Brightness
+ if(ret.get_g()>-brightness)
+ ret.set_g(ret.get_g()+brightness);
+ else if(ret.get_g()<brightness)
+ ret.set_g(ret.get_g()-brightness);
+ else
+ ret.set_g(0);
+
+ // Adjust B Channel Brightness
+ if(ret.get_b()>-brightness)
+ ret.set_b(ret.get_b()+brightness);
+ else if(ret.get_b()<brightness)
+ ret.set_b(ret.get_b()-brightness);
+ else
+ ret.set_b(0);
+ }
+
+ // Return the color, adjusting the hue if necessary
+ if(!!hue_adjust)
+ return ret.rotate_uv(hue_adjust);
+ else
+ return ret;
+}
+
+bool
+Layer_ColorCorrect::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(hue_adjust);
+ IMPORT(brightness);
+ IMPORT(contrast);
+ IMPORT(exposure);
+
+ if(param=="gamma" && value.get_type()==ValueBase::TYPE_REAL)
+ {
+ gamma.set_gamma(1.0/value.get(Real()));
+ return true;
+ }
+ return false;
+}
+
+ValueBase
+Layer_ColorCorrect::get_param(const String ¶m)const
+{
+ EXPORT(hue_adjust);
+ EXPORT(brightness);
+ EXPORT(contrast);
+ EXPORT(exposure);
+
+ if(param=="gamma")
+ return 1.0/gamma.get_gamma();
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return ValueBase();
+}
+
+Layer::Vocab
+Layer_ColorCorrect::get_param_vocab()const
+{
+ Layer::Vocab ret;
+
+ ret.push_back(ParamDesc("hue_adjust")
+ .set_local_name(_("Hue Adjust"))
+ );
+
+ ret.push_back(ParamDesc("brightness")
+ .set_local_name(_("Brightness"))
+ );
+
+ ret.push_back(ParamDesc("contrast")
+ .set_local_name(_("Contrast"))
+ );
+
+ ret.push_back(ParamDesc("exposure")
+ .set_local_name(_("Exposure Adjust"))
+ );
+
+ ret.push_back(ParamDesc("gamma")
+ .set_local_name(_("Gamma Adjustment"))
+ );
+
+ return ret;
+}
+
+Color
+Layer_ColorCorrect::get_color(Context context, const Point &pos)const
+{
+ return correct_color(context.get_color(pos));
+}
+
+bool
+Layer_ColorCorrect::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+
+ int x,y;
+
+ Surface::pen pen(surface->begin());
+
+ for(y=0;y<renddesc.get_h();y++,pen.inc_y(),pen.dec_x(x))
+ for(x=0;x<renddesc.get_w();x++,pen.inc_x())
+ pen.put_value(correct_color(pen.get_value()));
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
+
+Rect
+Layer_ColorCorrect::get_full_bounding_rect(Context context)const
+{
+ return context.get_full_bounding_rect();
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file colorcorrect.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LAYER_COLORCORRECT_H
+#define __SYNFIG_LAYER_COLORCORRECT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer.h>
+#include <synfig/angle.h>
+#include <synfig/gamma.h>
+#include <synfig/rect.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Layer_ColorCorrect : public Layer
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ Angle hue_adjust;
+ Real brightness;
+ Real contrast;
+ Real exposure;
+
+ Gamma gamma;
+
+ Color correct_color(const Color &in)const;
+
+public:
+
+ Layer_ColorCorrect();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+
+ virtual Rect get_full_bounding_rect(Context context)const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+
+ virtual Vocab get_param_vocab()const;
+}; // END of class Layer_ColorCorrect
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file halftone.cpp
+** \brief blehh
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "halftone.h"
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+
+/* === P R O C E D U R E S ================================================= */
+
+#define SQRT2 (1.414213562f)
+
+/* === M E T H O D S ======================================================= */
+
+float
+Halftone::operator()(const Point &point, const float& luma, float supersample)const
+{
+ float halftone(mask(point));
+
+ if(supersample>=0.5f)
+ supersample=0.4999999999f;
+
+ halftone=(halftone-0.5f)*(1.0f-supersample*2.0f)+0.5f;
+
+ const float diff(halftone-luma);
+
+ if(supersample)
+ {
+ const float amount(diff/(supersample*2.0f)+0.5f);
+
+ if(amount<=0.0f+0.01f)
+ return 1.0f;
+ else if(amount>=1.0f-0.01f)
+ return 0.0f;
+ else
+ return 1.0f-amount;
+ }
+ else
+ {
+ if(diff>=0)
+ return 0.0f;
+ else
+ return 1.0f;
+ }
+
+ return 0.0f;
+}
+
+float
+Halftone::mask(synfig::Point point)const
+{
+ float radius1;
+ float radius2;
+
+ point-=offset;
+
+ {
+ const float a(Angle::sin(-angle).get()), b(Angle::cos(-angle).get());
+ const float u(point[0]),v(point[1]);
+
+ point[0]=b*u-a*v;
+ point[1]=a*u+b*v;
+ }
+
+ if(type==TYPE_STRIPE)
+ {
+ Point pnt(fmod(point[0],size[0]),fmod(point[1],size[1]));
+ while(pnt[0]<0)pnt[0]+=abs(size[0]);
+ while(pnt[1]<0)pnt[1]+=abs(size[1]);
+
+ float x(pnt[1]/size[1]);
+ if(x>0.5)x=1.0-x;
+ x*=2;
+ return x;
+ }
+
+ {
+ Point pnt(fmod(point[0],size[0]),fmod(point[1],size[1]));
+ while(pnt[0]<0)pnt[0]+=abs(size[0]);
+ while(pnt[1]<0)pnt[1]+=abs(size[1]);
+ pnt-=Vector(size[0]*0.5,size[1]*0.5);
+ pnt*=2.0;
+ pnt[0]/=size[0];
+ pnt[1]/=size[1];
+
+ radius1=pnt.mag()/SQRT2;
+ radius1*=radius1;
+ }
+ if(type==TYPE_DARKONLIGHT || type== TYPE_LIGHTONDARK)
+ return radius1;
+
+ {
+ Point pnt(fmod(point[0]+size[0]*0.5,size[0]),fmod(point[1]+size[0]*0.5,size[1]));
+ while(pnt[0]<0)pnt[0]+=abs(size[0]);
+ while(pnt[1]<0)pnt[1]+=abs(size[1]);
+ pnt-=Vector(size[0]*0.5,size[1]*0.5);
+ pnt*=2.0;
+ pnt[0]/=size[0];
+ pnt[1]/=size[1];
+
+ radius2=pnt.mag()/SQRT2;
+ radius2*=radius2;
+ }
+
+ if(type==TYPE_DIAMOND)
+ {
+ //return (radius1+(1.0f-radius2))*0.5;
+ float x((radius1+(1.0f-radius2))*0.5);
+ //float x(((radius2-radius1)*((radius1+(1.0f-radius2))*0.5)+radius1)*2.0f);
+ x-=0.5;
+ x*=2.0;
+ if(x<0)x=-sqrt(-x);else x=sqrt(x);
+ x*=1.01f;
+ x/=2.0;
+ x+=0.5;
+ return x;
+ }
+
+ if(type==TYPE_SYMMETRIC)
+ {
+ float x(((radius2-radius1)*((radius1+(1.0f-radius2))*0.5)+radius1)*2.0f);
+ x-=0.5;
+ x*=2.0;
+ if(x<0)x=-sqrt(-x);else x=sqrt(x);
+ x*=1.01f;
+ x/=2.0;
+ x+=0.5;
+ return x;
+ }
+ return 0;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file halftone.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_HALFTONE_H
+#define __SYNFIG_HALFTONE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/vector.h>
+#include <synfig/angle.h>
+
+/* === M A C R O S ========================================================= */
+
+#define TYPE_SYMMETRIC 0
+#define TYPE_DARKONLIGHT 1
+#define TYPE_LIGHTONDARK 2
+#define TYPE_DIAMOND 3
+#define TYPE_STRIPE 4
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class Halftone
+{
+public:
+
+ int type;
+ synfig::Point offset;
+ synfig::Vector size;
+ synfig::Angle angle;
+
+ float mask(synfig::Point point)const;
+
+ float operator()(const synfig::Point &point, const float& intensity, float supersample=0)const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file halftone2.cpp
+** \brief blehh
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "halftone2.h"
+#include "halftone.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Halftone2);
+SYNFIG_LAYER_SET_NAME(Halftone2,"halftone2");
+SYNFIG_LAYER_SET_LOCAL_NAME(Halftone2,_("Halftone 2"));
+SYNFIG_LAYER_SET_CATEGORY(Halftone2,_("Filters"));
+SYNFIG_LAYER_SET_VERSION(Halftone2,"0.0");
+SYNFIG_LAYER_SET_CVS_ID(Halftone2,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Halftone2::Halftone2():
+ color_dark(Color::black()),
+ color_light(Color::white())
+{
+ halftone.offset=(synfig::Point(0,0));
+ halftone.size=(synfig::Vector(0.25,0.25));
+ halftone.angle=(Angle::zero());
+ halftone.type=TYPE_SYMMETRIC;
+
+ set_blend_method(Color::BLEND_STRAIGHT);
+}
+
+inline Color
+Halftone2::color_func(const Point &point, float supersample,const Color& color)const
+{
+ const float amount(halftone(point,color.get_y(),supersample));
+ Color halfcolor;
+
+ if(amount<=0.0f)
+ halfcolor=color_dark;
+ else if(amount>=1.0f)
+ halfcolor=color_light;
+ else
+ halfcolor=Color::blend(color_light,color_dark,amount,Color::BLEND_STRAIGHT);
+
+ halfcolor.set_a(color.get_a());
+
+ return halfcolor;
+}
+
+inline float
+Halftone2::calc_supersample(const synfig::Point &/*x*/, float pw,float /*ph*/)const
+{
+ return abs(pw/(halftone.size).mag());
+}
+
+synfig::Layer::Handle
+Halftone2::hit_check(synfig::Context /*context*/, const synfig::Point &/*point*/)const
+{
+ return const_cast<Halftone2*>(this);
+}
+
+bool
+Halftone2::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(color_dark);
+ IMPORT(color_light);
+
+ IMPORT_AS(halftone.size,"size");
+ IMPORT_AS(halftone.type,"type");
+ IMPORT_AS(halftone.angle,"angle");
+ IMPORT_AS(halftone.offset,"offset");
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+Halftone2::get_param(const String & param)const
+{
+ EXPORT_AS(halftone.size,"size");
+ EXPORT_AS(halftone.type,"type");
+ EXPORT_AS(halftone.angle,"angle");
+ EXPORT_AS(halftone.offset,"offset");
+
+ EXPORT(color_dark);
+ EXPORT(color_light);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+Halftone2::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("offset")
+ .set_local_name(_("Mask Offset"))
+ .set_is_distance()
+ );
+ ret.push_back(ParamDesc("angle")
+ .set_local_name(_("Mask Angle"))
+ .set_origin("offset")
+ );
+ ret.push_back(ParamDesc("size")
+ .set_local_name(_("Mask Size"))
+ .set_is_distance()
+ .set_origin("offset")
+ );
+ ret.push_back(ParamDesc("color_light")
+ .set_local_name(_("Light Color"))
+ );
+ ret.push_back(ParamDesc("color_dark")
+ .set_local_name(_("Dark Color"))
+ );
+ ret.push_back(ParamDesc("type")
+ .set_local_name(_("Type"))
+ .set_hint("enum")
+ .add_enum_value(TYPE_SYMMETRIC,"symmetric",_("Symmetric"))
+ .add_enum_value(TYPE_LIGHTONDARK,"lightondark",_("Light On Dark"))
+ //.add_enum_value(TYPE_DARKONLIGHT,"darkonlight",_("Dark on Light"))
+ .add_enum_value(TYPE_DIAMOND,"diamond",_("Diamond"))
+ .add_enum_value(TYPE_STRIPE,"stripe",_("Stripe"))
+ );
+
+ return ret;
+}
+
+Color
+Halftone2::get_color(Context context, const Point &point)const
+{
+ const Color undercolor(context.get_color(point));
+ const Color color(color_func(point,0,undercolor));
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,undercolor,get_amount(),get_blend_method());
+}
+
+bool
+Halftone2::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+ if(get_amount()==0)
+ return true;
+
+ const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
+ const Point tl(renddesc.get_tl());
+ const int w(surface->get_w());
+ const int h(surface->get_h());
+ const float supersample_size(abs(pw/(halftone.size).mag()));
+
+ Surface::pen pen(surface->begin());
+ Point pos;
+ int x,y;
+
+ if(is_solid_color())
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(
+ color_func(
+ pos,
+ supersample_size,
+ pen.get_value()
+ )
+ );
+ }
+ else
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(
+ Color::blend(
+ color_func(
+ pos,
+ supersample_size,
+ pen.get_value()
+ ),
+ pen.get_value(),
+ get_amount(),
+ get_blend_method()
+ )
+ );
+ }
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file halftone2.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_HALFTONE2_H
+#define __SYNFIG_HALFTONE2_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/vector.h>
+#include <synfig/valuenode.h>
+#include <synfig/layer_composite.h>
+#include <synfig/time.h>
+#include <synfig/angle.h>
+#include "halftone.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class Halftone2 : public synfig::Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ Halftone halftone;
+ synfig::Color color_dark;
+ synfig::Color color_light;
+
+ synfig::Color color_func(const synfig::Point &x, float supersample,const synfig::Color &under_color)const;
+
+ float calc_supersample(const synfig::Point &x, float pw,float ph)const;
+
+ //float halftone_func(synfig::Point x)const;
+
+public:
+ Halftone2();
+
+ virtual bool set_param(const synfig::String ¶m, const synfig::ValueBase &value);
+ virtual synfig::ValueBase get_param(const synfig::String ¶m)const;
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+ virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual Vocab get_param_vocab()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file halftone3.cpp
+** \brief blehh
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "halftone3.h"
+#include "halftone.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Halftone3);
+SYNFIG_LAYER_SET_NAME(Halftone3,"halftone3");
+SYNFIG_LAYER_SET_LOCAL_NAME(Halftone3,_("Halftone 3"));
+SYNFIG_LAYER_SET_CATEGORY(Halftone3,_("Filters"));
+SYNFIG_LAYER_SET_VERSION(Halftone3,"0.0");
+SYNFIG_LAYER_SET_CVS_ID(Halftone3,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+#define HALFSQRT2 (0.7)
+#define SQRT2 (1.414213562f)
+
+/* === M E T H O D S ======================================================= */
+
+Halftone3::Halftone3()
+{
+ size=(synfig::Vector(0.25,0.25));
+ type=TYPE_SYMMETRIC;
+
+ for(int i=0;i<3;i++)
+ {
+ tone[i].size=size;
+ tone[i].type=type;
+ tone[i].offset=(synfig::Point(0,0));
+ tone[i].angle=Angle::deg(30.0)*(float)i;
+ }
+
+ subtractive=true;
+
+ if(subtractive)
+ {
+ color[0]=Color::cyan();
+ color[1]=Color::magenta();
+ color[2]=Color::yellow();
+ }
+ else
+ {
+ color[0]=Color::red();
+ color[1]=Color::green();
+ color[2]=Color::blue();
+ }
+
+ set_blend_method(Color::BLEND_STRAIGHT);
+
+ for(int i=0;i<3;i++)
+ for(int j=0;j<3;j++)
+ inverse_matrix[i][j]=(j==i)?1.0f:0.0f;
+
+ sync();
+}
+
+void
+Halftone3::sync()
+{
+ for(int i=0;i<3;i++)
+ {
+ tone[i].size=size;
+ tone[i].type=type;
+ }
+
+#define matrix inverse_matrix
+ //float matrix[3][3];
+
+ if(subtractive)
+ {
+ for(int i=0;i<3;i++)
+ {
+ matrix[i][0]=1.0f-(color[i].get_r());
+ matrix[i][1]=1.0f-(color[i].get_g());
+ matrix[i][2]=1.0f-(color[i].get_b());
+ float mult=sqrt(matrix[i][0]*matrix[i][0]+matrix[i][1]*matrix[i][1]+matrix[i][2]*matrix[i][2]);
+ if(mult)
+ {
+ matrix[i][0]/=mult;
+ matrix[i][1]/=mult;
+ matrix[i][2]/=mult;
+ matrix[i][0]/=mult;
+ matrix[i][1]/=mult;
+ matrix[i][2]/=mult;
+ }
+ }
+ }
+ else
+ {
+ for(int i=0;i<3;i++)
+ {
+ matrix[i][0]=color[i].get_r();
+ matrix[i][1]=color[i].get_g();
+ matrix[i][2]=color[i].get_b();
+ float mult=sqrt(matrix[i][0]*matrix[i][0]+matrix[i][1]*matrix[i][1]+matrix[i][2]*matrix[i][2]);
+ if(mult)
+ {
+ matrix[i][0]/=mult;
+ matrix[i][1]/=mult;
+ matrix[i][2]/=mult;
+ matrix[i][0]/=mult;
+ matrix[i][1]/=mult;
+ matrix[i][2]/=mult;
+ }
+ }
+ }
+#undef matrix
+
+
+
+#if 0
+ // Insert guass-jordan elimination code here
+ int k=0,i=0,j=0,z_size=3;
+#define A inverse_matrix
+
+ for (k=0;k<z_size;k++)
+ // the pivot element
+ { A[k][k]= -1/A[k][k];
+
+ //the pivot column
+ for (i=0;i<z_size;i++)
+ if (i!=k) A[i][k]*=A[k][k];
+
+ //elements not in a pivot row or column
+ for (i=0;i<z_size;i++)
+ if (i!=k)
+ for (j=0;j<z_size;j++)
+ if (j!=k)
+ A[i][j]+=A[i][k]*A[k][j];
+
+ //elements in a pivot row
+ for (i=0;i<z_size;i++)
+ if (i!=k)
+ A[k][i]*=A[k][k];
+ }
+
+ //change sign
+ for (i=0;i<z_size;i++) /*reverse sign*/
+ for (j=0;j<z_size;j++)
+ A[i][j]=-A[i][j];
+#undef A
+#endif
+}
+
+inline Color
+Halftone3::color_func(const Point &point, float supersample,const Color& in_color)const
+{
+ Color halfcolor;
+
+ float chan[3];
+
+
+ if(subtractive)
+ {
+ chan[0]=inverse_matrix[0][0]*(1.0f-in_color.get_r())+inverse_matrix[0][1]*(1.0f-in_color.get_g())+inverse_matrix[0][2]*(1.0f-in_color.get_b());
+ chan[1]=inverse_matrix[1][0]*(1.0f-in_color.get_r())+inverse_matrix[1][1]*(1.0f-in_color.get_g())+inverse_matrix[1][2]*(1.0f-in_color.get_b());
+ chan[2]=inverse_matrix[2][0]*(1.0f-in_color.get_r())+inverse_matrix[2][1]*(1.0f-in_color.get_g())+inverse_matrix[2][2]*(1.0f-in_color.get_b());
+
+ halfcolor=Color::white();
+ halfcolor-=(~color[0])*tone[0](point,chan[0],supersample);
+ halfcolor-=(~color[1])*tone[1](point,chan[1],supersample);
+ halfcolor-=(~color[2])*tone[2](point,chan[2],supersample);
+
+ halfcolor.set_a(in_color.get_a());
+ }
+ else
+ {
+ chan[0]=inverse_matrix[0][0]*in_color.get_r()+inverse_matrix[0][1]*in_color.get_g()+inverse_matrix[0][2]*in_color.get_b();
+ chan[1]=inverse_matrix[1][0]*in_color.get_r()+inverse_matrix[1][1]*in_color.get_g()+inverse_matrix[1][2]*in_color.get_b();
+ chan[2]=inverse_matrix[2][0]*in_color.get_r()+inverse_matrix[2][1]*in_color.get_g()+inverse_matrix[2][2]*in_color.get_b();
+
+ halfcolor=Color::black();
+ halfcolor+=color[0]*tone[0](point,chan[0],supersample);
+ halfcolor+=color[1]*tone[1](point,chan[1],supersample);
+ halfcolor+=color[2]*tone[2](point,chan[2],supersample);
+
+ halfcolor.set_a(in_color.get_a());
+ }
+
+ return halfcolor;
+}
+
+inline float
+Halftone3::calc_supersample(const synfig::Point &/*x*/, float pw,float /*ph*/)const
+{
+ return abs(pw/(tone[0].size).mag());
+}
+
+synfig::Layer::Handle
+Halftone3::hit_check(synfig::Context /*context*/, const synfig::Point &/*point*/)const
+{
+ return const_cast<Halftone3*>(this);
+}
+
+bool
+Halftone3::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT_PLUS(size, {tone[0].size=size; tone[1].size=size; tone[2].size=size;});
+ IMPORT_PLUS(type, {tone[0].type=type; tone[1].type=type; tone[2].type=type;});
+
+ IMPORT_PLUS(color[0],sync());
+ IMPORT_PLUS(color[1],sync());
+ IMPORT_PLUS(color[2],sync());
+
+ IMPORT_PLUS(subtractive,sync());
+
+ IMPORT(tone[0].angle);
+ IMPORT(tone[0].offset);
+
+ IMPORT(tone[1].angle);
+ IMPORT(tone[1].offset);
+
+ IMPORT(tone[2].angle);
+ IMPORT(tone[2].offset);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+Halftone3::get_param(const String & param)const
+{
+ EXPORT(size);
+ EXPORT(type);
+
+ EXPORT(color[0]);
+ EXPORT(color[1]);
+ EXPORT(color[2]);
+
+ EXPORT(subtractive);
+
+ EXPORT(tone[0].angle);
+ EXPORT(tone[0].offset);
+
+ EXPORT(tone[1].angle);
+ EXPORT(tone[1].offset);
+
+ EXPORT(tone[2].angle);
+ EXPORT(tone[2].offset);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+Halftone3::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("size")
+ .set_local_name(_("Mask Size"))
+ );
+ ret.push_back(ParamDesc("type")
+ .set_local_name(_(" Type"))
+ .set_hint("enum")
+ .add_enum_value(TYPE_SYMMETRIC,"symmetric",_("Symmetric"))
+ .add_enum_value(TYPE_LIGHTONDARK,"lightondark",_("Light On Dark"))
+ //.add_enum_value(TYPE_DARKONLIGHT,"darkonlight",_("Dark on Light"))
+ .add_enum_value(TYPE_DIAMOND,"diamond",_("Diamond"))
+ .add_enum_value(TYPE_STRIPE,"stripe",_("Stripe"))
+ );
+ ret.push_back(ParamDesc("subtractive")
+ .set_local_name(_("Subtractive Flag"))
+ );
+
+ for(int i=0;i<3;i++)
+ {
+ String chan_name(strprintf("Chan%d",i));
+
+ ret.push_back(ParamDesc(strprintf("color[%d]",i))
+ .set_local_name(chan_name+_(" Color"))
+ );
+
+ ret.push_back(ParamDesc(strprintf("tone[%d].offset",i))
+ .set_local_name(chan_name+_(" Mask Offset"))
+ .set_is_distance()
+ );
+ ret.push_back(ParamDesc(strprintf("tone[%d].angle",i))
+ .set_local_name(chan_name+_(" Mask Angle"))
+ .set_origin(strprintf("tone[%d].offset",i))
+ );
+ }
+
+ return ret;
+}
+
+Color
+Halftone3::get_color(Context context, const Point &point)const
+{
+ const Color undercolor(context.get_color(point));
+ const Color color(color_func(point,0,undercolor));
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,undercolor,get_amount(),get_blend_method());
+}
+
+bool
+Halftone3::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+ if(get_amount()==0)
+ return true;
+
+ const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
+ const Point tl(renddesc.get_tl());
+ const int w(surface->get_w());
+ const int h(surface->get_h());
+ const float supersample_size(abs(pw/(tone[0].size).mag()));
+
+ Surface::pen pen(surface->begin());
+ Point pos;
+ int x,y;
+
+ if(is_solid_color())
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(
+ color_func(
+ pos,
+ supersample_size,
+ pen.get_value()
+ )
+ );
+ }
+ else
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(
+ Color::blend(
+ color_func(
+ pos,
+ supersample_size,
+ pen.get_value()
+ ),
+ pen.get_value(),
+ get_amount(),
+ get_blend_method()
+ )
+ );
+ }
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file halftone3.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_HALFTONE3_H
+#define __SYNFIG_HALFTONE3_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/vector.h>
+#include <synfig/valuenode.h>
+#include <synfig/layer_composite.h>
+#include <synfig/time.h>
+#include <synfig/angle.h>
+#include "halftone.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class Halftone3 : public synfig::Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ synfig::Vector size;
+ int type;
+ Halftone tone[3];
+ synfig::Color color[3];
+ float inverse_matrix[3][3];
+ bool subtractive;
+
+ synfig::Color color_func(const synfig::Point &x, float supersample,const synfig::Color &under_color)const;
+
+ float calc_supersample(const synfig::Point &x, float pw,float ph)const;
+
+ //float halftone_func(synfig::Point x)const;
+
+ void sync();
+
+public:
+ Halftone3();
+
+ virtual bool set_param(const synfig::String ¶m, const synfig::ValueBase &value);
+ virtual synfig::ValueBase get_param(const synfig::String ¶m)const;
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+ virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual Vocab get_param_vocab()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file lumakey.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "lumakey.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/segment.h>
+
+#endif
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(LumaKey);
+SYNFIG_LAYER_SET_NAME(LumaKey,"lumakey");
+SYNFIG_LAYER_SET_LOCAL_NAME(LumaKey,_("Luma Key"));
+SYNFIG_LAYER_SET_CATEGORY(LumaKey,_("Filters"));
+SYNFIG_LAYER_SET_VERSION(LumaKey,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(LumaKey,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+LumaKey::LumaKey():
+ Layer_Composite (1.0,Color::BLEND_STRAIGHT)
+{
+ set_blend_method(Color::BLEND_STRAIGHT);
+}
+
+
+bool
+LumaKey::set_param(const String ¶m, const ValueBase &value)
+{
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+LumaKey::get_param(const String ¶m)const
+{
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+LumaKey::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+/* ret.push_back(ParamDesc("color")
+ .set_local_name(_("Color"))
+ .set_description(_("Color of checkers"))
+ );
+ ret.push_back(ParamDesc("pos")
+ .set_local_name(_("Offset"))
+ );
+ ret.push_back(ParamDesc("size")
+ .set_local_name(_("Size"))
+ .set_description(_("Size of checkers"))
+ .set_origin("pos")
+ );
+*/
+ return ret;
+}
+
+synfig::Layer::Handle
+LumaKey::hit_check(synfig::Context context, const synfig::Point &getpos)const
+{
+ return context.hit_check(getpos);
+}
+
+Color
+LumaKey::get_color(Context context, const Point &getpos)const
+{
+ const Color color(context.get_color(getpos));
+
+ if(get_amount()==0.0)
+ return color;
+
+ Color ret(color);
+ ret.set_a(ret.get_y()*ret.get_a());
+ ret.set_y(1);
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return ret;
+
+ return Color::blend(ret,color,get_amount(),get_blend_method());
+}
+
+bool
+LumaKey::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+
+ int x,y;
+
+ Surface::pen pen(surface->begin());
+
+ for(y=0;y<renddesc.get_h();y++,pen.inc_y(),pen.dec_x(x))
+ for(x=0;x<renddesc.get_w();x++,pen.inc_x())
+ {
+ Color tmp(pen.get_value());
+ tmp.set_a(tmp.get_y()*tmp.get_a());
+ tmp.set_y(1);
+ pen.put_value(tmp);
+ }
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
+
+Rect
+LumaKey::get_bounding_rect(Context context)const
+{
+ if(is_disabled())
+ return Rect::zero();
+
+ return context.get_full_bounding_rect();
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file lumakey.h
+** \brief Checkerboard Layer
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LUMAKEY_H
+#define __SYNFIG_LUMAKEY_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class LumaKey : public synfig::Layer_Composite, public synfig::Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+private:
+
+public:
+ LumaKey();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+
+ virtual synfig::ValueBase get_param(const synfig::String & param)const;
+
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+
+ virtual Vocab get_param_vocab()const;
+
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+ virtual synfig::Rect get_bounding_rect(synfig::Context context)const;
+
+ virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_filter/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include <synfig/string.h>
+#include <synfig/canvas.h>
+
+#include "blur.h"
+#include "colorcorrect.h"
+#include "halftone2.h"
+#include "halftone3.h"
+#include "lumakey.h"
+#include "radialblur.h"
+
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(libmod_filter)
+ MODULE_NAME("Filters")
+ MODULE_DESCRIPTION("Writeme")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(libmod_filter)
+ BEGIN_LAYERS
+ LAYER(Blur_Layer)
+ LAYER(Halftone2)
+ LAYER(Halftone3)
+ LAYER(LumaKey)
+ LAYER(RadialBlur)
+ LAYER(Layer_ColorCorrect)
+ END_LAYERS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_filter" Sec_mod_filter
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_filter.dll "src\modules\mod_filter\.libs\libmod_filter-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_filter"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file radialblur.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "radialblur.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/transform.h>
+#include <ETL/misc>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(RadialBlur);
+SYNFIG_LAYER_SET_NAME(RadialBlur,"radial_blur");
+SYNFIG_LAYER_SET_LOCAL_NAME(RadialBlur,_("Radial Blur"));
+SYNFIG_LAYER_SET_CATEGORY(RadialBlur,_("Blurs"));
+SYNFIG_LAYER_SET_VERSION(RadialBlur,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(RadialBlur,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+RadialBlur::RadialBlur():
+ origin (0,0),
+ size (0.2),
+ fade_out(false)
+{
+}
+
+RadialBlur::~RadialBlur()
+{
+}
+
+bool
+RadialBlur::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(origin);
+ IMPORT(size);
+ IMPORT(fade_out);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+RadialBlur::get_param(const String ¶m)const
+{
+ EXPORT(origin);
+ EXPORT(size);
+ EXPORT(fade_out);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+RadialBlur::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("origin")
+ .set_local_name(_("Origin"))
+ .set_description(_("Point where you want the origin to be"))
+ );
+
+ ret.push_back(ParamDesc("size")
+ .set_local_name(_("Size"))
+ .set_description(_("Size of blur"))
+ .set_origin("origin")
+ );
+
+ ret.push_back(ParamDesc("fade_out")
+ .set_local_name(_("Fade Out"))
+ );
+
+ return ret;
+}
+
+Color
+RadialBlur::get_color(Context context, const Point &p)const
+{
+ //! \writeme
+ return context.get_color(p);
+}
+
+bool
+RadialBlur::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ if(cb && !cb->amount_complete(0,10000))
+ return false;
+
+ Surface tmp_surface;
+ const Point tl(renddesc.get_tl()), br(renddesc.get_br());
+ const int w(renddesc.get_w()), h(renddesc.get_h());
+ const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
+
+ Rect rect(tl, br);
+ Point pos;
+
+ // find how far towards the origin of the blur we are going to
+ // wander for each of the 4 corners of our tile, expanding the
+ // render description for each of them if necessary
+ int x, y;
+ for(y=0,pos[1]=tl[1];y<h;y+=(h-1),pos[1]+=ph*(h-1))
+ for(x=0,pos[0]=tl[0];x<w;x+=(w-1),pos[0]+=pw*(w-1))
+ rect.expand((pos-origin)*(1.0f-size) + origin);
+
+ // round out to the nearest pixel
+ Point tmp_surface_tl = Point(tl[0] - pw*(int((tl[0]-rect.get_min()[0])/pw+1-1e-6)),
+ tl[1] - ph*(int((tl[1]-rect.get_max()[1])/ph+1-1e-6)));
+ Point tmp_surface_br = Point(br[0] + pw*(int((rect.get_max()[0]-br[0])/pw+2-1e-6)),
+ br[1] + ph*(int((rect.get_min()[1]-br[1])/ph+2-1e-6)));
+
+ // round to nearest integer width and height (should be very
+ // nearly whole numbers already, but dont want to round 5.99999
+ // down to 5)
+ int tmp_surface_width = int((tmp_surface_br[0]-tmp_surface_tl[0])/pw + 0.5);
+ int tmp_surface_height = int((tmp_surface_br[1]-tmp_surface_tl[1])/ph + 0.5);
+
+ RendDesc desc(renddesc);
+ desc.clear_flags();
+ desc.set_wh(tmp_surface_width,tmp_surface_height);
+ desc.set_tl(tmp_surface_tl);
+ desc.set_br(tmp_surface_br);
+
+ // render the layers beneath us
+ if(!context.accelerated_render(&tmp_surface,quality,desc,cb))
+ return false;
+
+ // copy the part of the layers beneath us that corresponds to this tile
+ surface->set_wh(w, h);
+ Surface::pen pen(surface->get_pen(0, 0));
+ tmp_surface.blit_to(pen,
+ int((tl[0] - tmp_surface_tl[0])/pw + 0.5),
+ int((tl[1] - tmp_surface_tl[1])/ph + 0.5),
+ w, h);
+
+ Surface::alpha_pen apen(surface->begin());
+
+ apen.set_alpha(get_amount());
+ apen.set_blend_method(get_blend_method());
+
+/*
+ int steps(5);
+
+ if(quality>=9)steps=20;
+ else if(quality>=5)steps=30;
+ else if(quality>=4)steps=60;
+ else if(quality>=3)steps=100;
+ else steps=120;
+*/
+
+ Surface::value_prep_type cooker;
+
+ // loop through the pixels
+ for(y=0,pos[1]=tl[1];y<h;y++,apen.inc_y(),apen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,apen.inc_x(),pos[0]+=pw)
+ {
+ Point
+ begin(pos-tmp_surface_tl),
+ end((pos-origin)*(1.0f-size) + origin-tmp_surface_tl);
+ begin[0]/=pw;begin[1]/=ph;
+ end[0]/=pw;end[1]/=ph;
+
+ Color pool(Color::alpha());
+ int poolsize(0);
+
+ int x0(round_to_int(begin[0])),
+ y0(round_to_int(begin[1])),
+ x1(round_to_int(end[0])),
+ y1(round_to_int(end[1]));
+
+ int i;
+ int steep = 1;
+ int sx, sy; /* step positive or negative (1 or -1) */
+ int dx, dy; /* delta (difference in X and Y between points) */
+ int e;
+ int w(tmp_surface_width), h(tmp_surface_height);
+
+ dx = abs(x1 - x0);
+ sx = ((x1 - x0) > 0) ? 1 : -1;
+ dy = abs(y1 - y0);
+ sy = ((y1 - y0) > 0) ? 1 : -1;
+ if (dy > dx)
+ {
+ steep = 0;
+ swap(x0, y0);
+ swap(dx, dy);
+ swap(sx, sy);
+ swap(w,h);
+ }
+ e = (dy << 1) - dx;
+ for (i = 0; i < dx; i++)
+ {
+ if(y0>=0 && x0>=0 && y0<h && x0<w)
+ {
+ if(fade_out)
+ {
+ if (steep)
+ pool+=cooker.cook(tmp_surface[y0][x0])*(i-dx);
+ else
+ pool+=cooker.cook(tmp_surface[x0][y0])*(i-dx);
+ poolsize+=(i-dx);
+ }
+ else
+ {
+ if (steep)
+ pool+=cooker.cook(tmp_surface[y0][x0]);
+ else
+ pool+=cooker.cook(tmp_surface[x0][y0]);
+ poolsize+=1;
+ }
+ } else
+ printf("%s:%d unexpected %d >= %d or %d >= %d?\n", __FILE__, __LINE__, x0, w, y0, h);
+
+ while (e >= 0)
+ {
+ y0 += sy;
+ e -= (dx << 1);
+ }
+ x0 += sx;
+ e += (dy << 1);
+ }
+ if(poolsize)
+ {
+ pool/=poolsize;
+ apen.put_value(cooker.uncook(pool));
+ }
+/*
+ Point begin,end;
+ begin=pos;
+ end=(pos-origin)*(1.0f-size)+origin;
+
+ Color pool(Color::alpha());
+ float f,poolsize(0);
+ int i;
+ int steps(steps*size);
+ for(f=0,i=0;i<steps;i++,f+=1.0f/(steps-1))
+ {
+ Point loc((end-begin)*f+begin-tl);
+ loc[0]/=pw;loc[1]/=ph;
+
+ if(fade_out)
+ pool+=tmp_surface.linear_sample(loc[0],loc[1])*(i-steps),poolsize+=(i-steps);
+ else
+ pool+=tmp_surface.linear_sample(loc[0],loc[1]),poolsize+=1;
+ }
+ pool/=poolsize;
+ apen.put_value(pool);
+*/
+ }
+
+
+ if(cb && !cb->amount_complete(10000,10000)) return false;
+
+// #define DRAW_TILE_OUTLINES
+#ifdef DRAW_TILE_OUTLINES
+ // draw red lines to show tiles
+ {
+ int x, y;
+ if (w != 0 && h != 0) {
+ Surface::alpha_pen apen(surface->begin());
+ apen.set_alpha(get_amount());
+ apen.set_blend_method(get_blend_method());
+ apen.set_value(Color(1, 0, 0, .1));
+ for (x = 0; x < w; x++) { apen.put_value(); apen.inc_x(); } apen.dec_x(w);
+ for (y = 0; y < h; y++) { apen.put_value(); apen.inc_y(); } apen.dec_y(h);
+ }
+ }
+#endif // DRAW_TILE_OUTLINES
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file radialblur.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_RADIALBLUR_H
+#define __SYNFIG_RADIALBLUR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/vector.h>
+#include <synfig/angle.h>
+#include <synfig/layer_composite.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class RadialBlur : public Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+ friend class RadialBlur_Trans;
+private:
+ Vector origin;
+ Real size;
+ bool fade_out;
+
+public:
+ RadialBlur();
+ ~RadialBlur();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+ virtual ValueBase get_param(const synfig::String & param)const;
+ virtual Color get_color(Context context, const Point &pos)const;
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+ virtual Vocab get_param_vocab()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_filter"
+ Delete "$INSTDIR\lib\synfig\modules\mod_filter.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+# GCC on MacOS X does not take kindly to the -ffastmath optimization
+# in this module for some reason.
+AM_CXXFLAGS=`echo @CXXFLAGS@ | sed s/-ffast-math//g`
+
+moduledir=@MODULE_DIR@
+
+module_LTLIBRARIES = libmod_geometry.la
+libmod_geometry_la_SOURCES = rectangle.cpp rectangle.h star.h star.cpp checkerboard.cpp checkerboard.h circle.cpp circle.h region.h region.cpp outline.h outline.cpp main.cpp
+libmod_geometry_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_geometry_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+libmod_geometry_la_LDFLAGS = -module -no-undefined
+EXTRA_DIST= mod_geometry.nsh unmod_geometry.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file checkerboard.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "checkerboard.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/segment.h>
+
+#endif
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(CheckerBoard);
+SYNFIG_LAYER_SET_NAME(CheckerBoard,"checker_board");
+SYNFIG_LAYER_SET_LOCAL_NAME(CheckerBoard,_("Checkerboard"));
+SYNFIG_LAYER_SET_CATEGORY(CheckerBoard,_("Geometry"));
+SYNFIG_LAYER_SET_VERSION(CheckerBoard,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(CheckerBoard,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+CheckerBoard::CheckerBoard():
+ Layer_Composite (1.0,Color::BLEND_STRAIGHT),
+ color (Color::black()),
+ pos (Point(0.125,0.125)),
+ size (Point(0.25,0.25))
+{
+
+ set_blend_method(Color::BLEND_STRAIGHT);
+}
+
+inline bool
+CheckerBoard::point_test(const synfig::Point& getpos)const
+{
+ int val=((int)((getpos[0]-pos[0])/size[0])+(int)((getpos[1]-pos[1])/size[1]));
+ if(getpos[0]-pos[0] < 0.0)
+ val++;
+ if(getpos[1]-pos[1] < 0.0)
+ val++;
+ return val&1;
+}
+
+bool
+CheckerBoard::set_param(const String ¶m, const ValueBase &value)
+{
+ IMPORT(color);
+ IMPORT(pos);
+ IMPORT(pos[0]);
+ IMPORT(pos[1]);
+ IMPORT(size);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+CheckerBoard::get_param(const String ¶m)const
+{
+ EXPORT(color);
+ EXPORT(pos);
+ EXPORT(pos[0]);
+ EXPORT(pos[1]);
+ EXPORT(size);
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+CheckerBoard::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("color")
+ .set_local_name(_("Color"))
+ .set_description(_("Color of checkers"))
+ );
+ ret.push_back(ParamDesc("pos")
+ .set_local_name(_("Offset"))
+ );
+ ret.push_back(ParamDesc("size")
+ .set_local_name(_("Size"))
+ .set_description(_("Size of checkers"))
+ .set_origin("pos")
+ );
+
+ return ret;
+}
+
+synfig::Layer::Handle
+CheckerBoard::hit_check(synfig::Context context, const synfig::Point &getpos)const
+{
+ if(get_amount()!=0.0 && point_test(getpos))
+ {
+ synfig::Layer::Handle tmp;
+ if(get_blend_method()==Color::BLEND_BEHIND && (tmp=context.hit_check(getpos)))
+ return tmp;
+ if(Color::is_onto(get_blend_method()) && !(tmp=context.hit_check(getpos)))
+ return 0;
+ return const_cast<CheckerBoard*>(this);
+ }
+ else
+ return context.hit_check(getpos);
+}
+
+Color
+CheckerBoard::get_color(Context context, const Point &getpos)const
+{
+ if(get_amount()!=0.0 && point_test(getpos))
+ {
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,context.get_color(getpos),get_amount(),get_blend_method());
+ }
+ else
+ return context.get_color(getpos);
+}
+
+bool
+CheckerBoard::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+ if(get_amount()==0)
+ return true;
+
+ int x,y;
+
+ const Point tl(renddesc.get_tl());
+ Point pos;
+ const int w(surface->get_w());
+ const int h(surface->get_h());
+ const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
+
+ Surface::alpha_pen apen(surface->begin());
+
+ apen.set_alpha(get_amount());
+ apen.set_blend_method(get_blend_method());
+ apen.set_value(color);
+
+ for(y=0,pos[1]=tl[1];y<h;y++,apen.inc_y(),apen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,apen.inc_x(),pos[0]+=pw)
+ if(point_test(pos))
+ apen.put_value();
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file checkerboard.h
+** \brief Checkerboard Layer
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_CHECKERBOARD_H
+#define __SYNFIG_CHECKERBOARD_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class CheckerBoard : public synfig::Layer_Composite, public synfig::Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+private:
+ synfig::Color color;
+ synfig::Point pos;
+ synfig::Point size;
+
+ bool point_test(const synfig::Point& x)const;
+
+public:
+ CheckerBoard();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+
+ virtual synfig::ValueBase get_param(const synfig::String & param)const;
+
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+
+ virtual Vocab get_param_vocab()const;
+
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file circle.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "circle.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#include <cmath>
+
+#endif
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* -- G L O B A L S --------------------------------------------------------- */
+
+SYNFIG_LAYER_INIT(Circle);
+SYNFIG_LAYER_SET_NAME(Circle,"circle");
+SYNFIG_LAYER_SET_LOCAL_NAME(Circle,_("Circle"));
+SYNFIG_LAYER_SET_CATEGORY(Circle,_("Geometry"));
+SYNFIG_LAYER_SET_VERSION(Circle,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Circle,"$Id$");
+
+/* -- F U N C T I O N S ----------------------------------------------------- */
+
+Circle::Circle():
+ Layer_Composite (1.0,Color::BLEND_STRAIGHT),
+ color (Color::black()),
+ pos (0,0),
+ radius (1),
+ feather (0),
+ invert (false),
+ falloff (FALLOFF_INTERPOLATION_LINEAR)
+{
+ constructcache();
+}
+
+bool
+Circle::ImportParameters(const String ¶m, const ValueBase &value)
+{
+ IMPORT(color);
+ IMPORT(radius);
+ IMPORT(feather);
+ IMPORT(invert);
+ IMPORT(pos);
+ IMPORT(falloff);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+bool
+Circle::set_param(const String ¶m, const ValueBase &value)
+{
+ if(ImportParameters(param,value))
+ {
+ constructcache();
+ return true;
+ }
+
+ return false;
+}
+
+ValueBase
+Circle::get_param(const String ¶m)const
+{
+ EXPORT(color);
+ EXPORT(radius);
+ EXPORT(feather);
+ EXPORT(invert);
+ EXPORT(pos);
+ EXPORT(falloff);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+Circle::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("color")
+ .set_local_name(_("Color"))
+ );
+ ret.push_back(ParamDesc("radius")
+ .set_local_name(_("Radius"))
+ .set_origin("pos")
+ .set_is_distance()
+ );
+ ret.push_back(ParamDesc("feather")
+ .set_local_name(_("Feather"))
+ .set_is_distance()
+ );
+ ret.push_back(ParamDesc("pos")
+ .set_local_name(_("Center"))
+ );
+ ret.push_back(ParamDesc("invert")
+ .set_local_name(_("Invert"))
+ .set_description(_("Invert the circle"))
+ );
+
+ ret.push_back(ParamDesc("falloff")
+ .set_local_name(_("Falloff"))
+ .set_description(_("Determines the falloff function for the feather"))
+ .set_hint("enum")
+ .add_enum_value(FALLOFF_INTERPOLATION_LINEAR,"linear",_("Linear"))
+ .add_enum_value(FALLOFF_SQUARED,"squared",_("Squared"))
+ .add_enum_value(FALLOFF_SQRT,"sqrt",_("Square Root"))
+ .add_enum_value(FALLOFF_SIGMOND,"sigmond",_("Sigmond"))
+ .add_enum_value(FALLOFF_COSINE,"cosine",_("Cosine"))
+ );
+
+ return ret;
+}
+
+synfig::Layer::Handle
+Circle::hit_check(synfig::Context context, const synfig::Point &point)const
+{
+ Point temp=pos-point;
+
+ if(get_amount()==0)
+ return context.hit_check(point);
+
+ bool in_circle(temp.mag_squared() <= radius*radius);
+
+ if(invert)
+ {
+ in_circle=!in_circle;
+ if(in_circle && get_amount()-(feather/radius)<=0.1 && get_blend_method()!=Color::BLEND_STRAIGHT)
+ in_circle=false;
+ }
+ else
+ {
+ if(get_amount()-(feather/radius)<=0.0)
+ in_circle=false;
+ }
+
+ if(in_circle)
+ {
+ synfig::Layer::Handle tmp;
+ if(get_blend_method()==Color::BLEND_BEHIND && (tmp=context.hit_check(point)))
+ return tmp;
+ if(Color::is_onto(get_blend_method()) && !(tmp=context.hit_check(point)))
+ return 0;
+ return const_cast<Circle*>(this);
+ }
+
+ return context.hit_check(point);
+}
+
+//falloff functions
+Real Circle::SqdFalloff(const Circle::CircleDataCache &c, const Real &mag_sqd)
+{
+ //squared proportional falloff
+ return (c.outer_radius_sqd - mag_sqd) / c.diff_sqd;
+}
+
+Real Circle::InvSqdFalloff(const Circle::CircleDataCache &c, const Real &mag_sqd)
+{
+ //squared proportional falloff
+ return 1.0 - (c.outer_radius_sqd - mag_sqd) / c.diff_sqd;
+}
+
+
+Real Circle::SqrtFalloff(const Circle::CircleDataCache &c, const Real &mag_sqd)
+{
+ //linear distance falloff
+ Real ret = ( c.outer_radius - sqrt(mag_sqd) ) / c.double_feather;
+ //then take the square root of it
+ ret = sqrt(ret);
+ return ret;
+}
+
+Real Circle::InvSqrtFalloff(const Circle::CircleDataCache &c, const Real &mag_sqd)
+{
+ //linear distance falloff
+ Real ret = ( c.outer_radius - sqrt(mag_sqd) ) / c.double_feather;
+ //then take the square root of it
+ ret = 1.0 - sqrt(ret);
+ return ret;
+}
+
+Real Circle::LinearFalloff(const Circle::CircleDataCache &c, const Real &mag_sqd)
+{
+ //linear distance falloff
+ return ( c.outer_radius - sqrt(mag_sqd) ) / c.double_feather;
+}
+
+Real Circle::InvLinearFalloff(const Circle::CircleDataCache &c, const Real &mag_sqd)
+{
+ return 1.0 - ( c.outer_radius - sqrt(mag_sqd) ) / c.double_feather;
+ //linear distance falloff
+}
+
+Real Circle::SigmondFalloff(const Circle::CircleDataCache &c, const Real &mag_sqd)
+{
+ //linear distance falloff
+ Real ret = ( c.outer_radius - sqrt(mag_sqd) ) / c.double_feather;
+ // inverse exponential of the linear falloff (asymptotes at 0 and 1)
+ // \frac{1.0}{ 1 + e^{- \( a*10-5 \)}}
+ ret = 1.0 / (1 + exp(-(ret*10-5)) );
+ return ret;
+}
+
+Real Circle::InvSigmondFalloff(const Circle::CircleDataCache &c, const Real &mag_sqd)
+{
+ //linear distance falloff
+ Real ret = ( c.outer_radius - sqrt(mag_sqd) ) / c.double_feather;
+ // inverse exponential of the linear falloff (asymptotes at 0 and 1)
+ // \frac{1.0}{ 1 + e^{- \( a*10-5 \)}}
+ ret = 1.0 - 1.0 / (1 + exp(-(ret*10-5)) );
+ return ret;
+}
+
+
+Real
+Circle::CosineFalloff(const Circle::CircleDataCache &c, const Real &mag_sqd)
+{
+ //Cosine distance falloff
+ return (1.0f-cos((( c.outer_radius - sqrt(mag_sqd) ) / c.double_feather)*3.1415927))*0.5f;
+}
+
+Real
+Circle::InvCosineFalloff(const Circle::CircleDataCache &c, const Real &mag_sqd)
+{
+ return 1.0f-(1.0f-cos((( c.outer_radius - sqrt(mag_sqd) ) / c.double_feather)*3.1415927))*0.5f;
+ //Cosine distance falloff
+}
+
+void Circle::constructcache()
+{
+ cache.inner_radius = radius - feather;
+ if(cache.inner_radius < 0)
+ cache.inner_radius = 0;
+
+ cache.outer_radius = radius + feather;
+
+ cache.inner_radius_sqd = cache.inner_radius > 0 ? (radius-feather)*(radius-feather) : 0;
+ cache.outer_radius_sqd = (radius+feather)*(radius+feather);
+
+ cache.diff_sqd = feather*feather*4.0;
+ cache.double_feather = feather*2.0;
+
+ falloff_func = GetFalloffFunc();
+}
+
+Circle::FALLOFF_FUNC *Circle::GetFalloffFunc()const
+{
+ switch(falloff)
+ {
+ case FALLOFF_SQUARED: return invert?InvSqdFalloff:SqdFalloff;
+
+ case FALLOFF_SQRT: return invert?InvSqrtFalloff:SqrtFalloff;
+
+ case FALLOFF_INTERPOLATION_LINEAR: return invert?InvLinearFalloff:LinearFalloff;
+
+ case FALLOFF_SIGMOND: return invert?InvSigmondFalloff:SigmondFalloff;
+
+ case FALLOFF_COSINE:
+ default: return invert?InvCosineFalloff:CosineFalloff;
+ }
+}
+
+Color
+Circle::get_color(Context context, const Point &point)const
+{
+ if(radius==0 || is_disabled())
+ return context.get_color(point);
+
+
+ Point temp=pos-point;
+
+ /*const Real inner_radius = radius-feather;
+ const Real outer_radius = radius+feather;
+
+ const Real inner_radius_sqd = inner_radius > 0 ? (radius-feather)*(radius-feather) : 0;
+ const Real outer_radius_sqd = (radius+feather)*(radius+feather);
+
+ const Real diff_radii_sqd = outer_radius_sqd - inner_radius_sqd;
+ const Real double_feather = feather*2.0;*/
+
+ /*const Real &inner_radius = cache.inner_radius;
+ const Real &outer_radius = cache.outer_radius;*/
+
+ const Real &inner_radius_sqd = cache.inner_radius_sqd;
+ const Real &outer_radius_sqd = cache.outer_radius_sqd;
+
+ /*const Real &diff_radii_sqd = cache.diff_radii_sqd;
+ const Real &double_feather = cache.double_feather;*/
+
+ const Vector::value_type mag_squared = temp.mag_squared();
+
+ //Outside the circle, with feathering enabled
+ if( mag_squared > outer_radius_sqd )
+ {
+ // inverted -> outside == colored in
+ if(invert)
+ {
+ if(get_amount() == 1 && get_blend_method() == Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,context.get_color(point),get_amount(),get_blend_method());
+ }
+ else
+ return context.get_color(point);
+ }
+
+ //inside the circle's solid area (with feathering)
+ else if(mag_squared <= inner_radius_sqd)
+ {
+ // !invert -> solid area
+ if(!invert)
+ if(get_amount() == 1 && get_blend_method() == Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,context.get_color(point),get_amount(),get_blend_method());
+ else
+ return context.get_color(point);
+ }
+
+ //If we get here, the pixel is within the feathering area, and is thus subject to falloff
+ else
+ {
+ Color::value_type alpha;
+
+ /*switch(falloff)
+ {
+
+ case FALLOFF_SQUARED:
+ //squared proportional falloff
+ alpha = (outer_radius_sqd - mag_squared) / diff_radii_sqd;
+ break;
+
+ case FALLOFF_SQRT:
+ //linear distance falloff
+ alpha = ( outer_radius - sqrt(mag_squared) ) / double_feather;
+ //then take the square root of it
+ alpha = sqrt(alpha);
+ break;
+
+ case FALLOFF_INTERPOLATION_LINEAR:
+ //linear distance falloff
+ alpha = ( outer_radius - sqrt(mag_squared) ) / double_feather;
+ break;
+
+ case FALLOFF_SIGMOND:
+ default:
+ //linear distance falloff
+ alpha = ( outer_radius - sqrt(mag_squared) ) / double_feather;
+ // inverse exponential of the linear falloff (asymptotes at 0 and 1)
+ // \frac{1.0}{ 1 + e^{- \( a*10-5 \)}}
+ alpha = 1.0 / (1 + exp(-(alpha*10-5)) );
+ break;
+ }
+
+ //If we're inverted, we need to invert the falloff value
+ if(invert)
+ alpha=1.0-alpha;*/
+
+ alpha = falloff_func(cache,mag_squared);
+
+ //Compose falloff value with amount from the composite layer, and that is the blend value
+ alpha *= get_amount();
+
+ return Color::blend(color,context.get_color(point),alpha,get_blend_method());
+ }
+}
+
+Color NormalBlend(Color a, Color b, float amount)
+{
+ return (b-a)*amount+a;
+}
+
+
+bool
+Circle::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ // trivial case
+ if(is_disabled() || (radius==0 && invert==false))
+ return context.accelerated_render(surface,quality, renddesc, cb);
+
+ // Another trivial case
+ if(invert && radius==0 && is_solid_color())
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ surface->fill(color);
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+ return true;
+ }
+
+ // Window Boundaries
+ const Point tl(renddesc.get_tl());
+ const Point br(renddesc.get_br());
+ const int w(renddesc.get_w());
+ const int h(renddesc.get_h());
+
+ const Real x_neg = tl[0] > br[0] ? -1 : 1;
+ const Real y_neg = tl[1] > br[1] ? -1 : 1;
+
+ // Width and Height of a pixel
+ const Real pw = (br[0] - tl[0]) / w;
+ const Real ph = (br[1] - tl[1]) / h;
+
+ // Increasing the feather amount by the size of
+ // a pixel will create an anti-aliased appearance
+ const Real newfeather=feather + (abs(ph)+abs(pw))/4.0;
+
+ //int u,v;
+ int left = (int) floor( (pos[0] - x_neg*(radius+newfeather) - tl[0]) / pw );
+ int right = (int) ceil( (pos[0] + x_neg*(radius+newfeather) - tl[0]) / pw );
+ int top = (int) floor( (pos[1] - y_neg*(radius+newfeather) - tl[1]) / ph );
+ int bottom = (int) ceil( (pos[1] + y_neg*(radius+newfeather) - tl[1]) / ph );
+
+ //clip the rectangle bounds
+ if(left < 0)
+ left = 0;
+ if(top < 0)
+ top = 0;
+ if(right >= w)
+ right = w-1;
+ if(bottom >= h)
+ bottom = h-1;
+
+ const Real inner_radius = radius-newfeather>0 ? radius-newfeather : 0;
+ const Real outer_radius = radius+newfeather;
+
+ const Real inner_radius_sqd = inner_radius*inner_radius;
+ const Real outer_radius_sqd = outer_radius*outer_radius;
+
+ const Real diff_radii_sqd = 4*newfeather*std::max(newfeather,radius);//4.0*radius*newfeather;
+ const Real double_feather = newfeather * 2.0;
+
+ //Compile the temporary cache for the falloff calculations
+ FALLOFF_FUNC *func = GetFalloffFunc();
+
+ const CircleDataCache cache =
+ {
+ inner_radius,outer_radius,
+ inner_radius_sqd,outer_radius_sqd,
+ diff_radii_sqd,double_feather
+ };
+
+ //info("Circle: Initialized everything");
+
+ //let the rendering begin
+ SuperCallback supercb(cb,0,9000,10000);
+
+ //if it's a degenerate circle, do what we need to do, and then leave
+ if(left >= right || top >= bottom)
+ {
+ if(invert)
+ {
+ if(get_amount() == 1 && get_blend_method() == Color::BLEND_STRAIGHT)
+ {
+ surface->set_wh(w,h);
+ surface->fill(color);
+ return true;
+ }else
+ {
+ // Render what is behind us
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ Surface::alpha_pen p(surface->begin(),get_amount(),_BlendFunc(get_blend_method()));
+
+ p.set_value(color);
+ p.put_block(h,w);
+ return true;
+ }
+ }else
+ {
+ // Render what is behind us
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+ return true;
+ }
+ }
+
+ if( (pos[0] - tl[0])*(pos[0] - tl[0]) + (pos[1] - tl[1])*(pos[1] - tl[1]) < inner_radius_sqd
+ && (pos[0] - br[0])*(pos[0] - br[0]) + (pos[1] - br[1])*(pos[1] - br[1]) < inner_radius_sqd
+ && (pos[0] - tl[0])*(pos[0] - tl[0]) + (pos[1] - br[1])*(pos[1] - br[1]) < inner_radius_sqd
+ && (pos[0] - br[0])*(pos[0] - br[0]) + (pos[1] - tl[1])*(pos[1] - tl[1]) < inner_radius_sqd )
+ {
+ if(invert)
+ {
+ // Render what is behind us
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+ }else
+ {
+ if(get_amount() == 1 && get_blend_method() == Color::BLEND_STRAIGHT)
+ {
+ surface->set_wh(w,h);
+ surface->fill(color);
+ return true;
+ }
+ }
+ }
+
+ //info("Circle: Non degenerate, rasterize %c", invert);
+
+ //we start in the middle of the left-top pixel
+ Real leftf = (left + 0.5)*pw + tl[0];
+ Real topf = (top + 0.5)*ph + tl[1];
+
+ //the looping variables
+ Real x,y;
+ int i,j;
+
+ //Loop normally, since we are not inverted
+ if(!invert)
+ {
+ // Render what is behind us
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ //make topf and leftf relative to the center of the circle
+ leftf -= pos[0];
+ topf -= pos[1];
+
+ j = top;
+ y = topf;
+
+ //Loop over the valid y-values in the bounding square
+ for(;j <= bottom; j++, y += ph)
+ {
+ i = left;
+ x = leftf;
+
+ //for each y-value, Loop over the bounding x-values in the bounding square
+ for(;i <= right; i++, x += pw)
+ {
+ //for each pixel, figure out the distance and blend
+ Real r = x*x + y*y;
+
+ //if in the inner circle then the full color shows through
+ if(r <= inner_radius_sqd)
+ {
+ if(get_amount() == 1 && get_blend_method() == Color::BLEND_STRAIGHT)
+ (*surface)[j][i]=color;
+ else
+ (*surface)[j][i]=Color::blend(color,(*surface)[j][i],get_amount(),get_blend_method());
+ }
+ //if it's within the outer circle then it's in the feathering range
+ else if(r <= outer_radius_sqd)
+ {
+ /*float myamount;
+
+ switch(falloff)
+ {
+ case FALLOFF_SQUARED:
+ myamount = (outer_radius_sqd - r) / diff_radii_sqd;
+ break;
+
+ case FALLOFF_SQRT:
+ myamount = (outer_radius - sqrt(r)) / double_feather;
+ myamount = sqrt(myamount);
+ break;
+
+ case FALLOFF_INTERPOLATION_LINEAR:
+ myamount = (outer_radius - sqrt(r)) / double_feather;
+ break;
+
+ case FALLOFF_SIGMOND:
+ default:
+ myamount = (outer_radius - sqrt(r)) / double_feather;
+ myamount = 1.0 / ( 1 + exp(-(myamount*10 - 5)) );
+ break;
+ }*/
+
+ Real myamount = func(cache,r);
+
+ //if(myamount<0.0)myamount=0.0;
+ //if(myamount>1.0)myamount=1.0;
+ myamount *= get_amount();
+ (*surface)[j][i] = Color::blend(color,(*surface)[j][i],myamount,get_blend_method());
+ }
+ }
+ }
+ }
+ else
+ {
+ Surface background;
+ RendDesc desc(renddesc);
+ desc.set_flags(0);
+
+ int offset_x=0,offset_y=0;
+
+ //fill the surface with the background color initially
+ surface->set_wh(w,h);
+ surface->fill(color);
+
+ //then render the background to an alternate surface
+ if(get_amount() == 1 && get_blend_method() == Color::BLEND_STRAIGHT)
+ {
+ offset_x = left;
+ offset_y = top;
+
+ //if there is no background showing through we are done
+ if(right < left || bottom < top)
+ return true;
+
+ desc.set_subwindow(left,top,right-left+1,bottom-top+1);
+
+ // Render what is behind us
+ if(!context.accelerated_render(&background,quality,desc,&supercb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+ }
+ else
+ {
+ left = 0;
+ right = w-1;
+ top = 0;
+ bottom = h-1;
+
+ leftf = /*0.5*pw +*/ tl[0];
+ topf = /*0.5*ph +*/ tl[1];
+
+ // Render what is behind us
+ if(!context.accelerated_render(&background,quality,renddesc,&supercb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+ }
+
+ topf -= pos[1];
+ leftf-= pos[0];
+
+ j = top;
+ y = topf;
+
+ for(;j <= bottom; j++, y+=ph)
+ {
+ i = left;
+ x = leftf;
+
+ for(;i <= right; i++, x+=pw)
+ {
+ Vector::value_type r = x*x + y*y;
+
+ if(r < inner_radius_sqd)
+ {
+ (*surface)[j][i] = background[j-offset_y][i-offset_x];
+ }
+ else if(r < outer_radius_sqd)
+ {
+ /*float amount;
+
+ switch(falloff)
+ {
+ case FALLOFF_SQUARED:
+ amount = (r - inner_radius_sqd) / diff_radii_sqd;
+ break;
+ case FALLOFF_INTERPOLATION_LINEAR:
+ amount = (sqrt(r) - inner_radius) / double_feather;
+ break;
+ case FALLOFF_SQRT:
+ amount = (outer_radius - sqrt(r)) / double_feather;
+ amount = 1.0 - sqrt(amount);
+ break;
+ case FALLOFF_SIGMOND:
+ default:
+ amount = (outer_radius - sqrt(r)) / double_feather;
+ amount = 1.0 - ( 1.0/( 1 + exp(-(amount*10-5)) ) );
+ break;
+ }*/
+
+ Real amount = func(cache,r);
+
+ if(amount<0.0)amount=0.0;
+ if(amount>1.0)amount=1.0;
+
+ amount*=get_amount();
+
+ (*surface)[j][i]=Color::blend(color,background[j-offset_y][i-offset_x],amount,get_blend_method());
+ }else if(get_amount() != 1 || get_blend_method() != Color::BLEND_STRAIGHT)
+ {
+ (*surface)[j][i]=Color::blend(color,background[j][i],get_amount(),get_blend_method());
+ }
+ }
+ }
+ }
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
+
+Rect
+Circle::get_bounding_rect()const
+{
+ if(invert)
+ return Rect::full_plane();
+
+ Rect bounds(
+ pos[0]+(radius+feather),
+ pos[1]+(radius+feather),
+ pos[0]-(radius+feather),
+ pos[1]-(radius+feather)
+ );
+
+ return bounds;
+}
+
+Rect
+Circle::get_full_bounding_rect(Context context)const
+{
+ if(invert)
+ {
+ if(is_solid_color() && color.get_a()==0)
+ {
+ Rect bounds(
+ pos[0]+(radius+feather),
+ pos[1]+(radius+feather),
+ pos[0]-(radius+feather),
+ pos[1]-(radius+feather)
+ );
+ return bounds & context.get_full_bounding_rect();
+ }
+ return Rect::full_plane();
+ }
+
+ return Layer_Composite::get_full_bounding_rect(context);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file circle.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifndef __SYNFIG_LAYER_CIRCLE_H__
+#define __SYNFIG_LAYER_CIRCLE_H__
+
+/* -- H E A D E R S --------------------------------------------------------- */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* -- M A C R O S ----------------------------------------------------------- */
+
+/* -- T Y P E D E F S ------------------------------------------------------- */
+
+/* -- S T R U C T S & C L A S S E S ----------------------------------------- */
+
+class Circle : public synfig::Layer_Composite, public synfig::Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+private:
+ synfig::Color color;
+ synfig::Point pos;
+ synfig::Real radius;
+ synfig::Real feather;
+ bool invert;
+ int falloff;
+
+ //Caching system for circle
+ struct CircleDataCache
+ {
+ Real inner_radius;
+ Real outer_radius;
+
+ Real inner_radius_sqd;
+ Real outer_radius_sqd;
+
+ Real diff_sqd;
+ Real double_feather;
+ };
+
+ typedef Real FALLOFF_FUNC(const CircleDataCache &c, const Real &mag_sqd);
+
+ FALLOFF_FUNC *falloff_func;
+ CircleDataCache cache;
+
+ void constructcache();
+
+ static Real SqdFalloff(const CircleDataCache &c, const Real &mag_sqd);
+ static Real InvSqdFalloff(const CircleDataCache &c, const Real &mag_sqd);
+ static Real SqrtFalloff(const CircleDataCache &c, const Real &mag_sqd);
+ static Real InvSqrtFalloff(const CircleDataCache &c, const Real &mag_sqd);
+ static Real LinearFalloff(const CircleDataCache &c, const Real &mag_sqd);
+ static Real InvLinearFalloff(const CircleDataCache &c, const Real &mag_sqd);
+ static Real SigmondFalloff(const CircleDataCache &c, const Real &mag_sqd);
+ static Real InvSigmondFalloff(const CircleDataCache &c, const Real &mag_sqd);
+ static Real CosineFalloff(const CircleDataCache &c, const Real &mag_sqd);
+ static Real InvCosineFalloff(const CircleDataCache &c, const Real &mag_sqd);
+
+ FALLOFF_FUNC *GetFalloffFunc()const;
+ bool ImportParameters(const String ¶m, const ValueBase &value);
+
+public:
+ enum Falloff
+ {
+ FALLOFF_SQUARED =0,
+ FALLOFF_INTERPOLATION_LINEAR =1,
+ FALLOFF_SMOOTH =2,
+ FALLOFF_COSINE =2,
+ FALLOFF_SIGMOND =3,
+ FALLOFF_SQRT =4
+ };
+
+ Circle();
+
+ virtual bool set_param(const String ¶m, const ValueBase &value);
+
+ virtual ValueBase get_param(const String ¶m)const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+
+ virtual synfig::Rect get_full_bounding_rect(synfig::Context context)const;
+ virtual synfig::Rect get_bounding_rect()const;
+
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual Vocab get_param_vocab()const;
+};
+
+/* -- E X T E R N S --------------------------------------------------------- */
+
+
+/* -- E N D ----------------------------------------------------------------- */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_geometry/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include <synfig/string.h>
+#include <synfig/canvas.h>
+
+#include "checkerboard.h"
+#include "circle.h"
+#include "region.h"
+#include "outline.h"
+#include "star.h"
+#include "rectangle.h"
+
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(libmod_geometry)
+ MODULE_NAME("Geometry")
+ MODULE_DESCRIPTION("writeme")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(libmod_geometry)
+ BEGIN_LAYERS
+ LAYER(CheckerBoard)
+ LAYER(Circle)
+ LAYER(Region)
+ LAYER(Outline)
+ LAYER(Star)
+ LAYER(Rectangle)
+
+ LAYER_ALIAS(Outline,"BLine")
+ LAYER_ALIAS(Outline,"Bezier")
+ LAYER_ALIAS(Region,"Region")
+ LAYER_ALIAS(Circle,"Circle")
+ LAYER_ALIAS(CheckerBoard,"CheckerBoard")
+
+ END_LAYERS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_geometry" Sec_mod_geometry
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_geometry.dll "src\modules\mod_geometry\.libs\libmod_geometry-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_geometry"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file outline.cpp
+** \brief Template
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+//! \note This whole file should be rewritten at some point (darco)
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "outline.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#include <ETL/calculus>
+#include <ETL/bezier>
+#include <ETL/hermite>
+#include <vector>
+
+#include <synfig/valuenode_bline.h>
+
+#endif
+
+using namespace etl;
+
+/* === M A C R O S ========================================================= */
+
+#define SAMPLES 50
+#define ROUND_END_FACTOR (4)
+#define CUSP_THRESHOLD (0.40)
+#define SPIKE_AMOUNT (4)
+#define NO_LOOP_COOKIE synfig::Vector(84951305,7836658)
+#define EPSILON (0.000000001)
+#define CUSP_TANGENT_ADJUST (0.025)
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Outline);
+SYNFIG_LAYER_SET_NAME(Outline,"outline");
+SYNFIG_LAYER_SET_LOCAL_NAME(Outline,_("Outline"));
+SYNFIG_LAYER_SET_CATEGORY(Outline,_("Geometry"));
+SYNFIG_LAYER_SET_VERSION(Outline,"0.2");
+SYNFIG_LAYER_SET_CVS_ID(Outline,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+// This function was adapted from what was
+// described on http://www.whisqu.se/per/docs/math28.htm
+Point line_intersection(
+ const Point& p1,
+ const Vector& t1,
+ const Point& p2,
+ const Vector& t2
+)
+{
+ const float& x0(p1[0]);
+ const float& y0(p1[1]);
+
+ const float x1(p1[0]+t1[0]);
+ const float y1(p1[1]+t1[1]);
+
+ const float& x2(p2[0]);
+ const float& y2(p2[1]);
+
+ const float x3(p2[0]+t2[0]);
+ const float y3(p2[1]+t2[1]);
+
+ const float near_infinity((float)1e+10);
+
+ float m1,m2; // the slopes of each line
+
+ // compute slopes, note the cludge for infinity, however, this will
+ // be close enough
+
+ if ((x1-x0)!=0)
+ m1 = (y1-y0)/(x1-x0);
+ else
+ m1 = near_infinity;
+
+ if ((x3-x2)!=0)
+ m2 = (y3-y2)/(x3-x2);
+ else
+ m2 = near_infinity;
+
+ // compute constants
+ const float& a1(m1);
+ const float& a2(m2);
+ const float b1(-1.0f);
+ const float b2(-1.0f);
+ const float c1(y0-m1*x0);
+ const float c2(y2-m2*x2);
+
+ // compute the inverse of the determinate
+ const float det_inv(1.0f/(a1*b2 - a2*b1));
+
+ // use Kramers rule to compute the intersection
+ return Point(
+ ((b1*c2 - b2*c1)*det_inv),
+ ((a2*c1 - a1*c2)*det_inv)
+ );
+} // end Intersect_Lines
+
+/* === M E T H O D S ======================================================= */
+
+
+Outline::Outline()
+{
+ old_version=false;
+ round_tip[0]=true;
+ round_tip[1]=true;
+ sharp_cusps=true;
+ width=1.0f;
+ loopyness=1.0f;
+ expand=0;
+ homogeneous_width=true;
+ clear();
+
+ vector<BLinePoint> bline_point_list;
+ bline_point_list.push_back(BLinePoint());
+ bline_point_list.push_back(BLinePoint());
+ bline_point_list.push_back(BLinePoint());
+ bline_point_list[0].set_vertex(Point(0,1));
+ bline_point_list[1].set_vertex(Point(0,-1));
+ bline_point_list[2].set_vertex(Point(1,0));
+ bline_point_list[0].set_tangent(bline_point_list[1].get_vertex()-bline_point_list[2].get_vertex()*0.5f);
+ bline_point_list[1].set_tangent(bline_point_list[2].get_vertex()-bline_point_list[0].get_vertex()*0.5f);
+ bline_point_list[2].set_tangent(bline_point_list[0].get_vertex()-bline_point_list[1].get_vertex()*0.5f);
+ bline_point_list[0].set_width(1.0f);
+ bline_point_list[1].set_width(1.0f);
+ bline_point_list[2].set_width(1.0f);
+ bline=bline_point_list;
+
+ needs_sync=true;
+}
+
+
+/*! The Sync() function takes the values
+** and creates a polygon to be rendered
+** with the polygon layer.
+*/
+void
+Outline::sync()
+{
+ clear();
+
+ if (!bline.get_list().size())
+ {
+ synfig::warning(string("Outline::sync():")+_("No verticies in outline " + string("\"") + get_description() + string("\"")));
+ return;
+ }
+
+ try {
+#if 1
+
+ const bool loop(bline.get_loop());
+ const vector<synfig::BLinePoint> bline_(bline.get_list().begin(),bline.get_list().end());
+#define bline bline_
+
+ vector<BLinePoint>::const_iterator
+ iter,
+ next(bline.begin());
+
+ const vector<BLinePoint>::const_iterator
+ end(bline.end());
+
+ vector<Point>
+ side_a,
+ side_b;
+
+ if(loop)
+ iter=--bline.end();
+ else
+ iter=next++;
+
+ // iter next
+ // ---- ----
+ // looped nth 1st
+ // !looped 1st 2nd
+
+ Vector first_tangent=bline.front().get_tangent2();
+ Vector last_tangent=iter->get_tangent1();
+
+ // if we are looped and drawing sharp cusps, we'll need a value for the incoming tangent
+ if (loop && sharp_cusps && last_tangent.is_equal_to(Vector::zero()))
+ {
+ hermite<Vector> curve((iter-1)->get_vertex(), iter->get_vertex(), (iter-1)->get_tangent2(), iter->get_tangent1());
+ const derivative< hermite<Vector> > deriv(curve);
+ last_tangent=deriv(1.0-CUSP_TANGENT_ADJUST);
+ }
+
+ // `first' is for making the cusps; don't do that for the first point if we're not looped
+ for(bool first=!loop; next!=end; iter=next++)
+ {
+ Vector prev_t(iter->get_tangent1());
+ Vector iter_t(iter->get_tangent2());
+ Vector next_t(next->get_tangent1());
+
+ bool split_flag(iter->get_split_tangent_flag());
+
+ // if iter.t2 == 0 and next.t1 == 0, this is a straight line
+ if(iter_t.is_equal_to(Vector::zero()) && next_t.is_equal_to(Vector::zero()))
+ {
+ iter_t=next_t=next->get_vertex()-iter->get_vertex();
+ // split_flag=true;
+
+ // if the two points are on top of each other, ignore this segment
+ // leave `first' true if was before
+ if (iter_t.is_equal_to(Vector::zero()))
+ continue;
+ }
+
+ // Setup the curve
+ hermite<Vector> curve(
+ iter->get_vertex(),
+ next->get_vertex(),
+ iter_t,
+ next_t
+ );
+
+ const float
+ iter_w((iter->get_width()*width)*0.5f+expand),
+ next_w((next->get_width()*width)*0.5f+expand);
+
+ const derivative< hermite<Vector> > deriv(curve);
+
+ if (first)
+ first_tangent = deriv(CUSP_TANGENT_ADJUST);
+
+ // Make cusps as necessary
+ if(!first && sharp_cusps && split_flag && (!prev_t.is_equal_to(iter_t) || iter_t.is_equal_to(Vector::zero())) && !last_tangent.is_equal_to(Vector::zero()))
+ {
+ Vector curr_tangent(deriv(CUSP_TANGENT_ADJUST));
+
+ const Vector t1(last_tangent.perp().norm());
+ const Vector t2(curr_tangent.perp().norm());
+
+ Real cross(t1*t2.perp());
+ Real perp((t1-t2).mag());
+ if(cross>CUSP_THRESHOLD)
+ {
+ const Point p1(iter->get_vertex()+t1*iter_w);
+ const Point p2(iter->get_vertex()+t2*iter_w);
+
+ side_a.push_back(line_intersection(p1,last_tangent,p2,curr_tangent));
+ }
+ else if(cross<-CUSP_THRESHOLD)
+ {
+ const Point p1(iter->get_vertex()-t1*iter_w);
+ const Point p2(iter->get_vertex()-t2*iter_w);
+
+ side_b.push_back(line_intersection(p1,last_tangent,p2,curr_tangent));
+ }
+ else if(cross>0 && perp>1)
+ {
+ float amount(max(0.0f,(float)(cross/CUSP_THRESHOLD))*(SPIKE_AMOUNT-1)+1);
+
+ side_a.push_back(iter->get_vertex()+(t1+t2).norm()*iter_w*amount);
+ }
+ else if(cross<0 && perp>1)
+ {
+ float amount(max(0.0f,(float)(-cross/CUSP_THRESHOLD))*(SPIKE_AMOUNT-1)+1);
+
+ side_b.push_back(iter->get_vertex()-(t1+t2).norm()*iter_w*amount);
+ }
+ }
+
+ // Make the outline
+ if(homogeneous_width)
+ {
+ const float length(curve.length());
+ float dist(0);
+ Point lastpoint;
+ for(float n=0.0f;n<0.999999f;n+=1.0f/SAMPLES)
+ {
+ const Vector d(deriv(n>CUSP_TANGENT_ADJUST?n:CUSP_TANGENT_ADJUST).perp().norm());
+ const Vector p(curve(n));
+
+ if(n)
+ dist+=(p-lastpoint).mag();
+
+ const float w(((next_w-iter_w)*(dist/length)+iter_w));
+
+ side_a.push_back(p+d*w);
+ side_b.push_back(p-d*w);
+
+ lastpoint=p;
+ }
+ }
+ else
+ for(float n=0.0f;n<0.999999f;n+=1.0f/SAMPLES)
+ {
+ const Vector d(deriv(n>CUSP_TANGENT_ADJUST?n:CUSP_TANGENT_ADJUST).perp().norm());
+ const Vector p(curve(n));
+ const float w(((next_w-iter_w)*n+iter_w));
+
+ side_a.push_back(p+d*w);
+ side_b.push_back(p-d*w);
+ }
+ last_tangent=deriv(1.0-CUSP_TANGENT_ADJUST);
+ side_a.push_back(curve(1.0)+last_tangent.perp().norm()*next_w);
+ side_b.push_back(curve(1.0)-last_tangent.perp().norm()*next_w);
+
+ first=false;
+ }
+
+ if(loop)
+ {
+ reverse(side_b.begin(),side_b.end());
+ add_polygon(side_a);
+ add_polygon(side_b);
+ return;
+ }
+
+ // Insert code for adding end tip
+ if(round_tip[1] && !loop && side_a.size())
+ {
+ // remove the last point
+ side_a.pop_back();
+
+ const Point vertex(bline.back().get_vertex());
+ const Vector tangent(last_tangent.norm());
+ const float w((bline.back().get_width()*width)*0.5f+expand);
+
+ hermite<Vector> curve(
+ vertex+tangent.perp()*w,
+ vertex-tangent.perp()*w,
+ tangent*w*ROUND_END_FACTOR,
+ -tangent*w*ROUND_END_FACTOR
+ );
+
+ for(float n=0.0f;n<0.999999f;n+=1.0f/SAMPLES)
+ side_a.push_back(curve(n));
+ }
+
+ for(;!side_b.empty();side_b.pop_back())
+ side_a.push_back(side_b.back());
+
+ // Insert code for adding begin tip
+ if(round_tip[0] && !loop && side_a.size())
+ {
+ // remove the last point
+ side_a.pop_back();
+
+ const Point vertex(bline.front().get_vertex());
+ const Vector tangent(first_tangent.norm());
+ const float w((bline.front().get_width()*width)*0.5f+expand);
+
+ hermite<Vector> curve(
+ vertex-tangent.perp()*w,
+ vertex+tangent.perp()*w,
+ -tangent*w*ROUND_END_FACTOR,
+ tangent*w*ROUND_END_FACTOR
+ );
+
+ for(float n=0.0f;n<0.999999f;n+=1.0f/SAMPLES)
+ side_a.push_back(curve(n));
+ }
+
+ add_polygon(side_a);
+
+
+#else /* 1 */
+
+ bool loop_;
+ if(bline.get_contained_type()==ValueBase::TYPE_BLINEPOINT)
+ {
+ ValueBase value(bline);
+
+ if(loopyness<0.5f)
+ {
+ value.set_loop(false);
+ loop_=false;
+ }
+ else
+ loop_=value.get_loop();
+
+ segment_list=convert_bline_to_segment_list(value);
+ width_list=convert_bline_to_width_list(value);
+ }
+ else
+ {
+ clear();
+ return;
+ }
+
+
+
+ if(segment_list.empty())
+ {
+ synfig::warning("Outline: segment_list is empty, layer disabled");
+ clear();
+ return;
+ }
+
+
+ // Repair the width list if we need to
+ {
+ Real default_width;
+ if(width_list.empty())
+ default_width=0.01;
+ else
+ default_width=width_list.back();
+
+ while(width_list.size()<segment_list.size()+1)
+ width_list.push_back(default_width);
+ while(width_list.size()>segment_list.size()+1)
+ width_list.pop_back();
+
+ }
+
+ // Repair the zero tangents (if any)
+ {
+ vector<Segment>::iterator iter;
+ for(iter=segment_list.begin();iter!=segment_list.end();++iter)
+ {
+ if(iter->t1.mag_squared()<=EPSILON && iter->t2.mag_squared()<=EPSILON)
+ iter->t1=iter->t2=iter->p2-iter->p1;
+ }
+ }
+
+ vector<Real>::iterator iter;
+ vector<Real> scaled_width_list;
+ for(iter=width_list.begin();iter!=width_list.end();++iter)
+ {
+ scaled_width_list.push_back((*iter*width+expand)*0.5f);
+ }
+
+ Vector::value_type n;
+ etl::hermite<Vector> curve;
+ vector<Point> vector_list;
+ Vector last_tangent(segment_list.back().t2);
+ clear();
+
+ if(!loop_)
+ last_tangent=NO_LOOP_COOKIE;
+
+ {
+ vector<Segment>::iterator iter;
+ vector<Real>::iterator witer;
+ for(
+ iter=segment_list.begin(),
+ witer=scaled_width_list.begin();
+ iter!=segment_list.end();
+ ++iter,++witer)
+ {
+ if(iter->t1.mag_squared()<=EPSILON && iter->t2.mag_squared()<=EPSILON)
+ {
+ vector_list.push_back(iter->p1-(iter->p2-iter->p1).perp().norm()*witer[0]);
+ vector_list.push_back((iter->p2-iter->p1)*0.05+iter->p1-(iter->p2-iter->p1).perp().norm()*((witer[1]-witer[0])*0.05+witer[0]));
+ vector_list.push_back((iter->p2-iter->p1)*0.95+iter->p1-(iter->p2-iter->p1).perp().norm()*((witer[1]-witer[0])*0.95+witer[0]));
+ vector_list.push_back(iter->p2-(iter->p2-iter->p1).perp().norm()*witer[1]);
+ }
+ else
+ {
+ curve.p1()=iter->p1;
+ curve.t1()=iter->t1;
+ curve.p2()=iter->p2;
+ curve.t2()=iter->t2;
+ curve.sync();
+
+ etl::derivative<etl::hermite<Vector> > deriv(curve);
+
+ // without this if statement, the broken tangents would
+ // have boxed edges
+ if(sharp_cusps && last_tangent!=NO_LOOP_COOKIE && !last_tangent.is_equal_to(iter->t1))
+ {
+ //Vector curr_tangent(iter->t1);
+ Vector curr_tangent(deriv(CUSP_TANGENT_ADJUST));
+
+ const Vector t1(last_tangent.perp().norm());
+ const Vector t2(curr_tangent.perp().norm());
+
+ Point p1(iter->p1+t1*witer[0]);
+ Point p2(iter->p1+t2*witer[0]);
+
+ Real cross(t1*t2.perp());
+
+ if(cross>CUSP_THRESHOLD)
+ vector_list.push_back(line_intersection(p1,last_tangent,p2,curr_tangent));
+ else if(cross>0)
+ {
+ float amount(max(0.0f,(float)(cross/CUSP_THRESHOLD))*(SPIKE_AMOUNT-1)+1);
+ // Push back something to make it look vaguely round;
+ //vector_list.push_back(iter->p1+(t1*1.25+t2).norm()*witer[0]*amount);
+ vector_list.push_back(iter->p1+(t1+t2).norm()*witer[0]*amount);
+ //vector_list.push_back(iter->p1+(t1+t2*1.25).norm()*witer[0]*amount);
+ }
+ }
+ //last_tangent=iter->t2;
+ last_tangent=deriv(1.0f-CUSP_TANGENT_ADJUST);
+
+ for(n=0.0f;n<1.0f;n+=1.0f/SAMPLES)
+ vector_list.push_back(curve(n)+deriv(n>CUSP_TANGENT_ADJUST?n:CUSP_TANGENT_ADJUST).perp().norm()*((witer[1]-witer[0])*n+witer[0]) );
+ vector_list.push_back(curve(1.0)+deriv(1.0-CUSP_TANGENT_ADJUST).perp().norm()*witer[1]);
+
+ }
+ }
+ if(round_tip[1] && !loop_/* && (!sharp_cusps || segment_list.front().p1!=segment_list.back().p2)*/)
+ {
+ // remove the last point
+ vector_list.pop_back();
+
+ iter--;
+
+ curve.p1()=iter->p2+Vector(last_tangent[1],-last_tangent[0]).norm()*(*witer);
+ curve.p2()=iter->p2-(Vector(last_tangent[1],-last_tangent[0]).norm()*(*witer));
+ curve.t2()=-(curve.t1()=last_tangent/last_tangent.mag()*(*witer)*ROUND_END_FACTOR);
+ curve.sync();
+ for(n=0.0f;n<1.0f;n+=1.0f/SAMPLES)
+ vector_list.push_back(curve(n));
+
+ // remove the last point
+ vector_list.pop_back();
+ }
+ }
+
+ if(!loop_)
+ last_tangent=NO_LOOP_COOKIE;
+ else
+ {
+ add_polygon(vector_list);
+ vector_list.clear();
+ last_tangent=segment_list.front().t1;
+ }
+
+ //else
+ // last_tangent=segment_list.back().t2;
+
+ {
+ vector<Segment>::reverse_iterator iter;
+ vector<Real>::reverse_iterator witer;
+ for(
+ iter=segment_list.rbegin(),
+ witer=scaled_width_list.rbegin(),++witer;
+ !(iter==segment_list.rend());
+ ++iter,++witer)
+ {
+
+ if(iter->t1.mag_squared()<=EPSILON && iter->t2.mag_squared()<=EPSILON)
+ {
+ vector_list.push_back(iter->p2+(iter->p2-iter->p1).perp().norm()*witer[0]);
+ vector_list.push_back((iter->p2-iter->p1)*0.95+iter->p1+(iter->p2-iter->p1).perp().norm()*((witer[-1]-witer[0])*0.95+witer[0]));
+ vector_list.push_back((iter->p2-iter->p1)*0.05+iter->p1+(iter->p2-iter->p1).perp().norm()*((witer[-1]-witer[0])*0.05+witer[0]));
+ vector_list.push_back(iter->p1+(iter->p2-iter->p1).perp().norm()*witer[-1]);
+ }
+ else
+ {
+ curve.p1()=iter->p1;
+ curve.t1()=iter->t1;
+ curve.p2()=iter->p2;
+ curve.t2()=iter->t2;
+ curve.sync();
+
+ etl::derivative<etl::hermite<Vector> > deriv(curve);
+
+ // without this if statement, the broken tangents would
+ // have boxed edges
+ if(sharp_cusps && last_tangent!=NO_LOOP_COOKIE && !last_tangent.is_equal_to(iter->t2))
+ {
+ //Vector curr_tangent(iter->t2);
+ Vector curr_tangent(deriv(1.0f-CUSP_TANGENT_ADJUST));
+
+ const Vector t1(last_tangent.perp().norm());
+ const Vector t2(curr_tangent.perp().norm());
+
+ Point p1(iter->p2-t1*witer[-1]);
+ Point p2(iter->p2-t2*witer[-1]);
+
+ Real cross(t1*t2.perp());
+
+ //if(last_tangent.perp().norm()*curr_tangent.norm()<-CUSP_THRESHOLD)
+ if(cross>CUSP_THRESHOLD)
+ vector_list.push_back(line_intersection(p1,last_tangent,p2,curr_tangent));
+ else if(cross>0)
+ {
+ float amount(max(0.0f,(float)(cross/CUSP_THRESHOLD))*(SPIKE_AMOUNT-1)+1);
+ // Push back something to make it look vaguely round;
+ //vector_list.push_back(iter->p2-(t1*1.25+t2).norm()*witer[-1]*amount);
+ vector_list.push_back(iter->p2-(t1+t2).norm()*witer[-1]*amount);
+ //vector_list.push_back(iter->p2-(t1+t2*1.25).norm()*witer[-1]*amount);
+ }
+ }
+ //last_tangent=iter->t1;
+ last_tangent=deriv(CUSP_TANGENT_ADJUST);
+
+ for(n=1.0f;n>CUSP_TANGENT_ADJUST;n-=1.0f/SAMPLES)
+ vector_list.push_back(curve(n)-deriv(1-n>CUSP_TANGENT_ADJUST?n:1-CUSP_TANGENT_ADJUST).perp().norm()*((witer[-1]-witer[0])*n+witer[0]) );
+ vector_list.push_back(curve(0.0f)-deriv(CUSP_TANGENT_ADJUST).perp().norm()*witer[0]);
+ }
+ }
+ if(round_tip[0] && !loop_/* && (!sharp_cusps || segment_list.front().p1!=segment_list.back().p2)*/)
+ {
+ // remove the last point
+ vector_list.pop_back();
+ iter--;
+ witer--;
+
+ curve.p1()=iter->p1+Vector(last_tangent[1],-last_tangent[0]).norm()*(*witer);
+ curve.p2()=iter->p1-(Vector(last_tangent[1],-last_tangent[0]).norm()*(*witer));
+ curve.t1()=-(curve.t2()=last_tangent/last_tangent.mag()*(*witer)*ROUND_END_FACTOR);
+ curve.sync();
+
+ for(n=1.0;n>0.0;n-=1.0/SAMPLES)
+ vector_list.push_back(curve(n));
+
+ // remove the last point
+ vector_list.pop_back();
+ }
+ }
+
+ //if(loop_)
+ // reverse(vector_list.begin(),vector_list.end());
+
+#ifdef _DEBUG
+ {
+ vector<Point>::iterator iter;
+ for(iter=vector_list.begin();iter!=vector_list.end();++iter)
+ if(!iter->is_valid())
+ {
+ synfig::error("Outline::sync(): Bad point in vector_list!");
+ }
+ //synfig::info("BLEHH__________--- x:%f, y:%f",vector_list.front()[0],vector_list.front()[1]);
+ }
+#endif /* _DEBUG */
+
+ add_polygon(vector_list);
+
+
+#endif /* 1 */
+ } catch (...) { synfig::error("Outline::sync(): Exception thrown"); throw; }
+}
+
+#undef bline
+
+bool
+Outline::set_param(const String & param, const ValueBase &value)
+{
+ if(param=="segment_list")
+ {
+ if(dynamic_param_list().count("segment_list"))
+ {
+ connect_dynamic_param("bline",dynamic_param_list().find("segment_list")->second);
+ disconnect_dynamic_param("segment_list");
+ synfig::warning("Outline::set_param(): Updated valuenode connection to use the new \"bline\" parameter.");
+ }
+ else
+ synfig::warning("Outline::set_param(): The parameter \"segment_list\" is deprecated. Use \"bline\" instead.");
+ }
+
+ if( (param=="segment_list" || param=="bline") && value.get_type()==ValueBase::TYPE_LIST)
+ {
+ //if(value.get_contained_type()!=ValueBase::TYPE_BLINEPOINT)
+ // return false;
+
+ bline=value;
+
+ return true;
+ }
+ /*
+ if( param=="seg" && value.get_type()==ValueBase::TYPE_SEGMENT)
+ {
+ if(!segment_list.empty())
+ segment_list.clear();
+
+ segment_list.push_back(value.get(Segment()));
+ loop_=false;
+ //sync();
+ return true;
+ }
+ if( param=="w[0]" && value.get_type()==ValueBase::TYPE_REAL)
+ {
+ if(width_list.size()<2)
+ {
+ width_list.push_back(value.get(Real()));
+ width_list.push_back(value.get(Real()));
+ }
+ else
+ {
+ width_list[0]=value.get(Real());
+ }
+ width=1;
+ //sync();
+ return true;
+ }
+
+ if( param=="w[1]" && value.get_type()==ValueBase::TYPE_REAL)
+ {
+ if(width_list.size()<2)
+ {
+ width_list.push_back(value.get(Real()));
+ width_list.push_back(value.get(Real()));
+ }
+ else
+ {
+ width_list[1]=value.get(Real());
+ }
+ width=1;
+ //sync();
+ return true;
+ }
+
+ if( param=="width_list" && value.same_type_as(width_list))
+ {
+ width_list=value;
+ //sync();
+ return true;
+ }
+ */
+
+ IMPORT(round_tip[0]);
+ IMPORT(round_tip[1]);
+ IMPORT(sharp_cusps);
+ IMPORT_PLUS(width,if(old_version){width*=2.0;});
+ IMPORT(loopyness);
+ IMPORT(expand);
+ IMPORT(homogeneous_width);
+
+ if(param!="vector_list")
+ return Layer_Polygon::set_param(param,value);
+
+ return false;
+}
+
+void
+Outline::set_time(Context context, Time time)const
+{
+ const_cast<Outline*>(this)->sync();
+ context.set_time(time);
+}
+
+void
+Outline::set_time(Context context, Time time, Vector pos)const
+{
+ const_cast<Outline*>(this)->sync();
+ context.set_time(time,pos);
+}
+
+ValueBase
+Outline::get_param(const String& param)const
+{
+ EXPORT(bline);
+ EXPORT(expand);
+ //EXPORT(width_list);
+ //EXPORT(segment_list);
+ EXPORT(homogeneous_width);
+ EXPORT(round_tip[0]);
+ EXPORT(round_tip[1]);
+ EXPORT(sharp_cusps);
+ EXPORT(width);
+ EXPORT(loopyness);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ if(param!="vector_list")
+ return Layer_Polygon::get_param(param);
+ return ValueBase();
+}
+
+Layer::Vocab
+Outline::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Polygon::get_param_vocab());
+
+ // Pop off the polygon parameter from the polygon vocab
+ ret.pop_back();
+
+ ret.push_back(ParamDesc("bline")
+ .set_local_name(_("Vertices"))
+ .set_origin("offset")
+ .set_scalar("width")
+ .set_description(_("A list of BLine Points"))
+ );
+
+ /*
+ ret.push_back(ParamDesc("width_list")
+ .set_local_name(_("Point Widths"))
+ .set_origin("segment_list")
+ .hidden()
+ .not_critical()
+ );
+ */
+
+ ret.push_back(ParamDesc("width")
+ .set_is_distance()
+ .set_local_name(_("Outline Width"))
+ );
+
+ ret.push_back(ParamDesc("expand")
+ .set_is_distance()
+ .set_local_name(_("Expand"))
+ );
+
+ ret.push_back(ParamDesc("sharp_cusps")
+ .set_local_name(_("Sharp Cusps"))
+ .set_description(_("Determines cusp type"))
+ );
+
+ ret.push_back(ParamDesc("round_tip[0]")
+ .set_local_name(_("Rounded Begin"))
+ .set_description(_("Round off the tip"))
+ );
+
+ ret.push_back(ParamDesc("round_tip[1]")
+ .set_local_name(_("Rounded End"))
+ .set_description(_("Round off the tip"))
+ );
+ ret.push_back(ParamDesc("loopyness")
+ .set_local_name(_("Loopyness"))
+ );
+ ret.push_back(ParamDesc("homogeneous_width")
+ .set_local_name(_("Homogeneous"))
+ );
+
+ return ret;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file outline.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_OUTLINE_H
+#define __SYNFIG_OUTLINE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <list>
+#include <vector>
+#include <synfig/layer_polygon.h>
+#include <synfig/segment.h>
+#include <synfig/value.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class Outline : public synfig::Layer_Polygon
+{
+ SYNFIG_LAYER_MODULE_EXT
+private:
+
+ synfig::ValueBase bline;
+
+ std::vector<synfig::Segment> segment_list;
+ std::vector<synfig::Real> width_list;
+
+ bool round_tip[2];
+
+ bool sharp_cusps;
+
+ bool loop_;
+
+ synfig::Real width;
+
+ synfig::Real expand;
+
+ Real loopyness;
+ bool old_version;
+
+ bool needs_sync;
+
+ bool homogeneous_width;
+
+public:
+
+ Outline();
+
+ //! Updates the polygon data to match the parameters.
+ void sync();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Vocab get_param_vocab()const;
+ virtual void set_time(Context context, Time time)const;
+ virtual void set_time(Context context, Time time, Vector pos)const;
+ virtual bool set_version(const String &ver){if(ver=="0.1")old_version=true; return true;}
+ virtual void reset_version(){old_version=false;}
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file rectangle.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <ETL/pen>
+#include <ETL/misc>
+
+#include "rectangle.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Rectangle);
+SYNFIG_LAYER_SET_NAME(Rectangle,"rectangle");
+SYNFIG_LAYER_SET_LOCAL_NAME(Rectangle,_("Rectangle"));
+SYNFIG_LAYER_SET_CATEGORY(Rectangle,_("Geometry"));
+SYNFIG_LAYER_SET_VERSION(Rectangle,"0.2");
+SYNFIG_LAYER_SET_CVS_ID(Rectangle,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/*
+inline int ceil_to_int(const float x) { return static_cast<int>(ceil(x)); }
+inline int ceil_to_int(const double x) { return static_cast<int>(ceil(x)); }
+
+inline int floor_to_int(const float x) { return static_cast<int>(floor(x)); }
+inline int floor_to_int(const double x) { return static_cast<int>(floor(x)); }
+*/
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Rectangle::Rectangle():
+ Layer_Composite(1.0,Color::BLEND_STRAIGHT),
+ color(Color::black()),
+ point1(0,0),
+ point2(1,1),
+ expand(0),
+ invert(false)
+{
+}
+
+bool
+Rectangle::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(color);
+ IMPORT(point1);
+ IMPORT(point2);
+ IMPORT(expand);
+ IMPORT(invert);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+Rectangle::get_param(const String ¶m)const
+{
+ EXPORT(color);
+ EXPORT(point1);
+ EXPORT(point2);
+ EXPORT(expand);
+ EXPORT(invert);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+Rectangle::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("color")
+ .set_local_name(_("Color"))
+ );
+
+ ret.push_back(ParamDesc("point1")
+ .set_local_name(_("Point 1"))
+ .set_box("point2")
+ );
+
+ ret.push_back(ParamDesc("point2")
+ .set_local_name(_("Point 2"))
+ );
+
+ ret.push_back(ParamDesc("expand")
+ .set_is_distance()
+ .set_local_name(_("Expand amount"))
+ );
+
+ ret.push_back(ParamDesc("invert")
+ .set_local_name(_("Invert the rectangle"))
+ );
+
+ return ret;
+}
+
+synfig::Layer::Handle
+Rectangle::hit_check(synfig::Context context, const synfig::Point &pos)const
+{
+ if(is_disabled())
+ return context.hit_check(pos);
+
+ Point max,min;
+
+ max[0]=std::max(point1[0],point2[0])+expand;
+ max[1]=std::max(point1[1],point2[1])+expand;
+ min[0]=std::min(point1[0],point2[0])-expand;
+ min[1]=std::min(point1[1],point2[1])-expand;
+
+ bool intersect(false);
+
+ if( pos[0]<max[0] && pos[0]>min[0] &&
+ pos[1]<max[1] && pos[1]>min[1] )
+ {
+ intersect=true;
+ }
+
+ if(invert)
+ intersect=!intersect;
+
+ if(intersect)
+ {
+ synfig::Layer::Handle tmp;
+ if(get_blend_method()==Color::BLEND_BEHIND && (tmp=context.hit_check(pos)))
+ return tmp;
+ if(Color::is_onto(get_blend_method()) && !(tmp=context.hit_check(pos)))
+ return 0;
+ return const_cast<Rectangle*>(this);
+ }
+
+ return context.hit_check(pos);
+}
+
+bool
+Rectangle::is_solid_color()const
+{
+ return Layer_Composite::is_solid_color() ||
+ (get_blend_method() == Color::BLEND_COMPOSITE &&
+ get_amount() == 1.0f &&
+ color.get_a() == 1.0f);
+}
+
+Color
+Rectangle::get_color(Context context, const Point &pos)const
+{
+ if(is_disabled())
+ return context.get_color(pos);
+
+ Point max,min;
+
+ max[0]=std::max(point1[0],point2[0])+expand;
+ max[1]=std::max(point1[1],point2[1])+expand;
+ min[0]=std::min(point1[0],point2[0])-expand;
+ min[1]=std::min(point1[1],point2[1])-expand;
+
+/**************************
+// This is darco's old-old-old feathered box code
+// it produces really nice feathered edges
+ if(feather!=0.0)
+ {
+ if( pos[0]<=max[0]-feather/2.0 && pos[0]>=min[0]+feather/2.0 &&
+ pos[1]<=max[1]-feather/2.0 && pos[1]>=min[1]+feather/2.0 )
+ {
+ if(invert)
+ return (*context).GetColor(context,pos);
+ else
+ return color;
+ }
+
+ if( pos[0]>=max[0]+feather/2.0 || pos[0]<=min[0]-feather/2.0 ||
+ pos[1]>=max[1]+feather/2.0 || pos[1]<=min[1]-feather/2.0 )
+ {
+ if(invert)
+ return color;
+ else
+ return (*context).GetColor(context,pos);
+ }
+
+ Color::unit alpha=1000000;
+ Color::unit alpha2=1000000;
+
+ if(max[0]-pos[0]+feather/2.0<alpha)
+ alpha=max[0]-pos[0]+feather/2.0;
+ if(pos[0]-min[0]+feather/2.0<alpha)
+ alpha=pos[0]-min[0]+feather/2.0;
+
+ if(max[1]-pos[1]+feather/2.0<alpha2)
+ alpha2=max[1]-pos[1]+feather/2.0;
+ if(pos[1]-min[1]+feather/2.0<alpha2)
+ alpha2=pos[1]-min[1]+feather/2.0;
+
+
+ if(alpha<=feather && alpha2<=feather)
+ {
+ alpha=feather-alpha;
+ alpha2=feather-alpha2;
+
+ alpha=sqrt(alpha*alpha+alpha2*alpha2);
+
+ if(alpha>=feather)
+ {
+ if(invert)
+ return color;
+ else
+ return (*context).GetColor(context,pos);
+ }
+
+ alpha=feather-alpha;
+ }
+ else
+ {
+ alpha=(alpha<alpha2)?alpha:alpha2;
+ }
+
+ alpha/=feather;
+
+ if(invert)
+ alpha=1.0-alpha;
+
+ return Color::blend(color,context.get_color(pos),alpha,get_blend_method());
+ }
+
+*****************/
+
+ if( pos[0]<max[0] && pos[0]>min[0] &&
+ pos[1]<max[1] && pos[1]>min[1] )
+ {
+ if(invert)
+ return context.get_color(pos);
+ else
+ {
+ if(is_solid_color())
+ return color;
+ else
+ return Color::blend(color,context.get_color(pos),get_amount(),get_blend_method());
+
+ }
+ }
+
+ if(invert)
+ {
+ if(is_solid_color())
+ return color;
+ else
+ return Color::blend(color,context.get_color(pos),get_amount(),get_blend_method());
+ }
+
+ return context.get_color(pos);
+}
+
+bool
+Rectangle::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ if(is_disabled())
+ return context.accelerated_render(surface,quality,renddesc,cb);
+
+ const Point tl(renddesc.get_tl());
+ const Point br(renddesc.get_br());
+
+ const int w(renddesc.get_w());
+ const int h(renddesc.get_h());
+
+ // Width and Height of a pixel
+ const Real pw = (br[0] - tl[0]) / w;
+ const Real ph = (br[1] - tl[1]) / h;
+
+ Point max(point1),min(point2);
+
+
+
+
+ /*
+
+ if(invert)
+ {
+ max=context.get_bounding_rect().get_max();
+ min=context.get_bounding_rect().get_min();
+ }
+ else
+ {
+ max=context.get_full_bounding_rect().get_max();
+ min=context.get_full_bounding_rect().get_min();
+ }
+ */
+
+
+
+
+
+ if((min[0] > max[0]) ^ (pw < 0))swap(min[0],max[0]);
+ if((min[1] > max[1]) ^ (ph < 0))swap(min[1],max[1]);
+
+ if(min[0] > max[0])
+ {
+ min[0]+=expand;
+ max[0]-=expand;
+ }
+ else
+ {
+ min[0]-=expand;
+ max[0]+=expand;
+ }
+
+ if(min[1] > max[1])
+ {
+ min[1]+=expand;
+ max[1]-=expand;
+ }
+ else
+ {
+ min[1]-=expand;
+ max[1]+=expand;
+ }
+
+ if(invert)
+ {
+ int left(floor_to_int((min[0]-tl[0])/pw));
+ int right(ceil_to_int((max[0]-tl[0])/pw));
+ int top(floor_to_int((min[1]-tl[1])/ph));
+ int bottom(ceil_to_int((max[1]-tl[1])/ph));
+
+ float left_edge((min[0]-tl[0])/pw-float(left));
+ float right_edge(float(right)-(max[0]-tl[0])/pw);
+ float top_edge((min[1]-tl[1])/ph-float(top));
+ float bottom_edge(float(bottom)-(max[1]-tl[1])/ph);
+
+ if(top<0)top=0,top_edge=0;
+ if(left<0)left=0,left_edge=0;
+ if(bottom>h)bottom=h,bottom_edge=0;
+ if(right>w)right=w,right_edge=0;
+
+ if(is_solid_color())
+ {
+ Surface subimage;
+ RendDesc desc(renddesc);
+ desc.set_flags(0);
+
+ //fill the surface with the background color initially
+ surface->set_wh(w,h);
+ surface->fill(color);
+
+ // Check for the case where there is nothing to render
+ if (right <= left || bottom <= top)
+ return true;
+
+ desc.set_subwindow(left,top,right-left,bottom-top);
+
+ // Render what is behind us
+ if(!context.accelerated_render(&subimage,quality,desc,cb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ Surface::pen pen(surface->get_pen(left,top));
+
+ subimage.blit_to(pen);
+ }
+ else
+ {
+ if(!context.accelerated_render(surface,quality,renddesc,cb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ Surface subimage;
+
+ // Check for the case where there is something to render
+ if (right > left && bottom > top)
+ {
+ // save a copy of the overlapping region from surface into subimage
+ subimage.set_wh(right-left,bottom-top);
+ Surface::pen subimage_pen(subimage.begin());
+ surface->blit_to(subimage_pen,left,top,right-left,bottom-top);
+ }
+
+ // fill surface with the rectangle's colour
+ Surface::alpha_pen surface_pen(surface->begin(),get_amount(),get_blend_method());
+ surface->fill(color,surface_pen,w,h);
+
+ if (subimage)
+ {
+ // copy the saved overlapping region back from subimage into surface
+ Surface::pen pen(surface->get_pen(left,top));
+ subimage.blit_to(pen);
+ }
+ else
+ // if there's no overlapping region, return now of the following code corrupts memory
+ return true;
+ }
+
+ Surface::alpha_pen pen;
+
+ if(bottom-1>=0 && bottom_edge)
+ {
+ pen=Surface::alpha_pen(surface->get_pen(left,bottom-1),get_amount()*bottom_edge,get_blend_method());
+ surface->fill(color,pen,right-left,1);
+ }
+
+ if(right-1>=0 && right_edge)
+ {
+ pen=Surface::alpha_pen(surface->get_pen(right-1,top),get_amount()*right_edge,get_blend_method());
+ surface->fill(color,pen,1,bottom-top);
+ }
+
+ if(left>=0 && left_edge)
+ {
+ pen=Surface::alpha_pen(surface->get_pen(left,top),get_amount()*left_edge,get_blend_method());
+ surface->fill(color,pen,1,bottom-top);
+ }
+
+ if(top>=0 && top_edge)
+ {
+ pen=Surface::alpha_pen(surface->get_pen(left,top),get_amount()*top_edge,get_blend_method());
+ surface->fill(color,pen,right-left,1);
+ }
+
+ return true;
+ }
+
+ // not inverted
+
+ int left(ceil_to_int((min[0]-tl[0])/pw));
+ int right(floor_to_int((max[0]-tl[0])/pw));
+ int top(ceil_to_int((min[1]-tl[1])/ph));
+ int bottom(floor_to_int((max[1]-tl[1])/ph));
+
+ float left_edge(float(left)-(min[0]-tl[0])/pw);
+ float right_edge((max[0]-tl[0])/pw-float(right));
+ float top_edge(float(top)-(min[1]-tl[1])/ph);
+ float bottom_edge((max[1]-tl[1])/ph-float(bottom));
+
+ if(top<=0)top=0,top_edge=0;
+ if(left<=0)left=0,left_edge=0;
+ if(bottom>=h)bottom=h,bottom_edge=0;
+ if(right>=w)right=w,right_edge=0;
+
+/*
+ top = std::max(0,top);
+ left = std::max(0,left);
+ bottom = std::min(h,bottom);
+ right = std::min(w,right);
+*/
+
+ // optimisation - if the whole tile is covered by this rectangle,
+ // and the rectangle is a solid colour, we don't need to render
+ // what's behind us
+ if (is_solid_color() && top == 0 && left == 0 && bottom == h && right == w)
+ {
+ surface->set_wh(w,h);
+ surface->fill(color);
+ return true;
+ }
+
+ // Render what is behind us
+ if(!context.accelerated_render(surface,quality,renddesc,cb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+
+ // In the case where there is nothing to render...
+ if (right < left || bottom < top)
+ return true;
+
+ Surface::alpha_pen pen;
+
+ if(right-left>0&&bottom-top>0)
+ {
+ if(is_solid_color())
+ surface->fill(color,left,top,right-left,bottom-top);
+ else
+ {
+ pen=Surface::alpha_pen(surface->get_pen(left,top),get_amount(),get_blend_method());
+ surface->fill(color,pen,right-left,bottom-top);
+ }
+ }
+
+ if(bottom<surface->get_h() && bottom_edge>=0.0001)
+ {
+ pen=Surface::alpha_pen(surface->get_pen(left,bottom),get_amount()*bottom_edge,get_blend_method());
+ surface->fill(color,pen,right-left,1);
+ }
+
+ if(right<surface->get_w() && right_edge>=0.0001)
+ {
+ pen=Surface::alpha_pen(surface->get_pen(right,top),get_amount()*right_edge,get_blend_method());
+ surface->fill(color,pen,1,bottom-top);
+ }
+
+ if(left>0 && left_edge>=0.0001)
+ {
+ pen=Surface::alpha_pen(surface->get_pen(left-1,top),get_amount()*left_edge,get_blend_method());
+ surface->fill(color,pen,1,bottom-top);
+ }
+
+ if(top>0 && top_edge>=0.0001)
+ {
+ pen=Surface::alpha_pen(surface->get_pen(left,top-1),get_amount()*top_edge,get_blend_method());
+ surface->fill(color,pen,right-left,1);
+ }
+
+
+ return true;
+}
+
+Rect
+Rectangle::get_bounding_rect()const
+{
+ if(invert)
+ return Rect::full_plane();
+
+ Point max(point1),min(point2);
+ if((min[0] > max[0]))swap(min[0],max[0]);
+ if((min[1] > max[1]))swap(min[1],max[1]);
+ if(min[0] > max[0])
+ {
+ min[0]+=expand;
+ max[0]-=expand;
+ }
+ else
+ {
+ min[0]-=expand;
+ max[0]+=expand;
+ }
+
+ if(min[1] > max[1])
+ {
+ min[1]+=expand;
+ max[1]-=expand;
+ }
+ else
+ {
+ min[1]-=expand;
+ max[1]+=expand;
+ }
+
+ Rect bounds(min,max);
+
+ return bounds;
+}
+
+Rect
+Rectangle::get_full_bounding_rect(Context context)const
+{
+ if(invert)
+ {
+ if(is_solid_color() && color.get_a()==0)
+ {
+ Point max(point1),min(point2);
+ if((min[0] > max[0]))swap(min[0],max[0]);
+ if((min[1] > max[1]))swap(min[1],max[1]);
+ if(min[0] > max[0])
+ {
+ min[0]+=expand;
+ max[0]-=expand;
+ }
+ else
+ {
+ min[0]-=expand;
+ max[0]+=expand;
+ }
+
+ if(min[1] > max[1])
+ {
+ min[1]+=expand;
+ max[1]-=expand;
+ }
+ else
+ {
+ min[1]-=expand;
+ max[1]+=expand;
+ }
+
+ Rect bounds(min,max);
+
+ return bounds & context.get_full_bounding_rect();
+ }
+ return Rect::full_plane();
+ }
+
+ return Layer_Composite::get_full_bounding_rect(context);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file rectangle.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_FILLEDRECT_H
+#define __SYNFIG_FILLEDRECT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+#include <synfig/value.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class Rectangle : public synfig::Layer_Composite, public synfig::Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ synfig::Color color;
+
+ synfig::Point point1;
+ synfig::Point point2;
+
+ synfig::Real expand;
+
+ bool invert;
+
+public:
+
+ Rectangle();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+
+ virtual synfig::ValueBase get_param(const synfig::String & param)const;
+
+ virtual bool is_solid_color()const;
+
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+
+ virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual synfig::Rect get_bounding_rect()const;
+ virtual synfig::Rect get_full_bounding_rect(synfig::Context context)const;
+
+ virtual Vocab get_param_vocab()const;
+}; // END of class FilledRect
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file region.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "region.h"
+#include <ETL/stringf>
+#include <ETL/bezier>
+#include <ETL/hermite>
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/segment.h>
+#include <synfig/valuenode_bline.h>
+
+#endif
+
+using namespace etl;
+
+/* === M A C R O S ========================================================= */
+
+#define SAMPLES 75
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Region);
+SYNFIG_LAYER_SET_NAME(Region,"region");
+SYNFIG_LAYER_SET_LOCAL_NAME(Region,_("Region"));
+SYNFIG_LAYER_SET_CATEGORY(Region,_("Geometry"));
+SYNFIG_LAYER_SET_VERSION(Region,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Region,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Region::Region()
+{
+ clear();
+ vector<BLinePoint> bline_point_list;
+ bline_point_list.push_back(BLinePoint());
+ bline_point_list.push_back(BLinePoint());
+ bline_point_list.push_back(BLinePoint());
+ bline_point_list[0].set_vertex(Point(0,1));
+ bline_point_list[1].set_vertex(Point(0,-1));
+ bline_point_list[2].set_vertex(Point(1,0));
+ bline_point_list[0].set_tangent(bline_point_list[1].get_vertex()-bline_point_list[2].get_vertex()*0.5f);
+ bline_point_list[1].set_tangent(bline_point_list[2].get_vertex()-bline_point_list[0].get_vertex()*0.5f);
+ bline_point_list[2].set_tangent(bline_point_list[0].get_vertex()-bline_point_list[1].get_vertex()*0.5f);
+ bline_point_list[0].set_width(1.0f);
+ bline_point_list[1].set_width(1.0f);
+ bline_point_list[2].set_width(1.0f);
+ bline=bline_point_list;
+}
+
+void
+Region::sync()
+{
+ if(bline.get_contained_type()==ValueBase::TYPE_BLINEPOINT)
+ {
+ segment_list=convert_bline_to_segment_list(bline);
+ }
+ else
+ {
+ synfig::warning("Region: incorrect type on bline, layer disabled");
+ clear();
+ return;
+ }
+
+ if(segment_list.empty())
+ {
+ synfig::warning("Region: segment_list is empty, layer disabled");
+ clear();
+ return;
+ }
+
+ bool looped = bline.get_loop();
+
+ Vector::value_type n;
+ etl::hermite<Vector> curve;
+ vector<Point> vector_list;
+
+ vector<Segment>::const_iterator iter=segment_list.begin();
+ //Vector last = iter->p1;
+
+ //make sure the shape has a clean slate for writing
+ //clear();
+
+ //and start off at the first point
+ //move_to(last[0],last[1]);
+
+ for(;iter!=segment_list.end();++iter)
+ {
+ //connect them with a line if they aren't already joined
+ /*if(iter->p1 != last)
+ {
+ line_to(iter->p1[0],iter->p1[1]);
+ }
+
+ //curve to the next end point
+ curve_to(iter->p1[0] + iter->t1[0]/3.0,iter->p1[1] + iter->t1[1]/3.0,
+ iter->p2[0] - iter->t2[0]/3.0,iter->p2[1] - iter->t2[1]/3.0,
+ iter->p2[0],iter->p2[1]);
+
+ last = iter->p2;*/
+
+ if(iter->t1.is_equal_to(Vector(0,0)) && iter->t2.is_equal_to(Vector(0,0)))
+ {
+ vector_list.push_back(iter->p2);
+ }
+ else
+ {
+ curve.p1()=iter->p1;
+ curve.t1()=iter->t1;
+ curve.p2()=iter->p2;
+ curve.t2()=iter->t2;
+ curve.sync();
+
+ for(n=0.0;n<1.0;n+=1.0/SAMPLES)
+ vector_list.push_back(curve(n));
+ }
+ }
+
+ //add the starting point onto the end so it actually fits the shape, so we can be extra awesome...
+ if(!looped)
+ vector_list.push_back(segment_list[0].p1);
+
+ clear();
+ add_polygon(vector_list);
+
+ /*close();
+ endpath();*/
+}
+
+bool
+Region::set_param(const String & param, const ValueBase &value)
+{
+ if(param=="segment_list")
+ {
+ if(dynamic_param_list().count("segment_list"))
+ {
+ connect_dynamic_param("bline",dynamic_param_list().find("segment_list")->second);
+ disconnect_dynamic_param("segment_list");
+ synfig::warning("Region::set_param(): Updated valuenode connection to use the new \"bline\" parameter.");
+ }
+ else
+ synfig::warning("Region::set_param(): The parameter \"segment_list\" is deprecated. Use \"bline\" instead.");
+ }
+
+ if( (param=="segment_list" || param=="bline") && value.get_type()==ValueBase::TYPE_LIST)
+ {
+ //if(value.get_contained_type()!=ValueBase::TYPE_BLINEPOINT)
+ // return false;
+
+ bline=value;
+
+ return true;
+ }
+
+/* if( param=="segment_list" && value.get_type()==ValueBase::TYPE_LIST)
+ {
+ if(value.get_contained_type()==ValueBase::TYPE_BLINEPOINT)
+ segment_list=convert_bline_to_segment_list(value);
+ else
+ if(value.get_contained_type()==ValueBase::TYPE_SEGMENT)
+ segment_list=value;
+ else
+ if(value.empty())
+ segment_list.clear();
+ else
+ return false;
+ sync();
+ return true;
+ }
+ */
+ return Layer_Shape::set_param(param,value);
+}
+
+ValueBase
+Region::get_param(const String& param)const
+{
+ EXPORT(bline);
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Shape::get_param(param);
+}
+
+Layer::Vocab
+Region::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Shape::get_param_vocab());
+
+ ret.push_back(ParamDesc("bline")
+ .set_local_name(_("Vertices"))
+ .set_origin("offset")
+ );
+
+ return ret;
+}
+
+void
+Region::set_time(Context context, Time time)const
+{
+ const_cast<Region*>(this)->sync();
+ context.set_time(time);
+}
+
+void
+Region::set_time(Context context, Time time, Vector pos)const
+{
+ const_cast<Region*>(this)->sync();
+ context.set_time(time,pos);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file region.h
+** \brief Header File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_REGION_H
+#define __SYNFIG_REGION_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_polygon.h>
+#include <list>
+#include <vector>
+#include <synfig/value.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig { class Segment; }
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class Region : protected synfig::Layer_Polygon//Shape
+{
+ SYNFIG_LAYER_MODULE_EXT
+private:
+ synfig::ValueBase bline;
+ std::vector<synfig::Segment> segment_list;
+public:
+ Region();
+
+ //! Updates the polygon data to match the parameters.
+ void sync();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Vocab get_param_vocab()const;
+ virtual void set_time(Context context, Time time)const;
+ virtual void set_time(Context context, Time time, Vector pos)const;
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file star.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "star.h"
+#include <ETL/stringf>
+#include <ETL/bezier>
+#include <ETL/hermite>
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/segment.h>
+
+#endif
+
+using namespace etl;
+
+/* === M A C R O S ========================================================= */
+
+#define SAMPLES 75
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Star);
+SYNFIG_LAYER_SET_NAME(Star,"star");
+SYNFIG_LAYER_SET_LOCAL_NAME(Star,_("Star"));
+SYNFIG_LAYER_SET_CATEGORY(Star,_("Geometry"));
+SYNFIG_LAYER_SET_VERSION(Star,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Star,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Star::Star():
+ radius1(1.0),
+ radius2(0.38),
+ points(5),
+ angle(Angle::deg(90))
+{
+ sync();
+}
+
+void
+Star::sync()
+{
+ Angle dist_between_points(Angle::rot(1)/float(points));
+ std::vector<Point> vector_list;
+
+ int i;
+ for(i=0;i<points;i++)
+ {
+ Angle dist1(dist_between_points*i+angle);
+ Angle dist2(dist_between_points*i+dist_between_points/2+angle);
+ vector_list.push_back(Point(Angle::cos(dist1).get()*radius1,Angle::sin(dist1).get()*radius1));
+ vector_list.push_back(Point(Angle::cos(dist2).get()*radius2,Angle::sin(dist2).get()*radius2));
+ }
+ clear();
+ add_polygon(vector_list);
+}
+
+bool
+Star::set_param(const String & param, const ValueBase &value)
+{
+ if( param=="radius1" && value.same_type_as(radius1))
+ {
+ value.put(&radius1);
+ sync();
+ return true;
+ }
+
+ if( param=="radius2" && value.same_type_as(radius2))
+ {
+ value.put(&radius2);
+ sync();
+ return true;
+ }
+
+ if( param=="points" && value.same_type_as(points))
+ {
+ value.put(&points);
+ if(points<2)points=2;
+ sync();
+ return true;
+ }
+
+ if( param=="angle" && value.same_type_as(angle))
+ {
+ value.put(&angle);
+ sync();
+ return true;
+ }
+
+ if(param=="vector_list")
+ return false;
+
+ return Layer_Polygon::set_param(param,value);
+}
+
+ValueBase
+Star::get_param(const String& param)const
+{
+ EXPORT(radius1);
+ EXPORT(radius2);
+ EXPORT(points);
+ EXPORT(angle);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ if(param=="vector_list")
+ return ValueBase();
+
+ return Layer_Polygon::get_param(param);
+}
+
+Layer::Vocab
+Star::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Polygon::get_param_vocab());
+
+ // Pop off the polygon parameter from the polygon vocab
+ ret.pop_back();
+
+ ret.push_back(ParamDesc("radius1")
+ .set_local_name(_("Outer Radius"))
+ .set_description(_("The radius of the outer points in the star"))
+ .set_is_distance()
+ .set_origin("offset")
+ );
+
+ ret.push_back(ParamDesc("radius2")
+ .set_local_name(_("Inner Radius"))
+ .set_description(_("The radius of the inner points in the star"))
+ .set_is_distance()
+ .set_origin("offset")
+ );
+
+ ret.push_back(ParamDesc("angle")
+ .set_local_name(_("Angle"))
+ .set_description(_("The orientation of the star"))
+ .set_origin("offset")
+ );
+
+ ret.push_back(ParamDesc("points")
+ .set_local_name(_("Points"))
+ .set_description(_("The number of points in the star"))
+ );
+
+ return ret;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file star.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STAR_H
+#define __SYNFIG_STAR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_polygon.h>
+#include <list>
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class Star : protected synfig::Layer_Polygon
+{
+ SYNFIG_LAYER_MODULE_EXT
+private:
+
+ Real radius1;
+ Real radius2;
+ int points;
+ Angle angle;
+public:
+ Star();
+
+ //! Updates the polygon data to match the parameters.
+ void sync();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Vocab get_param_vocab()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_geometry"
+ Delete "$INSTDIR\lib\synfig\modules\mod_geometry.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+module_LTLIBRARIES = libmod_gif.la
+libmod_gif_la_SOURCES = main.cpp trgt_gif.cpp trgt_gif.h
+libmod_gif_la_LDFLAGS = -module -no-undefined
+libmod_gif_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_gif_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+EXTRA_DIST= mod_gif.nsh unmod_gif.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_gif/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include "trgt_gif.h"
+
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(mod_gif)
+ MODULE_NAME("GIF Target")
+ MODULE_DESCRIPTION("Target for the GIF image format (B/W only)")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(mod_gif)
+ BEGIN_TARGETS
+ TARGET(gif)
+ END_TARGETS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_gif" Sec_mod_gif
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_gif.dll "src\modules\mod_gif\.libs\libmod_gif-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_gif"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_gif.cpp
+** \brief BMP Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_TARGET
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ETL/stringf>
+#include "trgt_gif.h"
+#include <stdio.h>
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+#define MAX_FRAME_RATE (20.0)
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_TARGET_INIT(gif);
+SYNFIG_TARGET_SET_NAME(gif,"gif");
+SYNFIG_TARGET_SET_EXT(gif,"gif");
+SYNFIG_TARGET_SET_VERSION(gif,"0.1");
+SYNFIG_TARGET_SET_CVS_ID(gif,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+gif::gif(const char *filename_):
+ filename(filename_),
+ file( (filename=="-")?stdout:fopen(filename_,"wb") ),
+ imagecount(0),
+
+ lossy(true),
+ multi_image(false),
+ dithering(true),
+ color_bits(8),
+ iframe_density(30),
+ loop_count(0x7fff),
+ local_palette(true)
+{
+}
+
+gif::~gif()
+{
+ if(file)
+ fputc(';',file.get()); // Image terminator
+}
+
+bool
+gif::set_rend_desc(RendDesc *given_desc)
+{
+ if(given_desc->get_frame_rate()>MAX_FRAME_RATE)
+ given_desc->set_frame_rate(MAX_FRAME_RATE);
+
+ desc=*given_desc;
+
+ if(desc.get_frame_end()-desc.get_frame_start()>0)
+ {
+ multi_image=true;
+ //set_remove_alpha();
+ imagecount=desc.get_frame_end()-desc.get_frame_start();
+ }
+ else
+ multi_image=false;
+ return true;
+}
+
+bool
+gif::init()
+{
+ int w=desc.get_w(),h=desc.get_h();
+
+ if(!file)
+ {
+ synfig::error(strprintf(_("Unable to open \"%s\" for write access!"),filename.c_str()));
+ return false;
+ }
+
+ rootsize=color_bits; // Size of pixel bits
+
+ curr_frame.set_wh(w,h);
+ prev_frame.set_wh(w,h);
+ curr_surface.set_wh(w,h);
+ curr_frame.clear();
+ prev_frame.clear();
+ curr_surface.clear();
+
+ if(get_quality()>5)
+ lossy=true;
+ else
+ lossy=false;
+
+ // Output the header
+ fprintf(file.get(),"GIF89a");
+ fputc(w&0x000000ff,file.get());
+ fputc((w&0x0000ff00)>>8,file.get());
+ fputc(h&0x000000ff,file.get());
+ fputc((h&0x0000ff00)>>8,file.get());
+ if(!local_palette)
+ fputc(0xF0+(rootsize-1),file.get()); // flags
+ else
+ fputc((0xF0+(rootsize-1))&~(1<<7),file.get()); // flags
+
+ fputc(0,file.get()); // backgound color
+ fputc(0,file.get()); // Pixel Aspect Ratio
+
+ DEBUGPOINT();
+
+ if(!local_palette)
+ {
+ DEBUGPOINT();
+ curr_palette=Palette::grayscale(256/(1<<(8-rootsize))-1);
+ output_curr_palette();
+ }
+
+ if(loop_count && multi_image)
+ {
+ DEBUGPOINT();
+ fputc(33,file.get()); // 33 (hex 0x21) GIF Extension code
+ fputc(255,file.get()); // 255 (hex 0xFF) Application Extension Label
+ fputc(11,file.get()); // 11 (hex (0x0B) Length of Application Block
+ fprintf(file.get(),"NETSCAPE2.0");
+ fputc(3,file.get()); // 3 (hex 0x03) Length of Data Sub-Block
+ fputc(1,file.get()); // 1 (hex 0x01)
+ fputc(loop_count&0x000000ff,file.get());
+ fputc((loop_count&0x0000ff00)>>8,file.get());
+ fputc(0,file.get()); // 0 (hex 0x00) a Data Sub-block Terminator.
+ }
+ DEBUGPOINT();
+
+ return true;
+}
+
+void
+gif::output_curr_palette()
+{
+ // Output the color table
+ for(i=0;i<256/(1<<(8-rootsize));i++)
+ {
+ if(i<(signed)curr_palette.size())
+ {
+ Color color(curr_palette[i].color.clamped());
+ //fputc(i*(1<<(8-rootsize)),file.get());
+ //fputc(i*(1<<(8-rootsize)),file.get());
+ //fputc(i*(1<<(8-rootsize)),file.get());
+ fputc(gamma().r_F32_to_U8(color.get_r()),file.get());
+ fputc(gamma().g_F32_to_U8(color.get_g()),file.get());
+ fputc(gamma().b_F32_to_U8(color.get_b()),file.get());
+ }
+ else
+ {
+ fputc(255,file.get());
+ fputc(0,file.get());
+ fputc(255,file.get());
+ }
+ }
+}
+
+bool
+gif::start_frame(synfig::ProgressCallback *callback)
+{
+// int
+// w=desc.get_w(),
+// h=desc.get_h();
+
+ if(!file)
+ {
+ if(callback)callback->error(string("BUG:")+_("Description not set!"));
+ return false;
+ }
+
+ if(callback)callback->task(filename+strprintf(" %d",imagecount));
+
+
+
+ return true;
+}
+
+void
+gif::end_frame()
+{
+ int w=desc.get_w(),h=desc.get_h(),i;
+ unsigned int value;
+ int
+ delaytime=round_to_int(100.0/desc.get_frame_rate());
+
+ bool build_off_previous(multi_image);
+
+ Palette prev_palette(curr_palette);
+
+ // Fill in the background color
+ if(!get_remove_alpha())
+ {
+ Surface::alpha_pen pen(curr_surface.begin(),1.0,Color::BLEND_BEHIND);
+ pen.set_value(get_canvas()->rend_desc().get_bg_color());
+ for(int y=0;y<curr_surface.get_h();y++,pen.inc_y())
+ {
+ int x;
+ for(x=0;x<curr_surface.get_w();x++,pen.inc_x())
+ {
+ if(pen.get_value().get_a()>0.1)
+ pen.put_value();
+ else
+ pen[0][0]=Color::alpha();
+ }
+ pen.dec_x(x);
+ }
+ }
+
+ if(local_palette)
+ {
+ curr_palette=Palette(curr_surface,256/(1<<(8-rootsize))-build_off_previous-1);
+ synfig::info("curr_palette.size()=%d",curr_palette.size());
+ }
+
+ int transparent_index(curr_palette.find_closest(Color(1,0,1,0))-curr_palette.begin());
+ bool has_transparency(curr_palette[transparent_index].color.get_a()<=0.00001);
+
+ if(has_transparency)
+ build_off_previous=false;
+
+ if(build_off_previous)
+ {
+ transparent_index=0;
+ has_transparency=true;
+ }
+
+#define DISPOSE_UNDEFINED (0)
+#define DISPOSE_NONE (1<<2)
+#define DISPOSE_RESTORE_BGCOLOR (2<<2)
+#define DISPOSE_RESTORE_PREVIOUS (3<<2)
+ int gec_flags(0);
+ if(build_off_previous)
+ gec_flags|=DISPOSE_NONE;
+ else
+ gec_flags|=DISPOSE_RESTORE_PREVIOUS;
+ if(has_transparency)
+ gec_flags|=1;
+
+ // output the Graphic Control Extension
+ fputc(0x21,file.get()); // Extension introducer
+ fputc(0xF9,file.get()); // Graphic Control Label
+ fputc(4,file.get()); // Block Size
+ fputc(gec_flags,file.get()); // Flags (Packed Fields)
+ fputc(delaytime&0x000000ff,file.get()); // Delay Time (MSB)
+ fputc((delaytime&0x0000ff00)>>8,file.get()); // Delay Time (LSB)
+ fputc(transparent_index,file.get()); // Transparent Color Index
+ fputc(0,file.get()); // Block Terminator
+
+ // output the image header
+ fputc(',',file.get());
+ fputc(0,file.get()); // image left
+ fputc(0,file.get()); // image left
+ fputc(0,file.get()); // image top
+ fputc(0,file.get()); // image top
+ fputc(w&0x000000ff,file.get());
+ fputc((w&0x0000ff00)>>8,file.get());
+ fputc(h&0x000000ff,file.get());
+ fputc((h&0x0000ff00)>>8,file.get());
+ if(local_palette)
+ fputc(0x80|(rootsize-1),file.get()); // flags
+ else
+ fputc(0x00+ rootsize-1,file.get()); // flags
+
+
+ if(local_palette)
+ {
+ Palette out(curr_palette);
+
+ if(build_off_previous)
+ curr_palette.insert(curr_palette.begin(),Color(1,0,1,0));
+ output_curr_palette();
+ curr_palette=out;
+ }
+
+ bs=bitstream(file);
+
+ // Prepare ourselves for LZW compression
+ codesize=rootsize+1;
+ nextcode=(1<<rootsize)+2;
+ table=lzwcode::NewTable((1<<rootsize));
+ node=table;
+
+ // Output the rootsize
+ fputc(rootsize,file.get()); // rootsize;
+
+ // Push a table reset into the bitstream
+ bs.push_value(1<<rootsize,codesize);
+
+ for(int cur_scanline=0;cur_scanline<desc.get_h();cur_scanline++)
+ {
+ //convert_color_format(curr_frame[cur_scanline], curr_surface[cur_scanline], desc.get_w(), PF_GRAY, gamma());
+
+ // Now we compress it!
+ for(i=0;i<w;i++)
+ {
+ Color color(curr_surface[cur_scanline][i].clamped());
+ Palette::iterator iter(curr_palette.find_closest(color));
+
+ if(dithering)
+ {
+ Color error(color-iter->color);
+ //error*=0.25;
+ if(curr_surface.get_h()>cur_scanline+1)
+ {
+ curr_surface[cur_scanline+1][i-1] += error * ((float)3/(float)16);
+ curr_surface[cur_scanline+1][i] += error * ((float)5/(float)16);
+ if(curr_surface.get_w()>i+1)
+ curr_surface[cur_scanline+1][i+1] += error * ((float)1/(float)16);
+ }
+ if(curr_surface.get_w()>i+1)
+ curr_surface[cur_scanline][i+1] += error * ((float)7/(float)16);
+ }
+
+ curr_frame[cur_scanline][i]=iter-curr_palette.begin();
+
+ value=curr_frame[cur_scanline][i];
+ if(build_off_previous)
+ value++;
+ if(value>(unsigned)(1<<rootsize)-1)
+ value=(1<<rootsize)-1;
+
+ // If the pixel is the same as the one that
+ // is already there, then we should make it
+ // transparent
+ if(build_off_previous)
+ {
+ if(lossy)
+ {
+
+ // Lossy
+ if(
+ abs( ( iter->color-prev_palette[prev_frame[cur_scanline][i]-1].color ).get_y() ) > (1.0/16.0) ||
+// abs((int)value-(int)prev_frame[cur_scanline][i])>2||
+// (value<=2 && value!=prev_frame[cur_scanline][i]) ||
+ (imagecount%iframe_density)==0 || imagecount==desc.get_frame_end()-1 ) // lossy version
+ prev_frame[cur_scanline][i]=value;
+ else
+ {
+ prev_frame[cur_scanline][i]=value;
+ value=0;
+ }
+ }
+ else
+ {
+ // lossless version
+ if(value!=prev_frame[cur_scanline][i])
+ prev_frame[cur_scanline][i]=value;
+ else
+ value=0;
+ }
+ }
+ else
+ prev_frame[cur_scanline][i]=value;
+
+ next=node->FindCode(value);
+ if(next)
+ node=next;
+ else
+ {
+ node->AddNode(nextcode, value);
+ bs.push_value(node->code, codesize);
+ node = table->FindCode(value);
+
+ // Check to see if we need to increase the codesize
+ if (nextcode == ( 1 << codesize))
+ codesize += 1;
+
+ nextcode += 1;
+
+ // check to see if we have filled up the table
+ if (nextcode == 4096)
+ {
+ // output the clear code: make sure to use the current
+ // codesize
+ bs.push_value((unsigned) 1 << rootsize, codesize);
+
+ delete table;
+ table = lzwcode::NewTable((1<<rootsize));
+ codesize = rootsize + 1;
+ nextcode = (1 << rootsize) + 2;
+
+ // since we have a new table, need the correct prefix
+ node = table->FindCode(value);
+ }
+ }
+ }
+ }
+
+
+
+
+
+ // Push the last code onto the bitstream
+ bs.push_value(node->code,codesize);
+
+ // Push a end-of-stream code onto the bitstream
+ bs.push_value((1<<rootsize)+1,codesize);
+
+ // Make sure everything is dumped out
+ bs.dump();
+
+ delete table;
+
+ fputc(0,file.get()); // Block terminator
+
+ fflush(file.get());
+ imagecount++;
+}
+
+synfig::Color*
+gif::start_scanline(int scanline)
+{
+ cur_scanline=scanline;
+ return curr_surface[scanline];
+}
+
+bool
+gif::end_scanline()
+{
+ if(!file)
+ return false;
+
+// int w=desc.get_w(),i;
+// unsigned int value;
+
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_gif.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRGT_GIF_H
+#define __SYNFIG_TRGT_GIF_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/target_scanline.h>
+#include <synfig/string.h>
+#include <synfig/smartfile.h>
+#include <cstdio>
+#include <synfig/surface.h>
+#include <synfig/palette.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class gif : public synfig::Target_Scanline
+{
+ SYNFIG_TARGET_MODULE_EXT
+private:
+ // Class for abstracting the
+ // output of the codes
+ struct bitstream
+ {
+ synfig::SmartFILE file;
+ unsigned char pool;
+ char curr_bit;
+ bitstream():pool(0),curr_bit(0),curr_pos(0) {}
+ bitstream(synfig::SmartFILE file):file(file),pool(0),curr_bit(0),curr_pos(0) {}
+ unsigned char buffer[256];
+ int curr_pos;
+
+ // Pushes a single bit onto the bit
+ void push_bit(bool bit)
+ {
+ if(bit)
+ pool|=(1<<(curr_bit));
+ curr_bit++;
+ if(curr_bit==8)
+ empty();
+ }
+
+ // Emptys out the current pool into
+ // the buffer. Calls 'dump()' if the
+ // buffer is full.
+ void empty()
+ {
+ buffer[curr_pos++]=pool;
+ curr_bit=0;
+ pool=0;
+ if(curr_pos==255)dump();
+ }
+
+ // If there is anything in the
+ // buffer or in the pool, it
+ // dumps it to the filestream.
+ // Buffer and pool are cleared.
+ void dump()
+ {
+ if(curr_bit)
+ empty();
+ if(curr_pos || curr_bit)
+ {
+ fputc(curr_pos,file.get());
+ fwrite(buffer,curr_pos,1,file.get());
+ curr_pos=0;
+ }
+ }
+
+ // Pushes a symbol of the given size
+ // onto the bitstream.
+ void push_value(int value, int size)
+ {
+ int i;
+ for(i=0;i<size;i++)
+ push_bit((value>>(i))&1);
+ }
+ };
+
+ // Class for dealing with the LZW codes
+ struct lzwcode
+ {
+ int value; // the data element or character
+ int code; // lzwcode
+ struct lzwcode* kids; // children of this node
+ struct lzwcode* next; // siblings of this node
+
+ lzwcode():value(0),code(0),kids(0),next(0) { }
+
+ lzwcode *FindCode(int value)
+ {
+ lzwcode *node=this;
+
+ // check the children (kids) of the node for the value
+ for (node = node->kids; node != 0; node = node->next)
+ if (node->value == value)
+ return(node);
+ return(0);
+ }
+
+ void AddNode(unsigned short code, unsigned short value)
+ {
+ lzwcode *n = new lzwcode;
+
+ // add a new child to node; the child will have code and value
+ n->value = value;
+ n->code = code;
+ n->kids = 0;
+ n->next = this->kids;
+ this->kids = n;
+ }
+
+ static lzwcode * NewTable(int values)
+ {
+ int i;
+ lzwcode * table = new lzwcode;
+
+ table->kids = 0;
+ for (i = 0; i < values; i++)
+ table->AddNode( i, i);
+
+ return(table);
+ }
+
+ // Destructor just deletes any
+ // children and sibblings.
+ ~lzwcode()
+ {
+ if(kids)
+ delete kids;
+ if(next)
+ delete next;
+ }
+ };
+
+private:
+ bitstream bs;
+ synfig::String filename;
+ synfig::SmartFILE file;
+ int
+ i, // General-purpose index
+ codesize, // Current code size
+ rootsize, // Size of pixel bits (will be recalculted)
+ nextcode; // Next code to use
+ lzwcode *table,*next,*node;
+
+ synfig::Surface curr_surface;
+ etl::surface<unsigned char> curr_frame;
+ etl::surface<unsigned char> prev_frame;
+
+ int imagecount;
+ int cur_scanline;
+
+
+ // GIF compression parameters
+ bool lossy;
+ bool multi_image;
+ bool dithering;
+ int color_bits;
+ int iframe_density;
+ int loop_count;
+ bool local_palette;
+
+ synfig::Palette curr_palette;
+
+ void output_curr_palette();
+
+public:
+ gif(const char *filename);
+
+ virtual bool set_rend_desc(synfig::RendDesc *desc);
+ virtual bool init();
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+ virtual void end_frame();
+
+ virtual ~gif();
+
+ virtual synfig::Color * start_scanline(int scanline);
+ virtual bool end_scanline(void);
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_gif"
+ Delete "$INSTDIR\lib\synfig\modules\mod_gif.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+module_LTLIBRARIES = libmod_gradient.la
+libmod_gradient_la_SOURCES = curvegradient.cpp curvegradient.h lineargradient.cpp lineargradient.h conicalgradient.cpp conicalgradient.h spiralgradient.cpp spiralgradient.h radialgradient.cpp radialgradient.h main.cpp
+libmod_gradient_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_gradient_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+libmod_gradient_la_LDFLAGS = -module -no-undefined
+EXTRA_DIST= mod_gradient.nsh unmod_gradient.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file conicalgradient.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/angle.h>
+
+#include "conicalgradient.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(ConicalGradient);
+SYNFIG_LAYER_SET_NAME(ConicalGradient,"conical_gradient");
+SYNFIG_LAYER_SET_LOCAL_NAME(ConicalGradient,_("Conical Gradient"));
+SYNFIG_LAYER_SET_CATEGORY(ConicalGradient,_("Gradients"));
+SYNFIG_LAYER_SET_VERSION(ConicalGradient,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(ConicalGradient,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+ConicalGradient::ConicalGradient():
+ Layer_Composite(1.0,Color::BLEND_STRAIGHT),
+ gradient(Color::black(),Color::white()),
+ center(0,0),
+ angle(Angle::zero()),
+ symmetric(false)
+{
+}
+
+bool
+ConicalGradient::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(gradient);
+ IMPORT(center);
+ IMPORT(angle);
+ IMPORT(symmetric);
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+ConicalGradient::get_param(const String ¶m)const
+{
+ EXPORT(gradient);
+ EXPORT(center);
+ EXPORT(angle);
+ EXPORT(symmetric);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+ConicalGradient::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("gradient")
+ .set_local_name(_("Gradient"))
+ );
+
+ ret.push_back(ParamDesc("center")
+ .set_local_name(_("Center"))
+ );
+
+ ret.push_back(ParamDesc("angle")
+ .set_local_name(_("Angle"))
+ .set_origin("center")
+ );
+
+ ret.push_back(ParamDesc("symmetric")
+ .set_local_name(_("Symmetric"))
+ );
+
+ return ret;
+}
+
+inline Color
+ConicalGradient::color_func(const Point &pos, float supersample)const
+{
+ const Point centered(pos-center);
+ Angle::rot a=Angle::tan(-centered[1],centered[0]).mod();
+ a+=angle;
+ Real dist(a.mod().get());
+
+ dist-=floor(dist);
+
+ if(symmetric)
+ {
+ dist*=2.0;
+ supersample*=2.0;
+ if(dist>1)dist=2.0-dist;
+ }
+/* if(dist+supersample*0.5>1.0)
+ {
+ Color pool(gradient(dist,supersample*0.5)*(1.0-(dist-supersample*0.5)));
+ pool+=gradient((dist+supersample*0.5)-1.0,supersample*0.5)*((dist+supersample*0.5)-1.0);
+ if(pool.get_a() && pool.is_valid())
+ {
+ pool.set_r(pool.get_r()/pool.get_a());
+ pool.set_g(pool.get_g()/pool.get_a());
+ pool.set_b(pool.get_b()/pool.get_a());
+ pool.set_a(pool.get_a()/supersample);
+ }
+ return pool;
+ }
+
+ if(dist-supersample*0.5<0.0)
+ {
+ Color pool(gradient(dist,supersample*0.5)*(dist+supersample*0.5));
+ pool+=gradient(1.0-(dist-supersample*0.5),supersample*0.5)*(-(dist-supersample*0.5));
+ if(pool.get_a() && pool.is_valid())
+ {
+ pool.set_r(pool.get_r()/pool.get_a());
+ pool.set_g(pool.get_g()/pool.get_a());
+ pool.set_b(pool.get_b()/pool.get_a());
+ pool.set_a(pool.get_a()/supersample);
+ return pool;
+ }
+ }
+*/
+ if(dist+supersample*0.5>1.0)
+ {
+ float left(supersample*0.5-(dist-1.0));
+ float right(supersample*0.5+(dist-1.0));
+ Color pool(gradient(1.0-(left*0.5),left).premult_alpha()*left/supersample);
+ pool+=gradient(right*0.5,right).premult_alpha()*right/supersample;
+ return pool.demult_alpha();
+ }
+ if(dist-supersample*0.5<0.0)
+ {
+ float left(supersample*0.5-dist);
+ float right(supersample*0.5+dist);
+ Color pool(gradient(right*0.5,right).premult_alpha()*right/supersample);
+ pool+=gradient(1.0-left*0.5,left).premult_alpha()*left/supersample;
+ return pool.demult_alpha();
+ }
+
+ return gradient(dist,supersample);
+}
+
+float
+ConicalGradient::calc_supersample(const synfig::Point &x, float pw,float ph)const
+{
+ Point adj(x-center);
+ if(abs(adj[0])<abs(pw*0.5) && abs(adj[1])<abs(ph*0.5))
+ return 0.5;
+ return (pw/Point(x-center).mag())/(PI*2);
+}
+
+synfig::Layer::Handle
+ConicalGradient::hit_check(synfig::Context context, const synfig::Point &point)const
+{
+ if(get_blend_method()==Color::BLEND_STRAIGHT && get_amount()>=0.5)
+ return const_cast<ConicalGradient*>(this);
+ if(get_amount()==0.0)
+ return context.hit_check(point);
+ if((get_blend_method()==Color::BLEND_STRAIGHT || get_blend_method()==Color::BLEND_COMPOSITE) && color_func(point).get_a()>0.5)
+ return const_cast<ConicalGradient*>(this);
+ return context.hit_check(point);
+}
+
+Color
+ConicalGradient::get_color(Context context, const Point &pos)const
+{
+ const Color color(color_func(pos));
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,context.get_color(pos),get_amount(),get_blend_method());
+}
+
+bool
+ConicalGradient::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ }
+ else
+ {
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+ if(get_amount()==0)
+ return true;
+ }
+
+
+ int x,y;
+
+ Surface::pen pen(surface->begin());
+ const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
+ Point pos;
+ Point tl(renddesc.get_tl());
+ const int w(surface->get_w());
+ const int h(surface->get_h());
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ if(quality<9)
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(color_func(pos,calc_supersample(pos,pw,ph)));
+ }
+ else
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(color_func(pos,0));
+ }
+ }
+ else
+ {
+ if(quality<9)
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(Color::blend(color_func(pos,calc_supersample(pos,pw,ph)),pen.get_value(),get_amount(),get_blend_method()));
+ }
+ else
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(Color::blend(color_func(pos,0),pen.get_value(),get_amount(),get_blend_method()));
+ }
+ }
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file conicalgradient.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_CONICALGRADIENT_H
+#define __SYNFIG_CONICALGRADIENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+#include <synfig/value.h>
+#include <synfig/gradient.h>
+#include <synfig/angle.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class ConicalGradient : public synfig::Layer_Composite, public synfig::Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ synfig::Gradient gradient;
+
+ synfig::Point center;
+
+ synfig::Angle angle;
+
+ bool symmetric;
+
+ synfig::Color color_func(const synfig::Point &x, float supersample=0)const;
+
+ float calc_supersample(const synfig::Point &x, float pw,float ph)const;
+
+public:
+
+ ConicalGradient();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+
+ virtual synfig::ValueBase get_param(const synfig::String & param)const;
+
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+
+ virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual Vocab get_param_vocab()const;
+}; // END of class ConicalGradient
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file curvegradient.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "curvegradient.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <ETL/bezier>
+#include <ETL/hermite>
+#include <ETL/calculus>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(CurveGradient);
+SYNFIG_LAYER_SET_NAME(CurveGradient,"curve_gradient");
+SYNFIG_LAYER_SET_LOCAL_NAME(CurveGradient,_("Curve Gradient"));
+SYNFIG_LAYER_SET_CATEGORY(CurveGradient,_("Gradients"));
+SYNFIG_LAYER_SET_VERSION(CurveGradient,"0.0");
+SYNFIG_LAYER_SET_CVS_ID(CurveGradient,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+inline float calculate_distance(const synfig::BLinePoint& a,const synfig::BLinePoint& b)
+{
+#if 1
+ const Point& c1(a.get_vertex());
+ const Point c2(a.get_vertex()+a.get_tangent2()/3);
+ const Point c3(b.get_vertex()-b.get_tangent1()/3);
+ const Point& c4(b.get_vertex());
+ return (c1-c2).mag()+(c2-c3).mag()+(c3-c4).mag();
+#else
+#endif
+}
+
+inline float calculate_distance(const std::vector<synfig::BLinePoint>& bline, bool bline_loop)
+{
+ std::vector<synfig::BLinePoint>::const_iterator iter,next,ret;
+ std::vector<synfig::BLinePoint>::const_iterator end(bline.end());
+
+ float dist(0);
+
+ if (bline.empty()) return dist;
+
+ next=bline.begin();
+
+ if(bline_loop)
+ iter=--bline.end();
+ else
+ iter=next++;
+
+ for(;next!=end;iter=next++)
+ {
+ // Setup the curve
+ etl::hermite<Vector> curve(
+ iter->get_vertex(),
+ next->get_vertex(),
+ iter->get_tangent2(),
+ next->get_tangent1());
+
+// dist+=calculate_distance(*iter,*next);
+ dist+=curve.length();
+ }
+
+ return dist;
+}
+
+std::vector<synfig::BLinePoint>::const_iterator
+find_closest(bool fast, const std::vector<synfig::BLinePoint>& bline,const Point& p,float& t,bool loop=false,float *bline_dist_ret=0)
+{
+ std::vector<synfig::BLinePoint>::const_iterator iter,next,ret;
+ std::vector<synfig::BLinePoint>::const_iterator end(bline.end());
+
+ ret=bline.end();
+ float dist(100000000000.0);
+
+ next=bline.begin();
+
+ float best_bline_dist(0);
+ float best_bline_len(0);
+ float total_bline_dist(0);
+ float best_pos(0);
+ etl::hermite<Vector> best_curve;
+
+ if(loop)
+ iter=--bline.end();
+ else
+ iter=next++;
+
+ Point bp;
+
+ for(;next!=end;iter=next++)
+ {
+ // Setup the curve
+ etl::hermite<Vector> curve(
+ iter->get_vertex(),
+ next->get_vertex(),
+ iter->get_tangent2(),
+ next->get_tangent1());
+
+ /*
+ const float t(curve.find_closest(p,6,0.01,0.99));
+ bp=curve(t);if((bp-p).mag_squared()<dist) { ret=iter; dist=(bp-p).mag_squared(); ret_t=t; }
+ */
+
+ float thisdist(0);
+ float len(0);
+ if(bline_dist_ret)
+ {
+ //len=calculate_distance(*iter,*next);
+ len=curve.length();
+ }
+
+ if (fast)
+ {
+#define POINT_CHECK(x) bp=curve(x); thisdist=(bp-p).mag_squared(); if(thisdist<dist) { ret=iter; dist=thisdist; best_bline_dist=total_bline_dist; best_bline_len=len; best_curve=curve; }
+ POINT_CHECK(0.0001);
+ POINT_CHECK((1.0/6.0));
+ POINT_CHECK((2.0/6.0));
+ POINT_CHECK((3.0/6.0));
+ POINT_CHECK((4.0/6.0));
+ POINT_CHECK((5.0/6.0));
+ POINT_CHECK(0.9999);
+ }
+ else
+ {
+ float pos = curve.find_closest(fast, p);
+ thisdist=(curve(pos)-p).mag_squared();
+ if(thisdist<dist)
+ {
+ ret=iter;
+ dist=thisdist;
+ best_bline_dist=total_bline_dist;
+ best_bline_len=len;
+ best_curve=curve;
+ best_pos = pos;
+ }
+ }
+
+ total_bline_dist+=len;
+ }
+
+ t = best_pos;
+
+ if(bline_dist_ret)
+ {
+ //! \todo is this a redundant call to find_closest()?
+ // note bline_dist_ret is null except when 'perpendicular' is true
+ *bline_dist_ret=best_bline_dist+best_curve.find_distance(0,best_curve.find_closest(fast, p));
+// *bline_dist_ret=best_bline_dist+best_curve.find_closest(fast, p)*best_bline_len;
+ }
+
+ return ret;
+}
+
+/* === M E T H O D S ======================================================= */
+
+inline void
+CurveGradient::sync()
+{
+ curve_length_=calculate_distance(bline, bline_loop);
+}
+
+
+CurveGradient::CurveGradient():
+ offset(0,0),
+ width(0.25),
+ gradient(Color::black(), Color::white()),
+ loop(false),
+ zigzag(false),
+ perpendicular(false),
+ fast(true)
+{
+ bline.push_back(BLinePoint());
+ bline.push_back(BLinePoint());
+ bline.push_back(BLinePoint());
+ bline[0].set_vertex(Point(0,1));
+ bline[1].set_vertex(Point(0,-1));
+ bline[2].set_vertex(Point(1,0));
+ bline[0].set_tangent(bline[1].get_vertex()-bline[2].get_vertex()*0.5f);
+ bline[1].set_tangent(bline[2].get_vertex()-bline[0].get_vertex()*0.5f);
+ bline[2].set_tangent(bline[0].get_vertex()-bline[1].get_vertex()*0.5f);
+ bline[0].set_width(1.0f);
+ bline[1].set_width(1.0f);
+ bline[2].set_width(1.0f);
+ bline_loop=true;
+
+ sync();
+}
+
+inline Color
+CurveGradient::color_func(const Point &point_, int quality, float supersample)const
+{
+ Vector tangent;
+ Vector diff;
+ Point p1;
+ Real thickness;
+ Real dist;
+
+ float perp_dist;
+ bool edge_case = false;
+
+ if(bline.size()==0)
+ return Color::alpha();
+ else if(bline.size()==1)
+ {
+ tangent=bline.front().get_tangent1();
+ p1=bline.front().get_vertex();
+ thickness=bline.front().get_width();
+ }
+ else
+ {
+ float t;
+ Point point(point_-offset);
+
+ std::vector<synfig::BLinePoint>::const_iterator iter,next;
+
+ // Figure out the BLinePoints we will be using,
+ // Taking into account looping.
+ if(perpendicular)
+ {
+ next=find_closest(fast,bline,point,t,bline_loop,&perp_dist);
+ perp_dist/=curve_length_;
+ }
+ else // not perpendicular
+ {
+ next=find_closest(fast,bline,point,t,bline_loop);
+ }
+
+ iter=next++;
+ if(next==bline.end()) next=bline.begin();
+
+ // Setup the curve
+ etl::hermite<Vector> curve(
+ iter->get_vertex(),
+ next->get_vertex(),
+ iter->get_tangent2(),
+ next->get_tangent1()
+ );
+
+ // Setup the derivative function
+ etl::derivative<etl::hermite<Vector> > deriv(curve);
+
+ int search_iterations(7);
+
+ /*if(quality==0)search_iterations=8;
+ else if(quality<=2)search_iterations=10;
+ else if(quality<=4)search_iterations=8;
+ */
+ if(perpendicular)
+ {
+ if(quality>7)
+ search_iterations=4;
+ }
+ else // not perpendicular
+ {
+ if(quality<=6)search_iterations=7;
+ else if(quality<=7)search_iterations=6;
+ else if(quality<=8)search_iterations=5;
+ else search_iterations=4;
+ }
+
+ // Figure out the closest point on the curve
+ if (fast)
+ t = curve.find_closest(fast, point,search_iterations);
+
+ // Calculate our values
+ p1=curve(t); // the closest point on the curve
+ tangent=deriv(t).norm(); // the unit tangent at that point
+
+ // if the point we're nearest to is at either end of the
+ // bline, our distance from the curve is the distance from the
+ // point on the curve. we need to know which side of the
+ // curve we're on, so find the average of the two tangents at
+ // this point
+ if (t<0.00001 || t>0.99999)
+ {
+ if (t<0.5)
+ {
+ if (iter->get_split_tangent_flag())
+ {
+ tangent=(iter->get_tangent1().norm()+tangent).norm();
+ edge_case=true;
+ }
+ }
+ else
+ {
+ if (next->get_split_tangent_flag())
+ {
+ tangent=(next->get_tangent2().norm()+tangent).norm();
+ edge_case=true;
+ }
+ }
+ }
+
+ if(perpendicular)
+ {
+ tangent*=curve_length_;
+ p1-=tangent*perp_dist;
+ tangent=-tangent.perp();
+ }
+ else // not perpendicular
+ // the width of the bline at the closest point on the curve
+ thickness=(next->get_width()-iter->get_width())*t+iter->get_width();
+ }
+
+ if(perpendicular)
+ {
+ if(quality>7)
+ {
+ dist=perp_dist;
+/* diff=tangent.perp();
+ const Real mag(diff.inv_mag());
+ supersample=supersample*mag;
+*/
+ supersample=0;
+ }
+ else
+ {
+ diff=tangent.perp();
+ //p1-=diff*0.5;
+ const Real mag(diff.inv_mag());
+ supersample=supersample*mag;
+ diff*=mag*mag;
+ dist=((point_-offset)*diff-p1*diff);
+ }
+ }
+ else // not perpendicular
+ {
+ if (edge_case)
+ {
+ diff=(p1-(point_-offset));
+ if(diff*tangent.perp()<0) diff=-diff;
+ diff=diff.norm()*thickness*width;
+ }
+ else
+ diff=tangent.perp()*thickness*width;
+
+ p1-=diff*0.5;
+ const Real mag(diff.inv_mag());
+ supersample=supersample*mag;
+ diff*=mag*mag;
+ dist=((point_-offset)*diff-p1*diff);
+ }
+
+ if(loop)
+ dist-=floor(dist);
+
+ if(zigzag)
+ {
+ dist*=2.0;
+ supersample*=2.0;
+ if(dist>1)dist=2.0-dist;
+ }
+
+ if(loop)
+ {
+ if(dist+supersample*0.5>1.0)
+ {
+ float left(supersample*0.5-(dist-1.0));
+ float right(supersample*0.5+(dist-1.0));
+ Color pool(gradient(1.0-(left*0.5),left).premult_alpha()*left/supersample);
+ if (zigzag) pool+=gradient(1.0-right*0.5,right).premult_alpha()*right/supersample;
+ else pool+=gradient(right*0.5,right).premult_alpha()*right/supersample;
+ return pool.demult_alpha();
+ }
+ if(dist-supersample*0.5<0.0)
+ {
+ float left(supersample*0.5-dist);
+ float right(supersample*0.5+dist);
+ Color pool(gradient(right*0.5,right).premult_alpha()*right/supersample);
+ if (zigzag) pool+=gradient(left*0.5,left).premult_alpha()*left/supersample;
+ else pool+=gradient(1.0-left*0.5,left).premult_alpha()*left/supersample;
+ return pool.demult_alpha();
+ }
+ }
+ return gradient(dist,supersample);
+}
+
+float
+CurveGradient::calc_supersample(const synfig::Point &/*x*/, float pw,float /*ph*/)const
+{
+ return pw;
+}
+
+synfig::Layer::Handle
+CurveGradient::hit_check(synfig::Context context, const synfig::Point &point)const
+{
+ if(get_blend_method()==Color::BLEND_STRAIGHT && get_amount()>=0.5)
+ return const_cast<CurveGradient*>(this);
+ if(get_amount()==0.0)
+ return context.hit_check(point);
+ if((get_blend_method()==Color::BLEND_STRAIGHT || get_blend_method()==Color::BLEND_COMPOSITE|| get_blend_method()==Color::BLEND_ONTO) && color_func(point).get_a()>0.5)
+ return const_cast<CurveGradient*>(this);
+ return context.hit_check(point);
+}
+
+bool
+CurveGradient::set_param(const String & param, const ValueBase &value)
+{
+
+
+ IMPORT(offset);
+ IMPORT(perpendicular);
+ IMPORT(fast);
+
+ if(param=="bline" && value.get_type()==ValueBase::TYPE_LIST)
+ {
+ bline=value;
+ bline_loop=value.get_loop();
+ sync();
+
+ return true;
+ }
+
+ IMPORT(width);
+ IMPORT(gradient);
+ IMPORT(loop);
+ IMPORT(zigzag);
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+CurveGradient::get_param(const String & param)const
+{
+ EXPORT(offset);
+ EXPORT(bline);
+ EXPORT(gradient);
+ EXPORT(loop);
+ EXPORT(zigzag);
+ EXPORT(width);
+ EXPORT(perpendicular);
+ EXPORT(fast);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+CurveGradient::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("offset")
+ .set_local_name(_("Offset")));
+
+ ret.push_back(ParamDesc("width")
+ .set_is_distance()
+ .set_local_name(_("Width")));
+
+ ret.push_back(ParamDesc("bline")
+ .set_local_name(_("Vertices"))
+ .set_origin("offset")
+ .set_scalar("width")
+ .set_description(_("A list of BLine Points")));
+
+ ret.push_back(ParamDesc("gradient")
+ .set_local_name(_("Gradient")));
+ ret.push_back(ParamDesc("loop")
+ .set_local_name(_("Loop")));
+ ret.push_back(ParamDesc("zigzag")
+ .set_local_name(_("ZigZag")));
+ ret.push_back(ParamDesc("perpendicular")
+ .set_local_name(_("Perpendicular")));
+ ret.push_back(ParamDesc("fast")
+ .set_local_name(_("Fast")));
+
+ return ret;
+}
+
+Color
+CurveGradient::get_color(Context context, const Point &point)const
+{
+ const Color color(color_func(point,0));
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,context.get_color(point),get_amount(),get_blend_method());
+}
+
+bool
+CurveGradient::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ }
+ else
+ {
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+ if(get_amount()==0)
+ return true;
+ }
+
+
+ int x,y;
+
+ Surface::pen pen(surface->begin());
+ const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
+ Point pos;
+ Point tl(renddesc.get_tl());
+ const int w(surface->get_w());
+ const int h(surface->get_h());
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(color_func(pos,quality,calc_supersample(pos,pw,ph)));
+ }
+ else
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(Color::blend(color_func(pos,quality,calc_supersample(pos,pw,ph)),pen.get_value(),get_amount(),get_blend_method()));
+ }
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file curvegradient.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_CURVEGRADIENT_H
+#define __SYNFIG_CURVEGRADIENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/vector.h>
+#include <synfig/layer_composite.h>
+#include <synfig/gradient.h>
+#include <synfig/blinepoint.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class CurveGradient : public Layer_Composite, public Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+ std::vector<synfig::BLinePoint> bline;
+
+ Point offset;
+ Real width;
+ Gradient gradient;
+ Real curve_length_;
+
+ bool loop;
+ bool zigzag;
+ bool bline_loop;
+ bool perpendicular;
+ bool fast;
+
+ void sync();
+
+ synfig::Color color_func(const synfig::Point &x, int quality=10, float supersample=0)const;
+
+ float calc_supersample(const synfig::Point &x, float pw,float ph)const;
+
+public:
+ CurveGradient();
+
+ virtual bool set_param(const String ¶m, const ValueBase &value);
+ virtual ValueBase get_param(const String ¶m)const;
+ virtual Color get_color(Context context, const Point &pos)const;
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual Vocab get_param_vocab()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file lineargradient.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "lineargradient.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(LinearGradient);
+SYNFIG_LAYER_SET_NAME(LinearGradient,"linear_gradient");
+SYNFIG_LAYER_SET_LOCAL_NAME(LinearGradient,_("Linear Gradient"));
+SYNFIG_LAYER_SET_CATEGORY(LinearGradient,_("Gradients"));
+SYNFIG_LAYER_SET_VERSION(LinearGradient,"0.0");
+SYNFIG_LAYER_SET_CVS_ID(LinearGradient,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+inline void
+LinearGradient::sync()
+{
+ diff=(p2-p1);
+ const Real mag(diff.inv_mag());
+ diff*=mag*mag;
+}
+
+
+LinearGradient::LinearGradient():
+ p1(1,1),
+ p2(-1,-1),
+ gradient(Color::black(), Color::white()),
+ loop(false),
+ zigzag(false)
+{
+ sync();
+}
+
+inline Color
+LinearGradient::color_func(const Point &point, float supersample)const
+{
+ Real dist(point*diff-p1*diff);
+
+ if(loop)
+ dist-=floor(dist);
+
+ if(zigzag)
+ {
+ dist*=2.0;
+ supersample*=2.0;
+ if(dist>1)dist=2.0-dist;
+ }
+
+ if(loop)
+ {
+ if(dist+supersample*0.5>1.0)
+ {
+ float left(supersample*0.5-(dist-1.0));
+ float right(supersample*0.5+(dist-1.0));
+ Color pool(gradient(1.0-(left*0.5),left).premult_alpha()*left/supersample);
+ if (zigzag) pool+=gradient(1.0-right*0.5,right).premult_alpha()*right/supersample;
+ else pool+=gradient(right*0.5,right).premult_alpha()*right/supersample;
+ return pool.demult_alpha();
+ }
+ if(dist-supersample*0.5<0.0)
+ {
+ float left(supersample*0.5-dist);
+ float right(supersample*0.5+dist);
+ Color pool(gradient(right*0.5,right).premult_alpha()*right/supersample);
+ if (zigzag) pool+=gradient(left*0.5,left).premult_alpha()*left/supersample;
+ else pool+=gradient(1.0-left*0.5,left).premult_alpha()*left/supersample;
+ return pool.demult_alpha();
+ }
+ }
+ return gradient(dist,supersample);
+}
+
+float
+LinearGradient::calc_supersample(const synfig::Point &/*x*/, float pw,float /*ph*/)const
+{
+ return pw/(p2-p1).mag();
+}
+
+synfig::Layer::Handle
+LinearGradient::hit_check(synfig::Context context, const synfig::Point &point)const
+{
+ if(get_blend_method()==Color::BLEND_STRAIGHT && get_amount()>=0.5)
+ return const_cast<LinearGradient*>(this);
+ if(get_amount()==0.0)
+ return context.hit_check(point);
+ if((get_blend_method()==Color::BLEND_STRAIGHT || get_blend_method()==Color::BLEND_COMPOSITE) && color_func(point).get_a()>0.5)
+ return const_cast<LinearGradient*>(this);
+ return context.hit_check(point);
+}
+
+bool
+LinearGradient::set_param(const String & param, const ValueBase &value)
+{
+ if(param=="p1" && value.same_type_as(p1))
+ {
+ p1=value.get(p1);
+ sync();
+ return true;
+ }
+ if(param=="p2" && value.same_type_as(p2))
+ {
+ p2=value.get(p2);
+ sync();
+ return true;
+ }
+ //IMPORT(p1);
+ //IMPORT(p2);
+
+
+ IMPORT(gradient);
+ IMPORT(loop);
+ IMPORT(zigzag);
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+LinearGradient::get_param(const String & param)const
+{
+ EXPORT(p1);
+ EXPORT(p2);
+ EXPORT(gradient);
+ EXPORT(loop);
+ EXPORT(zigzag);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+LinearGradient::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("p1")
+ .set_local_name(_("Point 1"))
+ .set_connect("p2")
+ );
+ ret.push_back(ParamDesc("p2")
+ .set_local_name(_("Point 2"))
+ );
+ ret.push_back(ParamDesc("gradient")
+ .set_local_name(_("Gradient"))
+ );
+ ret.push_back(ParamDesc("loop")
+ .set_local_name(_("Loop"))
+ );
+ ret.push_back(ParamDesc("zigzag")
+ .set_local_name(_("ZigZag"))
+ );
+
+ return ret;
+}
+
+Color
+LinearGradient::get_color(Context context, const Point &point)const
+{
+ const Color color(color_func(point));
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,context.get_color(point),get_amount(),get_blend_method());
+}
+
+bool
+LinearGradient::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ }
+ else
+ {
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+ if(get_amount()==0)
+ return true;
+ }
+
+
+ int x,y;
+
+ Surface::pen pen(surface->begin());
+ const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
+ Point pos;
+ Point tl(renddesc.get_tl());
+ const int w(surface->get_w());
+ const int h(surface->get_h());
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(color_func(pos,calc_supersample(pos,pw,ph)));
+ }
+ else
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(Color::blend(color_func(pos,calc_supersample(pos,pw,ph)),pen.get_value(),get_amount(),get_blend_method()));
+ }
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file lineargradient.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_INTERPOLATION_LINEARGRADIENT_H
+#define __SYNFIG_INTERPOLATION_LINEARGRADIENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/vector.h>
+#include <synfig/layer_composite.h>
+#include <synfig/gradient.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class LinearGradient : public Layer_Composite, public Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ Point p1,p2;
+ Vector diff;
+ Gradient gradient;
+
+ bool loop;
+ bool zigzag;
+
+ void sync();
+
+ synfig::Color color_func(const synfig::Point &x, float supersample=0)const;
+
+ float calc_supersample(const synfig::Point &x, float pw,float ph)const;
+
+public:
+ LinearGradient();
+
+ virtual bool set_param(const String ¶m, const ValueBase &value);
+ virtual ValueBase get_param(const String ¶m)const;
+ virtual Color get_color(Context context, const Point &pos)const;
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual Vocab get_param_vocab()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_gradient/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include <synfig/string.h>
+#include <synfig/canvas.h>
+
+#include "lineargradient.h"
+#include "radialgradient.h"
+#include "conicalgradient.h"
+#include "spiralgradient.h"
+#include "curvegradient.h"
+
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(libmod_gradient)
+ MODULE_NAME("Gradient")
+ MODULE_DESCRIPTION("Writeme")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(libmod_gradient)
+ BEGIN_LAYERS
+ LAYER(LinearGradient)
+ LAYER(RadialGradient)
+ LAYER(ConicalGradient)
+ LAYER(SpiralGradient)
+ LAYER(CurveGradient)
+ END_LAYERS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_gradient" Sec_mod_gradient
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_gradient.dll "src\modules\mod_gradient\.libs\libmod_gradient-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_gradient"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_gradient/radialgradient.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#include "radialgradient.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(RadialGradient);
+SYNFIG_LAYER_SET_NAME(RadialGradient,"radial_gradient");
+SYNFIG_LAYER_SET_LOCAL_NAME(RadialGradient,_("Radial Gradient"));
+SYNFIG_LAYER_SET_CATEGORY(RadialGradient,_("Gradients"));
+SYNFIG_LAYER_SET_VERSION(RadialGradient,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(RadialGradient,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+RadialGradient::RadialGradient():
+ Layer_Composite(1.0,Color::BLEND_STRAIGHT),
+ gradient(Color::black(),Color::white()),
+ center(0,0),
+ radius(0.5),
+ loop(false),
+ zigzag(false)
+{
+}
+
+bool
+RadialGradient::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(gradient);
+ IMPORT(center);
+ IMPORT(radius);
+ IMPORT(loop);
+ IMPORT(zigzag);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+RadialGradient::get_param(const String ¶m)const
+{
+ EXPORT(gradient);
+ EXPORT(center);
+ EXPORT(radius);
+ EXPORT(loop);
+ EXPORT(zigzag);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+RadialGradient::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("gradient")
+ .set_local_name(_("Gradient"))
+ );
+
+ ret.push_back(ParamDesc("center")
+ .set_local_name(_("Center"))
+ );
+
+ ret.push_back(ParamDesc("radius")
+ .set_local_name(_("Radius"))
+ .set_description(_("This is the radius of the circle"))
+ .set_is_distance()
+ .set_origin("center")
+ );
+
+ ret.push_back(ParamDesc("loop")
+ .set_local_name(_("Loop"))
+ );
+
+ ret.push_back(ParamDesc("zigzag")
+ .set_local_name(_("ZigZag"))
+ );
+
+ return ret;
+}
+
+inline Color
+RadialGradient::color_func(const Point &point, float supersample)const
+{
+ Real dist((point-center).mag()/radius);
+
+ if(zigzag)
+ {
+ dist*=2.0;
+ supersample*=2.0;
+ if(dist>1)dist=2.0-dist;
+ }
+
+ if(loop)
+ {
+ dist-=floor(dist);
+
+ if(dist+supersample*0.5>1.0)
+ {
+ float left(supersample*0.5-(dist-1.0));
+ float right(supersample*0.5+(dist-1.0));
+ Color pool(gradient(1.0-(left*0.5),left).premult_alpha()*left/supersample);
+ if (zigzag) pool+=gradient(1.0-right*0.5,right).premult_alpha()*right/supersample;
+ else pool+=gradient(right*0.5,right).premult_alpha()*right/supersample;
+ return pool.demult_alpha();
+ }
+ if(dist-supersample*0.5<0.0)
+ {
+ float left(supersample*0.5-dist);
+ float right(supersample*0.5+dist);
+ Color pool(gradient(right*0.5,right).premult_alpha()*right/supersample);
+ if (zigzag) pool+=gradient(left*0.5,left).premult_alpha()*left/supersample;
+ else pool+=gradient(1.0-left*0.5,left).premult_alpha()*left/supersample;
+ return pool.demult_alpha();
+ }
+ }
+
+ return gradient(dist,supersample);
+}
+
+
+float
+RadialGradient::calc_supersample(const synfig::Point &/*x*/, float pw,float /*ph*/)const
+{
+// return sqrt(pw*pw+ph*ph)/radius;
+ return 1.2*pw/radius;
+}
+
+synfig::Layer::Handle
+RadialGradient::hit_check(synfig::Context context, const synfig::Point &point)const
+{
+ if(get_blend_method()==Color::BLEND_STRAIGHT && get_amount()>=0.5)
+ return const_cast<RadialGradient*>(this);
+ if(get_amount()==0.0)
+ return context.hit_check(point);
+ if((get_blend_method()==Color::BLEND_STRAIGHT || get_blend_method()==Color::BLEND_COMPOSITE) && color_func(point).get_a()>0.5)
+ return const_cast<RadialGradient*>(this);
+ return context.hit_check(point);
+}
+
+Color
+RadialGradient::get_color(Context context, const Point &pos)const
+{
+ const Color color(color_func(pos));
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,context.get_color(pos),get_amount(),get_blend_method());
+}
+
+bool
+RadialGradient::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ }
+ else
+ {
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+ if(get_amount()==0)
+ return true;
+ }
+
+
+ int x,y;
+
+ Surface::pen pen(surface->begin());
+ const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
+ Point pos;
+ Point tl(renddesc.get_tl());
+ const int w(surface->get_w());
+ const int h(surface->get_h());
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(color_func(pos,calc_supersample(pos,pw,ph)));
+ }
+ else
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(Color::blend(color_func(pos,calc_supersample(pos,pw,ph)),pen.get_value(),get_amount(),get_blend_method()));
+ }
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file radialgradient.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_RADIALGRADIENT_H
+#define __SYNFIG_RADIALGRADIENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+#include <synfig/value.h>
+#include <synfig/gradient.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class RadialGradient : public synfig::Layer_Composite, public synfig::Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ synfig::Gradient gradient;
+
+ synfig::Point center;
+
+ synfig::Real radius;
+
+ bool loop;
+ bool zigzag;
+
+ synfig::Color color_func(const synfig::Point &x, float supersample=0)const;
+
+ float calc_supersample(const synfig::Point &x, float pw,float ph)const;
+
+public:
+
+ RadialGradient();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+
+ virtual synfig::ValueBase get_param(const synfig::String & param)const;
+
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+
+ virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual Vocab get_param_vocab()const;
+}; // END of class RadialGradient
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file spiralgradient.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#include "spiralgradient.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(SpiralGradient);
+SYNFIG_LAYER_SET_NAME(SpiralGradient,"spiral_gradient");
+SYNFIG_LAYER_SET_LOCAL_NAME(SpiralGradient,_("Spiral Gradient"));
+SYNFIG_LAYER_SET_CATEGORY(SpiralGradient,_("Gradients"));
+SYNFIG_LAYER_SET_VERSION(SpiralGradient,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(SpiralGradient,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+SpiralGradient::SpiralGradient():
+ Layer_Composite(1.0,Color::BLEND_STRAIGHT),
+ gradient(Color::black(),Color::white()),
+ center(0,0),
+ radius(0.5),
+ angle(Angle::zero()),
+ clockwise(false)
+{
+}
+
+bool
+SpiralGradient::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(gradient);
+ IMPORT(center);
+ IMPORT(radius);
+ IMPORT(angle);
+ IMPORT(clockwise);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+SpiralGradient::get_param(const String ¶m)const
+{
+ EXPORT(gradient);
+ EXPORT(center);
+ EXPORT(radius);
+ EXPORT(angle);
+ EXPORT(clockwise);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+SpiralGradient::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("gradient")
+ .set_local_name(_("Gradient"))
+ );
+
+ ret.push_back(ParamDesc("center")
+ .set_local_name(_("Center"))
+ );
+
+ ret.push_back(ParamDesc("radius")
+ .set_local_name(_("Radius"))
+ .set_description(_("This is the radius of the circle"))
+ .set_is_distance()
+ .set_origin("center")
+ );
+
+ ret.push_back(ParamDesc("angle")
+ .set_local_name(_("Angle"))
+ .set_origin("center")
+ );
+
+ ret.push_back(ParamDesc("clockwise")
+ .set_local_name(_("Clockwise"))
+ );
+
+ return ret;
+}
+
+inline Color
+SpiralGradient::color_func(const Point &pos, float supersample)const
+{
+ const Point centered(pos-center);
+ Angle a;
+ a=Angle::tan(-centered[1],centered[0]).mod();
+ a=a+angle;
+
+ if(supersample<0.00001)supersample=0.00001;
+
+ Real dist((pos-center).mag()/radius);
+ if(clockwise)
+ dist+=Angle::rot(a.mod()).get();
+ else
+ dist-=Angle::rot(a.mod()).get();
+
+ dist-=floor(dist);
+ if(dist+supersample*0.5>1.0)
+ {
+ float left(supersample*0.5-(dist-1.0));
+ float right(supersample*0.5+(dist-1.0));
+ Color pool(gradient(1.0-(left*0.5),left).premult_alpha()*left/supersample);
+ pool+=gradient(right*0.5,right).premult_alpha()*right/supersample;
+ return pool.demult_alpha();
+ }
+ if(dist-supersample*0.5<0.0)
+ {
+ float left(supersample*0.5-dist);
+ float right(supersample*0.5+dist);
+ Color pool(gradient(right*0.5,right).premult_alpha()*right/supersample);
+ pool+=gradient(1.0-left*0.5,left).premult_alpha()*left/supersample;
+ return pool.demult_alpha();
+ }
+
+ return gradient(dist,supersample);
+}
+
+float
+SpiralGradient::calc_supersample(const synfig::Point &x, float pw,float /*ph*/)const
+{
+ return (1.41421*pw/radius+(1.41421*pw/Point(x-center).mag())/(PI*2))*0.5;
+}
+
+synfig::Layer::Handle
+SpiralGradient::hit_check(synfig::Context context, const synfig::Point &point)const
+{
+ if(get_blend_method()==Color::BLEND_STRAIGHT && get_amount()>=0.5)
+ return const_cast<SpiralGradient*>(this);
+ if(get_amount()==0.0)
+ return context.hit_check(point);
+ if((get_blend_method()==Color::BLEND_STRAIGHT || get_blend_method()==Color::BLEND_COMPOSITE) && color_func(point).get_a()>0.5)
+ return const_cast<SpiralGradient*>(this);
+ return context.hit_check(point);
+}
+
+Color
+SpiralGradient::get_color(Context context, const Point &pos)const
+{
+ const Color color(color_func(pos));
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,context.get_color(pos),get_amount(),get_blend_method());
+}
+
+bool
+SpiralGradient::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ }
+ else
+ {
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+ if(get_amount()==0)
+ return true;
+ }
+
+
+ int x,y;
+
+ Surface::pen pen(surface->begin());
+ const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
+ Point pos;
+ Point tl(renddesc.get_tl());
+ const int w(surface->get_w());
+ const int h(surface->get_h());
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(color_func(pos,calc_supersample(pos,pw,ph)));
+ }
+ else
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(Color::blend(color_func(pos,calc_supersample(pos,pw,ph)),pen.get_value(),get_amount(),get_blend_method()));
+ }
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file spiralgradient.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_SPIRALGRADIENT_H
+#define __SYNFIG_SPIRALGRADIENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/layer_composite.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+#include <synfig/value.h>
+#include <synfig/gradient.h>
+#include <synfig/angle.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class SpiralGradient : public synfig::Layer_Composite, public synfig::Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ synfig::Gradient gradient;
+
+ synfig::Point center;
+
+ synfig::Real radius;
+
+ synfig::Angle angle;
+
+ bool clockwise;
+
+ synfig::Color color_func(const synfig::Point &x, float supersample=0)const;
+
+ float calc_supersample(const synfig::Point &x, float pw,float ph)const;
+
+public:
+
+ SpiralGradient();
+
+ virtual bool set_param(const synfig::String & param, const synfig::ValueBase &value);
+
+ virtual synfig::ValueBase get_param(const synfig::String & param)const;
+
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+
+ virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+ virtual Vocab get_param_vocab()const;
+}; // END of class SpiralGradient
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_gradient"
+ Delete "$INSTDIR\lib\synfig\modules\mod_gradient.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+if WITH_IMAGEMAGICK
+module_LTLIBRARIES = libmod_imagemagick.la
+libmod_imagemagick_la_SOURCES = main.cpp mptr_imagemagick.cpp mptr_imagemagick.h trgt_imagemagick.cpp trgt_imagemagick.h
+libmod_imagemagick_la_LDFLAGS = -module -no-undefined
+libmod_imagemagick_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_imagemagick_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+else
+endif
+
+
+EXTRA_DIST= mod_imagemagick.nsh unmod_imagemagick.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_imagemagick/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include "mptr_imagemagick.h"
+#include "trgt_imagemagick.h"
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(mod_imagemagick)
+ MODULE_NAME("ImageMagick Module")
+ MODULE_DESCRIPTION("Provides targets and importers for nearly every format that ImageMagick supports")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(mod_imagemagick)
+ BEGIN_TARGETS
+ TARGET(imagemagick_trgt)
+ TARGET_EXT(imagemagick_trgt,"jpg")
+ TARGET_EXT(imagemagick_trgt,"jpeg")
+ TARGET_EXT(imagemagick_trgt,"png")
+ TARGET_EXT(imagemagick_trgt,"tga")
+ TARGET_EXT(imagemagick_trgt,"tif")
+ TARGET_EXT(imagemagick_trgt,"tiff")
+ TARGET_EXT(imagemagick_trgt,"pcx")
+ TARGET_EXT(imagemagick_trgt,"ps")
+ TARGET_EXT(imagemagick_trgt,"pdf")
+ TARGET_EXT(imagemagick_trgt,"pgm")
+ TARGET_EXT(imagemagick_trgt,"psd")
+ TARGET_EXT(imagemagick_trgt,"xcf")
+ TARGET_EXT(imagemagick_trgt,"svg")
+ TARGET_EXT(imagemagick_trgt,"xpm")
+ TARGET_EXT(imagemagick_trgt,"miff")
+ TARGET_EXT(imagemagick_trgt,"eps")
+ TARGET_EXT(imagemagick_trgt,"cmyk")
+ TARGET_EXT(imagemagick_trgt,"gif")
+ END_TARGETS
+ BEGIN_IMPORTERS
+ IMPORTER_EXT(imagemagick_mptr,"jpg")
+ IMPORTER_EXT(imagemagick_mptr,"jpeg")
+ IMPORTER_EXT(imagemagick_mptr,"png")
+ IMPORTER_EXT(imagemagick_mptr,"bmp")
+ IMPORTER_EXT(imagemagick_mptr,"gif")
+ IMPORTER_EXT(imagemagick_mptr,"pcx")
+ IMPORTER_EXT(imagemagick_mptr,"tif")
+ IMPORTER_EXT(imagemagick_mptr,"tiff")
+ IMPORTER_EXT(imagemagick_mptr,"tga")
+ IMPORTER_EXT(imagemagick_mptr,"ps")
+ IMPORTER_EXT(imagemagick_mptr,"pdf")
+ IMPORTER_EXT(imagemagick_mptr,"pgm")
+ IMPORTER_EXT(imagemagick_mptr,"psd")
+ IMPORTER_EXT(imagemagick_mptr,"xcf")
+ IMPORTER_EXT(imagemagick_mptr,"svg")
+ IMPORTER_EXT(imagemagick_mptr,"tim")
+ IMPORTER_EXT(imagemagick_mptr,"xpm")
+ IMPORTER_EXT(imagemagick_mptr,"miff")
+ IMPORTER_EXT(imagemagick_mptr,"ico")
+ IMPORTER_EXT(imagemagick_mptr,"eps")
+ IMPORTER_EXT(imagemagick_mptr,"ttf")
+ IMPORTER_EXT(imagemagick_mptr,"pix")
+ IMPORTER_EXT(imagemagick_mptr,"rla")
+ IMPORTER_EXT(imagemagick_mptr,"mat")
+ IMPORTER_EXT(imagemagick_mptr,"html")
+ IMPORTER_EXT(imagemagick_mptr,"ept")
+ IMPORTER_EXT(imagemagick_mptr,"dcm")
+ IMPORTER_EXT(imagemagick_mptr,"fig")
+ END_IMPORTERS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_imagemagick" Sec_mod_imagemagick
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_imagemagick.dll "src\modules\mod_imagemagick\.libs\libmod_imagemagick-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_imagemagick"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_imagemagick.cpp
+** \brief ppm Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ETL/stringf>
+#include "mptr_imagemagick.h"
+#include <stdio.h>
+#include <algorithm>
+#include <functional>
+#include <ETL/stringf>
+#include <synfig/general.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_IMPORTER_INIT(imagemagick_mptr);
+SYNFIG_IMPORTER_SET_NAME(imagemagick_mptr,"imagemagick");
+SYNFIG_IMPORTER_SET_EXT(imagemagick_mptr,"miff");
+SYNFIG_IMPORTER_SET_VERSION(imagemagick_mptr,"0.1");
+SYNFIG_IMPORTER_SET_CVS_ID(imagemagick_mptr,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+
+imagemagick_mptr::imagemagick_mptr(const char *f)
+{
+
+ filename=f;
+ file=NULL;
+}
+
+imagemagick_mptr::~imagemagick_mptr()
+{
+ if(file)
+ pclose(file);
+}
+
+bool
+imagemagick_mptr::get_frame(synfig::Surface &surface,Time /*time*/, synfig::ProgressCallback *cb)
+{
+//#define HAS_LIBPNG 1
+
+#if 1
+ if(file)
+ pclose(file);
+
+ string command;
+
+ if(filename.empty())
+ {
+ if(cb)cb->error(_("No file to load"));
+ else synfig::error(_("No file to load"));
+ return false;
+ }
+ string temp_file="/tmp/deleteme.png";
+
+ if(filename.find("psd")!=String::npos)
+ command=strprintf("convert \"%s\" -flatten \"png32:%s\"\n",filename.c_str(),temp_file.c_str());
+ else
+ command=strprintf("convert \"%s\" \"png32:%s\"\n",filename.c_str(),temp_file.c_str());
+
+ synfig::info("command=%s",command.c_str());
+
+ if(system(command.c_str())!=0)
+ return false;
+
+ Importer::Handle importer(Importer::open(temp_file));
+
+ DEBUGPOINT();
+
+ if(!importer)
+ {
+ if(cb)cb->error(_("Unable to open ")+temp_file);
+ else synfig::error(_("Unable to open ")+temp_file);
+ return false;
+ }
+
+ DEBUGPOINT();
+
+ if(!importer->get_frame(surface,0,cb))
+ {
+ if(cb)cb->error(_("Unable to get frame from ")+temp_file);
+ else synfig::error(_("Unable to get frame from ")+temp_file);
+ return false;
+ }
+
+ if(!surface)
+ {
+ if(cb)cb->error(_("Bad surface from ")+temp_file);
+ else synfig::error(_("Bad surface from ")+temp_file);
+ return false;
+ }
+
+ if(1)
+ {
+ // remove odd premultiplication
+ for(int i=0;i<surface.get_w()*surface.get_h();i++)
+ {
+ Color c(surface[0][i]);
+
+ if(c.get_a())
+ {
+ surface[0][i].set_r(c.get_r()/c.get_a()/c.get_a());
+ surface[0][i].set_g(c.get_g()/c.get_a()/c.get_a());
+ surface[0][i].set_b(c.get_b()/c.get_a()/c.get_a());
+ }
+ else
+ {
+ surface[0][i].set_r(0);
+ surface[0][i].set_g(0);
+ surface[0][i].set_b(0);
+ }
+ surface[0][i].set_a(c.get_a());
+ }
+ }
+
+ Surface bleh(surface);
+ surface=bleh;
+
+
+ //remove(temp_file.c_str());
+ DEBUGPOINT();
+ return true;
+
+#else
+ if(file)
+ pclose(file);
+
+ string command;
+
+ if(filename.empty())
+ {
+ if(cb)cb->error(_("No file to load"));
+ else synfig::error(_("No file to load"));
+ return false;
+ }
+
+ command=strprintf("convert \"%s\" -flatten ppm:-\n",filename.c_str());
+
+ file=popen(command.c_str(),"r");
+
+ if(!file)
+ {
+ if(cb)cb->error(_("Unable to open pipe to imagemagick"));
+ else synfig::error(_("Unable to open pipe to imagemagick"));
+ return false;
+ }
+ int w,h;
+ float divisor;
+ char cookie[2];
+
+ while((cookie[0]=fgetc(file))!='P' && !feof(file));
+
+ if(feof(file))
+ {
+ if(cb)cb->error(_("Reached end of stream without finding PPM header"));
+ else synfig::error(_("Reached end of stream without finding PPM header"));
+ return false;
+ }
+
+ cookie[1]=fgetc(file);
+
+ if(cookie[0]!='P' || cookie[1]!='6')
+ {
+ if(cb)cb->error(string(_("stream not in PPM format"))+" \""+cookie[0]+cookie[1]+'"');
+ else synfig::error(string(_("stream not in PPM format"))+" \""+cookie[0]+cookie[1]+'"');
+ return false;
+ }
+
+ fgetc(file);
+ fscanf(file,"%d %d\n",&w,&h);
+ fscanf(file,"%f",&divisor);
+ fgetc(file);
+
+ if(feof(file))
+ {
+ if(cb)cb->error(_("Premature end of file (after header)"));
+ else synfig::error(_("Premature end of file (after header)"));
+ return false;
+ }
+
+ int x;
+ int y;
+ frame.set_wh(w,h);
+ for(y=0;y<frame.get_h();y++)
+ for(x=0;x<frame.get_w();x++)
+ {
+ if(feof(file))
+ {
+ if(cb)cb->error(_("Premature end of file"));
+ else synfig::error(_("Premature end of file"));
+ return false;
+ }
+ float b=gamma().r_U8_to_F32((unsigned char)fgetc(file));
+ float g=gamma().g_U8_to_F32((unsigned char)fgetc(file));
+ float r=gamma().b_U8_to_F32((unsigned char)fgetc(file));
+/*
+ float b=(float)(unsigned char)fgetc(file)/divisor;
+ float g=(float)(unsigned char)fgetc(file)/divisor;
+ float r=(float)(unsigned char)fgetc(file)/divisor;
+*/
+ frame[y][x]=Color(
+ b,
+ g,
+ r,
+ 1.0
+ );
+ }
+
+ surface=frame;
+
+ return true;
+#endif
+
+
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_imagemagick.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_MPTR_IMAGEMAGICK_H
+#define __SYNFIG_MPTR_IMAGEMAGICK_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/importer.h>
+#include <stdio.h>
+#include "string.h"
+#include <synfig/surface.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class imagemagick_mptr : public synfig::Importer
+{
+ SYNFIG_IMPORTER_MODULE_EXT
+private:
+ synfig::String filename;
+ FILE *file;
+ int cur_frame;
+ synfig::Surface frame;
+
+public:
+ imagemagick_mptr(const char *filename);
+
+ ~imagemagick_mptr();
+
+ virtual bool get_frame(synfig::Surface &surface,synfig::Time time, synfig::ProgressCallback *callback);
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_imagemagick.cpp
+** \brief ppm Target Module
+**
+** \legal
+** $Id$
+**
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_TARGET
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ETL/stringf>
+#include "trgt_imagemagick.h"
+#include <stdio.h>
+#include <algorithm>
+#include <functional>
+#include <ETL/clock>
+#include <ETL/misc>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_TARGET_INIT(imagemagick_trgt);
+SYNFIG_TARGET_SET_NAME(imagemagick_trgt,"imagemagick");
+SYNFIG_TARGET_SET_EXT(imagemagick_trgt,"miff");
+SYNFIG_TARGET_SET_VERSION(imagemagick_trgt,"0.1");
+SYNFIG_TARGET_SET_CVS_ID(imagemagick_trgt,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+imagemagick_trgt::imagemagick_trgt(const char *Filename)
+{
+ file=NULL;
+ filename=Filename;
+ multi_image=false;
+ buffer=NULL;
+ color_buffer=0;
+}
+
+imagemagick_trgt::~imagemagick_trgt()
+{
+ if(file)
+ pclose(file);
+ file=NULL;
+ delete [] buffer;
+ delete [] color_buffer;
+}
+
+bool
+imagemagick_trgt::set_rend_desc(RendDesc *given_desc)
+{
+ String ext(find(filename.begin(),filename.end(),'.')+1,filename.end());
+ if(ext=="xpm")
+ pf=PF_RGB;
+ else
+ pf=PF_RGB|PF_A;
+
+ desc=*given_desc;
+ return true;
+}
+
+bool
+imagemagick_trgt::init()
+{
+ imagecount=desc.get_frame_start();
+ if(desc.get_frame_end()-desc.get_frame_start()>0)
+ multi_image=true;
+
+ delete [] buffer;
+ buffer=new unsigned char[channels(pf)*desc.get_w()];
+ delete [] color_buffer;
+ color_buffer=new Color[desc.get_w()];
+ return true;
+}
+
+void
+imagemagick_trgt::end_frame()
+{
+ if(file)
+ {
+ fputc(0,file);
+ fflush(file);
+ pclose(file);
+ }
+ file=NULL;
+}
+
+bool
+imagemagick_trgt::start_frame(synfig::ProgressCallback *cb)
+{
+ string command;
+
+ if(channels(pf)==4)
+ command=strprintf("convert -depth 8 -size %dx%d rgba:-[0] -density %dx%d \"%s\"\n",desc.get_w(),desc.get_h(),round_to_int(desc.get_x_res()/39.3700787402),round_to_int(desc.get_y_res()/39.3700787402),filename.c_str());
+ else
+ command=strprintf("convert -depth 8 -size %dx%d rgb:-[0] -density %dx%d \"%s\"\n",desc.get_w(),desc.get_h(),round_to_int(desc.get_x_res()/39.3700787402),round_to_int(desc.get_y_res()/39.3700787402),filename.c_str());
+
+ file=popen(command.c_str(),"w");
+
+ if(!file)
+ {
+ const char *msg=_("Unable to open pipe to imagemagick's convert utility");
+ if(cb)cb->error(N_(msg));
+ else synfig::error(N_(msg));
+ return false;
+ }
+
+ //etl::yield();
+
+ return true;
+}
+
+Color *
+imagemagick_trgt::start_scanline(int /*scanline*/)
+{
+ return color_buffer;
+}
+
+bool
+imagemagick_trgt::end_scanline(void)
+{
+ if(!file)
+ return false;
+
+ convert_color_format(buffer, color_buffer, desc.get_w(), pf, gamma());
+
+ if(!fwrite(buffer,channels(pf),desc.get_w(),file))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_imagemagick.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRGT_IMAGEMAGICK_H
+#define __SYNFIG_TRGT_IMAGEMAGICK_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/target_scanline.h>
+#include <synfig/string.h>
+#include <cstdio>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+
+class imagemagick_trgt : public synfig::Target_Scanline
+{
+ SYNFIG_TARGET_MODULE_EXT
+private:
+ int imagecount;
+ bool multi_image;
+ FILE *file;
+ synfig::String filename;
+ unsigned char *buffer;
+ synfig::Color *color_buffer;
+ synfig::PixelFormat pf;
+public:
+ imagemagick_trgt(const char *filename);
+ virtual ~imagemagick_trgt();
+
+ virtual bool set_rend_desc(synfig::RendDesc *desc);
+ virtual bool init();
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+ virtual void end_frame();
+ virtual synfig::Color * start_scanline(int scanline);
+ virtual bool end_scanline();
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_imagemagick"
+ Delete "$INSTDIR\lib\synfig\modules\mod_imagemagick.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+if HAVE_LIBJPEG
+module_LTLIBRARIES = libmod_jpeg.la
+libmod_jpeg_la_SOURCES = main.cpp trgt_jpeg.cpp trgt_jpeg.h mptr_jpeg.cpp mptr_jpeg.h
+libmod_jpeg_la_LDFLAGS = -module @JPEG_LIBS@ -no-undefined
+libmod_jpeg_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_jpeg_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+else
+endif
+EXTRA_DIST= mod_jpeg.nsh unmod_jpeg.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_jpeg/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include "trgt_jpeg.h"
+#include "mptr_jpeg.h"
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(mod_jpeg)
+ MODULE_NAME("JPEG Module (libjpeg)")
+ MODULE_DESCRIPTION("Provides a JPEG target and importer")
+ MODULE_AUTHOR("Robert B. Quattlebaum Jr")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(mod_jpeg)
+ BEGIN_TARGETS
+ TARGET(jpeg_trgt)
+ TARGET_EXT(jpeg_trgt,"jpeg")
+ TARGET_EXT(jpeg_trgt,"jpg")
+ END_TARGETS
+ BEGIN_IMPORTERS
+ IMPORTER_EXT(jpeg_mptr,"jpg")
+ IMPORTER_EXT(jpeg_mptr,"jpeg")
+ END_IMPORTERS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_jpeg" Sec_mod_jpeg
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_jpeg.dll "src\modules\mod_jpeg\.libs\libmod_jpeg-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_jpeg"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_jpeg.cpp
+** \brief ppm Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/*! \todo Support 16 bit JPEG files
+** \todo Support for paletted JPEG files
+** \todo Support GAMMA correction
+** \todo Fix memory leaks
+*/
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "mptr_jpeg.h"
+#include <synfig/importer.h>
+#include <synfig/time.h>
+#include <synfig/general.h>
+
+
+#include <cstdio>
+#include <algorithm>
+#include <functional>
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+#define JPEG_CHECK_BYTES 8
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_IMPORTER_INIT(jpeg_mptr);
+SYNFIG_IMPORTER_SET_NAME(jpeg_mptr,"jpeg");
+SYNFIG_IMPORTER_SET_EXT(jpeg_mptr,"jpg");
+SYNFIG_IMPORTER_SET_VERSION(jpeg_mptr,"0.1");
+SYNFIG_IMPORTER_SET_CVS_ID(jpeg_mptr,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+struct my_error_mgr {
+ struct jpeg_error_mgr pub; /* "public" fields */
+
+ jmp_buf setjmp_buffer; /* for return to caller */
+};
+
+typedef struct my_error_mgr * my_error_ptr;
+
+/*
+ * Here's the routine that will replace the standard error_exit method:
+ */
+
+void
+jpeg_mptr::my_error_exit (j_common_ptr cinfo)
+{
+ /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
+ my_error_ptr myerr = (my_error_ptr) cinfo->err;
+
+ /* Always display the message. */
+ /* We could postpone this until after returning, if we chose. */
+ (*cinfo->err->output_message) (cinfo);
+
+ /* Return control to the setjmp point */
+ longjmp(myerr->setjmp_buffer, 1);
+}
+
+
+
+
+
+jpeg_mptr::jpeg_mptr(const char *file_name)
+{
+ struct my_error_mgr jerr;
+ filename=file_name;
+
+ /* Open the file pointer */
+ FILE *file = fopen(file_name, "rb");
+ if (!file)
+ {
+ //! \todo THROW SOMETHING
+ throw String("error on importer construction, *WRITEME*1");
+ return;
+ }
+
+ /* Step 1: allocate and initialize JPEG decompression object */
+
+ /* We set up the normal JPEG error routines, then override error_exit. */
+ cinfo.err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = my_error_exit;
+ /* Establish the setjmp return context for my_error_exit to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error.
+ * We need to clean up the JPEG object, close the input file, and return.
+ */
+ jpeg_destroy_decompress(&cinfo);
+ fclose(file);
+ throw String("error on importer construction, *WRITEME*2");
+ }
+ /* Now we can initialize the JPEG decompression object. */
+ jpeg_create_decompress(&cinfo);
+
+ /* Step 2: specify data source (eg, a file) */
+
+ jpeg_stdio_src(&cinfo, file);
+
+ /* Step 3: read file parameters with jpeg_read_header() */
+
+ (void) jpeg_read_header(&cinfo, TRUE);
+ /* We can ignore the return value from jpeg_read_header since
+ * (a) suspension is not possible with the stdio data source, and
+ * (b) we passed TRUE to reject a tables-only JPEG file as an error.
+ * See libjpeg.doc for more info.
+ */
+
+ /* Step 4: set parameters for decompression */
+
+ /* In this example, we don't need to change any of the defaults set by
+ * jpeg_read_header(), so we do nothing here.
+ */
+
+ /* Step 5: Start decompressor */
+
+ (void) jpeg_start_decompress(&cinfo);
+ /* We can ignore the return value since suspension is not possible
+ * with the stdio data source.
+ */
+
+ JSAMPARRAY buffer; /* Output row buffer */
+ int row_stride; /* physical row width in output buffer */
+ row_stride = cinfo.output_width * cinfo.output_components;
+ /* Make a one-row-high sample array that will go away when done with image */
+ buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
+
+ if(!buffer)
+ {
+ synfig::error("jpeg_mptr: error: alloc of \"buffer\" failed (bug?)");
+ throw String("alloc of \"buffer\" failed (bug?)");
+ }
+
+ int x;
+ int y;
+ surface_buffer.set_wh(cinfo.output_width,cinfo.output_height);
+
+ switch(cinfo.output_components)
+ {
+ case 3:
+ for(y=0;y<surface_buffer.get_h();y++)
+ {
+ int x;
+ jpeg_read_scanlines(&cinfo, buffer, 1);
+ for(x=0;x<surface_buffer.get_w();x++)
+ {
+ float r=gamma().g_U8_to_F32((unsigned char)buffer[0][x*3+0]);
+ float g=gamma().g_U8_to_F32((unsigned char)buffer[0][x*3+1]);
+ float b=gamma().g_U8_to_F32((unsigned char)buffer[0][x*3+2]);
+ surface_buffer[y][x]=Color(
+ r,
+ g,
+ b,
+ 1.0
+ );
+/*
+ surface_buffer[y][x]=Color(
+ (float)(unsigned char)buffer[0][x*3+0]*(1.0/255.0),
+ (float)(unsigned char)buffer[0][x*3+1]*(1.0/255.0),
+ (float)(unsigned char)buffer[0][x*3+2]*(1.0/255.0),
+ 1.0
+ );
+*/
+ }
+ }
+ break;
+
+ case 1:
+ for(y=0;y<surface_buffer.get_h();y++)
+ {
+ jpeg_read_scanlines(&cinfo, buffer, 1);
+ for(x=0;x<surface_buffer.get_w();x++)
+ {
+ float gray=gamma().g_U8_to_F32((unsigned char)buffer[0][x]);
+// float gray=(float)(unsigned char)buffer[0][x]*(1.0/255.0);
+ surface_buffer[y][x]=Color(
+ gray,
+ gray,
+ gray,
+ 1.0
+ );
+ }
+ }
+ break;
+
+ default:
+ synfig::error("jpeg_mptr: error: Unsupported color type");
+ //! \todo THROW SOMETHING
+ throw String("error on importer construction, *WRITEME*6");
+ return;
+ }
+
+ /* Step 7: Finish decompression */
+
+ (void) jpeg_finish_decompress(&cinfo);
+ /* We can ignore the return value since suspension is not possible
+ * with the stdio data source.
+ */
+
+ /* Step 8: Release JPEG decompression object */
+
+ /* This is an important step since it will release a good deal of memory. */
+ jpeg_destroy_decompress(&cinfo);
+
+ /* After finish_decompress, we can close the input file.
+ * Here we postpone it until after no more JPEG errors are possible,
+ * so as to simplify the setjmp error logic above. (Actually, I don't
+ * think that jpeg_destroy can do an error exit, but why assume anything...)
+ */
+ fclose(file);
+}
+
+jpeg_mptr::~jpeg_mptr()
+{
+}
+
+bool
+jpeg_mptr::get_frame(synfig::Surface &surface,Time, synfig::ProgressCallback */*cb*/)
+{
+ surface.mirror(surface_buffer);
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_jpeg.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_MPTR_JPEG_H
+#define __SYNFIG_MPTR_JPEG_H
+
+/* === H E A D E R S ======================================================= */
+
+#define NOMINMAX
+#include <synfig/importer.h>
+#include <synfig/string.h>
+#include <synfig/surface.h>
+_ETL_BEGIN_CDECLS
+#include <jpeglib.h>
+_ETL_END_CDECLS
+#include <setjmp.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class jpeg_mptr : public synfig::Importer
+{
+ SYNFIG_IMPORTER_MODULE_EXT
+private:
+ synfig::String filename;
+ synfig::Surface surface_buffer;
+
+ struct jpeg_decompress_struct cinfo;
+
+ static void my_error_exit (j_common_ptr cinfo);
+
+public:
+ jpeg_mptr(const char *filename);
+ ~jpeg_mptr();
+
+ virtual bool get_frame(synfig::Surface &surface,synfig::Time time, synfig::ProgressCallback *callback);
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_jpeg.cpp
+** \brief jpeg_trgt Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_TARGET
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trgt_jpeg.h"
+#include <jpeglib.h>
+#include <ETL/stringf>
+#include <cstdio>
+#include <algorithm>
+#include <functional>
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_TARGET_INIT(jpeg_trgt);
+SYNFIG_TARGET_SET_NAME(jpeg_trgt,"jpeg");
+SYNFIG_TARGET_SET_EXT(jpeg_trgt,"jpg");
+SYNFIG_TARGET_SET_VERSION(jpeg_trgt,"0.1");
+SYNFIG_TARGET_SET_CVS_ID(jpeg_trgt,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+jpeg_trgt::jpeg_trgt(const char *Filename)
+{
+ file=NULL;
+ filename=Filename;
+ buffer=NULL;
+ ready=false;
+ quality=95;
+ color_buffer=0;
+ set_remove_alpha();
+}
+
+jpeg_trgt::~jpeg_trgt()
+{
+ if(ready)
+ {
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+ ready=false;
+ }
+ if(file)
+ fclose(file);
+ file=NULL;
+ delete [] buffer;
+ delete [] color_buffer;
+}
+
+bool
+jpeg_trgt::set_rend_desc(RendDesc *given_desc)
+{
+ desc=*given_desc;
+ imagecount=desc.get_frame_start();
+ if(desc.get_frame_end()-desc.get_frame_start()>0)
+ multi_image=true;
+ else
+ multi_image=false;
+ return true;
+}
+
+bool
+jpeg_trgt::start_frame(synfig::ProgressCallback *callback)
+{
+ int w=desc.get_w(),h=desc.get_h();
+
+ if(file && file!=stdout)
+ fclose(file);
+ if(filename=="-")
+ {
+ if(callback)callback->task(strprintf("(stdout) %d",imagecount).c_str());
+ file=stdout;
+ }
+ else if(multi_image)
+ {
+ String
+ newfilename(filename),
+ ext(find(filename.begin(),filename.end(),'.'),filename.end());
+ newfilename.erase(find(newfilename.begin(),newfilename.end(),'.'),newfilename.end());
+
+ newfilename+=etl::strprintf("%04d",imagecount)+ext;
+ file=fopen(newfilename.c_str(),"wb");
+ if(callback)callback->task(newfilename);
+ }
+ else
+ {
+ file=fopen(filename.c_str(),"wb");
+ if(callback)callback->task(filename);
+ }
+
+ if(!file)
+ return false;
+
+ delete [] buffer;
+ buffer=new unsigned char[3*w];
+
+ delete [] color_buffer;
+ color_buffer=new Color[w];
+
+
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+ jpeg_stdio_dest(&cinfo, file);
+
+ cinfo.image_width = w; /* image width and height, in pixels */
+ cinfo.image_height = h;
+ cinfo.input_components = 3; /* # of color components per pixel */
+ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
+ /* Now use the library's routine to set default compression parameters.
+ * (You must set at least cinfo.in_color_space before calling this,
+ * since the defaults depend on the source color space.)
+ */
+ jpeg_set_defaults(&cinfo);
+ /* Now you can set any non-default parameters you wish to.
+ * Here we just illustrate the use of quality (quantization table) scaling:
+ */
+ jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
+
+ /* Step 4: Start compressor */
+
+ /* TRUE ensures that we will write a complete interchange-JPEG file.
+ * Pass TRUE unless you are very sure of what you're doing.
+ */
+ jpeg_start_compress(&cinfo, TRUE);
+
+ ready=true;
+ return true;
+}
+
+void
+jpeg_trgt::end_frame()
+{
+ if(ready)
+ {
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+ ready=false;
+ }
+
+ if(file && file!=stdout)
+ fclose(file);
+ file=NULL;
+ imagecount++;
+}
+
+Color *
+jpeg_trgt::start_scanline(int /*scanline*/)
+{
+ return color_buffer;
+}
+
+bool
+jpeg_trgt::end_scanline()
+{
+ if(!file || !ready)
+ return false;
+
+ convert_color_format(buffer, color_buffer, desc.get_w(), PF_RGB,gamma());
+ JSAMPROW *row_pointer(&buffer);
+ jpeg_write_scanlines(&cinfo, row_pointer, 1);
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_jpeg.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRGT_JPEG_H
+#define __SYNFIG_TRGT_JPEG_H
+
+/* === H E A D E R S ======================================================= */
+
+#define NOMINMAX
+#include <synfig/target_scanline.h>
+#include <synfig/string.h>
+#include <cstdio>
+_ETL_BEGIN_CDECLS
+#include <jpeglib.h>
+_ETL_END_CDECLS
+#include <setjmp.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class jpeg_trgt : public synfig::Target_Scanline
+{
+ SYNFIG_TARGET_MODULE_EXT
+private:
+ FILE *file;
+ int w,h,quality;
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+
+
+ bool multi_image,ready;
+ int imagecount;
+ synfig::String filename;
+ unsigned char *buffer;
+ synfig::Color *color_buffer;
+public:
+ jpeg_trgt(const char *filename);
+ virtual ~jpeg_trgt();
+
+ virtual bool set_rend_desc(synfig::RendDesc *desc);
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+ virtual void end_frame();
+
+ virtual synfig::Color * start_scanline(int scanline);
+ virtual bool end_scanline();
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_jpeg"
+ Delete "$INSTDIR\lib\synfig\modules\mod_jpeg.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+if WITH_LIBAVCODEC
+module_LTLIBRARIES = libmod_libavcodec.la
+libmod_libavcodec_la_SOURCES = main.cpp trgt_av.cpp trgt_av.h mptr.cpp mptr.h
+libmod_libavcodec_la_LDFLAGS = -module -no-undefined
+libmod_libavcodec_la_CXXFLAGS = @SYNFIG_CFLAGS@ @LIBAVCODEC_CFLAGS@ -D__STDC_CONSTANT_MACROS
+libmod_libavcodec_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@ @LIBAVCODEC_LIBS@
+else
+endif
+EXTRA_DIST= mod_libavcodec.nsh unmod_libavcodec.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_libavcodec/main.cpp
+** \brief writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include <synfig/layer.h>
+
+//#include "mptr.h"
+#include "trgt_av.h"
+
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(mod_libavcodec)
+ MODULE_NAME("LibAVCodec Module (From FFMPEG)")
+ MODULE_DESCRIPTION("Provides import/export ability for AVI, MPG, ASF, and a variety of other formats.")
+ MODULE_AUTHOR("Adrian Bentley")
+ MODULE_VERSION("0.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(mod_libavcodec)
+ BEGIN_TARGETS
+ TARGET(Target_LibAVCodec)
+ //TARGET_EXT(Target_LibAVCodec,"mpg")
+ //TARGET_EXT(Target_LibAVCodec,"mpeg")
+ //TARGET_EXT(Target_LibAVCodec,"mov")
+ TARGET_EXT(Target_LibAVCodec,"asf")
+ TARGET_EXT(Target_LibAVCodec,"rm")
+ //TARGET_EXT(Target_LibAVCodec,"mpg")
+ TARGET_EXT(Target_LibAVCodec,"wmv")
+ TARGET_EXT(Target_LibAVCodec,"yuv")
+ //TARGET_EXT(Target_LibAVCodec,"dv")
+ END_TARGETS
+ BEGIN_IMPORTERS
+// IMPORTER(bmp_mptr)
+ END_IMPORTERS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_libavcodec" Sec_mod_libavcodec
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_libavcodec.dll "src\modules\mod_libavcodec\.libs\libmod_libavcodec-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_libavcodec"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr.cpp
+** \brief writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "mptr.h"
+#include <synfig/general.h>
+#include <synfig/surface.h>
+
+#include <algorithm>
+#include <functional>
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_IMPORTER_INIT(Importer_LibAVCodec);
+SYNFIG_IMPORTER_SET_NAME(Importer_LibAVCodec,"libav");
+SYNFIG_IMPORTER_SET_EXT(Importer_LibAVCodec,"avi");
+SYNFIG_IMPORTER_SET_VERSION(Importer_LibAVCodec,"0.1");
+SYNFIG_IMPORTER_SET_CVS_ID(Importer_LibAVCodec,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+
+Importer_LibAVCodec::Importer_LibAVCodec(const char *file):
+ filename(file)
+{
+}
+
+Importer_LibAVCodec::~Importer_LibAVCodec()
+{
+}
+
+bool
+Importer_LibAVCodec::get_frame(synfig::Surface &/*surface*/,Time, synfig::ProgressCallback */*cb*/)
+{
+ return false;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr.h
+** \brief writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_MPTR_H
+#define __SYNFIG_MPTR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/importer.h>
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <cstdio>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class Importer_LibAVCodec : public synfig::Importer
+{
+SYNFIG_IMPORTER_MODULE_EXT
+
+private:
+ synfig::String filename;
+
+public:
+ Importer_LibAVCodec(const char *filename);
+ ~Importer_LibAVCodec();
+
+ virtual bool get_frame(synfig::Surface &surface,synfig::Time time, synfig::ProgressCallback *callback);
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_av.cpp
+** \brief \writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trgt_av.h"
+
+extern "C"
+{
+#include <avformat.h>
+}
+
+#include <synfig/general.h>
+
+#include <cstdio>
+#include <algorithm>
+#include <functional>
+#endif
+
+#ifdef WIN32
+#define snprintf _snprintf
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === I N F O ============================================================= */
+
+SYNFIG_TARGET_INIT(Target_LibAVCodec);
+SYNFIG_TARGET_SET_NAME(Target_LibAVCodec,"libav");
+SYNFIG_TARGET_SET_EXT(Target_LibAVCodec,"avi");
+SYNFIG_TARGET_SET_VERSION(Target_LibAVCodec,"0.1");
+SYNFIG_TARGET_SET_CVS_ID(Target_LibAVCodec,"$Id$");
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+bool Target_LibAVCodec::registered = false;
+
+//for now compilation
+//float STREAM_DURATION = 5.0f;
+
+struct VideoInfo
+{
+ int w,h;
+ int fps;
+
+ int bitrate;
+};
+
+struct AudioInfo
+{
+ int samplerate; //in HZ
+ int samplesize; //in bytes
+};
+
+AVFrame *alloc_picture(int pix_fmt, int width, int height)
+{
+ AVFrame *picture;
+ uint8_t *picture_buf;
+ int size;
+
+ picture = avcodec_alloc_frame();
+ if (!picture)
+ return NULL;
+ size = avpicture_get_size(pix_fmt, width, height);
+ picture_buf = (uint8_t *)malloc(size);
+ if (!picture_buf) {
+ av_free(picture);
+ return NULL;
+ }
+ avpicture_fill((AVPicture *)picture, picture_buf,
+ pix_fmt, width, height);
+ return picture;
+}
+
+void free_picture(AVFrame *pic)
+{
+ av_free(pic->data[0]);
+ av_free(pic);
+}
+
+//the frame must be RGB24
+static void convert_surface_frame(AVFrame *pic, const Surface &s, const Gamma &gamma)
+{
+ unsigned int j;
+ Surface::const_pen p = s.begin();
+ unsigned int w,h;
+ Color c;
+
+ uint8_t *ptr;
+ int stride;
+
+ w = s.size().x;
+ h = s.size().y;
+
+ ptr = pic->data[0];
+ stride = pic->linesize[0];
+
+ for(j = 0; j < h; j++, p.inc_y(), ptr += stride)
+ {
+ uint8_t *tptr = ptr;
+
+ //use convert_color_format instead...
+ #if 0
+ const int channels = 3;
+
+ for(int i = 0; i < w; i++, p.inc_x(), tptr += channels)
+ {
+ c = p.get_value();
+
+ Color::value_type r = c.get_r();
+ Color::value_type g = c.get_g();
+ Color::value_type b = c.get_b();
+ Color::value_type a = c.get_a();
+
+ //premultiply alpha
+ r *= a;
+ g *= a;
+ b *= a;
+
+ //essentially treats it as if it has a background color of black
+
+ //we must also clamp the rgb values [0,1]
+ r = min(1.0f,r);
+ g = min(1.0f,g);
+ b = min(1.0f,b);
+
+ r = max(0.0f,r);
+ g = max(0.0f,g);
+ b = max(0.0f,b);
+
+ //now scale to range of char [0,255]
+ tptr[0] = (int)(r*255);
+ tptr[1] = (int)(g*255);
+ tptr[2] = (int)(b*255);
+ }
+
+ p.dec_x(w);
+ #else
+
+ convert_color_format((unsigned char *)tptr,&p.get_value(),w,PF_RGB,gamma);
+
+ #endif
+ }
+}
+
+//Audio Streamer (abstracts the open, write and close operations for audio streams)
+#if 0
+class AudioEncoder
+{
+public:
+
+ void *samples;
+
+ vector<unsigned char>audiobuffer;
+
+ int audio_input_frame_size;
+
+ bool open(AVFormatContext *formatc, AVStream *stream)
+ {
+ AVCodecContext *context;
+ AVCodec *codec;
+
+ context = &stream->codec;
+
+ //find audio encoder
+ codec = avcodec_find_encoder(context->codec_id);
+ if(!codec)
+ {
+ synfig::warning("audio-open: could not find codec");
+ return 0;
+ }
+
+ //open the codec
+ if(avcodec_open(context, codec) < 0)
+ {
+ synfig::warning("audio-open: could not open codec");
+ return 0;
+ }
+
+ /* hardcoded example for generating samples array*/
+ /*
+ t = 0;
+ tincr = 2 * M_PI * 110.0 / c->sample_rate;
+ tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;*/
+
+ audiobuffer.resize(10000);
+
+ /* ugly hack for PCM codecs (will be removed ASAP with new PCM
+ support to compute the input frame size in samples */
+ if (context->frame_size <= 1) {
+ audio_input_frame_size = audiobuffer.size() / context->channels;
+ switch(stream->codec.codec_id) {
+ case CODEC_ID_PCM_S16LE:
+ case CODEC_ID_PCM_S16BE:
+ case CODEC_ID_PCM_U16LE:
+ case CODEC_ID_PCM_U16BE:
+ audio_input_frame_size >>= 1;
+ break;
+ default:
+ break;
+ }
+ } else {
+ audio_input_frame_size = context->frame_size;
+ }
+
+ //hardcoded array
+ //samples = (int16_t *)malloc(audio_input_frame_size * 2 * c->channels);
+
+ return true;
+ }
+
+ bool write_frame(AVFormatContext *formatc, AVStream *stream, void *samples)
+ {
+ int size;
+ AVCodecContext *context;
+
+ context = &stream->codec;
+
+ //hardcoded in example
+ //must read in from somewhere...
+ //get_audio_frame(samples, audio_input_frame_size, c->channels);
+
+ //encode the audio
+ const short int*samps=(const short int *)samples; //assuming it's set from somewhere right now
+
+ size = avcodec_encode_audio(context, &audiobuffer[0], audiobuffer.size(), samps);
+
+ //write the compressed audio to a file
+ if(av_write_frame(formatc, stream->index, &audiobuffer[0], size) != 0)
+ {
+ synfig::warning("audio-write_frame: unable to write the entire audio frame");
+ return 0;
+ }
+
+ return true;
+ }
+
+ void close(AVFormatContext *formatc, AVStream *stream)
+ {
+ //we may also want to catch delayed frames from here (don't for now)
+
+ if(stream)
+ {
+ avcodec_close(&stream->codec);
+ }
+
+ //if(samples)av_free(samples);
+ audiobuffer.resize(0);
+ }
+};
+
+#endif
+
+class VideoEncoder
+{
+public:
+ AVFrame *encodable; //for compressiong and output to a file (in compatible pixel format)
+
+ vector<unsigned char> videobuffer;
+
+ bool startedencoding;
+
+ //int stream_nb_frames;
+
+ bool open(AVFormatContext *formatc, AVStream *stream)
+ {
+ if(!formatc || !stream)
+ {
+ synfig::warning("Attempt to open a video codec with a bad format or stream");
+ return false;
+ }
+
+ //codec and context
+ AVCodec *codec;
+ AVCodecContext *context;
+
+ //get from inside stream
+ context = stream->codec;
+
+ //search for desired codec (contained in the stream)
+ codec = avcodec_find_encoder(context->codec_id);
+ if(!codec)
+ {
+ synfig::warning("Open_video: could not find desired codec");
+ return 0;
+ }
+
+ //try to open the codec
+ if(avcodec_open(context, codec) < 0)
+ {
+ synfig::warning("open_video: could not open desired codec");
+ return 0;
+ }
+
+ videobuffer.resize(0);
+ if(!(formatc->oformat->flags & AVFMT_RAWPICTURE))
+ {
+ //resize buffer to desired buffersize
+ videobuffer.resize(200000); //TODO: need to figure out a good size
+ }
+
+ //allocate the base picture which will be used to encode
+ /*picture = alloc_picture(PIX_FMT_RGBA32, context->width, context->height);
+ if(!picture)
+ {
+ synfig::warning("open_video: could not allocate the picture to be encoded");
+ return 0;
+ }*/
+
+ //if our output (rgb) needs to be translated to a different coordinate system, need a temporary picture in that color space
+
+ /* Should use defaults of RGB
+ Possible formats:
+ PIX_FMT_RGB24
+ PIX_FMT_BGR24
+ PIX_FMT_RGBA32 //stored in cpu endianness (!!!!)
+
+ (possibly translate directly to required coordinate systems later on... less error)
+ */
+ encodable = NULL;
+ if(context->pix_fmt != PIX_FMT_RGB24)
+ {
+ encodable = alloc_picture(context->pix_fmt, context->width, context->height);
+ if(!encodable)
+ {
+ synfig::warning("open_video: could not allocate encodable picture");
+ return 0;
+ }
+ }
+
+ return true;
+ }
+
+ //write a frame with the frame passed in
+ bool write_frame(AVFormatContext *formatc, AVStream *stream, AVFrame *pict)
+ {
+ if(!formatc || !stream)
+ {
+ synfig::warning("Attempt to open a video codec with a bad format or stream");
+ return false;
+ }
+
+ int size,
+ ret = 0;
+ AVCodecContext *context = stream->codec;
+
+ /*
+ If pict is invalid (NULL), then we are done compressing frames and we are trying to get
+ the buffer cleared out (or if it's already in the right format) so no transform necessary
+ */
+ if ( pict )
+ {
+ startedencoding = true;
+ }
+
+
+ if ( pict && context->pix_fmt != PIX_FMT_RGB24 )
+ {
+ //We're using RGBA at the moment, write custom conversion code later (get less accuracy errors)
+ img_convert((AVPicture *)encodable, context->pix_fmt,
+ (AVPicture *)pict, PIX_FMT_RGB24,
+ context->width, context->height);
+
+ pict = encodable;
+ }
+
+ AVPacket pkt;
+ av_init_packet(&pkt);
+ pkt.stream_index = stream->index;
+ pkt.data = (uint8_t *)pict;
+ pkt.size = sizeof(AVPicture);
+ if( context->coded_frame )
+ pkt.pts = context->coded_frame->pts;
+ if( context->coded_frame && context->coded_frame->key_frame)
+ pkt.flags |= PKT_FLAG_KEY;
+
+ //cludge for raw picture format (they said they'd fix)
+ if (formatc->oformat->flags & AVFMT_RAWPICTURE)
+ {
+ ret = av_write_frame(formatc, &pkt);
+ }
+ else
+ {
+ //encode our given image
+ size = avcodec_encode_video(context, &videobuffer[0], videobuffer.size(), pict);
+
+ //if greater than zero we've got stuff to write
+ if (size > 0)
+ {
+ av_init_packet(&pkt);
+ pkt.stream_index = stream->index;
+ pkt.data = &videobuffer[0];
+ pkt.size = size;
+ if( context->coded_frame )
+ pkt.pts = context->coded_frame->pts;
+ if( context->coded_frame && context->coded_frame->key_frame)
+ pkt.flags |= PKT_FLAG_KEY;
+
+ ret = av_write_frame(formatc, &pkt);
+
+ //error detect - possibly throw later...
+ if(ret < 0)
+ {
+ synfig::warning("write_frame: error while writing video frame");
+ return false;
+ }
+ }
+ //if 0, it was buffered (if invalid picture we don't have ANY data left)
+ else
+ {
+ //if we're clearing the buffers and there was no stuff to be written, we're done (like in codec example)
+ if(pict == NULL)
+ {
+ return false;
+ startedencoding = false;
+ }
+
+ //buffered picture
+ }
+ }
+
+ return true;
+ }
+
+ void close(AVFormatContext */*formatc*/, AVStream *stream)
+ {
+ if(stream)
+ avcodec_close(stream->codec);
+
+ if (encodable)
+ {
+ free_picture(encodable);
+ encodable = 0;
+ }
+
+ videobuffer.resize(0);
+ }
+};
+
+class Target_LibAVCodec::LibAVEncoder
+{
+public:
+
+ bool initialized;
+
+ AVOutputFormat *format; //reference to global, do not delete
+
+ AVFormatContext *formatc;
+
+ AVStream *video_st;
+ //AVStream *audio_st;
+
+ double video_pts;
+ //double audio_pts;
+
+ VideoEncoder vid;
+ VideoInfo vInfo;
+
+ /*AudioEncoder aud;
+ AudioInfo aInfo;*/
+
+ AVFrame *picture; //for encoding to RGB24 (perhaps RGBA later)
+
+ int frame_count;
+ int num_frames;
+
+ LibAVEncoder()
+ {
+ format = 0;
+ formatc = 0;
+
+ //video settings
+ video_st = 0;
+ video_pts = 0;
+
+ vid.encodable = 0;
+ //vid.stream_nb_frames = 2; //reasonable default
+
+ initialized = false;
+ picture = 0;
+
+ frame_count = 0;
+ num_frames = 0;
+
+ //aud.samples = 0;
+ //audio_st = 0;
+ //audio_pts = 0;
+ }
+
+ ~LibAVEncoder()
+ {
+ CleanUp();
+ }
+
+ bool Initialize(const char *filename, const char *typestring)
+ {
+ //guess if we have a type string, otherwise use filename
+ if (typestring)
+ {
+ //formatptr guess_format(type, filename, MIME type)
+ format = guess_format(typestring,NULL,NULL);
+ }
+ else
+ {
+ format = guess_format(NULL, filename, NULL);
+ }
+
+ if(!format)
+ {
+ synfig::warning("Unable to Guess the output, defaulting to mpeg");
+ format = guess_format("mpeg", NULL, NULL);
+ }
+
+ if(!format)
+ {
+ synfig::warning("Unable to find output format");
+ return 0;
+ }
+
+ //allocate the output context
+ formatc = (AVFormatContext *)av_mallocz(sizeof(AVFormatContext));
+ if(!formatc)
+ {
+ synfig::warning("Memory error\n");
+ return 0;
+ }
+ //set the output format to the one we found
+ formatc->oformat = format;
+
+ //print the output filename
+ snprintf(formatc->filename, sizeof(formatc->filename), "%s", filename);
+
+ //initial
+ video_st = NULL;
+ //audio_st = NULL;
+
+ //video stream
+ if(format->video_codec != CODEC_ID_NONE)
+ {
+ video_st = add_video_stream(format->video_codec,vInfo);
+ if(!video_st)
+ {
+ av_free(formatc);
+ }
+ }
+
+ //audio stream
+ /*if(format->audio_codec != CODEC_ID_NONE)
+ {
+ audio_st = add_audio_stream(format->audio_codec,aInfo);
+ }*/
+
+ //set output parameters: required in ALL cases
+
+ video_st->codec->time_base= (AVRational){1,vInfo.fps};
+ video_st->codec->width = vInfo.w;
+ video_st->codec->height = vInfo.h;
+ video_st->codec->pix_fmt = PIX_FMT_YUV420P;
+
+ //dump the formatting information as the file header
+ dump_format(formatc, 0, filename, 1);
+
+ //open codecs and allocate buffers
+ if(video_st)
+ {
+ if(!vid.open(formatc, video_st))
+ {
+ synfig::warning("Could not open video encoder");
+ return 0;
+ }
+ }
+ /*if(audio_st)
+ {
+ if(!aud.open(formatc, audio_st))
+ {
+ synfig::warning("Could not open audio encoder");
+ return 0;
+ }
+ }*/
+
+ //open output file
+ if(!(format->flags & AVFMT_NOFILE))
+ {
+ //use libav's file open function (what does it do differently????)
+ if(url_fopen(&formatc->pb, filename, URL_WRONLY) < 0)
+ {
+ synfig::warning("Unable to open file: %s", filename);
+ return 0;
+ }
+ }
+
+ //allocate the picture to render to
+ //may have to retrieve the width, height from the codec... for resizing...
+ picture = alloc_picture(PIX_FMT_RGB24,vInfo.w,vInfo.h);//video_st->codec.width, video_st->codec.height);
+ if(!picture)
+ {
+ synfig::warning("Unable to allocate the temporary AVFrame surface");
+ return 0;
+ }
+
+ initialized = true;
+ //vInfo.w = video_st->codec.width;
+ //vInfo.h = video_st->codec.height;
+
+ //write the stream header
+ av_write_header(formatc);
+
+ return true;
+ }
+
+ void CleanUp()
+ {
+ int i;
+
+ if(picture) free_picture(picture);
+
+ //do all the clean up file rendering
+ if(formatc && video_st)
+ {
+ //want to scan in delayed frames until no longer needed (TODO)
+ if(vid.startedencoding) while( vid.write_frame(formatc, video_st, 0) );
+
+ //may want to move this... probably to the end of the last frame...
+ av_write_trailer(formatc);
+ }
+
+ //close codecs
+ if (video_st)
+ vid.close(formatc,video_st);
+ /*if (audio_st)
+ aud.close(formatc,audio_st);*/
+
+ /* write the trailer, if any */
+ if(formatc)
+ {
+ /* free the streams */
+ for(i = 0; i < formatc->nb_streams; i++)
+ {
+ av_freep(&formatc->streams[i]);
+ }
+
+ if(!(format->flags & AVFMT_NOFILE))
+ {
+ /* close the output file */
+ url_fclose(&formatc->pb);
+ }
+
+ /* free the stream */
+ av_free(formatc);
+ }
+
+ initialized = false;
+
+ format = 0;
+ formatc = 0;
+
+ //video settings
+ video_st = 0;
+ video_pts = 0;
+
+ vid.encodable = 0;
+ //vid.stream_nb_frames = 2; //reasonable default
+
+ initialized = false;
+ picture = 0;
+ }
+
+ //create a video output stream
+ AVStream *add_video_stream(int codec_id, const VideoInfo &info)
+ {
+ AVCodecContext *context;
+ AVStream *st;
+
+ st = av_new_stream(formatc, 0);
+ if(!st)
+ {
+ synfig::warning("video-add_stream: Unable to allocate stream");
+ return 0;
+ }
+
+ context = st->codec;
+ context->codec_id = (CodecID)codec_id;
+ context->codec_type = CODEC_TYPE_VIDEO;
+
+ //PARAMETERS MUST BE PASSED IN SOMEHOW (ANOTHER FUNCTION PARAMETER???)
+
+ /* resolution must be a multiple of two */
+ context->width = info.w;
+ context->height = info.h;
+
+ //have another way to input these
+ context->bit_rate = info.bitrate; //TODO: Make dependant on the quality
+
+ /* frames per second */
+ // FIXME: Port next two lines to recent libavcodec versions
+ //context->frame_rate = info.fps;
+ //context->frame_rate_base = 1;
+
+ /* "High Quality" */
+ context->mb_decision=FF_MB_DECISION_BITS;
+
+ context->gop_size = info.fps/4; /* emit one intra frame every twelve frames at most */
+
+ //HACK: MPEG requires b frames be set... any better way to do this?
+ if (context->codec_id == CODEC_ID_MPEG1VIDEO ||
+ context->codec_id == CODEC_ID_MPEG2VIDEO)
+ {
+ /* just for testing, we also add B frames */
+ context->max_b_frames = 2;
+ }
+
+ return st;
+ }
+
+ // add an audio output stream
+ AVStream *add_audio_stream(int codec_id,const AudioInfo &/*aInfo*/)
+ {
+ AVCodecContext *context;
+ AVStream *stream;
+
+ stream = av_new_stream(formatc, 1);
+ if(!stream)
+ {
+ synfig::warning("could not alloc stream");
+ return 0;
+ }
+
+ context = stream->codec;
+ context->codec_id = (CodecID)codec_id;
+ context->codec_type = CODEC_TYPE_AUDIO;
+
+ /* put sample parameters */
+ context->bit_rate = 64000;
+ context->sample_rate = 44100;
+ context->channels = 2;
+
+ return stream;
+ }
+};
+
+/* === M E T H O D S ======================================================= */
+
+Target_LibAVCodec::Target_LibAVCodec(const char *Filename):
+ filename(Filename)
+{
+ if(!registered)
+ {
+ registered = true;
+ av_register_all();
+ }
+ set_remove_alpha();
+
+ data = new LibAVEncoder;
+}
+
+Target_LibAVCodec::~Target_LibAVCodec()
+{
+ data->CleanUp();
+}
+
+bool
+Target_LibAVCodec::set_rend_desc(RendDesc *given_desc)
+{
+ // This is where you can determine how you want stuff
+ // to be rendered! given_desc is the suggestion, and
+ // you need to modify it to suit the needs of the codec.
+ // ie: Making the pixel dimensions divisible by 8, etc...
+
+ desc=*given_desc;
+
+ //resize surface (round even)
+ int w = desc.get_w();
+ int h = desc.get_h();
+ Point tl = desc.get_tl();
+ Point br = desc.get_br();
+ Real pw = desc.get_pw();
+ Real ph = desc.get_ph();
+
+ //resize to the size it should be...
+ //desc.set_subwindow(-offx/2,-offy/2, desc.get_w() - offx?(offx + 8):0, desc.get_h() - offy?(offy + 8):0);
+
+ //if resolution is broken, change the size... or something
+ //budge to nearest pixel values
+ if(w&1)
+ {
+ w += 1;
+ tl[0] -= pw/2;
+ br[0] += pw/2;
+ }
+
+ if(h&1)
+ {
+ h += 1;
+ tl[1] -= ph/2;
+ br[1] += ph/2;
+ }
+
+ desc.set_w(w);
+ desc.set_h(h);
+ desc.set_tl(tl);
+ desc.set_br(br);
+
+ data->vInfo.w = w;
+ data->vInfo.h = h;
+
+ //may want to round frame rate
+ data->vInfo.fps = (int)floor(desc.get_frame_rate()+0.5);
+#define MEGABYTES_PER_HOUR(x) (((x)*1024/3600*1024*8)/*/640*w/480*h*/)
+ data->vInfo.bitrate = MEGABYTES_PER_HOUR(400);
+ //data->vInfo.bitrate = 800000; //make customizable somehow
+
+ desc.set_frame_rate(data->vInfo.fps);
+
+ data->frame_count = desc.get_frame_start();
+ data->num_frames = desc.get_frame_end()+1; //number of frames should be 1 greater than the last one
+
+ surface.set_wh(data->vInfo.w,data->vInfo.h);
+
+ return true;
+}
+
+void
+Target_LibAVCodec::end_frame()
+{
+ //AVStream *audio_st = data->audio_st;
+ AVStream *video_st = data->video_st;
+
+ AVFormatContext *formatc = data->formatc;
+
+ //double &audio_pts = data->audio_pts;
+ //double &video_pts = data->video_pts;
+
+ //ignore audio for now
+ /*if (audio_st)
+ audio_pts = (double)audio_st->pts.val * formatc->pts_num / formatc->pts_den;
+ else
+ audio_pts = 0.0;
+
+ if (video_st)
+ video_pts = (double)video_st->pts.val * formatc->pts_num / formatc->pts_den;
+ else
+ video_pts = 0.0;*/
+
+ //hardcoded crappiness
+ /*if ((!audio_st || audio_pts >= STREAM_DURATION) &&
+ (!video_st || video_pts >= STREAM_DURATION))
+ break;*/
+
+ if(data->frame_count >= data->num_frames) return;
+
+ //copy the current surface to the buffer
+ if(data->picture)convert_surface_frame(data->picture,surface,gamma());
+
+ //encode the frame and write it to the file
+ if(!data->vid.write_frame(formatc,video_st,data->picture))
+ {
+ synfig::warning("Unable to write a frame");
+ }
+
+ data->frame_count++;
+
+ if(data->frame_count >= data->num_frames)
+ {
+ data->CleanUp();
+ }
+
+ /* write interleaved audio and video frames */
+ /*if (!video_st || (video_st && audio_st && audio_pts < video_pts)) {
+ data->aud.write_frame(formatc,audio_st);
+ } else {
+ data->vid.write_frame(formatc,video_st);
+ }*/
+}
+
+bool
+Target_LibAVCodec::start_frame(synfig::ProgressCallback */*callback*/)
+{
+ //prepare all the color buffer stuff, etc.
+
+ return true;
+}
+
+Color *
+Target_LibAVCodec::start_scanline(int scanline)
+{
+ return surface[scanline];
+
+ return 0; // This should kill the render process
+}
+
+bool
+Target_LibAVCodec::end_scanline()
+{
+ //don't need to do anything until the whole frame is done
+ return true;
+}
+
+bool Target_LibAVCodec::init()
+{
+ //hardcode test for mpeg
+ if(!data->Initialize(filename.c_str(),NULL))
+ {
+ synfig::warning("Unable to Initialize the audio video encoders");
+ return 0;
+ }
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_av.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRGT_H
+#define __SYNFIG_TRGT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/target_scanline.h>
+#include <synfig/string.h>
+#include <cstdio>
+#include "synfig/surface.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class Target_LibAVCodec : public synfig::Target_Scanline
+{
+ SYNFIG_TARGET_MODULE_EXT
+private:
+ synfig::String filename;
+
+ class LibAVEncoder;
+ LibAVEncoder *data;
+
+ static bool registered;
+
+ synfig::Surface surface;
+
+public:
+ Target_LibAVCodec(const char *filename);
+ virtual ~Target_LibAVCodec();
+
+ virtual bool init();
+
+ virtual bool set_rend_desc(synfig::RendDesc *desc);
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+ virtual void end_frame();
+ virtual synfig::Color * start_scanline(int scanline);
+ virtual bool end_scanline();
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_libavcodec"
+ Delete "$INSTDIR\lib\synfig\modules\mod_libavcodec.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+# FIXME: THIS DOES NOT ACTUALLY WORK YET
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+if HAVE_LIBMNG
+module_LTLIBRARIES = libmod_mng.la
+libmod_mng_la_SOURCES = main.cpp trgt_mng.cpp trgt_mng.h
+libmod_mng_la_LDFLAGS = -module @MNG_LIBS@ -no-undefined
+libmod_mng_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_mng_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+else
+endif
+EXTRA_DIST= mod_mng.nsh unmod_mng.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_mng/main.cpp
+** \brief MNG plugin
+**
+** $Id$
+**
+** \legal
+** Copyright 2007 Paul Wise
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** FIXME: THIS DOES NOT ACTUALLY WORK YET
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include "trgt_mng.h"
+/* FIXME: Implement MNG import
+#include "mptr_mng.h"
+*/
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(mod_mng)
+ MODULE_NAME("MNG Module (libmng)")
+/* FIXME: Implement MNG import
+ MODULE_DESCRIPTION("Provides an MNG target and importer")
+*/
+ MODULE_DESCRIPTION("Provides an MNG target")
+ MODULE_AUTHOR("Paul Wise")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(mod_mng)
+ BEGIN_TARGETS
+ TARGET(mng_trgt)
+ END_TARGETS
+/* FIXME: implement MNG import
+ BEGIN_IMPORTERS
+ IMPORTER(mng_mptr)
+ END_IMPORTERS
+*/
+MODULE_INVENTORY_END
--- /dev/null
+; FIXME: THIS DOES NOT ACTUALLY WORK YET
+
+Section "mod_mng" Sec_mod_mng
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+ File /oname=mod_mng.dll "src\modules\mod_mng\.libs\libmod_mng-0.dll"
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_mng"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_mng.cpp
+** \brief MNG Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright 2007 Paul Wise
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** FIXME: THIS DOES NOT ACTUALLY WORK YET
+**
+** You will need to read the PNG and MNG specs to understand this code
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_TARGET
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trgt_mng.h"
+#include <libmng.h>
+#include <ETL/stringf>
+#include <cstdio>
+#include <algorithm>
+#include <functional>
+#include <ETL/misc>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_TARGET_INIT(mng_trgt);
+SYNFIG_TARGET_SET_NAME(mng_trgt,"mng");
+SYNFIG_TARGET_SET_EXT(mng_trgt,"mng");
+SYNFIG_TARGET_SET_VERSION(mng_trgt,"0.1");
+SYNFIG_TARGET_SET_CVS_ID(mng_trgt,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+static mng_ptr MNG_DECL mng_alloc_proc(mng_size_t size){
+ return (mng_ptr)calloc(1,size);
+}
+
+static void MNG_DECL mng_free_proc(mng_ptr ptr, mng_size_t size)
+{
+ free(ptr); return;
+}
+
+static mng_bool MNG_DECL mng_null_proc(mng_handle mng)
+{
+ synfig::error("mng_trgt: error: mng_null_proc");
+ return MNG_TRUE;
+}
+
+static mng_bool MNG_DECL mng_write_proc(mng_handle mng, mng_ptr buf, mng_uint32 size, mng_uint32* written)
+{
+ synfig::error("mng_trgt: error: mng_write_proc");
+ FILE* file = (FILE*)mng_get_userdata (mng);
+ *written = fwrite(buf, 1, size, file);
+ return MNG_TRUE;
+}
+
+static mng_bool MNG_DECL mng_error_proc(
+ mng_handle mng, mng_int32 error, mng_int8 severity, mng_chunkid chunkname,
+ mng_uint32 chunkseq, mng_int32 extra1, mng_int32 extra2, mng_pchar errortext){
+ mng_trgt* me = (mng_trgt*)mng_get_userdata (mng);
+ fprintf(stderr,"mng_trgt: error: %s",errortext);
+ // me->ready=false;
+ return MNG_TRUE;
+}
+
+mng_trgt::mng_trgt(const char *Filename):
+ filename(Filename)
+{
+ file=NULL;
+ buffer=NULL;
+ color_buffer=NULL;
+ zbuffer=NULL;
+ zbuffer_len=0;
+ ready=false;
+}
+
+mng_trgt::~mng_trgt()
+{
+ synfig::error("mng_trgt: error: ~mng_trgt");
+ if( mng != MNG_NULL){
+ mng_putchunk_mend(mng);
+ if( mng_write(mng) != 0 ){
+ mng_int8 severity;
+ mng_chunkid chunkname;
+ mng_uint32 chunkseq;
+ mng_int32 extra1;
+ mng_int32 extra2;
+ mng_pchar errortext;
+ mng_getlasterror(mng, &severity, &chunkname, &chunkseq, &extra1,&extra2, &errortext);
+ synfig::error("mng_trgt: error: couldn't write mng: %s",errortext);
+ }
+ mng_cleanup (&mng);
+ }
+ if( file != NULL ) fclose(file); file=NULL;
+ if( buffer != NULL ){ delete [] buffer; buffer = NULL; }
+ if( color_buffer != NULL ){ delete [] color_buffer; color_buffer = NULL; }
+ if( zbuffer != NULL ){ free(zbuffer); zbuffer = NULL; zbuffer_len = 0; }
+}
+
+bool
+mng_trgt::set_rend_desc(RendDesc *given_desc)
+{
+ desc=*given_desc;
+ imagecount=desc.get_frame_start();
+ if(desc.get_frame_end()-desc.get_frame_start()>0)
+ multi_image=true;
+ else
+ multi_image=false;
+ return true;
+}
+
+
+bool
+mng_trgt::init(){
+ time_t t = time (NULL);
+ struct tm* gmt = gmtime(&t);
+ w=desc.get_w(); h=desc.get_h();
+ //synfig::error("mng_trgt: init %d %d",w,h);
+ file = fopen(filename.c_str(), "wb");
+ if( file == NULL ) goto cleanup_on_error;
+ mng = mng_initialize((mng_ptr)file, mng_alloc_proc, mng_free_proc, MNG_NULL);
+ if(mng == MNG_NULL) goto cleanup_on_error;
+ if( mng_setcb_errorproc(mng, mng_error_proc) != 0 ) goto cleanup_on_error;
+ if( mng_setcb_writedata(mng, mng_write_proc) != 0 ) goto cleanup_on_error;
+ if( mng_setcb_openstream(mng, mng_null_proc) != 0 ) goto cleanup_on_error;
+ if( mng_setcb_closestream(mng, mng_null_proc) != 0 ) goto cleanup_on_error;
+ if( mng_create(mng) != 0 ) goto cleanup_on_error;
+ if( mng_putchunk_mhdr(mng, w, h, multi_image?1000:0, 1, desc.get_frame_end()-desc.get_frame_start(), 0, 0) != 0 ) goto cleanup_on_error;
+ if( mng_putchunk_term(mng, MNG_TERMACTION_REPEAT, MNG_ITERACTION_LASTFRAME, 0, 0x7fffffff) != 0 ) goto cleanup_on_error;
+ if( mng_putchunk_text(mng, sizeof(MNG_TEXT_TITLE), MNG_TEXT_TITLE, get_canvas()->get_name().length(), const_cast<char *>(get_canvas()->get_name().c_str()) ) != 0 ) goto cleanup_on_error;
+ if( mng_putchunk_text(mng, sizeof(MNG_TEXT_DESCRIPTION), MNG_TEXT_DESCRIPTION, get_canvas()->get_description().length(), const_cast<char *>(get_canvas()->get_description().c_str()) ) != 0 ) goto cleanup_on_error;
+ if( mng_putchunk_text(mng, sizeof(MNG_TEXT_SOFTWARE), MNG_TEXT_SOFTWARE, sizeof("SYNFIG"), "SYNFIG" ) != 0 ) goto cleanup_on_error;
+ /* FIXME: not sure if this is correct */
+ if( mng_putchunk_gama(mng, MNG_FALSE, (int)(1.0/gamma().get_gamma()*100000)) != 0 ) goto cleanup_on_error;
+ if( mng_putchunk_phyg(mng, MNG_FALSE,round_to_int(desc.get_x_res()),round_to_int(desc.get_y_res()),MNG_UNIT_METER) != 0 ) goto cleanup_on_error;
+ if( mng_putchunk_time(mng, gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday, gmt->tm_hour, gmt->tm_min, gmt->tm_sec) != 0 ) goto cleanup_on_error;
+ buffer=new unsigned char[4*w];
+ if( buffer == NULL ) goto cleanup_on_error;
+ color_buffer=new Color[w];
+ if( color_buffer == NULL ) goto cleanup_on_error;
+ return true;
+
+cleanup_on_error:
+ ready=false;
+ if( mng != MNG_NULL){
+ mng_int8 severity;
+ mng_chunkid chunkname;
+ mng_uint32 chunkseq;
+ mng_int32 extra1;
+ mng_int32 extra2;
+ mng_pchar errortext;
+ mng_getlasterror (mng, &severity, &chunkname, &chunkseq, &extra1,&extra2, &errortext);
+ synfig::error("mng_trgt: libmng: %s",errortext);
+ mng_cleanup (&mng);
+ }
+ if( file && file!=stdout ) fclose(file); file=NULL;
+ if( buffer != NULL ){ delete [] buffer; buffer = NULL; }
+ if( color_buffer != NULL ){ delete [] color_buffer; color_buffer = NULL; }
+ return false;
+}
+
+void
+mng_trgt::end_frame()
+{
+ //synfig::error("mng_trgt: endf %d %d",w,h);
+ //synfig::error("mng_trgt: error: endframe");
+ deflate(&zstream,Z_FINISH);
+ deflateEnd(&zstream);
+ if( mng != MNG_NULL ){
+ mng_int8 severity;
+ mng_chunkid chunkname;
+ mng_uint32 chunkseq;
+ mng_int32 extra1;
+ mng_int32 extra2;
+ mng_pchar errortext;
+ mng_putchunk_idat(mng, zbuffer_len, zbuffer);
+ //mng_getlasterror (mng, &severity, &chunkname, &chunkseq, &extra1,&extra2, &errortext);
+ //synfig::error("mng_trgt: libmng: %s %d",errortext,zbuffer_len);
+ mng_putchunk_iend(mng);
+ //mng_getlasterror (mng, &severity, &chunkname, &chunkseq, &extra1,&extra2, &errortext);
+ //synfig::error("mng_trgt: libmng: %s %d",errortext);
+ }
+ imagecount++;
+ ready=false;
+}
+
+bool
+mng_trgt::start_frame(synfig::ProgressCallback *callback)
+{
+ //synfig::error("mng_trgt: startf %d %d",w,h);
+ //synfig::error("mng_trgt: error: startframe");
+ /*
+ FIXME: figure out if we need this
+ mng_putchunk_fram(mng,
+ MNG_FALSE,
+ MNG_FRAMINGMODE_NOCHANGE,
+ 0,
+ NULL,
+ MNG_CHANGEDELAY_NO,
+ MNG_CHANGETIMOUT_NO,
+ MNG_CHANGECLIPPING_NO,
+ MNG_CHANGESYNCID_NO,
+ 0,
+ 0,
+ 0,
+ layer_offset_x,
+ layer_offset_x + layer_cols,
+ layer_offset_y,
+ layer_offset_y + layer_rows,
+ 0,
+ 0)
+ mng_getchunk_fram(mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint8 *iMode,
+ mng_uint32 *iNamesize,
+ mng_pchar *zName,
+ mng_uint8 *iChangedelay,
+ mng_uint8 *iChangetimeout,
+ mng_uint8 *iChangeclipping,
+ mng_uint8 *iChangesyncid,
+ mng_uint32 *iDelay,
+ mng_uint32 *iTimeout,
+ mng_uint8 *iBoundarytype,
+ mng_int32 *iBoundaryl,
+ mng_int32 *iBoundaryr,
+ mng_int32 *iBoundaryt,
+ mng_int32 *iBoundaryb,
+ mng_uint32 *iCount,
+ mng_uint32p *pSyncids);
+ */
+ if( mng == MNG_NULL ) return false;
+ if( mng_putchunk_defi(mng,0,MNG_DONOTSHOW_VISIBLE,MNG_ABSTRACT,MNG_FALSE,0,0,MNG_FALSE,0,0,0,0) != 0) return false;
+ if( mng_putchunk_ihdr(mng,w,h,MNG_BITDEPTH_8,MNG_COLORTYPE_RGBA,MNG_COMPRESSION_DEFLATE, 0/*MNG_FILTER_NO_DIFFERING*/,MNG_INTERLACE_NONE) != 0) return false;
+ zstream.zalloc = Z_NULL;
+ zstream.zfree = Z_NULL;
+ zstream.opaque = Z_NULL;
+ zstream.data_type = Z_BINARY;
+ if( deflateInit(&zstream, Z_DEFAULT_COMPRESSION) != Z_OK ) return false;
+ //zbuffer_len = deflateBound(&zstream,4*w*h);
+ if(zbuffer == NULL){
+ zbuffer_len = 4*w*h;
+ zbuffer = (unsigned char*)realloc(zbuffer, zbuffer_len);
+ zstream.next_out = zbuffer;
+ zstream.avail_out = zbuffer_len;
+ }
+ ready=true;
+ return true;
+}
+
+Color *
+mng_trgt::start_scanline(int scanline)
+{
+ //synfig::error("mng_trgt: starts %d %d",w,h);
+ //synfig::error("mng_trgt: error: startscanline");
+ return color_buffer;
+}
+
+bool
+mng_trgt::end_scanline()
+{
+ //synfig::error("mng_trgt: ends %d %d",w,h);
+ //synfig::error("mng_trgt: error: endscanline");
+ if(!file || !ready)
+ return false;
+ convert_color_format(buffer, color_buffer, desc.get_w(), PF_RGB|PF_A, gamma());
+ /* FIXME: Implement buffer management */
+ zstream.next_in = buffer;
+ zstream.avail_in = 4*w;
+ deflate(&zstream,Z_NO_FLUSH);
+ return true;
+}
--- /dev/null
+/*! ========================================================================
+** Synfig
+**
+** Copyright (c) 2007 Paul Wise
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+**
+** === N O T E S ===========================================================
+**
+** FIXME: THIS DOES NOT ACTUALLY WORK YET
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRGT_MNG_H
+#define __SYNFIG_TRGT_MNG_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/target_scanline.h>
+#include <synfig/string.h>
+#include <cstdio>
+
+#include <png.h>
+#include <jpeglib.h>
+
+#if !defined(MNG_SUPPORT_FULL)
+#define MNG_SUPPORT_FULL 1
+#endif
+
+#if !defined(MNG_SUPPORT_READ)
+#define MNG_SUPPORT_READ 1
+#endif
+
+#if !defined(MNG_SUPPORT_WRITE)
+#define MNG_SUPPORT_WRITE 1
+#endif
+
+#if !defined(MNG_SUPPORT_DISPLAY)
+#define MNG_SUPPORT_DISPLAY 1
+#endif
+
+#if !defined(MNG_ACCESS_CHUNKS)
+#define MNG_ACCESS_CHUNKS 1
+#endif
+
+#include <libmng.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class mng_trgt : public synfig::Target_Scanline
+{
+ SYNFIG_TARGET_MODULE_EXT
+
+private:
+
+ FILE *file;
+ int w,h;
+ mng_handle mng;
+
+ bool multi_image,ready;
+ int imagecount;
+ synfig::String filename;
+ unsigned char *buffer;
+ synfig::Color *color_buffer;
+
+ z_stream zstream;
+ unsigned char* zbuffer;
+ unsigned int zbuffer_len;
+
+public:
+
+ mng_trgt(const char *filename);
+ virtual ~mng_trgt();
+
+ virtual bool set_rend_desc(synfig::RendDesc *desc);
+ virtual bool init();
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+ virtual void end_frame();
+
+ virtual synfig::Color * start_scanline(int scanline);
+ virtual bool end_scanline();
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+; FIXME: THIS DOES NOT ACTUALLY WORK YET
+Section "un.mod_mng"
+ Delete "$INSTDIR\lib\synfig\modules\mod_mng.dll"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+module_LTLIBRARIES = libmod_noise.la
+libmod_noise_la_SOURCES = random.cpp random.h distort.cpp distort.h noise.cpp noise.h main.cpp
+libmod_noise_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_noise_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+libmod_noise_la_LDFLAGS = -module -no-undefined
+EXTRA_DIST= mod_noise.nsh unmod_noise.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file distort.cpp
+** \brief blehh
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "distort.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(NoiseDistort);
+SYNFIG_LAYER_SET_NAME(NoiseDistort,"noise_distort");
+SYNFIG_LAYER_SET_LOCAL_NAME(NoiseDistort,_("Noise Distort"));
+SYNFIG_LAYER_SET_CATEGORY(NoiseDistort,_("Distortions"));
+SYNFIG_LAYER_SET_VERSION(NoiseDistort,"0.0");
+SYNFIG_LAYER_SET_CVS_ID(NoiseDistort,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+NoiseDistort::NoiseDistort():
+ size(1,1)
+{
+ set_blend_method(Color::BLEND_STRAIGHT);
+ smooth=2;
+ detail=4;
+ speed=0;
+ random.set_seed(time(NULL));
+ turbulent=false;
+ displacement=Vector(0.25,0.25);
+}
+
+inline Color
+NoiseDistort::color_func(const Point &point, float /*supersample*/,Context context)const
+{
+ Color ret(0,0,0,0);
+
+ float x(point[0]/size[0]*(1<<detail));
+ float y(point[1]/size[1]*(1<<detail));
+
+ int i;
+ Time time;
+ time=speed*curr_time;
+ int temp_smooth(smooth);
+ int smooth((!speed && temp_smooth==3)?5:temp_smooth);
+
+ {
+ Vector vect(0,0);
+ for(i=0;i<detail;i++)
+ {
+ vect[0]=random(smooth,0+(detail-i)*5,x,y,time)+vect[0]*0.5;
+ vect[1]=random(smooth,1+(detail-i)*5,x,y,time)+vect[1]*0.5;
+
+ if(vect[0]<-1)vect[0]=-1;if(vect[0]>1)vect[0]=1;
+ if(vect[1]<-1)vect[1]=-1;if(vect[1]>1)vect[1]=1;
+
+ if(turbulent)
+ {
+ vect[0]=abs(vect[0]);
+ vect[1]=abs(vect[1]);
+ }
+
+ x/=2.0f;
+ y/=2.0f;
+ }
+
+ if(!turbulent)
+ {
+ vect[0]=vect[0]/2.0f+0.5f;
+ vect[1]=vect[1]/2.0f+0.5f;
+ }
+ vect[0]=(vect[0]-0.5f)*displacement[0];
+ vect[1]=(vect[1]-0.5f)*displacement[1];
+
+ ret=context.get_color(point+vect);
+ }
+ return ret;
+}
+
+inline float
+NoiseDistort::calc_supersample(const synfig::Point &/*x*/, float /*pw*/,float /*ph*/)const
+{
+ return 0.0f;
+}
+
+void
+NoiseDistort::set_time(synfig::Context context, synfig::Time t)const
+{
+ curr_time=t;
+ context.set_time(t);
+}
+
+void
+NoiseDistort::set_time(synfig::Context context, synfig::Time t, const synfig::Point &point)const
+{
+ curr_time=t;
+ context.set_time(t,point);
+}
+
+synfig::Layer::Handle
+NoiseDistort::hit_check(synfig::Context context, const synfig::Point &point)const
+{
+ if(get_blend_method()==Color::BLEND_STRAIGHT && get_amount()>=0.5)
+ return const_cast<NoiseDistort*>(this);
+ if(get_amount()==0.0)
+ return context.hit_check(point);
+ if(color_func(point,0,context).get_a()>0.5)
+ return const_cast<NoiseDistort*>(this);
+ return false;
+}
+
+bool
+NoiseDistort::set_param(const String & param, const ValueBase &value)
+{
+ if(param=="seed" && value.same_type_as(int()))
+ {
+ random.set_seed(value.get(int()));
+ return true;
+ }
+ IMPORT(size);
+ IMPORT(speed);
+ IMPORT(smooth);
+ IMPORT(detail);
+ IMPORT(turbulent);
+ IMPORT(displacement);
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+NoiseDistort::get_param(const String & param)const
+{
+ if(param=="seed")
+ return random.get_seed();
+ EXPORT(size);
+ EXPORT(speed);
+ EXPORT(smooth);
+ EXPORT(detail);
+ EXPORT(displacement);
+ EXPORT(turbulent);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+NoiseDistort::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("displacement")
+ .set_local_name(_("Displacement"))
+ );
+
+ ret.push_back(ParamDesc("size")
+ .set_local_name(_("Size"))
+ );
+ ret.push_back(ParamDesc("seed")
+ .set_local_name(_("Random Seed"))
+ );
+ ret.push_back(ParamDesc("smooth")
+ .set_local_name(_("Interpolation"))
+ .set_description(_("What type of interpolation to use"))
+ .set_hint("enum")
+ .add_enum_value(0,"nearest",_("Nearest Neighbor"))
+ .add_enum_value(1,"linear",_("Linear"))
+ .add_enum_value(2,"cosine",_("Cosine"))
+ .add_enum_value(3,"spline",_("Spline"))
+ .add_enum_value(4,"cubic",_("Cubic"))
+ );
+ ret.push_back(ParamDesc("detail")
+ .set_local_name(_("Detail"))
+ );
+ ret.push_back(ParamDesc("speed")
+ .set_local_name(_("Animation Speed"))
+ );
+ ret.push_back(ParamDesc("turbulent")
+ .set_local_name(_("Turbulent"))
+ );
+
+ return ret;
+}
+
+Color
+NoiseDistort::get_color(Context context, const Point &point)const
+{
+ const Color color(color_func(point,0,context));
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,context.get_color(point),get_amount(),get_blend_method());
+}
+
+Rect
+NoiseDistort::get_bounding_rect(Context context)const
+{
+ if(is_disabled())
+ return Rect::zero();
+
+ if(Color::is_onto(get_blend_method()))
+ return context.get_full_bounding_rect();
+
+ Rect bounds(context.get_full_bounding_rect().expand_x(displacement[0]).expand_y(displacement[1]));
+
+ return bounds;
+}
+
+/*
+bool
+NoiseDistort::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ }
+ else
+ {
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+ if(get_amount()==0)
+ return true;
+ }
+
+
+ int x,y;
+
+ Surface::pen pen(surface->begin());
+ const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
+ Point pos;
+ Point tl(renddesc.get_tl());
+ const int w(surface->get_w());
+ const int h(surface->get_h());
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(color_func(pos,calc_supersample(pos,pw,ph),context));
+ }
+ else
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(Color::blend(color_func(pos,calc_supersample(pos,pw,ph),context),pen.get_value(),get_amount(),get_blend_method()));
+ }
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
+*/
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file distort.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_NOISE_DISTORT_H
+#define __SYNFIG_NOISE_DISTORT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/vector.h>
+#include <synfig/valuenode.h>
+#include <synfig/layer_composite.h>
+#include <synfig/gradient.h>
+#include <synfig/time.h>
+#include "random.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class NoiseDistort : public synfig::Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ synfig::Vector size;
+
+ Random random;
+ int smooth;
+ int detail;
+ synfig::Real speed;
+ bool turbulent;
+ synfig::Vector displacement;
+
+ //void sync();
+ mutable synfig::Time curr_time;
+
+ synfig::Color color_func(const synfig::Point &x, float supersample,synfig::Context context)const;
+
+ float calc_supersample(const synfig::Point &x, float pw,float ph)const;
+
+public:
+ NoiseDistort();
+
+ virtual bool set_param(const synfig::String ¶m, const synfig::ValueBase &value);
+ virtual synfig::ValueBase get_param(const synfig::String ¶m)const;
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+ //virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+ virtual void set_time(synfig::Context context, synfig::Time time)const;
+ virtual void set_time(synfig::Context context, synfig::Time time, const synfig::Point &point)const;
+ virtual synfig::Rect get_bounding_rect(synfig::Context context)const;
+
+ virtual Vocab get_param_vocab()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_noise/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include <synfig/string.h>
+#include <synfig/canvas.h>
+#include <synfig/valuenode.h>
+
+#include "noise.h"
+#include "distort.h"
+#include "random.h"
+
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(libmod_noise)
+ MODULE_NAME("Noise")
+ MODULE_DESCRIPTION("writeme")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(libmod_noise)
+ BEGIN_LAYERS
+ LAYER(Noise)
+ LAYER(NoiseDistort)
+ END_LAYERS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_noise" Sec_mod_noise
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_noise.dll "src\modules\mod_noise\.libs\libmod_noise-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_noise"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file noise.cpp
+** \brief blehh
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "noise.h"
+
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Noise);
+SYNFIG_LAYER_SET_NAME(Noise,"noise");
+SYNFIG_LAYER_SET_LOCAL_NAME(Noise,_("Noise Gradient"));
+SYNFIG_LAYER_SET_CATEGORY(Noise,_("Gradients"));
+SYNFIG_LAYER_SET_VERSION(Noise,"0.0");
+SYNFIG_LAYER_SET_CVS_ID(Noise,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Noise::Noise():
+ size(1,1),
+ gradient(Color::black(), Color::white())
+{
+ smooth=2;
+ detail=4;
+ speed=0;
+ do_alpha=false;
+ random.set_seed(time(NULL));
+ turbulent=false;
+ displacement=Vector(1,1);
+ do_displacement=false;
+ super_sample=false;
+}
+
+
+
+inline Color
+Noise::color_func(const Point &point, float pixel_size,Context /*context*/)const
+{
+ Color ret(0,0,0,0);
+
+ float x(point[0]/size[0]*(1<<detail));
+ float y(point[1]/size[1]*(1<<detail));
+ float x2(0),y2(0);
+
+ if(super_sample&&pixel_size)
+ {
+ x2=(point[0]+pixel_size)/size[0]*(1<<detail);
+ y2=(point[1]+pixel_size)/size[1]*(1<<detail);
+ }
+
+ int i;
+ Time time;
+ time=speed*curr_time;
+ int smooth((!speed && Noise::smooth==3)?5:Noise::smooth);
+
+ float t(time);
+
+ {
+ float amount=0.0f;
+ float amount2=0.0f;
+ float amount3=0.0f;
+ float alpha=0.0f;
+ for(i=0;i<detail;i++)
+ {
+ amount=random(smooth,0+(detail-i)*5,x,y,t)+amount*0.5;
+ if(amount<-1)amount=-1;if(amount>1)amount=1;
+
+ if(super_sample&&pixel_size)
+ {
+ amount2=random(smooth,0+(detail-i)*5,x2,y,t)+amount2*0.5;
+ if(amount2<-1)amount2=-1;if(amount2>1)amount2=1;
+
+ amount3=random(smooth,0+(detail-i)*5,x,y2,t)+amount3*0.5;
+ if(amount3<-1)amount3=-1;if(amount3>1)amount3=1;
+
+ if(turbulent)
+ {
+ amount2=abs(amount2);
+ amount3=abs(amount3);
+ }
+
+ x2*=0.5f;
+ y2*=0.5f;
+ }
+
+ if(do_alpha)
+ {
+ alpha=random(smooth,3+(detail-i)*5,x,y,t)+alpha*0.5;
+ if(alpha<-1)alpha=-1;if(alpha>1)alpha=1;
+ }
+
+ if(turbulent)
+ {
+ amount=abs(amount);
+ alpha=abs(alpha);
+ }
+
+ x*=0.5f;
+ y*=0.5f;
+ //t*=0.5f;
+ }
+
+ if(!turbulent)
+ {
+ amount=amount/2.0f+0.5f;
+ alpha=alpha/2.0f+0.5f;
+
+ if(super_sample&&pixel_size)
+ {
+ amount2=amount2/2.0f+0.5f;
+ amount3=amount3/2.0f+0.5f;
+ }
+ }
+
+ if(super_sample && pixel_size)
+ ret=gradient(amount,max(amount3,max(amount,amount2))-min(amount3,min(amount,amount2)));
+ else
+ ret=gradient(amount);
+
+ if(do_alpha)
+ ret.set_a(ret.get_a()*(alpha));
+ }
+ return ret;
+}
+
+inline float
+Noise::calc_supersample(const synfig::Point &/*x*/, float /*pw*/,float /*ph*/)const
+{
+ return 0.0f;
+}
+
+void
+Noise::set_time(synfig::Context context, synfig::Time t)const
+{
+ curr_time=t;
+ context.set_time(t);
+}
+
+void
+Noise::set_time(synfig::Context context, synfig::Time t, const synfig::Point &point)const
+{
+ curr_time=t;
+ context.set_time(t,point);
+}
+
+synfig::Layer::Handle
+Noise::hit_check(synfig::Context context, const synfig::Point &point)const
+{
+ if(get_blend_method()==Color::BLEND_STRAIGHT && get_amount()>=0.5)
+ return const_cast<Noise*>(this);
+ if(get_amount()==0.0)
+ return context.hit_check(point);
+ if(color_func(point,0,context).get_a()>0.5)
+ return const_cast<Noise*>(this);
+ return false;
+}
+
+bool
+Noise::set_param(const String & param, const ValueBase &value)
+{
+ if(param=="seed" && value.same_type_as(int()))
+ {
+ random.set_seed(value.get(int()));
+ return true;
+ }
+ IMPORT(size);
+ IMPORT(speed);
+ IMPORT(smooth);
+ IMPORT(detail);
+ IMPORT(do_alpha);
+ IMPORT(gradient);
+ IMPORT(turbulent);
+ IMPORT(super_sample);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+Noise::get_param(const String & param)const
+{
+ if(param=="seed")
+ return random.get_seed();
+ EXPORT(size);
+ EXPORT(speed);
+ EXPORT(smooth);
+ EXPORT(detail);
+ EXPORT(do_alpha);
+ EXPORT(gradient);
+ EXPORT(turbulent)
+ EXPORT(super_sample);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+Noise::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("gradient")
+ .set_local_name(_("Gradient"))
+ );
+ ret.push_back(ParamDesc("seed")
+ .set_local_name(_("Random Seed"))
+ );
+ ret.push_back(ParamDesc("size")
+ .set_local_name(_("Size"))
+ );
+ ret.push_back(ParamDesc("smooth")
+ .set_local_name(_("Interpolation"))
+ .set_description(_("What type of interpolation to use"))
+ .set_hint("enum")
+ .add_enum_value(0,"nearest",_("Nearest Neighbor"))
+ .add_enum_value(1,"linear",_("Linear"))
+ .add_enum_value(2,"cosine",_("Cosine"))
+ .add_enum_value(3,"spline",_("Spline"))
+ .add_enum_value(4,"cubic",_("Cubic"))
+ );
+ ret.push_back(ParamDesc("detail")
+ .set_local_name(_("Detail"))
+ );
+ ret.push_back(ParamDesc("speed")
+ .set_local_name(_("Animation Speed"))
+ );
+ ret.push_back(ParamDesc("turbulent")
+ .set_local_name(_("Turbulent"))
+ );
+ ret.push_back(ParamDesc("do_alpha")
+ .set_local_name(_("Do Alpha"))
+ );
+ ret.push_back(ParamDesc("super_sample")
+ .set_local_name(_("Super Sampling"))
+ );
+
+ return ret;
+}
+
+Color
+Noise::get_color(Context context, const Point &point)const
+{
+ const Color color(color_func(point,0,context));
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,context.get_color(point),get_amount(),get_blend_method());
+}
+
+bool
+Noise::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ }
+ else
+ {
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+ if(get_amount()==0)
+ return true;
+ }
+
+
+ int x,y;
+
+ Surface::pen pen(surface->begin());
+ const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
+ Point pos;
+ Point tl(renddesc.get_tl());
+ const int w(surface->get_w());
+ const int h(surface->get_h());
+ float supersampleradius((abs(pw)+abs(ph))*0.5f);
+ if(quality>=8)
+ supersampleradius=0;
+
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(color_func(pos,supersampleradius,context));
+ }
+ else
+ {
+ for(y=0,pos[1]=tl[1];y<h;y++,pen.inc_y(),pen.dec_x(x),pos[1]+=ph)
+ for(x=0,pos[0]=tl[0];x<w;x++,pen.inc_x(),pos[0]+=pw)
+ pen.put_value(Color::blend(color_func(pos,supersampleradius,context),pen.get_value(),get_amount(),get_blend_method()));
+ }
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file noise.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_NOISE_H
+#define __SYNFIG_NOISE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/vector.h>
+#include <synfig/valuenode.h>
+
+#include <synfig/layer_composite.h>
+#include <synfig/gradient.h>
+#include <synfig/time.h>
+#include "random.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class Noise : public synfig::Layer_Composite, public synfig::Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ synfig::Vector size;
+
+ Random random;
+ int smooth;
+ int detail;
+ bool do_alpha;
+ synfig::Gradient gradient;
+ synfig::Real speed;
+ bool turbulent;
+ bool do_displacement;
+ synfig::Vector displacement;
+
+ //void sync();
+ mutable synfig::Time curr_time;
+
+ bool super_sample;
+
+ synfig::Color color_func(const synfig::Point &x, float supersample,synfig::Context context)const;
+
+ float calc_supersample(const synfig::Point &x, float pw,float ph)const;
+
+public:
+ Noise();
+
+ virtual bool set_param(const synfig::String ¶m, const synfig::ValueBase &value);
+ virtual synfig::ValueBase get_param(const synfig::String ¶m)const;
+ virtual synfig::Color get_color(synfig::Context context, const synfig::Point &pos)const;
+ virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;
+ synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+ virtual void set_time(synfig::Context context, synfig::Time time)const;
+ virtual void set_time(synfig::Context context, synfig::Time time, const synfig::Point &point)const;
+
+ virtual Vocab get_param_vocab()const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_noise/random.cpp
+** \brief blehh
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "random.h"
+#include <synfig/quick_rng.h>
+#include <cmath>
+#include <cstdlib>
+#endif
+
+/* === M A C R O S ========================================================= */
+
+#define PI (3.1415927)
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+void
+Random::set_seed(int x)
+{
+ seed_=x;
+}
+
+float
+Random::operator()(const int salt,const int x,const int y,const int t)const
+{
+ static const unsigned int a(21870);
+ static const unsigned int b(11213);
+ static const unsigned int c(36979);
+ static const unsigned int d(31337);
+
+ quick_rng rng(
+ ( static_cast<unsigned int>(x+y) * a ) ^
+ ( static_cast<unsigned int>(y+t) * b ) ^
+ ( static_cast<unsigned int>(t+x) * c ) ^
+ ( static_cast<unsigned int>(seed_+salt) * d )
+ );
+
+ return rng.f() * 2.0f - 1.0f;
+}
+
+float
+Random::operator()(int smooth,int subseed,float xf,float yf,float tf)const
+{
+ int x((int)floor(xf));
+ int y((int)floor(yf));
+ int t((int)floor(tf));
+
+ switch(smooth)
+ {
+ case 4: // cubic
+ {
+ #define f(j,i,k) ((*this)(subseed,i,j,k))
+ //Using catmull rom interpolation because it doesn't blur at all
+ //bezier curve with intermediate ctrl pts: 0.5/3(p(i+1) - p(i-1)) and similar
+ float xfa [4], tfa[4];
+
+ //precalculate indices (all clamped) and offset
+ const int xa[] = {x-1,x,x+1,x+2};
+
+ const int ya[] = {y-1,y,y+1,y+2};
+
+ const int ta[] = {t-1,t,t+1,t+2};
+
+ const float dx(xf-x);
+ const float dy(yf-y);
+ const float dt(tf-t);
+
+ //figure polynomials for each point
+ const float txf[] =
+ {
+ 0.5*dx*(dx*(dx*(-1) + 2) - 1), //-t + 2t^2 -t^3
+ 0.5*(dx*(dx*(3*dx - 5)) + 2), //2 - 5t^2 + 3t^3
+ 0.5*dx*(dx*(-3*dx + 4) + 1), //t + 4t^2 - 3t^3
+ 0.5*dx*dx*(dx-1) //-t^2 + t^3
+ };
+
+ const float tyf[] =
+ {
+ 0.5*dy*(dy*(dy*(-1) + 2) - 1), //-t + 2t^2 -t^3
+ 0.5*(dy*(dy*(3*dy - 5)) + 2), //2 - 5t^2 + 3t^3
+ 0.5*dy*(dy*(-3*dy + 4) + 1), //t + 4t^2 - 3t^3
+ 0.5*dy*dy*(dy-1) //-t^2 + t^3
+ };
+
+ const float ttf[] =
+ {
+ 0.5*dt*(dt*(dt*(-1) + 2) - 1), //-t + 2t^2 -t^3
+ 0.5*(dt*(dt*(3*dt - 5)) + 2), //2 - 5t^2 + 3t^3
+ 0.5*dt*(dt*(-3*dt + 4) + 1), //t + 4t^2 - 3t^3
+ 0.5*dt*dt*(dt-1) //-t^2 + t^3
+ };
+
+ //evaluate polynomial for each row
+ for(int i = 0; i < 4; ++i)
+ {
+ for(int j = 0; j < 4; ++j)
+ {
+ tfa[j] = f(ya[i],xa[j],ta[0])*ttf[0] + f(ya[i],xa[j],ta[1])*ttf[1] + f(ya[i],xa[j],ta[2])*ttf[2] + f(ya[i],xa[j],ta[3])*ttf[3];
+ }
+ xfa[i] = tfa[0]*txf[0] + tfa[1]*txf[1] + tfa[2]*txf[2] + tfa[3]*txf[3];
+ }
+
+ //return the cumulative column evaluation
+ return xfa[0]*tyf[0] + xfa[1]*tyf[1] + xfa[2]*tyf[2] + xfa[3]*tyf[3];
+#undef f
+ }
+ break;
+
+
+ case 5: // Fast Spline (non-animated)
+ {
+#define P(x) (((x)>0)?((x)*(x)*(x)):0.0f)
+#define R(x) ( P(x+2) - 4.0f*P(x+1) + 6.0f*P(x) - 4.0f*P(x-1) )*(1.0f/6.0f)
+#define F(i,j) ((*this)(subseed,i+x,j+y)*(R((i)-a)*R(b-(j))))
+#define FT(i,j,k) ((*this)(subseed,i+x,j+y,k+t)*(R((i)-a)*R(b-(j))*R((k)-c)))
+#define Z(i,j) ret+=F(i,j)
+#define ZT(i,j,k) ret+=FT(i,j,k)
+#define X(i,j) // placeholder... To make box more symmetric
+#define XT(i,j,k) // placeholder... To make box more symmetric
+
+ float a(xf-x), b(yf-y);
+
+ // Interpolate
+ float ret(F(0,0));
+ Z(-1,-1); Z(-1, 0); Z(-1, 1); Z(-1, 2);
+ Z( 0,-1); X( 0, 0); Z( 0, 1); Z( 0, 2);
+ Z( 1,-1); Z( 1, 0); Z( 1, 1); Z( 1, 2);
+ Z( 2,-1); Z( 2, 0); Z( 2, 1); Z( 2, 2);
+
+ return ret;
+ }
+
+ case 3: // Spline (animated)
+ {
+ float a(xf-x), b(yf-y), c(tf-t);
+
+ // Interpolate
+ float ret(FT(0,0,0));
+ ZT(-1,-1,-1); ZT(-1, 0,-1); ZT(-1, 1,-1); ZT(-1, 2,-1);
+ ZT( 0,-1,-1); ZT( 0, 0,-1); ZT( 0, 1,-1); ZT( 0, 2,-1);
+ ZT( 1,-1,-1); ZT( 1, 0,-1); ZT( 1, 1,-1); ZT( 1, 2,-1);
+ ZT( 2,-1,-1); ZT( 2, 0,-1); ZT( 2, 1,-1); ZT( 2, 2,-1);
+
+ ZT(-1,-1, 0); ZT(-1, 0, 0); ZT(-1, 1, 0); ZT(-1, 2, 0);
+ ZT( 0,-1, 0); XT( 0, 0, 0); ZT( 0, 1, 0); ZT( 0, 2, 0);
+ ZT( 1,-1, 0); ZT( 1, 0, 0); ZT( 1, 1, 0); ZT( 1, 2, 0);
+ ZT( 2,-1, 0); ZT( 2, 0, 0); ZT( 2, 1, 0); ZT( 2, 2, 0);
+
+ ZT(-1,-1, 1); ZT(-1, 0, 1); ZT(-1, 1, 1); ZT(-1, 2, 1);
+ ZT( 0,-1, 1); ZT( 0, 0, 1); ZT( 0, 1, 1); ZT( 0, 2, 1);
+ ZT( 1,-1, 1); ZT( 1, 0, 1); ZT( 1, 1, 1); ZT( 1, 2, 1);
+ ZT( 2,-1, 1); ZT( 2, 0, 1); ZT( 2, 1, 1); ZT( 2, 2, 1);
+
+ ZT(-1,-1, 2); ZT(-1, 0, 2); ZT(-1, 1, 2); ZT(-1, 2, 2);
+ ZT( 0,-1, 2); ZT( 0, 0, 2); ZT( 0, 1, 2); ZT( 0, 2, 2);
+ ZT( 1,-1, 2); ZT( 1, 0, 2); ZT( 1, 1, 2); ZT( 1, 2, 2);
+ ZT( 2,-1, 2); ZT( 2, 0, 2); ZT( 2, 1, 2); ZT( 2, 2, 2);
+
+ return ret;
+
+/*
+
+ float dx=xf-x;
+ float dy=yf-y;
+ float dt=tf-t;
+
+ float ret=0;
+ int i,j,h;
+ for(h=-1;h<=2;h++)
+ for(i=-1;i<=2;i++)
+ for(j=-1;j<=2;j++)
+ ret+=(*this)(subseed,i+x,j+y,h+t)*(R(i-dx)*R(j-dy)*R(h-dt));
+ return ret;
+*/
+ }
+ break;
+#undef X
+#undef Z
+#undef F
+#undef P
+#undef R
+
+ case 2: // Cosine
+ if((float)t==tf)
+ {
+ int x((int)floor(xf));
+ int y((int)floor(yf));
+ float a=xf-x;
+ float b=yf-y;
+ a=(1.0f-cos(a*PI))*0.5f;
+ b=(1.0f-cos(b*PI))*0.5f;
+ float c=1.0-a;
+ float d=1.0-b;
+ int x2=x+1,y2=y+1;
+ return
+ (*this)(subseed,x,y,t)*(c*d)+
+ (*this)(subseed,x2,y,t)*(a*d)+
+ (*this)(subseed,x,y2,t)*(c*b)+
+ (*this)(subseed,x2,y2,t)*(a*b);
+ }
+ else
+ {
+ float a=xf-x;
+ float b=yf-y;
+ float c=tf-t;
+
+ a=(1.0f-cos(a*3.1415927))*0.5f;
+ b=(1.0f-cos(b*3.1415927))*0.5f;
+
+ // We don't perform this on the time axis, otherwise we won't
+ // get smooth motion
+ //c=(1.0f-cos(c*3.1415927))*0.5f;
+
+ float d=1.0-a;
+ float e=1.0-b;
+ float f=1.0-c;
+
+ int x2=x+1,y2=y+1,t2=t+1;
+
+ return
+ (*this)(subseed,x,y,t)*(d*e*f)+
+ (*this)(subseed,x2,y,t)*(a*e*f)+
+ (*this)(subseed,x,y2,t)*(d*b*f)+
+ (*this)(subseed,x2,y2,t)*(a*b*f)+
+ (*this)(subseed,x,y,t2)*(d*e*c)+
+ (*this)(subseed,x2,y,t2)*(a*e*c)+
+ (*this)(subseed,x,y2,t2)*(d*b*c)+
+ (*this)(subseed,x2,y2,t2)*(a*b*c);
+ }
+ case 1: // Linear
+ if((float)t==tf)
+ {
+ int x((int)floor(xf));
+ int y((int)floor(yf));
+ float a=xf-x;
+ float b=yf-y;
+ float c=1.0-a;
+ float d=1.0-b;
+ int x2=x+1,y2=y+1;
+ return
+ (*this)(subseed,x,y,t)*(c*d)+
+ (*this)(subseed,x2,y,t)*(a*d)+
+ (*this)(subseed,x,y2,t)*(c*b)+
+ (*this)(subseed,x2,y2,t)*(a*b);
+ }
+ else
+ {
+
+ float a=xf-x;
+ float b=yf-y;
+ float c=tf-t;
+
+ float d=1.0-a;
+ float e=1.0-b;
+ float f=1.0-c;
+
+ int x2=x+1,y2=y+1,t2=t+1;
+
+ return
+ (*this)(subseed,x,y,t)*(d*e*f)+
+ (*this)(subseed,x2,y,t)*(a*e*f)+
+ (*this)(subseed,x,y2,t)*(d*b*f)+
+ (*this)(subseed,x2,y2,t)*(a*b*f)+
+ (*this)(subseed,x,y,t2)*(d*e*c)+
+ (*this)(subseed,x2,y,t2)*(a*e*c)+
+ (*this)(subseed,x,y2,t2)*(d*b*c)+
+ (*this)(subseed,x2,y2,t2)*(a*b*c);
+ }
+ default:
+ case 0:
+ return (*this)(subseed,x,y,t);
+ }
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_noise/random.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_RANDOM_H
+#define __SYNFIG_RANDOM_H
+
+/* === H E A D E R S ======================================================= */
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+
+#define POOL_SIZE (256)
+class Random
+{
+ int seed_;
+public:
+
+ void set_seed(int x);
+ int get_seed()const { return seed_; }
+
+ float operator()(int subseed,int x,int y=0, int t=0)const;
+ float operator()(int smooth,int subseed,float x,float y=0, float t=0)const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_noise"
+ Delete "$INSTDIR\lib\synfig\modules\mod_noise.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+if WITH_OPENEXR
+module_LTLIBRARIES = libmod_openexr.la
+libmod_openexr_la_SOURCES = main.cpp mptr_openexr.cpp mptr_openexr.h trgt_openexr.cpp trgt_openexr.h
+libmod_openexr_la_LDFLAGS = -module @PNG_LIBS@ -no-undefined
+libmod_openexr_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@ @OPENEXR_LIBS@
+libmod_openexr_la_CXXFLAGS = @SYNFIG_CFLAGS@ @OPENEXR_CFLAGS@
+else
+endif
+
+
+EXTRA_DIST= mod_openexr.nsh unmod_openexr.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_openexr/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#else
+#warning HAVE_CONFIG_H not defined!
+#endif
+
+#include <synfig/module.h>
+#include "trgt_openexr.h"
+#include "mptr_openexr.h"
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(mod_openexr)
+ MODULE_NAME("OpenEXR Module")
+ MODULE_DESCRIPTION("Provides support for the EXR image format.")
+ MODULE_AUTHOR("Industrial Light & Magic")
+ MODULE_VERSION("1.0.4")
+ MODULE_COPYRIGHT("OpenEXR Library is Copyright (c) 2003 Lucas Digital Ltd. LLC.")
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(mod_openexr)
+ BEGIN_TARGETS
+ TARGET(exr_trgt)
+ END_TARGETS
+ BEGIN_IMPORTERS
+ IMPORTER(exr_mptr)
+ END_IMPORTERS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_openexr" Sec_mod_openexr
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_openexr.dll "src\modules\mod_openexr\.libs\libmod_openexr-0.dll"
+
+ SetOutPath "$INSTDIR\bin"
+ File /oname=libHalf-4.dll "src\modules\mod_openexr\.libs\libHalf-4.dll"
+ File /oname=libIlmImf-4.dll "src\modules\mod_openexr\.libs\libIlmImf-4.dll"
+ File /oname=libIlmThread-4.dll "src\modules\mod_openexr\.libs\libIlmThread-4.dll"
+ File /oname=libIex-4.dll "src\modules\mod_openexr\.libs\libIex-4.dll"
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_openexr"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_openexr.cpp
+** \brief ppm Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "mptr_openexr.h"
+#include <synfig/general.h>
+#include <synfig/surface.h>
+#include <ETL/stringf>
+#include <cstdio>
+#include <algorithm>
+#include <functional>
+
+#include <ImfArray.h>
+#include <ImfRgbaFile.h>
+#include <exception>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_IMPORTER_INIT(exr_mptr);
+SYNFIG_IMPORTER_SET_NAME(exr_mptr,"openexr");
+SYNFIG_IMPORTER_SET_EXT(exr_mptr,"exr");
+SYNFIG_IMPORTER_SET_VERSION(exr_mptr,"0.1");
+SYNFIG_IMPORTER_SET_CVS_ID(exr_mptr,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+exr_mptr::exr_mptr(const char *file)
+{
+ filename=file;
+}
+
+exr_mptr::~exr_mptr()
+{
+}
+
+bool
+exr_mptr::get_frame(synfig::Surface &out_surface,Time, synfig::ProgressCallback *cb)
+{
+ try
+ {
+
+ Imf::RgbaInputFile in(filename.c_str());
+
+ int w = in.dataWindow().max.x - in.dataWindow().min.x + 1;
+ int h = in.dataWindow().max.y - in.dataWindow().min.y + 1;
+ //int dx = in.dataWindow().min.x;
+ //int dy = in.dataWindow().min.y;
+
+#ifdef USE_HALF_TYPE
+ out_surface.set_wh(w,h);
+ in.setFrameBuffer (reinterpret_cast<Imf::Rgba *>(out_surface[0]), 1, w);
+
+ in.readPixels (in.dataWindow().min.y, in.dataWindow().max.y);
+
+#else
+ etl::surface<Imf::Rgba> in_surface;
+ in_surface.set_wh(w,h);
+ in.setFrameBuffer (reinterpret_cast<Imf::Rgba *>(in_surface[0]), 1, w);
+
+ in.readPixels (in.dataWindow().min.y, in.dataWindow().max.y);
+
+ int x;
+ int y;
+ out_surface.set_wh(w,h);
+ for(y=0;y<out_surface.get_h();y++)
+ for(x=0;x<out_surface.get_w();x++)
+ {
+ Color &color(out_surface[y][x]);
+ Imf::Rgba &rgba(in_surface[y][x]);
+ color.set_r(rgba.r);
+ color.set_g(rgba.g);
+ color.set_b(rgba.b);
+ color.set_a(rgba.a);
+ }
+#endif
+ }
+ catch (const std::exception &e)
+ {
+ if(cb)cb->error(e.what());
+ else synfig::error(e.what());
+ return false;
+ }
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_openexr.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_MPTR_OPENEXR_H
+#define __SYNFIG_MPTR_OPENEXR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/importer.h>
+#include <stdio.h>
+#include <synfig/string.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class exr_mptr : public synfig::Importer
+{
+ SYNFIG_IMPORTER_MODULE_EXT
+
+private:
+ synfig::String filename;
+public:
+ exr_mptr(const char *filename);
+ ~exr_mptr();
+
+
+
+ virtual bool get_frame(synfig::Surface &surface,synfig::Time time, synfig::ProgressCallback *callback);
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_openexr.cpp
+** \brief exr_trgt Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_TARGET
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trgt_openexr.h"
+#include <ETL/stringf>
+#include <cstdio>
+#include <algorithm>
+#include <functional>
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_TARGET_INIT(exr_trgt);
+SYNFIG_TARGET_SET_NAME(exr_trgt,"openexr");
+SYNFIG_TARGET_SET_EXT(exr_trgt,"exr");
+SYNFIG_TARGET_SET_VERSION(exr_trgt,"1.0.4");
+SYNFIG_TARGET_SET_CVS_ID(exr_trgt,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+bool
+exr_trgt::ready()
+{
+ return (bool)exr_file;
+}
+
+exr_trgt::exr_trgt(const char *Filename):
+ multi_image(false),
+ imagecount(0),
+ filename(Filename),
+ exr_file(0)
+{
+ buffer=0;
+#ifndef USE_HALF_TYPE
+ buffer_color=0;
+#endif
+
+ // OpenEXR uses linear gamma
+ gamma().set_gamma(1.0);
+}
+
+exr_trgt::~exr_trgt()
+{
+ if(exr_file)
+ delete exr_file;
+
+ if(buffer) delete [] buffer;
+#ifndef USE_HALF_TYPE
+ if(buffer_color) delete [] buffer_color;
+#endif
+}
+
+bool
+exr_trgt::set_rend_desc(RendDesc *given_desc)
+{
+ //given_desc->set_pixel_format(PixelFormat((int)PF_RAW_COLOR));
+ desc=*given_desc;
+ imagecount=desc.get_frame_start();
+ if(desc.get_frame_end()-desc.get_frame_start()>0)
+ multi_image=true;
+ else
+ multi_image=false;
+ return true;
+}
+
+bool
+exr_trgt::start_frame(synfig::ProgressCallback *cb)
+{
+ int w=desc.get_w(),h=desc.get_h();
+
+ String frame_name;
+
+ if(exr_file)
+ delete exr_file;
+ if(multi_image)
+ {
+ String
+ newfilename(filename),
+ ext(find(filename.begin(),filename.end(),'.'),filename.end());
+ newfilename.erase(find(newfilename.begin(),newfilename.end(),'.'),newfilename.end());
+
+ newfilename+=etl::strprintf("%04d",imagecount)+ext;
+ frame_name=newfilename;
+ if(cb)cb->task(newfilename);
+ }
+ else
+ {
+ frame_name=filename;
+ if(cb)cb->task(filename);
+ }
+ exr_file=new Imf::RgbaOutputFile(frame_name.c_str(),w,h,Imf::WRITE_RGBA,desc.get_pixel_aspect());
+#ifndef USE_HALF_TYPE
+ if(buffer_color) delete [] buffer_color;
+ buffer_color=new Color[w];
+#endif
+ //if(buffer) delete [] buffer;
+ //buffer=new Imf::Rgba[w];
+ out_surface.set_wh(w,h);
+
+ return true;
+}
+
+void
+exr_trgt::end_frame()
+{
+ if(exr_file)
+ {
+ exr_file->setFrameBuffer(out_surface[0],1,desc.get_w());
+ exr_file->writePixels(desc.get_h());
+
+ delete exr_file;
+ }
+
+ exr_file=0;
+
+ imagecount++;
+}
+
+Color *
+exr_trgt::start_scanline(int i)
+{
+ scanline=i;
+#ifndef USE_HALF_TYPE
+ return reinterpret_cast<Color *>(buffer_color);
+#else
+ return reinterpret_cast<Color *>(out_surface[scanline]);
+// return reinterpret_cast<unsigned char *>(buffer);
+#endif
+}
+
+bool
+exr_trgt::end_scanline()
+{
+ if(!ready())
+ return false;
+
+#ifndef USE_HALF_TYPE
+ int i;
+ for(i=0;i<desc.get_w();i++)
+ {
+// Imf::Rgba &rgba=buffer[i];
+ Imf::Rgba &rgba=out_surface[scanline][i];
+ Color &color=buffer_color[i];
+ rgba.r=color.get_r();
+ rgba.g=color.get_g();
+ rgba.b=color.get_b();
+ rgba.a=color.get_a();
+ }
+#endif
+
+ //exr_file->setFrameBuffer(buffer,1,desc.get_w());
+ //exr_file->writePixels(1);
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_openexr.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRGT_OPENEXR_H
+#define __SYNFIG_TRGT_OPENEXR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/target_scanline.h>
+#include <synfig/string.h>
+#include <synfig/surface.h>
+#include <cstdio>
+#include <OpenEXR/ImfArray.h>
+#include <OpenEXR/ImfRgbaFile.h>
+#include <exception>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class exr_trgt : public synfig::Target_Scanline
+{
+public:
+private:
+ bool multi_image;
+ int imagecount,scanline;
+ synfig::String filename;
+ Imf::RgbaOutputFile *exr_file;
+ Imf::Rgba *buffer;
+ etl::surface<Imf::Rgba> out_surface;
+#ifndef USE_HALF_TYPE
+ synfig::Color *buffer_color;
+#endif
+
+ bool ready();
+public:
+ exr_trgt(const char *filename);
+ virtual ~exr_trgt();
+
+ virtual bool set_rend_desc(synfig::RendDesc *desc);
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+ virtual void end_frame();
+
+ virtual synfig::Color * start_scanline(int scanline);
+ virtual bool end_scanline(void);
+
+
+ SYNFIG_TARGET_MODULE_EXT
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_openexr"
+ Delete "$INSTDIR\bin\libIex-4.dll"
+ Delete "$INSTDIR\bin\libIlmImf-4.dll"
+ Delete "$INSTDIR\bin\libIlmThread-4.dll"
+ Delete "$INSTDIR\bin\libHalf-4.dll"
+ Delete "$INSTDIR\lib\synfig\modules\mod_openexr.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR\bin"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+module_LTLIBRARIES = libmod_particle.la
+libmod_particle_la_SOURCES = random.cpp random.h plant.cpp plant.h main.cpp
+libmod_particle_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_particle_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+libmod_particle_la_LDFLAGS = -module -no-undefined
+EXTRA_DIST= mod_particle.nsh unmod_particle.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_particle/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include <synfig/string.h>
+#include <synfig/canvas.h>
+
+#include "plant.h"
+
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(libmod_particle)
+ MODULE_NAME("Particle Systems")
+ MODULE_DESCRIPTION("writeme")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(libmod_particle)
+ BEGIN_LAYERS
+ LAYER(Plant)
+ END_LAYERS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_particle" Sec_mod_particle
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_particle.dll "src\modules\mod_particle\.libs\libmod_particle-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_particle"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file plant.cpp
+** \brief Template
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/angle.h>
+#include "plant.h"
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+
+#include <ETL/calculus>
+#include <ETL/bezier>
+#include <ETL/hermite>
+#include <vector>
+
+#include <synfig/valuenode_bline.h>
+
+#endif
+
+using namespace etl;
+
+/* === M A C R O S ========================================================= */
+
+#define SAMPLES 300
+#define ROUND_END_FACTOR (4)
+#define CUSP_THRESHOLD (0.15)
+#define NO_LOOP_COOKIE synfig::Vector(84951305,7836658)
+#define EPSILON (0.000000001)
+#define CUSP_TANGENT_ADJUST (0.025)
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Plant);
+SYNFIG_LAYER_SET_NAME(Plant,"plant");
+SYNFIG_LAYER_SET_LOCAL_NAME(Plant,_("Plant"));
+SYNFIG_LAYER_SET_CATEGORY(Plant,_("Other"));
+SYNFIG_LAYER_SET_VERSION(Plant,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Plant,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+
+Plant::Plant():
+ split_angle(Angle::deg(10)),
+ gravity(0,-0.1),
+ velocity(0.3),
+ perp_velocity(0.0),
+ step(0.01),
+ sprouts(10)
+{
+ bounding_rect=Rect::zero();
+ random_factor=0.2;
+ random.set_seed(time(NULL));
+
+ bline.push_back(BLinePoint());
+ bline.push_back(BLinePoint());
+ bline.push_back(BLinePoint());
+ bline[0].set_vertex(Point(0,1));
+ bline[1].set_vertex(Point(0,-1));
+ bline[2].set_vertex(Point(1,0));
+ bline[0].set_tangent(bline[1].get_vertex()-bline[2].get_vertex()*0.5f);
+ bline[1].set_tangent(bline[2].get_vertex()-bline[0].get_vertex()*0.5f);
+ bline[2].set_tangent(bline[0].get_vertex()-bline[1].get_vertex()*0.5f);
+ bline[0].set_width(1.0f);
+ bline[1].set_width(1.0f);
+ bline[2].set_width(1.0f);
+ bline_loop=true;
+ mass=(0.5);
+ splits=5;
+ drag=0.1;
+ size=0.015;
+ needs_sync_=true;
+ sync();
+ size_as_alpha=false;
+}
+
+void
+Plant::branch(int n,int depth,float t, float stunt_growth, synfig::Point position,synfig::Vector vel)const
+{
+ float next_split((1.0-t)/(splits-depth)+t/*+random_factor*random(40+depth,t*splits,0,0)/splits*/);
+ for(;t<next_split;t+=step)
+ {
+ vel[0]+=gravity[0]*step;
+ vel[1]+=gravity[1]*step;
+ vel*=(1.0-(drag)*step);
+ position[0]+=vel[0]*step;
+ position[1]+=vel[1]*step;
+
+ particle_list.push_back(Particle(position, gradient(t)));
+ if (particle_list.size() % 1000000 == 0)
+ synfig::info("constructed %d million particles...", particle_list.size()/1000000);
+
+ bounding_rect.expand(position);
+ }
+
+ if(t>=1.0-stunt_growth)return;
+
+ synfig::Real sin_v=synfig::Angle::cos(split_angle).get();
+ synfig::Real cos_v=synfig::Angle::sin(split_angle).get();
+
+ synfig::Vector velocity1(vel[0]*sin_v - vel[1]*cos_v + random_factor*random(Random::SMOOTH_COSINE, 30+n+depth, t*splits, 0.0f, 0.0f),
+ vel[0]*cos_v + vel[1]*sin_v + random_factor*random(Random::SMOOTH_COSINE, 32+n+depth, t*splits, 0.0f, 0.0f));
+ synfig::Vector velocity2(vel[0]*sin_v + vel[1]*cos_v + random_factor*random(Random::SMOOTH_COSINE, 31+n+depth, t*splits, 0.0f, 0.0f),
+ -vel[0]*cos_v + vel[1]*sin_v + random_factor*random(Random::SMOOTH_COSINE, 33+n+depth, t*splits, 0.0f, 0.0f));
+
+ Plant::branch(n,depth+1,t,stunt_growth,position,velocity1);
+ Plant::branch(n,depth+1,t,stunt_growth,position,velocity2);
+}
+
+void
+Plant::calc_bounding_rect()const
+{
+ std::vector<synfig::BLinePoint>::const_iterator iter,next;
+
+ bounding_rect=Rect::zero();
+
+ // Bline must have at least 2 points in it
+ if(bline.size()<2)
+ return;
+
+ next=bline.begin();
+
+ if(bline_loop)
+ iter=--bline.end();
+ else
+ iter=next++;
+
+ for(;next!=bline.end();iter=next++)
+ {
+ bounding_rect.expand(iter->get_vertex());
+ bounding_rect.expand(next->get_vertex());
+ bounding_rect.expand(iter->get_vertex()+iter->get_tangent2()*0.3333333333333);
+ bounding_rect.expand(next->get_vertex()-next->get_tangent1()*0.3333333333333);
+ bounding_rect.expand(next->get_vertex()+next->get_tangent2()*velocity);
+ }
+ bounding_rect.expand_x(gravity[0]);
+ bounding_rect.expand_y(gravity[1]);
+ bounding_rect.expand_x(size);
+ bounding_rect.expand_y(size);
+}
+
+void
+Plant::sync()const
+{
+ Mutex::Lock lock(mutex);
+ if (!needs_sync_) return;
+ time_t start_time; time(&start_time);
+ particle_list.clear();
+
+ bounding_rect=Rect::zero();
+
+ // Bline must have at least 2 points in it
+ if(bline.size()<2)
+ {
+ needs_sync_=false;
+ return;
+ }
+
+ std::vector<synfig::BLinePoint>::const_iterator iter,next;
+
+ etl::hermite<Vector> curve;
+
+ Real step(abs(this->step));
+
+ int seg(0);
+
+ next=bline.begin();
+
+ if(bline_loop) iter=--bline.end(); // iter is the last bline in the list; next is the first bline in the list
+ else iter=next++; // iter is the first bline in the list; next is the second bline in the list
+
+ // loop through the bline; seg counts the blines as we do so; stop before iter is the last bline in the list
+ for(;next!=bline.end();iter=next++,seg++)
+ {
+ curve.p1()=iter->get_vertex();
+ curve.t1()=iter->get_tangent2();
+ curve.p2()=next->get_vertex();
+ curve.t2()=next->get_tangent1();
+ curve.sync();
+ etl::derivative<etl::hermite<Vector> > deriv(curve);
+
+ Real f;
+
+ int i=0, branch_count = 0, steps = round_to_int(1.0/step);
+ for(f=0.0;f<1.0;f+=step,i++)
+ {
+ Point point(curve(f));
+
+ particle_list.push_back(Particle(point, gradient(0)));
+ if (particle_list.size() % 1000000 == 0)
+ synfig::info("constructed %d million particles...", particle_list.size()/1000000);
+
+ bounding_rect.expand(point);
+
+ Real stunt_growth(random_factor * (random(Random::SMOOTH_COSINE,i,f+seg,0.0f,0.0f)/2.0+0.5));
+ stunt_growth*=stunt_growth;
+
+ if((((i+1)*sprouts + steps/2) / steps) > branch_count) {
+ Vector branch_velocity(deriv(f).norm()*velocity + deriv(f).perp().norm()*perp_velocity);
+
+ branch_velocity[0] += random_factor * random(Random::SMOOTH_COSINE, 1, f*splits, 0.0f, 0.0f);
+ branch_velocity[1] += random_factor * random(Random::SMOOTH_COSINE, 2, f*splits, 0.0f, 0.0f);
+
+ branch_count++;
+ branch(i, 0, 0, // time
+ stunt_growth, // stunt growth
+ point, branch_velocity);
+ }
+ }
+ }
+
+ time_t end_time; time(&end_time);
+ if (end_time-start_time > 4)
+ synfig::info("Plant::sync() constructed %d particles in %d seconds\n",
+ particle_list.size(), int(end_time-start_time));
+ needs_sync_=false;
+}
+
+bool
+Plant::set_param(const String & param, const ValueBase &value)
+{
+ if(param=="bline" && value.get_type()==ValueBase::TYPE_LIST)
+ {
+ bline=value;
+ bline_loop=value.get_loop();
+ needs_sync_=true;
+
+ return true;
+ }
+ if(param=="seed" && value.same_type_as(int()))
+ {
+ random.set_seed(value.get(int()));
+ needs_sync_=true;
+ return true;
+ }
+ IMPORT_PLUS(split_angle,needs_sync_=true);
+ IMPORT_PLUS(gravity,needs_sync_=true);
+ IMPORT_PLUS(gradient,needs_sync_=true);
+ IMPORT_PLUS(velocity,needs_sync_=true);
+ IMPORT_PLUS(perp_velocity,needs_sync_=true);
+ IMPORT_PLUS(step,needs_sync_=true);
+ IMPORT_PLUS(splits,needs_sync_=true);
+ IMPORT_PLUS(sprouts,needs_sync_=true);
+ IMPORT_PLUS(random_factor,needs_sync_=true);
+ IMPORT_PLUS(drag,needs_sync_=true);
+ IMPORT(size);
+ IMPORT(size_as_alpha);
+
+ return Layer_Composite::set_param(param,value);
+}
+/*
+void
+Plant::set_time(Context context, Time time)const
+{
+ if(needs_sync==true)
+ {
+ sync();
+ needs_sync_=false;
+ }
+ //const_cast<Plant*>(this)->sync();
+ context.set_time(time);
+}
+
+void
+Plant::set_time(Context context, Time time, Vector pos)const
+{
+ if(needs_sync==true)
+ {
+ sync();
+ needs_sync_=false;
+ }
+ //const_cast<Plant*>(this)->sync();
+ context.set_time(time,pos);
+}
+*/
+ValueBase
+Plant::get_param(const String& param)const
+{
+ if(param=="seed")
+ return random.get_seed();
+ EXPORT(bline);
+ EXPORT(split_angle);
+ EXPORT(gravity);
+ EXPORT(velocity);
+ EXPORT(perp_velocity);
+ EXPORT(step);
+ EXPORT(gradient);
+ EXPORT(splits);
+ EXPORT(sprouts);
+ EXPORT(random_factor);
+ EXPORT(drag);
+ EXPORT(size);
+
+ EXPORT(size_as_alpha);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+Plant::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("bline")
+ .set_local_name(_("Vertices"))
+ .set_description(_("A list of BLine Points"))
+ //.set_origin("offset")
+ //.set_scalar("width")
+ );
+
+ ret.push_back(ParamDesc("gradient")
+ .set_local_name(_("Gradient"))
+ .set_description(_("Gradient to be used for coloring the plant"))
+ );
+
+ ret.push_back(ParamDesc("split_angle")
+ .set_local_name(_("Split Angle"))
+ .set_description(_("Angle by which each split deviates from its parent"))
+ );
+
+ ret.push_back(ParamDesc("gravity")
+ .set_local_name(_("Gravity"))
+ .set_description(_("Direction in which the shoots tend to face"))
+ .set_is_distance()
+ );
+
+ ret.push_back(ParamDesc("velocity")
+ .set_local_name(_("Tangential Velocity"))
+ .set_description(_("Amount to which shoots tend to grow along the tangent to the BLine"))
+ );
+
+ ret.push_back(ParamDesc("perp_velocity")
+ .set_local_name(_("Perpendicular Velocity"))
+ .set_description(_("Amount to which shoots tend to grow perpendicular to the tangent to the BLine"))
+ );
+
+ ret.push_back(ParamDesc("size")
+ .set_local_name(_("Stem Size"))
+ .set_description(_("Size of the stem"))
+ .set_is_distance()
+ );
+
+ ret.push_back(ParamDesc("size_as_alpha")
+ .set_local_name(_("Size As Alpha"))
+ .set_description(_("If enabled, the alpha channel from the gradient is multiplied by the stem size, and an alpha of 1.0 is used when rendering"))
+ );
+
+ ret.push_back(ParamDesc("step")
+ .set_local_name(_("Step"))
+ .set_description(_("Measure of the distance between points when rendering"))
+ );
+
+ ret.push_back(ParamDesc("seed")
+ .set_local_name(_("Seed"))
+ .set_description(_("Used to seed the pseudo-random number generator"))
+ );
+
+ ret.push_back(ParamDesc("splits")
+ .set_local_name(_("Splits"))
+ .set_description(_("Maximum number of times that each sprout can sprout recursively"))
+ );
+
+ ret.push_back(ParamDesc("sprouts")
+ .set_local_name(_("Sprouts"))
+ .set_description(_("Number of places that growth occurs on each bline section"))
+ );
+
+ ret.push_back(ParamDesc("random_factor")
+ .set_local_name(_("Random Factor"))
+ .set_description(_("Used to scale down all random effects. Set to zero to disable randomness"))
+ );
+
+ ret.push_back(ParamDesc("drag")
+ .set_local_name(_("Drag"))
+ .set_description(_("Drag slows the growth"))
+ );
+
+ return ret;
+}
+
+bool
+Plant::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ bool ret(context.accelerated_render(surface,quality,renddesc,cb));
+ if(is_disabled() || !ret)
+ return ret;
+
+ Surface dest_surface;
+ dest_surface.set_wh(surface->get_w(),surface->get_h());
+ dest_surface.clear();
+
+ const Point tl(renddesc.get_tl());
+ const Point br(renddesc.get_br());
+
+ const int w(renddesc.get_w());
+ const int h(renddesc.get_h());
+
+ const int surface_width(surface->get_w());
+ const int surface_height(surface->get_h());
+
+ // Width and Height of a pixel
+ const Real pw = (br[0] - tl[0]) / w;
+ const Real ph = (br[1] - tl[1]) / h;
+
+ if(needs_sync_==true)
+ sync();
+
+ std::vector<Particle>::reverse_iterator iter;
+
+ float radius(size*sqrt(1.0f/(abs(pw)*abs(ph))));
+
+ int x1,y1,x2,y2;
+ for(iter=particle_list.rbegin();iter!=particle_list.rend();++iter)
+ {
+ float scaled_radius(radius);
+ Color color(iter->color);
+ if(size_as_alpha)
+ {
+ scaled_radius*=color.get_a();
+ color.set_a(1);
+ }
+
+ // previously, radius was multiplied by sqrt(step)*12 only if
+ // the radius came out at less than 1 (pixel):
+ // if (radius<=1.0f) radius*=sqrt(step)*12.0f;
+ // seems a little arbitrary - does it help?
+
+ // calculate the box that this particle will be drawn as
+ float x1f=(iter->point[0]-tl[0])/pw-(scaled_radius*0.5);
+ float x2f=(iter->point[0]-tl[0])/pw+(scaled_radius*0.5);
+ float y1f=(iter->point[1]-tl[1])/ph-(scaled_radius*0.5);
+ float y2f=(iter->point[1]-tl[1])/ph+(scaled_radius*0.5);
+ x1=ceil_to_int(x1f);
+ x2=ceil_to_int(x2f)-1;
+ y1=ceil_to_int(y1f);
+ y2=ceil_to_int(y2f)-1;
+
+ // if the box is entirely off the canvas, go to the next particle
+ if(x1>surface_width || y1>surface_height || x2<0 || y2<0) continue;
+
+ float x1e=x1-x1f, x2e=x2f-x2, y1e=y1-y1f, y2e=y2f-y2;
+ // printf("x1e %.4f x2e %.4f y1e %.4f y2e %.4f\n", x1e, x2e, y1e, y2e);
+
+ // adjust the box so it's entirely on the canvas
+ if(x1<=0) { x1=0; x1e=0; }
+ if(y1<=0) { y1=0; y1e=0; }
+ if(x2>=surface_width) { x2=surface_width; x2e=0; }
+ if(y2>=surface_height) { y2=surface_height; y2e=0; }
+
+ int w(x2-x1), h(y2-y1);
+
+ Surface::alpha_pen surface_pen(dest_surface.get_pen(x1,y1),1.0f);
+ if(w>0 && h>0)
+ dest_surface.fill(color,surface_pen,w,h);
+
+ /* the rectangle doesn't cross any vertical pixel boundaries so we don't
+ * need to draw any top or bottom edges
+ */
+ if(x2<x1)
+ {
+ // case 1 - a single pixel
+ if(y2<y1)
+ {
+ surface_pen.move_to(x2,y2);
+ surface_pen.set_alpha((x2f-x1f)*(y2f-y1f));
+ surface_pen.put_value(color);
+ }
+ // case 2 - a single vertical column of pixels
+ else
+ {
+ surface_pen.move_to(x2,y1-1);
+ if (y1e!=0) // maybe draw top pixel
+ {
+ surface_pen.set_alpha(y1e*(x2f-x1f));
+ surface_pen.put_value(color);
+ }
+ surface_pen.inc_y();
+ surface_pen.set_alpha(x2f-x1f);
+ for(int i=y1; i<y2; i++) // maybe draw pixels between
+ {
+ surface_pen.put_value(color);
+ surface_pen.inc_y();
+ }
+ if (y2e!=0) // maybe draw bottom pixel
+ {
+ surface_pen.set_alpha(y2e*(x2f-x1f));
+ surface_pen.put_value(color);
+ }
+ }
+ }
+ else
+ {
+ // case 3 - a single horizontal row of pixels
+ if(y2<y1)
+ {
+ surface_pen.move_to(x1-1,y2);
+ if (x1e!=0) // maybe draw left pixel
+ {
+ surface_pen.set_alpha(x1e*(y2f-y1f));
+ surface_pen.put_value(color);
+ }
+ surface_pen.inc_x();
+ surface_pen.set_alpha(y2f-y1f);
+ for(int i=x1; i<x2; i++) // maybe draw pixels between
+ {
+ surface_pen.put_value(color);
+ surface_pen.inc_x();
+ }
+ if (x2e!=0) // maybe draw right pixel
+ {
+ surface_pen.set_alpha(x2e*(y2f-y1f));
+ surface_pen.put_value(color);
+ }
+ }
+ // case 4 - a proper block of pixels
+ else
+ {
+ if (x1e!=0) // maybe draw left edge
+ {
+ surface_pen.move_to(x1-1,y1-1);
+ if (y1e!=0) // maybe draw top left pixel
+ {
+ surface_pen.set_alpha(x1e*y1e);
+ surface_pen.put_value(color);
+ }
+ surface_pen.inc_y();
+ surface_pen.set_alpha(x1e);
+ for(int i=y1; i<y2; i++) // maybe draw pixels along the left edge
+ {
+ surface_pen.put_value(color);
+ surface_pen.inc_y();
+ }
+ if (y2e!=0) // maybe draw bottom left pixel
+ {
+ surface_pen.set_alpha(x1e*y2e);
+ surface_pen.put_value(color);
+ }
+ surface_pen.inc_x();
+ }
+ else
+ surface_pen.move_to(x1,y2);
+
+ if (y2e!=0) // maybe draw bottom edge
+ {
+ surface_pen.set_alpha(y2e);
+ for(int i=x1; i<x2; i++) // maybe draw pixels along the bottom edge
+ {
+ surface_pen.put_value(color);
+ surface_pen.inc_x();
+ }
+ if (x2e!=0) // maybe draw bottom right pixel
+ {
+ surface_pen.set_alpha(x2e*y2e);
+ surface_pen.put_value(color);
+ }
+ surface_pen.dec_y();
+ }
+ else
+ surface_pen.move_to(x2,y2-1);
+
+ if (x2e!=0) // maybe draw right edge
+ {
+ surface_pen.set_alpha(x2e);
+ for(int i=y1; i<y2; i++) // maybe draw pixels along the right edge
+ {
+ surface_pen.put_value(color);
+ surface_pen.dec_y();
+ }
+ if (y1e!=0) // maybe draw top right pixel
+ {
+ surface_pen.set_alpha(x2e*y1e);
+ surface_pen.put_value(color);
+ }
+ surface_pen.dec_x();
+ }
+ else
+ surface_pen.move_to(x2-1,y1-1);
+
+ if (y1e!=0) // maybe draw top edge
+ {
+ surface_pen.set_alpha(y1e);
+ for(int i=x1; i<x2; i++) // maybe draw pixels along the top edge
+ {
+ surface_pen.put_value(color);
+ surface_pen.dec_x();
+ }
+ }
+ }
+ }
+ }
+
+ Surface::alpha_pen pen(surface->get_pen(0,0),get_amount(),get_blend_method());
+ dest_surface.blit_to(pen);
+
+ return true;
+}
+
+Rect
+Plant::get_bounding_rect(Context context)const
+{
+ if(needs_sync_==true)
+ sync();
+
+ if(is_disabled())
+ return Rect::zero();
+
+ if(Color::is_onto(get_blend_method()))
+ return context.get_full_bounding_rect() & bounding_rect;
+
+ //if(get_blend_method()==Color::BLEND_BEHIND)
+ // return context.get_full_bounding_rect() | bounding_rect;
+ return bounding_rect;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file plant.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_PLANT_H
+#define __SYNFIG_PLANT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <list>
+#include <vector>
+#include <synfig/layer_composite.h>
+#include <synfig/segment.h>
+#include <synfig/blinepoint.h>
+#include <synfig/value.h>
+#include <synfig/gradient.h>
+#include <synfig/angle.h>
+#include "random.h"
+#include <synfig/rect.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class Plant : public synfig::Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+private:
+
+ std::vector<synfig::BLinePoint> bline;
+ bool bline_loop;
+
+ synfig::Gradient gradient;
+
+ struct Particle
+ {
+ synfig::Point point;
+ synfig::Color color;
+
+ Particle(const synfig::Point &point,const synfig::Color& color):
+ point(point),color(color) { }
+ };
+
+ mutable std::vector<Particle> particle_list;
+ mutable synfig::Rect bounding_rect;
+ synfig::Angle split_angle;
+ synfig::Vector gravity;
+ synfig::Real velocity;
+ synfig::Real perp_velocity;
+ synfig::Real step;
+ synfig::Real mass;
+ synfig::Real drag;
+ synfig::Real size;
+ int splits;
+ int sprouts;
+ synfig::Real random_factor;
+ Random random;
+
+ bool size_as_alpha;
+ mutable bool needs_sync_;
+ mutable synfig::Mutex mutex;
+
+ void branch(int n, int depth,float t, float stunt_growth, synfig::Point position,synfig::Vector velocity)const;
+ void sync()const;
+
+public:
+
+ Plant();
+
+ void calc_bounding_rect()const;
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Vocab get_param_vocab()const;
+
+ virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const;\
+
+ virtual synfig::Rect get_bounding_rect(synfig::Context context)const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_particle/random.cpp
+** \brief blehh
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "random.h"
+#include <cmath>
+#include <cstdlib>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+void
+Random::set_seed(int x)
+{
+ seed_=x;
+ srand(x);
+ int i;
+ for(i=0;i<POOL_SIZE;i++)
+ pool_[i]=rand();
+
+ x_mask=rand()+rand()*RAND_MAX;
+ y_mask=rand()+rand()*RAND_MAX;
+ t_mask=rand()+rand()*RAND_MAX;
+}
+
+// this picks one of the POOL_SIZE (256) preset values out of the pool
+// and scales it to be in the range (-1, 1). is that what it was
+// intended to do? the distribution is pretty terrible, too, with
+// some elements being picked a hundred times more often than others
+float
+Random::operator()(const int salt,const int x,const int y,const int t)const
+{
+ const int salt_hash(pool_[salt&(POOL_SIZE-1)]);
+
+ int index(((x^x_mask)+(y^y_mask)*234672+(t^t_mask)*8439573)^salt_hash);
+
+ index+=index*(index/POOL_SIZE);
+
+ return (float(pool_[index&(POOL_SIZE-1)])/float(RAND_MAX))*2.0f-1.0f;
+}
+
+float
+Random::operator()(SmoothType smooth,int subseed,float xf,float yf,float tf)const
+{
+ int x((int)floor(xf));
+ int y((int)floor(yf));
+ int t((int)floor(tf));
+
+ switch(smooth)
+ {
+ case SMOOTH_CUBIC: // cubic
+ {
+ #define f(j,i,k) ((*this)(subseed,i,j,k))
+ //Using catmull rom interpolation because it doesn't blur at all
+ // ( http://www.gamedev.net/reference/articles/article1497.asp )
+ //bezier curve with intermediate ctrl pts: 0.5/3(p(i+1) - p(i-1)) and similar
+ float xfa [4], tfa[4];
+
+ //precalculate indices (all clamped) and offset
+ const int xa[] = {x-1,x,x+1,x+2};
+
+ const int ya[] = {y-1,y,y+1,y+2};
+
+ const int ta[] = {t-1,t,t+1,t+2};
+
+ const float dx(xf-x);
+ const float dy(yf-y);
+ const float dt(tf-t);
+
+ //figure polynomials for each point
+ const float txf[] =
+ {
+ 0.5*dx*(dx*(dx*(-1) + 2) - 1), //-t + 2t^2 -t^3
+ 0.5*(dx*(dx*(3*dx - 5)) + 2), //2 - 5t^2 + 3t^3
+ 0.5*dx*(dx*(-3*dx + 4) + 1), //t + 4t^2 - 3t^3
+ 0.5*dx*dx*(dx-1) //-t^2 + t^3
+ };
+
+ const float tyf[] =
+ {
+ 0.5*dy*(dy*(dy*(-1) + 2) - 1), //-t + 2t^2 -t^3
+ 0.5*(dy*(dy*(3*dy - 5)) + 2), //2 - 5t^2 + 3t^3
+ 0.5*dy*(dy*(-3*dy + 4) + 1), //t + 4t^2 - 3t^3
+ 0.5*dy*dy*(dy-1) //-t^2 + t^3
+ };
+
+ const float ttf[] =
+ {
+ 0.5*dt*(dt*(dt*(-1) + 2) - 1), //-t + 2t^2 -t^3
+ 0.5*(dt*(dt*(3*dt - 5)) + 2), //2 - 5t^2 + 3t^3
+ 0.5*dt*(dt*(-3*dt + 4) + 1), //t + 4t^2 - 3t^3
+ 0.5*dt*dt*(dt-1) //-t^2 + t^3
+ };
+
+ //evaluate polynomial for each row
+ for(int i = 0; i < 4; ++i)
+ {
+ for(int j = 0; j < 4; ++j)
+ {
+ tfa[j] = f(ya[i],xa[j],ta[0])*ttf[0] + f(ya[i],xa[j],ta[1])*ttf[1] + f(ya[i],xa[j],ta[2])*ttf[2] + f(ya[i],xa[j],ta[3])*ttf[3];
+ }
+ xfa[i] = tfa[0]*txf[0] + tfa[1]*txf[1] + tfa[2]*txf[2] + tfa[3]*txf[3];
+ }
+
+ //return the cumulative column evaluation
+ return xfa[0]*tyf[0] + xfa[1]*tyf[1] + xfa[2]*tyf[2] + xfa[3]*tyf[3];
+#undef f
+ }
+ break;
+
+
+ case SMOOTH_FAST_SPLINE: // Fast Spline (non-animated)
+ {
+#define P(x) (((x)>0)?((x)*(x)*(x)):0.0f)
+#define R(x) ( P(x+2) - 4.0f*P(x+1) + 6.0f*P(x) - 4.0f*P(x-1) )*(1.0f/6.0f)
+#define F(i,j) ((*this)(subseed,i+x,j+y)*(R((i)-a)*R(b-(j))))
+#define FT(i,j,k) ((*this)(subseed,i+x,j+y,k+t)*(R((i)-a)*R(b-(j))*R((k)-c)))
+#define Z(i,j) ret+=F(i,j)
+#define ZT(i,j,k) ret+=FT(i,j,k)
+#define X(i,j) // placeholder... To make box more symmetric
+#define XT(i,j,k) // placeholder... To make box more symmetric
+
+ float a(xf-x), b(yf-y);
+
+ // Interpolate
+ float ret(F(0,0));
+ Z(-1,-1); Z(-1, 0); Z(-1, 1); Z(-1, 2);
+ Z( 0,-1); X( 0, 0); Z( 0, 1); Z( 0, 2);
+ Z( 1,-1); Z( 1, 0); Z( 1, 1); Z( 1, 2);
+ Z( 2,-1); Z( 2, 0); Z( 2, 1); Z( 2, 2);
+
+ return ret;
+ }
+
+ case SMOOTH_SPLINE: // Spline (animated)
+ {
+ float a(xf-x), b(yf-y), c(tf-t);
+
+ // Interpolate
+ float ret(FT(0,0,0));
+ ZT(-1,-1,-1); ZT(-1, 0,-1); ZT(-1, 1,-1); ZT(-1, 2,-1);
+ ZT( 0,-1,-1); ZT( 0, 0,-1); ZT( 0, 1,-1); ZT( 0, 2,-1);
+ ZT( 1,-1,-1); ZT( 1, 0,-1); ZT( 1, 1,-1); ZT( 1, 2,-1);
+ ZT( 2,-1,-1); ZT( 2, 0,-1); ZT( 2, 1,-1); ZT( 2, 2,-1);
+
+ ZT(-1,-1, 0); ZT(-1, 0, 0); ZT(-1, 1, 0); ZT(-1, 2, 0);
+ ZT( 0,-1, 0); XT( 0, 0, 0); ZT( 0, 1, 0); ZT( 0, 2, 0);
+ ZT( 1,-1, 0); ZT( 1, 0, 0); ZT( 1, 1, 0); ZT( 1, 2, 0);
+ ZT( 2,-1, 0); ZT( 2, 0, 0); ZT( 2, 1, 0); ZT( 2, 2, 0);
+
+ ZT(-1,-1, 1); ZT(-1, 0, 1); ZT(-1, 1, 1); ZT(-1, 2, 1);
+ ZT( 0,-1, 1); ZT( 0, 0, 1); ZT( 0, 1, 1); ZT( 0, 2, 1);
+ ZT( 1,-1, 1); ZT( 1, 0, 1); ZT( 1, 1, 1); ZT( 1, 2, 1);
+ ZT( 2,-1, 1); ZT( 2, 0, 1); ZT( 2, 1, 1); ZT( 2, 2, 1);
+
+ ZT(-1,-1, 2); ZT(-1, 0, 2); ZT(-1, 1, 2); ZT(-1, 2, 2);
+ ZT( 0,-1, 2); ZT( 0, 0, 2); ZT( 0, 1, 2); ZT( 0, 2, 2);
+ ZT( 1,-1, 2); ZT( 1, 0, 2); ZT( 1, 1, 2); ZT( 1, 2, 2);
+ ZT( 2,-1, 2); ZT( 2, 0, 2); ZT( 2, 1, 2); ZT( 2, 2, 2);
+
+ return ret;
+
+/*
+
+ float dx=xf-x;
+ float dy=yf-y;
+ float dt=tf-t;
+
+ float ret=0;
+ int i,j,h;
+ for(h=-1;h<=2;h++)
+ for(i=-1;i<=2;i++)
+ for(j=-1;j<=2;j++)
+ ret+=(*this)(subseed,i+x,j+y,h+t)*(R(i-dx)*R(j-dy)*R(h-dt));
+ return ret;
+*/
+ }
+ break;
+#undef X
+#undef Z
+#undef F
+#undef P
+#undef R
+
+ case SMOOTH_COSINE:
+ if((float)t==tf)
+ {
+ int x((int)floor(xf));
+ int y((int)floor(yf));
+ float a=xf-x;
+ float b=yf-y;
+ a=(1.0f-cos(a*3.1415927))*0.5f;
+ b=(1.0f-cos(b*3.1415927))*0.5f;
+ float c=1.0-a;
+ float d=1.0-b;
+ int x2=x+1,y2=y+1;
+ return
+ (*this)(subseed,x,y,t)*(c*d)+
+ (*this)(subseed,x2,y,t)*(a*d)+
+ (*this)(subseed,x,y2,t)*(c*b)+
+ (*this)(subseed,x2,y2,t)*(a*b);
+ }
+ else
+ {
+ float a=xf-x;
+ float b=yf-y;
+ float c=tf-t;
+
+ a=(1.0f-cos(a*3.1415927))*0.5f;
+ b=(1.0f-cos(b*3.1415927))*0.5f;
+
+ // We don't perform this on the time axis, otherwise we won't
+ // get smooth motion
+ //c=(1.0f-cos(c*3.1415927))*0.5f;
+
+ float d=1.0-a;
+ float e=1.0-b;
+ float f=1.0-c;
+
+ int x2=x+1,y2=y+1,t2=t+1;
+
+ return
+ (*this)(subseed,x,y,t)*(d*e*f)+
+ (*this)(subseed,x2,y,t)*(a*e*f)+
+ (*this)(subseed,x,y2,t)*(d*b*f)+
+ (*this)(subseed,x2,y2,t)*(a*b*f)+
+ (*this)(subseed,x,y,t2)*(d*e*c)+
+ (*this)(subseed,x2,y,t2)*(a*e*c)+
+ (*this)(subseed,x,y2,t2)*(d*b*c)+
+ (*this)(subseed,x2,y2,t2)*(a*b*c);
+ }
+ case SMOOTH_LINEAR:
+ if((float)t==tf)
+ {
+ int x((int)floor(xf));
+ int y((int)floor(yf));
+ float a=xf-x;
+ float b=yf-y;
+ float c=1.0-a;
+ float d=1.0-b;
+ int x2=x+1,y2=y+1;
+ return
+ (*this)(subseed,x,y,t)*(c*d)+
+ (*this)(subseed,x2,y,t)*(a*d)+
+ (*this)(subseed,x,y2,t)*(c*b)+
+ (*this)(subseed,x2,y2,t)*(a*b);
+ }
+ else
+ {
+
+ float a=xf-x;
+ float b=yf-y;
+ float c=tf-t;
+
+ float d=1.0-a;
+ float e=1.0-b;
+ float f=1.0-c;
+
+ int x2=x+1,y2=y+1,t2=t+1;
+
+ return
+ (*this)(subseed,x,y,t)*(d*e*f)+
+ (*this)(subseed,x2,y,t)*(a*e*f)+
+ (*this)(subseed,x,y2,t)*(d*b*f)+
+ (*this)(subseed,x2,y2,t)*(a*b*f)+
+ (*this)(subseed,x,y,t2)*(d*e*c)+
+ (*this)(subseed,x2,y,t2)*(a*e*c)+
+ (*this)(subseed,x,y2,t2)*(d*b*c)+
+ (*this)(subseed,x2,y2,t2)*(a*b*c);
+ }
+ default:
+ case SMOOTH_DEFAULT:
+ return (*this)(subseed,x,y,t);
+ }
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_particle/random.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_RANDOM_H
+#define __SYNFIG_RANDOM_H
+
+/* === H E A D E R S ======================================================= */
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+
+#define POOL_SIZE (256)
+class Random
+{
+ int pool_[POOL_SIZE];
+ int seed_;
+
+ int x_mask, y_mask, t_mask;
+
+public:
+
+ void set_seed(int x);
+ int get_seed()const { return seed_; }
+
+ enum SmoothType
+ {
+ SMOOTH_DEFAULT = 0,
+ SMOOTH_LINEAR = 1,
+ SMOOTH_COSINE = 2,
+ SMOOTH_SPLINE = 3,
+ SMOOTH_CUBIC = 4,
+ SMOOTH_FAST_SPLINE = 5,
+ };
+
+ float operator()(int salt,int x,int y=0, int t=0)const;
+ float operator()(SmoothType smooth,int subseed,float x,float y=0, float t=0)const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_particle"
+ Delete "$INSTDIR\lib\synfig\modules\mod_particle.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+if HAVE_LIBPNG
+module_LTLIBRARIES = libmod_png.la
+libmod_png_la_SOURCES = main.cpp trgt_png.cpp trgt_png.h mptr_png.cpp mptr_png.h
+libmod_png_la_LDFLAGS = -module @PNG_LIBS@ -no-undefined
+libmod_png_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_png_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+else
+endif
+EXTRA_DIST= mod_png.nsh unmod_png.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_png/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include "trgt_png.h"
+#include "mptr_png.h"
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(mod_png)
+ MODULE_NAME("PNG Module (libpng)")
+ MODULE_DESCRIPTION("Provides a PNG target and importer")
+ MODULE_AUTHOR("Robert B. Quattlebaum Jr")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(mod_png)
+ BEGIN_TARGETS
+ TARGET(png_trgt)
+ END_TARGETS
+ BEGIN_IMPORTERS
+ IMPORTER(png_mptr)
+ END_IMPORTERS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_png" Sec_mod_png
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_png.dll "src\modules\mod_png\.libs\libmod_png-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_png"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_png.cpp
+** \brief ppm Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/*!
+** \todo Support 16 bit PNG files
+** \todo Support GAMMA correction
+** \todo Fix memory leaks
+*/
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "mptr_png.h"
+#include <synfig/importer.h>
+#include <synfig/time.h>
+#include <synfig/general.h>
+
+
+#include <cstdio>
+#include <algorithm>
+#include <functional>
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+#define PNG_CHECK_BYTES 8
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_IMPORTER_INIT(png_mptr);
+SYNFIG_IMPORTER_SET_NAME(png_mptr,"png");
+SYNFIG_IMPORTER_SET_EXT(png_mptr,"png");
+SYNFIG_IMPORTER_SET_VERSION(png_mptr,"0.1");
+SYNFIG_IMPORTER_SET_CVS_ID(png_mptr,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+void
+png_mptr::png_out_error(png_struct */*png_data*/,const char *msg)
+{
+ //png_mptr *me=(png_mptr*)png_data->error_ptr;
+ synfig::error(strprintf("png_mptr: error: %s",msg));
+ //me->ready=false;
+}
+
+void
+png_mptr::png_out_warning(png_struct */*png_data*/,const char *msg)
+{
+ //png_mptr *me=(png_mptr*)png_data->error_ptr;
+ synfig::warning(strprintf("png_mptr: warning: %s",msg));
+ //me->ready=false;
+}
+
+int
+png_mptr::read_chunk_callback(png_struct */*png_data*/, png_unknown_chunkp /*chunk*/)
+{
+ /* The unknown chunk structure contains your
+ chunk data: */
+ //png_byte name[5];
+ //png_byte *data;
+ //png_size_t size;
+ /* Note that libpng has already taken care of
+ the CRC handling */
+
+ /* put your code here. Return one of the
+ following: */
+
+ //return (-n); /* chunk had an error */
+ return (0); /* did not recognize */
+ //return (n); /* success */
+}
+
+png_mptr::png_mptr(const char *file_name)
+{
+ filename=file_name;
+
+ /* Open the file pointer */
+ FILE *file = fopen(file_name, "rb");
+ if (!file)
+ {
+ //! \todo THROW SOMETHING
+ throw strprintf("Unable to physically open %s",file_name);
+ return;
+ }
+
+
+ /* Make sure we are dealing with a PNG format file */
+ png_byte header[PNG_CHECK_BYTES];
+ fread(header, 1, PNG_CHECK_BYTES, file);
+ bool is_png = !png_sig_cmp(header, 0, PNG_CHECK_BYTES);
+ if (!is_png)
+ {
+ //! \todo THROW SOMETHING
+ throw strprintf("This (\"%s\") doesn't appear to be a PNG file",file_name);
+ return;
+ }
+
+
+ png_structp png_ptr = png_create_read_struct
+ (PNG_LIBPNG_VER_STRING, (png_voidp)this,
+ &png_mptr::png_out_error, &png_mptr::png_out_warning);
+ if (!png_ptr)
+ {
+ //! \todo THROW SOMETHING
+ throw String("error on importer construction, *WRITEME*3");
+ return;
+ }
+
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ {
+ png_destroy_read_struct(&png_ptr,
+ (png_infopp)NULL, (png_infopp)NULL);
+ //! \todo THROW SOMETHING
+ throw String("error on importer construction, *WRITEME*4");
+ return;
+ }
+
+ png_infop end_info = png_create_info_struct(png_ptr);
+ if (!end_info)
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr,
+ (png_infopp)NULL);
+ //! \todo THROW SOMETHING
+ throw String("error on importer construction, *WRITEME*4");
+ return;
+ }
+
+
+
+ png_init_io(png_ptr, file);
+ png_set_sig_bytes(png_ptr,PNG_CHECK_BYTES);
+
+ double fgamma;
+ if (png_get_gAMA(png_ptr, info_ptr, &fgamma))
+ {
+ synfig::info("PNG: Image gamma is %f",fgamma);
+ png_set_gamma(png_ptr, gamma().get_gamma(), fgamma);
+ }
+
+
+ /*
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ synfig::error("Unable to setup longjump");
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+ fclose(file);
+ //! \todo THROW SOMETHING
+ throw String("error on importer construction, *WRITEME*5");
+ return;
+ }
+ */
+
+ png_set_read_user_chunk_fn(png_ptr, this, &png_mptr::read_chunk_callback);
+
+
+ png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_PACKING|PNG_TRANSFORM_STRIP_16, NULL);
+
+ int bit_depth,color_type,interlace_type, compression_type,filter_method;
+ png_uint_32 width,height;
+
+ png_get_IHDR(png_ptr, info_ptr, &width, &height,
+ &bit_depth, &color_type, &interlace_type,
+ &compression_type, &filter_method);
+
+ png_bytep *row_pointers=new png_bytep[height];
+ row_pointers = png_get_rows(png_ptr, info_ptr);
+ int x;
+ int y;
+ surface_buffer.set_wh(width,height);
+
+ switch(color_type)
+ {
+ case PNG_COLOR_TYPE_RGB:
+ DEBUGPOINT();
+ for(y=0;y<surface_buffer.get_h();y++)
+ for(x=0;x<surface_buffer.get_w();x++)
+ {
+ float r=gamma().r_U8_to_F32((unsigned char)row_pointers[y][x*3+0]);
+ float g=gamma().g_U8_to_F32((unsigned char)row_pointers[y][x*3+1]);
+ float b=gamma().b_U8_to_F32((unsigned char)row_pointers[y][x*3+2]);
+ surface_buffer[y][x]=Color(
+ r,
+ g,
+ b,
+ 1.0
+ );
+/*
+ surface_buffer[y][x]=Color(
+ (float)(unsigned char)row_pointers[y][x*3+0]*(1.0/255.0),
+ (float)(unsigned char)row_pointers[y][x*3+1]*(1.0/255.0),
+ (float)(unsigned char)row_pointers[y][x*3+2]*(1.0/255.0),
+ 1.0
+ );
+*/
+ }
+ break;
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ DEBUGPOINT();
+ for(y=0;y<surface_buffer.get_h();y++)
+ for(x=0;x<surface_buffer.get_w();x++)
+ {
+ float r=gamma().r_U8_to_F32((unsigned char)row_pointers[y][x*4+0]);
+ float g=gamma().g_U8_to_F32((unsigned char)row_pointers[y][x*4+1]);
+ float b=gamma().b_U8_to_F32((unsigned char)row_pointers[y][x*4+2]);
+ surface_buffer[y][x]=Color(
+ r,
+ g,
+ b,
+ (float)(unsigned char)row_pointers[y][x*4+3]*(1.0/255.0)
+ );
+ /*
+ surface_buffer[y][x]=Color(
+ (float)(unsigned char)row_pointers[y][x*4+0]*(1.0/255.0),
+ (float)(unsigned char)row_pointers[y][x*4+1]*(1.0/255.0),
+ (float)(unsigned char)row_pointers[y][x*4+2]*(1.0/255.0),
+ (float)(unsigned char)row_pointers[y][x*4+3]*(1.0/255.0)
+ );
+ */
+ }
+ break;
+
+ case PNG_COLOR_TYPE_GRAY:
+ for(y=0;y<surface_buffer.get_h();y++)
+ for(x=0;x<surface_buffer.get_w();x++)
+ {
+ float gray=gamma().g_U8_to_F32((unsigned char)row_pointers[y][x]);
+ //float gray=(float)(unsigned char)row_pointers[y][x]*(1.0/255.0);
+ surface_buffer[y][x]=Color(
+ gray,
+ gray,
+ gray,
+ 1.0
+ );
+ }
+ break;
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ for(y=0;y<surface_buffer.get_h();y++)
+ for(x=0;x<surface_buffer.get_w();x++)
+ {
+ float gray=gamma().g_U8_to_F32((unsigned char)row_pointers[y][x*2]);
+// float gray=(float)(unsigned char)row_pointers[y][x*2]*(1.0/255.0);
+ surface_buffer[y][x]=Color(
+ gray,
+ gray,
+ gray,
+ (float)(unsigned char)row_pointers[y][x*2+1]*(1.0/255.0)
+ );
+ }
+ break;
+
+ case PNG_COLOR_TYPE_PALETTE:
+ synfig::warning("png_mptr: Paletted PNGs aren't yet fully supported.");
+ for(y=0;y<surface_buffer.get_h();y++)
+ for(x=0;x<surface_buffer.get_w();x++)
+ {
+ float r=gamma().r_U8_to_F32((unsigned char)png_ptr->palette[row_pointers[y][x]].red);
+ float g=gamma().g_U8_to_F32((unsigned char)png_ptr->palette[row_pointers[y][x]].green);
+ float b=gamma().b_U8_to_F32((unsigned char)png_ptr->palette[row_pointers[y][x]].blue);
+ surface_buffer[y][x]=Color(
+ r,
+ g,
+ b,
+ 1.0
+ );
+ }
+ break;
+ default:
+ synfig::error("png_mptr: error: Unsupported color type");
+ //! \todo THROW SOMETHING
+ throw String("error on importer construction, *WRITEME*6");
+ return;
+ }
+
+ DEBUGPOINT();
+
+ // \fixme These shouldn't be uncommented, but for some
+ // reason, they crash the program. I will have to look into this
+ // later. This is a memory leak, but it shouldn't be too bad.
+
+ /*
+ png_read_end(png_ptr, end_info);
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+ fclose(file);
+ */
+
+ delete [] row_pointers;
+}
+
+png_mptr::~png_mptr()
+{
+ DEBUGPOINT();
+}
+
+bool
+png_mptr::get_frame(synfig::Surface &surface,Time, synfig::ProgressCallback */*cb*/)
+{
+ surface.mirror(surface_buffer);
+// surface=surface_buffer;
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_png.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_MPTR_PNG_H
+#define __SYNFIG_MPTR_PNG_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/importer.h>
+#include <synfig/string.h>
+#include <synfig/surface.h>
+#include <png.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class png_mptr : public synfig::Importer
+{
+ SYNFIG_IMPORTER_MODULE_EXT
+private:
+ synfig::String filename;
+ synfig::Surface surface_buffer;
+
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_infop end_info;
+
+ static void png_out_error(png_struct *png_data,const char *msg);
+ static void png_out_warning(png_struct *png_data,const char *msg);
+ static int read_chunk_callback(png_struct *png_data, png_unknown_chunkp chunk);
+
+public:
+ png_mptr(const char *filename);
+ ~png_mptr();
+
+ virtual bool get_frame(synfig::Surface &surface,synfig::Time time, synfig::ProgressCallback *callback);
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_png.cpp
+** \brief png_trgt Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_TARGET
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trgt_png.h"
+#include <png.h>
+#include <ETL/stringf>
+#include <cstdio>
+#include <algorithm>
+#include <functional>
+#include <ETL/misc>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_TARGET_INIT(png_trgt);
+SYNFIG_TARGET_SET_NAME(png_trgt,"png");
+SYNFIG_TARGET_SET_EXT(png_trgt,"png");
+SYNFIG_TARGET_SET_VERSION(png_trgt,"0.1");
+SYNFIG_TARGET_SET_CVS_ID(png_trgt,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+void
+png_trgt::png_out_error(png_struct *png_data,const char *msg)
+{
+ png_trgt *me=(png_trgt*)png_data->error_ptr;
+ synfig::error(strprintf("png_trgt: error: %s",msg));
+ me->ready=false;
+}
+
+void
+png_trgt::png_out_warning(png_struct *png_data,const char *msg)
+{
+ png_trgt *me=(png_trgt*)png_data->error_ptr;
+ synfig::warning(strprintf("png_trgt: warning: %s",msg));
+ me->ready=false;
+}
+
+
+//Target *png_trgt::New(const char *filename){ return new png_trgt(filename);}
+
+png_trgt::png_trgt(const char *Filename)
+{
+ file=NULL;
+ filename=Filename;
+ buffer=NULL;
+ ready=false;
+ color_buffer=0;
+}
+
+png_trgt::~png_trgt()
+{
+ if(file)
+ fclose(file);
+ file=NULL;
+ delete [] buffer;
+ delete [] color_buffer;
+}
+
+bool
+png_trgt::set_rend_desc(RendDesc *given_desc)
+{
+ //given_desc->set_pixel_format(PixelFormat((int)PF_RGB|(int)PF_A));
+ desc=*given_desc;
+ imagecount=desc.get_frame_start();
+ if(desc.get_frame_end()-desc.get_frame_start()>0)
+ multi_image=true;
+ else
+ multi_image=false;
+ return true;
+}
+
+void
+png_trgt::end_frame()
+{
+ if(ready && file)
+ {
+ png_write_end(png_ptr,info_ptr);
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ }
+
+ if(file && file!=stdout)
+ fclose(file);
+ file=NULL;
+ imagecount++;
+ ready=false;
+}
+
+bool
+png_trgt::start_frame(synfig::ProgressCallback *callback)
+{
+ int w=desc.get_w(),h=desc.get_h();
+
+ if(file && file!=stdout)
+ fclose(file);
+ if(filename=="-")
+ {
+ if(callback)callback->task(strprintf("(stdout) %d",imagecount).c_str());
+ file=stdout;
+ }
+ else if(multi_image)
+ {
+ String
+ newfilename(filename),
+ ext(find(filename.begin(),filename.end(),'.'),filename.end());
+ newfilename.erase(find(newfilename.begin(),newfilename.end(),'.'),newfilename.end());
+
+ newfilename+=etl::strprintf("%04d",imagecount)+ext;
+ file=fopen(newfilename.c_str(),"wb");
+ if(callback)callback->task(newfilename);
+ }
+ else
+ {
+ file=fopen(filename.c_str(),"wb");
+ if(callback)callback->task(filename);
+ }
+
+ if(!file)
+ return false;
+
+ delete [] buffer;
+ buffer=new unsigned char[4*w];
+
+ delete [] color_buffer;
+ color_buffer=new Color[w];
+
+ png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)this,png_out_error, png_out_warning);
+ if (!png_ptr)
+ {
+ synfig::error("Unable to setup PNG struct");
+ fclose(file);
+ return false;
+ }
+
+ info_ptr= png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ {
+ synfig::error("Unable to setup PNG info struct");
+ fclose(file);
+ png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
+ return false;
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ synfig::error("Unable to setup longjump");
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ fclose(file);
+ return false;
+ }
+ png_init_io(png_ptr,file);
+ png_set_filter(png_ptr,0,PNG_FILTER_NONE);
+
+ setjmp(png_jmpbuf(png_ptr));
+ png_set_IHDR(png_ptr,info_ptr,w,h,8,PNG_COLOR_TYPE_RGBA,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
+
+ // Write the gamma
+ //png_set_gAMA(png_ptr, info_ptr,1.0/gamma().get_gamma());
+ png_set_gAMA(png_ptr, info_ptr,gamma().get_gamma());
+
+ // Write the physical size
+ png_set_pHYs(png_ptr,info_ptr,round_to_int(desc.get_x_res()),round_to_int(desc.get_y_res()),PNG_RESOLUTION_METER);
+
+ // Output any text info along with the file
+ png_text comments[]=
+ {
+ { PNG_TEXT_COMPRESSION_NONE, "Title", const_cast<char *>(get_canvas()->get_name().c_str()),
+ strlen(get_canvas()->get_name().c_str()) },
+ { PNG_TEXT_COMPRESSION_NONE, "Description", const_cast<char *>(get_canvas()->get_description().c_str()),
+ strlen(get_canvas()->get_description().c_str()) },
+// { PNG_TEXT_COMPRESSION_NONE, "Copyright", "(c) 2004 Voria Studios, LLC",
+// strlen("(c) 2004 Voria Studios, LLC") },
+ { PNG_TEXT_COMPRESSION_NONE, "Software", "SYNFIG",
+ strlen("SYNFIG") },
+ };
+ png_set_text(png_ptr,info_ptr,comments,sizeof(comments)/sizeof(png_text));
+
+ png_write_info_before_PLTE(png_ptr, info_ptr);
+ png_write_info(png_ptr, info_ptr);
+ ready=true;
+ return true;
+}
+
+Color *
+png_trgt::start_scanline(int /*scanline*/)
+{
+ return color_buffer;
+}
+
+bool
+png_trgt::end_scanline()
+{
+ if(!file || !ready)
+ return false;
+
+ convert_color_format(buffer, color_buffer, desc.get_w(), PF_RGB|PF_A, gamma());
+
+ setjmp(png_jmpbuf(png_ptr));
+ png_write_row(png_ptr,buffer);
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_png.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRGT_PNG_H
+#define __SYNFIG_TRGT_PNG_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/target_scanline.h>
+#include <synfig/string.h>
+#include <cstdio>
+#include <png.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class png_trgt : public synfig::Target_Scanline
+{
+ SYNFIG_TARGET_MODULE_EXT
+private:
+ FILE *file;
+ int w,h;
+ png_structp png_ptr;
+ png_infop info_ptr;
+
+ static void png_out_error(png_struct *png,const char *msg);
+ static void png_out_warning(png_struct *png,const char *msg);
+ bool multi_image,ready;
+ int imagecount;
+ synfig::String filename;
+ unsigned char *buffer;
+ synfig::Color *color_buffer;
+public:
+ png_trgt(const char *filename);
+ virtual ~png_trgt();
+
+ virtual bool set_rend_desc(synfig::RendDesc *desc);
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+ virtual void end_frame();
+
+ virtual synfig::Color * start_scanline(int scanline);
+ virtual bool end_scanline();
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_png"
+ Delete "$INSTDIR\lib\synfig\modules\mod_png.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+EXTRADIST=trgt_mpg.cpp trgt_mpg.h
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+module_LTLIBRARIES = libmod_ppm.la
+libmod_ppm_la_SOURCES = main.cpp trgt_ppm.cpp trgt_ppm.h mptr_ppm.cpp mptr_ppm.h # trgt_mpg.cpp trgt_mpg.h
+libmod_ppm_la_LDFLAGS = -module -no-undefined
+libmod_ppm_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_ppm_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+EXTRA_DIST= mod_ppm.nsh unmod_ppm.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_ppm/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include "trgt_ppm.h"
+#include "mptr_ppm.h"
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(mod_ppm)
+ MODULE_NAME("PPM Target")
+ MODULE_DESCRIPTION("Provides a PPM target")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(mod_ppm)
+ BEGIN_TARGETS
+ TARGET(ppm)
+ END_TARGETS
+ BEGIN_IMPORTERS
+ IMPORTER(ppm_mptr)
+ END_IMPORTERS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_ppm" Sec_mod_ppm
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_ppm.dll "src\modules\mod_ppm\.libs\libmod_ppm-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_ppm"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_ppm.cpp
+** \brief ppm Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "mptr_ppm.h"
+#include <synfig/importer.h>
+#include <synfig/time.h>
+#include <synfig/surface.h>
+#include <synfig/general.h>
+#include <synfig/smartfile.h>
+
+#include <cstdio>
+#include <algorithm>
+#include <functional>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_IMPORTER_INIT(ppm_mptr);
+SYNFIG_IMPORTER_SET_NAME(ppm_mptr,"ppm");
+SYNFIG_IMPORTER_SET_EXT(ppm_mptr,"ppm");
+SYNFIG_IMPORTER_SET_VERSION(ppm_mptr,"0.1");
+SYNFIG_IMPORTER_SET_CVS_ID(ppm_mptr,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+ppm_mptr::ppm_mptr(const char *file)
+{
+ filename=file;
+}
+
+ppm_mptr::~ppm_mptr()
+{
+}
+
+bool
+ppm_mptr::get_frame(synfig::Surface &surface,Time, synfig::ProgressCallback *cb)
+{
+ SmartFILE file(fopen(filename.c_str(),"rb"));
+ if(!file)
+ {
+ if(cb)cb->error("pp_mptr::GetFrame(): "+strprintf(_("Unable to open %s"),filename.c_str()));
+ return false;
+ }
+ int w,h;
+ float divisor;
+
+ if(fgetc(file.get())!='P' || fgetc(file.get())!='6')
+ {
+ if(cb)cb->error("pp_mptr::GetFrame(): "+strprintf(_("%s was not in PPM format"),filename.c_str()));
+ return false;
+ }
+
+ fgetc(file.get());
+ fscanf(file.get(),"%d %d\n",&w,&h);
+ fscanf(file.get(),"%f",&divisor);
+ fgetc(file.get());
+
+ int x;
+ int y;
+ surface.set_wh(w,h);
+ for(y=0;y<surface.get_h();y++)
+ for(x=0;x<surface.get_w();x++)
+ {
+/*
+ surface[y][x]=Color(
+ (float)(unsigned char)fgetc(file)/divisor,
+ (float)(unsigned char)fgetc(file)/divisor,
+ (float)(unsigned char)fgetc(file)/divisor,
+ 1.0
+ );
+*/
+ float r=gamma().r_U8_to_F32((unsigned char)fgetc(file.get()));
+ float g=gamma().g_U8_to_F32((unsigned char)fgetc(file.get()));
+ float b=gamma().b_U8_to_F32((unsigned char)fgetc(file.get()));
+ surface[y][x]=Color(
+ r,
+ g,
+ b,
+ 1.0
+ );
+ }
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_ppm.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_MPTR_PPM_H
+#define __SYNFIG_MPTR_PPM_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/importer.h>
+#include <synfig/string.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class ppm_mptr : public synfig::Importer
+{
+ SYNFIG_IMPORTER_MODULE_EXT
+private:
+ synfig::String filename;
+public:
+ ppm_mptr(const char *filename);
+ ~ppm_mptr();
+
+ virtual bool get_frame(synfig::Surface &surface,synfig::Time time, synfig::ProgressCallback *callback);
+}; // END of class ppm_mptr
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_mpg.cpp
+** \brief bsd_mpeg1 Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_TARGET
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ETL/stringf>
+#include "trgt_mpg.h"
+#include <stdio.h>
+#include <iostream>
+#include <algorithm>
+#include <functional>
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+const char bsd_mpeg1::Name[]="mpeg1";
+const char bsd_mpeg1::Ext[]="mpg";
+
+#define tmp_dir string("/tmp/")
+
+/* === M E T H O D S ======================================================= */
+
+Target *
+bsd_mpeg1::New(const char *filename)
+{
+ return new bsd_mpeg1(filename);
+}
+
+bsd_mpeg1::bsd_mpeg1(const char *Filename)
+{
+ filename=Filename;
+ passthru=ppm::New((tmp_dir+"temp.ppm").c_str());
+ paramfile=NULL;
+
+}
+
+bsd_mpeg1::~bsd_mpeg1()
+{
+ if(paramfile)
+ fclose(paramfile);
+ delete passthru;
+ cerr<<"Encoding "<<filename<<"with \"mpeg_encode\" utility..."<<endl;
+ if(system("mpeg_encode -float-dct -realquiet /tmp/temp.param")!=0)
+ {
+ cerr<<"Failed to encode "<<filename<<"with \"mpeg_encode\" utility"<<endl;
+ cerr<<"Are you sure it is installed?"<<endl;
+ }
+}
+
+bool
+bsd_mpeg1::set_rend_desc(RendDesc *given_desc)
+{
+ if(paramfile)
+ fclose(paramfile);
+
+
+ paramfile=fopen((tmp_dir+"temp.param").c_str(),"wt");
+ int bitrate=150; // kbytes per second
+ int buffer_drift=50; // bitrate drift (in kbytes per second)
+
+ bitrate*=8*1024;
+ buffer_drift*=8*1024;
+
+ fprintf(paramfile,
+ "PATTERN IBBPBBPBBPBBPBBP\n"
+ "OUTPUT %s\n"
+ "BASE_FILE_FORMAT PPM\n"
+ "INPUT_CONVERT *\n"
+ "GOP_SIZE 16\n"
+ "SLICES_PER_FRAME 1\n"
+ "INPUT_DIR \n"
+ "PIXEL HALF\n"
+ "RANGE 10\n"
+ "PSEARCH_ALG LOGARITHMIC\n"
+ "BSEARCH_ALG CROSS2\n"
+// "IQSCALE 8\n"
+// "PQSCALE 10\n"
+// "BQSCALE 25\n"
+ "IQSCALE 3\n"
+ "PQSCALE 5\n"
+ "BQSCALE 10\n"
+ "REFERENCE_FRAME ORIGINAL\n"
+ "BIT_RATE %d\n"
+// "BIT_RATE 1000000\n"
+// "BUFFER_SIZE 327680\n"
+ "BUFFER_SIZE %d\n"
+ ,filename.c_str(),bitrate,buffer_drift);
+ float fps=given_desc->get_frame_rate();
+
+ // Valid framerates:
+ // 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60
+
+ if(fps <24.0)
+ {
+ fprintf(paramfile,"FRAME_RATE 23.976\n");
+ given_desc->set_frame_rate(23.976);
+ }
+ if(fps>=24.0 && fps <25.0)
+ {
+ fprintf(paramfile,"FRAME_RATE 24\n");
+ given_desc->set_frame_rate(24);
+ }
+ if(fps>=25.0 && fps <29.97)
+ {
+ fprintf(paramfile,"FRAME_RATE 25\n");
+ given_desc->set_frame_rate(25);
+ }
+ if(fps>=29.97 && fps <30.0)
+ {
+ fprintf(paramfile,"FRAME_RATE 29.97\n");
+ given_desc->set_frame_rate(29.97);
+ }
+ if(fps>=29.97 && fps <30.0)
+ {
+ fprintf(paramfile,"FRAME_RATE 29.97\n");
+ given_desc->set_frame_rate(29.97);
+ }
+ if(fps>=30.0 && fps <50.0)
+ {
+ fprintf(paramfile,"FRAME_RATE 30\n");
+ given_desc->set_frame_rate(30.0);
+ }
+ if(fps>=50.0 && fps <59.94)
+ {
+ fprintf(paramfile,"FRAME_RATE 50\n");
+ given_desc->set_frame_rate(50);
+ }
+ if(fps>=59.94)
+ {
+ fprintf(paramfile,"FRAME_RATE 59.94\n");
+ given_desc->set_frame_rate(59.94);
+ }
+
+ // Make sure that the width and height
+ // are multiples of 8
+ given_desc->set_w((given_desc->get_w()+4)/8*8);
+ given_desc->set_h((given_desc->get_h()+4)/8*8);
+
+ if(!passthru->set_rend_desc(given_desc))
+ return false;
+
+ desc=*given_desc;
+
+ fprintf(paramfile,
+ "INPUT\n"
+ "tmp/temp*.ppm [%04d-%04d]\n"
+ "END_INPUT\n",desc.get_frame_start(),desc.get_frame_end()-1);
+
+ fclose(paramfile);
+ paramfile=NULL;
+
+ return true;
+}
+
+void
+bsd_mpeg1::end_frame()
+{
+ passthru->end_frame();
+}
+
+bool
+bsd_mpeg1::start_frame(synfig::ProgressCallback *callback)
+{
+ return passthru->start_frame(callback);
+}
+
+unsigned char *
+bsd_mpeg1::start_scanline(int scanline)
+{
+ return passthru->start_scanline(scanline);
+}
+
+bool
+bsd_mpeg1::end_scanline(void)
+{
+ return passthru->end_scanline();
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_mpg.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRGT_MPG_H
+#define __SYNFIG_TRGT_MPG_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/synfig.h>
+#include <stdio.h>
+#include "trgt_ppm.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+
+class bsd_mpeg1 : public synfig::Target
+{
+public:
+private:
+// synfig::RendDesc desc;
+ synfig::Target *passthru;
+ String filename;
+ FILE *paramfile;
+public:
+ bsd_mpeg1(const char *filename);
+
+ virtual bool set_rend_desc(synfig::RendDesc *desc);
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+ virtual void end_frame();
+
+ virtual ~bsd_mpeg1();
+
+
+ virtual unsigned char * start_scanline(int scanline);
+ virtual bool end_scanline(void);
+
+ static synfig::Target *New(const char *filename);
+
+ static const char Name[];
+ static const char Ext[];
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_ppm.cpp
+** \brief ppm Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_TARGET
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trgt_ppm.h"
+#include <ETL/stringf>
+#include <cstdio>
+#include <algorithm>
+#include <functional>
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_TARGET_INIT(ppm);
+SYNFIG_TARGET_SET_NAME(ppm,"ppm");
+SYNFIG_TARGET_SET_EXT(ppm,"ppm");
+SYNFIG_TARGET_SET_VERSION(ppm,"0.1");
+SYNFIG_TARGET_SET_CVS_ID(ppm,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+ppm::ppm(const char *Filename)
+{
+ filename=Filename;
+ multi_image=false;
+ buffer=NULL;
+ color_buffer=0;
+ set_remove_alpha();
+}
+
+ppm::~ppm()
+{
+ delete [] buffer;
+ delete [] color_buffer;
+}
+
+bool
+ppm::set_rend_desc(RendDesc *given_desc)
+{
+ //given_desc->set_pixel_format(PF_RGB);
+ desc=*given_desc;
+ imagecount=desc.get_frame_start();
+ if(desc.get_frame_end()-desc.get_frame_start()>0)
+ multi_image=true;
+ else
+ multi_image=false;
+ return true;
+}
+
+void
+ppm::end_frame()
+{
+ imagecount++;
+}
+
+bool
+ppm::start_frame(synfig::ProgressCallback *callback)
+{
+ int w=desc.get_w(),h=desc.get_h();
+
+ if(filename=="-")
+ {
+ if(callback)callback->task(strprintf("(stdout) %d",imagecount).c_str());
+ file=SmartFILE(stdout);
+ }
+ else if(multi_image)
+ {
+ String
+ newfilename(filename),
+ ext(find(filename.begin(),filename.end(),'.'),filename.end());
+ newfilename.erase(find(newfilename.begin(),newfilename.end(),'.'),newfilename.end());
+
+ newfilename+=etl::strprintf("%04d",imagecount)+ext;
+ file=SmartFILE(fopen(newfilename.c_str(),"wb"));
+ if(callback)callback->task(newfilename);
+ }
+ else
+ {
+ file=SmartFILE(fopen(filename.c_str(),"wb"));
+ if(callback)callback->task(filename);
+ }
+
+ if(!file)
+ return false;
+
+ fprintf(file.get(), "P6\n");
+ fprintf(file.get(), "%d %d\n", w, h);
+ fprintf(file.get(), "%d\n", 255);
+
+ delete [] buffer;
+ buffer=new unsigned char[3*w];
+
+ delete [] color_buffer;
+ color_buffer=new Color[desc.get_w()];
+
+ return true;
+}
+
+Color *
+ppm::start_scanline(int /*scanline*/)
+{
+ return color_buffer;
+}
+
+bool
+ppm::end_scanline()
+{
+ if(!file)
+ return false;
+
+ convert_color_format(buffer, color_buffer, desc.get_w(), PF_RGB, gamma());
+
+ if(!fwrite(buffer,1,desc.get_w()*3,file.get()))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_ppm.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRGT_PPM_H
+#define __SYNFIG_TRGT_PPM_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/target_scanline.h>
+#include <synfig/string.h>
+#include <synfig/smartfile.h>
+#include <cstdio>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class ppm : public synfig::Target_Scanline
+{
+ SYNFIG_TARGET_MODULE_EXT
+
+private:
+ int imagecount;
+ bool multi_image;
+ synfig::SmartFILE file;
+ synfig::String filename;
+ synfig::Color *color_buffer;
+ unsigned char *buffer;
+public:
+ ppm(const char *filename);
+ virtual ~ppm();
+
+ virtual bool set_rend_desc(synfig::RendDesc *desc);
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+ virtual void end_frame();
+
+ virtual synfig::Color * start_scanline(int scanline);
+ virtual bool end_scanline();
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_ppm"
+ Delete "$INSTDIR\lib\synfig\modules\mod_ppm.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+module_LTLIBRARIES = libmod_yuv420p.la
+libmod_yuv420p_la_SOURCES = main.cpp trgt_yuv.cpp trgt_yuv.h
+libmod_yuv420p_la_LDFLAGS = -module -no-undefined
+libmod_yuv420p_la_CXXFLAGS = @SYNFIG_CFLAGS@
+libmod_yuv420p_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+EXTRA_DIST= mod_yuv420p.nsh unmod_yuv420p.nsh
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mod_yuv420p/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include "trgt_yuv.h"
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(mod_yuv420p)
+ MODULE_NAME("YUV420P Target")
+ MODULE_DESCRIPTION("writeme")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(mod_yuv420p)
+ BEGIN_TARGETS
+ TARGET(yuv)
+ END_TARGETS
+MODULE_INVENTORY_END
--- /dev/null
+; The stuff to install
+Section "mod_yuv420p" Sec_mod_yuv420p
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=mod_yuv420p.dll "src\modules\mod_yuv420p\.libs\libmod_yuv420p-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "mod_yuv420p"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_yuv.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_TARGET
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "trgt_yuv.h"
+#include <ETL/stringf>
+#include <cstdio>
+#include <algorithm>
+#include <functional>
+#endif
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === M A C R O S ========================================================= */
+
+#define Y_FLOOR (16)
+#define Y_CEIL (235)
+#define Y_RANGE (Y_CEIL-Y_FLOOR)
+
+#define UV_FLOOR (16)
+#define UV_CEIL (240)
+#define UV_RANGE (UV_CEIL-UV_FLOOR)
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_TARGET_INIT(yuv);
+SYNFIG_TARGET_SET_NAME(yuv,"yuv420p");
+SYNFIG_TARGET_SET_EXT(yuv,"yuv");
+SYNFIG_TARGET_SET_VERSION(yuv,"0.1");
+SYNFIG_TARGET_SET_CVS_ID(yuv,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+yuv::yuv(const char *FILENAME):
+ filename(FILENAME),
+ file( (filename=="-")?stdout:fopen(filename.c_str(),"wb") ),
+ dithering(true)
+{
+ // YUV420P doesn't have an alpha channel
+ set_remove_alpha();
+}
+
+yuv::~yuv()
+{
+}
+
+bool
+yuv::set_rend_desc(RendDesc *given_desc)
+{
+ given_desc->clear_flags();
+
+ // Make sure our width is divisible by two
+ given_desc->set_w(given_desc->get_w()*2/2);
+ given_desc->set_h(given_desc->get_h()*2/2);
+
+ desc=*given_desc;
+
+ // Set up our surface
+ surface.set_wh(desc.get_w(),desc.get_h());
+
+ return true;
+}
+
+bool
+yuv::start_frame(synfig::ProgressCallback */*callback*/)
+{
+ return static_cast<bool>(file);
+}
+
+Color *
+yuv::start_scanline(int x)
+{
+ return surface[x];
+}
+
+bool
+yuv::end_scanline()
+{
+ return static_cast<bool>(file);
+}
+
+void
+yuv::end_frame()
+{
+ const int w=desc.get_w(),h=desc.get_h();
+ int x,y;
+
+ assert(file);
+
+ // Output Y' channel, adjusting
+ // the gamma as we go
+ for(y=0;y<h;y++)
+ for(x=0;x<w;x++)
+ {
+ Color& c(surface[y][x]);
+ c=c.clamped();
+ c.set_r(gamma().r_F32_to_F32(c.get_r()));
+ c.set_g(gamma().g_F32_to_F32(c.get_g()));
+ c.set_b(gamma().b_F32_to_F32(c.get_b()));
+ float f(c.get_y());
+ int i(max(min(round_to_int(c.get_y()*Y_RANGE),Y_RANGE),0)+Y_FLOOR);
+
+ if(dithering)
+ {
+ const float er(f-((float)i-Y_FLOOR)/Y_RANGE);
+ const Color error(er,er,er);
+
+ if(surface.get_h()>y+1)
+ {
+ surface[y+1][x-1]+=error * ((float)3/(float)16);
+ surface[y+1][x]+=error * ((float)5/(float)16);
+ if(surface.get_w()>x+1)
+ surface[y+1][x+1]+=error * ((float)1/(float)16);
+ }
+ if(surface.get_w()>x+1)
+ surface[y][x+1]+=error * ((float)7/(float)16);
+ }
+
+ fputc(i,file.get());
+ }
+
+
+ // Create new super-sampled surface
+ Surface sm_surface(w/2,h/2);
+ for(y=0;y<h;y+=2)
+ for(x=0;x<w;x+=2)
+ {
+ Color c(Color::alpha());
+ c+=surface[y][x];
+ c+=surface[y+1][x];
+ c+=surface[y][x+1];
+ c+=surface[y+1][x+1];
+ c/=4;
+ sm_surface[y/2][x/2]=c;
+ }
+
+ // Output U channel
+ for(y=0;y<sm_surface.get_h();y++)
+ for(x=0;x<sm_surface.get_w();x++)
+ {
+ const Color& c(sm_surface[y][x]);
+ const float f(c.get_u());
+ const int i(max(min(round_to_int((f+0.5f)*UV_RANGE),UV_RANGE),0)+UV_FLOOR);
+
+ if(dithering)
+ {
+ const float er(f-((((float)i-UV_FLOOR)/UV_RANGE)-0.5f));
+ const Color error(Color::YUV(0,er,0));
+
+ if(sm_surface.get_h()>y+1)
+ {
+ sm_surface[y+1][x-1]+=error * ((float)3/(float)16);
+ sm_surface[y+1][x]+=error * ((float)5/(float)16);
+ if(sm_surface.get_w()>x+1)
+ sm_surface[y+1][x+1]+=error * ((float)1/(float)16);
+ }
+ if(sm_surface.get_w()>x+1)
+ sm_surface[y][x+1]+=error * ((float)7/(float)16);
+ }
+ fputc(i,file.get());
+ }
+
+ // Output V channel
+ for(y=0;y<sm_surface.get_h();y++)
+ for(x=0;x<sm_surface.get_w();x++)
+ {
+ const Color& c(sm_surface[y][x]);
+ const float f(c.get_v());
+ const int i(max(min(round_to_int((f+0.5f)*UV_RANGE),UV_RANGE),0)+UV_FLOOR);
+
+ if(dithering)
+ {
+ const float er(f-((((float)i-UV_FLOOR)/UV_RANGE)-0.5f));
+ const Color error(Color::YUV(0,0,er));
+
+ if(sm_surface.get_h()>y+1)
+ {
+ sm_surface[y+1][x-1]+=error * ((float)3/(float)16);
+ sm_surface[y+1][x]+=error * ((float)5/(float)16);
+ if(sm_surface.get_w()>x+1)
+ sm_surface[y+1][x+1]+=error * ((float)1/(float)16);
+ }
+ if(sm_surface.get_w()>x+1)
+ sm_surface[y][x+1]+=error * ((float)7/(float)16);
+ }
+ fputc(i,file.get());
+ }
+
+ // Flush out the frame
+ fflush(file.get());
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file trgt_yuv.h
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRGT_PPM_H
+#define __SYNFIG_TRGT_PPM_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/target_scanline.h>
+#include <synfig/string.h>
+#include <synfig/surface.h>
+#include <synfig/smartfile.h>
+#include <cstdio>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class yuv : public synfig::Target_Scanline
+{
+ SYNFIG_TARGET_MODULE_EXT
+
+private:
+
+ synfig::String filename;
+ synfig::SmartFILE file;
+ synfig::Surface surface;
+
+ bool dithering;
+
+public:
+
+ yuv(const char *filename);
+ virtual ~yuv();
+
+ virtual bool set_rend_desc(synfig::RendDesc *desc);
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+ virtual void end_frame();
+
+ virtual synfig::Color* start_scanline(int scanline);
+ virtual bool end_scanline();
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+Section "un.mod_yuv420p"
+ Delete "$INSTDIR\lib\synfig\modules\mod_yuv420p.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src
+
+moduledir=@MODULE_DIR@
+
+module_LTLIBRARIES = libmptr_mplayer.la
+libmptr_mplayer_la_SOURCES = main.cpp mptr_mplayer.cpp mptr_mplayer.h
+libmptr_mplayer_la_LDFLAGS = -module -no-undefined
+libmptr_mplayer_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@
+
+
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_mplayer/main.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_MODULE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/module.h>
+#include "mptr_mplayer.h"
+#endif
+
+/* === E N T R Y P O I N T ================================================= */
+
+MODULE_DESC_BEGIN(mptr_mplayer)
+ MODULE_NAME("MPlayer Movie Importer")
+ MODULE_DESCRIPTION("ARGH")
+ MODULE_AUTHOR("Robert B. Quattlebaum")
+ MODULE_VERSION("1.0")
+ MODULE_COPYRIGHT(SYNFIG_COPYRIGHT)
+MODULE_DESC_END
+
+MODULE_INVENTORY_BEGIN(mptr_mplayer)
+ BEGIN_IMPORTERS
+ IMPORTER_EXT(mplayer_mptr,"avi")
+ IMPORTER_EXT(mplayer_mptr,"mpg")
+ IMPORTER_EXT(mplayer_mptr,"mpeg")
+ IMPORTER_EXT(mplayer_mptr,"mov")
+ IMPORTER_EXT(mplayer_mptr,"rm")
+ END_IMPORTERS
+MODULE_INVENTORY_END
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_mplayer.cpp
+** \brief ppm Target Module
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/synfig.h>
+#include <ETL/stringf>
+#include "mptr_mplayer.h"
+#include <stdio.h>
+#include <iostream>
+#include <algorithm>
+#include <functional>
+#include <ETL/stringf>
+#endif
+
+/* === M A C R O S ========================================================= */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+const char mplayer_mptr::Name[]="avi";
+const char mplayer_mptr::Ext[]="avi";
+
+/* === M E T H O D S ======================================================= */
+
+Importer *
+mplayer_mptr::New(const char *file)
+{
+ return new mplayer_mptr(file);
+}
+
+mplayer_mptr::mplayer_mptr(const char *file)
+{
+ filename=file;
+}
+
+mplayer_mptr::~mplayer_mptr()
+{
+}
+
+bool
+mplayer_mptr::GetFrame(Time time, synfig::Surface &surface, synfig::ProgressCallback *)
+{
+ int ret;
+ ret=system(
+ strprintf("/usr/local/bin/mencoder \"%s\" -ovc rawrgb -ss %f -endpos 0 -nosound -o /tmp/tmp.synfig.rgbdata | grep \"VIDEO\" > /tmp/tmp.synfig.size",
+ filename.c_str(),
+ time
+ ).c_str()
+ );
+ /*
+ if(ret!=0)
+ {
+ cerr<<"mencoder execution failed."<<endl;
+ return false;
+ }
+*/
+ FILE *sizefile=fopen("/tmp/tmp.synfig.size","rt");
+ FILE *rgbfile=fopen("/tmp/tmp.synfig.rgbdata","rb");
+ if(!rgbfile)
+ {
+ cerr<<"unable to open /tmp/tmp.synfig.rgbdata"<<endl;
+ return false;
+ }
+ if(!sizefile)
+ {
+ cerr<<"unable to open /tmp/tmp.synfig.size"<<endl;
+ return false;
+ }
+
+ int w=4,h=4,x,y;
+ char bleh[500];
+
+ fscanf(sizefile,"%s %s %dx%d",bleh,bleh,&w,&h);
+
+ cerr<<strprintf("w:%d, h:%d, time:%f",w,h,time)<<endl;
+ fseek(rgbfile,2047+3*8,SEEK_CUR);
+ surface.set_wh(w,h);
+ for(y=0;y<h;y++)
+ for(x=0;x<w;x++)
+ {
+ unsigned char
+ b=(unsigned char)fgetc(rgbfile),
+ g=(unsigned char)fgetc(rgbfile),
+ r=(unsigned char)fgetc(rgbfile);
+
+ surface[h-y-1][x]=Color(
+ (float)r/255.0,
+ (float)g/255.0,
+ (float)b/255.0,
+ 1.0
+ );
+ }
+
+ fclose(rgbfile);
+ fclose(sizefile);
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mptr_mplayer.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_MPTR_MPLAYER_H
+#define __SYNFIG_MPTR_MPLAYER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <synfig/synfig.h>
+#include <stdio.h>
+#include "string.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class mplayer_mptr : public synfig::Importer
+{
+public:
+private:
+ String filename;
+
+public:
+ mplayer_mptr(const char *filename);
+ ~mplayer_mptr();
+
+
+ static const char Name[];
+ static const char Ext[];
+
+ virtual bool GetFrame(synfig::Time time, synfig::Surface &, synfig::ProgressCallback *);
+
+ static synfig::Importer *New(const char *filename);
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+lyr_std
+mod_gradient
+mod_geometry
+mod_noise
+mod_particle
+lyr_freetype
+mod_filter
+mod_ffmpeg
+mod_imagemagick
+mod_bmp
+mod_dv
+mod_png
+mod_ppm
+mod_gif
+mod_openexr
+mod_jpeg
+mod_libavcodec
+mod_yuv420p
--- /dev/null
+; The stuff to install
+Section "@MODNAME@" Sec_@MODNAME@
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\lib\synfig\modules"
+
+ ; Put file there
+ File /oname=@MODNAME@.dll "src\modules\@MODNAME@\.libs\lib@MODNAME@-0.dll"
+
+
+ FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a
+ FileSeek $0 0 END
+ FileWrite $0 "@MODNAME@"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+ FileClose $0
+
+SectionEnd
+
--- /dev/null
+Section "un.@MODNAME@"
+ Delete "$INSTDIR\lib\synfig\modules\@MODNAME@.dll"
+ RMDir "$INSTDIR\lib\synfig\modules"
+ RMDir "$INSTDIR\lib\synfig"
+ RMDir "$INSTDIR\lib"
+ RMDir "$INSTDIR"
+SectionEnd
+
--- /dev/null
+# $Id$
+
+# SUBDIRS=proto
+
+MAINTAINERCLEANFILES=Makefile.in proto/nodebase.h
+INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/libltdl
+
+EXTRA_DIST=surfacenew.cpp pch.h proto/Makefile proto/nodebase.h proto/nodebase.px proto/proto.m4 synfig.nsh
+
+LAYERHEADERS=layer_motionblur.h layer_pastecanvas.h layer_solidcolor.h layer_polygon.h layer_composite.h layer_bitmap.h layer_mime.h layer_shape.h
+LAYERSOURCES=layer_motionblur.cpp layer_pastecanvas.cpp layer_solidcolor.cpp layer_polygon.cpp layer_composite.cpp layer_bitmap.cpp layer_mime.cpp layer_shape.cpp
+
+TARGETHEADERS=target_scanline.h target_tile.h target_multi.h target_null.h target_null_tile.h
+TARGETSOURCES=target_scanline.cpp target_tile.cpp target_multi.cpp target_null.cpp target_null_tile.cpp
+
+IMPORTERHEADERS=listimporter.h
+IMPORTERSOURCES=listimporter.cpp
+
+VALUENODEHEADERS=valuenode_exp.h valuenode_sine.h valuenode_radialcomposite.h valuenode_bline.h valuenode_blinecalcvertex.h valuenode_blinecalctangent.h valuenode_segcalcvertex.h valuenode_segcalctangent.h valuenode_twotone.h valuenode_repeat_gradient.h valuenode_stripes.h valuenode_add.h valuenode_subtract.h valuenode_const.h valuenode_range.h valuenode_reference.h valuenode_linear.h valuenode_composite.h valuenode_dynamiclist.h valuenode_animated.h valuenode_scale.h valuenode_timedswap.h valuenode_gradientrotate.h
+VALUENODESOURCES=valuenode_exp.cpp valuenode_sine.cpp valuenode_radialcomposite.cpp valuenode_bline.cpp valuenode_blinecalcvertex.cpp valuenode_blinecalctangent.cpp valuenode_segcalcvertex.cpp valuenode_segcalctangent.cpp valuenode_twotone.cpp valuenode_repeat_gradient.cpp valuenode_stripes.cpp valuenode_add.cpp valuenode_subtract.cpp valuenode_const.cpp valuenode_range.cpp valuenode_reference.cpp valuenode_linear.cpp valuenode_composite.cpp valuenode_dynamiclist.cpp valuenode_animated.cpp valuenode_scale.cpp valuenode_timedswap.cpp valuenode_gradientrotate.cpp
+
+VALUEHEADERS=blinepoint.h gradient.h value.h
+VALUESOURCES=blinepoint.cpp gradient.cpp value.cpp
+
+SYNFIGHEADERS=protocol.h surfacenew.h mutex.h timepointcollect.h interpolation.h guidset.h guid.h quick_rng.h rect.h node.h smartfile.h distance.h palette.h main.h waypoint.h activepoint.h gamma.h uniqueid.h canvasbase.h context.h real.h paramdesc.h string_decl.h angle.h keyframe.h synfig.h renddesc.h general.h importer.h surface.h module.h layer.h vector.h color.h canvas.h render.h target.h loadcanvas.h savecanvas.h valuenode.h version.h segment.h types.h exception.h string.h time.h blur.h transform.h curve_helper.h polynomial_root.h curveset.h
+SYNFIGSOURCES=mutex.cpp timepointcollect.cpp rect.cpp node.cpp guid.cpp loadcanvas.cpp distance.cpp palette.cpp paramdesc.cpp waypoint.cpp activepoint.cpp gamma.cpp uniqueid.cpp context.cpp renddesc.cpp time.cpp exception.cpp keyframe.cpp main.cpp surface.cpp module.cpp importer.cpp layer.cpp color.cpp canvas.cpp render.cpp target.cpp savecanvas.cpp valuenode.cpp blur.cpp curve_helper.cpp polynomial_root.cpp transform.cpp curveset.cpp
+
+lib_LTLIBRARIES = libsynfig.la
+libsynfig_la_SOURCES = $(VALUEHEADERS) $(VALUESOURCES) $(LAYERSOURCES) $(LAYERHEADERS) $(TARGETHEADERS) $(TARGETSOURCES) $(VALUENODEHEADERS) $(VALUENODESOURCES) $(SYNFIGHEADERS) $(SYNFIGSOURCES) $(IMPORTERHEADERS) $(IMPORTERSOURCES)
+libsynfig_la_LIBADD = @LIBLTDL@ @SYNFIG_LIBS@ @LIBADD_DL@
+libsynfig_la_CXXFLAGS = @SYNFIG_CFLAGS@ -DLIBDIR="\"@libdir@\"" -DSYSCONFDIR="\"@sysconfdir@\""
+libsynfig_la_LDFLAGS = -export-dynamic -no-undefined -version-info 0:0:0
+
+include_synfigdir=@synfigincludedir@/synfig
+include_synfig_HEADERS = $(SYNFIGHEADERS) $(LAYERHEADERS) $(TARGETHEADERS) $(VALUENODEHEADERS) $(IMPORTERHEADERS) $(VALUEHEADERS)
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file activepoint.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "activepoint.h"
+#include "guid.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+synfig::GUID
+Activepoint::get_guid()const
+{
+ return GUID::hasher(get_uid());
+}
--- /dev/null
+#include <stdio.h>
+/* === S Y N F I G ========================================================= */
+/*! \file activepoint.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_ACTIVEPOINT_H
+#define __SYNFIG_ACTIVEPOINT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "time.h"
+#include "uniqueid.h"
+#include <ETL/handle>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+class GUID;
+class ValueNode;
+
+struct Activepoint : public UniqueID
+{
+private:
+ etl::loose_handle<ValueNode> parent_;
+ int index;
+
+public:
+ //! Time of the activepoint
+ Time time;
+
+ //! Priority
+ int priority;
+
+ //! Does this activepoint turn the entry on, or off?
+ bool state;
+
+ bool operator<(const Activepoint& rhs) { return time<rhs.time; }
+ bool operator<(const Time& rhs) { return time<rhs; }
+
+ Activepoint(const Time &time, const bool &state, int p=0): time(time), priority(p),state(state) { }
+ //! \todo Should priority be initialised here, or elsewhere? This avoids a valgrind warning for now.
+ Activepoint(): priority(0) { }
+
+ const Time& get_time()const { return time; }
+ void set_time(const Time& x) { time=x; }
+
+ bool get_state()const { return state; }
+ void set_state(bool x) { state=x; }
+
+ int get_priority()const { return priority; }
+ void set_priority(int x) { priority=x; }
+
+ const etl::loose_handle<ValueNode> &get_parent_value_node()const { return parent_; }
+ void set_parent_value_node(const etl::loose_handle<ValueNode> &x) { parent_=x; }
+
+ int get_parent_index()const { return index; }
+ void set_parent_index(int x) { index=x; }
+
+ GUID get_guid()const;
+}; // END of struct ValueNode_BLine::Activepoint
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file angle.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_ANGLE_H
+#define __SYNFIG_ANGLE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/angle>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \typedef Angle
+** \todo writeme
+*/
+typedef etl::angle Angle;
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file blinepoint.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "blinepoint.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+void
+synfig::BLinePoint::reverse()
+{
+ if(split_tangent_)
+ {
+ std::swap(tangent_[0],tangent_[1]);
+ tangent_[0]=-tangent_[0];
+ tangent_[1]=-tangent_[1];
+ }
+ else
+ {
+ tangent_[0]=-tangent_[0];
+ tangent_[1]=-tangent_[1];
+ }
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file blinepoint.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_BLINEPOINT_H
+#define __SYNFIG_BLINEPOINT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "vector.h"
+#include "uniqueid.h"
+#include <algorithm>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class BLinePoint : public UniqueID
+{
+private:
+ Point vertex_;
+ Vector tangent_[2];
+ float width_;
+ float origin_;
+ bool split_tangent_;
+
+public:
+
+ BLinePoint():
+ vertex_(Point(0,0)),
+ width_(0.01),
+ origin_(0.0),
+ split_tangent_(false)
+ { tangent_[0] = Point(0,0); tangent_[1] = Point(0,0); }
+
+ const Point& get_vertex()const { return vertex_; }
+ void set_vertex(const Point& x) { vertex_=x; }
+
+
+ const Vector& get_tangent1()const { return tangent_[0]; }
+ const Vector& get_tangent2()const { return split_tangent_?tangent_[1]:tangent_[0]; }
+ void set_tangent(const Vector& x) { tangent_[0]=tangent_[1]=x; }
+ void set_tangent1(const Vector& x) { tangent_[0]=x; }
+ void set_tangent2(const Vector& x) { tangent_[1]=x; }
+
+
+ const float& get_width()const { return width_; }
+ void set_width(float x) { width_=x; }
+
+ // We store the origin offset by 0.5 so that
+ // can have the origin set to the default by zeroing
+ // out the structure.
+ float get_origin()const { return origin_+0.5f; }
+ void set_origin(float x) { origin_=x-0.5f; }
+
+
+ const bool& get_split_tangent_flag()const { return split_tangent_; }
+ void set_split_tangent_flag(bool x=true) { split_tangent_=x; }
+
+ void reverse();
+
+}; // END of class BLinePoint
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file synfig/blur.cpp
+** \brief Blur Implementation File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <synfig/general.h>
+#include <synfig/surface.h>
+
+#include "blur.h"
+
+#include <stdexcept>
+#include <ETL/stringf>
+
+#include <ETL/pen>
+#include <ETL/gaussian>
+#include <ETL/boxblur>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+Point Blur::operator ()(const Point &pos) const
+{
+ Point blurpos(pos);
+
+ switch(type)
+ {
+ case CROSS:
+ if(rand()%2)
+ {
+ if(size[0])
+ blurpos[0]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[0];
+ }
+ else
+ {
+ if(size[1])
+ blurpos[1]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[1];
+ }
+ break;
+
+ case DISC:
+ {
+ Angle theta=Angle::rotations((float)rand()/(float)RAND_MAX);
+ Vector::value_type mag=(float)rand()/(float)RAND_MAX;
+ Vector vect((float)Angle::cos(theta).get()*mag,(float)Angle::sin(theta).get()*mag);
+
+ blurpos[0]+=vect[0]*size[0];
+ blurpos[1]+=vect[1]*size[1];
+ }
+ break;
+
+ case FASTGAUSSIAN:
+ case GAUSSIAN:
+ // Not quite a true gaussian blur,
+ // but the results are close enough for me.
+ if(size[0])
+ {
+ blurpos[0]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[0]*3/4;
+ blurpos[0]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[0]*3/4;
+ }
+ if(size[1])
+ {
+ blurpos[1]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[1]*3/4;
+ blurpos[1]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[1]*3/4;
+ }
+ break;
+
+ case BOX:
+ default:
+ if(size[0])
+ blurpos[0]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[0];
+ if(size[1])
+ blurpos[1]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[1];
+ break;
+ }
+
+ return blurpos;
+}
+
+Point Blur::operator ()(synfig::Real x, synfig::Real y) const
+{
+ return (*this)(Point(x,y));
+}
+
+//blur functions to make my life easier
+
+template <typename T>
+static inline T zero()
+{
+ return (T)0;
+}
+
+template <>
+static inline Color zero<Color>()
+{
+ return Color::alpha();
+}
+
+template <typename T,typename AT,class VP>
+static void GuassianBlur_2x2(etl::surface<T,AT,VP> &surface)
+{
+ int x,y;
+ T Tmp1,Tmp2,SR0;
+
+ T *SC0=new T[surface.get_w()];
+
+ memcpy(SC0,surface[0],surface.get_w()*sizeof(T));
+
+ for(y=0;y<surface.get_h();y++)
+ {
+ SR0=surface[y][0];
+ for(x=0;x<surface.get_w();x++)
+ {
+ Tmp1=surface[y][x];
+ Tmp2=SR0+Tmp1;
+ SR0=Tmp1;
+ surface[y][x]=(SC0[x]+Tmp2)/4;
+ SC0[x]=Tmp2;
+ }
+ }
+ delete [] SC0;
+}
+
+template <typename T,typename AT,class VP>
+static void GuassianBlur_3x3(etl::surface<T,AT,VP> &surface)
+{
+ int x,y,u,v,w,h;
+ T Tmp1,Tmp2,SR0,SR1;
+
+ w=surface.get_w();
+ h=surface.get_h();
+
+ T *SC0=new T[w+1];
+ T *SC1=new T[w+1];
+
+ // Setup the row bufers
+ for(x=0;x<w;x++)SC0[x]=surface[0][x]*4;
+// memcpy(SC1,surface[0],w*sizeof(T));
+
+ for(y=0;y<=h;y++)
+ {
+ if(y>=h)
+ v=h-1;
+ else
+ v=y;
+
+ SR0=SR1=surface[y][0];
+ for(x=0;x<=w;x++)
+ {
+ if(x>=w)
+ u=w-1;
+ else
+ u=x;
+
+ // Row Machine
+ Tmp1=surface[v][u];
+ Tmp2=SR0+Tmp1;
+ SR0=Tmp1;
+ Tmp1=SR1+Tmp2;
+ SR1=Tmp2;
+
+ // Column Machine
+ Tmp2=SC0[x]+Tmp1;
+ SC0[x]=Tmp1;
+ if(y&&x)
+ surface[y-1][x-1]=(SC1[x]+Tmp2)/16;
+ SC1[x]=Tmp2;
+ }
+ }
+
+ delete [] SC0;
+ delete [] SC1;
+}
+
+template <typename T,typename AT,class VP>
+inline static void GaussianBlur_5x5_(etl::surface<T,AT,VP> &surface,T *SC0,T *SC1,T *SC2,T *SC3)
+{
+ int x,y,u,v,w,h;
+ T Tmp1,Tmp2,SR0,SR1,SR2,SR3;
+
+ w=surface.get_w();
+ h=surface.get_h();
+
+ // Setup the row bufers
+ for(x=0;x<w;x++)SC0[x+2]=surface[0][x]*24;
+// memset(SC0,0,(w+2)*sizeof(T));
+ memset(SC1,0,(w+2)*sizeof(T));
+ memset(SC2,0,(w+2)*sizeof(T));
+ memset(SC3,0,(w+2)*sizeof(T));
+
+ for(y=0;y<h+2;y++)
+ {
+ if(y>=h)
+ v=h-1;
+ else
+ v=y;
+
+ SR0=SR1=SR2=SR3=0;
+ SR0=surface[v][0]*1.5;
+ for(x=0;x<w+2;x++)
+ {
+ if(x>=w)
+ u=w-1;
+ else
+ u=x;
+
+ // Row Machine
+ Tmp1=surface[v][u];
+ Tmp2=SR0+Tmp1;
+ SR0=Tmp1;
+ Tmp1=SR1+Tmp2;
+ SR1=Tmp2;
+ Tmp2=SR2+Tmp1;
+ SR2=Tmp1;
+ Tmp1=SR3+Tmp2;
+ SR3=Tmp2;
+
+ // Column Machine
+ Tmp2=SC0[x]+Tmp1;
+ SC0[x]=Tmp1;
+ Tmp1=SC1[x]+Tmp2;
+ SC1[x]=Tmp2;
+ Tmp2=SC2[x]+Tmp1;
+ SC2[x]=Tmp1;
+ if(y>1&&x>1)
+ surface[y-2][x-2]=(SC3[x]+Tmp2)/256;
+ SC3[x]=Tmp2;
+ }
+ }
+
+}
+
+template <typename T,typename AT,class VP>
+inline static void GaussianBlur_5x5(etl::surface<T,AT,VP> &surface)
+{
+ int w=surface.get_w();
+
+ T *SC0=new T[w+2];
+ T *SC1=new T[w+2];
+ T *SC2=new T[w+2];
+ T *SC3=new T[w+2];
+
+ GaussianBlur_5x5_(surface,SC0,SC1,SC2,SC3);
+
+ delete [] SC0;
+ delete [] SC1;
+ delete [] SC2;
+ delete [] SC3;
+}
+
+template <typename T,typename AT,class VP>
+static void GuassianBlur_nxn(etl::surface<T,AT,VP> &surface,int n)
+{
+ int x,y,u,v,w,h;
+ int half_n=n/2,i;
+ T inv_divisor=pow(2.0,(n-1));
+ T Tmp1,Tmp2;
+ inv_divisor=1.0/(inv_divisor*inv_divisor);
+
+ w=surface.get_w();
+ h=surface.get_h();
+
+ T SR[n-1];
+ T *SC[n-1];
+
+ for(i=0;i<n-1;i++)
+ {
+ SC[i]=new T[w+half_n];
+ if(!SC[i])
+ {
+ throw(runtime_error(strprintf(__FILE__":%d:Malloc failure",__LINE__)));
+ return;
+ }
+ memset(SC[i],0,(w+half_n)*sizeof(T));
+ }
+
+ // Setup the first row
+// for(x=0;x<w;x++)SC[0][x+half_n]=surface[0][x]*550.0;//*pow(2.0,(n-1))*(2.0/n);
+
+ for(y=0;y<h+half_n;y++)
+ {
+ if(y>=h)
+ v=h-1;
+ else
+ v=y;
+
+ memset(SR,0,(n-1)*sizeof(T));
+
+// SR[0]=surface[v][0]*(2.0-1.9/n);
+
+ for(x=0;x<w+half_n;x++)
+ {
+ if(x>=w)
+ u=w-1;
+ else
+ u=x;
+
+ Tmp1=surface[v][u];
+ // Row Machine
+ for(i=0;i<half_n;i++)
+ {
+ Tmp2=SR[i*2]+Tmp1;
+ SR[i*2]=Tmp1;
+ Tmp1=SR[i*2+1]+Tmp2;
+ SR[i*2+1]=Tmp2;
+ }
+
+ // Column Machine
+ for(i=0;i<half_n-1;i++)
+ {
+ Tmp2=SC[i*2][x]+Tmp1;
+ SC[i*2][x]=Tmp1;
+ Tmp1=SC[i*2+1][x]+Tmp2;
+ SC[i*2+1][x]=Tmp2;
+ }
+ Tmp2=SC[n-3][x]+Tmp1;
+ SC[n-3][x]=Tmp1;
+ if(y>=half_n&&x>=half_n)
+ surface[y-half_n][x-half_n]=(SC[n-2][x]+Tmp2)*inv_divisor;
+ SC[n-2][x]=Tmp2;
+ }
+ }
+
+ for(i=0;i<n-1;i++)
+ delete [] SC[i];
+}
+
+template <typename T,typename AT,class VP>
+static void GuassianBlur_2x1(etl::surface<T,AT,VP> &surface)
+{
+ int x,y;
+ AT Tmp1,Tmp2,SR0;
+
+ for(y=0;y<surface.get_h();y++)
+ {
+ SR0=surface[y][0];
+ for(x=0;x<surface.get_w();x++)
+ {
+ Tmp1=surface[y][x];
+ Tmp2=SR0+Tmp1;
+ SR0=Tmp1;
+ surface[y][x]=(Tmp2)/2;
+ }
+ }
+}
+
+template <typename T,typename AT,class VP>
+static void GuassianBlur_3x1(etl::surface<T,AT,VP> &surface)
+{
+ int x,y;
+ AT Tmp1,Tmp2,SR0,SR1;
+
+ for(y=0;y<surface.get_h();y++)
+ {
+ SR0=SR1=surface[y][0];
+ for(x=0;x<surface.get_w();x++)
+ {
+ // Row Machine
+ Tmp1=surface[y][x];
+ Tmp2=SR0+Tmp1;
+ SR0=Tmp1;
+ Tmp1=SR1+Tmp2;
+ SR1=Tmp2;
+
+ if(x)
+ surface[y][x-1]=(Tmp1)/4;
+ }
+ }
+}
+
+template <typename T,typename AT,class VP>
+static void GuassianBlur_1x2(etl::surface<T,AT,VP> &surface)
+{
+ int x,y;
+ AT Tmp1,Tmp2,SR0;
+
+ for(x=0;x<surface.get_w();x++)
+ {
+ SR0 = zero<T>();
+ for(y=0;y<surface.get_h();y++)
+ {
+ Tmp1=surface[y][x];
+ Tmp2=SR0+Tmp1;
+ SR0=Tmp1;
+ surface[y][x]=(Tmp2)/2;
+ }
+ }
+}
+
+template <typename T,typename AT,class VP>
+static void GuassianBlur_1x3(etl::surface<T,AT,VP> &surface)
+{
+ int x,y;
+ AT Tmp1,Tmp2,SR0,SR1;
+
+ for(x=0;x<surface.get_w();x++)
+ {
+ SR0=SR1=surface[0][x];
+ for(y=0;y<surface.get_h();y++)
+ {
+ // Row Machine
+ Tmp1=surface[y][x];
+ Tmp2=SR0+Tmp1;
+ SR0=Tmp1;
+ Tmp1=SR1+Tmp2;
+ SR1=Tmp2;
+
+ if(y)
+ surface[y-1][x]=(Tmp1)/4;
+ }
+ }
+}
+
+//THE GOOD ONE!!!!!!!!!
+bool Blur::operator ()(const Surface &surface,
+ const Vector &resolution,
+ Surface &out) const
+{
+ int w = surface.get_w(),
+ h = surface.get_h();
+
+ if(w == 0 || h == 0 || resolution[0] == 0 || resolution[1] == 0) return false;
+
+ const Real pw = resolution[0]/w,
+ ph = resolution[1]/h;
+
+ int halfsizex = (int) (abs(size[0]*.5/pw) + 1),
+ halfsizey = (int) (abs(size[1]*.5/ph) + 1);
+
+ int x,y;
+
+ SuperCallback blurcall(cb,0,5000,5000);
+
+ Surface worksurface(w,h);
+
+ //synfig::info("Blur: check surface = %s", surface_valid(surface)?"true":"false");
+
+ // Premultiply the alpha
+ for(y=0;y<h;y++)
+ {
+ for(x=0;x<w;x++)
+ {
+ Color a = surface[y][x];
+ a.set_r(a.get_r()*a.get_a());
+ a.set_g(a.get_g()*a.get_a());
+ a.set_b(a.get_b()*a.get_a());
+ worksurface[y][x] = a;
+ }
+ }
+
+ switch(type)
+ {
+ case Blur::DISC: // D I S C ----------------------------------------------------------
+ {
+ int bw = halfsizex;
+ int bh = halfsizey;
+
+ if(size[0] && size[1] && w*h>2)
+ {
+ int x2,y2;
+ Surface tmp_surface(worksurface);
+
+ for(y=0;y<h;y++)
+ {
+ for(x=0;x<w;x++)
+ {
+ //accumulate all the pixels in an ellipse of w,h about the current pixel
+ Color color=Color::alpha();
+ int total=0;
+
+ for(y2=-bh;y2<=bh;y2++)
+ {
+ for(x2=-bw;x2<=bw;x2++)
+ {
+ //get the floating point distance away from the origin pixel in relative coords
+ float tmp_x=(float)x2/bw;
+ float tmp_y=(float)y2/bh;
+ tmp_x*=tmp_x;
+ tmp_y*=tmp_y;
+
+ //ignore if it's outside of the disc
+ if( tmp_x+tmp_y>1.0)
+ continue;
+
+ //cap the pixel indices to inside the surface
+ int u= x+x2,
+ v= y+y2;
+
+ if( u < 0 ) u = 0;
+ if( u >= w ) u = w-1;
+
+ if( v < 0 ) v = 0;
+ if( v >= h ) v = h-1;
+
+ //accumulate the color, and # of pixels added in
+ color += tmp_surface[v][u];
+ total++;
+ }
+ }
+
+ //blend the color with the original color
+ //if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ worksurface[y][x]=color/total;
+ //else
+ // worksurface[y][x]=Color::blend(color/total,tmp_surface[y][x],get_amount(),get_blend_method());
+ }
+ if(!blurcall.amount_complete(y,h))
+ {
+ //if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+ }
+ break;
+ }
+
+ //if we don't qualify for disc blur just use box blur
+ }
+
+ case Blur::BOX: // B O X -------------------------------------------------------
+ {
+ //horizontal part
+ //synfig::info("Blur: Starting Box blur (surface valid %d)", (int)surface_valid(worksurface));
+
+ Surface temp_surface;
+ temp_surface.set_wh(w,h);
+
+ if(size[0])
+ {
+ int length = halfsizex;
+ length=std::max(1,length);
+
+ //synfig::info("Blur: hbox blur work -> temp %d", length);
+ etl::hbox_blur(worksurface.begin(),worksurface.end(),length,temp_surface.begin());
+ }
+ else temp_surface = worksurface;
+ //synfig::info("Blur: hbox finished");
+
+ //vertical part
+ //Surface temp_surface2;
+ //temp_surface2.set_wh(w,h);
+
+ if(size[1])
+ {
+ int length = halfsizey;
+ length = std::max(1,length);
+
+ //synfig::info("Blur: vbox blur temp -> work %d",length);
+ etl::vbox_blur(temp_surface.begin(),temp_surface.end(),length,worksurface.begin());
+ }
+ else worksurface = temp_surface;
+ //synfig::info("Blur: vbox finished");
+
+ //blend with the original surface
+ /*int x,y;
+ for(y=0;y<h;y++)
+ {
+ for(x=0;x<w;x++)
+ {
+ worksurface[y][x]=temp_surface2[y][x];//Color::blend(temp_surface2[y][x],worksurface[y][x],get_amount(),get_blend_method());
+ }
+ }*/
+ }
+ break;
+
+ case Blur::FASTGAUSSIAN: // F A S T G A U S S I A N ----------------------------------------------
+ {
+ //fast gaussian is treated as a 3x3 type of thing, except expanded to work with the length
+
+ /* 1 2 1
+ 2 4 2
+ 1 2 1
+ */
+
+ Surface temp_surface;
+ temp_surface.set_wh(w,h);
+
+ //Surface temp_surface2;
+ //temp_surface2.set_wh(w,h);
+
+ //horizontal part
+ if(size[0])
+ {
+ Real length=abs((float)w/(resolution[0]))*size[0]*0.5+1;
+ length=std::max(1.0,length);
+
+ //two box blurs produces: 1 2 1
+ etl::hbox_blur(worksurface.begin(),w,h,(int)(length*3/4),temp_surface.begin());
+ etl::hbox_blur(temp_surface.begin(),w,h,(int)(length*3/4),worksurface.begin());
+ }
+ //else temp_surface2=worksurface;
+
+ //vertical part
+ if(size[1])
+ {
+ Real length=abs((float)h/(resolution[1]))*size[1]*0.5+1;
+ length=std::max(1.0,length);
+
+ //two box blurs produces: 1 2 1 on the horizontal 1 2 1
+ etl::vbox_blur(worksurface.begin(),w,h,(int)(length*3/4),temp_surface.begin());
+ etl::vbox_blur(temp_surface.begin(),w,h,(int)(length*3/4),worksurface.begin());
+ }
+ //else temp_surface2=temp_surface2;
+
+ /*int x,y;
+ for(y=0;y<h;y++)
+ {
+ for(x=0;x<w;x++)
+ {
+ worksurface[y][x]=temp_surface2[y][x];//Color::blend(temp_surface2[y][x],worksurface[y][x],get_amount(),get_blend_method());
+ }
+ }*/
+ }
+ break;
+
+ case Blur::CROSS: // C R O S S -------------------------------------------------------
+ {
+ //horizontal part
+ Surface temp_surface;
+ temp_surface.set_wh(worksurface.get_w(),worksurface.get_h());
+
+ if(size[0])
+ {
+ int length = halfsizex;
+ length = std::max(1,length);
+
+ etl::hbox_blur(worksurface.begin(),worksurface.end(),length,temp_surface.begin());
+ }
+ else temp_surface = worksurface;
+
+ //vertical part
+ Surface temp_surface2;
+ temp_surface2.set_wh(worksurface.get_w(),worksurface.get_h());
+
+ if(size[1])
+ {
+ int length = halfsizey;
+ length = std::max(1,length);
+
+ etl::vbox_blur(worksurface.begin(),worksurface.end(),length,temp_surface2.begin());
+ }
+ else temp_surface2 = worksurface;
+
+ //blend the two together
+ int x,y;
+
+ for(y=0;y<h;y++)
+ {
+ for(x=0;x<w;x++)
+ {
+ worksurface[y][x] = (temp_surface[y][x]+temp_surface2[y][x])/2;//Color::blend((temp_surface[y][x]+temp_surface2[y][x])/2,worksurface[y][x],get_amount(),get_blend_method());
+ }
+ }
+
+ break;
+ }
+
+ case Blur::GAUSSIAN: // G A U S S I A N ----------------------------------------------
+ {
+ #ifndef GAUSSIAN_ADJUSTMENT
+ #define GAUSSIAN_ADJUSTMENT (0.05)
+ #endif
+
+ Real pw = (Real)w/(resolution[0]);
+ Real ph = (Real)h/(resolution[1]);
+
+ Surface temp_surface;
+ Surface *gauss_surface;
+
+ //synfig::warning("Didn't crash yet b1");
+
+ //if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ gauss_surface = &worksurface;
+ /*else
+ {
+ temp_surface = worksurface;
+ gauss_surface = &temp_surface;
+ }*/
+
+ /* Squaring the pw and ph values
+ is necessary to insure consistant
+ results when rendered to different
+ resolutions.
+ Unfortunately, this automatically
+ squares our rendertime.
+ There has got to be a faster way...
+ */
+ pw=pw*pw;
+ ph=ph*ph;
+
+ int bw = (int)(abs(pw)*size[0]*GAUSSIAN_ADJUSTMENT+0.5);
+ int bh = (int)(abs(ph)*size[1]*GAUSSIAN_ADJUSTMENT+0.5);
+ int max=bw+bh;
+
+ Color *SC0=new class Color[w+2];
+ Color *SC1=new class Color[w+2];
+ Color *SC2=new class Color[w+2];
+ Color *SC3=new class Color[w+2];
+ memset(SC0,0,(w+2)*sizeof(Color));
+ memset(SC0,0,(w+2)*sizeof(Color));
+ memset(SC0,0,(w+2)*sizeof(Color));
+ memset(SC0,0,(w+2)*sizeof(Color));
+
+ //synfig::warning("Didn't crash yet b2");
+ //int i = 0;
+
+ while(bw&&bh)
+ {
+ if(!blurcall.amount_complete(max-(bw+bh),max))return false;
+
+ if(bw>=4 && bh>=4)
+ {
+ etl::gaussian_blur_5x5_(gauss_surface->begin(),gauss_surface->get_w(),gauss_surface->get_h(),SC0,SC1,SC2,SC3);
+ bw-=4,bh-=4;
+ }
+ else
+ if(bw>=2 && bh>=2)
+ {
+ etl::gaussian_blur_3x3(gauss_surface->begin(),gauss_surface->end());
+ bw-=2,bh-=2;
+ }
+ else
+ if(bw>=1 && bh>=1)
+ {
+ GuassianBlur_2x2(*gauss_surface);
+ bw--,bh--;
+ }
+
+ //synfig::warning("Didn't crash yet bi - %d",i++);
+ }
+ while(bw)
+ {
+ if(!blurcall.amount_complete(max-(bw+bh),max))return false;
+ if(bw>=2)
+ {
+ GuassianBlur_3x1(*gauss_surface);
+ bw-=2;
+ }
+ else
+ if(bw>=1)
+ {
+ GuassianBlur_2x1(*gauss_surface);
+ bw--;
+ }
+ //synfig::warning("Didn't crash yet bi - %d",i++);
+ }
+ while(bh)
+ {
+ if(!blurcall.amount_complete(max-(bw+bh),max))return false;
+ if(bh>=2)
+ {
+ GuassianBlur_1x3(*gauss_surface);
+ bh-=2;
+ }
+ else
+ if(bh>=1)
+ {
+ GuassianBlur_1x2(*gauss_surface);
+ bh--;
+ }
+ //synfig::warning("Didn't crash yet bi - %d",i++);
+ }
+
+ delete [] SC0;
+ delete [] SC1;
+ delete [] SC2;
+ delete [] SC3;
+
+ /*if(get_amount()!=1.0 || get_blend_method()!=Color::BLEND_STRAIGHT)
+ {
+ int x,y;
+ for(y=0;y<renddesc.get_h();y++)
+ for(x=0;x<renddesc.get_w();x++)
+ worksurface[y][x]=Color::blend(temp_surface[y][x],worksurface[y][x],get_amount(),get_blend_method());
+ }*/
+ //synfig::warning("Didn't crash yet b end",i++);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // Scale up the alpha
+
+ //be sure the surface is of the correct size
+ //surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ out.set_wh(w,h);
+
+ //divide out the alpha
+ for(y=0;y<h;y++)
+ {
+ for(x=0;x<w;x++)
+ {
+ Color a = worksurface[y][x];
+ if(a.get_a())
+ {
+ a.set_r(a.get_r()/a.get_a());
+ a.set_g(a.get_g()/a.get_a());
+ a.set_b(a.get_b()/a.get_a());
+ out[y][x]=a;
+ }
+ else out[y][x]=Color::alpha();
+ }
+ }
+
+ //we are FRIGGGIN done....
+ blurcall.amount_complete(100,100);
+
+ return true;
+}
+
+bool Blur::operator ()(const surface<float> &surface,
+ const Vector &resolution,
+ surface<float> &out) const
+{
+ int w = surface.get_w(),
+ h = surface.get_h();
+
+ if(w == 0 || h == 0 || resolution[0] == 0 || resolution[1] == 0) return false;
+
+ const Real pw = resolution[0]/w,
+ ph = resolution[1]/h;
+
+ int halfsizex = (int) (abs(size[0]*.5/pw) + 1),
+ halfsizey = (int) (abs(size[1]*.5/ph) + 1);
+ int x,y;
+
+ SuperCallback blurcall(cb,0,5000,5000);
+
+ etl::surface<float> worksurface(surface);
+
+ //don't need to premultiply because we are dealing with ONLY alpha
+
+ switch(type)
+ {
+ case Blur::DISC: // D I S C ----------------------------------------------------------
+ {
+ int bw = halfsizex;
+ int bh = halfsizey;
+
+ if(size[0] && size[1] && w*h>2)
+ {
+ int x2,y2;
+ etl::surface<float> tmp_surface(worksurface);
+
+ for(y=0;y<h;y++)
+ {
+ for(x=0;x<w;x++)
+ {
+ //accumulate all the pixels in an ellipse of w,h about the current pixel
+ float a = 0;
+ int total=0;
+
+ for(y2=-bh;y2<=bh;y2++)
+ {
+ for(x2=-bw;x2<=bw;x2++)
+ {
+ //get the floating point distance away from the origin pixel in relative coords
+ float tmp_x=(float)x2/bw;
+ float tmp_y=(float)y2/bh;
+ tmp_x*=tmp_x;
+ tmp_y*=tmp_y;
+
+ //ignore if it's outside of the disc
+ if( tmp_x+tmp_y>1.0)
+ continue;
+
+ //cap the pixel indices to inside the surface
+ int u= x+x2,
+ v= y+y2;
+
+ if( u < 0 ) u = 0;
+ if( u >= w ) u = w-1;
+
+ if( v < 0 ) v = 0;
+ if( v >= h ) v = h-1;
+
+ //accumulate the color, and # of pixels added in
+ a += tmp_surface[v][u];
+ total++;
+ }
+ }
+
+ //blend the color with the original color
+ //if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ worksurface[y][x]=a/total;
+ //else
+ // worksurface[y][x]=Color::blend(color/total,tmp_surface[y][x],get_amount(),get_blend_method());
+ }
+ if(!blurcall.amount_complete(y,h))
+ {
+ //if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
+ return false;
+ }
+ }
+ break;
+ }
+
+ //if we don't qualify for disc blur just use box blur
+ }
+
+ case Blur::BOX: // B O X -------------------------------------------------------
+ {
+ //horizontal part
+ etl::surface<float> temp_surface;
+ temp_surface.set_wh(w,h);
+
+ if(size[0])
+ {
+ int length = halfsizex;
+ length=std::max(1,length);
+
+ etl::hbox_blur(worksurface.begin(),worksurface.end(),length,temp_surface.begin());
+ }
+ else temp_surface = worksurface;
+
+ //vertical part
+ //etl::surface<float> temp_surface2;
+ //temp_surface2.set_wh(w,h);
+
+ if(size[1])
+ {
+ int length = halfsizey;
+ length = std::max(1,length);
+ etl::vbox_blur(temp_surface.begin(),temp_surface.end(),length,worksurface.begin());
+ }
+ else worksurface = temp_surface;
+
+ //blend with the original surface
+ /*int x,y;
+ for(y=0;y<h;y++)
+ {
+ for(x=0;x<w;x++)
+ {
+ worksurface[y][x]=temp_surface2[y][x];//Color::blend(temp_surface2[y][x],worksurface[y][x],get_amount(),get_blend_method());
+ }
+ }*/
+ }
+ break;
+
+ case Blur::FASTGAUSSIAN: // F A S T G A U S S I A N ----------------------------------------------
+ {
+ //fast gaussian is treated as a 3x3 type of thing, except expanded to work with the length
+
+ /* 1 2 1
+ 2 4 2
+ 1 2 1
+ */
+
+ etl::surface<float> temp_surface;
+ temp_surface.set_wh(w,h);
+
+ //etl::surface<float> temp_surface2;
+ //temp_surface2.set_wh(w,h);
+
+ //horizontal part
+ if(size[0])
+ {
+ Real length=abs((float)w/(resolution[0]))*size[0]*0.5+1;
+ length=std::max(1.0,length);
+
+ //two box blurs produces: 1 2 1
+ etl::hbox_blur(worksurface.begin(),w,h,(int)(length*3/4),temp_surface.begin());
+ etl::hbox_blur(temp_surface.begin(),w,h,(int)(length*3/4),worksurface.begin());
+ }
+ //else temp_surface2=worksurface;
+
+ //vertical part
+ if(size[1])
+ {
+ Real length=abs((float)h/(resolution[1]))*size[1]*0.5+1;
+ length=std::max(1.0,length);
+
+ //two box blurs produces: 1 2 1 on the horizontal 1 2 1
+ etl::vbox_blur(worksurface.begin(),w,h,(int)(length*3/4),temp_surface.begin());
+ etl::vbox_blur(temp_surface.begin(),w,h,(int)(length*3/4),worksurface.begin());
+ }
+ //else temp_surface2=temp_surface2;
+
+ /*int x,y;
+ for(y=0;y<h;y++)
+ {
+ for(x=0;x<w;x++)
+ {
+ worksurface[y][x]=temp_surface2[y][x];//Color::blend(temp_surface2[y][x],worksurface[y][x],get_amount(),get_blend_method());
+ }
+ }*/
+ }
+ break;
+
+ case Blur::CROSS: // C R O S S -------------------------------------------------------
+ {
+ //horizontal part
+ etl::surface<float> temp_surface;
+ temp_surface.set_wh(worksurface.get_w(),worksurface.get_h());
+
+ if(size[0])
+ {
+ int length = halfsizex;
+ length = std::max(1,length);
+
+ etl::hbox_blur(worksurface.begin(),worksurface.end(),length,temp_surface.begin());
+ }
+ else temp_surface = worksurface;
+
+ //vertical part
+ etl::surface<float> temp_surface2;
+ temp_surface2.set_wh(worksurface.get_w(),worksurface.get_h());
+
+ if(size[1])
+ {
+ int length = halfsizey;
+ length = std::max(1,length);
+
+ etl::vbox_blur(worksurface.begin(),worksurface.end(),length,temp_surface2.begin());
+ }
+ else temp_surface2 = worksurface;
+
+ //blend the two together
+ int x,y;
+
+ for(y=0;y<h;y++)
+ {
+ for(x=0;x<w;x++)
+ {
+ worksurface[y][x] = (temp_surface[y][x]+temp_surface2[y][x])/2;//Color::blend((temp_surface[y][x]+temp_surface2[y][x])/2,worksurface[y][x],get_amount(),get_blend_method());
+ }
+ }
+
+ break;
+ }
+
+ case Blur::GAUSSIAN: // G A U S S I A N ----------------------------------------------
+ {
+ #ifndef GAUSSIAN_ADJUSTMENT
+ #define GAUSSIAN_ADJUSTMENT (0.05)
+ #endif
+
+ Real pw = (Real)w/(resolution[0]);
+ Real ph = (Real)h/(resolution[1]);
+
+ //etl::surface<float> temp_surface;
+ etl::surface<float> *gauss_surface;
+
+ //if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ gauss_surface = &worksurface;
+ /*else
+ {
+ temp_surface = worksurface;
+ gauss_surface = &temp_surface;
+ }*/
+
+ /* Squaring the pw and ph values
+ is necessary to insure consistant
+ results when rendered to different
+ resolutions.
+ Unfortunately, this automatically
+ squares our rendertime.
+ There has got to be a faster way...
+ */
+ pw=pw*pw;
+ ph=ph*ph;
+
+ int bw = (int)(abs(pw)*size[0]*GAUSSIAN_ADJUSTMENT+0.5);
+ int bh = (int)(abs(ph)*size[1]*GAUSSIAN_ADJUSTMENT+0.5);
+ int max=bw+bh;
+
+ float *SC0=new float[w+2];
+ float *SC1=new float[w+2];
+ float *SC2=new float[w+2];
+ float *SC3=new float[w+2];
+
+ memset(SC0,0,(w+2)*sizeof(float));
+ memset(SC0,0,(w+2)*sizeof(float));
+ memset(SC0,0,(w+2)*sizeof(float));
+ memset(SC0,0,(w+2)*sizeof(float));
+
+ //int i = 0;
+
+ while(bw&&bh)
+ {
+ if(!blurcall.amount_complete(max-(bw+bh),max))return false;
+
+ if(bw>=4 && bh>=4)
+ {
+ etl::gaussian_blur_5x5_(gauss_surface->begin(),gauss_surface->get_w(),gauss_surface->get_h(),SC0,SC1,SC2,SC3);
+ bw-=4,bh-=4;
+ }
+ else
+ if(bw>=2 && bh>=2)
+ {
+ etl::gaussian_blur_3x3(gauss_surface->begin(),gauss_surface->end());
+ bw-=2,bh-=2;
+ }
+ else
+ if(bw>=1 && bh>=1)
+ {
+ GuassianBlur_2x2(*gauss_surface);
+ bw--,bh--;
+ }
+ }
+
+ while(bw)
+ {
+ if(!blurcall.amount_complete(max-(bw+bh),max))return false;
+ if(bw>=2)
+ {
+ GuassianBlur_3x1(*gauss_surface);
+ bw-=2;
+ }
+ else
+ if(bw>=1)
+ {
+ GuassianBlur_2x1(*gauss_surface);
+ bw--;
+ }
+ }
+
+ while(bh)
+ {
+ if(!blurcall.amount_complete(max-(bw+bh),max))return false;
+ if(bh>=2)
+ {
+ GuassianBlur_1x3(*gauss_surface);
+ bh-=2;
+ }
+ else
+ if(bh>=1)
+ {
+ GuassianBlur_1x2(*gauss_surface);
+ bh--;
+ }
+ }
+
+ delete [] SC0;
+ delete [] SC1;
+ delete [] SC2;
+ delete [] SC3;
+
+ /*if(get_amount()!=1.0 || get_blend_method()!=Color::BLEND_STRAIGHT)
+ {
+ int x,y;
+ for(y=0;y<renddesc.get_h();y++)
+ for(x=0;x<renddesc.get_w();x++)
+ worksurface[y][x]=Color::blend(temp_surface[y][x],worksurface[y][x],get_amount(),get_blend_method());
+ }*/
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ //be sure the surface is of the correct size
+ //surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ out.set_wh(w,h);
+
+ //divide out the alpha - don't need to cause we rock
+ out = worksurface;
+
+ //we are FRIGGGIN done....
+ blurcall.amount_complete(100,100);
+
+ return true;
+}
+
+/* === E N T R Y P O I N T ================================================= */
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file synfig/blur.h
+** \brief Blur Helper Header file
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_BLUR_HELPER_H
+#define __SYNFIG_BLUR_HELPER_H
+
+/* === H E A D E R S ======================================================= */
+#include <synfig/surface.h>
+#include <synfig/color.h>
+#include <synfig/vector.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+class synfig::ProgressCallback;
+
+class Blur
+{
+public:
+ enum Type
+ {
+ BOX =0,
+ FASTGAUSSIAN =1,
+ CROSS =2,
+ GAUSSIAN =3,
+ DISC =4,
+
+ FORCE_DWORD = 0x8fffffff
+ };
+
+private:
+ synfig::Point size;
+ int type;
+
+ synfig::ProgressCallback *cb;
+
+public:
+ synfig::Point & set_size(const synfig::Point &v) { return (size = v); }
+ const synfig::Point & get_size() const { return size; }
+ synfig::Point & get_size() { return size; }
+
+ int & set_type(const int &t) { return (type = t); }
+ const int & get_type() const { return type; }
+ int & get_type() { return type; }
+
+ Blur() {}
+ Blur(const synfig::Point &s, int t, synfig::ProgressCallback *callb=0):size(s), type(t), cb(callb) {}
+ Blur(synfig::Real sx, synfig::Real sy, int t, synfig::ProgressCallback *callb = 0): size(sx,sy), type(t), cb(callb) {}
+
+ //Parametric Blur
+ synfig::Point operator ()(const synfig::Point &p) const;
+ synfig::Point operator ()(synfig::Real x, synfig::Real y) const;
+
+ //Surface based blur
+ // input surface can be the same as output surface,
+ // though both have to be the same size
+ bool operator ()(const synfig::Surface &surface, const synfig::Vector &resolution, synfig::Surface &out) const;
+
+ bool operator ()(const etl::surface<float> &surface, const synfig::Vector &resolution, etl::surface<float> &out) const;
+ //bool operator ()(const etl::surface<unsigned char> &surface, const synfig::Vector &resolution, etl::surface<unsigned char> &out) const;
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file canvas.cpp
+** \brief Canvas Class Member Definitions
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "layer.h"
+#include "canvas.h"
+#include <cassert>
+#include "exception.h"
+#include "time.h"
+#include "context.h"
+#include "layer_pastecanvas.h"
+#include <sigc++/bind.h>
+
+#endif
+
+using namespace synfig;
+using namespace etl;
+using namespace std;
+
+namespace synfig { extern Canvas::Handle open_canvas(const String &filename); };
+
+/* === M A C R O S ========================================================= */
+
+struct _CanvasCounter
+{
+ static int counter;
+ ~_CanvasCounter()
+ {
+ if(counter)
+ synfig::error("%d canvases not yet deleted!",counter);
+ }
+} _canvas_counter;
+
+int _CanvasCounter::counter(0);
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Canvas::Canvas(const string &id):
+ id_ (id),
+ cur_time_ (0),
+ is_inline_ (false),
+ is_dirty_ (true),
+ op_flag_ (false)
+{
+ _CanvasCounter::counter++;
+ clear();
+}
+
+void
+Canvas::on_changed()
+{
+ is_dirty_=true;
+ Node::on_changed();
+}
+
+Canvas::~Canvas()
+{
+ //if(is_inline() && parent_) assert(0);
+ _CanvasCounter::counter--;
+ //DEBUGPOINT();
+ clear();
+ begin_delete();
+}
+
+Canvas::iterator
+Canvas::end()
+{
+ return CanvasBase::end()-1;
+}
+
+Canvas::const_iterator
+Canvas::end()const
+{
+ return CanvasBase::end()-1;
+}
+
+Canvas::reverse_iterator
+Canvas::rbegin()
+{
+ return CanvasBase::rbegin()+1;
+}
+
+Canvas::const_reverse_iterator
+Canvas::rbegin()const
+{
+ return CanvasBase::rbegin()+1;
+}
+
+int
+Canvas::size()const
+{
+ return CanvasBase::size()-1;
+}
+
+void
+Canvas::clear()
+{
+ while(!empty())
+ {
+ Layer::Handle layer(front());
+ //if(layer->count()>2)synfig::info("before layer->count()=%d",layer->count());
+
+ erase(begin());
+ //if(layer->count()>1)synfig::info("after layer->count()=%d",layer->count());
+ }
+ //CanvasBase::clear();
+
+ // We need to keep a blank handle at the
+ // end of the image list, and acts at
+ // the bottom. Without it, the layers
+ // would just continue going when polled
+ // for a color.
+ CanvasBase::push_back(Layer::Handle());
+
+ changed();
+}
+
+bool
+Canvas::empty()const
+{
+ return CanvasBase::size()<=1;
+}
+
+Layer::Handle &
+Canvas::back()
+{
+ return *(CanvasBase::end()-1);
+}
+
+const Layer::Handle &
+Canvas::back()const
+{
+ return *(CanvasBase::end()-1);
+}
+
+Context
+Canvas::get_context()const
+{
+ return begin();
+}
+
+const ValueNodeList &
+Canvas::value_node_list()const
+{
+ if(is_inline() && parent_)
+ return parent_->value_node_list();
+ return value_node_list_;
+}
+
+KeyframeList &
+Canvas::keyframe_list()
+{
+ if(is_inline() && parent_)
+ return parent_->keyframe_list();
+ return keyframe_list_;
+}
+
+const KeyframeList &
+Canvas::keyframe_list()const
+{
+ if(is_inline() && parent_)
+ return parent_->keyframe_list();
+ return keyframe_list_;
+}
+
+etl::handle<Layer>
+Canvas::find_layer(const Point &pos)
+{
+ return get_context().hit_check(pos);
+}
+
+static bool
+valid_id(const String &x)
+{
+ static const char bad_chars[]=" :#@$^&()*";
+ unsigned int i;
+
+ if(!x.empty() && x[0]>='0' && x[0]<='9')
+ return false;
+
+ for(i=0;i<sizeof(bad_chars);i++)
+ if(x.find_first_of(bad_chars[i])!=string::npos)
+ return false;
+
+ return true;
+}
+
+void
+Canvas::set_id(const String &x)
+{
+ if(is_inline() && parent_)
+ throw runtime_error("Inline Canvas cannot have an ID");
+
+ if(!valid_id(x))
+ throw runtime_error("Invalid ID");
+ id_=x;
+ signal_id_changed_();
+}
+
+void
+Canvas::set_name(const String &x)
+{
+ name_=x;
+ signal_meta_data_changed()("name");
+ signal_meta_data_changed("name")();
+}
+
+void
+Canvas::set_author(const String &x)
+{
+ author_=x;
+ signal_meta_data_changed()("author");
+ signal_meta_data_changed("author")();
+}
+
+void
+Canvas::set_description(const String &x)
+{
+ description_=x;
+ signal_meta_data_changed()("description");
+ signal_meta_data_changed("description")();
+}
+
+void
+Canvas::set_time(Time t)const
+{
+ if(is_dirty_ || !get_time().is_equal(t))
+ {
+#if 0
+ if(is_root())
+ {
+ synfig::info("is_dirty_=%d",is_dirty_);
+ synfig::info("get_time()=%f",(float)get_time());
+ synfig::info("t=%f",(float)t);
+ }
+#endif
+
+ // ...questionable
+ const_cast<Canvas&>(*this).cur_time_=t;
+
+ is_dirty_=false;
+ get_context().set_time(t);
+ }
+ is_dirty_=false;
+}
+
+Canvas::LooseHandle
+Canvas::get_root()const
+{
+ return parent_?parent_->get_root().get():const_cast<synfig::Canvas *>(this);
+}
+
+int
+Canvas::get_depth(etl::handle<Layer> layer)const
+{
+ const_iterator iter;
+ int i(0);
+ for(iter=begin();iter!=end();++iter,i++)
+ {
+ if(layer==*iter)
+ return i;
+ }
+ return -1;
+}
+
+String
+Canvas::get_relative_id(etl::loose_handle<const Canvas> x)const
+{
+ if(x->get_root()==this)
+ return ":";
+ if(is_inline() && parent_)
+ return parent_->_get_relative_id(x);
+ return _get_relative_id(x);
+}
+
+String
+Canvas::_get_relative_id(etl::loose_handle<const Canvas> x)const
+{
+ if(is_inline() && parent_)
+ return parent_->_get_relative_id(x);
+
+ if(x.get()==this)
+ return String();
+
+ if(parent()==x.get())
+ return get_id();
+
+ String id;
+
+ const Canvas* canvas=this;
+
+ for(;!canvas->is_root();canvas=canvas->parent().get())
+ id=':'+canvas->get_id()+id;
+
+ if(x && get_root()!=x->get_root())
+ {
+ //String file_name=get_file_name();
+ //String file_path=x->get_file_path();
+
+ String file_name;
+ if(is_absolute_path(get_file_name()))
+ file_name=etl::relative_path(x->get_file_path(),get_file_name());
+ else
+ file_name=get_file_name();
+
+ // If the path of X is inside of file_name,
+ // then remove it.
+ //if(file_name.size()>file_path.size())
+ // if(file_path==String(file_name,0,file_path.size()))
+ // file_name.erase(0,file_path.size()+1);
+
+ id=file_name+'#'+id;
+ }
+
+ return id;
+}
+
+
+ValueNode::Handle
+Canvas::find_value_node(const String &id)
+{
+ return
+ ValueNode::Handle::cast_const(
+ const_cast<const Canvas*>(this)->find_value_node(id)
+ );
+}
+
+ValueNode::ConstHandle
+Canvas::find_value_node(const String &id)const
+{
+ if(is_inline() && parent_)
+ return parent_->find_value_node(id);
+
+ if(id.empty())
+ throw Exception::IDNotFound("Empty ID");
+
+ // If we do not have any resolution, then we assume that the
+ // request is for this immediate canvas
+ if(id.find_first_of(':')==string::npos && id.find_first_of('#')==string::npos)
+ return value_node_list_.find(id);
+
+ String canvas_id(id,0,id.rfind(':'));
+ String value_node_id(id,id.rfind(':')+1);
+ if(canvas_id.empty())
+ canvas_id=':';
+ //synfig::warning("constfind:value_node_id: "+value_node_id);
+ //synfig::warning("constfind:canvas_id: "+canvas_id);
+
+ return find_canvas(canvas_id)->value_node_list_.find(value_node_id);
+}
+
+ValueNode::Handle
+Canvas::surefind_value_node(const String &id)
+{
+ if(is_inline() && parent_)
+ return parent_->surefind_value_node(id);
+
+ if(id.empty())
+ throw Exception::IDNotFound("Empty ID");
+
+ // If we do not have any resolution, then we assume that the
+ // request is for this immediate canvas
+ if(id.find_first_of(':')==string::npos && id.find_first_of('#')==string::npos)
+ return value_node_list_.surefind(id);
+
+ String canvas_id(id,0,id.rfind(':'));
+ String value_node_id(id,id.rfind(':')+1);
+ if(canvas_id.empty())
+ canvas_id=':';
+
+ return surefind_canvas(canvas_id)->value_node_list_.surefind(value_node_id);
+}
+
+void
+Canvas::add_value_node(ValueNode::Handle x, const String &id)
+{
+ if(is_inline() && parent_)
+ return parent_->add_value_node(x,id);
+// throw runtime_error("You cannot add a ValueNode to an inline Canvas");
+
+ //DEBUGPOINT();
+ if(x->is_exported())
+ throw runtime_error("ValueNode is already exported");
+
+ if(id.empty())
+ throw Exception::BadLinkName("Empty ID");
+
+ if(id.find_first_of(':',0)!=string::npos)
+ throw Exception::BadLinkName("Bad character");
+
+ try
+ {
+ //DEBUGPOINT();
+ if(PlaceholderValueNode::Handle::cast_dynamic(value_node_list_.find(id)))
+ throw Exception::IDNotFound("add_value_node()");
+
+ //DEBUGPOINT();
+ throw Exception::IDAlreadyExists(id);
+ }
+ catch(Exception::IDNotFound)
+ {
+ //DEBUGPOINT();
+ x->set_id(id);
+
+ x->set_parent_canvas(this);
+
+ if(!value_node_list_.add(x))
+ {
+ synfig::error("Unable to add ValueNode");
+ throw std::runtime_error("Unable to add ValueNode");
+ }
+ //DEBUGPOINT();
+
+ return;
+ }
+}
+
+/*
+void
+Canvas::rename_value_node(ValueNode::Handle x, const String &id)
+{
+ if(id.empty())
+ throw Exception::BadLinkName("Empty ID");
+
+ if(id.find_first_of(": ",0)!=string::npos)
+ throw Exception::BadLinkName("Bad character");
+
+ try
+ {
+ if(PlaceholderValueNode::Handle::cast_dynamic(value_node_list_.find(id)))
+ throw Exception::IDNotFound("rename_value_node");
+ throw Exception::IDAlreadyExists(id);
+ }
+ catch(Exception::IDNotFound)
+ {
+ x->set_id(id);
+
+ return;
+ }
+}
+*/
+
+void
+Canvas::remove_value_node(ValueNode::Handle x)
+{
+ if(is_inline() && parent_)
+ return parent_->remove_value_node(x);
+// throw Exception::IDNotFound("Canvas::remove_value_node() was called from an inline canvas");
+
+ if(!x)
+ throw Exception::IDNotFound("Canvas::remove_value_node() was passed empty handle");
+
+ if(!value_node_list_.erase(x))
+ throw Exception::IDNotFound("Canvas::remove_value_node(): ValueNode was not found inside of this canvas");
+
+ //x->set_parent_canvas(0);
+
+ x->set_id("");
+}
+
+
+etl::handle<Canvas>
+Canvas::surefind_canvas(const String &id)
+{
+ if(is_inline() && parent_)
+ return parent_->surefind_canvas(id);
+
+ if(id.empty())
+ return this;
+
+ // If the ID contains a "#" character, then a filename is
+ // expected on the left side.
+ if(id.find_first_of('#')!=string::npos)
+ {
+ // If '#' is the first character, remove it
+ // and attempt to parse the ID again.
+ if(id[0]=='#')
+ return surefind_canvas(String(id,1));
+
+ //! \todo This needs a lot more optimization
+ String file_name(id,0,id.find_first_of('#'));
+ String external_id(id,id.find_first_of('#')+1);
+
+ file_name=unix_to_local_path(file_name);
+
+ Canvas::Handle external_canvas;
+
+ // If the composition is already open, then use it.
+ if(externals_.count(file_name))
+ external_canvas=externals_[file_name];
+ else
+ {
+ if(is_absolute_path(file_name))
+ external_canvas=open_canvas(file_name);
+ else
+ external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name);
+
+ if(!external_canvas)
+ throw Exception::FileNotFound(file_name);
+ externals_[file_name]=external_canvas;
+ }
+
+ return Handle::cast_const(external_canvas.constant()->find_canvas(external_id));
+ }
+
+ // If we do not have any resolution, then we assume that the
+ // request is for this immediate canvas
+ if(id.find_first_of(':')==string::npos)
+ {
+ Children::iterator iter;
+
+ // Search for the image in the image list,
+ // and return it if it is found
+ for(iter=children().begin();iter!=children().end();iter++)
+ if(id==(*iter)->get_id())
+ return *iter;
+
+ // Create a new canvas and return it
+ //synfig::warning("Implicitly creating canvas named "+id);
+ return new_child_canvas(id);
+ }
+
+ // If the first character is the separator, then
+ // this references the root canvas.
+ if(id[0]==':')
+ return get_root()->surefind_canvas(string(id,1));
+
+ // Now we know that the requested Canvas is in a child
+ // of this canvas. We have to find that canvas and
+ // call "find_canvas" on it, and return the result.
+
+ String canvas_name=string(id,0,id.find_first_of(':'));
+
+ Canvas::Handle child_canvas=surefind_canvas(canvas_name);
+
+ return child_canvas->surefind_canvas(string(id,id.find_first_of(':')+1));
+}
+
+Canvas::Handle
+Canvas::find_canvas(const String &id)
+{
+ return
+ Canvas::Handle::cast_const(
+ const_cast<const Canvas*>(this)->find_canvas(id)
+ );
+}
+
+Canvas::ConstHandle
+Canvas::find_canvas(const String &id)const
+{
+ if(is_inline() && parent_)return parent_->find_canvas(id);
+
+ if(id.empty())
+ return this;
+
+ // If the ID contains a "#" character, then a filename is
+ // expected on the left side.
+ if(id.find_first_of('#')!=string::npos)
+ {
+ // If '#' is the first character, remove it
+ // and attempt to parse the ID again.
+ if(id[0]=='#')
+ return find_canvas(String(id,1));
+
+ //! \todo This needs a lot more optimization
+ String file_name(id,0,id.find_first_of('#'));
+ String external_id(id,id.find_first_of('#')+1);
+
+ file_name=unix_to_local_path(file_name);
+
+ Canvas::Handle external_canvas;
+
+ // If the composition is already open, then use it.
+ if(externals_.count(file_name))
+ external_canvas=externals_[file_name];
+ else
+ {
+ if(is_absolute_path(file_name))
+ external_canvas=open_canvas(file_name);
+ else
+ external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name);
+
+ if(!external_canvas)
+ throw Exception::FileNotFound(file_name);
+ externals_[file_name]=external_canvas;
+ }
+
+ return Handle::cast_const(external_canvas.constant()->find_canvas(external_id));
+ }
+
+ // If we do not have any resolution, then we assume that the
+ // request is for this immediate canvas
+ if(id.find_first_of(':')==string::npos)
+ {
+ Children::const_iterator iter;
+
+ // Search for the image in the image list,
+ // and return it if it is found
+ for(iter=children().begin();iter!=children().end();iter++)
+ if(id==(*iter)->get_id())
+ return *iter;
+
+ throw Exception::IDNotFound("Child Canvas in Parent Canvas: (child)"+id);
+ }
+
+ // If the first character is the separator, then
+ // this references the root canvas.
+ if(id.find_first_of(':')==0)
+ return get_root()->find_canvas(string(id,1));
+
+ // Now we know that the requested Canvas is in a child
+ // of this canvas. We have to find that canvas and
+ // call "find_canvas" on it, and return the result.
+
+ String canvas_name=string(id,0,id.find_first_of(':'));
+
+ Canvas::ConstHandle child_canvas=find_canvas(canvas_name);
+
+ return child_canvas->find_canvas(string(id,id.find_first_of(':')+1));
+}
+
+
+Canvas::Handle
+Canvas::create()
+{
+ return new Canvas("Untitled");
+}
+
+void
+Canvas::push_back(etl::handle<Layer> x)
+{
+// DEBUGPOINT();
+// int i(x->count());
+ insert(end(),x);
+ //if(x->count()!=i+1)synfig::info("push_back before %d, after %d",i,x->count());
+}
+
+void
+Canvas::push_front(etl::handle<Layer> x)
+{
+// DEBUGPOINT();
+// int i(x->count());
+ insert(begin(),x);
+ //if(x->count()!=i+1)synfig::error("push_front before %d, after %d",i,x->count());
+}
+
+void
+Canvas::insert(iterator iter,etl::handle<Layer> x)
+{
+// int i(x->count());
+ CanvasBase::insert(iter,x);
+
+ /*if(x->count()!=i+1)
+ {
+ synfig::error(__FILE__":%d: Canvas::insert(): ***FAILURE*** before %d, after %d",__LINE__,i,x->count());
+ return;
+ //throw runtime_error("Canvas Insertion Failed");
+ }*/
+
+ x->set_canvas(this);
+
+
+ add_child(x.get());
+
+
+ LooseHandle correct_canvas(this);
+ //while(correct_canvas->is_inline())correct_canvas=correct_canvas->parent();
+ Layer::LooseHandle loose_layer(x);
+
+ add_connection(loose_layer,
+ sigc::connection::connection(
+ x->signal_added_to_group().connect(
+ sigc::bind(
+ sigc::mem_fun(
+ *correct_canvas,
+ &Canvas::add_group_pair),
+ loose_layer))));
+ add_connection(loose_layer,
+ sigc::connection::connection(
+ x->signal_removed_from_group().connect(
+ sigc::bind(
+ sigc::mem_fun(
+ *correct_canvas,
+ &Canvas::remove_group_pair),
+ loose_layer))));
+
+
+ if(!x->get_group().empty())
+ add_group_pair(x->get_group(),x);
+
+
+ changed();
+}
+
+void
+Canvas::push_back_simple(etl::handle<Layer> x)
+{
+ CanvasBase::insert(end(),x);
+ changed();
+}
+
+void
+Canvas::erase(Canvas::iterator iter)
+{
+ if(!(*iter)->get_group().empty())
+ remove_group_pair((*iter)->get_group(),(*iter));
+
+ // HACK: We really shouldn't be wiping
+ // out these signals entirely. We should
+ // only be removing the specific connections
+ // that we made. At the moment, I'm too
+ // lazy to add the code to keep track
+ // of those connections, and no one else
+ // is using these signals, so I'll just
+ // leave these next two lines like they
+ // are for now - darco 07-30-2004
+
+ // so don't wipe them out entirely
+ // - dooglus 09-21-2007
+ disconnect_connections(*iter);
+
+ if(!op_flag_)remove_child(iter->get());
+
+ CanvasBase::erase(iter);
+ if(!op_flag_)changed();
+}
+
+Canvas::Handle
+Canvas::clone(const GUID& deriv_guid)const
+{
+ synfig::String name;
+ if(is_inline())
+ name="inline";
+ else
+ {
+ name=get_id()+"_CLONE";
+
+ throw runtime_error("Cloning of non-inline canvases is not yet suported");
+ }
+
+ Handle canvas(new Canvas(name));
+
+ if(is_inline())
+ {
+ canvas->is_inline_=true;
+ canvas->parent_=0;
+ //canvas->set_inline(parent());
+ }
+
+ canvas->set_guid(get_guid()^deriv_guid);
+
+ const_iterator iter;
+ for(iter=begin();iter!=end();++iter)
+ {
+ Layer::Handle layer((*iter)->clone(deriv_guid));
+ if(layer)
+ {
+ assert(layer.count()==1);
+ int presize(size());
+ canvas->push_back(layer);
+ if(!(layer.count()>1))
+ {
+ synfig::error("Canvas::clone(): Cloned layer insertion failure!");
+ synfig::error("Canvas::clone(): \tlayer.count()=%d",layer.count());
+ synfig::error("Canvas::clone(): \tlayer->get_name()=%s",layer->get_name().c_str());
+ synfig::error("Canvas::clone(): \tbefore size()=%d",presize);
+ synfig::error("Canvas::clone(): \tafter size()=%d",size());
+ }
+ assert(layer.count()>1);
+ }
+ else
+ {
+ synfig::error("Unable to clone layer");
+ }
+ }
+
+ canvas->signal_group_pair_removed().clear();
+ canvas->signal_group_pair_added().clear();
+
+ return canvas;
+}
+
+void
+Canvas::set_inline(LooseHandle parent)
+{
+ if(is_inline_ && parent_)
+ {
+
+ }
+
+ id_="inline";
+ is_inline_=true;
+ parent_=parent;
+
+ // Have the parent inherit all of the group stuff
+
+ std::map<String,std::set<etl::handle<Layer> > >::const_iterator iter;
+
+ for(iter=group_db_.begin();iter!=group_db_.end();++iter)
+ {
+ parent->group_db_[iter->first].insert(iter->second.begin(),iter->second.end());
+ }
+
+ rend_desc()=parent->rend_desc();
+}
+
+Canvas::Handle
+Canvas::create_inline(Handle parent)
+{
+ assert(parent);
+ //if(parent->is_inline())
+ // return create_inline(parent->parent());
+
+ Handle canvas(new Canvas("inline"));
+ canvas->set_inline(parent);
+ return canvas;
+}
+
+Canvas::Handle
+Canvas::new_child_canvas()
+{
+ if(is_inline() && parent_)
+ return parent_->new_child_canvas();
+// runtime_error("You cannot create a child Canvas in an inline Canvas");
+
+ // Create a new canvas
+ children().push_back(create());
+ Canvas::Handle canvas(children().back());
+
+ canvas->parent_=this;
+
+ canvas->rend_desc()=rend_desc();
+
+ return canvas;
+}
+
+Canvas::Handle
+Canvas::new_child_canvas(const String &id)
+{
+ if(is_inline() && parent_)
+ return parent_->new_child_canvas(id);
+// runtime_error("You cannot create a child Canvas in an inline Canvas");
+
+ // Create a new canvas
+ children().push_back(create());
+ Canvas::Handle canvas(children().back());
+
+ canvas->set_id(id);
+ canvas->parent_=this;
+ canvas->rend_desc()=rend_desc();
+
+ return canvas;
+}
+
+Canvas::Handle
+Canvas::add_child_canvas(Canvas::Handle child_canvas, const synfig::String& id)
+{
+ if(is_inline() && parent_)
+ return parent_->add_child_canvas(child_canvas,id);
+
+ if(child_canvas->parent() && !child_canvas->is_inline())
+ throw std::runtime_error("Cannot add child canvas because it belongs to someone else!");
+
+ if(!valid_id(id))
+ throw runtime_error("Invalid ID");
+
+ try
+ {
+ find_canvas(id);
+ throw Exception::IDAlreadyExists(id);
+ }
+ catch(Exception::IDNotFound)
+ {
+ if(child_canvas->is_inline())
+ child_canvas->is_inline_=false;
+ child_canvas->id_=id;
+ children().push_back(child_canvas);
+ child_canvas->parent_=this;
+ }
+
+ return child_canvas;
+}
+
+void
+Canvas::remove_child_canvas(Canvas::Handle child_canvas)
+{
+ if(is_inline() && parent_)
+ return parent_->remove_child_canvas(child_canvas);
+
+ if(child_canvas->parent_!=this)
+ throw runtime_error("Given child does not belong to me");
+
+ if(find(children().begin(),children().end(),child_canvas)==children().end())
+ throw Exception::IDNotFound(child_canvas->get_id());
+
+ children().remove(child_canvas);
+
+ child_canvas->parent_=0;
+}
+
+void
+Canvas::set_file_name(const String &file_name)
+{
+ if(parent())
+ parent()->set_file_name(file_name);
+ else
+ {
+ file_name_=file_name;
+ signal_file_name_changed_();
+ }
+}
+
+sigc::signal<void>&
+Canvas::signal_file_name_changed()
+{
+ if(parent())
+ return signal_file_name_changed();
+ else
+ return signal_file_name_changed_;
+}
+
+String
+Canvas::get_file_name()const
+{
+ if(parent())
+ return parent()->get_file_name();
+ return file_name_;
+}
+
+String
+Canvas::get_file_path()const
+{
+ if(parent())
+ return parent()->get_file_path();
+ return dirname(file_name_);
+}
+
+
+String
+Canvas::get_meta_data(const String& key)const
+{
+ if(!meta_data_.count(key))
+ return String();
+ return meta_data_.find(key)->second;
+}
+
+void
+Canvas::set_meta_data(const String& key, const String& data)
+{
+ if(meta_data_[key]!=data)
+ {
+ meta_data_[key]=data;
+ signal_meta_data_changed()(key);
+ signal_meta_data_changed(key)();
+ }
+}
+
+void
+Canvas::erase_meta_data(const String& key)
+{
+ if(meta_data_.count(key))
+ {
+ meta_data_.erase(key);
+ signal_meta_data_changed()(key);
+ signal_meta_data_changed(key)();
+ }
+}
+
+std::list<String>
+Canvas::get_meta_data_keys()const
+{
+ std::list<String> ret;
+
+ std::map<String,String>::const_iterator iter;
+
+ for(iter=meta_data_.begin();!(iter==meta_data_.end());++iter)
+ ret.push_back(iter->first);
+
+ return ret;
+}
+
+void
+synfig::optimize_layers(Context context, Canvas::Handle op_canvas, bool seen_motion_blur_in_parent)
+{
+ Context iter;
+
+ std::vector< std::pair<float,Layer::Handle> > sort_list;
+ int i, motion_blur_i=0; // motion_blur_i is for resolving which layer comes first in the event of a z_depth tie
+ float motion_blur_z_depth=0; // the z_depth of the least deep motion blur layer in this context
+ bool seen_motion_blur_locally = false;
+ bool motion_blurred; // the final result - is this layer blurred or not?
+
+ // If the parent didn't cause us to already be motion blurred,
+ // check whether there's a motion blur in this context,
+ // and if so, calculate its z_depth.
+ if (!seen_motion_blur_in_parent)
+ for(iter=context,i=0;*iter;iter++,i++)
+ {
+ Layer::Handle layer=*iter;
+
+ // If the layer isn't active, don't worry about it
+ if(!layer->active())
+ continue;
+
+ // Any layer with an amount of zero is implicitly disabled.
+ ValueBase value(layer->get_param("amount"));
+ if(value.get_type()==ValueBase::TYPE_REAL && value.get(Real())==0)
+ continue;
+
+ if(layer->get_name()=="MotionBlur")
+ {
+ float z_depth(layer->get_z_depth()*1.0001+i);
+
+ // If we've seen a motion blur before in this context...
+ if (seen_motion_blur_locally)
+ {
+ // ... then we're only interested in this one if it's less deep...
+ if (z_depth < motion_blur_z_depth)
+ {
+ motion_blur_z_depth = z_depth;
+ motion_blur_i = i;
+ }
+ }
+ // ... otherwise we're always interested in it.
+ else
+ {
+ motion_blur_z_depth = z_depth;
+ motion_blur_i = i;
+ seen_motion_blur_locally = true;
+ }
+ }
+ }
+
+ // Go ahead and start romping through the canvas to paste
+ for(iter=context,i=0;*iter;iter++,i++)
+ {
+ Layer::Handle layer=*iter;
+ float z_depth(layer->get_z_depth()*1.0001+i);
+
+ // If the layer isn't active, don't worry about it
+ if(!layer->active())
+ continue;
+
+ // Any layer with an amount of zero is implicitly disabled.
+ ValueBase value(layer->get_param("amount"));
+ if(value.get_type()==ValueBase::TYPE_REAL && value.get(Real())==0)
+ continue;
+
+ Layer_PasteCanvas* paste_canvas(static_cast<Layer_PasteCanvas*>(layer.get()));
+
+ // note: this used to include "&& paste_canvas->get_time_offset()==0", but then
+ // time-shifted layers weren't being sorted by z-depth (bug #1806852)
+ if(layer->get_name()=="PasteCanvas")
+ {
+ // we need to blur the sub canvas if:
+ // our parent is blurred,
+ // or the child is lower than a local blur,
+ // or the child is at the same z_depth as a local blur, but later in the context
+
+#if 0 // DEBUG
+ if (seen_motion_blur_in_parent) synfig::info("seen BLUR in parent\n");
+ else if (seen_motion_blur_locally)
+ if (z_depth > motion_blur_z_depth) synfig::info("paste is deeper than BLUR\n");
+ else if (z_depth == motion_blur_z_depth) { synfig::info("paste is same depth as BLUR\n");
+ if (i > motion_blur_i) synfig::info("paste is physically deeper than BLUR\n");
+ else synfig::info("paste is less physically deep than BLUR\n");
+ } else synfig::info("paste is less deep than BLUR\n");
+ else synfig::info("no BLUR at all\n");
+#endif // DEBUG
+
+ motion_blurred = (seen_motion_blur_in_parent ||
+ (seen_motion_blur_locally &&
+ (z_depth > motion_blur_z_depth ||
+ (z_depth == motion_blur_z_depth && i > motion_blur_i))));
+
+ Canvas::Handle sub_canvas(Canvas::create_inline(op_canvas));
+ Canvas::Handle paste_sub_canvas = paste_canvas->get_sub_canvas();
+ if(paste_sub_canvas)
+ optimize_layers(paste_sub_canvas->get_context(),sub_canvas,motion_blurred);
+//#define SYNFIG_OPTIMIZE_PASTE_CANVAS 1
+
+#ifdef SYNFIG_OPTIMIZE_PASTE_CANVAS
+ Canvas::iterator sub_iter;
+ // Determine if we can just remove the paste canvas
+ // altogether
+ if(paste_canvas->get_blend_method()==Color::BLEND_COMPOSITE && paste_canvas->get_amount()==1.0f && paste_canvas->get_zoom()==0 && paste_canvas->get_time_offset()==0 && paste_canvas->get_origin()==Point(0,0))
+ try{
+ for(sub_iter=sub_canvas->begin();sub_iter!=sub_canvas->end();++sub_iter)
+ {
+ Layer* layer=sub_iter->get();
+
+ // any layers that deform end up breaking things
+ // so do things the old way if we run into anything like this
+ if(!dynamic_cast<Layer_NoDeform*>(layer))
+ throw int();
+
+ ValueBase value(layer->get_param("blend_method"));
+ if(value.get_type()!=ValueBase::TYPE_INTEGER || value.get(int())!=(int)Color::BLEND_COMPOSITE)
+ throw int();
+ }
+
+ // It has turned out that we don't need a paste canvas
+ // layer, so just go ahead and add all the layers onto
+ // the current stack and be done with it
+ while(sub_canvas->size())
+ {
+ sort_list.push_back(std::pair<float,Layer::Handle>(z_depth,sub_canvas->front()));
+ //op_canvas->push_back_simple(sub_canvas->front());
+ sub_canvas->pop_front();
+ }
+ continue;
+ }catch(int) { }
+#endif
+ Layer::Handle new_layer(Layer::create("PasteCanvas"));
+ dynamic_cast<Layer_PasteCanvas*>(new_layer.get())->set_muck_with_time(false);
+ if (motion_blurred)
+ {
+ Layer::DynamicParamList dynamic_param_list(paste_canvas->dynamic_param_list());
+ for(Layer::DynamicParamList::const_iterator iter(dynamic_param_list.begin()); iter != dynamic_param_list.end(); ++iter)
+ new_layer->connect_dynamic_param(iter->first, iter->second);
+ }
+ Layer::ParamList param_list(paste_canvas->get_param_list());
+ //param_list.erase("canvas");
+ new_layer->set_param_list(param_list);
+ dynamic_cast<Layer_PasteCanvas*>(new_layer.get())->set_sub_canvas(sub_canvas);
+ dynamic_cast<Layer_PasteCanvas*>(new_layer.get())->set_muck_with_time(true);
+ layer=new_layer;
+ }
+
+ sort_list.push_back(std::pair<float,Layer::Handle>(z_depth,layer));
+ //op_canvas->push_back_simple(layer);
+ }
+
+ //sort_list.sort();
+ stable_sort(sort_list.begin(),sort_list.end());
+ std::vector< std::pair<float,Layer::Handle> >::iterator iter2;
+ for(iter2=sort_list.begin();iter2!=sort_list.end();++iter2)
+ op_canvas->push_back_simple(iter2->second);
+ op_canvas->op_flag_=true;
+}
+
+void
+Canvas::get_times_vfunc(Node::time_set &set) const
+{
+ const_iterator i = begin(),
+ iend = end();
+
+ for(; i != iend; ++i)
+ {
+ const Node::time_set &tset = (*i)->get_times();
+ set.insert(tset.begin(),tset.end());
+ }
+}
+
+std::set<etl::handle<Layer> >
+Canvas::get_layers_in_group(const String&group)
+{
+ if(is_inline() && parent_)
+ return parent_->get_layers_in_group(group);
+
+ if(group_db_.count(group)==0)
+ return std::set<etl::handle<Layer> >();
+ return group_db_.find(group)->second;
+}
+
+std::set<String>
+Canvas::get_groups()const
+{
+ if(is_inline() && parent_)
+ return parent_->get_groups();
+
+ std::set<String> ret;
+ std::map<String,std::set<etl::handle<Layer> > >::const_iterator iter;
+ for(iter=group_db_.begin();iter!=group_db_.end();++iter)
+ ret.insert(iter->first);
+ return ret;
+}
+
+int
+Canvas::get_group_count()const
+{
+ if(is_inline() && parent_)
+ return parent_->get_group_count();
+
+ return group_db_.size();
+}
+
+void
+Canvas::add_group_pair(String group, etl::handle<Layer> layer)
+{
+ group_db_[group].insert(layer);
+ if(group_db_[group].size()==1)
+ signal_group_added()(group);
+ else
+ signal_group_changed()(group);
+
+ signal_group_pair_added()(group,layer);
+
+ if(is_inline() && parent_)
+ return parent_->add_group_pair(group,layer);
+}
+
+void
+Canvas::remove_group_pair(String group, etl::handle<Layer> layer)
+{
+ group_db_[group].erase(layer);
+
+ signal_group_pair_removed()(group,layer);
+
+ if(group_db_[group].empty())
+ {
+ group_db_.erase(group);
+ signal_group_removed()(group);
+ }
+ else
+ signal_group_changed()(group);
+
+ if(is_inline() && parent_)
+ return parent_->remove_group_pair(group,layer);
+}
+
+void
+Canvas::add_connection(Layer::LooseHandle layer, sigc::connection connection)
+{
+ connections_[layer].push_back(connection);
+}
+
+void
+Canvas::disconnect_connections(Layer::LooseHandle layer)
+{
+ std::vector<sigc::connection>::iterator iter;
+ for(iter=connections_[layer].begin();iter!=connections_[layer].end();++iter)
+ iter->disconnect();
+ connections_[layer].clear();
+}
+
+void
+Canvas::rename_group(const String&old_name,const String&new_name)
+{
+ if(is_inline() && parent_)
+ return parent_->rename_group(old_name,new_name);
+
+ {
+ std::map<String,std::set<etl::handle<Layer> > >::iterator iter;
+ iter=group_db_.find(old_name);
+ if(iter!=group_db_.end())
+ for(++iter;iter!=group_db_.end() && iter->first.find(old_name)==0;iter=group_db_.find(old_name),++iter)
+ {
+ String name(iter->first,old_name.size(),String::npos);
+ name=new_name+name;
+ rename_group(iter->first,name);
+ }
+ }
+
+ std::set<etl::handle<Layer> > layers(get_layers_in_group(old_name));
+ std::set<etl::handle<Layer> >::iterator iter;
+
+ for(iter=layers.begin();iter!=layers.end();++iter)
+ {
+ (*iter)->remove_from_group(old_name);
+ (*iter)->add_to_group(new_name);
+ }
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file canvas.h
+** \brief Canvas Class Implementation
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_CANVAS_H
+#define __SYNFIG_CANVAS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <map>
+#include <list>
+#include <ETL/handle>
+#include <sigc++/signal.h>
+#include <sigc++/connection.h>
+
+#include "vector.h"
+#include "string.h"
+#include "canvasbase.h"
+#include "valuenode.h"
+#include "keyframe.h"
+#include "renddesc.h"
+#include "node.h"
+#include "guid.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Context;
+class GUID;
+
+/*! \class Canvas
+** \todo writeme
+*/
+class Canvas : public CanvasBase, public Node
+{
+ /*
+ -- ** -- T Y P E S -----------------------------------------------------------
+ */
+
+public:
+ typedef etl::handle<Canvas> Handle;
+ typedef etl::loose_handle<Canvas> LooseHandle;
+ typedef etl::handle<const Canvas> ConstHandle;
+
+ typedef std::list<Handle> Children;
+
+ friend void synfig::optimize_layers(Context, Canvas::Handle, bool seen_motion_blur);
+
+ /*
+ -- ** -- D A T A -------------------------------------------------------------
+ */
+
+private:
+
+ //! Contains the ID string for the Canvas
+ /*! \see get_id(), set_id() */
+ String id_;
+
+ //! Contains the name of the Canvas
+ /*! \see set_name(), get_name() */
+ String name_;
+
+ //! Contains a description of the Canvas
+ /*! \see set_description(), get_description() */
+ String description_;
+
+ //! Contains the author's name
+ /*! \see set_author(), get_author() */
+ String author_;
+
+ //! Contains the author's email address
+ /*! \todo This private parameter has no binding, so it's unusable at the moment */
+ String email_;
+
+ //! File name of Canvas
+ /*! \see get_file_name(), set_file_name() */
+ String file_name_;
+
+ //! Metadata map for Canvas.
+ /*! \see get_meta_data(), set_meta_data(), erase_meta_data() */
+ std::map<String, String> meta_data_;
+
+ //! Contains a list of ValueNodes that are in this Canvas
+ /*! \see value_node_list(), find_value_node() */
+ ValueNodeList value_node_list_;
+
+ //! \writeme
+ KeyframeList keyframe_list_;
+
+ //! A handle to the parent canvas of this canvas.
+ /*! If canvas is a root canvas, then this handle is empty
+ ** \see parent()
+ */
+ LooseHandle parent_;
+
+ //! List containing any child Canvases
+ /*! \see children() */
+ Children children_;
+
+ //! Render Description for Canvas
+ /*! \see rend_desc() */
+ RendDesc desc_;
+
+ //! Contains the value of the last call to set_time()
+ Time cur_time_;
+
+ //! \writeme
+ mutable std::map<String,Handle> externals_;
+
+ //! This flag is set if this canvas is "inline"
+ bool is_inline_;
+
+ mutable bool is_dirty_;
+
+ bool op_flag_;
+
+ //! Layer Group database
+ std::map<String,std::set<etl::handle<Layer> > > group_db_;
+
+ //! Layer Connection database
+ std::map<etl::loose_handle<Layer>,std::vector<sigc::connection> > connections_;
+
+ /*
+ -- ** -- S I G N A L S -------------------------------------------------------
+ */
+
+private:
+
+ //! Group Added
+ sigc::signal<void,String> signal_group_added_;
+
+ //! Group Removed
+ sigc::signal<void,String> signal_group_removed_;
+
+ //! Group Changed
+ sigc::signal<void,String> signal_group_changed_;
+
+ sigc::signal<void,String,etl::handle<synfig::Layer> > signal_group_pair_added_;
+ sigc::signal<void,String,etl::handle<synfig::Layer> > signal_group_pair_removed_;
+
+ //! Layers Reordered
+ sigc::signal<void,int*> signal_layers_reordered_;
+
+ //! RendDesc Changed
+ sigc::signal<void> signal_rend_desc_changed_;
+
+ //! ID Changed
+ sigc::signal<void> signal_id_changed_;
+
+ //! Dirty
+ //sigc::signal<void> signal_dirty_;
+
+ //! FileName Changed
+ sigc::signal<void> signal_file_name_changed_;
+
+ //! Metadata Changed
+ sigc::signal<void, String> signal_meta_data_changed_;
+
+ //! Key-Specific meta data changed signals
+ std::map<String, sigc::signal<void> > signal_map_meta_data_changed_;
+
+
+ //! ValueBasenode Changed
+ sigc::signal<void, etl::handle<ValueNode> > signal_value_node_changed_;
+
+ sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> > signal_value_node_child_added_;
+
+ sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> > signal_value_node_child_removed_;
+
+ /*
+ -- ** -- S I G N A L I N T E R F A C E -------------------------------------
+ */
+
+public:
+
+ sigc::signal<void,String,etl::handle<synfig::Layer> >& signal_group_pair_added() { return signal_group_pair_added_; }
+ sigc::signal<void,String,etl::handle<synfig::Layer> >& signal_group_pair_removed() { return signal_group_pair_removed_; }
+
+ //! Group Added
+ sigc::signal<void,String>& signal_group_added() { return signal_group_added_; }
+
+ //! Group Removed
+ sigc::signal<void,String>& signal_group_removed() { return signal_group_removed_; }
+
+ //! Group Changed
+ sigc::signal<void,String>& signal_group_changed() { return signal_group_changed_; }
+
+ //! Layers Reordered
+ sigc::signal<void,int*>& signal_layers_reordered() { return signal_layers_reordered_; }
+
+ //! RendDesc Changed
+ sigc::signal<void>& signal_rend_desc_changed() { return signal_rend_desc_changed_; }
+
+ //! ID Changed
+ sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
+
+ //! File name Changed
+ sigc::signal<void>& signal_file_name_changed();
+
+ //! Metadata Changed
+ sigc::signal<void, String>& signal_meta_data_changed() { return signal_meta_data_changed_; }
+
+ //! Metadata Changed
+ sigc::signal<void>& signal_meta_data_changed(const String& key) { return signal_map_meta_data_changed_[key]; }
+
+
+ sigc::signal<void, etl::handle<ValueNode> >& signal_value_node_changed() { return signal_value_node_changed_; }
+
+ //! Dirty
+ sigc::signal<void>& signal_dirty() { return signal_changed(); }
+
+ //! \writeme
+ sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> >& signal_value_node_child_added() { return signal_value_node_child_added_; }
+
+ //! \writeme
+ sigc::signal<void, etl::handle<ValueNode>, etl::handle<ValueNode> >& signal_value_node_child_removed() { return signal_value_node_child_removed_; }
+
+ /*
+ -- ** -- C O N S T R U C T O R S ---------------------------------------------
+ */
+
+protected:
+
+ Canvas(const String &name);
+
+public:
+
+ ~Canvas();
+
+ /*
+ -- ** -- M E M B E R F U N C T I O N S -------------------------------------
+ */
+
+public:
+
+ //! Returns the set of layers in group
+ std::set<etl::handle<Layer> > get_layers_in_group(const String&group);
+
+ //! Gets all the groups
+ std::set<String> get_groups()const;
+
+ //! Gets the number of groups in this canvas
+ int get_group_count()const;
+
+ //! Renames the given group
+ void rename_group(const String&old_name,const String&new_name);
+
+ //! \writeme
+ bool is_inline()const { return is_inline_; }
+
+ //! Returns a handle to the RendDesc for this Canvas
+ RendDesc &rend_desc() { return desc_; }
+
+ //! Returns a handle to the RendDesc for this Canvas
+ const RendDesc &rend_desc()const { return desc_; }
+
+ //! Gets the name of the canvas
+ const String & get_name()const { return name_; }
+
+ //! Sets the name of the canvas
+ void set_name(const String &x);
+
+ //! Gets the author of the canvas
+ const String & get_author()const { return author_; }
+
+ //! Sets the author of the canvas
+ void set_author(const String &x);
+
+ //! Gets the description of the canvas
+ const String & get_description()const { return description_; }
+
+ //! Sets the name of the canvas
+ void set_description(const String &x);
+
+ //! Gets the ID of the canvas
+ const String & get_id()const { return id_; }
+
+ //! Sets the ID of the canvas
+ void set_id(const String &x);
+
+ //! Returns the data string for the given meta data key
+ String get_meta_data(const String& key)const;
+
+ //! Returns a list of meta data keys
+ std::list<String> get_meta_data_keys()const;
+
+ //! Sets a meta data key to a specific string
+ void set_meta_data(const String& key, const String& data);
+
+ //! Removes a meta data key
+ void erase_meta_data(const String& key);
+
+ //! \writeme
+ String get_relative_id(etl::loose_handle<const Canvas> x)const;
+
+ //! \internal \writeme
+ String _get_relative_id(etl::loose_handle<const Canvas> x)const;
+
+ //! Returns \c true if the Canvas is a root Canvas. \c false otherwise
+ bool is_root()const { return !parent_; }
+
+ //! Returns a handle to the parent Canvas.
+ /*! The returned handle will be empty if this is a root canvas */
+ LooseHandle parent()const { return parent_; }
+
+ LooseHandle get_root()const;
+
+ //! Returns a list of all child canvases in this canvas
+ std::list<Handle> &children() { return children_; }
+
+ //! Returns a list of all child canvases in this canvas
+ const std::list<Handle> &children()const { return children_; }
+
+ //! Gets the color at the specified point
+ //Color get_color(const Point &pos)const;
+
+ //! Sets the time for all the layers in the canvas
+ void set_time(Time t)const;
+
+ //! \writeme
+ Time get_time()const { return cur_time_; }
+
+ //! Returns the number of layers in the canvas
+ int size()const;
+
+ //! Removes all the layers from the canvas
+ void clear();
+
+ //! Returns true if the canvas has no layers
+ bool empty()const;
+
+ //! Returns a reference to the ValueNodeList for this Canvas
+ // ValueNodeList &value_node_list() { return value_node_list_; }
+
+ //! Returns a reference to the ValueNodeList for this Canvas
+ const ValueNodeList &value_node_list()const;
+
+ //! Returns a reference to the KeyframeList for this Canvas
+ KeyframeList &keyframe_list();
+
+ //! Returns a reference to the KeyframeList for this Canvas
+ const KeyframeList &keyframe_list()const;
+
+ //! Finds the ValueNode in the Canvas with the given \a id
+ /*! \return If found, returns a handle to the ValueNode.
+ ** Otherwise, returns an empty handle.
+ */
+ ValueNode::Handle find_value_node(const String &id);
+
+ //! \internal \writeme
+ ValueNode::Handle surefind_value_node(const String &id);
+
+ //! Finds the ValueNode in the Canvas with the given \a id
+ /*! \return If found, returns a handle to the ValueNode.
+ ** Otherwise, returns an empty handle.
+ */
+ ValueNode::ConstHandle find_value_node(const String &id)const;
+
+ //! \writeme
+ void add_value_node(ValueNode::Handle x, const String &id);
+
+ //! writeme
+ //void rename_value_node(ValueNode::Handle x, const String &id);
+
+ //! \writeme
+ void remove_value_node(ValueNode::Handle x);
+
+ //! \writeme
+ void remove_value_node(const String &id) { remove_value_node(find_value_node(id)); }
+
+ //! Finds a child Canvas in the Canvas with the given \a name
+ /*! \return If found, returns a handle to the child Canvas.
+ ** If not found, it creates a new Canvas and returns it
+ ** If an error occurs, it returns an empty handle
+ */
+ Handle surefind_canvas(const String &id);
+
+ //! Finds a child Canvas in the Canvas with the given \a id
+ /*! \return If found, returns a handle to the child Canvas.
+ ** Otherwise, returns an empty handle.
+ */
+ Handle find_canvas(const String &id);
+
+ //! Finds a child Canvas in the Canvas with the given \a id
+ /*! \return If found, returns a handle to the child Canvas.
+ ** Otherwise, returns an empty handle.
+ */
+ ConstHandle find_canvas(const String &id)const;
+
+ //! Sets the file path for the Canvas
+ //void set_file_path(const String &);
+
+ //! Returns the file path from the file name
+ String get_file_path()const;
+
+ //! Sets the filename (with path)
+ void set_file_name(const String &);
+
+ //! Gets the filename (with path)
+ String get_file_name()const;
+
+ //! Creates a new child canvas, and returns its handle
+ Handle new_child_canvas();
+
+ //! Creates a new child canvas with an ID of \a id, and returns its handle
+ Handle new_child_canvas(const String &id);
+
+ //! Adds the given canvas as a child
+ Handle add_child_canvas(Handle child_canvas, const String &id);
+
+ void remove_child_canvas(Handle child_canvas);
+
+ etl::handle<Layer> find_layer(const Point &pos);
+
+ int get_depth(etl::handle<Layer>)const;
+
+ Context get_context()const;
+
+ iterator end();
+
+ const_iterator end()const;
+
+ reverse_iterator rbegin();
+
+ const_reverse_iterator rbegin()const;
+
+ etl::handle<Layer> &back();
+
+ void push_back(etl::handle<Layer> x);
+
+ void push_front(etl::handle<Layer> x);
+
+ void push_back_simple(etl::handle<Layer> x);
+
+ void insert(iterator iter,etl::handle<Layer> x);
+ void erase(iterator iter);
+
+ const etl::handle<Layer> &back()const;
+
+ void set_inline(LooseHandle parent);
+
+ static Handle create();
+
+ static Handle create_inline(Handle parent);
+
+ Handle clone(const GUID& deriv_guid=GUID())const;
+
+private:
+ void add_group_pair(String group, etl::handle<Layer> layer);
+ void remove_group_pair(String group, etl::handle<Layer> layer);
+ void add_connection(etl::loose_handle<Layer> layer, sigc::connection connection);
+ void disconnect_connections(etl::loose_handle<Layer> layer);
+
+protected:
+ virtual void on_changed();
+ virtual void get_times_vfunc(Node::time_set &set) const;
+}; // END of class Canvas
+
+void optimize_layers(Context context, Canvas::Handle op_canvas, bool seen_motion_blur=false);
+
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file canvasbase.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_CANVASBASE_H
+#define __SYNFIG_CANVASBASE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <deque>
+#include <ETL/handle>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+namespace synfig {
+
+class Layer;
+
+typedef std::deque< etl::handle< Layer > > CanvasBase;
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file color.cpp
+** \brief Color Class
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ETL/angle>
+#include "color.h"
+#include <cstdio>
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+
+#endif
+
+using namespace synfig;
+using namespace etl;
+using namespace std;
+
+/* === M A C R O S ========================================================= */
+
+#define COLOR_EPSILON (0.000001f)
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+
+
+ColorReal
+Color::hex2real(String s)
+{
+ std::istringstream i(s);
+ int n;
+ i.fill('0');
+ if (!(i >> hex >> n))
+ throw String("bad conversion from hex string \"") + s + String("\"");
+ return n / 255.0f;
+}
+
+const String
+Color::real2hex(ColorReal c)
+{
+ std::ostringstream o;
+ o.width(2);
+ o.fill('0');
+ if (c<0) c = 0;
+ if (c>1) c = 1;
+ o << hex << int(c*255.0f);
+ return o.str();
+}
+
+void
+Color::set_hex(String& hex)
+{
+ value_type r, g, b;
+ try
+ {
+ if (hex.size() == 1)
+ {
+ r = hex2real(hex.substr(0,1)+hex.substr(0,1));
+ r_ = g_ = b_ = r;
+ }
+ else if (hex.size() == 3)
+ {
+ r = hex2real(hex.substr(0,1)+hex.substr(0,1));
+ g = hex2real(hex.substr(1,1)+hex.substr(1,1));
+ b = hex2real(hex.substr(2,1)+hex.substr(2,1));
+ r_ = r; g_ = g; b_ = b;
+ }
+ else if (hex.size() == 6)
+ {
+ r = hex2real(hex.substr(0,2));
+ g = hex2real(hex.substr(2,2));
+ b = hex2real(hex.substr(4,2));
+ r_ = r; g_ = g; b_ = b;
+ }
+ }
+ catch (string s)
+ {
+ printf("caught <%s>\n", s.c_str());
+ return;
+ }
+}
+
+const String
+Color::get_string(void)const
+{
+ std::ostringstream o;
+ o << std::fixed << std::setprecision(3) << "#" << get_hex() << " : " << std::setw(6) << a_;
+ return String(o.str().c_str());
+}
+
+#if 0
+Color&
+Color::rotate_uv(const Angle& theta)const
+{
+/*/
+ Color ret(*this);
+ ret.set_hue(ret.get_hue()+theta);
+ return ret;
+/*/
+ const float
+ a(angle::sin(theta).get()),
+ b(angle::cos(theta).get());
+ const float
+ u(get_u()),
+ v(get_v());
+
+ return set_uv(b*u-a*v,a*u+b*v);
+ //return YUV(get_y(),b*u-a*v,a*u+b*v,get_a());
+//*/
+}
+#endif
+
+Color
+Color::clamped_negative()const
+{
+ Color ret=*this;
+
+ if(ret.a_==0)
+ return alpha();
+
+ if(ret.a_<0)
+ ret=-ret;
+
+ if(ret.r_<0)
+ {
+ ret.g_-=ret.r_;
+ ret.b_-=ret.r_;
+ ret.r_=0.0f;
+ }
+ if(ret.g_<0)
+ {
+ ret.r_-=ret.g_;
+ ret.b_-=ret.g_;
+ ret.g_=0.0f;
+ }
+ if(ret.b_<0)
+ {
+ ret.r_-=ret.b_;
+ ret.g_-=ret.b_;
+ ret.b_=0.0f;
+ }
+
+ if(ret.r_>1) ret.r_=1;
+ if(ret.g_>1) ret.g_=1;
+ if(ret.b_>1) ret.b_=1;
+ if(ret.a_>1) ret.a_=1;
+
+ if(isnan(ret.get_r())) ret.r_=0.5;
+ if(isnan(ret.get_g())) ret.g_=0.5;
+ if(isnan(ret.get_b())) ret.b_=0.5;
+ if(isnan(ret.get_a())) ret.a_=1;
+
+/*
+ if(ret.r_>1) { ret.g_/=ret.r_; ret.b_/=ret.r_; ret.r_=1; }
+ if(ret.g_>1) { ret.r_/=ret.g_; ret.b_/=ret.g_; ret.g_=1; }
+ if(ret.b_>1) { ret.g_/=ret.b_; ret.r_/=ret.b_; ret.b_=1; }
+ if(ret.a_>1) ret.a_=1;
+*/
+
+ return ret;
+}
+
+Color
+Color::clamped()const
+{
+ Color ret(*this);
+ if(ret.get_r()<0)
+ ret.set_r(0);
+ if(ret.get_g()<0)
+ ret.set_g(0);
+ if(ret.get_b()<0)
+ ret.set_b(0);
+ if(ret.get_a()<0)
+ ret.set_a(0);
+
+ if(ret.r_>1) ret.r_=1;
+ if(ret.g_>1) ret.g_=1;
+ if(ret.b_>1) ret.b_=1;
+ if(ret.a_>1) ret.a_=1;
+
+ if(isnan(ret.get_r())) ret.r_=0.5;
+ if(isnan(ret.get_g())) ret.g_=0.5;
+ if(isnan(ret.get_b())) ret.b_=0.5;
+ if(isnan(ret.get_a())) ret.a_=1;
+
+ return(ret);
+}
+
+typedef Color (*blendfunc)(Color &,Color &,float);
+
+static Color
+blendfunc_COMPOSITE(Color &src,Color &dest,float amount)
+{
+ //c_dest'=c_src+(1.0-a_src)*c_dest
+ //a_dest'=a_src+(1.0-a_src)*a_dest
+
+ float a_src=src.get_a()*amount;
+ float a_dest=dest.get_a();
+
+ // if a_arc==0.0
+ //if(fabsf(a_src)<COLOR_EPSILON) return dest;
+
+ // Scale the source and destination by their alpha values
+ src*=a_src;
+ dest*=a_dest;
+
+ dest=src + dest*(1.0f-a_src);
+
+ a_dest=a_src + a_dest*(1.0f-a_src);
+
+ // if a_dest!=0.0
+ if(fabsf(a_dest)>COLOR_EPSILON)
+ {
+ dest/=a_dest;
+ dest.set_a(a_dest);
+ }
+ else
+ {
+ dest=Color::alpha();
+ }
+ assert(dest.is_valid());
+ return dest;
+}
+
+static Color
+blendfunc_STRAIGHT(Color &src,Color &bg,float amount)
+{
+ //a_out'=(a_src-a_bg)*amount+a_bg
+ //c_out'=(((c_src*a_src)-(c_bg*a_bg))*amount+(c_bg*a_bg))/a_out'
+
+ // ie: if(amount==1.0)
+ //if(fabsf(amount-1.0f)<COLOR_EPSILON)return src;
+
+ Color out;
+
+ float a_out((src.get_a()-bg.get_a())*amount+bg.get_a());
+
+ // if a_out!=0.0
+ if(fabsf(a_out)>COLOR_EPSILON)
+// if(a_out>COLOR_EPSILON || a_out<-COLOR_EPSILON)
+ {
+ out=((src*src.get_a()-bg*bg.get_a())*amount+bg*bg.get_a())/a_out;
+ out.set_a(a_out);
+ }
+ else
+ out=Color::alpha();
+
+ assert(out.is_valid());
+ return out;
+}
+
+static Color
+blendfunc_ONTO(Color &a,Color &b,float amount)
+{
+ float alpha(b.get_a());
+ return blendfunc_COMPOSITE(a,b.set_a(1.0f),amount).set_a(alpha);
+}
+
+static Color
+blendfunc_STRAIGHT_ONTO(Color &a,Color &b,float amount)
+{
+ a.set_a(a.get_a()*b.get_a());
+ return blendfunc_STRAIGHT(a,b,amount);
+}
+
+static Color
+blendfunc_BRIGHTEN(Color &a,Color &b,float amount)
+{
+ const float alpha(a.get_a()*amount);
+
+ if(b.get_r()<a.get_r()*alpha)
+ b.set_r(a.get_r()*alpha);
+
+ if(b.get_g()<a.get_g()*alpha)
+ b.set_g(a.get_g()*alpha);
+
+ if(b.get_b()<a.get_b()*alpha)
+ b.set_b(a.get_b()*alpha);
+
+ return b;
+}
+
+static Color
+blendfunc_DARKEN(Color &a,Color &b,float amount)
+{
+ const float alpha(a.get_a()*amount);
+
+ if(b.get_r()>(a.get_r()-1.0f)*alpha+1.0f)
+ b.set_r((a.get_r()-1.0f)*alpha+1.0f);
+
+ if(b.get_g()>(a.get_g()-1.0f)*alpha+1.0f)
+ b.set_g((a.get_g()-1.0f)*alpha+1.0f);
+
+ if(b.get_b()>(a.get_b()-1.0f)*alpha+1.0f)
+ b.set_b((a.get_b()-1.0f)*alpha+1.0f);
+
+
+ return b;
+}
+
+static Color
+blendfunc_ADD(Color &a,Color &b,float amount)
+{
+ const float alpha(a.get_a()*amount);
+
+ b.set_r(b.get_r()+a.get_r()*alpha);
+ b.set_g(b.get_g()+a.get_g()*alpha);
+ b.set_b(b.get_b()+a.get_b()*alpha);
+
+ return b;
+}
+
+static Color
+blendfunc_SUBTRACT(Color &a,Color &b,float amount)
+{
+ const float alpha(a.get_a()*amount);
+
+ b.set_r(b.get_r()-a.get_r()*alpha);
+ b.set_g(b.get_g()-a.get_g()*alpha);
+ b.set_b(b.get_b()-a.get_b()*alpha);
+
+ return b;
+}
+
+static Color
+blendfunc_DIFFERENCE(Color &a,Color &b,float amount)
+{
+ const float alpha(a.get_a()*amount);
+
+ b.set_r(abs(b.get_r()-a.get_r()*alpha));
+ b.set_g(abs(b.get_g()-a.get_g()*alpha));
+ b.set_b(abs(b.get_b()-a.get_b()*alpha));
+
+ return b;
+}
+
+static Color
+blendfunc_MULTIPLY(Color &a,Color &b,float amount)
+{
+ if(amount<0) a=~a, amount=-amount;
+
+ amount*=a.get_a();
+ b.set_r(((b.get_r()*a.get_r())-b.get_r())*(amount)+b.get_r());
+ b.set_g(((b.get_g()*a.get_g())-b.get_g())*(amount)+b.get_g());
+ b.set_b(((b.get_b()*a.get_b())-b.get_b())*(amount)+b.get_b());
+ return b;
+}
+
+static Color
+blendfunc_DIVIDE(Color &a,Color &b,float amount)
+{
+ amount*=a.get_a();
+
+ // We add COLOR_EPSILON in order to avoid a divide-by-zero condition.
+ // This causes DIVIDE to bias toward positive values, but the effect is
+ // really negligible. There is a reason why we use COLOR_EPSILON--we
+ // want the change to be imperceptable.
+
+ b.set_r(((b.get_r()/(a.get_r()+COLOR_EPSILON))-b.get_r())*(amount)+b.get_r());
+ b.set_g(((b.get_g()/(a.get_g()+COLOR_EPSILON))-b.get_g())*(amount)+b.get_g());
+ b.set_b(((b.get_b()/(a.get_b()+COLOR_EPSILON))-b.get_b())*(amount)+b.get_b());
+
+ return b;
+}
+
+static Color
+blendfunc_COLOR(Color &a,Color &b,float amount)
+{
+ Color temp(b);
+ temp.set_uv(a.get_u(),a.get_v());
+ return (temp-b)*amount*a.get_a()+b;
+}
+
+static Color
+blendfunc_HUE(Color &a,Color &b,float amount)
+{
+ Color temp(b);
+ temp.set_hue(a.get_hue());
+ return (temp-b)*amount*a.get_a()+b;
+}
+
+static Color
+blendfunc_SATURATION(Color &a,Color &b,float amount)
+{
+ Color temp(b);
+ temp.set_s(a.get_s());
+ return (temp-b)*amount*a.get_a()+b;
+}
+
+static Color
+blendfunc_LUMINANCE(Color &a,Color &b,float amount)
+{
+ Color temp(b);
+ temp.set_y(a.get_y());
+ return (temp-b)*amount*a.get_a()+b;
+}
+
+static Color
+blendfunc_BEHIND(Color &a,Color &b,float amount)
+{
+ if(a.get_a()==0)a.set_a(COLOR_EPSILON); //!< \hack
+ a.set_a(a.get_a()*amount);
+ return blendfunc_COMPOSITE(b,a,1.0);
+}
+
+static Color
+blendfunc_ALPHA_BRIGHTEN(Color &a,Color &b,float amount)
+{
+ if(a.get_a()<b.get_a()*amount)
+ return a.set_a(a.get_a()*amount);
+ return b;
+}
+
+static Color
+blendfunc_ALPHA_DARKEN(Color &a,Color &b,float amount)
+{
+ if(a.get_a()*amount>b.get_a())
+ return a.set_a(a.get_a()*amount);
+ return b;
+}
+
+static Color
+blendfunc_SCREEN(Color &a,Color &b,float amount)
+{
+ if(amount<0) a=~a, amount=-amount;
+
+ a.set_r(1.0-(1.0f-a.get_r())*(1.0f-b.get_r()));
+ a.set_g(1.0-(1.0f-a.get_g())*(1.0f-b.get_g()));
+ a.set_b(1.0-(1.0f-a.get_b())*(1.0f-b.get_b()));
+
+ return blendfunc_ONTO(a,b,amount);
+}
+
+static Color
+blendfunc_OVERLAY(Color &a,Color &b,float amount)
+{
+ if(amount<0) a=~a, amount=-amount;
+
+ Color rm;
+ rm.set_r(b.get_r()*a.get_r());
+ rm.set_g(b.get_g()*a.get_g());
+ rm.set_b(b.get_b()*a.get_b());
+
+ Color rs;
+ rs.set_r(1.0-(1.0f-a.get_r())*(1.0f-b.get_r()));
+ rs.set_g(1.0-(1.0f-a.get_g())*(1.0f-b.get_g()));
+ rs.set_b(1.0-(1.0f-a.get_b())*(1.0f-b.get_b()));
+
+ Color& ret(a);
+
+ ret.set_r(a.get_r()*rs.get_r() + (1.0-a.get_r())*rm.get_r());
+ ret.set_g(a.get_g()*rs.get_g() + (1.0-a.get_g())*rm.get_g());
+ ret.set_b(a.get_b()*rs.get_b() + (1.0-a.get_b())*rm.get_b());
+
+ return blendfunc_ONTO(ret,b,amount);
+}
+
+static Color
+blendfunc_HARD_LIGHT(Color &a,Color &b,float amount)
+{
+ if(amount<0) a=~a, amount=-amount;
+
+ if(a.get_r()>0.5f) a.set_r(1.0-(1.0f-(a.get_r()*2.0f-1.0f))*(1.0f-b.get_r()));
+ else a.set_r(b.get_r()*(a.get_r()*2.0f));
+ if(a.get_g()>0.5f) a.set_g(1.0-(1.0f-(a.get_g()*2.0f-1.0f))*(1.0f-b.get_g()));
+ else a.set_g(b.get_g()*(a.get_g()*2.0f));
+ if(a.get_b()>0.5f) a.set_b(1.0-(1.0f-(a.get_b()*2.0f-1.0f))*(1.0f-b.get_b()));
+ else a.set_b(b.get_b()*(a.get_b()*2.0f));
+
+ return blendfunc_ONTO(a,b,amount);
+}
+
+static Color
+blendfunc_ALPHA_OVER(Color &a,Color &b,float amount)
+{
+ Color rm(b);
+
+ //multiply the inverse alpha channel with the one below us
+ rm.set_a((1-a.get_a())*b.get_a());
+
+ return blendfunc_STRAIGHT(rm,b,amount);
+}
+
+
+Color
+Color::blend(Color a, Color b,float amount, Color::BlendMethod type)
+{
+#if 0
+ if(isnan(a.get_r()) || isnan(a.get_g()) || isnan(a.get_b()))
+ {
+#ifdef _DEBUG
+ a=magenta().set_a(a.get_a());
+#else
+ a=black().set_a(a.get_a());
+#endif
+ }
+
+ if(isnan(b.get_r()) || isnan(b.get_g()) || isnan(b.get_b()))
+ {
+#ifdef _DEBUG
+ b=magenta().set_a(b.get_a());
+#else
+ b=black().set_a(b.get_a());
+#endif
+ }
+#endif
+
+/*
+ if(!a.is_valid()&&b.is_valid())
+ return b;
+
+ if(a.is_valid()&&!b.is_valid())
+ return a;
+
+ if(!a.is_valid()||!b.is_valid())
+ {
+#ifdef _DEBUG
+ return magenta();
+#else
+ return black();
+#endif
+ }
+*/
+
+ // No matter what blend method is being used,
+ // if the amount is equal to zero, then only B
+ // will shine through
+ if(fabsf(amount)<=COLOR_EPSILON)return b;
+
+ assert(type<BLEND_END);
+
+ const static blendfunc vtable[BLEND_END]=
+ {
+ blendfunc_COMPOSITE,
+ blendfunc_STRAIGHT,
+ blendfunc_BRIGHTEN,
+ blendfunc_DARKEN,
+ blendfunc_ADD,
+ blendfunc_SUBTRACT,
+ blendfunc_MULTIPLY,
+ blendfunc_DIVIDE,
+ blendfunc_COLOR,
+ blendfunc_HUE,
+ blendfunc_SATURATION,
+ blendfunc_LUMINANCE,
+ blendfunc_BEHIND,
+ blendfunc_ONTO,
+ blendfunc_ALPHA_BRIGHTEN,
+ blendfunc_ALPHA_DARKEN,
+ blendfunc_SCREEN,
+ blendfunc_HARD_LIGHT,
+ blendfunc_DIFFERENCE,
+ blendfunc_ALPHA_OVER,
+ blendfunc_OVERLAY,
+ blendfunc_STRAIGHT_ONTO,
+ };
+
+ return vtable[type](a,b,amount);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file color.h
+** \brief Color Class Implementation
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_COLOR_H
+#define __SYNFIG_COLOR_H
+
+/* === H E A D E R S ======================================================= */
+
+
+//#include <cmath>
+#include <math.h>
+#include <cassert>
+#include "gamma.h"
+#include <synfig/string.h>
+
+#ifdef USE_HALF_TYPE
+#include <OpenEXR/half.h>
+#endif
+
+#ifndef SYNFIG_NO_ANGLE
+# include "angle.h"
+#endif
+
+/* === M A C R O S ========================================================= */
+
+#define use_colorspace_gamma() App::use_colorspace_gamma
+#define colorspace_gamma() (2.2f)
+#define gamma_in(x) ((x>=0) ? pow((float)x,1.0f/colorspace_gamma()) : -pow((float)-x,1.0f/colorspace_gamma()))
+#define gamma_out(x) ((x>=0) ? pow((float)x, colorspace_gamma()) : -pow((float)-x, colorspace_gamma()))
+
+#ifdef WIN32
+#include <float.h>
+#ifndef isnan
+extern "C" { int _isnan(double x); }
+#define isnan _isnan
+#endif
+#endif
+
+// For some reason isnan() isn't working on macosx any more.
+// This is a quick fix.
+#if defined(__APPLE__) && !defined(SYNFIG_ISNAN_FIX)
+#ifdef isnan
+#undef isnan
+#endif
+inline bool isnan(double x) { return x != x; }
+inline bool isnan(float x) { return x != x; }
+#define SYNFIG_ISNAN_FIX 1
+#endif
+
+namespace synfig {
+
+#ifdef USE_HALF_TYPE
+typedef half ColorReal;
+#else
+typedef float ColorReal;
+#endif
+
+static const float EncodeYUV[3][3]=
+{
+ { 0.299f, 0.587f, 0.114f },
+ { -0.168736f, -0.331264f, 0.5f },
+ { 0.5f, -0.418688f, -0.081312f }
+};
+
+static const float DecodeYUV[3][3]=
+{
+ { 1.0f, 0.0f, 1.402f },
+ { 1.0f, -0.344136f, -0.714136f },
+ { 1.0f, 1.772f, 0.0f }
+};
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+#ifdef USE_HALF_TYPE
+class ColorAccumulator;
+#endif
+
+
+
+
+/*! \class Color
+** \todo Writeme
+** Future optimizations: lookup table for sqrt()?
+*/
+class Color
+{
+public:
+ typedef ColorReal value_type;
+
+private:
+ value_type a_, r_, g_, b_;
+
+public:
+
+ const String get_string(void)const;
+
+ Color &
+ operator+=(const Color &rhs)
+ {
+ r_+=rhs.r_;
+ g_+=rhs.g_;
+ b_+=rhs.b_;
+ a_+=rhs.a_;
+ return *this;
+ }
+
+ Color &
+ operator-=(const Color &rhs)
+ {
+ r_-=rhs.r_;
+ g_-=rhs.g_;
+ b_-=rhs.b_;
+ a_-=rhs.a_;
+ return *this;
+ }
+
+ Color &
+ operator*=(const float &rhs)
+ {
+ r_*=rhs;
+ g_*=rhs;
+ b_*=rhs;
+ a_*=rhs;
+ return *this;
+ }
+
+ Color &
+ operator/=(const float &rhs)
+ {
+ const float temp(value_type(1)/rhs);
+ r_*=temp;
+ g_*=temp;
+ b_*=temp;
+ a_*=temp;
+ return *this;
+ }
+
+ Color
+ operator+(const Color &rhs)const
+ { return Color(*this)+=rhs; }
+
+ Color
+ operator-(const Color &rhs)const
+ { return Color(*this)-=rhs; }
+
+ Color
+ operator*(const float &rhs)const
+ { return Color(*this)*=rhs; }
+
+ Color
+ operator/(const float &rhs)const
+ { return Color(*this)/=rhs; }
+
+ bool
+ operator==(const Color &rhs)const
+ { return r_==rhs.r_ && g_==rhs.g_ && b_==rhs.b_ && a_==rhs.a_; }
+
+ bool
+ operator!=(const Color &rhs)const
+ { return r_!=rhs.r_ || g_!=rhs.g_ || b_!=rhs.b_ || a_!=rhs.a_; }
+
+ Color
+ operator-()const
+ { return Color(-r_,-g_,-b_,-a_); }
+
+ //! Effectively 1.0-color
+ Color
+ operator~()const
+ { return Color(1.0f-r_,1.0f-g_,1.0f-b_,a_); }
+
+ bool is_valid()const
+ { return !isnan(r_) && !isnan(g_) && !isnan(b_) && !isnan(a_); }
+
+ Color premult_alpha() const
+ {
+ return Color (r_*a_, g_*a_, b_*a_, a_);
+ }
+
+ Color demult_alpha() const
+ {
+ if(a_)
+ {
+ const value_type inva = 1/a_;
+ return Color (r_*inva, g_*inva, b_*inva, a_);
+ }else return alpha();
+ }
+
+public:
+ // ETL/trunk/ETL/_gaussian.h does:
+ // SR1=SR2=SR3=typename T::value_type();
+ // and expects that to give it initialised colors
+ // Otherwise the 'gaussian' blur type is random.
+ Color() :a_(0), r_(0), g_(0), b_(0) { }
+ Color(const value_type &f) :a_(f),r_(f), g_(f), b_(f) { }
+ Color(int f) :a_(f),r_(f), g_(f), b_(f) { }
+
+ /*! \param R Red
+ ** \param G Green
+ ** \param B Blue
+ ** \param A Opacity(alpha) */
+ Color(const value_type& R, const value_type& G, const value_type& B, const value_type& A=1):
+ a_(A),
+ r_(R),
+ g_(G),
+ b_(B) { }
+
+ /*! \param c Source for color components
+ ** \param A Opacity(alpha) */
+ Color(const Color& c, const value_type& A):
+ a_(A),
+ r_(c.r_),
+ g_(c.g_),
+ b_(c.b_) { }
+
+
+ //! Copy constructor
+ Color(const Color& c):
+ a_(c.a_),
+ r_(c.r_),
+ g_(c.g_),
+ b_(c.b_) { }
+
+#ifdef USE_HALF_TYPE
+ friend class ColorAccumulator;
+ //! Convert constructor
+ Color(const ColorAccumulator& c);
+#endif
+
+ //! Copy constructor
+ //Color(const Color &c) { memcpy((void*)this, (const void*)&c, sizeof(Color)); }
+
+ /*const Color &operator=(const value_type &i)
+ {
+ r_ = g_ = b_ = a_ = i;
+ return *this;
+ }*/
+ //Color& operator=(const Color &c) { memcpy((void*)this, (const void*)&c, sizeof(Color)); return *this; }
+
+ //! Returns the RED component
+ const value_type& get_r()const { return r_; }
+
+ //! Returns the GREEN component
+ const value_type& get_g()const { return g_; }
+
+ //! Returns the BLUE component
+ const value_type& get_b()const { return b_; }
+
+ //! Returns the amount of opacity (alpha)
+ const value_type& get_a()const { return a_; }
+
+ //! Synonym for get_a(). \see get_a()
+ const value_type& get_alpha()const { return get_a(); }
+
+ //! Converts a 2 character hex string \a s (00-ff) into a ColorReal (0.0-1.0)
+ static ColorReal hex2real(String s);
+
+ //! Converts a ColorReal \a c (0.0-1.0) into a 2 character hex string (00-ff)
+ static const String real2hex(ColorReal c);
+
+ //! Returns the color as a 6 character hex sting
+ const String get_hex()const { return String(real2hex(r_)+real2hex(g_)+real2hex(b_)); }
+
+ //! Sets the color's R, G, and B from a 3 or 6 character hex string
+ void set_hex(String& hex);
+
+ //! Sets the RED component to \a x
+ Color& set_r(const value_type& x) { r_ = x; return *this; }
+
+ //! Sets the GREEN component to \a x
+ Color& set_g(const value_type& x) { g_ = x; return *this; }
+
+ //! Sets the BLUE component to \a x
+ Color& set_b(const value_type& x) { b_ = x; return *this; }
+
+ //! Sets the opacity (alpha) to \a x
+ Color& set_a(const value_type& x) { a_ = x; return *this; }
+
+ //! Synonym for set_a(). \see set_a()
+ Color& set_alpha(const value_type& x) { return set_a(x); }
+
+ //! Returns color's luminance
+ float
+ get_y() const
+ {
+ return
+ (float)get_r()*EncodeYUV[0][0]+
+ (float)get_g()*EncodeYUV[0][1]+
+ (float)get_b()*EncodeYUV[0][2];
+ }
+
+
+ //! Returns U component of chromanance
+ float
+ get_u() const
+ {
+ return
+ (float)get_r()*EncodeYUV[1][0]+
+ (float)get_g()*EncodeYUV[1][1]+
+ (float)get_b()*EncodeYUV[1][2];
+ }
+
+
+ //! Returns V component of chromanance
+ float
+ get_v() const
+ {
+ return
+ (float)get_r()*EncodeYUV[2][0]+
+ (float)get_g()*EncodeYUV[2][1]+
+ (float)get_b()*EncodeYUV[2][2];
+ }
+
+ //! Returns the color's saturation
+ /*! This is is the magnitude of the U and V components.
+ ** \see set_s() */
+ float
+ get_s() const
+ {
+ const float u(get_u()), v(get_v());
+ return sqrt(u*u+v*v);
+ }
+
+ //! Sets the luminance (\a y) and chromanance (\a u and \a v)
+ Color&
+ set_yuv(const float &y, const float &u, const float &v)
+ {
+ set_r(y*DecodeYUV[0][0]+u*DecodeYUV[0][1]+v*DecodeYUV[0][2]);
+ set_g(y*DecodeYUV[1][0]+u*DecodeYUV[1][1]+v*DecodeYUV[1][2]);
+ set_b(y*DecodeYUV[2][0]+u*DecodeYUV[2][1]+v*DecodeYUV[2][2]);
+ return *this;
+ }
+
+ //! Sets color luminance
+ Color& set_y(const float &y) { return set_yuv(y,get_u(),get_v()); }
+
+ //! Set U component of chromanance
+ Color& set_u(const float &u) { return set_yuv(get_y(),u,get_v()); }
+
+ //! Set V component of chromanance
+ Color& set_v(const float &v) { return set_yuv(get_y(),get_u(),v); }
+
+ //! Set the U and V components of chromanance
+ Color& set_uv(const float& u, const float& v) { return set_yuv(get_y(),u,v); }
+
+ //! Sets the color's saturation
+ /*! \see get_s() */
+ Color&
+ set_s(const float &x)
+ {
+ float u(get_u()), v(get_v());
+ const float s(sqrt(u*u+v*v));
+ if(s)
+ {
+ u=(u/s)*x;
+ v=(v/s)*x;
+ return set_uv(u,v);
+ }
+ return *this;
+ }
+
+ //! YUV Color constructor
+ static Color YUV(const float& y, const float& u, const float& v, const value_type& a=1)
+ { return Color().set_yuv(y,u,v).set_a(a); }
+
+#ifndef SYNFIG_NO_ANGLE
+ //! Returns the hue of the chromanance
+ /*! This is the angle of the U and V components.
+ ** \see set_hue() */
+ Angle
+ get_hue() const
+ { return Angle::tan(get_u(),get_v()); }
+
+ //! Synonym for get_hue(). \see get_hue()
+ Angle get_uv_angle() const { return get_hue(); }
+
+ //! Sets the color's hue
+ /*! \see get_hue() */
+ Color&
+ set_hue(const Angle& theta)
+ {
+ const float s(get_s());
+ const float
+ u(s*(float)Angle::sin(theta).get()),
+ v(s*(float)Angle::cos(theta).get());
+ return set_uv(u,v);
+ }
+
+ //! Synonym for set_hue(). \see set_hue()
+ Color& set_uv_angle(const Angle& theta) { return set_hue(theta); }
+
+ //! Rotates the chromanance vector by amount specified by \a theta
+ Color& rotate_uv(const Angle& theta)
+ {
+ const float a(Angle::sin(theta).get()), b(Angle::cos(theta).get());
+ const float u(get_u()), v(get_v());
+
+ return set_uv(b*u-a*v,a*u+b*v);
+ }
+
+ //! Sets the luminance (\a y) and chromanance (\a s and \a theta).
+ /*! \param y Luminance
+ ** \param s Saturation
+ ** \param theta Hue */
+ Color& set_yuv(const float& y, const float& s, const Angle& theta)
+ {
+ return
+ set_yuv(
+ y,
+ s*(float)Angle::sin(theta).get(),
+ s*(float)Angle::cos(theta).get()
+ );
+ }
+
+ //! YUV color constructor where the chroma is in the saturation/hue form.
+ /*! \param y Luminance
+ ** \param s Saturation
+ ** \param theta Hue
+ ** \param a Opacity (alpha) */
+ static Color YUV(const float& y, const float& s, const Angle& theta, const value_type& a=1)
+ { return Color().set_yuv(y,s,theta).set_a(a); }
+
+#endif
+
+ //! Clamps a color so that its values are in range. Ignores attempting to visualize negative colors.
+ Color clamped()const;
+
+ //! Clamps a color so that its values are in range.
+ Color clamped_negative()const;
+
+ /* Preset Colors */
+
+ //! Preset Color Constructors
+ //@{
+#ifdef HAS_VIMAGE
+ static inline Color alpha() { return Color(0,0,0,0.0000001f); }
+#else
+ static inline Color alpha() { return Color(0,0,0,0); }
+#endif
+ static inline Color black() { return Color(0,0,0); }
+ static inline Color white() { return Color(1,1,1); }
+ static inline Color gray() { return Color(0.5f,0.5f,0.5f); }
+ static inline Color magenta() { return Color(1,0,1); }
+ static inline Color red() { return Color(1,0,0); }
+ static inline Color green() { return Color(0,1,0); }
+ static inline Color blue() { return Color(0,0,1); }
+ static inline Color cyan() { return Color(0,1,1); }
+ static inline Color yellow() { return Color(1,1,0); }
+ //@}
+
+ //! \writeme
+ enum BlendMethod
+ {
+ BLEND_COMPOSITE=0, //!< Color A is composited onto B (Taking A's alpha into account)
+ BLEND_STRAIGHT=1, //!< Straight linear interpolation from A->B (Alpha ignored)
+ BLEND_ONTO=13, //!< Similar to BLEND_COMPOSITE, except that B's alpha is maintained
+ BLEND_STRAIGHT_ONTO=21, //!< <deprecated> \writeme
+ BLEND_BEHIND=12, //!< Similar to BLEND_COMPOSITE, except that B is composited onto A.
+ BLEND_SCREEN=16, //!< \writeme
+ BLEND_OVERLAY=20, //!< \writeme
+ BLEND_HARD_LIGHT=17, //!< \writeme
+ BLEND_MULTIPLY=6, //!< Simple A*B.
+ BLEND_DIVIDE=7, //!< Simple B/A
+ BLEND_ADD=4, //!< Simple A+B.
+ BLEND_SUBTRACT=5, //!< Simple A-B.
+ BLEND_DIFFERENCE=18, //!< Simple |A-B|.
+ BLEND_BRIGHTEN=2, //!< If composite is brighter than B, use composite. B otherwise.
+ BLEND_DARKEN=3, //!< If composite is darker than B, use composite. B otherwise.
+ BLEND_COLOR=8, //!< Preserves the U and V channels of color A
+ BLEND_HUE=9, //!< Preserves the angle of the UV vector of color A
+ BLEND_SATURATION=10, //!< Preserves the magnitude of the UV Vector of color A
+ BLEND_LUMINANCE=11, //!< Preserves the Y channel of color A
+
+ BLEND_ALPHA_BRIGHTEN=14, //!< <deprecated> If A is less opaque than B, use A
+ BLEND_ALPHA_DARKEN=15, //!< <deprecated> If A is more opaque than B, use B
+ BLEND_ALPHA_OVER=19, //!< <deprecated> multiply alphas and then straight blends using the amount
+
+ BLEND_END=22 //!< \internal
+ };
+
+ /* Other */
+ static Color blend(Color a, Color b,float amount,BlendMethod type=BLEND_COMPOSITE);
+
+ static bool is_onto(BlendMethod x)
+ {
+ return x==BLEND_BRIGHTEN
+ || x==BLEND_DARKEN
+ || x==BLEND_ADD
+ || x==BLEND_SUBTRACT
+ || x==BLEND_MULTIPLY
+ || x==BLEND_DIVIDE
+ || x==BLEND_COLOR
+ || x==BLEND_HUE
+ || x==BLEND_SATURATION
+ || x==BLEND_LUMINANCE
+ || x==BLEND_ONTO
+ || x==BLEND_STRAIGHT_ONTO
+ || x==BLEND_SCREEN
+ || x==BLEND_OVERLAY
+ || x==BLEND_DIFFERENCE
+ || x==BLEND_HARD_LIGHT
+ ;
+ }
+/*protected:
+
+ value_type& operator[](const int i)
+ {
+ assert(i>=0);
+ assert(i<(signed)(sizeof(Color)/sizeof(value_type)));
+ return (&r_)[i];
+ }
+
+ const value_type& operator[](const int i)const
+ {
+ assert(i>=0);
+ assert(i<(signed)(sizeof(Color)/sizeof(value_type)));
+ return (&r_)[i];
+ }
+*/
+}; // END of class Color
+
+#ifndef USE_HALF_TYPE
+typedef Color ColorAccumulator;
+#else
+class ColorAccumulator
+{
+ friend class Color;
+public:
+ typedef float value_type;
+
+private:
+ value_type a_, r_, g_, b_;
+
+public:
+
+ ColorAccumulator &
+ operator+=(const ColorAccumulator &rhs)
+ {
+ r_+=rhs.r_;
+ g_+=rhs.g_;
+ b_+=rhs.b_;
+ a_+=rhs.a_;
+ return *this;
+ }
+
+ ColorAccumulator &
+ operator-=(const ColorAccumulator &rhs)
+ {
+ r_-=rhs.r_;
+ g_-=rhs.g_;
+ b_-=rhs.b_;
+ a_-=rhs.a_;
+ return *this;
+ }
+
+ ColorAccumulator &
+ operator*=(const float &rhs)
+ {
+ r_*=rhs;
+ g_*=rhs;
+ b_*=rhs;
+ a_*=rhs;
+ return *this;
+ }
+
+ ColorAccumulator &
+ operator/=(const float &rhs)
+ {
+ const float temp(value_type(1)/rhs);
+ r_*=temp;
+ g_*=temp;
+ b_*=temp;
+ a_*=temp;
+ return *this;
+ }
+
+ ColorAccumulator
+ operator+(const ColorAccumulator &rhs)const
+ { return Color(*this)+=rhs; }
+
+ ColorAccumulator
+ operator-(const ColorAccumulator &rhs)const
+ { return Color(*this)-=rhs; }
+
+ ColorAccumulator
+ operator*(const float &rhs)const
+ { return Color(*this)*=rhs; }
+
+ ColorAccumulator
+ operator/(const float &rhs)const
+ { return Color(*this)/=rhs; }
+
+ bool
+ operator==(const ColorAccumulator &rhs)const
+ { return r_==rhs.r_ && g_==rhs.g_ && b_==rhs.b_ && a_!=rhs.a_; }
+
+ bool
+ operator!=(const ColorAccumulator &rhs)const
+ { return r_!=rhs.r_ || g_!=rhs.g_ || b_!=rhs.b_ || a_!=rhs.a_; }
+
+ Color
+ operator-()const
+ { return ColorAccumulator(-r_,-g_,-b_,-a_); }
+
+ bool is_valid()const
+ { return !isnan(r_) && !isnan(g_) && !isnan(b_) && !isnan(a_); }
+
+public:
+ ColorAccumulator() { }
+
+ /*! \param R Red
+ ** \param G Green
+ ** \param B Blue
+ ** \param A Opacity(alpha) */
+ ColorAccumulator(const value_type& R, const value_type& G, const value_type& B, const value_type& A=1):
+ a_(A),
+ r_(R),
+ g_(G),
+ b_(B) { }
+
+ //! Copy constructor
+ ColorAccumulator(const ColorAccumulator& c):
+ a_(c.a_),
+ r_(c.r_),
+ g_(c.g_),
+ b_(c.b_) { }
+
+ //! Converter
+ ColorAccumulator(const Color& c):
+ a_(c.a_),
+ r_(c.r_),
+ g_(c.g_),
+ b_(c.b_) { }
+
+ //! Converter
+ ColorAccumulator(int c): a_(c),r_(c), g_(c), b_(c) { }
+
+ //! Returns the RED component
+ const value_type& get_r()const { return r_; }
+
+ //! Returns the GREEN component
+ const value_type& get_g()const { return g_; }
+
+ //! Returns the BLUE component
+ const value_type& get_b()const { return b_; }
+
+ //! Returns the amount of opacity (alpha)
+ const value_type& get_a()const { return a_; }
+
+ //! Synonym for get_a(). \see get_a()
+ const value_type& get_alpha()const { return get_a(); }
+
+ //! Sets the RED component to \a x
+ ColorAccumulator& set_r(const value_type& x) { r_ = x; return *this; }
+
+ //! Sets the GREEN component to \a x
+ ColorAccumulator& set_g(const value_type& x) { g_ = x; return *this; }
+
+ //! Sets the BLUE component to \a x
+ ColorAccumulator& set_b(const value_type& x) { b_ = x; return *this; }
+
+ //! Sets the opacity (alpha) to \a x
+ ColorAccumulator& set_a(const value_type& x) { a_ = x; return *this; }
+
+ //! Synonym for set_a(). \see set_a()
+ ColorAccumulator& set_alpha(const value_type& x) { return set_a(x); }
+};
+
+inline
+Color::Color(const ColorAccumulator& c):
+ a_(c.a_),
+ r_(c.r_),
+ g_(c.g_),
+ b_(c.b_) { }
+
+#endif
+
+
+
+
+
+enum PixelFormat
+{
+/* Bit Descriptions (ON/OFF)
+** ----+-------------
+** 0 Color Channels (Gray/RGB)
+** 1 Alpha Channel (WITH/WITHOUT)
+** 2 ZDepth (WITH/WITHOUT)
+** 3 Endian (BGR/RGB)
+** 4 Alpha Location (Start/End)
+** 5 ZDepth Location (Start/End)
+** 6 Alpha/ZDepth Arangement (ZA,AZ)
+** 7 Alpha Range (Inverted,Normal)
+** 8 Z Range (Inverted,Normal)
+*/
+ PF_RGB=0,
+ PF_GRAY=(1<<0), //!< If set, use one grayscale channel. If clear, use three channels for RGB
+ PF_A=(1<<1), //!< If set, include alpha channel
+ PF_Z=(1<<2), //!< If set, include ZDepth channel
+ PF_BGR=(1<<3), //!< If set, reverse the order of the RGB channels
+ PF_A_START=(1<<4), //!< If set, alpha channel is before the color data. If clear, it is after.
+ PF_Z_START=(1<<5), //!< If set, ZDepth channel is before the color data. If clear, it is after.
+ PF_ZA=(1<<6), //!< If set, the ZDepth channel will be infront of the alpha channel. If clear, they are reversed.
+
+ PF_A_INV=(1<<7), //!< If set, the alpha channel is stored as 1.0-a
+ PF_Z_INV=(1<<8), //!< If set, the ZDepth channel is stored as 1.0-z
+ PF_RAW_COLOR=(1<<9)+(1<<1) //!< If set, the data represents a raw Color datastructure, and all other bits are ignored.
+};
+
+inline PixelFormat operator|(PixelFormat lhs, PixelFormat rhs)
+ { return static_cast<PixelFormat>((int)lhs|(int)rhs); }
+
+inline PixelFormat operator&(PixelFormat lhs, PixelFormat rhs)
+ { return static_cast<PixelFormat>((int)lhs&(int)rhs); }
+#define FLAGS(x,y) (((x)&(y))==(y))
+
+//! Returns the number of channels that the given PixelFormat calls for
+inline int
+channels(PixelFormat x)
+{
+ int chan=0;
+ if(FLAGS(x,PF_GRAY))
+ ++chan;
+ else
+ chan+=3;
+ if(FLAGS(x,PF_A))
+ ++chan;
+ if(FLAGS(x,PF_Z))
+ ++chan;
+ if(FLAGS(x,PF_RAW_COLOR))
+ chan=sizeof(Color);
+
+ return chan;
+}
+
+inline unsigned char *
+Color2PixelFormat(const Color &color, const PixelFormat &pf, unsigned char *out, const Gamma &gamma)
+{
+ if(FLAGS(pf,PF_RAW_COLOR))
+ {
+ Color *outcol=reinterpret_cast<Color *>(out);
+ *outcol=color;
+ out+=sizeof(color);
+ return out;
+ }
+
+ int alpha=(int)((FLAGS(pf,PF_A_INV)?(-(float)color.get_a()+1):(float)color.get_a())*255);
+ if(alpha<0)alpha=0;
+ if(alpha>255)alpha=255;
+
+ if(FLAGS(pf,PF_ZA|PF_A_START|PF_Z_START))
+ {
+ if(FLAGS(pf,PF_Z_START))
+ *out++/*=(unsigned char)(color.GetZ()*255.0f)*/;
+ if(FLAGS(pf,PF_A_START))
+ *out++=static_cast<unsigned char>(alpha);
+ }
+ else
+ {
+ if(FLAGS(pf,PF_A_START))
+ *out++=static_cast<unsigned char>(alpha);
+ if(FLAGS(pf,PF_Z_START))
+ *out++/*=(unsigned char)(color.GetZ()*255.0f)*/;
+
+ }
+
+ if(FLAGS(pf,PF_GRAY))
+ *out++=static_cast<unsigned char>(gamma.g_F32_to_U8(color.get_y()));
+ else
+ {
+ if(FLAGS(pf,PF_BGR))
+ {
+ *out++=static_cast<unsigned char>(gamma.r_F32_to_U8(color.get_b()));
+ *out++=static_cast<unsigned char>(gamma.g_F32_to_U8(color.get_g()));
+ *out++=static_cast<unsigned char>(gamma.b_F32_to_U8(color.get_r()));
+ }
+ else
+ {
+ *out++=static_cast<unsigned char>(gamma.r_F32_to_U8(color.get_r()));
+ *out++=static_cast<unsigned char>(gamma.g_F32_to_U8(color.get_g()));
+ *out++=static_cast<unsigned char>(gamma.b_F32_to_U8(color.get_b()));
+ }
+ }
+
+ if(FLAGS(pf,PF_ZA))
+ {
+ if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))
+ out++;//*out++=(unsigned char)(color.GetZ()*255.0f);
+ if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A))
+ *out++=static_cast<unsigned char>(alpha);
+ }
+ else
+ {
+ if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))
+ out++;//*out++=(unsigned char)(color.GetZ()*255.0f);
+ if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A))
+ *out++=static_cast<unsigned char>(alpha);
+ }
+ return out;
+}
+
+inline void
+convert_color_format(unsigned char *dest, const Color *src, int w, PixelFormat pf,const Gamma &gamma)
+{
+ assert(w>=0);
+ while(w--)
+ dest=Color2PixelFormat((*(src++)).clamped(),pf,dest,gamma);
+}
+
+inline const unsigned char *
+PixelFormat2Color(Color &color, const PixelFormat &pf,const unsigned char *out)
+{
+ if(FLAGS(pf,PF_ZA|PF_A_START|PF_Z_START))
+ {
+ if(FLAGS(pf,PF_Z_START))
+ out++;//color.SetZ((Color::value_type)*out++/255.0f);
+ if(FLAGS(pf,PF_A_START))
+ color.set_a((float)*out++/255);
+ }
+ else
+ {
+ if(FLAGS(pf,PF_A_START))
+ color.set_a((float)*out++/255);
+ if(FLAGS(pf,PF_Z_START))
+ out++;//color.SetZ((Color::value_type)*out++/255.0f);
+ }
+
+ if(FLAGS(pf,PF_GRAY))
+ color.set_yuv((float)*out++/255,0,0);
+ else
+ {
+ if(FLAGS(pf,PF_BGR))
+ {
+ color.set_b((float)*out++/255);
+ color.set_g((float)*out++/255);
+ color.set_r((float)*out++/255);
+ }
+ else
+ {
+ color.set_r((float)*out++/255);
+ color.set_g((float)*out++/255);
+ color.set_b((float)*out++/255);
+ }
+ }
+
+ if(FLAGS(pf,PF_ZA))
+ {
+ if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))
+ out++;//color.SetZ((Color::value_type)*out++/255.0f);
+ if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A))
+ color.set_a((float)*out++/255);
+ }
+ else
+ {
+ if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A))
+ color.set_a((float)*out++/255);
+ if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))
+ out++;//color.SetZ((Color::value_type)*out++/255.0f);
+ }
+ return out;
+}
+
+
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file context.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "context.h"
+#include "layer.h"
+#include "string.h"
+#include "vector.h"
+#include "color.h"
+#include "surface.h"
+#include "renddesc.h"
+#include "valuenode.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+//#define SYNFIG_PROFILE_LAYERS
+//#define SYNFIG_DEBUG_LAYERS
+
+/* === G L O B A L S ======================================================= */
+
+#ifdef SYNFIG_PROFILE_LAYERS
+#include <ETL/clock>
+static int depth(0);
+static std::map<String,float> time_table;
+static std::map<String,int> run_table;
+static etl::clock profile_timer;
+static String curr_layer;
+static void
+_print_profile_report()
+{
+ synfig::info(">>>> Profile Report: (Times are in msecs)");
+ std::map<String,float>::iterator iter;
+ float total_time(0);
+ for(iter=time_table.begin();iter!=time_table.end();++iter)
+ {
+ String layer(iter->first);
+ float time(iter->second);
+ int runs(run_table[layer]);
+ total_time+=time;
+ synfig::info(" Layer \"%s\",\tExecs: %03d, Avg Time: %05.1f, Total Time: %05.1f",layer.c_str(),runs,time/runs*1000,time*1000);
+ }
+ synfig::info("Total Time: %f seconds", total_time);
+ synfig::info("<<<< End of Profile Report");
+}
+
+#endif
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Color
+Context::get_color(const Point &pos)const
+{
+ Context context(*this);
+
+ while(!context->empty())
+ {
+ // If this layer is active, then go
+ // ahead and break out of the loop
+ if((*context)->active())
+ break;
+
+ // Otherwise, we want to keep searching
+ // till we find either an active layer,
+ // or the end of the layer list
+ ++context;
+ }
+
+ // If this layer isn't defined, return alpha
+ if((context)->empty()) return Color::alpha();
+
+ RWLock::ReaderLock lock((*context)->get_rw_lock());
+
+ return (*context)->get_color(context+1, pos);
+}
+
+Rect
+Context::get_full_bounding_rect()const
+{
+ Context context(*this);
+
+ while(!context->empty())
+ {
+ // If this layer is active, then go
+ // ahead and break out of the loop
+ if((*context)->active())
+ break;
+
+ // Otherwise, we want to keep searching
+ // till we find either an active layer,
+ // or the end of the layer list
+ ++context;
+ }
+
+ // If this layer isn't defined, return zero-sized rectangle
+ if(context->empty()) return Rect::zero();
+
+ return (*context)->get_full_bounding_rect(context+1);
+}
+
+
+/* Profiling will go like this:
+ Profile start = +, stop = -
+
+ +
+ -
+
+ time diff is recorded
+
+ to get the independent times we need to break at the one inside and record etc...
+ so it looks more like this:
+
+ +
+ -
+ +
+ -
+ +
+ ...
+ -
+ +
+ -
+ +
+ -
+
+ at each minus we must record all the info for that which we are worried about...
+ each layer can do work before or after the other work is done... so both values must be recorded...
+*/
+
+bool
+Context::accelerated_render(Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb) const
+{
+ #ifdef SYNFIG_PROFILE_LAYERS
+ String layer_name(curr_layer);
+
+ //sum the pre-work done by layer above us... (curr_layer is layer above us...)
+ if(depth>0)
+ {
+ time_table[curr_layer]+=profile_timer();
+ //if(run_table.count(curr_layer))run_table[curr_layer]++;
+ // else run_table[curr_layer]=1;
+ }
+ #endif
+
+ const Rect bbox(renddesc.get_rect());
+
+ Context context(*this);
+ for(;!(context)->empty();++context)
+ {
+ // If we are not active
+ // then move on to next layer
+ if(!(*context)->active())
+ continue;
+
+ const Rect layer_bounds((*context)->get_bounding_rect());
+
+ // If the box area is less than zero
+ // then move on to next layer
+ if(layer_bounds.area()<=0.0000000000001)
+ continue;
+
+ // If the boxes do not intersect
+ // then move on to next layer
+ if(!(layer_bounds && bbox))
+ continue;
+
+ // Break out of the loop--we have found a good layer
+ break;
+ }
+
+ // If this layer isn't defined, return alpha
+ if((context)->empty())
+ {
+#ifdef SYNFIG_DEBUG_LAYERS
+ synfig::info("Context::accelerated_render(): Hit end of list");
+#endif
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ surface->clear();
+ #ifdef SYNFIG_PROFILE_LAYERS
+ profile_timer.reset();
+ #endif
+ return true;
+ }
+
+#ifdef SYNFIG_DEBUG_LAYERS
+ synfig::info("Context::accelerated_render(): Descending into %s",(*context)->get_name().c_str());
+#endif
+
+ try {
+ RWLock::ReaderLock lock((*context)->get_rw_lock());
+
+ #ifdef SYNFIG_PROFILE_LAYERS
+
+ //go down one layer :P
+ depth++;
+ curr_layer=(*context)->get_name(); //make sure the layer inside is referring to the correct layer outside
+ profile_timer.reset(); // +
+ bool ret((*context)->accelerated_render(context+1,surface,quality,renddesc, cb));
+
+ //post work for the previous layer
+ time_table[curr_layer]+=profile_timer(); //-
+ if(run_table.count(curr_layer))run_table[curr_layer]++;
+ else run_table[curr_layer]=1;
+
+ depth--;
+ curr_layer = layer_name; //we are now onto this layer (make sure the post gets recorded correctly...
+
+ //print out the table it we're done...
+ if(depth==0) _print_profile_report(),time_table.clear(),run_table.clear();
+ profile_timer.reset(); //+
+ return ret;
+ #else
+ return (*context)->accelerated_render(context+1,surface,quality,renddesc, cb);
+ #endif
+
+ }
+ catch(std::bad_alloc)
+ {
+ synfig::error("Context::accelerated_render(): Layer \"%s\" threw a bad_alloc exception!",(*context)->get_name().c_str());
+#ifdef _DEBUG
+ return false;
+#else
+ ++context;
+ return context.accelerated_render(surface, quality, renddesc, cb);
+#endif
+ }
+ catch(...)
+ {
+ synfig::error("Context::accelerated_render(): Layer \"%s\" threw an exception, rethrowing...",(*context)->get_name().c_str());
+ throw;
+ }
+}
+
+void
+Context::set_time(Time time)const
+{
+ Context context(*this);
+ while(!(context)->empty())
+ {
+ // If this layer is active, then go
+ // ahead and break out of the loop
+ if((*context)->active() && !(*context)->dirty_time_.is_equal(time))
+ break;
+
+ // Otherwise, we want to keep searching
+ // till we find either an active layer,
+ // or the end of the layer list
+ ++context;
+ }
+
+ // If this layer isn't defined, just return
+ if((context)->empty()) return;
+
+ // Set up a wrter lock
+ RWLock::WriterLock lock((*context)->get_rw_lock());
+
+ //synfig::info("%s: dirty_time=%f",(*context)->get_name().c_str(),(float)(*context)->dirty_time_);
+ //synfig::info("%s: time=%f",(*context)->get_name().c_str(),(float)time);
+
+ {
+ Layer::ParamList params;
+ Layer::DynamicParamList::const_iterator iter;
+
+ for(iter=(*context)->dynamic_param_list().begin();iter!=(*context)->dynamic_param_list().end();iter++)
+ params[iter->first]=(*iter->second)(time);
+
+ (*context)->set_param_list(params);
+
+ (*context)->set_time(context+1,time);
+ (*context)->dirty_time_=time;
+
+ }
+}
+
+void
+Context::set_time(Time time,const Vector &/*pos*/)const
+{
+ set_time(time);
+/*
+ Context context(*this);
+ while(!(context)->empty())
+ {
+ // If this layer is active, then go
+ // ahead and break out of the loop
+ if((*context)->active())
+ break;
+
+ // Otherwise, we want to keep searching
+ // till we find either an active layer,
+ // or the end of the layer list
+ ++context;
+ }
+
+ // If this layer isn't defined, just return
+ if((context)->empty()) return;
+
+ else
+ {
+ Layer::ParamList params;
+ Layer::DynamicParamList::const_iterator iter;
+
+ for(iter=(*context)->dynamic_param_list().begin();iter!=(*context)->dynamic_param_list().end();iter++)
+ params[iter->first]=(*iter->second)(time);
+
+ (*context)->set_param_list(params);
+
+ (*context)->set_time(context+1,time,pos);
+ }
+*/
+}
+
+etl::handle<Layer>
+Context::hit_check(const Point &pos)const
+{
+ Context context(*this);
+
+ while(!context->empty())
+ {
+ // If this layer is active, then go
+ // ahead and break out of the loop
+ if((*context)->active())
+ break;
+
+ // Otherwise, we want to keep searching
+ // till we find either an active layer,
+ // or the end of the layer list
+ ++context;
+ }
+
+ // If this layer isn't defined, return an empty handle
+ if((context)->empty()) return 0;
+
+ return (*context)->hit_check(context+1, pos);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file context.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_CONTEXT_H
+#define __SYNFIG_CONTEXT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "canvasbase.h"
+#include "rect.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Vector;
+typedef Vector Point;
+class Color;
+class Surface;
+class RendDesc;
+class ProgressCallback;
+class Layer;
+class Time;
+class Rect;
+
+/*! \class Context
+** \todo writeme
+** \see Layer, Canvas */
+class Context : public CanvasBase::const_iterator
+{
+public:
+ Context() { }
+
+ Context(const CanvasBase::const_iterator &x):CanvasBase::const_iterator(x) { }
+
+ Context operator=(const CanvasBase::const_iterator &x)
+ { return CanvasBase::const_iterator::operator=(x); }
+
+ /*! \todo write me */
+ Color get_color(const Point &pos)const;
+
+ /*! \todo write me */
+ bool accelerated_render(Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb) const;
+
+ /*! \todo write me */
+ void set_time(Time time)const;
+
+ /*! \writeme */
+ void set_time(Time time,const Vector &pos)const;
+
+ Rect get_full_bounding_rect()const;
+
+ /*! \writeme */
+ etl::handle<Layer> hit_check(const Point &point)const;
+
+}; // END of class Context
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file curve_helper.cpp
+** \brief Curve Helper File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "curve_helper.h"
+
+#include <algorithm>
+#include <vector>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+#define ERR 1e-11
+const Real ERROR = 1e-11;
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Real synfig::find_closest(const etl::bezier<Point> &curve, const Point &point,
+ float step, Real *dout, float *tout)
+{
+#if 0
+ float time(curve.find_closest(point,4));
+ Real dist((curve(time)-point).mag());
+ if(dout) *dout=dist;
+ if(tout) *tout=time;
+ return time;
+#else
+ Real d,closest = 1.0e50;
+ float t,time,closestt = -1;
+ Vector p0,p1,end;
+
+ if(dout && *dout > 0)
+ closest = *dout;
+
+ p0 = curve[0];
+ end = curve[3];
+
+ for(t = step; t < 1; t+=step, p0=p1)
+ {
+ p1 = curve(t);
+ d = line_point_distsq(p0,p1,point,time);
+
+ if(d<closest)
+ {
+ closest=d;
+ closestt = t-step + time*step;//t+(time-1)*step; //time between [t-step,t]
+ }
+ }
+
+ d = line_point_distsq(p0,end,point,time);
+ if(d<closest)
+ {
+ closest = d;
+ closestt= t-step + time*(1-t+step); //time between [t-step,1.0]
+ }
+
+ //set the time value if we found a closer point
+ if(closestt >=0)
+ {
+ if(tout) *tout = closestt;
+ }
+
+ return closest;
+#endif
+}
+
+// Line and BezHull Definitions
+void BezHull::Bound(const etl::bezier<Point> &b)
+{
+ #if 1
+
+ //with a starting vertex, find the only vertex that has all other vertices on its right
+ int i,j;
+ int first,cur,last;
+
+ float d,ds;
+
+ Vector n,vi;
+ Vector::value_type deqn;
+
+ //get left most vertex
+ d = b[0][0];
+ first = 0;
+ for(i = 1; i < 4; ++i)
+ {
+ if(b[i][0] < d)
+ {
+ d = b[i][0];
+ first = i;
+ }
+ }
+ cur = last = first;
+ size = 0;
+
+ //find the farthest point with all points on right
+ ds = 0;
+ do //should reassign cur so it won't break on first step
+ {
+ for(i = 0; i < 4; ++i)
+ {
+ if(i == cur || i == last) continue;
+
+ //rotate vector to right to make normal
+ vi = -(b[i] - b[cur]).perp();
+ d = vi.mag_squared();
+
+ //we want only the farthest (solves the case with many points on a line)
+ if(d > ds)
+ {
+ ds = d;
+ deqn = n*b[cur];
+ for(j = 0; j < 4; ++j)
+ {
+ d = n*b[i] - deqn;
+ if(d < 0) break; //we're on left, nope!
+ }
+
+ //everyone is on right... yay! :)
+ if(d >= 0)
+ {
+ //advance point and add last one into hull
+ p[size++] = p[last];
+ last = cur;
+ cur = i;
+ }
+ }
+ }
+ }while(cur != first);
+
+ #else
+
+ //will work but does not keep winding order
+
+ //convex hull alg.
+ //build set of line segs which have no points on other side...
+ //start with initial normal segments
+
+ //start with single triangle
+ p[0] = b[0];
+ p[1] = b[1];
+ p[2] = b[2];
+ p[3] = b[3];
+
+ //initial reject (if point is inside triangle don't care)
+ {
+ Vector v1,v2,vp;
+
+ v1 = p[1]-p[0];
+ v2 = p[2]-p[0];
+
+ vp = p[3]-p[0];
+
+ float s = (vp*v1) / (v1*v1),
+ t = (vp*v2) / (v2*v2);
+
+ //if we're inside the triangle we don't this sissy point
+ if( s >= 0 && s <= 1 && t >= 0 && t <= 1 )
+ {
+ size = 3;
+ return;
+ }
+ }
+
+ //expand triangle based on info...
+ bool line;
+ int index,i,j;
+ float ds,d;
+
+ //distance from point to vertices
+ line = false;
+ index = 0;
+ ds = (p[0]-b[3]).mag_squared();
+ for(i = 1; i < 3; ++i)
+ {
+ d = (p[3]-p[i]).mag_squared();
+ if(d < ds)
+ {
+ index = i;
+ ds = d;
+ }
+ }
+
+ //distance to line
+ float t;
+ j = 2;
+ for(i = 0; i < 3; j = i++)
+ {
+ d = line_point_distsq(p[j],p[i],b[4],t);
+ if(d < ds)
+ {
+ index = j;
+ ds = d;
+ line = true;
+ }
+ }
+
+ //We don't need no stinkin extra vertex, just replace
+ if(!line)
+ {
+ p[index] = p[3];
+ size = 3;
+ }else
+ {
+ //must expand volume to work with point...
+ // after the index then
+
+ /* Pattern:
+ 0 - push 1,2 -> 2,3
+ 1 - push 2 -> 3
+ 2 - none
+ */
+ for(i = 3; i > index+1; --i)
+ {
+ p[i] = p[i-1];
+ }
+
+ p[index] = b[3]; //recopy b3
+ size = 4;
+ }
+
+ #endif
+}
+
+//Line Intersection
+int
+synfig::intersect(const Point &p1, const Vector &v1, float &t1,
+ const Point &p2, const Vector &v2, float &t2)
+{
+ /* Parametric intersection:
+ l1 = p1 + tv1, l2 = p2 + sv2
+
+ 0 = p1+tv1-(p2+sv2)
+ group parameters: sv2 - tv1 = p1-p2
+
+ ^ = transpose
+ invert matrix (on condition det != 0):
+ A[t s]^ = [p1-p2]^
+
+ A = [-v1 v2]
+
+ det = v1y.v2x - v1x.v2y
+
+ if non 0 then A^-1 = invdet * | v2y -v2x |
+ | v1y -v1x |
+
+ [t s]^ = A^-1 [p1-p2]^
+ */
+
+ Vector::value_type det = v1[1]*v2[0] - v1[0]*v2[1];
+
+ //is determinant valid?
+ if(det > ERR || det < -ERR)
+ {
+ Vector p_p = p1-p2;
+
+ det = 1/det;
+
+ t1 = det*(v2[1]*p_p[0] - v2[0]*p_p[1]);
+ t2 = det*(v1[1]*p_p[0] - v1[0]*p_p[1]);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//Returns the true or false intersection of a rectangle and a line
+int intersect(const Rect &r, const Point &p, const Vector &v)
+{
+ float t[4] = {0};
+
+ /*get horizontal intersections and then vertical intersections
+ and intersect them
+
+ Vertical planes - n = (1,0)
+ Horizontal planes - n = (0,1)
+
+ so if we are solving for ray with implicit line
+ */
+
+ //solve horizontal
+ if(v[0] > ERR || v[0] < -ERR)
+ {
+ //solve for t0, t1
+ t[0] = (r.minx - p[0])/v[0];
+ t[1] = (r.maxx - p[0])/v[0];
+ }else
+ {
+ return (int)(p[1] >= r.miny && p[1] <= r.maxy);
+ }
+
+ //solve vertical
+ if(v[1] > ERR || v[1] < -ERR)
+ {
+ //solve for t0, t1
+ t[2] = (r.miny - p[1])/v[1];
+ t[3] = (r.maxy - p[1])/v[1];
+ }else
+ {
+ return (int)(p[0] >= r.minx && p[0] <= r.maxx);
+ }
+
+ return (int)(t[0] <= t[3] && t[1] >= t[2]);
+}
+
+int synfig::intersect(const Rect &r, const Point &p)
+{
+ return (p[1] < r.maxy && p[1] > r.miny) && p[0] > r.minx;
+}
+
+//returns 0 or 1 for true or false number of intersections of a ray with a bezier convex hull
+int intersect(const BezHull &bh, const Point &p, const Vector &v)
+{
+ float mint = 0, maxt = 1e20;
+
+ //polygon cliping
+ Vector n;
+ Vector::value_type nv;
+
+ Point last = bh.p[3];
+ for(int i = 0; i < bh.size; ++i)
+ {
+ n = (bh.p[i] - last).perp(); //rotate 90 deg.
+
+ /*
+ since rotated left
+ if n.v < 0 - going in
+ > 0 - going out
+ = 0 - parallel
+ */
+ nv = n*v;
+
+ //going OUT
+ if(nv > ERR)
+ {
+ maxt = min(maxt,(float)((n*(p-last))/nv));
+ }else
+ if( nv < -ERR) //going IN
+ {
+ mint = max(mint,(float)((n*(p-last))/nv));
+ }else
+ {
+ if( n*(p-last) > 0 ) //outside entirely
+ {
+ return 0;
+ }
+ }
+
+ last = bh.p[i];
+ }
+
+ return 0;
+}
+
+int Clip(const Rect &r, const Point &p1, const Point &p2, Point *op1, Point *op2)
+{
+ float t1=0,t2=1;
+ Vector v=p2-p1;
+
+ /*get horizontal intersections and then vertical intersections
+ and intersect them
+
+ Vertical planes - n = (1,0)
+ Horizontal planes - n = (0,1)
+
+ so if we are solving for ray with implicit line
+ */
+
+ //solve horizontal
+ if(v[0] > ERR || v[0] < -ERR)
+ {
+ //solve for t0, t1
+ float tt1 = (r.minx - p1[0])/v[0],
+ tt2 = (r.maxx - p1[0])/v[0];
+
+ //line in positive direction (normal comparisons
+ if(tt1 < tt2)
+ {
+ t1 = max(t1,tt1);
+ t2 = min(t2,tt2);
+ }else
+ {
+ t1 = max(t1,tt2);
+ t2 = min(t2,tt1);
+ }
+ }else
+ {
+ if(p1[1] < r.miny || p1[1] > r.maxy)
+ return 0;
+ }
+
+ //solve vertical
+ if(v[1] > ERR || v[1] < -ERR)
+ {
+ //solve for t0, t1
+ float tt1 = (r.miny - p1[1])/v[1],
+ tt2 = (r.maxy - p1[1])/v[1];
+
+ //line in positive direction (normal comparisons
+ if(tt1 < tt2)
+ {
+ t1 = max(t1,tt1);
+ t2 = min(t2,tt2);
+ }else
+ {
+ t1 = max(t1,tt2);
+ t2 = min(t2,tt1);
+ }
+ }else
+ {
+ if(p1[0] < r.minx || p1[0] > r.maxx)
+ return 0;
+ }
+
+ if(op1) *op1 = p1 + v*t1;
+ if(op2) *op2 = p1 + v*t2;
+
+ return 1;
+}
+
+static void clean_bez(const bezier<Point> &b, bezier<Point> &out)
+{
+ bezier<Point> temp;
+
+ temp = b;
+ temp.set_r(0);
+ temp.set_s(1);
+
+ if(b.get_r() != 0)
+ temp.subdivide(0,&temp,b.get_r());
+
+ if(b.get_s() != 1)
+ temp.subdivide(&temp,0,b.get_s());
+
+ out = temp;
+}
+
+// CIntersect Definitions
+
+CIntersect::CIntersect()
+ : max_depth(10) //depth of 10 means timevalue parameters will have an approx. error bound of 2^-10
+{
+}
+
+struct CIntersect::SCurve
+{
+ bezier<Point> b; //the current subdivided curve
+ float rt,st;
+ //float mid, //the midpoint time value on this section of the subdivided curve
+ // scale; //the current delta in time values this curve would be on original curve
+
+ float mag; //approximate sum of magnitudes of each edge of control polygon
+ Rect aabb; //Axis Aligned Bounding Box for quick (albeit less accurate) collision
+
+ SCurve() {}
+
+ SCurve(const bezier<Point> &c,float rin, float sin)
+ :b(c),rt(rin),st(sin),mag(1)
+ {
+ Bound(aabb,b);
+ }
+
+ void Split(SCurve &l, SCurve &r) const
+ {
+ b.subdivide(&l.b,&r.b);
+
+ l.rt = rt;
+ r.st = st;
+ l.st = r.rt = (rt+st)/2;
+
+ Bound(l.aabb,l.b);
+ Bound(r.aabb,r.b);
+ }
+};
+
+//Curve to the left of point test
+static int recurse_intersect(const CIntersect::SCurve &b, const Point &p1, int depthleft = 10)
+{
+ //reject when the line does not intersect the bounding box
+ if(!intersect(b.aabb,p1)) return 0;
+
+ //accept curves (and perform super detailed check for intersections)
+ //if the values are below tolerance
+
+ //NOTE FOR BETTERING OF ALGORITHM: SHOULD ALSO/IN-PLACE-OF CHECK MAGNITUDE OF EDGES (or approximate)
+ if(depthleft <= 0)
+ {
+ //NOTE FOR IMPROVEMENT: Polish roots based on original curve
+ // (may be too expensive to be effective)
+ int turn = 0;
+
+ for(int i = 0; i < 3; ++i)
+ {
+ //intersect line segmentsssss
+
+ //solve for the y_value
+ Vector v = b.b[i+1] - b.b[i];
+
+ if(v[1] > ERROR && v[1] < ERROR)
+ {
+ Real xi = (p1[1] - b.b[i][1])/v[1];
+
+ //and add in the turn (up or down) if it's valid
+ if(xi < p1[0]) turn += (v[1] > 0) ? 1 : -1;
+ }
+ }
+
+ return turn;
+ }
+
+ //subdivide the curve and continue
+ CIntersect::SCurve l1,r1;
+ b.Split(l1,r1); //subdivide left
+
+ //test each subdivision against the point
+ return recurse_intersect(l1,p1) + recurse_intersect(r1,p1);
+}
+
+int intersect(const bezier<Point> &b, const Point &p)
+{
+ CIntersect::SCurve sb;
+ clean_bez(b,sb.b);
+
+ sb.rt = 0; sb.st = 1;
+ sb.mag = 1; Bound(sb.aabb,sb.b);
+
+ return recurse_intersect(sb,p);
+}
+
+//Curve curve intersection
+void CIntersect::recurse_intersect(const SCurve &left, const SCurve &right, int depth)
+{
+ //reject curves that do not overlap with bouding boxes
+ if(!intersect(left.aabb,right.aabb)) return;
+
+ //accept curves (and perform super detailed check for intersections)
+ //if the values are below tolerance
+
+ //NOTE FOR BETTERING OF ALGORITHM: SHOULD ALSO/IN-PLACE-OF CHECK MAGNITUDE OF EDGES (or approximate)
+ if(depth >= max_depth)
+ {
+ //NOTE FOR IMPROVEMENT: Polish roots based on original curve with the Jacobian
+ // (may be too expensive to be effective)
+
+ //perform root approximation
+ //collide line segments
+
+ float t,s;
+
+ for(int i = 0; i < 3; ++i)
+ {
+ for(int j = 0; j < 3; ++j)
+ {
+ //intersect line segmentsssss
+ if(intersect_line_segments(left.b[i],left.b[i+1],t,right.b[j],right.b[j+1],s))
+ {
+ //We got one Jimmy
+ times.push_back(intersect_set::value_type(t,s));
+ }
+ }
+ }
+
+ return;
+ }
+
+ //NOTE FOR IMPROVEMENT: only subdivide one curve and choose the one that has
+ // the highest approximated length
+ //fast approximation to curve length may be hard (accurate would
+ // involve 3 square roots), could sum the squares which would be
+ // quick but inaccurate
+
+ SCurve l1,r1,l2,r2;
+ left.Split(l1,r1); //subdivide left
+ right.Split(l2,r2); //subdivide right
+
+ //Test each cantidate against eachother
+ recurse_intersect(l1,l2);
+ recurse_intersect(l1,r2);
+ recurse_intersect(r1,l2);
+ recurse_intersect(r1,r2);
+}
+
+
+
+bool CIntersect::operator()(const bezier<Point> &c1, const bezier<Point> &c2)
+{
+ times.clear();
+
+ //need to subdivide and check recursive bounding regions against eachother
+ //so track a list of dirty curves and compare compare compare
+
+
+ //temporary curves for subdivision
+ CIntersect intersector;
+ CIntersect::SCurve left,right;
+
+ //Make sure the parameters are normalized (so we don't compare unwanted parts of the curves,
+ // and don't miss any for that matter)
+
+ //left curve
+ //Compile information about curve
+ clean_bez(c1,left.b);
+ left.rt = 0; left.st = 1;
+ Bound(left.aabb, left.b);
+
+ //right curve
+ //Compile information about right curve
+ clean_bez(c2,right.b);
+ right.rt = 0; right.st = 1;
+ Bound(right.aabb, right.b);
+
+ //Perform Curve intersection
+ intersector.recurse_intersect(left,right);
+
+ //Get information about roots (yay! :P)
+ return times.size() != 0;
+}
+
+//point inside curve - return +/- hit up or down edge
+int intersect_scurve(const CIntersect::SCurve &b, const Point &p)
+{
+ //initial reject/approve etc.
+
+ /*
+ *-----------*---------
+ | |
+ | |
+ | |
+ | 1 | 2
+ | |
+ | |
+ | |
+ | |
+ *-----------*--------
+ 1,2 are only regions not rejected
+ */
+ if(p[0] < b.aabb.minx || p[1] < b.aabb.miny || p[1] > b.aabb.maxy)
+ return 0;
+
+ //approve only if to the right of rect around 2 end points
+ {
+ Rect r;
+ r.set_point(b.b[0][0],b.b[0][1]);
+ r.expand(b.b[3][0],b.b[3][1]);
+
+ if(p[0] >= r.maxx && p[1] <= r.maxy && p[1] >= r.miny)
+ {
+ float df = b.b[3][1] - b.b[0][1];
+
+ return df >= 0 ? 1 : -1;
+ }
+ }
+
+ //subdivide and check again!
+ CIntersect::SCurve l,r;
+ b.Split(l,r);
+ return intersect_scurve(l,p) + intersect_scurve(r,p);
+}
+
+int synfig::intersect(const bezier<Point> &b, const Point &p)
+{
+ CIntersect::SCurve c(b,0,1);
+
+ return intersect_scurve(c,p);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file curve_helper.h
+** \brief Curve Helper Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_CURVE_HELPER_H
+#define __SYNFIG_CURVE_HELPER_H
+
+/* === H E A D E R S ======================================================= */
+#include <ETL/bezier>
+
+#include "rect.h"
+#include "real.h"
+#include "vector.h"
+
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+//line helper functions
+inline Real line_point_distsq(const Point &p1, const Point &p2,
+ const Point &p, float &t)
+{
+ Vector v,vt;
+
+ v = p2 - p1;
+ vt = p - p1;
+
+ t = v.mag_squared() > 1e-12 ? (vt*v)/v.mag_squared() : 0; //get the projected time value for the current line
+
+ //get distance to line segment with the time value clamped 0-1
+ if(t >= 1) //use p+v
+ {
+ vt += v; //makes it pp - (p+v)
+ t = 1;
+ }else if(t > 0) //use vt-proj
+ {
+ vt -= v * t; // vt - proj_v(vt) //must normalize the projection vector to work
+ }else
+ {
+ t = 0;
+ }
+
+ //else use p
+ return vt.mag_squared();
+}
+
+
+//----- RAY CLASS AND FUNCTIONS --------------
+struct Ray
+{
+ Point p;
+ Vector v;
+
+ Ray() {}
+ Ray(const Point &pin, const Vector &vin):p(pin), v(vin) {}
+};
+
+/* This algorithm calculates the INTERSECTION of 2 line segments
+ (not the closest point or anything like that, just intersection)
+ //parameter values returned are [0,1]
+*/
+int intersect(const Point &p1, const Vector &v1, float &t1,
+ const Point &p2, const Vector &v2, float &t2);
+
+inline bool intersect_line_segments(const Point &a, const Point &b, float &tout,
+ const Point &c, const Point &d, float &sout)
+{
+ Vector v1(b-a), v2(d-c);
+
+ //ok so treat both lines as parametric (so we can find the time values simultaneously)
+ float t,s;
+
+ if( intersect(a,v1,t, b,v2,s) && t >= 0 && t <= 1 && s >= 0 && s <= 1 )
+ {
+ tout = t;
+ sout = s;
+ return true;
+ }
+
+ return false;
+}
+
+//Find the closest point on the curve to a point (and return its distance, and time value)
+Real find_closest(const etl::bezier<Point> &curve, const Point &point, float step, Real *closest, float *t);
+
+//----------- Rectangle helper functions ---------------
+
+template < typename T >
+inline void Bound(etl::rect<T> &r, const etl::bezier<Point> &b)
+{
+ r.set_point(b[0][0],b[0][1]);
+ r.expand(b[1][0],b[1][1]);
+ r.expand(b[2][0],b[2][1]);
+ r.expand(b[3][0],b[3][1]);
+}
+
+/*template < typename T >
+inline bool intersect(const etl::rect<T> &r1, const etl::rect<T> &r2)
+{
+ return (r1.minx < r2.maxx) &
+ (r2.minx < r1.maxx) &
+ (r1.miny < r2.maxy) &
+ (r2.miny < r1.maxy);
+}*/
+
+//----- Convex Hull of a Bezier Curve --------------
+struct BezHull
+{
+ Point p[4];
+ int size;
+
+ void Bound(const etl::bezier<Point> &b);
+};
+
+//Line Intersection
+int intersect(const Rect &r1, const Point &p, const Vector &v);
+int intersect(const Rect &r1, const Point &p); //inside or to the right
+int intersect(const BezHull &bh, const Point &p, const Vector &v);
+//int intersect(const etl::bezier<Point> &b, const Point &p, const Vector &v);
+int intersect(const etl::bezier<Point> &b, const Point &p); //for use in containment tests for regions
+
+//Curve intersection object
+class CIntersect
+{
+public:
+ struct SCurve;
+private:
+ void recurse_intersect(const SCurve &left, const SCurve &right, int depth = 0);
+
+public:
+ //size should be equal
+ typedef std::vector< std::pair<float,float > > intersect_set;
+ intersect_set times;
+
+ int max_depth;
+
+ CIntersect();
+
+ bool operator()(const etl::bezier<Point> &b1, const etl::bezier<Point> &b2);
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file curveset.cpp
+** \brief Curve Set Implementation File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "curve_helper.h"
+#include "curveset.h"
+#include "blinepoint.h"
+#include <ETL/bezier>
+#include <vector>
+#include <list>
+#include <set>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+const Real ERROR = 1e-10;
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+template < typename T >
+inline bool Zero(const T &a, const T &tol = (T)ERROR)
+{
+ return a < tol && a > -tol;
+}
+
+CurvePoint::CurvePoint(const Point &pin, const Vector &left, const Vector &right)
+:p(pin),l(left),r(right)
+{
+}
+
+CurvePoint::CurvePoint(const BLinePoint &bpoint)
+{
+ p = bpoint.get_vertex();
+
+ l = p + bpoint.get_tangent1()*(1/3.0f);
+ r = p + bpoint.get_tangent2()*(1/3.0f);
+}
+
+struct ipoint
+{
+ int curveindex;
+ int vertindex;
+ float tvalue;
+
+ ipoint *next;
+ ipoint *prev;
+ ipoint *neighbor;
+
+ int go_in; //going in = 1, coming out = -1
+
+ ipoint()
+ {
+ next = this;
+ prev = this;
+ neighbor = 0;
+ }
+
+ bool operator<(const ipoint &rhs) const
+ {
+ if(curveindex == rhs.curveindex)
+ {
+ if(vertindex == rhs.vertindex)
+ {
+ return tvalue < rhs.tvalue;
+ }else return vertindex < rhs.vertindex;
+ }else return curveindex < rhs.curveindex;
+ }
+
+ bool operator >(const ipoint &rhs) const
+ {
+ return rhs < *this;
+ }
+
+ void insert_after(ipoint *i)
+ {
+ //from: next - next.prev
+ //to: next* - i - next.prev*
+
+ ipoint *bef = this,
+ *aft = next;
+
+ //assuming the input point is not connected to anything, we don't have to do anything with it...
+ bef->next = i;
+ i->prev = bef;
+ aft->prev = i;
+ i->next = aft;
+ }
+
+ void insert_before(ipoint *i)
+ {
+ //from: prev.next - prev
+ //to: prev.next* - i - prev*
+
+ ipoint *bef = prev,
+ *aft = this;
+
+ //assuming the input point is not connected to anything, we don't have to do anything with it...
+ bef->next = i;
+ i->prev = bef;
+ aft->prev = i;
+ i->next = aft;
+ }
+
+ void insert_sorted(ipoint *i)
+ {
+ ipoint *search = this;
+
+ if(*i < *this)
+ {
+ //we go forward
+ search = this;
+ do
+ {
+ search = search->next;
+ }while(*i < *search && search != this); //ending conditions...
+
+ //now we insert previously...
+ search->insert_before(i);
+ }else if(*i > *this)
+ {
+ //we go backwards...
+ search = this;
+ do
+ {
+ search = search->prev;
+ }while(*i > *search && search != this); //ending conditions...
+
+ //now we insert previously...
+ search->insert_after(i);
+ }
+ }
+};
+
+enum SetOp
+{
+ INTERSECT = 0,
+ UNION,
+ SUBTRACT,
+ INVSUBTRACT,
+ NUM_SETOPERATIONS
+};
+
+class PolygonClipper
+{
+public:
+ typedef vector<ipoint *> CurveInts; //in no particular order
+
+ vector<CurveInts> c1ints;
+ vector<CurveInts> c2ints;
+
+ //get the intersections
+ void GetIntersections(const CurveSet &lhs, const CurveSet &rhs)
+ {
+ CIntersect isect;
+ bezier<Point> b1,b2;
+
+ int i1,j1,ci1,s1;
+ int i2,j2,ci2,s2;
+
+ //clear out so everyone's happy
+ c1ints.clear();
+ c2ints.clear();
+
+ c1ints.resize(lhs.set.size());
+ c2ints.resize(rhs.set.size());
+
+ //loop through everyone and be happy...
+
+ //intersect each curve with each other curve, and we're good
+ for(ci1=0;ci1 < (int)lhs.set.size(); ++ci1)
+ {
+ const CurveSet::region &cur1 = lhs.set[ci1];
+ s1 = cur1.size();
+ for(j1 = s1-1, i1=0; i1 < s1; j1 = i1++)
+ {
+ b1[0] = cur1[j1].p;
+ b1[3] = cur1[i1].p;
+ b1[1] = b1[0] + cur1[j1].r/3;
+ b1[2] = b1[3] - cur1[i1].l/3;
+
+ for(ci2=0;ci2 < (int)rhs.set.size(); ++ci2)
+ {
+ const CurveSet::region &cur2 = rhs.set[ci2];
+ s2 = cur2.size();
+ for(j2 = s2-1, i2=0; i2 < s2; j2 = i2++)
+ {
+ b2[0] = cur2[j2].p;
+ b2[3] = cur2[i2].p;
+ b2[1] = b2[0] + cur2[j2].r/3;
+ b2[2] = b2[3] - cur2[i2].l/3;
+
+ isect(b1,b2);
+
+ for(int index=0; index < (int)isect.times.size(); ++index)
+ {
+ //prepare basic intersection information
+ ipoint *ip1 = new ipoint, *ip2 = new ipoint;
+
+ //set parameters
+ ip1->curveindex = ci1; ip1->vertindex = j1; ip1->tvalue = isect.times[index].first;
+ ip2->curveindex = ci2; ip2->vertindex = j2; ip2->tvalue = isect.times[index].second;
+
+ //set neighbors
+ ip1->neighbor = ip2;
+ ip2->neighbor = ip1;
+
+ //first one just goes on end of list
+ c1ints[ci1].back()->insert_sorted(ip1);
+ c1ints[ci1].push_back(ip1);
+
+ //second one must go in order
+ c2ints[ci2].back()->insert_sorted(ip2);
+ c2ints[ci2].push_back(ip2);
+
+ //we're all good...
+ }
+ }
+ }
+ }
+ }
+
+ //Now figure out the containment properties of each int point
+ Point p;
+ int inside = 0;
+ for(int i = 0; i < (int)c1ints.size(); ++i)
+ {
+ if(c1ints[i].size() == 0) continue;
+
+ //must test insideness for the edges
+ ipoint *start, *iter;
+ start = iter = c1ints[i].front();
+
+ //i == iter->curveindex == the index of the current curve we're looking at
+
+ //set the initial insideness on the other curve...
+ p = lhs.set[i][iter->vertindex].p;
+ inside = rhs.intersect(p)%2; //if it's inside by the even odd rule
+
+ do
+ {
+ iter->go_in = inside? -1 : 1; //leaving if inside, or coming in if not
+ inside = !inside;
+ iter = iter->next;
+ }while(iter != start); //I hope this isn't an infinite loop!
+ }
+
+ //and curve 2
+ for(int i = 0; i < (int)c2ints.size(); ++i)
+ {
+ if(c2ints[i].size() == 0) continue;
+
+ //must test insideness for the edges
+ ipoint *start, *iter;
+ start = iter = c1ints[i].front();
+
+ //set the initial insideness on the other curve...
+ p = rhs.set[i][iter->vertindex].p;
+ inside = lhs.intersect(p)%2; //if it's inside by the even odd rule
+
+ do
+ {
+ iter->go_in = inside? -1 : 1; //leaving if inside, or coming in if not
+ inside = !inside;
+ iter = iter->next;
+ }while(iter != start); //I hope this isn't an infinite loop!
+ }
+ }
+
+ bool ConstructSet(CurveSet &/*c*/, const CurveSet &lhs, const CurveSet &rhs, int type)
+ {
+ bool in1,in2;
+
+ switch(type)
+ {
+ case INTERSECT: //1&2
+ {
+ in1 = true; in2 = true;
+ break;
+ }
+
+ case UNION: //1|2
+ {
+ in1 = false; in2 = false;
+ break;
+ }
+
+ case SUBTRACT: //1-2
+ {
+ in1 = true; in2 = false;
+ break;
+ }
+
+ case INVSUBTRACT: //2-1
+ {
+ in1 = false; in2 = true;
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ //traverse path based on inside flags
+
+ //fill all the paths of native stuff
+ set<ipoint *> ipset;
+ for(int ci=0; ci<(int)c1ints.size(); ++ci)
+ {
+ for(int i=0; i < (int)c1ints[ci].size(); ++i)
+ {
+ ipset.insert(c1ints[ci][i]);
+ }
+ }
+
+ //
+ while(ipset.size() > 0)
+ {
+ //start from one point (always on curveset 1) and traverse until we find it again
+ ipoint *start, *iter;
+ start = iter = *ipset.begin();
+
+ //All the info to swap when we transition curves...
+ const CurveSet *cur, *other;
+ bool curin, otherin;
+ bool delcur = true;
+
+ set<ipoint *>::iterator deliter;
+
+ int ci,i1,i2,size;
+ float t1,t2;
+
+ CurveSet::region current;
+ CurvePoint cp;
+
+ cur = &lhs; other = &rhs;
+ curin = in1; otherin = in2;
+ delcur = true;
+
+ do
+ {
+ //remove the current iter from the set
+ if(delcur)
+ {
+ deliter = ipset.find(iter);
+ if(deliter != ipset.end()) ipset.erase(deliter);
+ }
+
+ //go to next and accumulate information
+ ci = iter->curveindex;
+ i1 = iter->vertindex;
+ t1 = iter->tvalue;
+ iter = iter->next; //move to next and get its info
+
+ i2 = iter->vertindex;
+ t2 = iter->tvalue;
+
+ size = cur->set[ci].size();
+
+ //record all the stuff between us...
+ //start on an intersection - get the curve point...
+
+
+ //transition curves...
+ iter = iter->neighbor;
+ swap(cur,other);
+ swap(curin,otherin);
+ delcur = !delcur;
+ }while(iter != start); //I hope THIS isn't an infinite loop
+ }
+
+ return true;
+ }
+};
+
+void CurveSet::SetClamp(int &i, int &si)
+{
+ if(si > 0 && si < (int)set.size())
+ {
+ if(i >= (int)set[si].size())
+ {
+ i -= set[si].size();
+ si++;
+ }else if (i < 0)
+ {
+ i += set[si].size();
+ si--;
+ }
+ }
+}
+
+void CurveSet::CleanUp(int /*curve*/)
+{
+}
+
+/* Detect intersections that are crazy happy good
+
+ Performance annoyances:
+ 1) Recursing down to find an intersection at the end points that doesn't actually exist
+ (can be helped a bit by not including the edges of bouding rectaingles)
+ 2) Intersecting curves is slow... oh well
+
+ Algorithm:
+ 1) Inside out scheme, track when edges go into and come out of various objects etc.
+
+ + doesn't require initial conditions
+ - only works with odd-even rule
+*/
+
+CurveSet CurveSet::operator &(const CurveSet &/*rhs*/) const
+{
+ return *this;
+}
+
+CurveSet CurveSet::operator |(const CurveSet &/*rhs*/) const
+{
+ return *this;
+}
+
+CurveSet CurveSet::operator -(const CurveSet &/*rhs*/) const
+{
+ return *this;
+}
+
+int CurveSet::intersect(const Point &p) const
+{
+ int inter = 0, ci,i,j,s;
+ bezier<Point> b;
+
+ for(ci=0; ci < (int)set.size(); ++ci)
+ {
+ const vector<CurvePoint> &curve = set[ci];
+ s = curve.size();
+ for(j=s-1,i=0; i < s; j = i++)
+ {
+ b[0] = curve[j].p; b[3] = curve[i].p;
+ b[1] = b[0] + curve[j].r/3; b[2] = b[3] - curve[i].l/3;
+
+ inter += synfig::intersect(b,p);
+ }
+ }
+
+ return inter;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file curveset.h
+** \brief Curve Set Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_CURVESET_H
+#define __SYNFIG_CURVESET_H
+
+/* === H E A D E R S ======================================================= */
+#include "blinepoint.h"
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+namespace synfig
+{
+
+class BLinePoint;
+
+struct CurvePoint
+{
+ Point p;
+ Point l,r;
+
+ CurvePoint () {}
+ CurvePoint(const Point &pin, const Vector &left, const Vector &right);
+
+ CurvePoint(const BLinePoint &bpoint);
+};
+
+class CurveSet
+{
+ bool invert; //winding order...
+
+ void CleanUp(int curve = 0);
+public:
+
+ typedef std::vector<CurvePoint> region;
+ typedef std::vector<region> set_type;
+
+ set_type set; //specifies a region object (assumes looping)
+
+ void SetClamp(int &i, int &si);
+
+ //actual stuff
+ CurveSet()
+ {
+ }
+
+ //anything supporting iterator type operations
+ template < typename Iterator >
+ CurveSet(Iterator begin, Iterator end, bool invert = false)
+ {
+ set.push_back(std::vector<CurvePoint>(begin,end));
+ CleanUp(invert);
+ }
+
+ CurveSet operator &(const CurveSet &rhs) const; //intersect
+ CurveSet operator |(const CurveSet &rhs) const; //union
+ CurveSet operator -(const CurveSet &rhs) const; //subtract
+
+
+ //Point containment
+ int intersect(const Point &p) const;
+};
+
+}
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file distance.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "distance.h"
+#include "renddesc.h"
+#include "general.h"
+#include <ctype.h>
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+#define POINTS_PER_INCH (72.0)
+
+/* === G L O B A L S ======================================================= */
+
+#define METERS_PER_UNIT (rend_desc.get_physical_w()/abs(rend_desc.get_tl()[0]-rend_desc.get_br()[0]))
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Distance::Distance(const synfig::String& str)
+{
+ (*this)=str;
+/* int i(0);
+ float val;
+ int ret(strscanf(str,"%f%n",&val,&i));
+ synfig::info("Distance::Distance(): ret=%d, val=%f",ret,val);
+
+ if(ret<=0)
+ {
+ // Error
+ synfig::error("Distance::Distance(): Bad value \"%s\"",str.c_str());
+ value_=0;
+ }
+ else
+ value_=val;
+
+ synfig::info("Distance::Distance(): system=\"%s\"",String(str.begin()+i,str.end()).c_str());
+ system_=ident_system(String(str.begin()+i,str.end()));
+*/
+}
+
+Distance&
+Distance::operator=(const synfig::String& str)
+{
+ int i(0);
+ float val;
+ int ret(strscanf(str,"%f%n",&val,&i));
+ // synfig::info("Distance::Distance(): ret=%d, val=%f",ret,val);
+
+ if(ret<=0)
+ {
+ // Error
+ synfig::error("Distance::Distance(): Bad value \"%s\"",str.c_str());
+ return *this;
+ }
+ else
+ value_=val;
+
+ synfig::String sys(str.begin()+i,str.end());
+
+ if(sys.size())
+ system_=ident_system(sys);
+ return *this;
+}
+
+synfig::String
+Distance::get_string(int digits)const
+{
+ digits=min(9,max(0,digits));
+ String fmt(strprintf("%%.%01df%%s",digits));
+ return strprintf(fmt.c_str(),value_,system_name(system_).c_str());
+}
+
+void
+Distance::convert(Distance::System target, const RendDesc& rend_desc)
+{
+ value_=get(target,rend_desc);
+ system_=target;
+}
+
+Real
+Distance::get(Distance::System target, const RendDesc& rend_desc)const
+{
+ if(target==SYSTEM_UNITS)
+ return units(rend_desc);
+ if(target==SYSTEM_PIXELS)
+ return units(rend_desc)*METERS_PER_UNIT*rend_desc.get_x_res();
+
+ return meters_to_system(meters(rend_desc),target);
+}
+
+Real
+Distance::meters()const
+{
+ switch(system_)
+ {
+ case SYSTEM_INCHES: return value_/39.3700787402;
+ case SYSTEM_POINTS: return value_/POINTS_PER_INCH/39.3700787402;
+ case SYSTEM_METERS: return value_;
+ case SYSTEM_CENTIMETERS: return value_/100.0;
+ case SYSTEM_MILLIMETERS: return value_/1000.0;
+ default: throw BadSystem();
+ }
+}
+
+Real
+Distance::meters(const RendDesc& rend_desc)const
+{
+ if(system_>SYSTEM_PIXELS)
+ return meters();
+ if(system_==SYSTEM_UNITS)
+ return value_*METERS_PER_UNIT;
+ if(system_==SYSTEM_PIXELS)
+ return value_/rend_desc.get_x_res();
+
+ throw BadSystem();
+}
+
+Real
+Distance::units(const RendDesc& rend_desc)const
+{
+ if(system_==SYSTEM_UNITS)
+ return value_;
+
+ Real ret;
+
+ if(system_>SYSTEM_PIXELS)
+ ret=meters();
+ else
+ ret=value_/rend_desc.get_x_res();
+
+ return ret/METERS_PER_UNIT;
+}
+
+
+Real // (static)
+Distance::meters_to_system(Real x,System target_system)
+{
+ switch(target_system)
+ {
+ case SYSTEM_INCHES: return x*39.3700787402;
+ case SYSTEM_POINTS: return x*39.3700787402*POINTS_PER_INCH;
+ case SYSTEM_METERS: return x;
+ case SYSTEM_CENTIMETERS: return x*100.0;
+ case SYSTEM_MILLIMETERS: return x*1000.0;
+ default: throw BadSystem();
+ }
+}
+
+Distance::System // (static)
+Distance::ident_system(const synfig::String& x)
+{
+ synfig::String str;
+
+ // Make it all upper case, and remove white space
+ for(unsigned int i=0;i<x.size();i++)if(x[i]!=' ' && x[i]!='\t')str+=toupper(x[i]);
+
+ // If it is plural, make it singular
+ if(str[str.size()-1]=='S')
+ str=synfig::String(str.begin(),str.end()-1);
+
+ if(str.empty() || str=="U" || str=="UNIT")
+ return SYSTEM_UNITS;
+ if(str=="PX" || str=="PIXEL")
+ return SYSTEM_PIXELS;
+ if(str=="PT" || str=="POINT")
+ return SYSTEM_POINTS;
+ if(str=="IN" || str=="\"" || str=="INCHE" || str=="INCH")
+ return SYSTEM_INCHES;
+ if(str=="M" || str=="METER")
+ return SYSTEM_METERS;
+ if(str=="CM" || str=="CENTIMETER")
+ return SYSTEM_CENTIMETERS;
+ if(str=="MM" || str=="MILLIMETER")
+ return SYSTEM_MILLIMETERS;
+
+ synfig::warning("Distance::ident_system(): Unknown distance system \"%s\"",x.c_str());
+
+ return SYSTEM_UNITS;
+}
+
+synfig::String // (static)
+Distance::system_name(Distance::System system)
+{
+ switch(system)
+ {
+ case SYSTEM_UNITS: return "u";
+ case SYSTEM_PIXELS: return "px";
+ case SYSTEM_POINTS: return "pt";
+ case SYSTEM_INCHES: return "in";
+ case SYSTEM_METERS: return "m";
+ case SYSTEM_MILLIMETERS: return "mm";
+ case SYSTEM_CENTIMETERS: return "cm";
+
+ default: throw BadSystem();
+ }
+ return synfig::String();
+}
+
+synfig::String // (static)
+Distance::system_local_name(Distance::System system)
+{
+ switch(system)
+ {
+ case SYSTEM_UNITS: return _("Units");
+ case SYSTEM_PIXELS: return _("Pixels");
+ case SYSTEM_POINTS: return _("Points");
+ case SYSTEM_INCHES: return _("Inches");
+ case SYSTEM_METERS: return _("Meters");
+ case SYSTEM_MILLIMETERS:return _("Millimeters");
+ case SYSTEM_CENTIMETERS:return _("Centimeters");
+
+ default: throw BadSystem();
+ }
+ return synfig::String();
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file distance.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_DISTANCE_H
+#define __SYNFIG_DISTANCE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "real.h"
+#include "string.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class RendDesc;
+
+class Distance
+{
+public:
+ typedef Real value_type;
+
+ enum System
+ {
+ SYSTEM_UNITS, //!<
+ SYSTEM_PIXELS, //!<
+
+ SYSTEM_POINTS, //!<
+ SYSTEM_INCHES, //!<
+ SYSTEM_METERS, //!<
+ SYSTEM_MILLIMETERS, //!<
+ SYSTEM_CENTIMETERS, //!<
+
+ SYSTEM_END //!< \internal
+ };
+
+ class BadSystem { };
+
+private:
+ value_type value_;
+
+ System system_;
+
+
+public:
+
+ Distance(){ }
+ Distance(const value_type& value, System system):value_(value),system_(system) { }
+ explicit Distance(const synfig::String& string);
+
+ operator Real()const { return value_; }
+
+ Distance& operator=(const Real& rhs) { value_=rhs; return *this; }
+
+ Distance& operator=(const synfig::String& rhs);
+
+ synfig::String get_string(int digits=4)const;
+
+ const System& get_system()const { return system_; }
+
+ const Real& get()const { return value_; }
+
+ Real get(System system, const RendDesc& rend_desc)const;
+
+ void convert(System system, const RendDesc& rend_desc);
+
+ Real meters()const;
+ Real meters(const RendDesc& rend_desc)const;
+ Real units(const RendDesc& rend_desc)const;
+
+ static Real meters_to_system(Real x, System target_system);
+ static System ident_system(const synfig::String& str);
+ static synfig::String system_name(System system);
+ static synfig::String system_local_name(System system);
+
+ const Distance& operator+=(const Distance &rhs) { value_+=meters_to_system(rhs.meters(),system_); return *this; }
+ const Distance& operator-=(const Distance &rhs) { value_-=meters_to_system(rhs.meters(),system_); return *this; }
+
+ const Distance& operator+=(const float &rhs) { value_+=rhs; return *this; }
+ const Distance& operator-=(const float &rhs) { value_-=rhs; return *this; }
+ const Distance& operator*=(const float &rhs) { value_*=rhs; return *this; }
+ const Distance& operator/=(const float &rhs) { value_/=rhs; return *this; }
+
+/*
+ template<typename U> const Time& operator+=(const U &rhs) { value_+=rhs; return *this; }
+ template<typename U> const Time& operator-=(const U &rhs) { value_-=rhs; return *this; }
+ template<typename U> const Time& operator*=(const U &rhs) { value_*=rhs; return *this; }
+ template<typename U> const Time& operator/=(const U &rhs) { value_/=rhs; return *this; }
+
+ template<typename U> Time operator+(const U &rhs)const { return value_+rhs; }
+ template<typename U> Time operator-(const U &rhs)const { return value_-rhs; }
+ template<typename U> Time operator*(const U &rhs)const { return value_*rhs; }
+ template<typename U> Time operator/(const U &rhs)const { return value_/rhs; }
+
+ Time operator-()const { return -value_; }
+*/
+}; // END of class Distance
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file exception.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "exception.h"
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Exception::BadLinkName::BadLinkName(const String &what):
+ std::runtime_error(what)
+// std::runtime_error(_("Bad Link Name")+what.empty()?"":(String(": ")+what))
+{
+ synfig::error("EXCEPTION: bad link name: "+what);
+}
+
+Exception::BadType::BadType(const String &what):
+ std::runtime_error(what)
+// std::runtime_error(_("Bad Type")+what.empty()?"":(String(": ")+what))
+{
+ synfig::error("EXCEPTION: bad type: "+what);
+}
+
+Exception::BadFrameRate::BadFrameRate(const String &what):
+ std::runtime_error(what)
+// std::runtime_error(_("Bad Link Name")+what.empty()?"":(String(": ")+what))
+{
+ synfig::error("EXCEPTION: bad frame rate: "+what);
+}
+
+Exception::BadTime::BadTime(const String &what):
+ std::runtime_error(what)
+// std::runtime_error(_("Bad Link Name")+what.empty()?"":(String(": ")+what))
+{
+ synfig::error("EXCEPTION: bad time: "+what);
+}
+
+Exception::NotFound::NotFound(const String &what):
+ std::runtime_error(what)
+// std::runtime_error(_("Not Found")+what.empty()?"":(String(": ")+what))
+{
+// synfig::error("EXCEPTION: not found: "+what);
+}
+
+Exception::IDNotFound::IDNotFound(const String &what):
+ NotFound(what)
+// std::runtime_error(_("Not Found")+what.empty()?"":(String(": ")+what))
+{
+// synfig::error("EXCEPTION: not found: "+what);
+}
+
+Exception::FileNotFound::FileNotFound(const String &what):
+ NotFound(what)
+// std::runtime_error(_("Not Found")+what.empty()?"":(String(": ")+what))
+{
+ synfig::error("EXCEPTION: file not found: "+what);
+}
+
+Exception::IDAlreadyExists::IDAlreadyExists(const String &what):
+ std::runtime_error(what)
+// std::runtime_error(_("ID Already Exists")+what.empty()?"":(String(": ")+what))
+{
+ synfig::error("EXCEPTION: id already exists: "+what);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file exception.h
+** \brief Exceptions
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_EXCEPTION_H
+#define __SYNFIG_EXCEPTION_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <stdexcept>
+#include "string_decl.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+namespace Exception {
+
+class BadLinkName : public std::runtime_error
+{
+public:
+ BadLinkName(const String &what);
+}; // END of class BadLinkName
+
+class BadType : public std::runtime_error
+{
+public:
+ BadType(const String &what);
+}; // END of class BadType
+
+class IDAlreadyExists : public std::runtime_error
+{
+public:
+ IDAlreadyExists(const String &what);
+};
+
+class NotFound : public std::runtime_error
+{
+public:
+ NotFound(const String &what);
+};
+
+class IDNotFound : public NotFound
+{
+public:
+ IDNotFound(const String &what);
+};
+
+class FileNotFound : public NotFound
+{
+public:
+ FileNotFound(const String &what);
+};
+
+class BadTime : public std::runtime_error
+{
+public:
+ BadTime(const String &what);
+};
+
+class BadFrameRate : public std::runtime_error
+{
+public:
+ BadFrameRate(const String &what);
+};
+
+}; // END of namespace Exception
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file gamma.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "gamma.h"
+#include <cmath>
+#include <algorithm>
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+//using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+void
+Gamma::set_gamma(float x)
+{
+ gamma_r=gamma_g=gamma_b=x;
+ int i;
+ red_blue_level=1.0f;
+ for(i=0;i<65536;i++)
+ {
+ float f(float(i)/65536.0f);
+ f=pow(f,gamma_r);
+ table_r_U16_to_U8[i]=table_g_U16_to_U8[i]=table_b_U16_to_U8[i]=(unsigned char)(f*(255.0f-(black_level*255))+0.5f + black_level*255.0f);
+ }
+
+ for(i=0;i<256;i++)
+ table_r_U8_to_F32[i]=table_g_U8_to_F32[i]=table_b_U8_to_F32[i]=pow((float(i)/255.0f)*(1.0f-black_level)+black_level,gamma_r);
+}
+
+
+void
+Gamma::refresh_gamma_r()
+{
+ int i;
+// const float scalar(min(red_blue_level,1.0f));
+ const float scalar(1.0f);
+ for(i=0;i<65536;i++)
+ {
+ float f(float(i)/65536.0f);
+ f=pow(f,gamma_r)*scalar;
+ table_r_U16_to_U8[i]=(unsigned char)(f*(255.0f-(black_level*255))+0.5f + black_level*255.0f);
+ }
+
+ for(i=0;i<256;i++)
+ table_r_U8_to_F32[i]=pow((float(i)/255.0f)*(1.0f-black_level)+black_level,gamma_r)*scalar;
+}
+
+void
+Gamma::refresh_gamma_g()
+{
+ int i;
+// const float scalar(sqrt(min(red_blue_level,2.0f-red_blue_level)));
+ const float scalar(1.0f);
+ for(i=0;i<65536;i++)
+ {
+ float f(float(i)/65536.0f);
+ f=pow(f,gamma_g)*scalar;
+ table_g_U16_to_U8[i]=(unsigned char)(f*(255.0f-(black_level*255))+0.5f + black_level*255.0f);
+ }
+ for(i=0;i<256;i++)
+ table_g_U8_to_F32[i]=pow((float(i)/255.0f)*(1.0f-black_level)+black_level,gamma_g)*scalar;
+}
+
+void
+Gamma::refresh_gamma_b()
+{
+ int i;
+// const float scalar(min(2.0f-red_blue_level,1.0f));
+ const float scalar(1.0f);
+ for(i=0;i<65536;i++)
+ {
+ float f(float(i)/65536.0f);
+ f=pow(f,gamma_b)*scalar;
+ table_b_U16_to_U8[i]=(unsigned char)(f*(255.0f-(black_level*255))+0.5f + black_level*255.0f);
+ }
+ for(i=0;i<256;i++)
+ table_b_U8_to_F32[i]=pow((float(i)/255.0f)*(1.0f-black_level)+black_level,gamma_b)*scalar;
+}
+
+void
+Gamma::set_gamma_r(float x)
+{
+ // If the gamma hasn't changed, then don't recompute the tables
+ if(x==gamma_r) return;
+
+ gamma_r=x;
+ refresh_gamma_r();
+}
+
+void
+Gamma::set_gamma_g(float x)
+{
+ // If the gamma hasn't changed, then don't recompute the tables
+ if(x==gamma_g) return;
+
+ gamma_g=x;
+ refresh_gamma_g();
+}
+
+void
+Gamma::set_gamma_b(float x)
+{
+ // If the gamma hasn't changed, then don't recompute the tables
+ if(x==gamma_b) return;
+
+ gamma_b=x;
+ refresh_gamma_b();
+}
+
+void
+Gamma::set_black_level(float x)
+{
+ // If the black_level hasn't changed, then don't recompute the tables
+ if(x==black_level) return;
+
+ black_level=x;
+
+ // Rebuild tables
+ refresh_gamma_r();
+ refresh_gamma_g();
+ refresh_gamma_b();
+}
+
+void
+Gamma::set_red_blue_level(float x)
+{
+ // If the black_level hasn't changed, then don't recompute the tables
+ if(x==red_blue_level) return;
+
+ red_blue_level=x;
+
+ // Rebuild tables
+ refresh_gamma_r();
+ refresh_gamma_g();
+ refresh_gamma_b();
+}
+
+void
+Gamma::set_all(float r, float g, float b, float black, float red_blue)
+{
+ // If nothing has changed, then don't recompute the tables
+ if(gamma_r==r && gamma_g==g && gamma_b==b && black_level==black && red_blue_level==red_blue)
+ return;
+
+ gamma_r=r;
+ gamma_g=g;
+ gamma_b=b;
+ black_level=black;
+ red_blue_level=red_blue;
+
+ // Rebuild tables
+ refresh_gamma_r();
+ refresh_gamma_g();
+ refresh_gamma_b();
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file gamma.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_GAMMA_H
+#define __SYNFIG_GAMMA_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <cmath>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class Gamma
+** \brief This class performs color correction on Color classes.
+** \stub
+*/
+class Gamma
+{
+ float gamma_r;
+ float gamma_g;
+ float gamma_b;
+ float black_level;
+ float red_blue_level;
+
+ unsigned char table_r_U16_to_U8[65536];
+ unsigned char table_g_U16_to_U8[65536];
+ unsigned char table_b_U16_to_U8[65536];
+
+ float table_r_U8_to_F32[256];
+ float table_g_U8_to_F32[256];
+ float table_b_U8_to_F32[256];
+
+public:
+ Gamma(float x=1):black_level(0) { set_gamma(x); }
+
+ void set_gamma(float x);
+ void set_gamma_r(float x);
+ void set_gamma_g(float x);
+ void set_gamma_b(float x);
+ void set_black_level(float x);
+
+ void set_red_blue_level(float x);
+ void set_all(float r, float g, float b, float black, float red_blue=1.0f);
+
+ float get_gamma()const { return (gamma_r+gamma_g+gamma_b)*0.33333333; }
+ float get_gamma_r()const { return gamma_r; }
+ float get_gamma_g()const { return gamma_g; }
+ float get_gamma_b()const { return gamma_b; }
+ float get_black_level()const { return black_level; }
+ float get_red_blue_level()const { return red_blue_level; }
+
+ void refresh_gamma_r();
+ void refresh_gamma_g();
+ void refresh_gamma_b();
+
+ const unsigned char &r_U16_to_U8(int i)const { return table_r_U16_to_U8[i]; }
+ const unsigned char &g_U16_to_U8(int i)const { return table_g_U16_to_U8[i]; }
+ const unsigned char &b_U16_to_U8(int i)const { return table_b_U16_to_U8[i]; }
+
+ const unsigned char &r_F32_to_U8(float x)const { return table_r_U16_to_U8[(int)(x*65535.0f)]; }
+ const unsigned char &g_F32_to_U8(float x)const { return table_g_U16_to_U8[(int)(x*65535.0f)]; }
+ const unsigned char &b_F32_to_U8(float x)const { return table_b_U16_to_U8[(int)(x*65535.0f)]; }
+
+ unsigned short r_F32_to_U16(float x)const { return (unsigned short)table_r_U16_to_U8[(int)(x*65535.0f)]<<8; }
+ unsigned short g_F32_to_U16(float x)const { return (unsigned short)table_g_U16_to_U8[(int)(x*65535.0f)]<<8; }
+ unsigned short b_F32_to_U16(float x)const { return (unsigned short)table_b_U16_to_U8[(int)(x*65535.0f)]<<8; }
+
+ const float& r_U8_to_F32(int i)const { return table_r_U8_to_F32[i]; }
+ const float& g_U8_to_F32(int i)const { return table_g_U8_to_F32[i]; }
+ const float& b_U8_to_F32(int i)const { return table_b_U8_to_F32[i]; }
+
+ float r_F32_to_F32(float x)const { return static_cast<float>(pow(x,gamma_r)*(1.0f-black_level)+black_level); }
+ float g_F32_to_F32(float x)const { return static_cast<float>(pow(x,gamma_g)*(1.0f-black_level)+black_level); }
+ float b_F32_to_F32(float x)const { return static_cast<float>(pow(x,gamma_b)*(1.0f-black_level)+black_level); }
+}; // END of class Gamma
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file general.h
+** \brief General macros, classes, and procedure declarations
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_GENERAL_H
+#define __SYNFIG_GENERAL_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/stringf>
+#include "string.h"
+#include "version.h"
+#include <locale.h>
+
+/* === M A C R O S ========================================================= */
+
+// Quick hack to keep stuff working until gettext support is added
+#ifndef _
+#define _(x) (x)
+#define N_(x) (x)
+//#define gettext(x) (x)
+#endif
+
+#define SYNFIG_COPYRIGHT "Copyright (c) 2001-2005 Robert B. Quattlebaum Jr., Adrian Bentley"
+
+
+#ifdef _DEBUG
+#ifdef __FUNC__
+#define DEBUGPOINT() synfig::warning(etl::strprintf(__FILE__":"__FUNC__":%d DEBUGPOINT",__LINE__))
+#define DEBUGINFO(x) synfig::warning(etl::strprintf(__FILE__":"__FUNC__":%d:DEBUGINFO:",__LINE__)+x)
+#else
+#define DEBUGPOINT() synfig::warning(etl::strprintf(__FILE__":%d DEBUGPOINT",__LINE__))
+#define DEBUGINFO(x) synfig::warning(etl::strprintf(__FILE__":%d:DEBUGINFO:",__LINE__)+x)
+#endif
+
+#else
+#define DEBUGPOINT()
+#define DEBUGINFO(x)
+#endif
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ChangeLocale {
+ const String previous;
+ const int category;
+public:
+ ChangeLocale(int category, const char *locale):
+ previous(setlocale(category,locale)),category(category)
+ {
+ }
+ ~ChangeLocale() {
+ setlocale(category,previous.c_str());
+ }
+};
+
+/*! \class ProgressCallback
+** \todo writeme
+*/
+class ProgressCallback
+{
+public:
+
+ virtual ~ProgressCallback() { }
+ virtual bool task(const String &/*task*/) { return true; }
+ virtual bool error(const String &/*task*/) { return true; }
+ virtual bool warning(const String &/*task*/) { return true; }
+ virtual bool amount_complete(int /*current*/, int /*total*/) { return true; }
+
+ virtual bool valid() const { return true; }
+};
+
+typedef ProgressCallback ProgressManager;
+
+/*! \class SuperCallback
+** \todo writeme
+*/
+class SuperCallback : public ProgressCallback
+{
+ ProgressCallback *cb;
+ int start,end,tot;
+ int w;
+public:
+
+ SuperCallback() { cb=NULL; }
+ SuperCallback(ProgressCallback *cb,int start, int end, int total):cb(cb),start(start),end(end),tot(total)
+ {
+ //make sure we don't "inherit" if our subcallback is invalid
+ if(!cb || !cb->valid())
+ cb = NULL;
+ w=end-start;
+ }
+ virtual bool task(const String &task) { if(cb)return cb->task(task); return true; }
+ virtual bool error(const String &task) { if(cb)return cb->error(task); return true; }
+ virtual bool warning(const String &task) { if(cb)return cb->warning(task); return true; }
+ virtual bool amount_complete(int cur, int total) { if(cb)return cb->amount_complete(start+cur*w/total,tot); return true; }
+
+ virtual bool valid() const { return cb != 0; }
+};
+
+/*! \class SoftwareExpired
+** \brief This class is thrown when the software timeout has been reached.
+*/
+class SoftwareExpired
+{
+}; // END of class SoftwareExpired
+
+
+#ifdef DEATH_TIME
+inline void CHECK_EXPIRE_TIME() { if(time(0)>DEATH_TIME) throw SoftwareExpired(); }
+#else
+#define CHECK_EXPIRE_TIME() while(0){ }
+#endif
+
+/*
+extern bool add_to_module_search_path(const std:string &path);
+extern bool add_to_config_search_path(const std:string &path);
+*/
+
+//! Shutdown the synfig environment
+extern void shutdown();
+
+//! Reports an error
+/*! Call this when an error occurs, describing what happened */
+extern void error(const char *format,...);
+extern void error(const String &str);
+
+//! Reports a warning
+/*! Call this when something questionable occurs, describing what happened */
+extern void warning(const char *format,...);
+extern void warning(const String &str);
+
+//! Reports some information
+/*! Call this to report various information. Please be sparse... */
+extern void info(const char *format,...);
+extern void info(const String &str);
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file gradient.cpp
+** \brief Color Gradient Class Member Definitions
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "gradient.h"
+#include "general.h"
+#include <stdexcept>
+#include "exception.h"
+#include <algorithm>
+
+#include <ETL/misc>
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+synfig::Gradient::Gradient(const Color &c1, const Color &c2)
+{
+ push_back(CPoint(0.0,c1));
+ push_back(CPoint(1.0,c2));
+}
+
+synfig::Gradient::Gradient(const Color &c1, const Color &c2, const Color &c3)
+{
+ push_back(CPoint(0.0,c1));
+ push_back(CPoint(0.5,c2));
+ push_back(CPoint(1.0,c3));
+}
+
+// This sort algorithm MUST be stable
+// ie: it must not change the order of items with the same value.
+// I am using a bubble sort.
+// This algorithm will sort a nearly-sorted list at ~O(N), and
+// it will sort an inverse sorted list at ~O(N*N).
+void
+synfig::Gradient::sort()
+{
+ stable_sort(begin(),end());
+ /*
+ iterator iter;
+ iterator iter2,next;
+
+ for(iter=begin();iter!=end();iter++)
+ {
+ for(next=iter, iter2=next--;iter2!=begin();iter2=next--)
+ {
+ if(*iter<*next)
+ {
+ //insert(next,*iter);
+ //erase(iter);
+ iter_swap(next,iter);
+
+ continue;
+ }
+ else
+ break;
+ }
+ }
+ */
+}
+
+static synfig::ColorAccumulator
+supersample_helper(const synfig::Gradient::CPoint &color1, const synfig::Gradient::CPoint &color2, float begin, float end, float &weight)
+{
+ if(color1.pos==color2.pos || color1.pos>=end || color2.pos<=begin)
+ {
+ weight=0;
+ return Color::alpha();
+ }
+ if(color1.pos>=begin && color2.pos<end)
+ {
+ weight=color2.pos-color1.pos;
+ ColorAccumulator ret=Color::blend(color2.color,color1.color, 0.5, Color::BLEND_STRAIGHT).premult_alpha()*weight;
+ return ret;
+ }
+ if(color1.pos>=begin && color2.pos>=end)
+ {
+ weight=end-color1.pos;
+ float pos((end+color1.pos)*0.5);
+ float amount((pos-color1.pos)/(color2.pos-color1.pos));
+ //if(abs(amount)>1)amount=(amount>0)?1:-1;
+ ColorAccumulator ret(Color::blend(color2.color,color1.color, amount, Color::BLEND_STRAIGHT).premult_alpha()*weight);
+ return ret;
+ }
+ if(color1.pos<begin && color2.pos<end)
+ {
+ weight=color2.pos-begin;
+ float pos((begin+color2.pos)*0.5);
+ float amount((pos-color1.pos)/(color2.pos-color1.pos));
+ //if(abs(amount)>1)amount=(amount>0)?1:-1;
+ ColorAccumulator ret(Color::blend(color2.color,color1.color, amount, Color::BLEND_STRAIGHT).premult_alpha()*weight);
+ return ret;
+ }
+ synfig::error("color1.pos=%f",color1.pos);
+ synfig::error("color2.pos=%f",color2.pos);
+ synfig::error("begin=%f",begin);
+ synfig::error("end=%f",end);
+
+ weight=0;
+ return Color::alpha();
+
+// assert(0);
+}
+
+static void show_gradient(const Gradient::CPointList x)
+{
+ int i = 0;
+ for (Gradient::const_iterator iter = x.begin(); iter != x.end(); iter++)
+ printf("%3d : %.3f %s\n", i++, (*iter).pos, (*iter).color.get_string().c_str());
+}
+
+Gradient &
+synfig::Gradient::operator+=(const Gradient &rhs)
+{
+ bool print=false; // for debugging
+ if (print) { printf("\nadding lhs:\n"); show_gradient(this->cpoints); printf("\n"); }
+ if (print) { printf("adding rhs:\n"); show_gradient(rhs.cpoints); printf("\n"); }
+ CPointList ret;
+ const_iterator iter1 = begin(), iter2 = rhs.begin(), left_same, right_same;
+ CPoint left, right;
+ if (iter1 != end()) left = *iter1;
+ if (iter2 != rhs.end()) right = *iter2;
+ int pos1 = 0, pos2 = 0;
+ CPoint old1, old2;
+
+ // if there are cpoints in both gradients run through both until one runs out
+ if (iter1 != end() && iter2 != rhs.end())
+ while(true)
+ // if the left one has the first cpoint
+ if (left.pos < right.pos)
+ {
+ // add on the right gradient's value at this point
+ if (print) printf("using pos %.2f from left %d in loop\n", left.pos, pos1++);
+ ret.push_back(CPoint(left.pos, left.color + rhs(left.pos)));
+ if(++iter1 == end()) break;
+ left=*iter1;
+ }
+ // if the right one has the first cpoint
+ else if (left.pos > right.pos)
+ {
+ // add on the left gradient's value at this point
+ if (print) printf("using pos %.2f from right %d in loop\n", right.pos, pos2++);
+ ret.push_back(CPoint(right.pos, right.color + (*this)(right.pos)));
+ if(++iter2 == rhs.end()) break;
+ right=*iter2;
+ }
+ // they both have a cpoint at the same time
+ else
+ {
+ int tpos1 = pos1, tpos2 = pos2;
+ // skip past all cpoints at the same position
+ for(left_same = ++iter1; iter1 != end() && (*iter1).pos == left.pos; iter1++, pos1++)
+ if (print) printf("skipping past pos %d in left\n", pos1);
+ for(right_same = ++iter2; iter2 != rhs.end() && (*iter2).pos == right.pos; iter2++, pos2++)
+ if (print) printf("skipping past pos %d in right\n", pos2);
+
+ // if there is only one cpoint at this position in each gradient,
+ // there's only one corresponding cpoint in the sum
+ if (iter1 == left_same && iter2 == right_same)
+ {
+ if (print) printf("two singles at left %d and right %d\n", pos1++, pos2++);
+ ret.push_back(CPoint(left.pos, left.color + right.color));
+ }
+ // otherwise we sum the first in each, and the last in each
+ else
+ {
+ if (print) printf("[copying %d from left %d and %d from right %d at %.2f]\n", iter1-left_same+1, tpos1, iter2-right_same+1, tpos2, left.pos);
+ // merge the front two cpoints
+ if (print) printf(" copy front from left %d right %d\n", tpos1++, tpos2++);
+ ret.push_back(CPoint(left.pos, left.color + right.color));
+
+ // merge the middle pairs of points - each middle point merges with its counterpart
+ while(left_same < iter1-1 && right_same < iter2-1)
+ {
+ old1 = *(left_same++);
+ old2 = *(right_same++);
+ if (print) printf(" copy middle from left %d and right %d\n", tpos1++, tpos2++);
+ ret.push_back(CPoint(old1.pos, old1.color+old2.color));
+ }
+ // if one gradient has more middle points than the other, merge the rest with the last point in the other gradient
+ for(old2 = (*(iter2-1)); left_same < iter1-1; left_same++)
+ {
+ old1 = *left_same;
+ if (print) printf(" copy middle from left %d plus end of right\n", tpos1++);
+ ret.push_back(CPoint(old1.pos, old1.color + old2.color));
+ }
+ for(old1 = (*(iter1-1)); right_same < iter2-1; right_same++)
+ {
+ old2 = *right_same;
+ if (print) printf(" copy middle from right %d plus end of left\n", tpos2++);
+ ret.push_back(CPoint(old2.pos, old1.color + old2.color));
+ }
+ // merge the back two cpoints
+ if (print) printf(" copy end from left %d right %d\n", pos1++, pos2++);
+ ret.push_back(CPoint(left.pos, (*(iter1-1)).color + (*(iter2-1)).color));
+ }
+ // make sure we update 'left' and 'right'
+ if (iter1 != end()) left=*iter1;
+ if (iter2 == rhs.end()) break;
+ right = *iter2;
+ if (iter1 == end()) break;
+ }
+
+ // one of the gradients has run out of points
+ // does the left one have points left?
+ if (iter1 != end())
+ while(true)
+ {
+ if (print) printf("finish end from left %d\n", pos1++);
+ ret.push_back(CPoint(left.pos, left.color + rhs(left.pos)));
+ if(++iter1 == end()) break;
+ left = *iter1;
+ }
+ // the left one was empty, so maybe the right one has points left
+ else if (iter2 != rhs.end())
+ while(true)
+ {
+ if (print) printf("finish end from right %d\n", pos2++);
+ ret.push_back(CPoint(right.pos, right.color + (*this)(right.pos)));
+ if(++iter2 == rhs.end()) break;
+ right = *iter2;
+ }
+
+ if (print) { printf("\nsummed ret:\n"); show_gradient(ret); printf("\n"); }
+ cpoints = ret;
+ return *this;
+}
+
+Gradient &
+synfig::Gradient::operator-=(const Gradient &rhs)
+{
+ return (*this)+=(rhs*-1);
+}
+
+Gradient &
+synfig::Gradient::operator*=(const float &rhs)
+{
+ if (rhs == 0)
+ cpoints.clear();
+ else
+ for (iterator iter = cpoints.begin(); iter!=cpoints.end(); iter++)
+ (*iter).color *= rhs;
+ return *this;
+}
+
+Gradient &
+synfig::Gradient::operator/=(const float &rhs)
+{
+ for (iterator iter = cpoints.begin(); iter!=cpoints.end(); iter++)
+ (*iter).color /= rhs;
+ return *this;
+}
+
+Color
+synfig::Gradient::operator()(const Real &x,float supersample)const
+{
+ if(cpoints.empty())
+ return Color(0,0,0,0);
+ if(supersample<0)
+ supersample=-supersample;
+ if(supersample>2.0)
+ supersample=2.0f;
+
+ float begin_sample(x-supersample*0.5);
+ float end_sample(x+supersample*0.5);
+
+ if(cpoints.size()==1 || end_sample<=cpoints.front().pos || isnan(x))
+ return cpoints.front().color;
+
+ if(begin_sample>=cpoints.back().pos)
+ return cpoints.back().color;
+
+ /*
+ if(end_sample>=back().pos)
+ end_sample=back().pos;
+
+ if(begin_sample<=front().pos)
+ begin_sample=front().pos;
+ */
+
+ const_iterator iter,next;
+
+ /*
+ //optimizize...
+ Real left = x-supersample/2, right = x+supersample/2;
+
+ if(left < front().pos) left = front().pos;
+ if(right > back().pos) right = back().pos;
+
+ //find using binary search...
+ const_iterator iterl,iterr;
+
+ //the binary search should give us the values BEFORE the point we're looking for...
+ iterl = binary_find(begin(),end(),left);
+ iterr = binary_find(iterl,end(),right);
+
+ //now integrate over the range of left to right...
+
+ if(iterl == iterr)
+ {
+ iterr++; //let's look at the next one shall we :)
+
+ //interpolate neighboring colors
+ const Real one = iterr->pos - iterl->pos;
+ const Real lambda = (x - iterl->pos)/one;
+
+ //(1-l)iterl + (l)iterr
+ return iterl->color.premult_alpha()*(1-lambda) + iterr->color.premult_alpha()*lambda;
+
+ //return Color::blend(iterr->color,iterl->color,lambda,Color::BLEND_STRAIGHT);
+ }else
+ {
+ //itegration madness
+ const_iterator i = iterl, ie = iterr+1;
+ Real wlast = left;
+
+ ColorAccumulator clast,cwork;
+ {
+ const Real lambda = (x - iterl->pos)/(iterr->pos - iterl->pos);
+
+ //premultiply because that's the form in which we can combine things...
+ clast = iterl->color.premult_alpha()*(1-lambda) + iterr->color.premult_alpha()*lambda;
+ //Color::blend((i+1)->color,i->color,(left - i->pos)/((i+1)->pos - i->pos),Color::BLEND_STRAIGHT);
+ }
+
+ ColorAccumulator accum = 0;
+
+ //loop through all the trapezoids and integrate them as we go...
+ // area of trap = (yi + yi1)*(xi1 - xi)
+ // yi = clast, xi = wlast, yi1 = i->color, xi1 = i->pos
+
+ for(;i<=iterr; wlast=i->pos,clast=i->color.premult_alpha(),++i)
+ {
+ const Real diff = i->pos - wlast;
+ if(diff > 0) //only accumulate if there will be area to add
+ {
+ cwork = i->color.premult_alpha();
+ accum += (cwork + clast)*diff;
+ }
+ }
+
+ {
+ const_iterator ibef = i-1;
+ const Real diff = right - ibef->pos;
+
+ if(diff > 0)
+ {
+ const Real lambda = diff/(i->pos - ibef->pos);
+ cwork = ibef->color.premult_alpha()*(1-lambda) + i->color.premult_alpha()*lambda;
+
+ accum += (cwork + clast)*diff; //can probably optimize this more... but it's not too bad
+ }
+ }
+
+ accum /= supersample; //should be the total area it was sampled over...
+ return accum.demult_alpha();
+ }*/
+
+ next=begin(),iter=next++;
+
+ //add for optimization
+ next = binary_find(begin(),end(),(Real)begin_sample);
+ iter = next++;
+
+ //! As a future optimization, this could be performed faster
+ //! using a binary search.
+ for(;iter<end();iter=next++)
+ {
+ if(next==end() || x>=iter->pos && x<next->pos && iter->pos!=next->pos)
+ {
+ // If the supersample region falls square in between
+ // two CPoints, then we don't have to do anything special.
+ if(next!=end() && (!supersample || (iter->pos<=begin_sample && next->pos>=end_sample)))
+ {
+ const Real dist(next->pos-iter->pos);
+ const Real pos(x-iter->pos);
+ const Real amount(pos/dist);
+ return Color::blend(next->color,iter->color, amount, Color::BLEND_STRAIGHT);
+ }
+ // In this case our supersample region extends over one or more
+ // CPoints. So, we need to calculate our coverage amount.
+ ColorAccumulator pool(Color::alpha());
+ float divisor(0.0),weight(0);
+
+ const_iterator iter2,next2;
+ iter2=iter;
+ if(iter==begin() && iter->pos>x)
+ {
+ weight=x-iter->pos;
+ //weight*=iter->color.get_a();
+ pool+=ColorAccumulator(iter->color).premult_alpha()*weight;
+ divisor+=weight;
+ }
+ else
+ {
+ while(iter2->pos>=begin_sample)
+ {
+ if(iter2==begin())
+ {
+ weight=iter2->pos-(begin_sample);
+ //weight*=iter2->color.get_a();
+ pool+=ColorAccumulator(iter2->color).premult_alpha()*weight;
+ divisor+=weight;
+ break;
+ }
+ next2=iter2--;
+ pool+=supersample_helper(*iter2, *next2, begin_sample, end_sample, weight);
+ divisor+=weight;
+ }
+ }
+
+ next2=iter;
+ iter2=next2++;
+ while(iter2->pos<=end_sample)
+ {
+ if(next2==end())
+ {
+ weight=(end_sample)-iter2->pos;
+ pool+=ColorAccumulator(iter2->color).premult_alpha()*weight;
+ divisor+=weight;
+ break;
+ }
+ pool+=supersample_helper(*iter2, *next2, begin_sample, end_sample, weight);
+ divisor+=weight;
+ iter2=next2++;
+ }
+
+ if(divisor && pool.get_a() && pool.is_valid())
+ {
+/*
+ pool.set_r(pool.get_r()/pool.get_a());
+ pool.set_g(pool.get_g()/pool.get_a());
+ pool.set_b(pool.get_b()/pool.get_a());
+ pool.set_a(pool.get_a()/divisor);
+*/
+ pool/=divisor;
+ pool.set_r(pool.get_r()/pool.get_a());
+ pool.set_g(pool.get_g()/pool.get_a());
+ pool.set_b(pool.get_b()/pool.get_a());
+ if(pool.is_valid())
+ return pool;
+ else
+ return Color::alpha();
+ }
+ else
+ return Color::alpha();
+ }
+ }
+
+ // We should never get to this point.
+
+ synfig::error("synfig::Gradient::operator()(): Logic Error (x=%f)",x);
+ assert(0);
+ throw std::logic_error(strprintf("synfig::Gradient::operator()(): Logic Error (x=%f)",x));
+}
+
+synfig::Gradient::iterator
+synfig::Gradient::proximity(const Real &x)
+{
+ iterator iter;
+ float dist(100000000);
+ float prev_pos(-0230);
+ // This algorithm requires a sorted list.
+ for(iter=begin();iter<end();iter++)
+ {
+ float new_dist;
+
+ if(prev_pos==iter->pos)
+ new_dist=(abs(x-iter->pos-0.00001));
+ else
+ new_dist=(abs(x-iter->pos));
+
+ if(new_dist>dist)
+ {
+ iter--;
+ return iter;
+ }
+ dist=new_dist;
+ prev_pos=iter->pos;
+ }
+ iter--;
+ return iter;
+}
+
+synfig::Gradient::const_iterator
+synfig::Gradient::proximity(const Real &x)const
+{
+ return const_cast<Gradient*>(this)->proximity(x);
+ /*
+ const_iterator iter;
+ float dist(100000000);
+
+ // This algorithm requires a sorted list.
+ for(iter=begin();iter<end();iter++)
+ {
+ const float new_dist(abs(x-iter->pos));
+ if(new_dist>dist)
+ {
+ iter--;
+ return iter;
+ }
+ dist=new_dist;
+ }
+ iter--;
+ return iter;
+ */
+}
+
+synfig::Gradient::iterator
+synfig::Gradient::find(const UniqueID &id)
+{
+ iterator iter;
+
+ for(iter=begin();iter<end();iter++)
+ {
+ if(id==*iter)
+ return iter;
+ }
+
+ throw Exception::NotFound("synfig::Gradient::find(): Unable to find UniqueID in gradient");
+}
+
+synfig::Gradient::const_iterator
+synfig::Gradient::find(const UniqueID &id)const
+{
+ const_iterator iter;
+
+ for(iter=begin();iter<end();iter++)
+ {
+ if(id==*iter)
+ return iter;
+ }
+
+ throw Exception::NotFound("synfig::Gradient::find()const: Unable to find UniqueID in gradient");
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file gradient.h
+** \brief Color Gradient Class
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_GRADIENT_H
+#define __SYNFIG_GRADIENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "real.h"
+#include "color.h"
+#include <vector>
+#include <utility>
+#include "uniqueid.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \struct GradientCPoint
+** \brief \todo
+*/
+struct GradientCPoint : public UniqueID
+{
+ Real pos;
+ Color color;
+
+ bool operator<(const GradientCPoint &rhs)const { return pos<rhs.pos; }
+ bool operator<(const Real &rhs)const { return pos<rhs; }
+
+ GradientCPoint() { }
+ GradientCPoint(const Real &pos, const Color &color):pos(pos),color(color) { }
+}; // END of class GradientCPoint
+
+
+/*! \class Gradient
+** \brief Color Gradient Class
+*/
+using namespace std;
+class Gradient
+{
+public:
+ typedef GradientCPoint CPoint;
+ typedef vector<CPoint> CPointList;
+ typedef CPointList::const_iterator const_iterator;
+ typedef CPointList::iterator iterator;
+ typedef CPointList::const_reverse_iterator const_reverse_iterator;
+ typedef CPointList::reverse_iterator reverse_iterator;
+private:
+ CPointList cpoints;
+public:
+ Gradient() { }
+
+ //! Two-Tone Color Gradient Convenience Constructor
+ Gradient(const Color &c1, const Color &c2);
+
+ //! Three-Tone Color Gradient Convenience Constructor
+ Gradient(const Color &c1, const Color &c2, const Color &c3);
+
+ //! Alias for sort (Implemented for consistency)
+ void sync() { sort(); }
+
+ //! You should call this function after changing stuff.
+ void sort();
+
+ void push_back(const CPoint cpoint) { cpoints.push_back(cpoint); }
+ iterator erase(iterator iter) { return cpoints.erase(iter); }
+ bool empty()const { return cpoints.empty(); }
+ size_t size()const { return cpoints.size(); }
+
+ iterator begin() { return cpoints.begin(); }
+ iterator end() { return cpoints.end(); }
+ reverse_iterator rbegin() { return cpoints.rbegin(); }
+ reverse_iterator rend() { return cpoints.rend(); }
+ const_iterator begin()const { return cpoints.begin(); }
+ const_iterator end()const { return cpoints.end(); }
+ const_reverse_iterator rbegin()const { return cpoints.rbegin(); }
+ const_reverse_iterator rend()const { return cpoints.rend(); }
+
+ Gradient &operator+=(const Gradient &rhs);
+ Gradient &operator-=(const Gradient &rhs);
+ Gradient &operator*=(const float &rhs);
+ Gradient &operator/=(const float &rhs);
+
+ Gradient operator+(const Gradient &rhs)const { return Gradient(*this)+=rhs; }
+ Gradient operator-(const Gradient &rhs)const { return Gradient(*this)-=rhs; }
+ Gradient operator*(const float &rhs)const { return Gradient(*this)*=rhs; }
+ Gradient operator/(const float &rhs)const { return Gradient(*this)/=rhs; }
+
+ Color operator()(const Real &x, float supersample=0)const;
+
+ //! Returns the iterator of the CPoint closest to \a x
+ iterator proximity(const Real &x);
+
+ //! Returns the const_iterator of the CPoint closest to \a x
+ const_iterator proximity(const Real &x)const;
+
+ //! Returns the iterator of the CPoint with UniqueID \a id
+ iterator find(const UniqueID &id);
+
+ //! Returns the const_iterator of the CPoint with UniqueID \a id
+ const_iterator find(const UniqueID &id)const;
+}; // END of class Gradient
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file guid.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define HASH_MAP_H <ext/hash_map>
+#define SUBTRACT_RNG_H <ext/functional>
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "guid.h"
+#include "quick_rng.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ETL/stringf>
+#include <functional>
+
+#ifdef _DEBUG
+#include "general.h"
+#endif
+
+#ifdef HASH_MAP_H
+#include HASH_MAP_H
+using namespace __gnu_cxx;
+#endif
+
+#ifdef SUBTRACT_RNG_H
+#include SUBTRACT_RNG_H
+using namespace __gnu_cxx;
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+#define MANUAL_GUID_CALC
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+#define GUID_RNG quick_rng
+//#define GUID_RNG subtractive_rng
+
+
+
+#ifdef MANUAL_GUID_CALC
+#include <time.h>
+static GUID_RNG _a, _b;
+static void _set_up_rand_long_long(uint64_t &x);
+static void _get_rand_long_long(uint64_t &x);
+static void (*get_rand_long_long)(uint64_t&)=_set_up_rand_long_long;
+static void _set_up_rand_long_long(uint64_t &x)
+{
+#ifdef _DEBUG
+ synfig::info("Starting up GUID system...");
+#endif
+ _a=GUID_RNG(time(0)+clock());
+ _b=GUID_RNG(clock());
+ get_rand_long_long=_get_rand_long_long;
+ _get_rand_long_long(x);
+}
+
+static void _get_rand_long_long(uint64_t &x)
+{
+ //subtractive_rng _c(clock());
+ unsigned short* data(reinterpret_cast<unsigned short *>(&x));
+ data[0]=_a(65536);
+ data[1]=_a(65536);
+ data[2]=_a(65536);
+ data[3]=_a(65536);
+}
+
+#else
+// Use OS-Dependent method
+
+#ifdef _WIN32
+// Win32
+static void get_rand_long_long(uint64_t &x)
+{
+ _GUID* guid(reinterpret_cast<_GUID*>(&x));
+ CoCreateGuid(guid);
+}
+
+#else
+// Unix
+static int rand_fd;
+static void _set_up_rand_long_long(uint64_t &x);
+static void _get_rand_long_long(uint64_t &x);
+static void (*get_rand_long_long)(uint64_t&)=_set_up_rand_long_long;
+static void _set_up_rand_long_long(uint64_t &x)
+{
+#ifdef _DEBUG
+ synfig::info("Starting up GUID system...");
+#endif
+ rand_fd=open("/dev/urandom",O_RDONLY);
+ get_rand_long_long=_get_rand_long_long;
+ _get_rand_long_long(x);
+}
+
+static void _get_rand_long_long(uint64_t &x){ read(rand_fd,&x,sizeof(x));}
+
+#endif
+#endif
+
+
+
+void
+synfig::GUID::make_unique()
+{
+ get_rand_long_long(data.u_64.a);
+ get_rand_long_long(data.u_64.b);
+}
+
+synfig::GUID
+synfig::GUID::hasher(const String& str)
+{
+#ifdef HASH_MAP_H
+ hash<const char*> string_hash_;
+ const unsigned int seed(
+ string_hash_(
+ str.c_str()
+ )
+ );
+#else
+ const unsigned int seed(0x3B642879);
+ for(int i=0;i<str.size();i++)
+ {
+ seed^=(seed*str[i])*i
+ seed=(seed>>(32-(i%24)))^(seed<<(i%24))
+ }
+#endif
+
+ GUID_RNG random(seed);
+ GUID ret(0);
+ ret.data.u_32.a=random(~(unsigned int)0);
+ ret.data.u_32.b=random(~(unsigned int)0);
+ ret.data.u_32.c=random(~(unsigned int)0);
+ ret.data.u_32.d=random(~(unsigned int)0);
+ return ret;
+}
+
+synfig::GUID
+synfig::GUID::hasher(int i)
+{
+ GUID ret(0);
+ GUID_RNG random(i);
+ ret.data.u_32.a=random(~(unsigned int)0);
+ ret.data.u_32.b=random(~(unsigned int)0);
+ ret.data.u_32.c=random(~(unsigned int)0);
+ ret.data.u_32.d=random(~(unsigned int)0);
+ return ret;
+}
+
+String
+synfig::GUID::get_string()const
+{
+ return strprintf("%08X%08X%08X%08X",data.u_32.a,data.u_32.b,data.u_32.c,data.u_32.d);
+}
+
+synfig::GUID::GUID(const String &str)
+{
+ strscanf(str,"%08X%08X%08X%08X",&data.u_32.a,&data.u_32.b,&data.u_32.c,&data.u_32.d);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file guid.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_GUID_H
+#define __SYNFIG_GUID_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "string.h"
+#include <stdint.h>
+#include <cassert>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class GUID
+{
+ union {
+ struct {
+ unsigned int a;
+ unsigned int b;
+ unsigned int c;
+ unsigned int d;
+ } u_32;
+ struct {
+ uint64_t a;
+ uint64_t b;
+ } u_64;
+
+ } data;
+
+public:
+ GUID()
+ { make_unique(); }
+ GUID(const GUID& x):data(x.data)
+ { }
+ GUID(const int i){assert(!i); data.u_64.a=0;data.u_64.b=0;}
+
+ GUID(const String& str);
+
+ static GUID zero() { return GUID(0); }
+ static GUID hasher(const String& str);
+ static GUID hasher(int i);
+
+ operator bool()const { return data.u_32.a||data.u_32.b||data.u_32.c||data.u_32.d; }
+
+ uint64_t get_hi()const { return data.u_64.a; }
+ uint64_t get_lo()const { return data.u_64.b; }
+
+ uint64_t get_hi_hi()const { return data.u_32.a; }
+ uint64_t get_hi_lo()const { return data.u_32.b; }
+ uint64_t get_lo_hi()const { return data.u_32.c; }
+ uint64_t get_lo_lo()const { return data.u_32.d; }
+
+ void make_unique();
+ String get_string()const;
+
+ bool operator==(const GUID& rhs)const
+ { return data.u_64.a==rhs.data.u_64.a && data.u_64.b==rhs.data.u_64.b; }
+ bool operator!=(const GUID& rhs)const
+ { return data.u_64.a!=rhs.data.u_64.a || data.u_64.b!=rhs.data.u_64.b; }
+ bool operator<(const GUID& rhs)const
+ { return (data.u_64.a==rhs.data.u_64.a)?(data.u_64.b<rhs.data.u_64.b):(data.u_64.a<rhs.data.u_64.a); }
+ bool operator>(const GUID& rhs)const
+ { return (data.u_64.a==rhs.data.u_64.a)?(data.u_64.b>rhs.data.u_64.b):(data.u_64.a>rhs.data.u_64.a); }
+ bool operator<=(const GUID& rhs)const
+ { return operator<(rhs) || operator==(rhs); }
+ bool operator>=(const GUID& rhs)const
+ { return operator>(rhs) || operator==(rhs); }
+
+ //! Operator '^' (xor)
+ /*! If A ^ B == C, then C ^ B == A and B ^ A == C.
+ ** Also keep in mind that A ^ A == 0 and A ^ B ^ B = A. */
+ GUID& operator^=(const GUID& rhs)
+ {
+ data.u_32.a^=rhs.data.u_32.a;
+ data.u_32.b^=rhs.data.u_32.b;
+ data.u_32.c^=rhs.data.u_32.c;
+ data.u_32.d^=rhs.data.u_32.d;
+ return *this;
+ }
+ GUID operator^(const GUID& rhs)const { return GUID(*this)^=rhs; }
+
+ //! Operator '%' (alt-xor)
+ /*! A % B != B % A. */
+ GUID& operator%=(const GUID& rhs)
+ {
+ data.u_32.a^=rhs.data.u_32.b;
+ data.u_32.b^=rhs.data.u_32.c;
+ data.u_32.c^=rhs.data.u_32.d;
+ data.u_32.d^=rhs.data.u_32.a;
+ return *this;
+ }
+ GUID operator%(const GUID& rhs)const { return GUID(*this)%=rhs; }
+
+};
+
+class GUIDHash
+{
+public:
+ size_t operator()(const GUID& guid)const
+ {
+ return
+ guid.get_hi_hi()+
+ guid.get_hi_lo()+
+ guid.get_lo_hi()+
+ guid.get_lo_lo();
+ }
+};
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file guidset.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_GUIDSET_H
+#define __SYNFIG_GUIDSET_H
+
+#define HASH_SET_H <ext/hash_set>
+
+/* === H E A D E R S ======================================================= */
+
+#include "guid.h"
+
+#ifdef HASH_SET_H
+#include HASH_SET_H
+#else
+#include <set>
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class GUIDSet : public
+#ifdef HASH_SET_H
+std::set<synfig::GUID>
+#else
+std::hash_set<synfig::GUID,synfig::GUIDHash>
+#endif
+{
+}; // END of class GUIDSet
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file importer.cpp
+** \brief writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "canvas.h"
+#include "importer.h"
+#include "surface.h"
+#include <algorithm>
+#include "string.h"
+#include <map>
+#include <ctype.h>
+#include <functional>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+Importer::Book* synfig::Importer::book_;
+
+map<String,Importer::LooseHandle> *__open_importers;
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+bool
+Importer::subsys_init()
+{
+ book_=new Book();
+ __open_importers=new map<String,Importer::LooseHandle>();
+ return true;
+}
+
+bool
+Importer::subsys_stop()
+{
+ delete book_;
+ delete __open_importers;
+ return true;
+}
+
+Importer::Book&
+Importer::book()
+{
+ return *book_;
+}
+
+Importer::Handle
+Importer::open(const String &filename)
+{
+ if(filename.empty())
+ {
+ synfig::error(_("Importer::open(): Cannot open empty filename"));
+ return 0;
+ }
+
+ // If we already have an importer open under that filename,
+ // then use it instead.
+ if(__open_importers->count(filename))
+ {
+ //synfig::info("Found importer already open, using it...");
+ return (*__open_importers)[filename];
+ }
+
+ if(find(filename.begin(),filename.end(),'.')==filename.end())
+ {
+ synfig::error(_("Importer::open(): Couldn't find extension"));
+ return 0;
+ }
+
+ String ext=string(filename.begin()+filename.find_last_of('.')+1,filename.end());
+ std::transform(ext.begin(),ext.end(),ext.begin(),&::tolower);
+
+
+ if(!Importer::book().count(ext))
+ {
+ synfig::error(_("Importer::open(): Unknown file type -- ")+ext);
+ return 0;
+ }
+
+ try {
+ Importer::Handle importer;
+ importer=Importer::book()[ext](filename.c_str());
+ (*__open_importers)[filename]=importer;
+ return importer;
+ }
+ catch (String str)
+ {
+ synfig::error(str);
+ }
+ return 0;
+}
+
+Importer::Importer():
+ gamma_(2.2)
+{
+}
+
+
+Importer::~Importer()
+{
+ // Remove ourselves from the open importer list
+ map<String,Importer::LooseHandle>::iterator iter;
+ for(iter=__open_importers->begin();iter!=__open_importers->end();++iter)
+ if(iter->second==this)
+ {
+ __open_importers->erase(iter);
+ }
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file importer.h
+** \brief writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_IMPORTER_H
+#define __SYNFIG_IMPORTER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <map>
+//#include <cmath>
+#include <ETL/handle>
+#include "string.h"
+//#include "surface.h"
+//#include "general.h"
+//#include "vector.h"
+#include "time.h"
+#include "gamma.h"
+
+/* === M A C R O S ========================================================= */
+
+//! \writeme
+#define SYNFIG_IMPORTER_MODULE_EXT public: static const char name__[], version__[], ext__[],cvs_id__[]; static Importer *create(const char *filename);
+
+//! Sets the name of the importer
+#define SYNFIG_IMPORTER_SET_NAME(class,x) const char class::name__[]=x
+
+//! \writeme
+#define SYNFIG_IMPORTER_SET_EXT(class,x) const char class::ext__[]=x
+
+//! Sets the version of the importer
+#define SYNFIG_IMPORTER_SET_VERSION(class,x) const char class::version__[]=x
+
+//! Sets the CVS ID of the importer
+#define SYNFIG_IMPORTER_SET_CVS_ID(class,x) const char class::cvs_id__[]=x
+
+//! \writeme
+#define SYNFIG_IMPORTER_INIT(class) synfig::Importer* class::create(const char *filename) { return new class(filename); }
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Surface;
+class ProgressCallback;
+
+/*! \class Importer
+** \brief Used for importing bitmaps of various formats, including animations
+** \todo Write more detailed description
+*/
+class Importer : public etl::shared_object
+{
+public:
+ typedef Importer* (*Factory)(const char *filename);
+ typedef std::map<String,Factory> Book;
+ static Book* book_;
+
+ static Book& book();
+
+ static bool subsys_init();
+ static bool subsys_stop();
+
+ typedef etl::handle<Importer> Handle;
+ typedef etl::loose_handle<Importer> LooseHandle;
+ typedef etl::handle<const Importer> ConstHandle;
+
+private:
+ Gamma gamma_;
+
+protected:
+ Importer();
+
+public:
+
+ Gamma& gamma() { return gamma_; }
+ const Gamma& gamma()const { return gamma_; }
+
+ virtual ~Importer();
+
+ //! Gets a frame and puts it into \a surface
+ /*! \param surface Reference to surface to put frame into
+ ** \param time For animated importers, determines which frame to get.
+ ** For static importers, this parameter is unused.
+ ** \param callback Pointer to callback class for progress, errors, etc.
+ ** \return \c true on success, \c false on error
+ ** \see ProgressCallback, Surface
+ */
+ virtual bool get_frame(Surface &surface,Time time, ProgressCallback *callback=NULL)=0;
+
+ //! Returns \c true if the importer pays attention to the \a time parameter of get_frame()
+ virtual bool is_animated() { return false; }
+
+ //! Attempts to open \a filename, and returns a handle to the associated Importer
+ static Handle open(const String &filename);
+};
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file interpolation.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_INTERPOLATION_H
+#define __SYNFIG_INTERPOLATION_H
+
+/* === H E A D E R S ======================================================= */
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+enum Interpolation
+{
+ INTERPOLATION_TCB,
+ INTERPOLATION_CONSTANT,
+ INTERPOLATION_LINEAR,
+ INTERPOLATION_HALT,
+ INTERPOLATION_MANUAL,
+ INTERPOLATION_UNDEFINED,
+ INTERPOLATION_NIL
+}; // END enum Interpolation
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file keyframe.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <algorithm>
+
+#include <ETL/stringf>
+
+#include "keyframe.h"
+#include "exception.h"
+#include "general.h"
+#include <ETL/misc>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Keyframe::Keyframe():
+ time_(0)
+{
+}
+
+Keyframe::Keyframe(const Time &time):
+ time_(time)
+{
+}
+
+Keyframe::~Keyframe()
+{
+}
+
+void
+KeyframeList::dump()const
+{
+ const_iterator iter;
+ int i;
+ synfig::info(">>>>>>>>BEGIN KEYFRAME DUMP");
+ for(iter=begin(),i=0;iter!=end();++iter,i++)
+ {
+ synfig::info("#%d, time: %s, desc: %s",i,iter->get_time().get_string().c_str(),iter->get_description().c_str());
+ }
+ synfig::info("<<<<<<<<END KEYFRAME DUMP");
+}
+
+void
+KeyframeList::sync()
+{
+ //DEBUGPOINT();
+ //synfig::info("PRE-SORT:");
+ //dump();
+ sort(begin(),end());
+ //synfig::info("POST-SORT:");
+ //dump();
+ //DEBUGPOINT();
+}
+
+KeyframeList::iterator
+KeyframeList::find(const UniqueID &x)
+{
+ KeyframeList::iterator iter;
+ iter=std::find(begin(),end(),x);
+ if(iter==end())
+ throw Exception::NotFound(strprintf("KeyframeList::find(): Can't find UniqueID %d",x.get_uid()));
+ return iter;
+}
+
+KeyframeList::const_iterator
+KeyframeList::find(const UniqueID &x)const
+{
+ KeyframeList::const_iterator iter;
+ iter=std::find(begin(),end(),x);
+ if(iter==end())
+ throw Exception::NotFound(strprintf("KeyframeList::find(): Can't find UniqueID %d",x.get_uid()));
+ return iter;
+}
+
+KeyframeList::iterator
+KeyframeList::add(const Keyframe &x)
+{
+ push_back(x);
+ iterator ret(end());
+ ret--;
+ assert(x==*ret);
+ sync();
+ return ret;
+}
+
+void
+KeyframeList::erase(const UniqueID &x)
+{
+ std::vector<Keyframe>::erase(find(x));
+}
+
+KeyframeList::iterator
+KeyframeList::find(const Time &x)
+{
+ KeyframeList::iterator iter;
+ iter=binary_find(begin(),end(),x);
+ if(iter!=end() && iter->get_time().is_equal(x))
+ return iter;
+/* iter++;
+ if(iter!=end() && iter->get_time().is_equal(x))
+ return iter;
+*/
+ throw Exception::NotFound(strprintf("KeyframeList::find(): Can't find Keyframe %s",x.get_string().c_str()));
+}
+
+KeyframeList::iterator
+KeyframeList::find_next(const Time &x)
+{
+ KeyframeList::iterator iter(binary_find(begin(),end(),x));
+
+ if(iter!=end())
+ {
+ if(iter->get_time().is_more_than(x))
+ return iter;
+ ++iter;
+ if(iter!=end())
+ {
+ if(iter->get_time().is_more_than(x))
+ return iter;
+/* ++iter;
+ if(iter!=end() && iter->get_time().is_more_than(x))
+ return iter;
+*/
+ }
+ }
+
+ throw Exception::NotFound(strprintf("KeyframeList::find(): Can't find next Keyframe %s",x.get_string().c_str()));
+}
+
+
+KeyframeList::iterator
+KeyframeList::find_prev(const Time &x)
+{
+ KeyframeList::iterator iter(binary_find(begin(),end(),x));
+
+ if(iter!=end())
+ {
+ if(iter->get_time()+Time::epsilon()<x)
+ return iter;
+ if(iter!=begin() && (--iter)->get_time()+Time::epsilon()<x)
+ return iter;
+ }
+ throw Exception::NotFound(strprintf("KeyframeList::find(): Can't find prev Keyframe %s",x.get_string().c_str()));
+
+}
+
+
+
+KeyframeList::const_iterator
+KeyframeList::find(const Time &x)const
+{
+ return const_cast<KeyframeList*>(this)->find(x);
+}
+
+
+KeyframeList::const_iterator
+KeyframeList::find_next(const Time &x)const
+{
+ return const_cast<KeyframeList*>(this)->find_next(x);
+
+}
+
+
+KeyframeList::const_iterator
+KeyframeList::find_prev(const Time &x)const
+{
+ return const_cast<KeyframeList*>(this)->find_prev(x);
+
+}
+
+void
+KeyframeList::find_prev_next(const Time& time, Time &prev, Time &next)const
+{
+ try { prev=find_prev(time)->get_time(); }
+ catch(...) { prev=Time::begin(); }
+ try { next=find_next(time)->get_time(); }
+ catch(...) { next=Time::end(); }
+}
+
+void
+KeyframeList::insert_time(const Time& location, const Time& delta)
+{
+// synfig::info("KeyframeList::insert_time(): loc=%s, delta=%s",location.get_string().c_str(),delta.get_string().c_str());
+ if(!delta)
+ return;
+ try
+ {
+ iterator iter(find_next(location));
+ for(;iter!=end();++iter)
+ {
+ iter->set_time(iter->get_time()+delta);
+ }
+ sync();
+ }
+ catch(Exception::NotFound) { }
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file keyframe.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_KEYFRAME_H
+#define __SYNFIG_KEYFRAME_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/handle>
+#include <vector>
+#include "string.h"
+#include "time.h"
+#include "uniqueid.h"
+#include "guid.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+//! \writeme
+class Keyframe : public UniqueID
+{
+public:
+
+ Time time_;
+ String desc_;
+ GUID guid_;
+
+public:
+
+ Keyframe();
+
+ Keyframe(const Time &time);
+
+ ~Keyframe();
+
+ void set_time(Time x) { time_=x; }
+
+ Time get_time()const { return time_; }
+
+ void set_description(String x) { desc_=x; }
+
+ String get_description()const { return desc_; }
+
+ const GUID& get_guid()const { return guid_; }
+ void set_guid(const GUID& x) { guid_=x; }
+
+ using UniqueID::operator<;
+ using UniqueID::operator==;
+ using UniqueID::operator!=;
+ using UniqueID::operator=;
+
+ bool operator<(const Keyframe &rhs)const { return time_<rhs.time_; }
+ bool operator<(const Time &rhs)const { return time_<rhs; }
+
+// bool operator==(const Keyframe &rhs)const { return id_==rhs.id_; }
+ bool operator==(const Time &rhs)const { return time_==rhs; }
+
+// bool operator!=(const Keyframe &rhs)const { return id_!=rhs.id_; }
+ bool operator!=(const Time &rhs)const { return time_!=rhs; }
+}; // END of class Keyframe
+
+class KeyframeList : public std::vector<Keyframe>
+{
+
+public:
+
+ iterator add(const Keyframe &x);
+
+ void erase(const UniqueID &x);
+
+ iterator find(const UniqueID &x);
+
+ const_iterator find(const UniqueID &x)const;
+
+ //! Finds the keyframe at an exact point in time
+ iterator find(const Time &x);
+
+ //! Finds the keyframe after that point in time
+ iterator find_next(const Time &x);
+
+ //! Finds the keyframe before that point in time
+ iterator find_prev(const Time &x);
+
+ const_iterator find(const Time &x)const;
+ const_iterator find_next(const Time &x)const;
+ const_iterator find_prev(const Time &x)const;
+
+ void find_prev_next(const Time& time, Time &prev, Time &next)const;
+
+ void insert_time(const Time& location, const Time& delta);
+
+ void dump()const;
+ void sync();
+};
+
+//typedef std::list<Keyframe> KeyframeList;
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer.cpp
+** \brief Layer class implementation
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "canvas.h"
+#include "layer.h"
+#include "render.h"
+#include "value.h"
+#include "layer_bitmap.h"
+#include "layer_mime.h"
+#include "context.h"
+#include "paramdesc.h"
+
+#include "layer_solidcolor.h"
+#include "layer_polygon.h"
+#include "layer_pastecanvas.h"
+#include "layer_motionblur.h"
+
+#include "valuenode_const.h"
+
+#include "transform.h"
+#include "rect.h"
+#include "guid.h"
+
+#include <sigc++/adaptors/bind.h>
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+static Layer::Book* _layer_book;
+
+struct _LayerCounter
+{
+ static int counter;
+ ~_LayerCounter()
+ {
+ if(counter)
+ synfig::error("%d layers not yet deleted!",counter);
+ }
+} _layer_counter;
+
+int _LayerCounter::counter(0);
+
+/* === P R O C E D U R E S ================================================= */
+
+Layer::Book&
+Layer::book()
+{
+ return *_layer_book;
+}
+
+void
+Layer::register_in_book(const BookEntry &entry)
+{
+ book()[entry.name]=entry;
+}
+
+bool
+Layer::subsys_init()
+{
+ _layer_book=new Book();
+
+#define INCLUDE_LAYER(class) synfig::Layer::book()[synfig::String(class::name__)]=BookEntry(class::create,class::name__,class::local_name__,class::category__,class::cvs_id__,class::version__)
+#define LAYER_ALIAS(class,alias) synfig::Layer::book()[synfig::String(alias)]=synfig::Layer::BookEntry(class::create,alias,alias,_("Do Not Use"),class::cvs_id__,class::version__);
+
+ INCLUDE_LAYER(Layer_SolidColor); LAYER_ALIAS(Layer_SolidColor, "solid_color");
+ INCLUDE_LAYER(Layer_PasteCanvas); LAYER_ALIAS(Layer_PasteCanvas, "paste_canvas");
+ INCLUDE_LAYER(Layer_Polygon); LAYER_ALIAS(Layer_Polygon, "Polygon");
+ INCLUDE_LAYER(Layer_MotionBlur); LAYER_ALIAS(Layer_MotionBlur, "motion_blur");
+
+#undef INCLUDE_LAYER
+
+ return true;
+}
+
+bool
+Layer::subsys_stop()
+{
+ delete _layer_book;
+ return true;
+}
+
+/* === M E T H O D S ======================================================= */
+
+Layer::Layer():
+ active_(true),
+ z_depth_(0.0f),
+ dirty_time_(Time::end())
+{
+ _LayerCounter::counter++;
+}
+
+Layer::LooseHandle
+synfig::Layer::create(const String &name)
+{
+ if(!book().count(name))
+ {
+ return Layer::LooseHandle(new Layer_Mime(name));
+ }
+
+ Layer* layer(book()[name].factory());
+ return Layer::LooseHandle(layer);
+}
+
+synfig::Layer::~Layer()
+{
+ _LayerCounter::counter--;
+ while(!dynamic_param_list_.empty())
+ {
+ remove_child(dynamic_param_list_.begin()->second.get());
+ dynamic_param_list_.erase(dynamic_param_list_.begin());
+ }
+
+ remove_from_all_groups();
+
+ parent_death_connect_.disconnect();
+ begin_delete();
+}
+
+void
+synfig::Layer::set_canvas(etl::loose_handle<Canvas> x)
+{
+ if(canvas_!=x)
+ {
+ parent_death_connect_.disconnect();
+ canvas_=x;
+ if(x)
+ {
+ parent_death_connect_=x->signal_deleted().connect(
+ sigc::bind(
+ sigc::mem_fun(
+ *this,
+ &Layer::set_canvas
+ ),
+ etl::loose_handle<synfig::Canvas>(0)
+ )
+ );
+ }
+ on_canvas_set();
+ }
+}
+
+void
+synfig::Layer::on_canvas_set()
+{
+}
+
+etl::loose_handle<synfig::Canvas>
+synfig::Layer::get_canvas()const
+{
+ return canvas_;
+}
+
+int
+Layer::get_depth()const
+{
+ if(!get_canvas())
+ return -1;
+ return get_canvas()->get_depth(const_cast<synfig::Layer*>(this));
+}
+
+void
+Layer::set_active(bool x)
+{
+ if(active_!=x)
+ {
+ active_=x;
+
+ Node::on_changed();
+ signal_status_changed_();
+ }
+}
+
+void
+Layer::set_description(const String& x)
+{
+ if(description_!=x)
+ {
+ description_=x;
+ signal_description_changed_();
+ }
+}
+
+bool
+Layer::connect_dynamic_param(const String& param, etl::loose_handle<ValueNode> value_node)
+{
+ ValueNode::Handle previous(dynamic_param_list_[param]);
+
+ if(previous==value_node)
+ return true;
+
+ dynamic_param_list_[param]=ValueNode::Handle(value_node);
+
+ if(previous)
+ remove_child(previous.get());
+
+ add_child(value_node.get());
+
+ if(!value_node->is_exported() && get_canvas())
+ {
+ value_node->set_parent_canvas(get_canvas());
+ }
+
+ changed();
+ return true;
+}
+
+bool
+Layer::disconnect_dynamic_param(const String& param)
+{
+ ValueNode::Handle previous(dynamic_param_list_[param]);
+
+ if(previous)
+ {
+ dynamic_param_list_.erase(param);
+ remove_child(previous.get());
+ changed();
+ }
+ return true;
+}
+
+void
+Layer::on_changed()
+{
+ dirty_time_=Time::end();
+ if(active())
+ Node::on_changed();
+}
+
+bool
+Layer::set_param(const String ¶m, const ValueBase &value)
+{
+ if(param=="z_depth" && value.same_type_as(z_depth_))
+ {
+ z_depth_=value.get(z_depth_);
+ return true;
+ }
+ return false;
+}
+
+etl::handle<Transform>
+Layer::get_transform()const
+{
+ return 0;
+}
+
+float
+Layer::get_z_depth(const synfig::Time& t)const
+{
+ if(!dynamic_param_list().count("z_depth"))
+ return z_depth_;
+ return (*dynamic_param_list().find("z_depth")->second)(t).get(Real());
+}
+
+Layer*
+Layer::simple_clone()const
+{
+ if(!book().count(get_name())) return 0;
+ Layer *ret = create(get_name()).get();
+ ret->set_canvas(get_canvas());
+ ret->set_description(get_description());
+ ret->set_param_list(get_param_list());
+ return ret;
+}
+
+Layer::Handle
+Layer::clone(const GUID& deriv_guid) const
+{
+ if(!book().count(get_name())) return 0;
+
+ //Layer *ret = book()[get_name()].factory();//create(get_name()).get();
+ Handle ret = create(get_name()).get();
+
+ ret->group_=group_;
+ //ret->set_canvas(get_canvas());
+ ret->set_description(get_description());
+ ret->set_active(active());
+ ret->set_guid(get_guid()^deriv_guid);
+
+ //ret->set_param_list(get_param_list());
+ // Process the parameter list so that
+ // we can duplicate any inline canvases
+ ParamList param_list(get_param_list());
+ for(ParamList::const_iterator iter(param_list.begin()); iter != param_list.end(); ++iter)
+ {
+ if(dynamic_param_list().count(iter->first)==0 && iter->second.get_type()==ValueBase::TYPE_CANVAS)
+ {
+
+ // This parameter is a canvas. We need a close look.
+ Canvas::Handle canvas(iter->second.get(Canvas::Handle()));
+ if(canvas && canvas->is_inline())
+ {
+ // This parameter is an inline canvas! we need to clone it
+ // before we set it as a parameter.
+ Canvas::Handle new_canvas(canvas->clone(deriv_guid));
+ ValueBase value(new_canvas);
+ ret->set_param(iter->first, value);
+ continue;
+ }
+ }
+
+ // This is a normal parameter,go ahead and set it.
+ ret->set_param(iter->first, iter->second);
+ }
+
+ // Duplicate the dynamic paramlist, but only the exported data nodes
+ DynamicParamList::const_iterator iter;
+ for(iter=dynamic_param_list().begin();iter!=dynamic_param_list().end();++iter)
+ {
+ // Make sure we clone inline canvases
+ if(iter->second->get_type()==ValueBase::TYPE_CANVAS)
+ {
+ Canvas::Handle canvas((*iter->second)(0).get(Canvas::Handle()));
+ if(canvas->is_inline())
+ {
+ Canvas::Handle new_canvas(canvas->clone(deriv_guid));
+ ValueBase value(new_canvas);
+ ret->connect_dynamic_param(iter->first,ValueNode_Const::create(value));
+ continue;
+ }
+ }
+
+ if(iter->second->is_exported())
+ ret->connect_dynamic_param(iter->first,iter->second);
+ else
+ ret->connect_dynamic_param(iter->first,iter->second->clone(deriv_guid));
+ }
+
+ //ret->set_canvas(0);
+
+ return ret;
+}
+
+Rect
+Layer::get_full_bounding_rect(Context context)const
+{
+ if(active())
+ return context.get_full_bounding_rect()|get_bounding_rect();
+ return context.get_full_bounding_rect();
+}
+
+Rect
+Layer::get_bounding_rect()const
+{
+ return Rect::full_plane();
+}
+
+bool
+Layer::set_param_list(const ParamList &list)
+{
+ bool ret=true;
+ if(!list.size())
+ return false;
+ ParamList::const_iterator iter(list.begin());
+ for(;iter!=list.end();++iter)
+ {
+ if(!set_param(iter->first, iter->second))ret=false;
+ }
+ return ret;
+}
+
+Layer::ParamList
+Layer::get_param_list()const
+{
+ ParamList ret;
+
+ Vocab vocab(get_param_vocab());
+
+ Vocab::const_iterator iter=vocab.begin();
+ for(;iter!=vocab.end();++iter)
+ {
+ ret[iter->get_name()]=get_param(iter->get_name());
+ }
+ return ret;
+}
+
+ValueBase
+Layer::get_param(const String & param)const
+{
+ if(param=="z_depth")
+ return get_z_depth();
+
+ return ValueBase();
+}
+
+String
+Layer::get_version()const
+{
+ return get_param("version__").get(String());
+}
+
+bool
+Layer::set_version(const String &/*ver*/)
+{
+ return false;
+}
+
+void
+Layer::reset_version()
+{
+}
+
+
+void
+Layer::set_time(Context context, Time time)const
+{
+ context.set_time(time);
+ dirty_time_=time;
+}
+
+void
+Layer::set_time(Context context, Time time, const Point &pos)const
+{
+ context.set_time(time,pos);
+ dirty_time_=time;
+}
+
+Color
+Layer::get_color(Context context, const Point &pos)const
+{
+ return context.get_color(pos);
+}
+
+synfig::Layer::Handle
+Layer::hit_check(synfig::Context context, const synfig::Point &pos)const
+{
+ return context.hit_check(pos);
+}
+
+/* The default accelerated renderer
+** is anything but accelerated...
+*/
+bool
+Layer::accelerated_render(Context context,Surface *surface,int /*quality*/, const RendDesc &renddesc, ProgressCallback *cb) const
+{
+ handle<Target> target=surface_target(surface);
+ if(!target)
+ {
+ if(cb)cb->error(_("Unable to create surface target"));
+ return false;
+ }
+ RendDesc desc=renddesc;
+ target->set_rend_desc(&desc);
+
+ // When we render, we want to
+ // make sure that we are rendered too...
+ // Since the context iterator is for
+ // the layer after us, we need to back up.
+ // This could be considered a hack, as
+ // it is a possibility that we are indeed
+ // not the previous layer.
+ --context;
+
+ return render(context,target,desc,cb);
+ //return render_threaded(context,target,desc,cb,2);
+}
+
+String
+Layer::get_name()const
+{
+ return get_param("name__").get(String());
+}
+
+String
+Layer::get_local_name()const
+{
+ return get_param("local_name__").get(String());
+}
+
+
+Layer::Vocab
+Layer::get_param_vocab()const
+{
+ Layer::Vocab ret;
+
+ ret.push_back(ParamDesc(z_depth_,"z_depth")
+ .set_local_name(_("Z Depth"))
+ .set_animation_only(true)
+ );
+
+ return ret;
+}
+
+void
+Layer::get_times_vfunc(Node::time_set &set) const
+{
+ DynamicParamList::const_iterator i = dynamic_param_list_.begin(),
+ end = dynamic_param_list_.end();
+
+ for(; i != end; ++i)
+ {
+ const Node::time_set &tset = i->second->get_times();
+ set.insert(tset.begin(),tset.end());
+ }
+}
+
+
+void
+Layer::add_to_group(const String&x)
+{
+ if(x==group_)
+ return;
+ if(!group_.empty())
+ remove_from_all_groups();
+ group_=x;
+ signal_added_to_group()(group_);
+}
+
+void
+Layer::remove_from_group(const String&x)
+{
+ if(group_==x)
+ remove_from_all_groups();
+}
+
+void
+Layer::remove_from_all_groups()
+{
+ if(group_.empty())
+ return;
+ signal_removed_from_group()(group_);
+ group_.clear();
+}
+
+String
+Layer::get_group()const
+{
+ return group_;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer.h
+** \brief Layer Class Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LAYER_H
+#define __SYNFIG_LAYER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "string_decl.h"
+#include <map>
+#include <ETL/handle>
+#include "real.h"
+#include "string.h"
+#include <sigc++/signal.h>
+#include <sigc++/connection.h>
+#include "node.h"
+#include "time.h"
+#include "guid.h"
+
+/* === M A C R O S ========================================================= */
+
+//! \writeme
+#define SYNFIG_LAYER_MODULE_EXT public: static const char name__[], version__[], cvs_id__[], local_name__[], category__[]; static Layer *create();
+
+//! Sets the name of the layer
+#define SYNFIG_LAYER_SET_NAME(class,x) const char class::name__[]=x
+
+//! Sets the local name of the layer
+#define SYNFIG_LAYER_SET_LOCAL_NAME(class,x) const char class::local_name__[]=x;
+
+//! Sets the category of the layer
+#define SYNFIG_LAYER_SET_CATEGORY(class,x) const char class::category__[]=x
+
+//! Sets the version string for the layer
+#define SYNFIG_LAYER_SET_VERSION(class,x) const char class::version__[]=x
+
+//! Sets the CVS ID string for the layer
+#define SYNFIG_LAYER_SET_CVS_ID(class,x) const char class::cvs_id__[]=x
+
+//! \writeme
+#define SYNFIG_LAYER_INIT(class) synfig::Layer* class::create() { return new class(); }
+
+//! \writeme
+#define IMPORT_PLUS(x,y) if(param==#x && value.same_type_as(x)) { value.put(&x);{y;}return true;}
+
+//! \writeme
+#define IMPORT_AS(x,y) if(param==y && value.same_type_as(x)) { value.put(&x); return true;}
+
+//! \writeme
+#define IMPORT(x) IMPORT_AS(x,#x)
+
+//! \writeme
+#define EXPORT_AS(x,y) if(param==y) { return ValueBase(x); }
+
+//! \writeme
+#define EXPORT(x) EXPORT_AS(x,#x)
+
+//! \writeme
+#define EXPORT_NAME() if(param=="Name" || param=="name" || param=="name__") { return name__; } if(param=="local_name__") { return local_name__; }
+
+//! \writeme
+#define EXPORT_VERSION() if(param=="Version" || param=="version" || param=="version__") { return version__; }
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Canvas;
+class Vector;
+typedef Vector Point;
+class Canvas;
+class ParamDesc;
+class ParamVocab;
+class ValueNode;
+class ValueBase;
+class Time;
+class Surface;
+class RendDesc;
+class ProgressCallback;
+class Context;
+class Color;
+class Transform;
+class Rect;
+class GUID;
+
+
+/*! \class Layer
+** \todo writeme
+** \see Canvas
+*/
+class Layer : public Node
+{
+ friend class ValueNode;
+ friend class Context;
+
+ /*
+ -- ** -- T Y P E S -----------------------------------------------------------
+ */
+
+public:
+
+ //! Type that represents a pointer to a layer's constructor
+ typedef Layer* (*Factory)();
+
+ struct BookEntry
+ {
+ Factory factory;
+ String name;
+ String local_name;
+ String category;
+ String cvs_id;
+ String version;
+ BookEntry() { }
+ BookEntry(Factory factory, const String& name,const String& local_name,const String& category,const String& cvs_id,const String& version):
+ factory(factory),name(name),local_name(local_name),category(category),cvs_id(cvs_id),version(version) { }
+ };
+
+ typedef std::map<String,BookEntry> Book;
+
+ static void register_in_book(const BookEntry &);
+
+ static Book& book();
+
+ static bool subsys_init();
+
+ static bool subsys_stop();
+
+ typedef std::map<String,ValueBase> ParamList;
+
+ typedef etl::handle<Layer> Handle;
+
+ typedef etl::loose_handle<Layer> LooseHandle;
+
+ typedef etl::handle<const Layer> ConstHandle;
+
+ typedef std::map<String,etl::rhandle<ValueNode> > DynamicParamList;
+
+ //! A list type which describes all the parameters that a layer has.
+ /*! \see get_param_vocab() */
+ typedef ParamVocab Vocab;
+
+ /*
+ -- ** -- D A T A -------------------------------------------------------------
+ */
+
+private:
+
+ /*! \c true if the layer is visible, \c false if it is to be skipped
+ ** \see set_active(), enable(), disable, active()
+ */
+ bool active_;
+
+ //! Handle to the canvas to which this layer belongs
+ etl::loose_handle<Canvas> canvas_;
+
+ DynamicParamList dynamic_param_list_;
+
+ //! A description of what this layer does
+ String description_;
+
+ //! \writeme
+ float z_depth_;
+
+ //! \writeme
+ mutable Time dirty_time_;
+
+ //! Contains the name of the group that this layer belongs to
+ String group_;
+
+ //! \writeme
+ sigc::connection parent_death_connect_;
+
+ /*
+ -- ** -- S I G N A L S -------------------------------------------------------
+ */
+
+private:
+
+ //! Status Changed
+ sigc::signal<void> signal_status_changed_;
+
+ //! Parameter changed
+ sigc::signal<void,String> signal_param_changed_;
+
+ //! Description Changed
+ sigc::signal<void> signal_description_changed_;
+
+ //! Moved
+ sigc::signal<void, int, etl::handle<Canvas> > signal_moved_;
+
+ sigc::signal<void, String> signal_added_to_group_;
+
+ sigc::signal<void, String> signal_removed_from_group_;
+
+ /*
+ -- ** -- S I G N A L I N T E R F A C E -------------------------------------
+ */
+
+public:
+
+ //! Status Changed
+ sigc::signal<void>& signal_status_changed() { return signal_status_changed_; }
+
+ //! Parameter changed
+ sigc::signal<void,String>& signal_param_changed() { return signal_param_changed_; }
+
+ //! Description Changed
+ sigc::signal<void>& signal_description_changed() { return signal_description_changed_;}
+
+ //! Moved
+ sigc::signal<void, int, etl::handle<Canvas> >& signal_moved() { return signal_moved_; }
+
+ sigc::signal<void, String>& signal_added_to_group() { return signal_added_to_group_; }
+
+ sigc::signal<void, String>& signal_removed_from_group() { return signal_removed_from_group_; }
+
+ /*
+ -- ** -- C O N S T R U C T O R S ---------------------------------------------
+ */
+
+protected:
+
+ Layer();
+
+public:
+ virtual ~Layer();
+
+ /*
+ -- ** -- M E M B E R F U N C T I O N S -------------------------------------
+ */
+
+public:
+
+ virtual void on_canvas_set();
+
+ //! Adds this layer to the given layer group
+ void add_to_group(const String&);
+
+ //! Removes this layer from the given layer group
+ void remove_from_group(const String&);
+
+ //! Removes this layer from all layer groups
+ void remove_from_all_groups();
+
+ //! Gets the name of the group that this layer belongs to
+ String get_group()const;
+
+ //! writeme
+ //DynamicParamList &dynamic_param_list() { return dynamic_param_list_; }
+
+ //! \todo writeme
+ const DynamicParamList &dynamic_param_list()const { return dynamic_param_list_; }
+
+ bool connect_dynamic_param(const String& param, etl::loose_handle<ValueNode>);
+ bool disconnect_dynamic_param(const String& param);
+
+ //! Enables the layer for rendering (Making it \em active)
+ void enable() { set_active(true); }
+
+ //! Disables the layer for rendering. (Making it \em inactive)
+ /*! When a layer is disabled, it will be skipped when the
+ ** canvas is rendered. */
+ void disable() { set_active(false); }
+
+ //! Sets the 'active' flag for the Layer to the state described by \a x
+ /*! When a layer is disabled, it will be skipped when the
+ ** canvas is rendered. */
+ void set_active(bool x);
+
+ //! Returns that status of the 'active' flag
+ bool active()const { return active_; }
+
+ //! Returns the position of the layer in the canvas.
+ /*! Returns negative on error */
+ int get_depth()const;
+
+ //! \writeme
+ float get_z_depth()const { return z_depth_; }
+
+ //! \writeme
+ float get_z_depth(const synfig::Time& t)const;
+
+ //! \writeme
+ void set_z_depth(float x) { z_depth_=x; }
+
+ //! Sets the Canvas that this Layer is a part of
+ void set_canvas(etl::loose_handle<Canvas> canvas);
+
+ //! Returns a handle to the Canvas to which this Layer belongs
+ etl::loose_handle<Canvas> get_canvas()const;
+
+ //! \writeme
+ const String& get_description()const { return description_; }
+
+ //! \writeme
+ void set_description(const String& x);
+
+ /*
+ -- ** -- V I R T U A L F U N C T I O N S -----------------------------------
+ */
+
+public:
+ virtual Rect get_bounding_rect()const;
+
+ virtual Rect get_full_bounding_rect(Context context)const;
+
+ //! Returns a string containing the name of the Layer
+ virtual String get_name()const;
+
+ //! Returns a string containing the localized name of the Layer
+ virtual String get_local_name()const;
+
+ //! Gets the paramater vocabulary
+ virtual Vocab get_param_vocab()const;
+
+ //! Gets the version string for this layer
+ virtual String get_version()const;
+
+ //! \writeme
+ virtual etl::handle<Transform> get_transform()const;
+
+ //! Sets the virtual version to use for backwards-compatibility
+ /*!
+ ** \see reset_version() */
+ virtual bool set_version(const String &ver);
+
+ //! Resets the virtual version
+ /*!
+ ** \see set_version() */
+ virtual void reset_version();
+
+ //! Sets the parameter described by \a param to \a value.
+ /*! \param param The name of the parameter to set
+ ** \param value What the parameter is to be set to.
+ ** \return \c true on success, \c false upon rejection or failure.
+ ** If it returns \c false, then the Layer is assumed to remain unchanged.
+ ** \sa get_param()
+ ** \todo \a param should be of the type <tt>const String \¶m</tt>
+ */
+ virtual bool set_param(const String ¶m, const ValueBase &value);
+
+ //! Sets a list of parameters
+ virtual bool set_param_list(const ParamList &);
+
+ //! Get the value of the specified parameter.
+ /*! \return The requested parameter value, or (upon failure) a NIL ValueBase.
+ ** \sa set_param()
+ ** \todo \a param should be of the type <tt>const String \&</tt>
+ */
+ virtual ValueBase get_param(const String ¶m)const;
+
+ //! Get a list of all of the parameters and their values
+ virtual ParamList get_param_list()const;
+
+ //! Sets the \a time for the selected Layer and those under it
+ /*! \param context Context iterator refering to next Layer.
+ ** \param time writeme
+ ** \see Handle::set_time()
+ */
+ virtual void set_time(Context context, Time time)const;
+
+ //! Sets the \a time for the selected Layer and those under it for a specific \a point
+ /*! \param context Context iterator refering to next Layer.
+ ** \param time writeme
+ ** \param point writeme
+ ** \see Handle::set_time()
+ ** \todo \a point should be of the type <tt>const Point \&</tt> */
+ virtual void set_time(Context context, Time time, const Point &point)const;
+
+ //! Gets the color of the Canvas at \a pos
+ /*! \param context Context iterator refering to next Layer.
+ ** \param pos Point which indicates where the Color should come from
+ ** \see Handle::get_color()
+ */
+ virtual Color get_color(Context context, const Point &pos)const;
+
+ //! Renders the Canvas to the given Surface in an accelerated manner
+ /*! \param context Context iterator refering to next Layer.
+ ** \param surface Pointer to Surface to render to.
+ ** \param quality The requested quality-level to render at.
+ ** \param renddesc The associated RendDesc.
+ ** \param cb Pointer to callback object. May be NULL if there is no callback.
+ ** \return \c true on success, \c false on failure
+ ** \see Handle::accelerated_render()
+ */
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+
+ //! Checks to see if a part of the layer is directly under \a point
+ /*! \param context Context iterator refering to next Layer.
+ ** \param point The point to check
+ ** \return The handle of the layer under \a point. If there is not
+ ** a layer under \a point, then returns an empty handle. */
+ virtual Handle hit_check(Context context, const Point &point)const;
+
+ //! Duplicates the Layer
+ virtual Handle clone(const GUID& deriv_guid=GUID())const;
+
+ //! Duplicates the Layer without duplicating the value nodes
+ virtual Layer *simple_clone()const;
+
+protected:
+
+ //! This is called whenever a parameter is changed
+ virtual void on_changed();
+
+ //! Called to figure out the animation time information
+ virtual void get_times_vfunc(Node::time_set &set) const;
+
+ /*
+ -- ** -- S T A T I C F U N C T I O N S --------------------------------------
+ */
+
+public:
+
+ //! Creates a Layer of type \a type
+ /*! If the Layer type is unknown, then a Mime layer is created in its place.
+ ** \param type A string describing the name of the layer to construct.
+ ** \return Always returns a handle to a new Layer.
+ ** \see Mime
+ */
+ static Layer::LooseHandle create(const String &type);
+
+}; // END of class Layer
+
+}; // END of namespace synfig
+
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_bitmap.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "layer_bitmap.h"
+#include "layer.h"
+#include "time.h"
+#include "string.h"
+#include "vector.h"
+
+#include "context.h"
+#include "time.h"
+#include "color.h"
+#include "surface.h"
+#include "renddesc.h"
+#include "target.h"
+
+#include "general.h"
+#include "paramdesc.h"
+#include <ETL/misc>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+synfig::Layer_Bitmap::Layer_Bitmap():
+ Layer_Composite (1.0,Color::BLEND_COMPOSITE),
+ tl (-0.5,0.5),
+ br (0.5,-0.5),
+ c (1),
+ surface (128,128),
+ gamma_adjust (1.0)
+{
+}
+
+bool
+synfig::Layer_Bitmap::set_param(const String & param, ValueBase value)
+{
+ IMPORT(tl);
+ IMPORT(br);
+ IMPORT(c);
+ if(param=="gamma_adjust"&& value.get_type()==ValueBase::TYPE_REAL)
+ {
+ gamma_adjust=1.0/value.get(Real());
+ //gamma_adjust.set_gamma(1.0/value.get(Real()));
+ return true;
+ }
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+synfig::Layer_Bitmap::get_param(const String & param)const
+{
+ EXPORT(tl);
+ EXPORT(br);
+ EXPORT(c);
+ if(param=="gamma_adjust")
+ return 1.0/gamma_adjust;
+
+ if(param=="_width")
+ {
+ return surface.get_w();
+ }
+ if(param=="_height")
+ {
+ return surface.get_h();
+ }
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+Layer_Bitmap::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("tl")
+ .set_local_name(_("Top-Left"))
+ .set_description(_("Upper left-hand Corner of image"))
+ );
+
+ ret.push_back(ParamDesc("br")
+ .set_local_name(_("Bottom-Right"))
+ .set_description(_("Lower right-hand Corner of image"))
+ );
+
+ ret.push_back(ParamDesc("c")
+ .set_local_name(_("Interpolation"))
+ .set_description(_("What type of interpolation to use"))
+ .set_hint("enum")
+ .add_enum_value(0,"nearest",_("Nearest Neighbor"))
+ .add_enum_value(1,"linear",_("Linear"))
+ .add_enum_value(2,"cosine",_("Cosine"))
+ .add_enum_value(3,"cubic",_("Cubic"))
+ );
+
+ ret.push_back(ParamDesc("gamma_adjust")
+ .set_local_name(_("Gamma Adjustment"))
+ );
+
+ return ret;
+}
+
+synfig::Layer::Handle
+Layer_Bitmap::hit_check(synfig::Context context, const synfig::Point &pos)const
+{
+ Point surface_pos;
+ surface_pos=pos-tl;
+
+ surface_pos[0]/=br[0]-tl[0];
+ if(surface_pos[0]<=1.0 && surface_pos[0]>=0.0)
+ {
+ surface_pos[1]/=br[1]-tl[1];
+ if(surface_pos[1]<=1.0 && surface_pos[1]>=0.0)
+ {
+ return const_cast<Layer_Bitmap*>(this);
+ }
+ }
+
+ return context.hit_check(pos);
+}
+
+inline
+const Color&
+synfig::Layer_Bitmap::filter(const Color& c)const
+{
+ if(gamma_adjust==1.0)
+ return c;
+ static Color x;
+ x=c;
+
+ x.set_r(powf((float)x.get_r(),gamma_adjust));
+ x.set_g(powf((float)x.get_g(),gamma_adjust));
+ x.set_b(powf((float)x.get_b(),gamma_adjust));
+ return x;
+}
+
+Color
+synfig::Layer_Bitmap::get_color(Context context, const Point &pos)const
+{
+ Point surface_pos;
+
+ if(!get_amount())
+ return context.get_color(pos);
+
+ surface_pos=pos-tl;
+
+ surface_pos[0]/=br[0]-tl[0];
+ if(surface_pos[0]<=1.0 && surface_pos[0]>=0.0)
+ {
+ surface_pos[1]/=br[1]-tl[1];
+ if(surface_pos[1]<=1.0 && surface_pos[1]>=0.0)
+ {
+ surface_pos[0]*=surface.get_w();
+ surface_pos[1]*=surface.get_h();
+
+ Color ret(Color::alpha());
+
+ switch(c)
+ {
+ case 6: // Undefined
+ case 5: // Undefined
+ case 4: // Undefined
+ case 3: // Cubic
+ ret=surface.cubic_sample(surface_pos[0],surface_pos[1]);
+ break;
+
+ case 2: // Cosine
+ ret=surface.cosine_sample(surface_pos[0],surface_pos[1]);
+ break;
+ case 1: // Linear
+ ret=surface.linear_sample(surface_pos[0],surface_pos[1]);
+ break;
+ case 0: // Nearest Neighbor
+ default:
+ {
+ int x(min(surface.get_w()-1,max(0,round_to_int(surface_pos[0]))));
+ int y(min(surface.get_h()-1,max(0,round_to_int(surface_pos[1]))));
+ ret= surface[y][x];
+ }
+ break;
+ }
+
+ ret=filter(ret);
+
+ if(get_amount()==1 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return ret;
+ else
+ return Color::blend(ret,context.get_color(pos),get_amount(),get_blend_method());
+ }
+ }
+
+ return context.get_color(pos);
+}
+
+bool
+Layer_Bitmap::accelerated_render(Context context,Surface *out_surface,int quality, const RendDesc &renddesc, ProgressCallback *cb) const
+{
+ int interp=c;
+ if(quality>=10)
+ interp=0;
+ else if(quality>=5 && interp>1)
+ interp=1;
+
+ // We can only handle NN and Linear at the moment
+ //if(interp>1)
+ // return Layer_Composite::accelerated_render(context,out_surface,quality,renddesc,cb);
+
+ //if we don't actually have a valid surface just skip us
+ if(!surface.is_valid())
+ {
+ // Render what is behind us
+ return context.accelerated_render(out_surface,quality,renddesc,cb);
+ }
+
+ SuperCallback subcb(cb,1,10000,10001+renddesc.get_h());
+
+ if( get_amount()==1 &&
+ get_blend_method()==Color::BLEND_STRAIGHT &&
+ renddesc.get_tl()==tl &&
+ renddesc.get_br()==br)
+ {
+ // Check for the trivial case
+ if(surface.get_w()==renddesc.get_w() && surface.get_h()==renddesc.get_h() && gamma_adjust==1.0f)
+ {
+ if(cb && !cb->amount_complete(0,100)) return false;
+ *out_surface=surface;
+ if(cb && !cb->amount_complete(100,100)) return false;
+ return true;
+ }
+ out_surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ }
+ else
+ {
+ // Render what is behind us
+ if(!context.accelerated_render(out_surface,quality,renddesc,&subcb))
+ return false;
+ }
+
+ if(cb && !cb->amount_complete(10000,10001+renddesc.get_h())) return false;
+
+ Point obr = renddesc.get_br(),
+ otl = renddesc.get_tl();
+
+ //Vector::value_type pw=renddesc.get_w()/(renddesc.get_br()[0]-renddesc.get_tl()[0]);
+ //Vector::value_type ph=renddesc.get_h()/(renddesc.get_br()[1]-renddesc.get_tl()[1]);
+
+ //A = representation of input (just tl,br) //just a scaling right now
+ //B = representation of output (just tl,br) //just a scaling right now
+ //sa = scaling for input (0,1) -> (0,w/h)
+ //sb = scaling for output (0,1) -> (0,w/h)
+
+ float inwf = br[0] - tl[0];
+ float inhf = br[1] - tl[1];
+
+ float outwf = obr[0] - otl[0];
+ float outhf = obr[1] - otl[1];
+
+ int inw = surface.get_w();
+ int inh = surface.get_h();
+
+ int outw = renddesc.get_w();
+ int outh = renddesc.get_h();
+
+ //need to get the input coords in output space, so we can clip
+
+ //get the desired corners of the bitmap (in increasing order) in integers
+ //floating point corners
+ float x1f = (tl[0] - otl[0])*outw/outwf;
+ float x2f = (br[0] - otl[0])*outw/outwf;
+ float y1f = (tl[1] - otl[1])*outh/outhf;
+ float y2f = (br[1] - otl[1])*outh/outhf;
+
+ if(x1f > x2f) swap(x1f,x2f);
+ if(y1f > y2f) swap(y1f,y2f);
+
+ int x_start = max(0,(int)floor(x1f)); //probably floor
+ int x_end = min(outw,(int)ceil(x2f)); //probably ceil
+ int y_start = max(0,(int)floor(y1f)); //probably floor
+ int y_end = min(outh,(int)ceil(y2f)); //probably ceil
+
+ //need to get the x,y,dx,dy values from output space to input, so we can do fast interpolation
+
+ //get the starting position in input space... for interpolating
+
+ // in int -> out float:
+ // Sb(B^-1)A(Sa^-1) x
+ float inx_start = (((x_start/*+0.5f*/)*outwf/outw + otl[0]) - tl[0])*inw/inwf; //may want to bias this (center of pixel)???
+ float iny_start = (((y_start/*+0.5f*/)*outhf/outh + otl[1]) - tl[1])*inh/inhf; //may want to bias this (center of pixel)???
+
+ //calculate the delta values in input space for one pixel movement in output space
+ //same matrix but with a vector instead of a point...
+ float indx = outwf*(inw)/((outw)*inwf); //translations died
+ float indy = outhf*(inh)/((outh)*inhf); //translations died
+
+ //perhaps use a DDA algorithm... if faster...
+ // will still want pixel fractions to be floating point since colors are
+
+ //synfig::info("xstart:%d ystart:%d xend:%d yend:%d",x_start,y_start,x_end,y_end);
+
+ //start drawing at the start of the bitmap (either origin or corner of input...)
+ //and get other info
+ Surface::alpha_pen pen(out_surface->get_pen(x_start,y_start));
+ pen.set_alpha(get_amount());
+ pen.set_blend_method(get_blend_method());
+
+ //check if we should use the downscale filtering
+ if(quality <= 7)
+ {
+ //the stride of the value should be inverted because we want to downsample
+ //when the stride is small, not big
+ //int multw = (int)ceil(indx);
+ //int multh = (int)ceil(indy);
+
+ if(indx > 1.7 || indy > 1.7)
+ {
+ /*synfig::info("Decided to downsample? ratios - (%f,%f) -> (%d,%d)",
+ indx, indy, multw, multh); */
+
+ //use sample rect here...
+
+ float iny, inx;
+ int x,y;
+
+ //Point sample - truncate
+ iny = iny_start;//+0.5f;
+ for(y = y_start; y < y_end; ++y, pen.inc_y(), iny += indy)
+ {
+ inx = inx_start;//+0.5f;
+ for(x = x_start; x < x_end; x++, pen.inc_x(), inx += indx)
+ {
+ Color rc = surface.sample_rect_clip(inx,iny,inx+indx,iny+indy);
+ pen.put_value(filter(rc));
+ }
+ pen.dec_x(x_end-x_start);
+ }
+
+ //Color c = (*out_surface)[0][0];
+ //synfig::info("ValueBase of first pixel = (%f,%f,%f,%f)",c.get_r(),c.get_g(),c.get_b(),c.get_a());
+
+ return true;
+ }
+ }
+
+ //perform normal interpolation
+ if(interp==0)
+ {
+ //synfig::info("Decided to do nearest neighbor");
+ float iny, inx;
+ int x,y;
+
+ //Point sample - truncate
+ iny = iny_start;//+0.5f;
+ for(y = y_start; y < y_end; y++, pen.inc_y(), iny += indy)
+ {
+ inx = inx_start;//+0.5f;
+ int yclamp = min(inh-1, max(0, round_to_int(iny)));
+ for(x = x_start; x < x_end; x++, pen.inc_x(), inx += indx)
+ {
+ int xclamp = min(inw-1, max(0, round_to_int(inx)));
+ Color c = filter(surface[yclamp][xclamp]);
+ pen.put_value(c); //must get rid of the clip
+ }
+ pen.dec_x(x_end-x_start);
+ }
+ }
+ else
+ if(interp==1)
+ {
+ //bilinear filtering
+
+ //float xmf,xpf,ymf,ypf;
+ //int xm,xp,ym,yp;
+ float inx,iny;
+ int x,y;
+
+ //can probably buffer for x values...
+
+ //loop and based on inx,iny sample input image
+ iny = iny_start;
+ for(y = y_start; y < y_end; y++, pen.inc_y(), iny += indy)
+ {
+ inx = inx_start;
+ for(x = x_start; x < x_end; x++, pen.inc_x(), inx += indx)
+ {
+ pen.put_value(filter(surface.linear_sample(inx,iny)));
+ }
+ pen.dec_x(x_end-x_start);
+
+ }
+ }
+ else
+ if(interp==2)
+ {
+ //cosine filtering
+
+ //float xmf,xpf,ymf,ypf;
+ //int xm,xp,ym,yp;
+ float inx,iny;
+ int x,y;
+
+ //can probably buffer for x values...
+
+ //loop and based on inx,iny sample input image
+ iny = iny_start;
+ for(y = y_start; y < y_end; y++, pen.inc_y(), iny += indy)
+ {
+ inx = inx_start;
+ for(x = x_start; x < x_end; x++, pen.inc_x(), inx += indx)
+ {
+ pen.put_value(filter(surface.cosine_sample(inx,iny)));
+ }
+ pen.dec_x(x_end-x_start);
+
+ }
+ }
+ else
+ {
+ //cubic filtering
+
+ //float xmf,xpf,ymf,ypf;
+ //int xm,xp,ym,yp;
+ float inx,iny;
+ int x,y;
+
+ //can probably buffer for x values...
+
+ //loop and based on inx,iny sample input image
+ iny = iny_start;
+ for(y = y_start; y < y_end; y++, pen.inc_y(), iny += indy)
+ {
+ inx = inx_start;
+ for(x = x_start; x < x_end; x++, pen.inc_x(), inx += indx)
+ {
+ pen.put_value(filter(surface.cubic_sample(inx,iny)));
+ }
+ pen.dec_x(x_end-x_start);
+
+ }
+ }
+
+ return true;
+}
+
+Rect
+Layer_Bitmap::get_bounding_rect()const
+{
+ return Rect(tl,br);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_bitmap.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LAYER_BITMAP_H
+#define __SYNFIG_LAYER_BITMAP_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "layer_composite.h"
+#include "surface.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class Layer_Bitmap
+** \todo writeme
+*/
+class Layer_Bitmap : public Layer_Composite, public Layer_NoDeform
+{
+ const Color& filter(const Color& c)const;
+public:
+ typedef etl::handle<Layer_Bitmap> Handle;
+
+ Point tl;
+ Point br;
+ int c;
+ mutable Surface surface;
+
+ Real gamma_adjust;
+
+ Layer_Bitmap();
+
+ virtual bool set_param(const String & param, ValueBase value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+
+ virtual Vocab get_param_vocab()const;
+
+ virtual Rect get_bounding_rect()const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+
+ virtual synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+}; // END of class Layer_Bitmap
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_composite.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "layer_composite.h"
+#include "context.h"
+#include "time.h"
+#include "color.h"
+#include "surface.h"
+#include "renddesc.h"
+#include "target.h"
+
+#include "layer_bitmap.h"
+
+#include "general.h"
+#include "render.h"
+#include "paramdesc.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+bool
+Layer_Composite::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc_, ProgressCallback *cb) const
+{
+ RendDesc renddesc(renddesc_);
+
+ if(!amount_)
+ return context.accelerated_render(surface,quality,renddesc,cb);
+
+ CanvasBase image;
+
+ SuperCallback stageone(cb,0,50000,100000);
+ SuperCallback stagetwo(cb,50000,100000,100000);
+
+ Layer_Bitmap::Handle surfacelayer(new class Layer_Bitmap());
+
+ Context iter;
+
+ for(iter=context;*iter;iter++)
+ image.push_back(*iter);
+
+ image.push_front(surfacelayer.get());
+
+ // We want to go ahead and schedule any other
+ // layers...
+// while(dynamic_cast<Layer_Composite*>(context->get()))
+// while(context->get() &&
+// &context->get()->AcceleratedRender==
+// &Layer_Composite::AcceleratedRender)
+// image.push_back(*(context++));
+
+ image.push_back(0); // Alpha black
+
+ // Render the backdrop
+ if(!context.accelerated_render(&surfacelayer->surface,quality,renddesc,&stageone))
+ return false;
+
+ if(quality<=4)surfacelayer->c=3;else
+ if(quality<=5)surfacelayer->c=2;
+ else if(quality<=6)surfacelayer->c=1;
+ else surfacelayer->c=0;
+ surfacelayer->tl=renddesc.get_tl();
+ surfacelayer->br=renddesc.get_br();
+ surfacelayer->set_blend_method(Color::BLEND_STRAIGHT);
+
+ image.push_front(const_cast<synfig::Layer_Composite*>(this));
+
+ // Set up a surface target
+ Target::Handle target(surface_target(surface));
+
+ if(!target)
+ {
+ if(cb)cb->error(_("Unable to create surface target"));
+ return false;
+ }
+
+ RendDesc desc(renddesc);
+
+ target->set_rend_desc(&desc);
+
+ // Render the scene
+ return render(Context(image.begin()),target,desc,&stagetwo);
+ //return render_threaded(Context(image.begin()),target,desc,&stagetwo,2);
+}
+
+Rect
+Layer_Composite::get_full_bounding_rect(Context context)const
+{
+ if(is_disabled() || Color::is_onto(get_blend_method()))
+ return context.get_full_bounding_rect();
+
+ return context.get_full_bounding_rect()|get_bounding_rect();
+}
+
+Layer::Vocab
+Layer_Composite::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer::get_param_vocab());
+
+ ret.push_back(ParamDesc(amount_,"amount")
+ .set_local_name(_("Amount"))
+ );
+ ret.push_back(ParamDesc(blend_method_,"blend_method")
+ .set_local_name(_("Blend Method"))
+ );
+
+ return ret;
+}
+
+bool
+Layer_Composite::set_param(const String & param, const ValueBase &value)
+{
+ if(param=="amount" && value.same_type_as(amount_))
+ amount_=value.get(amount_);
+ else
+ if(param=="blend_method" && value.same_type_as(int()))
+ blend_method_=static_cast<Color::BlendMethod>(value.get(int()));
+ else
+ return Layer::set_param(param,value);
+ return true;
+}
+
+ValueBase
+Layer_Composite::get_param(const String & param)const
+{
+ if(param=="amount")
+ return get_amount();
+ if(param=="blend_method")
+ return static_cast<int>(get_blend_method());
+ return Layer::get_param(param);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_composite.h
+** \brief Composite Layer Class Implementation
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LAYER_COMPOSITE_H
+#define __SYNFIG_LAYER_COMPOSITE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "layer.h"
+#include "color.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Layer_NoDeform {};
+
+
+/*! \class Layer_Composite
+** \brief Base class for layers that put stuff ontop of lower layers
+*/
+class Layer_Composite : public Layer
+{
+private:
+
+ float amount_;
+
+ Color::BlendMethod blend_method_;
+
+protected:
+
+ Layer_Composite(
+ float amount=1.0,
+ Color::BlendMethod blend_method=Color::BLEND_COMPOSITE
+ ):
+ amount_ (amount),
+ blend_method_ (blend_method)
+ { }
+
+public:
+
+ float get_amount()const { return amount_; }
+
+ Layer_Composite& set_amount(float x) { amount_=x; return *this; }
+
+ Color::BlendMethod get_blend_method()const { return blend_method_; }
+
+ Layer_Composite& set_blend_method(Color::BlendMethod x) { blend_method_=x; return *this; }
+
+ virtual bool is_solid_color()const { return amount_==1.0f && blend_method_==Color::BLEND_STRAIGHT; }
+
+ bool is_disabled()const { return amount_==0.0f; }
+
+ virtual Vocab get_param_vocab()const;
+
+ virtual bool set_param(const String ¶m, const ValueBase &value);
+
+ virtual ValueBase get_param(const String ¶m)const;
+
+ virtual Rect get_full_bounding_rect(Context context)const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+}; // END of class Layer_Composite
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_mime.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "layer_mime.h"
+
+#include "layer.h"
+#include "time.h"
+#include "string.h"
+#include "vector.h"
+
+#include "context.h"
+#include "time.h"
+#include "color.h"
+#include "surface.h"
+#include "renddesc.h"
+#include "target.h"
+
+#include "general.h"
+#include "paramdesc.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Layer_Mime::Layer_Mime(String x):name(x)
+{
+ // Throw a bogus default version onto the parameter list.
+ param_list["Version"]="9";
+}
+
+String
+Layer_Mime::get_version()const
+{
+ return get_param("Version").get(String());
+}
+
+bool
+Layer_Mime::set_version(const String &ver)
+{
+ return set_param("Version",ver);
+}
+
+String
+Layer_Mime::get_local_name()const
+{
+ return _("[MIME]")+get_name();
+}
+
+bool
+Layer_Mime::set_param(const String ¶m, const ValueBase &value)
+{
+ // Don't try to set the name
+ if(param=="name" || param=="Name" || param=="name__")
+ return false;
+
+ // Otherwise, remember this parameter's value
+ param_list[param]=value;
+ return true;
+}
+
+ValueBase
+Layer_Mime::get_param(const String ¶m)const
+{
+ // If they are requesting the name of
+ // the layer, just return it
+ if(param=="name" || param=="Name" || param=="name__")
+ return ValueBase(name);
+
+ // Otherwise, return the stored parameter value
+ map<string,ValueBase>::const_iterator iter=param_list.find(param);
+ if(iter!=param_list.end())
+ return iter->second;
+ return ValueBase();
+}
+
+Color
+Layer_Mime::get_color(Context context, const Point &pos)const
+{
+ // A Layer_Mime layer should do nothing at all.
+ return context.get_color(pos);
+}
+
+bool
+Layer_Mime::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ // A Layer_Mime layer should do nothing at all.
+ return context.accelerated_render(surface,quality,renddesc,cb);
+}
+
+Layer::Vocab
+Layer_Mime::get_param_vocab()const
+{
+ Layer::Vocab ret;
+ map<string,ValueBase>::const_iterator iter;
+
+ // Construct the vocabulary from the stored
+ // parameters
+ for(iter=param_list.begin();iter!=param_list.end();iter++)
+ {
+ // Make sure that we don't add the version
+ // into the vocabulary
+ if(iter->first!="Version")
+ ret.push_back(ParamDesc(iter->first));
+ }
+
+ // ... and return it
+ return ret;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_mime.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LAYER_MIME_H
+#define __SYNFIG_LAYER_MIME_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "layer.h"
+#include "string.h"
+#include <map>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class Layer_Mime
+** The mime layer is a layer that is used when an unknown
+** layer type is requested. This allows people without
+** all of the correct layers installed to still work with
+** that composition.
+*/
+class Layer_Mime : public Layer
+{
+ std::map<String,ValueBase> param_list;
+ String name;
+public:
+ Layer_Mime(String name);
+
+ virtual String get_version()const;
+
+ virtual bool set_version(const String &ver);
+
+ virtual bool set_param(const String ¶m, const ValueBase &value);
+
+ virtual ValueBase get_param(const String ¶m)const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+
+ virtual Vocab get_param_vocab()const;
+ virtual String get_local_name()const;
+
+};
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_motionblur.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "string.h"
+#include "layer_motionblur.h"
+#include "time.h"
+#include "context.h"
+#include "paramdesc.h"
+#include "renddesc.h"
+#include "surface.h"
+#include "value.h"
+#include "valuenode.h"
+#include "canvas.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace synfig;
+using namespace etl;
+using namespace std;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Layer_MotionBlur);
+SYNFIG_LAYER_SET_NAME(Layer_MotionBlur,"MotionBlur"); // todo: use motion_blur
+SYNFIG_LAYER_SET_LOCAL_NAME(Layer_MotionBlur,_("Motion Blur"));
+SYNFIG_LAYER_SET_CATEGORY(Layer_MotionBlur,_("Blurs"));
+SYNFIG_LAYER_SET_VERSION(Layer_MotionBlur,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Layer_MotionBlur,"$Id$");
+
+/* === M E M B E R S ======================================================= */
+
+Layer_MotionBlur::Layer_MotionBlur():
+ Layer_Composite (1.0,Color::BLEND_STRAIGHT),
+ aperture (0)
+{
+}
+
+bool
+Layer_MotionBlur::set_param(const String ¶m, const ValueBase &value)
+{
+
+ IMPORT(aperture);
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+Layer_MotionBlur::get_param(const String ¶m)const
+{
+ EXPORT(aperture);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+void
+Layer_MotionBlur::set_time(Context context, Time time)const
+{
+ context.set_time(time);
+ time_cur=time;
+}
+
+void
+Layer_MotionBlur::set_time(Context context, Time time, const Point &pos)const
+{
+ context.set_time(time,pos);
+ time_cur=time;
+}
+
+Color
+Layer_MotionBlur::get_color(Context context, const Point &pos)const
+{
+/* if(aperture)
+ {
+ Time time(time_cur);
+ time+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) *aperture -aperture*0.5;
+ context.set_time(time, pos);
+ }
+*/
+ return context.get_color(pos);
+}
+
+Layer::Vocab
+Layer_MotionBlur::get_param_vocab()const
+{
+ Layer::Vocab ret;
+ //ret=Layer_Composite::get_param_vocab();
+
+ ret.push_back(ParamDesc("aperture")
+ .set_local_name(_("Aperture"))
+ .set_description(_("Shutter Time"))
+ );
+
+ return ret;
+}
+
+bool
+Layer_MotionBlur::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ if(aperture && quality<=10)
+ {
+ //int x, y;
+ SuperCallback subimagecb;
+ int samples=1;
+ switch(quality)
+ {
+ case 1: // Production Quality
+ samples=32;
+ break;
+ case 2: // Excellent Quality
+ samples=24;
+ break;
+ case 3: // Good Quality
+ samples=16;
+ break;
+ case 4: // Moderate Quality
+ samples=12;
+ break;
+ case 5: // Draft Quality
+ samples=7;
+ break;
+ case 6:
+ samples=6;
+ break;
+ case 7:
+ samples=5;
+ break;
+ case 8:
+ samples=3;
+ break;
+ case 9:
+ samples=3;
+ break;
+ case 10: // Rough Quality
+ default:
+ samples=2;
+ break;
+
+ }
+
+ if (samples == 1) return context.accelerated_render(surface,quality,renddesc,cb);
+
+ Surface tmp;
+ int i;
+ float scale, divisor = 0;
+
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ surface->clear();
+
+ for(i=0;i<samples;i++)
+ {
+ subimagecb=SuperCallback(cb,i*(5000/samples),(i+1)*(5000/samples),5000);
+ context.set_time(time_cur-(aperture*(samples-1-i)/(samples-1)));
+ if(!context.accelerated_render(&tmp,quality,renddesc,&subimagecb))
+ return false;
+ scale = 1.0/(samples-i);
+ divisor += scale;
+ for(int y=0;y<renddesc.get_h();y++)
+ for(int x=0;x<renddesc.get_w();x++)
+ (*surface)[y][x]+=tmp[y][x].premult_alpha()*scale;
+ }
+ for(int y=0;y<renddesc.get_h();y++)
+ for(int x=0;x<renddesc.get_w();x++)
+ (*surface)[y][x]=((*surface)[y][x]/divisor).demult_alpha();
+ }
+ else
+ return context.accelerated_render(surface,quality,renddesc,cb);
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_motionblur.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LAYER_MOTIONBLUR_H__
+#define __SYNFIG_LAYER_MOTIONBLUR_H__
+
+/* === H E A D E R S ======================================================= */
+
+#include "layer_composite.h"
+#include "time.h"
+
+/* === S T R U C T S & C L A S S E S ======================================= */
+
+namespace synfig {
+
+class Layer_MotionBlur : public synfig::Layer_Composite
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ Time aperture;
+
+ mutable Time time_cur;
+
+public:
+
+ Layer_MotionBlur();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+
+ virtual void set_time(Context context, Time time)const;
+
+ virtual void set_time(Context context, Time time, const Point &point)const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+
+ virtual Vocab get_param_vocab()const;
+
+}; // END of class Layer_MotionBlur
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_pastecanvas.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "layer_pastecanvas.h"
+#include "string.h"
+#include "time.h"
+#include "context.h"
+#include "paramdesc.h"
+#include "renddesc.h"
+#include "surface.h"
+#include "value.h"
+#include "valuenode.h"
+#include "canvas.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+#define MAX_DEPTH 10
+
+//#ifdef __APPLE__
+//#define SYNFIG_NO_CLIP
+//#endif
+
+/* === C L A S S E S ======================================================= */
+
+class depth_counter // Makes our recursive depth counter exception-safe
+{
+ int *depth;
+public:
+ depth_counter(int &x):depth(&x) { (*depth)++; }
+ ~depth_counter() { (*depth)--; }
+};
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Layer_PasteCanvas);
+SYNFIG_LAYER_SET_NAME(Layer_PasteCanvas,"PasteCanvas"); // todo: use paste_canvas
+SYNFIG_LAYER_SET_LOCAL_NAME(Layer_PasteCanvas,_("Paste Canvas"));
+SYNFIG_LAYER_SET_CATEGORY(Layer_PasteCanvas,_("Other"));
+SYNFIG_LAYER_SET_VERSION(Layer_PasteCanvas,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Layer_PasteCanvas,"$Id$");
+
+/* === M E T H O D S ======================================================= */
+
+Layer_PasteCanvas::Layer_PasteCanvas():
+ origin(0,0),
+ depth(0),
+ zoom(0),
+ time_offset(0)
+{
+ children_lock=false;
+ muck_with_time_=true;
+ curr_time=Time::begin();
+}
+
+Layer_PasteCanvas::~Layer_PasteCanvas()
+{
+/* if(canvas)
+ canvas->parent_set.erase(this);
+*/
+
+ //if(canvas)DEBUGINFO(strprintf("%d",canvas->count()));
+
+ set_sub_canvas(0);
+
+ //if(canvas && (canvas->is_inline() || !get_canvas() || get_canvas()->get_root()!=canvas->get_root()))
+ // canvas->unref();
+}
+
+String
+Layer_PasteCanvas::get_local_name()const
+{
+ if(!canvas) return _("Pasted Canvas");
+ if(canvas->is_inline()) return _("Inline Canvas");
+ if(canvas->get_root()==get_canvas()->get_root()) return '[' + canvas->get_id() + ']';
+
+ return '[' + canvas->get_file_name() + ']';
+}
+
+Layer::Vocab
+Layer_PasteCanvas::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("origin")
+ .set_local_name(_("Origin"))
+ .set_description(_("Point where you want the origin to be"))
+ );
+ ret.push_back(ParamDesc("canvas")
+ .set_local_name(_("Canvas"))
+ .set_description(_("Canvas to paste"))
+ );
+ ret.push_back(ParamDesc("zoom")
+ .set_local_name(_("Zoom"))
+ .set_description(_("Size of canvas"))
+ );
+
+ ret.push_back(ParamDesc("time_offset")
+ .set_local_name(_("Time Offset"))
+ );
+
+ ret.push_back(ParamDesc("children_lock")
+ .set_local_name(_("Children Lock"))
+ );
+
+ return ret;
+}
+
+bool
+Layer_PasteCanvas::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(origin);
+
+ if(param=="canvas" && value.same_type_as(Canvas::Handle()))
+ {
+ set_sub_canvas(value.get(Canvas::Handle()));
+ return true;
+ }
+
+// IMPORT(canvas);
+ IMPORT(children_lock);
+ IMPORT(zoom);
+ IMPORT(time_offset);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+void
+Layer_PasteCanvas::set_sub_canvas(etl::handle<synfig::Canvas> x)
+{
+ if(canvas && muck_with_time_)
+ remove_child(canvas.get());
+
+ if(canvas && (canvas->is_inline() || !get_canvas() || get_canvas()->get_root()!=canvas->get_root()))
+ canvas->unref();
+
+ child_changed_connection.disconnect();
+
+ canvas=x;
+
+ /*if(canvas)
+ child_changed_connection=canvas->signal_changed().connect(
+ sigc::mem_fun(
+ *this,
+ &Layer_PasteCanvas::changed
+ )
+ );
+ */
+ if(canvas)
+ bounds=(canvas->get_context().get_full_bounding_rect()-canvas->rend_desc().get_focus())*exp(zoom)+origin+canvas->rend_desc().get_focus();
+
+ if(canvas && muck_with_time_)
+ add_child(canvas.get());
+
+ if(canvas && (canvas->is_inline() || !get_canvas() || get_canvas()->get_root()!=canvas->get_root()))
+ canvas->ref();
+
+ if(canvas)
+ on_canvas_set();
+}
+
+// This is called whenever the parent canvas gets set/changed
+void
+Layer_PasteCanvas::on_canvas_set()
+{
+ //synfig::info("before count()=%d",count());
+ if(get_canvas() && canvas && canvas->is_inline() && canvas->parent()!=get_canvas())
+ {
+ //synfig::info("during count()=%d",count());
+ canvas->set_inline(get_canvas());
+ }
+ //synfig::info("after count()=%d",count());
+}
+
+ValueBase
+Layer_PasteCanvas::get_param(const String& param)const
+{
+ EXPORT(origin);
+ EXPORT(canvas);
+ EXPORT(zoom);
+ EXPORT(time_offset);
+ EXPORT(children_lock);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+void
+Layer_PasteCanvas::set_time(Context context, Time time)const
+{
+ if(depth==MAX_DEPTH)return;depth_counter counter(depth);
+ curr_time=time;
+
+ context.set_time(time);
+ if(canvas)
+ {
+ canvas->set_time(time+time_offset);
+
+ bounds=(canvas->get_context().get_full_bounding_rect()-canvas->rend_desc().get_focus())*exp(zoom)+origin+canvas->rend_desc().get_focus();
+ }
+ else
+ bounds=Rect::zero();
+}
+
+synfig::Layer::Handle
+Layer_PasteCanvas::hit_check(synfig::Context context, const synfig::Point &pos)const
+{
+ if(depth==MAX_DEPTH)return 0;depth_counter counter(depth);
+
+ if (canvas) {
+ Point target_pos=(pos-canvas->rend_desc().get_focus()-origin)/exp(zoom)+canvas->rend_desc().get_focus();
+
+ if(canvas && get_amount() && canvas->get_context().get_color(target_pos).get_a()>=0.25)
+ {
+ if(!children_lock)
+ {
+ return canvas->get_context().hit_check(target_pos);
+ }
+ return const_cast<Layer_PasteCanvas*>(this);
+ }
+ }
+ return context.hit_check(pos);
+}
+
+Color
+Layer_PasteCanvas::get_color(Context context, const Point &pos)const
+{
+ if(!canvas || !get_amount())
+ return context.get_color(pos);
+
+ if(depth==MAX_DEPTH)return Color::alpha();depth_counter counter(depth);
+
+ Point target_pos=(pos-canvas->rend_desc().get_focus()-origin)/exp(zoom)+canvas->rend_desc().get_focus();
+
+ return Color::blend(canvas->get_context().get_color(target_pos),context.get_color(pos),get_amount(),get_blend_method());
+}
+
+
+bool
+Layer_PasteCanvas::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ if(cb && !cb->amount_complete(0,10000)) return false;
+
+ if(depth==MAX_DEPTH)
+ {
+ DEBUGPOINT();
+ // if we are at the extent of our depth,
+ // then we should just return whatever is under us.
+ return context.accelerated_render(surface,quality,renddesc,cb);
+ }
+ depth_counter counter(depth);
+
+ if(!canvas || !get_amount())
+ return context.accelerated_render(surface,quality,renddesc,cb);
+
+ if(muck_with_time_ && curr_time!=Time::begin() && canvas->get_time()!=curr_time+time_offset)
+ {
+ canvas->set_time(curr_time+time_offset);
+ }
+
+ SuperCallback stageone(cb,0,4500,10000);
+ SuperCallback stagetwo(cb,4500,9000,10000);
+ SuperCallback stagethree(cb,9000,9999,10000);
+
+ RendDesc desc(renddesc);
+ Vector::value_type zoomfactor=1.0/exp(zoom);
+ desc.clear_flags();
+ desc.set_tl((desc.get_tl()-canvas->rend_desc().get_focus()-origin)*zoomfactor+canvas->rend_desc().get_focus());
+ desc.set_br((desc.get_br()-canvas->rend_desc().get_focus()-origin)*zoomfactor+canvas->rend_desc().get_focus());
+ desc.set_flags(RendDesc::PX_ASPECT);
+
+ if(is_solid_color() || context->empty())
+ {
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ surface->clear();
+ }
+ else if(!context.accelerated_render(surface,quality,renddesc,&stageone))
+ return false;
+ Color::BlendMethod blend_method(get_blend_method());
+
+ const Rect full_bounding_rect(canvas->get_context().get_full_bounding_rect());
+
+ if(context->empty())
+ {
+ if(Color::is_onto(blend_method))
+ return true;
+
+ if(blend_method==Color::BLEND_COMPOSITE)
+ blend_method=Color::BLEND_STRAIGHT;
+ }
+ else
+ if(!etl::intersect(context.get_full_bounding_rect(),full_bounding_rect+origin))
+ {
+ if(Color::is_onto(blend_method))
+ return true;
+
+ if(blend_method==Color::BLEND_COMPOSITE)
+ blend_method=Color::BLEND_STRAIGHT;
+ }
+
+#ifndef SYNFIG_NO_CLIP
+ {
+ //synfig::info("PasteCanv Clip");
+ Rect area(desc.get_rect()&full_bounding_rect);
+
+ Point min(area.get_min());
+ Point max(area.get_max());
+
+ if(desc.get_tl()[0]>desc.get_br()[0])
+ swap(min[0],max[0]);
+ if(desc.get_tl()[1]>desc.get_br()[1])
+ swap(min[1],max[1]);
+
+ const int
+ x(floor_to_int((min[0]-desc.get_tl()[0])/desc.get_pw())),
+ y(floor_to_int((min[1]-desc.get_tl()[1])/desc.get_ph())),
+ w(ceil_to_int((max[0]-desc.get_tl()[0])/desc.get_pw())-x),
+ h(ceil_to_int((max[1]-desc.get_tl()[1])/desc.get_ph())-y);
+
+ desc.set_subwindow(x,y,w,h);
+
+ Surface pastesurface;
+
+ if(area.area()<=0.000001 || desc.get_w()==0 || desc.get_h()==0)
+ {
+ if(cb && !cb->amount_complete(10000,10000)) return false;
+
+ return true;
+ }
+
+ if(!canvas->get_context().accelerated_render(&pastesurface,quality,desc,&stagetwo))
+ return false;
+
+ Surface::alpha_pen apen(surface->get_pen(x,y));
+
+ apen.set_alpha(get_amount());
+ apen.set_blend_method(blend_method);
+
+ pastesurface.blit_to(apen);
+ }
+#else
+ {
+ Surface pastesurface;
+
+ if(!canvas->get_context().accelerated_render(&pastesurface,quality,desc,&stagetwo))
+ return false;
+
+ Surface::alpha_pen apen(surface->begin());
+
+ apen.set_alpha(get_amount());
+ apen.set_blend_method(blend_method);
+
+ pastesurface.blit_to(apen);
+ }
+#endif
+
+ if(cb && !cb->amount_complete(10000,10000)) return false;
+
+ return true;
+}
+
+Rect
+Layer_PasteCanvas::get_bounding_rect()const
+{
+ return bounds;
+}
+
+void Layer_PasteCanvas::get_times_vfunc(Node::time_set &set) const
+{
+ Node::time_set tset;
+ if(canvas) tset = canvas->get_times();
+
+ Node::time_set::iterator i = tset.begin(),
+ end = tset.end();
+
+ //Make sure we offset the time...
+ //TODO: SOMETHING STILL HAS TO BE DONE WITH THE OTHER DIRECTION
+ // (recursing down the tree needs to take this into account too...)
+ for(; i != end; ++i)
+ {
+ set.insert(*i + time_offset);
+ }
+
+ Layer::get_times_vfunc(set);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_pastecanvas.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LAYER_PASTEIMAGE_H
+#define __SYNFIG_LAYER_PASTEIMAGE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "layer_composite.h"
+#include "color.h"
+#include "vector.h"
+#include "real.h"
+#include "time.h"
+#include "canvasbase.h"
+#include "canvas.h"
+#include "rect.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Layer_PasteCanvas : public Layer_Composite, public Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+private:
+
+ Vector origin;
+
+ etl::loose_handle<synfig::Canvas> canvas;
+
+ //! Recursion depth counter
+ mutable int depth;
+
+ Real zoom;
+
+ Time time_offset;
+
+ mutable Time curr_time;
+
+ bool muck_with_time_;
+
+ bool children_lock;
+
+ mutable Rect bounds;
+
+ sigc::connection child_changed_connection;
+public:
+
+ virtual void on_canvas_set();
+
+ void set_muck_with_time(bool x=false) { muck_with_time_=x; }
+
+ etl::handle<synfig::Canvas> get_sub_canvas()const { return canvas; }
+ void set_sub_canvas(etl::handle<synfig::Canvas> x);
+
+ Real get_zoom()const { return zoom; }
+
+ Time get_time_offset()const { return time_offset; }
+
+ Point get_origin()const { return origin; }
+
+ Layer_PasteCanvas();
+ virtual ~Layer_PasteCanvas();
+
+ virtual String get_local_name()const;
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+
+ virtual void set_time(Context context, Time time)const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+
+ virtual Vocab get_param_vocab()const;
+
+ virtual synfig::Rect get_bounding_rect()const;
+
+ virtual synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+protected:
+ virtual void get_times_vfunc(Node::time_set &set) const;
+
+}; // END of class Layer_PasteCanvas
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_polygon.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "layer_polygon.h"
+#include "string.h"
+#include "time.h"
+#include "context.h"
+#include "paramdesc.h"
+#include "renddesc.h"
+#include "surface.h"
+#include "value.h"
+#include "valuenode.h"
+//#include "ETL/bezier"
+#include <vector>
+
+#include <deque>
+using std::deque;
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Layer_Polygon);
+SYNFIG_LAYER_SET_NAME(Layer_Polygon,"polygon");
+SYNFIG_LAYER_SET_LOCAL_NAME(Layer_Polygon,_("Polygon"));
+SYNFIG_LAYER_SET_CATEGORY(Layer_Polygon,_("Geometry"));
+SYNFIG_LAYER_SET_VERSION(Layer_Polygon,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Layer_Polygon,"$Id$");
+
+/* === C L A S S E S ======================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Layer_Polygon::Layer_Polygon():
+ Layer_Shape (1.0,Color::BLEND_COMPOSITE),
+ vector_list (0)
+{
+ vector_list.push_back(Point(0,0.5));
+ vector_list.push_back(Point(-0.333333,0));
+ vector_list.push_back(Point(0.333333,0));
+ sync();
+}
+
+Layer_Polygon::~Layer_Polygon()
+{
+}
+
+void
+Layer_Polygon::sync()
+{
+/*
+ int i,pointcount=vector_list.size();
+
+ if(pointcount<3)
+ return;
+
+ //Layer_Shape::clear();
+ //clear();
+
+ // Build edge table
+ move_to(vector_list[0][0],vector_list[0][1]);
+
+ for(i = 1;i < pointcount; i++)
+ {
+ if(isnan(vector_list[i][0]) || isnan(vector_list[i][1]))
+ break;
+ line_to(vector_list[i][0],vector_list[i][1]);
+ }
+ close();
+ //endpath();
+*/
+}
+
+void
+Layer_Polygon::add_polygon(const vector<Point> &point_list)
+{
+ int i,pointcount=point_list.size();
+
+ if(pointcount<3)
+ return;
+
+ //Layer_Shape::clear();
+ //clear();
+
+ // Build edge table
+ move_to(point_list[0][0],point_list[0][1]);
+
+ for(i = 1;i < pointcount; i++)
+ {
+ if(isnan(point_list[i][0]) || isnan(point_list[i][1]))
+ break;
+ line_to(point_list[i][0],point_list[i][1]);
+ }
+ close();
+ //endpath();
+}
+
+void
+Layer_Polygon::clear()
+{
+ Layer_Shape::clear();
+ vector_list.clear();
+}
+
+bool
+Layer_Polygon::set_param(const String & param, const ValueBase &value)
+{
+ if( param=="vector_list" && value.same_type_as(vector_list))
+ {
+ vector_list=value;
+ Layer_Shape::clear();
+ add_polygon(value);
+ sync();
+ return true;
+ }
+
+ return Layer_Shape::set_param(param,value);
+}
+
+ValueBase
+Layer_Polygon::get_param(const String ¶m)const
+{
+ EXPORT(vector_list);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Shape::get_param(param);
+}
+
+Layer::Vocab
+Layer_Polygon::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Shape::get_param_vocab());
+
+ ret.push_back(ParamDesc("vector_list")
+ .set_local_name(_("Vector List"))
+ .set_origin("offset")
+ );
+
+ return ret;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_polygon.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LAYER_POLYGON_H
+#define __SYNFIG_LAYER_POLYGON_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "layer_shape.h"
+#include "color.h"
+#include "vector.h"
+#include <list>
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class Layer_Polygon
+** \brief writeme
+** \todo This layer needs to support multiple polygons */
+class Layer_Polygon : public Layer_Shape
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ //exported data
+ std::vector< Point > vector_list;
+
+protected:
+
+ Layer_Polygon();
+
+public:
+
+ ~Layer_Polygon();
+
+ //! Adds a polygon to the layer
+ /*! The edge data is automatically added to the
+ ** EdgeTable, so there is no need to call sync()
+ ** after adding a polygon using this function.
+ ** \param point_list A list containing the
+ ** points that define the polygon's parameter.
+ */
+ void add_polygon(const std::vector<Point> &point_list);
+
+ //! Clears out any polygon data
+ /*! Also clears out the EdgeTable, so there is no
+ ** need to call sync() after using this function.
+ */
+ void clear();
+
+ //! Updates EdgeTable so it will reflect the parameter data
+ void sync();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Vocab get_param_vocab()const;
+
+private:
+ class PolySpan;
+ bool render_polyspan(Surface *surface,PolySpan &polyspan)const;
+}; // END of Layer_Polygon
+
+}; // END of namespace synfig
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_shape.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "layer_shape.h"
+#include "string.h"
+#include "time.h"
+#include "context.h"
+#include "paramdesc.h"
+#include "renddesc.h"
+#include "surface.h"
+#include "value.h"
+#include "valuenode.h"
+#include "float.h"
+#include "blur.h"
+
+#include "curve_helper.h"
+
+#include <vector>
+
+#include <deque>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Layer_Shape);
+SYNFIG_LAYER_SET_NAME(Layer_Shape,"shape");
+SYNFIG_LAYER_SET_LOCAL_NAME(Layer_Shape,_("Shape"));
+SYNFIG_LAYER_SET_CATEGORY(Layer_Shape,_("Internal"));
+SYNFIG_LAYER_SET_VERSION(Layer_Shape,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Layer_Shape,"$Id$");
+
+#define EPSILON 1e-12
+
+template < class T >
+inline bool IsZero(const T &n)
+{
+ return (n < EPSILON) && (n > -EPSILON);
+}
+
+/* === C L A S S E S ======================================================= */
+
+//Assumes 64 byte aligned structures if at all
+struct Primitive
+{
+ int operation;
+ int number;
+
+ //Point data[0];
+
+ enum Operations
+ {
+ NONE = -1,
+ MOVE_TO = 0, //(x,y)+ after first point treated as line_to
+ CLOSE, // NOT RUNLENGTH enabled
+ LINE_TO, //(x,y)+ continuous func
+ CONIC_TO, //(x1,y1,x,y)+ " "
+ CONIC_TO_SMOOTH, //(x,y)+ " "
+ CUBIC_TO, //(x1,y1,x2,y2,x,y)+ " "
+ CUBIC_TO_SMOOTH, //(x2,y2,x,y)+ " "
+ END
+ };
+};
+
+//******** CURVE FUNCTIONS *****************
+const int MAX_SUBDIVISION_SIZE = 64;
+const int MIN_SUBDIVISION_DRAW_LEVELS = 4;
+
+static void Subd_Conic_Stack(Point *arc)
+{
+ /*
+
+ b0
+ * 0+1 a
+ b1 b * 1+2*1+2 a
+ * 1+2 b *
+ b2 *
+ *
+
+ 0.1.2 -> 0.1 2 3.4
+
+ */
+
+ Real a,b;
+
+
+ arc[4][0] = arc[2][0];
+ b = arc[1][0];
+
+ a = arc[1][0] = (arc[0][0] + b)/2;
+ b = arc[3][0] = (arc[4][0] + b)/2;
+ arc[2][0] = (a + b)/2;
+
+
+ arc[4][1] = arc[2][1];
+ b = arc[1][1];
+
+ a = arc[1][1] = (arc[0][1] + b)/2;
+ b = arc[3][1] = (arc[4][1] + b)/2;
+ arc[2][1] = (a + b)/2;
+
+ /* //USING SIMD
+
+ arc[4] = arc[2];
+
+ arc[3] = (arc[2] + arc[1])/2;
+ arc[1] = (arc[0] + arc[1])/2;
+
+ arc[2] = (arc[1] + arc[3])/2;
+
+ */
+
+}
+
+static void Subd_Cubic_Stack(Point *arc)
+{
+ Real a,b,c;
+
+ /*
+
+ b0
+ * 0+1 a
+ b1 b * 1+2*1+2 a
+ * 1+2 b * 0+3*1+3*2+3
+ b2 c * 1+2*2+2 b *
+ * 2+3 c *
+ b3 *
+ *
+
+ 0.1 2.3 -> 0.1 2 3 4 5.6
+
+ */
+
+ arc[6][0] = arc[3][0];
+
+ b = arc[1][0];
+ c = arc[2][0];
+
+ a = arc[1][0] = (arc[0][0] + b)/2;
+ b = (b + c)/2;
+ c = arc[5][0] = (arc[6][0] + c)/2;
+
+ a = arc[2][0] = (a + b)/2;
+ b = arc[4][0] = (b + c)/2;
+
+ arc[3][0] = (a + b)/2;
+
+
+ arc[6][1] = arc[3][1];
+
+ b = arc[1][1];
+ c = arc[2][1];
+
+ a = arc[1][1] = (arc[0][1] + b)/2;
+ b = (b + c)/2;
+ c = arc[5][1] = (arc[6][1] + c)/2;
+
+ a = arc[2][1] = (a + b)/2;
+ b = arc[4][1] = (b + c)/2;
+
+ arc[3][1] = (a + b)/2;
+
+ /* //USING SIMD
+ temp
+
+ arc[6] = arc[3];
+
+ //backwards to avoid overwriting
+ arc[5] = (arc[2] + arc[3])/2;
+ temp = (arc[1] + arc[2])/2;
+ arc[1] = (arc[0] + arc[1])/2;
+
+ arc[4] = (temp + arc[5])/2;
+ arc[2] = (arc[1] + temp)/2;
+
+ arc[3] = (arc[2] + arc[4])/2;
+
+ */
+}
+
+//************** PARAMETRIC RENDERER SUPPORT STRUCTURES ****************
+
+// super segment
+struct MonoSegment
+{
+ Rect aabb;
+ int ydir;
+ vector<Point> pointlist;
+
+ MonoSegment(int dir = 0, Real x0 = 0, Real x1 = 0, Real y0 = 0, Real y1 = 0)
+ {
+ aabb.minx = x0;
+ aabb.maxx = x1;
+ aabb.miny = y0;
+ aabb.maxy = y1;
+
+ ydir = dir;
+ }
+
+ int intersect(Real x,Real y) const
+ {
+ if((y < aabb.miny+EPSILON) || (y > aabb.maxy) || (x < aabb.minx)) return 0;
+ if(x > aabb.maxx) return ydir;
+
+ //int i = 0;
+ //int size = pointlist.size();
+ //vector<Point>::const_iterator end = pointlist.end();
+ vector<Point>::const_iterator p = pointlist.begin();
+
+ //assumes that the rect culled away anything that would be beyond the edges
+ if(ydir > 0)
+ {
+ while(y > (*++p)[1]);
+ }
+ else
+ {
+ while(y < (*++p)[1]);
+ }
+
+ //for the loop to break there must have been a slope (straight line would do nothing)
+ //vector<Point>::const_iterator p1 = p-1;
+ Real dy = p[-1][1] - p[0][1];
+ Real dx = p[-1][0] - p[0][0];
+
+ assert(dy != 0);
+
+ Real xi = p[0][0] + (y - p[0][1]) * dx / dy;
+ return (x > xi)*ydir;
+ }
+};
+
+struct CurveArray
+{
+ Rect aabb; //not necessarily as effective - can only reject values
+ vector<Point> pointlist; //run length - p0, p1, p2, p3 = p10, p11, p12, p13 = p20 ...
+ vector<char> degrees;
+
+ CurveArray(Real x0 = 0, Real x1 = 0, Real y0 = 0, Real y1 = 0)
+ {
+ aabb.set(x0,y0,x1,y1);
+ }
+
+ void reset(Real x0 = 0, Real x1 = 0, Real y0 = 0, Real y1 = 0)
+ {
+ aabb.set(x0,y0,x1,y1);
+ pointlist.clear();
+ degrees.clear();
+ }
+
+ int size () const
+ {
+ return degrees.size();
+ }
+
+ void Start(Point m)
+ {
+ reset(m[0],m[0],m[1],m[1]);
+ pointlist.push_back(m);
+ }
+
+ void AddCubic(Point p1, Point p2, Point dest)
+ {
+ aabb.expand(p1[0],p1[1]);
+ aabb.expand(p2[0],p2[1]);
+ aabb.expand(dest[0],dest[1]);
+
+ pointlist.push_back(p1);
+ pointlist.push_back(p2);
+ pointlist.push_back(dest);
+
+ degrees.push_back(3);
+ }
+
+ void AddConic(Point p1, Point dest)
+ {
+ aabb.expand(p1[0],p1[1]);
+ aabb.expand(dest[0],dest[1]);
+
+ pointlist.push_back(p1);
+ pointlist.push_back(dest);
+
+ degrees.push_back(2);
+ }
+
+ static int intersect_conic(Real x, Real y, Point *p, int /*level*/ = 0)
+ {
+ Real ymin,ymax,xmin,xmax;
+ int intersects = 0;
+
+ //sort the overall curve ys - degenerate detection
+ ymin = min(p[0][1],p[2][1]);
+ ymax = max(p[0][1],p[2][1]);
+
+ xmin = min(min(p[0][0],p[1][0]),p[2][0]);
+ xmax = max(max(p[0][0],p[1][0]),p[2][0]);
+
+ //to the left, to the right and out of range y, or completely out of range y
+ if( x < xmin ) return 0;
+ if( x > xmax && (y > ymax || y < ymin) ) return 0;
+ if( (y > ymax && y > p[1][1]) || (y < ymin && y < p[1][1]) ) return 0;
+
+ //degenerate line max
+ if(ymin == ymax == p[1][1])
+ return 0;
+
+ //degenerate accept - to the right and crossing the base line
+ if(x > xmax)
+ {
+ return (y <= ymax && y >= ymin);
+ }
+
+ //solve for curve = y
+
+ //real roots:
+ //0 roots - 0 intersection
+ //1 root - get x, and figure out x
+ //2 roots (non-double root) - get 2 xs, and count xs to the left
+
+ //for conic we can assume 1 intersection for monotonic curve
+ Real a = p[2][1] - 2*p[1][1] + p[0][1],
+ b = 2*p[1][1] - 2*p[0][1],
+ c = p[0][1] - y;
+
+ Real t1 = -1, t2 = -1;
+
+ if(a == 0)
+ {
+ //linear - easier :)
+ if(b == 0) return 0; //may not need this check
+
+ t1 = - c / b; //bt + c = 0 solved
+ }else
+ {
+ //2 degree polynomial
+ Real b2_4ac = b*b - 4*a*c;
+
+ //if there are double/no roots - no intersections (in real #s that is)
+ if(b2_4ac <= 0)
+ {
+ return 0;
+ }
+
+ b2_4ac = sqrt(b2_4ac);
+
+ t1 = (-b - b2_4ac) / 2*a,
+ t2 = (-b + b2_4ac) / 2*a;
+ }
+
+ //calculate number of intersections
+ if(t1 >= 0 && t1 <= 1)
+ {
+ const Real t = t1;
+ const Real invt = 1 - t;
+
+ //find x val and it counts if it's to the left of the point
+ const Real xi = invt*invt*p[0][0] + 2*t*invt*p[1][0] + t*t*p[2][0];
+ const Real dy_t = 2*a*t + b;
+
+ if(dy_t)
+ {
+ intersects += (x >= xi) * ( dy_t > 0 ? 1 : -1);
+ }
+ }
+
+ if(t2 >= 0 && t2 <= 1)
+ {
+ const Real t = t2;
+ const Real invt = 1 - t;
+
+ //find x val and it counts if it's to the left of the point
+ const Real xi = invt*invt*p[0][0] + 2*t*invt*p[1][0] + t*t*p[2][0];
+ const Real dy_t = 2*a*t + b;
+
+ if(dy_t)
+ {
+ intersects += (x >= xi) * ( dy_t > 0 ? 1 : -1);
+ }
+ }
+
+ return intersects;
+ }
+
+ static int quadratic_eqn(Real a, Real b, Real c, Real *t0, Real *t1)
+ {
+ const Real b2_4ac = b*b - 4*a*c;
+
+ //degenerate reject (can't take sqrt)
+ if(b2_4ac < 0)
+ {
+ return 0;
+ }
+
+ const Real sqrtb2_4ac = sqrt(b2_4ac);
+ const Real signb = b < 0 ? -1 : 1;
+ const Real q = - 0.5 * (b + signb * sqrtb2_4ac);
+
+ *t0 = q/a;
+ *t1 = c/q;
+
+ return sqrtb2_4ac == 0 ? 1 : 2;
+ }
+
+ //Newton-Raphson root polishing (we don't care about bounds, assumes very near the desired root)
+ static Real polish_cubicroot(Real a, Real b, Real c, Real d, Real t, Real *dpdt)
+ {
+ const Real cn[4] = {a,b,c,d};
+ Real p,dp,newt,oldpmag=FLT_MAX;
+
+ //eval cubic eqn and its derivative
+ for(;;)
+ {
+ p = cn[0]*t + cn[1];
+ dp = cn[0];
+
+ for(int i = 2; i < 4; i++)
+ {
+ dp = p + dp*t;
+ p = cn[i] + p*t;
+ }
+
+ if(dp == 0)
+ {
+ synfig::warning("polish_cubicroot: Derivative should not vanish!!!");
+ return t;
+ }
+
+ newt = t - p/dp;
+
+ if(newt == t || fabs(p) >= oldpmag)
+ {
+ *dpdt = dp;
+ return t;
+ }
+
+ t = newt;
+ oldpmag = fabs(p);
+ }
+ }
+
+ static int intersect_cubic(Real x, Real y, Point *p, int /*level*/ = 0)
+ {
+ const Real INVALIDROOT = -FLT_MAX;
+ Real ymin,ymax,xmin,xmax;
+ Real ymin2,ymax2,ymintot,ymaxtot;
+ int intersects = 0;
+
+ //sort the overall curve ys and xs - degenerate detection
+
+ //open span for the two end points
+ ymin = min(p[0][1],p[3][1]);
+ ymax = max(p[0][1],p[3][1]);
+
+ //other points etc.
+ ymin2 = min(p[1][1],p[2][1]);
+ ymax2 = max(p[1][1],p[2][1]);
+
+ ymintot = min(ymin,ymin2);
+ ymaxtot = max(ymax,ymax2);
+
+ //the entire curve control polygon is in this x range
+ xmin = min(min(p[0][0],p[1][0]),min(p[2][0],p[3][0]));
+ xmax = max(max(p[0][0],p[1][0]),max(p[2][0],p[3][0]));
+
+ //outside all y boundaries (no intersect)
+ if( (y > ymaxtot) || (y < ymintot) ) return 0;
+
+ //left of curve (no intersect)
+ if(x < xmin) return 0;
+
+ //right of curve (and outside base range)
+ if( x > xmax )
+ {
+ if( (y > ymax) || (y < ymin) ) return 0;
+
+ //degenerate accept - to the right and inside the [ymin,ymax] range (already rejected if out of range)
+ const Real n = p[3][1] - p[0][1];
+
+ //extract the sign from the value (we need valid data)
+ return n < 0 ? -1 : 1;
+ }
+
+ //degenerate horizontal line max -- doesn't happen enough to check for
+ if( ymintot == ymaxtot ) return 0;
+
+ //calculate roots:
+ // can have 0,1,2, or 3 real roots
+ // if any of them are double then reject the two...
+
+ // y-coefficients for f_y(t) - y = 0
+ Real a = p[3][1] - 3*p[2][1] + 3*p[1][1] - p[0][1],
+ b = 3*p[2][1] - 6*p[1][1] + 3*p[0][1],
+ c = 3*p[1][1] - 3*p[0][1],
+ d = p[0][1] - y;
+
+ Real ax = p[3][0] - 3*p[2][0] + 3*p[1][0] - p[0][0],
+ bx = 3*p[2][0] - 6*p[1][0] + 3*p[0][0],
+ cx = 3*p[1][0] - 3*p[0][0],
+ dx = p[0][0];
+
+ Real t1 = INVALIDROOT, t2 = INVALIDROOT, t3 = INVALIDROOT, t, dydt;
+
+ if(a == 0)
+ {
+ //only 2nd degree
+ if(b == 0)
+ {
+ //linear
+ if(c == 0) return 0;
+
+ t1 = - d / c; //equation devolved into: ct + d = 0 - solve...
+ }else
+ {
+ //0 roots = 0 intersections, 1 root = 2 intersections at the same place (0 effective)
+ if(quadratic_eqn(a,b,c,&t1,&t2) != 2) return 0;
+ }
+ }else
+ {
+ //cubic - sigh....
+
+ //algorithm courtesy of Numerical Recipes in C (algorithm copied from pg. 184/185)
+ Real an = b / a,
+ bn = c / a,
+ cn = d / a;
+
+ //if cn is 0 (or really really close), then we can simplify this...
+ if(IsZero(cn))
+ {
+ t3 = 0;
+
+ //0 roots = 0 intersections, 1 root = 2 intersections at the same place (0 effective)
+ if(quadratic_eqn(a,b,c,&t1,&t2) != 2)
+ {
+ t1 = t2 = INVALIDROOT;
+ }
+ }
+ else
+ {
+ //otherwise run the normal cubic root equation
+ Real Q = (an*an - 3.0*bn) / 9.0;
+ Real R = ((2.0*an*an - 9.0*bn)*an + 27.0*cn)/54.0;
+
+ if(R*R < Q*Q*Q)
+ {
+ Real theta = acos(R / sqrt(Q*Q*Q));
+
+ t1 = -2.0*sqrt(Q)*cos(theta/3) - an/3.0;
+ t2 = -2.0*sqrt(Q)*cos((theta+2*PI)/3.0) - an/3.0;
+ t3 = -2.0*sqrt(Q)*cos((theta-2*PI)/3.0) - an/3.0;
+
+ //don't need to reorder,l just need to eliminate double/triple roots
+ //if(t3 == t2 && t1 == t2) t2 = t3 = INVALIDROOT;
+ if(t3 == t2) t2 = t3 = INVALIDROOT;
+ if(t1 == t2) t1 = t2 = INVALIDROOT;
+ if(t1 == t3) t1 = t3 = INVALIDROOT;
+ }else
+ {
+ Real signR = R < 0 ? -1 : 1;
+ Real A = - signR * pow(signR*R + sqrt(R*R - Q*Q*Q),1/3.0);
+
+ Real B;
+ if(A == 0) B = 0;
+ else B = Q / A;
+
+ //single real root in this case
+ t1 = (A + B) - an/3.0;
+ }
+ }
+ }
+
+ //if(t1 != INVALIDROOT)
+ {
+ t = t1;//polish_cubicroot(a,b,c,d,t1,&dydt);
+ if(t >= 0 && t < 1)
+ {
+ //const Real invt = 1 - t;
+
+ //find x val and it counts if it's to the left of the point
+ const Real xi = ((ax*t + bx)*t + cx)*t + dx;
+ dydt = (3*a*t + 2*b)*t + c;
+
+ if(dydt)
+ {
+ intersects += (x >= xi) * ( dydt > 0 ? 1 : -1);
+ }
+ }
+ }
+
+ //if(t2 != INVALIDROOT)
+ {
+ t = t2;//polish_cubicroot(a,b,c,d,t2,&dydt);
+ if(t >= 0 && t < 1)
+ {
+ //const Real invt = 1 - t;
+
+ //find x val and it counts if it's to the left of the point
+ const Real xi = ((ax*t + bx)*t + cx)*t + dx;
+ dydt = (3*a*t + 2*b)*t + c;
+
+ if(dydt)
+ {
+ intersects += (x >= xi) * ( dydt > 0 ? 1 : -1);
+ }
+ }
+ }
+
+ //if(t3 != INVALIDROOT)
+ {
+ t = t3;//polish_cubicroot(a,b,c,d,t3,&dydt);
+ if(t >= 0 && t < 1)
+ {
+ //const Real invt = 1 - t;
+
+ //find x val and it counts if it's to the left of the point
+ const Real xi = ((ax*t + bx)*t + cx)*t + dx;
+ dydt = (3*a*t + 2*b)*t + c;
+
+ if(dydt)
+ {
+ intersects += (x >= xi) * ( dydt > 0 ? 1 : -1);
+ }
+ }
+ }
+
+ return intersects;
+ }
+
+ int intersect(Real x,Real y, Point *table) const
+ {
+ if((y < aabb.miny) || (y > aabb.maxy) || (x < aabb.minx)) return 0;
+
+ int i, curdeg, intersects = 0;
+ const int numcurves = degrees.size();
+
+ vector<Point>::const_iterator p = pointlist.begin();
+
+ for(i=0; i < numcurves; i++)
+ {
+ curdeg = degrees[i];
+
+ switch(curdeg)
+ {
+ case 2:
+ {
+ table[0] = *p++;
+ table[1] = *p++;
+ table[2] = *p; //we want to include the last point for the next curve
+
+ intersects += intersect_conic(x,y,table);
+
+ break;
+ }
+
+ case 3:
+ {
+ table[0] = *p++;
+ table[1] = *p++;
+ table[2] = *p++;
+ table[3] = *p; //we want to include the last point for the next curve
+
+ intersects += intersect_cubic(x,y,table);
+
+ break;
+ }
+
+ default:
+ {
+ warning("Invalid degree (%d) inserted into the list (index: %d)\n", curdeg, i);
+ return 0;
+ }
+ }
+ }
+
+ return intersects;
+ }
+};
+
+struct Layer_Shape::Intersector
+{
+ Rect aabb;
+
+ //! true iff aabb hasn't been initialised yet
+ bool initaabb;
+
+ int flags;
+
+ enum IntersectorFlags
+ {
+ NotClosed = 0x8000
+ };
+
+ enum PrimitiveType
+ {
+ TYPE_NONE = 0,
+ TYPE_LINE,
+ TYPE_CURVE
+ };
+
+ Real cur_x,cur_y;
+ Real close_x,close_y;
+
+ vector<MonoSegment> segs; //monotonically increasing
+ vector<CurveArray> curves; //big array of consecutive curves
+
+ int prim;
+ Vector tangent;
+
+ Intersector()
+ {
+ clear();
+ }
+
+ bool notclosed()
+ {
+ return (flags & NotClosed) || (cur_x != close_x) || (cur_y != close_y);
+ }
+
+ void move_to(Real x, Real y)
+ {
+ close();
+
+ close_x = cur_x = x;
+ close_y = cur_y = y;
+
+ tangent[0] = tangent[1] = 0;
+
+ if(initaabb)
+ {
+ aabb.set_point(x,y);
+ initaabb = false;
+ }else aabb.expand(x,y);
+
+ prim = TYPE_NONE;
+ }
+
+ void line_to(Real x, Real y)
+ {
+ int dir = (y > cur_y)*1 + (-1)*(y < cur_y);
+
+ //check for context (if not line start a new segment)
+ //if we're not in line mode (covers 0 set case), or if directions are different (not valid for 0 direction)
+ if(prim != TYPE_LINE || (dir && segs.back().ydir != dir))
+ {
+ MonoSegment seg(dir,x,x,y,y);
+
+ seg.aabb.expand(cur_x,cur_y);
+ seg.pointlist.push_back(Point(cur_x,cur_y));
+ seg.pointlist.push_back(Point(x,y));
+ segs.push_back(seg);
+ }
+ //add to the last segment, because it works
+ else
+ {
+ segs.back().pointlist.push_back(Point(x,y));
+ segs.back().aabb.expand(x,y);
+ }
+
+
+
+ cur_x = x;
+ cur_y = y;
+ aabb.expand(x,y); //expand the entire thing's bounding box
+
+ tangent[0] = x - cur_x;
+ tangent[1] = x - cur_y;
+
+ flags |= NotClosed;
+ prim = TYPE_LINE;
+ }
+
+ void conic_to_smooth(Real x, Real y)
+ {
+ const Real x1 = tangent[0]/2.0 + cur_x;
+ const Real y1 = tangent[1]/2.0 + cur_y;
+
+ conic_to(x1,y1,x,y);
+ }
+
+ void conic_to(Real x1, Real y1, Real x, Real y)
+ {
+ //if we're not already a curve start one
+ if(prim != TYPE_CURVE)
+ {
+ CurveArray c;
+
+ c.Start(Point(cur_x,cur_y));
+ c.AddConic(Point(x1,y1),Point(x,y));
+
+ curves.push_back(c);
+ }else
+ {
+ curves.back().AddConic(Point(x1,y1),Point(x,y));
+ }
+
+ cur_x = x;
+ cur_y = y;
+
+ aabb.expand(x1,y1);
+ aabb.expand(x,y);
+
+ tangent[0] = 2*(x - x1);
+ tangent[1] = 2*(y - y1);
+
+ flags |= NotClosed;
+ prim = TYPE_CURVE;
+ }
+
+ void curve_to_smooth(Real x2, Real y2, Real x, Real y)
+ {
+ Real x1 = tangent[0]/3.0 + cur_x;
+ Real y1 = tangent[1]/3.0 + cur_y;
+
+ curve_to(x1,y1,x2,y2,x,y);
+ }
+
+ void curve_to(Real x1, Real y1, Real x2, Real y2, Real x, Real y)
+ {
+ //if we're not already a curve start one
+ if(prim != TYPE_CURVE)
+ {
+ CurveArray c;
+
+ c.Start(Point(cur_x,cur_y));
+ c.AddCubic(Point(x1,y1),Point(x2,y2),Point(x,y));
+
+ curves.push_back(c);
+ }else
+ {
+ curves.back().AddCubic(Point(x1,y1),Point(x2,y2),Point(x,y));
+ }
+
+ cur_x = x;
+ cur_y = y;
+
+ //expand bounding box around ALL of it
+ aabb.expand(x1,y1);
+ aabb.expand(x2,y2);
+ aabb.expand(x,y);
+
+ tangent[0] = 3*(x - x2);
+ tangent[1] = 3*(y - y2);
+
+ flags |= NotClosed;
+ prim = TYPE_CURVE;
+ }
+
+ void close()
+ {
+ if(flags & NotClosed)
+ {
+ if(cur_x != close_x || cur_y != close_y)
+ {
+ line_to(close_x,close_y);
+ }
+
+ flags &= ~NotClosed;
+ }
+ }
+
+ //assumes the line to count the intersections with is (-1,0)
+ int intersect (Real x, Real y) const
+ {
+ int inter = 0;
+ unsigned int i;
+ vector<MonoSegment>::const_iterator s = segs.begin();
+ vector<CurveArray>::const_iterator c = curves.begin();
+
+ Point memory[3*MAX_SUBDIVISION_SIZE + 1];
+
+ for(i = 0; i < segs.size(); i++,s++)
+ {
+ inter += s->intersect(x,y);
+ }
+
+ for(i=0; i < curves.size(); i++,c++)
+ inter += c->intersect(x,y,memory);
+
+ return inter;
+ }
+
+ //intersect an arbitrary line
+ //int intersect (Real x, Real y, Real vx, Real vy) {return 0;}
+
+ void clear()
+ {
+ segs.clear();
+ curves.clear();
+
+ flags = 0;
+ cur_x = cur_y = close_x = close_y = 0;
+ prim = TYPE_NONE;
+ tangent[0] = tangent[1] = 0;
+ initaabb = true;
+ }
+};
+
+//*********** SCANLINE RENDERER SUPPORT STRUCTURES ***************
+struct PenMark
+{
+ int y,x;
+ Real cover,area;
+
+ PenMark(){}
+ PenMark(int xin, int yin, Real c, Real a)
+ :y(yin),x(xin),cover(c),area(a) {}
+
+ void set(int xin, int yin, Real c, Real a) { y = yin; x = xin; cover = c; area = a; }
+
+ void setcoord(int xin, int yin) { y = yin; x = xin; }
+
+ void setcover(Real c, Real a) { cover = c; area = a; }
+ void addcover(Real c, Real a) { cover += c; area += a; }
+
+ bool operator < (const PenMark &rhs) const
+ {
+ return y == rhs.y ? x < rhs.x : y < rhs.y;
+ }
+};
+
+typedef rect<int> ContextRect;
+
+class Layer_Shape::PolySpan
+{
+public:
+ typedef deque<PenMark> cover_array;
+
+ Point arc[3*MAX_SUBDIVISION_SIZE + 1];
+
+ cover_array covers;
+ PenMark current;
+
+ int open_index;
+
+ //ending position of last primitive
+ Real cur_x;
+ Real cur_y;
+
+ //starting position of current primitive list
+ Real close_x;
+ Real close_y;
+
+ //flags for the current segment
+ int flags;
+
+ //the window that will be drawn (used for clipping)
+ ContextRect window;
+
+ //for assignment to flags value
+ enum PolySpanFlags
+ {
+ NotSorted = 0x8000,
+ NotClosed = 0x4000
+ };
+
+ //default constructor - 0 everything
+ PolySpan() :current(0,0,0,0),flags(NotSorted)
+ {
+ cur_x = cur_y = close_x = close_y = 0;
+ open_index = 0;
+ }
+
+ bool notclosed() const
+ {
+ return (flags & NotClosed) || (cur_x != close_x) || (cur_y != close_y);
+ }
+
+ //0 out all the variables involved in processing
+ void clear()
+ {
+ covers.clear();
+ cur_x = cur_y = close_x = close_y = 0;
+ open_index = 0;
+ current.set(0,0,0,0);
+ flags = NotSorted;
+ }
+
+ //add the current cell, but only if there is information to add
+ void addcurrent()
+ {
+ if(current.cover || current.area)
+ {
+ covers.push_back(current);
+ }
+ }
+
+ //move to the next cell (cover values 0 initially), keeping the current if necessary
+ void move_pen(int x, int y)
+ {
+ if(y != current.y || x != current.x)
+ {
+ addcurrent();
+ current.set(x,y,0,0);
+ }
+ }
+
+ //close the primitives with a line (or rendering will not work as expected)
+ void close()
+ {
+ if(flags & NotClosed)
+ {
+ if(cur_x != close_x || cur_y != close_y)
+ {
+ line_to(close_x,close_y);
+ addcurrent();
+ current.setcover(0,0);
+ }
+ flags &= ~NotClosed;
+ }
+ }
+
+ // Not recommended - destroys any separation of spans currently held
+ void merge_all()
+ {
+ sort(covers.begin(),covers.end());
+ open_index = 0;
+ }
+
+ //will sort the marks if they are not sorted
+ void sort_marks()
+ {
+ if(flags & NotSorted)
+ {
+ //only sort the open index
+ addcurrent();
+ current.setcover(0,0);
+
+ sort(covers.begin() + open_index,covers.end());
+ flags &= ~NotSorted;
+ }
+ }
+
+ //encapsulate the current sublist of marks (used for drawing)
+ void encapsulate_current()
+ {
+ //sort the current list then reposition the open list section
+ sort_marks();
+ open_index = covers.size();
+ }
+
+ //move to start a new primitive list (enclose the last primitive if need be)
+ void move_to(Real x, Real y)
+ {
+ close();
+ if(isnan(x))x=0;
+ if(isnan(y))y=0;
+ move_pen((int)floor(x),(int)floor(y));
+ close_y = cur_y = y;
+ close_x = cur_x = x;
+ }
+
+ //primitive_to functions
+ void line_to(Real x, Real y);
+ void conic_to(Real x1, Real y1, Real x, Real y);
+ void cubic_to(Real x1, Real y1, Real x2, Real y2, Real x, Real y);
+
+ void draw_scanline(int y, Real x1, Real y1, Real x2, Real y2);
+ void draw_line(Real x1, Real y1, Real x2, Real y2);
+
+ Real ExtractAlpha(Real area, WindingStyle winding_style)
+ {
+ if (area < 0)
+ area = -area;
+
+ if (winding_style == WINDING_NON_ZERO)
+ {
+ // non-zero winding style
+ if (area > 1)
+ return 1;
+ }
+ else // if (winding_style == WINDING_EVEN_ODD)
+ {
+ // even-odd winding style
+ while (area > 1)
+ area -= 2;
+
+ // want pyramid like thing
+ if (area < 0)
+ area = -area;
+ }
+
+ return area;
+ }
+};
+
+/* === M E T H O D S ======================================================= */
+
+Layer_Shape::Layer_Shape(const Real &a, const Color::BlendMethod m):
+ Layer_Composite (a,m),
+ edge_table (new Intersector),
+ color (Color::black()),
+ offset (0,0),
+ invert (false),
+ antialias (true),
+ blurtype (Blur::FASTGAUSSIAN),
+ feather (0),
+ winding_style (WINDING_NON_ZERO),
+ bytestream (0),
+ lastbyteop (Primitive::NONE),
+ lastoppos (-1)
+{
+}
+
+Layer_Shape::~Layer_Shape()
+{
+ delete edge_table;
+}
+
+void
+Layer_Shape::clear()
+{
+ edge_table->clear();
+ bytestream.clear();
+}
+
+bool
+Layer_Shape::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(color);
+ IMPORT(offset);
+ IMPORT(invert);
+ IMPORT(antialias);
+ IMPORT(feather);
+ IMPORT(blurtype);
+ IMPORT(winding_style);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+Layer_Shape::get_param(const String ¶m)const
+{
+ EXPORT(color);
+ EXPORT(offset);
+ EXPORT(invert);
+ EXPORT(antialias);
+ EXPORT(feather);
+ EXPORT(blurtype);
+ EXPORT(winding_style);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+Layer_Shape::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("color")
+ .set_local_name(_("Color"))
+ .set_description(_("Layer_Shape Color"))
+ );
+ ret.push_back(ParamDesc("offset")
+ .set_local_name(_("Position"))
+ );
+ ret.push_back(ParamDesc("invert")
+ .set_local_name(_("Invert"))
+ );
+ ret.push_back(ParamDesc("antialias")
+ .set_local_name(_("Antialiasing"))
+ );
+ ret.push_back(ParamDesc("feather")
+ .set_local_name(_("Feather"))
+ .set_is_distance()
+ );
+ ret.push_back(ParamDesc("blurtype")
+ .set_local_name(_("Type of Feather"))
+ .set_description(_("Type of feathering to use"))
+ .set_hint("enum")
+ .add_enum_value(Blur::BOX,"box",_("Box Blur"))
+ .add_enum_value(Blur::FASTGAUSSIAN,"fastgaussian",_("Fast Gaussian Blur"))
+ .add_enum_value(Blur::CROSS,"cross",_("Cross-Hatch Blur"))
+ .add_enum_value(Blur::GAUSSIAN,"gaussian",_("Gaussian Blur"))
+ .add_enum_value(Blur::DISC,"disc",_("Disc Blur"))
+ );
+ ret.push_back(ParamDesc("winding_style")
+ .set_local_name(_("Winding Style"))
+ .set_description(_("Winding style to use"))
+ .set_hint("enum")
+ .add_enum_value(WINDING_NON_ZERO,"nonzero",_("Non Zero"))
+ .add_enum_value(WINDING_EVEN_ODD,"evenodd",_("Even/Odd"))
+ );
+
+ return ret;
+}
+
+synfig::Layer::Handle
+Layer_Shape::hit_check(synfig::Context context, const synfig::Point &p)const
+{
+ Point pos(p-offset);
+
+ int intercepts = edge_table->intersect(pos[0],pos[1]);
+
+ // If we have an odd number of intercepts, we are inside.
+ // If we have an even number of intercepts, we are outside.
+ bool intersect = ((!!intercepts) ^ invert);
+
+ if(get_amount() == 0 || get_blend_method() == Color::BLEND_ALPHA_OVER)
+ {
+ intersect = false;
+ }
+
+ if(intersect)
+ {
+ synfig::Layer::Handle tmp;
+ if(get_blend_method()==Color::BLEND_BEHIND && (tmp=context.hit_check(p)))
+ return tmp;
+ if(Color::is_onto(get_blend_method()))
+ {
+ //if there's something in the lower layer then we're set...
+ if(!context.hit_check(p).empty())
+ return const_cast<Layer_Shape*>(this);
+ }else if(get_blend_method() == Color::BLEND_ALPHA_OVER)
+ {
+ synfig::info("layer_shape::hit_check - we've got alphaover");
+ //if there's something in the lower layer then we're set...
+ if(color.get_a() < 0.1 && get_amount() > .9)
+ {
+ synfig::info("layer_shape::hit_check - can see through us... so nothing");
+ return Handle();
+ }else return context.hit_check(p);
+ }else
+ return const_cast<Layer_Shape*>(this);
+ }
+
+ return context.hit_check(p);
+}
+
+Color
+Layer_Shape::get_color(Context context, const Point &p)const
+{
+ Point pp = p;
+
+ if(feather)
+ pp = Blur(feather,feather,blurtype)(p);
+
+ Point pos(pp-offset);
+
+ int intercepts = edge_table->intersect(pos[0],pos[1]);
+
+ // If we have an odd number of intercepts, we are inside.
+ // If we have an even number of intercepts, we are outside.
+ bool intersect = ((!!intercepts) ^ invert);
+
+ if(!intersect)
+ return context.get_color(pp);
+
+ //Ok, we're inside... bummmm ba bum buM...
+ if(get_blend_method() == Color::BLEND_STRAIGHT && get_amount() == 1)
+ return color;
+ else
+ return Color::blend(color,context.get_color(p),get_amount(),get_blend_method());
+}
+
+//************** SCANLINE RENDERING *********************
+void Layer_Shape::PolySpan::line_to(Real x, Real y)
+{
+ Real n[4];
+ bool afterx = false;
+
+ const Real xin(x), yin(y);
+
+ Real dx = x - cur_x;
+ Real dy = y - cur_y;
+
+ //CLIP IT!!!!
+ try {
+ //outside y - ignore entirely
+ if( (cur_y >= window.maxy && y >= window.maxy)
+ ||(cur_y < window.miny && y < window.miny) )
+ {
+ cur_x = x;
+ cur_y = y;
+ }
+ else //not degenerate - more complicated
+ {
+ if(dy > 0) //be sure it's not tooooo small
+ {
+ // cur_y ... window.miny ... window.maxy ... y
+
+ //initial degenerate - initial clip
+ if(cur_y < window.miny)
+ {
+ //new clipped start point (must also move pen)
+ n[2] = cur_x + (window.miny - cur_y) * dx / dy;
+
+ cur_x = n[2];
+ cur_y = window.miny;
+ move_pen((int)floor(cur_x),window.miny);
+ }
+
+ //generate data for the ending clipped info
+ if(y > window.maxy)
+ {
+ //initial line to intersection (and degenerate)
+ n[2] = x + (window.maxy - y) * dx / dy;
+
+ //intersect coords
+ x = n[2];
+ y = window.maxy;
+ }
+ }
+ else
+ {
+ //initial degenerate - initial clip
+ if(cur_y > window.maxy)
+ {
+ //new clipped start point (must also move pen)
+ n[2] = cur_x + (window.maxy - cur_y) * dx / dy;
+
+ cur_x = n[2];
+ cur_y = window.maxy;
+ move_pen((int)floor(cur_x),window.maxy);
+ }
+
+ //generate data for the ending clipped info
+ if(y < window.miny)
+ {
+ //initial line to intersection (and degenerate)
+ n[2] = x + (window.miny - y) * dx / dy;
+
+ //intersect coords
+ x = n[2];
+ y = window.miny;
+ }
+ }
+
+ //all degenerate - but require bounded clipped values
+ if( (cur_x >= window.maxx && x >= window.maxx)
+ ||(cur_x < window.minx && x < window.minx) )
+ {
+ //clip both vertices - but only needed in the x direction
+ cur_x = max(cur_x, (Real)window.minx);
+ cur_x = min(cur_x, (Real)window.maxx);
+
+ //clip the dest values - y is already clipped
+ x = max(x,(Real)window.minx);
+ x = min(x,(Real)window.maxx);
+
+ //must start at new point...
+ move_pen((int)floor(cur_x),(int)floor(cur_y));
+
+ draw_line(cur_x,cur_y,x,y);
+
+ cur_x = xin;
+ cur_y = yin;
+ }
+ else
+ {
+ //clip x
+ if(dx > 0)
+ {
+ //initial degenerate - initial clip
+ if(cur_x < window.minx)
+ {
+ //need to draw an initial segment from clippedx,cur_y to clippedx,intersecty
+ n[2] = cur_y + (window.minx - cur_x) * dy / dx;
+
+ move_pen(window.minx,(int)floor(cur_y));
+ draw_line(window.minx,cur_y,window.minx,n[2]);
+
+ cur_x = window.minx;
+ cur_y = n[2];
+ }
+
+ //generate data for the ending clipped info
+ if(x > window.maxx)
+ {
+ //initial line to intersection (and degenerate)
+ n[2] = y + (window.maxx - x) * dy / dx;
+
+ n[0] = window.maxx;
+ n[1] = y;
+
+ //intersect coords
+ x = window.maxx;
+ y = n[2];
+ afterx = true;
+ }
+ }else
+ {
+ //initial degenerate - initial clip
+ if(cur_x > window.maxx)
+ {
+ //need to draw an initial segment from clippedx,cur_y to clippedx,intersecty
+ n[2] = cur_y + (window.maxx - cur_x) * dy / dx;
+
+ move_pen(window.maxx,(int)floor(cur_y));
+ draw_line(window.maxx,cur_y,window.maxx,n[2]);
+
+ cur_x = window.maxx;
+ cur_y = n[2];
+ }
+
+ //generate data for the ending clipped info
+ if(x < window.minx)
+ {
+ //initial line to intersection (and degenerate)
+ n[2] = y + (window.minx - x) * dy / dx;
+
+ n[0] = window.minx;
+ n[1] = y;
+
+ //intersect coords
+ x = window.minx;
+ y = n[2];
+ afterx = true;
+ }
+ }
+
+ move_pen((int)floor(cur_x),(int)floor(cur_y));
+ //draw the relevant line (clipped)
+ draw_line(cur_x,cur_y,x,y);
+
+ if(afterx)
+ {
+ draw_line(x,y,n[0],n[1]);
+ }
+
+ cur_x = xin;
+ cur_y = yin;
+ }
+ }
+ } catch(...) { synfig::error("line_to: cur_x=%f, cur_y=%f, x=%f, y=%f", cur_x, cur_y, x, y); throw; }
+
+ flags |= NotClosed|NotSorted;
+}
+
+static inline bool clip_conic(const Point *const p, const ContextRect &r)
+{
+ const Real minx = min(min(p[0][0],p[1][0]),p[2][0]);
+ const Real miny = min(min(p[0][1],p[1][1]),p[2][1]);
+ const Real maxx = max(max(p[0][0],p[1][0]),p[2][0]);
+ const Real maxy = max(max(p[0][1],p[1][1]),p[2][1]);
+
+ return (minx > r.maxx) ||
+ (maxx < r.minx) ||
+ (miny > r.maxy) ||
+ (maxy < r.miny);
+}
+
+static inline bool clip_cubic(const Point *const p, const ContextRect &r)
+{
+ /*const Real minx = min(min(p[0][0],p[1][0]),min(p[2][0],p[3][0]));
+ const Real miny = min(min(p[0][1],p[1][1]),min(p[2][1],p[3][1]));
+ const Real maxx = max(max(p[0][0],p[1][0]),max(p[2][0],p[3][1]));
+ const Real maxy = max(max(p[0][1],p[1][1]),max(p[2][1],p[3][1]));
+
+ return (minx > r.maxx) ||
+ (maxx < r.minx) ||
+ (miny > r.maxy) ||
+ (maxy < r.miny);*/
+
+ return ((p[0][0] > r.maxx) && (p[1][0] > r.maxx) && (p[2][0] > r.maxx) && (p[3][0] > r.maxx)) ||
+ ((p[0][0] < r.minx) && (p[1][0] < r.minx) && (p[2][0] < r.minx) && (p[3][0] < r.minx)) ||
+ ((p[0][1] > r.maxy) && (p[1][1] > r.maxy) && (p[2][1] > r.maxy) && (p[3][1] > r.maxy)) ||
+ ((p[0][1] < r.miny) && (p[1][1] < r.miny) && (p[2][1] < r.miny) && (p[3][1] < r.miny));
+}
+
+static inline Real max_edges_cubic(const Point *const p)
+{
+ const Real x1 = p[1][0] - p[0][0];
+ const Real y1 = p[1][1] - p[0][1];
+
+ const Real x2 = p[2][0] - p[1][0];
+ const Real y2 = p[2][1] - p[1][1];
+
+ const Real x3 = p[3][0] - p[2][0];
+ const Real y3 = p[3][1] - p[2][1];
+
+ const Real d1 = x1*x1 + y1*y1;
+ const Real d2 = x2*x2 + y2*y2;
+ const Real d3 = x3*x3 + y3*y3;
+
+ return max(max(d1,d2),d3);
+}
+
+static inline Real max_edges_conic(const Point *const p)
+{
+ const Real x1 = p[1][0] - p[0][0];
+ const Real y1 = p[1][1] - p[0][1];
+
+ const Real x2 = p[2][0] - p[1][0];
+ const Real y2 = p[2][1] - p[1][1];
+
+ const Real d1 = x1*x1 + y1*y1;
+ const Real d2 = x2*x2 + y2*y2;
+
+ return max(d1,d2);
+}
+
+void Layer_Shape::PolySpan::conic_to(Real x1, Real y1, Real x, Real y)
+{
+ Point *current = arc;
+ int level = 0;
+ int num = 0;
+ bool onsecond = false;
+
+ arc[0] = Point(x,y);
+ arc[1] = Point(x1,y1);
+ arc[2] = Point(cur_x,cur_y);
+
+ //just draw the line if it's outside
+ if(clip_conic(arc,window))
+ {
+ line_to(x,y);
+ return;
+ }
+
+ //Ok so it's not super degenerate, subdivide and draw (run through minimum subdivision levels first)
+ while(current >= arc)
+ {
+ if(num >= MAX_SUBDIVISION_SIZE)
+ {
+ warning("Curve subdivision somehow ran out of space while tesselating!");
+
+ //do something...
+ assert(0);
+ return;
+ }else
+ //if the curve is clipping then draw degenerate
+ if(clip_conic(current,window))
+ {
+ line_to(current[0][0],current[0][1]); //backwards so front is destination
+ current -= 2;
+ if(onsecond) level--;
+ onsecond = true;
+ num--;
+ continue;
+ }else
+ //if we are not at the level minimum
+ if(level < MIN_SUBDIVISION_DRAW_LEVELS)
+ {
+ Subd_Conic_Stack(current);
+ current += 2; //cursor on second curve
+ level ++;
+ num ++;
+ onsecond = false;
+ continue;
+ }else
+ //split it again, if it's too big
+ if(max_edges_conic(current) > 0.25) //distance of .5 (cover no more than half the pixel)
+ {
+ Subd_Conic_Stack(current);
+ current += 2; //cursor on second curve
+ level ++;
+ num ++;
+ onsecond = false;
+ }
+ else //NOT TOO BIG? RENDER!!!
+ {
+ //cur_x,cur_y = current[2], so we need to go 1,0
+ line_to(current[1][0],current[1][1]);
+ line_to(current[0][0],current[0][1]);
+
+ current -= 2;
+ if(onsecond) level--;
+ num--;
+ onsecond = true;
+ }
+ }
+}
+
+void Layer_Shape::PolySpan::cubic_to(Real x1, Real y1, Real x2, Real y2, Real x, Real y)
+{
+ Point *current = arc;
+ int num = 0;
+ int level = 0;
+ bool onsecond = false;
+
+ arc[0] = Point(x,y);
+ arc[1] = Point(x2,y2);
+ arc[2] = Point(x1,y1);
+ arc[3] = Point(cur_x,cur_y);
+
+ //just draw the line if it's outside
+ if(clip_cubic(arc,window))
+ {
+ line_to(x,y);
+ return;
+ }
+
+ //Ok so it's not super degenerate, subdivide and draw (run through minimum subdivision levels first)
+ while(current >= arc) //once current goes below arc, there are no more curves left
+ {
+ if(num >= MAX_SUBDIVISION_SIZE)
+ {
+ warning("Curve subdivision somehow ran out of space while tesselating!");
+
+ //do something...
+ assert(0);
+ return;
+ }else
+
+ //if we are not at the level minimum
+ if(level < MIN_SUBDIVISION_DRAW_LEVELS)
+ {
+ Subd_Cubic_Stack(current);
+ current += 3; //cursor on second curve
+ level ++;
+ num ++;
+ onsecond = false;
+ continue;
+ }else
+ //if the curve is clipping then draw degenerate
+ if(clip_cubic(current,window))
+ {
+ line_to(current[0][0],current[0][1]); //backwards so front is destination
+ current -= 3;
+ if(onsecond) level--;
+ onsecond = true;
+ num --;
+ continue;
+ }
+ else
+ //split it again, if it's too big
+ if(max_edges_cubic(current) > 0.25) //could use max_edges<3>
+ {
+ Subd_Cubic_Stack(current);
+ current += 3; //cursor on second curve
+ level ++;
+ num ++;
+ onsecond = false;
+ }
+ else //NOT TOO BIG? RENDER!!!
+ {
+ //cur_x,cur_y = current[3], so we need to go 2,1,0
+ line_to(current[2][0],current[2][1]);
+ line_to(current[1][0],current[1][1]);
+ line_to(current[0][0],current[0][1]);
+
+ current -= 3;
+ if(onsecond) level--;
+ num --;
+ onsecond = true;
+ }
+ }
+}
+
+//******************** LINE ALGORITHMS ****************************
+// THESE CALCULATE THE AREA AND THE COVER FOR THE MARKS, TO THEN SCAN CONVERT
+// - BROKEN UP INTO SCANLINES (draw_line - y intersections),
+// THEN THE COVER AND AREA PER TOUCHED PIXEL IS CALCULATED (draw_scanline - x intersections)
+void Layer_Shape::PolySpan::draw_scanline(int y, Real x1, Real fy1, Real x2, Real fy2)
+{
+ int ix1 = (int)floor(x1);
+ int ix2 = (int)floor(x2);
+ Real fx1 = x1 - ix1;
+ Real fx2 = x2 - ix2;
+
+ Real dx,dy,dydx,mult;
+
+ dx = x2 - x1;
+ dy = fy2 - fy1;
+
+ //case horizontal line
+ if(fy1 == fy2)
+ {
+ move_pen(ix2,y); //pen needs to be at the last coord
+ return;
+ }
+
+ //case all in same pixel
+ if(ix1 == ix2) //impossible for degenerate case (covered by the previous cases)
+ {
+ current.addcover(dy,(fx1 + fx2)*dy/2); //horizontal trapazoid area
+ return;
+ }
+
+ if(dx > 0)
+ {
+ // ----> fx1...1 0...1 ... 0...1 0...fx2
+ dydx = dy / dx;
+
+ //set initial values
+ //Iterate through the covered pixels
+ mult = (1 - fx1)*dydx; //next y intersection diff value (at 1)
+
+ //first pixel
+ current.addcover(mult,(1 + fx1)*mult/2); // fx1,fy1,1,fy@1 - starting trapazoidal area
+
+ //move to the next pixel
+ fy1 += mult;
+ ix1++;
+
+ move_pen(ix1,y);
+
+ //set up for whole ones
+ while(ix1 != ix2)
+ {
+ //trapezoid(0,y1,1,y1+dydx);
+ current.addcover(dydx,dydx/2); //accumulated area 1/2 the cover
+
+ //move to next pixel (+1)
+ ix1++;
+ fy1 += dydx;
+ move_pen(ix1,y);
+ }
+
+ //last pixel
+ //final y-pos - last intersect pos
+ mult = fx2 * dydx;
+ current.addcover(mult,(0+fx2)*mult/2);
+ }else
+ {
+ // fx2...1 0...1 ... 0...1 0...fx1 <----
+ //mult = (0 - fx1) * dy / dx;
+ //neg sign sucked into dydx
+ dydx = -dy / dx;
+
+ //set initial values
+ //Iterate through the covered pixels
+ mult = fx1*dydx; //next y intersection diff value
+
+ //first pixel
+ current.addcover(mult,fx1*mult/2); // fx1,fy1,0,fy@0 - starting trapazoidal area
+
+ //move to next pixel
+ fy1 += mult;
+ ix1--;
+
+ move_pen(ix1,y);
+
+ //set up for whole ones
+ while(ix1 != ix2)
+ {
+ //trapezoid(0,y1,1,y1+dydx);
+ current.addcover(dydx,dydx/2); //accumulated area 1/2 the cover
+
+ //move to next pixel (-1)
+ fy1 += dydx;
+ ix1--;
+ move_pen(ix1,y);
+ }
+
+ //last pixel
+ mult = fy2 - fy1; //final y-pos - last intersect pos
+
+ current.addcover(mult,(fx2+1)*mult/2);
+ }
+}
+
+void Layer_Shape::PolySpan::draw_line(Real x1, Real y1, Real x2, Real y2)
+{
+ int iy1 = (int)floor(y1);
+ int iy2 = (int)floor(y2);
+ Real fy1 = y1 - iy1;
+ Real fy2 = y2 - iy2;
+
+ assert(!isnan(fy1));
+ assert(!isnan(fy2));
+
+ Real dx,dy,dxdy,mult,x_from,x_to;
+
+ const Real SLOPE_EPSILON = 1e-10;
+
+ //case all one scanline
+ if(iy1 == iy2)
+ {
+ draw_scanline(iy1,x1,y1,x2,y2);
+ return;
+ }
+
+ //difference values
+ dy = y2 - y1;
+ dx = x2 - x1;
+
+ //case vertical line
+ if(dx < SLOPE_EPSILON && dx > -SLOPE_EPSILON)
+ {
+ //calc area and cover on vertical line
+ if(dy > 0)
+ {
+ // ----> fx1...1 0...1 ... 0...1 0...fx2
+ Real sub;
+
+ int ix1 = (int)floor(x1);
+ Real fx1 = x1 - ix1;
+
+ //current pixel
+ sub = 1 - fy1;
+
+ current.addcover(sub,fx1*sub);
+
+ //next pixel
+ iy1++;
+
+ //move pen to next pixel
+ move_pen(ix1,iy1);
+
+ while(iy1 != iy2)
+ {
+ //accumulate cover
+ current.addcover(1,fx1);
+
+ //next pixel
+ iy1++;
+ move_pen(ix1,iy1);
+ }
+
+ //last pixel
+ current.addcover(fy2,fy2*fx1);
+ }else
+ {
+ Real sub;
+
+ int ix1 = (int)floor(x1);
+ Real fx1 = x1 - ix1;
+
+ //current pixel
+ sub = 0 - fy1;
+
+ current.addcover(sub,fx1*sub);
+
+ //next pixel
+ iy1--;
+
+ move_pen(ix1,iy1);
+
+ while(iy1 != iy2)
+ {
+ //accumulate in current pixel
+ current.addcover(-1,-fx1);
+
+ //move to next
+ iy1--;
+ move_pen(ix1,iy1);
+ }
+
+ current.addcover(fy2-1,(fy2-1)*fx1);
+ }
+ return;
+ }
+
+ //case normal line - guaranteed dx != 0 && dy != 0
+
+ //calculate the initial intersection with "next" scanline
+ if(dy > 0)
+ {
+ dxdy = dx / dy;
+
+ mult = (1 - fy1) * dxdy;
+
+ //x interset scanline
+ x_from = x1 + mult;
+ draw_scanline(iy1,x1,fy1,x_from,1);
+
+ //move to next line
+ iy1++;
+
+ move_pen((int)floor(x_from),iy1);
+
+ while(iy1 != iy2)
+ {
+ //keep up on the x axis, and render the current scanline
+ x_to = x_from + dxdy;
+ draw_scanline(iy1,x_from,0,x_to,1);
+ x_from = x_to;
+
+ //move to next pixel
+ iy1++;
+ move_pen((int)floor(x_from),iy1);
+ }
+
+ //draw the last one, fractional
+ draw_scanline(iy2,x_from,0,x2,fy2);
+
+ }else
+ {
+ dxdy = -dx / dy;
+
+ mult = fy1 * dxdy;
+
+ //x interset scanline
+ x_from = x1 + mult;
+ draw_scanline(iy1,x1,fy1,x_from,0);
+
+ //each line after
+ iy1--;
+
+ move_pen((int)floor(x_from),iy1);
+
+ while(iy1 != iy2)
+ {
+ x_to = x_from + dxdy;
+ draw_scanline(iy1,x_from,1,x_to,0);
+ x_from = x_to;
+
+ iy1--;
+ move_pen((int)floor(x_from),iy1);
+ }
+ //draw the last one, fractional
+ draw_scanline(iy2,x_from,1,x2,fy2);
+ }
+}
+
+//****** LAYER PEN OPERATIONS (move_to, line_to, etc.) ******
+void Layer_Shape::move_to(Real x, Real y)
+{
+ //const int sizeblock = sizeof(Primitive)+sizeof(Point);
+ Primitive op;
+ Point p(x,y);
+
+ op.operation = Primitive::MOVE_TO;
+ op.number = 1; //one point for now
+
+ if(lastbyteop == Primitive::MOVE_TO)
+ {
+ char *ptr = &bytestream[lastoppos];
+ memcpy(ptr,&op,sizeof(op));
+ memcpy(ptr+sizeof(op),&p,sizeof(p));
+ }
+ else //make a new op
+ {
+ lastbyteop = Primitive::MOVE_TO;
+ lastoppos = bytestream.size();
+
+ bytestream.insert(bytestream.end(),(char*)&op,(char*)(&op+1)); //insert the bytes for the header
+ bytestream.insert(bytestream.end(),(char*)&p,(char*)(&p+1)); //insert the bytes for data
+ }
+
+ edge_table->move_to(x,y);
+}
+
+void Layer_Shape::close()
+{
+ Primitive op;
+
+ op.operation = Primitive::CLOSE;
+ op.number = 0;
+
+ if(lastbyteop == Primitive::CLOSE)
+ {
+ }else
+ {
+ lastbyteop = Primitive::CLOSE;
+ lastoppos = bytestream.size();
+
+ bytestream.insert(bytestream.end(),(char*)&op,(char*)(&op+1)); //insert header
+ }
+
+ edge_table->close();
+ //should not affect the bounding box since it would just be returning to old point...
+}
+
+void Layer_Shape::endpath()
+{
+ Primitive op;
+
+ op.operation = Primitive::END;
+ op.number = 0;
+
+ if(lastbyteop == Primitive::END || lastbyteop == Primitive::NONE)
+ {
+ }else
+ {
+ bytestream.insert(bytestream.end(),(char*)&op,(char*)(&op+1));
+ }
+ //should not affect the bounding box since it would just be returning to old point... if at all
+}
+
+void Layer_Shape::line_to(Real x, Real y)
+{
+ assert(!isnan(x));
+ assert(!isnan(y));
+
+ //const int sizeblock = sizeof(Primitive)+sizeof(Point);
+ Primitive op;
+ Point p(x,y);
+
+ op.operation = Primitive::LINE_TO;
+ op.number = 1; //one point for now
+
+ if(lastbyteop == Primitive::MOVE_TO || lastbyteop == Primitive::LINE_TO)
+ {
+ //only need to insert the point
+ bytestream.insert(bytestream.end(),(char*)&p,(char*)(&p+1));
+
+ Primitive * prim = (Primitive *)&bytestream[lastoppos];
+ prim->number++; //increment number of points in the list
+ }else
+ {
+ lastbyteop = Primitive::LINE_TO;
+ lastoppos = bytestream.size();
+
+ bytestream.insert(bytestream.end(),(char*)&op,(char*)(&op+1)); //insert the bytes for the header
+ bytestream.insert(bytestream.end(),(char*)&p,(char*)(&p+1)); //insert the bytes for data
+ }
+
+ edge_table->line_to(x,y);
+}
+
+void Layer_Shape::conic_to(Real x1, Real y1, Real x, Real y)
+{
+ //const int sizeblock = sizeof(Primitive)+sizeof(Point)*2;
+ Primitive op;
+ Point p(x,y);
+ Point p1(x1,y1);
+
+ op.operation = Primitive::CONIC_TO;
+ op.number = 2; //2 points for now
+
+ if(lastbyteop == Primitive::CONIC_TO)
+ {
+ //only need to insert the new points
+ bytestream.insert(bytestream.end(),(char*)&p1,(char*)(&p1+1));
+ bytestream.insert(bytestream.end(),(char*)&p,(char*)(&p+1));
+
+ Primitive * prim = (Primitive *)&bytestream[lastoppos];
+ prim->number += 2; //increment number of points in the list
+ }else
+ {
+ lastbyteop = Primitive::CONIC_TO;
+ lastoppos = bytestream.size();
+
+ bytestream.insert(bytestream.end(),(char*)&op,(char*)(&op+1)); //insert the bytes for the header
+ bytestream.insert(bytestream.end(),(char*)&p1,(char*)(&p1+1)); //insert the bytes for data
+ bytestream.insert(bytestream.end(),(char*)&p,(char*)(&p+1)); //insert the bytes for data
+ }
+
+ edge_table->conic_to(x1,y1,x,y);
+}
+
+void Layer_Shape::conic_to_smooth(Real x, Real y) //x1,y1 derived from current tangent
+{
+ //const int sizeblock = sizeof(Primitive)+sizeof(Point);
+ Primitive op;
+ Point p(x,y);
+
+ op.operation = Primitive::CONIC_TO_SMOOTH;
+ op.number = 1; //2 points for now
+
+ if(lastbyteop == Primitive::CONIC_TO_SMOOTH)
+ {
+ //only need to insert the new point
+ bytestream.insert(bytestream.end(),(char*)&p,(char*)(&p+1));
+
+ Primitive * prim = (Primitive *)&bytestream[lastoppos];
+ prim->number += 1; //increment number of points in the list
+ }else
+ {
+ lastbyteop = Primitive::CONIC_TO_SMOOTH;
+ lastoppos = bytestream.size();
+
+ bytestream.insert(bytestream.end(),(char*)&op,(char*)(&op+1)); //insert the bytes for the header
+ bytestream.insert(bytestream.end(),(char*)&p,(char*)(&p+1)); //insert the bytes for data
+ }
+
+ edge_table->conic_to_smooth(x,y);
+}
+
+void Layer_Shape::curve_to(Real x1, Real y1, Real x2, Real y2, Real x, Real y)
+{
+ //const int sizeblock = sizeof(Primitive)+sizeof(Point)*3;
+ Primitive op;
+ Point p(x,y);
+ Point p1(x1,y1);
+ Point p2(x2,y2);
+
+ op.operation = Primitive::CUBIC_TO;
+ op.number = 3; //3 points for now
+
+ if(lastbyteop == Primitive::CUBIC_TO)
+ {
+ //only need to insert the new points
+ bytestream.insert(bytestream.end(),(char*)&p1,(char*)(&p1+1));
+ bytestream.insert(bytestream.end(),(char*)&p2,(char*)(&p2+1));
+ bytestream.insert(bytestream.end(),(char*)&p,(char*)(&p+1));
+
+ Primitive * prim = (Primitive *)&bytestream[lastoppos];
+ prim->number += 3; //increment number of points in the list
+ }else
+ {
+ lastbyteop = Primitive::CUBIC_TO;
+ lastoppos = bytestream.size();
+
+ bytestream.insert(bytestream.end(),(char*)&op,(char*)(&op+1)); //insert the bytes for the header
+ bytestream.insert(bytestream.end(),(char*)&p1,(char*)(&p1+1)); //insert the bytes for data
+ bytestream.insert(bytestream.end(),(char*)&p2,(char*)(&p2+1)); //insert the bytes for data
+ bytestream.insert(bytestream.end(),(char*)&p,(char*)(&p+1)); //insert the bytes for data
+ }
+
+ edge_table->curve_to(x1,y1,x2,y2,x,y);
+}
+
+void Layer_Shape::curve_to_smooth(Real x2, Real y2, Real x, Real y) //x1,y1 derived from current tangent
+{
+ //const int sizeblock = sizeof(Primitive)+sizeof(Point)*3;
+ Primitive op;
+ Point p(x,y);
+ Point p2(x2,y2);
+
+ op.operation = Primitive::CUBIC_TO_SMOOTH;
+ op.number = 2; //3 points for now
+
+ if(lastbyteop == Primitive::CUBIC_TO_SMOOTH)
+ {
+ //only need to insert the new points
+ bytestream.insert(bytestream.end(),(char*)&p2,(char*)(&p2+1));
+ bytestream.insert(bytestream.end(),(char*)&p,(char*)(&p+1));
+
+ Primitive * prim = (Primitive *)&bytestream[lastoppos];
+ prim->number += 2; //increment number of points in the list
+ }else
+ {
+ lastbyteop = Primitive::CUBIC_TO_SMOOTH;
+ lastoppos = bytestream.size();
+
+ bytestream.insert(bytestream.end(),(char*)&op,(char*)(&op+1)); //insert the bytes for the header
+ bytestream.insert(bytestream.end(),(char*)&p2,(char*)(&p2+1)); //insert the bytes for data
+ bytestream.insert(bytestream.end(),(char*)&p,(char*)(&p+1)); //insert the bytes for data
+ }
+}
+
+// ACCELERATED RENDER FUNCTION - TRANSLATE BYTE CODE INTO FUNCTION CALLS
+
+bool Layer_Shape::render_polyspan(Surface *surface, PolySpan &polyspan,
+ Color::BlendMethod got_blend_method, Color::value_type got_amount) const
+{
+ Surface::alpha_pen p(surface->begin(),got_amount,_BlendFunc(got_blend_method));
+ PolySpan::cover_array::iterator cur_mark = polyspan.covers.begin();
+ PolySpan::cover_array::iterator end_mark = polyspan.covers.end();
+
+ Real cover,area,alpha;
+
+ int y,x;
+
+ p.set_value(color);
+ cover = 0;
+
+ if(cur_mark == end_mark)
+ {
+ //no marks at all
+ if(invert)
+ {
+ p.move_to(polyspan.window.minx,polyspan.window.miny);
+ p.put_block(polyspan.window.maxy - polyspan.window.miny,polyspan.window.maxx - polyspan.window.minx);
+ }
+ return true;
+ }
+
+ //fill initial rect / line
+ if(invert)
+ {
+ //fill all the area above the first vertex
+ p.move_to(polyspan.window.minx,polyspan.window.miny);
+ y = polyspan.window.miny;
+ int l = polyspan.window.maxx - polyspan.window.minx;
+
+ p.put_block(cur_mark->y - polyspan.window.miny,l);
+
+ //fill the area to the left of the first vertex on that line
+ l = cur_mark->x - polyspan.window.minx;
+ p.move_to(polyspan.window.minx,cur_mark->y);
+ if(l) p.put_hline(l);
+ }
+
+ for(;;)
+ {
+ y = cur_mark->y;
+ x = cur_mark->x;
+
+ p.move_to(x,y);
+
+ area = cur_mark->area;
+ cover += cur_mark->cover;
+
+ //accumulate for the current pixel
+ while(++cur_mark != polyspan.covers.end())
+ {
+ if(y != cur_mark->y || x != cur_mark->x)
+ break;
+
+ area += cur_mark->area;
+ cover += cur_mark->cover;
+ }
+
+ //draw pixel - based on covered area
+ if(area) //if we're ok, draw the current pixel
+ {
+ alpha = polyspan.ExtractAlpha(cover - area, winding_style);
+ if(invert) alpha = 1 - alpha;
+
+ if(!antialias)
+ {
+ if(alpha >= .5) p.put_value();
+ }
+ else if(alpha) p.put_value_alpha(alpha);
+
+ p.inc_x();
+ x++;
+ }
+
+ //if we're done, don't use iterator and exit
+ if(cur_mark == end_mark) break;
+
+ //if there is no more live pixels on this line, goto next
+ if(y != cur_mark->y)
+ {
+ if(invert)
+ {
+ //fill the area at the end of the line
+ p.put_hline(polyspan.window.maxx - x);
+
+ //fill area at the beginning of the next line
+ p.move_to(polyspan.window.minx,cur_mark->y);
+ p.put_hline(cur_mark->x - polyspan.window.minx);
+ }
+
+ cover = 0;
+
+ continue;
+ }
+
+ //draw span to next pixel - based on total amount of pixel cover
+ if(x < cur_mark->x)
+ {
+ alpha = polyspan.ExtractAlpha(cover, winding_style);
+ if(invert) alpha = 1 - alpha;
+
+ if(!antialias)
+ {
+ if(alpha >= .5) p.put_hline(cur_mark->x - x);
+ }
+ else if(alpha) p.put_hline(cur_mark->x - x,alpha);
+ }
+ }
+
+ //fill the after stuff
+ if(invert)
+ {
+ //fill the area at the end of the line
+ p.put_hline(polyspan.window.maxx - x);
+
+ //fill area at the beginning of the next line
+ p.move_to(polyspan.window.minx,y+1);
+ p.put_block(polyspan.window.maxy - y - 1,polyspan.window.maxx - polyspan.window.minx);
+ }
+
+ return true;
+}
+
+bool Layer_Shape::render_polyspan(etl::surface<float> *surface, PolySpan &polyspan) const
+{
+ etl::surface<float>::pen p(surface->begin());
+ PolySpan::cover_array::iterator cur_mark = polyspan.covers.begin();
+ PolySpan::cover_array::iterator end_mark = polyspan.covers.end();
+
+ Real cover,area,alpha;
+
+ int y,x;
+
+ cover = 0;
+
+ //the pen always writes 1 (unless told to do otherwise)
+ p.set_value(1);
+
+ if(cur_mark == end_mark)
+ {
+ //no marks at all
+ if(invert)
+ {
+ p.move_to(polyspan.window.minx,polyspan.window.miny);
+ p.put_block(polyspan.window.maxy - polyspan.window.miny,polyspan.window.maxx - polyspan.window.minx);
+ }
+ return true;
+ }
+
+ //fill initial rect / line
+ if(invert)
+ {
+ //fill all the area above the first vertex
+ p.move_to(polyspan.window.minx,polyspan.window.miny);
+ y = polyspan.window.miny;
+ int l = polyspan.window.maxx - polyspan.window.minx;
+
+ p.put_block(cur_mark->y - polyspan.window.miny,l);
+
+ //fill the area to the left of the first vertex on that line
+ l = cur_mark->x - polyspan.window.minx;
+ p.move_to(polyspan.window.minx,cur_mark->y);
+ if(l) p.put_hline(l);
+
+ for(;;)
+ {
+ y = cur_mark->y;
+ x = cur_mark->x;
+
+ p.move_to(x,y);
+
+ area = cur_mark->area;
+ cover += cur_mark->cover;
+
+ //accumulate for the current pixel
+ while(++cur_mark != polyspan.covers.end())
+ {
+ if(y != cur_mark->y || x != cur_mark->x)
+ break;
+
+ area += cur_mark->area;
+ cover += cur_mark->cover;
+ }
+
+ //draw pixel - based on covered area
+ if(area) //if we're ok, draw the current pixel
+ {
+ alpha = 1 - polyspan.ExtractAlpha(cover - area, winding_style);
+ if(!antialias)
+ {
+ if(alpha >= .5) p.put_value();
+ }
+ else if(alpha) p.put_value(alpha);
+
+ p.inc_x();
+ x++;
+ }
+
+ //if we're done, don't use iterator and exit
+ if(cur_mark == end_mark) break;
+
+ //if there is no more live pixels on this line, goto next
+ if(y != cur_mark->y)
+ {
+ //fill the area at the end of the line
+ p.put_hline(polyspan.window.maxx - x);
+
+ //fill area at the beginning of the next line
+ p.move_to(polyspan.window.minx,cur_mark->y);
+ p.put_hline(cur_mark->x - polyspan.window.minx);
+
+ cover = 0;
+
+ continue;
+ }
+
+ //draw span to next pixel - based on total amount of pixel cover
+ if(x < cur_mark->x)
+ {
+ alpha = 1 - polyspan.ExtractAlpha(cover, winding_style);
+ if(!antialias)
+ {
+ if(alpha >= .5) p.put_hline(cur_mark->x - x);
+ }
+ else if(alpha) p.put_hline(cur_mark->x - x,alpha);
+ }
+ }
+
+ //fill the area at the end of the line
+ p.put_hline(polyspan.window.maxx - x);
+
+ //fill area at the beginning of the next line
+ p.move_to(polyspan.window.minx,y+1);
+ p.put_block(polyspan.window.maxy - y - 1,polyspan.window.maxx - polyspan.window.minx);
+ }else
+ {
+ for(;;)
+ {
+ y = cur_mark->y;
+ x = cur_mark->x;
+
+ p.move_to(x,y);
+
+ area = cur_mark->area;
+ cover += cur_mark->cover;
+
+ //accumulate for the current pixel
+ while(++cur_mark != polyspan.covers.end())
+ {
+ if(y != cur_mark->y || x != cur_mark->x)
+ break;
+
+ area += cur_mark->area;
+ cover += cur_mark->cover;
+ }
+
+ //draw pixel - based on covered area
+ if(area) //if we're ok, draw the current pixel
+ {
+ alpha = polyspan.ExtractAlpha(cover - area, winding_style);
+ if(!antialias)
+ {
+ if(alpha >= .5) p.put_value();
+ }
+ else if(alpha) p.put_value(alpha);
+
+ p.inc_x();
+ x++;
+ }
+
+ //if we're done, don't use iterator and exit
+ if(cur_mark == end_mark) break;
+
+ //if there is no more live pixels on this line, goto next
+ if(y != cur_mark->y)
+ {
+ cover = 0;
+
+ continue;
+ }
+
+ //draw span to next pixel - based on total amount of pixel cover
+ if(x < cur_mark->x)
+ {
+ alpha = polyspan.ExtractAlpha(cover, winding_style);
+ if(!antialias)
+ {
+ if(alpha >= .5) p.put_hline(cur_mark->x - x);
+ }
+ else if(alpha) p.put_hline(cur_mark->x - x,alpha);
+ }
+ }
+ }
+
+ return true;
+}
+
+bool
+Layer_Shape::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ const unsigned int w = renddesc.get_w();
+ const unsigned int h = renddesc.get_h();
+
+ const Real pw = abs(renddesc.get_pw());
+ const Real ph = abs(renddesc.get_ph());
+
+ //const Real OFFSET_EPSILON = 1e-8;
+ SuperCallback stageone(cb,1,10000,15001+renddesc.get_h());
+ SuperCallback stagetwo(cb,10000,10001+renddesc.get_h(),15001+renddesc.get_h());
+ SuperCallback stagethree(cb,10001+renddesc.get_h(),15001+renddesc.get_h(),15001+renddesc.get_h());
+
+ // Render what is behind us
+
+ //clip if it satisfies the invert solid thing
+ if(is_solid_color() && invert)
+ {
+ Rect aabb = edge_table->aabb;
+ Point tl = renddesc.get_tl() - offset;
+
+ Real pw = renddesc.get_pw(),
+ ph = renddesc.get_ph();
+
+ Rect nrect;
+
+ Real pixelfeatherx = abs(feather/pw),
+ pixelfeathery = abs(feather/ph);
+
+ nrect.set_point((aabb.minx - tl[0])/pw,(aabb.miny - tl[1])/ph);
+ nrect.expand((aabb.maxx - tl[0])/pw,(aabb.maxy - tl[1])/ph);
+
+ RendDesc optdesc(renddesc);
+
+ //make sure to expand so we gain subpixels rather than lose them
+ nrect.minx = floor(nrect.minx-pixelfeatherx); nrect.miny = floor(nrect.miny-pixelfeathery);
+ nrect.maxx = ceil(nrect.maxx+pixelfeatherx); nrect.maxy = ceil(nrect.maxy+pixelfeathery);
+
+ //make sure the subwindow is clipped with our tile window (minimize useless drawing)
+ set_intersect(nrect,nrect,Rect(0,0,renddesc.get_w(),renddesc.get_h()));
+
+ //must resize the surface first
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ surface->clear();
+
+ //only render anything if it's visible from our current tile
+ if(nrect.valid())
+ {
+ //set the subwindow to the viewable pixels and render it to the subsurface
+ optdesc.set_subwindow((int)nrect.minx, (int)nrect.miny,
+ (int)(nrect.maxx - nrect.minx), (int)(nrect.maxy - nrect.miny));
+
+ Surface optimizedbacksurf;
+ if(!context.accelerated_render(&optimizedbacksurf,quality,optdesc,&stageone))
+ return false;
+
+ //blit that onto the original surface so we can pretend that nothing ever happened
+ Surface::pen p = surface->get_pen((int)nrect.minx,(int)nrect.miny);
+ optimizedbacksurf.blit_to(p);
+ }
+ }else
+ {
+ if(!context.accelerated_render(surface,quality,renddesc,&stageone))
+ return false;
+ }
+
+ if(cb && !cb->amount_complete(10000,10001+renddesc.get_h())) return false;
+
+ if(feather)
+ {
+ //we have to blur rather than be crappy
+
+ //so make a separate surface
+ RendDesc workdesc(renddesc);
+
+ etl::surface<float> shapesurface;
+
+ //the expanded size = 1/2 the size in each direction rounded up
+ int halfsizex = (int) (abs(feather*.5/pw) + 3),
+ halfsizey = (int) (abs(feather*.5/ph) + 3);
+
+ //expand by 1/2 size in each direction on either side
+ switch(blurtype)
+ {
+ case Blur::DISC:
+ case Blur::BOX:
+ case Blur::CROSS:
+ {
+ workdesc.set_subwindow(-max(1,halfsizex),-max(1,halfsizey),w+2*max(1,halfsizex),h+2*max(1,halfsizey));
+ break;
+ }
+ case Blur::FASTGAUSSIAN:
+ {
+ if(quality < 4)
+ {
+ halfsizex*=2;
+ halfsizey*=2;
+ }
+ workdesc.set_subwindow(-max(1,halfsizex),-max(1,halfsizey),w+2*max(1,halfsizex),h+2*max(1,halfsizey));
+ break;
+ }
+ case Blur::GAUSSIAN:
+ {
+ #define GAUSSIAN_ADJUSTMENT (0.05)
+ Real pw = (Real)workdesc.get_w()/(workdesc.get_br()[0]-workdesc.get_tl()[0]);
+ Real ph = (Real)workdesc.get_h()/(workdesc.get_br()[1]-workdesc.get_tl()[1]);
+
+ pw=pw*pw;
+ ph=ph*ph;
+
+ halfsizex = (int)(abs(pw)*feather*GAUSSIAN_ADJUSTMENT+0.5);
+ halfsizey = (int)(abs(ph)*feather*GAUSSIAN_ADJUSTMENT+0.5);
+
+ halfsizex = (halfsizex + 1)/2;
+ halfsizey = (halfsizey + 1)/2;
+ workdesc.set_subwindow( -halfsizex, -halfsizey, w+2*halfsizex, h+2*halfsizey );
+
+ break;
+ }
+ }
+
+ shapesurface.set_wh(workdesc.get_w(),workdesc.get_h());
+ shapesurface.clear();
+
+ //render the shape
+ if(!render_shape(&shapesurface,quality,workdesc,&stagetwo))return false;
+
+ //blur the image
+ Blur(feather,feather,blurtype,&stagethree)(shapesurface,workdesc.get_br()-workdesc.get_tl(),shapesurface);
+
+ //blend with stuff below it...
+ unsigned int u = halfsizex, v = halfsizey, x = 0, y = 0;
+ for(y = 0; y < h; y++,v++)
+ {
+ u = halfsizex;
+ for(x = 0; x < w; x++,u++)
+ {
+ float a = shapesurface[v][u];
+ if(a)
+ {
+ //a = floor(a*255+0.5f)/255;
+ (*surface)[y][x]=Color::blend(color,(*surface)[y][x],a*get_amount(),get_blend_method());
+ }
+ //else (*surface)[y][x] = worksurface[v][u];
+ }
+ }
+
+ //we are done
+ if(cb && !cb->amount_complete(100,100))
+ {
+ synfig::warning("Layer_Shape: could not set amount complete");
+ return false;
+ }
+
+ return true;
+ }else
+ {
+ //might take out to reduce code size
+ return render_shape(surface,true,quality,renddesc,&stagetwo);
+ }
+
+}
+
+bool
+Layer_Shape::render_shape(Surface *surface,bool useblend,int /*quality*/,
+ const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ int tmp(0);
+
+ SuperCallback progress(cb,0,renddesc.get_h(),renddesc.get_h());
+
+ // If our amount is set to zero, no need to render anything
+ if(!get_amount())
+ return true;
+
+ //test new polygon renderer
+ // Build edge table
+ // Width and Height of a pixel
+ const int w = renddesc.get_w();
+ const int h = renddesc.get_h();
+ const Real pw = renddesc.get_w()/(renddesc.get_br()[0]-renddesc.get_tl()[0]);
+ const Real ph = renddesc.get_h()/(renddesc.get_br()[1]-renddesc.get_tl()[1]);
+
+ const Point tl = renddesc.get_tl();
+
+ Vector tangent (0,0);
+
+ PolySpan span;
+
+ //optimization for tesselating only inside tiles
+ span.window.minx = 0;
+ span.window.miny = 0;
+ span.window.maxx = w;
+ span.window.maxy = h;
+
+ //pointers for processing the bytestream
+ const char *current = &bytestream[0];
+ const char *end = &bytestream[bytestream.size()];
+
+ int operation = Primitive::NONE;
+ int number = 0;
+ int curnum;
+
+ Primitive *curprim;
+ Point *data;
+
+ Real x,y,x1,y1,x2,y2;
+
+
+ while(current < end)
+ {
+ tmp++;
+
+ try {
+
+ //get the op code safely
+ curprim = (Primitive *)current;
+
+ //advance past indices
+ current += sizeof(Primitive);
+ if(current > end)
+ {
+ warning("Layer_Shape::accelerated_render - Error in the byte stream, not enough space for next declaration");
+ return false;
+ }
+
+ //get the relevant data
+ operation = curprim->operation;
+ number = curprim->number;
+
+ if(operation == Primitive::END)
+ break;
+
+ if(operation == Primitive::CLOSE)
+ {
+ if(span.notclosed())
+ {
+ tangent[0] = span.close_x - span.cur_x;
+ tangent[1] = span.close_y - span.cur_y;
+ span.close();
+ }
+ continue;
+ }
+
+ data = (Point*)current;
+ current += sizeof(Point)*number;
+
+ //check data positioning
+ if(current > end)
+ {
+ warning("Layer_Shape::accelerated_render - Error in the byte stream, in sufficient data space for declared number of points");
+ return false;
+ }
+
+ } catch(...) { synfig::error("Layer_Shape::render_shape()1: Caught an exception after %d loops, rethrowing...", tmp); throw; }
+
+ //transfer all the data - RLE optimized
+ for(curnum=0; curnum < number;)
+ {
+ switch(operation)
+ {
+ case Primitive::MOVE_TO:
+ {
+ x = data[curnum][0];
+ x = (x - tl[0] + offset[0])*pw;
+ y = data[curnum][1];
+ y = (y - tl[1] + offset[1])*ph;
+
+ if(curnum == 0)
+ {
+ span.move_to(x,y);
+
+ tangent[0] = 0;
+ tangent[1] = 0;
+ }
+ else
+ {
+ tangent[0] = x - span.cur_x;
+ tangent[1] = y - span.cur_y;
+
+ span.line_to(x,y);
+ }
+
+ curnum++; //only advance one point
+
+ break;
+ }
+
+ case Primitive::LINE_TO:
+ {
+ x = data[curnum][0];
+ x = (x - tl[0] + offset[0])*pw;
+ y = data[curnum][1];
+ y = (y - tl[1] + offset[1])*ph;
+
+ tangent[0] = x - span.cur_x;
+ tangent[1] = y - span.cur_y;
+
+ span.line_to(x,y);
+ curnum++;
+ break;
+ }
+
+ case Primitive::CONIC_TO:
+ {
+ x = data[curnum+1][0];
+ x = (x - tl[0] + offset[0])*pw;
+ y = data[curnum+1][1];
+ y = (y - tl[1] + offset[1])*ph;
+
+ x1 = data[curnum][0];
+ x1 = (x1 - tl[0] + offset[0])*pw;
+ y1 = data[curnum][1];
+ y1 = (y1 - tl[1] + offset[1])*ph;
+
+ tangent[0] = 2*(x - x1);
+ tangent[1] = 2*(y - y1);
+
+ span.conic_to(x1,y1,x,y);
+ curnum += 2;
+ break;
+ }
+
+ case Primitive::CONIC_TO_SMOOTH:
+ {
+ x = data[curnum][0];
+ x = (x - tl[0] + offset[0])*pw;
+ y = data[curnum][1];
+ y = (y - tl[1] + offset[1])*ph;
+
+ x1 = span.cur_x + tangent[0]/2;
+ y1 = span.cur_y + tangent[1]/2;
+
+ tangent[0] = 2*(x - x1);
+ tangent[1] = 2*(y - y1);
+
+ span.conic_to(x1,y1,x,y);
+ curnum ++;
+
+ break;
+ }
+
+ case Primitive::CUBIC_TO:
+ {
+ x = data[curnum+2][0];
+ x = (x - tl[0] + offset[0])*pw;
+ y = data[curnum+2][1];
+ y = (y - tl[1] + offset[1])*ph;
+
+ x2 = data[curnum+1][0];
+ x2 = (x2 - tl[0] + offset[0])*pw;
+ y2 = data[curnum+1][1];
+ y2 = (y2 - tl[1] + offset[1])*ph;
+
+ x1 = data[curnum][0];
+ x1 = (x1 - tl[0] + offset[0])*pw;
+ y1 = data[curnum][1];
+ y1 = (y1 - tl[1] + offset[1])*ph;
+
+ tangent[0] = 2*(x - x2);
+ tangent[1] = 2*(y - y2);
+
+ span.cubic_to(x1,y1,x2,y2,x,y);
+ curnum += 3;
+
+ break;
+ }
+
+ case Primitive::CUBIC_TO_SMOOTH:
+ {
+ x = data[curnum+1][0];
+ x = (x - tl[0] + offset[0])*pw;
+ y = data[curnum+1][1];
+ y = (y - tl[1] + offset[1])*ph;
+
+ x2 = data[curnum][0];
+ x2 = (x2 - tl[0] + offset[0])*pw;
+ y2 = data[curnum][1];
+ y2 = (y2 - tl[1] + offset[1])*ph;
+
+ x1 = span.cur_x + tangent[0]/3.0;
+ y1 = span.cur_y + tangent[1]/3.0;
+
+ tangent[0] = 2*(x - x2);
+ tangent[1] = 2*(y - y2);
+
+ span.cubic_to(x1,y1,x2,y2,x,y);
+ curnum += 2;
+
+ break;
+ }
+ }
+ }
+ }
+
+ //sort the bastards so we can render everything
+ span.sort_marks();
+
+ return render_polyspan(surface, span,
+ useblend?get_blend_method():Color::BLEND_STRAIGHT,
+ useblend?get_amount():1.0);
+}
+
+bool
+Layer_Shape::render_shape(surface<float> *surface,int /*quality*/,
+ const RendDesc &renddesc, ProgressCallback */*cb*/)const
+{
+ // If our amount is set to zero, no need to render anything
+ if(!get_amount())
+ return true;
+
+ //test new polygon renderer
+ // Build edge table
+ // Width and Height of a pixel
+ const int w = renddesc.get_w();
+ const int h = renddesc.get_h();
+ const Real pw = renddesc.get_w()/(renddesc.get_br()[0]-renddesc.get_tl()[0]);
+ const Real ph = renddesc.get_h()/(renddesc.get_br()[1]-renddesc.get_tl()[1]);
+
+ const Point tl = renddesc.get_tl();
+
+ Vector tangent (0,0);
+
+ PolySpan span;
+
+ //optimization for tesselating only inside tiles
+ span.window.minx = 0;
+ span.window.miny = 0;
+ span.window.maxx = w;
+ span.window.maxy = h;
+
+ //pointers for processing the bytestream
+ const char *current = &bytestream[0];
+ const char *end = &bytestream[bytestream.size()];
+
+ int operation = Primitive::NONE;
+ int number = 0;
+ int curnum;
+
+ Primitive *curprim;
+ Point *data;
+
+ Real x,y,x1,y1,x2,y2;
+
+ while(current < end)
+ {
+ //get the op code safely
+ curprim = (Primitive *)current;
+
+ //advance past indices
+ current += sizeof(Primitive);
+ if(current > end)
+ {
+ warning("Layer_Shape::accelerated_render - Error in the byte stream, not enough space for next declaration");
+ return false;
+ }
+
+ //get the relevant data
+ operation = curprim->operation;
+ number = curprim->number;
+
+ if(operation == Primitive::END)
+ break;
+
+ if(operation == Primitive::CLOSE)
+ {
+ if(span.notclosed())
+ {
+ tangent[0] = span.close_x - span.cur_x;
+ tangent[1] = span.close_y - span.cur_y;
+ span.close();
+ }
+ continue;
+ }
+
+ data = (Point*)current;
+ current += sizeof(Point)*number;
+
+ //check data positioning
+ if(current > end)
+ {
+ warning("Layer_Shape::accelerated_render - Error in the byte stream, in sufficient data space for declared number of points");
+ return false;
+ }
+
+ //transfer all the data
+ for(curnum=0; curnum < number;)
+ {
+ switch(operation)
+ {
+ case Primitive::MOVE_TO:
+ {
+ x = data[curnum][0];
+ x = (x - tl[0] + offset[0])*pw;
+ y = data[curnum][1];
+ y = (y - tl[1] + offset[1])*ph;
+
+ if(curnum == 0)
+ {
+ span.move_to(x,y);
+
+ tangent[0] = 0;
+ tangent[1] = 0;
+ }
+ else
+ {
+ tangent[0] = x - span.cur_x;
+ tangent[1] = y - span.cur_y;
+
+ span.line_to(x,y);
+ }
+
+ curnum++; //only advance one point
+
+ break;
+ }
+
+ case Primitive::LINE_TO:
+ {
+ x = data[curnum][0];
+ x = (x - tl[0] + offset[0])*pw;
+ y = data[curnum][1];
+ y = (y - tl[1] + offset[1])*ph;
+
+ tangent[0] = x - span.cur_x;
+ tangent[1] = y - span.cur_y;
+
+ span.line_to(x,y);
+ curnum++;
+ break;
+ }
+
+ case Primitive::CONIC_TO:
+ {
+ x = data[curnum+1][0];
+ x = (x - tl[0] + offset[0])*pw;
+ y = data[curnum+1][1];
+ y = (y - tl[1] + offset[1])*ph;
+
+ x1 = data[curnum][0];
+ x1 = (x1 - tl[0] + offset[0])*pw;
+ y1 = data[curnum][1];
+ y1 = (y1 - tl[1] + offset[1])*ph;
+
+ tangent[0] = 2*(x - x1);
+ tangent[1] = 2*(y - y1);
+
+ span.conic_to(x1,y1,x,y);
+ curnum += 2;
+ break;
+ }
+
+ case Primitive::CONIC_TO_SMOOTH:
+ {
+ x = data[curnum][0];
+ x = (x - tl[0] + offset[0])*pw;
+ y = data[curnum][1];
+ y = (y - tl[1] + offset[1])*ph;
+
+ x1 = span.cur_x + tangent[0]/2;
+ y1 = span.cur_y + tangent[1]/2;
+
+ tangent[0] = 2*(x - x1);
+ tangent[1] = 2*(y - y1);
+
+ span.conic_to(x1,y1,x,y);
+ curnum ++;
+
+ break;
+ }
+
+ case Primitive::CUBIC_TO:
+ {
+ x = data[curnum+2][0];
+ x = (x - tl[0] + offset[0])*pw;
+ y = data[curnum+2][1];
+ y = (y - tl[1] + offset[1])*ph;
+
+ x2 = data[curnum+1][0];
+ x2 = (x2 - tl[0] + offset[0])*pw;
+ y2 = data[curnum+1][1];
+ y2 = (y2 - tl[1] + offset[1])*ph;
+
+ x1 = data[curnum][0];
+ x1 = (x1 - tl[0] + offset[0])*pw;
+ y1 = data[curnum][1];
+ y1 = (y1 - tl[1] + offset[1])*ph;
+
+ tangent[0] = 2*(x - x2);
+ tangent[1] = 2*(y - y2);
+
+ span.cubic_to(x1,y1,x2,y2,x,y);
+ curnum += 3;
+
+ break;
+ }
+
+ case Primitive::CUBIC_TO_SMOOTH:
+ {
+ x = data[curnum+1][0];
+ x = (x - tl[0] + offset[0])*pw;
+ y = data[curnum+1][1];
+ y = (y - tl[1] + offset[1])*ph;
+
+ x2 = data[curnum][0];
+ x2 = (x2 - tl[0] + offset[0])*pw;
+ y2 = data[curnum][1];
+ y2 = (y2 - tl[1] + offset[1])*ph;
+
+ x1 = span.cur_x + tangent[0]/3.0;
+ y1 = span.cur_y + tangent[1]/3.0;
+
+ tangent[0] = 2*(x - x2);
+ tangent[1] = 2*(y - y2);
+
+ span.cubic_to(x1,y1,x2,y2,x,y);
+ curnum += 2;
+
+ break;
+ }
+ }
+ }
+ }
+
+ //sort the bastards so we can render everything
+ span.sort_marks();
+
+ return render_polyspan(surface, span);
+}
+
+Rect
+Layer_Shape::get_bounding_rect()const
+{
+ if(invert)
+ return Rect::full_plane();
+
+ if (edge_table->initaabb)
+ return Rect::zero();
+
+ Rect bounds(edge_table->aabb+offset);
+ bounds.expand(max((bounds.get_min() - bounds.get_max()).mag()*0.01,
+ feather));
+
+ return bounds;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_shape.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LAYER_SHAPE_H
+#define __SYNFIG_LAYER_SHAPE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "layer_composite.h"
+#include "color.h"
+#include "vector.h"
+#include "blur.h"
+
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class Layer_Shape
+** \brief writeme */
+class Layer_Shape : public Layer_Composite, public Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+ enum WindingStyle
+ {
+ WINDING_NON_ZERO=0, //!< less than -1 --> 1; -1 --> 1; 0 --> 0; 1 --> 1; greater than 1 --> 1
+ WINDING_EVEN_ODD=1, //!< add or subtract multiples of 2 to get into range -1:1, then as above
+
+ WINDING_END=2 //!< \internal
+ };
+
+private:
+
+ //internal cacheing
+ struct Intersector;
+ Intersector *edge_table;
+
+ //exported data
+ Color color;
+
+ Point offset;
+ bool invert;
+ bool antialias;
+
+ int blurtype;
+ Real feather;
+ WindingStyle winding_style;
+
+ std::vector< char > bytestream;
+
+ //for use in creating the bytestream
+ int lastbyteop;
+ int lastoppos;
+
+protected:
+
+ Layer_Shape(const Real &a = 1.0, const Color::BlendMethod m = Color::BLEND_COMPOSITE);
+
+public:
+
+ ~Layer_Shape();
+
+ //! Clears out any data
+ /*! Also clears out the Intersector
+ */
+ void clear();
+ //void sync();
+
+ void move_to(Real x, Real y);
+ void line_to(Real x, Real y);
+ void conic_to(Real x1, Real y1, Real x, Real y);
+ void conic_to_smooth(Real x, Real y); //x1,y1 derived from current tangent
+ void curve_to(Real x1, Real y1, Real x2, Real y2, Real x, Real y);
+ void curve_to_smooth(Real x2, Real y2, Real x, Real y); //x1,y1 derived from current tangent
+ void close();
+ void endpath();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Vocab get_param_vocab()const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+ virtual synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+ virtual Rect get_bounding_rect()const;
+
+private:
+ class PolySpan;
+ bool render_polyspan(Surface *surface,PolySpan &polyspan,
+ Color::BlendMethod method,Color::value_type amount)const;
+ bool render_polyspan(etl::surface<float> *surface,PolySpan &polyspan)const;
+ virtual bool render_shape(Surface *surface,bool useblend,int quality,const RendDesc &renddesc, ProgressCallback *cb)const;
+ virtual bool render_shape(etl::surface<float> *surface,int quality,const RendDesc &renddesc, ProgressCallback *cb)const;
+}; // END of Layer_Shape
+
+}; // END of namespace synfig
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_solidcolor.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "layer_solidcolor.h"
+#include "string.h"
+#include "time.h"
+#include "context.h"
+#include "paramdesc.h"
+#include "renddesc.h"
+#include "surface.h"
+#include "value.h"
+#include "valuenode.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+SYNFIG_LAYER_INIT(Layer_SolidColor);
+SYNFIG_LAYER_SET_NAME(Layer_SolidColor,"SolidColor"); // todo: use solid_color
+SYNFIG_LAYER_SET_LOCAL_NAME(Layer_SolidColor,_("Solid Color"));
+SYNFIG_LAYER_SET_CATEGORY(Layer_SolidColor,_("Geometry"));
+SYNFIG_LAYER_SET_VERSION(Layer_SolidColor,"0.1");
+SYNFIG_LAYER_SET_CVS_ID(Layer_SolidColor,"$Id$");
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Layer_SolidColor::Layer_SolidColor():
+ Layer_Composite(1.0,Color::BLEND_STRAIGHT),
+ color(Color::black())
+{
+}
+
+bool
+Layer_SolidColor::set_param(const String & param, const ValueBase &value)
+{
+ IMPORT(color);
+
+ return Layer_Composite::set_param(param,value);
+}
+
+ValueBase
+Layer_SolidColor::get_param(const String ¶m)const
+{
+ EXPORT(color);
+
+ EXPORT_NAME();
+ EXPORT_VERSION();
+
+ return Layer_Composite::get_param(param);
+}
+
+Layer::Vocab
+Layer_SolidColor::get_param_vocab()const
+{
+ Layer::Vocab ret(Layer_Composite::get_param_vocab());
+
+ ret.push_back(ParamDesc("color")
+ .set_local_name(_("Color"))
+ );
+
+ return ret;
+}
+
+synfig::Layer::Handle
+Layer_SolidColor::hit_check(synfig::Context context, const synfig::Point &point)const
+{
+ if(get_blend_method()==Color::BLEND_STRAIGHT && get_amount()>=0.5)
+ return const_cast<Layer_SolidColor*>(this);
+ else
+ if(get_blend_method()==Color::BLEND_COMPOSITE && get_amount()*color.get_a()>=0.5)
+ return const_cast<Layer_SolidColor*>(this);
+
+ Layer::Handle layer(context.hit_check(point));
+
+ return layer?layer:const_cast<Layer_SolidColor*>(this);
+}
+
+Color
+Layer_SolidColor::get_color(Context context, const Point &pos)const
+{
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ return color;
+ else
+ return Color::blend(color,context.get_color(pos),get_amount(),get_blend_method());
+}
+
+bool
+Layer_SolidColor::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT)
+ {
+ // Mark our progress as starting
+ if(cb && !cb->amount_complete(0,1000))
+ return false;
+
+ surface->set_wh(renddesc.get_w(),renddesc.get_h());
+ surface->fill(color);
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(1000,1000))
+ return false;
+
+ return true;
+ }
+
+ SuperCallback supercb(cb,0,9500,10000);
+
+ if(!context.accelerated_render(surface,quality,renddesc,&supercb))
+ return false;
+
+ int x,y;
+
+ Surface::alpha_pen apen(surface->begin());
+
+ apen.set_value(color);
+ apen.set_alpha(get_amount());
+ apen.set_blend_method(get_blend_method());
+
+ for(y=0;y<renddesc.get_h();y++,apen.inc_y(),apen.dec_x(x))
+ for(x=0;x<renddesc.get_w();x++,apen.inc_x())
+ apen.put_value();
+
+ // Mark our progress as finished
+ if(cb && !cb->amount_complete(10000,10000))
+ return false;
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file layer_solidcolor.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LAYER_SOLIDCOLOR_H
+#define __SYNFIG_LAYER_SOLIDCOLOR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "layer_composite.h"
+#include "color.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Layer_SolidColor : public Layer_Composite, public Layer_NoDeform
+{
+ SYNFIG_LAYER_MODULE_EXT
+
+private:
+
+ Color color;
+
+public:
+
+ Layer_SolidColor();
+
+ virtual bool set_param(const String & param, const synfig::ValueBase &value);
+
+ virtual ValueBase get_param(const String & param)const;
+
+ virtual Color get_color(Context context, const Point &pos)const;
+
+ virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+
+ virtual Vocab get_param_vocab()const;
+
+ virtual synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const;
+
+}; // END of class Layer_SolidColor
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file listimporter.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "listimporter.h"
+#include "general.h"
+#include <fstream>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+#define LIST_IMPORTER_CACHE_SIZE 20
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ListImporter::ListImporter(const String &filename)
+{
+ fps=15;
+
+ ifstream stream(filename.c_str());
+
+ if(!stream)
+ {
+ synfig::error("Unable to open "+filename);
+ return;
+ }
+ String line;
+ String prefix=etl::dirname(filename)+ETL_DIRECTORY_SEPARATOR;
+ while(!stream.eof())
+ {
+ getline(stream,line);
+ if(line.empty())
+ continue;
+ // If we have a framerate, then use it
+ if(line.find(String("FPS "))==0)
+ {
+ fps=atof(String(line.begin()+4,line.end()).c_str());
+ //synfig::warning("FPS=%f",fps);
+ if(!fps)
+ fps=15;
+ continue;
+ }
+ filename_list.push_back(prefix+line);
+ }
+}
+
+Importer*
+ListImporter::create(const char *filename)
+{
+ return new ListImporter(filename);
+}
+
+ListImporter::~ListImporter()
+{
+}
+
+bool
+ListImporter::get_frame(Surface &surface,Time time, ProgressCallback *cb)
+{
+// DEBUGPOINT();
+ int frame=static_cast<int>(time*fps);
+// DEBUGPOINT();
+
+ if(!filename_list.size())
+ {
+ if(cb)cb->error(_("No images in list"));
+ else synfig::error(_("No images in list"));
+ return false;
+ }
+
+// DEBUGPOINT();
+ if(frame<0)frame=0;
+ if(frame>=(signed)filename_list.size())frame=filename_list.size()-1;
+
+// DEBUGPOINT();
+ // See if that frame is cached
+ std::list<std::pair<int,Surface> >::iterator iter;
+ for(iter=frame_cache.begin();iter!=frame_cache.end();++iter)
+ {
+ if(iter->first==frame)
+ {
+// DEBUGPOINT();
+ surface.mirror(iter->second);
+ return static_cast<bool>(surface);
+ }
+ }
+
+ Importer::Handle importer(Importer::open(filename_list[frame]));
+
+// DEBUGPOINT();
+
+ if(!importer)
+ {
+ if(cb)cb->error(_("Unable to open ")+filename_list[frame]);
+ else synfig::error(_("Unable to open ")+filename_list[frame]);
+ return false;
+ }
+
+// DEBUGPOINT();
+
+ if(!importer->get_frame(surface,0,cb))
+ {
+ if(cb)cb->error(_("Unable to get frame from ")+filename_list[frame]);
+ else synfig::error(_("Unable to get frame from ")+filename_list[frame]);
+ return false;
+ }
+
+// DEBUGPOINT();
+
+ if(frame_cache.size()>=LIST_IMPORTER_CACHE_SIZE)
+ frame_cache.pop_front();
+
+// DEBUGPOINT();
+
+ frame_cache.push_back(std::pair<int,Surface>(frame,surface));
+
+// DEBUGPOINT();
+
+ surface.mirror(frame_cache.back().second);
+
+// DEBUGPOINT();
+
+ return static_cast<bool>(surface);
+}
+
+bool
+ListImporter::is_animated()
+{
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file listimporter.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LISTIMPORTER_H
+#define __SYNFIG_LISTIMPORTER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "importer.h"
+#include "surface.h"
+#include <ETL/smart_ptr>
+#include <vector>
+//#include <deque>
+#include <list>
+#include <utility>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class ListImporter
+** \todo Write more detailed description
+*/
+class ListImporter : public Importer
+{
+ float fps;
+ std::vector<String> filename_list;
+ std::list<std::pair<int,Surface> > frame_cache;
+protected:
+ ListImporter(const String &filename);
+
+public:
+
+ virtual ~ListImporter();
+
+ virtual bool get_frame(Surface &surface,Time time, ProgressCallback *callback=NULL);
+
+ virtual bool is_animated();
+
+ static Importer* create(const char *filename);
+};
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file loadcanvas.cpp
+** \brief writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#include <ETL/stringf>
+#include <libxml++/libxml++.h>
+#include <vector>
+#include <stdexcept>
+#include <iostream>
+
+#include "loadcanvas.h"
+#include "valuenode.h"
+#include "valuenode_subtract.h"
+#include "valuenode_animated.h"
+#include "valuenode_composite.h"
+#include "valuenode_const.h"
+#include "valuenode_linear.h"
+#include "valuenode_dynamiclist.h"
+#include "valuenode_reference.h"
+#include "valuenode_scale.h"
+#include "valuenode_timedswap.h"
+#include "valuenode_twotone.h"
+#include "valuenode_stripes.h"
+#include "valuenode_segcalctangent.h"
+#include "valuenode_segcalcvertex.h"
+#include "valuenode_bline.h"
+
+#include "layer.h"
+#include "string.h"
+
+#include "exception.h"
+
+#include "gradient.h"
+
+#include <map>
+#include <sigc++/bind.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace synfig;
+using namespace etl;
+
+/*
+class test_class {
+static int bleh;
+public:
+ test_class() { assert(!bleh); bleh++; synfig::info("test_class: initi: %d",bleh); }
+ ~test_class() { assert(bleh); synfig::info("test_class: uninit: %d",bleh); bleh--; }
+};
+int test_class::bleh(0);
+
+test_class test_class_instance;
+*/
+
+/* === M A C R O S ========================================================= */
+
+inline bool is_whitespace(char x) { return ((x)=='\n' || (x)=='\t' || (x)==' '); }
+
+/* === P R O C E D U R E S ================================================= */
+
+static std::map<String, Canvas::LooseHandle>* open_canvas_map_(0);
+
+std::map<synfig::String, etl::loose_handle<Canvas> >& synfig::get_open_canvas_map()
+{
+ if(!open_canvas_map_)
+ open_canvas_map_=new std::map<String, Canvas::LooseHandle>;
+ return *open_canvas_map_;
+}
+
+static void _remove_from_open_canvas_map(Canvas *x) { get_open_canvas_map().erase(etl::absolute_path(x->get_file_name())); }
+
+static void _canvas_file_name_changed(Canvas *x)
+{
+ std::map<synfig::String, etl::loose_handle<Canvas> >::iterator iter;
+
+ for(iter=get_open_canvas_map().begin();iter!=get_open_canvas_map().end();++iter)
+ if(iter->second==x)
+ break;
+ assert(iter!=get_open_canvas_map().end());
+ if(iter==get_open_canvas_map().end())
+ return;
+ get_open_canvas_map().erase(iter->first);
+ get_open_canvas_map()[etl::absolute_path(x->get_file_name())]=x;
+
+}
+
+Canvas::Handle
+synfig::open_canvas(const String &filename)
+{
+ CanvasParser parser;
+
+ parser.set_allow_errors(true);
+
+ Canvas::Handle canvas=parser.parse_from_file(filename);
+
+ if(parser.error_count())
+ return Canvas::Handle();
+
+ return canvas;
+}
+
+Canvas::Handle
+synfig::open_canvas_as(const String &filename,const String &as)
+{
+ CanvasParser parser;
+
+ parser.set_allow_errors(true);
+
+ Canvas::Handle canvas=parser.parse_from_file_as(filename,as);
+
+ if(parser.error_count())
+ return Canvas::Handle();
+
+ return canvas;
+}
+
+Canvas::Handle
+synfig::string_to_canvas(const String &data)
+{
+ CanvasParser parser;
+
+ parser.set_allow_errors(true);
+
+ Canvas::Handle canvas=parser.parse_from_string(data);
+
+ if(parser.error_count())
+ return Canvas::Handle();
+
+ return canvas;
+}
+
+/* === M E T H O D S ======================================================= */
+
+void
+CanvasParser::error_unexpected_element(xmlpp::Node *element,const String &got, const String &expected)
+{
+ error(element,strprintf(_("Unexpected element <%s>, Expected <%s>"),got.c_str(),expected.c_str()));
+}
+
+void
+CanvasParser::error_unexpected_element(xmlpp::Node *element,const String &got)
+{
+ error(element,strprintf(_("Unexpected element <%s>"),got.c_str()));
+}
+
+void
+CanvasParser::warning(xmlpp::Node *element, const String &text)
+{
+ string str=strprintf("%s:<%s>:%d: warning: ",filename.c_str(),element->get_name().c_str(),element->get_line())+text;
+ //synfig::warning(str);
+ cerr<<str<<endl;
+ total_warnings_++;
+ if(total_warnings_>=max_warnings_)
+ fatal_error(element, _("Too many warnings"));
+}
+
+void
+CanvasParser::error(xmlpp::Node *element, const String &text)
+{
+ string str=strprintf("%s:<%s>:%d: error: ",filename.c_str(),element->get_name().c_str(),element->get_line())+text;
+ total_errors_++;
+ if(!allow_errors_)
+ throw runtime_error(str);
+ cerr<<str<<endl;
+ // synfig::error(str);
+}
+
+void
+CanvasParser::fatal_error(xmlpp::Node *element, const String &text)
+{
+ string str=strprintf("%s:<%s>:%d:",filename.c_str(),element->get_name().c_str(),element->get_line())+text;
+ throw runtime_error(str);
+}
+
+
+
+Keyframe
+CanvasParser::parse_keyframe(xmlpp::Element *element,Canvas::Handle canvas)
+{
+ assert(element->get_name()=="keyframe");
+
+ if(!element->get_attribute("time"))
+ {
+ error(element,strprintf(_("<%s> is missing \"%s\" attribute"),"real","time"));
+ return Keyframe();
+ }
+
+ Keyframe ret(Time(element->get_attribute("time")->get_value(),canvas->rend_desc().get_frame_rate()));
+
+
+ if(element->get_children().empty())
+ return ret;
+
+ if(element->get_child_text()->get_content().empty())
+ return ret;
+
+ ret.set_description(element->get_child_text()->get_content());
+
+ return ret;
+}
+
+
+Real
+CanvasParser::parse_real(xmlpp::Element *element)
+{
+ assert(element->get_name()=="real");
+
+ if(!element->get_children().empty())
+ warning(element, strprintf(_("<%s> should not contain anything"),"real"));
+
+ if(!element->get_attribute("value"))
+ {
+ error(element,strprintf(_("<%s> is missing \"value\" attribute"),"real"));
+ return false;
+ }
+
+ string val=element->get_attribute("value")->get_value();
+
+ return atof(val.c_str());
+}
+
+Time
+CanvasParser::parse_time(xmlpp::Element *element,Canvas::Handle canvas)
+{
+ assert(element->get_name()=="time");
+
+ if(!element->get_children().empty())
+ warning(element, strprintf(_("<%s> should not contain anything"),"time"));
+
+ if(!element->get_attribute("value"))
+ {
+ error(element,strprintf(_("<%s> is missing \"value\" attribute"),"time"));
+ return false;
+ }
+
+ string val=element->get_attribute("value")->get_value();
+
+ return Time(val,canvas->rend_desc().get_frame_rate());
+}
+
+int
+CanvasParser::parse_integer(xmlpp::Element *element)
+{
+ assert(element->get_name()=="integer");
+
+ if(!element->get_children().empty())
+ warning(element, strprintf(_("<%s> should not contain anything"),"integer"));
+
+ if(!element->get_attribute("value"))
+ {
+ error(element,strprintf(_("<%s> is missing \"value\" attribute"),"integer"));
+ return false;
+ }
+
+ string val=element->get_attribute("value")->get_value();
+
+ return atoi(val.c_str());
+}
+
+// see 'minor hack' at the end of parse_vector() below
+// making this 'static' to give it file local scope
+// stops it working (where working means working around
+// bug #1509627)
+Vector &canvas_parser_vector_id(Vector &vector)
+{
+ return vector;
+}
+
+Vector
+CanvasParser::parse_vector(xmlpp::Element *element)
+{
+ assert(element->get_name()=="vector");
+
+ if(element->get_children().empty())
+ {
+ error(element, "Undefined value in <vector>");
+ return Vector();
+ }
+
+ Vector vect;
+
+ xmlpp::Element::NodeList list = element->get_children();
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ xmlpp::Element *child=dynamic_cast<xmlpp::Element*>((xmlpp::Node*)*iter);
+ if(!child)
+ continue;
+ else
+ if(child->get_name()=="x")
+ {
+ if(child->get_children().empty())
+ {
+ error(element, "Undefined value in <x>");
+ return Vector();
+ }
+ vect[0]=atof(child->get_child_text()->get_content().c_str());
+ }
+ else
+ if(child->get_name()=="y")
+ {
+ if(child->get_children().empty())
+ {
+ error(element, "Undefined value in <y>");
+ return Vector();
+ }
+ vect[1]=atof(child->get_child_text()->get_content().c_str());
+ }
+ else
+ error_unexpected_element(child,child->get_name());
+ }
+ // Minor hack - gcc 4.1.2 and earlier think that we're not using
+ // 'vect' and optimize it out at -O2 and higher. This convinces
+ // them that we are really using it.
+ return canvas_parser_vector_id(vect);
+ // When the bug is fixed, we can just do this instead:
+ // return vect;
+}
+
+Color
+CanvasParser::parse_color(xmlpp::Element *element)
+{
+ assert(element->get_name()=="color");
+
+ if(element->get_children().empty())
+ {
+ error(element, "Undefined value in <color>");
+ return Color();
+ }
+
+ Color color(0);
+
+ xmlpp::Element::NodeList list = element->get_children();
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ xmlpp::Element *child(dynamic_cast<xmlpp::Element*>(*iter));
+ if(!child)
+ continue;
+ else
+ if(child->get_name()=="r")
+ {
+ if(child->get_children().empty())
+ {
+ error(element, "Undefined value in <r>");
+ return Color();
+ }
+ color.set_r(atof(child->get_child_text()->get_content().c_str()));
+ }
+ else
+ if(child->get_name()=="g")
+ {
+ if(child->get_children().empty())
+ {
+ error(element, "Undefined value in <g>");
+ return Color();
+ }
+ color.set_g(atof(child->get_child_text()->get_content().c_str()));
+ }
+ else
+ if(child->get_name()=="b")
+ {
+ if(child->get_children().empty())
+ {
+ error(element, "Undefined value in <b>");
+ return Color();
+ }
+ color.set_b(atof(child->get_child_text()->get_content().c_str()));
+ }
+ else
+ if(child->get_name()=="a")
+ {
+ if(child->get_children().empty())
+ {
+ error(element, "Undefined value in <a>");
+ return Color();
+ }
+ color.set_a(atof(child->get_child_text()->get_content().c_str()));
+ }
+ else
+ error_unexpected_element(child,child->get_name());
+ }
+
+ return color;
+}
+
+synfig::String
+CanvasParser::parse_string(xmlpp::Element *element)
+{
+ assert(element->get_name()=="string");
+
+ if(element->get_children().empty())
+ {
+ warning(element, "Undefined value in <string>");
+ return synfig::String();
+ }
+
+ if(element->get_child_text()->get_content().empty())
+ {
+ warning(element, "Content element of <string> appears to be empty");
+ return synfig::String();
+ }
+
+ return element->get_child_text()->get_content();
+}
+
+bool
+CanvasParser::parse_bool(xmlpp::Element *element)
+{
+ assert(element->get_name()=="bool");
+
+ if(!element->get_children().empty())
+ warning(element, strprintf(_("<%s> should not contain anything"),"bool"));
+
+ if(!element->get_attribute("value"))
+ {
+ error(element,strprintf(_("<%s> is missing \"value\" attribute"),"bool"));
+ return false;
+ }
+
+ string val=element->get_attribute("value")->get_value();
+
+ if(val=="true" || val=="1")
+ return true;
+ if(val=="false" || val=="0")
+ return false;
+
+ error(element,strprintf(_("Bad value \"%s\" in <%s>"),val.c_str(),"bool"));
+
+ return false;
+}
+
+Gradient
+CanvasParser::parse_gradient(xmlpp::Element *node)
+{
+ assert(node->get_name()=="gradient");
+ Gradient ret;
+
+ xmlpp::Element::NodeList list = node->get_children();
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ xmlpp::Element *child(dynamic_cast<xmlpp::Element*>(*iter));
+ if(!child)
+ continue;
+ else
+ {
+ Gradient::CPoint cpoint;
+ cpoint.color=parse_color(child);
+
+ if(!child->get_attribute("pos"))
+ {
+ error(child,strprintf(_("<%s> is missing \"pos\" attribute"),"gradient"));
+ return Gradient();
+ }
+
+ cpoint.pos=atof(child->get_attribute("pos")->get_value().c_str());
+
+ ret.push_back(cpoint);
+ }
+ }
+ ret.sort();
+ return ret;
+}
+
+ValueBase
+CanvasParser::parse_list(xmlpp::Element *element,Canvas::Handle canvas)
+{
+ vector<ValueBase> value_list;
+
+ xmlpp::Element::NodeList list = element->get_children();
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ xmlpp::Element *child(dynamic_cast<xmlpp::Element*>(*iter));
+ if(!child)
+ continue;
+ else
+ {
+ value_list.push_back(parse_value(child,canvas));
+ if(!value_list.back().is_valid())
+ {
+ value_list.pop_back();
+ error(child,"Bad ValueBase");
+ continue;
+ }
+ }
+ }
+ return value_list;
+}
+
+Segment
+CanvasParser::parse_segment(xmlpp::Element *element)
+{
+ assert(element->get_name()=="segment");
+
+ if(element->get_children().empty())
+ {
+ error(element, "Undefined value in <segment>");
+ return Segment();
+ }
+
+ Segment seg;
+
+ xmlpp::Element::NodeList list = element->get_children();
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ xmlpp::Element *child(dynamic_cast<xmlpp::Element*>(*iter));
+ if(!child)
+ continue;
+ else
+ if(child->get_name()=="p1")
+ {
+ xmlpp::Element::NodeList list = child->get_children();
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter)) break;
+
+ if(iter==list.end())
+ {
+ error(element, "Undefined value in <p1>");
+ continue;
+ }
+
+ if((*iter)->get_name()!="vector")
+ {
+ error_unexpected_element((*iter),(*iter)->get_name(),"vector");
+ continue;
+ }
+
+ seg.p1=parse_vector(dynamic_cast<xmlpp::Element*>(*iter));
+ }
+ else
+ if(child->get_name()=="t1")
+ {
+ xmlpp::Element::NodeList list = child->get_children();
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter)) break;
+
+ if(iter==list.end())
+ {
+ error(element, "Undefined value in <t1>");
+ continue;
+ }
+
+ if((*iter)->get_name()!="vector")
+ {
+ error_unexpected_element((*iter),(*iter)->get_name(),"vector");
+ continue;
+ }
+
+ seg.t1=parse_vector(dynamic_cast<xmlpp::Element*>(*iter));
+ }
+ else
+ if(child->get_name()=="p2")
+ {
+ xmlpp::Element::NodeList list = child->get_children();
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter)) break;
+
+ if(iter==list.end())
+ {
+ error(element, "Undefined value in <p2>");
+ continue;
+ }
+
+ if((*iter)->get_name()!="vector")
+ {
+ error_unexpected_element((*iter),(*iter)->get_name(),"vector");
+ continue;
+ }
+
+ seg.p2=parse_vector(dynamic_cast<xmlpp::Element*>(*iter));
+ }
+ else
+ if(child->get_name()=="t2")
+ {
+ xmlpp::Element::NodeList list = child->get_children();
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter)) break;
+
+ if(iter==list.end())
+ {
+ error(element, "Undefined value in <t2>");
+ continue;
+ }
+
+ if((*iter)->get_name()!="vector")
+ {
+ error_unexpected_element((*iter),(*iter)->get_name(),"vector");
+ continue;
+ }
+
+ seg.t2=parse_vector(dynamic_cast<xmlpp::Element*>(*iter));
+ }
+ else
+ error_unexpected_element(child,child->get_name());
+ }
+ return seg;
+}
+
+BLinePoint
+CanvasParser::parse_bline_point(xmlpp::Element *element)
+{
+ assert(element->get_name()=="bline_point");
+ if(element->get_children().empty())
+ {
+ error(element, "Undefined value in <bline_point>");
+ return BLinePoint();
+ }
+
+ BLinePoint ret;
+ ret.set_split_tangent_flag(false);
+
+ xmlpp::Element::NodeList list = element->get_children();
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ xmlpp::Element *child(dynamic_cast<xmlpp::Element*>(*iter));
+ if(!child)
+ continue;
+ else
+ // Vertex
+ if(child->get_name()[0]=='v' || child->get_name()=="p1")
+ {
+ xmlpp::Element::NodeList list = child->get_children();
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter)) break;
+
+ if(iter==list.end())
+ {
+ error(element, "Undefined value in <vertex>");
+ continue;
+ }
+
+ if((*iter)->get_name()!="vector")
+ {
+ error_unexpected_element((*iter),(*iter)->get_name(),"vector");
+ continue;
+ }
+
+ ret.set_vertex(parse_vector(dynamic_cast<xmlpp::Element*>(*iter)));
+ }
+ else
+ // Tangent 1
+ if(child->get_name()=="t1" || child->get_name()=="tangent")
+ {
+ xmlpp::Element::NodeList list = child->get_children();
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter)) break;
+
+ if(iter==list.end())
+ {
+ error(element, "Undefined value in <t1>");
+ continue;
+ }
+
+ if((*iter)->get_name()!="vector")
+ {
+ error_unexpected_element((*iter),(*iter)->get_name(),"vector");
+ continue;
+ }
+
+ ret.set_tangent1(parse_vector(dynamic_cast<xmlpp::Element*>(*iter)));
+ }
+ else
+ // Tangent 2
+ if(child->get_name()=="t2")
+ {
+ xmlpp::Element::NodeList list = child->get_children();
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter)) break;
+
+ if(iter==list.end())
+ {
+ error(element, "Undefined value in <t2>");
+ continue;
+ }
+
+ if((*iter)->get_name()!="vector")
+ {
+ error_unexpected_element((*iter),(*iter)->get_name(),"vector");
+ continue;
+ }
+
+ ret.set_tangent2(parse_vector(dynamic_cast<xmlpp::Element*>(*iter)));
+ ret.set_split_tangent_flag(true);
+ }
+ else
+ // width
+ if(child->get_name()=="width")
+ {
+ xmlpp::Element::NodeList list = child->get_children();
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter)) break;
+
+ if(iter==list.end())
+ {
+ error(element, "Undefined value in <width>");
+ continue;
+ }
+
+ if((*iter)->get_name()!="real")
+ {
+ error_unexpected_element((*iter),(*iter)->get_name(),"real");
+ continue;
+ }
+
+ ret.set_width(parse_real(dynamic_cast<xmlpp::Element*>(*iter)));
+ }
+ else
+ // origin
+ if(child->get_name()=="origin")
+ {
+ xmlpp::Element::NodeList list = child->get_children();
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter)) break;
+
+ if(iter==list.end())
+ {
+ error(element, "Undefined value in <origin>");
+ continue;
+ }
+
+ if((*iter)->get_name()!="real")
+ {
+ error_unexpected_element((*iter),(*iter)->get_name(),"real");
+ continue;
+ }
+
+ ret.set_origin(parse_real(dynamic_cast<xmlpp::Element*>(*iter)));
+ }
+ else
+ error_unexpected_element(child,child->get_name());
+ }
+ return ret;
+}
+
+Angle
+CanvasParser::parse_angle(xmlpp::Element *element)
+{
+ assert(element->get_name()=="angle");
+
+ if(!element->get_children().empty())
+ warning(element, strprintf(_("<%s> should not contain anything"),"angle"));
+
+ if(!element->get_attribute("value"))
+ {
+ error(element,strprintf(_("<%s> is missing \"value\" attribute"),"angle"));
+ return Angle();
+ }
+
+ string val=element->get_attribute("value")->get_value();
+
+ return Angle::deg(atof(val.c_str()));
+}
+
+ValueBase
+CanvasParser::parse_value(xmlpp::Element *element,Canvas::Handle canvas)
+{
+ if(element->get_name()=="real")
+ return parse_real(element);
+ else
+ if(element->get_name()=="time")
+ return parse_time(element,canvas);
+ else
+ if(element->get_name()=="integer")
+ return parse_integer(element);
+ else
+ if(element->get_name()=="string")
+ return parse_string(element);
+ else
+ if(element->get_name()=="vector")
+ return parse_vector(element);
+ else
+ if(element->get_name()=="color")
+ return parse_color(element);
+ else
+ if(element->get_name()=="segment")
+ return parse_segment(element);
+ else
+ if(element->get_name()=="list")
+ return parse_list(element,canvas);
+ else
+ if(element->get_name()=="gradient")
+ return parse_gradient(element);
+ else
+ if(element->get_name()=="bool")
+ return parse_bool(element);
+ else
+ //if(element->get_name()=="canvas")
+ // return parse_canvas(element,canvas,true); // inline canvas
+ //else
+ if(element->get_name()=="angle" || element->get_name()=="degrees" || element->get_name()=="radians" || element->get_name()=="rotations")
+ return parse_angle(element);
+ else
+ if(element->get_name()=="bline_point")
+ return parse_bline_point(element);
+ else
+ if(element->get_name()=="canvas")
+ return ValueBase(parse_canvas(element,canvas,true));
+ else
+ {
+ DEBUGPOINT();
+ error_unexpected_element(element,element->get_name());
+ }
+
+ return ValueBase();
+}
+
+
+
+
+ValueNode_Animated::Handle
+CanvasParser::parse_animated(xmlpp::Element *element,Canvas::Handle canvas)
+{
+ assert(element->get_name()=="hermite" || element->get_name()=="animated");
+
+ if(!element->get_attribute("type"))
+ {
+ error(element,"Missing attribute \"type\" in <animated>");
+ return ValueNode_Animated::Handle();
+ }
+
+ ValueBase::Type type=ValueBase::ident_type(element->get_attribute("type")->get_value());
+
+ if(!type)
+ {
+ error(element,"Bad type in <animated>");
+ return ValueNode_Animated::Handle();
+ }
+
+ ValueNode_Animated::Handle value_node=ValueNode_Animated::create(type);
+
+ if(!value_node)
+ {
+ error(element,strprintf(_("Unable to create <animated> with type \"%s\""),ValueBase::type_name(type).c_str()));
+ return ValueNode_Animated::Handle();
+ }
+
+ value_node->set_root_canvas(canvas->get_root());
+
+ xmlpp::Element::NodeList list = element->get_children();
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ xmlpp::Element *child(dynamic_cast<xmlpp::Element*>(*iter));
+ if(!child)
+ continue;
+ else
+ if(child->get_name()=="waypoint")
+ {
+ if(!child->get_attribute("time"))
+ {
+ error(child,_("<waypoint> is missing attribute \"time\""));
+ continue;
+ }
+
+ Time time(child->get_attribute("time")->get_value(),canvas->rend_desc().get_frame_rate());
+
+
+ ValueNode::Handle waypoint_value_node;
+ xmlpp::Element::NodeList list = child->get_children();
+
+ if(child->get_attribute("use"))
+ {
+ if(!list.empty())
+ warning(child,_("Found \"use\" attribute for <waypoint>, but it wasn't empty. Ignoring contents..."));
+
+ // the waypoint might look like this, in which case we won't find "mycanvas" in the list of valuenodes, 'cos it's a canvas
+ //
+ // <animated type="canvas">
+ // <waypoint time="0s" use="mycanvas"/>
+ // </animated>
+ if (type==ValueBase::TYPE_CANVAS)
+ waypoint_value_node=ValueNode_Const::create(canvas->surefind_canvas(child->get_attribute("use")->get_value()));
+ else
+ waypoint_value_node=canvas->surefind_value_node(child->get_attribute("use")->get_value());
+ }
+ else
+ {
+ if(child->get_children().empty())
+ {
+ error(child, strprintf(_("<%s> is missing its data"),"waypoint"));
+ continue;
+ }
+
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter)) break;
+
+ if(iter==list.end())
+ {
+ error(child, strprintf(_("<%s> is missing its data"),"waypoint"));
+ continue;
+ }
+
+ waypoint_value_node=parse_value_node(dynamic_cast<xmlpp::Element*>(*iter),canvas);
+
+ /*
+ ValueBase data=parse_value(dynamic_cast<xmlpp::Element*>(*iter),canvas);
+
+ if(!data.is_valid())
+ {
+ error(child,_("Bad data for <waypoint>"));
+ continue;
+ }
+ */
+ if(!waypoint_value_node)
+ {
+ error(child,_("Bad data for <waypoint>"));
+ continue;
+ }
+
+ /*! HACK -- This is a temporary fix to help repair some
+ ** weirdness that is currently going on (10-21-2004).
+ ** This short circuits the linking of waypoints,
+ ** a feature which is so obscure that we can get
+ ** away with something like this pretty easily.
+ */
+ waypoint_value_node=waypoint_value_node->clone();
+
+ // Warn if there is trash after the param value
+ for(iter++; iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter))
+ warning((*iter),strprintf(_("Unexpected element <%s> after <waypoint> data, ignoring..."),(*iter)->get_name().c_str()));
+ }
+
+
+ try {
+ ValueNode_Animated::WaypointList::iterator waypoint=value_node->new_waypoint(time,waypoint_value_node);
+
+ if(child->get_attribute("tension"))
+ {
+ synfig::String str(child->get_attribute("tension")->get_value());
+ waypoint->set_tension(atof(str.c_str()));
+ }
+ if(child->get_attribute("temporal-tension"))
+ {
+ synfig::String str(child->get_attribute("temporal-tension")->get_value());
+ waypoint->set_time_tension(atof(str.c_str()));
+ }
+ if(child->get_attribute("continuity"))
+ {
+ synfig::String str(child->get_attribute("continuity")->get_value());
+ waypoint->set_continuity(atof(str.c_str()));
+ }
+ if(child->get_attribute("bias"))
+ {
+ synfig::String str(child->get_attribute("bias")->get_value());
+ waypoint->set_bias(atof(str.c_str()));
+ }
+
+ if(child->get_attribute("before"))
+ {
+ string val=child->get_attribute("before")->get_value();
+ if(val=="halt")
+ waypoint->set_before(INTERPOLATION_HALT);
+ else if(val=="constant")
+ waypoint->set_before(INTERPOLATION_CONSTANT);
+ else if(val=="linear")
+ waypoint->set_before(INTERPOLATION_LINEAR);
+ else if(val=="manual")
+ waypoint->set_before(INTERPOLATION_MANUAL);
+ else if(val=="auto")
+ waypoint->set_before(INTERPOLATION_TCB);
+ else
+ error(child,strprintf(_("\"%s\" not a valid value for attribute \"%s\" in <%s>"),val.c_str(),"before","waypoint"));
+ }
+
+ if(child->get_attribute("after"))
+ {
+ string val=child->get_attribute("after")->get_value();
+ if(val=="halt")
+ waypoint->set_after(INTERPOLATION_HALT);
+ else if(val=="constant")
+ waypoint->set_after(INTERPOLATION_CONSTANT);
+ else if(val=="linear")
+ waypoint->set_after(INTERPOLATION_LINEAR);
+ else if(val=="manual")
+ waypoint->set_after(INTERPOLATION_MANUAL);
+ else if(val=="auto")
+ waypoint->set_after(INTERPOLATION_TCB);
+ else
+ error(child,strprintf(_("\"%s\" not a valid value for attribute \"%s\" in <%s>"),val.c_str(),"before","waypoint"));
+ }
+ }
+ catch(Exception::BadTime x)
+ {
+ warning(child,x.what());
+ }
+ continue;
+
+ }
+ else
+ error_unexpected_element(child,child->get_name());
+ }
+ value_node->changed();
+ return value_node;
+}
+
+etl::handle<LinkableValueNode>
+CanvasParser::parse_linkable_value_node(xmlpp::Element *element,Canvas::Handle canvas)
+{
+ handle<LinkableValueNode> value_node;
+ ValueBase::Type type;
+
+ // Determine the type
+ if(element->get_attribute("type"))
+ {
+ type=ValueBase::ident_type(element->get_attribute("type")->get_value());
+
+ if(!type)
+ {
+ error(element,"Bad type in ValueNode");
+ return 0;
+ }
+ }
+ else
+ {
+ error(element,"Missing type in ValueNode");
+ return 0;
+ }
+
+ value_node=LinkableValueNode::create(element->get_name(),type);
+
+ if(!value_node)
+ {
+ error(element,"Unknown ValueNode type "+element->get_name());
+ return 0;
+ }
+
+ if(value_node->get_type()!=type)
+ {
+ error(element,"ValueNode did not accept type");
+ return 0;
+ }
+
+ value_node->set_root_canvas(canvas->get_root());
+
+ int i;
+ for(i=0;i<value_node->link_count();i++)
+ {
+ if(element->get_attribute(value_node->link_name(i)))
+ try {
+ String id(element->get_attribute(value_node->link_name(i))->get_value());
+
+ if(!value_node->set_link(i,
+ canvas->surefind_value_node(
+ id
+ )
+ )
+ ) error(element,strprintf(_("Unable to set link \"%s\" to ValueNode \"%s\" (link #%d in \"%s\")"),value_node->link_name(i).c_str(),id.c_str(),i,value_node->get_name().c_str()));
+ }
+ catch(Exception::IDNotFound)
+ {
+ error(element,"Unable to resolve "+element->get_attribute(value_node->link_name(i))->get_value());
+ }
+ catch(Exception::FileNotFound)
+ {
+ error(element,"Unable to open file referenced in "+element->get_attribute(value_node->link_name(i))->get_value());
+ }
+ catch(...)
+ {
+ error(element,strprintf(_("Unknown Exception thrown when referencing ValueNode \"%s\""),
+ element->get_attribute(value_node->link_name(i))->get_value().c_str()));
+ throw;
+ }
+ }
+
+
+
+ xmlpp::Element::NodeList list = element->get_children();
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ xmlpp::Element *child(dynamic_cast<xmlpp::Element*>(*iter));
+ try
+ {
+ if(!child)
+ continue;
+ int index=value_node->get_link_index_from_name(child->get_name());
+
+ xmlpp::Element::NodeList list = child->get_children();
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter)) break;
+
+ if(iter==list.end())
+ {
+ error(child,_("element is missing its contents"));
+ continue;
+ }
+
+ ValueNode::Handle link=parse_value_node(dynamic_cast<xmlpp::Element*>(*iter),canvas);
+
+ if(!link)
+ {
+ error((*iter),"Parse of ValueNode failed");
+ }
+ else
+ if(!value_node->set_link(index,link))
+ {
+ //error(dynamic_cast<xmlpp::Element*>(*iter),strprintf("Unable to connect value node ('%s' of type '%s') to link %d",link->get_name().c_str(),ValueBase::type_name(link->get_type()).c_str(),index));
+ error(element,strprintf("Unable to connect value node ('%s' of type '%s') to link %d",link->get_name().c_str(),ValueBase::type_name(link->get_type()).c_str(),index));
+ }
+
+ // \todo do a search for more elements and warn if they are found
+
+ }
+ catch(Exception::BadLinkName)
+ {
+ error_unexpected_element(child,child->get_name());
+ }
+ catch(...)
+ {
+ error(child,strprintf(_("Unknown Exception thrown when working on element \"%s\""),child->get_name().c_str()));
+ throw;
+ }
+ }
+
+ return value_node;
+}
+
+handle<ValueNode_Composite>
+CanvasParser::parse_composite(xmlpp::Element *element,Canvas::Handle canvas)
+{
+ assert(element->get_name()=="composite");
+
+ if(!element->get_attribute("type"))
+ {
+ error(element,"Missing attribute \"type\" in <composite>");
+ return handle<ValueNode_Composite>();
+ }
+
+ ValueBase::Type type=ValueBase::ident_type(element->get_attribute("type")->get_value());
+
+ if(!type)
+ {
+ error(element,"Bad type in <composite>");
+ return handle<ValueNode_Composite>();
+ }
+
+ handle<ValueNode_Composite> value_node=ValueNode_Composite::create(type);
+ handle<ValueNode> c[6];
+
+ if(!value_node)
+ {
+ error(element,strprintf(_("Unable to create <composite>")));
+ return handle<ValueNode_Composite>();
+ }
+
+ int i;
+
+ for(i=0;i<value_node->link_count();i++)
+ {
+ string name=strprintf("c%d",i+1);
+ if(c[i])
+ {
+ error(element,name+" was already defined in <composite>");
+ continue;
+ }
+ if(element->get_attribute(name))
+ {
+ c[i]=canvas->surefind_value_node(element->get_attribute(name)->get_value());
+ if(c[i])
+ {
+ if(!value_node->set_link(i,c[i]))
+ {
+ error(element,'"'+name+"\" attribute in <composite> has bad type");
+ }
+ }
+ else
+ error(element,'"'+name+"\" attribute in <composite> references unknown ID");
+ }
+ }
+
+ xmlpp::Element::NodeList list = element->get_children();
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ xmlpp::Element *child(dynamic_cast<xmlpp::Element*>(*iter));
+ if(!child)
+ continue;
+ else
+ for(i=0;i<value_node->link_count();i++)
+ {
+ string name=strprintf("c%d",i+1);
+ if(child->get_name()==name)
+ {
+ if(c[i])
+ {
+ error(child,name+" was already defined in <composite>");
+ break;
+ }
+
+ xmlpp::Element::NodeList list = child->get_children();
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter)) break;
+
+ if(iter==list.end())
+ {
+ error(child,strprintf(_("<%s> is missing its contents"),name.c_str()));
+ break;
+ }
+
+ c[i]=parse_value_node(dynamic_cast<xmlpp::Element*>(*iter),canvas);
+
+ if(!c[i])
+ {
+ error((*iter),"Parse of "+name+" ValueNode failed");
+ break;
+ }
+
+ if(!value_node->set_link(i,c[i]))
+ {
+ error(child,strprintf(_("<%s> has a bad value"),name.c_str()));
+ break;
+ }
+
+ // \todo do a search for more elements and warn if they are found
+ break;
+ }
+ }
+ // somewhat of a hack, but it works
+ if(i==value_node->link_count()) error_unexpected_element(child,child->get_name());
+ }
+
+ switch(value_node->link_count())
+ {
+ case 1:
+ if(!value_node->get_link(0))
+ {
+ error(element,"<composite> is missing parameters");
+ return handle<ValueNode_Composite>();
+ }
+ break;
+ case 2:
+ if(!value_node->get_link(0) ||!value_node->get_link(1))
+ {
+ error(element,"<composite> is missing parameters");
+ return handle<ValueNode_Composite>();
+ }
+ break;
+ case 3:
+ if(!value_node->get_link(0) ||!value_node->get_link(1) ||!value_node->get_link(2))
+ {
+ error(element,"<composite> is missing parameters");
+ return handle<ValueNode_Composite>();
+ }
+ break;
+ case 4:
+ if(!value_node->get_link(0) ||!value_node->get_link(1) ||!value_node->get_link(2) ||!value_node->get_link(3))
+ {
+ error(element,"<composite> is missing parameters");
+ return handle<ValueNode_Composite>();
+ }
+ break;
+ }
+ return value_node;
+}
+
+// This will also parse a bline
+handle<ValueNode_DynamicList>
+CanvasParser::parse_dynamic_list(xmlpp::Element *element,Canvas::Handle canvas)
+{
+ assert(element->get_name()=="dynamic_list" || element->get_name()=="bline");
+
+ const float fps(canvas?canvas->rend_desc().get_frame_rate():0);
+
+ if(!element->get_attribute("type"))
+ {
+ error(element,"Missing attribute \"type\" in <dynamic_list>");
+ return handle<ValueNode_DynamicList>();
+ }
+
+ ValueBase::Type type=ValueBase::ident_type(element->get_attribute("type")->get_value());
+
+ if(!type)
+ {
+ error(element,"Bad type in <dynamic_list>");
+ return handle<ValueNode_DynamicList>();
+ }
+
+ handle<ValueNode_DynamicList> value_node;
+ handle<ValueNode_BLine> bline_value_node;
+
+ if(element->get_name()=="bline")
+ {
+ value_node=bline_value_node=ValueNode_BLine::create();
+ if(element->get_attribute("loop"))
+ {
+ String loop=element->get_attribute("loop")->get_value();
+ if(loop=="true" || loop=="1" || loop=="TRUE" || loop=="True")
+ bline_value_node->set_loop(true);
+ else
+ bline_value_node->set_loop(false);
+ }
+
+ }
+ else
+ value_node=ValueNode_DynamicList::create(type);
+
+ if(!value_node)
+ {
+ error(element,strprintf(_("Unable to create <dynamic_list>")));
+ return handle<ValueNode_DynamicList>();
+ }
+
+ value_node->set_root_canvas(canvas->get_root());
+
+ xmlpp::Element::NodeList list = element->get_children();
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ xmlpp::Element *child(dynamic_cast<xmlpp::Element*>(*iter));
+ if(!child)
+ continue;
+ else
+ if(child->get_name()=="entry")
+ {
+ ValueNode_DynamicList::ListEntry list_entry;
+
+ // Parse begin/end waypoints
+ {
+ typedef synfig::ValueNode_DynamicList::ListEntry::Activepoint Activepoint;
+ typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
+
+ String begin_sequence;
+ String end_sequence;
+
+ ActivepointList &timing_info(list_entry.timing_info);
+
+ if(child->get_attribute("begin"))
+ begin_sequence=child->get_attribute("begin")->get_value();
+
+ if(child->get_attribute("on"))
+ begin_sequence=child->get_attribute("on")->get_value();
+
+ if(child->get_attribute("end"))
+ end_sequence=child->get_attribute("end")->get_value();
+
+ if(child->get_attribute("off"))
+ end_sequence=child->get_attribute("off")->get_value();
+
+ // clear out any auto-start
+ if(!begin_sequence.empty())
+ timing_info.clear();
+
+ //! \optimize
+ while(!begin_sequence.empty())
+ {
+ String::iterator iter(find(begin_sequence.begin(),begin_sequence.end(),','));
+ String timecode(begin_sequence.begin(), iter);
+ int priority=0;
+
+ // skip whitespace before checking for a priority
+ while (isspace(timecode[0]))
+ timecode=timecode.substr(1);
+
+ // If there is a priority, then grab it and remove
+ // it from the timecode
+ if(timecode[0]=='p')
+ {
+ //priority=timecode[1]-'0';
+ //timecode=String(timecode.begin()+3,timecode.end());
+ int space=timecode.find_first_of(' ');
+ priority=atoi(String(timecode,1,space-1).c_str());
+ timecode=String(timecode.begin()+space+1,timecode.end());
+ //synfig::info("priority: %d timecode: %s",priority,timecode.c_str());
+ }
+
+ timing_info.push_back(
+ Activepoint(
+ Time(
+ timecode,
+ fps
+ ),
+ true, // Mark as a "on" activepoint
+ priority
+ )
+ );
+
+ if(iter==begin_sequence.end())
+ begin_sequence.clear();
+ else
+ begin_sequence=String(iter+1,begin_sequence.end());
+ }
+
+ //! \optimize
+ while(!end_sequence.empty())
+ {
+ String::iterator iter(find(end_sequence.begin(),end_sequence.end(),','));
+ String timecode(end_sequence.begin(), iter);
+ int priority=0;
+
+ // skip whitespace before checking for a priority
+ while (isspace(timecode[0]))
+ timecode=timecode.substr(1);
+
+ // If there is a priority, then grab it and remove
+ // it from the timecode
+ if(timecode[0]=='p')
+ {
+ //priority=timecode[1]-'0';
+ //timecode=String(timecode.begin()+3,timecode.end());
+ int space=timecode.find_first_of(' ');
+ priority=atoi(String(timecode,1,space-1).c_str());
+ timecode=String(timecode.begin()+space+1,timecode.end());
+ //synfig::info("priority: %d timecode: %s",priority,timecode.c_str());
+ }
+
+ timing_info.push_back(
+ Activepoint(
+ Time(
+ timecode,
+ fps
+ ),
+ false, // Mark as a "off" activepoint
+ priority
+ )
+ );
+ if(iter==end_sequence.end())
+ end_sequence.clear();
+ else
+ end_sequence=String(iter+1,end_sequence.end());
+ }
+
+ timing_info.sort();
+ }
+
+ if(child->get_attribute("use"))
+ {
+ // \todo does this need to be able to read 'use="canvas"', like waypoints can now? (see 'surefind_canvas' in this file)
+ string id=child->get_attribute("use")->get_value();
+ try
+ {
+ list_entry.value_node=canvas->surefind_value_node(id);
+ }
+ catch(Exception::IDNotFound)
+ {
+ error(child,"\"use\" attribute in <entry> references unknown ID -- "+id);
+ continue;
+ }
+ }
+ else
+ {
+ xmlpp::Element::NodeList list = child->get_children();
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter)) break;
+
+ if(iter==list.end())
+ {
+ error(child,strprintf(_("<entry> is missing its contents or missing \"use\" element")));
+ continue;
+ }
+
+ list_entry.value_node=parse_value_node(dynamic_cast<xmlpp::Element*>(*iter),canvas);
+
+ if(!list_entry.value_node)
+ error((*iter),"Parse of ValueNode failed");
+
+ // \todo do a search for more elements and warn if they are found
+
+ }
+
+ value_node->add(list_entry);
+ value_node->set_link(value_node->link_count()-1,list_entry.value_node);
+ }
+ else
+ error_unexpected_element(child,child->get_name());
+ }
+ return value_node;
+}
+
+handle<ValueNode>
+CanvasParser::parse_value_node(xmlpp::Element *element,Canvas::Handle canvas)
+{
+ handle<ValueNode> value_node;
+ assert(element);
+
+ GUID guid;
+
+ if(element->get_attribute("guid"))
+ {
+ guid=GUID(element->get_attribute("guid")->get_value())^canvas->get_root()->get_guid();
+ value_node=guid_cast<ValueNode>(guid);
+ if(value_node)
+ return value_node;
+ }
+
+ // If ValueBase::ident_type() recognises the name, then we know it's a ValueBase
+ if(element->get_name()!="canvas" && ValueBase::ident_type(element->get_name()))
+ {
+ ValueBase data=parse_value(element,canvas);
+
+ if(!data.is_valid())
+ {
+ error(element,strprintf(_("Bad data in <%s>"),element->get_name().c_str()));
+ return value_node;
+ }
+
+ // We want to convert this ValueBase into a
+ // ValueNode_Const. That way, we can treat the
+ // ID like any other Datanode. Think of this
+ // as a shorthand for creating constant ValueNodes.
+
+ value_node=ValueNode_Const::create(data);
+ }
+ else
+ if(element->get_name()=="hermite" || element->get_name()=="animated")
+ value_node=parse_animated(element,canvas);
+ else
+ if(element->get_name()=="composite")
+ value_node=parse_composite(element,canvas);
+ else
+ if(element->get_name()=="dynamic_list")
+ value_node=parse_dynamic_list(element,canvas);
+ else
+ if(element->get_name()=="bline") // This is not a typo. The dynamic list parser will parse a bline.
+ value_node=parse_dynamic_list(element,canvas);
+ else
+ if(LinkableValueNode::book().count(element->get_name()))
+ value_node=parse_linkable_value_node(element,canvas);
+ else
+ if(element->get_name()=="canvas")
+ value_node=ValueNode_Const::create(parse_canvas(element,canvas,true));
+ else
+ {
+ error_unexpected_element(element,element->get_name());
+ error(element, "Expected a ValueNode");
+ }
+
+
+ value_node->set_root_canvas(canvas->get_root());
+
+
+ // If we were successful, and our element has
+ // an ID attribute, go ahead and add it to the
+ // value_node list
+ if(value_node && element->get_attribute("id"))
+ {
+ string id=element->get_attribute("id")->get_value();
+
+ //value_node->set_id(id);
+
+ // If there is already a value_node in the list
+ // with the same ID, then that is an error
+ try { canvas->add_value_node(value_node,id); }
+ catch(Exception::BadLinkName)
+ {
+ warning(element,strprintf(_("Bad ID \"%s\""),id.c_str()));
+ return value_node;
+ }
+ catch(Exception::IDAlreadyExists)
+ {
+ error(element,strprintf(_("Duplicate ID \"%s\""),id.c_str()));
+ return value_node;
+ }
+ catch(...)
+ {
+ error(element,strprintf(_("Unknown Exception thrown when adding ValueNode \"%s\""),id.c_str()));
+ throw;
+ }
+ }
+ value_node->set_guid(guid);
+ return value_node;
+}
+
+void
+CanvasParser::parse_canvas_defs(xmlpp::Element *element,Canvas::Handle canvas)
+{
+ assert(element->get_name()=="defs");
+ xmlpp::Element::NodeList list = element->get_children();
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ xmlpp::Element *child(dynamic_cast<xmlpp::Element*>(*iter));
+ if(!child)
+ continue;
+ else
+ if(child->get_name()=="canvas")
+ parse_canvas(child, canvas);
+ else
+ parse_value_node(child,canvas);
+ }
+}
+
+Layer::Handle
+CanvasParser::parse_layer(xmlpp::Element *element,Canvas::Handle canvas)
+{
+
+ assert(element->get_name()=="layer");
+ Layer::Handle layer;
+
+ if(!element->get_attribute("type"))
+ {
+ error(element,_("Missing \"type\" attribute to \"layer\" element"));
+ return Layer::Handle();
+ }
+
+ layer=Layer::create(element->get_attribute("type")->get_value());
+ layer->set_canvas(canvas);
+
+ if(element->get_attribute("group"))
+ {
+ layer->add_to_group(
+ element->get_attribute("group")->get_value()
+ );
+ }
+
+ // Handle the version attribute
+ if(element->get_attribute("version"))
+ {
+ String version(element->get_attribute("version")->get_value());
+ if(version>layer->get_version())
+ warning(element,_("Installed layer version is larger than layer version in file"));
+ if(version!=layer->get_version())
+ layer->set_version(version);
+ }
+
+ // Handle the description
+ if(element->get_attribute("desc"))
+ layer->set_description(element->get_attribute("desc")->get_value());
+
+ if(element->get_attribute("active"))
+ layer->set_active(element->get_attribute("active")->get_value()=="false"?false:true);
+
+ xmlpp::Element::NodeList list = element->get_children();
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ xmlpp::Element *child(dynamic_cast<xmlpp::Element*>(*iter));
+ if(!child)
+ continue;
+ else
+ if(child->get_name()=="name")
+ warning(child,_("<name> entry for <layer> is not yet supported. Ignoring..."));
+ else
+ if(child->get_name()=="desc")
+ warning(child,_("<desc> entry for <layer> is not yet supported. Ignoring..."));
+ else
+ if(child->get_name()=="param")
+ {
+ xmlpp::Element::NodeList list = child->get_children();
+
+ if(!child->get_attribute("name"))
+ {
+ error(child,_("Missing \"name\" attribute for <param>."));
+ continue;
+ }
+
+ String param_name=child->get_attribute("name")->get_value();
+
+ if(child->get_attribute("use"))
+ {
+ // If the "use" attribute is used, then the
+ // element should be empty. Warn the user if
+ // we find otherwise.
+ if(!list.empty())
+ warning(child,_("Found \"use\" attribute for <param>, but it wasn't empty. Ignoring contents..."));
+
+ String str= child->get_attribute("use")->get_value();
+
+ if(layer->get_param(param_name).get_type()==ValueBase::TYPE_CANVAS)
+ {
+ if(!layer->set_param(param_name,canvas->surefind_canvas(str)))
+ error((*iter),_("Layer rejected canvas link"));
+ }
+ else
+ try
+ {
+ handle<ValueNode> value_node=canvas->surefind_value_node(str);
+
+ // Assign the value_node to the dynamic parameter list
+ layer->connect_dynamic_param(param_name,value_node);
+ }
+ catch(Exception::IDNotFound)
+ {
+ error(child,strprintf(_("Unknown ID (%s) referenced in <param>"),str.c_str()));
+ }
+
+ continue;
+ }
+
+ xmlpp::Element::NodeList::iterator iter;
+
+ // Search for the first non-text XML element
+ for(iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter))
+ break;
+ //if(!(!dynamic_cast<xmlpp::Element*>(*iter) && (*iter)->get_name()=="text"||(*iter)->get_name()=="comment" )) break;
+
+ if(iter==list.end())
+ {
+ error(child,_("<param> is either missing its contents, or missing a \"use\" attribute."));
+ continue;
+ }
+
+ // If we recognise the element name as a
+ // ValueBase, then treat is at one
+ if(/*(*iter)->get_name()!="canvas" && */ValueBase::ident_type((*iter)->get_name()) && !dynamic_cast<xmlpp::Element*>(*iter)->get_attribute("guid"))
+ {
+ ValueBase data=parse_value(dynamic_cast<xmlpp::Element*>(*iter),canvas);
+
+ if(!data.is_valid())
+ {
+ error((*iter),_("Bad data for <param>"));
+ continue;
+ }
+
+ // Set the layer's parameter, and make sure that
+ // the layer liked it
+ if(!layer->set_param(param_name,data))
+ {
+ warning((*iter),_("Layer rejected value for <param>"));
+ continue;
+ }
+ }
+ else // ... otherwise, we assume that it is a ValueNode
+ {
+ handle<ValueNode> value_node=parse_value_node(dynamic_cast<xmlpp::Element*>(*iter),canvas);
+
+ if(!value_node)
+ {
+ error((*iter),_("Bad data for <param>"));
+ continue;
+ }
+
+ // Assign the value_node to the dynamic parameter list
+ layer->connect_dynamic_param(param_name,value_node);
+ }
+
+ // Warn if there is trash after the param value
+ for(iter++; iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::Element*>(*iter))
+ warning((*iter),strprintf(_("Unexpected element <%s> after <param> data, ignoring..."),(*iter)->get_name().c_str()));
+ continue;
+ }
+ else
+ error_unexpected_element(child,child->get_name());
+ }
+
+ layer->reset_version();
+ return layer;
+}
+
+Canvas::Handle
+CanvasParser::parse_canvas(xmlpp::Element *element,Canvas::Handle parent,bool inline_, String filename)
+{
+
+ if(element->get_name()!="canvas")
+ {
+ error_unexpected_element(element,element->get_name(),"canvas");
+ return Canvas::Handle();
+ }
+ Canvas::Handle canvas;
+
+
+
+ if(parent && (element->get_attribute("id") || inline_))
+ {
+ if(inline_)
+ {
+ canvas=Canvas::create_inline(parent);
+ }
+ else
+ {
+ try
+ {
+ canvas=parent->find_canvas(element->get_attribute("id")->get_value());
+ }
+ catch(...)
+ {
+ canvas=parent->new_child_canvas(element->get_attribute("id")->get_value());
+ }
+ }
+ canvas->rend_desc().clear_flags();
+ }
+ else
+ {
+ canvas=Canvas::create();
+ if(filename=="/dev/stdin")
+ canvas->set_file_name("./stdin.sif");
+ else
+ canvas->set_file_name(filename);
+ canvas->rend_desc().clear_flags();
+ }
+
+ if(element->get_attribute("guid"))
+ {
+ GUID guid(element->get_attribute("guid")->get_value());
+ if(guid_cast<Canvas>(guid))
+ return guid_cast<Canvas>(guid);
+ else
+ canvas->set_guid(guid);
+ }
+
+ if(element->get_attribute("width"))
+ canvas->rend_desc().set_w(atoi(element->get_attribute("width")->get_value().c_str()));
+
+ if(element->get_attribute("height"))
+ canvas->rend_desc().set_h(atoi(element->get_attribute("height")->get_value().c_str()));
+
+ if(element->get_attribute("xres"))
+ canvas->rend_desc().set_x_res(atof(element->get_attribute("xres")->get_value().c_str()));
+
+ if(element->get_attribute("yres"))
+ canvas->rend_desc().set_y_res(atof(element->get_attribute("yres")->get_value().c_str()));
+
+
+ if(element->get_attribute("fps"))
+ canvas->rend_desc().set_frame_rate(atof(element->get_attribute("fps")->get_value().c_str()));
+
+ if(element->get_attribute("start-time"))
+ canvas->rend_desc().set_time_start(Time(element->get_attribute("start-time")->get_value(),canvas->rend_desc().get_frame_rate()));
+
+ if(element->get_attribute("begin-time"))
+ canvas->rend_desc().set_time_start(Time(element->get_attribute("begin-time")->get_value(),canvas->rend_desc().get_frame_rate()));
+
+ if(element->get_attribute("end-time"))
+ canvas->rend_desc().set_time_end(Time(element->get_attribute("end-time")->get_value(),canvas->rend_desc().get_frame_rate()));
+
+ if(element->get_attribute("antialias"))
+ canvas->rend_desc().set_antialias(atoi(element->get_attribute("antialias")->get_value().c_str()));
+
+ if(element->get_attribute("view-box"))
+ {
+ string values=element->get_attribute("view-box")->get_value();
+ Vector
+ tl,
+ br;
+ tl[0]=atof(string(values.data(),values.find(' ')).c_str());
+ values=string(values.begin()+values.find(' ')+1,values.end());
+ tl[1]=atof(string(values.data(),values.find(' ')).c_str());
+ values=string(values.begin()+values.find(' ')+1,values.end());
+ br[0]=atof(string(values.data(),values.find(' ')).c_str());
+ values=string(values.begin()+values.find(' ')+1,values.end());
+ br[1]=atof(values.c_str());
+
+ canvas->rend_desc().set_tl(tl);
+ canvas->rend_desc().set_br(br);
+ }
+
+ if(element->get_attribute("bgcolor"))
+ {
+ string values=element->get_attribute("bgcolor")->get_value();
+ Color bg;
+
+ bg.set_r(atof(string(values.data(),values.find(' ')).c_str()));
+ values=string(values.begin()+values.find(' ')+1,values.end());
+
+ bg.set_g(atof(string(values.data(),values.find(' ')).c_str()));
+ values=string(values.begin()+values.find(' ')+1,values.end());
+
+ bg.set_b(atof(string(values.data(),values.find(' ')).c_str()));
+ values=string(values.begin()+values.find(' ')+1,values.end());
+
+ bg.set_a(atof(values.c_str()));
+
+ canvas->rend_desc().set_bg_color(bg);
+ }
+
+ if(element->get_attribute("focus"))
+ {
+ string values=element->get_attribute("focus")->get_value();
+ Vector focus;
+
+ focus[0]=atof(string(values.data(),values.find(' ')).c_str());
+ values=string(values.begin()+values.find(' ')+1,values.end());
+ focus[1]=atof(values.c_str());
+
+ canvas->rend_desc().set_focus(focus);
+ }
+
+ canvas->rend_desc().set_flags(RendDesc::PX_ASPECT|RendDesc::IM_SPAN);
+
+ xmlpp::Element::NodeList list = element->get_children();
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ xmlpp::Element *child(dynamic_cast<xmlpp::Element*>(*iter));
+ if(child)
+ {
+ if(child->get_name()=="defs")
+ {
+ if(canvas->is_inline())
+ error(child,_("Inline canvas cannot have a <defs> section"));
+ parse_canvas_defs(child, canvas);
+ }
+ else
+ if(child->get_name()=="keyframe")
+ {
+ if(canvas->is_inline())
+ {
+ warning(child,_("Inline canvas cannot have keyframes"));
+ continue;
+ }
+
+ canvas->keyframe_list().add(parse_keyframe(child,canvas));
+ canvas->keyframe_list().sync();
+ }
+ else
+ if(child->get_name()=="meta")
+ {
+ if(canvas->is_inline())
+ {
+ warning(child,_("Inline canvases cannot have metadata"));
+ continue;
+ }
+
+ String name,content;
+
+ if(!child->get_attribute("name"))
+ {
+ warning(child,_("<meta> must have a name"));
+ continue;
+ }
+
+ if(!child->get_attribute("content"))
+ {
+ warning(child,_("<meta> must have content"));
+ continue;
+ }
+
+ canvas->set_meta_data(child->get_attribute("name")->get_value(),child->get_attribute("content")->get_value());
+ }
+ else if(child->get_name()=="name")
+ {
+ xmlpp::Element::NodeList list = child->get_children();
+
+ // If we don't have any name, warn
+ if(list.empty())
+ warning(child,_("blank \"name\" entitity"));
+
+ string tmp;
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::TextNode*>(*iter))tmp+=dynamic_cast<xmlpp::TextNode*>(*iter)->get_content();
+ canvas->set_name(tmp);
+ }
+ else
+ if(child->get_name()=="desc")
+ {
+
+ xmlpp::Element::NodeList list = child->get_children();
+
+ // If we don't have any description, warn
+ if(list.empty())
+ warning(child,_("blank \"desc\" entitity"));
+
+ string tmp;
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::TextNode*>(*iter))tmp+=dynamic_cast<xmlpp::TextNode*>(*iter)->get_content();
+ canvas->set_description(tmp);
+ }
+ else
+ if(child->get_name()=="author")
+ {
+
+ xmlpp::Element::NodeList list = child->get_children();
+
+ // If we don't have any description, warn
+ if(list.empty())
+ warning(child,_("blank \"author\" entitity"));
+
+ string tmp;
+ for(xmlpp::Element::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ if(dynamic_cast<xmlpp::TextNode*>(*iter))tmp+=dynamic_cast<xmlpp::TextNode*>(*iter)->get_content();
+ canvas->set_author(tmp);
+ }
+ else
+ if(child->get_name()=="layer")
+ {
+ //if(canvas->is_inline())
+ // canvas->push_front(parse_layer(child,canvas->parent()));
+ //else
+ canvas->push_front(parse_layer(child,canvas));
+ }
+ else
+ error_unexpected_element(child,child->get_name());
+ }
+// else
+// if((child->get_name()=="text"||child->get_name()=="comment") && child->has_child_text())
+// continue;
+ }
+
+ if(canvas->value_node_list().placeholder_count())
+ {
+ error(element,strprintf(_("Canvas %s has undefined ValueNodes"),canvas->get_id().c_str()));
+ }
+
+ return canvas;
+}
+
+Canvas::Handle
+CanvasParser::parse_from_file(const String &file)
+{
+ return parse_from_file_as(file,file);
+}
+
+Canvas::Handle
+CanvasParser::parse_from_file_as(const String &file_,const String &as_)
+{
+ CHECK_EXPIRE_TIME();
+ try
+ {
+ ChangeLocale change_locale(LC_NUMERIC, "C");
+ String file(unix_to_local_path(file_));
+ String as(unix_to_local_path(as_));
+
+ if(get_open_canvas_map().count(etl::absolute_path(as)))
+ return get_open_canvas_map()[etl::absolute_path(as)];
+
+ filename=as;
+ total_warnings_=0;
+ xmlpp::DomParser parser(file);
+ if(parser)
+ {
+ Canvas::Handle canvas(parse_canvas(parser.get_document()->get_root_node(),0,false,as));
+ get_open_canvas_map()[etl::absolute_path(as)]=canvas;
+ canvas->signal_deleted().connect(sigc::bind(sigc::ptr_fun(_remove_from_open_canvas_map),canvas.get()));
+ canvas->signal_file_name_changed().connect(sigc::bind(sigc::ptr_fun(_canvas_file_name_changed),canvas.get()));
+
+
+
+ const ValueNodeList& value_node_list(canvas->value_node_list());
+
+ again:
+ ValueNodeList::const_iterator iter;
+ for(iter=value_node_list.begin();iter!=value_node_list.end();++iter)
+ {
+ ValueNode::Handle value_node(*iter);
+ if(value_node->is_exported() && value_node->get_id().find("Unnamed")==0)
+ {
+ canvas->remove_value_node(value_node);
+ goto again;
+ }
+ }
+
+ return canvas;
+ }
+ }
+ catch(Exception::BadLinkName) { synfig::error("BadLinkName Thrown"); }
+ catch(Exception::BadType) { synfig::error("BadType Thrown"); }
+ catch(Exception::FileNotFound) { synfig::error("FileNotFound Thrown"); }
+ catch(Exception::IDNotFound) { synfig::error("IDNotFound Thrown"); }
+ catch(Exception::IDAlreadyExists) { synfig::error("IDAlreadyExists Thrown"); }
+ catch(const std::exception& ex)
+ {
+ synfig::error("Standard Exception: "+String(ex.what()));
+ return Canvas::Handle();
+ }
+ catch(const String& str)
+ {
+ cerr<<str<<endl;
+ // synfig::error(str);
+ return Canvas::Handle();
+ }
+ return Canvas::Handle();
+}
+
+Canvas::Handle
+CanvasParser::parse_from_string(const String &data)
+{
+ CHECK_EXPIRE_TIME();
+
+ try
+ {
+ ChangeLocale change_locale(LC_NUMERIC, "C");
+ filename=_("<INTERNAL>");
+ total_warnings_=0;
+ xmlpp::DomParser parser;
+ parser.parse_memory(data);
+ xmlpp::Element *root=parser.get_document()->get_root_node();
+ if(parser)
+ {
+ Canvas::Handle canvas(parse_canvas(root));
+ canvas->signal_deleted().connect(sigc::bind(sigc::ptr_fun(_remove_from_open_canvas_map),canvas.get()));
+ canvas->signal_file_name_changed().connect(sigc::bind(sigc::ptr_fun(_canvas_file_name_changed),canvas.get()));
+
+ const ValueNodeList& value_node_list(canvas->value_node_list());
+ again:
+ ValueNodeList::const_iterator iter;
+ for(iter=value_node_list.begin();iter!=value_node_list.end();++iter)
+ {
+ ValueNode::Handle value_node(*iter);
+ if(value_node->is_exported() && value_node->get_id().find("Unnamed")==0)
+ {
+ canvas->remove_value_node(value_node);
+ goto again;
+ }
+ }
+
+ return canvas;
+ }
+ }
+ catch(Exception::BadLinkName) { synfig::error("BadLinkName Thrown"); }
+ catch(Exception::BadType) { synfig::error("BadType Thrown"); }
+ catch(Exception::FileNotFound) { synfig::error("FileNotFound Thrown"); }
+ catch(Exception::IDNotFound) { synfig::error("IDNotFound Thrown"); }
+ catch(Exception::IDAlreadyExists) { synfig::error("IDAlreadyExists Thrown"); }
+ catch(const std::exception& ex)
+ {
+ synfig::error("Standard Exception: "+String(ex.what()));
+ return Canvas::Handle();
+ }
+ catch(const String& str)
+ {
+ cerr<<str<<endl;
+ // synfig::error(str);
+ return Canvas::Handle();
+ }
+ return Canvas::Handle();
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file loadcanvas.h
+** \brief writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_LOADCANVAS_H
+#define __SYNFIG_LOADCANVAS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "string.h"
+#include "canvas.h"
+#include "valuenode.h"
+#include "vector.h"
+#include "value.h"
+#include "valuenode_subtract.h"
+#include "valuenode_animated.h"
+#include "valuenode_composite.h"
+#include "valuenode_dynamiclist.h"
+#include "keyframe.h"
+#include "guid.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace xmlpp { class Node; class Element; };
+
+namespace synfig {
+
+/*! \class CanvasParser
+** \todo writeme
+*/
+class CanvasParser
+{
+ /*
+ -- ** -- D A T A -------------------------------------------------------------
+ */
+
+private:
+
+ int max_warnings_;
+
+ int total_warnings_;
+
+ int total_errors_;
+
+ bool allow_errors_;
+
+ String filename;
+
+ String path;
+
+ GUID guid_;
+
+ /*
+ -- ** -- C O N S T R U C T O R S ---------------------------------------------
+ */
+
+public:
+
+ CanvasParser():
+ max_warnings_ (1000),
+ total_warnings_ (0),
+ total_errors_ (0),
+ allow_errors_ (false)
+ { }
+
+ /*
+ -- ** -- M E M B E R F U N C T I O N S -------------------------------------
+ */
+
+public:
+
+ //! \todo writeme
+ CanvasParser &set_allow_errors(bool x) { allow_errors_=x; return *this; }
+
+ //! Sets the maximum number of warnings before a fatal error is thrown
+ CanvasParser &set_max_warnings(int i) { max_warnings_=i; return *this; }
+
+ //! Returns the maximum number of warnings before a fatal_error is thrown
+ int get_max_warnings() { return max_warnings_; }
+
+ //! Returns the number of errors in the last parse
+ int error_count()const { return total_errors_; }
+
+ //! Returns the number of warnings in the last parse
+ int warning_count()const { return total_warnings_; }
+
+ void set_path(const synfig::String& x) { path=x; }
+
+ const synfig::String& get_path()const { return path; }
+
+ //! \todo writeme
+ Canvas::Handle parse_from_file(const String &filename);
+
+ Canvas::Handle parse_from_file_as(const String &filename,const String &as);
+
+ //! \todo writeme
+ Canvas::Handle parse_from_string(const String &data);
+
+private:
+
+ // Error/Warning handling functions
+
+ void error(xmlpp::Node *node,const String &text);
+ void fatal_error(xmlpp::Node *node,const String &text);
+ void warning(xmlpp::Node *node,const String &text);
+ void error_unexpected_element(xmlpp::Node *node,const String &got, const String &expected);
+ void error_unexpected_element(xmlpp::Node *node,const String &got);
+
+ // Parsing Functions
+
+ Canvas::Handle parse_canvas(xmlpp::Element *node,Canvas::Handle parent=0,bool inline_=false, String path=".");
+ void parse_canvas_defs(xmlpp::Element *node,Canvas::Handle canvas);
+ etl::handle<Layer> parse_layer(xmlpp::Element *node,Canvas::Handle canvas);
+ ValueBase parse_value(xmlpp::Element *node,Canvas::Handle canvas);
+ etl::handle<ValueNode> parse_value_node(xmlpp::Element *node,Canvas::Handle canvas);
+
+ // ValueBase Parsing Functions
+
+ Real parse_real(xmlpp::Element *node);
+ Time parse_time(xmlpp::Element *node,Canvas::Handle canvas);
+ int parse_integer(xmlpp::Element *node);
+ Vector parse_vector(xmlpp::Element *node);
+ Color parse_color(xmlpp::Element *node);
+ Angle parse_angle(xmlpp::Element *node);
+ String parse_string(xmlpp::Element *node);
+ bool parse_bool(xmlpp::Element *node);
+ Segment parse_segment(xmlpp::Element *node);
+ ValueBase parse_list(xmlpp::Element *node,Canvas::Handle canvas);
+ Gradient parse_gradient(xmlpp::Element *node);
+ BLinePoint parse_bline_point(xmlpp::Element *node);
+
+ Keyframe parse_keyframe(xmlpp::Element *node,Canvas::Handle canvas);
+
+ // ValueNode Parsing Functions
+
+ etl::handle<ValueNode_Animated> parse_animated(xmlpp::Element *node,Canvas::Handle canvas);
+ etl::handle<ValueNode_Subtract> parse_subtract(xmlpp::Element *node,Canvas::Handle canvas);
+ etl::handle<LinkableValueNode> parse_linkable_value_node(xmlpp::Element *node,Canvas::Handle canvas);
+ etl::handle<ValueNode_Composite> parse_composite(xmlpp::Element *node,Canvas::Handle canvas);
+ etl::handle<ValueNode_DynamicList> parse_dynamic_list(xmlpp::Element *node,Canvas::Handle canvas);
+
+}; // END of CanvasParser
+
+/* === E X T E R N S ======================================================= */
+
+//! Loads a canvas from \a filename
+/*! \return The Canvas's handle on success, an empty handle on failure */
+extern Canvas::Handle open_canvas(const String &filename);
+extern Canvas::Handle open_canvas_as(const String &filename,const String &as);
+
+//! Retrieves a Canvas from a string in XML format
+extern Canvas::Handle string_to_canvas(const String &data);
+
+std::map<synfig::String, etl::loose_handle<Canvas> >& get_open_canvas_map();
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file synfig/main.cpp
+** \brief \writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+//#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <iostream>
+#include "version.h"
+#include "general.h"
+#include "module.h"
+#include <cstdlib>
+#include <ltdl.h>
+#include <stdexcept>
+#include "target.h"
+#include <ETL/stringf>
+#include "listimporter.h"
+#include "color.h"
+#include "vector.h"
+#include <fstream>
+#include "layer.h"
+#include "valuenode.h"
+
+#include "main.h"
+#include "loadcanvas.h"
+
+#include "guid.h"
+
+#include "mutex.h"
+
+#ifdef DEATH_TIME
+#include <time.h>
+#endif
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+#define MODULE_LIST_FILENAME "synfig_modules.cfg"
+
+/* === S T A T I C S ======================================================= */
+
+static etl::reference_counter synfig_ref_count_(0);
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+
+
+
+
+
+
+
+const char *
+synfig::get_version()
+{
+#ifdef VERSION
+ return VERSION;
+#else
+ return "Unknown";
+#endif
+}
+
+const char *
+synfig::get_build_date()
+{
+ return __DATE__;
+}
+
+const char *
+synfig::get_build_time()
+{
+ return __TIME__;
+}
+
+extern const char *get_build_time();
+
+bool
+synfig::check_version_(int version,int vec_size, int color_size,int canvas_size,int layer_size)
+{
+ bool ret=true;
+
+ CHECK_EXPIRE_TIME();
+
+ if(version!=SYNFIG_LIBRARY_VERSION)
+ {
+ synfig::error(_("API Version mismatch (LIB:%d, PROG:%d)"),SYNFIG_LIBRARY_VERSION,version);
+ ret=false;
+ }
+ if(vec_size!=sizeof(Vector))
+ {
+ synfig::error(_("Size of Vector mismatch (app:%d, lib:%d)"),vec_size,sizeof(Vector));
+ ret=false;
+ }
+ if(color_size!=sizeof(Color))
+ {
+ synfig::error(_("Size of Color mismatch (app:%d, lib:%d)"),color_size,sizeof(Color));
+ ret=false;
+ }
+ if(canvas_size!=sizeof(Canvas))
+ {
+ synfig::error(_("Size of Canvas mismatch (app:%d, lib:%d)"),canvas_size,sizeof(Canvas));
+ ret=false;
+ }
+ if(layer_size!=sizeof(Layer))
+ {
+ synfig::error(_("Size of Layer mismatch (app:%d, lib:%d)"),layer_size,sizeof(Layer));
+ ret=false;
+ }
+
+ return ret;
+}
+
+static void broken_pipe_signal (int /*sig*/) {
+ synfig::warning("Broken Pipe...");
+}
+
+bool retrieve_modules_to_load(String filename,std::list<String> &modules_to_load)
+{
+ if(filename=="standard")
+ {
+ return false;
+/*
+ if(find(modules_to_load.begin(),modules_to_load.end(),"trgt_bmp")==modules_to_load.end())
+ modules_to_load.push_back("trgt_bmp");
+ if(find(modules_to_load.begin(),modules_to_load.end(),"trgt_gif")==modules_to_load.end())
+ modules_to_load.push_back("trgt_gif");
+ if(find(modules_to_load.begin(),modules_to_load.end(),"trgt_dv")==modules_to_load.end())
+ modules_to_load.push_back("trgt_dv");
+ if(find(modules_to_load.begin(),modules_to_load.end(),"mod_ffmpeg")==modules_to_load.end())
+ modules_to_load.push_back("mod_ffmpeg");
+ if(find(modules_to_load.begin(),modules_to_load.end(),"mod_imagemagick")==modules_to_load.end())
+ modules_to_load.push_back("mod_imagemagick");
+ if(find(modules_to_load.begin(),modules_to_load.end(),"lyr_std")==modules_to_load.end())
+ modules_to_load.push_back("lyr_std");
+ if(find(modules_to_load.begin(),modules_to_load.end(),"lyr_freetype")==modules_to_load.end())
+ modules_to_load.push_back("lyr_freetype");
+#ifdef HAVE_LIBPNG
+ if(find(modules_to_load.begin(),modules_to_load.end(),"trgt_png")==modules_to_load.end())
+ modules_to_load.push_back("trgt_png");
+#endif
+#ifdef HAVE_OPENEXR
+ if(find(modules_to_load.begin(),modules_to_load.end(),"mod_openexr")==modules_to_load.end())
+ modules_to_load.push_back("mod_openexr");
+#endif
+*/
+ }
+ else
+ {
+ std::ifstream file(filename.c_str());
+ if(!file)
+ {
+ // warning("Cannot open "+filename);
+ return false;
+ }
+ while(file)
+ {
+ String modulename;
+ getline(file,modulename);
+ if(!modulename.empty() && find(modules_to_load.begin(),modules_to_load.end(),modulename)==modules_to_load.end())
+ modules_to_load.push_back(modulename);
+ }
+ }
+
+
+
+ return true;
+}
+
+
+
+
+
+synfig::Main::Main(const synfig::String& basepath,ProgressCallback *cb):
+ ref_count_(synfig_ref_count_)
+{
+ if(ref_count_.count())
+ return;
+
+ synfig_ref_count_.reset();
+ ref_count_=synfig_ref_count_;
+
+ // Add initialization after this point
+
+
+ CHECK_EXPIRE_TIME();
+
+ String prefix=basepath+"/..";
+ unsigned int i;
+#ifdef _DEBUG
+ std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+#endif
+
+#if defined(HAVE_SIGNAL_H) && defined(SIGPIPE)
+ signal(SIGPIPE, broken_pipe_signal);
+#endif
+
+ //_config_search_path=new vector"string.h"();
+
+ // Init the subsystems
+ if(cb)cb->amount_complete(0, 100);
+ if(cb)cb->task(_("Starting Subsystem \"Modules\""));
+ if(!Module::subsys_init(prefix))
+ throw std::runtime_error(_("Unable to initialize subsystem \"Module\""));
+
+ if(cb)cb->task(_("Starting Subsystem \"Layers\""));
+ if(!Layer::subsys_init())
+ {
+ Module::subsys_stop();
+ throw std::runtime_error(_("Unable to initialize subsystem \"Layers\""));
+ }
+
+ if(cb)cb->task(_("Starting Subsystem \"Targets\""));
+ if(!Target::subsys_init())
+ {
+ Layer::subsys_stop();
+ Module::subsys_stop();
+ throw std::runtime_error(_("Unable to initialize subsystem \"Targets\""));
+ }
+
+ if(cb)cb->task(_("Starting Subsystem \"Importers\""));
+ if(!Importer::subsys_init())
+ {
+ Target::subsys_stop();
+ Layer::subsys_stop();
+ Module::subsys_stop();
+ throw std::runtime_error(_("Unable to initialize subsystem \"Importers\""));
+ }
+
+ if(cb)cb->task(_("Starting Subsystem \"ValueNodes\""));
+ if(!ValueNode::subsys_init())
+ {
+ Importer::subsys_stop();
+ Target::subsys_stop();
+ Layer::subsys_stop();
+ Module::subsys_stop();
+ throw std::runtime_error(_("Unable to initialize subsystem \"ValueNodes\""));
+ }
+
+ // Load up the list importer
+ Importer::book()[String("lst")]=ListImporter::create;
+
+
+
+ // Load up the modules
+ std::list<String> modules_to_load;
+ std::vector<String> locations;
+
+ if(!getenv("SYNFIG_MODULE_LIST"))
+ {
+ locations.push_back("standard");
+ locations.push_back("./"MODULE_LIST_FILENAME); //1
+ locations.push_back("../etc/"MODULE_LIST_FILENAME); //1
+ locations.push_back("~/.synfig/"MODULE_LIST_FILENAME); //2
+ locations.push_back(prefix+"/etc/"+MODULE_LIST_FILENAME); //3
+ locations.push_back("/usr/local/etc/"MODULE_LIST_FILENAME);
+ #ifdef SYSCONFDIR
+ locations.push_back(SYSCONFDIR"/"MODULE_LIST_FILENAME);
+ #endif
+ #ifdef __APPLE__
+ locations.push_back("/Library/Frameworks/synfig.framework/Resources/"MODULE_LIST_FILENAME);
+ locations.push_back("/Library/Synfig/"MODULE_LIST_FILENAME);
+ locations.push_back("~/Library/Synfig/"MODULE_LIST_FILENAME);
+ #endif
+ #ifdef WIN32
+ locations.push_back("C:\\Program Files\\Synfig\\etc\\"MODULE_LIST_FILENAME);
+ #endif
+ }
+ else
+ {
+ locations.push_back(getenv("SYNFIG_MODULE_LIST"));
+ }
+/*
+ const char *locations[]=
+ {
+ "standard", //0
+ "./"MODULE_LIST_FILENAME, //1
+ "../etc/"MODULE_LIST_FILENAME, //1
+ "~/.synfig/"MODULE_LIST_FILENAME, //2
+ "/usr/local/lib/synfig/modules/"MODULE_LIST_FILENAME, //3
+ "/usr/local/etc/"MODULE_LIST_FILENAME,
+#ifdef SYSCONFDIR
+ SYSCONFDIR"/"MODULE_LIST_FILENAME,
+#endif
+#ifdef __APPLE__
+ "/Library/Frameworks/synfig.framework/Resources/"MODULE_LIST_FILENAME,
+ "/Library/SYNFIG/"MODULE_LIST_FILENAME,
+ "~/Library/SYNFIG/"MODULE_LIST_FILENAME,
+#endif
+#ifdef WIN32
+ "C:\\Program Files\\SYNFIG\\etc\\"MODULE_LIST_FILENAME,
+#endif
+ };
+*/
+
+ for(i=0;i<locations.size();i++)
+ if(retrieve_modules_to_load(locations[i],modules_to_load))
+ if(cb)cb->task(strprintf(_("Loading modules from %s"),locations[i].c_str()));
+
+ std::list<String>::iterator iter;
+
+ for(i=0,iter=modules_to_load.begin();iter!=modules_to_load.end();++iter,i++)
+ {
+ Module::Register(*iter,cb);
+ if(cb)cb->amount_complete((i+1)*100,modules_to_load.size()*100);
+ }
+
+// load_modules(cb);
+
+ CHECK_EXPIRE_TIME();
+
+
+ if(cb)cb->amount_complete(100, 100);
+ if(cb)cb->task(_("DONE"));
+}
+
+synfig::Main::~Main()
+{
+ ref_count_.detach();
+ if(!synfig_ref_count_.unique())
+ return;
+ synfig_ref_count_.detach();
+
+ // Add deinitialization after this point
+
+ if(get_open_canvas_map().size())
+ {
+ synfig::warning("Canvases still open!");
+ std::map<synfig::String, etl::loose_handle<Canvas> >::iterator iter;
+ for(iter=get_open_canvas_map().begin();iter!=get_open_canvas_map().end();++iter)
+ {
+ synfig::warning("%s: count()=%d",iter->first.c_str(), iter->second.count());
+ }
+ }
+
+ synfig::info("ValueNode::subsys_stop()");
+ ValueNode::subsys_stop();
+ synfig::info("Importer::subsys_stop()");
+ Importer::subsys_stop();
+ synfig::info("Target::subsys_stop()");
+ Target::subsys_stop();
+ synfig::info("Layer::subsys_stop()");
+ Layer::subsys_stop();
+ /*! \fixme For some reason, uncommenting the next line will cause things to crash.
+ This needs to be looked into at some point. */
+ // synfig::info("Module::subsys_stop()");
+ // Module::subsys_stop();
+ synfig::info("Exiting");
+
+#if defined(HAVE_SIGNAL_H) && defined(SIGPIPE)
+ signal(SIGPIPE, SIG_DFL);
+#endif
+}
+
+void
+synfig::error(const char *format,...)
+{
+ va_list args;
+ va_start(args,format);
+ error(vstrprintf(format,args));
+}
+
+void
+synfig::error(const String &str)
+{
+ static Mutex mutex; Mutex::Lock lock(mutex);
+ cerr<<"synfig("<<getpid()<<"): "<<_("error")<<": "+str<<endl;
+}
+
+void
+synfig::warning(const char *format,...)
+{
+ va_list args;
+ va_start(args,format);
+ warning(vstrprintf(format,args));
+}
+
+void
+synfig::warning(const String &str)
+{
+ static Mutex mutex; Mutex::Lock lock(mutex);
+ cerr<<"synfig("<<getpid()<<"): "<<_("warning")<<": "+str<<endl;
+}
+
+void
+synfig::info(const char *format,...)
+{
+ va_list args;
+ va_start(args,format);
+ info(vstrprintf(format,args));
+}
+
+void
+synfig::info(const String &str)
+{
+ static Mutex mutex; Mutex::Lock lock(mutex);
+ cerr<<"synfig("<<getpid()<<"): "<<_("info")<<": "+str<<endl;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file synfig/main.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_MAIN_H
+#define __SYNFIG_MAIN_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/ref_count>
+#include "general.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class synfig::Main
+** \brief \writeme
+**
+** \writeme
+*/
+class Main
+{
+ etl::reference_counter ref_count_;
+public:
+ Main(const synfig::String& basepath,ProgressCallback *cb=0);
+ ~Main();
+
+ static void load_modules(ProgressCallback *cb=0);
+
+ const etl::reference_counter& ref_count()const { return ref_count_; }
+}; // END of class Main
+
+}; // END if namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file synfig/module.cpp
+** \brief writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "module.h"
+#include "general.h"
+#include <ETL/stringf>
+
+#ifndef USE_CF_BUNDLES
+#include <ltdl.h>
+#endif
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+Module::Book *synfig::Module::book_;
+
+/* === P R O C E D U R E S ================================================= */
+
+bool
+Module::subsys_init(const String &prefix)
+{
+#ifndef USE_CF_BUNDLES
+ #ifndef SYNFIG_LTDL_NO_STATIC
+ //LTDL_SET_PRELOADED_SYMBOLS();
+ #endif
+
+ if(lt_dlinit())
+ {
+ error(_("Errors on lt_dlinit()"));
+ error(lt_dlerror());
+ return false;
+ }
+
+ lt_dladdsearchdir(".");
+ lt_dladdsearchdir("~/.synfig/modules");
+ lt_dladdsearchdir((prefix+"/lib/synfig/modules").c_str());
+#ifdef LIBDIR
+ lt_dladdsearchdir(LIBDIR"/synfig/modules");
+#endif
+#ifdef __APPLE__
+ lt_dladdsearchdir("/Library/Frameworks/synfig.framework/Resources/modules");
+#endif
+ lt_dladdsearchdir("/usr/local/lib/synfig/modules");
+ lt_dladdsearchdir(".");
+#endif
+ book_=new Book;
+ return true;
+}
+
+bool
+Module::subsys_stop()
+{
+ delete book_;
+
+#ifndef USE_CF_BUNDLES
+ lt_dlexit();
+#endif
+ return true;
+}
+
+bool
+register_default_modules()
+{
+ return true;
+}
+
+Module::Book&
+Module::book()
+{
+ return *book_;
+}
+
+void
+synfig::Module::Register(Module::Handle mod)
+{
+ book()[mod->Name()]=mod;
+}
+
+bool
+synfig::Module::Register(const String &module_name, ProgressCallback *callback)
+{
+#ifndef USE_CF_BUNDLES
+ lt_dlhandle module;
+
+ if(callback)callback->task(strprintf(_("Attempting to register \"%s\""),module_name.c_str()));
+
+ module=lt_dlopenext((string("lib")+module_name).c_str());
+ if(!module)module=lt_dlopenext(module_name.c_str());
+
+ if(!module)
+ {
+ if(callback)callback->warning(strprintf(_("Unable to find module \"%s\" (%s)"),module_name.c_str(),lt_dlerror()));
+ return false;
+ }
+
+ if(callback)callback->task(strprintf(_("Found module \"%s\""),module_name.c_str()));
+
+ Module::constructor_type constructor=NULL;
+ Handle mod;
+
+ if(!constructor)
+ {
+// if(callback)callback->task(string("looking for -> ")+module_name+"_LTX_new_instance()");
+ constructor=(Module::constructor_type )lt_dlsym(module,(module_name+"_LTX_new_instance").c_str());
+ }
+
+ if(!constructor)
+ {
+// if(callback)callback->task(string("looking for -> lib")+module_name+"_LTX_new_instance()");
+ constructor=(Module::constructor_type )lt_dlsym(module,(string("lib")+module_name+"_LTX_new_instance").c_str());
+ }
+ if(!constructor)
+ {
+// if(callback)callback->task(string("looking for -> lib")+module_name+"_LTX_new_instance()");
+ constructor=(Module::constructor_type )lt_dlsym(module,(string("_lib")+module_name+"_LTX_new_instance").c_str());
+ }
+ if(!constructor)
+ {
+// if(callback)callback->task(string("looking for -> lib")+module_name+"_LTX_new_instance()");
+ constructor=(Module::constructor_type )lt_dlsym(module,(string("_")+module_name+"_LTX_new_instance").c_str());
+ }
+
+ if(constructor)
+ {
+// if(callback)callback->task(strprintf("Executing callback for \"%s\"",module_name.c_str()));
+ mod=handle<Module>((*constructor)(callback));
+ }
+ else
+ {
+ if(callback)callback->error(strprintf(_("Unable to find entrypoint in module \"%s\" (%s)"),module_name.c_str(),lt_dlerror()));
+ return false;
+ }
+
+// if(callback)callback->task(strprintf("Done executing callback for \"%s\"",module_name.c_str()));
+
+ if(mod)
+ {
+// if(callback)callback->task(strprintf("Registering \"%s\"",module_name.c_str()));
+ Register(mod);
+ }
+ else
+ {
+ if(callback)callback->error(_("Entrypoint did not return a module."));
+ return false;
+ }
+
+ if(callback)callback->task(strprintf(_("Success for \"%s\""),module_name.c_str()));
+
+#endif
+ return false;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file synfig/module.h
+** \brief writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_MODULE_H
+#define __SYNFIG_MODULE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "general.h"
+#include <ETL/handle>
+#include <map>
+#include "string.h"
+#include <utility>
+#include "vector.h"
+#include "color.h"
+#include "layer.h"
+#include "canvas.h"
+
+//#include "value.h"
+
+/* === M A C R O S ========================================================= */
+
+//! Marks the start of a module description
+#define MODULE_DESC_BEGIN(x) struct x##_modclass : public synfig::Module { x##_modclass(synfig::ProgressCallback *callback=NULL);
+
+//! Sets the localized name of the module
+#define MODULE_NAME(x) virtual const char * Name() { return x; }
+
+//! Sets a localized description of the module
+#define MODULE_DESCRIPTION(x) virtual const char * Desc() { return x; }
+
+//! Sets the name of the module's author
+#define MODULE_AUTHOR(x) virtual const char * Author() { return x; }
+
+//! Sets the version string for the module
+#define MODULE_VERSION(x) virtual const char * Version() { return x; }
+
+//! Sets the copyright string for the module
+#define MODULE_COPYRIGHT(x) virtual const char * Copyright() { return x; }
+
+//! Describes the module's construction function
+#define MODULE_CONSTRUCTOR(x) bool constructor_(synfig::ProgressCallback *cb) { return x(cb); }
+
+//! Describes the module's destruction function
+#define MODULE_DESTRUCTOR(x) virtual void destructor_() { return x(); }
+
+//! Marks the end of a module description
+#define MODULE_DESC_END };
+
+//#if 0
+#ifdef __APPLE__
+//! Marks the start of a module's inventory
+#define MODULE_INVENTORY_BEGIN(x) extern "C" { \
+ synfig::Module* _##x##_LTX_new_instance(synfig::ProgressCallback *cb) \
+ { if(SYNFIG_CHECK_VERSION()){x##_modclass *mod=new x##_modclass(cb); mod->constructor_(cb); return mod; }\
+ if(cb)cb->error(#x": Unable to load module due to version mismatch."); return NULL; } \
+ }; x##_modclass::x##_modclass(synfig::ProgressCallback */*cb*/) {
+#else
+//! Marks the start of a module's inventory
+#define MODULE_INVENTORY_BEGIN(x) extern "C" { \
+ synfig::Module* x##_LTX_new_instance(synfig::ProgressCallback *cb) \
+ { if(SYNFIG_CHECK_VERSION()){x##_modclass *mod=new x##_modclass(cb); mod->constructor_(cb); return mod; }\
+ if(cb)cb->error(#x": Unable to load module due to version mismatch."); return NULL; } \
+ }; x##_modclass::x##_modclass(synfig::ProgressCallback */*cb*/) {
+#endif
+
+//! Marks the start of the layers in the module's inventory
+#define BEGIN_LAYERS {
+
+//! DEPRECATED - use @INCLUDE_LAYER()
+//#define LAYER(x) synfig::Layer::book()[synfig::String(x::name__)]=x::create;
+#define LAYER(class) synfig::Layer::register_in_book(synfig::Layer::BookEntry(class::create,class::name__,class::local_name__,class::category__,class::cvs_id__,class::version__));
+#define LAYER_ALIAS(class,alias) synfig::Layer::register_in_book(synfig::Layer::BookEntry(class::create,alias,alias,_("Do Not Use"),class::cvs_id__,class::version__));
+
+//! Marks the end of the layers in the module's inventory
+#define END_LAYERS }
+
+//! Marks the start of the targets in the module's inventory
+#define BEGIN_TARGETS {
+
+#define TARGET(x) synfig::Target::book()[synfig::String(x::name__)]=std::pair<synfig::Target::Factory,synfig::String>(x::create,synfig::String(x::ext__));synfig::Target::ext_book()[synfig::String(x::ext__)]=x::name__;
+
+#define TARGET_EXT(x,y) synfig::Target::ext_book()[synfig::String(y)]=x::name__;
+
+//! Marks the end of the targets in the module's inventory
+#define END_TARGETS }
+
+//! Marks the start of the importers in the module's inventory
+#define BEGIN_IMPORTERS {
+
+#define IMPORTER(x) synfig::Importer::book()[synfig::String(x::ext__)]=x::create;
+
+#define IMPORTER_EXT(x,y) synfig::Importer::book()[synfig::String(y)]=x::create;
+
+//! Marks the end of the importers in the module's inventory
+#define END_IMPORTERS }
+
+//! Marks the end of a module's inventory
+#define MODULE_INVENTORY_END }
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ProgressCallback;
+
+/*! \class Module
+** \todo writeme
+*/
+class Module : public etl::shared_object
+{
+public:
+ bool constructor_(synfig::ProgressCallback */*cb*/) { return true; }
+ virtual void destructor_() { }
+
+ typedef etl::handle<Module> Handle;
+ typedef etl::loose_handle<Module> LooseHandle;
+ typedef etl::handle<const Module> ConstHandle;
+
+public:
+ typedef Module*(*constructor_type)(ProgressCallback *);
+ typedef std::map<String, Handle > Book;
+private:
+ static Book* book_;
+public:
+ static Book& book();
+
+ static bool subsys_init(const String &prefix);
+ static bool subsys_stop();
+ static bool register_default_modules();
+
+ static void Register(Handle mod);
+ static bool Register(const String &module_name, ProgressCallback *cb=NULL);
+ static inline void Register(Module *mod) { Register(Handle(mod)); }
+
+ virtual const char * Name() { return " "; }
+ virtual const char * Desc() { return " "; }
+ virtual const char * Author() { return " "; }
+ virtual const char * Version() { return " "; }
+ virtual const char * Copyright() { return SYNFIG_COPYRIGHT; }
+
+ virtual ~Module() { destructor_(); }
+};
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mutex.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "mutex.h"
+
+#ifdef HAVE_LIBPTHREAD
+#define USING_PTHREADS 1
+#else
+#ifdef _WIN32
+#define USING_WIN32_THREADS 1
+#endif
+#endif
+
+#ifdef USING_WIN32_THREADS
+#include <windows.h>
+#endif
+
+#ifdef USING_PTHREADS
+#include <pthread.h>
+#endif
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+//using namespace std;
+//using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+
+
+
+
+
+bool
+Mutex::is_locked()
+{
+ if(try_lock())
+ {
+ unlock();
+ return false;
+ }
+ return true;
+}
+
+void
+RecMutex::unlock_all()
+{
+ while(is_locked()) unlock();
+}
+
+#ifdef USING_PTHREADS
+Mutex::Mutex()
+{
+ pthread_mutex_t*const mtx_ptr(new pthread_mutex_t);
+
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+
+ //#ifdef PTHREAD_PRIO_INHERIT
+ //pthread_mutexattr_setprioceiling(&attr,PTHREAD_PRIO_INHERIT);
+ //#endif
+
+ //#ifdef PTHREAD_MUTEX_RECURSIVE
+ //pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
+ //#endif
+
+ pthread_mutex_init(mtx_ptr,&attr);
+ pthread_mutexattr_destroy(&attr);
+
+ blackbox=mtx_ptr;
+}
+
+Mutex::~Mutex()
+{
+ pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
+ pthread_mutex_destroy(mtx_ptr);
+ delete mtx_ptr;
+}
+
+void
+Mutex::lock()
+{
+ pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
+ pthread_mutex_lock(mtx_ptr);
+}
+
+void
+Mutex::unlock()
+{
+ pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
+ pthread_mutex_unlock(mtx_ptr);
+}
+
+bool
+Mutex::try_lock()
+{
+ pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
+ return !(bool) pthread_mutex_trylock(mtx_ptr);
+}
+
+
+RecMutex::RecMutex()
+{
+ pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
+ pthread_mutexattr_t attr;
+
+ // Backtrack and get rid of the non-recursive mutex
+ pthread_mutex_destroy(mtx_ptr);
+
+ pthread_mutexattr_init(&attr);
+
+ pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
+
+ pthread_mutex_init(mtx_ptr,&attr);
+ pthread_mutexattr_destroy(&attr);
+}
+
+
+
+RWLock::RWLock()
+{
+ pthread_rwlock_t*const rwlock_ptr(new pthread_rwlock_t);
+
+ pthread_rwlock_init(rwlock_ptr, NULL);
+
+ blackbox=rwlock_ptr;
+}
+
+RWLock::~RWLock()
+{
+ pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
+
+ pthread_rwlock_destroy(rwlock_ptr);
+
+ delete rwlock_ptr;
+}
+
+void
+RWLock::reader_lock()
+{
+ pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
+
+ pthread_rwlock_rdlock(rwlock_ptr);
+}
+
+void
+RWLock::reader_unlock()
+{
+ pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
+
+ pthread_rwlock_unlock(rwlock_ptr);
+}
+
+bool
+RWLock::reader_trylock()
+{
+ pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
+
+ return !pthread_rwlock_tryrdlock(rwlock_ptr);
+}
+
+void
+RWLock::writer_lock()
+{
+ pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
+
+ pthread_rwlock_wrlock(rwlock_ptr);
+}
+
+void
+RWLock::writer_unlock()
+{
+ pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
+
+ pthread_rwlock_unlock(rwlock_ptr);
+}
+
+bool
+RWLock::writer_trylock()
+{
+ pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
+
+ return !pthread_rwlock_trywrlock(rwlock_ptr);
+}
+
+#endif
+
+#ifdef USING_WIN32_THREADS
+Mutex::Mutex()
+{
+ HANDLE& mtx(*reinterpret_cast<HANDLE*>(&blackbox));
+ mtx=CreateMutex(NULL, FALSE, NULL);
+}
+
+Mutex::~Mutex()
+{
+ HANDLE mtx(reinterpret_cast<HANDLE>(blackbox));
+ CloseHandle(mtx);
+}
+
+void
+Mutex::lock()
+{
+ HANDLE mtx(reinterpret_cast<HANDLE>(blackbox));
+ WaitForSingleObject(mtx, INFINITE);
+}
+
+void
+Mutex::unlock()
+{
+ HANDLE mtx(reinterpret_cast<HANDLE>(blackbox));
+ ReleaseMutex(mtx);
+}
+
+bool
+Mutex::try_lock()
+{
+ HANDLE mtx(reinterpret_cast<HANDLE>(blackbox));
+ return WaitForSingleObject(mtx, 0)==WAIT_FAILED;
+}
+
+
+RecMutex::RecMutex()
+{
+ // Win32 mutexes are recursive by default.
+}
+
+
+RWLock::RWLock()
+{
+}
+
+RWLock::~RWLock()
+{
+}
+
+void
+RWLock::reader_lock()
+{
+}
+
+void
+RWLock::reader_unlock()
+{
+}
+
+bool
+RWLock::reader_trylock()
+{
+}
+
+void
+RWLock::writer_lock()
+{
+}
+
+void
+RWLock::writer_unlock()
+{
+}
+
+bool
+RWLock::writer_trylock()
+{
+}
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file mutex.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_MUTEX_H
+#define __SYNFIG_MUTEX_H
+
+/* === H E A D E R S ======================================================= */
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class RecMutex;
+
+class Mutex
+{
+ friend class RecMutex;
+
+protected:
+ void* blackbox;
+
+public:
+
+ class Lock
+ {
+ Mutex& mutex;
+ public:
+ Lock(Mutex& x):mutex(x) { mutex.lock(); }
+ ~Lock() { mutex.unlock(); }
+ };
+
+ Mutex();
+ ~Mutex();
+
+ void lock();
+ void unlock();
+ bool try_lock();
+ bool is_locked();
+
+private:
+ //! Non-copyable
+ Mutex(const Mutex&);
+
+ //! Non-assignable
+ void operator=(const Mutex&);
+};
+
+class RecMutex : public Mutex
+{
+public:
+ RecMutex();
+
+ void unlock_all();
+};
+
+class RWLock
+{
+ void* blackbox;
+
+public:
+
+ class ReaderLock
+ {
+ RWLock& rw_lock;
+ public:
+ ReaderLock(RWLock& x):rw_lock(x) { rw_lock.reader_lock(); }
+ ~ReaderLock() { rw_lock.reader_unlock(); }
+ };
+ class WriterLock
+ {
+ RWLock& rw_lock;
+ public:
+ WriterLock(RWLock& x):rw_lock(x) { rw_lock.writer_lock(); }
+ ~WriterLock() { rw_lock.writer_unlock(); }
+ };
+
+ RWLock();
+ ~RWLock();
+
+ void reader_lock();
+ void reader_unlock();
+ bool reader_trylock();
+
+ void writer_lock();
+ void writer_unlock();
+ bool writer_trylock();
+};
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file node.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define HASH_MAP_H <ext/hash_map>
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "node.h"
+#include "proto/nodebase.h"
+
+#ifdef HASH_MAP_H
+#include HASH_MAP_H
+using namespace __gnu_cxx;
+#else
+#include <map>
+#endif
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+// About BE_FRUGAL_WITH_GUIDS
+// If this macro is set, then a GUID will NOT
+// be calculated until the first call to get_guid()
+// This also means that the node doesn't get
+// added to the database until get_guid() is called
+// for the first time, or set_guid() is called.
+// If it is expensive to calculate GUIDs, then
+// this can improve performance a tad in
+// some cases. Otherwise, it doesn't change
+// much of anything.
+#define BE_FRUGAL_WITH_GUIDS 1
+
+#ifndef __sys_clock
+#ifndef _WIN32
+# include <time.h>
+# define __sys_clock ::clock
+#else
+# ifdef __GNUG__
+# include <time.h>
+# define __sys_clock ::clock
+# else
+typedef int clock_t;
+extern clock_t _clock();
+# define CLOCKS_PER_SEC 1000
+# define __sys_clock _clock
+# endif
+#endif
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+#ifdef HASH_MAP_H
+typedef hash_map<GUID,Node*,GUIDHash> GlobalNodeMap;
+#else
+typedef map<GUID,Node*> GlobalNodeMap;
+#endif
+
+static GlobalNodeMap* global_node_map_;
+
+static GlobalNodeMap& global_node_map()
+{
+ if(!global_node_map_)
+ global_node_map_=new GlobalNodeMap;
+ return *global_node_map_;
+}
+
+/* === P R O C E D U R E S ================================================= */
+
+synfig::Node*
+synfig::find_node(const GUID& guid)
+{
+ if(global_node_map().count(guid)==0)
+ return 0;
+ return global_node_map()[guid];
+}
+
+static void
+refresh_node(synfig::Node* node, GUID old_guid)
+{
+ assert(global_node_map().count(old_guid));
+ global_node_map().erase(old_guid);
+ assert(!global_node_map().count(old_guid));
+ global_node_map()[node->get_guid()]=node;
+}
+
+/* === M E T H O D S ======================================================= */
+
+void
+TimePoint::absorb(const TimePoint& x)
+{
+ if(get_guid()==x.get_guid())
+ return;
+ set_guid(get_guid()^x.get_guid());
+
+ if(get_after()==INTERPOLATION_NIL)
+ set_after(x.get_after());
+ if(get_before()==INTERPOLATION_NIL)
+ set_before(x.get_before());
+
+ if(get_after()!=x.get_after() && x.get_after()!=INTERPOLATION_NIL)
+ set_after(INTERPOLATION_UNDEFINED);
+ if(get_before()!=x.get_before() && x.get_before()!=INTERPOLATION_NIL)
+ set_before(INTERPOLATION_UNDEFINED);
+}
+
+TimePointSet::iterator
+TimePointSet::insert(const TimePoint& x)
+{
+ iterator iter(find(x));
+ if(iter!=end())
+ {
+ const_cast<TimePoint&>(*iter).absorb(x);
+ return iter;
+ }
+ return std::set<TimePoint>::insert(x).first;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Node::Node():
+ guid_(0),
+ bchanged(true),
+ deleting_(false)
+{
+#ifndef BE_FRUGAL_WITH_GUIDS
+ guid_.make_unique();
+ assert(guid_);
+ assert(!global_node_map().count(guid_));
+ global_node_map()[guid_]=this;
+#endif
+}
+
+Node::~Node()
+{
+ begin_delete();
+
+ if(guid_)
+ {
+ assert(global_node_map().count(guid_));
+ global_node_map().erase(guid_);
+ assert(!global_node_map().count(guid_));
+ }
+}
+
+void
+Node::changed()
+{
+ time_last_changed_=__sys_clock();
+ on_changed();
+}
+
+
+//! Gets the GUID for this value node
+const GUID&
+Node::get_guid()const
+{
+#ifdef BE_FRUGAL_WITH_GUIDS
+ if(!guid_)
+ {
+ const_cast<GUID&>(guid_).make_unique();
+ assert(guid_);
+ assert(!global_node_map().count(guid_));
+ global_node_map()[guid_]=const_cast<Node*>(this);
+ }
+#endif
+
+ return guid_;
+}
+
+//! Sets the GUID for this value node
+void
+Node::set_guid(const GUID& x)
+{
+ assert(x);
+
+#ifdef BE_FRUGAL_WITH_GUIDS
+ if(!guid_)
+ {
+ guid_=x;
+ assert(!global_node_map().count(guid_));
+ global_node_map()[guid_]=this;
+ }
+ else
+#endif
+ if(guid_!=x)
+ {
+ GUID oldguid(guid_);
+ guid_=x;
+ refresh_node(this, oldguid);
+ on_guid_changed(oldguid);
+ }
+}
+
+int
+Node::get_time_last_changed()const
+{
+ return time_last_changed_;
+}
+
+void
+Node::add_child(Node*x)
+{
+ x->parent_set.insert(this);
+}
+
+void
+Node::remove_child(Node*x)
+{
+ if(x->parent_set.count(this)) x->parent_set.erase(this);
+}
+
+int
+Node::parent_count()const
+{
+ return parent_set.size();
+}
+
+const Node::time_set &
+Node::get_times() const
+{
+ if(bchanged)
+ {
+ times.clear();
+ get_times_vfunc(times);
+ bchanged = false;
+ }
+
+ //set the output set...
+ return times;
+}
+
+void
+Node::begin_delete()
+{
+ if(!deleting_)
+ {
+ deleting_=true; signal_deleted()();
+ }
+}
+
+void
+Node::on_changed()
+{
+ bchanged = true;
+ signal_changed()();
+
+ std::set<Node*>::iterator iter;
+ for(iter=parent_set.begin();iter!=parent_set.end();++iter)
+ {
+ (*iter)->changed();
+ }
+}
+
+void
+Node::on_guid_changed(GUID guid)
+{
+ signal_guid_changed()(guid);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file node.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_PARENTNODE_H
+#define __SYNFIG_PARENTNODE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sigc++/signal.h>
+#include <set>
+#include "time.h"
+#include "guid.h"
+#include <ETL/handle>
+#include "interpolation.h"
+#include "mutex.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class TimePoint
+{
+ GUID guid;
+ Time time;
+ Interpolation before,after;
+public:
+
+ TimePoint(const Time& x=Time::begin()):
+ guid(0),
+ time(x),
+ before(INTERPOLATION_NIL),
+ after(INTERPOLATION_NIL)
+ {
+ }
+
+ const GUID& get_guid()const { return guid; }
+ const Time& get_time()const { return time; }
+ Interpolation get_before()const { return before; }
+ Interpolation get_after()const { return after; }
+
+ void set_guid(const GUID& x) { guid=x; }
+ void set_time(const Time& x) { time=x; }
+ void set_before(Interpolation x) { before=x; }
+ void set_after(Interpolation x) { after=x; }
+
+ void absorb(const TimePoint& x);
+}; // END of class TimePoint
+
+inline TimePoint operator+(TimePoint lhs,const Time& rhs)
+ { lhs.set_time(lhs.get_time()+rhs); return lhs; }
+
+inline bool operator<(const TimePoint& lhs,const TimePoint& rhs)
+ { return lhs.get_time()<rhs.get_time(); }
+
+inline bool operator<(const TimePoint& lhs,const Time& rhs)
+ { return lhs.get_time()<rhs; }
+
+inline bool operator<(const Time& lhs,const TimePoint& rhs)
+ { return lhs<rhs.get_time(); }
+
+inline bool operator==(const TimePoint& lhs,const TimePoint& rhs)
+ { return lhs.get_time()==rhs.get_time(); }
+
+inline bool operator!=(const TimePoint& lhs,const TimePoint& rhs)
+ { return lhs.get_time()!=rhs.get_time(); }
+
+class TimePointSet : public std::set<TimePoint>
+{
+public:
+ iterator insert(const TimePoint& x);
+
+ template <typename ITER> void insert(ITER begin, ITER end)
+ { for(;begin!=end;++begin) insert(*begin); }
+
+}; // END of class TimePointSet
+
+class Node : public etl::rshared_object
+{
+ /*
+ -- ** -- T Y P E S -----------------------------------------------------------
+ */
+
+public:
+
+ //! \writeme
+ typedef TimePointSet time_set;
+
+ /*
+ -- ** -- D A T A -------------------------------------------------------------
+ */
+
+private:
+
+ //! \writeme
+ GUID guid_;
+
+ //! cached time values for all the childrens
+ mutable time_set times;
+
+ //! \writeme
+ mutable bool bchanged;
+
+ //! \writeme
+ mutable int time_last_changed_;
+
+ //! \writeme
+ mutable RWLock rw_lock_;
+
+ //! \writeme
+ bool deleting_;
+
+public:
+
+ //! \todo This should really be private
+ std::set<Node*> parent_set;
+
+ /*
+ -- ** -- S I G N A L S -------------------------------------------------------
+ */
+
+private:
+
+ sigc::signal<void> signal_changed_;
+
+ //! GUID Changed
+ /*! \note The second parameter is the *OLD* guid! */
+ sigc::signal<void,GUID> signal_guid_changed_;
+
+ //! Deleted
+ sigc::signal<void> signal_deleted_;
+
+ /*
+ -- ** -- S I G N A L I N T E R F A C E -------------------------------------
+ */
+
+public:
+
+ sigc::signal<void>& signal_deleted() { return signal_deleted_; }
+
+ sigc::signal<void>& signal_changed() { return signal_changed_; }
+
+ //! GUID Changed
+ /*! \note The second parameter is the *OLD* guid! */
+ sigc::signal<void,GUID>& signal_guid_changed() { return signal_guid_changed_; }
+
+ /*
+ -- ** -- C O N S T R U C T O R S ---------------------------------------------
+ */
+
+protected:
+
+ Node();
+
+ // This class cannot be copied -- use clone() if necessary
+private:
+ Node(const Node &x);
+
+public:
+ virtual ~Node();
+
+ /*
+ -- ** -- M E M B E R F U N C T I O N S -------------------------------------
+ */
+
+public:
+
+ void changed();
+
+ //! Gets the GUID for this value node
+ const GUID& get_guid()const;
+
+ //! Sets the GUID for this value node
+ void set_guid(const GUID& x);
+
+ int get_time_last_changed()const;
+
+ void add_child(Node*x);
+
+ void remove_child(Node*x);
+
+ int parent_count()const;
+
+ const time_set &get_times() const;
+
+ RWLock& get_rw_lock()const { return rw_lock_; }
+
+protected:
+
+ void begin_delete();
+
+ /*
+ -- ** -- V I R T U A L F U N C T I O N S -----------------------------------
+ */
+
+protected:
+ virtual void on_changed();
+
+ virtual void on_guid_changed(GUID guid);
+
+ /*! Function to be overloaded that fills
+ */
+ virtual void get_times_vfunc(time_set &set) const = 0;
+};
+
+synfig::Node* find_node(const synfig::GUID& guid);
+
+template<typename T> etl::handle<T>
+guid_cast(const synfig::GUID& guid)
+{
+ return etl::handle<T>::cast_dynamic(synfig::find_node(guid));
+}
+
+typedef etl::handle<Node> NodeHandle;
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file palette.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "palette.h"
+#include "surface.h"
+#include "general.h"
+#include <fstream>
+#include <iostream>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+#define PALETTE_FILE_COOKIE "SYNFIGPAL1.0"
+
+/* === G L O B A L S ======================================================= */
+
+bool weight_less_than(const PaletteItem& lhs,const PaletteItem& rhs)
+{
+ return lhs.weight<rhs.weight;
+}
+
+bool luma_less_than(const PaletteItem& lhs,const PaletteItem& rhs)
+{
+ return lhs.color.get_y()<rhs.color.get_y();
+}
+
+bool luma_less_than(const PaletteItem& lhs,const float& rhs)
+{
+ return lhs.color.get_y()<rhs;
+}
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Palette::Palette():
+ name_(_("Unnamed"))
+{
+}
+
+Palette::Palette(const String& name_):
+ name_(name_)
+{
+}
+
+void
+PaletteItem::add(const Color& x,int xweight)
+{
+ color=(color*weight+x*xweight)/(weight+xweight);
+ weight+=xweight;
+}
+
+Palette::Palette(const Surface& surface, int max_colors):
+ name_(_("Surface Palette"))
+{
+ max_colors-=2;
+ for(int i=0;(signed)size()<(max_colors-1) && i<max_colors*16;++i) {
+ int x=rand()%surface.get_w();
+ int y=rand()%surface.get_h();
+
+ float dist;
+ Color color(surface[y][x]);
+
+ if(empty())
+ {
+ push_back(color);
+ continue;
+ }
+
+ if(color.get_a()==0)
+ {
+ if(front().color.get_a()!=0)
+ insert(begin(),Color(1,0,1,0));
+ front().weight+=400;
+ continue;
+ }
+
+ iterator iter(find_closest(color,&dist));
+ if(sqrt(dist)<0.005)
+ {
+ iter->add(color);
+ continue;
+ }
+
+ /*if(size()>=max_colors)
+ {
+ iterator iterlight(find_light());
+ PaletteItem light(*iterlight);
+ erase(iterlight);
+ find_closest(light.color)->add(light.color,light.weight);
+ }
+ */
+
+ push_back(color);
+ continue;
+ }
+
+/*
+
+ max_colors-=2;
+ for(int y=0;y<surface.get_h();y++)
+ for(int x=0;x<surface.get_w();x++)
+ {
+ float dist;
+ Color color(surface[y][x]);
+
+ if(empty())
+ {
+ push_back(color);
+ continue;
+ }
+
+ if(color.get_a()==0)
+ {
+ if(front().color.get_a()!=0)
+ insert(begin(),Color(1,0,1,0));
+ front().weight+=400;
+ continue;
+ }
+
+ iterator iter(find_closest(color,&dist));
+ if(sqrt(dist)<0.005)
+ {
+ iter->add(color);
+ continue;
+ }
+
+
+ push_back(color);
+ continue;
+ }
+ sort(rbegin(),rend());
+
+ iterator iter;
+
+ iterator best_match(begin());
+ while((signed)size()>max_colors)
+ {
+ PaletteItem item(back());
+ pop_back();
+ find_closest(item.color)->add(item.color,item.weight);
+ }
+*/
+ push_back(Color::black());
+ push_back(Color::white());
+
+// sort(begin(),end(),&luma_less_than);
+}
+
+Palette::const_iterator
+Palette::find_closest(const Color& color, float* dist)const
+{
+ // For the sake of avoiding cut-and-paste
+ // bugs, we'll just use the non-const
+ // find_closest()... It doesn't change anything
+ // anyway.
+ return const_cast<Palette*>(this)->find_closest(color,dist);
+}
+
+Palette::iterator
+Palette::find_closest(const Color& color, float* dist)
+{
+ iterator iter;
+
+ iterator best_match(begin());
+ float best_dist(1000000);
+
+ const float prep_y(powf(color.get_y(),2.2f)*color.get_a());
+ const float prep_u(color.get_u());
+ const float prep_v(color.get_v());
+
+ for(iter=begin();iter!=end();++iter)
+ {
+ const float diff_y(prep_y-powf(iter->color.get_y(),2.2f)*iter->color.get_a());
+ const float diff_u(prep_u-iter->color.get_u());
+ const float diff_v(prep_v-iter->color.get_v());
+ const float diff_a(color.get_a()-iter->color.get_a());
+
+
+ const float dist(
+ diff_y*diff_y*1.5f+
+ diff_a*diff_a+
+
+ diff_u*diff_u+
+ diff_v*diff_v
+
+ // cross product
+ /*abs(
+ prep_u*iter->color.get_u()-
+ prep_v*iter->color.get_v()
+ )*/
+ );
+ if(dist<best_dist)
+ {
+ best_dist=dist;
+ best_match=iter;
+ }
+ }
+ if(dist)
+ *dist=best_dist;
+
+ return best_match;
+}
+
+
+Palette::iterator
+Palette::find_heavy()
+{
+ iterator iter;
+
+ iterator best_match(begin());
+
+ for(iter=begin();iter!=end();++iter)
+ {
+ if(iter->weight>best_match->weight)
+ best_match=iter;
+ }
+
+ return best_match;
+}
+
+Palette::iterator
+Palette::find_light()
+{
+ iterator iter;
+
+ iterator best_match(begin());
+
+ for(iter=begin();iter!=end();++iter)
+ {
+ if(iter->weight<best_match->weight)
+ best_match=iter;
+ }
+
+ return best_match;
+}
+
+Palette
+Palette::grayscale(int steps)
+{
+ Palette ret;
+ for(int i=0;i<steps;i++)
+ {
+ float amount(i/(steps-1));
+ float y(powf(amount,2.2f));
+ ret.push_back(
+ PaletteItem(
+ Color(y,y,y),
+ strprintf(_("%0.2f%% Gray"),amount)
+ )
+ );
+ }
+ return ret;
+}
+
+void
+Palette::save_to_file(const synfig::String& filename)const
+{
+ const_iterator iter;
+
+ std::ofstream file(filename.c_str());
+
+ if(!file)
+ throw strprintf(_("Unable to open %s for write"),filename.c_str());
+
+ file<<PALETTE_FILE_COOKIE<<endl;
+ file<<name_<<endl;
+ for(iter=begin();iter!=end();++iter)
+ {
+ file<<iter->name<<endl;
+ file
+ <<iter->color.get_r()<<endl
+ <<iter->color.get_g()<<endl
+ <<iter->color.get_b()<<endl
+ <<iter->color.get_a()<<endl;
+
+ }
+}
+
+Palette
+Palette::load_from_file(const synfig::String& filename)
+{
+ std::ifstream file(filename.c_str());
+
+ if(!file)
+ throw strprintf(_("Unable to open %s for read"),filename.c_str());
+
+ Palette ret;
+ String line;
+
+ getline(file,line);
+
+ if(line!=PALETTE_FILE_COOKIE)
+ throw strprintf(_("%s does not appear to be a palette file"),filename.c_str());
+
+ getline(file,ret.name_);
+
+ while(!file.eof())
+ {
+ PaletteItem item;
+ getline(file,item.name);
+ if(!file.eof())break;
+
+ getline(file,line);
+ if(!file.eof())break;
+ item.color.set_r(atof(line.c_str()));
+
+ getline(file,line);
+ if(!file.eof())break;
+ item.color.set_g(atof(line.c_str()));
+
+ getline(file,line);
+ if(!file.eof())break;
+ item.color.set_b(atof(line.c_str()));
+
+ getline(file,line);
+ if(!file.eof())break;
+ item.color.set_a(atof(line.c_str()));
+
+ ret.push_back(item);
+ }
+
+ return ret;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file palette.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_PALETTE_H
+#define __SYNFIG_PALETTE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "color.h"
+#include "string.h"
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Surface;
+
+struct PaletteItem
+{
+ Color color;
+ String name;
+ int weight;
+
+ PaletteItem():weight(1) { }
+
+ PaletteItem(const Color& color, const String& name, int weight=1):
+ color(color),name(name),weight(weight) { }
+
+ PaletteItem(const Color& color, int weight=1):
+ color(color),weight(weight) { }
+
+ void add(const Color& x, int weight=1);
+
+ bool operator<(const PaletteItem& rhs)const { return weight<rhs.weight; }
+}; // END of struct PaletteItem
+
+class Palette : public std::vector<PaletteItem>
+{
+ String name_;
+
+public:
+ Palette();
+ Palette(const String& name_);
+
+ /*! Generates a palette for the given
+ ** surface
+ */
+ Palette(const Surface& surface, int size=256);
+
+ iterator find_closest(const Color& color, float* dist=0);
+ const_iterator find_closest(const Color& color, float* dist=0)const;
+
+ iterator find_heavy();
+
+ iterator find_light();
+
+ static Palette grayscale(int steps=16);
+
+ void save_to_file(const synfig::String& filename)const;
+
+ static Palette load_from_file(const synfig::String& filename);
+}; // END of class Palette
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file paramdesc.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "paramdesc.h"
+#include "value.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ParamDesc::ParamDesc(synfig::Color::BlendMethod, const String &a):
+ name_ (a),
+ local_name_ (a),
+ scalar_ (1.0),
+ critical_ (true),
+ hidden_ (false),
+ invisible_duck_ (false),
+ is_distance_ (false),
+ animation_only_ (false)
+{
+ set_local_name(_("Blend Method"))
+ .set_hint("enum")
+ .add_enum_value(Color::BLEND_COMPOSITE,"composite",_("Composite"))
+ .add_enum_value(Color::BLEND_STRAIGHT,"straight",_("Straight"))
+ .add_enum_value(Color::BLEND_ONTO,"onto",_("Onto"))
+ .add_enum_value(Color::BLEND_STRAIGHT_ONTO,"straightonto",_("StraightOnto"))
+ .add_enum_value(Color::BLEND_BEHIND,"behind",_("Behind"))
+ .add_enum_value(Color::BLEND_SCREEN,"screen",_("Screen"))
+ .add_enum_value(Color::BLEND_OVERLAY,"overlay",_("Overlay"))
+ .add_enum_value(Color::BLEND_HARD_LIGHT,"hard_light",_("Hard Light"))
+ .add_enum_value(Color::BLEND_MULTIPLY,"multiply",_("Multiply"))
+ .add_enum_value(Color::BLEND_DIVIDE,"divide",_("Divide"))
+ .add_enum_value(Color::BLEND_ADD,"add",_("Add"))
+ .add_enum_value(Color::BLEND_SUBTRACT,"subtract",_("Subtract"))
+ .add_enum_value(Color::BLEND_DIFFERENCE,"difference",_("Difference"))
+ .add_enum_value(Color::BLEND_BRIGHTEN,"brighten",_("Brighten"))
+ .add_enum_value(Color::BLEND_DARKEN,"darken",_("Darken"))
+ .add_enum_value(Color::BLEND_COLOR,"color",_("Color"))
+ .add_enum_value(Color::BLEND_HUE,"hue",_("Hue"))
+ .add_enum_value(Color::BLEND_SATURATION,"saturation",_("Saturation"))
+ .add_enum_value(Color::BLEND_LUMINANCE,"luminance",_("Luminance"))
+// These are deprecated
+ .add_enum_value(Color::BLEND_ALPHA_OVER,"alphaover",_("Alpha Over"))
+// .add_enum_value(Color::BLEND_ALPHA_BRIGHTEN,"alphabrighten",_("Alpha Brighten"))
+// .add_enum_value(Color::BLEND_ALPHA_DARKEN,"alphadarken",_("Alpha Darken"))
+ ; // end of enums
+}
+
+ParamDesc::ParamDesc(const ValueBase&, const String &a):
+ name_ (a),
+ local_name_ (a),
+ scalar_ (1.0),
+ critical_ (true),
+ hidden_ (false),
+ invisible_duck_ (false),
+ is_distance_ (false),
+ animation_only_ (false)
+{
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file paramdesc.h
+** \brief ParamDesc Class Implementation
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_PARAMDESC_H
+#define __SYNFIG_PARAMDESC_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "string.h"
+#include "real.h"
+#include "color.h"
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueBase;
+
+/*! \class ParamDesc
+** \brief Parameter Description Class
+** \todo writeme
+*/
+class ParamDesc
+{
+public:
+
+ //! \writeme
+ struct EnumData
+ {
+ int value;
+ String name;
+ String local_name;
+ EnumData(int value, const String &name, const String &local_name):
+ value(value),
+ name(name),
+ local_name(local_name)
+ {
+ }
+ };
+
+ /*
+ -- ** -- D A T A -------------------------------------------------------------
+ */
+
+private:
+ String name_; //! The actual parameter name
+ String local_name_; //! Localized name
+ String desc_; //! Short description of parameter (Think tooltops)
+ String group_; //! Which group this parameter is a member of (optional)
+ String hint_; //! Parameter hint
+ String origin_; //! Parameter origin
+ String connect_;
+ String box_;
+ Real scalar_; //! Scalar value for visual editing
+ bool critical_;
+ bool hidden_;
+ bool invisible_duck_;
+ bool is_distance_;
+ bool animation_only_;
+
+ std::list<EnumData> enum_list_;
+
+ /*
+ -- ** -- C O N S T R U C T O R S ---------------------------------------------
+ */
+
+public:
+
+ ParamDesc(const String &a="IM_A_BUG_SO_REPORT_ME"):
+ name_ (a),
+ local_name_ (a),
+ scalar_ (1.0),
+ critical_ (true),
+ hidden_ (false),
+ invisible_duck_ (false),
+ is_distance_ (false),
+ animation_only_ (false)
+ { }
+
+ ParamDesc(const ValueBase&, const String &a);
+
+ ParamDesc(synfig::Color::BlendMethod, const String &a);
+
+
+ /*
+ -- ** -- M E M B E R F U N C T I O N S -------------------------------------
+ */
+
+public:
+
+ //! \writeme
+ const std::list<EnumData> &get_enum_list()const { return enum_list_; }
+
+ //! Sets the localized name of the parameter.
+ ParamDesc &set_local_name(const String &n) { local_name_=n; return *this; }
+
+ //! Sets the localized description of the parameter.
+ ParamDesc &set_description(const String &d) { desc_=d; return *this; }
+
+ //! Sets the group that this parameter is a member of
+ ParamDesc &set_group(const String &n) { group_=n; return *this; }
+
+ //! Sets a "hint" for the parameter.
+ ParamDesc &set_hint(const String &h) { hint_=h; return *this; }
+
+ //! \writeme
+ ParamDesc &set_connect(const String &h) { connect_=h; return *this; }
+
+ //! \writeme
+ ParamDesc &set_box(const String &h) { box_=h; return *this; }
+
+ //! Sets a flag regarding the duck visibility
+ ParamDesc &set_invisible_duck(bool x=true) { invisible_duck_=x; return *this; }
+
+ //! Returns the flag regarding duck visibility
+ bool get_invisible_duck() { return invisible_duck_; }
+
+
+ //! \writeme
+ ParamDesc &set_animation_only(bool x=true) { animation_only_=x; return *this; }
+
+ //! \writeme
+ bool get_animation_only() { return animation_only_; }
+
+
+ //! Sets which parameter is to be used as the origin when the user edits visually.
+ ParamDesc &set_origin(const String &h) { origin_=h; return *this; }
+
+ //! Sets the scalar value for the parameter
+ /*! This value determines how the value is to be presented
+ ** to the user when editing visually. */
+ ParamDesc &set_scalar(const Real &n) { scalar_=n; return *this; }
+ ParamDesc &set_scalar(const String &h) { hint_=h; return *this; }
+
+ //! Marks the parameter as not necessary for saving or copying
+ ParamDesc ¬_critical() { critical_=false; return *this; }
+
+ //! \writeme
+ ParamDesc &hidden() { hidden_=true; return *this; }
+
+ //! Marks the parameter as only readable. Implies not_critical()
+ /*! \todo This function needs to be written, as it is only a stub */
+ ParamDesc &read_only() { return *this; }
+
+ //! Marks the parameter as only writable. Implies not_critical()
+ /*! \todo This function needs to be written, as it is only a stub */
+ ParamDesc &write_only() { return *this; }
+
+ //! Adds a description of a possible enumeration value
+ /*! Only relevant if the parameter is of an integer type and hint set to \c "enum" . */
+ ParamDesc &add_enum_value(int val, const String &enum_name,const String &enum_local_name)
+ { enum_list_.push_back(EnumData(val,enum_name,enum_local_name)); return *this; }
+
+ //! Returns the localized name of the parameter
+ const String &get_local_name()const { return local_name_; }
+
+ //! Returns the name of the parameter
+ const String &get_name()const { return name_; }
+
+ //! Returns the localized description of the parameter
+ const String &get_description()const { return desc_; }
+
+ //! Returns the paramater's group
+ const String &get_group()const { return group_; }
+
+ //! Returns a "hint" about the parameter, regarding how it is to be displayed to the user
+ const String &get_hint()const { return hint_; }
+
+ //! Returns the name of the parameter that is defined as the "origin". Used for visual editing.
+ const String &get_origin()const { return origin_; }
+
+ //! \writeme
+ const String &get_connect()const { return connect_; }
+
+ //! \writeme
+ const String &get_box()const { return box_; }
+
+ //! Returns the scalar value for the parameter. Used for visual editing.
+ const Real &get_scalar()const { return scalar_; }
+
+ //! Returns \c true if the layer is critical, \c false otherwise.
+ bool get_critical()const { return critical_; }
+
+ //! Returns \c true if the layer is hidden, \c false otherwise.
+ bool get_hidden()const { return hidden_; }
+
+
+
+ ParamDesc& set_is_distance(bool x=true) { is_distance_=x; return *this;}
+ bool get_is_distance()const { return is_distance_; }
+}; // END of class ParamDesc
+
+class ParamVocab : public std::list< ParamDesc >
+{
+};
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file pch.h
+** \brief Pre-Compiled Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_PCH_H
+#define __SYNFIG_PCH_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <iostream>
+#include "synfig.h"
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file polynomial_root.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "polynomial_root.h"
+#include <complex>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+//using namespace etl;
+//using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+typedef complex<float> Complex;
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+#define EPSS 1.0e-7
+#define MR 8
+#define MT 10
+#define MAXIT (MT*MR)
+
+/*EPSS is the estimated fractional roundoff error. We try to break (rare) limit
+cycles with MR different fractional values, once every MT steps, for MAXIT total allowed iterations.
+*/
+
+/* Explanation:
+
+ A polynomial can be represented like so:
+ Pn(x) = (x - x1)(x - x2)...(x - xn) where xi = complex roots
+
+ We can get the following:
+ ln|Pn(x)| = ln|x - x1| + ln|x - x2| + ... + ln|x - xn|
+
+ G := d ln|Pn(x)| / dx =
+ +1/(x-x1) + 1/(x-x2) + ... + 1/(x-xn)
+
+ and
+
+ H := - d2 ln|Pn(x)| / d2x =
+ +1/(x-x1)^2 + 1/(x-x2)^2 + ... + 1/(x-xn)^2
+
+ which gives
+ H = [Pn'/Pn]^2 - Pn''/Pn
+
+ Laguerre's formula guesses that the root we are seeking x1 is located
+ some distance a from our current guess x, and all the other roots are
+ located at distance b.
+
+ Using this:
+
+ 1/a + (n-1)/b = G
+
+ and
+
+ 1/a^2 + (n-1)/b^2 = H
+
+ which yields this solution for a:
+
+ a = n / G +- sqrt( (n-1)(nH - G^2) )
+
+ where +- is determined by which ever yields the largest magnitude for the denominator.
+ a can easily be complex since the factor inside the square-root can be negative.
+
+ This method iterates (x=x-a) until a is sufficiently small.
+*/
+
+/* Given the degree m and the m+1 complex coefficients a[0..m] of the polynomial sum(i=0,m){a[i]x^i},
+and given a complex value x, this routine improves x by laguerre's method until it converges,
+within the achievable roundoff limit, to a root of the given polynomial. The number of iterations taken
+is returned as `its'.
+*/
+void laguer(Complex a[], int m, Complex *x, int *its)
+{
+ int iter,j;
+ float abx, abp, abm, err;
+ Complex dx,x1,b,d,f,g,h,sq,gp,gm,g2;
+
+ //Fractions used to break a limit cycle
+ static float frac[MR+1] = {0.0,0.5,0.25,0.75,0.13,0.38,0.62,0.88,1.0};
+
+ for(iter = 1; iter <= MAXIT; ++iter)
+ {
+ *its = iter; //number of iterations so far
+
+ b = a[m]; //the highest coefficient
+ err = abs(b); //its magnitude
+
+ d = f = Complex(0,0); //clear variables for use
+ abx = abs(*x); //the magnitude of the current root
+
+ //Efficent computation of the polynomial and its first 2 derivatives
+ for(j = m-1; j >= 0; --j)
+ {
+ f = (*x)*f + d;
+ d = (*x)*d + b;
+ b = (*x)*b + a[j];
+
+ err = abs(b) + abx*err;
+ }
+
+ //Estimate the roundoff error in evaluation polynomial
+ err *= EPSS;
+
+ //Are we on the root?
+ if(abs(b) < err)
+ {
+ return;
+ }
+
+ //General case: use Laguerre's formula
+ //a = n / G +- sqrt( (n-1)(nH - G^2) )
+ //x = x - a
+
+ g = d / b; //get G
+ g2 = g * g; //for the sqrt calc
+
+ h = g2 - 2.0f * (f / b); //get H
+
+ sq = pow( (float)(m-1) * ((float)m*h - g2), 0.5f ); //get the sqrt
+
+ //get the denominator
+ gp = g + sq;
+ gm = g - sq;
+
+ abp = abs(gp);
+ abm = abs(gm);
+
+ //get the denominator with the highest magnitude
+ if(abp < abm)
+ {
+ abp = abm;
+ gp = gm;
+ }
+
+ //if the denominator is positive do one thing, otherwise do the other
+ dx = (abp > 0.0) ? (float)m / gp : polar((1+abx),(float)iter);
+ x1 = *x - dx;
+
+ //Have we converged?
+ if( *x == x1 )
+ {
+ return;
+ }
+
+ //Every so often take a fractional step, to break any limit cycle (itself a rare occurrence).
+ if( iter % MT )
+ {
+ *x = x1;
+ }else
+ {
+ *x = *x - (frac[iter/MT]*dx);
+ }
+ }
+
+ //very unusual - can occur only for complex roots. Try a different starting guess for the root.
+ //nrerror("too many iterations in laguer");
+ return;
+}
+
+#define EPS 2.0e-6
+#define MAXM 100 //a small number, and maximum anticipated value of m..
+
+/* Given the degree m and the m+1 complex coefficients a[0..m] of the polynomial a0 + a1*x +...+ an*x^n
+ the routine successively calls laguer and finds all m complex roots in roots[1..m].
+ The boolean variable polish should be input as true (1) if polishing (also by Laguerre's Method)
+ is desired, false (0) if the roots will be subsequently polished by other means.
+*/
+void RootFinder::find_all_roots(bool polish)
+{
+ int i,its,j,jj;
+ Complex x,b,c;
+ int m = coefs.size()-1;
+
+ //make sure roots is big enough
+ roots.resize(m);
+
+ if(workcoefs.size() < MAXM) workcoefs.resize(MAXM);
+
+ //Copy the coefficients for successive deflation
+ for(j = 0; j <= m; ++j)
+ {
+ workcoefs[j] = coefs[j];
+ }
+
+ //Loop over each root to be found
+ for(j = m-1; j >= 0; --j)
+ {
+ //Start at 0 to favor convergence to smallest remaining root, and find the root
+ x = Complex(0,0);
+ laguer(&workcoefs[0],j+1,&x,&its); //must add 1 to get the degree
+
+ //if it is close enough to a real root, then make it so
+ if(abs(x.imag()) <= 2.0*EPS*abs(x.real()))
+ {
+ x = Complex(x.real());
+ }
+
+ roots[j] = x;
+
+ //forward deflation
+
+ //the degree is j+1 since j(0,m-1)
+ b = workcoefs[j+1];
+ for(jj = j; jj >= 0; --jj)
+ {
+ c = workcoefs[jj];
+ workcoefs[jj] = b;
+ b = x*b + c;
+ }
+ }
+
+ //Polish the roots using the undeflated coefficients
+ if(polish)
+ {
+ for(j = 0; j < m; ++j)
+ {
+ laguer(&coefs[0],m,&roots[j],&its);
+ }
+ }
+
+ //Sort roots by their real parts by straight insertion
+ for(j = 1; j < m; ++j)
+ {
+ x = roots[j];
+ for( i = j-1; i >= 1; --i)
+ {
+ if(roots[i].real() <= x.real()) break;
+ roots[i+1] = roots[i];
+ }
+ roots[i+1] = x;
+ }
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file polynomial_root.h
+** \brief Polynomial Root Finder Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_POLYNOMIAL_ROOT_H
+#define __SYNFIG_POLYNOMIAL_ROOT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <complex>
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+template < typename T = float, typename F = float >
+class Polynomial : public std::vector<T> //a0 + a1x + a2x^2 + ... + anx^n
+{
+public:
+
+ //Will maintain all lower constants
+ void degree(unsigned int d, const T & def = (T)0) { resize(d+1,def); }
+ unsigned int degree()const { return size() - 1; }
+
+ const Polynomial & operator+=(const Polynomial &p)
+ {
+ if(p.size() > size())
+ resize(p.size(), (T)0);
+
+ for(int i = 0; i < p.size(); ++i)
+ {
+ (*this)[i] += p[i];
+ }
+ return *this;
+ }
+
+ const Polynomial & operator-=(const Polynomial &p)
+ {
+ if(p.size() > size())
+ resize(p.size(), (T)0);
+
+ for(int i = 0; i < p.size(); ++i)
+ {
+ (*this)[i] -= p[i];
+ }
+ return *this;
+ }
+
+ const Polynomial & operator*=(const Polynomial &p)
+ {
+ if(p.size() < 1)
+ {
+ resize(0);
+ return *this;
+ }
+
+ unsigned int i,j;
+ std::vector<T> nc(*this);
+
+ //in place for constant stuff
+ for(i = 0; i < nc.size(); ++i)
+ {
+ (*this)[i] *= p[0];
+ }
+
+ if(p.size() < 2) return *this;
+
+ resize(size() + p.degree());
+ for(int i = 0; i < nc.size(); ++i)
+ {
+ for(int j = 1; j < p.size(); ++j)
+ {
+ nc[i+j] += nc[i]*p[j];
+ }
+ }
+
+ return *this;
+ }
+};
+
+class RootFinder
+{
+ std::vector< std::complex<float> > workcoefs;
+ int its;
+
+public:
+ std::vector< std::complex<float> > coefs; //the number of coefficients determines the degree of polynomial
+
+ std::vector< std::complex<float> > roots;
+
+ void find_all_roots(bool polish);
+};
+
+
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+
+M4=m4
+
+PROTO_PP=$(M4) proto.m4
+
+FILES=nodebase.h
+
+all: $(FILES)
+
+clean:
+ $(RM) $(FILES)
+
+SUFFIXES=.px .h
+
+.SUFFIXES: $(SUFFIXES)
+
+.px.h: proto.m4
+ $(PROTO_PP) $< > $@
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file nodebase.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_NODEBASE_H
+#define __SYNFIG_NODEBASE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "../protocol.h"
+#include "../string.h"
+#include "../guid.h"
+#include <sigc++/slot.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+namespace Proto {
+
+typedef int Query;
+typedef int NodeList;
+
+class NodeBase : public Protocol
+{
+public:
+
+ PX_DEFINE_DATA(guid, GUID)
+
+ PX_DEFINE_FUNC(func_test, float, int, int)
+
+ PX_DEFINE_DATA(id, String)
+
+ PX_DEFINE_DATA(root, NodeHandle)
+
+ PX_DEFINE_FUNC(signal_changed, sigc::signal<void>)
+ PX_DEFINE_FUNC(signal_deleted, sigc::signal<void>)
+
+ PX_DEFINE_FUNC_CONST(get_parents, const NodeList)
+ PX_DEFINE_FUNC_CONST(get_children, const NodeList)
+
+ PX_DEFINE_FUNC(query_children, NodeList, Query)
+
+}; // END of class Proto::NodeBase
+
+}; // END of namespace Proto
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+dnl
+
+ define(`forloop',
+ `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')')
+ define(`_forloop',
+ `$4`'ifelse($1, `$3', ,
+ `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')')
+
+define(`_PRINT_ARGS',`dnl
+ifelse($#,1,,`$2 v$1`'ifelse($#,2,,`, _PRINT_ARGS(incr($1), shift(shift($@)))')')dnl
+')dnl
+
+define(`_PRINT_ARGS2',`dnl
+ifelse($#,1,,`v$1`'ifelse($#,2,,`, _PRINT_ARGS2(incr($1), shift(shift($@)))')')dnl
+')dnl
+
+dnl PX_DEFINE_FUNC(func_name, ret_type, args...)
+define(`PX_DEFINE_FUNC',`
+ sigc::slot< $2`'ifelse($#,2,,`, shift(shift($@))') > _slot_$1;
+ $2 $1(ifelse($#,2,,`_PRINT_ARGS(1,shift(shift($@)))')) {
+ return _slot_$1(ifelse($#,2,,`_PRINT_ARGS2(1,shift(shift($@)))'));
+ }
+')dnl
+
+dnl PX_DEFINE_FUNC_CONST(func_name, ret_type, args...)
+define(`PX_DEFINE_FUNC_CONST',`
+ sigc::slot< $2`'ifelse($#,2,,`, shift(shift($@))') > _slot_$1_const;
+ $2 $1(ifelse($#,2,,`_PRINT_ARGS(1,shift(shift($@)))'))const {
+ return _slot_$1_const(ifelse($#,2,,`_PRINT_ARGS2(1,shift(shift($@)))'));
+ }
+')dnl
+
+define(`PX_DEFINE_DATA', `dnl
+PX_DEFINE_FUNC_CONST(get_$1, $2)
+PX_DEFINE_FUNC(set_$1, void, $2)
+')dnl
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file protocol.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_PROTOCOL_H
+#define __SYNFIG_PROTOCOL_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sigc++/signal.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*
+ * class Object
+{
+public:
+
+ sigc::signal_
+ bool find_protocol(Protocol& proto)
+ {
+
+ }
+};
+*/
+
+class Protocol
+{
+public:
+ class Type;
+
+}; // END of class Protocol
+
+class Protocol::Type
+{
+}; // END of class Protocol::Type
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file quick_rng.h
+** \brief Template Header
+**
+** $Id: guid.h 335 2007-03-16 00:39:09Z dooglus $
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_QUICK_RNG_H
+#define __SYNFIG_QUICK_RNG_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <stdint.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+// A fast 32-bit linear congruential random number generator
+class quick_rng
+{
+ uint32_t next;
+public:
+ quick_rng(uint32_t seed=0):next(seed) { }
+
+ void set_seed(uint32_t x)
+ {
+ next=x;
+ }
+
+ uint32_t i32()
+ {
+ static const uint32_t a(1664525);
+ static const uint32_t c(1013904223);
+
+ return next=next*a+c;
+ }
+
+ uint32_t i16()
+ {
+ return i32()>>16;
+ }
+
+ float f()
+ {
+ static const float m(int(65535));
+
+ return float(i16())/m;
+ }
+
+ uint32_t operator()(const uint32_t& m)
+ {
+ if(m==65536)
+ return i16();
+ else
+ if(m<=65536)
+ return i16()%m;
+ else
+ return i32()%m;
+ }
+};
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file real.h
+** \brief Provides the synfig::Real typedef
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_REAL_H
+#define __SYNFIG_REAL_H
+
+/* === T Y P E D E F S ===================================================== */
+
+namespace synfig {
+
+/*! \typedef Real
+** \todo writeme
+*/
+typedef double Real;
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file rect.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "rect.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Rect
+Rect::full_plane()
+{
+ const double infinity(HUGE_VAL);
+ return Rect(-infinity, -infinity, infinity, infinity);
+}
+
+Rect
+Rect::horizontal_strip(const value_type &y1, const value_type &y2)
+{
+ const double infinity(HUGE_VAL);
+ return Rect(-infinity, y1, infinity, y2);
+}
+
+Rect
+Rect::vertical_strip(const value_type &x1, const value_type &x2)
+{
+ int i, j;
+ const double infinity(HUGE_VAL);
+ return Rect(x1, -infinity, x2, infinity);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file rect.h
+** \brief Rectangle Class
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_RECT_H
+#define __SYNFIG_RECT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/rect>
+#include "real.h"
+#include "vector.h"
+#include <limits>
+#include <cmath>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Rect : public etl::rect<Real>
+{
+public:
+
+ using etl::rect<Real>::set_point;
+ using etl::rect<Real>::expand;
+ using etl::rect<Real>::set;
+
+ static Rect full_plane();
+
+ static Rect horizontal_strip(const value_type &y1, const value_type &y2);
+ static Rect vertical_strip(const value_type &x1, const value_type &x2);
+
+ static Rect zero()
+ {
+ return Rect(
+ 0,
+ 0,
+ 0,
+ 0
+ );
+ }
+
+ Rect() { }
+
+ Rect(const Point& x) { set_point(x); }
+
+ Rect(const Point& min, const Point& max) { set_point(min); expand(max); }
+
+ Rect(const value_type &x1,const value_type &y1) { set_point(x1,y1); }
+
+ Rect(const value_type &x1,const value_type &y1,
+ const value_type &x2,const value_type &y2)
+ {
+ set_point(x1,y1);
+ expand(x2,y2);
+ }
+
+ void set_point(const Point& max) { set_point(max[0],max[1]); }
+
+ Rect& expand(const Point& max) { expand(max[0],max[1]); return *this; }
+
+ Rect& expand(const Real& r) { minx-=r; miny-=r; maxx+=r; maxy+=r; return *this; }
+
+ Rect& expand_x(const Real& r) { minx-=r; maxx+=r; return *this; }
+
+ Rect& expand_y(const Real& r) { miny-=r; maxy+=r; return *this; }
+
+ Rect& set(const Point& min,const Point& max) { set(min[0],min[1],max[0],max[1]); return *this; }
+
+ Point get_min()const { return Point(minx,miny); }
+ Point get_max()const { return Point(maxx,maxy); }
+
+ bool is_inside(const Point& x) { return x[0]>minx && x[0]<maxx && x[1]>miny && x[1]<maxy; }
+
+ Real area()const
+ {
+ return (maxx-minx)*(maxy-miny);
+ }
+
+ // Operators
+
+ Rect& operator+=(const Vector& rhs)
+ {
+ minx+=rhs[0]; miny+=rhs[1];
+ maxx+=rhs[0]; maxy+=rhs[1];
+ return *this;
+ }
+
+ Rect& operator-=(const Vector& rhs)
+ {
+ minx-=rhs[0]; miny-=rhs[1];
+ maxx-=rhs[0]; maxy-=rhs[1];
+ return *this;
+ }
+
+ Rect& operator*=(const Real& rhs)
+ {
+ minx*=rhs; miny*=rhs;
+ maxx*=rhs; maxy*=rhs;
+ return *this;
+ }
+
+ Rect& operator/=(Real rhs)
+ {
+ rhs=1.0/rhs; // Avoid doing several divisions
+ minx*=rhs; miny*=rhs;
+ maxx*=rhs; maxy*=rhs;
+ return *this;
+ }
+
+ Rect& operator&=(const Rect& rhs)
+ {
+ if(rhs.area()>0.00000001 && area()>0.00000001)
+ etl::set_intersect(*this,*this,rhs);
+ else
+ *this=zero();
+ return *this;
+ }
+
+ Rect& operator|=(const Rect& rhs)
+ {
+ if(rhs.area()>0.00000001 && area()>0.00000001)
+ etl::set_union(*this,*this,rhs);
+ else
+ {
+ if(area()<rhs.area())
+ *this=rhs;
+ }
+ return *this;
+ }
+
+ Rect operator+(const Vector& rhs)const { return Rect(*this)+=rhs; }
+
+ Rect operator-(const Vector& rhs)const { return Rect(*this)-=rhs; }
+
+ Rect operator*(const Real& rhs)const { return Rect(*this)*=rhs; }
+
+ Rect operator/(const Real& rhs)const { return Rect(*this)/=rhs; }
+
+ Rect operator&(const Rect& rhs)const { return Rect(*this)&=rhs; }
+
+ Rect operator|(const Rect& rhs)const { return Rect(*this)|=rhs; }
+
+ bool operator&&(const Rect& rhs)const { return etl::intersect(*this, rhs); }
+
+ bool is_valid()const { return valid(); }
+}; // END of class Rect
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file synfig/renddesc.cpp
+** \brief RendDesc
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "renddesc.h"
+#include <ETL/misc>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+RendDesc &
+RendDesc::apply(const RendDesc &x)
+{
+ operator=(x);
+ return *this;
+}
+
+const Color &
+RendDesc::get_bg_color()const
+{
+ return background;
+}
+
+RendDesc &
+RendDesc::set_bg_color(const Color &bg)
+{
+ background=bg; return *this;
+}
+
+Real
+RendDesc::get_physical_w()const
+{
+ return (Real)get_w()/get_x_res();
+}
+
+Real
+RendDesc::get_physical_h()const
+{
+ return (Real)get_h()/get_y_res();
+}
+
+RendDesc&
+RendDesc::set_physical_w(Real w)
+{
+ set_w(round_to_int(w*get_x_res()));
+ return *this;
+}
+
+RendDesc&
+RendDesc::set_physical_h(Real h)
+{
+ set_h(round_to_int(h*get_y_res()));
+ return *this;
+}
+
+int
+RendDesc::get_w()const
+{
+ return w_;
+}
+
+RendDesc &
+RendDesc::set_w(int x)
+{
+ if(FLAGS(flags,LINK_PX_ASPECT))
+ {
+ h_=h_*x/w_;
+ w_=x;
+ }
+ else if(FLAGS(flags,LINK_PX_AREA))
+ {
+ //! \writeme
+ w_=x;
+ }
+ else if(FLAGS(flags,PX_ASPECT))
+ {
+ Vector d=br_-tl_;
+ float old_span=get_span();
+
+ // If we should preserve image width
+ if( FLAGS(flags,IM_W)
+ || (FLAGS(flags,IM_ZOOMIN) && d[1]>d[1]/x*w_)
+ || (FLAGS(flags,IM_ZOOMOUT) && d[1]<d[1]/x*w_))
+ {
+ br_[1]-=focus[1];
+ br_[1]=br_[1]/x*w_;
+ br_[1]+=focus[1];
+ tl_[1]-=focus[1];
+ tl_[1]=tl_[1]/x*w_;
+ tl_[1]+=focus[1];
+ } else
+ {
+ br_[0]-=focus[0];
+ br_[0]=br_[0]/w_*x;
+ br_[0]+=focus[0];
+ tl_[0]-=focus[0];
+ tl_[0]=tl_[0]/w_*x;
+ tl_[0]+=focus[0];
+ }
+
+ w_=x;
+
+ if(FLAGS(flags,IM_SPAN))
+ set_span(old_span);
+ }
+ else if(FLAGS(flags,PX_AREA))
+ {
+ //! \writeme
+ w_=x;
+ }
+ else
+ w_=x;
+
+ return *this;
+}
+
+int
+RendDesc::get_h()const
+{
+ return h_;
+}
+
+RendDesc &
+RendDesc::set_h(int y)
+{
+ if(FLAGS(flags,LINK_PX_ASPECT))
+ {
+ w_=w_*y/h_;
+ h_=y;
+ }
+ else if(FLAGS(flags,LINK_PX_AREA))
+ {
+ //! \writeme
+ h_=y;
+ }
+ else if(FLAGS(flags,PX_ASPECT))
+ {
+ Vector d=br_-tl_;
+ float old_span=get_span();
+
+ // If we should preserve image width
+ if( FLAGS(flags,IM_W)
+ || (FLAGS(flags,IM_ZOOMIN) && d[0]>d[0]/y*h_)
+ || (FLAGS(flags,IM_ZOOMOUT) && d[0]<d[0]/y*h_))
+ {
+ br_[0]-=focus[0];
+ br_[0]=br_[0]/y*h_;
+ br_[0]+=focus[0];
+ tl_[0]-=focus[0];
+ tl_[0]=tl_[0]/y*h_;
+ tl_[0]+=focus[0];
+ } else
+ {
+ br_[1]-=focus[1];
+ br_[1]=br_[1]/h_*y;
+ br_[1]+=focus[1];
+ tl_[1]-=focus[1];
+ tl_[1]=tl_[1]/h_*y;
+ tl_[1]+=focus[1];
+ }
+
+ h_=y;
+
+ if(FLAGS(flags,IM_SPAN))
+ set_span(old_span);
+ }
+ else if(FLAGS(flags,PX_AREA))
+ {
+ //! \writeme
+ h_=y;
+ }
+ else
+ h_=y;
+
+ return *this;
+}
+
+RendDesc &
+RendDesc::set_wh(int x, int y)
+{
+ // FIXME: This is a working hack...
+ set_w(x);
+ set_h(y);
+
+ return *this;
+}
+
+Real
+RendDesc::get_x_res()const
+{
+ return x_res;
+}
+
+RendDesc &
+RendDesc::set_x_res(Real x)
+{
+ x_res=x; return *this;
+}
+
+Real
+RendDesc::get_y_res()const
+{
+ return y_res;
+}
+
+RendDesc &
+RendDesc::set_y_res(Real y)
+{
+ y_res=y; return *this;
+}
+
+int
+RendDesc::get_frame_start()const
+{
+ return time_begin*frame_rate;
+}
+
+RendDesc &
+RendDesc::set_frame_start(int x)
+{
+ return set_time_start(Time(x)/frame_rate);
+}
+
+int
+RendDesc::get_frame_end()const
+{
+ return time_end*frame_rate;
+}
+
+RendDesc &
+RendDesc::set_frame_end(int x)
+{
+ return set_time_end(Time(x)/frame_rate);
+}
+
+
+const Time
+RendDesc::get_time_start()const
+{
+ return time_begin;
+}
+
+RendDesc &
+RendDesc::set_time_start(Time x)
+{
+ if(x>time_end)
+ time_begin=time_end=x;
+ else
+ time_begin=x;
+ return *this;
+}
+
+
+const Time
+RendDesc::get_time_end()const
+{
+ return time_end;
+}
+
+RendDesc &
+RendDesc::set_time_end(Time x)
+{
+ if(x<time_begin)
+ time_end=time_begin=x;
+ else
+ time_end=x;
+ return *this;
+}
+
+RendDesc &
+RendDesc::set_time(Time x)
+{
+ time_end=time_begin=x;
+ return *this;
+}
+
+RendDesc &
+RendDesc::set_frame(int x)
+{
+ return set_time(Time(x)/frame_rate);
+}
+
+const float &
+RendDesc::get_frame_rate()const
+{
+ return frame_rate;
+}
+
+RendDesc &
+RendDesc::set_frame_rate(float x)
+{
+ frame_rate=x;
+ return *this;
+}
+
+const bool &
+RendDesc::get_interlaced()const
+{
+ return interlaced;
+}
+
+RendDesc &
+RendDesc::set_interlaced(bool x)
+{ interlaced=x; return *this; }
+
+//! Return the status of the clamp flag
+const bool &
+RendDesc::get_clamp()const
+{ return clamp; }
+
+//! Set the clamp flag
+RendDesc &
+RendDesc::set_clamp(bool x)
+{ clamp=x; return *this; }
+
+//! Set constraint flags
+RendDesc &
+RendDesc::set_flags(const int &x)
+{ flags=x; return *this; }
+
+//! Clear constraint flags
+RendDesc &
+RendDesc::clear_flags()
+{ flags=0; return *this; }
+
+int
+RendDesc::get_flags()const
+{ return flags; }
+
+
+//! Return the aspect ratio of a single pixel
+Real
+RendDesc::get_pixel_aspect()const
+{
+ Vector tmp=br_-tl_;
+ tmp[0]/=w_;
+ tmp[1]/=h_;
+ tmp[0]/=tmp[1];
+ if(tmp[0]<0.0)
+ return -tmp[0];
+ return tmp[0];
+}
+
+//! Return the aspect ratio of the entire image
+Real
+RendDesc::get_image_aspect()const
+{
+ Point tmp=br_-tl_;
+ tmp[0]/=tmp[1];
+ if(tmp[0]<0.0)
+ return -tmp[0];
+ return tmp[0];
+}
+
+
+//! Return the antialias amount
+const int &
+RendDesc::get_antialias()const
+{ return a; }
+
+//! Set the antilaias amount
+RendDesc &
+RendDesc::set_antialias(const int &x)
+{ a=x; return *this; }
+
+
+//! Return the distance from the bottom-right to the top-left
+Real
+RendDesc::get_span()const
+{
+ return (br_-tl_).mag();
+}
+
+//! Set the span distance
+RendDesc &
+RendDesc::set_span(const Real &x)
+{
+ Vector::value_type ratio=x/get_span();
+
+ if(!FLAGS(flags,IM_W|IM_H) || FLAGS(flags,IM_ASPECT))
+ {
+ br_-=focus;
+ br_=br_*ratio;
+ br_+=focus;
+ tl_-=focus;
+ tl_=tl_*ratio;
+ tl_+=focus;
+ }
+ else if(FLAGS(flags,IM_W))
+ {
+ //! \writeme or fix me
+ br_-=focus;
+ br_=br_*ratio;
+ br_+=focus;
+ tl_-=focus;
+ tl_=tl_*ratio;
+ tl_+=focus;
+ }else // IM_H
+ {
+ //! \writeme or fix me
+ br_-=focus;
+ br_=br_*ratio;
+ br_+=focus;
+ tl_-=focus;
+ tl_=tl_*ratio;
+ tl_+=focus;
+ }
+
+ return *this;
+}
+
+
+/*
+const Gamma &
+RendDesc::get_gamma()const
+{ return gamma; }
+
+RendDesc &
+RendDesc::set_gamma(const Gamma &x)
+{ gamma=x; return *this; }
+*/
+
+const Point &
+RendDesc::get_focus()const
+{ return focus; }
+
+RendDesc &
+RendDesc::set_focus(const Point &x)
+{ focus=x; return *this; }
+
+
+const Point &
+RendDesc::get_tl()const
+{ return tl_; }
+
+const Point &
+RendDesc::get_br()const
+{ return br_; }
+
+RendDesc &
+RendDesc::set_tl(const Point &x)
+{
+ if(FLAGS(flags,PX_ASPECT))
+ {
+ Vector new_size(x-br_);
+ new_size[0]=abs(new_size[0]);
+ new_size[1]=abs(new_size[1]);
+
+ Vector old_size(tl_-br_);
+ old_size[0]=abs(old_size[0]);
+ old_size[1]=abs(old_size[1]);
+
+ if(new_size[0]!=old_size[0])
+ w_=round_to_int(new_size[0]*w_/old_size[0]);
+
+ if(new_size[1]!=old_size[1])
+ h_=round_to_int(new_size[1]*h_/old_size[1]);
+ }
+
+ tl_=x; return *this;
+}
+
+RendDesc &
+RendDesc::set_br(const Point &x)
+{
+ if(FLAGS(flags,PX_ASPECT))
+ {
+ Vector new_size(x-tl_);
+ new_size[0]=abs(new_size[0]);
+ new_size[1]=abs(new_size[1]);
+
+ Vector old_size(tl_-br_);
+ old_size[0]=abs(old_size[0]);
+ old_size[1]=abs(old_size[1]);
+
+ if(new_size[0]!=old_size[0])
+ w_=round_to_int(new_size[0]*w_/old_size[0]);
+
+ if(new_size[1]!=old_size[1])
+ h_=round_to_int(new_size[1]*h_/old_size[1]);
+ }
+ br_=x; return *this;
+}
+
+RendDesc &
+RendDesc::set_viewport(const Point &__tl, const Point &__br)
+{ tl_=__tl; br_=__br; return *this; }
+
+RendDesc &
+RendDesc::set_viewport(Real a,Real b,Real c,Real d)
+{ tl_=Point(a,b); br_=Point(c,d); return *this; }
+
+Real
+RendDesc::get_pw()const
+{
+ return (br_[0] - tl_[0]) / w_;
+}
+
+Real
+RendDesc::get_ph()const
+{
+ return (br_[1] - tl_[1]) / h_;
+}
+
+RendDesc &
+RendDesc::set_subwindow(int x, int y, int w, int h)
+{
+ const Real pw(get_pw());
+ const Real ph(get_ph());
+
+ tl_[0]+=pw*x;
+ tl_[1]+=ph*y;
+
+ br_[0]-=pw*(w_-(x+w));
+ br_[1]-=ph*(h_-(y+h));
+
+ w_=w;
+ h_=h;
+
+ return *this;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file synfig/renddesc.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_RENDERDESC_H
+#define __SYNFIG_RENDERDESC_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "vector.h"
+#include "color.h"
+#include "types.h"
+#include <cmath>
+#include "rect.h"
+
+/* === M A C R O S ========================================================= */
+
+#ifndef DPM2DPI
+#define DPM2DPI(x) (float(x)/39.3700787402f)
+#define DPI2DPM(x) (float(x)*39.3700787402f)
+#endif
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class RendDesc
+** \todo writeme
+*/
+class RendDesc
+{
+public:
+ enum Lock
+ {
+ PX_ASPECT=(1<<0),
+ PX_AREA=(1<<1),
+ PX_W=(1<<2),
+ PX_H=(1<<3),
+
+ IM_ASPECT=(1<<4),
+ IM_SPAN=(1<<5),
+ IM_W=(1<<6),
+ IM_H=(1<<7),
+ IM_ZOOMIN=(1<<8),
+ IM_ZOOMOUT=(1<<9),
+
+ LINK_PX_ASPECT=(1<<10),
+ LINK_PX_AREA=(1<<11),
+ LINK_IM_ASPECT=(1<<12),
+ LINK_IM_SPAN=(1<<13),
+ LINK_IM_CENTER=(1<<14)
+ };
+
+private:
+ int w_,h_;
+ Real x_res;
+ Real y_res;
+ Point tl_, br_;
+ Point focus;
+ int a;
+ //Gamma gamma;
+ Color background;
+ int flags;
+ bool interlaced;
+ bool clamp;
+
+ float frame_rate;
+ Time time_begin, time_end;
+
+public:
+
+ enum
+ {
+ ANTIALIAS_UNIFORM,
+ ANTIALIAS_MONTE_CARLO,
+ ANTIALIAS_JITTERED,
+ ANTIALIAS_ADAPTIVE,
+ ANTIALIAS_QUINTCUNX
+ } AntialiasFilter;
+
+ //! Default Constructor
+ RendDesc():
+ w_ (480),
+ h_ (270),
+ x_res (DPI2DPM(72.0f)),
+ y_res (DPI2DPM(72.0f)),
+ tl_ (-4,2.25),
+ br_ (4,-2.25),
+ focus (0,0),
+ a (2),
+ background (Color::gray()),
+ flags (0),
+ interlaced (false),
+ clamp (false),
+ frame_rate (24),
+ time_begin (0),
+ time_end (0)
+ { }
+
+ //! \writeme
+ RendDesc &apply(const RendDesc &x);
+
+ //! \writeme
+ const Color &get_bg_color()const;
+
+ //! \writeme
+ RendDesc &set_bg_color(const Color &bg);
+
+ //! Return the width of the composition in pixels
+ int get_w()const;
+
+ //! Set the width of the composition in pixels.
+ /*! The other parameters are adjusted according to the
+ ** constraints placed on the flags.
+ */
+ RendDesc &set_w(int x);
+
+ //! Return the height of the composition in pixels
+ int get_h()const;
+
+ //! Set the height of the composition in pixels.
+ /*! The other parameters are adjusted according to the
+ ** constraints placed on the flags.
+ */
+ RendDesc &set_h(int y);
+
+ //! Sets the width and height of the composition in pixels
+ RendDesc &set_wh(int x, int y);
+
+ //! Returns the horizontal resolution (in dots per meter)
+ Real get_x_res()const;
+
+ //! Sets the horizontal resolution (in dots per meter)
+ RendDesc &set_x_res(Real x);
+
+ //! Returns the vertical resolution (in dots per meter)
+ Real get_y_res()const;
+
+ //! Sets the vertical resolution (in dots per meter)
+ RendDesc &set_y_res(Real y);
+
+
+ //! Return the physical width of the composition in meters
+ Real get_physical_w()const;
+
+ //! Return the physical height of the composition in meters
+ Real get_physical_h()const;
+
+ //! Set the physical width of the composition in meters
+ RendDesc &set_physical_w(Real w);
+
+ //! Set the physical height of the composition in meters
+ RendDesc &set_physical_h(Real h);
+
+
+ //! Return the index of the first frame
+ int get_frame_start()const;
+
+ //! Set the index of the first frame
+ RendDesc &set_frame_start(int x);
+
+ //! Return the index of the last frame
+ int get_frame_end()const;
+
+ //! Set the index of the last frame
+ RendDesc &set_frame_end(int x);
+
+ //! Return the starting time of the animation
+ const Time get_time_start()const;
+
+ //! Set the time that the animation will start
+ RendDesc &set_time_start(Time x);
+
+ //! Return the end time of the animation
+ const Time get_time_end()const;
+
+ //! Set the time that the animation will end
+ RendDesc &set_time_end(Time x);
+
+ //! Setup for one frame at the given time
+ RendDesc &set_time(Time x);
+
+ //! Setup for one frame
+ RendDesc &set_frame(int x);
+
+ //! Return the frame rate (frames-per-second)
+ const float &get_frame_rate()const;
+
+ //! Set the frame rate (frames-per-second)
+ RendDesc &set_frame_rate(float x);
+
+ //! Return the status of the interlaced flag
+ const bool &get_interlaced()const;
+
+ //! Set the interlace flag
+ RendDesc &set_interlaced(bool x);
+
+ //! Return the status of the clamp flag
+ const bool &get_clamp()const;
+
+ //! Set the clamp flag
+ RendDesc &set_clamp(bool x);
+
+ //! Set constraint flags
+ RendDesc &set_flags(const int &x);
+
+ //! Clear constraint flags
+ RendDesc &clear_flags();
+
+ //! Get constraint flags
+ int get_flags()const;
+
+ //! Return the aspect ratio of a single pixel
+ Point::value_type get_pixel_aspect()const;
+
+ //! Return the aspect ratio of the entire image
+ Point::value_type get_image_aspect()const;
+
+ //! Return the antialias amount
+ const int &get_antialias()const;
+
+ //! Set the antilaias amount
+ RendDesc &set_antialias(const int &x);
+
+ //! Return the distance from the bottom-right to the top-left
+ Real get_span()const;
+
+ //! Set the span distance
+ RendDesc& set_span(const Real &x);
+
+ //const Gamma &get_gamma()const;
+
+ //RendDesc &set_gamma(const Gamma &x);
+
+ const Point &get_focus()const;
+
+ RendDesc &set_focus(const Point &x);
+
+ const Point &get_tl()const;
+
+ RendDesc &set_tl(const Point &x);
+
+ const Point &get_br()const;
+
+ RendDesc &set_br(const Point &x);
+
+ Rect get_rect()const { return Rect(get_tl(),get_br()); }
+
+ RendDesc &set_viewport(const Point &__tl, const Point &__br);
+
+ RendDesc &set_viewport(Vector::value_type a,Vector::value_type b,Vector::value_type c,Vector::value_type d);
+
+ //! Returns the width of one pixel
+ Real get_pw()const;
+
+ //! Returns the height of one pixel
+ Real get_ph()const;
+
+ //! Sets viewport to represent the screen at the give pixel coordinates
+ RendDesc &set_subwindow(int x, int y, int w, int h);
+}; // END of class RendDesc
+
+//! This operator allows the combining of RendDesc::Lock flags using the '|' operator
+/*! \see RendDesc::Lock, RendDesc */
+inline RendDesc::Lock operator|(RendDesc::Lock lhs, RendDesc::Lock rhs)
+{
+ return static_cast<RendDesc::Lock>((int)lhs|(int)rhs);
+}
+
+//! This operator allows the masking of RendDesc::Lock flags using the '&' operator
+/*! \see RendDesc::Lock, RendDesc */
+inline RendDesc::Lock operator&(RendDesc::Lock lhs, RendDesc::Lock rhs)
+{
+ return static_cast<RendDesc::Lock>((int)lhs&(int)rhs);
+}
+
+//! This operator allows the inverting of RendDesc::Lock flags using the '~' operator
+/*! \see RendDesc::Lock, RendDesc */
+inline RendDesc::Lock operator~(RendDesc::Lock rhs)
+{
+ return static_cast<RendDesc::Lock>(~(int)rhs);
+}
+
+//! This operator is for checking RendDesc::Lock flags.
+/*! Don't think of it as "less then or equal to", but think of it
+** like an arrow. Is \a rhs inside of \a lhs ?
+** \see RendDesc::Lock, RendDesc */
+inline bool operator<=(RendDesc::Lock lhs, RendDesc::Lock rhs)
+{
+ return static_cast<int>(lhs) & static_cast<int>(rhs)==static_cast<int>(rhs);
+}
+
+
+}; /* end namespace synfig */
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file synfig/render.cpp
+** \brief Renderer
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef WIN32
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+#endif
+
+#include "render.h"
+#include "target.h"
+#include "canvas.h"
+#include <ETL/handle>
+#include <cassert>
+#include "context.h"
+#include "surface.h"
+
+#endif
+
+using namespace std;
+using namespace synfig;
+using namespace etl;
+
+/* === M A C R O S ========================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+bool
+synfig::parametric_render(
+ Context context,
+ Surface &surface,
+ const RendDesc &desc,
+ ProgressCallback *callback
+)
+{
+ Point::value_type
+ u,v, // Current location in image
+ su,sv, // Starting locations
+ du, dv, // Distance between pixels
+ dsu,dsv; // Distance between subpixels
+
+ bool
+ no_clamp=!desc.get_clamp();
+
+ int
+ w(desc.get_w()),
+ h(desc.get_h()),
+ a(desc.get_antialias());
+
+ Point
+ tl(desc.get_tl()),
+ br(desc.get_br());
+
+ //Gamma
+ // gamma(desc.get_gamma());
+
+ int
+ x,y, // Current location on output bitmap
+ x2,y2; // Subpixel counters
+
+ Color::value_type
+ pool; // Alpha pool (for correct alpha antialiasing)
+
+ // Calculate the number of channels
+ //chan=channels(desc.get_pixel_format());
+
+ // Calculate the distance between pixels
+ du=(br[0]-tl[0])/(Point::value_type)w;
+ dv=(br[1]-tl[1])/(Point::value_type)h;
+
+ // Calculate the distance between sub pixels
+ dsu=du/(Point::value_type)a;
+ dsv=dv/(Point::value_type)a;
+
+ // Calculate the starting points
+ //su=tl[0]+(du-dsu)/(Point::value_type)2.0;
+ //sv=tl[1]-(dv-dsv)/(Point::value_type)2.0;
+ su=tl[0];
+ sv=tl[1];
+
+ surface.set_wh(desc.get_w(),desc.get_h());
+
+ assert(surface);
+
+ // Loop through all horizontal lines
+ for(y=0,v=sv;y<h;y++,v+=dv)
+ {
+ // Set the current pixel pointer
+ // to the start of the line
+ Color *colordata=surface[y];
+
+ assert(colordata);
+
+ // If we have a callback that we need
+ // to report to, do so now.
+ if(callback)
+ if( callback->amount_complete(y,h) == false )
+ {
+ // If the callback returns false,
+ // then the render has been aborted.
+
+ return false;
+ }
+
+ // Loop through every pixel in row
+ for(x=0,u=su;x<w;x++,u+=du)
+ {
+ Color &c(*(colordata++));
+ c=Color::alpha();
+
+ // Loop through all subpixels
+ for(y2=0,pool=0;y2<a;y2++)
+ for(x2=0;x2<a;x2++)
+ {
+ Color color=context.get_color(
+ Point(
+ u+(Point::value_type)(x2)*dsu,
+ v+(Point::value_type)(y2)*dsv
+ )
+ );
+ if(!no_clamp)
+ {
+ color=color.clamped();
+ c+=color*color.get_a();
+ pool+=color.get_a();
+ }
+ else
+ {
+ c+=color*color.get_a();
+ pool+=color.get_a();
+ }
+ }
+ if(pool)
+ c/=pool;
+ }
+ }
+
+ // Give the callback one more last call,
+ // this time with the full height as the
+ // current line
+ if(callback)
+ callback->amount_complete(h,h);
+
+ // Report our success
+ return(true);
+}
+
+bool
+synfig::render(
+ Context context,
+ Target_Scanline::Handle target,
+ const RendDesc &desc,
+ ProgressCallback *callback)
+{
+ Point::value_type
+ u,v, // Current location in image
+ su,sv, // Starting locations
+ du, dv, // Distance between pixels
+ dsu,dsv; // Distance between subpixels
+
+ bool
+ no_clamp=!desc.get_clamp();
+
+ int
+ w(desc.get_w()),
+ h(desc.get_h()),
+ a(desc.get_antialias());
+
+ Point
+ tl(desc.get_tl()),
+ br(desc.get_br());
+
+ //Gamma
+ // gamma(desc.get_gamma());
+
+ int
+ x,y, // Current location on output bitmap
+ x2,y2; // Subpixel counters
+
+ Color::value_type
+ pool; // Alpha pool (for correct alpha antialiasing)
+
+ assert(target);
+
+ // If we do not have a a target then bail
+ if(!target)
+ return false;
+
+ // Calculate the number of channels
+ //chan=channels(desc.get_pixel_format());
+
+ // Calculate the distance between pixels
+ du=(br[0]-tl[0])/(Point::value_type)w;
+ dv=(br[1]-tl[1])/(Point::value_type)h;
+
+ // Calculate the distance between sub pixels
+ dsu=du/(Point::value_type)a;
+ dsv=dv/(Point::value_type)a;
+
+ // Calculate the starting points
+ su=tl[0]+(du-dsu)/(Point::value_type)2.0;
+ sv=tl[1]-(dv-dsv)/(Point::value_type)2.0;
+
+ // Mark the start of a new frame.
+ if(!target->start_frame(callback))
+ return false;
+
+ // Loop through all horizontal lines
+ for(y=0,v=sv;y<h;y++,v+=dv)
+ {
+ // Set the current pixel pointer
+ // to the start of the line
+ Color *colordata=target->start_scanline(y);
+
+ if(!colordata)
+ {
+ if(callback)callback->error(_("Target panic"));
+ else throw(string(_("Target panic")));
+ return false;
+ }
+
+ // If we have a callback that we need
+ // to report to, do so now.
+ if(callback)
+ if( callback->amount_complete(y,h) == false )
+ {
+ // If the callback returns false,
+ // then the render has been aborted.
+ // Exit gracefuly.
+
+ target->end_scanline();
+ target->end_frame();
+ return false;
+ }
+
+ // Loop through every pixel in row
+ for(x=0,u=su;x<w;x++,u+=du)
+ {
+ Color &c(*(colordata++));
+ c=Color::alpha();
+
+ // Loop through all subpixels
+ for(y2=0,pool=0;y2<a;y2++)
+ for(x2=0;x2<a;x2++)
+ {
+ Color color=context.get_color(
+ Point(
+ u+(Point::value_type)(x2)*dsu,
+ v+(Point::value_type)(y2)*dsv
+ )
+ );
+ if(!no_clamp)
+ {
+ color=color.clamped();
+ c+=color*color.get_a();
+ pool+=color.get_a();
+ }
+ else
+ {
+ c+=color*color.get_a();
+ pool+=color.get_a();
+ }
+ }
+ if(pool)
+ c/=pool;
+ }
+
+ // Send the buffer to the render target.
+ // If anything goes wrong, cleanup and bail.
+ if(!target->end_scanline())
+ {
+ if(callback)callback->error(_("Target panic"));
+ else throw(string(_("Target panic")));
+ return false;
+ }
+ }
+
+ // Finish up the target's frame
+ target->end_frame();
+
+ // Give the callback one more last call,
+ // this time with the full height as the
+ // current line
+ if(callback)
+ callback->amount_complete(h,h);
+
+ // Report our success
+ return(true);
+}
+
+bool
+synfig::render_threaded(
+ Context context,
+ Target_Scanline::Handle target,
+ const RendDesc &desc,
+ ProgressCallback *callback,
+ int threads)
+{
+#ifndef WIN32
+ struct _render_thread
+ {
+ int
+ pipe_read,
+ pipe_write,
+ pid;
+ _render_thread()
+ {
+ pipe(&pipe_read);
+ pid=0;
+ }
+ ~_render_thread()
+ {
+ close(pipe_read);
+ close(pipe_write);
+ if(pid)
+ {
+ kill(pid,9);
+ }
+ }
+ } *render_thread;
+
+ int i, mythread=-1;
+
+ Point::value_type
+ u,v, // Current location in image
+ su,sv, // Starting locations
+ du, dv, // Distance between pixels
+ dsu,dsv; // Distance between subpixels
+
+ bool
+ no_clamp=!desc.get_clamp();
+
+ int
+ w(desc.get_w()),
+ h(desc.get_h()),
+ a(desc.get_antialias());
+
+ Point
+ tl(desc.get_tl()),
+ br(desc.get_br());
+
+ int
+ x,y, // Current location on output bitmap
+ x2,y2; // Subpixel counters
+
+ Color::value_type
+ pool; // Alpha pool (for correct alpha antialiasing)
+
+ assert(target);
+
+ // If we do not have a a target then bail
+ if(!target)
+ return false;
+
+ // Calculate the distance between pixels
+ du=(br[0]-tl[0])/(Point::value_type)w;
+ dv=(br[1]-tl[1])/(Point::value_type)h;
+
+ // Calculate the distance between sub pixels
+ dsu=du/(Point::value_type)a;
+ dsv=dv/(Point::value_type)a;
+
+ // Calculate the starting points
+ su=tl[0]+(du-dsu)/(Point::value_type)2.0;
+ sv=tl[1]-(dv-dsv)/(Point::value_type)2.0;
+
+ render_thread=new _render_thread[threads];
+
+ // Start the forks
+ for(i=0;i<threads;i++)
+ {
+ int pid=fork();
+ if(pid==0)
+ {
+ mythread=i;
+ goto renderthread;
+ }
+ render_thread[i].pid=pid;
+ }
+
+ // Mark the start of a new frame.
+ if(!target->start_frame(callback))
+ return false;
+
+ for(y=0;y<h;y++)
+ {
+ // Set the current pixel pointer
+ // to the start of the line
+ Color *colordata(target->start_scanline(y));
+
+ if(!colordata)
+ {
+ if(callback)callback->error(_("Target panic"));
+ else throw(string(_("Target panic")));
+ return false;
+ }
+
+ // If we have a callback that we need
+ // to report to, do so now.
+ if(callback)
+ if( callback->amount_complete(y,h) == false )
+ {
+ // If the callback returns false,
+ // then the render has been aborted.
+ // Exit gracefuly.
+
+ target->end_scanline();
+ target->end_frame();
+ delete [] render_thread;
+ return false;
+ }
+
+ read(render_thread[y%threads].pipe_read,colordata,w*sizeof(Color));
+
+ // Send the buffer to the render target.
+ // If anything goes wrong, cleanup and bail.
+ if(!target->end_scanline())
+ {
+ delete [] render_thread;
+ if(callback)callback->error(_("Target panic"));
+ else throw(string(_("Target panic")));
+ return false;
+ }
+ }
+
+ // Finish up the target's frame
+ target->end_frame();
+
+ // Give the callback one more last call,
+ // this time with the full height as the
+ // current line
+ if(callback)
+ callback->amount_complete(h,h);
+
+ delete [] render_thread;
+ return true;
+
+renderthread:
+
+ // Change the random seed, so that each thread has a different one
+ srand(mythread*20+threads+time(0));
+
+ Color *buffer(new Color[w]);
+
+ // Loop through all horizontal lines
+ for(y=mythread,v=sv+dv*(Real)mythread;y<h;y+=threads,v+=dv*(Real)threads)
+ {
+ // Set the current pixel pointer
+ // to the start of the line
+ Color* colordata(buffer);
+
+ // Loop through every pixel in row
+ for(x=0,u=su;x<w;x++,u+=du)
+ {
+ Color &c(*(colordata++));
+ c=Color::alpha();
+
+ // Loop through all subpixels
+ for(y2=0,pool=0;y2<a;y2++)
+ for(x2=0;x2<a;x2++)
+ {
+ Color color=context.get_color(
+ Point(
+ u+(Point::value_type)(x2)*dsu,
+ v+(Point::value_type)(y2)*dsv
+ )
+ );
+ if(!no_clamp)
+ {
+ color=color.clamped();
+ c+=color*color.get_a();
+ pool+=color.get_a();
+ }
+ else
+ {
+ c+=color*color.get_a();
+ pool+=color.get_a();
+ }
+ }
+ if(pool)
+ c/=pool;
+ }
+
+ // Send the buffer to the primary thread.
+ write(render_thread[mythread].pipe_write,buffer,w*sizeof(Color));
+ }
+
+ delete [] buffer;
+
+ _exit(0);
+ return false;
+#else
+ return render(context, target, desc, callback);
+
+#endif
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file synfig/render.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_RENDER_H
+#define __SYNFIG_RENDER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "target_scanline.h"
+#include "vector.h"
+#include "color.h"
+#include "renddesc.h"
+#include "general.h"
+#include "layer.h"
+#include "canvas.h"
+#include <ETL/handle>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+//! Renders starting at \a context to \a target
+/*! \warning \a Target::set_rend_desc() must have
+** already been called on \a target before
+** you call this function!
+*/
+extern bool render(Context context, Target_Scanline::Handle target, const RendDesc &desc,ProgressCallback *);
+
+extern bool parametric_render(Context context, Surface &surface, const RendDesc &desc,ProgressCallback *);
+
+extern bool render_threaded( Context context,
+ Target_Scanline::Handle target,
+ const RendDesc &desc,
+ ProgressCallback *callback,
+ int threads);
+
+}; /* end namespace synfig */
+
+/* -- E N D ----------------------------------------------------------------- */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file savecanvas.cpp
+** \brief Writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_SYS_ERRNO_H
+# include <sys/errno.h>
+#endif
+
+#include "savecanvas.h"
+#include "general.h"
+#include "valuenode.h"
+#include "valuenode_subtract.h"
+#include "valuenode_animated.h"
+#include "valuenode_composite.h"
+#include "valuenode_const.h"
+#include "valuenode_linear.h"
+#include "valuenode_dynamiclist.h"
+#include "valuenode_reference.h"
+#include "valuenode_segcalctangent.h"
+#include "valuenode_segcalcvertex.h"
+#include "valuenode_bline.h"
+#include "time.h"
+#include "keyframe.h"
+#include "layer.h"
+#include "string.h"
+#include "paramdesc.h"
+
+#include <libxml++/libxml++.h>
+#include <ETL/stringf>
+#include "gradient.h"
+#include <errno.h>
+
+extern "C" {
+#include <libxml/tree.h>
+}
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+#define COLOR_VALUE_TYPE_FORMAT "%f"
+#define VECTOR_VALUE_TYPE_FORMAT "%0.10f"
+#define TIME_TYPE_FORMAT "%0.3f"
+#define VIEW_BOX_FORMAT "%f %f %f %f"
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+xmlpp::Element* encode_canvas(xmlpp::Element* root,Canvas::ConstHandle canvas);
+xmlpp::Element* encode_value_node(xmlpp::Element* root,ValueNode::ConstHandle value_node,Canvas::ConstHandle canvas);
+
+xmlpp::Element* encode_keyframe(xmlpp::Element* root,const Keyframe &kf, float fps)
+{
+ root->set_name("keyframe");
+ root->set_attribute("time",kf.get_time().get_string(fps));
+ if(!kf.get_description().empty())
+ root->set_child_text(kf.get_description());
+ return root;
+}
+
+
+xmlpp::Element* encode_real(xmlpp::Element* root,Real v)
+{
+ root->set_name("real");
+ root->set_attribute("value",strprintf(VECTOR_VALUE_TYPE_FORMAT,v));
+ return root;
+}
+
+xmlpp::Element* encode_time(xmlpp::Element* root,Time t, float /*fps*/=0)
+{
+ root->set_name("time");
+ //root->set_attribute("value",t.get_string(fps));
+ root->set_attribute("value",t.get_string());
+ return root;
+}
+
+xmlpp::Element* encode_integer(xmlpp::Element* root,int i)
+{
+ root->set_name("integer");
+ root->set_attribute("value",strprintf("%i",i));
+ return root;
+}
+
+xmlpp::Element* encode_bool(xmlpp::Element* root,bool b)
+{
+ root->set_name("bool");
+ root->set_attribute("value",b?"true":"false");
+ return root;
+}
+
+xmlpp::Element* encode_string(xmlpp::Element* root,const String &str)
+{
+ root->set_name("string");
+ root->set_child_text(str);
+ return root;
+}
+
+xmlpp::Element* encode_vector(xmlpp::Element* root,Vector vect)
+{
+ root->set_name("vector");
+ root->add_child("x")->set_child_text(strprintf(VECTOR_VALUE_TYPE_FORMAT,(float)vect[0]));
+ root->add_child("y")->set_child_text(strprintf(VECTOR_VALUE_TYPE_FORMAT,(float)vect[1]));
+ return root;
+}
+
+xmlpp::Element* encode_color(xmlpp::Element* root,Color color)
+{
+ root->set_name("color");
+ root->add_child("r")->set_child_text(strprintf(COLOR_VALUE_TYPE_FORMAT,(float)color.get_r()));
+ root->add_child("g")->set_child_text(strprintf(COLOR_VALUE_TYPE_FORMAT,(float)color.get_g()));
+ root->add_child("b")->set_child_text(strprintf(COLOR_VALUE_TYPE_FORMAT,(float)color.get_b()));
+ root->add_child("a")->set_child_text(strprintf(COLOR_VALUE_TYPE_FORMAT,(float)color.get_a()));
+ return root;
+}
+
+xmlpp::Element* encode_angle(xmlpp::Element* root,Angle theta)
+{
+ root->set_name("angle");
+ root->set_attribute("value",strprintf("%f",(float)Angle::deg(theta).get()));
+ return root;
+}
+
+xmlpp::Element* encode_segment(xmlpp::Element* root,Segment seg)
+{
+ root->set_name("segment");
+ encode_vector(root->add_child("p1")->add_child("vector"),seg.p1);
+ encode_vector(root->add_child("t1")->add_child("vector"),seg.t1);
+ encode_vector(root->add_child("p2")->add_child("vector"),seg.p2);
+ encode_vector(root->add_child("t2")->add_child("vector"),seg.t2);
+ return root;
+}
+
+xmlpp::Element* encode_bline_point(xmlpp::Element* root,BLinePoint bline_point)
+{
+ root->set_name(ValueBase::type_name(ValueBase::TYPE_BLINEPOINT));
+
+ encode_vector(root->add_child("vertex")->add_child("vector"),bline_point.get_vertex());
+ encode_vector(root->add_child("t1")->add_child("vector"),bline_point.get_tangent1());
+
+ if(bline_point.get_split_tangent_flag())
+ encode_vector(root->add_child("t2")->add_child("vector"),bline_point.get_tangent2());
+
+ encode_real(root->add_child("width")->add_child("real"),bline_point.get_width());
+ encode_real(root->add_child("origin")->add_child("real"),bline_point.get_origin());
+ return root;
+}
+
+xmlpp::Element* encode_gradient(xmlpp::Element* root,Gradient x)
+{
+ root->set_name("gradient");
+
+ Gradient::const_iterator iter;
+ x.sort();
+ for(iter=x.begin();iter!=x.end();iter++)
+ {
+ xmlpp::Element *cpoint(encode_color(root->add_child("color"),iter->color));
+ cpoint->set_attribute("pos",strprintf("%f",iter->pos));
+ }
+ return root;
+}
+
+
+xmlpp::Element* encode_value(xmlpp::Element* root,const ValueBase &data,Canvas::ConstHandle canvas=0);
+
+xmlpp::Element* encode_list(xmlpp::Element* root,std::list<ValueBase> list, Canvas::ConstHandle canvas=0)
+{
+ root->set_name("list");
+
+ while(!list.empty())
+ {
+ encode_value(root->add_child("value"),list.front(),canvas);
+ list.pop_front();
+ }
+
+ return root;
+}
+
+xmlpp::Element* encode_value(xmlpp::Element* root,const ValueBase &data,Canvas::ConstHandle canvas)
+{
+ switch(data.get_type())
+ {
+ case ValueBase::TYPE_REAL:
+ return encode_real(root,data.get(Real()));
+ case ValueBase::TYPE_TIME:
+ if(canvas)
+ return encode_time(root,data.get(Time()),canvas->rend_desc().get_frame_rate());
+ else
+ return encode_time(root,data.get(Time()));
+ case ValueBase::TYPE_INTEGER:
+ return encode_integer(root,data.get(int()));
+ case ValueBase::TYPE_COLOR:
+ return encode_color(root,data.get(Color()));
+ case ValueBase::TYPE_VECTOR:
+ return encode_vector(root,data.get(Vector()));
+ case ValueBase::TYPE_ANGLE:
+ return encode_angle(root,data.get(Angle()));
+ case ValueBase::TYPE_BOOL:
+ return encode_bool(root,data.get(bool()));
+ case ValueBase::TYPE_STRING:
+ return encode_string(root,data.get(String()));
+ case ValueBase::TYPE_SEGMENT:
+ return encode_segment(root,data.get(Segment()));
+ case ValueBase::TYPE_BLINEPOINT:
+ return encode_bline_point(root,data.get(BLinePoint()));
+ case ValueBase::TYPE_GRADIENT:
+ return encode_gradient(root,data.get(Gradient()));
+ case ValueBase::TYPE_LIST:
+ return encode_list(root,data,canvas);
+ case ValueBase::TYPE_CANVAS:
+ return encode_canvas(root,data.get(Canvas::Handle()).get());
+ case ValueBase::TYPE_NIL:
+ synfig::error("Encountered NIL ValueBase");
+ root->set_name("nil");
+ return root;
+ default:
+ synfig::error(strprintf("Unknown value(%s), cannot create XML representation!",ValueBase::type_name(data.get_type()).c_str()));
+ root->set_name("nil");
+ return root;
+ }
+}
+
+xmlpp::Element* encode_animated(xmlpp::Element* root,ValueNode_Animated::ConstHandle value_node,Canvas::ConstHandle canvas=0)
+{
+ assert(value_node);
+ root->set_name("animated");
+
+ root->set_attribute("type",ValueBase::type_name(value_node->get_type()));
+
+ const ValueNode_Animated::WaypointList &waypoint_list=value_node->waypoint_list();
+ ValueNode_Animated::WaypointList::const_iterator iter;
+
+ for(iter=waypoint_list.begin();iter!=waypoint_list.end();++iter)
+ {
+ xmlpp::Element *waypoint_node=root->add_child("waypoint");
+ //waypoint_node->set_attribute("time",iter->get_time().get_string(canvas->rend_desc().get_frame_rate()));
+ waypoint_node->set_attribute("time",iter->get_time().get_string());
+
+ //waypoint_node->add_child(encode_value(iter->get_value(),canvas));
+ if(iter->get_value_node()->is_exported())
+ waypoint_node->set_attribute("use",iter->get_value_node()->get_relative_id(canvas));
+ else {
+ ValueNode::ConstHandle value_node = iter->get_value_node();
+ if(ValueNode_Const::ConstHandle::cast_dynamic(value_node)) {
+ const ValueBase data = ValueNode_Const::ConstHandle::cast_dynamic(value_node)->get_value();
+ if (data.get_type() == ValueBase::TYPE_CANVAS)
+ waypoint_node->set_attribute("use",data.get(Canvas::Handle()).get()->get_relative_id(canvas));
+ else
+ encode_value_node(waypoint_node->add_child("value_node"),iter->get_value_node(),canvas);
+ }
+ else
+ encode_value_node(waypoint_node->add_child("value_node"),iter->get_value_node(),canvas);
+ }
+
+ switch(iter->get_before())
+ {
+ case INTERPOLATION_HALT:
+ waypoint_node->set_attribute("before","halt");
+ break;
+ case INTERPOLATION_LINEAR:
+ // This is the default value for angles, so don't add a new attribute for them
+ if (value_node->get_type() != ValueBase::TYPE_ANGLE)
+ waypoint_node->set_attribute("before","linear");
+ break;
+ case INTERPOLATION_MANUAL:
+ waypoint_node->set_attribute("before","manual");
+ break;
+ case INTERPOLATION_CONSTANT:
+ waypoint_node->set_attribute("before","constant");
+ break;
+ case INTERPOLATION_TCB:
+ // This is the default value, so don't add a new attribute (unless it's an angle - they default to linear)
+ if (value_node->get_type() == ValueBase::TYPE_ANGLE)
+ waypoint_node->set_attribute("before","auto");
+ break;
+ default:
+ error("Unknown waypoint type for \"before\" attribute");
+ }
+
+ switch(iter->get_after())
+ {
+ case INTERPOLATION_HALT:
+ waypoint_node->set_attribute("after","halt");
+ break;
+ case INTERPOLATION_LINEAR:
+ // This is the default value for angles, so don't add a new attribute for them
+ if (value_node->get_type() != ValueBase::TYPE_ANGLE)
+ waypoint_node->set_attribute("after","linear");
+ break;
+ case INTERPOLATION_MANUAL:
+ waypoint_node->set_attribute("after","manual");
+ break;
+ case INTERPOLATION_CONSTANT:
+ waypoint_node->set_attribute("after","constant");
+ break;
+ case INTERPOLATION_TCB:
+ // This is the default value, so don't add a new attribute (unless it's an angle - they default to linear)
+ if (value_node->get_type() == ValueBase::TYPE_ANGLE)
+ waypoint_node->set_attribute("after","auto");
+ break;
+ default:
+ error("Unknown waypoint type for \"after\" attribute");
+ }
+
+ if(iter->get_tension()!=0.0)
+ waypoint_node->set_attribute("tension",strprintf("%f",iter->get_tension()));
+ if(iter->get_time_tension()!=0.0)
+ waypoint_node->set_attribute("temporal-tension",strprintf("%f",iter->get_time_tension()));
+ if(iter->get_continuity()!=0.0)
+ waypoint_node->set_attribute("continuity",strprintf("%f",iter->get_continuity()));
+ if(iter->get_bias()!=0.0)
+ waypoint_node->set_attribute("bias",strprintf("%f",iter->get_bias()));
+
+ }
+
+ return root;
+}
+
+xmlpp::Element* encode_composite(xmlpp::Element* root,ValueNode_Composite::ConstHandle value_node,Canvas::ConstHandle canvas=0)
+{
+ assert(value_node);
+ root->set_name("composite");
+
+ root->set_attribute("type",ValueBase::type_name(value_node->get_type()));
+
+ int i;
+ for(i=0;i<value_node->link_count();i++)
+ {
+ string name(strprintf("c%d",i+1));
+ assert(value_node->get_link(i));
+ if(value_node->get_link(i)->is_exported())
+ root->set_attribute(name,value_node->get_link(i)->get_relative_id(canvas));
+ else
+ encode_value_node(root->add_child(name)->add_child("value_node"),value_node->get_link(i).constant(),canvas);
+ }
+
+ return root;
+}
+
+xmlpp::Element* encode_subtract(xmlpp::Element* root,ValueNode_Subtract::ConstHandle value_node,Canvas::ConstHandle canvas=0)
+{
+ assert(value_node);
+ root->set_name("subtract");
+
+ ValueNode::ConstHandle lhs=value_node->get_lhs();
+ ValueNode::ConstHandle rhs=value_node->get_rhs();
+ ValueNode::ConstHandle scalar=value_node->get_scalar();
+
+ assert(lhs);
+ assert(rhs);
+
+ root->set_attribute("type",ValueBase::type_name(value_node->get_type()));
+
+ if(lhs==rhs)
+ warning("LHS is equal to RHS, this <subtract> will always be zero!");
+
+ //if(value_node->get_scalar()!=1)
+ // root->set_attribute("scalar",strprintf(VECTOR_VALUE_TYPE_FORMAT,value_node->get_scalar()));
+
+ if(!scalar->get_id().empty())
+ root->set_attribute("scalar",scalar->get_relative_id(canvas));
+ else
+ encode_value_node(root->add_child("scalar")->add_child("value_node"),scalar,canvas);
+
+ if(!lhs->get_id().empty())
+ root->set_attribute("lhs",lhs->get_relative_id(canvas));
+ else
+ encode_value_node(root->add_child("lhs")->add_child("value_node"),lhs,canvas);
+
+ if(!rhs->get_id().empty())
+ root->set_attribute("rhs",rhs->get_relative_id(canvas));
+ else
+ encode_value_node(root->add_child("rhs")->add_child("value_node"),rhs,canvas);
+
+ return root;
+}
+
+xmlpp::Element* encode_dynamic_list(xmlpp::Element* root,ValueNode_DynamicList::ConstHandle value_node,Canvas::ConstHandle canvas=0)
+{
+ assert(value_node);
+ const float fps(canvas?canvas->rend_desc().get_frame_rate():0);
+
+ root->set_name(value_node->get_name());
+
+ root->set_attribute("type",ValueBase::type_name(value_node->get_contained_type()));
+
+ vector<ValueNode_DynamicList::ListEntry>::const_iterator iter;
+
+ ValueNode_BLine::ConstHandle bline_value_node(ValueNode_BLine::ConstHandle::cast_dynamic(value_node));
+
+ if(bline_value_node)
+ {
+ if(bline_value_node->get_loop())
+ root->set_attribute("loop","true");
+ else
+ root->set_attribute("loop","false");
+ }
+
+ for(iter=value_node->list.begin();iter!=value_node->list.end();++iter)
+ {
+ xmlpp::Element *entry_node=root->add_child("entry");
+ assert(iter->value_node);
+ if(!iter->value_node->get_id().empty())
+ entry_node->set_attribute("use",iter->value_node->get_relative_id(canvas));
+ else
+ encode_value_node(entry_node->add_child("value_node"),iter->value_node,canvas);
+
+ // process waypoints
+ {
+ typedef synfig::ValueNode_DynamicList::ListEntry::Activepoint Activepoint;
+ typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
+ String begin_sequence;
+ String end_sequence;
+
+ const ActivepointList& timing_info(iter->timing_info);
+ ActivepointList::const_iterator entry_iter;
+
+ for(entry_iter=timing_info.begin();entry_iter!=timing_info.end();++entry_iter)
+ if(entry_iter->state==true)
+ {
+ if(entry_iter->priority)
+ {
+ printf("begin priority is %d\n", entry_iter->priority);
+ begin_sequence+=strprintf("p%d ",entry_iter->priority);
+ }
+ begin_sequence+=entry_iter->time.get_string(fps)+", ";
+ }
+ else
+ {
+ if(entry_iter->priority)
+ {
+ printf("end priority is %d\n", entry_iter->priority);
+ end_sequence+=strprintf("p%d ",entry_iter->priority);
+ }
+ end_sequence+=entry_iter->time.get_string(fps)+", ";
+ }
+
+ // If this is just a plane-jane vanilla entry,
+ // then don't bother with begins and ends
+ if(end_sequence.empty() && begin_sequence=="SOT, ")
+ begin_sequence.clear();
+
+ if(!begin_sequence.empty())
+ {
+ // Remove the last ", " stuff
+ begin_sequence=String(begin_sequence.begin(),begin_sequence.end()-2);
+ // Add the attribute
+ entry_node->set_attribute("on",begin_sequence);
+ }
+
+ if(!end_sequence.empty())
+ {
+ // Remove the last ", " stuff
+ end_sequence=String(end_sequence.begin(),end_sequence.end()-2);
+ // Add the attribute
+ entry_node->set_attribute("off",end_sequence);
+ }
+ }
+ }
+
+ return root;
+}
+
+// Generic linkable data node entry
+xmlpp::Element* encode_linkable_value_node(xmlpp::Element* root,LinkableValueNode::ConstHandle value_node,Canvas::ConstHandle canvas=0)
+{
+ assert(value_node);
+ root->set_name(value_node->get_name());
+
+ root->set_attribute("type",ValueBase::type_name(value_node->get_type()));
+
+ int i;
+ for(i=0;i<value_node->link_count();i++)
+ {
+ ValueNode::ConstHandle link=value_node->get_link(i).constant();
+ if(!link)
+ throw runtime_error("Bad link");
+ if(link->is_exported())
+ root->set_attribute(value_node->link_name(i),link->get_relative_id(canvas));
+ else
+ encode_value_node(root->add_child(value_node->link_name(i))->add_child("value_node"),link,canvas);
+ }
+
+ return root;
+}
+
+xmlpp::Element* encode_value_node(xmlpp::Element* root,ValueNode::ConstHandle value_node,Canvas::ConstHandle canvas)
+{
+ assert(value_node);
+
+ if(ValueNode_Animated::ConstHandle::cast_dynamic(value_node))
+ encode_animated(root,ValueNode_Animated::ConstHandle::cast_dynamic(value_node),canvas);
+ else
+ if(ValueNode_Composite::ConstHandle::cast_dynamic(value_node))
+ encode_composite(root,ValueNode_Composite::ConstHandle::cast_dynamic(value_node),canvas);
+ else
+ if(ValueNode_Subtract::ConstHandle::cast_dynamic(value_node))
+ encode_subtract(root,ValueNode_Subtract::ConstHandle::cast_dynamic(value_node),canvas);
+ else
+ if(ValueNode_DynamicList::ConstHandle::cast_dynamic(value_node))
+ encode_dynamic_list(root,ValueNode_DynamicList::ConstHandle::cast_dynamic(value_node),canvas);
+ else if(ValueNode_Const::ConstHandle::cast_dynamic(value_node))
+ {
+ encode_value(root,ValueNode_Const::ConstHandle::cast_dynamic(value_node)->get_value(),canvas);
+ }
+ else
+ if(LinkableValueNode::ConstHandle::cast_dynamic(value_node))
+ encode_linkable_value_node(root,LinkableValueNode::ConstHandle::cast_dynamic(value_node),canvas);
+ else
+ {
+ error(_("Unknown ValueNode Type (%s), cannot create an XML representation"),value_node->get_local_name().c_str());
+ root->set_name("nil");
+ }
+
+ assert(root);
+
+ if(!value_node->get_id().empty())
+ root->set_attribute("id",value_node->get_id());
+
+ if(value_node->rcount()>1)
+ root->set_attribute("guid",(value_node->get_guid()^canvas->get_root()->get_guid()).get_string());
+
+ return root;
+}
+
+xmlpp::Element* encode_layer(xmlpp::Element* root,Layer::ConstHandle layer)
+{
+ root->set_name("layer");
+
+ root->set_attribute("type",layer->get_name());
+ root->set_attribute("active",layer->active()?"true":"false");
+
+ if(!layer->get_version().empty())
+ root->set_attribute("version",layer->get_version());
+ if(!layer->get_description().empty())
+ root->set_attribute("desc",layer->get_description());
+ if(!layer->get_group().empty())
+ root->set_attribute("group",layer->get_group());
+
+ Layer::Vocab vocab(layer->get_param_vocab());
+ Layer::Vocab::const_iterator iter;
+
+ const Layer::DynamicParamList &dynamic_param_list=layer->dynamic_param_list();
+
+ for(iter=vocab.begin();iter!=vocab.end();++iter)
+ {
+ // Handle dynamic parameters
+ if(dynamic_param_list.count(iter->get_name()))
+ {
+ xmlpp::Element *node=root->add_child("param");
+ node->set_attribute("name",iter->get_name());
+
+ handle<const ValueNode> value_node=dynamic_param_list.find(iter->get_name())->second;
+
+ // If the valuenode has no ID, then it must be defined in-place
+ if(value_node->get_id().empty())
+ {
+ encode_value_node(node->add_child("value_node"),value_node,layer->get_canvas().constant());
+ }
+ else
+ {
+ node->set_attribute("use",value_node->get_relative_id(layer->get_canvas()));
+ }
+ }
+ else // Handle normal parameters
+ if(iter->get_critical())
+ {
+ ValueBase value=layer->get_param(iter->get_name());
+ if(!value.is_valid())
+ {
+ error("Layer doesn't know its own vocabulary -- "+iter->get_name());
+ continue;
+ }
+
+ if(value.get_type()==ValueBase::TYPE_CANVAS)
+ {
+ // the ->is_inline() below was crashing if the canvas
+ // contained a PasteCanvas with the default <No Image
+ // Selected> Canvas setting; this avoids the crash
+ if (!value.get(Canvas::LooseHandle()))
+ continue;
+
+ if (!value.get(Canvas::LooseHandle())->is_inline())
+ {
+ Canvas::Handle child(value.get(Canvas::LooseHandle()));
+
+ if(!value.get(Canvas::Handle()))
+ continue;
+ xmlpp::Element *node=root->add_child("param");
+ node->set_attribute("name",iter->get_name());
+ node->set_attribute("use",child->get_relative_id(layer->get_canvas()));
+ continue;
+ }
+ }
+ xmlpp::Element *node=root->add_child("param");
+ node->set_attribute("name",iter->get_name());
+
+ encode_value(node->add_child("value"),value,layer->get_canvas().constant());
+ }
+ }
+
+
+ return root;
+}
+
+xmlpp::Element* encode_canvas(xmlpp::Element* root,Canvas::ConstHandle canvas)
+{
+ assert(canvas);
+ const RendDesc &rend_desc=canvas->rend_desc();
+ root->set_name("canvas");
+
+ if(canvas->is_root())
+ root->set_attribute("version","0.1");
+
+ if(!canvas->get_id().empty() && !canvas->is_root() && !canvas->is_inline())
+ root->set_attribute("id",canvas->get_id());
+
+ if(!canvas->parent() || canvas->parent()->rend_desc().get_w()!=canvas->rend_desc().get_w())
+ root->set_attribute("width",strprintf("%d",rend_desc.get_w()));
+
+ if(!canvas->parent() || canvas->parent()->rend_desc().get_h()!=canvas->rend_desc().get_h())
+ root->set_attribute("height",strprintf("%d",rend_desc.get_h()));
+
+ if(!canvas->parent() || canvas->parent()->rend_desc().get_x_res()!=canvas->rend_desc().get_x_res())
+ root->set_attribute("xres",strprintf("%f",rend_desc.get_x_res()));
+
+ if(!canvas->parent() || canvas->parent()->rend_desc().get_y_res()!=canvas->rend_desc().get_y_res())
+ root->set_attribute("yres",strprintf("%f",rend_desc.get_y_res()));
+
+
+ if(!canvas->parent() ||
+ canvas->parent()->rend_desc().get_tl()!=canvas->rend_desc().get_tl() ||
+ canvas->parent()->rend_desc().get_br()!=canvas->rend_desc().get_br())
+ root->set_attribute("view-box",strprintf(VIEW_BOX_FORMAT,
+ rend_desc.get_tl()[0],
+ rend_desc.get_tl()[1],
+ rend_desc.get_br()[0],
+ rend_desc.get_br()[1])
+ );
+
+ if(!canvas->parent() || canvas->parent()->rend_desc().get_antialias()!=canvas->rend_desc().get_antialias())
+ root->set_attribute("antialias",strprintf("%d",rend_desc.get_antialias()));
+
+ if(!canvas->parent())
+ root->set_attribute("fps",strprintf(TIME_TYPE_FORMAT,rend_desc.get_frame_rate()));
+
+ if(!canvas->parent() || canvas->parent()->rend_desc().get_time_start()!=canvas->rend_desc().get_time_start())
+ root->set_attribute("begin-time",rend_desc.get_time_start().get_string(rend_desc.get_frame_rate()));
+
+ if(!canvas->parent() || canvas->parent()->rend_desc().get_time_end()!=canvas->rend_desc().get_time_end())
+ root->set_attribute("end-time",rend_desc.get_time_end().get_string(rend_desc.get_frame_rate()));
+
+ if(!canvas->is_inline())
+ {
+ root->set_attribute("bgcolor",strprintf(VIEW_BOX_FORMAT,
+ rend_desc.get_bg_color().get_r(),
+ rend_desc.get_bg_color().get_g(),
+ rend_desc.get_bg_color().get_b(),
+ rend_desc.get_bg_color().get_a())
+ );
+
+ if(!canvas->get_name().empty())
+ root->add_child("name")->set_child_text(canvas->get_name());
+ if(!canvas->get_description().empty())
+ root->add_child("desc")->set_child_text(canvas->get_description());
+ if(!canvas->get_author().empty())
+ root->add_child("author")->set_child_text(canvas->get_description());
+
+ std::list<String> meta_keys(canvas->get_meta_data_keys());
+ while(!meta_keys.empty())
+ {
+ xmlpp::Element* meta_element(root->add_child("meta"));
+ meta_element->set_attribute("name",meta_keys.front());
+ meta_element->set_attribute("content",canvas->get_meta_data(meta_keys.front()));
+ meta_keys.pop_front();
+ }
+ for(KeyframeList::const_iterator iter=canvas->keyframe_list().begin();iter!=canvas->keyframe_list().end();++iter)
+ encode_keyframe(root->add_child("keyframe"),*iter,canvas->rend_desc().get_frame_rate());
+ }
+
+ // Output the <defs> section
+ if(!canvas->is_inline() && !canvas->value_node_list().empty() || !canvas->children().empty())
+ {
+ xmlpp::Element *node=root->add_child("defs");
+ const ValueNodeList &value_node_list(canvas->value_node_list());
+
+ for(ValueNodeList::const_iterator iter=value_node_list.begin();iter!=value_node_list.end();++iter)
+ {
+ // If the value_node is a constant, then use the shorthand
+ if(handle<ValueNode_Const>::cast_dynamic(*iter))
+ {
+ ValueNode_Const::Handle value_node(ValueNode_Const::Handle::cast_dynamic(*iter));
+ reinterpret_cast<xmlpp::Element*>(encode_value(node->add_child("value"),value_node->get_value()))->set_attribute("id",value_node->get_id());
+ continue;
+ }
+ encode_value_node(node->add_child("value_node"),*iter,canvas);
+ // writeme
+ }
+
+ for(Canvas::Children::const_iterator iter=canvas->children().begin();iter!=canvas->children().end();++iter)
+ {
+ encode_canvas(node->add_child("canvas"),*iter);
+ }
+ }
+
+ Canvas::const_reverse_iterator iter;
+
+ for(iter=canvas->rbegin();iter!=canvas->rend();++iter)
+ encode_layer(root->add_child("layer"),*iter);
+
+ return root;
+}
+
+bool
+synfig::save_canvas(const String &filename, Canvas::ConstHandle canvas)
+{
+ ChangeLocale change_locale(LC_NUMERIC, "C");
+
+ synfig::String tmp_filename(filename+".TMP");
+
+ if (String(filename.begin() + filename.find_last_of('.')+1, filename.end()) == "sifz")
+ xmlSetCompressMode(9);
+ else
+ xmlSetCompressMode(0);
+
+ try
+ {
+ assert(canvas);
+ xmlpp::Document document;
+
+ encode_canvas(document.create_root_node("canvas"),canvas);
+
+ document.write_to_file_formatted(tmp_filename);
+ }
+ catch(...) { synfig::error("synfig::save_canvas(): Caught unknown exception"); return false; }
+
+
+#ifdef _WIN32
+ // On Win32 platforms, rename() has bad behavior. work around it.
+ char old_file[80]="sif.XXXXXXXX";
+ mktemp(old_file);
+ rename(filename.c_str(),old_file);
+ if(rename(tmp_filename.c_str(),filename.c_str())!=0)
+ {
+ rename(old_file,tmp_filename.c_str());
+ synfig::error("synfig::save_canvas(): Unable to rename file to correct filename, errno=%d",errno);
+ return false;
+ }
+ remove(old_file);
+#else
+ if(rename(tmp_filename.c_str(),filename.c_str())!=0)
+ {
+ synfig::error("synfig::save_canvas(): Unable to rename file to correct filename, errno=%d",errno);
+ return false;
+ }
+#endif
+
+ return true;
+}
+
+String
+synfig::canvas_to_string(Canvas::ConstHandle canvas)
+{
+ ChangeLocale change_locale(LC_NUMERIC, "C");
+ assert(canvas);
+
+ xmlpp::Document document;
+
+ encode_canvas(document.create_root_node("canvas"),canvas);
+
+ return document.write_to_string_formatted();
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file savecanvas.h
+** \brief writeme
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_SAVECANVAS_H
+#define __SYNFIG_SAVECANVAS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "string.h"
+#include "canvas.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/* === E X T E R N S ======================================================= */
+
+//! Saves a canvas to \a filename
+/*! \return \c true on success, \c false on error. */
+bool save_canvas(const String &filename, Canvas::ConstHandle canvas);
+
+//! Stores a Canvas in a string in XML format
+String canvas_to_string(Canvas::ConstHandle canvas);
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file segment.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_SEGMENT_H
+#define __SYNFIG_SEGMENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "vector.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \struct Segment
+** \todo writeme
+*/
+struct Segment
+{
+ Point p1,p2;
+ Vector t1,t2;
+
+ Segment() { }
+ Segment(Point p1,Vector t1,Point p2, Vector t2):
+ p1(p1),
+ p2(p2),
+ t1(t1),
+ t2(t2)
+ { }
+ Segment(Point p1,Point p2):
+ p1(p1),
+ p2(p2),
+ t1(p2-p1),
+ t2(p2-p1)
+ { }
+}; // END of struct Segment
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file smartfile.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_SMARTFILE_H
+#define __SYNFIG_SMARTFILE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <cstdio>
+#include <ETL/smart_ptr>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+struct _FILE_deleter
+{
+ void operator()(FILE* x)const { if(x!=stdout && x!=stdin) fclose(x); }
+};
+
+typedef etl::smart_ptr<FILE,_FILE_deleter> SmartFILE;
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file string.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STRING_H
+#define __SYNFIG_STRING_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <string>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+/*
+namespace std
+{
+template<class _CharT> struct char_traits;
+template<> struct char_traits<char>;
+template<typename _Alloc> class allocator;
+template<typename _CharT, typename _Traits,typename _Alloc>class basic_string;
+typedef basic_string<char,char_traits<char>,allocator<char> > string;
+
+}; // END of namespace std
+*/
+
+namespace synfig
+{
+
+/*! \typedef String
+** \todo writeme
+*/
+typedef std::string String;
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file string_decl.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STRING_DECL_H
+#define __SYNFIG_STRING_DECL_H
+
+/* === H E A D E R S ======================================================= */
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace std
+{
+template<class _CharT> struct char_traits;
+template<> struct char_traits<char>;
+template<typename _Alloc> class allocator;
+template<typename _CharT, typename _Traits,typename _Alloc>class basic_string;
+typedef basic_string<char,char_traits<char>,allocator<char> > string;
+
+}; // END of namespace std
+
+namespace synfig
+{
+
+/*! \typedef String
+** \todo writeme
+*/
+typedef std::string String;
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file surface.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "canvas.h"
+#include "surface.h"
+#include "target_scanline.h"
+#include "general.h"
+
+#ifdef HAS_VIMAGE
+#include <Accelerate/Accelerate.h>
+#endif
+
+#endif
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+class target2surface : public synfig::Target_Scanline
+{
+public:
+ Surface *surface;
+ bool sized;
+public:
+ target2surface(Surface *surface);
+ virtual ~target2surface();
+
+ virtual bool set_rend_desc(synfig::RendDesc *newdesc);
+
+ virtual bool start_frame(synfig::ProgressCallback *cb);
+
+ virtual void end_frame();
+
+ virtual Color * start_scanline(int scanline);
+
+ virtual bool end_scanline();
+};
+
+target2surface::target2surface(Surface *surface):surface(surface)
+{
+}
+
+target2surface::~target2surface()
+{
+}
+
+bool
+target2surface::set_rend_desc(synfig::RendDesc *newdesc)
+{
+ assert(newdesc);
+ assert(surface);
+ desc=*newdesc;
+ return synfig::Target_Scanline::set_rend_desc(newdesc);
+}
+
+bool
+target2surface::start_frame(synfig::ProgressCallback */*cb*/)
+{
+ if(surface->get_w() != desc.get_w() || surface->get_h() != desc.get_h())
+ {
+ surface->set_wh(desc.get_w(),desc.get_h());
+ }
+ return true;
+}
+
+void
+target2surface::end_frame()
+{
+ return;
+}
+
+Color *
+target2surface::start_scanline(int scanline)
+{
+ return (*surface)[scanline];
+}
+
+bool
+target2surface::end_scanline()
+{
+ return true;
+}
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Target_Scanline::Handle
+synfig::surface_target(Surface *surface)
+{
+ return Target_Scanline::Handle(new target2surface(surface));
+}
+
+void
+synfig::Surface::clear()
+{
+#ifdef HAS_VIMAGE
+ fill(Color(0.5,0.5,0.5,0.0000001));
+#else
+ etl::surface<Color, ColorAccumulator, ColorPrep>::clear();
+#endif
+}
+
+void
+synfig::Surface::blit_to(alpha_pen& pen, int x, int y, int w, int h)
+{
+ static const float epsilon(0.00001);
+ const float alpha(pen.get_alpha());
+ if( pen.get_blend_method()==Color::BLEND_STRAIGHT && fabs(alpha-1.0f)<epsilon )
+ {
+ if(x>=get_w() || y>=get_w())
+ return;
+
+ //clip source origin
+ if(x<0)
+ {
+ w+=x; //decrease
+ x=0;
+ }
+
+ if(y<0)
+ {
+ h+=y; //decrease
+ y=0;
+ }
+
+ //clip width against dest width
+ w = min((long)w,(long)(pen.end_x()-pen.x()));
+ h = min((long)h,(long)(pen.end_y()-pen.y()));
+
+ //clip width against src width
+ w = min(w,get_w()-x);
+ h = min(h,get_h()-y);
+
+ if(w<=0 || h<=0)
+ return;
+
+ for(int i=0;i<h;i++)
+ {
+ char* src(static_cast<char*>(static_cast<void*>(operator[](y)+x))+i*get_w()*sizeof(Color));
+ char* dest(static_cast<char*>(static_cast<void*>(pen.x()))+i*pen.get_width()*sizeof(Color));
+ memcpy(dest,src,w*sizeof(Color));
+ }
+ return;
+ }
+
+#ifdef HAS_VIMAGE
+ if( pen.get_blend_method()==Color::BLEND_COMPOSITE && fabs(alpha-1.0f)<epsilon )
+ {
+ if(x>=get_w() || y>=get_w())
+ return;
+
+ //clip source origin
+ if(x<0)
+ {
+ //u-=x; //increase
+ w+=x; //decrease
+ x=0;
+ }
+
+ if(y<0)
+ {
+ //v-=y; //increase
+ h+=y; //decrease
+ y=0;
+ }
+
+ //clip width against dest width
+ w = min(w,pen.end_x()-pen.x());
+ h = min(h,pen.end_y()-pen.y());
+
+ //clip width against src width
+ w = min(w,get_w()-x);
+ h = min(h,get_h()-y);
+
+ if(w<=0 || h<=0)
+ return;
+
+
+
+ vImage_Buffer top,bottom;
+ vImage_Buffer& dest(bottom);
+
+ top.data=static_cast<void*>(operator[](y)+x);
+ top.height=h;
+ top.width=w;
+ //top.rowBytes=get_w()*sizeof(Color); //! \fixme this should get the pitch!!
+ top.rowBytes=get_pitch();
+
+ bottom.data=static_cast<void*>(pen.x());
+ bottom.height=h;
+ bottom.width=w;
+ //bottom.rowBytes=pen.get_width()*sizeof(Color); //! \fixme this should get the pitch!!
+ bottom.rowBytes=pen.get_pitch(); //! \fixme this should get the pitch!!
+
+ vImage_Error ret;
+ ret=vImageAlphaBlend_ARGBFFFF(&top,&bottom,&dest,kvImageNoFlags);
+
+ assert(ret!=kvImageNoError);
+
+ return;
+ }
+#endif
+ etl::surface<Color, ColorAccumulator, ColorPrep>::blit_to(pen,x,y,w,h);
+}
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file surface.h
+** \brief Surface and Pen Definitions
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_SURFACE_H
+#define __SYNFIG_SURFACE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "color.h"
+#include "renddesc.h"
+#include <ETL/pen>
+#include <ETL/surface>
+#include <ETL/handle>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Target;
+class Target_Scanline;
+
+class ColorPrep
+{
+public:
+ ColorAccumulator cook(Color x)const
+ {
+ x.set_r(x.get_r()*x.get_a());
+ x.set_g(x.get_g()*x.get_a());
+ x.set_b(x.get_b()*x.get_a());
+ return x;
+ }
+ Color uncook(ColorAccumulator x)const
+ {
+ if(!x.get_a())
+ return Color::alpha();
+
+ const float a(1.0f/x.get_a());
+
+ x.set_r(x.get_r()*a);
+ x.set_g(x.get_g()*a);
+ x.set_b(x.get_b()*a);
+ return x;
+ }
+};
+
+/*! \class Surface
+** \brief Bitmap Surface
+** \todo writeme
+*/
+class Surface : public etl::surface<Color, ColorAccumulator, ColorPrep>
+{
+public:
+ typedef Color value_type;
+ class alpha_pen;
+
+ Surface() { }
+
+ Surface(const size_type::value_type &w, const size_type::value_type &h):
+ etl::surface<Color, ColorAccumulator,ColorPrep>(w,h) { }
+
+ Surface(const size_type &s):
+ etl::surface<Color, ColorAccumulator,ColorPrep>(s) { }
+
+ template <typename _pen>
+ Surface(const _pen &_begin, const _pen &_end):
+ etl::surface<Color, ColorAccumulator,ColorPrep>(_begin,_end) { }
+
+ template <class _pen> void blit_to(_pen &pen)
+ { return blit_to(pen,0,0, get_w(),get_h()); }
+
+ template <class _pen> void
+ blit_to(_pen& DEST_PEN, int x, int y, int w, int h)
+ {
+ etl::surface<Color, ColorAccumulator, ColorPrep>::blit_to(DEST_PEN,x,y,w,h);
+ }
+
+ void clear();
+
+ void blit_to(alpha_pen& DEST_PEN, int x, int y, int w, int h);
+}; // END of class Surface
+
+#ifndef DOXYGEN_SKIP
+
+/*! \internal Used by Pen_Alpha */
+struct _BlendFunc
+{
+ Color::BlendMethod blend_method;
+
+ _BlendFunc(Color::BlendMethod b= Color::BLEND_COMPOSITE):blend_method(b) { }
+
+ Color operator()(const Color &a,const Color &b,const Color::value_type &t)const
+ {
+ return Color::blend(b,a,t,blend_method);
+ }
+}; // END of class _BlendFunc
+
+#endif
+
+/*! \class Surface::alpha_pen
+** \brief Alpha-Blending Pen
+**
+** This pen works like a normal alpha pen, except that it supports
+** a variety of blending methods. Use set_blend_method() to select
+** which blending method you want to use.
+** The default blending method is Color::BLEND_COMPOSITE.
+** \see Color::BlendMethod
+*/
+class Surface::alpha_pen : public etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc >
+{
+public:
+ alpha_pen() { }
+ alpha_pen(const etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc > &x):
+ etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc >(x)
+ { }
+
+ alpha_pen(const etl::generic_pen<Color, ColorAccumulator>& pen, const Color::value_type &a = 1, const _BlendFunc &func = _BlendFunc()):
+ etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc >(pen,a,func)
+ { }
+
+ //! Sets the blend method to that described by \a method
+ void set_blend_method(Color::BlendMethod method) { affine_func_.blend_method=method; }
+
+ //! Returns the blend method being used for this pen
+ Color::BlendMethod get_blend_method()const { return affine_func_.blend_method; }
+}; // END of class Surface::alpha_pen
+
+//! Creates a target that will render to \a surface
+etl::handle<Target_Scanline> surface_target(Surface *surface);
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file surfacenew.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "surfacenew.h"
+#include <ETL/ref_count>
+#include "mutex.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class SurfaceNew::ChannelData
+{
+private:
+ etl::reference_counter ref_count_;
+
+ float* data_;
+ float* origin_;
+
+ int w_,h_,stride_;
+
+public:
+
+ RWLock rw_lock;
+
+ ChannelData():
+ is_defined_(false),
+ data_(0),
+ origin_(0),
+ w_(0),
+ h_(0)
+ {
+ }
+
+ ~ChannelData()
+ {
+ if(ref_count_.unique())
+ delete [] data_;
+ }
+
+ void set_wh(int w, int h)
+ {
+ w_=w;
+ h_=h;
+ stride_=w;
+
+ if(data_&&ref_count_.is_unique())
+ delete [] data_;
+
+ ref_count.make_unique();
+ data_=new float [w_*h_];
+ origin_=data_;
+ clear();
+ }
+
+ void crop(int x, int y, int w, int h)
+ {
+ origin_=origin+y*stride_+x;
+ w_=w;
+ h_=h;
+ }
+
+ int get_stride()const
+ {
+ return stride_;
+ }
+
+ void clear()
+ {
+ for(int i=0;i<h;i++)
+ bzero(origin_+stride_*i,w_*sizeof(float));
+ }
+
+ void fill(float v)
+ {
+ float* ptr(get_data());
+
+ for(int y=0;y<h;y++,ptr+=stride_)
+ for(int i=0;i<w_;i++)
+ ptr[i]=v;
+ }
+
+ float* get_data() { return origin_; }
+
+ void make_unique()
+ {
+ if(!ref_count_.unique())
+ {
+ ref_count_.make_unique();
+ float* old_data(origin_);
+ int old_stride;
+
+ data_=new float [w_*h_];
+ origin_=data_;
+ stride_=w_;
+
+ for(int i=0;i<h;i++)
+ memcpy(data_+i*stride_,old_data+i*old_stride,sizeof(float)*w_);
+ }
+ }
+}; // END of class ChannelData
+
+/* === M E T H O D S ======================================================= */
+
+SurfaceNew::SurfaceNew():
+ w_(0),
+ h_(0),
+ color_system_(COLORSYS_RGB),
+ premult_flag_(false)
+{
+}
+
+SurfaceNew~SurfaceNew()
+{
+}
+
+SurfaceNew::Handle
+SurfaceNew::create(int w, int h, ColorSystem sys=COLORSYS_RGB)
+{
+ Handle ret(new SurfaceNew);
+
+ ret.set_wh(w,h);
+ ret.set_color_system(sys);
+
+ return ret;
+}
+
+SurfaceNew::Handle
+SurfaceNew::create(const Surface&)
+{
+ // ***WRITEME***
+ return 0;
+}
+
+SurfaceNew::Handle
+SurfaceNew::create(HandleConst orig)
+{
+ Lock lock(orig);
+
+ Handle ret(new SurfaceNew);
+
+ ret.w_=orig.w_;
+ ret.h_=orig.h_;
+ ret.color_system_=orig.color_system_;
+ ret.premult_flag_=orig.premult_flag_;
+ ret.channel_map_=orig.channel_map_;
+
+ return ret;
+}
+
+Handle
+SurfaceNew::crop(HandleConst, int x, int y, int w, int h)
+{
+ Lock lock(orig);
+
+ Handle ret(new SurfaceNew);
+
+ ret.w_=orig.w_;
+ ret.h_=orig.h_;
+ ret.color_system_=orig.color_system_;
+ ret.premult_flag_=orig.premult_flag_;
+ ret.channel_map_=orig.channel_map_;
+
+ std::map<Channel,ChannelData>::iterator iter;
+ for(iter=ret.channel_map_.begin();iter!=ret.channel_map_.end();++iter)
+ iter->crop(x,y,w,h);
+
+ return ret;
+}
+
+int
+SurfaceNew::get_w()const
+{
+ return w_;
+}
+
+int
+SurfaceNew::get_h()const
+{
+ return h_;
+}
+
+void
+SurfaceNew::set_wh(int w, int h)
+{
+ if(w!=w_ || h!=h_)
+ {
+ w_=w;
+ h_=h;
+ channel_map_.clear();
+ }
+}
+
+SurfaceNew::ColorSystem
+SurfaceNew::get_color_system()const
+{
+ return color_system_;
+}
+
+void
+SurfaceNew::set_color_system(SurfaceNew::ColorSystem x)
+{
+ color_system_=x;
+}
+
+Color
+SurfaceNew::get_color(int x, int y)const
+{
+ // This operation is rather expensive, as it should be.
+ // I want to discurage people from using it all over the place.
+
+ Color ret(
+ lock_channel_const(CHAN_R).get_value(x,y),
+ lock_channel_const(CHAN_G).get_value(x,y),
+ lock_channel_const(CHAN_B).get_value(x,y),
+ lock_channel_const(CHAN_A).get_value(x,y)
+ );
+
+ if(get_premult())
+ {
+ ret=ret.demult_alpha();
+ }
+
+ return ret;
+}
+
+void
+SurfaceNew::lock()
+{
+ mutex_.lock();
+}
+
+void
+SurfaceNew::unlock()
+{
+ mutex_.unlock();
+}
+
+bool
+SurfaceNew::trylock()
+{
+ return mutex_.trylock();
+}
+
+SurfaceNew::ChannelLock
+SurfaceNew::lock_channel(SurfaceNew::Channel chan)
+{
+ if(!is_channel_defined(chan)
+ channel_map_[chan].set_wh(get_w(),get_h());
+ else
+ channel_map_[chan].make_unique();
+
+ ChannelLockConst channel_lock;
+
+ channel_lock.surface_=this;
+ channel_lock.channel_=chan;
+
+ channel_map_[chan].rw_lock.writer_lock();
+
+ return channel_lock;
+}
+
+SurfaceNew::ChannelLockConst
+SurfaceNew::lock_channel_const(SurfaceNew::Channel chan)const
+{
+ if(!is_channel_defined(chan)
+ channel_map_[chan].set_wh(get_w(),get_h());
+
+ ChannelLockConst channel_lock;
+
+ channel_lock.surface_=this;
+ channel_lock.channel_=chan;
+
+ channel_map_[chan].rw_lock.reader_lock();
+
+ return channel_lock;
+}
+
+SurfaceNew::ChannelLock
+SurfaceNew::lock_channel_alpha(SurfaceNew::Channel chan)
+{
+ // Change this when per-channel alpha
+ // is implemented
+ return lock_channel(CHAN_A);
+}
+
+SurfaceNew::ChannelLockConst
+SurfaceNew::lock_channel_alpha_const(SurfaceNew::Channel chan)const
+{
+ // Change this when per-channel alpha
+ // is implemented
+ return lock_channel_const(CHAN_A);
+}
+
+bool
+SurfaceNew::is_channel_defined(Channel chan)const
+{
+ return channel_map_.count(chan);
+}
+
+bool
+SurfaceNew::get_premult()const
+{
+ return premult_flag_;
+}
+
+void
+SurfaceNew::set_premult(bool x)
+{
+ if(x==premult_flag_)
+ return;
+
+ premult_flag_=x;
+
+ for(int i=0;i<3;i++)
+ {
+ Channel chan;
+ if(get_color_system()==COLORSYS_RGB)switch(i)
+ {
+ case 0: chan=CHAN_R;
+ case 1: chan=CHAN_G;
+ case 2: chan=CHAN_B;
+ }
+ else
+ if(get_color_system()==COLORSYS_YUV)switch(i)
+ {
+ case 0: chan=CHAN_Y;
+ case 1: chan=CHAN_U;
+ case 2: chan=CHAN_V;
+ }
+
+ // If this channel isn't defined, then
+ // skip it and move on to the next one
+ if(!is_channel_defined(chan))
+ continue;
+
+ ChannelLock color_channel(lock_channel(chan));
+ ChannelLockConst alpha_channel(lock_channel_alpha_const(chan));
+ const int w(get_w());
+ const int h(get_h());
+
+ float* color_ptr(color_channel.get_data_ptr());
+ const float* alpha_ptr(alpha_channel.get_data_ptr());
+
+ const int color_pitch(color_channel.get_data_ptr_stride()-w);
+ const int alpha_pitch(alpha_channel.get_data_ptr_stride()-w);
+
+ if(premult_flag_)
+ {
+ for(int y=0;y<h;y++,color_ptr+=color_pitch,alpha_ptr+=alpha_pitch)
+ for(int x=0;x<w;x++,color_ptr++,alpha_ptr++)
+ *color_ptr *= *alpha_ptr;
+ }
+ else
+ {
+ for(int y=0;y<h;y++,color_ptr+=color_pitch,alpha_ptr+=alpha_pitch)
+ for(int x=0;x<w;x++,color_ptr++,alpha_ptr++)
+ *color_ptr /= *alpha_ptr;
+ }
+ }
+}
+
+void
+SurfaceNew::blit(
+ Handle dest, int x_dest, int y_dest,
+ HandleConst src, int x_src, int y_src, int w_src, int h_src,
+ float amount=1.0, Color::BlendMethod bm=Color::BLEND_COMPOSITE
+)
+{
+ blit(
+ dest,
+ x_dest,
+ y_dest,
+ crop(
+ src,
+ x,
+ y,
+ w,
+ h
+ ),
+ amount,
+ bm
+ );
+}
+
+void
+SurfaceNew::blit(
+ Handle dest, int x_dest, int y_dest,
+ HandleConst src
+ float amount=1.0, Color::BlendMethod bm=Color::BLEND_COMPOSITE
+)
+{
+ int w(src->get_w()), h(src->get_h);
+
+ // Clip
+ {
+ int x(0), y(0);
+
+ if(x_dest+w>dest.get_w())
+ w=dest.get_w()-x_dest;
+ if(y_dest+h>dest.get_h())
+ h=dest.get_h()-y_dest;
+ if(x_dest<0)
+ {
+ x-=x_dest;
+ w+=x_dest;
+ }
+ if(y_dest<0)
+ {
+ y-=y_dest;
+ h+=y_dest;
+ }
+ src=crop(src,x,y,w,h);
+ }
+
+ dest=crop(dest,x_dest,y_dest,w,h);
+
+ if(bm==Color::BLEND_STRAIGHT)
+ {
+ chan_mlt(dest,amount/(1.0-amount));
+ chan_add(dest,src);
+ chan_mlt(dest,(1.0-amount)/amount);
+ }
+
+ if(bm==Color::BLEND_COMPOSITE)
+ {
+
+ }
+}
+
+
+
+// -----------------------------------------------------------------------------------
+
+SurfaceChannelLockConst::SurfaceChannelLockConst():
+ data_ptr_checked_out_(false)
+{
+}
+
+SurfaceChannelLockConst::~SurfaceChannelLockConst()
+{
+ if(data_ptr_checked_out_)
+ release_data_ptr();
+
+ if(surface_ && ref_count_.is_unique())
+ return surface->channel_map_[channel_].rw_lock.reader_unlock();
+ surface=0;
+}
+
+SurfaceChannel
+SurfaceChannelLockConst::get_channel()const
+{
+ return channel_;
+}
+
+int
+SurfaceChannelLockConst::get_w()const
+{
+ return surface_->get_w();
+}
+
+int
+SurfaceChannelLockConst::get_h()const
+{
+ return surface_->get_h();
+}
+
+float
+SurfaceChannelLockConst::get_value(int x, int y)
+{
+ // WOW! CRAZY SLOW!
+ const ChannelData& channel_data(surface_->channel_map_[channel_]);
+ return *(channel_data.get_data()+y*channel_data.get_stride()+x);
+}
+
+const float*
+SurfaceChannelLockConst::get_data_ptr()const
+{
+ data_ptr_checked_out_=true;
+
+ // WOW! CRAZY SLOW!
+ return surface_->channel_map_[channel_].get_data();
+}
+
+int
+SurfaceChannelLockConst::get_data_ptr_stride()const
+{
+ return surface_->channel_map_[channel_].get_stride();
+}
+
+void
+SurfaceChannelLockConst::release_data_ptr()const
+{
+ data_ptr_checked_out_=false;
+}
+
+SurfaceChannelLockConst::operator bool()const
+{
+ return static_cast<bool>(surface_);
+}
+
+// -----------------------------------------------------------------------------------
+
+SurfaceChannelLock::SurfaceChannelLock()
+{
+}
+
+SurfaceChannelLock::~SurfaceChannelLock()
+{
+ if(data_ptr_checked_out_)
+ release_data_ptr();
+
+ if(surface_ && ref_count_.is_unique())
+ return surface_->channel_map_[channel_].rw_lock.writer_unlock();
+ surface=0;
+}
+
+void
+SurfaceChannelLock::clear()
+{
+ return surface_->channel_map_[channel_].clear();
+}
+
+void
+SurfaceChannelLock::fill(float v)
+{
+ return surface_->channel_map_[channel_].fill(v);
+}
+
+void
+SurfaceChannelLock::set_value(int x, int y, float v)
+{
+ // WOW! CRAZY SLOW!
+ const ChannelData& channel_data(surface_->channel_map_[channel_]);
+ *(channel_data.get_data()+y*channel_data.get_stride()+x)=v;
+}
+
+float*
+SurfaceChannelLock::get_data_ptr()
+{
+ data_ptr_checked_out_=true;
+
+ // WOW! CRAZY SLOW!
+ return surface_->channel_map_[channel_].get_data();
+}
+
+
+
+// -----------------------------------------------------------------------------------
+
+
+
+void
+SurfaceNew::chan_mlt(ChannelLock& dest, float x)
+{
+ float* ptr(dest.get_data_ptr());
+ const int w(dest.get_w());
+ const int h(dest.get_h());
+ const int pitch(dest.get_data_pitch()-w);
+
+ int(y=0;y<h;y++,ptr+=pitch)
+ int(x=0;x<w;x++,ptr++)
+ *ptr*=x;
+}
+
+void
+SurfaceNew::chan_mlt(ChannelLock& dest, const ChannelLockConst& x)
+{
+ float* d_ptr(dest.get_data_ptr());
+ const float* s_ptr(x.get_data_ptr());
+ const int w(dest.get_w());
+ const int h(dest.get_h());
+ const int d_pitch(dest.get_data_stride()-w);
+ const int s_pitch(x.get_data_stride()-w);
+
+ int(y=0;y<h;y++,d_ptr+=d_pitch,s_ptr+=s_pitch)
+ int(x=0;x<w;x++,d_ptr++,s_ptr++)
+ *d_ptr *= *s_ptr;
+}
+
+void
+SurfaceNew::chan_div(ChannelLock& dest, float x)
+{
+ float* ptr(dest.get_data_ptr());
+ const int w(dest.get_w());
+ const int h(dest.get_h());
+ const int pitch(dest.get_data_pitch()-w);
+
+ int(y=0;y<h;y++,ptr+=pitch)
+ int(x=0;x<w;x++,ptr++)
+ *ptr/=x;
+}
+
+void
+SurfaceNew::chan_div(ChannelLock& dest, const ChannelLockConst& x)
+{
+ float* d_ptr(dest.get_data_ptr());
+ const float* s_ptr(x.get_data_ptr());
+ const int w(dest.get_w());
+ const int h(dest.get_h());
+ const int d_pitch(dest.get_data_stride()-w);
+ const int s_pitch(x.get_data_stride()-w);
+
+ int(y=0;y<h;y++,d_ptr+=d_pitch,s_ptr+=s_pitch)
+ int(x=0;x<w;x++,d_ptr++,s_ptr++)
+ *d_ptr /= *s_ptr;
+}
+
+void
+SurfaceNew::chan_add(ChannelLock& dest, float x)
+{
+ float* ptr(dest.get_data_ptr());
+ const int w(dest.get_w());
+ const int h(dest.get_h());
+ const int pitch(dest.get_data_pitch()-w);
+
+ int(y=0;y<h;y++,ptr+=pitch)
+ int(x=0;x<w;x++,ptr++)
+ *ptr+=x;
+}
+
+void
+SurfaceNew::chan_add(ChannelLock& dest, const ChannelLockConst& x)
+{
+ float* d_ptr(dest.get_data_ptr());
+ const float* s_ptr(x.get_data_ptr());
+ const int w(dest.get_w());
+ const int h(dest.get_h());
+ const int d_pitch(dest.get_data_stride()-w);
+ const int s_pitch(x.get_data_stride()-w);
+
+ int(y=0;y<h;y++,d_ptr+=d_pitch,s_ptr+=s_pitch)
+ int(x=0;x<w;x++,d_ptr++,s_ptr++)
+ *d_ptr += *s_ptr;
+}
+
+void
+SurfaceNew::chan_sub(ChannelLock& dest, float x)
+{
+ float* ptr(dest.get_data_ptr());
+ const int w(dest.get_w());
+ const int h(dest.get_h());
+ const int pitch(dest.get_data_pitch()-w);
+
+ int(y=0;y<h;y++,ptr+=pitch)
+ int(x=0;x<w;x++,ptr++)
+ *ptr-=x;
+}
+
+void
+SurfaceNew::chan_sub(ChannelLock& dest, const ChannelLockConst& x)
+{
+ float* d_ptr(dest.get_data_ptr());
+ const float* s_ptr(x.get_data_ptr());
+ const int w(dest.get_w());
+ const int h(dest.get_h());
+ const int d_pitch(dest.get_data_stride()-w);
+ const int s_pitch(x.get_data_stride()-w);
+
+ int(y=0;y<h;y++,d_ptr+=d_pitch,s_ptr+=s_pitch)
+ int(x=0;x<w;x++,d_ptr++,s_ptr++)
+ *d_ptr -= *s_ptr;
+}
+
+
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file surfacenew.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_SURFACENEW_H
+#define __SYNFIG_SURFACENEW_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/handle>
+#include <ETL/ref_count>
+#include "color.h"
+#include "mutex.h"
+#include <map>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Surface;
+class SurfaceChannelLock;
+class SurfaceChannelLockConst;
+
+//! \writeme
+enum SurfaceColorSystem
+{
+ COLORSYS_RGB,
+ COLORSYS_YUV,
+
+ COLORSYS_END
+}; // END of enum SurfaceColorSystem
+
+//! \writeme
+enum SurfaceChannel
+{
+ CHAN_A,
+ CHAN_R,
+ CHAN_G,
+ CHAN_B,
+
+ CHAN_Y,
+ CHAN_U,
+ CHAN_V,
+
+ CHAN_END
+}; // END of enum SurfaceChannel
+
+class SurfaceNew : etl::shared_object
+{
+ friend class SurfaceChannelLock;
+
+ /*
+ -- ** -- T Y P E S -----------------------------------------------------------
+ */
+
+public:
+
+ //! \writeme
+ typedef etl::handle<SurfaceNew> Handle;
+
+ //! \writeme
+ typedef etl::handle<const SurfaceNew> HandleConst;
+
+ //! \writeme
+ typedef etl::loose_handle<SurfaceNew> LooseHandle;
+
+ //! \writeme
+ typedef SurfaceChannel;
+
+ //! \writeme
+ typedef SurfaceChannelLock ChannelLock;
+
+ //! \writeme
+ typedef SurfaceChannelLockConst ChannelLockConst;
+
+ //! \writeme
+ typedef SurfaceColorSystem;
+
+ //! \writeme
+ class Lock
+ {
+ Handle x;
+ public:
+ Lock(const Handle& x):x(x) { x->lock(); }
+ void unlock() { if(x){ x->unlock(); x=0; } }
+ ~Lock() { unlock(); }
+ }; // END of class Lock
+ friend class Lock;
+
+private:
+
+ //! \writeme
+ class ChannelData;
+
+ /*
+ -- ** -- D A T A -------------------------------------------------------------
+ */
+
+private:
+
+ //! \writeme
+ RecMutex mutex_;
+
+ //! \writeme
+ int w_,h_;
+
+ //! \writeme
+ ColorSystem color_system_;
+
+ //! \writeme
+ bool premult_flag_;
+
+ //! \writeme
+ std::map<Channel,ChannelData> channel_map_;
+
+ /*
+ -- ** -- S I G N A L S -------------------------------------------------------
+ */
+
+private:
+
+ /*
+ -- ** -- S I G N A L I N T E R F A C E -------------------------------------
+ */
+
+public:
+
+ /*
+ -- ** -- C O N S T R U C T O R S ---------------------------------------------
+ */
+
+protected:
+
+ //! \writeme
+ SurfaceNew();
+
+public:
+
+ //! \writeme
+ virtual ~SurfaceNew();
+
+ /*
+ -- ** -- M E M B E R F U N C T I O N S -------------------------------------
+ */
+
+public:
+
+ //! \writeme
+ int get_w()const;
+
+ //! \writeme
+ int get_h()const;
+
+ //! \writeme
+ void set_wh(int w, int h);
+
+ //! \writeme
+ ColorSystem get_color_system()const;
+
+ //! \writeme
+ void set_color_system(ColorSystem x);
+
+ //! Should only be used in certain circumstances
+ Color get_color(int x, int y)const;
+
+ //! \writeme
+ void lock();
+
+ //! \writeme
+ void unlock();
+
+ //! \writeme
+ bool trylock();
+
+ //! \writeme
+ ChannelLock lock_channel(Channel chan);
+
+ //! \writeme
+ ChannelLockConst lock_channel_const(Channel chan)const;
+
+ //! \writeme
+ ChannelLock lock_channel_alpha(Channel chan);
+
+ //! \writeme
+ ChannelLockConst lock_channel_alpha_const(Channel chan)const;
+
+ //! \writeme
+ bool is_channel_defined(Channel chan)const;
+
+ //! \writeme
+ bool get_premult()const;
+
+ //! \writeme
+ void set_premult();
+
+ /*
+ -- ** -- S T A T I C F U N C T I O N S -------------------------------------
+ */
+
+public:
+
+ //! Normal SurfaceNew Constructor
+ static Handle create(int w=0, int h=0, ColorSystem sys=COLORSYS_RGB);
+
+ //! Converts an old Surface to a SurfaceNew
+ static Handle create(const Surface&);
+
+ //! Dupilcates a surface
+ static Handle create(HandleConst);
+
+ //! Creates a cropped copy of a surface
+ static Handle crop(HandleConst, int x, int y, int w, int h);
+
+ static void blit(
+ Handle dest,
+ int x_dest,
+ int y_dest,
+ HandleConst src,
+ float amount=1.0,
+ Color::BlendMethod bm=Color::BLEND_COMPOSITE
+ );
+
+ static void blit(
+ Handle dest,
+ int x_dest,
+ int y_dest,
+ Handle src,
+ int x_src,
+ int y_src,
+ int w_src,
+ int h_src,
+ float amount=1.0,
+ Color::BlendMethod bm=Color::BLEND_COMPOSITE
+ );
+
+
+ static void chan_mlt(ChannelLock& dest, float x);
+ static void chan_mlt(ChannelLock& dest, const ChannelLockConst& x);
+
+ static void chan_div(ChannelLock& dest, float x);
+ static void chan_div(ChannelLock& dest, const ChannelLockConst& x);
+
+ static void chan_add(ChannelLock& dest, float x);
+ static void chan_add(ChannelLock& dest, const ChannelLockConst& x);
+
+ static void chan_sub(ChannelLock& dest, float x);
+ static void chan_sub(ChannelLock& dest, const ChannelLockConst& x);
+}; // END of class SurfaceNew
+
+//! \writeme
+class SurfaceChannelLockConst
+{
+ friend class SurfaceNew;
+
+ /*
+ -- ** -- T Y P E S -----------------------------------------------------------
+ */
+
+public:
+
+ /*
+ -- ** -- D A T A -------------------------------------------------------------
+ */
+
+protected:
+
+ //! \writeme
+ SurfaceNew::Handle surface_;
+
+ //! \writeme
+ etl::reference_counter ref_count_;
+
+ //! \writeme
+ SurfaceChannel channel_;
+
+ //! \writeme
+ bool data_ptr_checked_out_;
+
+ /*
+ -- ** -- C O N S T R U C T O R S ---------------------------------------------
+ */
+
+public:
+
+ SurfaceChannelLockConst();
+
+ //! \writeme
+ ~SurfaceChannelLockConst();
+
+ /*
+ -- ** -- M E M B E R F U N C T I O N S -------------------------------------
+ */
+
+public:
+
+ //! \writeme
+ SurfaceChannel get_channel()const;
+
+ //! \writeme
+ int get_w()const;
+
+ //! \writeme
+ int get_h()const;
+
+ //! \writeme
+ float get_value(int x, int y);
+
+ //! \writeme
+ const float* get_data_ptr()const;
+
+ //! \writeme
+ int get_data_ptr_stride()const;
+
+ //! Releases the pointer obtained with get_data_ptr()
+ void release_data_ptr()const;
+
+ //! \writeme
+ operator bool()const;
+}; // END of class SurfaceChannelLockConst
+
+
+//! \writeme
+class SurfaceChannelLock : public SurfaceChannelLockConst
+{
+ friend class SurfaceNew;
+
+ using SurfaceChannelLock::get_data_ptr;
+
+ /*
+ -- ** -- T Y P E S -----------------------------------------------------------
+ */
+
+public:
+
+ /*
+ -- ** -- D A T A -------------------------------------------------------------
+ */
+
+private:
+
+ /*
+ -- ** -- C O N S T R U C T O R S ---------------------------------------------
+ */
+
+public:
+
+ //! \writeme
+ SurfaceChannelLock();
+
+ //! \writeme
+ ~SurfaceChannelLock();
+
+ /*
+ -- ** -- M E M B E R F U N C T I O N S -------------------------------------
+ */
+
+public:
+
+ //! \writeme
+ void clear();
+
+ //! \writeme
+ void fill(float value);
+
+ //! \writeme
+ void set_value(int x, int y, float v);
+
+ float* get_data_ptr();
+}; // END of class ChannelLock
+
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file synfig.h
+** \brief Primary Header for Synfig
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG__
+#define __SYNFIG__
+
+#ifndef __cplusplus
+#error Sorry, Synfig only supports C++ at this time. See README for details.
+#endif
+
+#warning The use of this header is deprecated. Please use the individual header files.
+
+/* === M A C R O S ========================================================= */
+
+/*! \def SYNFIG_LEAN
+** \brief Define this to remove unused features, speeding up compile time.
+**
+** Define SYNFIG_LEAN if your plug-in
+** or program doesn't use the synfig::Angle class
+** or the rendering subsystem. This can speed up
+** compiles. You may also wish to individualy
+** use the macros SYNFIG_NO_ANGLE and
+** SYNFIG_NO_RENDER.
+** \see SYNFIG_NO_ANGLE, SYNFIG_NO_RENDER
+*/
+#ifdef SYNFIG_LEAN
+# ifndef SYNFIG_NO_ANGLE
+# define SYNFIG_NO_ANGLE
+# endif
+# ifndef SYNFIG_NO_RENDER
+# define SYNFIG_NO_RENDER
+# endif
+#endif
+
+/*! \def SYNFIG_LAYER
+** The SYNFIG_LAYER macro is useful for when you
+** are compiling layers, and can help to improve
+** build time.
+*/
+#ifdef SYNFIG_LAYER
+# ifndef SYNFIG_NO_RENDER
+# define SYNFIG_NO_RENDER
+# endif
+# define SYNFIG_NO_LOADSAVE
+#endif
+
+/*! \def SYNFIG_TARGET
+** The SYNFIG_TARGET macro is useful for when you
+** are compiling render targets, and can help to
+** improve build time.
+*/
+#ifdef SYNFIG_TARGET
+# ifdef SYNFIG_NO_RENDER
+# error You defined SYNFIG_TARGET, but also SYNFIG_NO_RENDER. This doesnt make sense.
+# endif
+# ifndef SYNFIG_NO_ANGLE
+# define SYNFIG_NO_ANGLE
+# endif
+# define SYNFIG_NO_LOADSAVE
+#endif
+
+/*! \def SYNFIG_MODULE
+** \todo Writeme
+*/
+#ifdef SYNFIG_MODULE
+# define SYNFIG_NO_LOADSAVE
+#endif
+
+/*! \namespace synfig
+** \brief Where every function and class of the synfig library can be found
+** \todo Writeme
+*/
+
+/* === H E A D E R S ======================================================= */
+
+#include "version.h"
+#include "general.h"
+#include "module.h"
+#include "color.h"
+#include "canvas.h"
+#include "layer.h"
+#include "vector.h"
+#include "types.h"
+#include "segment.h"
+
+#ifndef SYNFIG_NO_RENDER
+# include "render.h"
+#endif
+
+#ifndef SYNFIG_LAYER
+#include "target.h"
+#endif
+
+#include "valuenode.h"
+#include "valuenode_subtract.h"
+//#include "valuenode_animated.h"
+#include "valuenode_composite.h"
+#include "valuenode_const.h"
+#include "valuenode_linear.h"
+#include "valuenode_dynamiclist.h"
+#include "valuenode_reference.h"
+
+#ifndef SYNFIG_NO_LOADSAVE
+# include "savecanvas.h"
+# include "loadcanvas.h"
+#endif
+
+#include "importer.h"
+#include "surface.h"
+
+#include "string.h"
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+; The stuff to install
+Section "Synfig Core"
+
+ SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\bin"
+
+ ; Put file there
+ File "src\synfig\.libs\libsynfig-0.dll"
+
+SectionEnd
+
+Section "un.Synfig Core"
+ Delete "$INSTDIR\bin\libsynfig-0.dll"
+ RMDir "$INSTDIR\bin"
+ RMDir "$INSTDIR"
+SectionEnd
+
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file target.cpp
+** \brief Target Class Implementation
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "target.h"
+#include "string.h"
+#include "canvas.h"
+#include "target_null.h"
+#include "target_null_tile.h"
+
+using namespace synfig;
+using namespace etl;
+using namespace std;
+
+synfig::Target::Book* synfig::Target::book_;
+synfig::Target::ExtBook* synfig::Target::ext_book_;
+
+static synfig::Gamma* default_gamma_;
+
+/* === P R O C E D U R E S ================================================= */
+
+bool
+Target::subsys_init()
+{
+ book_=new synfig::Target::Book();
+ ext_book_=new synfig::Target::ExtBook();
+
+ default_gamma_=new synfig::Gamma(1.0/2.2);
+ //default_gamma_->set_black_level(0.05); // Default to 5% black level.
+
+ book()["null"]=std::pair<synfig::Target::Factory,String>(Target_Null::create,"null");
+ ext_book()["null"]="null";
+ book()["null-tile"]=std::pair<synfig::Target::Factory,String>(Target_Null_Tile::create,"null-tile");
+ ext_book()["null-tile"]="null-tile";
+
+ return true;
+}
+
+bool
+Target::subsys_stop()
+{
+ delete book_;
+ delete ext_book_;
+ delete default_gamma_;
+ return true;
+}
+
+Target::Book&
+Target::book()
+{
+ return *book_;
+}
+
+Target::ExtBook&
+Target::ext_book()
+{
+ return *ext_book_;
+}
+
+
+/* === M E T H O D S ======================================================= */
+
+Target::Target():
+ quality_(4),
+ gamma_(*default_gamma_),
+ remove_alpha(false),
+ avoid_time_sync_(false)
+{
+}
+
+void
+synfig::Target::set_canvas(Canvas::Handle c)
+{
+ canvas=c;
+ RendDesc desc=canvas->rend_desc();
+ set_rend_desc(&desc);
+}
+
+
+Target::Handle
+Target::create(const String &name, const String &filename)
+{
+ if(!book().count(name))
+ return handle<Target>();
+
+ return Target::Handle(book()[name].first(filename.c_str()));
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file target.h
+** \brief Target Class Implementation
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TARGET_H
+#define __SYNFIG_TARGET_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "string_decl.h"
+#include <utility>
+//#include <list>
+#include <map>
+#include <ETL/handle>
+#include "renddesc.h"
+//#include "general.h"
+#include "color.h"
+#include "canvas.h"
+
+/* === M A C R O S ========================================================= */
+
+//! \writeme
+#define SYNFIG_TARGET_MODULE_EXT public: static const char name__[], version__[], ext__[],cvs_id__[]; static Target *create(const char *filename);
+
+//! Sets the name of the target
+#define SYNFIG_TARGET_SET_NAME(class,x) const char class::name__[]=x
+
+//! \writeme
+#define SYNFIG_TARGET_SET_EXT(class,x) const char class::ext__[]=x
+
+//! Sets the version of the target
+#define SYNFIG_TARGET_SET_VERSION(class,x) const char class::version__[]=x
+
+//! Sets the CVS ID of the target
+#define SYNFIG_TARGET_SET_CVS_ID(class,x) const char class::cvs_id__[]=x
+
+//! \writeme
+#define SYNFIG_TARGET_INIT(class) synfig::Target* class::create(const char *filename) { return new class(filename); }
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Surface;
+class RendDesc;
+class Canvas;
+class ProgressCallback;
+
+/*! \class Target
+** \brief Render-target
+** \todo writeme
+*/
+class Target : public etl::shared_object
+{
+public:
+ typedef etl::handle<Target> Handle;
+ typedef etl::loose_handle<Target> LooseHandle;
+ typedef etl::handle<const Target> ConstHandle;
+
+ typedef Target* (*Factory)(const char *filename);
+
+ //! A type for a map of targets, indexed by the name of the Target
+ typedef std::map<String,std::pair<Factory,String> > Book;
+
+ typedef std::map<String,String> ExtBook;
+
+ //! Target Book, indexed by the target's name
+ static Book* book_;
+
+ //! Map of target names indexed by associated file extension
+ static ExtBook* ext_book_;
+
+ static Book& book();
+ static ExtBook& ext_book();
+
+ static bool subsys_init();
+ static bool subsys_stop();
+
+ //! Adjusted Render description set by set_rend_desc()
+ RendDesc desc;
+
+ etl::handle<Canvas> canvas;
+
+ int quality_;
+ Gamma gamma_;
+
+ bool remove_alpha;
+
+ bool avoid_time_sync_;
+
+protected:
+
+ Target();
+
+public:
+ virtual ~Target() { }
+
+ int get_quality()const { return quality_; }
+
+ void set_quality(int q) { quality_=q; }
+
+ void set_avoid_time_sync(bool x=true) { avoid_time_sync_=x; }
+
+ bool get_avoid_time_sync()const { return avoid_time_sync_; }
+
+ bool get_remove_alpha()const { return remove_alpha; }
+
+ void set_remove_alpha(bool x=true) { remove_alpha=x; }
+
+ Gamma &gamma() { return gamma_; }
+
+ const Gamma &gamma()const { return gamma_; }
+
+ virtual void set_canvas(etl::handle<Canvas> c);
+
+ const etl::handle<Canvas> &get_canvas()const { return canvas; }
+
+ RendDesc &rend_desc() { return desc; }
+ const RendDesc &rend_desc()const { return desc; }
+
+ //! Renders the canvas to the target
+ virtual bool render(ProgressCallback *cb=NULL)=0;
+
+ //! Sets the RendDesc for the Target to \a desc.
+ /*! If there are any parts of \a desc that the render target
+ ** is not capable of doing, the render target will adjust
+ ** \a desc to fit its needs.
+ */
+ virtual bool set_rend_desc(RendDesc *d) { desc=*d; return true; }
+
+ virtual bool init() { return true; }
+
+ //! Creates a new Target described by \a type, outputing to a file described by \a filename.
+ static Handle create(const String &type, const String &filename);
+}; // END of class Target
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#include "canvas.h"
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file target_multi.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "target_multi.h"
+#include "string.h"
+#include "surface.h"
+#include "canvas.h"
+#include "context.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Target_Multi::Target_Multi(Target_Scanline::Handle a,Target_Scanline::Handle b):
+ a(a),
+ b(b)
+{
+}
+
+Target_Multi::~Target_Multi()
+{
+}
+
+void
+Target_Multi::set_canvas(etl::handle<Canvas> c)
+{
+ canvas=c;
+ RendDesc desc=canvas->rend_desc();
+ a->set_canvas(c);
+ b->set_canvas(c);
+ set_rend_desc(&desc);
+}
+
+bool
+Target_Multi::set_rend_desc(RendDesc *d)
+{
+ desc=*d;
+ return a->set_rend_desc(d) && b->set_rend_desc(d);
+}
+
+bool
+Target_Multi::init()
+{
+ return a->init() && b->init();
+}
+
+bool
+Target_Multi::add_frame(const synfig::Surface *surface)
+{
+ return a->add_frame(surface) && b->add_frame(surface);
+}
+
+bool
+Target_Multi::start_frame(ProgressCallback *cb)
+{
+ return a->start_frame(cb) && b->start_frame(cb);
+}
+
+void
+Target_Multi::end_frame()
+{
+ a->end_frame();
+ b->end_frame();
+}
+
+Color *
+Target_Multi::start_scanline(int scanline)
+{
+ buffer_a=a->start_scanline(scanline);
+ buffer_b=b->start_scanline(scanline);
+ return buffer_a;
+}
+
+bool
+Target_Multi::end_scanline()
+{
+ memcpy(buffer_b,buffer_a,sizeof(Color)*desc.get_w());
+ return a->end_scanline() && b->end_scanline();
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file target_multi.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TARGET_MULTI_H
+#define __SYNFIG_TARGET_MULTI_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "target_scanline.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class Target_Multi
+** \brief Render-target
+** \todo writeme
+*/
+class Target_Multi : public Target_Scanline
+{
+ Target_Scanline::Handle a,b;
+ Color *buffer_a;
+ Color *buffer_b;
+public:
+
+ Target_Multi(Target_Scanline::Handle a,Target_Scanline::Handle b);
+ virtual ~Target_Multi();
+ virtual bool add_frame(const synfig::Surface *surface);
+ virtual bool start_frame(ProgressCallback *cb=NULL);
+ virtual void end_frame();
+ virtual Color * start_scanline(int scanline);
+ virtual bool end_scanline();
+
+ virtual void set_canvas(etl::handle<Canvas> c);
+ virtual bool set_rend_desc(RendDesc *d);
+ virtual bool init();
+}; // END of class Target_Multi
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file target_null.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+//#include "target_null.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+//using namespace std;
+//using namespace etl;
+//using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file target_null.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TARGET_NULL_H
+#define __SYNFIG_TARGET_NULL_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "target_scanline.h"
+#include "general.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class Target_Null
+** \brief A target which renders to nothing. Useful for benchmarks and other tests.
+** \todo writeme
+*/
+class Target_Null : public Target_Scanline
+{
+ Color *buffer;
+
+ Target_Null():buffer(0) { }
+
+public:
+
+ ~Target_Null() { delete buffer; }
+
+ virtual bool start_frame(ProgressCallback */*cb*/=NULL)
+ { delete buffer; buffer=new Color[desc.get_w()*sizeof(Color)]; return true; }
+
+ virtual void end_frame() { delete buffer; buffer=0; return; }
+
+ virtual Color * start_scanline(int /*scanline*/) { return buffer; }
+
+ virtual bool end_scanline() { return true; }
+
+ static Target* create(const char */*filename*/=0) { return new Target_Null(); }
+}; // END of class Target_Null
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file target_null_tile.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+//#include "target_null.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+//using namespace std;
+//using namespace etl;
+//using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file target_null_tile.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TARGET_NULL_TILE_H
+#define __SYNFIG_TARGET_NULL_TILE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "target_tile.h"
+#include "general.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class Target_Null_Tile
+** \brief A target which renders to nothing using tiles. Useful for benchmarks and other tests.
+** \todo writeme
+*/
+class Target_Null_Tile : public Target_Tile
+{
+ Target_Null_Tile() { }
+
+public:
+
+ ~Target_Null_Tile() { }
+ virtual bool add_tile(const synfig::Surface &/*surface*/, int /*x*/, int /*y*/) { return true; }
+
+ virtual bool start_frame(ProgressCallback */*cb*/=NULL)
+ { return true; }
+
+ virtual void end_frame() { return; }
+
+ static Target* create(const char */*filename*/=0) { return new Target_Null_Tile(); }
+}; // END of class Target_Null_Tile
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file target_scanline.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "target_scanline.h"
+#include "string.h"
+#include "surface.h"
+#include "render.h"
+#include "canvas.h"
+#include "context.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+#define SYNFIG_OPTIMIZE_LAYER_TREE 1
+
+#define PIXEL_RENDERING_LIMIT 1500000
+
+#define USE_PIXELRENDERING_LIMIT 1
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Target_Scanline::Target_Scanline():
+ threads_(2)
+{
+ curr_frame_=0;
+}
+
+int
+Target_Scanline::next_frame(Time& time)
+{
+ int
+ total_frames(1),
+ frame_start(0),
+ frame_end(0);
+ Time
+ time_start(0),
+ time_end(0);
+
+ // If the description's end frame is equal to
+ // the start frame, then it is assumed that we
+ // are rendering only one frame. Correct it.
+ if(desc.get_frame_end()==desc.get_frame_start())
+ desc.set_frame_end(desc.get_frame_start()+1);
+
+ frame_start=desc.get_frame_start();
+ frame_end=desc.get_frame_end();
+ time_start=desc.get_time_start();
+ time_end=desc.get_time_end();
+
+ // Calculate the number of frames
+ total_frames=frame_end-frame_start;
+ if(total_frames<=0)total_frames=1;
+
+ //RendDesc rend_desc=desc;
+ //rend_desc.set_gamma(1);
+
+// int total_tiles(total_tiles());
+ time=(time_end-time_start)*curr_frame_/total_frames+time_start;
+ curr_frame_++;
+
+/* synfig::info("curr_frame_: %d",curr_frame_);
+ synfig::info("total_frames: %d",total_frames);
+ synfig::info("time_end: %s",time_end.get_string().c_str());
+ synfig::info("time_start: %s",time_start.get_string().c_str());
+*/
+// synfig::info("time: %s",time.get_string().c_str());
+
+ return total_frames- curr_frame_+1;
+}
+bool
+synfig::Target_Scanline::render(ProgressCallback *cb)
+{
+ SuperCallback super_cb;
+ int
+// i=0,
+ total_frames,
+ quality=get_quality(),
+ frame_start,
+ frame_end;
+ Time
+ t=0,
+ time_start,
+ time_end;
+
+ assert(canvas);
+ curr_frame_=0;
+
+ if( !init() ){
+ if(cb) cb->error(_("Target initialisation failure"));
+ return false;
+ }
+
+ // If the description's end frame is equal to
+ // the start frame, then it is assumed that we
+ // are rendering only one frame. Correct it.
+ if(desc.get_frame_end()==desc.get_frame_start())
+ desc.set_frame_end(desc.get_frame_start()+1);
+
+ frame_start=desc.get_frame_start();
+ frame_end=desc.get_frame_end();
+ time_start=desc.get_time_start();
+ time_end=desc.get_time_end();
+
+ // Calculate the number of frames
+ total_frames=frame_end-frame_start;
+
+
+ //RendDesc rend_desc=desc;
+
+ try {
+ // Grab the time
+ int i=next_frame(t);
+
+ //synfig::info("1time_set_to %s",t.get_string().c_str());
+
+ if(i>1)
+ do{
+
+ //if(total_frames>1)
+ //for(i=0,t=time_start;i<total_frames;i++)
+ //{
+ //t=((time_end-time_start)*((Real)i/(Real)total_frames)).round(desc.get_frame_rate())+time_start;
+
+ // If we have a callback, and it returns
+ // false, go ahead and bail. (it may be a user cancel)
+ if(cb && !cb->amount_complete(total_frames-(i-1),total_frames))
+ return false;
+
+ // Set the time that we wish to render
+ if(!get_avoid_time_sync() || canvas->get_time()!=t)
+ canvas->set_time(t);
+
+ Context context;
+
+ #ifdef SYNFIG_OPTIMIZE_LAYER_TREE
+ Canvas::Handle op_canvas(Canvas::create());
+ optimize_layers(canvas->get_context(), op_canvas);
+ context=op_canvas->get_context();
+ #else
+ context=canvas->get_context();
+ #endif
+
+ // If the quality is set to zero, then we
+ // use the parametric scanline-renderer.
+ if(quality==0)
+ {
+ if(threads_<=0)
+ {
+ if(!synfig::render(context,this,desc,0))
+ return false;
+ }
+ else
+ {
+ if(!synfig::render_threaded(context,this,desc,0,threads_))
+ return false;
+ }
+ }
+ else // If quality is set otherwise, then we use the accelerated renderer
+ {
+ #if USE_PIXELRENDERING_LIMIT
+ if(desc.get_w()*desc.get_h() > PIXEL_RENDERING_LIMIT)
+ {
+ synfig::info("Render BROKEN UP! (%d pixels)", desc.get_w()*desc.get_h());
+
+ Surface surface;
+ int rowheight = PIXEL_RENDERING_LIMIT/desc.get_w();
+ if (!rowheight) rowheight = 1; // TODO: render partial lines to stay within the limit?
+ int rows = desc.get_h()/rowheight;
+ int lastrowheight = desc.get_h() - rows*rowheight;
+
+ rows++;
+
+ synfig::info("\t blockh=%d,remh=%d,totrows=%d", rowheight,lastrowheight,rows);
+
+ // loop through all the full rows
+ if(!start_frame())
+ {
+ throw(string("add_frame(): target panic on start_frame()"));
+ return false;
+ }
+
+ for(int i=0; i < rows; ++i)
+ {
+ RendDesc blockrd = desc;
+
+ //render the strip at the normal size unless it's the last one...
+ if(i == rows-1)
+ {
+ if(!lastrowheight) break;
+ blockrd.set_subwindow(0,i*rowheight,desc.get_w(),lastrowheight);
+ }
+ else
+ {
+ blockrd.set_subwindow(0,i*rowheight,desc.get_w(),rowheight);
+ }
+
+ if(!context.accelerated_render(&surface,quality,blockrd,0))
+ {
+ if(cb)cb->error(_("Accelerated Renderer Failure"));
+ return false;
+ }else
+ {
+ int y;
+ int rowspan=sizeof(Color)*surface.get_w();
+ Surface::pen pen = surface.begin();
+
+ int yoff = i*rowheight;
+
+ for(y = 0; y < blockrd.get_h(); y++, pen.inc_y())
+ {
+ Color *colordata= start_scanline(y + yoff);
+ if(!colordata)
+ {
+ throw(string("add_frame(): call to start_scanline(y) returned NULL"));
+ return false;
+ }
+
+ if(get_remove_alpha())
+ {
+ for(int i = 0; i < surface.get_w(); i++)
+ colordata[i] = Color::blend(surface[y][i],desc.get_bg_color(),1.0f);
+ }
+ else
+ memcpy(colordata,surface[y],rowspan);
+
+ if(!end_scanline())
+ {
+ throw(string("add_frame(): target panic on end_scanline()"));
+ return false;
+ }
+ }
+ }
+ }
+
+ end_frame();
+
+ }else //use normal rendering...
+ {
+ #endif
+ Surface surface;
+
+ if(!context.accelerated_render(&surface,quality,desc,0))
+ {
+ // For some reason, the accelerated renderer failed.
+ if(cb)cb->error(_("Accelerated Renderer Failure"));
+ return false;
+ }
+ else
+ {
+ // Put the surface we renderer
+ // onto the target.
+ if(!add_frame(&surface))
+ {
+ if(cb)cb->error(_("Unable to put surface on target"));
+ return false;
+ }
+ }
+ #if USE_PIXELRENDERING_LIMIT
+ }
+ #endif
+ }
+ }while((i=next_frame(t)));
+ else
+ {
+ // Set the time that we wish to render
+ if(!get_avoid_time_sync() || canvas->get_time()!=t)
+ canvas->set_time(t);
+ Context context;
+
+ #ifdef SYNFIG_OPTIMIZE_LAYER_TREE
+ Canvas::Handle op_canvas(Canvas::create());
+ optimize_layers(canvas->get_context(), op_canvas);
+ context=op_canvas->get_context();
+ #else
+ context=canvas->get_context();
+ #endif
+
+ // If the quality is set to zero, then we
+ // use the parametric scanline-renderer.
+ if(quality==0)
+ {
+ if(threads_<=0)
+ {
+ if(!synfig::render(context,this,desc,cb))
+ return false;
+ }
+ else
+ {
+ if(!synfig::render_threaded(context,this,desc,cb,threads_))
+ return false;
+ }
+ }
+ else // If quality is set otherwise, then we use the accelerated renderer
+ {
+ #if USE_PIXELRENDERING_LIMIT
+ if(desc.get_w()*desc.get_h() > PIXEL_RENDERING_LIMIT)
+ {
+ synfig::info("Render BROKEN UP! (%d pixels)", desc.get_w()*desc.get_h());
+
+ Surface surface;
+ int totalheight = desc.get_h();
+ int rowheight = PIXEL_RENDERING_LIMIT/desc.get_w();
+ if (!rowheight) rowheight = 1; // TODO: render partial lines to stay within the limit?
+ int rows = desc.get_h()/rowheight;
+ int lastrowheight = desc.get_h() - rows*rowheight;
+
+ rows++;
+
+ synfig::info("\t blockh=%d,remh=%d,totrows=%d", rowheight,lastrowheight,rows);
+
+ // loop through all the full rows
+ if(!start_frame())
+ {
+ throw(string("add_frame(): target panic on start_frame()"));
+ return false;
+ }
+
+ for(int i=0; i < rows; ++i)
+ {
+ RendDesc blockrd = desc;
+
+ //render the strip at the normal size unless it's the last one...
+ if(i == rows-1)
+ {
+ if(!lastrowheight) break;
+ blockrd.set_subwindow(0,i*rowheight,desc.get_w(),lastrowheight);
+ }
+ else
+ {
+ blockrd.set_subwindow(0,i*rowheight,desc.get_w(),rowheight);
+ }
+
+ SuperCallback sc(cb, i*rowheight, (i+1)*rowheight, totalheight);
+
+ if(!context.accelerated_render(&surface,quality,blockrd,&sc))
+ {
+ if(cb)cb->error(_("Accelerated Renderer Failure"));
+ return false;
+ }else
+ {
+ int y;
+ int rowspan=sizeof(Color)*surface.get_w();
+ Surface::pen pen = surface.begin();
+
+ int yoff = i*rowheight;
+
+ for(y = 0; y < blockrd.get_h(); y++, pen.inc_y())
+ {
+ Color *colordata= start_scanline(y + yoff);
+ if(!colordata)
+ {
+ throw(string("add_frame(): call to start_scanline(y) returned NULL"));
+ return false;
+ }
+
+ if(get_remove_alpha())
+ {
+ for(int i = 0; i < surface.get_w(); i++)
+ colordata[i] = Color::blend(surface[y][i],desc.get_bg_color(),1.0f);
+ }
+ else
+ memcpy(colordata,surface[y],rowspan);
+
+ if(!end_scanline())
+ {
+ throw(string("add_frame(): target panic on end_scanline()"));
+ return false;
+ }
+ }
+ }
+
+ //I'm done with this part
+ sc.amount_complete(100,100);
+ }
+
+ end_frame();
+
+ }else
+ {
+ #endif
+ Surface surface;
+
+ if(!context.accelerated_render(&surface,quality,desc,cb))
+ {
+ if(cb)cb->error(_("Accelerated Renderer Failure"));
+ return false;
+ }
+ else
+ {
+ // Put the surface we renderer
+ // onto the target.
+ if(!add_frame(&surface))
+ {
+ if(cb)cb->error(_("Unable to put surface on target"));
+ return false;
+ }
+ }
+ #if USE_PIXELRENDERING_LIMIT
+ }
+ #endif
+ }
+ }
+
+ }
+ catch(String str)
+ {
+ if(cb)cb->error(_("Caught string :")+str);
+ return false;
+ }
+ catch(std::bad_alloc)
+ {
+ if(cb)cb->error(_("Ran out of memory (Probably a bug)"));
+ return false;
+ }
+ catch(...)
+ {
+ if(cb)cb->error(_("Caught unknown error, rethrowing..."));
+ throw;
+ }
+ return true;
+}
+
+bool
+Target_Scanline::add_frame(const Surface *surface)
+{
+ assert(surface);
+
+
+ int y;
+ int rowspan=sizeof(Color)*surface->get_w();
+ Surface::const_pen pen=surface->begin();
+
+ if(!start_frame())
+ {
+ throw(string("add_frame(): target panic on start_frame()"));
+ return false;
+ }
+
+ for(y=0;y<surface->get_h();y++,pen.inc_y())
+ {
+ Color *colordata= start_scanline(y);
+ if(!colordata)
+ {
+ throw(string("add_frame(): call to start_scanline(y) returned NULL"));
+ return false;
+ }
+
+ if(get_remove_alpha())
+ {
+ for(int i=0;i<surface->get_w();i++)
+ colordata[i]=Color::blend((*surface)[y][i],desc.get_bg_color(),1.0f);
+ }
+ else
+ memcpy(colordata,(*surface)[y],rowspan);
+
+ if(!end_scanline())
+ {
+ throw(string("add_frame(): target panic on end_scanline()"));
+ return false;
+ }
+ }
+
+ end_frame();
+
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file target_scanline.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TARGET_SCANLINE_H
+#define __SYNFIG_TARGET_SCANLINE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "target.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class Target_Scanline
+** \brief Render-target
+** \todo writeme
+*/
+class Target_Scanline : public Target
+{
+ int threads_;
+ int curr_frame_;
+
+public:
+ typedef etl::handle<Target_Scanline> Handle;
+ typedef etl::loose_handle<Target_Scanline> LooseHandle;
+ typedef etl::handle<const Target_Scanline> ConstHandle;
+
+ Target_Scanline();
+
+ //! Renders the canvas to the target
+ virtual bool render(ProgressCallback *cb=NULL);
+
+ //! Marks the start of a frame
+ /*! \return \c true on success, \c false upon an error.
+ ** \see end_frame(), start_scanline()
+ */
+ virtual bool start_frame(ProgressCallback *cb=NULL)=0;
+
+ virtual int next_frame(Time& time);
+
+ //! Marks the end of a frame
+ /*! \see start_frame() */
+ virtual void end_frame()=0;
+
+ //! Marks the start of a scanline
+ /*! \param scanline Which scanline is going to be rendered.
+ ** \return The address where the target wants the scanline
+ ** to be written.
+ ** \warning Must be called after start_frame()
+ ** \see end_scanline(), start_frame()
+ */
+ virtual Color * start_scanline(int scanline)=0;
+
+ //! Marks the end of a scanline
+ /*! Takes the data that was put at the address returned to by start_scanline()
+ ** and does whatever it is supose to do with it.
+ ** \return \c true on success, \c false on failure.
+ ** \see start_scanline()
+ */
+ virtual bool end_scanline()=0;
+
+ void set_threads(int x) { threads_=x; }
+
+ int get_threads()const { return threads_; }
+
+ bool add_frame(const synfig::Surface *surface);
+private:
+}; // END of class Target_Scanline
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file target_tile.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "target_tile.h"
+#include "string.h"
+#include "surface.h"
+#include "render.h"
+#include "canvas.h"
+#include "context.h"
+#include "general.h"
+#include <ETL/clock>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+const unsigned int DEF_TILE_WIDTH = 64;
+const unsigned int DEF_TILE_HEIGHT= 64;
+
+#define SYNFIG_OPTIMIZE_LAYER_TREE 1
+#ifdef _DEBUG
+#define SYNFIG_DISPLAY_EFFICIENCY 1
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Target_Tile::Target_Tile():
+ threads_(2),
+ tile_w_(DEF_TILE_WIDTH),
+ tile_h_(DEF_TILE_HEIGHT),
+ curr_tile_(0),
+ clipping_(true)
+{
+ curr_frame_=0;
+}
+
+int
+Target_Tile::next_frame(Time& time)
+{
+ int
+ total_frames(1),
+ frame_start(0),
+ frame_end(0);
+ Time
+ time_start(0),
+ time_end(0);
+
+ // If the description's end frame is equal to
+ // the start frame, then it is assumed that we
+ // are rendering only one frame. Correct it.
+ if(desc.get_frame_end()==desc.get_frame_start())
+ desc.set_frame_end(desc.get_frame_start()+1);
+
+ frame_start=desc.get_frame_start();
+ frame_end=desc.get_frame_end();
+ time_start=desc.get_time_start();
+ time_end=desc.get_time_end();
+
+ // Calculate the number of frames
+ total_frames=frame_end-frame_start;
+ if(total_frames<=0)total_frames=1;
+
+ //RendDesc rend_desc=desc;
+ //rend_desc.set_gamma(1);
+
+// int total_tiles(total_tiles());
+ time=(time_end-time_start)*curr_frame_/total_frames+time_start;
+ curr_frame_++;
+
+/* synfig::info("curr_frame_: %d",curr_frame_);
+ synfig::info("total_frames: %d",total_frames);
+ synfig::info("time_end: %s",time_end.get_string().c_str());
+ synfig::info("time_start: %s",time_start.get_string().c_str());
+*/
+// synfig::info("time: %s",time.get_string().c_str());
+
+ return total_frames- curr_frame_+1;
+}
+
+int
+Target_Tile::next_tile(int& x, int& y)
+{
+ // Width of the image(in tiles)
+ int tw(rend_desc().get_w()/tile_w_);
+ int th(rend_desc().get_h()/tile_h_);
+
+ // Add the last tiles (which will be clipped)
+ if(rend_desc().get_w()%tile_w_!=0)tw++;
+ if(rend_desc().get_h()%tile_h_!=0)th++;
+
+ x=(curr_tile_%tw)*tile_h_;
+ y=(curr_tile_/tw)*tile_w_;
+
+ curr_tile_++;
+ return (tw*th)-curr_tile_+1;
+}
+
+bool
+synfig::Target_Tile::render_frame_(Context context,ProgressCallback *cb)
+{
+ if(tile_w_<=0||tile_h_<=0)
+ {
+ if(cb)cb->error(_("Bad Tile Size"));
+ return false;
+ }
+ const RendDesc &rend_desc(desc);
+#define total_tiles total_tiles()
+
+ etl::clock total_time;
+ etl::clock::value_type work_time(0);
+ etl::clock::value_type find_tile_time(0);
+ etl::clock::value_type add_tile_time(0);
+ total_time.reset();
+
+ // If the quality is set to zero, then we
+ // use the parametric scanline-renderer.
+ if(get_quality()==0)
+ {
+ Surface surface;
+
+ RendDesc tile_desc;
+ int x,y,w,h;
+ int i;
+ etl::clock tile_timer;
+ tile_timer.reset();
+ while((i=next_tile(x,y)))
+ {
+ find_tile_time+=tile_timer();
+ SuperCallback super(cb,(total_tiles-i+1)*1000,(total_tiles-i+2)*1000,total_tiles*1000);
+ if(!super.amount_complete(0,1000))
+ return false;
+ //if(cb && !cb->amount_complete(total_tiles-i,total_tiles))
+ // return false;
+
+ // Perform clipping on the tile
+ if(clipping_)
+ {
+ w=x+tile_w_<rend_desc.get_w()?tile_w_:rend_desc.get_w()-x;
+ h=y+tile_h_<rend_desc.get_h()?tile_h_:rend_desc.get_h()-y;
+ if(w<=0||h<=0)continue;
+ }
+ else
+ {
+ w=tile_w_;
+ h=tile_h_;
+ }
+
+ tile_desc=rend_desc;
+ tile_desc.set_subwindow(x,y,w,h);
+ if(!parametric_render(context, surface, tile_desc,&super))
+ {
+ // For some reason, the parametric renderer failed.
+ if(cb)cb->error(_("Parametric Renderer Failure"));
+ return false;
+ }
+ else
+ {
+ if(!surface)
+ {
+ if(cb)cb->error(_("Bad surface"));
+ return false;
+ }
+ if(get_remove_alpha())
+ for(int i=0;i<surface.get_w()*surface.get_h();i++)
+ surface[0][i]=Color::blend(surface[0][i],desc.get_bg_color(),1.0f);
+
+ // Add the tile to the target
+ if(!add_tile(surface,x,y))
+ {
+ if(cb)cb->error(_("add_tile():Unable to put surface on target"));
+ return false;
+ }
+ }
+ tile_timer.reset();
+ }
+ }
+ else // If quality is set otherwise, then we use the accelerated renderer
+ {
+ Surface surface;
+
+ RendDesc tile_desc;
+ int x,y,w,h;
+ int i;
+ etl::clock tile_timer;
+ tile_timer.reset();
+ while((i=next_tile(x,y)))
+ {
+ find_tile_time+=tile_timer();
+ SuperCallback super(cb,(total_tiles-i)*1000,(total_tiles-i+1)*1000,total_tiles*1000);
+ if(!super.amount_complete(0,1000))
+ return false;
+// if(cb && !cb->amount_complete(total_tiles-i,total_tiles))
+// return false;
+ // Perform clipping on the tile
+ if(clipping_)
+ {
+ w=x+tile_w_<rend_desc.get_w()?tile_w_:rend_desc.get_w()-x;
+ h=y+tile_h_<rend_desc.get_h()?tile_h_:rend_desc.get_h()-y;
+ if(w<=0||h<=0)continue;
+ }
+ else
+ {
+ w=tile_w_;
+ h=tile_h_;
+ }
+
+ tile_desc=rend_desc;
+ tile_desc.set_subwindow(x,y,w,h);
+
+ etl::clock timer2;
+ timer2.reset();
+
+ if(!context.accelerated_render(&surface,get_quality(),tile_desc,&super))
+ {
+ // For some reason, the accelerated renderer failed.
+ if(cb)cb->error(_("Accelerated Renderer Failure"));
+ return false;
+ }
+ else
+ {
+ work_time+=timer2();
+ if(!surface)
+ {
+ if(cb)cb->error(_("Bad surface"));
+ return false;
+ }
+ if(get_remove_alpha())
+ for(int i=0;i<surface.get_w()*surface.get_h();i++)
+ surface[0][i]=Color::blend(surface[0][i],desc.get_bg_color(),1.0f);
+
+ etl::clock timer;
+ timer.reset();
+ // Add the tile to the target
+ if(!add_tile(surface,x,y))
+ {
+ if(cb)cb->error(_("add_tile():Unable to put surface on target"));
+ return false;
+ }
+ add_tile_time+=timer();
+ }
+ tile_timer.reset();
+ }
+ }
+ if(cb && !cb->amount_complete(total_tiles,total_tiles))
+ return false;
+
+#if SYNFIG_DISPLAY_EFFICIENCY==1
+ synfig::info(">>>>>> Render Time: %fsec, Find Tile Time: %fsec, Add Tile Time: %fsec, Total Time: %fsec",work_time,find_tile_time,add_tile_time,total_time());
+ synfig::info(">>>>>> FRAME EFFICIENCY: %f%%",(100.0f*work_time/total_time()));
+#endif
+#undef total_tiles
+ return true;
+}
+
+bool
+synfig::Target_Tile::render(ProgressCallback *cb)
+{
+ SuperCallback super_cb;
+ int
+ i=0,
+ total_frames,
+ frame_start,
+ frame_end;
+ Time
+ t=0,
+ time_start,
+ time_end;
+
+ assert(canvas);
+ curr_frame_=0;
+ init();
+ if( !init() ){
+ if(cb) cb->error(_("Target initialisation failure"));
+ return false;
+ }
+
+
+ // If the description's end frame is equal to
+ // the start frame, then it is assumed that we
+ // are rendering only one frame. Correct it.
+ if(desc.get_frame_end()==desc.get_frame_start())
+ desc.set_frame_end(desc.get_frame_start()+1);
+
+ frame_start=desc.get_frame_start();
+ frame_end=desc.get_frame_end();
+ time_start=desc.get_time_start();
+ time_end=desc.get_time_end();
+
+ // Calculate the number of frames
+ total_frames=frame_end-frame_start;
+
+
+
+ try {
+ // Grab the time
+ i=next_frame(t);
+
+ //synfig::info("1time_set_to %s",t.get_string().c_str());
+
+ if(i>=1)
+ {
+ do
+ {
+ curr_tile_=0;
+
+ // If we have a callback, and it returns
+ // false, go ahead and bail. (maybe a use cancel)
+ if(cb && !cb->amount_complete(total_frames-(i-1),total_frames))
+ return false;
+
+ if(!start_frame(cb))
+ return false;
+
+ // Set the time that we wish to render
+ //if(!get_avoid_time_sync() || canvas->get_time()!=t)
+ canvas->set_time(t);
+
+ Context context;
+
+ #ifdef SYNFIG_OPTIMIZE_LAYER_TREE
+ Canvas::Handle op_canvas(Canvas::create());
+ optimize_layers(canvas->get_context(), op_canvas);
+ context=op_canvas->get_context();
+ #else
+ context=canvas->get_context();
+ #endif
+
+/*
+ #ifdef SYNFIG_OPTIMIZE_LAYER_TREE
+ Context context;
+ Canvas::Handle op_canvas(Canvas::create());
+ // Set the time that we wish to render
+ canvas->set_time(t);
+ optimize_layers(canvas->get_context(), op_canvas);
+ context=op_canvas->get_context();
+ #else
+ Context context;
+ // Set the time that we wish to render
+ canvas->set_time(t);
+ context=canvas->get_context();
+ #endif
+*/
+
+ if(!render_frame_(context,0))
+ return false;
+ end_frame();
+ }while((i=next_frame(t)));
+ //synfig::info("tilerenderer: i=%d, t=%s",i,t.get_string().c_str());
+ }
+ else
+ {
+ curr_tile_=0;
+
+ if(!start_frame(cb))
+ return false;
+
+ // Set the time that we wish to render
+// if(!get_avoid_time_sync() || canvas->get_time()!=t)
+ canvas->set_time(t);
+
+ //synfig::info("2time_set_to %s",t.get_string().c_str());
+
+ Context context;
+
+ #ifdef SYNFIG_OPTIMIZE_LAYER_TREE
+ Canvas::Handle op_canvas(Canvas::create());
+ optimize_layers(canvas->get_context(), op_canvas);
+ context=op_canvas->get_context();
+ #else
+ context=canvas->get_context();
+ #endif
+
+ if(!render_frame_(context, cb))
+ return false;
+ end_frame();
+ }
+
+ }
+ catch(String str)
+ {
+ if(cb)cb->error(_("Caught string :")+str);
+ return false;
+ }
+ catch(std::bad_alloc)
+ {
+ if(cb)cb->error(_("Ran out of memory (Probably a bug)"));
+ return false;
+ }
+ catch(...)
+ {
+ if(cb)cb->error(_("Caught unknown error, rethrowing..."));
+ throw;
+ }
+ return true;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file target_tile.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TARGET_TILE_H
+#define __SYNFIG_TARGET_TILE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "target.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class Target_Tile
+** \brief Render-target
+** \todo writeme
+*/
+class Target_Tile : public Target
+{
+ int threads_;
+ int tile_w_;
+ int tile_h_;
+ int curr_tile_;
+ int curr_frame_;
+ bool clipping_;
+public:
+ typedef etl::handle<Target_Tile> Handle;
+ typedef etl::loose_handle<Target_Tile> LooseHandle;
+ typedef etl::handle<const Target_Tile> ConstHandle;
+
+ Target_Tile();
+
+ //! Renders the canvas to the target
+ virtual bool render(ProgressCallback *cb=NULL);
+
+ //! Determines which tile needs to be rendered next.
+ /*! Most cases will not have to redefine this function.
+ ** The default should be adequate in nearly all situations.
+ ** \returns The number of tiles left to go <i>plus one</i>.
+ ** This means that whenever this function returns zero,
+ ** there are no more tiles to render and that any value
+ ** in \a x or \a y should be disregarded. */
+ virtual int next_tile(int& x, int& y);
+
+ virtual int next_frame(Time& time);
+
+ //! Adds the tile at \a x , \a y contained in \a surface
+ virtual bool add_tile(const synfig::Surface &surface, int x, int y)=0;
+
+ virtual int total_tiles()const
+ {
+ // Width of the image(in tiles)
+ const int tw(rend_desc().get_w()/tile_w_+(rend_desc().get_w()%tile_w_?1:0));
+ const int th(rend_desc().get_h()/tile_h_+(rend_desc().get_h()%tile_h_?1:0));
+
+ return tw*th;
+ }
+
+ //! Marks the start of a frame
+ /*! \return \c true on success, \c false upon an error.
+ ** \see end_frame(), start_scanline()
+ */
+ virtual bool start_frame(ProgressCallback *cb=NULL)=0;
+
+ //! Marks the end of a frame
+ /*! \see start_frame() */
+ virtual void end_frame()=0;
+
+ void set_threads(int x) { threads_=x; }
+
+ int get_threads()const { return threads_; }
+
+ void set_tile_w(int w) { tile_w_=w; }
+
+ int get_tile_w()const { return tile_w_; }
+
+ void set_tile_h(int h) { tile_h_=h; }
+
+ int get_tile_h()const { return tile_h_; }
+
+ bool get_clipping()const { return clipping_; }
+
+ void set_clipping(bool x) { clipping_=x; }
+
+private:
+
+ bool render_frame_(Context context,ProgressCallback *cb=0);
+
+}; // END of class Target_Tile
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file time.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "time.h"
+#include <ETL/stringf>
+#include <ETL/misc>
+#include "general.h"
+#include <cmath>
+#include <cassert>
+#include <algorithm>
+#include <ctype.h>
+#include <math.h>
+
+
+#ifdef WIN32
+#include <float.h>
+#ifndef isnan
+extern "C" { int _isnan(double x); }
+#define isnan _isnan
+#endif
+#endif
+
+// For some reason isnan() isn't working on macosx any more.
+// This is a quick fix.
+#if defined(__APPLE__) && !defined(SYNFIG_ISNAN_FIX)
+#ifdef isnan
+#undef isnan
+#endif
+inline bool isnan(double x) { return x != x; }
+inline bool isnan(float x) { return x != x; }
+#define SYNFIG_ISNAN_FIX 1
+#endif
+
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+#define tolower ::tolower
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Time::Time(const String &str_, float fps):
+ value_(0)
+{
+ String str(str_);
+ std::transform(str.begin(),str.end(),str.begin(),&tolower);
+
+ // Start/Begin Of Time
+ if(str=="sot" || str=="bot")
+ {
+ operator=(begin());
+ return;
+ }
+ // End Of Time
+ if(str=="eot")
+ {
+ operator=(end());
+ return;
+ }
+
+
+ unsigned int pos=0;
+ int read;
+ float amount;
+
+ // Now try to read it in the letter-abreviated format
+ while(pos<str.size() && sscanf(String(str,pos).c_str(),"%f%n",&amount,&read))
+ {
+ pos+=read;
+ if(pos>=str.size() || read==0)
+ {
+ // Throw up a warning if there are no units
+ // and the amount isn't zero. There is no need
+ // to warn about units if the value is zero
+ // it is the only case where units are irrelevant.
+ if(amount!=0)
+ synfig::warning("Time(): No unit provided in time code, assuming SECONDS (\"%s\")",str.c_str());
+ value_+=amount;
+ return;
+ }
+ switch(str[pos])
+ {
+ case 'h':
+ case 'H':
+ value_+=amount*3600;
+ break;
+ case 'm':
+ case 'M':
+ value_+=amount*60;
+ break;
+ case 's':
+ case 'S':
+ value_+=amount;
+ break;
+ case 'f':
+ case 'F':
+ if(fps)
+ value_+=amount/fps;
+ else
+ synfig::warning("Time(): Individual frames referenced, but frame rate is unknown");
+ break;
+ case ':':
+ // try to read it in as a traditional time format
+ {
+ int hour,minute,second;
+ float frame;
+ if(fps && sscanf(str.c_str(),"%d:%d:%d.%f",&hour,&minute,&second,&frame)==4)
+ {
+ value_=frame/fps+(hour*3600+minute*60+second);
+ return;
+ }
+
+ if(sscanf(str.c_str(),"%d:%d:%d",&hour,&minute,&second)==3)
+ {
+ value_=hour*3600+minute*60+second;
+ return;
+ }
+ }
+ synfig::warning("Time(): Bad time format");
+ break;
+
+ default:
+ value_+=amount;
+ synfig::warning("Time(): Unexpected character '%c' when parsing time string \"%s\"",str[pos],str.c_str());
+ break;
+ }
+ pos++;
+ amount=0;
+ }
+}
+
+String
+Time::get_string(float fps, Time::Format format)const
+{
+ Time time(*this);
+
+ if(time<=begin())
+ return "SOT"; // Start Of Time
+ if(time>=end())
+ return "EOT"; // End Of Time
+
+ if(fps<0)fps=0;
+
+ if(ceil(time.value_)-time.value_<epsilon_())
+ time.value_=ceil(time.value_);
+
+ int hour,minute;
+
+ hour=time/3600;time-=hour*3600;
+ minute=time/60;time-=minute*60;
+
+ // <= is redefined, so this means "is the FORMAT_VIDEO bit set in the format?"
+ if(format<=FORMAT_VIDEO)
+ {
+ int second;
+ second=time;time-=second;
+
+ if(fps)
+ {
+ int frame;
+ frame=round_to_int(time*fps);
+
+ return strprintf("%02d:%02d:%02d.%02d",hour,minute,second,frame);
+ }
+ else
+ return strprintf("%02d:%02d:%02d",hour,minute,second);
+ }
+
+ String ret;
+ bool started = false;
+
+ if(format<=FORMAT_FULL || hour)
+ {
+ ret+=strprintf(format<=FORMAT_NOSPACES?"%dh":"%dh ",hour);
+ started = true;
+ }
+
+ if(format<=FORMAT_FULL || minute)
+ {
+ ret+=strprintf(format<=FORMAT_NOSPACES?"%dm":"%dm ",minute);
+ started = true;
+ }
+
+ if(fps)
+ {
+ int second;
+ float frame;
+ second=time;time-=second;
+ frame=time*fps;
+ if(format<=FORMAT_FULL || second)
+ {
+ ret+=strprintf(format<=FORMAT_NOSPACES?"%ds":"%ds ",(int)second);
+ started = true;
+ }
+
+ if(format<=FORMAT_FULL || frame || !started)
+ {
+ if(abs(frame-floor(frame)>=epsilon_()))
+ ret+=strprintf("%0.3ff",frame);
+ else
+ ret+=strprintf("%0.0ff",frame);
+ }
+ }
+ else
+ {
+ float second;
+ second=time;
+ if(format<=FORMAT_FULL || second || !started)
+ {
+ if(abs(second-floor(second))>=epsilon_())
+ ret+=strprintf("%0.8fs",second);
+ else
+ ret+=strprintf("%0.0fs",second);
+ }
+ }
+
+ return ret;
+}
+
+Time
+Time::round(float fps)const
+{
+ assert(fps>0);
+
+ value_type time(*this);
+
+ time*=fps;
+
+ if(abs(time-floor(time))<0.5)
+ return floor(time)/fps;
+ else
+ return ceil(time)/fps;
+}
+
+//! \writeme
+bool
+Time::is_valid()const
+{
+ return !isnan(value_);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file time.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TIME_H
+#define __SYNFIG_TIME_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "string_decl.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class Time
+** \todo writeme
+** \see TimeFormat, time_to_string(), string_to_time()
+*/
+class Time
+{
+public:
+ typedef double value_type;
+
+ /*! \enum Format
+ ** \todo writeme
+ ** \see Time, get_string() */
+ enum Format
+ {
+ FORMAT_NORMAL=0, //!< Represents the default method of printing the time
+ FORMAT_NOSPACES=(1<<0), //!< Remove any whitespace
+ FORMAT_FULL=(1<<1), //!< Do not remove units that have "zero" value
+ FORMAT_VIDEO=(1<<2), //!< Use the HH:MM:SS.ff format
+
+ FORMAT_END=(1<<4) //!< \internal Not used
+ }; // END of enum Format
+
+private:
+ value_type value_;
+
+ static const value_type epsilon_() { return static_cast<value_type>(0.0005); }
+
+public:
+ Time() { }
+
+ Time(const value_type &x):value_(x) { }
+
+ Time(int x):value_(x) { }
+
+ Time(int hour, int minute, float second):value_(static_cast<value_type>(second+hour*3600+minute*60)) { }
+
+ //! Constructs Time from the given string.
+ /*! \note If the string references frames, then the
+ ** frame rate (\a fps) should be provided from the
+ ** correct source. (Which is most likely the RendDesc
+ ** of the current Canvas)
+ ** The frame count will be ignored if the
+ ** FPS is not given. */
+ Time(const String &string, float fps=0);
+
+ //! Marks the exclusive negative boundary of time
+ static const Time begin() { return static_cast<synfig::Time>(-32767.0f*512.0f); }
+
+ //! Marks the exclusive positive boundary of time
+ static const Time end() { return static_cast<synfig::Time>(32767.0f*512.0f); }
+
+ //! Marks zero time
+ static const Time zero() { return static_cast<synfig::Time>(0); }
+
+ //! The amount of allowable error in calculations
+ static const Time epsilon() { return static_cast<synfig::Time>(epsilon_()); }
+
+ //! Returns a string describing the current time value
+ /*! \see Format */
+ String get_string(float fps=0, Time::Format format=FORMAT_NORMAL)const;
+
+ //! \writeme
+ bool is_valid()const;
+
+ //! Rounds time to the nearest frame for the given frame rate, \a fps
+ Time round(float fps)const;
+
+ bool is_equal(const Time& rhs)const { return (value_>rhs.value_)?value_-rhs.value_<=epsilon_():rhs.value_-value_<=epsilon_(); }
+ bool is_less_than(const Time& rhs)const { return rhs.value_-value_ > epsilon_(); }
+ bool is_more_than(const Time& rhs)const { return value_-rhs.value_ > epsilon_(); }
+
+ operator double()const { return value_; }
+
+ template<typename U> bool operator<(const U& rhs)const { return value_<rhs; }
+ template<typename U> bool operator>(const U& rhs)const { return value_>rhs; }
+ template<typename U> bool operator<=(const U& rhs)const { return value_<=rhs; }
+ template<typename U> bool operator>=(const U& rhs)const { return value_>=rhs; }
+ template<typename U> bool operator==(const U& rhs)const { return value_==rhs; }
+ template<typename U> bool operator!=(const U& rhs)const { return value_!=rhs; }
+
+#if 0
+ bool operator<(const Time& rhs)const { return value_<rhs.value_; }
+ bool operator>(const Time& rhs)const { return value_>rhs.value_; }
+ bool operator<=(const Time& rhs)const { return value_<=rhs.value_; }
+ bool operator>=(const Time& rhs)const { return value_>=rhs.value_; }
+ bool operator==(const Time& rhs)const { return value_==rhs.value_; }
+ bool operator!=(const Time& rhs)const { return value_!=rhs.value_; }
+#else
+ bool operator<(const Time& rhs)const { return is_less_than(rhs); }
+ bool operator>(const Time& rhs)const { return is_more_than(rhs); }
+ bool operator<=(const Time& rhs)const { return is_less_than(rhs)||is_equal(rhs); }
+ bool operator>=(const Time& rhs)const { return is_more_than(rhs)||is_equal(rhs); }
+ bool operator==(const Time& rhs)const { return is_equal(rhs); }
+ bool operator!=(const Time& rhs)const { return !is_equal(rhs); }
+#endif
+
+ template<typename U> const Time& operator+=(const U &rhs) { value_+=static_cast<value_type>(rhs); return *this; }
+ template<typename U> const Time& operator-=(const U &rhs) { value_-=static_cast<value_type>(rhs); return *this; }
+ template<typename U> const Time& operator*=(const U &rhs) { value_*=static_cast<value_type>(rhs); return *this; }
+ template<typename U> const Time& operator/=(const U &rhs) { value_/=static_cast<value_type>(rhs); return *this; }
+
+ template<typename U> Time operator+(const U &rhs)const { return value_+static_cast<value_type>(rhs); }
+ template<typename U> Time operator-(const U &rhs)const { return value_-static_cast<value_type>(rhs); }
+ template<typename U> Time operator*(const U &rhs)const { return value_*static_cast<value_type>(rhs); }
+ template<typename U> Time operator/(const U &rhs)const { return value_/static_cast<value_type>(rhs); }
+
+ Time operator-()const { return -value_; }
+}; // END of class Time
+
+//! This operator allows the combining of Time::Format flags using the '|' operator
+/*! \see Time::Format, Time::get_string() */
+inline Time::Format operator|(Time::Format lhs, Time::Format rhs)
+{ return static_cast<Time::Format>((int)lhs|(int)rhs); }
+
+//! This operator is for checking Time::Format flags.
+/*! Don't think of it as "less then or equal to", but think of it
+** like an arrow. Is \a rhs inside of \a lhs ?
+** \see Time::Format, Time::get_string() */
+inline bool operator<=(Time::Format lhs, Time::Format rhs)
+{ return (static_cast<int>(lhs) & static_cast<int>(rhs))==static_cast<int>(rhs); }
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file timepointcollect.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "timepointcollect.h"
+#include "valuenode_animated.h"
+#include "layer.h"
+#include "canvas.h"
+#include "value.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+//! \writeme
+int
+synfig::waypoint_collect(set<Waypoint, std::less<UniqueID> >& waypoint_set,const Time& time, const etl::handle<Node>& node)
+{
+ const TimePointSet& timepoint_set(node->get_times());
+
+ // Check to see if there is anything in here at the given time
+ if(timepoint_set.find(time)==timepoint_set.end())
+ return 0;
+
+ // Check if we are a linkable value node
+ LinkableValueNode::Handle linkable_value_node;
+ linkable_value_node=linkable_value_node.cast_dynamic(node);
+ if(linkable_value_node)
+ {
+ const int link_count(linkable_value_node->link_count());
+ int i,ret(0);
+ for(i=0;i<link_count;i++)
+ {
+ ret+=waypoint_collect(waypoint_set,time,linkable_value_node->get_link(i).get());
+ }
+ return ret;
+ }
+
+ // Check if we are a layer
+ Layer::Handle layer;
+ layer=layer.cast_dynamic(node);
+ if(layer)
+ {
+ const Layer::DynamicParamList& dyn_param_list(layer->dynamic_param_list());
+ Layer::DynamicParamList::const_iterator iter;
+ int ret(0);
+ for(iter=dyn_param_list.begin();iter!=dyn_param_list.end();++iter)
+ {
+ ret+=waypoint_collect(waypoint_set,time,iter->second);
+ }
+ ValueBase canvas_value(layer->get_param("canvas"));
+ if(canvas_value.get_type()==ValueBase::TYPE_CANVAS)
+ {
+ ret+=waypoint_collect(waypoint_set,time,Canvas::Handle(canvas_value.get(Canvas::Handle())));
+ }
+ return ret;
+ }
+
+ // Check if we are a canvas
+ Canvas::Handle canvas;
+ canvas=canvas.cast_dynamic(node);
+ if(canvas)
+ {
+ Canvas::const_iterator iter;
+ int ret(0);
+ for(iter=canvas->begin();iter!=canvas->end();++iter)
+ ret+=waypoint_collect(waypoint_set,time,*iter);
+ return ret;
+ }
+
+ // Check if we are an animated value node
+ ValueNode_Animated::Handle value_node_animated;
+ value_node_animated=value_node_animated.cast_dynamic(node);
+ if(value_node_animated)
+ {
+ try{
+ Waypoint waypoint=*value_node_animated->find(time);
+
+ // If it is already in the waypoint set, then
+ // don't bother adding it again
+ if(waypoint_set.find(waypoint)!=waypoint_set.end())
+ {
+ return 0;
+ }
+ waypoint_set.insert(waypoint);
+ return 1;
+ }catch(...)
+ {
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+//! \writeme
+int
+synfig::activepoint_collect(set<Activepoint, std::less<UniqueID> >& /*activepoint_set*/,const Time& time, const etl::handle<Node>& node)
+{
+ const TimePointSet& timepoint_set(node->get_times());
+
+ // Check to see if there is anything in here at the given time
+ if(timepoint_set.find(time)==timepoint_set.end());
+ return 0;
+
+ return 0;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file timepointcollect.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TIMEPOINTCOLLECT_H
+#define __SYNFIG_TIMEPOINTCOLLECT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <set>
+#include "activepoint.h"
+#include "waypoint.h"
+#include "node.h"
+#include "time.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+//! \writeme
+int waypoint_collect(std::set<Waypoint, std::less<UniqueID> >& waypoint_set,const Time& time, const etl::handle<Node>& node);
+
+//! \writeme
+int activepoint_collect(std::set<Activepoint, std::less<UniqueID> >& activepoint_set,const Time& time, const etl::handle<Node>& node);
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file transform.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "transform.h"
+#include <algorithm>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+synfig::GUID
+TransformStack::get_guid()const
+{
+ GUID ret(0);
+
+ for(const_iterator iter(begin());iter!=end();++iter)
+ ret%=(*iter)->get_guid();
+ return ret;
+}
+
+synfig::Vector
+TransformStack::perform(const synfig::Vector& x)const
+{
+ synfig::Vector ret(x);
+
+ for(const_reverse_iterator iter(rbegin());iter!=rend();++iter)
+ ret=(*iter)->perform(ret);
+
+ return ret;
+}
+
+synfig::Vector
+TransformStack::unperform(const synfig::Vector& x)const
+{
+ synfig::Vector ret(x);
+
+ for(const_iterator iter(begin());iter!=end();++iter)
+ ret=(*iter)->unperform(ret);
+
+ return ret;
+}
+
+synfig::Rect
+TransformStack::perform(const synfig::Rect& x)const
+{
+ Point min(x.get_min());
+ Point max(x.get_max());
+ Rect ret(perform(min),perform(max));
+
+ std::swap(min[1],max[1]);
+ ret
+ .expand(perform(min))
+ .expand(perform(max))
+ ;
+ return ret;
+}
+
+synfig::Rect
+TransformStack::unperform(const synfig::Rect& x)const
+{
+ Point min(x.get_min());
+ Point max(x.get_max());
+ Rect ret(unperform(min),unperform(max));
+
+ std::swap(min[1],max[1]);
+ ret
+ .expand(unperform(min))
+ .expand(unperform(max))
+ ;
+ return ret;
+}
+
+synfig::Rect
+Transform::perform(const synfig::Rect& x)const
+{
+ if(x.area()>1000000000000.0)
+ return Rect::full_plane();
+
+ Point min(x.get_min());
+ Point max(x.get_max());
+
+ Rect ret(perform(min),perform(max));
+
+ std::swap(min[1],max[1]);
+ ret
+ .expand(perform(min))
+ .expand(perform(max))
+ ;
+ return ret;
+}
+
+synfig::Rect
+Transform::unperform(const synfig::Rect& x)const
+{
+ if(x.area()>1000000000000.0)
+ return Rect::full_plane();
+
+ Point min(x.get_min());
+ Point max(x.get_max());
+
+ Rect ret(unperform(min),unperform(max));
+
+ std::swap(min[1],max[1]);
+ ret
+ .expand(unperform(min))
+ .expand(unperform(max))
+ ;
+ return ret;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file transform.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TRANSFORM_H
+#define __SYNFIG_TRANSFORM_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/handle>
+#include "vector.h"
+#include <list>
+#include "rect.h"
+#include "guid.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Transform : public etl::shared_object
+{
+ GUID guid_;
+
+public:
+ typedef etl::handle<Transform> Handle;
+
+protected:
+ Transform(const GUID& guid=GUID(0)):guid_(guid) { }
+
+public:
+
+ const GUID& get_guid()const { return guid_; }
+
+ virtual ~Transform() { }
+ virtual synfig::Vector perform(const synfig::Vector& x)const=0;
+ virtual synfig::Vector unperform(const synfig::Vector& x)const=0;
+
+ virtual synfig::Rect perform(const synfig::Rect& x)const;
+ virtual synfig::Rect unperform(const synfig::Rect& x)const;
+
+}; // END of class Transform
+
+class TransformStack : public std::list<Transform::Handle>
+{
+public:
+ GUID get_guid()const;
+
+ synfig::Vector perform(const synfig::Vector& x)const;
+ synfig::Vector unperform(const synfig::Vector& x)const;
+
+ synfig::Rect perform(const synfig::Rect& x)const;
+ synfig::Rect unperform(const synfig::Rect& x)const;
+
+ void push(const Transform::Handle& x) { if(x)push_back(x); }
+ void pop() { pop_back(); }
+}; // END of class TransformStack
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file types.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TYPES_H
+#define __SYNFIG_TYPES_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <cmath>
+
+#ifndef SYNFIG_NO_ANGLE
+#include "angle.h"
+#endif
+
+#include "time.h"
+#include "vector.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file uniqueid.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "uniqueid.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace synfig;
+
+/* === G L O B A L S ======================================================= */
+
+static int uniqueid_pool_(0);
+
+/* === M E T H O D S ======================================================= */
+
+int
+synfig::UniqueID::next_id()
+{
+ return ++uniqueid_pool_;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file uniqueid.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_UNIQUEID_H
+#define __SYNFIG_UNIQUEID_H
+
+/* === H E A D E R S ======================================================= */
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class UniqueIDLessThan;
+
+/*! \class UniqueID
+** \brief \todo
+*/
+class UniqueID
+{
+ friend class UniqueIDLessThan;
+
+ int id_;
+
+ explicit UniqueID(int id_):id_(id_) { }
+
+ static int next_id();
+
+public:
+
+ //! Returns the internal unique identifier for this object.
+ /*! The return value from this isn't really useful for
+ ** much other than debug output. Nonetheless, that is
+ ** one step above useless, so here it is. */
+ const int &get_uid()const { return id_; }
+
+ UniqueID():id_(next_id()) { }
+
+ void make_unique() { id_=next_id(); }
+
+ static const UniqueID nil() { return UniqueID(0); }
+
+ operator bool()const { return static_cast<bool>(id_); }
+
+ void mimic(const UniqueID& x) { id_=x.id_; }
+
+ bool operator==(const UniqueID &rhs)const { return id_==rhs.id_; }
+ bool operator!=(const UniqueID &rhs)const { return id_!=rhs.id_; }
+ bool operator<(const UniqueID &rhs)const { return id_<rhs.id_; }
+}; // END of class UniqueID
+
+/*! \class UniqueIDLessThan
+** \brief A function class used for sorting based on UniqueIDs
+*/
+class UniqueIDLessThan
+{
+public:
+ bool operator()(const UniqueID &lhs, const UniqueID &rhs)const
+ { return lhs.id_<rhs.id_; }
+};
+
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file value.cpp
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "value.h"
+#include "general.h"
+#include <ETL/stringf>
+#include "canvas.h"
+#include "gradient.h"
+
+
+
+#include "vector.h"
+#include "time.h"
+#include "segment.h"
+#include "color.h"
+
+#endif
+
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ValueBase::ValueBase():type(TYPE_NIL),data(0),ref_count(0),loop_(0)
+{
+}
+
+ValueBase::ValueBase(Type x):
+ type(x),
+ data(0),
+ loop_(0)
+{
+ switch(type)
+ {
+ case TYPE_BOOL: data=static_cast<void*>(new bool()); break;
+ case TYPE_INTEGER: data=static_cast<void*>(new int()); break;
+ case TYPE_ANGLE: data=static_cast<void*>(new Angle()); break;
+ case TYPE_VECTOR: data=static_cast<void*>(new Vector()); break;
+ case TYPE_TIME: data=static_cast<void*>(new Time()); break;
+ case TYPE_REAL: data=static_cast<void*>(new Real()); break;
+ case TYPE_COLOR: data=static_cast<void*>(new Color()); break;
+ case TYPE_SEGMENT: data=static_cast<void*>(new Segment()); break;
+ case TYPE_BLINEPOINT: data=static_cast<void*>(new BLinePoint()); break;
+ case TYPE_LIST: data=static_cast<void*>(new list_type()); break;
+ case TYPE_STRING: data=static_cast<void*>(new String()); break;
+ case TYPE_GRADIENT: data=static_cast<void*>(new Gradient()); break;
+ case TYPE_CANVAS: data=static_cast<void*>(new etl::handle<Canvas>()); break;
+ default: break;
+ }
+}
+
+ValueBase::~ValueBase()
+{
+ clear();
+}
+
+const char*
+ValueBase::get(const char*)const
+{
+ return get(String()).c_str();
+}
+
+void
+ValueBase::set(Canvas* x)
+{
+ clear();
+ if(x && x->is_inline())
+ {
+ _set(etl::handle<Canvas>(x));
+ }
+ else
+ {
+ _set(etl::loose_handle<Canvas>(x));
+ }
+ assert(get(x)==x);
+}
+
+void
+ValueBase::set(etl::loose_handle<Canvas> x)
+{
+ clear();
+ if(x && x->is_inline())
+ _set(etl::handle<Canvas>(x));
+ else
+ _set(etl::loose_handle<Canvas>(x));
+ assert(get(x)==x);
+}
+
+void
+ValueBase::set(etl::handle<Canvas> x)
+{
+ clear();
+ if(x && x->is_inline())
+ _set(etl::handle<Canvas>(x));
+ else
+ _set(etl::loose_handle<Canvas>(x));
+ assert(get(x)==x);
+}
+
+void
+ValueBase::set(const list_type &x)
+{
+ _set(x);
+}
+
+void
+ValueBase::set(const char* x)
+{
+ _set(String(x));
+}
+
+bool
+ValueBase::is_valid()const
+{
+ return type>TYPE_NIL && type<TYPE_END && ref_count;
+}
+
+bool
+ValueBase::empty()const
+{
+ return !is_valid() || ((type==TYPE_LIST)?get_list().empty():false);
+}
+
+ValueBase::Type
+ValueBase::get_contained_type()const
+{
+ if(type!=TYPE_LIST || empty())
+ return TYPE_NIL;
+ return get_list().front().get_type();
+}
+
+ValueBase&
+ValueBase::operator=(const ValueBase& x)
+{
+ if(data!=x.data)
+ {
+ clear();
+ type=x.type;
+ data=x.data;
+ ref_count=x.ref_count;
+ }
+ loop_=x.loop_;
+ return *this;
+}
+
+void
+ValueBase::clear()
+{
+ if(ref_count.unique() && data)
+ {
+ switch(type)
+ {
+ case TYPE_BOOL: delete static_cast<bool*>(data); break;
+ case TYPE_INTEGER: delete static_cast<int*>(data); break;
+ case TYPE_ANGLE: delete static_cast<Angle*>(data); break;
+ case TYPE_VECTOR: delete static_cast<Vector*>(data); break;
+ case TYPE_TIME: delete static_cast<Time*>(data); break;
+ case TYPE_REAL: delete static_cast<Real*>(data); break;
+ case TYPE_COLOR: delete static_cast<Color*>(data); break;
+ case TYPE_SEGMENT: delete static_cast<Segment*>(data); break;
+ case TYPE_BLINEPOINT: delete static_cast<BLinePoint*>(data); break;
+ case TYPE_LIST: delete static_cast<list_type*>(data); break;
+ case TYPE_STRING: delete static_cast<String*>(data); break;
+ case TYPE_GRADIENT: delete static_cast<Gradient*>(data); break;
+ case TYPE_CANVAS:
+ {
+ etl::handle<Canvas> canvas(get(etl::loose_handle<Canvas>()));
+ if(canvas && canvas->is_inline())
+ delete static_cast<etl::handle<Canvas>*>(data);
+ else
+ delete static_cast<etl::loose_handle<Canvas>*>(data);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ ref_count.detach();
+ data=0;
+ type=TYPE_NIL;
+}
+
+
+String
+ValueBase::type_name(Type id)
+{
+ // don't internationalize these type names - they're using in .sif files
+ switch(id)
+ {
+ case TYPE_REAL: return "real";
+ case TYPE_TIME: return "time";
+ case TYPE_INTEGER: return "integer";
+ case TYPE_BOOL: return "bool";
+ case TYPE_ANGLE: return "angle";
+ case TYPE_VECTOR: return "vector";
+ case TYPE_COLOR: return "color";
+ case TYPE_STRING: return "string";
+ case TYPE_CANVAS: return "canvas";
+ case TYPE_LIST: return "list";
+ case TYPE_SEGMENT: return "segment";
+ case TYPE_GRADIENT: return "gradient";
+ case TYPE_BLINEPOINT: return "bline_point";
+ case TYPE_NIL: return "nil";
+ default:
+ break;
+ }
+ synfig::warning("Encountered unknown ValueBase with an Type of %d",id);
+// assert(0);
+ return "UNKNOWN";
+}
+
+ValueBase::Type
+ValueBase::ident_type(const String &str)
+{
+ if(str=="nil" ||
+ str=="null") return TYPE_NIL;
+ else if(str=="time" ||
+ str==_("time")) return TYPE_TIME;
+ else if(str=="real" ||
+ str=="float" ||
+ str==_("real")) return TYPE_REAL;
+ else if(str=="integer" ||
+ str=="int" ||
+ str==_("integer")) return TYPE_INTEGER;
+ else if(str=="bool" ||
+ str==_("bool")) return TYPE_BOOL;
+ else if(str=="angle" ||
+ str=="degrees" ||
+ str=="radians" ||
+ str=="rotations") return TYPE_ANGLE;
+ else if(str=="vector" ||
+ str=="point") return TYPE_VECTOR;
+ else if(str=="color") return TYPE_COLOR;
+ else if(str=="string") return TYPE_STRING;
+ else if(str=="canvas") return TYPE_CANVAS;
+ else if(str=="list") return TYPE_LIST;
+ else if(str=="segment") return TYPE_SEGMENT;
+ else if(str=="gradient") return TYPE_GRADIENT;
+ else if(str=="bline_point" ||
+ str=="blinepoint") return TYPE_BLINEPOINT;
+
+ return TYPE_NIL;
+}
+
+bool
+ValueBase::operator==(const ValueBase& rhs)const
+{
+ if(get_type()!=rhs.get_type())
+ return false;
+ if(data==rhs.data)
+ return true;
+
+ switch(get_type())
+ {
+ case TYPE_TIME: return get(Time()).is_equal(rhs.get(Time()));
+ case TYPE_REAL: return abs(get(Real())-rhs.get(Real()))<=0.00000000000001;
+ case TYPE_INTEGER: return get(int())==rhs.get(int());
+ case TYPE_BOOL: return get(bool())==rhs.get(bool());
+ case TYPE_ANGLE: return get(Angle())==rhs.get(Angle());
+ case TYPE_VECTOR: return get(Vector()).is_equal_to(rhs.get(Vector()));
+ case TYPE_COLOR: return get(Color())==rhs.get(Color());
+ case TYPE_STRING: return get(String())==rhs.get(String());
+ case TYPE_CANVAS: return get(Canvas::LooseHandle())==rhs.get(Canvas::LooseHandle());
+ case TYPE_LIST: return get_list()==rhs.get_list();
+ case TYPE_SEGMENT: // return get(Segment())==rhs.get(Segment());
+ case TYPE_GRADIENT: // return get(Gradient())==rhs.get(Gradient());
+ case TYPE_BLINEPOINT: // return get(BLinePoint())==rhs.get(BLinePoint());
+ case TYPE_NIL:
+ default: return false;
+ }
+ return false;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file value.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUE_H
+#define __SYNFIG_VALUE_H
+
+/* === H E A D E R S ======================================================= */
+
+//#include "vector.h"
+//#include "time.h"
+#include "segment.h"
+//#include "color.h"
+#include "string.h"
+#include <list>
+#include <vector>
+#include <ETL/trivial>
+#include <ETL/handle>
+#include "general.h"
+//#include "gradient.h"
+#include "blinepoint.h"
+#include "exception.h"
+
+#ifdef USE_HALF_TYPE
+#include <OpenEXR/half.h>
+#endif
+
+#ifndef SYNFIG_NO_ANGLE
+#include "angle.h"
+#endif
+
+#include <ETL/ref_count>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Canvas;
+class Vector;
+class Time;
+class Segment;
+class Gradient;
+class BLinePoint;
+class Color;
+
+/*! \class ValueBase
+** \todo writeme
+*/
+class ValueBase
+{
+ /*
+ -- ** -- T Y P E S -----------------------------------------------------------
+ */
+
+public:
+
+ //! \writeme
+ enum Type
+ {
+ TYPE_NIL=0, //!< Represents an empty value
+
+ TYPE_BOOL,
+ TYPE_INTEGER,
+ TYPE_ANGLE, //!< Angle
+
+ // All types after this point are larger than 32 bits
+
+ TYPE_TIME, //!< Time
+ TYPE_REAL, //!< Real
+
+ // All types after this point are larger than 64 bits
+
+ TYPE_VECTOR, //!< Vector
+ TYPE_COLOR, //!< Color
+ TYPE_SEGMENT, //!< Segment
+ TYPE_BLINEPOINT, //!< BLinePoint
+
+ // All types after this point require construction/destruction
+
+ TYPE_LIST, //!< List
+ TYPE_CANVAS, //!< Canvas
+ TYPE_STRING, //!< String
+ TYPE_GRADIENT, //!< Color Gradient
+
+ TYPE_END //!< Not a valid type, used for sanity checks
+ };
+
+private:
+
+ typedef std::vector<ValueBase> list_type;
+
+ /*
+ -- ** -- D A T A -------------------------------------------------------------
+ */
+
+protected:
+
+ Type type;
+ void *data;
+ etl::reference_counter ref_count;
+ bool loop_;
+
+ /*
+ -- ** -- C O N S T R U C T O R S -----------------------------------
+ */
+
+public:
+
+ //! \writeme
+ ValueBase();
+
+ //! \writeme
+ template <typename T>
+ ValueBase(const T &x, bool loop_=false):
+ type(TYPE_NIL),data(0),ref_count(0),loop_(loop_)
+ { set(x); }
+
+ //! \writeme
+ ValueBase(Type x);
+
+ //! \writeme
+ ~ValueBase();
+
+ /*
+ -- ** -- O P E R A T O R S ---------------------------------------------------
+ */
+
+public:
+
+ //! \writeme
+ template <class T> ValueBase& operator=(const T& x)
+ { set(x); return *this; }
+
+ //! \writeme
+ ValueBase& operator=(const ValueBase& x);
+
+ //! \writeme
+ bool operator==(const ValueBase& rhs)const;
+
+ //! \writeme
+ bool operator!=(const ValueBase& rhs)const { return !operator==(rhs); }
+
+ //! Constant index operator for when value is of type TYPE_LIST
+ const ValueBase &operator[](int index)const
+ { assert(type==TYPE_LIST); assert(index>0); return get_list()[index]; }
+
+ /*
+ -- ** -- M E M B E R F U N C T I O N S -------------------------------------
+ */
+
+public:
+
+ //! \writeme
+ void clear();
+
+ //! \writeme
+ bool get_loop()const { return loop_; }
+
+ //! \writeme
+ void set_loop(bool x) { loop_=x; }
+
+ //! \writeme
+ bool empty()const;
+
+ //! \writeme
+ Type get_contained_type()const;
+
+ //! Returns true if the contained value is defined and valid.
+ bool is_valid()const;
+
+ //! Returns a string containing the name of the type
+ String type_name()const { return type_name(type); }
+
+ //! Returns the type of the contained value
+ const Type & get_type()const { return type; }
+
+ //! Checks the type of the parameter against itself. Returns true if they are of the same type.
+ template <class T> bool
+ same_type_as(const T &x)const
+ {
+ const Type testtype(get_type(x));
+
+ return same_type_as(testtype);
+ }
+
+ bool same_type_as(const Type testtype)const
+ {
+ if(testtype==type)return true;
+ if( (type==TYPE_REAL || type==TYPE_TIME) &&
+ (testtype==TYPE_REAL || testtype==TYPE_TIME) )
+ return true;
+ return false;
+ }
+
+
+ // === GET MEMBERS ========================================================
+ template <typename T>
+ const T &get(const T& x)const
+ {
+ assert(is_valid() && same_type_as(x));
+ return *static_cast<const T*>(data);
+ }
+ float get(const float &)const { return get(Real()); }
+ etl::loose_handle<Canvas> get(const etl::handle<Canvas>&)const
+ { return get(etl::loose_handle<Canvas>()); }
+ etl::loose_handle<Canvas> get(Canvas*)const
+ { return get(etl::loose_handle<Canvas>()); }
+ const char* get(const char*)const;
+ const list_type& get_list()const { return get(list_type()); }
+ // ========================================================================
+
+
+
+ // === PUT MEMBERS ========================================================
+ template <typename T>
+ void put(T* x)const
+ {
+ assert(same_type_as(*x));
+ *x=*static_cast<const T*>(data);
+ }
+ void put(float* x)const { *x=get(Real()); }
+ void put(char** x)const;
+ // ========================================================================
+
+
+
+ // === SET MEMBERS ========================================================
+ template <typename T> void set(const T& x) { _set(x); }
+ void set(const float &x) { _set(Real(x)); }
+ void set(const list_type &x);
+ void set(const char* x);
+ void set(Canvas*x);
+ void set(etl::loose_handle<Canvas> x);
+ void set(etl::handle<Canvas> x);
+ template <class T> void set(const std::vector<T> &x)
+ { _set(list_type(x.begin(),x.end())); }
+ template <class T> void set(const std::list<T> &x)
+ { _set(list_type(x.begin(),x.end())); }
+ // ========================================================================
+
+
+ /*
+ -- ** -- S T A T I C F U N C T I O N S -------------------------------------
+ */
+
+public:
+
+ //! Returns a string containing the name of the given Type
+ static String type_name(Type id);
+
+ //! Returns a the corresponding Type of the described type
+ static Type ident_type(const String &str);
+
+
+ // === GET TYPE MEMBERS ===================================================
+ static const Type get_type(bool) { return TYPE_BOOL; }
+ static const Type get_type(int) { return TYPE_INTEGER; }
+ static const Type get_type(const Time&) { return TYPE_TIME; }
+ static const Type get_type(const Real&) { return TYPE_REAL; }
+ static const Type get_type(const float&) { return TYPE_REAL; }
+ static const Type get_type(const Vector&) { return TYPE_VECTOR; }
+ static const Type get_type(const Color&) { return TYPE_COLOR; }
+ static const Type get_type(const Segment&) { return TYPE_SEGMENT; }
+ static const Type get_type(const BLinePoint&) { return TYPE_BLINEPOINT; }
+ static const Type get_type(const String&) { return TYPE_STRING; }
+ static const Type get_type(const Gradient&) { return TYPE_GRADIENT; }
+ static const Type get_type(Canvas*) { return TYPE_CANVAS; }
+ static const Type get_type(const etl::handle<Canvas>&)
+ { return TYPE_CANVAS; }
+ static const Type get_type(const etl::loose_handle<Canvas>&)
+ { return TYPE_CANVAS; }
+ static const Type get_type(const list_type&) { return TYPE_LIST; }
+ template <class T> static const Type get_type(const std::vector<T> &/*x*/)
+ { return TYPE_LIST; }
+ template <class T> static const Type get_type(const std::list<T> &/*x*/)
+ { return TYPE_LIST; }
+ // ========================================================================
+
+
+ /*
+ -- ** -- C A S T O P E R A T O R S -----------------------------------------
+ */
+
+public:
+
+ operator const list_type&()const { return get_list(); }
+ //operator const Color&()const { return get(Color()); }
+ //operator const Real&()const { return get(Real()); }
+ //operator const Time&()const { return get(Time()); }
+
+ operator const Vector&()const { return get(Vector()); }
+ operator const BLinePoint&()const { return get(BLinePoint()); }
+ //operator const int&()const { return get(int()); }
+ //operator const String&()const { return get(String()); }
+ //operator const char *()const { return get(String()).c_str(); }
+ operator const Segment&()const { return get(Segment()); }
+
+
+ /*
+ -- ** -- O T H E R -----------------------------------------------------------
+ */
+
+public:
+
+#ifdef USE_HALF_TYPE
+ half get(const half &)const { return get(Real()); }
+ void put(half*x)const { *x=get(Real()); }
+ void set(const half &x) { _set(Real(x)); }
+ static const Type get_type(const half&) { return TYPE_REAL; }
+ operator half()const { return get(Real()); }
+#endif
+
+#ifndef SYNFIG_NO_ANGLE
+ operator const Angle&()const { return get(Angle()); }
+ static const Type get_type(const Angle&) { return TYPE_ANGLE; }
+#endif
+
+ template <class T>
+ operator std::list<T>()const
+ {
+ assert(type==TYPE_LIST);
+ std::list<T> ret(get_list().begin(),get_list().end());
+ return ret;
+ }
+ template <class T>
+ operator std::vector<T>()const
+ {
+ assert(type==TYPE_LIST);
+ std::vector<T> ret(get_list().begin(),get_list().end());
+ return ret;
+ }
+
+
+private:
+
+ template <typename T> void
+ _set(const T& x)
+ {
+ const Type newtype(get_type(x));
+
+ assert(newtype!=TYPE_NIL);
+
+ if(newtype==type)
+ {
+ if(ref_count.unique())
+ {
+ *reinterpret_cast<T*>(data)=x;
+ return;
+ }
+ }
+
+ clear();
+
+ type=newtype;
+ ref_count.reset();
+ data=new T(x);
+ }
+}; // END of class ValueBase
+
+
+/*! \class Value
+** \todo writeme
+*/
+template <class T>
+class Value : public ValueBase
+{
+public:
+ Value(const T &x):ValueBase(x)
+ {
+ }
+
+ Value(const ValueBase &x):ValueBase(x)
+ {
+ if(!x.same_type_as(T()))
+ throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
+ }
+
+ Value()
+ {
+ }
+
+ T get()const { return ValueBase::get(T()); }
+
+ void put(T* x)const { ValueBase::put(x); }
+
+ void set(const T& x) { ValueBase::operator=(x); }
+
+ Value<T>& operator=(const T& x) { set(x); return *this; }
+
+ Value<T>& operator=(const Value<T>& x) { return ValueBase::operator=(x); }
+
+ Value<T>& operator=(const ValueBase& x)
+ {
+ if(!x.same_type_as(T()))
+ throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
+ return ValueBase::operator=(x);
+ }
+
+}; // END of class Value
+
+/*
+template <>
+class Value< std::list<CT> > : public ValueBase
+{
+public:
+ Value(const T &x):ValueBase(x)
+ {
+ }
+ Value(const ValueBase &x):ValueBase(x)
+ {
+ if(!x.same_type_as(T()))
+ throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
+ }
+ Value()
+ {
+ }
+
+ T get()const { return ValueBase::get(T()); }
+
+ void put(T* x)const { ValueBase::put(x); }
+
+ void set(const T& x) { ValueBase::operator=(x); }
+
+ Value<T>& operator=(const T& x) { set(x); return *this; }
+
+ Value<T>& operator=(const Value<T>& x) { return ValueBase::operator=(x); }
+
+ Value<T>& operator=(const ValueBase& x)
+ {
+ if(!x.same_type_as(T()))
+ throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
+ return ValueBase::operator=(x);
+ }
+
+}; // END of class Value
+*/
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#define SYNFIG_NO_ANGLE
+
+//#define HAS_HASH_MAP 1
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode.h"
+#include "general.h"
+#include "canvas.h"
+
+#include "valuenode_const.h"
+#include "valuenode_linear.h"
+#include "valuenode_composite.h"
+#include "valuenode_reference.h"
+#include "valuenode_scale.h"
+#include "valuenode_blinecalctangent.h"
+#include "valuenode_blinecalcvertex.h"
+#include "valuenode_segcalctangent.h"
+#include "valuenode_segcalcvertex.h"
+#include "valuenode_repeat_gradient.h"
+#include "valuenode_stripes.h"
+#include "valuenode_range.h"
+#include "valuenode_add.h"
+#include "valuenode_subtract.h"
+#include "valuenode_timedswap.h"
+#include "valuenode_twotone.h"
+#include "valuenode_bline.h"
+#include "valuenode_dynamiclist.h"
+#include "valuenode_radialcomposite.h"
+#include "valuenode_gradientrotate.h"
+#include "valuenode_sine.h"
+#include "valuenode_exp.h"
+
+#include "layer.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+static int value_node_count(0);
+
+static LinkableValueNode::Book *book_;
+
+
+ValueNode::LooseHandle
+synfig::find_value_node(const GUID& guid)
+{
+ return guid_cast<ValueNode>(guid);
+}
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+bool
+ValueNode::subsys_init()
+{
+ book_=new LinkableValueNode::Book();
+
+#define ADD_VALUENODE(class,name,local) \
+ (*book_)[name].factory=reinterpret_cast<LinkableValueNode::Factory>(&class::create); \
+ (*book_)[name].check_type=&class::check_type; \
+ (*book_)[name].local_name=local
+
+#define ADD_VALUENODE2(class,name,local) \
+ (*book_)[name].factory=reinterpret_cast<LinkableValueNode::Factory>(&class::create_from); \
+ (*book_)[name].check_type=&class::check_type; \
+ (*book_)[name].local_name=local
+
+ ADD_VALUENODE(ValueNode_Linear, "linear", _("Linear") );
+ ADD_VALUENODE(ValueNode_Composite, "composite", _("Composite") );
+ ADD_VALUENODE(ValueNode_RadialComposite,"radial_composite", _("Radial Composite") );
+ ADD_VALUENODE(ValueNode_Reference, "reference", _("Reference") );
+ ADD_VALUENODE(ValueNode_Repeat_Gradient,"repeat_gradient", _("Repeat Gradient") );
+ ADD_VALUENODE(ValueNode_Scale, "scale", _("Scale") );
+ ADD_VALUENODE(ValueNode_BLineCalcTangent,"blinecalctangent",_("BLine Tangent") );
+ ADD_VALUENODE(ValueNode_BLineCalcVertex,"blinecalcvertex", _("BLine Vertex") );
+ ADD_VALUENODE(ValueNode_SegCalcTangent, "segcalctangent", _("Segment Tangent") );
+ ADD_VALUENODE(ValueNode_SegCalcVertex, "segcalcvertex", _("Segment Vertex") );
+ ADD_VALUENODE(ValueNode_Stripes, "stripes", _("Stripes") );
+ ADD_VALUENODE(ValueNode_Range, "range", _("Range") );
+ ADD_VALUENODE(ValueNode_Add, "add", _("Add") );
+ ADD_VALUENODE(ValueNode_Subtract, "subtract", _("Subtract") );
+ ADD_VALUENODE(ValueNode_TimedSwap, "timed_swap", _("Timed Swap") );
+ ADD_VALUENODE(ValueNode_TwoTone, "twotone", _("Two-Tone") );
+ ADD_VALUENODE(ValueNode_BLine, "bline", _("BLine") );
+ ADD_VALUENODE2(ValueNode_DynamicList, "dynamic_list", _("Dynamic List") );
+ ADD_VALUENODE(ValueNode_GradientRotate, "gradient_rotate", _("Gradient Rotate") );
+ ADD_VALUENODE(ValueNode_Sine, "sine", _("Sine") );
+ ADD_VALUENODE(ValueNode_Exp, "exp", _("Exponential") );
+
+#undef ADD_VALUENODE
+#undef ADD_VALUENODE2
+
+ return true;
+}
+
+bool
+ValueNode::subsys_stop()
+{
+ delete book_;
+/* if(global_value_node_map.size() || value_node_count)
+ {
+ if(value_node_count)
+ synfig::error("%d ValueNodes haven't been destroyed yet!",value_node_count);
+
+ if(global_value_node_map.size()!=value_node_count)
+ synfig::error("value node count mismatch! map.size()!=value_node_count (%d!=%d)",global_value_node_map.size(),value_node_count);
+
+ GlobalValueNodeMap::iterator iter;
+ for(iter=global_value_node_map.begin();iter!=global_value_node_map.end();++iter)
+ {
+ if(!iter->second->is_exported())
+ synfig::info("%s: count:%d name:%s type:%s",
+ iter->first.get_string().c_str(),
+ iter->second->count(),
+ iter->second->get_name().c_str(),
+ ValueBase::type_name(iter->second->get_type()).c_str()
+ );
+ else
+ synfig::info("%s: id:%s count:%d name:%s type:%s",
+ iter->first.get_string().c_str(),
+ iter->second->get_id().c_str(),
+ iter->second->count(),
+ iter->second->get_name().c_str(),
+ ValueBase::type_name(iter->second->get_type()).c_str()
+ );
+ }
+ }
+*/
+ return true;
+}
+
+ValueNode::ValueNode(ValueBase::Type type):type(type)
+{
+ value_node_count++;
+}
+
+LinkableValueNode::Book&
+LinkableValueNode::book()
+{
+ return *book_;
+}
+
+LinkableValueNode::Handle
+LinkableValueNode::create(const String &name, const ValueBase& x)
+{
+ if(!book().count(name))
+ return 0;
+ return book()[name].factory(x);
+}
+
+bool
+LinkableValueNode::check_type(const String &name, ValueBase::Type x)
+{
+ if(!book().count(name) || !book()[name].check_type)
+ return false;
+ return book()[name].check_type(x);
+}
+
+bool
+LinkableValueNode::set_link(int i,ValueNode::Handle x)
+{
+ ValueNode::Handle previous(get_link(i));
+
+ if(set_link_vfunc(i,x))
+ {
+ if(previous)
+ remove_child(previous.get());
+ add_child(x.get());
+
+ if(!x->is_exported() && get_parent_canvas())
+ {
+ x->set_parent_canvas(get_parent_canvas());
+ }
+ changed();
+ return true;
+ }
+ return false;
+}
+
+ValueNode::LooseHandle
+LinkableValueNode::get_link(int i)const
+{
+ return get_link_vfunc(i);
+}
+
+void
+LinkableValueNode::unlink_all()
+{
+ for(int i=0;i<link_count();i++)
+ {
+ ValueNode::LooseHandle value_node(get_link(i));
+ if(value_node)
+ value_node->parent_set.erase(this);
+ }
+}
+
+ValueNode::~ValueNode()
+{
+ value_node_count--;
+
+ begin_delete();
+
+ //DEBUGPOINT();
+}
+
+void
+ValueNode::on_changed()
+{
+ etl::loose_handle<Canvas> parent_canvas = get_parent_canvas();
+ if(parent_canvas)
+ do // signal to all the ancestor canvases
+ parent_canvas->signal_value_node_changed()(this);
+ while (parent_canvas = parent_canvas->parent());
+ else if(get_root_canvas())
+ get_root_canvas()->signal_value_node_changed()(this);
+
+ Node::on_changed();
+}
+
+int
+ValueNode::replace(etl::handle<ValueNode> x)
+{
+ if(x.get()==this)
+ return 0;
+
+ while(parent_set.size())
+ {
+ (*parent_set.begin())->add_child(x.get());
+ (*parent_set.begin())->remove_child(this);
+ //x->parent_set.insert(*parent_set.begin());
+ //parent_set.erase(parent_set.begin());
+ }
+ int r(RHandle(this).replace(x));
+ x->changed();
+ return r;
+}
+
+void
+ValueNode::set_id(const String &x)
+{
+ if(name!=x)
+ {
+ name=x;
+ signal_id_changed_();
+ }
+}
+
+ValueNodeList::ValueNodeList():
+ placeholder_count_(0)
+{
+}
+
+bool
+ValueNodeList::count(const String &id)const
+{
+ const_iterator iter;
+
+ if(id.empty())
+ return false;
+
+ for(iter=begin();iter!=end() && id!=(*iter)->get_id();++iter);
+
+ if(iter==end())
+ return false;
+
+ return true;
+}
+
+ValueNode::Handle
+ValueNodeList::find(const String &id)
+{
+ iterator iter;
+
+ if(id.empty())
+ throw Exception::IDNotFound("Empty ID");
+
+ for(iter=begin();iter!=end() && id!=(*iter)->get_id();++iter);
+
+ if(iter==end())
+ throw Exception::IDNotFound("ValueNode in ValueNodeList: "+id);
+
+ return *iter;
+}
+
+ValueNode::ConstHandle
+ValueNodeList::find(const String &id)const
+{
+ const_iterator iter;
+
+ if(id.empty())
+ throw Exception::IDNotFound("Empty ID");
+
+ for(iter=begin();iter!=end() && id!=(*iter)->get_id();++iter);
+
+ if(iter==end())
+ throw Exception::IDNotFound("ValueNode in ValueNodeList: "+id);
+
+ return *iter;
+}
+
+ValueNode::Handle
+ValueNodeList::surefind(const String &id)
+{
+ if(id.empty())
+ throw Exception::IDNotFound("Empty ID");
+
+ ValueNode::Handle value_node;
+
+ try
+ {
+ value_node=find(id);
+ }
+ catch(Exception::IDNotFound)
+ {
+ value_node=PlaceholderValueNode::create();
+ value_node->set_id(id);
+ push_back(value_node);
+ placeholder_count_++;
+ }
+
+ return value_node;
+}
+
+bool
+ValueNodeList::erase(ValueNode::Handle value_node)
+{
+ assert(value_node);
+
+ iterator iter;
+
+ for(iter=begin();iter!=end();++iter)
+ if(value_node.get()==iter->get())
+ {
+ std::list<ValueNode::RHandle>::erase(iter);
+ if(PlaceholderValueNode::Handle::cast_dynamic(value_node))
+ placeholder_count_--;
+ return true;
+ }
+ return false;
+}
+
+bool
+ValueNodeList::add(ValueNode::Handle value_node)
+{
+ if(!value_node)
+ return false;
+ if(value_node->get_id().empty())
+ return false;
+
+ try
+ {
+ ValueNode::RHandle other_value_node=find(value_node->get_id());
+ if(PlaceholderValueNode::Handle::cast_dynamic(other_value_node))
+ {
+ other_value_node->replace(value_node);
+ placeholder_count_--;
+ return true;
+ }
+
+ return false;
+ }
+ catch(Exception::IDNotFound)
+ {
+ push_back(value_node);
+ return true;
+ }
+
+ return false;
+}
+
+void
+ValueNodeList::audit()
+{
+ iterator iter,next;
+
+ for(next=begin(),iter=next++;iter!=end();iter=next++)
+ if(iter->count()==1)
+ std::list<ValueNode::RHandle>::erase(iter);
+}
+
+
+String
+PlaceholderValueNode::get_name()const
+{
+ return "placeholder";
+}
+
+String
+PlaceholderValueNode::get_local_name()const
+{
+ return _("Placeholder");
+}
+
+ValueNode*
+PlaceholderValueNode::clone(const GUID& deriv_guid)const
+{
+ ValueNode* ret(new PlaceholderValueNode());
+ ret->set_guid(get_guid()^deriv_guid);
+ return ret;
+}
+
+PlaceholderValueNode::Handle
+PlaceholderValueNode::create(ValueBase::Type type)
+{
+ return new PlaceholderValueNode(type);
+}
+
+ValueBase
+PlaceholderValueNode::operator()(Time /*t*/)const
+{
+ assert(0);
+ return ValueBase();
+}
+
+PlaceholderValueNode::PlaceholderValueNode(ValueBase::Type type):
+ ValueNode(type)
+{
+}
+
+ValueNode*
+LinkableValueNode::clone(const GUID& deriv_guid)const
+{
+ { ValueNode* x(find_value_node(get_guid()^deriv_guid).get()); if(x)return x; }
+
+ int i;
+ LinkableValueNode *ret=create_new();
+ ret->set_guid(get_guid()^deriv_guid);
+
+ for(i=0;i<link_count();i++)
+ {
+ ValueNode::Handle link=get_link_vfunc(i);
+ if(!link->is_exported())
+ {
+ ValueNode::LooseHandle value_node(find_value_node(link->get_guid()^deriv_guid));
+ if(!value_node)
+ value_node=link->clone(deriv_guid);
+ ret->set_link(i,value_node);
+ }
+ else
+ ret->set_link(i,link);
+ }
+
+ return ret;
+}
+
+String
+ValueNode::get_relative_id(etl::loose_handle<const Canvas> x)const
+{
+ assert(is_exported());
+ assert(canvas_);
+
+ if(x.get()==canvas_.get())
+ return get_id();
+
+ return canvas_->_get_relative_id(x)+':'+get_id();
+}
+
+void
+ValueNode::set_parent_canvas(etl::loose_handle<Canvas> x)
+{
+ canvas_=x; if(x) root_canvas_=x->get_root();
+}
+
+void
+ValueNode::set_root_canvas(etl::loose_handle<Canvas> x)
+{
+ root_canvas_=x->get_root();
+}
+
+void LinkableValueNode::get_times_vfunc(Node::time_set &set) const
+{
+ ValueNode::LooseHandle h;
+
+ int size = link_count();
+
+ //just add it to the set...
+ for(int i=0; i < size; ++i)
+ {
+ h = get_link(i);
+
+ if(h)
+ {
+ const Node::time_set &tset = h->get_times();
+ set.insert(tset.begin(),tset.end());
+ }
+ }
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_H
+#define __SYNFIG_VALUENODE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "vector.h"
+#include "value.h"
+#include "string.h"
+#include <ETL/handle>
+#include <ETL/stringf>
+#include "exception.h"
+#include <map>
+#include <sigc++/signal.h>
+#include "guid.h"
+
+#ifndef SYNFIG_NO_ANGLE
+#include <ETL/angle>
+#endif
+
+#include "node.h"
+
+#include <set>
+
+/* === M A C R O S ========================================================= */
+
+// This is a hack for GCC 3.0.4... which has a broken dynamic_cast<>
+// It is deprecated, and will be removed soon.
+#if ( __GNUC__ == 3 ) && ( __GNUC__MINOR__ == 0 )
+# define DCAST_HACK_BASECLASS() int cast__
+# define DCAST_HACK_ID(x) static const int my_cast__(void) { return x; }
+# define DCAST_HACK_ENABLE() cast__=my_cast__()
+#else
+# define DCAST_HACK_BASECLASS()
+# define DCAST_HACK_ID(x)
+# define DCAST_HACK_ENABLE()
+#endif
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class Canvas;
+class LinkableValueNode;
+class Layer;
+
+/*! \class ValueNode
+** \todo writeme
+*/
+class ValueNode : public synfig::Node
+{
+ friend class Layer;
+ friend class LinkableValueNode;
+
+ /*
+ -- ** -- T Y P E S -----------------------------------------------------------
+ */
+
+public:
+
+ typedef etl::handle<ValueNode> Handle;
+
+ typedef etl::loose_handle<ValueNode> LooseHandle;
+
+ typedef etl::handle<const ValueNode> ConstHandle;
+
+ typedef etl::rhandle<ValueNode> RHandle;
+
+
+ static bool subsys_init();
+
+ static bool subsys_stop();
+
+ /*
+ -- ** -- D A T A -------------------------------------------------------------
+ */
+
+private:
+ ValueBase::Type type;
+ String name;
+ etl::loose_handle<Canvas> canvas_;
+ etl::loose_handle<Canvas> root_canvas_;
+
+ /*
+ -- ** -- S I G N A L S -------------------------------------------------------
+ */
+
+private:
+
+ //! ValueBase Changed
+ sigc::signal<void> signal_value_changed_;
+
+ //! Children Reordered
+ sigc::signal<void,int*> signal_children_reordered_;
+
+ //! Child Changed
+ sigc::signal<void,int> signal_child_changed_;
+
+ //! Child Removed
+ sigc::signal<void,int> signal_child_removed_;
+
+ //! Child Inserted
+ sigc::signal<void,int> signal_child_inserted_;
+
+ //! ID Changed
+ sigc::signal<void> signal_id_changed_;
+
+ /*
+ -- ** -- S I G N A L I N T E R F A C E -------------------------------------
+ */
+
+public:
+
+ //! ValueBase Changed
+ sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
+
+ //! Children Reordered
+ sigc::signal<void,int*>& signal_children_reordered() { return signal_children_reordered_; }
+
+ //! Child Changed
+ sigc::signal<void,int>& signal_child_changed() { return signal_child_changed_; }
+
+ //! Child Removed
+ sigc::signal<void,int>& signal_child_removed() { return signal_child_removed_; }
+
+ //! Child Inserted
+ sigc::signal<void,int>& signal_child_inserted() { return signal_child_inserted_; }
+
+ //! ID Changed
+ sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
+
+ /*
+ -- ** -- C O N S T R U C T O R S ---------------------------------------------
+ */
+
+protected:
+
+ ValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
+
+public:
+
+ virtual ~ValueNode();
+
+ /*
+ -- ** -- M E M B E R F U N C T I O N S -------------------------------------
+ */
+
+public:
+
+ //! Returns the value of the ValueNode at time \a t
+ virtual ValueBase operator()(Time /*t*/)const
+ { return ValueBase(); }
+
+ //! \internal Sets the id of the ValueNode
+ void set_id(const String &x);
+
+ //! Returns the id of the ValueNode
+ /*! The ID is used for keeping track of a
+ ** specific instance of a ValueNode. */
+ const String &get_id()const { return name; }
+
+ //! Returns the name of the ValueNode type
+ virtual String get_name()const=0;
+
+ //! Returns the localized name of the ValueNode type
+ virtual String get_local_name()const=0;
+
+
+ //! \writeme
+ virtual ValueNode* clone(const GUID& deriv_guid=GUID())const=0;
+
+ //! \writeme
+ bool is_exported()const { return !get_id().empty(); }
+
+ //! Returns the type of the ValueNode
+ ValueBase::Type get_type()const { return type; }
+
+ //! Returns a handle to the parent canvas, if it has one.
+ etl::loose_handle<Canvas> get_parent_canvas()const { return canvas_; }
+
+ //! Returns a handle to the parent canvas, if it has one.
+ etl::loose_handle<Canvas> get_root_canvas()const { return root_canvas_; }
+
+ //! \writeme
+ void set_parent_canvas(etl::loose_handle<Canvas> x);
+
+ //! \writeme
+ void set_root_canvas(etl::loose_handle<Canvas> x);
+
+ //! \writeme
+ String get_relative_id(etl::loose_handle<const Canvas> x)const;
+
+ int replace(etl::handle<ValueNode> x);
+
+protected:
+ //! Sets the type of the ValueNode
+ void set_type(ValueBase::Type t) { type=t; }
+
+ virtual void on_changed();
+
+public:
+ DCAST_HACK_BASECLASS();
+ DCAST_HACK_ID(0);
+}; // END of class ValueNode
+
+/*! \class PlaceholderValueNode
+** \todo writeme
+*/
+class PlaceholderValueNode : public ValueNode
+{
+public:
+ typedef etl::handle<PlaceholderValueNode> Handle;
+ typedef etl::loose_handle<PlaceholderValueNode> LooseHandle;
+ typedef etl::handle<const PlaceholderValueNode> ConstHandle;
+ typedef etl::rhandle<PlaceholderValueNode> RHandle;
+
+private:
+
+ PlaceholderValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
+
+public:
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual String get_name()const;
+
+ virtual String get_local_name()const;
+
+ virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
+
+ static Handle create(ValueBase::Type type=ValueBase::TYPE_NIL);
+
+protected:
+ virtual void get_times_vfunc(Node::time_set &/*set*/) const {}
+}; // END of class PlaceholderValueNode
+
+
+/*! \class LinkableValueNode
+** \todo writeme
+*/
+class LinkableValueNode : public ValueNode
+{
+ friend class ValueNode;
+public:
+
+ typedef etl::handle<LinkableValueNode> Handle;
+
+ typedef etl::loose_handle<LinkableValueNode> LooseHandle;
+
+ typedef etl::handle<const LinkableValueNode> ConstHandle;
+
+ typedef etl::rhandle<LinkableValueNode> RHandle;
+
+
+ //! Type that represents a pointer to a ValueNode's constructor
+ typedef LinkableValueNode* (*Factory)(const ValueBase&);
+
+ typedef bool (*CheckType)(ValueBase::Type);
+
+ struct BookEntry
+ {
+ String local_name;
+ Factory factory;
+ CheckType check_type;
+ };
+
+ typedef std::map<String,BookEntry> Book;
+
+ static Book& book();
+
+ static Handle create(const String &name, const ValueBase& x);
+
+ static bool check_type(const String &name, ValueBase::Type x);
+
+public:
+ LinkableValueNode(ValueBase::Type type=ValueBase::TYPE_NIL):
+ ValueNode(type) { }
+
+protected:
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x)=0;
+
+ void unlink_all();
+
+public:
+
+ virtual int link_count()const=0;
+
+ virtual String link_local_name(int i)const=0;
+
+ virtual String link_name(int i)const=0;
+
+ virtual int get_link_index_from_name(const String &name)const=0;
+
+ virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
+
+ bool set_link(int i,ValueNode::Handle x);
+ bool set_link(const String &name,ValueNode::Handle x) { return set_link(get_link_index_from_name(name),x); }
+
+ ValueNode::LooseHandle get_link(int i)const;
+ ValueNode::LooseHandle get_link(const String &name)const { return get_link(get_link_index_from_name(name)); }
+
+protected:
+ //! Sets the type of the ValueNode
+ void set_type(ValueBase::Type t) { ValueNode::set_type(t); }
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const=0;
+
+ // Wrapper for new operator, used by clone()
+ virtual LinkableValueNode* create_new()const=0;
+
+ virtual void get_times_vfunc(Node::time_set &set) const;
+}; // END of class LinkableValueNode
+
+/*! \class ValueNodeList
+** \brief A searchable value_node list container
+** \warning Do not confuse with ValueNode_DynamicList!
+** \todo writeme
+*/
+class ValueNodeList : public std::list<ValueNode::RHandle>
+{
+ int placeholder_count_;
+public:
+ ValueNodeList();
+
+ //! Finds the ValueNode in the list with the given \a name
+ /*! \return If found, returns a handle to the ValueNode.
+ ** Otherwise, returns an empty handle.
+ */
+ ValueNode::Handle find(const String &name);
+
+ //! Finds the ValueNode in the list with the given \a name
+ /*! \return If found, returns a handle to the ValueNode.
+ ** Otherwise, returns an empty handle.
+ */
+ ValueNode::ConstHandle find(const String &name)const;
+
+ //! Removes the \a value_node from the list
+ bool erase(ValueNode::Handle value_node);
+
+ //! \writeme
+ bool add(ValueNode::Handle value_node);
+
+ //! \writeme
+ bool count(const String &id)const;
+
+ //! Similar to find, but will create a placeholder value_node if it cannot be found.
+ ValueNode::Handle surefind(const String &name);
+
+ //! Removes any value_nodes with reference counts of 1.
+ void audit();
+
+ //! Placeholder Count
+ int placeholder_count()const { return placeholder_count_; }
+};
+
+ValueNode::LooseHandle find_value_node(const GUID& guid);
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_add.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "general.h"
+#include "valuenode_add.h"
+#include "valuenode_const.h"
+#include <stdexcept>
+#include "color.h"
+#include "vector.h"
+#include "angle.h"
+#include "real.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+synfig::ValueNode_Add::ValueNode_Add(const ValueBase &value):
+ LinkableValueNode(value.get_type())
+{
+ set_scalar(1.0);
+ ValueBase::Type id(value.get_type());
+
+ switch(id)
+ {
+ case ValueBase::TYPE_ANGLE:
+ set_link("lhs",ValueNode_Const::create(value.get(Angle())));
+ set_link("rhs",ValueNode_Const::create(Angle::deg(0)));
+ break;
+ case ValueBase::TYPE_COLOR:
+ set_link("lhs",ValueNode_Const::create(value.get(Color())));
+ set_link("rhs",ValueNode_Const::create(Color(0,0,0,0)));
+ break;
+ case ValueBase::TYPE_INTEGER:
+ set_link("lhs",ValueNode_Const::create(value.get(int())));
+ set_link("rhs",ValueNode_Const::create(int(0)));
+ break;
+ case ValueBase::TYPE_REAL:
+ set_link("lhs",ValueNode_Const::create(value.get(Real())));
+ set_link("rhs",ValueNode_Const::create(Real(0)));
+ break;
+ case ValueBase::TYPE_TIME:
+ set_link("lhs",ValueNode_Const::create(value.get(Time())));
+ set_link("rhs",ValueNode_Const::create(Time(0)));
+ break;
+ case ValueBase::TYPE_VECTOR:
+ set_link("lhs",ValueNode_Const::create(value.get(Vector())));
+ set_link("rhs",ValueNode_Const::create(Vector(0,0)));
+ break;
+ default:
+ assert(0);
+ throw runtime_error("synfig::ValueNode_Add:Bad type "+ValueBase::type_name(id));
+ }
+
+ assert(get_lhs()->get_type()==id);
+ assert(get_rhs()->get_type()==id);
+ assert(get_type()==id);
+
+ DCAST_HACK_ENABLE();
+}
+
+LinkableValueNode*
+ValueNode_Add::create_new()const
+{
+ return new ValueNode_Add(get_type());
+}
+
+ValueNode_Add*
+ValueNode_Add::create(const ValueBase& value)
+{
+ return new ValueNode_Add(value);
+}
+
+synfig::ValueNode_Add::~ValueNode_Add()
+{
+ unlink_all();
+}
+
+void
+ValueNode_Add::set_scalar(Real value)
+{
+ set_link("scalar",ValueNode_Const::create(value));
+}
+
+bool
+synfig::ValueNode_Add::set_scalar(ValueNode::Handle value)
+{
+ if(value->get_type()!=ValueBase::TYPE_REAL&& !PlaceholderValueNode::Handle::cast_dynamic(value))
+ return false;
+ scalar=value;
+ return true;
+}
+
+bool
+synfig::ValueNode_Add::set_lhs(ValueNode::Handle x)
+{
+ assert(get_type());
+
+ if(!x ||
+ (get_type()==ValueBase::TYPE_NIL && !check_type(x->get_type())) ||
+ (get_type()!=ValueBase::TYPE_NIL && x->get_type()!=get_type() && !PlaceholderValueNode::Handle::cast_dynamic(x)))
+ return false;
+
+ ref_a=x;
+
+ return true;
+}
+
+bool
+synfig::ValueNode_Add::set_rhs(ValueNode::Handle x)
+{
+ assert(get_type());
+
+ if(!x ||
+ (get_type()==ValueBase::TYPE_NIL && !check_type(x->get_type())) ||
+ (get_type()!=ValueBase::TYPE_NIL && x->get_type()!=get_type() && !PlaceholderValueNode::Handle::cast_dynamic(x)))
+ return false;
+
+ ref_b=x;
+
+ return true;
+}
+
+synfig::ValueBase
+synfig::ValueNode_Add::operator()(Time t)const
+{
+ if(!ref_a || !ref_b)
+ throw runtime_error(strprintf("ValueNode_Add: %s",_("One or both of my parameters aren't set!")));
+ switch(get_type())
+ {
+ case ValueBase::TYPE_ANGLE:
+ return ((*ref_a)(t).get(Angle())+(*ref_b)(t).get(Angle()))*(*scalar)(t).get(Real());
+ case ValueBase::TYPE_COLOR:
+ return ((*ref_a)(t).get(Color())+(*ref_b)(t).get(Color()))*(*scalar)(t).get(Real());
+ case ValueBase::TYPE_INTEGER:
+ {
+ Real ret = ((*ref_a)(t).get(int())+(*ref_b)(t).get(int()))*(*scalar)(t).get(Real()) + 0.5f;
+ if (ret < 0) return static_cast<int>(ret-1);
+ return static_cast<int>(ret);
+ }
+ case ValueBase::TYPE_REAL:
+ return ((*ref_a)(t).get(Vector::value_type())+(*ref_b)(t).get(Vector::value_type()))*(*scalar)(t).get(Real());
+ case ValueBase::TYPE_TIME:
+ return ((*ref_a)(t).get(Time())+(*ref_b)(t).get(Time()))*(*scalar)(t).get(Real());
+ case ValueBase::TYPE_VECTOR:
+ return ((*ref_a)(t).get(Vector())+(*ref_b)(t).get(Vector()))*(*scalar)(t).get(Real());
+ default:
+ assert(0);
+ break;
+ }
+ return ValueBase();
+}
+
+bool
+ValueNode_Add::set_link_vfunc(int i,ValueNode::Handle value)
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0:
+ if(set_lhs(value)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ return false;
+ case 1:
+ if(set_rhs(value)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ return false;
+ case 2:
+ scalar=value;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_Add::get_link_vfunc(int i)const
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0: return ref_a;
+ case 1: return ref_b;
+ case 2: return scalar;
+ default: return 0;
+ }
+}
+
+int
+ValueNode_Add::link_count()const
+{
+ return 3;
+}
+
+String
+ValueNode_Add::link_local_name(int i)const
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0: return _("LHS");
+ case 1: return _("RHS");
+ case 2: return _("Scalar");
+ default: return String();
+ }
+}
+
+String
+ValueNode_Add::link_name(int i)const
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0: return "lhs";
+ case 1: return "rhs";
+ case 2: return "scalar";
+ default: return String();
+ }
+}
+
+int
+ValueNode_Add::get_link_index_from_name(const String &name)const
+{
+ if(name=="lhs") return 0;
+ if(name=="rhs") return 1;
+ if(name=="scalar") return 2;
+ throw Exception::BadLinkName(name);
+}
+
+String
+ValueNode_Add::get_name()const
+{
+ return "add";
+}
+
+String
+ValueNode_Add::get_local_name()const
+{
+ return _("Add");
+}
+
+bool
+ValueNode_Add::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_ANGLE
+ || type==ValueBase::TYPE_COLOR
+ || type==ValueBase::TYPE_INTEGER
+ || type==ValueBase::TYPE_REAL
+ || type==ValueBase::TYPE_TIME
+ || type==ValueBase::TYPE_VECTOR;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_add.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_ADD_H
+#define __SYNFIG_VALUENODE_ADD_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+struct ValueNode_Add : public LinkableValueNode
+{
+ typedef etl::handle<ValueNode_Add> Handle;
+ typedef etl::handle<const ValueNode_Add> ConstHandle;
+
+protected:
+
+ ValueNode_Add(const ValueBase &value);
+
+private:
+
+ ValueNode::RHandle ref_a;
+ ValueNode::RHandle ref_b;
+ ValueNode::RHandle scalar;
+
+public:
+
+ virtual ~ValueNode_Add();
+
+// static Handle create(ValueBase::Type id=ValueBase::TYPE_NIL);
+
+ //! Sets the left-hand-side value_node
+ bool set_lhs(ValueNode::Handle a);
+
+ //! Gets the left-hand-side value_node
+ ValueNode::Handle get_lhs()const { return ref_a; }
+
+ //! Sets the right-hand-side value_node
+ bool set_rhs(ValueNode::Handle b);
+
+ //! Gets the right-hand-side value_node
+ ValueNode::Handle get_rhs()const { return ref_b; }
+
+ //! Sets the scalar value_node
+ bool set_scalar(ValueNode::Handle x);
+
+ //! Gets the scalar value_node
+ ValueNode::Handle get_scalar()const { return scalar; }
+
+ void set_scalar(Real x);
+
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+
+ virtual int link_count()const;
+
+ virtual String link_local_name(int i)const;
+ virtual String link_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+// static bool check_type(const ValueBase::Type &type);
+
+ LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_Add* create(const ValueBase &value=ValueBase());
+}; // END of class ValueNode_Add
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_animated.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <vector>
+#include <list>
+#include <stdexcept>
+
+#include <cmath>
+
+#include <ETL/bezier>
+#include <ETL/hermite>
+#include <ETL/spline>
+#include <ETL/handle>
+#include <ETL/misc>
+
+#include <algorithm>
+#include <typeinfo>
+
+#include "canvas.h"
+#include "general.h"
+#include "valuenode_animated.h"
+#include "valuenode_const.h"
+#include "exception.h"
+#include "gradient.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+// Fast binary search implementation
+/*
+template<typename I, typename T> inline I
+binary_find(I begin, I end, const T& value)
+{
+ I iter(begin+(end-begin)/2);
+
+ while(end-begin>1 && !(*iter==value))
+ {
+ ((*iter<value)?begin:end) = iter;
+
+ iter = begin+(end-begin)/2;
+ }
+ return iter;
+}
+*/
+
+/*
+template<typename T> String tangent_info(T a, T b, T v)
+{
+ return "...";
+}
+
+String tangent_info(Vector a, Vector b, Vector v)
+{
+ if(a==b)
+ return strprintf("(should be zero) T=[%f,%f], Pp=[%f,%f], Pn=[%f,%f]",v[0],v[1],a[0],a[1],b[0],b[1]);
+ else
+ return strprintf("(should NOT be zero) T=[%f,%f], Pp=[%f,%f], Pn=[%f,%f]",v[0],v[1],a[0],a[1],b[0],b[1]);
+}
+*/
+
+template <class T>
+struct subtractor : public std::binary_function<T, T, T>
+{
+ T operator()(const T &a,const T &b)const
+ {
+ return a-b;
+ }
+};
+
+template <>
+struct subtractor<Angle> : public std::binary_function<Angle, Angle, Angle>
+{
+ Angle operator()(const Angle &a,const Angle &b)const
+ {
+ return a.dist(b);
+ }
+};
+
+template <class T>
+struct magnitude : public std::unary_function<float, T>
+{
+ float operator()(const T &a)const
+ {
+ return abs(a);
+ }
+};
+
+template <>
+struct magnitude<Angle> : public std::unary_function<float, Angle>
+{
+ float operator()(const Angle &a)const
+ {
+ return abs(Angle::rad(a).get());
+ }
+};
+
+template <>
+struct magnitude<Vector> : public std::unary_function<float, Vector>
+{
+ float operator()(const Vector &a)const
+ {
+ return a.mag();
+ }
+};
+
+template <>
+struct magnitude<Color> : public std::unary_function<float, Color>
+{
+ float operator()(const Color &a)const
+ {
+ return abs(a.get_y());
+ }
+};
+
+
+
+
+
+template <class T>
+struct is_angle_type
+{
+ bool operator()()const
+ {
+ return false;
+ }
+};
+
+template <>
+struct is_angle_type<Angle>
+{
+ bool operator()()const
+ {
+ return true;
+ }
+};
+
+/* === G L O B A L S ======================================================= */
+
+/* === C L A S S E S ======================================================= */
+
+template<typename T>
+class _Hermite : public synfig::ValueNode_Animated
+{
+public:
+ typedef T value_type;
+ affine_combo<value_type,Time> affine_combo_func;
+ subtractor<value_type> subtract_func;
+ magnitude<value_type> magnitude_func;
+ is_angle_type<value_type> is_angle;
+private:
+ struct PathSegment
+ {
+ is_angle_type<value_type> is_angle;
+ subtractor<value_type> subtract_func;
+
+ mutable hermite<Time,Time> first;
+ mutable hermite<value_type,Time> second;
+ WaypointList::iterator start;
+ WaypointList::iterator end;
+
+ value_type resolve(const Time &t)const
+ {
+ bool start_static(start->is_static());
+ bool end_static(end->is_static());
+
+ if(!start_static || !end_static)
+ {
+ //if(!start_static)
+ second.p1()=start->get_value(t).get(value_type());
+ if(start->get_after()==INTERPOLATION_CONSTANT || end->get_before()==INTERPOLATION_CONSTANT)
+ return second.p1();
+ //if(!end_static)
+ second.p2()=end->get_value(t).get(value_type());
+
+ // At the moment, the only type of non-constant interpolation
+ // that we support is linear.
+ second.t1()=
+ second.t2()=subtract_func(second.p2(),second.p1());
+
+ second.sync();
+ }
+
+ return second(first(t));
+ }
+ };
+ typedef vector <
+ PathSegment
+ /*
+ pair <
+ hermite<Time,Time>,
+ hermite<value_type,Time>
+ >
+ */
+ > curve_list_type;
+
+ curve_list_type curve_list;
+
+ // Bounds of this curve
+ Time r,s;
+
+public:
+ ValueNode* clone(const GUID& deriv_guid)const
+ {
+ { ValueNode* x(find_value_node(get_guid()^deriv_guid).get()); if(x)return x; }
+ _Hermite<T>* ret(new _Hermite<T>());
+ ret->set_guid(get_guid()^deriv_guid);
+ for(WaypointList::const_iterator iter=waypoint_list().begin();iter!=waypoint_list().end();++iter)
+ ret->add(iter->clone(deriv_guid));
+ return ret;
+ }
+
+ _Hermite()
+ {
+ set_type(ValueBase(value_type()).get_type());
+ }
+
+ virtual WaypointList::iterator new_waypoint(Time t, ValueBase value)
+ {
+ // Make sure we are getting data of the correct type
+ //if(data.type!=type)
+ // return waypoint_list_type::iterator();
+
+ try { find(t); throw Exception::BadTime(_("A waypoint already exists at this point in time")); } catch(Exception::NotFound) { };
+ Waypoint waypoint(value,t);
+ waypoint.set_parent_value_node(this);
+
+ waypoint_list_.push_back(waypoint);
+ WaypointList::iterator ret=waypoint_list_.end();
+ --ret;
+
+ if(is_angle())
+ {
+ ret->set_before(INTERPOLATION_LINEAR);
+ ret->set_after(INTERPOLATION_LINEAR);
+ }
+
+ changed();
+
+ return ret;
+ }
+
+ virtual WaypointList::iterator new_waypoint(Time t, ValueNode::Handle value_node)
+ {
+ // Make sure we are getting data of the correct type
+ //if(data.type!=type)
+ // return waypoint_list_type::iterator();
+ try { find(t); throw Exception::BadTime(_("A waypoint already exists at this point in time")); } catch(Exception::NotFound) { };
+
+ Waypoint waypoint(value_node,t);
+ waypoint.set_parent_value_node(this);
+
+ waypoint_list_.push_back(waypoint);
+ WaypointList::iterator ret=waypoint_list_.end();
+ --ret;
+
+ if(is_angle())
+ {
+ ret->set_before(INTERPOLATION_LINEAR);
+ ret->set_after(INTERPOLATION_LINEAR);
+ }
+
+ changed();
+
+ return ret;
+ }
+
+ virtual void on_changed()
+ {
+ ValueNode_Animated::on_changed();
+
+ if(waypoint_list_.size()<=1)
+ return;
+ std::sort(waypoint_list_.begin(),waypoint_list_.end());
+ //waypoint_list_.sort();
+
+ r=waypoint_list_.front().get_time();
+ s=waypoint_list_.back().get_time();
+
+ curve_list.clear();
+
+ WaypointList::iterator prev,iter,next=waypoint_list_.begin();
+ int i=0;
+
+ for(iter=next++;iter!=waypoint_list_.end() && next!=waypoint_list_.end();prev=iter,iter=next++,i++)
+ {
+ typename curve_list_type::value_type curve;
+ WaypointList::iterator after_next(next);
+ ++after_next;
+
+ curve.start=iter;
+ curve.end=next;
+
+ // Set up the positions
+ curve.first.set_rs(iter->get_time(), next->get_time());
+ curve.second.set_rs(iter->get_time(), next->get_time());
+
+ Waypoint::Interpolation iter_get_after(iter->get_after());
+ Waypoint::Interpolation next_get_after(next->get_after());
+ Waypoint::Interpolation iter_get_before(iter->get_before());
+ Waypoint::Interpolation next_get_before(next->get_before());
+
+ if(is_angle())
+ {
+ if(iter_get_after==INTERPOLATION_TCB)
+ iter_get_after=INTERPOLATION_LINEAR;
+ if(next_get_after==INTERPOLATION_TCB)
+ next_get_after=INTERPOLATION_LINEAR;
+ if(iter_get_before==INTERPOLATION_TCB)
+ iter_get_before=INTERPOLATION_LINEAR;
+ if(next_get_before==INTERPOLATION_TCB)
+ next_get_before=INTERPOLATION_LINEAR;
+ }
+
+ if(iter->is_static() && next->is_static())
+ {
+ curve.second.p1()=iter->get_value().get(T());
+ curve.second.p2()=next->get_value().get(T());
+ if(iter_get_after==INTERPOLATION_CONSTANT || next_get_before==INTERPOLATION_CONSTANT)
+ {
+ // Sections must be constant on both sides.
+ // NOTE: this is commented out because of some
+ // user interface issues. Namely, if a section is
+ // constant and the user turns off the constant on
+ // one waypoint, this will end up turning it back on.
+ // Confusing.
+ //iter->get_after()=next->get_before()=INTERPOLATION_CONSTANT;
+ curve.second.p1()=
+ curve.second.p2()=iter->get_value().get(T());
+ curve.second.t1()=
+ curve.second.t2()=subtract_func(curve.second.p1(),curve.second.p2());
+ }
+ else
+ {
+ if(iter_get_after==INTERPOLATION_TCB && iter!=waypoint_list_.begin() && !is_angle())
+ {
+ if(iter->get_before()!=INTERPOLATION_TCB && !curve_list.empty())
+ {
+ curve.second.t1()=curve_list.back().second.t2();
+ }
+ else
+ {
+
+ const Real& t(iter->get_tension()); // Tension
+ const Real& c(iter->get_continuity()); // Continuity
+ const Real& b(iter->get_bias()); // Bias
+
+ // The folloing line works where the previous line fails.
+ value_type Pp; Pp=curve_list.back().second.p1(); // P_{i-1}
+
+ const value_type& Pc(curve.second.p1()); // P_i
+ const value_type& Pn(curve.second.p2()); // P_{i+1}
+
+ // TCB
+ value_type vect(static_cast<value_type>(subtract_func(Pc,Pp)*(((1.0-t)*(1.0+c)*(1.0+b))/2.0)+(Pn-Pc)*(((1.0-t)*(1.0-c)*(1.0-b))/2.0)));
+
+ // Tension Only
+ //value_type vect=(value_type)((Pn-Pp)*(1.0-t));
+
+ // Linear
+ //value_type vect=(value_type)(Pn-Pc);
+
+ // Debugging stuff
+ //synfig::info("%d:t1: %s",i,tangent_info(Pp,Pn,vect).c_str());
+
+ // Adjust for time
+ //vect=value_type(vect*(curve.second.get_dt()*2.0)/(curve.second.get_dt()+curve_list.back().second.get_dt()));
+ //vect=value_type(vect*(curve.second.get_dt())/(curve_list.back().second.get_dt()));
+
+ curve.second.t1()=vect;
+ }
+ }
+ else if(
+ iter_get_after==INTERPOLATION_LINEAR || iter_get_after==INTERPOLATION_HALT ||
+ (iter_get_after==INTERPOLATION_TCB && iter==waypoint_list_.begin()))
+ {
+ curve.second.t1()=subtract_func(curve.second.p2(),curve.second.p1());
+ }
+
+ if(iter_get_before==INTERPOLATION_TCB && iter->get_after()!=INTERPOLATION_TCB && !curve_list.empty())
+ {
+ curve_list.back().second.t2()=curve.second.t1();
+ curve_list.back().second.sync();
+ }
+
+
+ if(next_get_before==INTERPOLATION_TCB && after_next!=waypoint_list_.end() && !is_angle())
+ {
+ const Real &t(next->get_tension()); // Tension
+ const Real &c(next->get_continuity()); // Continuity
+ const Real &b(next->get_bias()); // Bias
+ const value_type &Pp(curve.second.p1()); // P_{i-1}
+ const value_type &Pc(curve.second.p2()); // P_i
+ value_type Pn; Pn=after_next->get_value().get(T()); // P_{i+1}
+
+ // TCB
+ value_type vect(static_cast<value_type>(subtract_func(Pc,Pp) * (((1.0-t)*(1.0-c)*(1.0+b))/2.0) +
+ (Pn-Pc) * (((1.0-t)*(1.0+c)*(1.0-b))/2.0)));
+
+ // Tension Only
+ //value_type vect((value_type)((Pn-Pp)*(1.0-t)));
+
+ // Linear
+ //value_type vect=(value_type)(Pc-Pp);
+
+ // Debugging stuff
+ //synfig::info("%d:t2: %s",i,tangent_info(Pp,Pn,vect).c_str());
+
+ // Adjust for time
+ //vect=value_type(vect*(curve.second.get_dt()*2.0)/(curve.second.get_dt()+(after_next->get_time()-next->get_time())));
+ //vect=value_type(vect*(curve.second.get_dt()/((after_next->get_time()-next->get_time()))));
+
+ curve.second.t2()=vect;
+ }
+ else if(
+ next_get_before==INTERPOLATION_LINEAR || next_get_before==INTERPOLATION_HALT ||
+ (next_get_before==INTERPOLATION_TCB && after_next==waypoint_list_.end()))
+ {
+ curve.second.t2()=subtract_func(curve.second.p2(),curve.second.p1());
+ }
+
+ // Adjust for time
+ const float timeadjust(0.5);
+
+ if(iter_get_after==INTERPOLATION_HALT)
+ curve.second.t1()*=0;
+ // if this isn't the first curve
+ else if(iter_get_after != INTERPOLATION_LINEAR && !curve_list.empty())
+ // adjust it for the curve that came before it
+ curve.second.t1() *=
+ // (time span of this curve) * 1.5
+ // -----------------------------------------------------------------
+ // ((time span of this curve) * 0.5) + (time span of previous curve)
+ (curve.second.get_dt()*(timeadjust+1)) /
+ (curve.second.get_dt()*timeadjust + curve_list.back().second.get_dt());
+
+ if(next_get_before==INTERPOLATION_HALT)
+ curve.second.t2()*=0;
+ // if this isn't the last curve
+ else if(next_get_before != INTERPOLATION_LINEAR && after_next!=waypoint_list_.end())
+ // adjust it for the curve that came after it
+ curve.second.t2() *=
+ // (time span of this curve) * 1.5
+ // -------------------------------------------------------------
+ // ((time span of this curve) * 0.5) + (time span of next curve)
+ (curve.second.get_dt()*(timeadjust+1)) /
+ (curve.second.get_dt()*timeadjust+(after_next->get_time()-next->get_time()));
+ } // not CONSTANT
+ }
+
+ // Set up the time to the default stuff
+ curve.first.set_rs(iter->get_time(), next->get_time());
+ curve.first.p1()=iter->get_time();
+ curve.first.p2()=next->get_time();
+ curve.first.t1()=(curve.first.p2()-curve.first.p1())*(1.0f-iter->get_time_tension());
+ curve.first.t2()=(curve.first.p2()-curve.first.p1())*(1.0f-next->get_time_tension());
+
+
+ curve.first.sync();
+ curve.second.sync();
+
+ curve_list.push_back(curve);
+ }
+ }
+
+ virtual ValueBase operator()(Time t)const
+ {
+ if(waypoint_list_.empty())
+ return value_type(); //! \todo Perhaps we should throw something here?
+ if(waypoint_list_.size()==1)
+ return waypoint_list_.front().get_value(t);
+ if(t<=r)
+ return waypoint_list_.front().get_value(t);
+ if(t>=s)
+ return waypoint_list_.back().get_value(t);
+
+ typename curve_list_type::const_iterator iter;
+
+ // This next line will set iter to the
+ // correct iterator for the given time.
+ for(iter=curve_list.begin();iter<curve_list.end() && t>=iter->first.get_s();++iter)
+ continue;
+ if(iter==curve_list.end())
+ return waypoint_list_.back().get_value(t);
+ return iter->resolve(t);
+ }
+};
+
+
+template<typename T>
+class _Constant : public synfig::ValueNode_Animated
+{
+public:
+ typedef T value_type;
+
+private:
+
+ // Bounds of this curve
+ Time r,s;
+
+public:
+ ValueNode* clone(const GUID& deriv_guid)const
+ {
+ { ValueNode* x(find_value_node(get_guid()^deriv_guid).get()); if(x)return x; }
+ _Constant<T>* ret(new _Constant<T>());
+ ret->set_guid(get_guid()^deriv_guid);
+ for(WaypointList::const_iterator iter=waypoint_list().begin();iter!=waypoint_list().end();++iter)
+ ret->add(iter->clone(deriv_guid));
+ return ret;
+ }
+
+ _Constant()
+ {
+ set_type(ValueBase(value_type()).get_type());
+ }
+
+ virtual WaypointList::iterator new_waypoint(Time t, ValueBase value)
+ {
+ // Make sure we are getting data of the correct type
+ //if(data.type!=type)
+ // return waypoint_list_type::iterator();
+ try { find(t); throw Exception::BadTime(_("A waypoint already exists at this point in time")); } catch(Exception::NotFound) { };
+
+ Waypoint waypoint(value,t);
+ waypoint.set_parent_value_node(this);
+
+ waypoint_list_.push_back(waypoint);
+ WaypointList::iterator ret=waypoint_list_.end();
+ --ret;
+ changed();
+
+ return ret;
+ }
+
+ virtual WaypointList::iterator new_waypoint(Time t, ValueNode::Handle value_node)
+ {
+ // Make sure we are getting data of the correct type
+ //if(data.type!=type)
+ // return waypoint_list_type::iterator();
+ try { find(t); throw Exception::BadTime(_("A waypoint already exists at this point in time")); } catch(Exception::NotFound) { };
+
+ Waypoint waypoint(value_node,t);
+ waypoint.set_parent_value_node(this);
+
+ waypoint_list_.push_back(waypoint);
+ WaypointList::iterator ret=waypoint_list_.end();
+ --ret;
+ changed();
+
+ return ret;
+ }
+
+ virtual void on_changed()
+ {
+ ValueNode_Animated::on_changed();
+
+ if(waypoint_list_.size()<=1)
+ return;
+ std::sort(waypoint_list_.begin(),waypoint_list_.end());
+ //waypoint_list_.sort();
+ r=waypoint_list_.front().get_time();
+ s=waypoint_list_.back().get_time();
+
+ }
+
+ virtual ValueBase operator()(Time t)const
+ {
+ if(waypoint_list_.size()==1)
+ return waypoint_list_.front().get_value(t);
+ if(waypoint_list_.empty())
+ return value_type();
+ if(t<=r)
+ return waypoint_list_.front().get_value(t);
+ if(t>=s)
+ return waypoint_list_.back().get_value(t);
+
+ typename WaypointList::const_iterator iter;
+ typename WaypointList::const_iterator next;
+
+ // This next line will set iter to the
+ // correct iterator for the given time.
+ for(next=waypoint_list_.begin(),iter=next++;next!=waypoint_list_.end() && t>=next->get_time();iter=next++)
+ continue;
+
+ return iter->get_value(t);
+ }
+};
+
+class _AnimBool : public synfig::ValueNode_Animated
+{
+public:
+ typedef bool value_type;
+
+private:
+
+ // Bounds of this curve
+ Time r,s;
+
+public:
+ ValueNode* clone(const GUID& deriv_guid)const
+ {
+ { ValueNode* x(find_value_node(get_guid()^deriv_guid).get()); if(x)return x; }
+ _AnimBool* ret(new _AnimBool());
+ ret->set_guid(get_guid()^deriv_guid);
+ for(WaypointList::const_iterator iter=waypoint_list().begin();iter!=waypoint_list().end();++iter)
+ ret->add(iter->clone(deriv_guid));
+ return ret;
+ }
+
+ _AnimBool()
+ {
+ set_type(ValueBase(value_type()).get_type());
+ }
+
+ virtual WaypointList::iterator new_waypoint(Time t, ValueBase value)
+ {
+ // Make sure we are getting data of the correct type
+ //if(data.type!=type)
+ // return waypoint_list_type::iterator();
+ try { find(t); throw Exception::BadTime(_("A waypoint already exists at this point in time")); } catch(Exception::NotFound) { };
+
+
+ Waypoint waypoint(value,t);
+ waypoint.set_parent_value_node(this);
+
+ waypoint_list_.push_back(waypoint);
+ WaypointList::iterator ret=waypoint_list_.end();
+ --ret;
+ changed();
+
+ return ret;
+ }
+
+ virtual WaypointList::iterator new_waypoint(Time t, ValueNode::Handle value_node)
+ {
+ // Make sure we are getting data of the correct type
+ //if(data.type!=type)
+ // return waypoint_list_type::iterator();
+ try { find(t); throw Exception::BadTime(_("A waypoint already exists at this point in time")); } catch(Exception::NotFound) { };
+
+ Waypoint waypoint(value_node,t);
+ waypoint.set_parent_value_node(this);
+
+ waypoint_list_.push_back(waypoint);
+ WaypointList::iterator ret=waypoint_list_.end();
+ --ret;
+ changed();
+
+ return ret;
+ }
+
+ virtual void on_changed()
+ {
+ ValueNode_Animated::on_changed();
+
+ if(waypoint_list_.size()<=1)
+ return;
+ std::sort(waypoint_list_.begin(),waypoint_list_.end());
+ //waypoint_list_.sort();
+ r=waypoint_list_.front().get_time();
+ s=waypoint_list_.back().get_time();
+
+ }
+
+ virtual ValueBase operator()(Time t)const
+ {
+ if(waypoint_list_.size()==1)
+ return waypoint_list_.front().get_value(t);
+ if(waypoint_list_.empty())
+ return false;
+ if(t<r)
+ return waypoint_list_.front().get_value(t);
+ if(t>s)
+ return waypoint_list_.back().get_value(t);
+
+ WaypointList::const_iterator iter;
+ WaypointList::const_iterator next;
+
+ // This next line will set iter to the
+ // correct iterator for the given time.
+ for(next=waypoint_list_.begin(),iter=next++;next!=waypoint_list_.end() && t>=next->get_time();iter=next++)
+ if(iter->get_time()==t)
+ return iter->get_value(t);
+
+ if(iter->get_time()==t)
+ return iter->get_value(t);
+
+ if(next!=waypoint_list_.end())
+ return iter->get_value(t).get(bool()) || next->get_value(t).get(bool());
+ return iter->get_value(t);
+ }
+};
+
+/* === M E T H O D S ======================================================= */
+
+ValueNode_Animated::ValueNode_Animated()
+{
+ DCAST_HACK_ENABLE();
+}
+
+int
+ValueNode_Animated::find(const Time& begin,const Time& end,std::vector<Waypoint*>& selected)
+{
+ Time curr_time(begin);
+ int ret(0);
+
+ // try to grab first waypoint
+ try
+ {
+ WaypointList::iterator iter;
+ iter=find(curr_time);
+ selected.push_back(&*iter);
+ ret++;
+ }
+ catch(...) { }
+
+ try
+ {
+ WaypointList::iterator iter;
+ while(true)
+ {
+ iter=find_next(curr_time);
+ curr_time=iter->get_time();
+ if(curr_time>=end)
+ break;
+ selected.push_back(&*iter);
+ ret++;
+ }
+ }
+ catch(...) { }
+
+ return ret;
+}
+
+/*
+void
+ValueNode_Animated::manipulate_time(const Time& old_begin,const Time& old_end,const Time& new_begin,const Time& new_end)
+{
+#define old_2_new(x) (((x)-old_begin)/(old_end-old_begin)*(new_end-new_begin)+new_begin)
+ std::vector<Waypoint*> selected;
+ std::vector<Waypoint*>::iterator iter;
+
+ if(find(old_begin,old_end,selected))
+ {
+ // check to make sure this operation is OK
+ for(iter=selected.begin();iter!=selected.end();++iter)
+ {
+ try
+ {
+ Time new_time(old_2_new((*iter)->get_time()));
+ if(new_time>=old_begin && new_time<old_end)
+ continue;
+ find(new_time);
+ // If we found a waypoint already at that time, then
+ // we need to abort
+ throw Exception::BadTime(_("Waypoint Conflict"));
+ }
+ catch(Exception::NotFound) { }
+
+ selected.back()->set_time(old_2_new(selected.back()->get_time()));
+ selected.pop_back();
+ }
+
+
+ while(!selected.empty())
+ {
+ selected.back()->set_time(old_2_new(selected.back()->get_time()));
+ selected.pop_back();
+ }
+
+ changed();
+ }
+#undef old_2_new
+}
+*/
+
+Waypoint
+ValueNode_Animated::new_waypoint_at_time(const Time& time)const
+{
+ Waypoint waypoint;
+ try
+ {
+ // Trivial case, we are sitting on a waypoint
+ waypoint=*find(time);
+ waypoint.make_unique();
+ }
+ catch(...)
+ {
+ if(waypoint_list().empty())
+ {
+ waypoint.set_value((*this)(time));
+ }
+ else
+ {
+ WaypointList::const_iterator prev;
+ WaypointList::const_iterator next;
+
+ bool has_prev(false), has_next(false);
+
+ try { prev=find_prev(time); has_prev=true; } catch(...) { }
+ try { next=find_next(time); has_next=true; } catch(...) { }
+
+ /*
+ WaypointList::const_iterator closest;
+
+ if(has_prev&&!has_next)
+ closest=prev;
+ else if(has_next&&!has_prev)
+ closest=next;
+ else if(time-prev->get_time()<next->get_time()-time)
+ closest=prev;
+ else
+ closest=next;
+
+ for(iter=waypoint_list().begin();iter!=waypoint_list().end();++iter)
+ {
+ const Real dist(abs(iter->get_time()-time));
+ if(dist<abs(closest->get_time()-time))
+ closest=iter;
+ }
+ */
+
+ if(has_prev && !prev->is_static())
+ waypoint.set_value_node(prev->get_value_node());
+ if(has_next && !next->is_static())
+ waypoint.set_value_node(next->get_value_node());
+ else
+ waypoint.set_value((*this)(time));
+
+ /*if(has_prev)
+ waypoint.set_after(prev->get_before());
+ if(has_next)
+ waypoint.set_before(next->get_after());
+ */
+ }
+ }
+ waypoint.set_time(time);
+ waypoint.set_parent_value_node(const_cast<ValueNode_Animated*>(this));
+// synfig::info("waypoint.get_after()=set to %d",waypoint.get_after());
+// synfig::info("waypoint.get_before()=set to %d",waypoint.get_before());
+
+ return waypoint;
+}
+
+ValueNode_Animated::WaypointList::iterator
+ValueNode_Animated::find(const UniqueID &x)
+{
+ ValueNode_Animated::WaypointList::iterator iter;
+ iter=std::find(waypoint_list().begin(),waypoint_list().end(),x);
+ if(iter==waypoint_list().end() || iter->get_uid()!=x.get_uid())
+ throw Exception::NotFound(strprintf("ValueNode_Animated::find(): Can't find UniqueID %d",x.get_uid()));
+ return iter;
+}
+
+ValueNode_Animated::WaypointList::const_iterator
+ValueNode_Animated::find(const UniqueID &x)const
+{
+ return const_cast<ValueNode_Animated*>(this)->find(x);
+ /*
+ ValueNode_Animated::WaypointList::const_iterator iter;
+ iter=std::find(waypoint_list().begin(),waypoint_list().end(),x);
+ if(iter!=waypoint_list().end() && iter->get_uid()!=x.get_uid())
+ throw Exception::NotFound(strprintf("ValueNode_Animated::find()const: Can't find UniqueID %d",x.get_uid()));
+ return iter;
+ */
+}
+
+ValueNode_Animated::WaypointList::iterator
+ValueNode_Animated::find(const Time &x)
+{
+ WaypointList::iterator iter(binary_find(waypoint_list().begin(),waypoint_list().end(),x));
+
+ if(iter!=waypoint_list().end() && x.is_equal(iter->get_time()))
+ return iter;
+
+ throw Exception::NotFound(strprintf("ValueNode_Animated::find(): Can't find Waypoint at %s",x.get_string().c_str()));
+}
+
+ValueNode_Animated::WaypointList::const_iterator
+ValueNode_Animated::find(const Time &x)const
+{
+ return const_cast<ValueNode_Animated*>(this)->find(x);
+ /*
+ WaypointList::const_iterator iter(binary_find(waypoint_list().begin(),waypoint_list().end(),x));
+
+ if(iter!=waypoint_list().end() && x.is_equal(iter->get_time()))
+ return iter;
+
+ throw Exception::NotFound(strprintf("ValueNode_Animated::find(): Can't find Waypoint at %s",x.get_string().c_str()));
+ */
+}
+
+ValueNode_Animated::WaypointList::iterator
+ValueNode_Animated::find_next(const Time &x)
+{
+ WaypointList::iterator iter(binary_find(waypoint_list().begin(),waypoint_list().end(),x));
+
+ if(iter!=waypoint_list().end())
+ {
+ if(iter->get_time().is_more_than(x))
+ return iter;
+ ++iter;
+ if(iter!=waypoint_list().end() && iter->get_time().is_more_than(x))
+ return iter;
+ }
+
+ throw Exception::NotFound(strprintf("ValueNode_Animated::find_next(): Can't find Waypoint after %s",x.get_string().c_str()));
+}
+
+ValueNode_Animated::WaypointList::const_iterator
+ValueNode_Animated::find_next(const Time &x)const
+{
+ return const_cast<ValueNode_Animated*>(this)->find_next(x);
+ /*
+ WaypointList::const_iterator iter(binary_find(waypoint_list().begin(),waypoint_list().end(),x));
+
+ if(iter!=waypoint_list().end())
+ {
+ if(iter->get_time()-Time::epsilon()>x)
+ return iter;
+ ++iter;
+ if(iter!=waypoint_list().end() && iter->get_time()-Time::epsilon()>x)
+ return iter;
+ }
+
+ throw Exception::NotFound(strprintf("ValueNode_Animated::find_next(): Can't find Waypoint after %s",x.get_string().c_str()));
+*/
+}
+
+ValueNode_Animated::WaypointList::iterator
+ValueNode_Animated::find_prev(const Time &x)
+{
+ WaypointList::iterator iter(binary_find(waypoint_list().begin(),waypoint_list().end(),x));
+
+ if(iter!=waypoint_list().end())
+ {
+ if(iter->get_time().is_less_than(x))
+ return iter;
+ if(iter!=waypoint_list().begin() && (--iter)->get_time().is_less_than(x))
+ return iter;
+ }
+
+ throw Exception::NotFound(strprintf("ValueNode_Animated::find_prev(): Can't find Waypoint after %s",x.get_string().c_str()));
+}
+
+ValueNode_Animated::WaypointList::const_iterator
+ValueNode_Animated::find_prev(const Time &x)const
+{
+ return const_cast<ValueNode_Animated*>(this)->find_prev(x);
+ /*
+ WaypointList::const_iterator iter(binary_find(waypoint_list().begin(),waypoint_list().end(),x));
+
+ if(iter!=waypoint_list().end())
+ {
+ if(iter->get_time()+Time::epsilon()<x)
+ return iter;
+ if(iter!=waypoint_list().begin() && (--iter)->get_time()+Time::epsilon()<x)
+ return iter;
+ }
+ throw Exception::NotFound(strprintf("ValueNode_Animated::find_prev(): Can't find Waypoint after %s",x.get_string().c_str()));
+ */
+}
+
+void
+ValueNode_Animated::erase(const UniqueID &x)
+{
+ waypoint_list().erase(find(x));
+}
+
+ValueNode_Animated::WaypointList::iterator
+ValueNode_Animated::add(const Waypoint &x)
+{
+ Waypoint waypoint(x);
+ waypoint.set_parent_value_node(this);
+ waypoint_list_.push_back(waypoint);
+ //assert(waypoint_list_.back().get_parent_value_node()==this);
+ WaypointList::iterator ret=waypoint_list_.end();
+ --ret;
+ changed();
+ return ret;
+}
+
+void
+ValueNode_Animated::set_type(ValueBase::Type t)
+{
+ ValueNode::set_type(t);
+}
+
+ValueNode_Animated::Handle
+synfig::ValueNode_Animated::create(ValueBase::Type type)
+{
+ switch(type)
+ {
+ case ValueBase::TYPE_TIME:
+ return ValueNode_Animated::Handle(new _Hermite<Time>);
+ case ValueBase::TYPE_REAL:
+ return ValueNode_Animated::Handle(new _Hermite<Vector::value_type>);
+ case ValueBase::TYPE_INTEGER:
+ return ValueNode_Animated::Handle(new _Hermite<int>);
+ case ValueBase::TYPE_ANGLE:
+ return ValueNode_Animated::Handle(new _Hermite<Angle>);
+ case ValueBase::TYPE_VECTOR:
+ return ValueNode_Animated::Handle(new _Hermite<Vector>);
+ case ValueBase::TYPE_COLOR:
+ return ValueNode_Animated::Handle(new _Hermite<Color>);
+
+ case ValueBase::TYPE_STRING:
+ return ValueNode_Animated::Handle(new _Constant<String>);
+ case ValueBase::TYPE_GRADIENT:
+ return ValueNode_Animated::Handle(new _Hermite<Gradient>);
+ case ValueBase::TYPE_BOOL:
+ return ValueNode_Animated::Handle(new _AnimBool);
+ case ValueBase::TYPE_CANVAS:
+ return ValueNode_Animated::Handle(new _Constant<Canvas::LooseHandle>);
+ default:
+ throw
+ Exception::BadType(strprintf(_("%s: You cannot use a %s in an animated ValueNode"),"synfig::ValueNode_Animated::create()",
+ ValueBase::type_name(type).c_str())
+ );
+ break;
+ }
+ return ValueNode_Animated::Handle();
+}
+
+ValueNode_Animated::Handle
+ValueNode_Animated::create(const ValueBase& value, const Time& time)
+{
+ return create(ValueNode::Handle(ValueNode_Const::create(value)),time);
+}
+
+ValueNode_Animated::Handle
+ValueNode_Animated::create(ValueNode::Handle value_node, const Time& time)
+{
+ ValueNode_Animated::Handle ret(create(value_node->get_type()));
+ ret->new_waypoint(time,value_node);
+ return ret;
+}
+
+ValueNode_Animated::~ValueNode_Animated()
+{
+}
+
+String
+ValueNode_Animated::get_name()const
+{
+ return "animated";
+}
+
+String
+ValueNode_Animated::get_local_name()const
+{
+ return _("Animated");
+}
+
+void ValueNode_Animated::get_times_vfunc(Node::time_set &set) const
+{
+ //add all the way point times to the value node...
+
+ WaypointList::const_iterator i = waypoint_list().begin(),
+ end = waypoint_list().end();
+
+ for(; i != end; ++i)
+ {
+ TimePoint t;
+ t.set_time(i->get_time());
+ t.set_before(i->get_before());
+ t.set_after(i->get_after());
+ t.set_guid(i->get_guid());
+ set.insert(t);
+ }
+}
+struct timecmp
+ {
+ Time t;
+
+ timecmp(const Time &c) :t(c) {}
+
+ bool operator()(const Waypoint &rhs) const
+ {
+ return t.is_equal(rhs.get_time());
+ }
+ };
+
+ ValueNode_Animated::findresult
+ ValueNode_Animated::find_uid(const UniqueID &x)
+ {
+ findresult f;
+ f.second = false;
+
+ //search for it... and set the bool part of the return value to true if we found it!
+ f.first = std::find(waypoint_list_.begin(), waypoint_list_.end(), x);
+ if(f.first != waypoint_list_.end())
+ f.second = true;
+
+ return f;
+ }
+
+ ValueNode_Animated::const_findresult
+ ValueNode_Animated::find_uid(const UniqueID &x)const
+ {
+ const_findresult f;
+ f.second = false;
+
+ //search for it... and set the bool part of the return value to true if we found it!
+ f.first = std::find(waypoint_list_.begin(), waypoint_list_.end(), x);
+ if(f.first != waypoint_list_.end())
+ f.second = true;
+
+ return f;
+ }
+
+ ValueNode_Animated::findresult
+ ValueNode_Animated::find_time(const Time &x)
+ {
+ findresult f;
+ f.second = false;
+
+ //search for it... and set the bool part of the return value to true if we found it!
+ f.first = std::find_if(waypoint_list_.begin(), waypoint_list_.end(), timecmp(x));
+ if(f.first != waypoint_list_.end())
+ f.second = true;
+
+ return f;
+ }
+
+ValueNode_Animated::const_findresult
+ValueNode_Animated::find_time(const Time &x)const
+{
+ const_findresult f;
+ f.second = false;
+
+ //search for it... and set the bool part of the return value to true if we found it!
+ f.first = std::find_if(waypoint_list_.begin(), waypoint_list_.end(), timecmp(x));
+ if(f.first != waypoint_list_.end())
+ f.second = true;
+
+ return f;
+}
+
+void
+ValueNode_Animated::insert_time(const Time& location, const Time& delta)
+{
+ if(!delta)
+ return;
+ try
+ {
+ WaypointList::iterator iter(find_next(location));
+ for(;iter!=waypoint_list().end();++iter)
+ {
+ iter->set_time(iter->get_time()+delta);
+ }
+ changed();
+ }
+ catch(Exception::NotFound) { }
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_animated.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_ANIMATED_H
+#define __SYNFIG_VALUENODE_ANIMATED_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <list>
+
+#include "valuenode.h"
+#include "uniqueid.h"
+#include "waypoint.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+struct ValueNode_Animated : public ValueNode
+{
+public:
+ typedef etl::handle<ValueNode_Animated> Handle;
+ typedef etl::handle<const ValueNode_Animated> ConstHandle;
+
+ typedef synfig::Waypoint Waypoint;
+ typedef synfig::WaypointList WaypointList;
+
+ typedef std::pair<WaypointList::iterator,bool> findresult;
+ typedef std::pair<WaypointList::const_iterator,bool> const_findresult;
+
+protected:
+ WaypointList waypoint_list_;
+
+public:
+ WaypointList &waypoint_list() { return waypoint_list_; }
+
+ const WaypointList &waypoint_list()const { return waypoint_list_; }
+
+ virtual WaypointList::iterator new_waypoint(Time t, ValueBase value)=0;
+
+ virtual WaypointList::iterator new_waypoint(Time t, ValueNode::Handle value_node)=0;
+
+ /*! \note this does not add any waypoint to the ValueNode! */
+ Waypoint new_waypoint_at_time(const Time& t)const;
+
+ WaypointList::iterator add(const Waypoint &x);
+
+ void erase(const UniqueID &x);
+
+ //either use find result (return bool and iterator) or
+ findresult find_uid(const UniqueID &x);
+ const_findresult find_uid(const UniqueID &x)const;
+ findresult find_time(const Time &x);
+ const_findresult find_time(const Time &x)const;
+
+ WaypointList::iterator find(const UniqueID &x);
+ WaypointList::const_iterator find(const UniqueID &x)const;
+ WaypointList::iterator find(const Time &x);
+ WaypointList::const_iterator find(const Time &x)const;
+
+ WaypointList::iterator find_next(const Time &x);
+ WaypointList::const_iterator find_next(const Time &x)const;
+ WaypointList::iterator find_prev(const Time &x);
+ WaypointList::const_iterator find_prev(const Time &x)const;
+
+ virtual ~ValueNode_Animated();
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+ static Handle create(ValueBase::Type type);
+
+ static Handle create(const ValueBase& value, const Time& time);
+
+ static Handle create(ValueNode::Handle value_node, const Time& time);
+
+ int find(const Time& begin,const Time& end,std::vector<Waypoint*>& list);
+
+ void insert_time(const Time& location, const Time& delta);
+
+protected:
+ ValueNode_Animated();
+
+ void set_type(ValueBase::Type t);
+ virtual void get_times_vfunc(Node::time_set &set) const;
+public:
+ DCAST_HACK_ID(4);
+};
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_bline.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode_bline.h"
+#include "valuenode_const.h"
+#include "valuenode_composite.h"
+#include "general.h"
+#include "exception.h"
+#include "blinepoint.h"
+#include <vector>
+#include <list>
+#include <algorithm>
+#include <ETL/hermite>
+#include <ETL/calculus>
+#include "segment.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+inline float
+linear_interpolation(const float& a, const float& b, float c)
+{ return (b-a)*c+a; }
+
+inline Vector
+linear_interpolation(const Vector& a, const Vector& b, float c)
+{ return (b-a)*c+a; }
+
+inline Vector
+radial_interpolation(const Vector& a, const Vector& b, float c)
+{
+ // if either extreme is zero then use linear interpolation instead
+ if (a.is_equal_to(Vector::zero()) || b.is_equal_to(Vector::zero()))
+ return linear_interpolation(a, b, c);
+
+ affine_combo<Real,float> mag_combo;
+ affine_combo<Angle,float> ang_combo;
+
+ Real mag(mag_combo(a.mag(),b.mag(),c));
+ Angle ang(ang_combo(Angle::tan(a[1],a[0]),Angle::tan(b[1],b[0]),c));
+
+ return Point( mag*Angle::cos(ang).get(),mag*Angle::sin(ang).get() );
+}
+
+inline void
+transform_coords(Vector in, Vector& out, const Point& coord_origin, const Point *coord_sys)
+{
+ in -= coord_origin;
+ out[0] = in * coord_sys[0];
+ out[1] = in * coord_sys[1];
+}
+
+inline void
+untransform_coords(const Vector& in, Vector& out, const Point& coord_origin, const Point *coord_sys)
+{
+ out[0] = in * coord_sys[0];
+ out[1] = in * coord_sys[1];
+ out += coord_origin;
+}
+
+ValueBase
+synfig::convert_bline_to_segment_list(const ValueBase& bline)
+{
+ std::vector<Segment> ret;
+
+// std::vector<BLinePoint> list(bline.operator std::vector<BLinePoint>());
+ //std::vector<BLinePoint> list(bline);
+ std::vector<BLinePoint> list(bline.get_list().begin(),bline.get_list().end());
+ std::vector<BLinePoint>::const_iterator iter;
+
+ BLinePoint prev,first;
+
+ //start with prev = first and iter on the second...
+
+ if(list.empty()) return ValueBase(ret,bline.get_loop());
+ first = prev = list.front();
+
+ for(iter=++list.begin();iter!=list.end();++iter)
+ {
+ ret.push_back(
+ Segment(
+ prev.get_vertex(),
+ prev.get_tangent2(),
+ iter->get_vertex(),
+ iter->get_tangent1()
+ )
+ );
+ prev=*iter;
+ }
+ if(bline.get_loop())
+ {
+ ret.push_back(
+ Segment(
+ prev.get_vertex(),
+ prev.get_tangent2(),
+ first.get_vertex(),
+ first.get_tangent1()
+ )
+ );
+ }
+ return ValueBase(ret,bline.get_loop());
+}
+
+ValueBase
+synfig::convert_bline_to_width_list(const ValueBase& bline)
+{
+ std::vector<Real> ret;
+// std::vector<BLinePoint> list(bline.operator std::vector<BLinePoint>());
+ //std::vector<BLinePoint> list(bline);
+ std::vector<BLinePoint> list(bline.get_list().begin(),bline.get_list().end());
+ std::vector<BLinePoint>::const_iterator iter;
+
+ if(bline.empty())
+ return ValueBase(ValueBase::TYPE_LIST);
+
+ for(iter=list.begin();iter!=list.end();++iter)
+ ret.push_back(iter->get_width());
+
+ if(bline.get_loop())
+ ret.push_back(list.front().get_width());
+
+ return ValueBase(ret,bline.get_loop());
+}
+
+
+/* === M E T H O D S ======================================================= */
+
+
+ValueNode_BLine::ValueNode_BLine():
+ ValueNode_DynamicList(ValueBase::TYPE_BLINEPOINT)
+{
+}
+
+ValueNode_BLine::~ValueNode_BLine()
+{
+}
+
+ValueNode_BLine*
+ValueNode_BLine::create(const ValueBase &value)
+{
+ if(value.get_type()!=ValueBase::TYPE_LIST)
+ return 0;
+
+ ValueNode_BLine* value_node(new ValueNode_BLine());
+
+ if(!value.empty())
+ {
+ switch(value.get_contained_type())
+ {
+ case ValueBase::TYPE_BLINEPOINT:
+ {
+// std::vector<BLinePoint> bline_points(value.operator std::vector<BLinePoint>());
+ //std::vector<BLinePoint> bline_points(value);
+ std::vector<BLinePoint> bline_points(value.get_list().begin(),value.get_list().end());
+ std::vector<BLinePoint>::const_iterator iter;
+
+ for(iter=bline_points.begin();iter!=bline_points.end();iter++)
+ {
+ value_node->add(ValueNode::Handle(ValueNode_Composite::create(*iter)));
+ }
+ value_node->set_loop(value.get_loop());
+ }
+ break;
+ case ValueBase::TYPE_SEGMENT:
+ {
+ // Here, we want to convert a list of segments
+ // into a list of BLinePoints. We make an assumption
+ // that the segment list is continuous(sp), but not necessarily
+ // smooth.
+
+ value_node->set_loop(false);
+// std::vector<Segment> segments(value.operator std::vector<Segment>());
+// std::vector<Segment> segments(value);
+ std::vector<Segment> segments(value.get_list().begin(),value.get_list().end());
+ std::vector<Segment>::const_iterator iter,last(segments.end());
+ --last;
+ ValueNode_Const::Handle prev,first;
+
+ for(iter=segments.begin();iter!=segments.end();iter++)
+ {
+#define PREV_POINT prev->get_value().get(BLinePoint())
+#define FIRST_POINT first->get_value().get(BLinePoint())
+#define CURR_POINT curr->get_value().get(BLinePoint())
+ if(iter==segments.begin())
+ {
+ prev=ValueNode_Const::create(ValueBase::TYPE_BLINEPOINT);
+ {
+ BLinePoint prev_point(PREV_POINT);
+ prev_point.set_vertex(iter->p1);
+ prev_point.set_tangent1(iter->t1);
+ prev_point.set_width(0.01);
+ prev_point.set_origin(0.5);
+ prev_point.set_split_tangent_flag(false);
+ prev->set_value(prev_point);
+ }
+ first=prev;
+ value_node->add(ValueNode::Handle(prev));
+
+ }
+ if(iter==last && iter->p2.is_equal_to(FIRST_POINT.get_vertex()))
+ {
+ value_node->set_loop(true);
+ if(!iter->t2.is_equal_to(FIRST_POINT.get_tangent1()))
+ {
+ BLinePoint first_point(FIRST_POINT);
+ first_point.set_tangent1(iter->t2);
+ first->set_value(first_point);
+ }
+ continue;
+ }
+
+ ValueNode_Const::Handle curr;
+ curr=ValueNode_Const::create(ValueBase::TYPE_BLINEPOINT);
+ {
+ BLinePoint curr_point(CURR_POINT);
+ curr_point.set_vertex(iter->p2);
+ curr_point.set_tangent1(iter->t2);
+ curr_point.set_width(0.01);
+ curr_point.set_origin(0.5);
+ curr_point.set_split_tangent_flag(false);
+ curr->set_value(curr_point);
+ }
+ if(!PREV_POINT.get_tangent1().is_equal_to(iter->t1))
+ {
+ BLinePoint prev_point(PREV_POINT);
+ prev_point.set_split_tangent_flag(true);
+ prev_point.set_tangent2(iter->t1);
+ prev->set_value(prev_point);
+ }
+ value_node->add(ValueNode::Handle(curr));
+ prev=curr;
+ }
+
+ }
+ break;
+ default:
+ // We got a list of who-knows-what. We don't have any idea
+ // what to do with it.
+ return 0;
+ break;
+ }
+ }
+
+
+ return value_node;
+}
+
+ValueNode_BLine::ListEntry
+ValueNode_BLine::create_list_entry(int index, Time time, Real origin)
+{
+ ValueNode_BLine::ListEntry ret;
+
+
+ synfig::BLinePoint prev,next;
+
+ int prev_i,next_i;
+
+ index=index%link_count();
+
+ assert(index>=0);
+ ret.index=index;
+ ret.set_parent_value_node(this);
+
+ if(!list[index].status_at_time(time))
+ next_i=find_next_valid_entry(index,time);
+ else
+ next_i=index;
+ prev_i=find_prev_valid_entry(index,time);
+
+ synfig::info("index=%d, next_i=%d, prev_i=%d",index,next_i,prev_i);
+
+ next=(*list[next_i].value_node)(time);
+ prev=(*list[prev_i].value_node)(time);
+
+ etl::hermite<Vector> curve(prev.get_vertex(),next.get_vertex(),prev.get_tangent2(),next.get_tangent1());
+ etl::derivative< etl::hermite<Vector> > deriv(curve);
+
+ synfig::BLinePoint bline_point;
+ bline_point.set_vertex(curve(origin));
+ bline_point.set_width((next.get_width()-prev.get_width())*origin+prev.get_width());
+ bline_point.set_tangent1(deriv(origin)*min(1.0-origin,origin));
+ bline_point.set_tangent2(bline_point.get_tangent1());
+ bline_point.set_split_tangent_flag(false);
+ bline_point.set_origin(origin);
+
+ ret.value_node=ValueNode_Composite::create(bline_point);
+
+ return ret;
+}
+
+ValueBase
+ValueNode_BLine::operator()(Time t)const
+{
+ std::vector<BLinePoint> ret_list;
+
+ std::vector<ListEntry>::const_iterator iter,first_iter;
+ bool first_flag(true);
+ bool rising;
+ int index(0);
+ float next_scale(1.0f);
+
+ BLinePoint prev,first;
+ first.set_origin(100.0f);
+
+ // loop through all the list's entries
+ for(iter=list.begin();iter!=list.end();++iter,index++)
+ {
+ // how 'on' is this vertex?
+ float amount(iter->amount_at_time(t,&rising));
+
+ assert(amount>=0.0f);
+ assert(amount<=1.0f);
+
+ // it's fully on
+ if(amount==1.0f)
+ {
+ if(first_flag)
+ {
+ first_iter=iter;
+ first=prev=(*iter->value_node)(t).get(prev);
+ first_flag=false;
+ ret_list.push_back(first);
+ continue;
+ }
+
+ BLinePoint curr;
+ curr=(*iter->value_node)(t).get(prev);
+
+ if(next_scale!=1.0f)
+ {
+ ret_list.back().set_split_tangent_flag(true);
+ ret_list.back().set_tangent2(prev.get_tangent2()*next_scale);
+
+ ret_list.push_back(curr);
+
+ ret_list.back().set_split_tangent_flag(true);
+ ret_list.back().set_tangent2(curr.get_tangent2());
+ ret_list.back().set_tangent1(curr.get_tangent1()*next_scale);
+
+ next_scale=1.0f;
+ }
+ else
+ {
+ ret_list.push_back(curr);
+ }
+
+ prev=curr;
+ }
+ // it's partly on
+ else if(amount>0.0f)
+ {
+ std::vector<ListEntry>::const_iterator begin_iter,end_iter;
+
+ // This is where the interesting stuff happens
+ // We need to seek forward in the list to see what the next
+ // active point is
+
+ BLinePoint blp_here_on; // the current vertex, when fully on
+ BLinePoint blp_here_off; // the current vertex, when fully off
+ BLinePoint blp_here_now; // the current vertex, right now (between on and off)
+ BLinePoint blp_prev_off; // the beginning of dynamic group when fully off
+ BLinePoint blp_next_off; // the end of the dynamic group when fully off
+
+ int dist_from_begin(0), dist_from_end(0);
+ Time off_time, on_time;
+
+ if(!rising) // if not rising, then we were fully on in the past, and will be fully off in the future
+ {
+ try{ on_time=iter->find_prev(t)->get_time(); }
+ catch(...) { on_time=Time::begin(); }
+ try{ off_time=iter->find_next(t)->get_time(); }
+ catch(...) { off_time=Time::end(); }
+ }
+ else // otherwise we were fully off in the past, and will be fully on in the future
+ {
+ try{ off_time=iter->find_prev(t)->get_time(); }
+ catch(...) { off_time=Time::begin(); }
+ try{ on_time=iter->find_next(t)->get_time(); }
+ catch(...) { on_time=Time::end(); }
+ }
+
+ blp_here_on=(*iter->value_node)(on_time).get(blp_here_on);
+// blp_here_on=(*iter->value_node)(t).get(blp_here_on);
+
+ // Find "end" of dynamic group - ie. search forward along
+ // the bline from the current point until we find a point
+ // which is more 'on'than the current one
+ end_iter=iter;
+// for(++end_iter;begin_iter!=list.end();++end_iter)
+ for(++end_iter;end_iter!=list.end();++end_iter)
+ if(end_iter->amount_at_time(t)>amount)
+ break;
+
+ // If we did not find an end of the dynamic group...
+ // Writeme! at least now it doesn't crash if first_iter
+ // isn't set yet
+ if(end_iter==list.end())
+ {
+ if(get_loop() && !first_flag)
+ end_iter=first_iter;
+ else
+ end_iter=--list.end();
+ }
+
+ blp_next_off=(*end_iter->value_node)(off_time).get(prev);
+
+ // Find "begin" of dynamic group
+ begin_iter=iter;
+ blp_prev_off.set_origin(100.0f); // set the origin to 100 (which is crazy) so that we can check to see if it was found
+ do
+ {
+ if(begin_iter==list.begin())
+ {
+ if(get_loop())
+ begin_iter=list.end();
+ else
+ break;
+ }
+
+ --begin_iter;
+ dist_from_begin++;
+
+ // if we've gone all around the loop, give up
+ if(begin_iter==iter)
+ break;
+
+ if(begin_iter->amount_at_time(t)>amount)
+ {
+ blp_prev_off=(*begin_iter->value_node)(off_time).get(prev);
+ break;
+ }
+ }while(true);
+
+ // If we did not find a begin
+ if(blp_prev_off.get_origin()==100.0f)
+ {
+ // Writeme! - this needs work, but at least now it
+ // doesn't crash
+ if(first_flag)
+ begin_iter=list.begin();
+ else
+ begin_iter=first_iter;
+ blp_prev_off=(*begin_iter->value_node)(off_time).get(prev);
+ }
+
+ // this is how the curve looks when we have completely vanished
+ etl::hermite<Vector> curve(blp_prev_off.get_vertex(), blp_next_off.get_vertex(),
+ blp_prev_off.get_tangent2(), blp_next_off.get_tangent1());
+ etl::derivative< etl::hermite<Vector> > deriv(curve);
+
+ // where would we be on this curve, how wide will we be, and
+ // where will our tangents point (all assuming that we hadn't vanished)
+ blp_here_off.set_vertex(curve(blp_here_on.get_origin()));
+ blp_here_off.set_width((blp_next_off.get_width()-blp_prev_off.get_width())*blp_here_on.get_origin()+blp_prev_off.get_width());
+ blp_here_off.set_tangent1(deriv(blp_here_on.get_origin()));
+ blp_here_off.set_tangent2(deriv(blp_here_on.get_origin()));
+
+ float prev_tangent_scalar(1.0f);
+ float next_tangent_scalar(1.0f);
+
+ //synfig::info("index_%d:dist_from_begin=%d",index,dist_from_begin);
+ //synfig::info("index_%d:dist_from_end=%d",index,dist_from_end);
+
+ // If we are the next to the begin
+ if(begin_iter==--std::vector<ListEntry>::const_iterator(iter) || dist_from_begin==1)
+ prev_tangent_scalar=linear_interpolation(blp_here_on.get_origin(), 1.0f, amount);
+ else
+ prev_tangent_scalar=linear_interpolation(blp_here_on.get_origin()-prev.get_origin(), 1.0f, amount);
+
+ // If we are the next to the end
+ if(end_iter==++std::vector<ListEntry>::const_iterator(iter) || dist_from_end==1)
+ next_tangent_scalar=linear_interpolation(1.0-blp_here_on.get_origin(), 1.0f, amount);
+ else if(list.end()!=++std::vector<ListEntry>::const_iterator(iter))
+ {
+ BLinePoint next;
+ next=((*(++std::vector<ListEntry>::const_iterator(iter))->value_node)(t).get(prev));
+ next_tangent_scalar=linear_interpolation(next.get_origin()-blp_here_on.get_origin(), 1.0f, amount);
+ }
+ else
+ //! \todo this isn't quite right; we should handle looped blines identically no matter where the loop happens
+ //! and we currently don't. this at least makes it a lot better than it was before
+ next_tangent_scalar=linear_interpolation(blp_next_off.get_origin()-blp_here_on.get_origin(), 1.0f, amount);
+ next_scale=next_tangent_scalar;
+
+ //blp_here_now.set_vertex(linear_interpolation(blp_here_off.get_vertex(), blp_here_on.get_vertex(), amount));
+ // if(false)
+ // {
+ // // My first try
+ // Point ref_point_begin(((*begin_iter->value_node)(off_time).get(prev).get_vertex() +
+ // (*end_iter->value_node)(off_time).get(prev).get_vertex()) * 0.5);
+ // Point ref_point_end(((*begin_iter->value_node)(on_time).get(prev).get_vertex() +
+ // (*end_iter->value_node)(on_time).get(prev).get_vertex()) * 0.5);
+ // Point ref_point_now(((*begin_iter->value_node)(t).get(prev).get_vertex() +
+ // (*end_iter->value_node)(t).get(prev).get_vertex()) * 0.5);
+ // Point ref_point_linear(linear_interpolation(ref_point_begin, ref_point_end, amount));
+ //
+ // blp_here_now.set_vertex(linear_interpolation(blp_here_off.get_vertex(), blp_here_on.get_vertex(), amount) +
+ // (ref_point_now-ref_point_linear));
+ // blp_here_now.set_tangent1(linear_interpolation(blp_here_off.get_tangent1(), blp_here_on.get_tangent1(), amount));
+ // blp_here_now.set_split_tangent_flag(blp_here_on.get_split_tangent_flag());
+ // if(blp_here_now.get_split_tangent_flag())
+ // blp_here_now.set_tangent2(linear_interpolation(blp_here_off.get_tangent2(), blp_here_on.get_tangent2(), amount));
+ // }
+ // else
+ {
+ // My second try
+
+ // define 3 coordinate systems:
+ Point off_coord_sys[2], off_coord_origin; // when the current vertex is completely off
+ Point on_coord_sys[2] , on_coord_origin; // when the current vertex is completely on
+ Point curr_coord_sys[2], curr_coord_origin; // the current state - somewhere in between
+
+ // for each of the 3 systems, the origin is half way between the previous and next active point
+ // and the axes are based on a vector from the next active point to the previous
+ {
+ const Point end_pos_at_off_time(( *end_iter->value_node)(off_time).get(prev).get_vertex());
+ const Point begin_pos_at_off_time((*begin_iter->value_node)(off_time).get(prev).get_vertex());
+ off_coord_origin=(begin_pos_at_off_time + end_pos_at_off_time)/2;
+ off_coord_sys[0]=(begin_pos_at_off_time - end_pos_at_off_time).norm();
+ off_coord_sys[1]=off_coord_sys[0].perp();
+
+ const Point end_pos_at_on_time(( *end_iter->value_node)(on_time).get(prev).get_vertex());
+ const Point begin_pos_at_on_time((*begin_iter->value_node)(on_time).get(prev).get_vertex());
+ on_coord_origin=(begin_pos_at_on_time + end_pos_at_on_time)/2;
+ on_coord_sys[0]=(begin_pos_at_on_time - end_pos_at_on_time).norm();
+ on_coord_sys[1]=on_coord_sys[0].perp();
+
+ const Point end_pos_at_current_time(( *end_iter->value_node)(t).get(prev).get_vertex());
+ const Point begin_pos_at_current_time((*begin_iter->value_node)(t).get(prev).get_vertex());
+ curr_coord_origin=(begin_pos_at_current_time + end_pos_at_current_time)/2;
+ curr_coord_sys[0]=(begin_pos_at_current_time - end_pos_at_current_time).norm();
+ curr_coord_sys[1]=curr_coord_sys[0].perp();
+
+ // Invert (transpose) the last of these matricies, since we use it for transform back
+ swap(curr_coord_sys[0][1],curr_coord_sys[1][0]);
+ }
+
+ /* The code that was here before used just end_iter as the origin, rather than the mid-point */
+
+ // We know our location and tangent(s) when fully on and fully off
+ // Transform each of these into their corresponding coordinate system
+ Point trans_on_point, trans_off_point;
+ Vector trans_on_t1, trans_on_t2, trans_off_t1, trans_off_t2;
+
+ transform_coords(blp_here_on.get_vertex(), trans_on_point, on_coord_origin, on_coord_sys);
+ transform_coords(blp_here_off.get_vertex(), trans_off_point, off_coord_origin, off_coord_sys);
+
+#define COORD_SYS_RADIAL_TAN_INTERP 1
+
+#ifdef COORD_SYS_RADIAL_TAN_INTERP
+ transform_coords(blp_here_on.get_tangent1(), trans_on_t1, Point::zero(), on_coord_sys);
+ transform_coords(blp_here_off.get_tangent1(), trans_off_t1, Point::zero(), off_coord_sys);
+
+ if(blp_here_on.get_split_tangent_flag())
+ {
+ transform_coords(blp_here_on.get_tangent2(), trans_on_t2, Point::zero(), on_coord_sys);
+ transform_coords(blp_here_off.get_tangent2(), trans_off_t2, Point::zero(), off_coord_sys);
+ }
+#endif
+
+ {
+ // Interpolate between the 'on' point and the 'off' point and untransform to get our point's location
+ Point tmp;
+ untransform_coords(linear_interpolation(trans_off_point, trans_on_point, amount),
+ tmp, curr_coord_origin, curr_coord_sys);
+ blp_here_now.set_vertex(tmp);
+ }
+
+#define INTERP_FUNCTION radial_interpolation
+//#define INTERP_FUNCTION linear_interpolation
+
+#ifdef COORD_SYS_RADIAL_TAN_INTERP
+ {
+ Vector tmp;
+ untransform_coords(INTERP_FUNCTION(trans_off_t1,trans_on_t1,amount), tmp, Point::zero(), curr_coord_sys);
+ blp_here_now.set_tangent1(tmp);
+ }
+#else
+ blp_here_now.set_tangent1(radial_interpolation(blp_here_off.get_tangent1(),blp_here_on.get_tangent1(),amount));
+#endif
+
+ if (blp_here_on.get_split_tangent_flag())
+ {
+ blp_here_now.set_split_tangent_flag(true);
+#ifdef COORD_SYS_RADIAL_TAN_INTERP
+ {
+ Vector tmp;
+ untransform_coords(INTERP_FUNCTION(trans_off_t2,trans_on_t2,amount), tmp, Point::zero(), curr_coord_sys);
+ blp_here_now.set_tangent2(tmp);
+ }
+#else
+ blp_here_now.set_tangent2(radial_interpolation(blp_here_off.get_tangent2(),blp_here_on.get_tangent2(),amount));
+#endif
+ }
+ else
+ blp_here_now.set_split_tangent_flag(false);
+ }
+
+ blp_here_now.set_origin(blp_here_on.get_origin());
+ blp_here_now.set_width(linear_interpolation(blp_here_off.get_width(), blp_here_on.get_width(), amount));
+
+ // Handle the case where we are the first vertex
+ if(first_flag)
+ {
+ blp_here_now.set_tangent1(blp_here_now.get_tangent1()*prev_tangent_scalar);
+ first_iter=iter;
+ first=prev=blp_here_now;
+ first_flag=false;
+ ret_list.push_back(blp_here_now);
+ continue;
+ }
+
+ ret_list.back().set_split_tangent_flag(true);
+ ret_list.back().set_tangent2(prev.get_tangent2()*prev_tangent_scalar);
+ ret_list.push_back(blp_here_now);
+ ret_list.back().set_split_tangent_flag(true);
+ //ret_list.back().set_tangent2(blp_here_now.get_tangent1());
+ ret_list.back().set_tangent1(blp_here_now.get_tangent1()*prev_tangent_scalar);
+
+ prev=blp_here_now;
+ }
+ }
+
+ if(next_scale!=1.0f)
+ {
+ ret_list.back().set_split_tangent_flag(true);
+ ret_list.back().set_tangent2(prev.get_tangent2()*next_scale);
+ }
+
+/*
+ if(get_loop() && !first_flag)
+ {
+ ret_list.push_back(
+ Segment(
+ prev.get_vertex(),
+ prev.get_tangent2(),
+ first.get_vertex(),
+ first.get_tangent1()
+ )
+ );
+ }
+*/
+
+ if(list.empty())
+ synfig::warning(string("ValueNode_BLine::operator()():")+_("No entries in list"));
+ else
+ if(ret_list.empty())
+ synfig::warning(string("ValueNode_BLine::operator()():")+_("No entries in ret_list"));
+
+ return ValueBase(ret_list,get_loop());
+}
+
+String
+ValueNode_BLine::link_local_name(int i)const
+{
+ assert(i>=0 && (unsigned)i<list.size());
+ return etl::strprintf(_("Vertex %03d"),i+1);
+}
+
+ValueNode*
+ValueNode_BLine::clone(const GUID& deriv_guid)const
+{
+ { ValueNode* x(find_value_node(get_guid()^deriv_guid).get()); if(x)return x; }
+
+ ValueNode_BLine* ret=new ValueNode_BLine();
+ ret->set_guid(get_guid()^deriv_guid);
+
+ std::vector<ListEntry>::const_iterator iter;
+
+ for(iter=list.begin();iter!=list.end();++iter)
+ {
+ if(iter->value_node->is_exported())
+ ret->add(*iter);
+ else
+ {
+ ListEntry list_entry(*iter);
+ //list_entry.value_node=find_value_node(iter->value_node->get_guid()^deriv_guid).get();
+ //if(!list_entry.value_node)
+ list_entry.value_node=iter->value_node->clone(deriv_guid);
+ ret->add(list_entry);
+ //ret->list.back().value_node=iter->value_node.clone();
+ }
+ }
+ ret->set_loop(get_loop());
+
+ return ret;
+}
+
+String
+ValueNode_BLine::get_name()const
+{
+ return "bline";
+}
+
+String
+ValueNode_BLine::get_local_name()const
+{
+ return _("BLine");
+}
+
+LinkableValueNode*
+ValueNode_BLine::create_new()const
+{
+ assert(0);
+ return 0;
+}
+
+bool
+ValueNode_BLine::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_LIST;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_bline.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_BLINE_H
+#define __SYNFIG_VALUENODE_BLINE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <vector>
+#include <list>
+
+#include "valuenode.h"
+#include "time.h"
+#include "uniqueid.h"
+#include "blinepoint.h"
+#include "valuenode_dynamiclist.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+
+//! Converts a list of bline points into a list of segments
+ValueBase convert_bline_to_segment_list(const ValueBase &bline);
+
+//! Converts a list of bline points into a list of widths
+ValueBase convert_bline_to_width_list(const ValueBase &bline);
+
+/*! \class ValueNode_BLine
+** \brief \writeme
+*/
+class ValueNode_BLine : public ValueNode_DynamicList
+{
+public:
+
+ typedef etl::handle<ValueNode_BLine> Handle;
+ typedef etl::handle<const ValueNode_BLine> ConstHandle;
+
+
+ ValueNode_BLine();
+
+public:
+
+
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual ~ValueNode_BLine();
+
+ virtual String link_local_name(int i)const;
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+ virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
+
+ virtual ListEntry create_list_entry(int index, Time time=0, Real origin=0.5);
+
+protected:
+
+ LinkableValueNode* create_new()const;
+
+public:
+ //using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_BLine* create(const ValueBase &x=ValueBase::TYPE_LIST);
+}; // END of class ValueNode_BLine
+
+typedef ValueNode_BLine::ListEntry::ActivepointList ActivepointList;
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_blinecalctangent.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode_blinecalctangent.h"
+#include "valuenode_bline.h"
+#include "valuenode_const.h"
+#include "valuenode_composite.h"
+#include "general.h"
+#include "exception.h"
+#include <ETL/hermite>
+#include <ETL/calculus>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ValueNode_BLineCalcTangent::ValueNode_BLineCalcTangent(const ValueBase::Type &x):
+ LinkableValueNode(x)
+{
+ if(x!=ValueBase::TYPE_ANGLE && x!=ValueBase::TYPE_VECTOR)
+ throw Exception::BadType(ValueBase::type_name(x));
+
+ ValueNode_BLine* value_node(new ValueNode_BLine());
+ set_link("bline",value_node);
+ set_link("loop",ValueNode_Const::create(bool(false)));
+ set_link("amount",ValueNode_Const::create(Real(0.5)));
+}
+
+LinkableValueNode*
+ValueNode_BLineCalcTangent::create_new()const
+{
+ return new ValueNode_BLineCalcTangent(get_type());
+}
+
+ValueNode_BLineCalcTangent*
+ValueNode_BLineCalcTangent::create(const ValueBase &x)
+{
+ return new ValueNode_BLineCalcTangent(x.get_type());
+}
+
+ValueNode_BLineCalcTangent::~ValueNode_BLineCalcTangent()
+{
+ unlink_all();
+}
+
+ValueBase
+ValueNode_BLineCalcTangent::operator()(Time t)const
+{
+ const std::vector<ValueBase> bline((*bline_)(t));
+ handle<ValueNode_BLine> bline_value_node(bline_);
+ const bool looped(bline_value_node->get_loop());
+ int size = bline.size(), from_vertex;
+ bool loop((*loop_)(t).get(bool()));
+ Real amount((*amount_)(t).get(Real()));
+ BLinePoint blinepoint0, blinepoint1;
+
+ if (!looped) size--;
+ if (size < 1)
+ switch (get_type())
+ {
+ case ValueBase::TYPE_ANGLE: return Angle();
+ case ValueBase::TYPE_VECTOR: return Vector();
+ default: assert(0); return ValueBase();
+ }
+ if (loop)
+ {
+ amount = amount - int(amount);
+ if (amount < 0) amount++;
+ }
+ else
+ {
+ if (amount < 0) amount = 0;
+ if (amount > 1) amount = 1;
+ }
+
+ vector<ValueBase>::const_iterator iter, next(bline.begin());
+
+ iter = looped ? --bline.end() : next++;
+ amount = amount * size;
+ from_vertex = int(amount);
+ if (from_vertex > size-1) from_vertex = size-1;
+ blinepoint0 = from_vertex ? *(next+from_vertex-1) : *iter;
+ blinepoint1 = *(next+from_vertex);
+
+ etl::hermite<Vector> curve(blinepoint0.get_vertex(), blinepoint1.get_vertex(),
+ blinepoint0.get_tangent2(), blinepoint1.get_tangent1());
+ etl::derivative< etl::hermite<Vector> > deriv(curve);
+
+#ifdef ETL_FIXED_DERIVATIVE
+ switch (get_type())
+ {
+ case ValueBase::TYPE_ANGLE: return (deriv(amount-from_vertex)*(0.5)).angle();
+ case ValueBase::TYPE_VECTOR: return deriv(amount-from_vertex)*(0.5);
+ default: assert(0); return ValueBase();
+ }
+#else
+ switch (get_type())
+ {
+ case ValueBase::TYPE_ANGLE: return (deriv(amount-from_vertex)*(-0.5)).angle();
+ case ValueBase::TYPE_VECTOR: return deriv(amount-from_vertex)*(-0.5);
+ default: assert(0); return ValueBase();
+ }
+#endif
+}
+
+String
+ValueNode_BLineCalcTangent::get_name()const
+{
+ return "blinecalctangent";
+}
+
+String
+ValueNode_BLineCalcTangent::get_local_name()const
+{
+ return _("BLine Tangent");
+}
+
+bool
+ValueNode_BLineCalcTangent::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0:
+ bline_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ case 1:
+ loop_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ case 2:
+ amount_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_BLineCalcTangent::get_link_vfunc(int i)const
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0: return bline_;
+ case 1: return loop_;
+ case 2: return amount_;
+ }
+
+ return 0;
+}
+
+int
+ValueNode_BLineCalcTangent::link_count()const
+{
+ return 3;
+}
+
+String
+ValueNode_BLineCalcTangent::link_name(int i)const
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0: return "bline";
+ case 1: return "loop";
+ case 2: return "amount";
+ }
+ return String();
+}
+
+String
+ValueNode_BLineCalcTangent::link_local_name(int i)const
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0: return _("BLine");
+ case 1: return _("Loop");
+ case 2: return _("Amount");
+ }
+ return String();
+}
+
+int
+ValueNode_BLineCalcTangent::get_link_index_from_name(const String &name)const
+{
+ if(name=="bline") return 0;
+ if(name=="loop") return 1;
+ if(name=="amount") return 2;
+ throw Exception::BadLinkName(name);
+}
+
+bool
+ValueNode_BLineCalcTangent::check_type(ValueBase::Type type)
+{
+ return (type==ValueBase::TYPE_ANGLE ||
+ type==ValueBase::TYPE_VECTOR);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_blinecalctangent.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_BLINECALCTANGENT_H
+#define __SYNFIG_VALUENODE_BLINECALCTANGENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueNode_BLineCalcTangent : public LinkableValueNode
+{
+ ValueNode::RHandle bline_;
+ ValueNode::RHandle loop_;
+ ValueNode::RHandle amount_;
+
+ ValueNode_BLineCalcTangent(const ValueBase::Type &x=ValueBase::TYPE_VECTOR);
+
+public:
+
+ typedef etl::handle<ValueNode_BLineCalcTangent> Handle;
+ typedef etl::handle<const ValueNode_BLineCalcTangent> ConstHandle;
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual ~ValueNode_BLineCalcTangent();
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+ virtual int link_count()const;
+ virtual String link_name(int i)const;
+
+ virtual String link_local_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+protected:
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+ LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_BLineCalcTangent* create(const ValueBase &x=ValueBase::TYPE_VECTOR);
+}; // END of class ValueNode_BLineCalcTangent
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_blinecalcvertex.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode_blinecalcvertex.h"
+#include "valuenode_bline.h"
+#include "valuenode_const.h"
+#include "valuenode_composite.h"
+#include "general.h"
+#include "exception.h"
+#include <ETL/hermite>
+
+#endif
+
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ValueNode_BLineCalcVertex::ValueNode_BLineCalcVertex(const ValueBase::Type &x):
+ LinkableValueNode(x)
+{
+ if(x!=ValueBase::TYPE_VECTOR)
+ throw Exception::BadType(ValueBase::type_name(x));
+
+ ValueNode_BLine* value_node(new ValueNode_BLine());
+ set_link("bline",value_node);
+ set_link("loop",ValueNode_Const::create(bool(false)));
+ set_link("amount",ValueNode_Const::create(Real(0.5)));
+}
+
+LinkableValueNode*
+ValueNode_BLineCalcVertex::create_new()const
+{
+ return new ValueNode_BLineCalcVertex(ValueBase::TYPE_VECTOR);
+}
+
+ValueNode_BLineCalcVertex*
+ValueNode_BLineCalcVertex::create(const ValueBase &x)
+{
+ return new ValueNode_BLineCalcVertex(x.get_type());
+}
+
+ValueNode_BLineCalcVertex::~ValueNode_BLineCalcVertex()
+{
+ unlink_all();
+}
+
+ValueBase
+ValueNode_BLineCalcVertex::operator()(Time t)const
+{
+ const std::vector<ValueBase> bline((*bline_)(t));
+ handle<ValueNode_BLine> bline_value_node(bline_);
+ const bool looped(bline_value_node->get_loop());
+ int size = bline.size(), from_vertex;
+ bool loop((*loop_)(t).get(bool()));
+ Real amount((*amount_)(t).get(Real()));
+ BLinePoint blinepoint0, blinepoint1;
+
+ if (!looped) size--;
+ if (size < 1) return Vector();
+ if (loop)
+ {
+ amount = amount - int(amount);
+ if (amount < 0) amount++;
+ }
+ else
+ {
+ if (amount < 0) amount = 0;
+ if (amount > 1) amount = 1;
+ }
+
+ vector<ValueBase>::const_iterator iter, next(bline.begin());
+
+ iter = looped ? --bline.end() : next++;
+ amount = amount * size;
+ from_vertex = int(amount);
+ if (from_vertex > size-1) from_vertex = size-1;
+ blinepoint0 = from_vertex ? *(next+from_vertex-1) : *iter;
+ blinepoint1 = *(next+from_vertex);
+
+ etl::hermite<Vector> curve(blinepoint0.get_vertex(), blinepoint1.get_vertex(),
+ blinepoint0.get_tangent2(), blinepoint1.get_tangent1());
+ return curve(amount-from_vertex);
+}
+
+
+
+
+
+
+
+String
+ValueNode_BLineCalcVertex::get_name()const
+{
+ return "blinecalcvertex";
+}
+
+String
+ValueNode_BLineCalcVertex::get_local_name()const
+{
+ return _("BLine Vertex");
+}
+
+bool
+ValueNode_BLineCalcVertex::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0:
+ bline_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ case 1:
+ loop_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ case 2:
+ amount_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_BLineCalcVertex::get_link_vfunc(int i)const
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0: return bline_;
+ case 1: return loop_;
+ case 2: return amount_;
+ }
+
+ return 0;
+}
+
+int
+ValueNode_BLineCalcVertex::link_count()const
+{
+ return 3;
+}
+
+String
+ValueNode_BLineCalcVertex::link_name(int i)const
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0: return "bline";
+ case 1: return "loop";
+ case 2: return "amount";
+ }
+ return String();
+}
+
+String
+ValueNode_BLineCalcVertex::link_local_name(int i)const
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0: return _("BLine");
+ case 1: return _("Loop");
+ case 2: return _("Amount");
+ }
+ return String();
+}
+
+int
+ValueNode_BLineCalcVertex::get_link_index_from_name(const String &name)const
+{
+ if(name=="bline") return 0;
+ if(name=="loop") return 1;
+ if(name=="amount") return 2;
+ throw Exception::BadLinkName(name);
+}
+
+bool
+ValueNode_BLineCalcVertex::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_VECTOR;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_blinecalcvertex.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_BLINECALCVERTEX_H
+#define __SYNFIG_VALUENODE_BLINECALCVERTEX_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueNode_BLineCalcVertex : public LinkableValueNode
+{
+ ValueNode::RHandle bline_;
+ ValueNode::RHandle loop_;
+ ValueNode::RHandle amount_;
+
+ ValueNode_BLineCalcVertex(const ValueBase::Type &x=ValueBase::TYPE_VECTOR);
+
+public:
+
+ typedef etl::handle<ValueNode_BLineCalcVertex> Handle;
+ typedef etl::handle<const ValueNode_BLineCalcVertex> ConstHandle;
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual ~ValueNode_BLineCalcVertex();
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+ virtual int link_count()const;
+ virtual String link_name(int i)const;
+
+ virtual String link_local_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+protected:
+ LinkableValueNode* create_new()const;
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_BLineCalcVertex* create(const ValueBase &x=ValueBase::TYPE_VECTOR);
+}; // END of class ValueNode_BLineCalcVertex
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_composite.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode_composite.h"
+#include "valuenode_const.h"
+#include <stdexcept>
+#include "general.h"
+#include "valuenode_radialcomposite.h"
+#include "vector.h"
+#include "color.h"
+#include "segment.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+synfig::ValueNode_Composite::ValueNode_Composite(const ValueBase &value):
+ LinkableValueNode(value.get_type())
+{
+ switch(get_type())
+ {
+ case ValueBase::TYPE_VECTOR:
+ set_link("x",ValueNode_Const::create(value.get(Vector())[0]));
+ set_link("y",ValueNode_Const::create(value.get(Vector())[1]));
+ break;
+ case ValueBase::TYPE_COLOR:
+ set_link("r",ValueNode_Const::create(value.get(Color()).get_r()));
+ set_link("g",ValueNode_Const::create(value.get(Color()).get_g()));
+ set_link("b",ValueNode_Const::create(value.get(Color()).get_b()));
+ set_link("a",ValueNode_Const::create(value.get(Color()).get_a()));
+ break;
+ case ValueBase::TYPE_SEGMENT:
+ set_link("p1",ValueNode_Const::create(value.get(Segment()).p1));
+ set_link("t1",ValueNode_Const::create(value.get(Segment()).t1));
+ set_link("p2",ValueNode_Const::create(value.get(Segment()).p2));
+ set_link("t2",ValueNode_Const::create(value.get(Segment()).t2));
+ break;
+ case ValueBase::TYPE_BLINEPOINT:
+ {
+ BLinePoint bline_point(value);
+ set_link(0,ValueNode_Const::create(bline_point.get_vertex()));
+ set_link(1,ValueNode_Const::create(bline_point.get_width()));
+ set_link(2,ValueNode_Const::create(bline_point.get_origin()));
+ set_link(3,ValueNode_Const::create(bline_point.get_split_tangent_flag()));
+ set_link(4,ValueNode_RadialComposite::create(bline_point.get_tangent1()));
+ set_link(5,ValueNode_RadialComposite::create(bline_point.get_tangent2()));
+ break;
+ }
+ default:
+ assert(0);
+ throw Exception::BadType(ValueBase::type_name(get_type()));
+ }
+}
+
+ValueNode_Composite::~ValueNode_Composite()
+{
+ unlink_all();
+}
+
+ValueNode_Composite*
+ValueNode_Composite::create(const ValueBase &value)
+{
+ return new ValueNode_Composite(value);
+}
+
+LinkableValueNode*
+ValueNode_Composite::create_new()const
+{
+ return new ValueNode_Composite(ValueBase(get_type()));
+}
+
+ValueBase
+synfig::ValueNode_Composite::operator()(Time t)const
+{
+ switch(get_type())
+ {
+ case ValueBase::TYPE_VECTOR:
+ {
+ Vector vect;
+ assert(components[0] && components[1]);
+ vect[0]=(*components[0])(t).get(Vector::value_type());
+ vect[1]=(*components[1])(t).get(Vector::value_type());
+ return vect;
+ }
+ case ValueBase::TYPE_COLOR:
+ {
+ Color color;
+ assert(components[0] && components[1] && components[2] && components[3]);
+ color.set_r((*components[0])(t).get(Vector::value_type()));
+ color.set_g((*components[1])(t).get(Vector::value_type()));
+ color.set_b((*components[2])(t).get(Vector::value_type()));
+ color.set_a((*components[3])(t).get(Vector::value_type()));
+ return color;
+ }
+ case ValueBase::TYPE_SEGMENT:
+ {
+ Segment seg;
+ assert(components[0] && components[1] && components[2] && components[3]);
+ seg.p1=(*components[0])(t).get(Point());
+ seg.t1=(*components[1])(t).get(Vector());
+ seg.p2=(*components[2])(t).get(Point());
+ seg.t2=(*components[3])(t).get(Vector());
+ return seg;
+ }
+ case ValueBase::TYPE_BLINEPOINT:
+ {
+ BLinePoint ret;
+ assert(components[0] && components[1] && components[2] && components[3] && components[4] && components[5]);
+ ret.set_vertex((*components[0])(t).get(Point()));
+ ret.set_width((*components[1])(t).get(Real()));
+ ret.set_origin((*components[2])(t).get(Real()));
+ ret.set_split_tangent_flag((*components[3])(t).get(bool()));
+ ret.set_tangent1((*components[4])(t).get(Vector()));
+ if(ret.get_split_tangent_flag())
+ ret.set_tangent2((*components[5])(t).get(Vector()));
+ return ret;
+ }
+ default:
+ synfig::error(string("ValueNode_Composite::operator():")+_("Bad type for composite"));
+ assert(components[0]);
+ return (*components[0])(t);
+ }
+}
+
+int
+ValueNode_Composite::link_count()const
+{
+ switch(get_type())
+ {
+ case ValueBase::TYPE_VECTOR:
+ return 2;
+ case ValueBase::TYPE_COLOR:
+ return 4;
+ case ValueBase::TYPE_SEGMENT:
+ return 4;
+ case ValueBase::TYPE_BLINEPOINT:
+ return 6;
+ default:
+ synfig::warning(string("ValueNode_Composite::component_count():")+_("Bad type for composite"));
+ return 1;
+ }
+}
+
+bool
+ValueNode_Composite::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i>=0);
+ assert(i<6);
+
+ if(PlaceholderValueNode::Handle::cast_dynamic(x))
+ {
+ components[i]=x;
+ return true;
+ }
+
+ switch(get_type())
+ {
+ case ValueBase::TYPE_VECTOR:
+ assert(i<2);
+ if(x->get_type()==ValueBase(Real()).get_type() || PlaceholderValueNode::Handle::cast_dynamic(x))
+ {
+ components[i]=x;
+ return true;
+ }
+ break;
+
+ case ValueBase::TYPE_COLOR:
+ assert(i<4);
+ if(x->get_type()==ValueBase(Real()).get_type() || PlaceholderValueNode::Handle::cast_dynamic(x))
+ {
+ components[i]=x;
+ return true;
+ }
+ break;
+
+ case ValueBase::TYPE_SEGMENT:
+ assert(i<4);
+ if(x->get_type()==ValueBase(Point()).get_type() || PlaceholderValueNode::Handle::cast_dynamic(x))
+ {
+ components[i]=x;
+ return true;
+ }
+ break;
+
+ case ValueBase::TYPE_BLINEPOINT:
+ assert(i<6);
+ if((i==0 || i==4 || i==5) && x->get_type()==ValueBase(Point()).get_type())
+ {
+ components[i]=x;
+ return true;
+ }
+ if((i==1 || i==2) && x->get_type()==ValueBase(Real()).get_type())
+ {
+ components[i]=x;
+ return true;
+ }
+ if(i==3 && x->get_type()==ValueBase(bool()).get_type())
+ {
+ components[i]=x;
+ return true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_Composite::get_link_vfunc(int i)const
+{
+ assert(i>=0 && i<6);
+ return components[i];
+}
+
+String
+ValueNode_Composite::link_local_name(int i)const
+{
+ assert(i>=0 && i<6);
+ switch(get_type())
+ {
+ case ValueBase::TYPE_VECTOR:
+ return strprintf("%c-Axis",'X'+i);
+
+ case ValueBase::TYPE_COLOR:
+ if(i==0)
+ return _("Red");
+ else if(i==1)
+ return _("Green");
+ else if(i==2)
+ return _("Blue");
+ else if(i==3)
+ return _("Alpha");
+
+ case ValueBase::TYPE_SEGMENT:
+ if(i==0)
+ return _("Vertex 1");
+ else if(i==1)
+ return _("Tangent 1");
+ else if(i==2)
+ return _("Vertex 2");
+ else if(i==3)
+ return _("Tangent 2");
+
+ case ValueBase::TYPE_BLINEPOINT:
+ if(i==0)
+ return _("Vertex");
+ else if(i==1)
+ return _("Width");
+ else if(i==2)
+ return _("Origin");
+ else if(i==3)
+ return _("Split Tangents");
+ else if(i==4)
+ return _("Tangent 1");
+ else if(i==5)
+ return _("Tangent 2");
+
+ default:
+ return etl::strprintf(_("C%d"),i+1);
+ }
+}
+
+
+String
+ValueNode_Composite::link_name(int i)const
+{
+ assert(i>=0 && i<5);
+ return strprintf("c%d",i);
+}
+
+int
+ValueNode_Composite::get_link_index_from_name(const String &name)const
+{
+ if(name.empty())
+ throw Exception::BadLinkName(name);
+
+ if(name[0]=='c')
+ return name[1]-'0';
+
+ switch(get_type())
+ {
+ case ValueBase::TYPE_COLOR:
+ if(name[0]=='r')
+ return 0;
+ if(name[0]=='g')
+ return 1;
+ if(name[0]=='b')
+ return 2;
+ if(name[0]=='a')
+ return 3;
+ case ValueBase::TYPE_SEGMENT:
+ if(name=="p1")
+ return 0;
+ if(name=="t1")
+ return 1;
+ if(name=="p2")
+ return 2;
+ if(name=="t2")
+ return 3;
+ case ValueBase::TYPE_VECTOR:
+ if(name[0]=='x')
+ return 0;
+ if(name[0]=='y')
+ return 1;
+ if(name[0]=='z')
+ return 2;
+ case ValueBase::TYPE_BLINEPOINT:
+ if(name[0]=='p' || name=="v1" || name=="p1")
+ return 0;
+ if(name=="w" || name=="width")
+ return 1;
+ if(name=="o" || name=="origin")
+ return 2;
+ if(name=="split")
+ return 3;
+ if(name=="t1")
+ return 4;
+ if(name=="t2")
+ return 5;
+ default:
+ break;
+ }
+
+ throw Exception::BadLinkName(name);
+}
+
+String
+ValueNode_Composite::get_name()const
+{
+ return "composite";
+}
+
+String
+ValueNode_Composite::get_local_name()const
+{
+ return _("Composite");
+}
+
+bool
+ValueNode_Composite::check_type(ValueBase::Type type)
+{
+ return
+ type==ValueBase::TYPE_SEGMENT ||
+ type==ValueBase::TYPE_VECTOR ||
+ type==ValueBase::TYPE_COLOR ||
+ type==ValueBase::TYPE_BLINEPOINT;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_composite.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_COMPOSITE_H
+#define __SYNFIG_VALUENODE_COMPOSITE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueNode_Composite : public LinkableValueNode
+{
+ ValueNode::RHandle components[6];
+ ValueNode_Composite(const ValueBase &value);
+
+public:
+ typedef etl::handle<ValueNode_Composite> Handle;
+ typedef etl::handle<const ValueNode_Composite> ConstHandle;
+
+
+ ~ValueNode_Composite();
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+ virtual int link_count()const;
+ virtual String link_name(int i)const;
+ virtual String link_local_name(int i)const;
+ virtual ValueBase operator()(Time t)const;
+
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+protected:
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+ LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::set_link_vfunc;
+ using synfig::LinkableValueNode::get_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_Composite* create(const ValueBase &x);
+}; // END of class ValueNode_Composite
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_const.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode_const.h"
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ValueNode_Const::ValueNode_Const()
+{
+ DCAST_HACK_ENABLE();
+}
+
+
+ValueNode_Const::ValueNode_Const(const ValueBase &x):
+ ValueNode (x.get_type()),
+ value (x)
+{
+ DCAST_HACK_ENABLE();
+}
+
+
+ValueNode_Const*
+ValueNode_Const::create(const ValueBase &x)
+{
+ return new ValueNode_Const(x);
+}
+
+
+ValueNode*
+ValueNode_Const::clone(const GUID& deriv_guid)const
+{
+ { ValueNode* x(find_value_node(get_guid()^deriv_guid).get()); if(x)return x; }
+ ValueNode* ret(new ValueNode_Const(value));
+ ret->set_guid(get_guid()^deriv_guid);
+ return ret;
+}
+
+
+ValueNode_Const::~ValueNode_Const()
+{
+}
+
+
+ValueBase
+ValueNode_Const::operator()(Time /*t*/)const
+{
+ return value;
+}
+
+
+const ValueBase &
+ValueNode_Const::get_value()const
+{
+ return value;
+}
+
+ValueBase &
+ValueNode_Const::get_value()
+{
+ return value;
+}
+
+void
+ValueNode_Const::set_value(const ValueBase &data)
+{
+ if(data!=value)
+ {
+ value=data;
+ changed();
+ }
+}
+
+
+String
+ValueNode_Const::get_name()const
+{
+ return "constant";
+}
+
+String
+ValueNode_Const::get_local_name()const
+{
+ return _("Constant");
+}
+
+void ValueNode_Const::get_times_vfunc(Node::time_set &/*set*/) const
+{
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_const.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_CONST_H
+#define __SYNFIG_VALUENODE_CONST_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueNode_Const : public ValueNode
+{
+public:
+ typedef etl::handle<ValueNode_Const> Handle;
+ typedef etl::handle<const ValueNode_Const> ConstHandle;
+
+private:
+ ValueBase value;
+
+ ValueNode_Const();
+ ValueNode_Const(const ValueBase &x);
+
+public:
+
+ virtual ValueBase operator()(Time t)const;
+ virtual ~ValueNode_Const();
+
+ const ValueBase &get_value()const;
+ ValueBase &get_value();
+ void set_value(const ValueBase &data);
+
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+ virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
+
+public:
+ static ValueNode_Const* create(const ValueBase &x=ValueBase());
+
+protected:
+ virtual void get_times_vfunc(Node::time_set &set) const;
+};
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_dynamiclist.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode_dynamiclist.h"
+#include "valuenode_const.h"
+#include "valuenode_composite.h"
+#include "general.h"
+#include "exception.h"
+#include <vector>
+#include <list>
+#include <algorithm>
+#include "canvas.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ValueNode_DynamicList::ListEntry::ListEntry():
+ index(0)
+{
+}
+
+ValueNode_DynamicList::ListEntry::ListEntry(const ValueNode::Handle &value_node):
+ value_node(value_node),
+ index(0)
+{
+}
+
+ValueNode_DynamicList::ListEntry::ListEntry(const ValueNode::Handle &value_node,Time begin, Time end):
+ value_node(value_node)
+{
+ add(begin,false);
+ add(end,false);
+ add((begin+end)*0.5,true);
+}
+
+ValueNode_DynamicList::ListEntry::ActivepointList::iterator
+ValueNode_DynamicList::ListEntry::add(Time time, bool status, int priority)
+{
+ typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList::iterator iterator;
+
+ //! \optimize
+ Activepoint ap(time,status,priority);
+ ap.set_parent_index(get_index());
+ ap.set_parent_value_node(get_parent_value_node());
+ timing_info.push_back(ap);
+ iterator iter(--iterator(timing_info.end()));
+ timing_info.sort();
+
+ return iter;
+}
+
+ValueNode_DynamicList::ListEntry::ActivepointList::iterator
+ValueNode_DynamicList::ListEntry::add(const Activepoint &x)
+{
+ typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList::iterator iterator;
+
+ //! \optimize
+ Activepoint ap(x);
+ ap.set_parent_index(get_index());
+ ap.set_parent_value_node(get_parent_value_node());
+ timing_info.push_back(ap);
+ iterator iter(--iterator(timing_info.end()));
+ timing_info.sort();
+
+ return iter;
+}
+
+void
+ValueNode_DynamicList::reindex()
+{
+ int i(0);
+
+ std::vector<ListEntry>::iterator iter;
+
+ for(iter=list.begin();iter!=list.end();++iter)
+ {
+ assert(iter->value_node);
+ if(iter->index!=i || iter->get_parent_value_node().get()!=this)
+ {
+ ActivepointList::iterator iter2;
+
+ if(iter->timing_info.size()) // is this line really necessary?
+ for(iter2=iter->timing_info.begin();iter2!=iter->timing_info.end();++iter2)
+ {
+ iter2->set_parent_index(i);
+ iter2->set_parent_value_node(this);
+ }
+ iter->index=i;
+ iter->set_parent_value_node(this);
+ }
+ }
+}
+
+ValueNode_DynamicList::ListEntry
+ValueNode_DynamicList::create_list_entry(int index, Time time, Real origin)
+{
+ ValueNode_DynamicList::ListEntry ret;
+
+
+ synfig::ValueBase prev,next;
+
+ index=index%link_count();
+
+ assert(index>=0);
+
+ ret.index=index;
+ ret.set_parent_value_node(this);
+
+ next=(*list[index].value_node)(time);
+
+ if(index!=0)
+ prev=(*list[index-1].value_node)(time);
+ else
+ {
+ if(get_loop())
+ prev=(*list[link_count()-1].value_node)(time);
+ else
+ {
+ prev=next;
+ }
+ }
+
+
+ switch(get_contained_type())
+ {
+ case ValueBase::TYPE_VECTOR:
+ {
+ Vector a(prev.get(Vector())), b(next.get(Vector()));
+ ret.value_node=ValueNode_Const::create((b-a)*origin+a);
+ break;
+ }
+ case ValueBase::TYPE_REAL:
+ {
+ Real a(prev.get(Real())), b(next.get(Real()));
+ ret.value_node=ValueNode_Const::create((b-a)*origin+a);
+ break;
+ }
+ case ValueBase::TYPE_COLOR:
+ {
+ Color a(prev.get(Color())), b(next.get(Color()));
+ ret.value_node=ValueNode_Composite::create((b-a)*origin+a);
+ break;
+ }
+ case ValueBase::TYPE_ANGLE:
+ {
+ Angle a(prev.get(Angle())), b(next.get(Angle()));
+ ret.value_node=ValueNode_Const::create((b-a)*origin+a);
+ break;
+ }
+ case ValueBase::TYPE_TIME:
+ {
+ Time a(prev.get(Time())), b(next.get(Time()));
+ ret.value_node=ValueNode_Const::create((b-a)*origin+a);
+ break;
+ }
+ default:
+ ret.value_node=ValueNode_Const::create(get_contained_type());
+ break;
+ }
+
+
+ return ret;
+}
+
+ValueNode_DynamicList::ListEntry::ActivepointList::iterator
+ValueNode_DynamicList::ListEntry::find(const UniqueID& x)
+{
+ return std::find(timing_info.begin(),timing_info.end(),x);
+}
+
+ValueNode_DynamicList::ListEntry::ActivepointList::const_iterator
+ValueNode_DynamicList::ListEntry::find(const UniqueID& x)const
+{
+ return std::find(timing_info.begin(),timing_info.end(),x);
+}
+
+void
+ValueNode_DynamicList::ListEntry::erase(const UniqueID& x)
+{
+ timing_info.erase(find(x));
+}
+
+ValueNode_DynamicList::ListEntry::ActivepointList::iterator
+ValueNode_DynamicList::ListEntry::find(const Time& x)
+{
+ typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
+
+ ActivepointList::iterator iter;
+
+ for(iter=timing_info.begin();iter!=timing_info.end();++iter)
+ if(iter->time==x)
+ return iter;
+
+ throw Exception::NotFound("ValueNode_DynamicList::ListEntry::find():"+x.get_string());
+}
+
+ValueNode_DynamicList::ListEntry::ActivepointList::const_iterator
+ValueNode_DynamicList::ListEntry::find(const Time& x)const
+{
+ typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
+
+ ActivepointList::const_iterator iter;
+
+ for(iter=timing_info.begin();iter!=timing_info.end();++iter)
+ if(iter->time==x)
+ return iter;
+
+ throw Exception::NotFound("ValueNode_DynamicList::ListEntry::find()const:"+x.get_string());
+}
+
+ValueNode_DynamicList::ListEntry::ActivepointList::iterator
+ValueNode_DynamicList::ListEntry::find_next(const Time& x)
+{
+ typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
+
+ ActivepointList::iterator iter;
+
+ for(iter=timing_info.begin();iter!=timing_info.end();++iter)
+ if(iter->time>x)
+ return iter;
+
+ throw Exception::NotFound("ValueNode_DynamicList::ListEntry::find_next():"+x.get_string());
+}
+
+ValueNode_DynamicList::ListEntry::ActivepointList::const_iterator
+ValueNode_DynamicList::ListEntry::find_next(const Time& x)const
+{
+ typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
+
+ ActivepointList::const_iterator iter;
+
+ for(iter=timing_info.begin();iter!=timing_info.end();++iter)
+ if(iter->time>x)
+ return iter;
+
+ throw Exception::NotFound("ValueNode_DynamicList::ListEntry::find_next()const:"+x.get_string());
+}
+
+ValueNode_DynamicList::ListEntry::ActivepointList::iterator
+ValueNode_DynamicList::ListEntry::find_prev(const Time& x)
+{
+ typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
+
+ ActivepointList::iterator iter;
+ iter=timing_info.end();
+ do
+ {
+ --iter;
+ if(iter->time<x)
+ return iter;
+ }
+ while(iter!=timing_info.begin());
+
+ throw Exception::NotFound("ValueNode_DynamicList::ListEntry::find_prev():"+x.get_string());
+}
+
+ValueNode_DynamicList::ListEntry::ActivepointList::const_iterator
+ValueNode_DynamicList::ListEntry::find_prev(const Time& x)const
+{
+ typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
+
+ ActivepointList::const_iterator iter;
+ iter=timing_info.end();
+ do
+ {
+ --iter;
+ if(iter->time<x)
+ return iter;
+ }
+ while(iter!=timing_info.begin());
+
+ throw Exception::NotFound("ValueNode_DynamicList::ListEntry::find_prev()const:"+x.get_string());
+}
+
+int
+ValueNode_DynamicList::ListEntry::find(const Time& begin,const Time& end,std::vector<Activepoint*>& selected)
+{
+ Time curr_time(begin);
+ int ret(0);
+
+ // try to grab first waypoint
+ try
+ {
+ ActivepointList::iterator iter;
+ iter=find(curr_time);
+ selected.push_back(&*iter);
+ ret++;
+ }
+ catch(...) { }
+
+ try
+ {
+ ActivepointList::iterator iter;
+ while(true)
+ {
+ iter=find_next(curr_time);
+ curr_time=iter->get_time();
+ if(curr_time>=end)
+ break;
+ selected.push_back(&*iter);
+ ret++;
+ }
+ }
+ catch(...) { }
+
+ return ret;
+}
+
+float
+ValueNode_DynamicList::ListEntry::amount_at_time(const Time &t,bool *rising)const
+{
+ typedef synfig::ValueNode_DynamicList::ListEntry::Activepoint Activepoint;
+ typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
+
+ if(timing_info.empty())
+ return 1.0f;
+
+ try
+ {
+ ActivepointList::const_iterator iter;
+ iter=find(t);
+ return iter->state?1.0f:0.0f;
+ }
+ catch(...) { }
+
+ ActivepointList::const_iterator prev_iter;
+ ActivepointList::const_iterator next_iter;
+
+ try { prev_iter=find_prev(t); }
+ catch(...) { return find_next(t)->state?1.0f:0.0f; }
+
+ try { next_iter=find_next(t); }
+ catch(...) { return prev_iter->state?1.0f:0.0f; }
+
+ if(next_iter->state==prev_iter->state)
+ return next_iter->state?1.0f:0.0f;
+
+ if(rising)*rising=next_iter->state;
+
+ if(next_iter->state==true)
+ return float((t-prev_iter->time)/(next_iter->time-prev_iter->time));
+
+ return float((next_iter->time-t)/(next_iter->time-prev_iter->time));
+}
+
+Activepoint
+ValueNode_DynamicList::ListEntry::new_activepoint_at_time(const Time& time)const
+{
+ Activepoint activepoint;
+
+ activepoint.set_state(status_at_time(time));
+ activepoint.set_priority(0);
+
+ return activepoint;
+}
+
+bool
+ValueNode_DynamicList::ListEntry::status_at_time(const Time &t)const
+{
+ typedef synfig::ValueNode_DynamicList::ListEntry::Activepoint Activepoint;
+ typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
+
+ ActivepointList::const_iterator entry_iter;
+ ActivepointList::const_iterator prev_iter;
+ bool state(true);
+
+ // New "symmetric" state mechanism
+ if(!timing_info.empty())
+ {
+ if(timing_info.size()==1)
+ state=timing_info.front().state;
+ else
+ {
+ //! \optimize Perhaps we should use a binary search...?
+ // This will give us the first activepoint that is after t.
+ for(entry_iter=timing_info.begin();entry_iter!=timing_info.end();++entry_iter)
+ {
+ if(entry_iter->time==t)
+ {
+ // If we hit the entry right on the nose, then we don't
+ // have to do anything more
+ return entry_iter->state;
+ }
+ if(entry_iter->time>t)
+ break;
+
+ }
+ prev_iter=entry_iter;
+ prev_iter--;
+
+ // ie:
+ //
+ // |-------|---t---|-------|
+ // prev_iter^ ^entry_iter
+
+ if(entry_iter==timing_info.end())
+ {
+ state=prev_iter->state;
+ }
+ else
+ if(entry_iter==timing_info.begin())
+ {
+ state=entry_iter->state;
+ }
+ else
+ if(entry_iter->priority==prev_iter->priority)
+ {
+ state=entry_iter->state || prev_iter->state;
+ }
+ else
+ if(entry_iter->priority>prev_iter->priority)
+ {
+ state=entry_iter->state;
+ }
+ else
+ {
+ state=prev_iter->state;
+ }
+ }
+ }
+ return state;
+}
+
+
+
+
+void
+ValueNode_DynamicList::add(const ValueNode::Handle &value_node, int index)
+{
+ ListEntry list_entry(value_node);
+ list_entry.timing_info.size();
+
+ if(index<0 || index>=(int)list.size())
+ {
+ list.push_back(list_entry);
+ }
+ else
+ {
+ list.insert(list.begin()+index,list_entry);
+ }
+
+ add_child(value_node.get());
+ reindex();
+ //changed();
+
+ if(get_parent_canvas())
+ get_parent_canvas()->signal_value_node_child_added()(this,value_node);
+ else if(get_root_canvas() && get_parent_canvas())
+ get_root_canvas()->signal_value_node_child_added()(this,value_node);
+}
+
+void
+ValueNode_DynamicList::add(const ListEntry &list_entry, int index)
+{
+ if(index<0 || index>=(int)list.size())
+ list.push_back(list_entry);
+ else
+ list.insert(list.begin()+index,list_entry);
+ add_child(list_entry.value_node.get());
+
+ reindex();
+ //changed();
+
+ if(get_parent_canvas())
+ get_parent_canvas()->signal_value_node_child_added()(this,list_entry.value_node);
+ else if(get_root_canvas() && get_parent_canvas())
+ get_root_canvas()->signal_value_node_child_added()(this,list_entry.value_node);
+}
+
+void
+ValueNode_DynamicList::erase(const ValueNode::Handle &value_node_)
+{
+ ValueNode::Handle value_node(value_node_);
+
+ assert(value_node);
+ if(!value_node)
+ throw String("ValueNode_DynamicList::erase(): Passed bad value node");
+
+ std::vector<ListEntry>::iterator iter;
+ for(iter=list.begin();iter!=list.end();++iter)
+ if(iter->value_node==value_node)
+ {
+ list.erase(iter);
+ if(value_node)
+ {
+ remove_child(value_node.get());
+ // changed to fix bug 1420091 - it seems that when a .sif file containing a bline layer encapsulated inside
+ // another layer, get_parent_canvas() is false and get_root_canvas() is true, but when we come to erase a
+ // vertex, both are true. So the signal is sent to the parent, but the signal wasn't sent to the parent
+ // when it was added. This probably isn't the right fix, but it seems to work for now. Note that the same
+ // strange "if (X) else if (Y && X)" code is also present in the two previous functions, above.
+
+ // if(get_parent_canvas())
+ // get_parent_canvas()->signal_value_node_child_removed()(this,value_node);
+ // else if(get_root_canvas() && get_parent_canvas())
+ // get_root_canvas()->signal_value_node_child_removed()(this,value_node);
+ if(get_root_canvas())
+ get_root_canvas()->signal_value_node_child_removed()(this,value_node);
+ }
+ break;
+ }
+ reindex();
+}
+
+
+ValueNode_DynamicList::ValueNode_DynamicList(ValueBase::Type container_type):
+ LinkableValueNode(ValueBase::TYPE_LIST),
+ container_type (container_type),
+ loop_(false)
+{
+ DCAST_HACK_ENABLE();
+}
+
+ValueNode_DynamicList::Handle
+ValueNode_DynamicList::create(ValueBase::Type id)
+{
+ return new ValueNode_DynamicList(id);
+}
+
+ValueNode_DynamicList::~ValueNode_DynamicList()
+{
+ unlink_all();
+}
+
+ValueNode_DynamicList*
+ValueNode_DynamicList::create_from(const ValueBase &value)
+{
+ //vector<ValueBase> value_list(value.operator vector<ValueBase>());
+ vector<ValueBase> value_list(value.get_list());
+
+ vector<ValueBase>::iterator iter;
+
+ if(value_list.empty())
+ return 0;
+
+ ValueNode_DynamicList* value_node(new ValueNode_DynamicList(value_list.front().get_type()));
+
+ for(iter=value_list.begin();iter!=value_list.end();++iter)
+ {
+ ValueNode::Handle item(ValueNode_Const::create(*iter));
+ value_node->add(ListEntry(item));
+ assert(value_node->list.back().value_node);
+ }
+ return value_node;
+}
+
+ValueBase
+ValueNode_DynamicList::operator()(Time t)const
+{
+ std::vector<ValueBase> ret_list;
+ std::vector<ListEntry>::const_iterator iter;
+
+ assert(container_type);
+
+ for(iter=list.begin();iter!=list.end();++iter)
+ {
+ bool state(iter->status_at_time(t));
+
+ if(state)
+ {
+ if(iter->value_node->get_type()==container_type)
+ ret_list.push_back((*iter->value_node)(t));
+ else
+ {
+ synfig::warning(string("ValueNode_DynamicList::operator()():")+_("List type/item type mismatch, throwing away mismatch"));
+ }
+ }
+ }
+
+ if(list.empty())
+ synfig::warning(string("ValueNode_DynamicList::operator()():")+_("No entries in list"));
+ else
+ if(ret_list.empty())
+ synfig::warning(string("ValueNode_DynamicList::operator()():")+_("No entries in ret_list"));
+
+ return ret_list;
+}
+
+bool
+ValueNode_DynamicList::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i>=0);
+ if((unsigned)i>=list.size())
+ return false;
+ if(x->get_type()!=container_type)
+ return false;
+ list[i].value_node=x;
+ return true;
+}
+
+ValueNode::LooseHandle
+ValueNode_DynamicList::get_link_vfunc(int i)const
+{
+ assert(i>=0);
+ if((unsigned)i>=list.size())
+ return 0;
+ return list[i].value_node;
+}
+
+int
+ValueNode_DynamicList::link_count()const
+{
+ return list.size();
+}
+
+String
+ValueNode_DynamicList::link_local_name(int i)const
+{
+ assert(i>=0 && (unsigned)i<list.size());
+ return etl::strprintf(_("Item %03d"),i+1);
+}
+
+ValueNode*
+ValueNode_DynamicList::clone(const GUID& deriv_guid)const
+{
+ { ValueNode* x(find_value_node(get_guid()^deriv_guid).get()); if(x)return x; }
+
+ ValueNode_DynamicList* ret=new ValueNode_DynamicList(container_type);
+ ret->set_guid(get_guid()^deriv_guid);
+
+ std::vector<ListEntry>::const_iterator iter;
+
+ for(iter=list.begin();iter!=list.end();++iter)
+ {
+ if(iter->value_node->is_exported())
+ ret->add(*iter);
+ else
+ {
+ ListEntry list_entry(*iter);
+ //list_entry.value_node=find_value_node(iter->value_node->get_guid()^deriv_guid).get();
+ //if(!list_entry.value_node)
+ list_entry.value_node=iter->value_node->clone(deriv_guid);
+ ret->add(list_entry);
+ //ret->list.back().value_node=iter->value_node.clone();
+ }
+ }
+ ret->set_loop(get_loop());
+ return ret;
+}
+
+String
+ValueNode_DynamicList::link_name(int i)const
+{
+ return strprintf("item%04d",i);
+}
+
+int
+ValueNode_DynamicList::get_link_index_from_name(const String &name)const
+{
+ throw Exception::BadLinkName(name);
+}
+
+String
+ValueNode_DynamicList::get_name()const
+{
+ return "dynamic_list";
+}
+
+String
+ValueNode_DynamicList::get_local_name()const
+{
+ return _("Dynamic List");
+}
+
+bool
+ValueNode_DynamicList::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_LIST;
+}
+
+ValueBase::Type
+ValueNode_DynamicList::get_contained_type()const
+{
+ return container_type;
+}
+
+LinkableValueNode*
+ValueNode_DynamicList::create_new()const
+{
+ assert(0);
+ return 0;
+}
+
+int
+ValueNode_DynamicList::find_next_valid_entry(int orig_item, Time t)const
+{
+ int curr_item;
+
+ for(curr_item=orig_item+1;curr_item!=orig_item;curr_item++)
+ {
+ if(curr_item==(int)list.size())
+ {
+ curr_item=0;
+ continue;
+ }
+ if(list[curr_item].status_at_time(t))
+ return curr_item;
+ }
+ return curr_item;
+}
+
+int
+ValueNode_DynamicList::find_prev_valid_entry(int orig_item, Time t)const
+{
+ int curr_item;
+
+ for(curr_item=orig_item-1;curr_item!=orig_item;curr_item--)
+ {
+ if(curr_item==-1)
+ {
+ curr_item=list.size();
+ continue;
+ }
+ if(list[curr_item].status_at_time(t))
+ return curr_item;
+ }
+ return curr_item;
+}
+
+const synfig::Node::time_set & ValueNode_DynamicList::ListEntry::get_times() const
+{
+ synfig::ActivepointList::const_iterator j = timing_info.begin(),
+ end = timing_info.end();
+
+ //must remerge with all the other values because we don't know if we've changed...
+ times = value_node->get_times();
+
+ for(; j != end; ++j)
+ {
+ TimePoint t;
+ t.set_time(j->get_time());
+ t.set_guid(j->get_guid());
+
+ times.insert(t);
+ }
+
+ return times;
+}
+
+void ValueNode_DynamicList::get_times_vfunc(Node::time_set &set) const
+{
+ //add in the active points
+ int size = list.size();
+
+ //rebuild all the info...
+ for(int i = 0; i < size; ++i)
+ {
+ const Node::time_set & tset= list[i].get_times();
+ set.insert(tset.begin(),tset.end());
+ }
+}
+
+
+//new find functions that don't throw
+struct timecmp
+{
+ Time t;
+
+ timecmp(const Time &c) :t(c) {}
+
+ bool operator()(const Activepoint &rhs) const
+ {
+ return t.is_equal(rhs.get_time());
+ }
+};
+
+ValueNode_DynamicList::ListEntry::findresult ValueNode_DynamicList::ListEntry::find_uid(const UniqueID& x)
+{
+ findresult f;
+ f.second = false;
+
+ f.first = std::find(timing_info.begin(),timing_info.end(),x);
+
+ if(f.first != timing_info.end())
+ {
+ f.second = true;
+ }
+
+ return f;
+}
+
+ValueNode_DynamicList::ListEntry::const_findresult ValueNode_DynamicList::ListEntry::find_uid(const UniqueID& x) const
+{
+ const_findresult f;
+ f.second = false;
+
+ f.first = std::find(timing_info.begin(),timing_info.end(),x);
+
+ if(f.first != timing_info.end())
+ {
+ f.second = true;
+ }
+
+ return f;
+}
+
+ValueNode_DynamicList::ListEntry::findresult ValueNode_DynamicList::ListEntry::find_time(const Time& x)
+{
+ findresult f;
+ f.second = false;
+
+ f.first = std::find_if(timing_info.begin(),timing_info.end(),timecmp(x));
+
+ if(f.first != timing_info.end())
+ {
+ f.second = true;
+ }
+
+ return f;
+}
+
+ValueNode_DynamicList::ListEntry::const_findresult ValueNode_DynamicList::ListEntry::find_time(const Time& x)const
+{
+ const_findresult f;
+ f.second = false;
+
+ f.first = std::find_if(timing_info.begin(),timing_info.end(),timecmp(x));
+
+ if(f.first != timing_info.end())
+ {
+ f.second = true;
+ }
+
+ return f;
+}
+
+void
+ValueNode_DynamicList::insert_time(const Time& location, const Time& delta)
+{
+ if(!delta)
+ return;
+
+ std::vector<ListEntry>::iterator iter(list.begin());
+ for(;iter!=list.end();++iter)
+ {
+ try
+ {
+ ListEntry& item(*iter);
+
+ ActivepointList::iterator iter(item.find_next(location));
+ for(;iter!=item.timing_info.end();++iter)
+ {
+ iter->set_time(iter->get_time()+delta);
+ }
+ }
+ catch(Exception::NotFound) { }
+ }
+ changed();
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_dynamiclist.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_DYNAMICLIST_H
+#define __SYNFIG_VALUENODE_DYNAMICLIST_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <vector>
+#include <list>
+
+#include "valuenode.h"
+#include "time.h"
+#include "uniqueid.h"
+#include "activepoint.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+class ValueNode_BLine;
+
+/*! \class ValueNode_DynamicList
+** \brief Animated List ValueNode
+**
+** This ValueNode was originally set up to have a list
+** of ValueNodes and their associated "on" and "off" points.
+** ie: Any time that was directly after an "on" point,
+** the item would be "on", and any time that was directly
+** after an "off" point would be "off". This is pretty intuitive.
+** However, it does have its problems.
+**
+** The problems arise when we introduce the concept of a
+** Keyframe. Keyframes can be manipulated via the Synfig
+** Application Library. They allow the user to quickly
+** and "automagickly" rearange an animation by moving
+** the associated keyframes. With the old way that the
+** "on" and "off" points were handled, this task became
+** overly complicated.
+**
+** What is required is a "symmetric" system of describing
+** "on" and "off" points. Instead of the point representing
+** the state of the item after that point in time, we have
+** the point represent <i>only that frame</i>. The state
+** of the item is calculated by looking at the points
+** around it: If either (or both) points are "on", then the
+** current state is "on". Otherwise, the point is "off"
+**
+** This may be a bit confusing at first, but it is required
+** if we want the keyframe mechanism to "just work".
+*/
+class ValueNode_DynamicList : public LinkableValueNode
+{
+public:
+
+ /*! \class ListEntry
+ ** \brief Contains a potential list item, and associated timing information
+ **
+ ** This structure contains a RHandle to a ValueNode,
+ ** as well as the associated on/off timing information
+ ** which determines when this item is included in the list.
+ **
+ ** The timing information is stored in the member <tt>timing_info</tt>.
+ */
+ struct ListEntry : public UniqueID
+ {
+ friend class ValueNode_DynamicList;
+ friend class ValueNode_BLine;
+ public:
+ typedef synfig::Activepoint Activepoint;
+
+ typedef std::list<Activepoint> ActivepointList;
+
+ typedef std::pair<ActivepointList::iterator,bool> findresult;
+ typedef std::pair<ActivepointList::const_iterator,bool> const_findresult;
+
+
+ private:
+ mutable Node::time_set times;
+ public:
+ ValueNode::RHandle value_node;
+
+ ActivepointList timing_info;
+
+ private:
+ int index;
+ etl::loose_handle<ValueNode> parent_;
+ void set_parent_value_node(const etl::loose_handle<ValueNode> &x) { parent_=x; }
+
+ public:
+
+ int get_index()const { return index; }
+
+
+ bool status_at_time(const Time &x)const;
+
+ float amount_at_time(const Time &x, bool *rising=0)const;
+
+ ActivepointList::iterator add(Time time, bool status, int priority=0);
+ ActivepointList::iterator add(const Activepoint &x);
+
+ findresult find_uid(const UniqueID& x);
+ const_findresult find_uid(const UniqueID& x)const;
+
+ findresult find_time(const Time& x);
+ const_findresult find_time(const Time& x)const;
+
+ ActivepointList::iterator find(const UniqueID& x);
+ ActivepointList::const_iterator find(const UniqueID& x)const;
+ ActivepointList::iterator find(const Time& x);
+ ActivepointList::const_iterator find(const Time& x)const;
+ ActivepointList::iterator find_prev(const Time& x);
+ ActivepointList::const_iterator find_prev(const Time& x)const;
+ ActivepointList::iterator find_next(const Time& x);
+ ActivepointList::const_iterator find_next(const Time& x)const;
+
+ Activepoint new_activepoint_at_time(const Time& x)const;
+
+ ActivepointList::iterator add(Time time)
+ { return add(time, status_at_time(time)); }
+
+ void erase(const UniqueID& x);
+
+ int find(const Time& begin,const Time& end,std::vector<Activepoint*>& list);
+
+ const synfig::Node::time_set &get_times() const;
+
+ const etl::loose_handle<ValueNode> &get_parent_value_node()const { return parent_; }
+
+ ListEntry();
+ ListEntry(const ValueNode::Handle &value_node);
+ ListEntry(const ValueNode::Handle &value_node,Time begin, Time end);
+ }; // END of struct ValueNode_DynamicList::ListEntry
+
+ typedef etl::handle<ValueNode_DynamicList> Handle;
+ typedef etl::handle<const ValueNode_DynamicList> ConstHandle;
+
+protected:
+ ValueNode_DynamicList(ValueBase::Type container_type=ValueBase::TYPE_NIL);
+
+ ValueBase::Type container_type;
+
+ bool loop_;
+
+
+public:
+ std::vector<ListEntry> list;
+
+public:
+
+ void add(const ValueNode::Handle &value_node, int index=-1);
+ void add(const ListEntry &value_node, int index=-1);
+ void erase(const ValueNode::Handle &value_node);
+ void reindex();
+
+ int find_next_valid_entry(int x, Time t)const;
+ int find_prev_valid_entry(int x, Time t)const;
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+
+ virtual int link_count()const;
+
+ virtual String link_name(int i)const;
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual ~ValueNode_DynamicList();
+
+ virtual String link_local_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+ bool get_loop()const { return loop_; }
+ void set_loop(bool x) { loop_=x; }
+
+ ValueBase::Type get_contained_type()const;
+
+
+ template <typename iterator> static Handle
+ create(iterator begin, iterator end)
+ {
+ Handle ret=create((*begin)->get_type());
+ for(;begin!=end;++begin)
+ ret->add(ListEntry(*begin));
+ return ret;
+ }
+
+ void insert_time(const Time& location, const Time& delta);
+ //void manipulate_time(const Time& old_begin,const Time& old_end,const Time& new_begin,const Time& new_end);
+
+ virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
+
+ virtual ListEntry create_list_entry(int index, Time time=0, Real origin=0.5);
+
+protected:
+
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+ LinkableValueNode* create_new()const;
+
+ virtual void get_times_vfunc(Node::time_set &set) const;
+
+public:
+ /*! \note The construction parameter (\a id) is the type that the list
+ ** contains, rather than the type that it will yield
+ ** (which is ValueBase::TYPE_LIST)
+ */
+ static Handle create(ValueBase::Type id=ValueBase::TYPE_NIL);
+ using synfig::LinkableValueNode::get_link_vfunc;
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_DynamicList* create_from(const ValueBase &x=ValueBase::TYPE_GRADIENT);
+}; // END of class ValueNode_DynamicList
+
+typedef ValueNode_DynamicList::ListEntry::Activepoint Activepoint;
+typedef ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_exp.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode_exp.h"
+#include "valuenode_const.h"
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ValueNode_Exp::ValueNode_Exp(const ValueBase &value):
+ LinkableValueNode(value.get_type())
+{
+ switch(value.get_type())
+ {
+ case ValueBase::TYPE_REAL:
+ set_link("exp",ValueNode_Const::create(Real(1)));
+ set_link("scale",ValueNode_Const::create(value.get(Real())));
+ break;
+ default:
+ throw Exception::BadType(ValueBase::type_name(value.get_type()));
+ }
+
+ DCAST_HACK_ENABLE();
+}
+
+LinkableValueNode*
+ValueNode_Exp::create_new()const
+{
+ return new ValueNode_Exp(get_type());
+}
+
+ValueNode_Exp*
+ValueNode_Exp::create(const ValueBase &x)
+{
+ return new ValueNode_Exp(x);
+}
+
+ValueNode_Exp::~ValueNode_Exp()
+{
+ unlink_all();
+}
+
+ValueBase
+ValueNode_Exp::operator()(Time t)const
+{
+ return (exp((*exp_)(t).get(Real())) *
+ (*scale_)(t).get(Real()));
+}
+
+String
+ValueNode_Exp::get_name()const
+{
+ return "exp";
+}
+
+String
+ValueNode_Exp::get_local_name()const
+{
+ return _("Exponential");
+}
+
+bool
+ValueNode_Exp::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ {
+ exp_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+ if(i==1)
+ {
+ scale_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_Exp::get_link_vfunc(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return exp_;
+ if(i==1)
+ return scale_;
+
+ return 0;
+}
+
+int
+ValueNode_Exp::link_count()const
+{
+ return 2;
+}
+
+String
+ValueNode_Exp::link_name(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return "exp";
+ if(i==1)
+ return "scale";
+ return String();
+}
+
+String
+ValueNode_Exp::link_local_name(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return _("Exponent");
+ if(i==1)
+ return _("Scale");
+ return String();
+}
+
+int
+ValueNode_Exp::get_link_index_from_name(const String &name)const
+{
+ if(name=="exp")
+ return 0;
+ if(name=="scale")
+ return 1;
+
+ throw Exception::BadLinkName(name);
+}
+
+bool
+ValueNode_Exp::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_REAL;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_exp.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_EXP_H
+#define __SYNFIG_VALUENODE_EXP_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueNode_Exp : public LinkableValueNode
+{
+ ValueNode::RHandle exp_;
+ ValueNode::RHandle scale_;
+
+ ValueNode_Exp(const ValueBase &value);
+
+public:
+
+ typedef etl::handle<ValueNode_Exp> Handle;
+ typedef etl::handle<const ValueNode_Exp> ConstHandle;
+
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual ~ValueNode_Exp();
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+ virtual int link_count()const;
+ virtual String link_name(int i)const;
+
+ virtual String link_local_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+protected:
+ LinkableValueNode* create_new()const;
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_Exp* create(const ValueBase &x);
+}; // END of class ValueNode_Exp
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_gradientrotate.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "general.h"
+#include "valuenode_gradientrotate.h"
+#include "valuenode_const.h"
+#include <stdexcept>
+#include "gradient.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+synfig::ValueNode_GradientRotate::ValueNode_GradientRotate(const Gradient& x):
+ LinkableValueNode(synfig::ValueBase::TYPE_GRADIENT)
+{
+ set_link("gradient",ValueNode_Const::create(x));
+ set_link("offset",ValueNode_Const::create(Real(0)));
+ DCAST_HACK_ENABLE();
+}
+
+LinkableValueNode*
+ValueNode_GradientRotate::create_new()const
+{
+ return new ValueNode_GradientRotate(Gradient());
+}
+
+ValueNode_GradientRotate*
+ValueNode_GradientRotate::create(const ValueBase& x)
+{
+ ValueBase::Type id(x.get_type());
+ if(id!=ValueBase::TYPE_GRADIENT)
+ {
+ assert(0);
+ throw runtime_error("synfig::ValueNode_GradientRotate:Bad type "+ValueBase::type_name(id));
+ }
+
+ ValueNode_GradientRotate* value_node=new ValueNode_GradientRotate(x.get(Gradient()));
+
+ assert(value_node->get_type()==id);
+
+ return value_node;
+}
+
+synfig::ValueNode_GradientRotate::~ValueNode_GradientRotate()
+{
+ unlink_all();
+}
+
+bool
+synfig::ValueNode_GradientRotate::set_gradient(ValueNode::Handle a)
+{
+ if(a->get_type()!=ValueBase::TYPE_GRADIENT&& !PlaceholderValueNode::Handle::cast_dynamic(a))
+ return false;
+
+ ref_gradient=a;
+
+ return true;
+}
+
+bool
+synfig::ValueNode_GradientRotate::set_offset(ValueNode::Handle b)
+{
+ if(b->get_type()!=ValueBase::TYPE_REAL&& !PlaceholderValueNode::Handle::cast_dynamic(b))
+ return false;
+ ref_offset=b;
+ return true;
+}
+
+synfig::ValueBase
+synfig::ValueNode_GradientRotate::operator()(Time t)const
+{
+ Gradient gradient;
+ gradient=(*ref_gradient)(t).get(gradient);
+ Real offset((*ref_offset)(t).get(Real()));
+ Gradient::iterator iter;
+ for(iter=gradient.begin();iter!=gradient.end();++iter)
+ iter->pos+=offset;
+
+ return gradient;
+}
+
+bool
+ValueNode_GradientRotate::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0:
+ if(set_gradient(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ case 1:
+ if(set_offset(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ }
+
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_GradientRotate::get_link_vfunc(int i)const
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0:
+ return ref_gradient;
+ case 1:
+ return ref_offset;
+ }
+ return 0;
+}
+
+int
+ValueNode_GradientRotate::link_count()const
+{
+ return 2;
+}
+
+String
+ValueNode_GradientRotate::link_local_name(int i)const
+{
+ assert(i>=0 && i<2);
+ switch(i)
+ {
+ case 0:
+ return _("Gradient");
+ case 1:
+ return _("Offset");
+ default:
+ return String();
+ }
+}
+
+String
+ValueNode_GradientRotate::link_name(int i)const
+{
+ assert(i>=0 && i<2);
+ switch(i)
+ {
+ case 0:
+ return "gradient";
+ case 1:
+ return "offset";
+ default: return String();
+ }
+}
+
+int
+ValueNode_GradientRotate::get_link_index_from_name(const String &name)const
+{
+ if(name=="gradient")
+ return 0;
+ if(name=="offset")
+ return 1;
+ throw Exception::BadLinkName(name);
+}
+
+String
+ValueNode_GradientRotate::get_name()const
+{
+ return "gradient_rotate";
+}
+
+String
+ValueNode_GradientRotate::get_local_name()const
+{
+ return _("Gradient Rotate");
+}
+
+bool
+ValueNode_GradientRotate::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_GRADIENT;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_gradientrotate.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_GRADIENTROTATE_H
+#define __SYNFIG_VALUENODE_GRADIENTROTATE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+struct ValueNode_GradientRotate : public LinkableValueNode
+{
+ typedef etl::handle<ValueNode_GradientRotate> Handle;
+ typedef etl::handle<const ValueNode_GradientRotate> ConstHandle;
+
+protected:
+
+ ValueNode_GradientRotate(const Gradient& x);
+
+private:
+
+ ValueNode::RHandle ref_gradient;
+ ValueNode::RHandle ref_offset;
+
+public:
+
+ virtual ~ValueNode_GradientRotate();
+
+// static Handle create(ValueBase::Type id=ValueBase::TYPE_GRADIENT);
+
+ //! Sets the left-hand-side value_node
+ bool set_gradient(ValueNode::Handle a);
+
+ //! Gets the left-hand-side value_node
+ ValueNode::Handle get_gradient()const { return ref_gradient; }
+
+ //! Sets the right-hand-side value_node
+ bool set_offset(ValueNode::Handle b);
+
+ //! Gets the right-hand-side value_node
+ ValueNode::Handle get_offset()const { return ref_gradient; }
+
+
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+
+ virtual int link_count()const;
+
+ virtual String link_local_name(int i)const;
+ virtual String link_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+// static bool check_type(const ValueBase::Type &type);
+protected:
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+ LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_GradientRotate* create(const ValueBase &x=ValueBase::TYPE_GRADIENT);
+}; // END of class ValueNode_GradientRotate
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_linear.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode_linear.h"
+#include "valuenode_const.h"
+#include "general.h"
+#include "color.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ValueNode_Linear::ValueNode_Linear(const ValueBase &value):
+ LinkableValueNode(value.get_type())
+{
+ switch(get_type())
+ {
+ case ValueBase::TYPE_ANGLE:
+ set_link("slope",ValueNode_Const::create(Angle::deg(0)));
+ set_link("offset",ValueNode_Const::create(value.get(Angle())));
+ break;
+ case ValueBase::TYPE_COLOR:
+ set_link("slope",ValueNode_Const::create(Color(0,0,0,0)));
+ set_link("offset",ValueNode_Const::create(value.get(Color())));
+ break;
+ case ValueBase::TYPE_INTEGER:
+ set_link("slope",ValueNode_Const::create(int(0)));
+ set_link("offset",ValueNode_Const::create(value.get(int())));
+ break;
+ case ValueBase::TYPE_REAL:
+ set_link("slope",ValueNode_Const::create(Real(0)));
+ set_link("offset",ValueNode_Const::create(value.get(Real())));
+ break;
+ case ValueBase::TYPE_TIME:
+ set_link("slope",ValueNode_Const::create(Time(0)));
+ set_link("offset",ValueNode_Const::create(value.get(Time())));
+ break;
+ case ValueBase::TYPE_VECTOR:
+ set_link("slope",ValueNode_Const::create(Vector(0,0)));
+ set_link("offset",ValueNode_Const::create(value.get(Vector())));
+ break;
+ default:
+ throw Exception::BadType(ValueBase::type_name(get_type()));
+ }
+
+ DCAST_HACK_ENABLE();
+}
+
+LinkableValueNode*
+ValueNode_Linear::create_new()const
+{
+ return new ValueNode_Linear(get_type());
+}
+
+ValueNode_Linear*
+ValueNode_Linear::create(const ValueBase &x)
+{
+ return new ValueNode_Linear(x);
+}
+
+ValueNode_Linear::~ValueNode_Linear()
+{
+ unlink_all();
+}
+
+ValueBase
+ValueNode_Linear::operator()(Time t)const
+{
+ switch(get_type())
+ {
+ case ValueBase::TYPE_ANGLE:
+ return (*m_)(t).get( Angle())*t+(*b_)(t).get( Angle());
+ case ValueBase::TYPE_COLOR:
+ return (*m_)(t).get( Color())*t+(*b_)(t).get( Color());
+ case ValueBase::TYPE_INTEGER:
+ {
+ Real ret = (*m_)(t).get(int())*t+(*b_)(t).get(int()) + 0.5f;
+ if (ret < 0) return static_cast<int>(ret-1);
+ return static_cast<int>(ret);
+ }
+ case ValueBase::TYPE_REAL:
+ return (*m_)(t).get( Real())*t+(*b_)(t).get( Real());
+ case ValueBase::TYPE_TIME:
+ return (*m_)(t).get( Time())*t+(*b_)(t).get( Time());
+ case ValueBase::TYPE_VECTOR:
+ return (*m_)(t).get(Vector())*t+(*b_)(t).get(Vector());
+ default:
+ assert(0);
+ break;
+ }
+ return ValueBase();
+}
+
+
+String
+ValueNode_Linear::get_name()const
+{
+ return "linear";
+}
+
+String
+ValueNode_Linear::get_local_name()const
+{
+ return _("Linear");
+}
+
+bool
+ValueNode_Linear::check_type(ValueBase::Type type)
+{
+ return
+ type==ValueBase::TYPE_ANGLE ||
+ type==ValueBase::TYPE_COLOR ||
+ type==ValueBase::TYPE_INTEGER ||
+ type==ValueBase::TYPE_REAL ||
+ type==ValueBase::TYPE_TIME ||
+ type==ValueBase::TYPE_VECTOR ;
+}
+
+bool
+ValueNode_Linear::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ {
+ m_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+ if(i==1)
+ {
+ b_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_Linear::get_link_vfunc(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0) return m_;
+ if(i==1) return b_;
+ return 0;
+}
+
+int
+ValueNode_Linear::link_count()const
+{
+ return 2;
+}
+
+String
+ValueNode_Linear::link_name(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0) return "slope";
+ if(i==1) return "offset";
+ return String();
+}
+
+String
+ValueNode_Linear::link_local_name(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ switch(get_type())
+ {
+ case ValueBase::TYPE_ANGLE:
+ case ValueBase::TYPE_COLOR:
+ case ValueBase::TYPE_INTEGER:
+ case ValueBase::TYPE_REAL:
+ case ValueBase::TYPE_TIME:
+ return _("Rate");
+ case ValueBase::TYPE_VECTOR:
+ default:
+ return _("Slope");
+ }
+ if(i==1)
+ return _("Offset");
+ return String();
+}
+
+int
+ValueNode_Linear::get_link_index_from_name(const String &name)const
+{
+ if(name=="slope") return 0;
+ if(name=="offset") return 1;
+
+ throw Exception::BadLinkName(name);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_linear.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_INTERPOLATION_LINEAR_H
+#define __SYNFIG_VALUENODE_INTERPOLATION_LINEAR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueNode_Linear : public LinkableValueNode
+{
+ ValueNode::RHandle m_;
+ ValueNode::RHandle b_;
+
+ ValueNode_Linear(const ValueBase &value);
+
+public:
+
+ typedef etl::handle<ValueNode_Linear> Handle;
+ typedef etl::handle<const ValueNode_Linear> ConstHandle;
+
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual ~ValueNode_Linear();
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+ virtual int link_count()const;
+ virtual String link_name(int i)const;
+
+ virtual String link_local_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+protected:
+ LinkableValueNode* create_new()const;
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_Linear* create(const ValueBase &x);
+}; // END of class ValueNode_Linear
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_radialcomposite.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode_radialcomposite.h"
+#include "valuenode_const.h"
+#include <stdexcept>
+#include "general.h"
+#include "color.h"
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+synfig::ValueNode_RadialComposite::ValueNode_RadialComposite(const ValueBase &value):
+ LinkableValueNode(value.get_type())
+{
+ switch(get_type())
+ {
+ case ValueBase::TYPE_VECTOR:
+ {
+ Vector vect(value.get(Vector()));
+ set_link("r",ValueNode_Const::create(vect.mag()));
+ set_link("t",ValueNode_Const::create(Angle(Angle::tan(vect[1],vect[0]))));
+ }
+ break;
+ case ValueBase::TYPE_COLOR:
+ set_link("y",ValueNode_Const::create(value.get(Color()).get_y()));
+ set_link("s",ValueNode_Const::create(value.get(Color()).get_s()));
+ set_link("h",ValueNode_Const::create(value.get(Color()).get_hue()));
+ set_link("a",ValueNode_Const::create(value.get(Color()).get_a()));
+ break;
+ default:
+ assert(0);
+ throw Exception::BadType(ValueBase::type_name(get_type()));
+ }
+}
+
+ValueNode_RadialComposite::~ValueNode_RadialComposite()
+{
+ unlink_all();
+}
+
+ValueNode_RadialComposite*
+ValueNode_RadialComposite::create(const ValueBase &value)
+{
+ return new ValueNode_RadialComposite(value);
+}
+
+LinkableValueNode*
+ValueNode_RadialComposite::create_new()const
+{
+ return new ValueNode_RadialComposite(ValueBase(get_type()));
+}
+
+ValueBase
+synfig::ValueNode_RadialComposite::operator()(Time t)const
+{
+ switch(get_type())
+ {
+ case ValueBase::TYPE_VECTOR:
+ {
+ Real mag;
+ Angle angle;
+ assert(components[0] && components[1]);
+ mag=(*components[0])(t).get(mag);
+ angle=(*components[1])(t).get(angle);
+ return Vector(Angle::cos(angle).get()*mag,Angle::sin(angle).get()*mag);
+ }
+ case ValueBase::TYPE_COLOR:
+ {
+ assert(components[0] && components[1] && components[2] && components[3]);
+ return Color::YUV(
+ (*components[0])(t).get(Real()),
+ (*components[1])(t).get(Real()),
+ (*components[2])(t).get(Angle()),
+ (*components[3])(t).get(Real())
+ );
+ }
+ default:
+ synfig::error(string("ValueNode_RadialComposite::operator():")+_("Bad type for radialcomposite"));
+ assert(components[0]);
+ return (*components[0])(t);
+ }
+}
+
+int
+ValueNode_RadialComposite::link_count()const
+{
+ switch(get_type())
+ {
+ case ValueBase::TYPE_VECTOR:
+ return 2;
+ case ValueBase::TYPE_COLOR:
+ return 4;
+ default:
+ synfig::warning(string("ValueNode_RadialComposite::component_count():")+_("Bad type for radialcomposite"));
+ return 1;
+ }
+}
+
+bool
+ValueNode_RadialComposite::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i>=0);
+ assert(i<6);
+
+ if(PlaceholderValueNode::Handle::cast_dynamic(x))
+ {
+ components[i]=x;
+ return true;
+ }
+
+ switch(get_type())
+ {
+ case ValueBase::TYPE_VECTOR:
+ assert(i<2);
+ if(i==0 && x->get_type()!=ValueBase::TYPE_REAL)
+ return false;
+ if(i==1 && x->get_type()!=ValueBase::TYPE_ANGLE)
+ return false;
+ components[i]=x;
+ return true;
+ break;
+
+ case ValueBase::TYPE_COLOR:
+ assert(i<4);
+ if((i==0 || i==1 || i==3) && x->get_type()!=ValueBase::TYPE_REAL)
+ return false;
+ if((i==2) && x->get_type()!=ValueBase::TYPE_ANGLE)
+ return false;
+ components[i]=x;
+ return true;
+ break;
+
+
+ default:
+ break;
+ }
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_RadialComposite::get_link_vfunc(int i)const
+{
+ assert(i>=0 && i<6);
+ return components[i];
+}
+
+String
+ValueNode_RadialComposite::link_local_name(int i)const
+{
+ assert(i>=0 && i<6);
+ switch(get_type())
+ {
+ case ValueBase::TYPE_VECTOR:
+ if(i==0)
+ return _("Radius");
+ else if(i==1)
+ return _("Theta");
+ break;
+
+ case ValueBase::TYPE_COLOR:
+ if(i==0)
+ return _("Luma");
+ else if(i==1)
+ return _("Saturation");
+ else if(i==2)
+ return _("Hue");
+ else if(i==3)
+ return _("Alpha");
+ break;
+
+ default:
+ break;
+ }
+
+ return etl::strprintf(_("C%d"),i+1);
+}
+
+
+String
+ValueNode_RadialComposite::link_name(int i)const
+{
+ assert(i>=0 && i<5);
+ return strprintf("c%d",i);
+}
+
+int
+ValueNode_RadialComposite::get_link_index_from_name(const String &name)const
+{
+ if(name.empty())
+ throw Exception::BadLinkName(name);
+
+ if(name[0]=='c')
+ return name[1]-'0';
+
+ switch(get_type())
+ {
+ case ValueBase::TYPE_COLOR:
+ if(name[0]=='y')
+ return 0;
+ if(name[0]=='s')
+ return 1;
+ if(name[0]=='h')
+ return 2;
+ if(name[0]=='a')
+ return 3;
+ case ValueBase::TYPE_VECTOR:
+ if(name[0]=='r')
+ return 0;
+ if(name[0]=='t')
+ return 1;
+ default:
+ break;
+ }
+
+ throw Exception::BadLinkName(name);
+}
+
+String
+ValueNode_RadialComposite::get_name()const
+{
+ return "radial_composite";
+}
+
+String
+ValueNode_RadialComposite::get_local_name()const
+{
+ return _("Radial Composite");
+}
+
+bool
+ValueNode_RadialComposite::check_type(ValueBase::Type type)
+{
+ return
+ type==ValueBase::TYPE_VECTOR ||
+ type==ValueBase::TYPE_COLOR;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_radialcomposite.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_RADIALCOMPOSITE_H
+#define __SYNFIG_VALUENODE_RADIALCOMPOSITE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueNode_RadialComposite : public LinkableValueNode
+{
+ ValueNode::RHandle components[6];
+ ValueNode_RadialComposite(const ValueBase &value);
+
+public:
+ typedef etl::handle<ValueNode_RadialComposite> Handle;
+ typedef etl::handle<const ValueNode_RadialComposite> ConstHandle;
+
+
+ virtual ~ValueNode_RadialComposite();
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+ virtual int link_count()const;
+ virtual String link_name(int i)const;
+ virtual String link_local_name(int i)const;
+ virtual ValueBase operator()(Time t)const;
+
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+protected:
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+ LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::set_link_vfunc;
+ using synfig::LinkableValueNode::get_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_RadialComposite* create(const ValueBase &x);
+}; // END of class ValueNode_RadialComposite
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_range.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "general.h"
+#include "valuenode_range.h"
+#include "valuenode_const.h"
+#include <stdexcept>
+#include "vector.h"
+#include "angle.h"
+#include "real.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+synfig::ValueNode_Range::ValueNode_Range(const ValueBase &value):
+ LinkableValueNode(value.get_type())
+{
+ ValueBase::Type id(value.get_type());
+
+ switch(id)
+ {
+ case ValueBase::TYPE_ANGLE:
+ set_link("min",ValueNode_Const::create(value.get(Angle())));
+ set_link("max",ValueNode_Const::create(value.get(Angle())));
+ set_link("link",ValueNode_Const::create(value.get(Angle())));
+ break;
+ case ValueBase::TYPE_INTEGER:
+ set_link("min",ValueNode_Const::create(value.get(int())));
+ set_link("max",ValueNode_Const::create(value.get(int())));
+ set_link("link",ValueNode_Const::create(value.get(int())));
+ break;
+ case ValueBase::TYPE_REAL:
+ set_link("min",ValueNode_Const::create(value.get(Real())));
+ set_link("max",ValueNode_Const::create(value.get(Real())));
+ set_link("link",ValueNode_Const::create(value.get(Real())));
+ break;
+ case ValueBase::TYPE_TIME:
+ set_link("min",ValueNode_Const::create(value.get(Time())));
+ set_link("max",ValueNode_Const::create(value.get(Time())));
+ set_link("link",ValueNode_Const::create(value.get(Time())));
+ break;
+ default:
+ assert(0);
+ throw runtime_error("synfig::ValueNode_Range:Bad type "+ValueBase::type_name(id));
+ }
+
+ assert(min_->get_type()==id);
+ assert(max_->get_type()==id);
+ assert(link_->get_type()==id);
+ assert(get_type()==id);
+
+ DCAST_HACK_ENABLE();
+}
+
+LinkableValueNode*
+ValueNode_Range::create_new()const
+{
+ return new ValueNode_Range(get_type());
+}
+
+ValueNode_Range*
+ValueNode_Range::create(const ValueBase& value)
+{
+ return new ValueNode_Range(value);
+}
+
+synfig::ValueNode_Range::~ValueNode_Range()
+{
+ unlink_all();
+}
+
+synfig::ValueBase
+synfig::ValueNode_Range::operator()(Time t)const
+{
+ if(!min_ || !max_ || !link_)
+ throw runtime_error(strprintf("ValueNode_Range: %s",_("Some of my parameters aren't set!")));
+
+ switch(get_type())
+ {
+ case ValueBase::TYPE_ANGLE:
+ {
+ Angle minimum = (* min_)(t).get(Angle());
+ Angle maximum = (* max_)(t).get(Angle());
+ Angle link = (*link_)(t).get(Angle());
+
+ // if link is between min and max, use it
+ if (Angle::deg((link-minimum).mod()).get() < Angle::deg((maximum-minimum).mod()).get())
+ return link;
+ // otherwise use whichever of min and max is closest to link
+ else if (link.dist(minimum).abs() < link.dist(maximum).abs())
+ return minimum;
+ else
+ return maximum;
+ }
+ case ValueBase::TYPE_INTEGER:
+ return std::max((*min_)(t).get(int()), std::min((*max_)(t).get(int()), (*link_)(t).get(int())));
+ case ValueBase::TYPE_REAL:
+ return std::max((*min_)(t).get(Real()), std::min((*max_)(t).get(Real()), (*link_)(t).get(Real())));
+ case ValueBase::TYPE_TIME:
+ return std::max((*min_)(t).get(Time()), std::min((*max_)(t).get(Time()), (*link_)(t).get(Time())));
+ default:
+ assert(0);
+ break;
+ }
+ return ValueBase();
+}
+
+bool
+ValueNode_Range::set_link_vfunc(int i,ValueNode::Handle value)
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0:
+ min_=value;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ case 1:
+ max_=value;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ case 2:
+ link_=value;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_Range::get_link_vfunc(int i)const
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0: return min_;
+ case 1: return max_;
+ case 2: return link_;
+ default: return 0;
+ }
+}
+
+int
+ValueNode_Range::link_count()const
+{
+ return 3;
+}
+
+String
+ValueNode_Range::link_local_name(int i)const
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0: return _("Min");
+ case 1: return _("Max");
+ case 2: return _("Link");
+ default: return String();
+ }
+}
+
+String
+ValueNode_Range::link_name(int i)const
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0: return "min";
+ case 1: return "max";
+ case 2: return "link";
+ default: return String();
+ }
+}
+
+int
+ValueNode_Range::get_link_index_from_name(const String &name)const
+{
+ if(name=="min") return 0;
+ if(name=="max") return 1;
+ if(name=="link") return 2;
+ throw Exception::BadLinkName(name);
+}
+
+String
+ValueNode_Range::get_name()const
+{
+ return "range";
+}
+
+String
+ValueNode_Range::get_local_name()const
+{
+ return _("Range");
+}
+
+bool
+ValueNode_Range::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_ANGLE
+ || type==ValueBase::TYPE_INTEGER
+ || type==ValueBase::TYPE_REAL
+ || type==ValueBase::TYPE_TIME;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_range.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_RANGE_H
+#define __SYNFIG_VALUENODE_RANGE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueNode_Range : public LinkableValueNode
+{
+ ValueNode::RHandle min_;
+ ValueNode::RHandle max_;
+ ValueNode::RHandle link_;
+
+ ValueNode_Range(const ValueBase &value);
+
+public:
+
+ typedef etl::handle<ValueNode_Range> Handle;
+ typedef etl::handle<const ValueNode_Range> ConstHandle;
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual ~ValueNode_Range();
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+ virtual int link_count()const;
+ virtual String link_name(int i)const;
+
+ virtual String link_local_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+protected:
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+ LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_Range* create(const ValueBase &value=ValueBase());
+}; // END of class ValueNode_Range
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_reference.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode_reference.h"
+#include "valuenode_const.h"
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ValueNode_Reference::ValueNode_Reference(const ValueBase::Type &x):
+ LinkableValueNode(x)
+{
+}
+
+ValueNode_Reference::ValueNode_Reference(const ValueNode::Handle &x):
+ LinkableValueNode(x->get_type())
+{
+ set_link("link",x);
+}
+
+ValueNode_Reference*
+ValueNode_Reference::create(const ValueBase &x)
+{
+ return new ValueNode_Reference(ValueNode_Const::create(x));
+}
+
+LinkableValueNode*
+ValueNode_Reference::create_new()const
+{
+ return new ValueNode_Reference(get_type());
+}
+
+ValueNode_Reference::~ValueNode_Reference()
+{
+ unlink_all();
+}
+
+bool
+ValueNode_Reference::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i==0);
+ if(x->get_type()!=get_type() && !PlaceholderValueNode::Handle::cast_dynamic(x))
+ return false;
+ link_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+}
+
+ValueNode::LooseHandle
+ValueNode_Reference::get_link_vfunc(int i)const
+{
+ assert(i==0);
+ return link_;
+}
+
+int
+ValueNode_Reference::link_count()const
+{
+ return 1;
+}
+
+String
+ValueNode_Reference::link_local_name(int i)const
+{
+ assert(i==0);
+ return _("Link");
+}
+
+String
+ValueNode_Reference::link_name(int /*i*/)const
+{
+ return "link";
+}
+
+int
+ValueNode_Reference::get_link_index_from_name(const String &name)const
+{
+ if(name=="link")
+ return 0;
+
+ throw Exception::BadLinkName(name);
+}
+
+ValueBase
+ValueNode_Reference::operator()(Time t)const
+{
+ return (*link_)(t);
+}
+
+
+String
+ValueNode_Reference::get_name()const
+{
+ return "reference";
+}
+
+String
+ValueNode_Reference::get_local_name()const
+{
+ return _("Reference");
+}
+
+bool
+ValueNode_Reference::check_type(ValueBase::Type type)
+{
+ if(type)
+ return true;
+ return false;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_reference.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_REFERENCE_H
+#define __SYNFIG_VALUENODE_REFERENCE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueNode_Reference : public LinkableValueNode
+{
+ ValueNode::RHandle link_;
+public:
+ typedef etl::handle<ValueNode_Reference> Handle;
+ typedef etl::handle<const ValueNode_Reference> ConstHandle;
+
+ ValueNode_Reference(const ValueBase::Type &x);
+
+ ValueNode_Reference(const ValueNode::Handle &x);
+
+// static Handle create(const ValueBase::Type &x);
+// static Handle create(const ValueNode::Handle &x);
+
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+
+ virtual int link_count()const;
+
+ virtual String link_name(int i)const;
+
+ virtual String link_local_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual ~ValueNode_Reference();
+
+ virtual String get_name()const;
+
+ virtual String get_local_name()const;
+
+protected:
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+ LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_Reference* create(const ValueBase &x);
+}; // END of class ValueNode_Reference
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_repeat_gradient.cpp
+** \brief Template File
+**
+** $Id: valuenode_repeat_gradient.cpp 604 2007-09-05 14:29:02Z dooglus $
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "general.h"
+#include "valuenode_repeat_gradient.h"
+#include "valuenode_const.h"
+#include <stdexcept>
+#include "color.h"
+#include "gradient.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+synfig::ValueNode_Repeat_Gradient::ValueNode_Repeat_Gradient(const Gradient& x):LinkableValueNode(synfig::ValueBase::TYPE_GRADIENT)
+{
+ set_link("gradient",ValueNode_Const::create(x));
+ set_link("count",count_=ValueNode_Const::create(int(3)));
+ set_link("width",ValueNode_Const::create(0.5));
+ set_link("specify_start",ValueNode_Const::create(true));
+ set_link("specify_end",ValueNode_Const::create(true));
+ set_link("start_color",ValueNode_Const::create(Color::alpha()));
+ set_link("end_color",ValueNode_Const::create(Color::alpha()));
+}
+
+LinkableValueNode*
+ValueNode_Repeat_Gradient::create_new()const
+{
+ return new ValueNode_Repeat_Gradient(Gradient());
+}
+
+ValueNode_Repeat_Gradient*
+ValueNode_Repeat_Gradient::create(const ValueBase& x)
+{
+ ValueBase::Type id(x.get_type());
+
+ if(id!=ValueBase::TYPE_GRADIENT)
+ {
+ assert(0);
+ throw runtime_error("synfig::ValueNode_Repeat_Gradient:Bad type "+ValueBase::type_name(id));
+ }
+
+ ValueNode_Repeat_Gradient* value_node=new ValueNode_Repeat_Gradient(x.get(Gradient()));
+
+ assert(value_node->get_type()==id);
+
+ return value_node;
+}
+
+synfig::ValueNode_Repeat_Gradient::~ValueNode_Repeat_Gradient()
+{
+ unlink_all();
+}
+
+bool
+synfig::ValueNode_Repeat_Gradient::set_gradient(ValueNode::Handle a)
+{
+ if(a->get_type()!=ValueBase::TYPE_GRADIENT)
+ return false;
+
+ gradient_=a;
+
+ return true;
+}
+
+bool
+synfig::ValueNode_Repeat_Gradient::set_width(ValueNode::Handle x)
+{
+ if(x->get_type()!=ValueBase::TYPE_REAL)
+ return false;
+
+ width_=x;
+
+ return true;
+}
+
+bool
+synfig::ValueNode_Repeat_Gradient::set_count(ValueNode::Handle b)
+{
+ if(b->get_type()!=ValueBase::TYPE_INTEGER)
+ return false;
+ count_=b;
+ return true;
+}
+
+bool
+synfig::ValueNode_Repeat_Gradient::set_specify_start(ValueNode::Handle a)
+{
+ if(a->get_type()!=ValueBase::TYPE_BOOL)
+ return false;
+ specify_start_=a;
+ return true;
+}
+
+bool
+synfig::ValueNode_Repeat_Gradient::set_specify_end(ValueNode::Handle a)
+{
+ if(a->get_type()!=ValueBase::TYPE_BOOL)
+ return false;
+ specify_end_=a;
+ return true;
+}
+
+bool
+synfig::ValueNode_Repeat_Gradient::set_start_color(ValueNode::Handle a)
+{
+ if(a->get_type()!=ValueBase::TYPE_COLOR)
+ return false;
+ start_color_=a;
+ return true;
+}
+
+bool
+synfig::ValueNode_Repeat_Gradient::set_end_color(ValueNode::Handle a)
+{
+ if(a->get_type()!=ValueBase::TYPE_COLOR)
+ return false;
+ end_color_=a;
+ return true;
+}
+
+synfig::ValueBase
+synfig::ValueNode_Repeat_Gradient::operator()(Time t)const
+{
+ const int count((*count_)(t).get(int()));
+ int i;
+ Gradient ret;
+
+ if(count<=0)
+ return ret;
+
+ const Gradient gradient((*gradient_)(t).get(Gradient()));
+ const float width(max(0.0,min(1.0,(*width_)(t).get(Real()))));
+ const bool specify_start((*specify_start_)(t).get(bool()));
+ const bool specify_end((*specify_end_)(t).get(bool()));
+
+ const float gradient_width_a(width/count);
+ const float gradient_width_b((1.0-width)/count);
+
+ Gradient::const_iterator iter;
+ Gradient::const_reverse_iterator riter;
+ if (specify_start)
+ ret.push_back(Gradient::CPoint(0,(*start_color_)(t).get(Color())));
+ for(i=0;i<count;i++)
+ {
+ float pos(float(i)/count);
+ if (width != 0.0)
+ for(iter=gradient.begin();iter!=gradient.end();iter++)
+ ret.push_back(Gradient::CPoint(pos+gradient_width_a*iter->pos,iter->color));
+ pos+=gradient_width_a;
+ if (width != 1.0)
+ for(riter=gradient.rbegin();riter!=gradient.rend();riter++)
+ ret.push_back(Gradient::CPoint(pos+gradient_width_b*(1-(riter->pos)),riter->color));
+ }
+ if (specify_end)
+ ret.push_back(Gradient::CPoint(1,(*end_color_)(t).get(Color())));
+ return ret;
+}
+
+bool
+ValueNode_Repeat_Gradient::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0:
+ if(set_gradient(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ case 1:
+ if(set_count(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ case 2:
+ if(set_width(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ case 3:
+ if(set_specify_start(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ case 4:
+ if(set_specify_end(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ case 5:
+ if(set_start_color(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ case 6:
+ if(set_end_color(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ }
+
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_Repeat_Gradient::get_link_vfunc(int i)const
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0: return gradient_;
+ case 1: return count_;
+ case 2: return width_;
+ case 3: return specify_start_;
+ case 4: return specify_end_;
+ case 5: return start_color_;
+ case 6: return end_color_;
+ default: return 0;
+ }
+}
+
+int
+ValueNode_Repeat_Gradient::link_count()const
+{
+ return 7;
+}
+
+String
+ValueNode_Repeat_Gradient::link_local_name(int i)const
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0: return _("Gradient");
+ case 1: return _("Count");
+ case 2: return _("Width");
+ case 3: return _("Specify Start");
+ case 4: return _("Specify End");
+ case 5: return _("Start Color");
+ case 6: return _("End Color");
+ default: return String();
+ }
+}
+
+String
+ValueNode_Repeat_Gradient::link_name(int i)const
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0: return "gradient";
+ case 1: return "count";
+ case 2: return "width";
+ case 3: return "specify_start";
+ case 4: return "specify_end";
+ case 5: return "start_color";
+ case 6: return "end_color";
+ default: return String();
+ }
+}
+
+int
+ValueNode_Repeat_Gradient::get_link_index_from_name(const String &name)const
+{
+ if(name=="gradient") return 0;
+ if(name=="count") return 1;
+ if(name=="width") return 2;
+ if(name=="specify_start") return 3;
+ if(name=="specify_end") return 4;
+ if(name=="start_color") return 5;
+ if(name=="end_color") return 6;
+ throw Exception::BadLinkName(name);
+}
+
+String
+ValueNode_Repeat_Gradient::get_name()const
+{
+ return "repeat_gradient";
+}
+
+String
+ValueNode_Repeat_Gradient::get_local_name()const
+{
+ return _("Repeat Gradient");
+}
+
+bool
+ValueNode_Repeat_Gradient::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_GRADIENT;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_repeat_gradient.h
+** \brief Template Header
+**
+** $Id: valuenode_repeat_gradient.h 335 2007-03-16 00:39:09Z dooglus $
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_REPEAT_GRADIENT_H
+#define __SYNFIG_VALUENODE_REPEAT_GRADIENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+struct ValueNode_Repeat_Gradient : public LinkableValueNode
+{
+ typedef etl::handle<ValueNode_Repeat_Gradient> Handle;
+ typedef etl::handle<const ValueNode_Repeat_Gradient> ConstHandle;
+
+protected:
+
+ ValueNode_Repeat_Gradient(const Gradient& x);
+
+private:
+
+ ValueNode::RHandle gradient_;
+ ValueNode::RHandle count_;
+ ValueNode::RHandle width_;
+ ValueNode::RHandle specify_start_;
+ ValueNode::RHandle specify_end_;
+ ValueNode::RHandle start_color_;
+ ValueNode::RHandle end_color_;
+
+public:
+
+ virtual ~ValueNode_Repeat_Gradient();
+
+ bool set_gradient(ValueNode::Handle a);
+ bool set_count(ValueNode::Handle b);
+ bool set_width(ValueNode::Handle x);
+ bool set_specify_start(ValueNode::Handle a);
+ bool set_specify_end(ValueNode::Handle a);
+ bool set_start_color(ValueNode::Handle a);
+ bool set_end_color(ValueNode::Handle a);
+
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+
+ virtual int link_count()const;
+
+ virtual String link_local_name(int i)const;
+ virtual String link_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+// static bool check_type(const ValueBase::Type &type);
+
+ LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_Repeat_Gradient* create(const ValueBase &x=ValueBase::TYPE_GRADIENT);
+}; // END of class ValueNode_Repeat_Gradient
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_scale.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "general.h"
+#include "valuenode_scale.h"
+#include "valuenode_const.h"
+#include <stdexcept>
+#include <cassert>
+#include "color.h"
+#include "vector.h"
+#include "time.h"
+#include "angle.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ValueNode_Scale::ValueNode_Scale(const ValueBase &value):
+ LinkableValueNode(value.get_type())
+{
+ set_scalar(1.0);
+ ValueBase::Type id(value.get_type());
+
+ switch(id)
+ {
+ case ValueBase::TYPE_ANGLE:
+ set_link("link",ValueNode_Const::create(value.get(Angle())));
+ break;
+ case ValueBase::TYPE_COLOR:
+ set_link("link",ValueNode_Const::create(value.get(Color())));
+ break;
+ case ValueBase::TYPE_INTEGER:
+ set_link("link",ValueNode_Const::create(value.get(int())));
+ break;
+ case ValueBase::TYPE_REAL:
+ set_link("link",ValueNode_Const::create(value.get(Real())));
+ break;
+ case ValueBase::TYPE_TIME:
+ set_link("link",ValueNode_Const::create(value.get(Time())));
+ break;
+ case ValueBase::TYPE_VECTOR:
+ set_link("link",ValueNode_Const::create(value.get(Vector())));
+ break;
+ default:
+ assert(0);
+ throw runtime_error("synfig::ValueNode_Scale:Bad type "+ValueBase::type_name(value.get_type()));
+ }
+
+ assert(value_node);
+ assert(get_value_node()->get_type()==id);
+ assert(get_type()==id);
+}
+
+LinkableValueNode*
+ValueNode_Scale::create_new()const
+{
+ return new ValueNode_Scale(get_type());
+}
+
+ValueNode_Scale*
+ValueNode_Scale::create(const ValueBase& value)
+{
+ return new ValueNode_Scale(value);
+}
+
+synfig::ValueNode_Scale::~ValueNode_Scale()
+{
+ unlink_all();
+}
+
+void
+ValueNode_Scale::set_scalar(Real x)
+{
+ set_link("scalar",ValueNode::Handle(ValueNode_Const::create(x)));
+}
+
+bool
+ValueNode_Scale::set_scalar(const ValueNode::Handle &x)
+{
+ if(!x
+ || x->get_type()!=ValueBase::TYPE_REAL
+ && !PlaceholderValueNode::Handle::cast_dynamic(x)
+ )
+ return false;
+ scalar=x;
+ return true;
+}
+
+ValueNode::Handle
+ValueNode_Scale::get_scalar()const
+{
+ return scalar;
+}
+
+bool
+ValueNode_Scale::set_value_node(const ValueNode::Handle &x)
+{
+ assert(get_type());
+
+ // if this isn't a proper value
+ if(!x ||
+ // or we don't have a type, and this value isn't one of the types we accept
+ (get_type()==ValueBase::TYPE_NIL && !check_type(x->get_type())) ||
+ // or we have a type and this value is a different type and (placeholder?)
+ (get_type()!=ValueBase::TYPE_NIL && x->get_type()!=get_type() && !PlaceholderValueNode::Handle::cast_dynamic(x)))
+ // then fail to set the value
+ return false;
+
+ value_node=x;
+
+ return true;
+}
+
+ValueNode::Handle
+ValueNode_Scale::get_value_node()const
+{
+ return value_node;
+}
+
+
+synfig::ValueBase
+synfig::ValueNode_Scale::operator()(Time t)const
+{
+ if(!value_node || !scalar)
+ throw runtime_error(strprintf("ValueNode_Scale: %s",_("One or both of my parameters aren't set!")));
+ else if(get_type()==ValueBase::TYPE_ANGLE)
+ return (*value_node)(t).get(Angle())*(*scalar)(t).get(Real());
+ else if(get_type()==ValueBase::TYPE_COLOR)
+ {
+ Color ret((*value_node)(t).get(Color()));
+ Real s((*scalar)(t).get(Real()));
+ ret.set_r(ret.get_r()*s);
+ ret.set_g(ret.get_g()*s);
+ ret.set_b(ret.get_b()*s);
+ return ret;
+ }
+ else if(get_type()==ValueBase::TYPE_INTEGER)
+ {
+ Real ret = (*value_node)(t).get(int())*(*scalar)(t).get(Real()) + 0.5f;
+ if (ret < 0) return static_cast<int>(ret-1);
+ return static_cast<int>(ret);
+ }
+ else if(get_type()==ValueBase::TYPE_REAL)
+ return (*value_node)(t).get(Real())*(*scalar)(t).get(Real());
+ else if(get_type()==ValueBase::TYPE_TIME)
+ return (*value_node)(t).get(Time())*(*scalar)(t).get(Time());
+ else if(get_type()==ValueBase::TYPE_VECTOR)
+ return (*value_node)(t).get(Vector())*(*scalar)(t).get(Real());
+
+ assert(0);
+ return ValueBase();
+}
+
+
+bool
+ValueNode_Scale::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ if(!(i==0 || i==1))
+ return false;
+
+ if(i==0 && !set_value_node(x))
+ return false;
+ else
+ if(i==1 && !set_scalar(x))
+ return false;
+
+ signal_child_changed()(i);signal_value_changed()();
+
+ return true;
+}
+
+ValueNode::LooseHandle
+ValueNode_Scale::get_link_vfunc(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return value_node;
+ else if(i==1)
+ return scalar;
+ return 0;
+}
+
+int
+ValueNode_Scale::link_count()const
+{
+ return 2;
+}
+
+String
+ValueNode_Scale::link_local_name(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return _("Link");
+ else if(i==1)
+ return _("Scalar");
+ return String();
+}
+
+String
+ValueNode_Scale::link_name(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return "link";
+ else if(i==1)
+ return "scalar";
+ return String();
+}
+
+int
+ValueNode_Scale::get_link_index_from_name(const String &name)const
+{
+ if(name=="link")
+ return 0;
+ if(name=="scalar")
+ return 1;
+
+ throw Exception::BadLinkName(name);
+}
+
+String
+ValueNode_Scale::get_name()const
+{
+ return "scale";
+}
+
+String
+ValueNode_Scale::get_local_name()const
+{
+ return _("Scale");
+}
+
+bool
+ValueNode_Scale::check_type(ValueBase::Type type)
+{
+ return
+ type==ValueBase::TYPE_ANGLE ||
+ type==ValueBase::TYPE_COLOR ||
+ type==ValueBase::TYPE_INTEGER ||
+ type==ValueBase::TYPE_REAL ||
+ type==ValueBase::TYPE_TIME ||
+ type==ValueBase::TYPE_VECTOR;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_scale.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_SCALE_H
+#define __SYNFIG_VALUENODE_SCALE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+struct ValueNode_Scale : public LinkableValueNode
+{
+ typedef etl::handle<ValueNode_Scale> Handle;
+ typedef etl::handle<const ValueNode_Scale> ConstHandle;
+
+private:
+ ValueNode::RHandle value_node;
+ ValueNode::RHandle scalar;
+
+ ValueNode_Scale(const ValueBase &value);
+
+public:
+
+ //static Handle create(ValueBase::Type id=ValueBase::TYPE_NIL);
+
+ //static Handle create(ValueNode::Handle value_node, Real scalar);
+
+ virtual ~ValueNode_Scale();
+
+ //! \writeme
+ bool set_value_node(const ValueNode::Handle &a);
+
+ //! \writeme
+ ValueNode::Handle get_value_node()const;
+
+ void set_scalar(Real x);
+
+ bool set_scalar(const ValueNode::Handle &x);
+
+ ValueNode::Handle get_scalar()const;
+
+
+
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+
+ virtual int link_count()const;
+
+ virtual String link_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual String get_name()const;
+
+ virtual String get_local_name()const;
+
+ virtual String link_local_name(int i)const;
+
+protected:
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+ virtual LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_Scale* create(const ValueBase &x);
+}; // END of class ValueNode_Scale
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_segcalctangent.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode_segcalctangent.h"
+#include "valuenode_const.h"
+#include "valuenode_composite.h"
+#include "general.h"
+#include "exception.h"
+#include <ETL/hermite>
+#include <ETL/calculus>
+#include "segment.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ValueNode_SegCalcTangent::ValueNode_SegCalcTangent(const ValueBase::Type &x):
+ LinkableValueNode(x)
+{
+ if(x!=ValueBase::TYPE_VECTOR)
+ throw Exception::BadType(ValueBase::type_name(x));
+
+ set_link("segment",ValueNode_Const::create(ValueBase::TYPE_SEGMENT));
+ set_link("amount",ValueNode_Const::create(Real(0.5)));
+}
+
+ValueNode_SegCalcTangent*
+ValueNode_SegCalcTangent::create(const ValueBase &x)
+{
+ return new ValueNode_SegCalcTangent(x.get_type());
+}
+
+ValueNode_SegCalcTangent::~ValueNode_SegCalcTangent()
+{
+ unlink_all();
+}
+
+ValueBase
+ValueNode_SegCalcTangent::operator()(Time t)const
+{
+ Segment segment((*segment_)(t).get(Segment()));
+
+ etl::hermite<Vector> curve(segment.p1,segment.p2,segment.t1,segment.t2);
+ etl::derivative< etl::hermite<Vector> > deriv(curve);
+
+#ifdef ETL_FIXED_DERIVATIVE
+ return deriv((*amount_)(t).get(Real()))*(0.5);
+#else
+ return deriv((*amount_)(t).get(Real()))*(-0.5);
+#endif
+
+}
+
+
+String
+ValueNode_SegCalcTangent::get_name()const
+{
+ return "segcalctangent";
+}
+
+String
+ValueNode_SegCalcTangent::get_local_name()const
+{
+ return _("Segment Tangent");
+}
+
+bool
+ValueNode_SegCalcTangent::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_VECTOR;
+}
+
+bool
+ValueNode_SegCalcTangent::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ {
+ segment_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+ if(i==1)
+ {
+ amount_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_SegCalcTangent::get_link_vfunc(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return segment_;
+ if(i==1)
+ return amount_;
+
+ return 0;
+}
+
+int
+ValueNode_SegCalcTangent::link_count()const
+{
+ return 2;
+}
+
+String
+ValueNode_SegCalcTangent::link_name(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return "segment";
+ if(i==1)
+ return "amount";
+ return String();
+}
+
+String
+ValueNode_SegCalcTangent::link_local_name(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return _("Segment");
+ if(i==1)
+ return _("Amount");
+ return String();
+}
+
+int
+ValueNode_SegCalcTangent::get_link_index_from_name(const String &name)const
+{
+ if(name=="segment")
+ return 0;
+ if(name=="amount")
+ return 1;
+
+ throw Exception::BadLinkName(name);
+}
+
+LinkableValueNode*
+ValueNode_SegCalcTangent::create_new()const
+{
+ return new ValueNode_SegCalcTangent(ValueBase::TYPE_VECTOR);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_segcalctangent.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_SEGCALCTANGENT_H
+#define __SYNFIG_VALUENODE_SEGCALCTANGENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueNode_SegCalcTangent : public LinkableValueNode
+{
+ ValueNode::RHandle segment_;
+ ValueNode::RHandle amount_;
+
+ ValueNode_SegCalcTangent(const ValueBase::Type &x=ValueBase::TYPE_VECTOR);
+
+public:
+
+ typedef etl::handle<ValueNode_SegCalcTangent> Handle;
+ typedef etl::handle<const ValueNode_SegCalcTangent> ConstHandle;
+
+ //static Handle create(const ValueBase::Type &x=ValueBase::TYPE_VECTOR);
+
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual ~ValueNode_SegCalcTangent();
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+ virtual int link_count()const;
+ virtual String link_name(int i)const;
+
+ virtual String link_local_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+protected:
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+ LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_SegCalcTangent* create(const ValueBase &x=ValueBase::TYPE_VECTOR);
+}; // END of class ValueNode_SegCalcTangent
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_segcalcvertex.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode_segcalcvertex.h"
+#include "valuenode_const.h"
+#include "valuenode_composite.h"
+#include "general.h"
+#include "exception.h"
+#include <ETL/hermite>
+#include "segment.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ValueNode_SegCalcVertex::ValueNode_SegCalcVertex(const ValueBase::Type &x):
+ LinkableValueNode(x)
+{
+ if(x!=ValueBase::TYPE_VECTOR)
+ throw Exception::BadType(ValueBase::type_name(x));
+
+ set_link("segment",ValueNode_Const::create(ValueBase::TYPE_SEGMENT));
+ set_link("amount",ValueNode_Const::create(Real(0.5)));
+}
+
+ValueNode_SegCalcVertex*
+ValueNode_SegCalcVertex::create(const ValueBase &x)
+{
+ return new ValueNode_SegCalcVertex(x.get_type());
+}
+
+ValueNode_SegCalcVertex::~ValueNode_SegCalcVertex()
+{
+ unlink_all();
+}
+
+ValueBase
+ValueNode_SegCalcVertex::operator()(Time t)const
+{
+ Segment segment((*segment_)(t).get(Segment()));
+
+ etl::hermite<Vector> curve(segment.p1,segment.p2,segment.t1,segment.t2);
+
+ return curve((*amount_)(t).get(Real()));
+}
+
+
+String
+ValueNode_SegCalcVertex::get_name()const
+{
+ return "segcalcvertex";
+}
+
+String
+ValueNode_SegCalcVertex::get_local_name()const
+{
+ return _("Segment Vertex");
+}
+
+bool
+ValueNode_SegCalcVertex::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_VECTOR;
+}
+
+bool
+ValueNode_SegCalcVertex::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ {
+ segment_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+ if(i==1)
+ {
+ amount_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_SegCalcVertex::get_link_vfunc(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return segment_;
+ if(i==1)
+ return amount_;
+
+ return 0;
+}
+
+int
+ValueNode_SegCalcVertex::link_count()const
+{
+ return 2;
+}
+
+String
+ValueNode_SegCalcVertex::link_name(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return "segment";
+ if(i==1)
+ return "amount";
+ return String();
+}
+
+String
+ValueNode_SegCalcVertex::link_local_name(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return _("Segment");
+ if(i==1)
+ return _("Amount");
+ return String();
+}
+
+int
+ValueNode_SegCalcVertex::get_link_index_from_name(const String &name)const
+{
+ if(name=="segment")
+ return 0;
+ if(name=="amount")
+ return 1;
+
+ throw Exception::BadLinkName(name);
+}
+
+LinkableValueNode*
+ValueNode_SegCalcVertex::create_new()const
+{
+ return new ValueNode_SegCalcVertex(ValueBase::TYPE_VECTOR);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_segcalcvertex.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_SEGCALCVERTEX_H
+#define __SYNFIG_VALUENODE_SEGCALCVERTEX_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueNode_SegCalcVertex : public LinkableValueNode
+{
+ ValueNode::RHandle segment_;
+ ValueNode::RHandle amount_;
+
+ ValueNode_SegCalcVertex(const ValueBase::Type &x=ValueBase::TYPE_VECTOR);
+
+public:
+
+ typedef etl::handle<ValueNode_SegCalcVertex> Handle;
+ typedef etl::handle<const ValueNode_SegCalcVertex> ConstHandle;
+
+// static Handle create(const ValueBase::Type &x=ValueBase::TYPE_VECTOR);
+
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual ~ValueNode_SegCalcVertex();
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+// static bool check_type(const ValueBase::Type &type);
+
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+ virtual int link_count()const;
+ virtual String link_name(int i)const;
+
+ virtual String link_local_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+protected:
+ LinkableValueNode* create_new()const;
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_SegCalcVertex* create(const ValueBase &x=ValueBase::TYPE_VECTOR);
+}; // END of class ValueNode_SegCalcVertex
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_sine.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "valuenode_sine.h"
+#include "valuenode_const.h"
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ValueNode_Sine::ValueNode_Sine(const ValueBase &value):
+ LinkableValueNode(value.get_type())
+{
+ switch(value.get_type())
+ {
+ case ValueBase::TYPE_REAL:
+ set_link("angle",ValueNode_Const::create(Angle::deg(90)));
+ set_link("amp",ValueNode_Const::create(value.get(Real())));
+ break;
+ default:
+ throw Exception::BadType(ValueBase::type_name(value.get_type()));
+ }
+
+ DCAST_HACK_ENABLE();
+}
+
+LinkableValueNode*
+ValueNode_Sine::create_new()const
+{
+ return new ValueNode_Sine(get_type());
+}
+
+ValueNode_Sine*
+ValueNode_Sine::create(const ValueBase &x)
+{
+ return new ValueNode_Sine(x);
+}
+
+ValueNode_Sine::~ValueNode_Sine()
+{
+ unlink_all();
+}
+
+ValueBase
+ValueNode_Sine::operator()(Time t)const
+{
+ return
+ Angle::sin(
+ (*angle_)(t).get(Angle())
+ ).get() * (*amp_)(t).get(Real())
+ ;
+}
+
+
+String
+ValueNode_Sine::get_name()const
+{
+ return "sine";
+}
+
+String
+ValueNode_Sine::get_local_name()const
+{
+ return _("Sine");
+}
+
+bool
+ValueNode_Sine::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_REAL;
+}
+
+bool
+ValueNode_Sine::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ {
+ angle_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+ if(i==1)
+ {
+ amp_=x;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_Sine::get_link_vfunc(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return angle_;
+ if(i==1)
+ return amp_;
+
+ return 0;
+}
+
+int
+ValueNode_Sine::link_count()const
+{
+ return 2;
+}
+
+String
+ValueNode_Sine::link_name(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return "angle";
+ if(i==1)
+ return "amp";
+ return String();
+}
+
+String
+ValueNode_Sine::link_local_name(int i)const
+{
+ assert(i==0 || i==1);
+ if(i==0)
+ return _("Angle");
+ if(i==1)
+ return _("Amplitude");
+ return String();
+}
+
+int
+ValueNode_Sine::get_link_index_from_name(const String &name)const
+{
+ if(name=="angle")
+ return 0;
+ if(name=="amp")
+ return 1;
+
+ throw Exception::BadLinkName(name);
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_sine.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_SINE_H
+#define __SYNFIG_VALUENODE_SINE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueNode_Sine : public LinkableValueNode
+{
+ ValueNode::RHandle angle_;
+ ValueNode::RHandle amp_;
+
+ ValueNode_Sine(const ValueBase &value);
+
+public:
+
+ typedef etl::handle<ValueNode_Sine> Handle;
+ typedef etl::handle<const ValueNode_Sine> ConstHandle;
+
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual ~ValueNode_Sine();
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+ virtual int link_count()const;
+ virtual String link_name(int i)const;
+
+ virtual String link_local_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+protected:
+ LinkableValueNode* create_new()const;
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_Sine* create(const ValueBase &x);
+}; // END of class ValueNode_Sine
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_stripes.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "general.h"
+#include "valuenode_stripes.h"
+#include "valuenode_const.h"
+#include <stdexcept>
+#include "color.h"
+#include "gradient.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+synfig::ValueNode_Stripes::ValueNode_Stripes():LinkableValueNode(synfig::ValueBase::TYPE_GRADIENT)
+{
+ set_link("color1",ValueNode_Const::create(Color::alpha()));
+ set_link("color2",ValueNode_Const::create(Color::black()));
+ set_link("stripes",stripes_=ValueNode_Const::create(int(5)));
+ set_link("width",ValueNode_Const::create(0.5));
+}
+
+LinkableValueNode*
+ValueNode_Stripes::create_new()const
+{
+ return new ValueNode_Stripes();
+}
+
+ValueNode_Stripes*
+ValueNode_Stripes::create(const ValueBase& x)
+{
+ ValueBase::Type id(x.get_type());
+
+ if(id!=ValueBase::TYPE_GRADIENT)
+ {
+ assert(0);
+ throw runtime_error("synfig::ValueNode_Stripes:Bad type "+ValueBase::type_name(id));
+ }
+
+ ValueNode_Stripes* value_node=new ValueNode_Stripes();
+
+ assert(value_node->get_type()==id);
+
+ return value_node;
+}
+
+synfig::ValueNode_Stripes::~ValueNode_Stripes()
+{
+ unlink_all();
+}
+
+bool
+synfig::ValueNode_Stripes::set_color1(ValueNode::Handle a)
+{
+ if(a->get_type()!=ValueBase::TYPE_COLOR)
+ return false;
+
+ color1_=a;
+
+ return true;
+}
+
+bool
+synfig::ValueNode_Stripes::set_color2(ValueNode::Handle a)
+{
+ if(a->get_type()!=ValueBase::TYPE_COLOR)
+ return false;
+
+ color2_=a;
+
+ return true;
+}
+
+bool
+synfig::ValueNode_Stripes::set_width(ValueNode::Handle x)
+{
+ if(x->get_type()!=ValueBase::TYPE_REAL)
+ return false;
+
+ width_=x;
+
+ return true;
+}
+
+bool
+synfig::ValueNode_Stripes::set_stripes(ValueNode::Handle b)
+{
+ if(b->get_type()!=ValueBase::TYPE_INTEGER)
+ return false;
+ stripes_=b;
+ return true;
+}
+
+synfig::ValueBase
+synfig::ValueNode_Stripes::operator()(Time t)const
+{
+ const int total((*stripes_)(t).get(int()));
+ int i;
+ Gradient ret;
+
+ if(total<=0)
+ return ret;
+
+ const Color color1((*color1_)(t).get(Color()));
+ const Color color2((*color2_)(t).get(Color()));
+ const float width(max(0.0,min(1.0,(*width_)(t).get(Real()))));
+
+ const float stripe_width_a(width/total);
+ const float stripe_width_b((1.0-width)/total);
+
+ for(i=0;i<total;i++)
+ {
+ float pos(float(i)/total+stripe_width_b/2);
+ ret.push_back(Gradient::CPoint(pos,color1));
+ ret.push_back(Gradient::CPoint(pos,color2));
+ pos+=stripe_width_a;
+ ret.push_back(Gradient::CPoint(pos,color2));
+ ret.push_back(Gradient::CPoint(pos,color1));
+ }
+ return ret;
+}
+
+bool
+ValueNode_Stripes::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0:
+ if(set_color1(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ case 1:
+ if(set_color2(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ case 2:
+ if(set_stripes(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ case 3:
+ if(set_width(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ }
+
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_Stripes::get_link_vfunc(int i)const
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0:
+ return color1_;
+ case 1:
+ return color2_;
+ case 2:
+ return stripes_;
+ case 3:
+ return width_;
+ }
+ return 0;
+}
+
+int
+ValueNode_Stripes::link_count()const
+{
+ return 4;
+}
+
+String
+ValueNode_Stripes::link_local_name(int i)const
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0:
+ return _("Color 1");
+ case 1:
+ return _("Color 2");
+ case 2:
+ return _("Stripe Count");
+ case 3:
+ return _("Width");
+ default:
+ return String();
+ }
+}
+
+String
+ValueNode_Stripes::link_name(int i)const
+{
+ assert(i>=0 && i<link_count());
+ switch(i)
+ {
+ case 0:
+ return "color1";
+ case 1:
+ return "color2";
+ case 2:
+ return "stripes";
+ case 3:
+ return "width";
+ default:
+ return String();
+ }
+}
+
+int
+ValueNode_Stripes::get_link_index_from_name(const String &name)const
+{
+ if(name=="color1")
+ return 0;
+ if(name=="color2")
+ return 1;
+ if(name=="stripes")
+ return 2;
+ if(name=="width")
+ return 3;
+ throw Exception::BadLinkName(name);
+}
+
+String
+ValueNode_Stripes::get_name()const
+{
+ return "stripes";
+}
+
+String
+ValueNode_Stripes::get_local_name()const
+{
+ return _("Stripes");
+}
+
+bool
+ValueNode_Stripes::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_GRADIENT;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_stripes.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_STRIPES_H
+#define __SYNFIG_VALUENODE_STRIPES_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+struct ValueNode_Stripes : public LinkableValueNode
+{
+ typedef etl::handle<ValueNode_Stripes> Handle;
+ typedef etl::handle<const ValueNode_Stripes> ConstHandle;
+
+protected:
+
+ ValueNode_Stripes();
+
+private:
+
+ ValueNode::RHandle color1_;
+ ValueNode::RHandle color2_;
+ ValueNode::RHandle stripes_;
+ ValueNode::RHandle width_;
+
+public:
+
+ virtual ~ValueNode_Stripes();
+
+// static Handle create(ValueBase::Type id=ValueBase::TYPE_GRADIENT);
+
+ bool set_color1(ValueNode::Handle a);
+ ValueNode::Handle get_color1()const { return color1_; }
+
+ bool set_color2(ValueNode::Handle a);
+ ValueNode::Handle get_color2()const { return color2_; }
+
+ bool set_stripes(ValueNode::Handle b);
+ ValueNode::Handle get_stripes()const { return stripes_; }
+
+ bool set_width(ValueNode::Handle x);
+
+
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+
+ virtual int link_count()const;
+
+ virtual String link_local_name(int i)const;
+ virtual String link_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+// static bool check_type(const ValueBase::Type &type);
+
+ LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_Stripes* create(const ValueBase &x=ValueBase::TYPE_GRADIENT);
+}; // END of class ValueNode_Stripes
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_subtract.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "general.h"
+#include "valuenode_subtract.h"
+#include "valuenode_const.h"
+#include <stdexcept>
+#include "color.h"
+#include "vector.h"
+#include "angle.h"
+#include "real.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+synfig::ValueNode_Subtract::ValueNode_Subtract(const ValueBase &value):
+ LinkableValueNode(value.get_type())
+{
+ set_scalar(1.0);
+ ValueBase::Type id(value.get_type());
+
+ switch(id)
+ {
+ case ValueBase::TYPE_ANGLE:
+ set_link("lhs",ValueNode_Const::create(value.get(Angle())));
+ set_link("rhs",ValueNode_Const::create(Angle::deg(0)));
+ break;
+ case ValueBase::TYPE_COLOR:
+ set_link("lhs",ValueNode_Const::create(value.get(Color())));
+ set_link("rhs",ValueNode_Const::create(Color(0,0,0,0)));
+ break;
+ case ValueBase::TYPE_INTEGER:
+ set_link("lhs",ValueNode_Const::create(value.get(int())));
+ set_link("rhs",ValueNode_Const::create(int(0)));
+ break;
+ case ValueBase::TYPE_REAL:
+ set_link("lhs",ValueNode_Const::create(value.get(Real())));
+ set_link("rhs",ValueNode_Const::create(Real(0)));
+ break;
+ case ValueBase::TYPE_TIME:
+ set_link("lhs",ValueNode_Const::create(value.get(Time())));
+ set_link("rhs",ValueNode_Const::create(Time(0)));
+ break;
+ case ValueBase::TYPE_VECTOR:
+ set_link("lhs",ValueNode_Const::create(value.get(Vector())));
+ set_link("rhs",ValueNode_Const::create(Vector(0,0)));
+ break;
+ default:
+ assert(0);
+ throw runtime_error("synfig::ValueNode_Subtract:Bad type "+ValueBase::type_name(id));
+ }
+
+ assert(get_lhs()->get_type()==id);
+ assert(get_rhs()->get_type()==id);
+ assert(get_type()==id);
+
+ DCAST_HACK_ENABLE();
+}
+
+LinkableValueNode*
+ValueNode_Subtract::create_new()const
+{
+ return new ValueNode_Subtract(get_type());
+}
+
+ValueNode_Subtract*
+ValueNode_Subtract::create(const ValueBase& value)
+{
+ return new ValueNode_Subtract(value);
+}
+
+synfig::ValueNode_Subtract::~ValueNode_Subtract()
+{
+ unlink_all();
+}
+
+void
+ValueNode_Subtract::set_scalar(Real value)
+{
+ set_link("scalar",ValueNode_Const::create(value));
+}
+
+bool
+synfig::ValueNode_Subtract::set_scalar(ValueNode::Handle value)
+{
+ if(value->get_type()!=ValueBase::TYPE_REAL&& !PlaceholderValueNode::Handle::cast_dynamic(value))
+ return false;
+ scalar=value;
+ return true;
+}
+
+bool
+synfig::ValueNode_Subtract::set_lhs(ValueNode::Handle x)
+{
+ assert(get_type());
+
+ if(!x ||
+ (get_type()==ValueBase::TYPE_NIL && !check_type(x->get_type())) ||
+ (get_type()!=ValueBase::TYPE_NIL && x->get_type()!=get_type() && !PlaceholderValueNode::Handle::cast_dynamic(x)))
+ return false;
+
+ ref_a=x;
+
+ return true;
+}
+
+bool
+synfig::ValueNode_Subtract::set_rhs(ValueNode::Handle x)
+{
+ assert(get_type());
+
+ if(!x ||
+ (get_type()==ValueBase::TYPE_NIL && !check_type(x->get_type())) ||
+ (get_type()!=ValueBase::TYPE_NIL && x->get_type()!=get_type() && !PlaceholderValueNode::Handle::cast_dynamic(x)))
+ return false;
+
+ ref_b=x;
+
+ return true;
+}
+
+synfig::ValueBase
+synfig::ValueNode_Subtract::operator()(Time t)const
+{
+ if(!ref_a || !ref_b)
+ throw runtime_error(strprintf("ValueNode_Subtract: %s",_("One or both of my parameters aren't set!")));
+ switch(get_type())
+ {
+ case ValueBase::TYPE_ANGLE:
+ return ((*ref_a)(t).get(Angle())-(*ref_b)(t).get(Angle()))*(*scalar)(t).get(Real());
+ case ValueBase::TYPE_COLOR:
+ return ((*ref_a)(t).get(Color())-(*ref_b)(t).get(Color()))*(*scalar)(t).get(Real());
+ case ValueBase::TYPE_INTEGER:
+ {
+ Real ret = ((*ref_a)(t).get(int())-(*ref_b)(t).get(int()))*(*scalar)(t).get(Real()) + 0.5f;
+ if (ret < 0) return static_cast<int>(ret-1);
+ return static_cast<int>(ret);
+ }
+ case ValueBase::TYPE_REAL:
+ return ((*ref_a)(t).get(Vector::value_type())-(*ref_b)(t).get(Vector::value_type()))*(*scalar)(t).get(Real());
+ case ValueBase::TYPE_TIME:
+ return ((*ref_a)(t).get(Time())-(*ref_b)(t).get(Time()))*(*scalar)(t).get(Real());
+ case ValueBase::TYPE_VECTOR:
+ return ((*ref_a)(t).get(Vector())-(*ref_b)(t).get(Vector()))*(*scalar)(t).get(Real());
+ default:
+ assert(0);
+ break;
+ }
+ return ValueBase();
+}
+
+bool
+ValueNode_Subtract::set_link_vfunc(int i,ValueNode::Handle value)
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0:
+ if(set_lhs(value)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ return false;
+ case 1:
+ if(set_rhs(value)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ return false;
+ case 2:
+ scalar=value;
+ signal_child_changed()(i);signal_value_changed()();
+ return true;
+ }
+
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_Subtract::get_link_vfunc(int i)const
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0: return ref_a;
+ case 1: return ref_b;
+ case 2: return scalar;
+ default: return 0;
+ }
+}
+
+int
+ValueNode_Subtract::link_count()const
+{
+ return 3;
+}
+
+String
+ValueNode_Subtract::link_local_name(int i)const
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0: return _("LHS");
+ case 1: return _("RHS");
+ case 2: return _("Scalar");
+ default: return String();
+ }
+}
+
+String
+ValueNode_Subtract::link_name(int i)const
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0: return "lhs";
+ case 1: return "rhs";
+ case 2: return "scalar";
+ default: return String();
+ }
+}
+
+int
+ValueNode_Subtract::get_link_index_from_name(const String &name)const
+{
+ if(name=="lhs") return 0;
+ if(name=="rhs") return 1;
+ if(name=="scalar") return 2;
+ throw Exception::BadLinkName(name);
+}
+
+String
+ValueNode_Subtract::get_name()const
+{
+ return "subtract";
+}
+
+String
+ValueNode_Subtract::get_local_name()const
+{
+ return _("Subtract");
+}
+
+bool
+ValueNode_Subtract::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_ANGLE
+ || type==ValueBase::TYPE_COLOR
+ || type==ValueBase::TYPE_INTEGER
+ || type==ValueBase::TYPE_REAL
+ || type==ValueBase::TYPE_TIME
+ || type==ValueBase::TYPE_VECTOR;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_subtract.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_SUBTRACT_H
+#define __SYNFIG_VALUENODE_SUBTRACT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+struct ValueNode_Subtract : public LinkableValueNode
+{
+ typedef etl::handle<ValueNode_Subtract> Handle;
+ typedef etl::handle<const ValueNode_Subtract> ConstHandle;
+
+protected:
+
+ ValueNode_Subtract(const ValueBase &value);
+
+private:
+
+ ValueNode::RHandle ref_a;
+ ValueNode::RHandle ref_b;
+ ValueNode::RHandle scalar;
+
+public:
+
+ virtual ~ValueNode_Subtract();
+
+// static Handle create(ValueBase::Type id=ValueBase::TYPE_NIL);
+
+ //! Sets the left-hand-side value_node
+ bool set_lhs(ValueNode::Handle a);
+
+ //! Gets the left-hand-side value_node
+ ValueNode::Handle get_lhs()const { return ref_a; }
+
+ //! Sets the right-hand-side value_node
+ bool set_rhs(ValueNode::Handle b);
+
+ //! Gets the right-hand-side value_node
+ ValueNode::Handle get_rhs()const { return ref_b; }
+
+ //! Sets the scalar value_node
+ bool set_scalar(ValueNode::Handle x);
+
+ //! Gets the scalar value_node
+ ValueNode::Handle get_scalar()const { return scalar; }
+
+ void set_scalar(Real x);
+
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+
+ virtual int link_count()const;
+
+ virtual String link_local_name(int i)const;
+ virtual String link_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+// static bool check_type(const ValueBase::Type &type);
+
+ LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_Subtract* create(const ValueBase &value=ValueBase());
+}; // END of class ValueNode_Subtract
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_timedswap.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "general.h"
+#include "valuenode_timedswap.h"
+#include "valuenode_const.h"
+#include <stdexcept>
+#include "color.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ValueNode_TimedSwap::ValueNode_TimedSwap(const ValueBase &value):
+ LinkableValueNode(value.get_type())
+{
+ switch(get_type())
+ {
+ case ValueBase::TYPE_ANGLE:
+ set_link("before",ValueNode_Const::create(value.get(Angle())));
+ set_link("after",ValueNode_Const::create(value.get(Angle())));
+ break;
+ case ValueBase::TYPE_COLOR:
+ set_link("before",ValueNode_Const::create(value.get(Color())));
+ set_link("after",ValueNode_Const::create(value.get(Color())));
+ break;
+ case ValueBase::TYPE_INTEGER:
+ set_link("before",ValueNode_Const::create(value.get(int())));
+ set_link("after",ValueNode_Const::create(value.get(int())));
+ break;
+ case ValueBase::TYPE_REAL:
+ set_link("before",ValueNode_Const::create(value.get(Real())));
+ set_link("after",ValueNode_Const::create(value.get(Real())));
+ break;
+ case ValueBase::TYPE_TIME:
+ set_link("before",ValueNode_Const::create(value.get(Time())));
+ set_link("after",ValueNode_Const::create(value.get(Time())));
+ break;
+ case ValueBase::TYPE_VECTOR:
+ set_link("before",ValueNode_Const::create(value.get(Vector())));
+ set_link("after",ValueNode_Const::create(value.get(Vector())));
+ break;
+ default:
+ throw Exception::BadType(ValueBase::type_name(get_type()));
+ }
+
+ set_link("time",ValueNode_Const::create(Time(2)));
+ set_link("length",ValueNode_Const::create(Time(1)));
+
+ DCAST_HACK_ENABLE();
+}
+
+ValueNode_TimedSwap*
+ValueNode_TimedSwap::create(const ValueBase& x)
+{
+ return new ValueNode_TimedSwap(x);
+}
+
+
+LinkableValueNode*
+ValueNode_TimedSwap::create_new()const
+{
+ return new ValueNode_TimedSwap(get_type());
+}
+
+
+synfig::ValueNode_TimedSwap::~ValueNode_TimedSwap()
+{
+ unlink_all();
+}
+
+
+
+bool
+ValueNode_TimedSwap::set_before(const ValueNode::Handle &x)
+{
+ if(!x || x->get_type()!=get_type()
+ && !PlaceholderValueNode::Handle::cast_dynamic(x))
+ return false;
+
+ before=x;
+
+ return true;
+}
+
+ValueNode::Handle
+ValueNode_TimedSwap::get_before()const
+{
+ return before;
+}
+
+
+bool
+ValueNode_TimedSwap::set_after(const ValueNode::Handle &x)
+{
+ if(!x || x->get_type()!=get_type()
+ && !PlaceholderValueNode::Handle::cast_dynamic(x))
+ return false;
+
+ after=x;
+
+ return true;
+}
+
+ValueNode::Handle
+ValueNode_TimedSwap::get_after()const
+{
+ return after;
+}
+
+
+bool
+ValueNode_TimedSwap::set_swap_time(const ValueNode::Handle &x)
+{
+ if(!x || (!ValueBase(x->get_type()).same_type_as(ValueBase::TYPE_TIME) &&
+ !PlaceholderValueNode::Handle::cast_dynamic(x)))
+ return false;
+
+ swap_time=x;
+ return true;
+}
+
+ValueNode::Handle
+ValueNode_TimedSwap::get_swap_time()const
+{
+ return swap_time;
+}
+
+bool
+ValueNode_TimedSwap::set_swap_length(const ValueNode::Handle &x)
+{
+ if(!x || (!ValueBase(x->get_type()).same_type_as(ValueBase::TYPE_TIME) &&
+ !PlaceholderValueNode::Handle::cast_dynamic(x)))
+ return false;
+
+ swap_length=x;
+ return true;
+}
+
+ValueNode::Handle
+ValueNode_TimedSwap::get_swap_length()const
+{
+ return swap_length;
+}
+
+
+
+synfig::ValueBase
+synfig::ValueNode_TimedSwap::operator()(Time t)const
+{
+ Time swptime=(*swap_time)(t).get(Time());
+ Time swplength=(*swap_length)(t).get(Time());
+
+ if(t>swptime)
+ return (*after)(t);
+
+ if(t<=swptime && t>swptime-swplength)
+ {
+ Real amount=(swptime-t)/swplength;
+ // if amount==0.0, then we are after
+ // if amount==1.0, then we are before
+
+ switch(get_type())
+ {
+ case ValueBase::TYPE_ANGLE:
+ {
+ Angle a=(*after)(t).get(Angle());
+ Angle b=(*before)(t).get(Angle());
+ return (b-a)*amount+a;
+ }
+ case ValueBase::TYPE_COLOR:
+ {
+ Color a=(*after)(t).get(Color());
+ Color b=(*before)(t).get(Color());
+ // note: Shouldn't this use a straight blend?
+ return (b-a)*amount+a;
+ }
+ case ValueBase::TYPE_INTEGER:
+ {
+ float a=(float)(*after)(t).get(int());
+ float b=(float)(*before)(t).get(int());
+ return static_cast<int>((b-a)*amount+a+0.5f);
+ }
+ case ValueBase::TYPE_REAL:
+ {
+ Real a=(*after)(t).get(Real());
+ Real b=(*before)(t).get(Real());
+ return (b-a)*amount+a;
+ }
+ case ValueBase::TYPE_TIME:
+ {
+ Time a=(*after)(t).get(Time());
+ Time b=(*before)(t).get(Time());
+ return (b-a)*amount+a;
+ }
+ case ValueBase::TYPE_VECTOR:
+ {
+ Vector a=(*after)(t).get(Vector());
+ Vector b=(*before)(t).get(Vector());
+ return (b-a)*amount+a;
+ }
+ default:
+ break;
+ }
+ }
+
+
+ /*! \todo this should interpolate from
+ ** before to after over the period defined
+ ** by swap_length */
+
+ return (*before)(t);
+}
+
+
+bool
+ValueNode_TimedSwap::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i>=0 && i<4);
+ switch(i)
+ {
+ case 0: return set_before(x);
+ case 1: return set_after(x);
+ case 2: return set_swap_time(x);
+ case 3: return set_swap_length(x);
+ }
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_TimedSwap::get_link_vfunc(int i)const
+{
+ assert(i>=0 && i<4);
+ switch(i)
+ {
+ case 0: return get_before();
+ case 1: return get_after();
+ case 2: return get_swap_time();
+ case 3: return get_swap_length();
+ }
+ return 0;
+}
+
+int
+ValueNode_TimedSwap::link_count()const
+{
+ return 4;
+}
+
+String
+ValueNode_TimedSwap::link_local_name(int i)const
+{
+ assert(i>=0 && i<4);
+ switch(i)
+ {
+ case 0: return _("Before");
+ case 1: return _("After");
+ case 2: return _("Swap Time");
+ case 3: return _("Swap Duration");
+ default:return String();
+ }
+}
+
+String
+ValueNode_TimedSwap::link_name(int i)const
+{
+ assert(i>=0 && i<4);
+ switch(i)
+ {
+ case 0: return "before";
+ case 1: return "after";
+ case 2: return "time";
+ case 3: return "length";
+ default:return String();
+ }
+}
+
+int
+ValueNode_TimedSwap::get_link_index_from_name(const String &name)const
+{
+ if(name=="before") return 0;
+ if(name=="after") return 1;
+ if(name=="time") return 2;
+ if(name=="length") return 3;
+
+ throw Exception::BadLinkName(name);
+}
+
+String
+ValueNode_TimedSwap::get_name()const
+{
+ return "timed_swap";
+}
+
+String
+ValueNode_TimedSwap::get_local_name()const
+{
+ return _("Timed Swap");
+}
+
+bool
+ValueNode_TimedSwap::check_type(ValueBase::Type type)
+{
+ return
+ type==ValueBase::TYPE_ANGLE ||
+ type==ValueBase::TYPE_COLOR ||
+ type==ValueBase::TYPE_INTEGER ||
+ type==ValueBase::TYPE_REAL ||
+ type==ValueBase::TYPE_TIME ||
+ type==ValueBase::TYPE_VECTOR;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_timedswap.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_TIMEDSWAP_H
+#define __SYNFIG_VALUENODE_TIMEDSWAP_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+struct ValueNode_TimedSwap : public LinkableValueNode
+{
+ typedef etl::handle<ValueNode_TimedSwap> Handle;
+ typedef etl::handle<const ValueNode_TimedSwap> ConstHandle;
+
+private:
+
+ ValueNode::RHandle before;
+ ValueNode::RHandle after;
+ ValueNode::RHandle swap_time;
+ ValueNode::RHandle swap_length;
+
+ ValueNode_TimedSwap(const ValueBase &value);
+
+public:
+
+// static Handle create(ValueBase::Type id);
+
+ virtual ~ValueNode_TimedSwap();
+
+ bool set_before(const ValueNode::Handle &a);
+ ValueNode::Handle get_before()const;
+ bool set_after(const ValueNode::Handle &a);
+ ValueNode::Handle get_after()const;
+
+ bool set_swap_time(const ValueNode::Handle &x);
+ ValueNode::Handle get_swap_time()const;
+
+ bool set_swap_length(const ValueNode::Handle &x);
+ ValueNode::Handle get_swap_length()const;
+
+
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+ virtual int link_count()const;
+ virtual String link_local_name(int i)const;
+ virtual String link_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+// static bool check_type(const ValueBase::Type &type);
+
+protected:
+
+ virtual LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_TimedSwap* create(const ValueBase &x);
+}; // END of class ValueNode_TimedSwap
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_twotone.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "general.h"
+#include "valuenode_twotone.h"
+#include "valuenode_const.h"
+#include <stdexcept>
+#include "color.h"
+#include "gradient.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+synfig::ValueNode_TwoTone::ValueNode_TwoTone():LinkableValueNode(synfig::ValueBase::TYPE_GRADIENT)
+{
+ set_link("color1",ValueNode_Const::create(Color::black()));
+ set_link("color2",ValueNode_Const::create(Color::white()));
+ DCAST_HACK_ENABLE();
+}
+
+LinkableValueNode*
+ValueNode_TwoTone::create_new()const
+{
+ return new ValueNode_TwoTone();
+}
+
+ValueNode_TwoTone*
+ValueNode_TwoTone::create(const ValueBase& x)
+{
+ ValueBase::Type id(x.get_type());
+ if(id!=ValueBase::TYPE_GRADIENT)
+ {
+ assert(0);
+ throw runtime_error("synfig::ValueNode_TwoTone:Bad type "+ValueBase::type_name(id));
+ }
+
+ ValueNode_TwoTone* value_node=new ValueNode_TwoTone();
+
+ assert(value_node->get_type()==id);
+
+ return value_node;
+}
+
+synfig::ValueNode_TwoTone::~ValueNode_TwoTone()
+{
+ unlink_all();
+}
+
+bool
+synfig::ValueNode_TwoTone::set_lhs(ValueNode::Handle a)
+{
+ if(a->get_type()!=ValueBase::TYPE_COLOR)
+ return false;
+
+ ref_a=a;
+
+ return true;
+}
+
+bool
+synfig::ValueNode_TwoTone::set_rhs(ValueNode::Handle b)
+{
+ if(b->get_type()!=ValueBase::TYPE_COLOR)
+ return false;
+ ref_b=b;
+ return true;
+}
+
+synfig::ValueBase
+synfig::ValueNode_TwoTone::operator()(Time t)const
+{
+ return Gradient((*ref_a)(t).get(Color()),(*ref_b)(t).get(Color()));
+}
+
+bool
+ValueNode_TwoTone::set_link_vfunc(int i,ValueNode::Handle x)
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0:
+ if(set_lhs(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ case 1:
+ if(set_rhs(x)) { signal_child_changed()(i);signal_value_changed()(); return true; }
+ else { return false; }
+ }
+
+ return false;
+}
+
+ValueNode::LooseHandle
+ValueNode_TwoTone::get_link_vfunc(int i)const
+{
+ assert(i>=0 && i<3);
+ switch(i)
+ {
+ case 0:
+ return ref_a;
+ case 1:
+ return ref_b;
+ }
+ return 0;
+}
+
+int
+ValueNode_TwoTone::link_count()const
+{
+ return 2;
+}
+
+String
+ValueNode_TwoTone::link_local_name(int i)const
+{
+ assert(i>=0 && i<2);
+ switch(i)
+ {
+ case 0:
+ return _("Color1");
+ case 1:
+ return _("Color2");
+ default:
+ return String();
+ }
+}
+
+String
+ValueNode_TwoTone::link_name(int i)const
+{
+ assert(i>=0 && i<2);
+ switch(i)
+ {
+ case 0:
+ return "color1";
+ case 1:
+ return "color2";
+ default:
+ return String();
+ }
+}
+
+int
+ValueNode_TwoTone::get_link_index_from_name(const String &name)const
+{
+ if(name=="color1")
+ return 0;
+ if(name=="color2")
+ return 1;
+ throw Exception::BadLinkName(name);
+}
+
+String
+ValueNode_TwoTone::get_name()const
+{
+ return "twotone";
+}
+
+String
+ValueNode_TwoTone::get_local_name()const
+{
+ return _("Two-Tone");
+}
+
+bool
+ValueNode_TwoTone::check_type(ValueBase::Type type)
+{
+ return type==ValueBase::TYPE_GRADIENT;
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file valuenode_twotone.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VALUENODE_TWOTONE_H
+#define __SYNFIG_VALUENODE_TWOTONE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "valuenode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+struct ValueNode_TwoTone : public LinkableValueNode
+{
+ typedef etl::handle<ValueNode_TwoTone> Handle;
+ typedef etl::handle<const ValueNode_TwoTone> ConstHandle;
+
+protected:
+
+ ValueNode_TwoTone();
+
+private:
+
+ ValueNode::RHandle ref_a;
+ ValueNode::RHandle ref_b;
+
+public:
+
+ virtual ~ValueNode_TwoTone();
+
+// static Handle create(ValueBase::Type id=ValueBase::TYPE_GRADIENT);
+
+ //! Sets the left-hand-side value_node
+ bool set_lhs(ValueNode::Handle a);
+
+ //! Gets the left-hand-side value_node
+ ValueNode::Handle get_lhs()const { return ref_a; }
+
+ //! Sets the right-hand-side value_node
+ bool set_rhs(ValueNode::Handle b);
+
+ //! Gets the right-hand-side value_node
+ ValueNode::Handle get_rhs()const { return ref_b; }
+
+
+ virtual bool set_link_vfunc(int i,ValueNode::Handle x);
+
+ virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
+
+ virtual int link_count()const;
+
+ virtual String link_local_name(int i)const;
+ virtual String link_name(int i)const;
+ virtual int get_link_index_from_name(const String &name)const;
+
+ virtual ValueBase operator()(Time t)const;
+
+ virtual String get_name()const;
+ virtual String get_local_name()const;
+
+// static bool check_type(const ValueBase::Type &type);
+
+ LinkableValueNode* create_new()const;
+
+public:
+ using synfig::LinkableValueNode::get_link_vfunc;
+
+ using synfig::LinkableValueNode::set_link_vfunc;
+ static bool check_type(ValueBase::Type type);
+ static ValueNode_TwoTone* create(const ValueBase &x=ValueBase::TYPE_GRADIENT);
+}; // END of class ValueNode_TwoTone
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file vector.h
+** \brief Various discreet type definitions
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VECTOR_H
+#define __SYNFIG_VECTOR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "angle.h"
+#include "real.h"
+#include <math.h>
+
+/* === M A C R O S ========================================================= */
+
+
+#ifdef WIN32
+#include <float.h>
+#ifndef isnan
+extern "C" { int _isnan(double x); }
+#define isnan _isnan
+#endif
+#endif
+
+// For some reason isnan() isn't working on macosx any more.
+// This is a quick fix.
+#if defined(__APPLE__) && !defined(SYNFIG_ISNAN_FIX)
+#ifdef isnan
+#undef isnan
+#endif
+inline bool isnan(double x) { return x != x; }
+inline bool isnan(float x) { return x != x; }
+#define SYNFIG_ISNAN_FIX 1
+#endif
+
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+/*! \class Vector
+** \todo writeme
+*/
+class Vector
+{
+public:
+ typedef Real value_type;
+
+private:
+ value_type _x, _y;
+
+public:
+ Vector(): _x(0.0), _y(0.0) { };
+ Vector(const value_type &x, const value_type &y):_x(x),_y(y) { };
+
+ bool is_valid()const { return !(isnan(_x) || isnan(_y)); }
+
+ value_type &
+ operator[](const int& i)
+ { return i?_y:_x; }
+
+ const value_type &
+ operator[](const int& i) const
+ { return i?_y:_x; }
+
+ const Vector &
+ operator+=(const Vector &rhs)
+ {
+ _x+=rhs._x;
+ _y+=rhs._y;
+ return *this;
+ }
+
+ const Vector &
+ operator-=(const Vector &rhs)
+ {
+ _x-=rhs._x;
+ _y-=rhs._y;
+ return *this;
+ }
+
+ const Vector &
+ operator*=(const value_type &rhs)
+ {
+ _x*=rhs;
+ _y*=rhs;
+ return *this;
+ }
+
+ const Vector &
+ operator/=(const value_type &rhs)
+ {
+ value_type tmp=1.0/rhs;
+ _x*=tmp;
+ _y*=tmp;
+ return *this;
+ }
+
+ Vector
+ operator+(const Vector &rhs)const
+ { return Vector(*this)+=rhs; }
+
+ Vector
+ operator-(const Vector &rhs)const
+ { return Vector(*this)-=rhs; }
+
+ Vector
+ operator*(const value_type &rhs)const
+ { return Vector(*this)*=rhs; }
+
+ Vector
+ operator/(const value_type &rhs)const
+ { return Vector(*this)/=rhs; }
+
+ Vector
+ operator-()const
+ { return Vector(-_x,-_y); }
+
+ value_type
+ operator*(const Vector &rhs)const
+ { return _x*rhs._x+_y*rhs._y; }
+
+ bool
+ operator==(const Vector &rhs)const
+ { return _x==rhs._x && _y==rhs._y; }
+
+ bool
+ operator!=(const Vector &rhs)const
+ { return _y!=rhs._y || _x!=rhs._x; }
+
+ //! Returns the squared magnitude of the vector
+ value_type mag_squared()const
+ { return _x*_x+_y*_y; }
+
+ //! Returns the magnitude of the vector
+ value_type mag()const
+ { return sqrt(mag_squared()); }
+
+ //! Returns the reciprocal of the magnitude of the vector
+ value_type inv_mag()const
+ { return 1.0/sqrt(mag_squared()); }
+
+ //! Returns a normalized version of the vector
+ Vector norm()const
+ { return (*this)*inv_mag(); }
+
+ //! Returns a perpendicular version of the vector
+ Vector perp()const
+ { return Vector(_y,-_x); }
+
+ Angle angle()const
+ { return Angle::rad(atan2(_y, _x)); }
+
+ bool is_equal_to(const Vector& rhs)const
+ {
+ static const value_type epsilon(0.0000000000001);
+// return (_x>rhs._x)?_x-rhs._x<=epsilon:rhs._x-_x<=epsilon && (_y>rhs._y)?_y-rhs._y<=epsilon:rhs._y-_y<=epsilon;
+ return (*this-rhs).mag_squared()<=epsilon;
+ }
+
+ static const Vector zero() { return Vector(0,0); }
+};
+
+/*! \typedef Point
+** \todo writeme
+*/
+typedef Vector Point;
+
+
+
+}; // END of namespace synfig
+
+namespace std {
+
+inline synfig::Vector::value_type
+abs(const synfig::Vector &rhs)
+ { return rhs.mag(); }
+
+}; // END of namespace std
+
+#include <ETL/bezier>
+
+_ETL_BEGIN_NAMESPACE
+
+template <>
+class bezier_base<synfig::Vector,float> : public std::unary_function<float,synfig::Vector>
+{
+public:
+ typedef synfig::Vector value_type;
+ typedef float time_type;
+private:
+
+ bezier_base<synfig::Vector::value_type,time_type> bezier_x,bezier_y;
+
+ value_type a,b,c,d;
+
+protected:
+ affine_combo<value_type,time_type> affine_func;
+
+public:
+ bezier_base() { }
+ bezier_base(
+ const value_type &a, const value_type &b, const value_type &c, const value_type &d,
+ const time_type &r=0.0, const time_type &s=1.0):
+ a(a),b(b),c(c),d(d) { set_rs(r,s); sync(); }
+
+ void sync()
+ {
+ bezier_x[0]=a[0],bezier_y[0]=a[1];
+ bezier_x[1]=b[0],bezier_y[1]=b[1];
+ bezier_x[2]=c[0],bezier_y[2]=c[1];
+ bezier_x[3]=d[0],bezier_y[3]=d[1];
+ bezier_x.sync();
+ bezier_y.sync();
+ }
+
+ value_type
+ operator()(time_type t)const
+ {
+ return synfig::Vector(bezier_x(t),bezier_y(t));
+ }
+
+ void evaluate(time_type t, value_type &f, value_type &df) const
+ {
+ t=(t-get_r())/get_dt();
+
+ const value_type p1 = affine_func(
+ affine_func(a,b,t),
+ affine_func(b,c,t)
+ ,t);
+ const value_type p2 = affine_func(
+ affine_func(b,c,t),
+ affine_func(c,d,t)
+ ,t);
+
+ f = affine_func(p1,p2,t);
+ df = (p2-p1)*3;
+ }
+
+ void set_rs(time_type new_r, time_type new_s) { bezier_x.set_rs(new_r,new_s); bezier_y.set_rs(new_r,new_s); }
+ void set_r(time_type new_r) { bezier_x.set_r(new_r); bezier_y.set_r(new_r); }
+ void set_s(time_type new_s) { bezier_x.set_s(new_s); bezier_y.set_s(new_s); }
+ const time_type &get_r()const { return bezier_x.get_r(); }
+ const time_type &get_s()const { return bezier_x.get_s(); }
+ time_type get_dt()const { return bezier_x.get_dt(); }
+
+ value_type &
+ operator[](int i)
+ { return (&a)[i]; }
+
+ const value_type &
+ operator[](int i) const
+ { return (&a)[i]; }
+
+ //! Bezier curve intersection function
+ time_type intersect(const bezier_base<value_type,time_type> &/*x*/, time_type /*near*/=0.0)const
+ {
+ return 0;
+ }
+};
+
+_ETL_END_NAMESPACE
+
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file version.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_VERSION_H
+#define __SYNFIG_VERSION_H
+
+/* === H E A D E R S ======================================================= */
+
+/* === M A C R O S ========================================================= */
+
+/*! \def SYNFIG_VERSION
+** \brief Synfig API Version
+**
+** The macro SYNFIG_VERSION can be set to ensure
+** compile-time compatibility with future versions
+** of Synfig. The first two digits are the major
+** version, the second two digits are the minor
+** version, and the last two digits are the
+** revision release.
+*/
+#ifndef SYNFIG_VERSION
+#define SYNFIG_VERSION (006000)
+#endif
+
+/*! Increment this value whenever
+** the library changes in a way
+** that breaks library compatibility
+*/
+#define SYNFIG_LIBRARY_VERSION 47
+
+/*! \writeme */
+#define SYNFIG_CHECK_VERSION() synfig::check_version_(SYNFIG_LIBRARY_VERSION,sizeof(synfig::Vector),sizeof(synfig::Color),sizeof(synfig::Canvas),sizeof(synfig::Layer))
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+//! Version checker \internal
+/*! Checks to make sure that the library
+** version matches with what the program
+** was compiled against.
+** \see SYNFIG_CHECK_VERSION()
+*/
+extern bool check_version_(int v,int vec_size, int color_size,int canvas_size,int layer_size);
+
+extern const char *get_version();
+
+extern const char *get_build_date();
+
+extern const char *get_build_time();
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file waypoint.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "waypoint.h"
+#include "valuenode_const.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Waypoint::Waypoint(ValueBase value, Time time):
+ priority_(0),
+ before(INTERPOLATION_TCB),
+ after(INTERPOLATION_TCB),
+ value_node(ValueNode_Const::create(value)),
+ time(time),
+ tension(0.0),
+ continuity(0.0),
+ bias(0),
+ time_tension(0.0f)
+{
+ if(value.get_type()==ValueBase::TYPE_ANGLE)
+ after=before=INTERPOLATION_LINEAR;
+}
+
+Waypoint::Waypoint(ValueNode::Handle value_node, Time time):
+ priority_(0),
+ before(INTERPOLATION_TCB),
+ after(INTERPOLATION_TCB),
+ value_node(value_node),
+ time(time),
+ tension(0.0),
+ continuity(0),
+ bias(0),
+ time_tension(0.0f)
+{
+ if(value_node->get_type()==ValueBase::TYPE_ANGLE)
+ after=before=INTERPOLATION_LINEAR;
+}
+
+Waypoint::Waypoint():
+ priority_(0),
+ before(INTERPOLATION_TCB),
+ after(INTERPOLATION_TCB),
+ tension(0),
+ continuity(0),
+ bias(0),
+ time_tension(0.0f)
+{
+}
+
+void
+Waypoint::set_value(const ValueBase &x)
+{
+ if(!value_node && x.get_type()==ValueBase::TYPE_ANGLE)
+ after=before=INTERPOLATION_LINEAR;
+
+ value_node=ValueNode_Const::create(x);
+}
+
+void
+Waypoint::set_value_node(const ValueNode::Handle &x)
+{
+ if(!value_node && x->get_type()==ValueBase::TYPE_ANGLE)
+ after=before=INTERPOLATION_LINEAR;
+
+ value_node=x;
+}
+
+bool
+Waypoint::is_static()const
+{
+ return static_cast<bool>(ValueNode_Const::Handle::cast_dynamic(value_node)) && value_node && !value_node->is_exported();
+}
+
+void
+Waypoint::set_time(const Time &x)
+{
+ time=x;
+}
+
+void
+Waypoint::apply_model(const Model &x)
+{
+ if(x.priority_flag) set_priority(x.get_priority());
+ if(x.before_flag) set_before(x.get_before());
+ if(x.after_flag) set_after(x.get_after());
+ if(x.tension_flag) set_tension(x.get_tension());
+ if(x.continuity_flag) set_continuity(x.get_continuity());
+ if(x.bias_flag) set_bias(x.get_bias());
+ if(x.temporal_tension_flag) set_temporal_tension(x.get_temporal_tension());
+}
+
+Waypoint
+Waypoint::clone(const GUID& deriv_guid)const
+{
+ Waypoint ret(*this);
+ ret.make_unique();
+ if(!ret.value_node->is_exported())
+ ret.value_node=value_node->clone(deriv_guid);
+ ret.parent_=0;
+ return ret;
+}
+
+ValueBase
+Waypoint::get_value()const { return (*value_node)(0); }
+
+ValueBase
+Waypoint::get_value(const Time &t)const { return (*value_node)(t); }
+
+synfig::GUID
+Waypoint::get_guid()const
+{
+ return GUID::hasher(get_uid());
+}
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file waypoint.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_WAYPOINT_H
+#define __SYNFIG_WAYPOINT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "time.h"
+#include "real.h"
+#include "value.h"
+//#include "valuenode.h"
+#include "uniqueid.h"
+#include <vector>
+#include "guid.h"
+#include "interpolation.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig {
+
+class ValueNode;
+class GUID;
+
+
+/*! \class Waypoint
+** \brief \writeme
+*/
+class Waypoint : public UniqueID
+{
+ /*
+ -- ** -- T Y P E S -----------------------------------------------------------
+ */
+
+public:
+
+ typedef synfig::Interpolation Interpolation;
+
+ class Model
+ {
+ friend class Waypoint;
+
+ int priority;
+ Interpolation before;
+ Interpolation after;
+ Real tension;
+ Real continuity;
+ Real bias;
+ Real temporal_tension;
+
+ bool priority_flag,before_flag,after_flag,tension_flag,continuity_flag,bias_flag,temporal_tension_flag;
+
+ public:
+ Model():
+ priority_flag(false),
+ before_flag(false),
+ after_flag(false),
+ tension_flag(false),
+ continuity_flag(false),
+ bias_flag(false),
+ temporal_tension_flag(false) { }
+
+ Interpolation get_before()const { return before; }
+ void set_before(Interpolation x) { before=x; before_flag=true;}
+
+ Interpolation get_after()const { return after; }
+ void set_after(Interpolation x) { after=x; after_flag=true;}
+
+ const Real &get_tension()const { return tension; }
+ void set_tension(const Real &x) { tension=x; tension_flag=true;}
+
+ const Real &get_continuity()const { return continuity; }
+ void set_continuity(const Real &x) { continuity=x; continuity_flag=true;}
+
+ const Real &get_bias()const { return bias; }
+ void set_bias(const Real &x) { bias=x; bias_flag=true;}
+
+ const Real &get_temporal_tension()const { return temporal_tension; }
+ void set_temporal_tension(const Real &x) { temporal_tension=x; temporal_tension_flag=true;}
+
+ int get_priority()const { return priority; }
+ void set_priority(int x) { priority=x; priority_flag=true;}
+
+ #define FLAG_MACRO(x) bool get_##x##_flag()const { return x##_flag; } void set_##x##_flag(bool y) { x##_flag=y; }
+ FLAG_MACRO(priority)
+ FLAG_MACRO(before)
+ FLAG_MACRO(after)
+ FLAG_MACRO(tension)
+ FLAG_MACRO(continuity)
+ FLAG_MACRO(bias)
+ FLAG_MACRO(temporal_tension)
+ #undef FLAG_MACRO
+
+ void reset()
+ {
+ priority_flag=false;
+ before_flag=false;
+ after_flag=false;
+ tension_flag=false;
+ continuity_flag=false;
+ bias_flag=false;
+ temporal_tension_flag=false;
+ }
+
+ bool is_trivial()const
+ {
+ return !(
+ priority_flag||
+ before_flag||
+ after_flag||
+ tension_flag||
+ continuity_flag||
+ bias_flag||
+ temporal_tension_flag
+ );
+ }
+ };
+
+ /*
+ -- ** -- D A T A -------------------------------------------------------------
+ */
+
+private:
+
+ int priority_;
+ etl::loose_handle<ValueNode> parent_;
+
+ Interpolation before, after;
+
+ etl::rhandle<ValueNode> value_node;
+
+ Time time;
+
+ // The following are for the INTERPOLATION_TCB type
+ Real tension;
+ Real continuity;
+ Real bias;
+
+ // The following are for the INTERPOLATION_MANUAL type
+ ValueBase cpoint_before,cpoint_after;
+
+
+ float time_tension;
+
+ /*
+ -- ** -- C O N S T R U C T O R S ---------------------------------------------
+ */
+
+public:
+
+ Waypoint(ValueBase value, Time time);
+ Waypoint(etl::handle<ValueNode> value_node, Time time);
+
+ Waypoint();
+
+ /*
+ -- ** -- M E M B E R F U N C T I O N S -------------------------------------
+ */
+
+public:
+
+ void apply_model(const Model &x);
+
+ Interpolation get_before()const { return before; }
+ void set_before(Interpolation x) { before=x; }
+
+ Interpolation get_after()const { return after; }
+ void set_after(Interpolation x) { after=x; }
+
+ ValueBase get_value()const;
+ ValueBase get_value(const Time &t)const;
+ void set_value(const ValueBase &x);
+
+ const etl::rhandle<ValueNode> &get_value_node()const { return value_node; }
+ void set_value_node(const etl::handle<ValueNode> &x);
+
+ const Real &get_tension()const { return tension; }
+ void set_tension(const Real &x) { tension=x; }
+
+ const Real &get_continuity()const { return continuity; }
+ void set_continuity(const Real &x) { continuity=x; }
+
+ const Real &get_bias()const { return bias; }
+ void set_bias(const Real &x) { bias=x; }
+
+ const Time &get_time()const { return time; }
+ void set_time(const Time &x);
+
+ int get_priority()const { return priority_; }
+ void set_priority(int x) { priority_=x; }
+
+ const etl::loose_handle<ValueNode> &get_parent_value_node()const { return parent_; }
+ void set_parent_value_node(const etl::loose_handle<ValueNode> &x) { parent_=x; }
+
+ bool is_static()const;
+
+ float get_time_tension()const { return time_tension; }
+ void set_time_tension(const float& x) { time_tension=x; }
+ float get_temporal_tension()const { return time_tension; }
+ void set_temporal_tension(const float& x) { time_tension=x; }
+
+ bool operator<(const Waypoint &rhs)const
+ { return time<rhs.time; }
+
+ bool operator<(const Time &rhs)const
+ { return time.is_less_than(rhs); }
+ bool operator>(const Time &rhs)const
+ { return time.is_more_than(rhs); }
+
+ bool operator==(const Time &rhs)const
+ { return time.is_equal(rhs); }
+ bool operator!=(const Time &rhs)const
+ { return !time.is_equal(rhs); }
+
+ bool operator==(const UniqueID &rhs)const
+ { return get_uid()==rhs.get_uid(); }
+ bool operator!=(const UniqueID &rhs)const
+ { return get_uid()!=rhs.get_uid(); }
+
+ Waypoint clone(const GUID& deriv_guid=GUID())const;
+
+ GUID get_guid()const;
+}; // END of class Waypoint
+
+typedef std::vector< Waypoint > WaypointList;
+
+}; // END of namespace synfig
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file synfig/src/template.cpp
+** \brief Template File
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/*
+** Insert headers here
+*/
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file synfig/src/template.h
+** \brief Template Header
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_TEMPLATE_H
+#define __SYNFIG_TEMPLATE_H
+
+/* === H E A D E R S ======================================================= */
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+/* === E N D =============================================================== */
+
+#endif
--- /dev/null
+# $Id$
+
+MAINTAINERCLEANFILES=Makefile.in
+EXTRA_DIST=tool.nsh
+
+INCLUDES=-I$(top_srcdir)/src
+
+bin_PROGRAMS = synfig
+
+synfig_SOURCES = main.cpp
+synfig_LDADD = -L../synfig -lsynfig @SYNFIG_LIBS@ @OPENEXR_HALF_LIBS@
+synfig_CXXFLAGS = -lsynfig @SYNFIG_CFLAGS@
+#synfig_LDFLAGS=-export-dynamic -dlopen self
+#-dlopen ../modules/example/libexample.la
+
--- /dev/null
+/* === S Y N F I G ========================================================= */
+/*! \file tool/main.cpp
+** \brief SYNFIG Tool
+**
+** $Id$
+**
+** \legal
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
+**
+** This package is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of
+** the License, or (at your option) any later version.
+**
+** This package is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+** \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+# include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <iostream>
+#include <ETL/stringf>
+#include <list>
+#include <ETL/clock>
+#include <algorithm>
+
+#include <synfig/loadcanvas.h>
+#include <synfig/savecanvas.h>
+#include <synfig/target_scanline.h>
+#include <synfig/module.h>
+#include <synfig/importer.h>
+#include <synfig/layer.h>
+#include <synfig/canvas.h>
+#include <synfig/target.h>
+#include <synfig/time.h>
+#include <synfig/string.h>
+#include <synfig/paramdesc.h>
+#include <synfig/main.h>
+#include <synfig/guid.h>
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+enum exit_code
+{
+ SYNFIGTOOL_OK =0,
+ SYNFIGTOOL_FILENOTFOUND =1,
+ SYNFIGTOOL_BORRED =2,
+ SYNFIGTOOL_HELP =3,
+ SYNFIGTOOL_UNKNOWNARGUMENT =4,
+ SYNFIGTOOL_UNKNOWNERROR =5,
+ SYNFIGTOOL_INVALIDTARGET =6,
+ SYNFIGTOOL_RENDERFAILURE =7,
+ SYNFIGTOOL_BLANK =8,
+ SYNFIGTOOL_BADVERSION =9,
+ SYNFIGTOOL_MISSINGARGUMENT =10
+};
+
+#ifndef VERSION
+#define VERSION "unknown"
+#define PACKAGE "synfig-tool"
+#endif
+
+#ifdef DEFAULT_QUALITY
+#undef DEFAULT_QUALITY
+#endif
+
+#define DEFAULT_QUALITY 2
+#define VERBOSE_OUT(x) if(verbosity>=(x))std::cerr
+
+/* === G L O B A L S ======================================================= */
+
+const char *progname;
+int verbosity=0;
+bool be_quiet=false;
+bool print_benchmarks=false;
+
+/* === M E T H O D S ======================================================= */
+
+class Progress : public synfig::ProgressCallback
+{
+ const char *program;
+
+public:
+
+ Progress(const char *name):program(name) { }
+
+ virtual bool
+ task(const String &task)
+ {
+ VERBOSE_OUT(1)<<program<<": "<<task<<std::endl;
+ return true;
+ }
+
+ virtual bool
+ error(const String &task)
+ {
+ std::cerr<<program<<": "<<_("error")<<": "<<task<<std::endl;
+ return true;
+ }
+
+ virtual bool
+ warning(const String &task)
+ {
+ std::cerr<<program<<": "<<_("warning")<<": "<<task<<std::endl;
+ return true;
+ }
+
+ virtual bool
+ amount_complete(int /*current*/, int /*total*/)
+ {
+ return true;
+ }
+};
+
+class RenderProgress : public synfig::ProgressCallback
+{
+ string taskname;
+
+ etl::clock clk;
+ int clk_scanline; // The scanline at which the clock was reset
+ etl::clock clk2;
+
+ float last_time;
+public:
+
+ RenderProgress():clk_scanline(0), last_time(0) { }
+
+ virtual bool
+ task(const String &thetask)
+ {
+ taskname=thetask;
+ return true;
+ }
+
+ virtual bool
+ error(const String &task)
+ {
+ std::cout<<_("error")<<": "<<task<<std::endl;
+ return true;
+ }
+
+ virtual bool
+ warning(const String &task)
+ {
+ std::cout<<_("warning")<<": "<<task<<std::endl;
+ return true;
+ }
+
+ virtual bool
+ amount_complete(int scanline, int h)
+ {
+ if(be_quiet)return true;
+ if(scanline!=h)
+ {
+ const float time(clk()*(float)(h-scanline)/(float)(scanline-clk_scanline));
+ const float delta(time-last_time);
+
+ int weeks=0,days=0,hours=0,minutes=0,seconds=0;
+
+ last_time=time;
+
+ if(clk2()<0.2)
+ return true;
+ clk2.reset();
+
+ if(scanline)
+ seconds=(int)time+1;
+ else
+ {
+ //cerr<<"reset"<<endl;
+ clk.reset();
+ clk_scanline=scanline;
+ }
+
+ if(seconds<0)
+ {
+ clk.reset();
+ clk_scanline=scanline;
+ seconds=0;
+ }
+ while(seconds>=60)
+ minutes++,seconds-=60;
+ while(minutes>=60)
+ hours++,minutes-=60;
+ while(hours>=24)
+ days++,hours-=24;
+ while(days>=7)
+ weeks++,days-=7;
+
+ cerr<<taskname<<": "<<_("Line")<<" "<<scanline<<_(" of ")<<h<<" -- ";
+ //cerr<<time/(h-clk_scanline)<<" ";
+ /*
+ if(delta>=-time/(h-clk_scanline) )
+ cerr<<">";
+ */
+ if(delta>=0 && clk()>4.0 && scanline>clk_scanline+200)
+ {
+ //cerr<<"reset"<<endl;
+ clk.reset();
+ clk_scanline=scanline;
+ }
+
+ if(weeks)
+ cerr<<weeks<<"w ";
+ if(days)
+ cerr<<days<<"d ";
+ if(hours)
+ cerr<<hours<<"h ";
+ if(minutes)
+ cerr<<minutes<<"m ";
+ if(seconds)
+ cerr<<seconds<<"s ";
+
+ cerr<<" \r";
+ }
+ else
+ cerr<<taskname<<": "<<_("DONE")<<" "<<endl;;
+ return true;
+ }
+};
+
+struct Job
+{
+ String filename;
+ String outfilename;
+
+ RendDesc desc;
+
+ Canvas::Handle root;
+ Canvas::Handle canvas;
+ Target::Handle target;
+
+ int quality;
+ bool sifout;
+};
+
+typedef list<String> arg_list_t;
+typedef list<Job> job_list_t;
+
+void guid_test()
+{
+ cout<<"GUID Test"<<endl;
+ for(int i=20;i;i--)
+ {
+ cout<<synfig::GUID().get_string()<<' '<<synfig::GUID().get_string()<<endl;
+ }
+}
+
+void signal_test_func()
+{
+ cout<<"**SIGNAL CALLED**"<<endl;
+}
+
+void signal_test()
+{
+ sigc::signal<void> sig;
+ sigc::connection conn;
+ cout<<"Signal Test"<<endl;
+ conn=sig.connect(sigc::ptr_fun(signal_test_func));
+ cout<<"Next line should exclaim signal called."<<endl;
+ sig();
+ conn.disconnect();
+ cout<<"Next line should NOT exclaim signal called."<<endl;
+ sig();
+ cout<<"done."<<endl;
+}
+
+/* === P R O C E D U R E S ================================================= */
+
+void display_help(int amount)
+{
+ class Argument
+ {
+ public:
+ Argument(const char *flag,const char *arg, string description)
+ {
+ const char spaces[]=" ";
+ if(arg)
+ cerr<<strprintf(" %s %s %s",flag, arg, spaces+strlen(arg)+strlen(flag)+1)+description<<endl;
+ else
+ cerr<<strprintf(" %s %s",flag,spaces+strlen(flag))+description<<endl;
+
+ }
+ };
+ cerr<<_("syntax: ")<<progname<<" [DEFAULT OPTIONS] ([SIF FILE] [SPECIFIC OPTIONS])..."<<endl;
+ cerr<<endl;
+ if(amount>=1)
+ {
+ Argument("-t","<output type>",_("Specify output target (Default:unknown)"));
+ Argument("-w","<pixel width>",_("Set the image width (Use zero for file default)"));
+ Argument("-h","<pixel height>",_("Set the image height (Use zero for file default)"));
+ Argument("-s","<image dist>",_("Set the diagonal size of image window (Span)"));
+ Argument("-a","<1...30>",_("Set antialias amount for parametric renderer."));
+ Argument("-Q","<0...10>",strprintf(_("Specify image quality for accelerated renderer (default=%d)"),DEFAULT_QUALITY).c_str());
+ Argument("-g","<amount>",_("Gamma (default=2.2)"));
+ Argument("-v",NULL,_("Verbose Output (add more for more verbosity)"));
+ Argument("-q",NULL,_("Quiet mode (No progress/time-remaining display)"));
+ Argument("-c","<canvas id>",_("Render the canvas with the given id instead of the root."));
+ Argument("-o","<output file>",_("Specify output filename"));
+ Argument("-T","<# of threads>",_("Enable multithreaded renderer using specified # of threads"));
+
+ Argument("-b",NULL,_("Print Benchmarks"));
+
+ Argument("--fps","<framerate>",_("Set the frame rate"));
+ Argument("--time","<time>",_("Render a single frame at <seconds>"));
+ Argument("--begin-time","<time>",_("Set the starting time"));
+ Argument("--end-time","<time>",_("Set the ending time"));
+ Argument("--dpi","<res>",_("Set the dots-per-inch"));
+ Argument("--append","<filename>",_("Append layers in <filename> to composition"));
+
+ Argument("--layer-info","<layer>",_("Print out layer's description, parameter info, etc."));
+ Argument("--layers",NULL,_("Print out the list of available layers"));
+ Argument("--targets",NULL,_("Print out the list of available targets"));
+ Argument("--importers",NULL,_("Print out the list of available importers"));
+ Argument("--valuenodes",NULL,_("Print out the list of available ValueNodes"));
+ Argument("--modules",NULL,_("Print out the list of loaded modules"));
+ Argument("--version",NULL,_("Print out version information"));
+ Argument("--info",NULL,_("Print out misc build information"));
+ Argument("--license",NULL,_("Print out license information"));
+
+#ifdef _DEBUG
+ Argument("--guid-test",NULL,_("Test GUID generation"));
+ Argument("--signal-test",NULL,_("Test signal implementation"));
+#endif
+ }
+ else
+
+ Argument("--help",NULL,_("Print out usage and syntax info"));
+ cerr<<endl;
+}
+
+int process_global_flags(arg_list_t &arg_list)
+{
+ arg_list_t::iterator iter, next;
+
+ for(next=arg_list.begin(),iter=next++;iter!=arg_list.end();iter=next++)
+ {
+ if(*iter == "--")
+ return SYNFIGTOOL_OK;
+
+ if(*iter == "--signal-test")
+ {
+ signal_test();
+ return SYNFIGTOOL_HELP;
+ }
+
+ if(*iter == "--guid-test")
+ {
+ guid_test();
+ return SYNFIGTOOL_HELP;
+ }
+
+
+ if(*iter == "--help")
+ {
+ display_help(1);
+
+ return SYNFIGTOOL_HELP;
+ }
+
+ if(*iter == "--info")
+ {
+ cout<<PACKAGE"-"VERSION<<endl;
+ cout<<"Compiled on "__DATE__ " at "__TIME__;
+#ifdef __GNUC__
+ cout<<" with GCC "<<__VERSION__;
+#endif
+#ifdef _MSC_VER
+ cout<<" with Microsoft Visual C++ "<<(_MSC_VER>>8)<<'.'<<(_MSC_VER&255);
+#endif
+#ifdef __TCPLUSPLUS__
+ cout<<" with Borland Turbo C++ "<<(__TCPLUSPLUS__>>8)<<'.'<<((__TCPLUSPLUS__&255)>>4)<<'.'<<(__TCPLUSPLUS__&15);
+#endif
+
+ cout<<endl<<SYNFIG_COPYRIGHT<<endl;
+ cout<<endl;
+ return SYNFIGTOOL_HELP;
+ }
+
+ if(*iter == "--layers")
+ {
+ Progress p(PACKAGE);
+ synfig::Main synfig_main(dirname(progname),&p);
+ synfig::Layer::Book::iterator iter=synfig::Layer::book().begin();
+ for(;iter!=synfig::Layer::book().end();iter++)
+ cout<<iter->first<<endl;
+
+ return SYNFIGTOOL_HELP;
+ }
+
+ if(*iter == "--layer-info")
+ {
+ Progress p(PACKAGE);
+ synfig::Main synfig_main(dirname(progname),&p);
+ iter=next++;
+ Layer::Handle layer=synfig::Layer::create(*iter);
+ cout<<"Layer Name: "<<layer->get_name()<<endl;
+ cout<<"Localized Layer Name: "<<layer->get_local_name()<<endl;
+ cout<<"Version: "<<layer->get_version()<<endl;
+ Layer::Vocab vocab=layer->get_param_vocab();
+ for(;!vocab.empty();vocab.pop_front())
+ {
+ cout<<"param - "<<vocab.front().get_name();
+ if(!vocab.front().get_critical())
+ cout<<" (not critical)";
+ cout<<endl<<"\tLocalized Name: "<<vocab.front().get_local_name()<<endl;
+ if(!vocab.front().get_description().empty())
+ cout<<"\tDescription: "<<vocab.front().get_description()<<endl;
+ if(!vocab.front().get_hint().empty())
+ cout<<"\tHint: "<<vocab.front().get_hint()<<endl;
+ }
+
+ return SYNFIGTOOL_HELP;
+ }
+
+ if(*iter == "--modules")
+ {
+ Progress p(PACKAGE);
+ synfig::Main synfig_main(dirname(progname),&p);
+ synfig::Module::Book::iterator iter=synfig::Module::book().begin();
+ for(;iter!=synfig::Module::book().end();iter++)
+ cout<<iter->first<<endl;
+ return SYNFIGTOOL_HELP;
+ }
+
+ if(*iter == "--targets")
+ {
+ Progress p(PACKAGE);
+ synfig::Main synfig_main(dirname(progname),&p);
+ synfig::Target::Book::iterator iter=synfig::Target::book().begin();
+ for(;iter!=synfig::Target::book().end();iter++)
+ cout<<iter->first<<endl;
+
+ return SYNFIGTOOL_HELP;
+ }
+
+ if(*iter == "--valuenodes")
+ {
+ Progress p(PACKAGE);
+ synfig::Main synfig_main(dirname(progname),&p);
+ synfig::LinkableValueNode::Book::iterator iter=synfig::LinkableValueNode::book().begin();
+ for(;iter!=synfig::LinkableValueNode::book().end();iter++)
+ cout<<iter->first<<endl;
+
+ return SYNFIGTOOL_HELP;
+ }
+
+ if(*iter == "--importers")
+ {
+ Progress p(PACKAGE);
+ synfig::Main synfig_main(dirname(progname),&p);
+ synfig::Importer::Book::iterator iter=synfig::Importer::book().begin();
+ for(;iter!=synfig::Importer::book().end();iter++)
+ cout<<iter->first<<endl;
+
+ return SYNFIGTOOL_HELP;
+ }
+
+ if(*iter == "--version")
+ {
+ cerr<<PACKAGE<<" "<<VERSION<<endl;
+
+ arg_list.erase(iter);
+
+ return SYNFIGTOOL_HELP;
+ }
+
+ if(*iter == "--license")
+ {
+ cerr<<PACKAGE<<" "<<VERSION<<endl;
+ cout<<SYNFIG_COPYRIGHT<<endl<<endl;
+ cerr<<"\
+** This package is free software; you can redistribute it and/or\n\
+** modify it under the terms of the GNU General Public License as\n\
+** published by the Free Software Foundation; either version 2 of\n\
+** the License, or (at your option) any later version.\n\
+**\n\
+** " << endl << endl;
+ arg_list.erase(iter);
+
+ return SYNFIGTOOL_HELP;
+ }
+
+ if(*iter == "-v")
+ {
+ verbosity++;
+
+ arg_list.erase(iter);
+
+ continue;
+ }
+
+ if(*iter == "-q")
+ {
+ be_quiet=true;
+
+ arg_list.erase(iter);
+
+ continue;
+ }
+ if(*iter == "-b")
+ {
+ print_benchmarks=true;
+
+ arg_list.erase(iter);
+
+ continue;
+ }
+ }
+
+ return SYNFIGTOOL_OK;
+}
+
+int extract_arg_cluster(arg_list_t &arg_list,arg_list_t &cluster)
+{
+ arg_list_t::iterator iter, next;
+
+ for(next=arg_list.begin(),iter=next++;iter!=arg_list.end();iter=next++)
+ {
+ if(*iter->begin() != '-')
+ {
+ //cerr<<*iter->begin()<<"-----------"<<endl;
+ return SYNFIGTOOL_OK;
+ }
+
+ if(
+ *iter=="-t" ||
+ *iter=="-w" ||
+ *iter=="-h" ||
+ *iter=="-a" ||
+ *iter=="-g" ||
+ *iter=="-o" ||
+ *iter=="-s" ||
+ *iter=="-Q" ||
+ *iter=="-c" ||
+ *iter=="--fps" ||
+ *iter=="--start-time" ||
+ *iter=="--begin-time" ||
+ *iter=="--end-time" ||
+ *iter=="--start-frame" ||
+ *iter=="--end-frame" ||
+ *iter=="--time" ||
+ *iter=="--frame" ||
+ *iter=="--dpi" ||
+ *iter=="--dpi-x" ||
+ *iter=="--dpi-y" ||
+ *iter=="--append" ||
+ *iter=="-T" )
+ {
+ cluster.push_back(*iter);
+ arg_list.erase(iter);
+ iter=next++;
+ if (iter==arg_list.end()) {
+ error("The `%s' flag requires a value. Use --help for a list of options.", cluster.back().c_str());
+ return SYNFIGTOOL_MISSINGARGUMENT;
+ }
+ }
+
+ cluster.push_back(*iter);
+ arg_list.erase(iter);
+ }
+
+ return SYNFIGTOOL_OK;
+}
+
+int extract_RendDesc(arg_list_t &arg_list,RendDesc &desc)
+{
+ arg_list_t::iterator iter, next;
+ int w=0,h=0;
+ float span=0;
+ for(next=arg_list.begin(),iter=next++;iter!=arg_list.end();iter=next++)
+ {
+ if(*iter=="-w")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ w=atoi(iter->c_str());
+ arg_list.erase(iter);
+ }
+ else if(*iter=="-h")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ h=atoi(iter->c_str());
+ arg_list.erase(iter);
+ }
+ else if(*iter=="-a")
+ {
+ int a;
+ arg_list.erase(iter);
+ iter=next++;
+ a=atoi(iter->c_str());
+ desc.set_antialias(a);
+ VERBOSE_OUT(1)<<strprintf(_("Antialiasing set to %d, (%d samples per pixel)"),a,a*a)<<endl;
+ arg_list.erase(iter);
+ }
+ else if(*iter=="-s")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ span=atof(iter->c_str());
+ VERBOSE_OUT(1)<<strprintf(_("Span set to %d units"),span)<<endl;
+ arg_list.erase(iter);
+ }
+ else if(*iter=="--fps")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ float fps=atof(iter->c_str());
+ desc.set_frame_rate(fps);
+ arg_list.erase(iter);
+ VERBOSE_OUT(1)<<strprintf(_("Frame rate set to %d frames per second"),fps)<<endl;
+ }
+ else if(*iter=="--dpi")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ float dpi=atof(iter->c_str());
+ float dots_per_meter=dpi*39.3700787402;
+ desc.set_x_res(dots_per_meter).set_y_res(dots_per_meter);
+ arg_list.erase(iter);
+ VERBOSE_OUT(1)<<strprintf(_("Physical resolution set to %f dpi"),dpi)<<endl;
+ }
+ else if(*iter=="--dpi-x")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ float dpi=atof(iter->c_str());
+ float dots_per_meter=dpi*39.3700787402;
+ desc.set_x_res(dots_per_meter);
+ arg_list.erase(iter);
+ VERBOSE_OUT(1)<<strprintf(_("Physical X resolution set to %f dpi"),dpi)<<endl;
+ }
+ else if(*iter=="--dpi-y")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ float dpi=atof(iter->c_str());
+ float dots_per_meter=dpi*39.3700787402;
+ desc.set_y_res(dots_per_meter);
+ arg_list.erase(iter);
+ VERBOSE_OUT(1)<<strprintf(_("Physical Y resolution set to %f dpi"),dpi)<<endl;
+ }
+ else if(*iter=="--start-time" || *iter=="--begin-time")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ desc.set_time_start(Time(*iter,desc.get_frame_rate()));
+ arg_list.erase(iter);
+ }
+ else if(*iter=="--end-time")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ desc.set_time_end(Time(*iter,desc.get_frame_rate()));
+ arg_list.erase(iter);
+ }
+ else if(*iter=="--time")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ desc.set_time(Time(*iter,desc.get_frame_rate()));
+ VERBOSE_OUT(1)<<_("Rendering frame at ")<<desc.get_time_start().get_string(desc.get_frame_rate())<<endl;
+ arg_list.erase(iter);
+ }
+ else if(*iter=="-g")
+ {
+ synfig::warning("Gamma argument is currently ignored");
+ arg_list.erase(iter);
+ iter=next++;
+ //desc.set_gamma(Gamma(atof(iter->c_str())));
+ arg_list.erase(iter);
+ }
+ }
+ if(w&&h)
+ {
+ desc.set_wh(w,h);
+ VERBOSE_OUT(1)<<strprintf(_("Resolution set to %dx%d"),w,h)<<endl;
+ }
+ else
+ {
+ if(w)
+ {
+ VERBOSE_OUT(1)<<strprintf(_("Width set to %d pixels"),w)<<endl;
+ desc.set_w(w);
+ }
+ if(h)
+ {
+ VERBOSE_OUT(1)<<strprintf(_("Height set to %d pixels"),h)<<endl;
+ desc.set_h(h);
+ }
+ }
+ if(span)
+ desc.set_span(span);
+ return SYNFIGTOOL_OK;
+}
+
+int extract_quality(arg_list_t &arg_list,int &quality)
+{
+ arg_list_t::iterator iter, next;
+ for(next=arg_list.begin(),iter=next++;iter!=arg_list.end();iter=next++)
+ {
+ if(*iter=="-Q")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ quality=atoi(iter->c_str());
+ VERBOSE_OUT(1)<<strprintf(_("Quality set to %d"),quality)<<endl;
+ arg_list.erase(iter);
+ }
+ }
+
+ return SYNFIGTOOL_OK;
+}
+
+int extract_threads(arg_list_t &arg_list,int &threads)
+{
+ arg_list_t::iterator iter, next;
+ for(next=arg_list.begin(),iter=next++;iter!=arg_list.end();iter=next++)
+ {
+ if(*iter=="-T")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ threads=atoi(iter->c_str());
+ VERBOSE_OUT(1)<<strprintf(_("Threads set to %d"),threads)<<endl;
+ arg_list.erase(iter);
+ }
+ }
+
+ return SYNFIGTOOL_OK;
+}
+
+int extract_target(arg_list_t &arg_list,string &type)
+{
+ arg_list_t::iterator iter, next;
+ type.clear();
+
+ for(next=arg_list.begin(),iter=next++;iter!=arg_list.end();iter=next++)
+ {
+ if(*iter=="-t")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ type=*iter;
+ arg_list.erase(iter);
+ }
+ }
+
+ return SYNFIGTOOL_OK;
+}
+
+int extract_append(arg_list_t &arg_list,string &filename)
+{
+ arg_list_t::iterator iter, next;
+ filename.clear();
+
+ for(next=arg_list.begin(),iter=next++;iter!=arg_list.end();iter=next++)
+ {
+ if(*iter=="--append")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ filename=*iter;
+ arg_list.erase(iter);
+ }
+ }
+
+ return SYNFIGTOOL_OK;
+}
+
+int extract_outfile(arg_list_t &arg_list,string &outfile)
+{
+ arg_list_t::iterator iter, next;
+ int ret=SYNFIGTOOL_FILENOTFOUND;
+ outfile.clear();
+
+ for(next=arg_list.begin(),iter=next++;iter!=arg_list.end();iter=next++)
+ {
+ if(*iter=="-o")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ outfile=*iter;
+ arg_list.erase(iter);
+ ret=SYNFIGTOOL_OK;
+ }
+ }
+
+ return ret;
+}
+
+int extract_canvasid(arg_list_t &arg_list,string &canvasid)
+{
+ arg_list_t::iterator iter, next;
+ //canvasid.clear();
+
+ for(next=arg_list.begin(),iter=next++;iter!=arg_list.end();iter=next++)
+ {
+ if(*iter=="-c")
+ {
+ arg_list.erase(iter);
+ iter=next++;
+ canvasid=*iter;
+ arg_list.erase(iter);
+ }
+ }
+
+ return SYNFIGTOOL_OK;
+}
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+int main(int argc, char *argv[])
+{
+ int i;
+ arg_list_t arg_list;
+ job_list_t job_list;
+
+ progname=argv[0];
+ Progress p(argv[0]);
+
+ if(!SYNFIG_CHECK_VERSION())
+ {
+ cerr<<_("FATAL: Synfig Version Mismatch")<<endl;
+ return SYNFIGTOOL_BADVERSION;
+ }
+ if(argc==1)
+ {
+ display_help(0);
+ return SYNFIGTOOL_BLANK;
+ }
+
+ for(i=1;i<argc;i++)
+ arg_list.push_back(argv[i]);
+
+ if((i=process_global_flags(arg_list)))
+ return i;
+
+ VERBOSE_OUT(1)<<_("verbosity set to ")<<verbosity<<endl;
+ synfig::Main synfig_main(dirname(progname),&p);
+
+ {
+ arg_list_t defaults, imageargs;
+ int ret;
+
+ // Grab the defaults before the first file
+ if ((ret = extract_arg_cluster(arg_list,defaults)) != SYNFIGTOOL_OK)
+ return ret;
+
+ while(arg_list.size())
+ {
+ string target_name;
+ job_list.push_front(Job());
+ int threads=0;
+
+ imageargs=defaults;
+ job_list.front().filename=arg_list.front();
+ arg_list.pop_front();
+
+ if ((ret = extract_arg_cluster(arg_list,imageargs)) != SYNFIGTOOL_OK)
+ return ret;
+
+ // Open the composition
+ {
+ job_list.front().root=open_canvas(job_list.front().filename);
+ }
+ if(!job_list.front().root)
+ {
+ cerr<<_("Unable to open ")<<job_list.front().filename<<"."<<endl;
+ cerr<<_("Throwing out job...")<<endl;
+ job_list.pop_front();
+ continue;
+ }
+
+ job_list.front().root->set_time(0);
+
+ string canvasid;
+ extract_canvasid(imageargs,canvasid);
+ if(!canvasid.empty())
+ {
+ try
+ {
+ job_list.front().canvas=job_list.front().root->find_canvas(canvasid);
+ }
+ catch(Exception::IDNotFound)
+ {
+ cerr<<_("Unable to find canvas with ID \"")<<canvasid<<_("\" in ")<<job_list.front().filename<<"."<<endl;
+ cerr<<_("Throwing out job...")<<endl;
+ job_list.pop_front();
+ continue;
+
+ }
+ catch(Exception::BadLinkName)
+ {
+ cerr<<_("Invalid canvas name \"")<<canvasid<<_("\" in ")<<job_list.front().filename<<"."<<endl;
+ cerr<<_("Throwing out job...")<<endl;
+ job_list.pop_front();
+ continue;
+
+ }
+ }
+ else
+ job_list.front().canvas=job_list.front().root;
+
+ extract_RendDesc(imageargs,job_list.front().canvas->rend_desc());
+ extract_target(imageargs,target_name);
+ extract_threads(imageargs,threads);
+ job_list.front().quality=DEFAULT_QUALITY;
+ extract_quality(imageargs,job_list.front().quality);
+ VERBOSE_OUT(2)<<_("Quality set to ")<<job_list.front().quality<<endl;
+ job_list.front().desc=job_list.front().canvas->rend_desc();
+ extract_outfile(imageargs,job_list.front().outfilename);
+
+ // Extract composite
+ do{
+ string composite_file;
+ extract_append(imageargs,composite_file);
+ if(!composite_file.empty())
+ {
+ Canvas::Handle composite(open_canvas(composite_file));
+ if(!composite)
+ break;
+ Canvas::reverse_iterator iter;
+ for(iter=composite->rbegin();iter!=composite->rend();++iter)
+ {
+ Layer::Handle layer(*iter);
+ if(layer->active())
+ job_list.front().canvas->push_front(layer->clone());
+ }
+ VERBOSE_OUT(2)<<_("Appended contents of ")<<composite_file<<endl;
+ }
+ }while(false);
+
+ VERBOSE_OUT(4)<<_("Attempting to determine target/outfile...")<<endl;
+
+ // If the target type is not yet defined,
+ // try to figure it out from the outfile.
+ if(target_name.empty() && !job_list.front().outfilename.empty())
+ {
+ VERBOSE_OUT(3)<<_("Target name undefined, attempting to figure it out")<<endl;
+ string ext=job_list.front().outfilename.substr(job_list.front().outfilename.rfind('.')+1);
+ if(Target::ext_book().count(ext))
+ target_name=Target::ext_book()[ext];
+ else
+ target_name=ext;
+ }
+
+ // If the target type is STILL not yet defined, then
+ // set it to a some sort of default
+ if(target_name.empty())
+ {
+ VERBOSE_OUT(2)<<_("Defaulting to PNG target...")<<endl;
+ target_name="png";
+ }
+
+ // If no output filename was provided, then
+ // create a output filename based on the
+ // given input filename. (ie: change the extension)
+ if(job_list.front().outfilename.empty())
+ {
+ job_list.front().outfilename=job_list.front().filename;
+ job_list.front().outfilename.erase(find(job_list.front().outfilename.begin(),job_list.front().outfilename.end(),'.'),job_list.front().outfilename.end());
+ job_list.front().outfilename+='.';
+ if(Target::book().count(target_name))
+ job_list.front().outfilename+=Target::book()[target_name].second;
+ else
+ job_list.front().outfilename+=target_name;
+ }
+
+ VERBOSE_OUT(4)<<"target_name="<<target_name<<endl;
+ VERBOSE_OUT(4)<<"outfile_name="<<job_list.front().outfilename<<endl;
+
+ VERBOSE_OUT(4)<<_("Creating the target...")<<endl;
+ job_list.front().target=synfig::Target::create(target_name,job_list.front().outfilename);
+
+ if(target_name=="sif")
+ {
+ job_list.front().sifout=true;
+ }
+ else
+ {
+ if(!job_list.front().target)
+ {
+ cerr<<_("Unknown target for ")<<job_list.front().filename<<": "<<target_name<<endl;
+ cerr<<_("Throwing out job...")<<endl;
+ job_list.pop_front();
+ continue;
+ }
+ job_list.front().sifout=false;
+ }
+
+ // Set the Canvas on the Target
+ if(job_list.front().target)
+ {
+ VERBOSE_OUT(4)<<_("Setting the canvas on the target...")<<endl;
+ job_list.front().target->set_canvas(job_list.front().canvas);
+ VERBOSE_OUT(4)<<_("Setting the quality of the target...")<<endl;
+ job_list.front().target->set_quality(job_list.front().quality);
+ }
+
+ // Set the threads for the target
+ if(job_list.front().target && Target_Scanline::Handle::cast_dynamic(job_list.front().target))
+ {
+ Target_Scanline::Handle::cast_dynamic(job_list.front().target)->set_threads(threads);
+ }
+
+ if(imageargs.size())
+ {
+ cerr<<_("Unidentified arguments for ")<<job_list.front().filename<<": ";
+ for(;imageargs.size();imageargs.pop_front())
+ cerr<<' '<<imageargs.front();
+ cerr<<endl;
+ cerr<<_("Throwing out job...")<<endl;
+ job_list.pop_front();
+ continue;
+ }
+ //string bleh;
+ //getline(cin,bleh);
+ }
+ }
+
+ if(arg_list.size())
+ {
+ cerr<<_("Unidentified arguments:");
+ for(;arg_list.size();arg_list.pop_front())
+ cerr<<' '<<arg_list.front();
+ cerr<<endl;
+ return SYNFIGTOOL_UNKNOWNARGUMENT;
+ }
+
+ if(!job_list.size())
+ {
+ cerr<<_("Nothing to do!")<<endl;
+ return SYNFIGTOOL_BORRED;
+ }
+
+ for(;job_list.size();job_list.pop_front())
+ {
+ VERBOSE_OUT(3)<<job_list.front().filename<<" -- "<<endl<<'\t'<<
+ strprintf("w:%d, h:%d, a:%d, pxaspect:%f, imaspect:%f, span:%f",
+ job_list.front().desc.get_w(),
+ job_list.front().desc.get_h(),
+ job_list.front().desc.get_antialias(),
+ job_list.front().desc.get_pixel_aspect(),
+ job_list.front().desc.get_image_aspect(),
+ job_list.front().desc.get_span()
+ )<<endl<<'\t'<<
+ strprintf("tl:[%f,%f], br:[%f,%f], focus:[%f,%f]",
+ job_list.front().desc.get_tl()[0],job_list.front().desc.get_tl()[1],
+ job_list.front().desc.get_br()[0],job_list.front().desc.get_br()[1],
+ job_list.front().desc.get_focus()[0],job_list.front().desc.get_focus()[1]
+ )<<endl;
+
+ RenderProgress p;
+ p.task(job_list.front().filename+" ==> "+job_list.front().outfilename);
+ if(!job_list.front().sifout)
+ {
+ VERBOSE_OUT(1)<<_("Rendering...")<<endl;
+ etl::clock timer;
+ timer.reset();
+ // Call the render member of the target
+ if(!job_list.front().target->render(&p))
+ {
+ cerr<<"Render Failure."<<endl;
+ return SYNFIGTOOL_RENDERFAILURE;
+ }
+ if(print_benchmarks)
+ {
+ cout<<job_list.front().filename+": Rendered in "<<timer()<<" seconds."<<endl;
+ }
+ }
+ else
+ {
+ if(!save_canvas(job_list.front().outfilename,job_list.front().canvas))
+ {
+ cerr<<"Render Failure."<<endl;
+ return SYNFIGTOOL_RENDERFAILURE;
+ }
+ }
+ }
+
+ job_list.clear();
+
+ VERBOSE_OUT(1)<<_("Done.")<<endl;
+
+ return SYNFIGTOOL_OK;
+}
--- /dev/null
+; The stuff to install
+Section "Synfig Tool"
+
+; SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath "$INSTDIR\bin"
+
+ ; Put file there
+ File "src\tool\.libs\synfig.exe"
+
+SectionEnd
+
+Section "un.Synfig Tool Uninstall"
+ Delete "$INSTDIR\bin\synfig.exe"
+ RMDir "$INSTDIR\bin"
+ RMDir "$INSTDIR"
+SectionEnd
+
+
--- /dev/null
+#!/bin/sh
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+
+bindir=@bindir@
+libexecdir=@libexecdir@
+datadir=@datadir@
+sysconfdir=@sysconfdir@
+sharedstatedir=@sharedstatedir@
+localstatedir=@localstatedir@
+libdir=@libdir@
+infodir=@infodir@
+mandir=@mandir@
+includedir=@includedir@
+
+LIBS="@SYNFIG_LIBS@"
+
+VERSION=@VERSION@
+PACKAGE=@PACKAGE@
+
+CFLAGS="@CONFIG_CFLAGS@"
+
+usage()
+{
+ cat <<EOF
+Usage: synfig-config [OPTION]...
+
+Generic options
+ --version print installed version of synfig.
+ --help display this help and exit.
+
+Compilation support options
+ --cflags print pre-processor and compiler flags
+ --libs print library linking information
+
+Install directories
+ --prefix --exec-prefix --bindir --libexecdir --datadir
+ --sysconfdir --sharedstatedir --localstatedir --libdir --infodir
+ --mandir --includedir
+
+EOF
+
+ exit 1
+}
+
+if test $# -eq 0; then
+ usage 1
+fi
+
+case $1 in
+--version)
+ echo $PACKAGE $VERSION
+ exit 0
+ ;;
+--exec-prefix)
+ echo $exec_prefix
+ exit 0
+ ;;
+--prefix)
+ echo $prefix
+ exit 0
+ ;;
+--help)
+ usage 0
+ ;;
+--cflags)
+ echo $CFLAGS
+ exit 0
+ ;;
+--cxxflags)
+ echo $CFLAGS
+ exit 0
+ ;;
+--libs)
+ echo $LIBS
+ exit 0
+ ;;
+esac
+
+echo Unknown option "$1"
+exit 4
--- /dev/null
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.in by autoheader. */
+
+#define USE_CF_BUNDLES 1
+
+/* Describes the time at which the library will stop working */
+/* #undef DEATH_TIME */
+
+/* enable apple vImage */
+/* #undef HAS_VIMAGE */
+
+/* Define to 1 if you have the `argz_append' function. */
+/* #undef HAVE_ARGZ_APPEND */
+
+/* Define to 1 if you have the `argz_create_sep' function. */
+/* #undef HAVE_ARGZ_CREATE_SEP */
+
+/* Define to 1 if you have the <argz.h> header file. */
+/* #undef HAVE_ARGZ_H */
+
+/* Define to 1 if you have the `argz_insert' function. */
+/* #undef HAVE_ARGZ_INSERT */
+
+/* Define to 1 if you have the `argz_next' function. */
+/* #undef HAVE_ARGZ_NEXT */
+
+/* Define to 1 if you have the `argz_stringify' function. */
+/* #undef HAVE_ARGZ_STRINGIFY */
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `bcopy' function. */
+/* #undef HAVE_BCOPY */
+
+/* Define to 1 if you have the `closedir' function. */
+#define HAVE_CLOSEDIR 1
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#define HAVE_CTYPE_H 1
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the GNU dld library. */
+/* #undef HAVE_DLD */
+
+/* Define to 1 if you have the <dld.h> header file. */
+/* #undef HAVE_DLD_H */
+
+/* Define to 1 if you have the `dlerror' function. */
+#define HAVE_DLERROR 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <dl.h> header file. */
+/* #undef HAVE_DL_H */
+
+/* Define if you have the _dyld_func_lookup function. */
+/* #undef HAVE_DYLD */
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if the system has the type `error_t'. */
+/* #undef HAVE_ERROR_T */
+
+/* Define to 1 if you have the `floorl' function. */
+#define HAVE_FLOORL 1
+
+/* Define to 1 if you have the `fork' function. */
+#define HAVE_FORK 1
+
+/* Define to 1 if you have the `index' function. */
+/* #undef HAVE_INDEX */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `isnan' function. */
+#define HAVE_ISNAN 1
+
+/* Define to 1 if you have the `isnanf' function. */
+/* #undef HAVE_ISNANF */
+
+/* Define to 1 if you have the `kill' function. */
+#define HAVE_KILL 1
+
+/* Define if you have the libdl library or equivalent. */
+#define HAVE_LIBDL 1
+
+/* Define if JPEG library is available */
+#define HAVE_LIBJPEG
+
+/* Define if PNG library is available */
+#define HAVE_LIBPNG
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#define HAVE_LIBPTHREAD 1
+
+/* Define if TIFF library is available */
+#define HAVE_LIBTIFF
+
+/* Define to 1 if you have the <mach-o/dyld.h> header file. */
+#define HAVE_MACH_O_DYLD_H 1
+
+/* Define to 1 if you have the <malloc.h> header file. */
+/* #undef HAVE_MALLOC_H */
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the `opendir' function. */
+#define HAVE_OPENDIR 1
+
+/* Define if OpenEXR is available */
+/* #undef HAVE_OPENEXR */
+
+/* Define to 1 if you have the `pipe' function. */
+#define HAVE_PIPE 1
+
+/* Define if libtool can extract symbol lists from object files. */
+#define HAVE_PRELOADED_SYMBOLS 1
+
+/* Define to 1 if you have the `readdir' function. */
+#define HAVE_READDIR 1
+
+/* Define to 1 if you have the `rindex' function. */
+/* #undef HAVE_RINDEX */
+
+/* Define if you have the shl_load function. */
+/* #undef HAVE_SHL_LOAD */
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strcmp' function. */
+#define HAVE_STRCMP 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strrchr' function. */
+#define HAVE_STRRCHR 1
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/dl.h> header file. */
+/* #undef HAVE_SYS_DL_H */
+
+/* Define to 1 if you have the <sys/errno.h> header file. */
+#define HAVE_SYS_ERRNO_H 1
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `_floorl' function. */
+/* #undef HAVE__FLOORL */
+
+/* Define to 1 if you have the `_isnan' function. */
+/* #undef HAVE__ISNAN */
+
+/* Define to 1 if you have the `_isnanf' function. */
+/* #undef HAVE__ISNANF */
+
+/* Define if the OS needs help to load dependent libraries for dlopen(). */
+/* #undef LTDL_DLOPEN_DEPLIBS */
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LTDL_OBJDIR ".libs/"
+
+/* Define to the name of the environment variable that determines the dynamic
+ library search path. */
+#define LTDL_SHLIBPATH_VAR "DYLD_LIBRARY_PATH"
+
+/* Define to the extension used for shared libraries, say, ".so". */
+#define LTDL_SHLIB_EXT ".so"
+
+/* Define to the system default library search path. */
+#define LTDL_SYSSEARCHPATH "/usr/local/lib:/lib:/usr/lib"
+
+/* LibLTDL is linked staticly */
+#define LT_SCOPE extern
+
+/* Define if dlsym() requires a leading underscore in symbol names. */
+/* #undef NEED_USCORE */
+
+/* Name of package */
+#define PACKAGE "synfig"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "darco@voria.com"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "Synfig Core"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "Synfig Core 0.61.05-257"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "synfig"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.61.05-257"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* enable layer profiling */
+/* #undef SYNFIG_PROFILE_LAYERS */
+
+/* Version number of package */
+#define VERSION "0.61.05-257"
+
+/* enable fontconfig support */
+#define WITH_FONTCONFIG
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to a type to use for `error_t' if it is not otherwise available. */
+#define error_t int
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ActivePerspectiveName</key>
+ <string>Project</string>
+ <key>AllowedModules</key>
+ <array>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Name</key>
+ <string>Groups and Files Outline View</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Name</key>
+ <string>Editor</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCTaskListModule</string>
+ <key>Name</key>
+ <string>Task List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Name</key>
+ <string>File and Smart Group Detail Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Name</key>
+ <string>Detailed Build Results Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Name</key>
+ <string>Project Batch Find Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXRunSessionModule</string>
+ <key>Name</key>
+ <string>Run Log</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Name</key>
+ <string>Bookmarks Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Name</key>
+ <string>Class Browser</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Name</key>
+ <string>Source Code Control Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXDebugBreakpointsModule</string>
+ <key>Name</key>
+ <string>Debug Breakpoints Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDockableInspector</string>
+ <key>Name</key>
+ <string>Inspector</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXOpenQuicklyModule</string>
+ <key>Name</key>
+ <string>Open Quickly Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Name</key>
+ <string>Debugger</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Name</key>
+ <string>Debug Console</string>
+ </dict>
+ </array>
+ <key>Description</key>
+ <string>DefaultDescriptionKey</string>
+ <key>DockingSystemVisible</key>
+ <false/>
+ <key>Extension</key>
+ <string>mode1</string>
+ <key>FavBarConfig</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>A6AF2FF30B9663F500EDBA70</string>
+ <key>XCBarModuleItemNames</key>
+ <dict/>
+ <key>XCBarModuleItems</key>
+ <array/>
+ </dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>com.apple.perspectives.project.mode1</string>
+ <key>MajorVersion</key>
+ <integer>31</integer>
+ <key>MinorVersion</key>
+ <integer>1</integer>
+ <key>Name</key>
+ <string>Default</string>
+ <key>Notifications</key>
+ <array/>
+ <key>OpenEditors</key>
+ <array/>
+ <key>PerspectiveWidths</key>
+ <array>
+ <integer>-1</integer>
+ <integer>-1</integer>
+ </array>
+ <key>Perspectives</key>
+ <array>
+ <dict>
+ <key>ChosenToolbarItems</key>
+ <array>
+ <string>active-target-popup</string>
+ <string>active-buildstyle-popup</string>
+ <string>action</string>
+ <string>clean</string>
+ <string>build-and-debug</string>
+ <string>build-and-run</string>
+ <string>buildOrClean</string>
+ <string>com.apple.ide.PBXToolbarStopButton</string>
+ <string>get-info</string>
+ <string>toggle-editor</string>
+ <string>servicesModuleCVS</string>
+ <string>com.apple.pbx.toolbar.searchfield</string>
+ </array>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProjectWithEditor</string>
+ <key>Identifier</key>
+ <string>perspective.project</string>
+ <key>IsVertical</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C08E77C0454961000C914BD</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>186</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>A6AF11960B965E2E00EDBA70</string>
+ <string>A6AF25F50B965F2D00EDBA70</string>
+ <string>A6AF2F4D0B965FC900EDBA70</string>
+ <string>A6AF20DC0B965ED900EDBA70</string>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>A6AF32410B96718700EDBA70</string>
+ <string>1C37FABC05509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {186, 348}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <true/>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {203, 366}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>186</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>506 231 924 407 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>203pt</string>
+ </dict>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20306471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>config.h</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20406471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>config.h</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>A6AF32480B9672A500EDBA70</string>
+ <key>history</key>
+ <array>
+ <string>A6AF2FE50B9663F500EDBA70</string>
+ <string>A6AF30B20B966B2700EDBA70</string>
+ <string>A6AF30B30B966B2700EDBA70</string>
+ <string>A6AF30B40B966B2700EDBA70</string>
+ <string>A6AF30C40B966C8700EDBA70</string>
+ <string>A6AF30CF0B966D7700EDBA70</string>
+ <string>A6AF30F50B96707D00EDBA70</string>
+ <string>A6AF30F60B96707D00EDBA70</string>
+ <string>A6AF31540B96711700EDBA70</string>
+ <string>A6AF31550B96711700EDBA70</string>
+ <string>A6AF31560B96711700EDBA70</string>
+ <string>A6AF31570B96711700EDBA70</string>
+ <string>A6AF31580B96711700EDBA70</string>
+ <string>A6AF31590B96711700EDBA70</string>
+ <string>A6AF315A0B96711700EDBA70</string>
+ <string>A6AF315B0B96711700EDBA70</string>
+ <string>A6AF315C0B96711700EDBA70</string>
+ <string>A6AF315D0B96711700EDBA70</string>
+ <string>A6AF315E0B96711700EDBA70</string>
+ <string>A6AF315F0B96711700EDBA70</string>
+ <string>A6AF31600B96711700EDBA70</string>
+ <string>A6AF31610B96711700EDBA70</string>
+ <string>A6AF31620B96711700EDBA70</string>
+ <string>A6AF31630B96711700EDBA70</string>
+ <string>A6AF31640B96711700EDBA70</string>
+ <string>A6AF31650B96711700EDBA70</string>
+ <string>A6AF31660B96711700EDBA70</string>
+ <string>A6AF31670B96711700EDBA70</string>
+ <string>A6AF31680B96711700EDBA70</string>
+ <string>A6AF31690B96711700EDBA70</string>
+ <string>A6AF316A0B96711700EDBA70</string>
+ <string>A6AF316B0B96711700EDBA70</string>
+ <string>A6AF316C0B96711700EDBA70</string>
+ <string>A6AF316D0B96711700EDBA70</string>
+ <string>A6AF316E0B96711700EDBA70</string>
+ <string>A6AF316F0B96711700EDBA70</string>
+ <string>A6AF31700B96711700EDBA70</string>
+ <string>A6AF31710B96711700EDBA70</string>
+ <string>A6AF31720B96711700EDBA70</string>
+ <string>A6AF31730B96711700EDBA70</string>
+ <string>A6AF31740B96711700EDBA70</string>
+ <string>A6AF31750B96711700EDBA70</string>
+ <string>A6AF31760B96711700EDBA70</string>
+ <string>A6AF31770B96711700EDBA70</string>
+ <string>A6AF31780B96711700EDBA70</string>
+ <string>A6AF31790B96711700EDBA70</string>
+ <string>A6AF317A0B96711700EDBA70</string>
+ <string>A6AF317B0B96711700EDBA70</string>
+ <string>A6AF317C0B96711700EDBA70</string>
+ <string>A6AF317D0B96711700EDBA70</string>
+ <string>A6AF317E0B96711700EDBA70</string>
+ <string>A6AF317F0B96711700EDBA70</string>
+ <string>A6AF31800B96711700EDBA70</string>
+ <string>A6AF31810B96711700EDBA70</string>
+ <string>A6AF31820B96711700EDBA70</string>
+ <string>A6AF31830B96711700EDBA70</string>
+ <string>A6AF31840B96711700EDBA70</string>
+ <string>A6AF31850B96711700EDBA70</string>
+ <string>A6AF31860B96711700EDBA70</string>
+ <string>A6AF31870B96711700EDBA70</string>
+ <string>A6AF31880B96711700EDBA70</string>
+ <string>A6AF31890B96711700EDBA70</string>
+ <string>A6AF318A0B96711700EDBA70</string>
+ <string>A6AF318B0B96711700EDBA70</string>
+ <string>A6AF318C0B96711700EDBA70</string>
+ <string>A6AF318D0B96711700EDBA70</string>
+ <string>A6AF318E0B96711700EDBA70</string>
+ <string>A6AF318F0B96711700EDBA70</string>
+ <string>A6AF31900B96711700EDBA70</string>
+ <string>A6AF31910B96711700EDBA70</string>
+ <string>A6AF31920B96711700EDBA70</string>
+ <string>A6AF31930B96711700EDBA70</string>
+ <string>A6AF31940B96711700EDBA70</string>
+ <string>A6AF31950B96711700EDBA70</string>
+ <string>A6AF31960B96711700EDBA70</string>
+ <string>A6AF31970B96711700EDBA70</string>
+ <string>A6AF31980B96711700EDBA70</string>
+ <string>A6AF31990B96711700EDBA70</string>
+ <string>A6AF319A0B96711700EDBA70</string>
+ <string>A6AF319B0B96711700EDBA70</string>
+ <string>A6AF319C0B96711700EDBA70</string>
+ <string>A6AF319D0B96711700EDBA70</string>
+ <string>A6AF319E0B96711700EDBA70</string>
+ <string>A6AF319F0B96711700EDBA70</string>
+ <string>A6AF31A00B96711700EDBA70</string>
+ <string>A6AF31A10B96711700EDBA70</string>
+ <string>A6AF31A20B96711700EDBA70</string>
+ <string>A6AF31A30B96711700EDBA70</string>
+ <string>A6AF31A40B96711700EDBA70</string>
+ <string>A6AF31A50B96711700EDBA70</string>
+ <string>A6AF32420B96718700EDBA70</string>
+ <string>A6AF32460B9672A500EDBA70</string>
+ <string>A6AF30F40B96707D00EDBA70</string>
+ </array>
+ <key>prevStack</key>
+ <array>
+ <string>A6AF2FE90B9663F500EDBA70</string>
+ <string>A6AF2FEB0B9663F500EDBA70</string>
+ <string>A6AF2FEC0B9663F500EDBA70</string>
+ <string>A6AF2FED0B9663F500EDBA70</string>
+ <string>A6AF2FEE0B9663F500EDBA70</string>
+ <string>A6AF2FEF0B9663F500EDBA70</string>
+ <string>A6AF30B50B966B2700EDBA70</string>
+ <string>A6AF30B60B966B2700EDBA70</string>
+ <string>A6AF30B70B966B2700EDBA70</string>
+ <string>A6AF30C50B966C8700EDBA70</string>
+ <string>A6AF30C60B966C8700EDBA70</string>
+ <string>A6AF30C70B966C8700EDBA70</string>
+ <string>A6AF30D20B966D7700EDBA70</string>
+ <string>A6AF30D30B966D7700EDBA70</string>
+ <string>A6AF30D40B966D7700EDBA70</string>
+ <string>A6AF30F80B96707D00EDBA70</string>
+ <string>A6AF30F90B96707D00EDBA70</string>
+ <string>A6AF30FA0B96707D00EDBA70</string>
+ <string>A6AF31A70B96711700EDBA70</string>
+ <string>A6AF31A80B96711700EDBA70</string>
+ <string>A6AF31A90B96711700EDBA70</string>
+ <string>A6AF31AA0B96711700EDBA70</string>
+ <string>A6AF31AB0B96711700EDBA70</string>
+ <string>A6AF31AC0B96711700EDBA70</string>
+ <string>A6AF31AD0B96711700EDBA70</string>
+ <string>A6AF31AE0B96711700EDBA70</string>
+ <string>A6AF31AF0B96711700EDBA70</string>
+ <string>A6AF31B00B96711700EDBA70</string>
+ <string>A6AF31B10B96711700EDBA70</string>
+ <string>A6AF31B20B96711700EDBA70</string>
+ <string>A6AF31B30B96711700EDBA70</string>
+ <string>A6AF31B40B96711700EDBA70</string>
+ <string>A6AF31B50B96711700EDBA70</string>
+ <string>A6AF31B60B96711700EDBA70</string>
+ <string>A6AF31B70B96711700EDBA70</string>
+ <string>A6AF31B80B96711700EDBA70</string>
+ <string>A6AF31B90B96711700EDBA70</string>
+ <string>A6AF31BA0B96711700EDBA70</string>
+ <string>A6AF31BB0B96711700EDBA70</string>
+ <string>A6AF31BC0B96711700EDBA70</string>
+ <string>A6AF31BD0B96711700EDBA70</string>
+ <string>A6AF31BE0B96711700EDBA70</string>
+ <string>A6AF31BF0B96711700EDBA70</string>
+ <string>A6AF31C00B96711700EDBA70</string>
+ <string>A6AF31C10B96711700EDBA70</string>
+ <string>A6AF31C20B96711700EDBA70</string>
+ <string>A6AF31C30B96711700EDBA70</string>
+ <string>A6AF31C40B96711700EDBA70</string>
+ <string>A6AF31C50B96711700EDBA70</string>
+ <string>A6AF31C60B96711700EDBA70</string>
+ <string>A6AF31C70B96711700EDBA70</string>
+ <string>A6AF31C80B96711700EDBA70</string>
+ <string>A6AF31C90B96711700EDBA70</string>
+ <string>A6AF31CA0B96711700EDBA70</string>
+ <string>A6AF31CB0B96711700EDBA70</string>
+ <string>A6AF31CC0B96711700EDBA70</string>
+ <string>A6AF31CD0B96711700EDBA70</string>
+ <string>A6AF31CE0B96711700EDBA70</string>
+ <string>A6AF31CF0B96711700EDBA70</string>
+ <string>A6AF31D00B96711700EDBA70</string>
+ <string>A6AF31D10B96711700EDBA70</string>
+ <string>A6AF31D20B96711700EDBA70</string>
+ <string>A6AF31D30B96711700EDBA70</string>
+ <string>A6AF31D40B96711700EDBA70</string>
+ <string>A6AF31D50B96711700EDBA70</string>
+ <string>A6AF31D60B96711700EDBA70</string>
+ <string>A6AF31D70B96711700EDBA70</string>
+ <string>A6AF31D80B96711700EDBA70</string>
+ <string>A6AF31D90B96711700EDBA70</string>
+ <string>A6AF31DA0B96711700EDBA70</string>
+ <string>A6AF31DB0B96711700EDBA70</string>
+ <string>A6AF31DC0B96711700EDBA70</string>
+ <string>A6AF31DD0B96711700EDBA70</string>
+ <string>A6AF31DE0B96711700EDBA70</string>
+ <string>A6AF31DF0B96711700EDBA70</string>
+ <string>A6AF31E00B96711700EDBA70</string>
+ <string>A6AF31E10B96711700EDBA70</string>
+ <string>A6AF31E20B96711700EDBA70</string>
+ <string>A6AF31E30B96711700EDBA70</string>
+ <string>A6AF31E40B96711700EDBA70</string>
+ <string>A6AF31E50B96711700EDBA70</string>
+ <string>A6AF31E60B96711700EDBA70</string>
+ <string>A6AF31E70B96711700EDBA70</string>
+ <string>A6AF31E80B96711700EDBA70</string>
+ <string>A6AF31E90B96711700EDBA70</string>
+ <string>A6AF31EA0B96711700EDBA70</string>
+ <string>A6AF31EB0B96711700EDBA70</string>
+ <string>A6AF31EC0B96711700EDBA70</string>
+ <string>A6AF31ED0B96711700EDBA70</string>
+ <string>A6AF31EE0B96711700EDBA70</string>
+ <string>A6AF31EF0B96711700EDBA70</string>
+ <string>A6AF31F00B96711700EDBA70</string>
+ <string>A6AF31F10B96711700EDBA70</string>
+ <string>A6AF31F20B96711700EDBA70</string>
+ <string>A6AF31F30B96711700EDBA70</string>
+ <string>A6AF31F40B96711700EDBA70</string>
+ <string>A6AF31F50B96711700EDBA70</string>
+ <string>A6AF31F60B96711700EDBA70</string>
+ <string>A6AF31F70B96711700EDBA70</string>
+ <string>A6AF31F80B96711700EDBA70</string>
+ <string>A6AF31F90B96711700EDBA70</string>
+ <string>A6AF31FA0B96711700EDBA70</string>
+ <string>A6AF32430B96718700EDBA70</string>
+ <string>A6AF32470B9672A500EDBA70</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {716, 275}}</string>
+ <key>RubberWindowFrame</key>
+ <string>506 231 924 407 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>275pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20506471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 280}, {716, 86}}</string>
+ <key>RubberWindowFrame</key>
+ <string>506 231 924 407 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>86pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>716pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCModuleDock</string>
+ <string>PBXNavigatorGroup</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>A6AF2FF10B9663F500EDBA70</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>A6AF2FF20B9663F500EDBA70</string>
+ <string>1CE0B20306471E060097A5F4</string>
+ <string>1CE0B20506471E060097A5F4</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.default</string>
+ </dict>
+ <dict>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProject</string>
+ <key>Identifier</key>
+ <string>perspective.morph</string>
+ <key>IsVertical</key>
+ <integer>0</integer>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C08E77C0454961000C914BD</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>186</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>29B97314FDCFA39411CA2CEA</string>
+ <string>1C37FABC05509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {186, 337}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <integer>1</integer>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {203, 355}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>186</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>373 269 690 397 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Morph</string>
+ <key>PreferredWidth</key>
+ <integer>300</integer>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.default.short</string>
+ </dict>
+ </array>
+ <key>PerspectivesBarVisible</key>
+ <false/>
+ <key>ShelfIsVisible</key>
+ <false/>
+ <key>SourceDescription</key>
+ <string>file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec'</string>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TimeStamp</key>
+ <real>0.0</real>
+ <key>ToolbarDisplayMode</key>
+ <integer>2</integer>
+ <key>ToolbarIsVisible</key>
+ <true/>
+ <key>ToolbarSizeMode</key>
+ <integer>2</integer>
+ <key>Type</key>
+ <string>Perspectives</string>
+ <key>UpdateMessage</key>
+ <string>The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'?</string>
+ <key>WindowJustification</key>
+ <integer>5</integer>
+ <key>WindowOrderList</key>
+ <array>
+ <string>A6AF2FAE0B96608300EDBA70</string>
+ <string>/Users/darco/Projects/Voria/synfig-core/synfig-core.xcodeproj</string>
+ </array>
+ <key>WindowString</key>
+ <string>506 231 924 407 0 0 1440 878 </string>
+ <key>WindowTools</key>
+ <array>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.build</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528F0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>canvas.h</string>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {1125, 392}}</string>
+ <key>RubberWindowFrame</key>
+ <string>156 -100 1125 689 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>392pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBuildLogShowsTranscriptDefaultKey</key>
+ <string>{{0, 251}, {1125, 0}}</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>XCMainBuildResultsModuleGUID</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Build</string>
+ <key>XCBuildResultsTrigger_Collapse</key>
+ <integer>1021</integer>
+ <key>XCBuildResultsTrigger_Open</key>
+ <integer>1011</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 397}, {1125, 251}}</string>
+ <key>RubberWindowFrame</key>
+ <string>156 -100 1125 689 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Proportion</key>
+ <string>251pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>648pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Build Results</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBuildResultsModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>A6AF2FAE0B96608300EDBA70</string>
+ <string>A6AF2FAF0B96608300EDBA70</string>
+ <string>1CD0528F0623707200166675</string>
+ <string>XCMainBuildResultsModuleGUID</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.build</string>
+ <key>WindowString</key>
+ <string>156 -100 1125 689 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>A6AF2FAE0B96608300EDBA70</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debugger</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>Debugger</key>
+ <dict>
+ <key>HorizontalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {317, 164}}</string>
+ <string>{{317, 0}, {377, 164}}</string>
+ </array>
+ </dict>
+ <key>VerticalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {694, 164}}</string>
+ <string>{{0, 164}, {694, 216}}</string>
+ </array>
+ </dict>
+ </dict>
+ <key>LauncherConfigVersion</key>
+ <string>8</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C162984064C10D400B95A72</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debug - GLUTExamples (Underwater)</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>DebugConsoleDrawerSize</key>
+ <string>{100, 120}</string>
+ <key>DebugConsoleVisible</key>
+ <string>None</string>
+ <key>DebugConsoleWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>DebugSTDIOWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>Frame</key>
+ <string>{{0, 0}, {694, 380}}</string>
+ <key>RubberWindowFrame</key>
+ <string>321 238 694 422 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugSessionModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <string>1C0AD2AB069F1E9B00FABCE6</string>
+ <string>1C162984064C10D400B95A72</string>
+ <string>1C0AD2AC069F1E9B00FABCE6</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debug</string>
+ <key>WindowString</key>
+ <string>321 238 694 422 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.find</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CDD528C0622207200134675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string><No Editor></string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528D0623707200166675</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <integer>1</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {781, 167}}</string>
+ <key>RubberWindowFrame</key>
+ <string>62 385 781 470 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>781pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>50%</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528E0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Project Find</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{8, 0}, {773, 254}}</string>
+ <key>RubberWindowFrame</key>
+ <string>62 385 781 470 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Proportion</key>
+ <string>50%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>428pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project Find</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXProjectFindModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <string>1C530D58069F1CE1000CFCEE</string>
+ <string>1C530D59069F1CE1000CFCEE</string>
+ <string>1CDD528C0622207200134675</string>
+ <string>1C530D5A069F1CE1000CFCEE</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>1CD0528E0623707200166675</string>
+ </array>
+ <key>WindowString</key>
+ <string>62 385 781 470 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>MENUSEPARATOR</string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debuggerConsole</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAAC065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debugger Console</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {440, 358}}</string>
+ <key>RubberWindowFrame</key>
+ <string>650 41 440 400 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Proportion</key>
+ <string>358pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>358pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger Console</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugCLIModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EAAD065D492600B07095</string>
+ <string>1C78EAAE065D492600B07095</string>
+ <string>1C78EAAC065D492600B07095</string>
+ </array>
+ <key>WindowString</key>
+ <string>650 41 440 400 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.run</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>LauncherConfigVersion</key>
+ <string>3</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528B0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Run</string>
+ <key>Runner</key>
+ <dict>
+ <key>HorizontalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {493, 167}}</string>
+ <string>{{0, 176}, {493, 267}}</string>
+ </array>
+ </dict>
+ <key>VerticalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {405, 443}}</string>
+ <string>{{414, 0}, {514, 443}}</string>
+ </array>
+ </dict>
+ </dict>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {460, 159}}</string>
+ <key>RubberWindowFrame</key>
+ <string>316 696 459 200 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXRunSessionModule</string>
+ <key>Proportion</key>
+ <string>159pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>159pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Run Log</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXRunSessionModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C0AD2B3069F1EA900FABCE6</string>
+ <string>1C0AD2B4069F1EA900FABCE6</string>
+ <string>1CD0528B0623707200166675</string>
+ <string>1C0AD2B5069F1EA900FABCE6</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.run</string>
+ <key>WindowString</key>
+ <string>316 696 459 200 0 0 1280 1002 </string>
+ <key>WindowToolGUID</key>
+ <string>1C0AD2B3069F1EA900FABCE6</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.scm</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB2065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string><No Editor></string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB3065D492600B07095</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <integer>1</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {452, 0}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>0pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD052920623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>SCM</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ConsoleFrame</key>
+ <string>{{0, 259}, {452, 0}}</string>
+ <key>Frame</key>
+ <string>{{0, 7}, {452, 259}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ <key>TableConfiguration</key>
+ <array>
+ <string>Status</string>
+ <real>30</real>
+ <string>FileName</string>
+ <real>199</real>
+ <string>Path</string>
+ <real>197.09500122070312</real>
+ </array>
+ <key>TableFrame</key>
+ <string>{{0, 0}, {452, 250}}</string>
+ </dict>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Proportion</key>
+ <string>262pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>266pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>SCM</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXCVSModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EAB4065D492600B07095</string>
+ <string>1C78EAB5065D492600B07095</string>
+ <string>1C78EAB2065D492600B07095</string>
+ <string>1CD052920623707200166675</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.scm</string>
+ <key>WindowString</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.breakpoints</string>
+ <key>IsVertical</key>
+ <integer>0</integer>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>no</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>168</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {168, 350}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <integer>0</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {185, 368}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>168</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>315 424 744 409 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>185pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA1AED706398EBD00589147</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{190, 0}, {554, 368}}</string>
+ <key>RubberWindowFrame</key>
+ <string>315 424 744 409 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>554pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>368pt</string>
+ </dict>
+ </array>
+ <key>MajorVersion</key>
+ <integer>2</integer>
+ <key>MinorVersion</key>
+ <integer>0</integer>
+ <key>Name</key>
+ <string>Breakpoints</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1CDDB66807F98D9800BB5817</string>
+ <string>1CDDB66907F98D9800BB5817</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>1CA1AED706398EBD00589147</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.breakpoints</string>
+ <key>WindowString</key>
+ <string>315 424 744 409 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1CDDB66807F98D9800BB5817</string>
+ <key>WindowToolIsVisible</key>
+ <integer>1</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debugAnimator</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debug Visualizer</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXNavigatorGroup</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debugAnimator</string>
+ <key>WindowString</key>
+ <string>100 100 700 500 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.bookmarks</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Bookmarks</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBookmarksModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>WindowString</key>
+ <string>538 42 401 187 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.classBrowser</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>OptionsSetName</key>
+ <string>Hierarchy, all classes</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA6456E063B45B4001379D8</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Class Browser - NSObject</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ClassesFrame</key>
+ <string>{{0, 0}, {374, 96}}</string>
+ <key>ClassesTreeTableConfiguration</key>
+ <array>
+ <string>PBXClassNameColumnIdentifier</string>
+ <real>208</real>
+ <string>PBXClassBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>Frame</key>
+ <string>{{0, 0}, {630, 331}}</string>
+ <key>MembersFrame</key>
+ <string>{{0, 105}, {374, 395}}</string>
+ <key>MembersTreeTableConfiguration</key>
+ <array>
+ <string>PBXMemberTypeIconColumnIdentifier</string>
+ <real>22</real>
+ <string>PBXMemberNameColumnIdentifier</string>
+ <real>216</real>
+ <string>PBXMemberTypeColumnIdentifier</string>
+ <real>97</real>
+ <string>PBXMemberBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <integer>1</integer>
+ <key>RubberWindowFrame</key>
+ <string>385 179 630 352 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Proportion</key>
+ <string>332pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>332pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Class Browser</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXClassBrowserModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C0AD2AF069F1E9B00FABCE6</string>
+ <string>1C0AD2B0069F1E9B00FABCE6</string>
+ <string>1CA6456E063B45B4001379D8</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.classbrowser</string>
+ <key>WindowString</key>
+ <string>385 179 630 352 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1C0AD2AF069F1E9B00FABCE6</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ </array>
+</dict>
+</plist>
--- /dev/null
+// !$*UTF8*$!
+{
+ A6AF11980B965E2E00EDBA70 /* Project object */ = {
+ activeBuildConfigurationName = Debug;
+ activeExecutable = A6AF30E40B966F6D00EDBA70 /* Synfig Tool */;
+ activeTarget = A6AF30E20B966F6D00EDBA70 /* Synfig Tool */;
+ addToTargets = (
+ A6AF20DA0B965ED900EDBA70 /* Synfig Framework */,
+ );
+ codeSenseManager = A6AF119D0B965E2E00EDBA70 /* Code sense */;
+ executables = (
+ A6AF30E40B966F6D00EDBA70 /* Synfig Tool */,
+ );
+ ignoreBreakpointsInProjectsDict = {
+ };
+ perUserDictionary = {
+ PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 45,
+ 20,
+ 42,
+ 43,
+ 43,
+ 20,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXFileDataSource_FiletypeID,
+ PBXFileDataSource_Filename_ColumnID,
+ PBXFileDataSource_Built_ColumnID,
+ PBXFileDataSource_ObjectSize_ColumnID,
+ PBXFileDataSource_Errors_ColumnID,
+ PBXFileDataSource_Warnings_ColumnID,
+ PBXFileDataSource_Target_ColumnID,
+ );
+ };
+ PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 200,
+ 99,
+ 20,
+ 42,
+ 43,
+ 43,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXFileDataSource_FiletypeID,
+ PBXFileDataSource_Filename_ColumnID,
+ PBXTargetDataSource_PrimaryAttribute,
+ PBXFileDataSource_Built_ColumnID,
+ PBXFileDataSource_ObjectSize_ColumnID,
+ PBXFileDataSource_Errors_ColumnID,
+ PBXFileDataSource_Warnings_ColumnID,
+ );
+ };
+ PBXPerProjectTemplateStateSaveDate = 194403886;
+ PBXWorkspaceStateSaveDate = 194403886;
+ };
+ perUserProjectItems = {
+ A6AF2FAA0B96608300EDBA70 /* PBXTextBookmark */ = A6AF2FAA0B96608300EDBA70 /* PBXTextBookmark */;
+ A6AF2FAC0B96608300EDBA70 /* PBXTextBookmark */ = A6AF2FAC0B96608300EDBA70 /* PBXTextBookmark */;
+ A6AF2FB00B9660CB00EDBA70 /* PBXTextBookmark */ = A6AF2FB00B9660CB00EDBA70 /* PBXTextBookmark */;
+ A6AF2FB10B9660CB00EDBA70 /* PBXTextBookmark */ = A6AF2FB10B9660CB00EDBA70 /* PBXTextBookmark */;
+ A6AF2FB30B9660CB00EDBA70 /* PBXTextBookmark */ = A6AF2FB30B9660CB00EDBA70 /* PBXTextBookmark */;
+ A6AF2FB50B9660CB00EDBA70 /* PBXTextBookmark */ = A6AF2FB50B9660CB00EDBA70 /* PBXTextBookmark */;
+ A6AF2FB60B9660CB00EDBA70 /* PBXTextBookmark */ = A6AF2FB60B9660CB00EDBA70 /* PBXTextBookmark */;
+ A6AF2FB80B9660CB00EDBA70 /* PBXTextBookmark */ = A6AF2FB80B9660CB00EDBA70 /* PBXTextBookmark */;
+ A6AF2FBB0B96614500EDBA70 /* PBXTextBookmark */ = A6AF2FBB0B96614500EDBA70 /* PBXTextBookmark */;
+ A6AF2FBC0B96614500EDBA70 /* PBXTextBookmark */ = A6AF2FBC0B96614500EDBA70 /* PBXTextBookmark */;
+ A6AF2FBD0B96614500EDBA70 /* PBXTextBookmark */ = A6AF2FBD0B96614500EDBA70 /* PBXTextBookmark */;
+ A6AF2FBE0B96614500EDBA70 /* PBXTextBookmark */ = A6AF2FBE0B96614500EDBA70 /* PBXTextBookmark */;
+ A6AF2FBF0B96614500EDBA70 /* PBXTextBookmark */ = A6AF2FBF0B96614500EDBA70 /* PBXTextBookmark */;
+ A6AF2FC00B96614500EDBA70 /* PBXTextBookmark */ = A6AF2FC00B96614500EDBA70 /* PBXTextBookmark */;
+ A6AF2FC10B96614500EDBA70 /* PBXTextBookmark */ = A6AF2FC10B96614500EDBA70 /* PBXTextBookmark */;
+ A6AF2FC20B96614500EDBA70 /* PBXTextBookmark */ = A6AF2FC20B96614500EDBA70 /* PBXTextBookmark */;
+ A6AF2FC60B96616500EDBA70 /* PBXTextBookmark */ = A6AF2FC60B96616500EDBA70 /* PBXTextBookmark */;
+ A6AF2FC80B96618900EDBA70 /* PBXTextBookmark */ = A6AF2FC80B96618900EDBA70 /* PBXTextBookmark */;
+ A6AF2FC90B96618900EDBA70 /* PBXTextBookmark */ = A6AF2FC90B96618900EDBA70 /* PBXTextBookmark */;
+ A6AF2FCA0B96618900EDBA70 /* PBXTextBookmark */ = A6AF2FCA0B96618900EDBA70 /* PBXTextBookmark */;
+ A6AF2FCB0B96618900EDBA70 /* PBXTextBookmark */ = A6AF2FCB0B96618900EDBA70 /* PBXTextBookmark */;
+ A6AF2FCD0B96619A00EDBA70 /* PBXTextBookmark */ = A6AF2FCD0B96619A00EDBA70 /* PBXTextBookmark */;
+ A6AF2FCE0B96619A00EDBA70 /* PBXTextBookmark */ = A6AF2FCE0B96619A00EDBA70 /* PBXTextBookmark */;
+ A6AF2FD40B96626800EDBA70 /* PBXTextBookmark */ = A6AF2FD40B96626800EDBA70 /* PBXTextBookmark */;
+ A6AF2FD50B96626800EDBA70 /* PBXTextBookmark */ = A6AF2FD50B96626800EDBA70 /* PBXTextBookmark */;
+ A6AF2FD60B96626800EDBA70 /* PBXTextBookmark */ = A6AF2FD60B96626800EDBA70 /* PBXTextBookmark */;
+ A6AF2FD70B96626800EDBA70 /* PBXTextBookmark */ = A6AF2FD70B96626800EDBA70 /* PBXTextBookmark */;
+ A6AF2FD90B9662F600EDBA70 /* PBXTextBookmark */ = A6AF2FD90B9662F600EDBA70 /* PBXTextBookmark */;
+ A6AF2FDA0B9662F600EDBA70 /* PBXTextBookmark */ = A6AF2FDA0B9662F600EDBA70 /* PBXTextBookmark */;
+ A6AF2FDB0B9662F600EDBA70 /* PBXTextBookmark */ = A6AF2FDB0B9662F600EDBA70 /* PBXTextBookmark */;
+ A6AF2FDC0B9662F600EDBA70 /* PBXTextBookmark */ = A6AF2FDC0B9662F600EDBA70 /* PBXTextBookmark */;
+ A6AF2FE30B9663F500EDBA70 /* PBXTextBookmark */ = A6AF2FE30B9663F500EDBA70 /* PBXTextBookmark */;
+ A6AF2FE50B9663F500EDBA70 /* PBXTextBookmark */ = A6AF2FE50B9663F500EDBA70 /* PBXTextBookmark */;
+ A6AF2FE60B9663F500EDBA70 /* PBXTextBookmark */ = A6AF2FE60B9663F500EDBA70 /* PBXTextBookmark */;
+ A6AF2FE70B9663F500EDBA70 /* PBXTextBookmark */ = A6AF2FE70B9663F500EDBA70 /* PBXTextBookmark */;
+ A6AF2FE80B9663F500EDBA70 /* PBXTextBookmark */ = A6AF2FE80B9663F500EDBA70 /* PBXTextBookmark */;
+ A6AF2FE90B9663F500EDBA70 /* PBXTextBookmark */ = A6AF2FE90B9663F500EDBA70 /* PBXTextBookmark */;
+ A6AF2FEB0B9663F500EDBA70 /* PBXTextBookmark */ = A6AF2FEB0B9663F500EDBA70 /* PBXTextBookmark */;
+ A6AF2FEC0B9663F500EDBA70 /* PBXTextBookmark */ = A6AF2FEC0B9663F500EDBA70 /* PBXTextBookmark */;
+ A6AF2FED0B9663F500EDBA70 /* PBXTextBookmark */ = A6AF2FED0B9663F500EDBA70 /* PBXTextBookmark */;
+ A6AF2FEE0B9663F500EDBA70 /* PBXTextBookmark */ = A6AF2FEE0B9663F500EDBA70 /* PBXTextBookmark */;
+ A6AF2FEF0B9663F500EDBA70 /* PBXTextBookmark */ = A6AF2FEF0B9663F500EDBA70 /* PBXTextBookmark */;
+ A6AF2FF00B9663F500EDBA70 /* PBXTextBookmark */ = A6AF2FF00B9663F500EDBA70 /* PBXTextBookmark */;
+ A6AF30400B9666E100EDBA70 /* PBXTextBookmark */ = A6AF30400B9666E100EDBA70 /* PBXTextBookmark */;
+ A6AF30410B9666E100EDBA70 /* PBXTextBookmark */ = A6AF30410B9666E100EDBA70 /* PBXTextBookmark */;
+ A6AF30430B9666E100EDBA70 /* PBXTextBookmark */ = A6AF30430B9666E100EDBA70 /* PBXTextBookmark */;
+ A6AF30440B9666E100EDBA70 /* PBXTextBookmark */ = A6AF30440B9666E100EDBA70 /* PBXTextBookmark */;
+ A6AF30450B96670D00EDBA70 /* PBXTextBookmark */ = A6AF30450B96670D00EDBA70 /* PBXTextBookmark */;
+ A6AF30740B96688E00EDBA70 /* PBXTextBookmark */ = A6AF30740B96688E00EDBA70 /* PBXTextBookmark */;
+ A6AF30750B96688E00EDBA70 /* PBXTextBookmark */ = A6AF30750B96688E00EDBA70 /* PBXTextBookmark */;
+ A6AF30770B96688E00EDBA70 /* PBXTextBookmark */ = A6AF30770B96688E00EDBA70 /* PBXTextBookmark */;
+ A6AF30780B96688E00EDBA70 /* PBXTextBookmark */ = A6AF30780B96688E00EDBA70 /* PBXTextBookmark */;
+ A6AF308B0B96691000EDBA70 /* PBXTextBookmark */ = A6AF308B0B96691000EDBA70 /* PBXTextBookmark */;
+ A6AF308C0B96691000EDBA70 /* PBXTextBookmark */ = A6AF308C0B96691000EDBA70 /* PBXTextBookmark */;
+ A6AF308E0B96691000EDBA70 /* PBXTextBookmark */ = A6AF308E0B96691000EDBA70 /* PBXTextBookmark */;
+ A6AF308F0B96691000EDBA70 /* PBXTextBookmark */ = A6AF308F0B96691000EDBA70 /* PBXTextBookmark */;
+ A6AF30A30B966B1700EDBA70 /* PBXTextBookmark */ = A6AF30A30B966B1700EDBA70 /* PBXTextBookmark */;
+ A6AF30A40B966B1700EDBA70 /* PBXTextBookmark */ = A6AF30A40B966B1700EDBA70 /* PBXTextBookmark */;
+ A6AF30A50B966B1700EDBA70 /* PBXTextBookmark */ = A6AF30A50B966B1700EDBA70 /* PBXTextBookmark */;
+ A6AF30A70B966B1700EDBA70 /* PBXTextBookmark */ = A6AF30A70B966B1700EDBA70 /* PBXTextBookmark */;
+ A6AF30A80B966B1700EDBA70 /* PBXTextBookmark */ = A6AF30A80B966B1700EDBA70 /* PBXTextBookmark */;
+ A6AF30A90B966B1700EDBA70 /* PBXTextBookmark */ = A6AF30A90B966B1700EDBA70 /* PBXTextBookmark */;
+ A6AF30AA0B966B1700EDBA70 /* PBXTextBookmark */ = A6AF30AA0B966B1700EDBA70 /* PBXTextBookmark */;
+ A6AF30AB0B966B1700EDBA70 /* PBXTextBookmark */ = A6AF30AB0B966B1700EDBA70 /* PBXTextBookmark */;
+ A6AF30AC0B966B1700EDBA70 /* PBXTextBookmark */ = A6AF30AC0B966B1700EDBA70 /* PBXTextBookmark */;
+ A6AF30AD0B966B1700EDBA70 /* PBXTextBookmark */ = A6AF30AD0B966B1700EDBA70 /* PBXTextBookmark */;
+ A6AF30AE0B966B1700EDBA70 /* PBXTextBookmark */ = A6AF30AE0B966B1700EDBA70 /* PBXTextBookmark */;
+ A6AF30B20B966B2700EDBA70 /* PBXTextBookmark */ = A6AF30B20B966B2700EDBA70 /* PBXTextBookmark */;
+ A6AF30B30B966B2700EDBA70 /* PBXTextBookmark */ = A6AF30B30B966B2700EDBA70 /* PBXTextBookmark */;
+ A6AF30B40B966B2700EDBA70 /* PBXTextBookmark */ = A6AF30B40B966B2700EDBA70 /* PBXTextBookmark */;
+ A6AF30B50B966B2700EDBA70 /* PBXTextBookmark */ = A6AF30B50B966B2700EDBA70 /* PBXTextBookmark */;
+ A6AF30B60B966B2700EDBA70 /* PBXTextBookmark */ = A6AF30B60B966B2700EDBA70 /* PBXTextBookmark */;
+ A6AF30B70B966B2700EDBA70 /* PBXTextBookmark */ = A6AF30B70B966B2700EDBA70 /* PBXTextBookmark */;
+ A6AF30B80B966B2700EDBA70 /* PBXTextBookmark */ = A6AF30B80B966B2700EDBA70 /* PBXTextBookmark */;
+ A6AF30BB0B966C6E00EDBA70 /* PBXTextBookmark */ = A6AF30BB0B966C6E00EDBA70 /* PBXTextBookmark */;
+ A6AF30BC0B966C6E00EDBA70 /* PBXTextBookmark */ = A6AF30BC0B966C6E00EDBA70 /* PBXTextBookmark */;
+ A6AF30BD0B966C6E00EDBA70 /* PBXTextBookmark */ = A6AF30BD0B966C6E00EDBA70 /* PBXTextBookmark */;
+ A6AF30BE0B966C6E00EDBA70 /* PBXTextBookmark */ = A6AF30BE0B966C6E00EDBA70 /* PBXTextBookmark */;
+ A6AF30C30B966C8700EDBA70 /* PBXTextBookmark */ = A6AF30C30B966C8700EDBA70 /* PBXTextBookmark */;
+ A6AF30C40B966C8700EDBA70 /* PBXTextBookmark */ = A6AF30C40B966C8700EDBA70 /* PBXTextBookmark */;
+ A6AF30C50B966C8700EDBA70 /* PBXTextBookmark */ = A6AF30C50B966C8700EDBA70 /* PBXTextBookmark */;
+ A6AF30C60B966C8700EDBA70 /* PBXTextBookmark */ = A6AF30C60B966C8700EDBA70 /* PBXTextBookmark */;
+ A6AF30C70B966C8700EDBA70 /* PBXTextBookmark */ = A6AF30C70B966C8700EDBA70 /* PBXTextBookmark */;
+ A6AF30C80B966C8700EDBA70 /* PBXTextBookmark */ = A6AF30C80B966C8700EDBA70 /* PBXTextBookmark */;
+ A6AF30C90B966CBD00EDBA70 /* PBXTextBookmark */ = A6AF30C90B966CBD00EDBA70 /* PBXTextBookmark */;
+ A6AF30CC0B966CD300EDBA70 /* PBXTextBookmark */ = A6AF30CC0B966CD300EDBA70 /* PBXTextBookmark */;
+ A6AF30CF0B966D7700EDBA70 /* PBXTextBookmark */ = A6AF30CF0B966D7700EDBA70 /* PBXTextBookmark */;
+ A6AF30D00B966D7700EDBA70 /* PBXTextBookmark */ = A6AF30D00B966D7700EDBA70 /* PBXTextBookmark */;
+ A6AF30D10B966D7700EDBA70 /* PBXTextBookmark */ = A6AF30D10B966D7700EDBA70 /* PBXTextBookmark */;
+ A6AF30D20B966D7700EDBA70 /* PBXTextBookmark */ = A6AF30D20B966D7700EDBA70 /* PBXTextBookmark */;
+ A6AF30D30B966D7700EDBA70 /* PBXTextBookmark */ = A6AF30D30B966D7700EDBA70 /* PBXTextBookmark */;
+ A6AF30D40B966D7700EDBA70 /* PBXTextBookmark */ = A6AF30D40B966D7700EDBA70 /* PBXTextBookmark */;
+ A6AF30D50B966D7700EDBA70 /* PBXTextBookmark */ = A6AF30D50B966D7700EDBA70 /* PBXTextBookmark */;
+ A6AF30F40B96707D00EDBA70 /* PBXTextBookmark */ = A6AF30F40B96707D00EDBA70 /* PBXTextBookmark */;
+ A6AF30F50B96707D00EDBA70 /* PBXTextBookmark */ = A6AF30F50B96707D00EDBA70 /* PBXTextBookmark */;
+ A6AF30F60B96707D00EDBA70 /* PBXTextBookmark */ = A6AF30F60B96707D00EDBA70 /* PBXTextBookmark */;
+ A6AF30F70B96707D00EDBA70 /* PBXBookmark */ = A6AF30F70B96707D00EDBA70 /* PBXBookmark */;
+ A6AF30F80B96707D00EDBA70 /* PBXTextBookmark */ = A6AF30F80B96707D00EDBA70 /* PBXTextBookmark */;
+ A6AF30F90B96707D00EDBA70 /* PBXTextBookmark */ = A6AF30F90B96707D00EDBA70 /* PBXTextBookmark */;
+ A6AF30FA0B96707D00EDBA70 /* PBXTextBookmark */ = A6AF30FA0B96707D00EDBA70 /* PBXTextBookmark */;
+ A6AF30FB0B96707D00EDBA70 /* PBXTextBookmark */ = A6AF30FB0B96707D00EDBA70 /* PBXTextBookmark */;
+ A6AF31540B96711700EDBA70 /* PBXTextBookmark */ = A6AF31540B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31550B96711700EDBA70 /* PBXTextBookmark */ = A6AF31550B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31560B96711700EDBA70 /* PBXTextBookmark */ = A6AF31560B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31570B96711700EDBA70 /* PBXTextBookmark */ = A6AF31570B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31580B96711700EDBA70 /* PBXTextBookmark */ = A6AF31580B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31590B96711700EDBA70 /* PBXTextBookmark */ = A6AF31590B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF315A0B96711700EDBA70 /* PBXTextBookmark */ = A6AF315A0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF315B0B96711700EDBA70 /* PBXTextBookmark */ = A6AF315B0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF315C0B96711700EDBA70 /* PBXTextBookmark */ = A6AF315C0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF315D0B96711700EDBA70 /* PBXTextBookmark */ = A6AF315D0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF315E0B96711700EDBA70 /* PBXTextBookmark */ = A6AF315E0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF315F0B96711700EDBA70 /* PBXTextBookmark */ = A6AF315F0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31600B96711700EDBA70 /* PBXTextBookmark */ = A6AF31600B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31610B96711700EDBA70 /* PBXTextBookmark */ = A6AF31610B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31620B96711700EDBA70 /* PBXTextBookmark */ = A6AF31620B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31630B96711700EDBA70 /* PBXTextBookmark */ = A6AF31630B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31640B96711700EDBA70 /* PBXTextBookmark */ = A6AF31640B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31650B96711700EDBA70 /* PBXTextBookmark */ = A6AF31650B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31660B96711700EDBA70 /* PBXTextBookmark */ = A6AF31660B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31670B96711700EDBA70 /* PBXTextBookmark */ = A6AF31670B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31680B96711700EDBA70 /* PBXTextBookmark */ = A6AF31680B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31690B96711700EDBA70 /* PBXTextBookmark */ = A6AF31690B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF316A0B96711700EDBA70 /* PBXTextBookmark */ = A6AF316A0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF316B0B96711700EDBA70 /* PBXTextBookmark */ = A6AF316B0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF316C0B96711700EDBA70 /* PBXTextBookmark */ = A6AF316C0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF316D0B96711700EDBA70 /* PBXTextBookmark */ = A6AF316D0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF316E0B96711700EDBA70 /* PBXTextBookmark */ = A6AF316E0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF316F0B96711700EDBA70 /* PBXTextBookmark */ = A6AF316F0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31700B96711700EDBA70 /* PBXTextBookmark */ = A6AF31700B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31710B96711700EDBA70 /* PBXTextBookmark */ = A6AF31710B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31720B96711700EDBA70 /* PBXTextBookmark */ = A6AF31720B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31730B96711700EDBA70 /* PBXTextBookmark */ = A6AF31730B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31740B96711700EDBA70 /* PBXTextBookmark */ = A6AF31740B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31750B96711700EDBA70 /* PBXTextBookmark */ = A6AF31750B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31760B96711700EDBA70 /* PBXTextBookmark */ = A6AF31760B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31770B96711700EDBA70 /* PBXTextBookmark */ = A6AF31770B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31780B96711700EDBA70 /* PBXTextBookmark */ = A6AF31780B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31790B96711700EDBA70 /* PBXTextBookmark */ = A6AF31790B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF317A0B96711700EDBA70 /* PBXTextBookmark */ = A6AF317A0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF317B0B96711700EDBA70 /* PBXTextBookmark */ = A6AF317B0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF317C0B96711700EDBA70 /* PBXTextBookmark */ = A6AF317C0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF317D0B96711700EDBA70 /* PBXTextBookmark */ = A6AF317D0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF317E0B96711700EDBA70 /* PBXTextBookmark */ = A6AF317E0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF317F0B96711700EDBA70 /* PBXTextBookmark */ = A6AF317F0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31800B96711700EDBA70 /* PBXTextBookmark */ = A6AF31800B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31810B96711700EDBA70 /* PBXTextBookmark */ = A6AF31810B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31820B96711700EDBA70 /* PBXTextBookmark */ = A6AF31820B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31830B96711700EDBA70 /* PBXTextBookmark */ = A6AF31830B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31840B96711700EDBA70 /* PBXTextBookmark */ = A6AF31840B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31850B96711700EDBA70 /* PBXTextBookmark */ = A6AF31850B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31860B96711700EDBA70 /* PBXTextBookmark */ = A6AF31860B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31870B96711700EDBA70 /* PBXTextBookmark */ = A6AF31870B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31880B96711700EDBA70 /* PBXTextBookmark */ = A6AF31880B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31890B96711700EDBA70 /* PBXTextBookmark */ = A6AF31890B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF318A0B96711700EDBA70 /* PBXTextBookmark */ = A6AF318A0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF318B0B96711700EDBA70 /* PBXTextBookmark */ = A6AF318B0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF318C0B96711700EDBA70 /* PBXTextBookmark */ = A6AF318C0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF318D0B96711700EDBA70 /* PBXTextBookmark */ = A6AF318D0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF318E0B96711700EDBA70 /* PBXTextBookmark */ = A6AF318E0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF318F0B96711700EDBA70 /* PBXTextBookmark */ = A6AF318F0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31900B96711700EDBA70 /* PBXTextBookmark */ = A6AF31900B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31910B96711700EDBA70 /* PBXTextBookmark */ = A6AF31910B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31920B96711700EDBA70 /* PBXTextBookmark */ = A6AF31920B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31930B96711700EDBA70 /* PBXTextBookmark */ = A6AF31930B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31940B96711700EDBA70 /* PBXTextBookmark */ = A6AF31940B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31950B96711700EDBA70 /* PBXTextBookmark */ = A6AF31950B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31960B96711700EDBA70 /* PBXTextBookmark */ = A6AF31960B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31970B96711700EDBA70 /* PBXTextBookmark */ = A6AF31970B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31980B96711700EDBA70 /* PBXTextBookmark */ = A6AF31980B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31990B96711700EDBA70 /* PBXTextBookmark */ = A6AF31990B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF319A0B96711700EDBA70 /* PBXTextBookmark */ = A6AF319A0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF319B0B96711700EDBA70 /* PBXTextBookmark */ = A6AF319B0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF319C0B96711700EDBA70 /* PBXTextBookmark */ = A6AF319C0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF319D0B96711700EDBA70 /* PBXTextBookmark */ = A6AF319D0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF319E0B96711700EDBA70 /* PBXTextBookmark */ = A6AF319E0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF319F0B96711700EDBA70 /* PBXTextBookmark */ = A6AF319F0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31A00B96711700EDBA70 /* PBXTextBookmark */ = A6AF31A00B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31A10B96711700EDBA70 /* PBXTextBookmark */ = A6AF31A10B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31A20B96711700EDBA70 /* PBXTextBookmark */ = A6AF31A20B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31A30B96711700EDBA70 /* PBXTextBookmark */ = A6AF31A30B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31A40B96711700EDBA70 /* PBXTextBookmark */ = A6AF31A40B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31A50B96711700EDBA70 /* PBXTextBookmark */ = A6AF31A50B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31A60B96711700EDBA70 /* PBXTextBookmark */ = A6AF31A60B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31A70B96711700EDBA70 /* PBXTextBookmark */ = A6AF31A70B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31A80B96711700EDBA70 /* PBXTextBookmark */ = A6AF31A80B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31A90B96711700EDBA70 /* PBXTextBookmark */ = A6AF31A90B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31AA0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31AA0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31AB0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31AB0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31AC0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31AC0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31AD0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31AD0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31AE0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31AE0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31AF0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31AF0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31B00B96711700EDBA70 /* PBXTextBookmark */ = A6AF31B00B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31B10B96711700EDBA70 /* PBXTextBookmark */ = A6AF31B10B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31B20B96711700EDBA70 /* PBXTextBookmark */ = A6AF31B20B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31B30B96711700EDBA70 /* PBXTextBookmark */ = A6AF31B30B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31B40B96711700EDBA70 /* PBXTextBookmark */ = A6AF31B40B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31B50B96711700EDBA70 /* PBXTextBookmark */ = A6AF31B50B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31B60B96711700EDBA70 /* PBXTextBookmark */ = A6AF31B60B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31B70B96711700EDBA70 /* PBXTextBookmark */ = A6AF31B70B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31B80B96711700EDBA70 /* PBXTextBookmark */ = A6AF31B80B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31B90B96711700EDBA70 /* PBXTextBookmark */ = A6AF31B90B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31BA0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31BA0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31BB0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31BB0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31BC0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31BC0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31BD0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31BD0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31BE0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31BE0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31BF0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31BF0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31C00B96711700EDBA70 /* PBXTextBookmark */ = A6AF31C00B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31C10B96711700EDBA70 /* PBXTextBookmark */ = A6AF31C10B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31C20B96711700EDBA70 /* PBXTextBookmark */ = A6AF31C20B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31C30B96711700EDBA70 /* PBXTextBookmark */ = A6AF31C30B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31C40B96711700EDBA70 /* PBXTextBookmark */ = A6AF31C40B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31C50B96711700EDBA70 /* PBXTextBookmark */ = A6AF31C50B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31C60B96711700EDBA70 /* PBXTextBookmark */ = A6AF31C60B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31C70B96711700EDBA70 /* PBXTextBookmark */ = A6AF31C70B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31C80B96711700EDBA70 /* PBXTextBookmark */ = A6AF31C80B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31C90B96711700EDBA70 /* PBXTextBookmark */ = A6AF31C90B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31CA0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31CA0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31CB0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31CB0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31CC0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31CC0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31CD0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31CD0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31CE0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31CE0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31CF0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31CF0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31D00B96711700EDBA70 /* PBXTextBookmark */ = A6AF31D00B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31D10B96711700EDBA70 /* PBXTextBookmark */ = A6AF31D10B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31D20B96711700EDBA70 /* PBXTextBookmark */ = A6AF31D20B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31D30B96711700EDBA70 /* PBXTextBookmark */ = A6AF31D30B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31D40B96711700EDBA70 /* PBXTextBookmark */ = A6AF31D40B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31D50B96711700EDBA70 /* PBXTextBookmark */ = A6AF31D50B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31D60B96711700EDBA70 /* PBXTextBookmark */ = A6AF31D60B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31D70B96711700EDBA70 /* PBXTextBookmark */ = A6AF31D70B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31D80B96711700EDBA70 /* PBXTextBookmark */ = A6AF31D80B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31D90B96711700EDBA70 /* PBXTextBookmark */ = A6AF31D90B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31DA0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31DA0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31DB0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31DB0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31DC0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31DC0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31DD0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31DD0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31DE0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31DE0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31DF0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31DF0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31E00B96711700EDBA70 /* PBXTextBookmark */ = A6AF31E00B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31E10B96711700EDBA70 /* PBXTextBookmark */ = A6AF31E10B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31E20B96711700EDBA70 /* PBXTextBookmark */ = A6AF31E20B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31E30B96711700EDBA70 /* PBXTextBookmark */ = A6AF31E30B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31E40B96711700EDBA70 /* PBXTextBookmark */ = A6AF31E40B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31E50B96711700EDBA70 /* PBXTextBookmark */ = A6AF31E50B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31E60B96711700EDBA70 /* PBXTextBookmark */ = A6AF31E60B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31E70B96711700EDBA70 /* PBXTextBookmark */ = A6AF31E70B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31E80B96711700EDBA70 /* PBXTextBookmark */ = A6AF31E80B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31E90B96711700EDBA70 /* PBXTextBookmark */ = A6AF31E90B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31EA0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31EA0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31EB0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31EB0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31EC0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31EC0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31ED0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31ED0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31EE0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31EE0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31EF0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31EF0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31F00B96711700EDBA70 /* PBXTextBookmark */ = A6AF31F00B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31F10B96711700EDBA70 /* PBXTextBookmark */ = A6AF31F10B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31F20B96711700EDBA70 /* PBXTextBookmark */ = A6AF31F20B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31F30B96711700EDBA70 /* PBXTextBookmark */ = A6AF31F30B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31F40B96711700EDBA70 /* PBXTextBookmark */ = A6AF31F40B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31F50B96711700EDBA70 /* PBXTextBookmark */ = A6AF31F50B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31F60B96711700EDBA70 /* PBXTextBookmark */ = A6AF31F60B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31F70B96711700EDBA70 /* PBXTextBookmark */ = A6AF31F70B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31F80B96711700EDBA70 /* PBXTextBookmark */ = A6AF31F80B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31F90B96711700EDBA70 /* PBXTextBookmark */ = A6AF31F90B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31FA0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31FA0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31FB0B96711700EDBA70 /* PBXTextBookmark */ = A6AF31FB0B96711700EDBA70 /* PBXTextBookmark */;
+ A6AF31FC0B96714000EDBA70 /* PBXTextBookmark */ = A6AF31FC0B96714000EDBA70 /* PBXTextBookmark */;
+ A6AF31FD0B96714000EDBA70 /* PBXTextBookmark */ = A6AF31FD0B96714000EDBA70 /* PBXTextBookmark */;
+ A6AF31FF0B96714000EDBA70 /* PBXTextBookmark */ = A6AF31FF0B96714000EDBA70 /* PBXTextBookmark */;
+ A6AF32000B96714000EDBA70 /* PBXTextBookmark */ = A6AF32000B96714000EDBA70 /* PBXTextBookmark */;
+ A6AF32420B96718700EDBA70 /* PBXTextBookmark */ = A6AF32420B96718700EDBA70 /* PBXTextBookmark */;
+ A6AF32430B96718700EDBA70 /* PBXTextBookmark */ = A6AF32430B96718700EDBA70 /* PBXTextBookmark */;
+ A6AF32440B96718700EDBA70 /* PBXTextBookmark */ = A6AF32440B96718700EDBA70 /* PBXTextBookmark */;
+ A6AF32460B9672A500EDBA70 /* PBXTextBookmark */ = A6AF32460B9672A500EDBA70 /* PBXTextBookmark */;
+ A6AF32470B9672A500EDBA70 /* PBXTextBookmark */ = A6AF32470B9672A500EDBA70 /* PBXTextBookmark */;
+ A6AF32480B9672A500EDBA70 /* PBXTextBookmark */ = A6AF32480B9672A500EDBA70 /* PBXTextBookmark */;
+ };
+ sourceControlManager = A6AF119C0B965E2E00EDBA70 /* Source Control */;
+ userBuildSettings = {
+ };
+ };
+ A6AF119C0B965E2E00EDBA70 /* Source Control */ = {
+ isa = PBXSourceControlManager;
+ fallbackIsa = XCSourceControlManager;
+ isSCMEnabled = 1;
+ scmConfiguration = {
+ SubversionToolPath = /usr/local/bin/svn;
+ };
+ scmType = scm.subversion;
+ };
+ A6AF119D0B965E2E00EDBA70 /* Code sense */ = {
+ isa = PBXCodeSenseManager;
+ indexTemplatePath = "";
+ };
+ A6AF20DA0B965ED900EDBA70 /* Synfig Framework */ = {
+ activeExec = 0;
+ };
+ A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1084, 840}}";
+ sepNavSelRange = "{1024, 21}";
+ sepNavVisRect = "{{0, 248}, {1084, 360}}";
+ };
+ };
+ A6AF29CB0B965F2E00EDBA70 /* activepoint.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {741, 1335}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29CC0B965F2E00EDBA70 /* angle.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 750}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29CE0B965F2E00EDBA70 /* blinepoint.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1395}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29D00B965F2E00EDBA70 /* blur.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1007, 1335}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29D20B965F2E00EDBA70 /* canvas.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1077, 7290}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29D30B965F2E00EDBA70 /* canvasbase.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 720}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29D50B965F2E00EDBA70 /* color.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {902, 13005}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29D70B965F2E00EDBA70 /* context.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {804, 1320}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29D90B965F2E00EDBA70 /* curve_helper.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {811, 2595}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29DB0B965F2E00EDBA70 /* curveset.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1395}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29DD0B965F2E00EDBA70 /* distance.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {839, 1935}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29DF0B965F2E00EDBA70 /* exception.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1470}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29E10B965F2E00EDBA70 /* gamma.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {818, 1635}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29E20B965F2E00EDBA70 /* general.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {902, 2460}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29E40B965F2E00EDBA70 /* gradient.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1560}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29E60B965F2E00EDBA70 /* guid.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {790, 2130}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29E70B965F2E00EDBA70 /* guidset.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 930}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29E90B965F2E00EDBA70 /* importer.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1070, 1860}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29EA0B965F2E00EDBA70 /* interpolation.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 810}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29EC0B965F2E00EDBA70 /* keyframe.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1935}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29EE0B965F2E00EDBA70 /* layer.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1049, 6825}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29F00B965F2E00EDBA70 /* layer_bitmap.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1014, 1185}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29F20B965F2E00EDBA70 /* layer_composite.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {965, 1425}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29F40B965F2E00EDBA70 /* layer_mime.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {965, 1140}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29F60B965F2E00EDBA70 /* layer_motionblur.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {965, 1080}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29F80B965F2E00EDBA70 /* layer_pastecanvas.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {965, 1800}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29FA0B965F2E00EDBA70 /* layer_polygon.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1455}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29FC0B965F2E00EDBA70 /* layer_shape.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {965, 1785}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF29FE0B965F2E00EDBA70 /* layer_solidcolor.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {965, 1080}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A450B965F2F00EDBA70 /* listimporter.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1095}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A470B965F2F00EDBA70 /* loadcanvas.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {818, 2850}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A490B965F2F00EDBA70 /* main.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 945}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A4D0B965F2F00EDBA70 /* module.cpp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {958, 2835}}";
+ sepNavSelRange = "{1168, 0}";
+ sepNavVisRect = "{{0, 2595}, {675, 221}}";
+ };
+ };
+ A6AF2A4E0B965F2F00EDBA70 /* module.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1539, 2595}}";
+ sepNavSelRange = "{263, 0}";
+ sepNavVisRect = "{{0, 585}, {675, 76}}";
+ };
+ };
+ A6AF2A500B965F2F00EDBA70 /* mutex.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1785}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A520B965F2F00EDBA70 /* node.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 3675}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A540B965F2F00EDBA70 /* palette.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1425}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A560B965F2F00EDBA70 /* paramdesc.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {713, 3420}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A590B965F2F00EDBA70 /* polynomial_root.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {797, 1815}}";
+ sepNavSelRange = "{1715, 0}";
+ sepNavVisRect = "{{0, 645}, {675, 76}}";
+ };
+ };
+ A6AF2A600B965F2F00EDBA70 /* protocol.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1035}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A610B965F2F00EDBA70 /* real.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 630}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A630B965F2F00EDBA70 /* rect.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {720, 2625}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A650B965F2F00EDBA70 /* renddesc.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {804, 4815}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A670B965F2F00EDBA70 /* render.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {783, 1005}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A680B965F2F00EDBA70 /* savecanvas.cpp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1112, 11460}}";
+ sepNavSelRange = "{1691, 0}";
+ sepNavVisRect = "{{0, 733}, {822, 279}}";
+ };
+ };
+ A6AF2A690B965F2F00EDBA70 /* savecanvas.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 825}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A6A0B965F2F00EDBA70 /* segment.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1020}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A6B0B965F2F00EDBA70 /* smartfile.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 795}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A6C0B965F2F00EDBA70 /* string.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 945}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A6D0B965F2F00EDBA70 /* string_decl.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 885}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A6F0B965F2F00EDBA70 /* surface.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {993, 2400}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A700B965F2F00EDBA70 /* surfacenew.cpp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {622, 10605}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {471, 83}}";
+ };
+ };
+ A6AF2A710B965F2F00EDBA70 /* surfacenew.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {822, 6015}}";
+ sepNavSelRange = "{2791, 0}";
+ sepNavVisRect = "{{0, 1688}, {822, 279}}";
+ };
+ };
+ A6AF2A720B965F2F00EDBA70 /* synfig.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 2085}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A750B965F2F00EDBA70 /* target.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1042, 2475}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A770B965F2F00EDBA70 /* target_multi.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1035}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A790B965F2F00EDBA70 /* target_null.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1080}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A7B0B965F2F00EDBA70 /* target_null_tile.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {692, 1005}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A7D0B965F2F00EDBA70 /* target_scanline.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1515}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A7F0B965F2F00EDBA70 /* target_tile.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1830}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A810B965F2F00EDBA70 /* time.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {937, 2490}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ sepNavWindowFrame = "{{160, 331}, {685, 437}}";
+ };
+ };
+ A6AF2A830B965F2F00EDBA70 /* timepointcollect.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {958, 825}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A850B965F2F00EDBA70 /* transform.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1305}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A860B965F2F00EDBA70 /* types.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 720}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A880B965F2F00EDBA70 /* uniqueid.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1380}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A8A0B965F2F00EDBA70 /* value.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {713, 6870}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A8C0B965F2F00EDBA70 /* valuenode.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {860, 5820}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A8E0B965F2F00EDBA70 /* valuenode_animated.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1770}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A900B965F2F00EDBA70 /* valuenode_bline.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1485}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A920B965F2F00EDBA70 /* valuenode_composite.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1170}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A940B965F2F00EDBA70 /* valuenode_const.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1155}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A960B965F2F00EDBA70 /* valuenode_dynamiclist.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {804, 3690}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A980B965F2F00EDBA70 /* valuenode_gradientrotate.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1560}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A9A0B965F2F00EDBA70 /* valuenode_linear.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1245}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A9C0B965F2F00EDBA70 /* valuenode_radialcomposite.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1170}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2A9E0B965F2F00EDBA70 /* valuenode_reference.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1290}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2AA00B965F2F00EDBA70 /* valuenode_scale.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1560}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2AA20B965F2F00EDBA70 /* valuenode_segcalctangent.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1260}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2AA40B965F2F00EDBA70 /* valuenode_segcalcvertex.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1275}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2AA60B965F2F00EDBA70 /* valuenode_sine.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1245}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2AA80B965F2F00EDBA70 /* valuenode_stripes.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1545}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2AAA0B965F2F00EDBA70 /* valuenode_subtract.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1650}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2AAC0B965F2F00EDBA70 /* valuenode_timedswap.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1515}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2AAE0B965F2F00EDBA70 /* valuenode_twotone.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 1545}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2AAF0B965F2F00EDBA70 /* vector.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {846, 4290}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2AB00B965F2F00EDBA70 /* version.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1196, 1170}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2AB20B965F2F00EDBA70 /* waypoint.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {867, 3855}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 76}}";
+ };
+ };
+ A6AF2AB30B965F2F00EDBA70 /* template.cpp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {573, 825}}";
+ sepNavSelRange = "{1004, 13}";
+ sepNavVisRect = "{{0, 375}, {471, 83}}";
+ sepNavWindowFrame = "{{207, 289}, {685, 437}}";
+ };
+ };
+ A6AF2ABA0B965F2F00EDBA70 /* main.cpp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1203, 16680}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {675, 221}}";
+ };
+ };
+ A6AF2FAA0B96608300EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "error: '::memcpy' has not been declared";
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ rLen = 1;
+ rLoc = 78;
+ rType = 1;
+ };
+ A6AF2FAB0B96608300EDBA70 /* cstring */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.cpp.h;
+ name = cstring;
+ path = "/usr/include/c++/4.0.0/cstring";
+ sourceTree = "<absolute>";
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {559, 1935}}";
+ sepNavSelRange = "{2380, 18}";
+ sepNavVisRect = "{{0, 689}, {471, 83}}";
+ };
+ };
+ A6AF2FAC0B96608300EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAD0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 190;
+ vrLoc = 2319;
+ };
+ A6AF2FAD0B96608300EDBA70 /* cstring */ = {
+ isa = PBXFileReference;
+ name = cstring;
+ path = "/usr/include/c++/4.0.0/cstring";
+ sourceTree = "<absolute>";
+ };
+ A6AF2FB00B9660CB00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 545;
+ vrLoc = 0;
+ };
+ A6AF2FB10B9660CB00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FB20B9660CB00EDBA70 /* ctime */;
+ name = "(null): 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 545;
+ vrLoc = 0;
+ };
+ A6AF2FB20B9660CB00EDBA70 /* ctime */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.cpp.h;
+ name = ctime;
+ path = "/usr/include/c++/4.0.0/ctime";
+ sourceTree = "<absolute>";
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {822, 1230}}";
+ sepNavSelRange = "{1952, 0}";
+ sepNavVisRect = "{{0, 537}, {822, 294}}";
+ };
+ };
+ A6AF2FB30B9660CB00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "Precompiling /System/Library/Frameworks/Carbon.framework/Headers/Carbon.h";
+ fRef = A6AF2FB40B9660CB00EDBA70 /* Carbon.h */;
+ rLen = 0;
+ rLoc = 0;
+ rType = 1;
+ };
+ A6AF2FB40B9660CB00EDBA70 /* Carbon.h */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.h;
+ name = Carbon.h;
+ path = /System/Library/Frameworks/Carbon.framework/Headers/Carbon.h;
+ sourceTree = "<absolute>";
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {822, 1230}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {822, 294}}";
+ };
+ };
+ A6AF2FB50B9660CB00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 545;
+ vrLoc = 0;
+ };
+ A6AF2FB60B9660CB00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FB70B9660CB00EDBA70 /* ctime */;
+ name = "(null): 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 545;
+ vrLoc = 0;
+ };
+ A6AF2FB70B9660CB00EDBA70 /* ctime */ = {
+ isa = PBXFileReference;
+ name = ctime;
+ path = "/usr/include/c++/4.0.0/ctime";
+ sourceTree = "<absolute>";
+ };
+ A6AF2FB80B9660CB00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FB90B9660CB00EDBA70 /* Carbon.h */;
+ name = "(null): 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 474;
+ vrLoc = 0;
+ };
+ A6AF2FB90B9660CB00EDBA70 /* Carbon.h */ = {
+ isa = PBXFileReference;
+ name = Carbon.h;
+ path = /System/Library/Frameworks/Carbon.framework/Headers/Carbon.h;
+ sourceTree = "<absolute>";
+ };
+ A6AF2FBB0B96614500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FB40B9660CB00EDBA70 /* Carbon.h */;
+ name = "Carbon.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 474;
+ vrLoc = 0;
+ };
+ A6AF2FBC0B96614500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 889;
+ vrLoc = 0;
+ };
+ A6AF2FBD0B96614500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "Distributing compilation of /Users/darco/Projects/Voria/synfig-core/src/synfig/activepoint.cpp";
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ rLen = 0;
+ rLoc = 0;
+ rType = 1;
+ };
+ A6AF2FBE0B96614500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FB40B9660CB00EDBA70 /* Carbon.h */;
+ name = "Carbon.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 474;
+ vrLoc = 0;
+ };
+ A6AF2FBF0B96614500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 322;
+ vrLoc = 2262;
+ };
+ A6AF2FC00B96614500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "activepoint.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 373;
+ vrLoc = 961;
+ };
+ A6AF2FC10B96614500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 889;
+ vrLoc = 0;
+ };
+ A6AF2FC20B96614500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "activepoint.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 800;
+ vrLoc = 0;
+ };
+ A6AF2FC60B96616500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "activepoint.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 800;
+ vrLoc = 0;
+ };
+ A6AF2FC80B96618900EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "activepoint.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 800;
+ vrLoc = 0;
+ };
+ A6AF2FC90B96618900EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "error: '::memcpy' has not been declared";
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ rLen = 1;
+ rLoc = 78;
+ rType = 1;
+ };
+ A6AF2FCA0B96618900EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "activepoint.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 800;
+ vrLoc = 0;
+ };
+ A6AF2FCB0B96618900EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 708;
+ vrLoc = 1191;
+ };
+ A6AF2FCD0B96619A00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "error: '::memcpy' has not been declared";
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ rLen = 1;
+ rLoc = 78;
+ rType = 1;
+ };
+ A6AF2FCE0B96619A00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 322;
+ vrLoc = 2262;
+ };
+ A6AF2FD40B96626800EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "{ return memchr(const_cast<const void*>(__p), __c, __n); }";
+ rLen = 61;
+ rLoc = 2771;
+ rType = 0;
+ vrLen = 397;
+ vrLoc = 2603;
+ };
+ A6AF2FD50B96626800EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "error: '::clock_t' has not been declared";
+ fRef = A6AF2FB20B9660CB00EDBA70 /* ctime */;
+ rLen = 1;
+ rLoc = 65;
+ rType = 1;
+ };
+ A6AF2FD60B96626800EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "{ return memchr(const_cast<const void*>(__p), __c, __n); }";
+ rLen = 61;
+ rLoc = 2771;
+ rType = 0;
+ vrLen = 397;
+ vrLoc = 2603;
+ };
+ A6AF2FD70B96626800EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FB20B9660CB00EDBA70 /* ctime */;
+ name = "ctime: 51";
+ rLen = 0;
+ rLoc = 1952;
+ rType = 0;
+ vrLen = 570;
+ vrLoc = 1507;
+ };
+ A6AF2FD90B9662F600EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FB20B9660CB00EDBA70 /* ctime */;
+ name = "ctime: 51";
+ rLen = 0;
+ rLoc = 1952;
+ rType = 0;
+ vrLen = 570;
+ vrLoc = 1507;
+ };
+ A6AF2FDA0B9662F600EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "error: '::memcpy' has not been declared";
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ rLen = 1;
+ rLoc = 78;
+ rType = 1;
+ };
+ A6AF2FDB0B9662F600EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FB20B9660CB00EDBA70 /* ctime */;
+ name = "ctime: 51";
+ rLen = 0;
+ rLoc = 1952;
+ rType = 0;
+ vrLen = 570;
+ vrLoc = 1507;
+ };
+ A6AF2FDC0B9662F600EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 0;
+ vrLoc = 0;
+ };
+ A6AF2FE30B9663F500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FE40B9663F500EDBA70 /* template.cpp */;
+ name = "(null): 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 193;
+ vrLoc = 0;
+ };
+ A6AF2FE40B9663F500EDBA70 /* template.cpp */ = {
+ isa = PBXFileReference;
+ name = template.cpp;
+ path = "/Users/darco/Projects/Voria/synfig-core/src/template.cpp";
+ sourceTree = "<absolute>";
+ };
+ A6AF2FE50B9663F500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29D10B965F2E00EDBA70 /* canvas.cpp */;
+ name = "canvas.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 207;
+ vrLoc = 0;
+ };
+ A6AF2FE60B9663F500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "activepoint.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 52;
+ vrLoc = 1052;
+ };
+ A6AF2FE70B9663F500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CC0B965F2E00EDBA70 /* angle.h */;
+ name = "angle.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 188;
+ vrLoc = 0;
+ };
+ A6AF2FE80B9663F500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "error: '::memcpy' has not been declared";
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ rLen = 1;
+ rLoc = 78;
+ rType = 1;
+ };
+ A6AF2FE90B9663F500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FEA0B9663F500EDBA70 /* template.cpp */;
+ name = "(null): 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 193;
+ vrLoc = 0;
+ };
+ A6AF2FEA0B9663F500EDBA70 /* template.cpp */ = {
+ isa = PBXFileReference;
+ name = template.cpp;
+ path = "/Users/darco/Projects/Voria/synfig-core/src/template.cpp";
+ sourceTree = "<absolute>";
+ };
+ A6AF2FEB0B9663F500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "activepoint.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 52;
+ vrLoc = 1052;
+ };
+ A6AF2FEC0B9663F500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 71;
+ vrLoc = 2364;
+ };
+ A6AF2FED0B9663F500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "activepoint.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 52;
+ vrLoc = 1052;
+ };
+ A6AF2FEE0B9663F500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 71;
+ vrLoc = 2364;
+ };
+ A6AF2FEF0B9663F500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CC0B965F2E00EDBA70 /* angle.h */;
+ name = "angle.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 188;
+ vrLoc = 0;
+ };
+ A6AF2FF00B9663F500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 91;
+ vrLoc = 2363;
+ };
+ A6AF303E0B9666C700EDBA70 /* signal_base.h */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.h;
+ name = signal_base.h;
+ path = "/Users/darco/Projects/Voria/synfig-core/../../../Library/Frameworks/sigc++.framework/Headers/signal_base.h";
+ sourceTree = "<absolute>";
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {846, 4515}}";
+ sepNavSelRange = "{898, 26}";
+ sepNavVisRect = "{{0, 299}, {822, 137}}";
+ sepNavWindowFrame = "{{184, 310}, {685, 437}}";
+ };
+ };
+ A6AF30400B9666E100EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 158;
+ vrLoc = 2333;
+ };
+ A6AF30410B9666E100EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "error: sigc++config.h: No such file or directory";
+ fRef = A6AF30420B9666E100EDBA70 /* signal_base.h */;
+ rLen = 1;
+ rLoc = 24;
+ rType = 1;
+ };
+ A6AF30420B9666E100EDBA70 /* signal_base.h */ = {
+ isa = PBXFileReference;
+ name = signal_base.h;
+ path = "/Users/darco/Projects/Voria/synfig-core/../../../Library/Frameworks/sigc++.framework/Headers/signal_base.h";
+ sourceTree = "<absolute>";
+ };
+ A6AF30430B9666E100EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 158;
+ vrLoc = 2333;
+ };
+ A6AF30440B9666E100EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF303E0B9666C700EDBA70 /* signal_base.h */;
+ name = "#include <sigc++config.h>";
+ rLen = 26;
+ rLoc = 898;
+ rType = 0;
+ vrLen = 236;
+ vrLoc = 822;
+ };
+ A6AF30450B96670D00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF303E0B9666C700EDBA70 /* signal_base.h */;
+ name = "#include <sigc++config.h>";
+ rLen = 26;
+ rLoc = 898;
+ rType = 0;
+ vrLen = 236;
+ vrLoc = 822;
+ };
+ A6AF30740B96688E00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 158;
+ vrLoc = 2333;
+ };
+ A6AF30750B96688E00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "error: sigc++/signal_base.h: No such file or directory";
+ fRef = A6AF30760B96688E00EDBA70 /* signal.h */;
+ rLen = 1;
+ rLoc = 7;
+ rType = 1;
+ };
+ A6AF30760B96688E00EDBA70 /* signal.h */ = {
+ isa = PBXFileReference;
+ name = signal.h;
+ path = "/Users/darco/Projects/Voria/synfig-core/../../../Library/Frameworks/sigc++.framework/Headers/signal.h";
+ sourceTree = "<absolute>";
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {2785, 49710}}";
+ sepNavSelRange = "{139421, 0}";
+ sepNavVisRect = "{{0, 0}, {822, 137}}";
+ };
+ };
+ A6AF30770B96688E00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 158;
+ vrLoc = 2333;
+ };
+ A6AF30780B96688E00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF30790B96688E00EDBA70 /* signal.h */;
+ name = "#include <sigc++/signal_base.h>";
+ rLen = 32;
+ rLoc = 118;
+ rType = 0;
+ vrLen = 212;
+ vrLoc = 0;
+ };
+ A6AF30790B96688E00EDBA70 /* signal.h */ = {
+ isa = PBXFileReference;
+ name = signal.h;
+ path = "/Users/darco/Projects/Voria/synfig-core/../../../Library/Frameworks/sigc++.framework/Headers/signal.h";
+ sourceTree = "<absolute>";
+ };
+ A6AF308B0B96691000EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF30760B96688E00EDBA70 /* signal.h */;
+ name = "signal.h: 3314";
+ rLen = 0;
+ rLoc = 139421;
+ rType = 0;
+ vrLen = 212;
+ vrLoc = 0;
+ };
+ A6AF308C0B96691000EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "error: sigc++config.h: No such file or directory";
+ fRef = A6AF308D0B96691000EDBA70 /* adaptor_trait.h */;
+ rLen = 1;
+ rLoc = 4;
+ rType = 1;
+ };
+ A6AF308D0B96691000EDBA70 /* adaptor_trait.h */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.h;
+ name = adaptor_trait.h;
+ path = "/Users/darco/Projects/Voria/synfig-core/../../../Library/Frameworks/sigc++.framework/Headers/adaptors/adaptor_trait.h";
+ sourceTree = "<absolute>";
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {986, 5490}}";
+ sepNavSelRange = "{15138, 0}";
+ sepNavVisRect = "{{0, 0}, {471, 83}}";
+ };
+ };
+ A6AF308E0B96691000EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF30760B96688E00EDBA70 /* signal.h */;
+ name = "signal.h: 3314";
+ rLen = 0;
+ rLoc = 139421;
+ rType = 0;
+ vrLen = 212;
+ vrLoc = 0;
+ };
+ A6AF308F0B96691000EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF30900B96691000EDBA70 /* adaptor_trait.h */;
+ name = "#include \"sigc++config.h\" //To get SIGC_TEMPLATE_KEYWORD_OPERATOR_OVERLOAD";
+ rLen = 75;
+ rLoc = 148;
+ rType = 0;
+ vrLen = 419;
+ vrLoc = 0;
+ };
+ A6AF30900B96691000EDBA70 /* adaptor_trait.h */ = {
+ isa = PBXFileReference;
+ name = adaptor_trait.h;
+ path = "/Users/darco/Projects/Voria/synfig-core/../../../Library/Frameworks/sigc++.framework/Headers/adaptors/adaptor_trait.h";
+ sourceTree = "<absolute>";
+ };
+ A6AF30A30B966B1700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF308D0B96691000EDBA70 /* adaptor_trait.h */;
+ name = "adaptor_trait.h: 366";
+ rLen = 0;
+ rLoc = 15138;
+ rType = 0;
+ vrLen = 426;
+ vrLoc = 0;
+ };
+ A6AF30A40B966B1700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A590B965F2F00EDBA70 /* polynomial_root.h */;
+ name = "polynomial_root.h: 46";
+ rLen = 0;
+ rLoc = 1715;
+ rType = 0;
+ vrLen = 609;
+ vrLoc = 1252;
+ };
+ A6AF30A50B966B1700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF30A60B966B1700EDBA70 /* errno.h */;
+ name = "#define errno (*__error())";
+ rLen = 27;
+ rLoc = 3353;
+ rType = 0;
+ vrLen = 333;
+ vrLoc = 3189;
+ };
+ A6AF30A60B966B1700EDBA70 /* errno.h */ = {
+ isa = PBXFileReference;
+ name = errno.h;
+ path = /usr/include/sys/errno.h;
+ sourceTree = "<absolute>";
+ };
+ A6AF30A70B966B1700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A680B965F2F00EDBA70 /* savecanvas.cpp */;
+ name = "savecanvas.cpp: 59";
+ rLen = 0;
+ rLoc = 1691;
+ rType = 0;
+ vrLen = 435;
+ vrLoc = 1493;
+ };
+ A6AF30A80B966B1700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A710B965F2F00EDBA70 /* surfacenew.h */;
+ name = "surfacenew.h: w_";
+ rLen = 0;
+ rLoc = 2791;
+ rType = 0;
+ vrLen = 251;
+ vrLoc = 2584;
+ };
+ A6AF30A90B966B1700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "error: expected namespace-name before ';' token";
+ fRef = A6AF2AB30B965F2F00EDBA70 /* template.cpp */;
+ rLen = 1;
+ rLoc = 40;
+ rType = 1;
+ };
+ A6AF30AA0B966B1700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF308D0B96691000EDBA70 /* adaptor_trait.h */;
+ name = "adaptor_trait.h: 366";
+ rLen = 0;
+ rLoc = 15138;
+ rType = 0;
+ vrLen = 426;
+ vrLoc = 0;
+ };
+ A6AF30AB0B966B1700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A590B965F2F00EDBA70 /* polynomial_root.h */;
+ name = "polynomial_root.h: 46";
+ rLen = 0;
+ rLoc = 1715;
+ rType = 0;
+ vrLen = 609;
+ vrLoc = 1252;
+ };
+ A6AF30AC0B966B1700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A680B965F2F00EDBA70 /* savecanvas.cpp */;
+ name = "savecanvas.cpp: 59";
+ rLen = 0;
+ rLoc = 1691;
+ rType = 0;
+ vrLen = 435;
+ vrLoc = 1493;
+ };
+ A6AF30AD0B966B1700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A710B965F2F00EDBA70 /* surfacenew.h */;
+ name = "surfacenew.h: w_";
+ rLen = 0;
+ rLoc = 2791;
+ rType = 0;
+ vrLen = 251;
+ vrLoc = 2584;
+ };
+ A6AF30AE0B966B1700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB30B965F2F00EDBA70 /* template.cpp */;
+ name = "using namespace etl;";
+ rLen = 21;
+ rLoc = 1187;
+ rType = 0;
+ vrLen = 620;
+ vrLoc = 1018;
+ };
+ A6AF30B20B966B2700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 69;
+ vrLoc = 1899;
+ };
+ A6AF30B30B966B2700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF308D0B96691000EDBA70 /* adaptor_trait.h */;
+ name = "adaptor_trait.h: 366";
+ rLen = 0;
+ rLoc = 15138;
+ rType = 0;
+ vrLen = 261;
+ vrLoc = 0;
+ };
+ A6AF30B40B966B2700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A700B965F2F00EDBA70 /* surfacenew.cpp */;
+ name = "surfacenew.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 196;
+ vrLoc = 0;
+ };
+ A6AF30B50B966B2700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2FAB0B96608300EDBA70 /* cstring */;
+ name = "using ::memcpy;";
+ rLen = 18;
+ rLoc = 2380;
+ rType = 0;
+ vrLen = 69;
+ vrLoc = 1899;
+ };
+ A6AF30B60B966B2700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF308D0B96691000EDBA70 /* adaptor_trait.h */;
+ name = "adaptor_trait.h: 366";
+ rLen = 0;
+ rLoc = 15138;
+ rType = 0;
+ vrLen = 261;
+ vrLoc = 0;
+ };
+ A6AF30B70B966B2700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A700B965F2F00EDBA70 /* surfacenew.cpp */;
+ name = "surfacenew.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 196;
+ vrLoc = 0;
+ };
+ A6AF30B80B966B2700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB30B965F2F00EDBA70 /* template.cpp */;
+ name = "template.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 196;
+ vrLoc = 0;
+ };
+ A6AF30B90B966C1800EDBA70 /* config.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {675, 3975}}";
+ sepNavSelRange = "{238, 0}";
+ sepNavVisRect = "{{0, 3732}, {675, 243}}";
+ };
+ };
+ A6AF30BB0B966C6E00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB30B965F2F00EDBA70 /* template.cpp */;
+ name = "using namespace etl;";
+ rLen = 21;
+ rLoc = 1187;
+ rType = 0;
+ vrLen = 620;
+ vrLoc = 1018;
+ };
+ A6AF30BC0B966C6E00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "error: config.h: No such file or directory";
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ rLen = 1;
+ rLoc = 28;
+ rType = 1;
+ };
+ A6AF30BD0B966C6E00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB30B965F2F00EDBA70 /* template.cpp */;
+ name = "using namespace etl;";
+ rLen = 21;
+ rLoc = 1187;
+ rType = 0;
+ vrLen = 620;
+ vrLoc = 1018;
+ };
+ A6AF30BE0B966C6E00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "#\tinclude <config.h>";
+ rLen = 21;
+ rLoc = 1024;
+ rType = 0;
+ vrLen = 580;
+ vrLoc = 672;
+ };
+ A6AF30C30B966C8700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF30B90B966C1800EDBA70 /* config.h */;
+ name = "config.h: 4";
+ rLen = 0;
+ rLoc = 160;
+ rType = 0;
+ vrLen = 176;
+ vrLoc = 239;
+ };
+ A6AF30C40B966C8700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB30B965F2F00EDBA70 /* template.cpp */;
+ name = HAVE_CONFIG_H;
+ rLen = 13;
+ rLoc = 1004;
+ rType = 0;
+ vrLen = 74;
+ vrLoc = 973;
+ };
+ A6AF30C50B966C8700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB30B965F2F00EDBA70 /* template.cpp */;
+ name = "template.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 196;
+ vrLoc = 0;
+ };
+ A6AF30C60B966C8700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF30B90B966C1800EDBA70 /* config.h */;
+ name = "config.h: 4";
+ rLen = 0;
+ rLoc = 160;
+ rType = 0;
+ vrLen = 176;
+ vrLoc = 239;
+ };
+ A6AF30C70B966C8700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB30B965F2F00EDBA70 /* template.cpp */;
+ name = HAVE_CONFIG_H;
+ rLen = 13;
+ rLoc = 1004;
+ rType = 0;
+ vrLen = 74;
+ vrLoc = 973;
+ };
+ A6AF30C80B966C8700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "#\tinclude <config.h>";
+ rLen = 21;
+ rLoc = 1024;
+ rType = 0;
+ vrLen = 99;
+ vrLoc = 979;
+ };
+ A6AF30C90B966CBD00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "#\tinclude <config.h>";
+ rLen = 21;
+ rLoc = 1024;
+ rType = 0;
+ vrLen = 580;
+ vrLoc = 672;
+ };
+ A6AF30CC0B966CD300EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "#\tinclude <config.h>";
+ rLen = 21;
+ rLoc = 1024;
+ rType = 0;
+ vrLen = 99;
+ vrLoc = 979;
+ };
+ A6AF30CF0B966D7700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "#\tinclude <config.h>";
+ rLen = 21;
+ rLoc = 1024;
+ rType = 0;
+ vrLen = 99;
+ vrLoc = 979;
+ };
+ A6AF30D00B966D7700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A4E0B965F2F00EDBA70 /* module.h */;
+ name = "module.h: 9";
+ rLen = 0;
+ rLoc = 263;
+ rType = 0;
+ vrLen = 909;
+ vrLoc = 1252;
+ };
+ A6AF30D10B966D7700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A4D0B965F2F00EDBA70 /* module.cpp */;
+ name = "module.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 865;
+ vrLoc = 0;
+ };
+ A6AF30D20B966D7700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "#\tinclude <config.h>";
+ rLen = 21;
+ rLoc = 1024;
+ rType = 0;
+ vrLen = 99;
+ vrLoc = 979;
+ };
+ A6AF30D30B966D7700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A4E0B965F2F00EDBA70 /* module.h */;
+ name = "module.h: 9";
+ rLen = 0;
+ rLoc = 263;
+ rType = 0;
+ vrLen = 909;
+ vrLoc = 1252;
+ };
+ A6AF30D40B966D7700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A4D0B965F2F00EDBA70 /* module.cpp */;
+ name = "module.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 865;
+ vrLoc = 0;
+ };
+ A6AF30D50B966D7700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF30B90B966C1800EDBA70 /* config.h */;
+ name = "config.h: 4";
+ rLen = 0;
+ rLoc = 146;
+ rType = 0;
+ vrLen = 649;
+ vrLoc = 0;
+ };
+ A6AF30E20B966F6D00EDBA70 /* Synfig Tool */ = {
+ activeExec = 0;
+ executables = (
+ A6AF30E40B966F6D00EDBA70 /* Synfig Tool */,
+ );
+ };
+ A6AF30E40B966F6D00EDBA70 /* Synfig Tool */ = {
+ isa = PBXExecutable;
+ activeArgIndex = 2147483647;
+ activeArgIndices = (
+ );
+ argumentStrings = (
+ );
+ autoAttachOnCrash = 1;
+ configStateDict = {
+ };
+ customDataFormattersEnabled = 1;
+ debuggerPlugin = GDBDebugging;
+ disassemblyDisplayState = 0;
+ enableDebugStr = 1;
+ environmentEntries = (
+ );
+ executableSystemSymbolLevel = 0;
+ executableUserSymbolLevel = 0;
+ libgmallocEnabled = 0;
+ name = "Synfig Tool";
+ sourceDirectories = (
+ );
+ };
+ A6AF30F40B96707D00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF30B90B966C1800EDBA70 /* config.h */;
+ name = USE_CF_BUNDLES;
+ rLen = 14;
+ rLoc = 132;
+ rType = 0;
+ vrLen = 646;
+ vrLoc = 0;
+ };
+ A6AF30F50B96707D00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A4D0B965F2F00EDBA70 /* module.cpp */;
+ name = "module.cpp: 40";
+ rLen = 0;
+ rLoc = 1168;
+ rType = 0;
+ vrLen = 324;
+ vrLoc = 4484;
+ };
+ A6AF30F60B96707D00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2ABA0B965F2F00EDBA70 /* main.cpp */;
+ name = "main.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 586;
+ vrLoc = 0;
+ };
+ A6AF30F70B96707D00EDBA70 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = A6AF29CB0B965F2E00EDBA70 /* activepoint.h */;
+ };
+ A6AF30F80B96707D00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF30B90B966C1800EDBA70 /* config.h */;
+ name = USE_CF_BUNDLES;
+ rLen = 14;
+ rLoc = 132;
+ rType = 0;
+ vrLen = 646;
+ vrLoc = 0;
+ };
+ A6AF30F90B96707D00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A4D0B965F2F00EDBA70 /* module.cpp */;
+ name = "module.cpp: 40";
+ rLen = 0;
+ rLoc = 1168;
+ rType = 0;
+ vrLen = 324;
+ vrLoc = 4484;
+ };
+ A6AF30FA0B96707D00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2ABA0B965F2F00EDBA70 /* main.cpp */;
+ name = "main.cpp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 586;
+ vrLoc = 0;
+ };
+ A6AF30FB0B96707D00EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CB0B965F2E00EDBA70 /* activepoint.h */;
+ name = "activepoint.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 0;
+ vrLoc = 0;
+ };
+ A6AF31540B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CB0B965F2E00EDBA70 /* activepoint.h */;
+ name = "activepoint.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 200;
+ vrLoc = 0;
+ };
+ A6AF31550B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CC0B965F2E00EDBA70 /* angle.h */;
+ name = "angle.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 188;
+ vrLoc = 0;
+ };
+ A6AF31560B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CE0B965F2E00EDBA70 /* blinepoint.h */;
+ name = "blinepoint.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 198;
+ vrLoc = 0;
+ };
+ A6AF31570B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29D00B965F2E00EDBA70 /* blur.h */;
+ name = "blur.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF31580B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29D20B965F2E00EDBA70 /* canvas.h */;
+ name = "canvas.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 202;
+ vrLoc = 0;
+ };
+ A6AF31590B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29D30B965F2E00EDBA70 /* canvasbase.h */;
+ name = "canvasbase.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 198;
+ vrLoc = 0;
+ };
+ A6AF315A0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29D50B965F2E00EDBA70 /* color.h */;
+ name = "color.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 199;
+ vrLoc = 0;
+ };
+ A6AF315B0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29D70B965F2E00EDBA70 /* context.h */;
+ name = "context.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 188;
+ vrLoc = 0;
+ };
+ A6AF315C0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29D90B965F2E00EDBA70 /* curve_helper.h */;
+ name = "curve_helper.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 206;
+ vrLoc = 0;
+ };
+ A6AF315D0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29DB0B965F2E00EDBA70 /* curveset.h */;
+ name = "curveset.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 195;
+ vrLoc = 0;
+ };
+ A6AF315E0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29DD0B965F2E00EDBA70 /* distance.h */;
+ name = "distance.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF315F0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29DF0B965F2E00EDBA70 /* exception.h */;
+ name = "exception.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 191;
+ vrLoc = 0;
+ };
+ A6AF31600B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29E10B965F2E00EDBA70 /* gamma.h */;
+ name = "gamma.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 188;
+ vrLoc = 0;
+ };
+ A6AF31610B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29E20B965F2E00EDBA70 /* general.h */;
+ name = "general.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 228;
+ vrLoc = 0;
+ };
+ A6AF31620B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29E40B965F2E00EDBA70 /* gradient.h */;
+ name = "gradient.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 199;
+ vrLoc = 0;
+ };
+ A6AF31630B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29E60B965F2E00EDBA70 /* guid.h */;
+ name = "guid.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 186;
+ vrLoc = 0;
+ };
+ A6AF31640B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29E70B965F2E00EDBA70 /* guidset.h */;
+ name = "guidset.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 192;
+ vrLoc = 0;
+ };
+ A6AF31650B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29E90B965F2E00EDBA70 /* importer.h */;
+ name = "importer.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 186;
+ vrLoc = 0;
+ };
+ A6AF31660B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29EA0B965F2E00EDBA70 /* interpolation.h */;
+ name = "interpolation.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 204;
+ vrLoc = 0;
+ };
+ A6AF31670B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29EC0B965F2E00EDBA70 /* keyframe.h */;
+ name = "keyframe.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF31680B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29EE0B965F2E00EDBA70 /* layer.h */;
+ name = "layer.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 187;
+ vrLoc = 0;
+ };
+ A6AF31690B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29F00B965F2E00EDBA70 /* layer_bitmap.h */;
+ name = "layer_bitmap.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 198;
+ vrLoc = 0;
+ };
+ A6AF316A0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29F20B965F2E00EDBA70 /* layer_composite.h */;
+ name = "layer_composite.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 225;
+ vrLoc = 0;
+ };
+ A6AF316B0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29F40B965F2E00EDBA70 /* layer_mime.h */;
+ name = "layer_mime.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 198;
+ vrLoc = 0;
+ };
+ A6AF316C0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29F60B965F2E00EDBA70 /* layer_motionblur.h */;
+ name = "layer_motionblur.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 210;
+ vrLoc = 0;
+ };
+ A6AF316D0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29F80B965F2E00EDBA70 /* layer_pastecanvas.h */;
+ name = "layer_pastecanvas.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 208;
+ vrLoc = 0;
+ };
+ A6AF316E0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29FA0B965F2E00EDBA70 /* layer_polygon.h */;
+ name = "layer_polygon.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 204;
+ vrLoc = 0;
+ };
+ A6AF316F0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29FC0B965F2E00EDBA70 /* layer_shape.h */;
+ name = "layer_shape.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 196;
+ vrLoc = 0;
+ };
+ A6AF31700B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29FE0B965F2E00EDBA70 /* layer_solidcolor.h */;
+ name = "layer_solidcolor.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 210;
+ vrLoc = 0;
+ };
+ A6AF31710B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A450B965F2F00EDBA70 /* listimporter.h */;
+ name = "listimporter.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 202;
+ vrLoc = 0;
+ };
+ A6AF31720B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A470B965F2F00EDBA70 /* loadcanvas.h */;
+ name = "loadcanvas.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 190;
+ vrLoc = 0;
+ };
+ A6AF31730B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A490B965F2F00EDBA70 /* main.h */;
+ name = "main.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 186;
+ vrLoc = 0;
+ };
+ A6AF31740B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A4E0B965F2F00EDBA70 /* module.h */;
+ name = "module.h: 9";
+ rLen = 0;
+ rLoc = 263;
+ rType = 0;
+ vrLen = 278;
+ vrLoc = 1252;
+ };
+ A6AF31750B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A500B965F2F00EDBA70 /* mutex.h */;
+ name = "mutex.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 184;
+ vrLoc = 0;
+ };
+ A6AF31760B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A520B965F2F00EDBA70 /* node.h */;
+ name = "node.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 182;
+ vrLoc = 0;
+ };
+ A6AF31770B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A540B965F2F00EDBA70 /* palette.h */;
+ name = "palette.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 192;
+ vrLoc = 0;
+ };
+ A6AF31780B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A560B965F2F00EDBA70 /* paramdesc.h */;
+ name = "paramdesc.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 211;
+ vrLoc = 0;
+ };
+ A6AF31790B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A590B965F2F00EDBA70 /* polynomial_root.h */;
+ name = "polynomial_root.h: 46";
+ rLen = 0;
+ rLoc = 1715;
+ rType = 0;
+ vrLen = 204;
+ vrLoc = 1591;
+ };
+ A6AF317A0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A600B965F2F00EDBA70 /* protocol.h */;
+ name = "protocol.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF317B0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A610B965F2F00EDBA70 /* real.h */;
+ name = "real.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 204;
+ vrLoc = 0;
+ };
+ A6AF317C0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A630B965F2F00EDBA70 /* rect.h */;
+ name = "rect.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 186;
+ vrLoc = 0;
+ };
+ A6AF317D0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A650B965F2F00EDBA70 /* renddesc.h */;
+ name = "renddesc.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF317E0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A670B965F2F00EDBA70 /* render.h */;
+ name = "render.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 190;
+ vrLoc = 0;
+ };
+ A6AF317F0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A690B965F2F00EDBA70 /* savecanvas.h */;
+ name = "savecanvas.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 190;
+ vrLoc = 0;
+ };
+ A6AF31800B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A6A0B965F2F00EDBA70 /* segment.h */;
+ name = "segment.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 192;
+ vrLoc = 0;
+ };
+ A6AF31810B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A6B0B965F2F00EDBA70 /* smartfile.h */;
+ name = "smartfile.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 196;
+ vrLoc = 0;
+ };
+ A6AF31820B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A6C0B965F2F00EDBA70 /* string.h */;
+ name = "string.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 190;
+ vrLoc = 0;
+ };
+ A6AF31830B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A6D0B965F2F00EDBA70 /* string_decl.h */;
+ name = "string_decl.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 200;
+ vrLoc = 0;
+ };
+ A6AF31840B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A6F0B965F2F00EDBA70 /* surface.h */;
+ name = "surface.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 204;
+ vrLoc = 0;
+ };
+ A6AF31850B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A720B965F2F00EDBA70 /* synfig.h */;
+ name = "synfig.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 200;
+ vrLoc = 0;
+ };
+ A6AF31860B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A750B965F2F00EDBA70 /* target.h */;
+ name = "target.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 202;
+ vrLoc = 0;
+ };
+ A6AF31870B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A770B965F2F00EDBA70 /* target_multi.h */;
+ name = "target_multi.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 202;
+ vrLoc = 0;
+ };
+ A6AF31880B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A790B965F2F00EDBA70 /* target_null.h */;
+ name = "target_null.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 200;
+ vrLoc = 0;
+ };
+ A6AF31890B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A7B0B965F2F00EDBA70 /* target_null_tile.h */;
+ name = "target_null_tile.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 210;
+ vrLoc = 0;
+ };
+ A6AF318A0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A7D0B965F2F00EDBA70 /* target_scanline.h */;
+ name = "target_scanline.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 208;
+ vrLoc = 0;
+ };
+ A6AF318B0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A7F0B965F2F00EDBA70 /* target_tile.h */;
+ name = "target_tile.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 200;
+ vrLoc = 0;
+ };
+ A6AF318C0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A810B965F2F00EDBA70 /* time.h */;
+ name = "time.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 186;
+ vrLoc = 0;
+ };
+ A6AF318D0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A830B965F2F00EDBA70 /* timepointcollect.h */;
+ name = "timepointcollect.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 210;
+ vrLoc = 0;
+ };
+ A6AF318E0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A850B965F2F00EDBA70 /* transform.h */;
+ name = "transform.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 196;
+ vrLoc = 0;
+ };
+ A6AF318F0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A860B965F2F00EDBA70 /* types.h */;
+ name = "types.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 188;
+ vrLoc = 0;
+ };
+ A6AF31900B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A880B965F2F00EDBA70 /* uniqueid.h */;
+ name = "uniqueid.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF31910B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A8A0B965F2F00EDBA70 /* value.h */;
+ name = "value.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 188;
+ vrLoc = 0;
+ };
+ A6AF31920B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A8C0B965F2F00EDBA70 /* valuenode.h */;
+ name = "valuenode.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 196;
+ vrLoc = 0;
+ };
+ A6AF31930B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A8E0B965F2F00EDBA70 /* valuenode_animated.h */;
+ name = "valuenode_animated.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 214;
+ vrLoc = 0;
+ };
+ A6AF31940B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A900B965F2F00EDBA70 /* valuenode_bline.h */;
+ name = "valuenode_bline.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 208;
+ vrLoc = 0;
+ };
+ A6AF31950B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A920B965F2F00EDBA70 /* valuenode_composite.h */;
+ name = "valuenode_composite.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 216;
+ vrLoc = 0;
+ };
+ A6AF31960B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A940B965F2F00EDBA70 /* valuenode_const.h */;
+ name = "valuenode_const.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 208;
+ vrLoc = 0;
+ };
+ A6AF31970B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A960B965F2F00EDBA70 /* valuenode_dynamiclist.h */;
+ name = "valuenode_dynamiclist.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 220;
+ vrLoc = 0;
+ };
+ A6AF31980B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A980B965F2F00EDBA70 /* valuenode_gradientrotate.h */;
+ name = "valuenode_gradientrotate.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 219;
+ vrLoc = 0;
+ };
+ A6AF31990B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A9A0B965F2F00EDBA70 /* valuenode_linear.h */;
+ name = "valuenode_linear.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 210;
+ vrLoc = 0;
+ };
+ A6AF319A0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A9C0B965F2F00EDBA70 /* valuenode_radialcomposite.h */;
+ name = "valuenode_radialcomposite.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 228;
+ vrLoc = 0;
+ };
+ A6AF319B0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A9E0B965F2F00EDBA70 /* valuenode_reference.h */;
+ name = "valuenode_reference.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 216;
+ vrLoc = 0;
+ };
+ A6AF319C0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AA00B965F2F00EDBA70 /* valuenode_scale.h */;
+ name = "valuenode_scale.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 208;
+ vrLoc = 0;
+ };
+ A6AF319D0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AA20B965F2F00EDBA70 /* valuenode_segcalctangent.h */;
+ name = "valuenode_segcalctangent.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 226;
+ vrLoc = 0;
+ };
+ A6AF319E0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AA40B965F2F00EDBA70 /* valuenode_segcalcvertex.h */;
+ name = "valuenode_segcalcvertex.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 224;
+ vrLoc = 0;
+ };
+ A6AF319F0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AA60B965F2F00EDBA70 /* valuenode_sine.h */;
+ name = "valuenode_sine.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 206;
+ vrLoc = 0;
+ };
+ A6AF31A00B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AA80B965F2F00EDBA70 /* valuenode_stripes.h */;
+ name = "valuenode_stripes.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 212;
+ vrLoc = 0;
+ };
+ A6AF31A10B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AAA0B965F2F00EDBA70 /* valuenode_subtract.h */;
+ name = "valuenode_subtract.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 214;
+ vrLoc = 0;
+ };
+ A6AF31A20B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AAC0B965F2F00EDBA70 /* valuenode_timedswap.h */;
+ name = "valuenode_timedswap.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 216;
+ vrLoc = 0;
+ };
+ A6AF31A30B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AAE0B965F2F00EDBA70 /* valuenode_twotone.h */;
+ name = "valuenode_twotone.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 212;
+ vrLoc = 0;
+ };
+ A6AF31A40B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AAF0B965F2F00EDBA70 /* vector.h */;
+ name = "vector.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 204;
+ vrLoc = 0;
+ };
+ A6AF31A50B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB00B965F2F00EDBA70 /* version.h */;
+ name = "version.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 192;
+ vrLoc = 0;
+ };
+ A6AF31A60B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB20B965F2F00EDBA70 /* waypoint.h */;
+ name = "waypoint.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF31A70B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CB0B965F2E00EDBA70 /* activepoint.h */;
+ name = "activepoint.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 200;
+ vrLoc = 0;
+ };
+ A6AF31A80B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB20B965F2F00EDBA70 /* waypoint.h */;
+ name = "waypoint.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF31A90B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CB0B965F2E00EDBA70 /* activepoint.h */;
+ name = "activepoint.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 200;
+ vrLoc = 0;
+ };
+ A6AF31AA0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CC0B965F2E00EDBA70 /* angle.h */;
+ name = "angle.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 188;
+ vrLoc = 0;
+ };
+ A6AF31AB0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CE0B965F2E00EDBA70 /* blinepoint.h */;
+ name = "blinepoint.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 198;
+ vrLoc = 0;
+ };
+ A6AF31AC0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29D00B965F2E00EDBA70 /* blur.h */;
+ name = "blur.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF31AD0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29D20B965F2E00EDBA70 /* canvas.h */;
+ name = "canvas.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 202;
+ vrLoc = 0;
+ };
+ A6AF31AE0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29D30B965F2E00EDBA70 /* canvasbase.h */;
+ name = "canvasbase.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 198;
+ vrLoc = 0;
+ };
+ A6AF31AF0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29D50B965F2E00EDBA70 /* color.h */;
+ name = "color.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 199;
+ vrLoc = 0;
+ };
+ A6AF31B00B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29D70B965F2E00EDBA70 /* context.h */;
+ name = "context.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 188;
+ vrLoc = 0;
+ };
+ A6AF31B10B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29D90B965F2E00EDBA70 /* curve_helper.h */;
+ name = "curve_helper.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 206;
+ vrLoc = 0;
+ };
+ A6AF31B20B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29DB0B965F2E00EDBA70 /* curveset.h */;
+ name = "curveset.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 195;
+ vrLoc = 0;
+ };
+ A6AF31B30B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29DD0B965F2E00EDBA70 /* distance.h */;
+ name = "distance.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF31B40B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29DF0B965F2E00EDBA70 /* exception.h */;
+ name = "exception.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 191;
+ vrLoc = 0;
+ };
+ A6AF31B50B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29E10B965F2E00EDBA70 /* gamma.h */;
+ name = "gamma.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 188;
+ vrLoc = 0;
+ };
+ A6AF31B60B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29E20B965F2E00EDBA70 /* general.h */;
+ name = "general.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 228;
+ vrLoc = 0;
+ };
+ A6AF31B70B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29E40B965F2E00EDBA70 /* gradient.h */;
+ name = "gradient.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 199;
+ vrLoc = 0;
+ };
+ A6AF31B80B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29E60B965F2E00EDBA70 /* guid.h */;
+ name = "guid.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 186;
+ vrLoc = 0;
+ };
+ A6AF31B90B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29E70B965F2E00EDBA70 /* guidset.h */;
+ name = "guidset.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 192;
+ vrLoc = 0;
+ };
+ A6AF31BA0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29E90B965F2E00EDBA70 /* importer.h */;
+ name = "importer.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 186;
+ vrLoc = 0;
+ };
+ A6AF31BB0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29EA0B965F2E00EDBA70 /* interpolation.h */;
+ name = "interpolation.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 204;
+ vrLoc = 0;
+ };
+ A6AF31BC0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29EC0B965F2E00EDBA70 /* keyframe.h */;
+ name = "keyframe.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF31BD0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29EE0B965F2E00EDBA70 /* layer.h */;
+ name = "layer.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 187;
+ vrLoc = 0;
+ };
+ A6AF31BE0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29F00B965F2E00EDBA70 /* layer_bitmap.h */;
+ name = "layer_bitmap.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 198;
+ vrLoc = 0;
+ };
+ A6AF31BF0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29F20B965F2E00EDBA70 /* layer_composite.h */;
+ name = "layer_composite.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 225;
+ vrLoc = 0;
+ };
+ A6AF31C00B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29F40B965F2E00EDBA70 /* layer_mime.h */;
+ name = "layer_mime.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 198;
+ vrLoc = 0;
+ };
+ A6AF31C10B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29F60B965F2E00EDBA70 /* layer_motionblur.h */;
+ name = "layer_motionblur.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 210;
+ vrLoc = 0;
+ };
+ A6AF31C20B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29F80B965F2E00EDBA70 /* layer_pastecanvas.h */;
+ name = "layer_pastecanvas.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 208;
+ vrLoc = 0;
+ };
+ A6AF31C30B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29FA0B965F2E00EDBA70 /* layer_polygon.h */;
+ name = "layer_polygon.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 204;
+ vrLoc = 0;
+ };
+ A6AF31C40B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29FC0B965F2E00EDBA70 /* layer_shape.h */;
+ name = "layer_shape.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 196;
+ vrLoc = 0;
+ };
+ A6AF31C50B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29FE0B965F2E00EDBA70 /* layer_solidcolor.h */;
+ name = "layer_solidcolor.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 210;
+ vrLoc = 0;
+ };
+ A6AF31C60B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A450B965F2F00EDBA70 /* listimporter.h */;
+ name = "listimporter.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 202;
+ vrLoc = 0;
+ };
+ A6AF31C70B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A470B965F2F00EDBA70 /* loadcanvas.h */;
+ name = "loadcanvas.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 190;
+ vrLoc = 0;
+ };
+ A6AF31C80B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A490B965F2F00EDBA70 /* main.h */;
+ name = "main.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 186;
+ vrLoc = 0;
+ };
+ A6AF31C90B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A4E0B965F2F00EDBA70 /* module.h */;
+ name = "module.h: 9";
+ rLen = 0;
+ rLoc = 263;
+ rType = 0;
+ vrLen = 278;
+ vrLoc = 1252;
+ };
+ A6AF31CA0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A500B965F2F00EDBA70 /* mutex.h */;
+ name = "mutex.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 184;
+ vrLoc = 0;
+ };
+ A6AF31CB0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A520B965F2F00EDBA70 /* node.h */;
+ name = "node.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 182;
+ vrLoc = 0;
+ };
+ A6AF31CC0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A540B965F2F00EDBA70 /* palette.h */;
+ name = "palette.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 192;
+ vrLoc = 0;
+ };
+ A6AF31CD0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A560B965F2F00EDBA70 /* paramdesc.h */;
+ name = "paramdesc.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 211;
+ vrLoc = 0;
+ };
+ A6AF31CE0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A590B965F2F00EDBA70 /* polynomial_root.h */;
+ name = "polynomial_root.h: 46";
+ rLen = 0;
+ rLoc = 1715;
+ rType = 0;
+ vrLen = 204;
+ vrLoc = 1591;
+ };
+ A6AF31CF0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A600B965F2F00EDBA70 /* protocol.h */;
+ name = "protocol.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF31D00B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A610B965F2F00EDBA70 /* real.h */;
+ name = "real.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 204;
+ vrLoc = 0;
+ };
+ A6AF31D10B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A630B965F2F00EDBA70 /* rect.h */;
+ name = "rect.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 186;
+ vrLoc = 0;
+ };
+ A6AF31D20B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A650B965F2F00EDBA70 /* renddesc.h */;
+ name = "renddesc.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF31D30B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A670B965F2F00EDBA70 /* render.h */;
+ name = "render.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 190;
+ vrLoc = 0;
+ };
+ A6AF31D40B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A690B965F2F00EDBA70 /* savecanvas.h */;
+ name = "savecanvas.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 190;
+ vrLoc = 0;
+ };
+ A6AF31D50B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A6A0B965F2F00EDBA70 /* segment.h */;
+ name = "segment.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 192;
+ vrLoc = 0;
+ };
+ A6AF31D60B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A6B0B965F2F00EDBA70 /* smartfile.h */;
+ name = "smartfile.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 196;
+ vrLoc = 0;
+ };
+ A6AF31D70B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A6C0B965F2F00EDBA70 /* string.h */;
+ name = "string.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 190;
+ vrLoc = 0;
+ };
+ A6AF31D80B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A6D0B965F2F00EDBA70 /* string_decl.h */;
+ name = "string_decl.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 200;
+ vrLoc = 0;
+ };
+ A6AF31D90B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A6F0B965F2F00EDBA70 /* surface.h */;
+ name = "surface.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 204;
+ vrLoc = 0;
+ };
+ A6AF31DA0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A720B965F2F00EDBA70 /* synfig.h */;
+ name = "synfig.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 200;
+ vrLoc = 0;
+ };
+ A6AF31DB0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A750B965F2F00EDBA70 /* target.h */;
+ name = "target.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 202;
+ vrLoc = 0;
+ };
+ A6AF31DC0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A770B965F2F00EDBA70 /* target_multi.h */;
+ name = "target_multi.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 202;
+ vrLoc = 0;
+ };
+ A6AF31DD0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A790B965F2F00EDBA70 /* target_null.h */;
+ name = "target_null.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 200;
+ vrLoc = 0;
+ };
+ A6AF31DE0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A7B0B965F2F00EDBA70 /* target_null_tile.h */;
+ name = "target_null_tile.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 210;
+ vrLoc = 0;
+ };
+ A6AF31DF0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A7D0B965F2F00EDBA70 /* target_scanline.h */;
+ name = "target_scanline.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 208;
+ vrLoc = 0;
+ };
+ A6AF31E00B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A7F0B965F2F00EDBA70 /* target_tile.h */;
+ name = "target_tile.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 200;
+ vrLoc = 0;
+ };
+ A6AF31E10B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A810B965F2F00EDBA70 /* time.h */;
+ name = "time.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 186;
+ vrLoc = 0;
+ };
+ A6AF31E20B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A830B965F2F00EDBA70 /* timepointcollect.h */;
+ name = "timepointcollect.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 210;
+ vrLoc = 0;
+ };
+ A6AF31E30B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A850B965F2F00EDBA70 /* transform.h */;
+ name = "transform.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 196;
+ vrLoc = 0;
+ };
+ A6AF31E40B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A860B965F2F00EDBA70 /* types.h */;
+ name = "types.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 188;
+ vrLoc = 0;
+ };
+ A6AF31E50B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A880B965F2F00EDBA70 /* uniqueid.h */;
+ name = "uniqueid.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF31E60B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A8A0B965F2F00EDBA70 /* value.h */;
+ name = "value.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 188;
+ vrLoc = 0;
+ };
+ A6AF31E70B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A8C0B965F2F00EDBA70 /* valuenode.h */;
+ name = "valuenode.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 196;
+ vrLoc = 0;
+ };
+ A6AF31E80B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A8E0B965F2F00EDBA70 /* valuenode_animated.h */;
+ name = "valuenode_animated.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 214;
+ vrLoc = 0;
+ };
+ A6AF31E90B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A900B965F2F00EDBA70 /* valuenode_bline.h */;
+ name = "valuenode_bline.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 208;
+ vrLoc = 0;
+ };
+ A6AF31EA0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A920B965F2F00EDBA70 /* valuenode_composite.h */;
+ name = "valuenode_composite.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 216;
+ vrLoc = 0;
+ };
+ A6AF31EB0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A940B965F2F00EDBA70 /* valuenode_const.h */;
+ name = "valuenode_const.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 208;
+ vrLoc = 0;
+ };
+ A6AF31EC0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A960B965F2F00EDBA70 /* valuenode_dynamiclist.h */;
+ name = "valuenode_dynamiclist.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 220;
+ vrLoc = 0;
+ };
+ A6AF31ED0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A980B965F2F00EDBA70 /* valuenode_gradientrotate.h */;
+ name = "valuenode_gradientrotate.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 219;
+ vrLoc = 0;
+ };
+ A6AF31EE0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A9A0B965F2F00EDBA70 /* valuenode_linear.h */;
+ name = "valuenode_linear.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 210;
+ vrLoc = 0;
+ };
+ A6AF31EF0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A9C0B965F2F00EDBA70 /* valuenode_radialcomposite.h */;
+ name = "valuenode_radialcomposite.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 228;
+ vrLoc = 0;
+ };
+ A6AF31F00B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2A9E0B965F2F00EDBA70 /* valuenode_reference.h */;
+ name = "valuenode_reference.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 216;
+ vrLoc = 0;
+ };
+ A6AF31F10B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AA00B965F2F00EDBA70 /* valuenode_scale.h */;
+ name = "valuenode_scale.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 208;
+ vrLoc = 0;
+ };
+ A6AF31F20B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AA20B965F2F00EDBA70 /* valuenode_segcalctangent.h */;
+ name = "valuenode_segcalctangent.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 226;
+ vrLoc = 0;
+ };
+ A6AF31F30B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AA40B965F2F00EDBA70 /* valuenode_segcalcvertex.h */;
+ name = "valuenode_segcalcvertex.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 224;
+ vrLoc = 0;
+ };
+ A6AF31F40B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AA60B965F2F00EDBA70 /* valuenode_sine.h */;
+ name = "valuenode_sine.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 206;
+ vrLoc = 0;
+ };
+ A6AF31F50B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AA80B965F2F00EDBA70 /* valuenode_stripes.h */;
+ name = "valuenode_stripes.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 212;
+ vrLoc = 0;
+ };
+ A6AF31F60B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AAA0B965F2F00EDBA70 /* valuenode_subtract.h */;
+ name = "valuenode_subtract.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 214;
+ vrLoc = 0;
+ };
+ A6AF31F70B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AAC0B965F2F00EDBA70 /* valuenode_timedswap.h */;
+ name = "valuenode_timedswap.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 216;
+ vrLoc = 0;
+ };
+ A6AF31F80B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AAE0B965F2F00EDBA70 /* valuenode_twotone.h */;
+ name = "valuenode_twotone.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 212;
+ vrLoc = 0;
+ };
+ A6AF31F90B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AAF0B965F2F00EDBA70 /* vector.h */;
+ name = "vector.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 204;
+ vrLoc = 0;
+ };
+ A6AF31FA0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB00B965F2F00EDBA70 /* version.h */;
+ name = "version.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 192;
+ vrLoc = 0;
+ };
+ A6AF31FB0B96711700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB20B965F2F00EDBA70 /* waypoint.h */;
+ name = "waypoint.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF31FC0B96714000EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "#\tinclude <config.h>";
+ rLen = 21;
+ rLoc = 1024;
+ rType = 0;
+ vrLen = 580;
+ vrLoc = 672;
+ };
+ A6AF31FD0B96714000EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "error: sigc++/signal.h: No such file or directory";
+ fRef = A6AF31FE0B96714000EDBA70 /* canvas.h */;
+ rLen = 1;
+ rLoc = 32;
+ rType = 1;
+ };
+ A6AF31FE0B96714000EDBA70 /* canvas.h */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.h;
+ name = canvas.h;
+ path = "/Users/darco/Projects/Voria/synfig-core/build/Debug/synfig.framework/Headers/canvas.h";
+ sourceTree = "<absolute>";
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1077, 7290}}";
+ sepNavSelRange = "{13641, 0}";
+ sepNavVisRect = "{{0, 450}, {675, 76}}";
+ };
+ };
+ A6AF31FF0B96714000EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */;
+ name = "#\tinclude <config.h>";
+ rLen = 21;
+ rLoc = 1024;
+ rType = 0;
+ vrLen = 580;
+ vrLoc = 672;
+ };
+ A6AF32000B96714000EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF32010B96714000EDBA70 /* canvas.h */;
+ name = "#include <sigc++/signal.h>";
+ rLen = 27;
+ rLoc = 1149;
+ rType = 0;
+ vrLen = 626;
+ vrLoc = 800;
+ };
+ A6AF32010B96714000EDBA70 /* canvas.h */ = {
+ isa = PBXFileReference;
+ name = canvas.h;
+ path = "/Users/darco/Projects/Voria/synfig-core/build/Debug/synfig.framework/Headers/canvas.h";
+ sourceTree = "<absolute>";
+ };
+ A6AF32420B96718700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB20B965F2F00EDBA70 /* waypoint.h */;
+ name = "waypoint.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF32430B96718700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF2AB20B965F2F00EDBA70 /* waypoint.h */;
+ name = "waypoint.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 194;
+ vrLoc = 0;
+ };
+ A6AF32440B96718700EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF32450B96718700EDBA70 /* canvas.h */;
+ name = "#include <sigc++/signal.h>";
+ rLen = 27;
+ rLoc = 1149;
+ rType = 0;
+ vrLen = 106;
+ vrLoc = 1111;
+ };
+ A6AF32450B96718700EDBA70 /* canvas.h */ = {
+ isa = PBXFileReference;
+ name = canvas.h;
+ path = "/Users/darco/Projects/Voria/synfig-core/build/Debug/synfig.framework/Headers/canvas.h";
+ sourceTree = "<absolute>";
+ };
+ A6AF32460B9672A500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF31FE0B96714000EDBA70 /* canvas.h */;
+ name = "canvas.h: 486";
+ rLen = 0;
+ rLoc = 13641;
+ rType = 0;
+ vrLen = 106;
+ vrLoc = 1111;
+ };
+ A6AF32470B9672A500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF31FE0B96714000EDBA70 /* canvas.h */;
+ name = "canvas.h: 486";
+ rLen = 0;
+ rLoc = 13641;
+ rType = 0;
+ vrLen = 106;
+ vrLoc = 1111;
+ };
+ A6AF32480B9672A500EDBA70 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = A6AF30B90B966C1800EDBA70 /* config.h */;
+ name = "config.h: 8";
+ rLen = 0;
+ rLoc = 238;
+ rType = 0;
+ vrLen = 389;
+ vrLoc = 6916;
+ };
+}
--- /dev/null
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ A6AF2E570B965F2F00EDBA70 /* activepoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */; };
+ A6AF2E5A0B965F2F00EDBA70 /* blinepoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29CD0B965F2E00EDBA70 /* blinepoint.cpp */; };
+ A6AF2E5C0B965F2F00EDBA70 /* blur.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29CF0B965F2E00EDBA70 /* blur.cpp */; };
+ A6AF2E5E0B965F2F00EDBA70 /* canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29D10B965F2E00EDBA70 /* canvas.cpp */; };
+ A6AF2E610B965F2F00EDBA70 /* color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29D40B965F2E00EDBA70 /* color.cpp */; };
+ A6AF2E630B965F2F00EDBA70 /* context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29D60B965F2E00EDBA70 /* context.cpp */; };
+ A6AF2E650B965F2F00EDBA70 /* curve_helper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29D80B965F2E00EDBA70 /* curve_helper.cpp */; };
+ A6AF2E670B965F2F00EDBA70 /* curveset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29DA0B965F2E00EDBA70 /* curveset.cpp */; };
+ A6AF2E690B965F2F00EDBA70 /* distance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29DC0B965F2E00EDBA70 /* distance.cpp */; };
+ A6AF2E6B0B965F2F00EDBA70 /* exception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29DE0B965F2E00EDBA70 /* exception.cpp */; };
+ A6AF2E6D0B965F2F00EDBA70 /* gamma.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29E00B965F2E00EDBA70 /* gamma.cpp */; };
+ A6AF2E700B965F2F00EDBA70 /* gradient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29E30B965F2E00EDBA70 /* gradient.cpp */; };
+ A6AF2E720B965F2F00EDBA70 /* guid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29E50B965F2E00EDBA70 /* guid.cpp */; };
+ A6AF2E750B965F2F00EDBA70 /* importer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29E80B965F2E00EDBA70 /* importer.cpp */; };
+ A6AF2E780B965F2F00EDBA70 /* keyframe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29EB0B965F2E00EDBA70 /* keyframe.cpp */; };
+ A6AF2E7A0B965F2F00EDBA70 /* layer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29ED0B965F2E00EDBA70 /* layer.cpp */; };
+ A6AF2E7C0B965F2F00EDBA70 /* layer_bitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29EF0B965F2E00EDBA70 /* layer_bitmap.cpp */; };
+ A6AF2E7E0B965F2F00EDBA70 /* layer_composite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29F10B965F2E00EDBA70 /* layer_composite.cpp */; };
+ A6AF2E800B965F2F00EDBA70 /* layer_mime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29F30B965F2E00EDBA70 /* layer_mime.cpp */; };
+ A6AF2E820B965F2F00EDBA70 /* layer_motionblur.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29F50B965F2E00EDBA70 /* layer_motionblur.cpp */; };
+ A6AF2E840B965F2F00EDBA70 /* layer_pastecanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29F70B965F2E00EDBA70 /* layer_pastecanvas.cpp */; };
+ A6AF2E860B965F2F00EDBA70 /* layer_polygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29F90B965F2E00EDBA70 /* layer_polygon.cpp */; };
+ A6AF2E880B965F2F00EDBA70 /* layer_shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29FB0B965F2E00EDBA70 /* layer_shape.cpp */; };
+ A6AF2E8A0B965F2F00EDBA70 /* layer_solidcolor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF29FD0B965F2E00EDBA70 /* layer_solidcolor.cpp */; };
+ A6AF2ED10B965F2F00EDBA70 /* listimporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A440B965F2F00EDBA70 /* listimporter.cpp */; };
+ A6AF2ED30B965F2F00EDBA70 /* loadcanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A460B965F2F00EDBA70 /* loadcanvas.cpp */; };
+ A6AF2ED50B965F2F00EDBA70 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A480B965F2F00EDBA70 /* main.cpp */; };
+ A6AF2EDA0B965F2F00EDBA70 /* module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A4D0B965F2F00EDBA70 /* module.cpp */; };
+ A6AF2EDC0B965F2F00EDBA70 /* mutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A4F0B965F2F00EDBA70 /* mutex.cpp */; };
+ A6AF2EDE0B965F2F00EDBA70 /* node.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A510B965F2F00EDBA70 /* node.cpp */; };
+ A6AF2EE00B965F2F00EDBA70 /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A530B965F2F00EDBA70 /* palette.cpp */; };
+ A6AF2EE20B965F2F00EDBA70 /* paramdesc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A550B965F2F00EDBA70 /* paramdesc.cpp */; };
+ A6AF2EE50B965F2F00EDBA70 /* polynomial_root.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A580B965F2F00EDBA70 /* polynomial_root.cpp */; };
+ A6AF2EEE0B965F2F00EDBA70 /* rect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A620B965F2F00EDBA70 /* rect.cpp */; };
+ A6AF2EF00B965F2F00EDBA70 /* renddesc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A640B965F2F00EDBA70 /* renddesc.cpp */; };
+ A6AF2EF20B965F2F00EDBA70 /* render.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A660B965F2F00EDBA70 /* render.cpp */; };
+ A6AF2EF40B965F2F00EDBA70 /* savecanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A680B965F2F00EDBA70 /* savecanvas.cpp */; };
+ A6AF2EFA0B965F2F00EDBA70 /* surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A6E0B965F2F00EDBA70 /* surface.cpp */; };
+ A6AF2F000B965F2F00EDBA70 /* target.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A740B965F2F00EDBA70 /* target.cpp */; };
+ A6AF2F020B965F2F00EDBA70 /* target_multi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A760B965F2F00EDBA70 /* target_multi.cpp */; };
+ A6AF2F040B965F2F00EDBA70 /* target_null.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A780B965F2F00EDBA70 /* target_null.cpp */; };
+ A6AF2F060B965F2F00EDBA70 /* target_null_tile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A7A0B965F2F00EDBA70 /* target_null_tile.cpp */; };
+ A6AF2F080B965F2F00EDBA70 /* target_scanline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A7C0B965F2F00EDBA70 /* target_scanline.cpp */; };
+ A6AF2F0A0B965F2F00EDBA70 /* target_tile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A7E0B965F2F00EDBA70 /* target_tile.cpp */; };
+ A6AF2F0C0B965F2F00EDBA70 /* time.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A800B965F2F00EDBA70 /* time.cpp */; };
+ A6AF2F0E0B965F2F00EDBA70 /* timepointcollect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A820B965F2F00EDBA70 /* timepointcollect.cpp */; };
+ A6AF2F100B965F2F00EDBA70 /* transform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A840B965F2F00EDBA70 /* transform.cpp */; };
+ A6AF2F130B965F2F00EDBA70 /* uniqueid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A870B965F2F00EDBA70 /* uniqueid.cpp */; };
+ A6AF2F150B965F2F00EDBA70 /* value.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A890B965F2F00EDBA70 /* value.cpp */; };
+ A6AF2F170B965F2F00EDBA70 /* valuenode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A8B0B965F2F00EDBA70 /* valuenode.cpp */; };
+ A6AF2F190B965F2F00EDBA70 /* valuenode_animated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A8D0B965F2F00EDBA70 /* valuenode_animated.cpp */; };
+ A6AF2F1B0B965F2F00EDBA70 /* valuenode_bline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A8F0B965F2F00EDBA70 /* valuenode_bline.cpp */; };
+ A6AF2F1D0B965F2F00EDBA70 /* valuenode_composite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A910B965F2F00EDBA70 /* valuenode_composite.cpp */; };
+ A6AF2F1F0B965F2F00EDBA70 /* valuenode_const.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A930B965F2F00EDBA70 /* valuenode_const.cpp */; };
+ A6AF2F210B965F2F00EDBA70 /* valuenode_dynamiclist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A950B965F2F00EDBA70 /* valuenode_dynamiclist.cpp */; };
+ A6AF2F230B965F2F00EDBA70 /* valuenode_gradientrotate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A970B965F2F00EDBA70 /* valuenode_gradientrotate.cpp */; };
+ A6AF2F250B965F2F00EDBA70 /* valuenode_linear.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A990B965F2F00EDBA70 /* valuenode_linear.cpp */; };
+ A6AF2F270B965F2F00EDBA70 /* valuenode_radialcomposite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A9B0B965F2F00EDBA70 /* valuenode_radialcomposite.cpp */; };
+ A6AF2F290B965F2F00EDBA70 /* valuenode_reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A9D0B965F2F00EDBA70 /* valuenode_reference.cpp */; };
+ A6AF2F2B0B965F2F00EDBA70 /* valuenode_scale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2A9F0B965F2F00EDBA70 /* valuenode_scale.cpp */; };
+ A6AF2F2D0B965F2F00EDBA70 /* valuenode_segcalctangent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2AA10B965F2F00EDBA70 /* valuenode_segcalctangent.cpp */; };
+ A6AF2F2F0B965F2F00EDBA70 /* valuenode_segcalcvertex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2AA30B965F2F00EDBA70 /* valuenode_segcalcvertex.cpp */; };
+ A6AF2F310B965F2F00EDBA70 /* valuenode_sine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2AA50B965F2F00EDBA70 /* valuenode_sine.cpp */; };
+ A6AF2F330B965F2F00EDBA70 /* valuenode_stripes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2AA70B965F2F00EDBA70 /* valuenode_stripes.cpp */; };
+ A6AF2F350B965F2F00EDBA70 /* valuenode_subtract.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2AA90B965F2F00EDBA70 /* valuenode_subtract.cpp */; };
+ A6AF2F370B965F2F00EDBA70 /* valuenode_timedswap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2AAB0B965F2F00EDBA70 /* valuenode_timedswap.cpp */; };
+ A6AF2F390B965F2F00EDBA70 /* valuenode_twotone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2AAD0B965F2F00EDBA70 /* valuenode_twotone.cpp */; };
+ A6AF2F3D0B965F2F00EDBA70 /* waypoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2AB10B965F2F00EDBA70 /* waypoint.cpp */; };
+ A6AF2F500B965FEF00EDBA70 /* libxml++.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A6AF2F4E0B965FEF00EDBA70 /* libxml++.framework */; };
+ A6AF2F510B965FEF00EDBA70 /* sigc++.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A6AF2F4F0B965FEF00EDBA70 /* sigc++.framework */; };
+ A6AF30E50B966F9300EDBA70 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6AF2ABA0B965F2F00EDBA70 /* main.cpp */; };
+ A6AF30E60B966F9A00EDBA70 /* synfig.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A6AF20DB0B965ED900EDBA70 /* synfig.framework */; };
+ A6AF30FE0B96709600EDBA70 /* activepoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29CB0B965F2E00EDBA70 /* activepoint.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF30FF0B96709600EDBA70 /* angle.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29CC0B965F2E00EDBA70 /* angle.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31000B96709600EDBA70 /* blinepoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29CE0B965F2E00EDBA70 /* blinepoint.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31010B96709600EDBA70 /* blur.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29D00B965F2E00EDBA70 /* blur.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31020B96709600EDBA70 /* canvas.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29D20B965F2E00EDBA70 /* canvas.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31030B96709600EDBA70 /* canvasbase.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29D30B965F2E00EDBA70 /* canvasbase.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31040B96709600EDBA70 /* color.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29D50B965F2E00EDBA70 /* color.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31050B96709600EDBA70 /* context.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29D70B965F2E00EDBA70 /* context.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31060B96709600EDBA70 /* curve_helper.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29D90B965F2E00EDBA70 /* curve_helper.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31070B96709600EDBA70 /* curveset.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29DB0B965F2E00EDBA70 /* curveset.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31080B96709600EDBA70 /* distance.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29DD0B965F2E00EDBA70 /* distance.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31090B96709600EDBA70 /* exception.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29DF0B965F2E00EDBA70 /* exception.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF310A0B96709600EDBA70 /* gamma.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29E10B965F2E00EDBA70 /* gamma.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF310B0B96709600EDBA70 /* general.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29E20B965F2E00EDBA70 /* general.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF310C0B96709600EDBA70 /* gradient.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29E40B965F2E00EDBA70 /* gradient.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF310D0B96709600EDBA70 /* guid.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29E60B965F2E00EDBA70 /* guid.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF310E0B96709600EDBA70 /* guidset.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29E70B965F2E00EDBA70 /* guidset.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF310F0B96709600EDBA70 /* importer.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29E90B965F2E00EDBA70 /* importer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31100B96709600EDBA70 /* interpolation.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29EA0B965F2E00EDBA70 /* interpolation.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31110B96709600EDBA70 /* keyframe.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29EC0B965F2E00EDBA70 /* keyframe.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31120B96709600EDBA70 /* layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29EE0B965F2E00EDBA70 /* layer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31130B96709600EDBA70 /* layer_bitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29F00B965F2E00EDBA70 /* layer_bitmap.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31140B96709600EDBA70 /* layer_composite.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29F20B965F2E00EDBA70 /* layer_composite.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31150B96709600EDBA70 /* layer_mime.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29F40B965F2E00EDBA70 /* layer_mime.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31160B96709600EDBA70 /* layer_motionblur.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29F60B965F2E00EDBA70 /* layer_motionblur.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31170B96709600EDBA70 /* layer_pastecanvas.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29F80B965F2E00EDBA70 /* layer_pastecanvas.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31180B96709600EDBA70 /* layer_polygon.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29FA0B965F2E00EDBA70 /* layer_polygon.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31190B96709600EDBA70 /* layer_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29FC0B965F2E00EDBA70 /* layer_shape.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF311A0B96709600EDBA70 /* layer_solidcolor.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF29FE0B965F2E00EDBA70 /* layer_solidcolor.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF311B0B96709600EDBA70 /* listimporter.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A450B965F2F00EDBA70 /* listimporter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF311C0B96709600EDBA70 /* loadcanvas.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A470B965F2F00EDBA70 /* loadcanvas.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF311D0B96709600EDBA70 /* main.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A490B965F2F00EDBA70 /* main.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF311E0B96709600EDBA70 /* module.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A4E0B965F2F00EDBA70 /* module.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF311F0B96709600EDBA70 /* mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A500B965F2F00EDBA70 /* mutex.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31200B96709600EDBA70 /* node.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A520B965F2F00EDBA70 /* node.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31210B96709600EDBA70 /* palette.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A540B965F2F00EDBA70 /* palette.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31220B96709600EDBA70 /* paramdesc.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A560B965F2F00EDBA70 /* paramdesc.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31230B96709600EDBA70 /* polynomial_root.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A590B965F2F00EDBA70 /* polynomial_root.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31240B96709600EDBA70 /* protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A600B965F2F00EDBA70 /* protocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31250B96709600EDBA70 /* real.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A610B965F2F00EDBA70 /* real.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31260B96709600EDBA70 /* rect.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A630B965F2F00EDBA70 /* rect.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31270B96709600EDBA70 /* renddesc.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A650B965F2F00EDBA70 /* renddesc.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31280B96709600EDBA70 /* render.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A670B965F2F00EDBA70 /* render.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31290B96709600EDBA70 /* savecanvas.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A690B965F2F00EDBA70 /* savecanvas.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF312A0B96709600EDBA70 /* segment.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A6A0B965F2F00EDBA70 /* segment.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF312B0B96709600EDBA70 /* smartfile.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A6B0B965F2F00EDBA70 /* smartfile.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF312C0B96709600EDBA70 /* string.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A6C0B965F2F00EDBA70 /* string.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF312D0B96709600EDBA70 /* string_decl.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A6D0B965F2F00EDBA70 /* string_decl.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF312E0B96709600EDBA70 /* surface.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A6F0B965F2F00EDBA70 /* surface.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF312F0B96709600EDBA70 /* synfig.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A720B965F2F00EDBA70 /* synfig.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31300B96709600EDBA70 /* target.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A750B965F2F00EDBA70 /* target.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31310B96709600EDBA70 /* target_multi.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A770B965F2F00EDBA70 /* target_multi.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31320B96709600EDBA70 /* target_null.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A790B965F2F00EDBA70 /* target_null.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31330B96709600EDBA70 /* target_null_tile.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A7B0B965F2F00EDBA70 /* target_null_tile.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31340B96709600EDBA70 /* target_scanline.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A7D0B965F2F00EDBA70 /* target_scanline.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31350B96709600EDBA70 /* target_tile.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A7F0B965F2F00EDBA70 /* target_tile.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31360B96709600EDBA70 /* time.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A810B965F2F00EDBA70 /* time.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31370B96709600EDBA70 /* timepointcollect.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A830B965F2F00EDBA70 /* timepointcollect.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31380B96709600EDBA70 /* transform.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A850B965F2F00EDBA70 /* transform.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31390B96709600EDBA70 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A860B965F2F00EDBA70 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF313A0B96709600EDBA70 /* uniqueid.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A880B965F2F00EDBA70 /* uniqueid.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF313B0B96709600EDBA70 /* value.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A8A0B965F2F00EDBA70 /* value.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF313C0B96709600EDBA70 /* valuenode.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A8C0B965F2F00EDBA70 /* valuenode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF313D0B96709600EDBA70 /* valuenode_animated.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A8E0B965F2F00EDBA70 /* valuenode_animated.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF313E0B96709600EDBA70 /* valuenode_bline.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A900B965F2F00EDBA70 /* valuenode_bline.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF313F0B96709600EDBA70 /* valuenode_composite.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A920B965F2F00EDBA70 /* valuenode_composite.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31400B96709600EDBA70 /* valuenode_const.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A940B965F2F00EDBA70 /* valuenode_const.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31410B96709600EDBA70 /* valuenode_dynamiclist.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A960B965F2F00EDBA70 /* valuenode_dynamiclist.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31420B96709600EDBA70 /* valuenode_gradientrotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A980B965F2F00EDBA70 /* valuenode_gradientrotate.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31430B96709600EDBA70 /* valuenode_linear.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A9A0B965F2F00EDBA70 /* valuenode_linear.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31440B96709600EDBA70 /* valuenode_radialcomposite.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A9C0B965F2F00EDBA70 /* valuenode_radialcomposite.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31450B96709600EDBA70 /* valuenode_reference.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2A9E0B965F2F00EDBA70 /* valuenode_reference.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31460B96709600EDBA70 /* valuenode_scale.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2AA00B965F2F00EDBA70 /* valuenode_scale.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31470B96709600EDBA70 /* valuenode_segcalctangent.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2AA20B965F2F00EDBA70 /* valuenode_segcalctangent.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31480B96709600EDBA70 /* valuenode_segcalcvertex.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2AA40B965F2F00EDBA70 /* valuenode_segcalcvertex.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31490B96709600EDBA70 /* valuenode_sine.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2AA60B965F2F00EDBA70 /* valuenode_sine.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF314A0B96709600EDBA70 /* valuenode_stripes.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2AA80B965F2F00EDBA70 /* valuenode_stripes.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF314B0B96709600EDBA70 /* valuenode_subtract.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2AAA0B965F2F00EDBA70 /* valuenode_subtract.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF314C0B96709600EDBA70 /* valuenode_timedswap.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2AAC0B965F2F00EDBA70 /* valuenode_timedswap.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF314D0B96709600EDBA70 /* valuenode_twotone.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2AAE0B965F2F00EDBA70 /* valuenode_twotone.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF314E0B96709600EDBA70 /* vector.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2AAF0B965F2F00EDBA70 /* vector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF314F0B96709600EDBA70 /* version.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2AB00B965F2F00EDBA70 /* version.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF31500B96709600EDBA70 /* waypoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A6AF2AB20B965F2F00EDBA70 /* waypoint.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A6AF32370B96714900EDBA70 /* sigc++.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A6AF2F4F0B965FEF00EDBA70 /* sigc++.framework */; };
+ A6AF323A0B96714D00EDBA70 /* libxml++.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A6AF2F4E0B965FEF00EDBA70 /* libxml++.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ A6AF30E90B966FB200EDBA70 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = A6AF11980B965E2E00EDBA70 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A6AF20DA0B965ED900EDBA70 /* Synfig Framework */;
+ remoteInfo = "Synfig Framework";
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ A6AF20DB0B965ED900EDBA70 /* synfig.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = synfig.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ A6AF20DD0B965ED900EDBA70 /* synfig-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "synfig-Info.plist"; sourceTree = "<group>"; };
+ A6AF25FC0B965F2D00EDBA70 /* libexample_la-filledrect.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libexample_la-filledrect.Plo"; sourceTree = "<group>"; };
+ A6AF25FD0B965F2D00EDBA70 /* libexample_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libexample_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF25FE0B965F2D00EDBA70 /* libexample_la-metaballs.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libexample_la-metaballs.Plo"; sourceTree = "<group>"; };
+ A6AF25FF0B965F2D00EDBA70 /* libexample_la-simplecircle.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libexample_la-simplecircle.Plo"; sourceTree = "<group>"; };
+ A6AF26000B965F2D00EDBA70 /* filledrect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = filledrect.cpp; sourceTree = "<group>"; };
+ A6AF26010B965F2D00EDBA70 /* filledrect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = filledrect.h; sourceTree = "<group>"; };
+ A6AF26020B965F2D00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF26030B965F2D00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF26040B965F2D00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF26050B965F2D00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF26060B965F2D00EDBA70 /* metaballs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = metaballs.cpp; sourceTree = "<group>"; };
+ A6AF26070B965F2D00EDBA70 /* metaballs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = metaballs.h; sourceTree = "<group>"; };
+ A6AF26080B965F2D00EDBA70 /* simplecircle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = simplecircle.cpp; sourceTree = "<group>"; };
+ A6AF26090B965F2D00EDBA70 /* simplecircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simplecircle.h; sourceTree = "<group>"; };
+ A6AF260C0B965F2D00EDBA70 /* liblyr_freetype_la-lyr_freetype.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_freetype_la-lyr_freetype.Plo"; sourceTree = "<group>"; };
+ A6AF260D0B965F2D00EDBA70 /* liblyr_freetype_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_freetype_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF260F0B965F2D00EDBA70 /* liblyr_freetype.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = liblyr_freetype.0.0.0.so; sourceTree = "<group>"; };
+ A6AF26100B965F2D00EDBA70 /* liblyr_freetype.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = liblyr_freetype.0.so; sourceTree = "<group>"; };
+ A6AF26110B965F2D00EDBA70 /* liblyr_freetype.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = liblyr_freetype.la; sourceTree = "<group>"; };
+ A6AF26120B965F2D00EDBA70 /* liblyr_freetype.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = liblyr_freetype.lai; sourceTree = "<group>"; };
+ A6AF26130B965F2D00EDBA70 /* liblyr_freetype.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = liblyr_freetype.so; sourceTree = "<group>"; };
+ A6AF26140B965F2D00EDBA70 /* liblyr_freetype_la-lyr_freetype.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_freetype_la-lyr_freetype.o"; sourceTree = "<group>"; };
+ A6AF26150B965F2D00EDBA70 /* liblyr_freetype_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_freetype_la-main.o"; sourceTree = "<group>"; };
+ A6AF26160B965F2D00EDBA70 /* liblyr_freetype.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = liblyr_freetype.la; sourceTree = "<group>"; };
+ A6AF26170B965F2D00EDBA70 /* liblyr_freetype_la-lyr_freetype.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_freetype_la-lyr_freetype.lo"; sourceTree = "<group>"; };
+ A6AF26180B965F2D00EDBA70 /* liblyr_freetype_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_freetype_la-main.lo"; sourceTree = "<group>"; };
+ A6AF26190B965F2D00EDBA70 /* lyr_freetype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lyr_freetype.cpp; sourceTree = "<group>"; };
+ A6AF261A0B965F2D00EDBA70 /* lyr_freetype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lyr_freetype.h; sourceTree = "<group>"; };
+ A6AF261B0B965F2D00EDBA70 /* lyr_freetype.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = lyr_freetype.nsh; sourceTree = "<group>"; };
+ A6AF261C0B965F2D00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF261D0B965F2D00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF261E0B965F2D00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF261F0B965F2D00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF26200B965F2D00EDBA70 /* unlyr_freetype.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unlyr_freetype.nsh; sourceTree = "<group>"; };
+ A6AF26230B965F2D00EDBA70 /* liblyr_std_la-bevel.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-bevel.Plo"; sourceTree = "<group>"; };
+ A6AF26240B965F2D00EDBA70 /* liblyr_std_la-booleancurve.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-booleancurve.Plo"; sourceTree = "<group>"; };
+ A6AF26250B965F2D00EDBA70 /* liblyr_std_la-clamp.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-clamp.Plo"; sourceTree = "<group>"; };
+ A6AF26260B965F2D00EDBA70 /* liblyr_std_la-import.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-import.Plo"; sourceTree = "<group>"; };
+ A6AF26270B965F2D00EDBA70 /* liblyr_std_la-insideout.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-insideout.Plo"; sourceTree = "<group>"; };
+ A6AF26280B965F2D00EDBA70 /* liblyr_std_la-julia.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-julia.Plo"; sourceTree = "<group>"; };
+ A6AF26290B965F2D00EDBA70 /* liblyr_std_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF262A0B965F2D00EDBA70 /* liblyr_std_la-mandelbrot.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-mandelbrot.Plo"; sourceTree = "<group>"; };
+ A6AF262B0B965F2D00EDBA70 /* liblyr_std_la-rotate.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-rotate.Plo"; sourceTree = "<group>"; };
+ A6AF262C0B965F2D00EDBA70 /* liblyr_std_la-shade.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-shade.Plo"; sourceTree = "<group>"; };
+ A6AF262D0B965F2D00EDBA70 /* liblyr_std_la-sphere_distort.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-sphere_distort.Plo"; sourceTree = "<group>"; };
+ A6AF262E0B965F2D00EDBA70 /* liblyr_std_la-stretch.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-stretch.Plo"; sourceTree = "<group>"; };
+ A6AF262F0B965F2D00EDBA70 /* liblyr_std_la-supersample.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-supersample.Plo"; sourceTree = "<group>"; };
+ A6AF26300B965F2D00EDBA70 /* liblyr_std_la-timeloop.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-timeloop.Plo"; sourceTree = "<group>"; };
+ A6AF26310B965F2D00EDBA70 /* liblyr_std_la-translate.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-translate.Plo"; sourceTree = "<group>"; };
+ A6AF26320B965F2D00EDBA70 /* liblyr_std_la-twirl.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-twirl.Plo"; sourceTree = "<group>"; };
+ A6AF26330B965F2D00EDBA70 /* liblyr_std_la-warp.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-warp.Plo"; sourceTree = "<group>"; };
+ A6AF26340B965F2D00EDBA70 /* liblyr_std_la-xorpattern.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-xorpattern.Plo"; sourceTree = "<group>"; };
+ A6AF26350B965F2D00EDBA70 /* liblyr_std_la-zoom.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-zoom.Plo"; sourceTree = "<group>"; };
+ A6AF26370B965F2D00EDBA70 /* liblyr_std.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = liblyr_std.0.0.0.so; sourceTree = "<group>"; };
+ A6AF26380B965F2D00EDBA70 /* liblyr_std.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = liblyr_std.0.so; sourceTree = "<group>"; };
+ A6AF26390B965F2D00EDBA70 /* liblyr_std.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = liblyr_std.la; sourceTree = "<group>"; };
+ A6AF263A0B965F2D00EDBA70 /* liblyr_std.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = liblyr_std.lai; sourceTree = "<group>"; };
+ A6AF263B0B965F2D00EDBA70 /* liblyr_std.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = liblyr_std.so; sourceTree = "<group>"; };
+ A6AF263C0B965F2D00EDBA70 /* liblyr_std_la-bevel.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-bevel.o"; sourceTree = "<group>"; };
+ A6AF263D0B965F2D00EDBA70 /* liblyr_std_la-booleancurve.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-booleancurve.o"; sourceTree = "<group>"; };
+ A6AF263E0B965F2D00EDBA70 /* liblyr_std_la-clamp.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-clamp.o"; sourceTree = "<group>"; };
+ A6AF263F0B965F2D00EDBA70 /* liblyr_std_la-import.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-import.o"; sourceTree = "<group>"; };
+ A6AF26400B965F2D00EDBA70 /* liblyr_std_la-insideout.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-insideout.o"; sourceTree = "<group>"; };
+ A6AF26410B965F2D00EDBA70 /* liblyr_std_la-julia.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-julia.o"; sourceTree = "<group>"; };
+ A6AF26420B965F2D00EDBA70 /* liblyr_std_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-main.o"; sourceTree = "<group>"; };
+ A6AF26430B965F2D00EDBA70 /* liblyr_std_la-mandelbrot.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-mandelbrot.o"; sourceTree = "<group>"; };
+ A6AF26440B965F2D00EDBA70 /* liblyr_std_la-rotate.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-rotate.o"; sourceTree = "<group>"; };
+ A6AF26450B965F2D00EDBA70 /* liblyr_std_la-shade.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-shade.o"; sourceTree = "<group>"; };
+ A6AF26460B965F2D00EDBA70 /* liblyr_std_la-sphere_distort.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-sphere_distort.o"; sourceTree = "<group>"; };
+ A6AF26470B965F2D00EDBA70 /* liblyr_std_la-stretch.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-stretch.o"; sourceTree = "<group>"; };
+ A6AF26480B965F2D00EDBA70 /* liblyr_std_la-supersample.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-supersample.o"; sourceTree = "<group>"; };
+ A6AF26490B965F2D00EDBA70 /* liblyr_std_la-timeloop.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-timeloop.o"; sourceTree = "<group>"; };
+ A6AF264A0B965F2D00EDBA70 /* liblyr_std_la-translate.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-translate.o"; sourceTree = "<group>"; };
+ A6AF264B0B965F2D00EDBA70 /* liblyr_std_la-twirl.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-twirl.o"; sourceTree = "<group>"; };
+ A6AF264C0B965F2D00EDBA70 /* liblyr_std_la-warp.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-warp.o"; sourceTree = "<group>"; };
+ A6AF264D0B965F2D00EDBA70 /* liblyr_std_la-xorpattern.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-xorpattern.o"; sourceTree = "<group>"; };
+ A6AF264E0B965F2D00EDBA70 /* liblyr_std_la-zoom.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "liblyr_std_la-zoom.o"; sourceTree = "<group>"; };
+ A6AF264F0B965F2D00EDBA70 /* bevel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bevel.cpp; sourceTree = "<group>"; };
+ A6AF26500B965F2D00EDBA70 /* bevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bevel.h; sourceTree = "<group>"; };
+ A6AF26510B965F2D00EDBA70 /* booleancurve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = booleancurve.cpp; sourceTree = "<group>"; };
+ A6AF26520B965F2D00EDBA70 /* booleancurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = booleancurve.h; sourceTree = "<group>"; };
+ A6AF26530B965F2D00EDBA70 /* clamp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = clamp.cpp; sourceTree = "<group>"; };
+ A6AF26540B965F2D00EDBA70 /* clamp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = clamp.h; sourceTree = "<group>"; };
+ A6AF26550B965F2D00EDBA70 /* import.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = import.cpp; sourceTree = "<group>"; };
+ A6AF26560B965F2D00EDBA70 /* import.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = import.h; sourceTree = "<group>"; };
+ A6AF26570B965F2D00EDBA70 /* insideout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = insideout.cpp; sourceTree = "<group>"; };
+ A6AF26580B965F2D00EDBA70 /* insideout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = insideout.h; sourceTree = "<group>"; };
+ A6AF26590B965F2D00EDBA70 /* julia.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = julia.cpp; sourceTree = "<group>"; };
+ A6AF265A0B965F2D00EDBA70 /* julia.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = julia.h; sourceTree = "<group>"; };
+ A6AF265B0B965F2D00EDBA70 /* liblyr_std.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = liblyr_std.la; sourceTree = "<group>"; };
+ A6AF265C0B965F2D00EDBA70 /* liblyr_std_la-bevel.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-bevel.lo"; sourceTree = "<group>"; };
+ A6AF265D0B965F2D00EDBA70 /* liblyr_std_la-booleancurve.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-booleancurve.lo"; sourceTree = "<group>"; };
+ A6AF265E0B965F2D00EDBA70 /* liblyr_std_la-clamp.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-clamp.lo"; sourceTree = "<group>"; };
+ A6AF265F0B965F2D00EDBA70 /* liblyr_std_la-import.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-import.lo"; sourceTree = "<group>"; };
+ A6AF26600B965F2D00EDBA70 /* liblyr_std_la-insideout.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-insideout.lo"; sourceTree = "<group>"; };
+ A6AF26610B965F2D00EDBA70 /* liblyr_std_la-julia.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-julia.lo"; sourceTree = "<group>"; };
+ A6AF26620B965F2D00EDBA70 /* liblyr_std_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-main.lo"; sourceTree = "<group>"; };
+ A6AF26630B965F2D00EDBA70 /* liblyr_std_la-mandelbrot.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-mandelbrot.lo"; sourceTree = "<group>"; };
+ A6AF26640B965F2D00EDBA70 /* liblyr_std_la-rotate.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-rotate.lo"; sourceTree = "<group>"; };
+ A6AF26650B965F2D00EDBA70 /* liblyr_std_la-shade.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-shade.lo"; sourceTree = "<group>"; };
+ A6AF26660B965F2D00EDBA70 /* liblyr_std_la-sphere_distort.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-sphere_distort.lo"; sourceTree = "<group>"; };
+ A6AF26670B965F2D00EDBA70 /* liblyr_std_la-stretch.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-stretch.lo"; sourceTree = "<group>"; };
+ A6AF26680B965F2D00EDBA70 /* liblyr_std_la-supersample.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-supersample.lo"; sourceTree = "<group>"; };
+ A6AF26690B965F2D00EDBA70 /* liblyr_std_la-timeloop.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-timeloop.lo"; sourceTree = "<group>"; };
+ A6AF266A0B965F2D00EDBA70 /* liblyr_std_la-translate.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-translate.lo"; sourceTree = "<group>"; };
+ A6AF266B0B965F2D00EDBA70 /* liblyr_std_la-twirl.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-twirl.lo"; sourceTree = "<group>"; };
+ A6AF266C0B965F2D00EDBA70 /* liblyr_std_la-warp.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-warp.lo"; sourceTree = "<group>"; };
+ A6AF266D0B965F2D00EDBA70 /* liblyr_std_la-xorpattern.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-xorpattern.lo"; sourceTree = "<group>"; };
+ A6AF266E0B965F2D00EDBA70 /* liblyr_std_la-zoom.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "liblyr_std_la-zoom.lo"; sourceTree = "<group>"; };
+ A6AF266F0B965F2D00EDBA70 /* lyr_std.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = lyr_std.nsh; sourceTree = "<group>"; };
+ A6AF26700B965F2D00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF26710B965F2D00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF26720B965F2D00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF26730B965F2D00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF26740B965F2D00EDBA70 /* mandelbrot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mandelbrot.cpp; sourceTree = "<group>"; };
+ A6AF26750B965F2D00EDBA70 /* mandelbrot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mandelbrot.h; sourceTree = "<group>"; };
+ A6AF26760B965F2D00EDBA70 /* radialgradient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = radialgradient.cpp; sourceTree = "<group>"; };
+ A6AF26770B965F2D00EDBA70 /* rotate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rotate.cpp; sourceTree = "<group>"; };
+ A6AF26780B965F2D00EDBA70 /* rotate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rotate.h; sourceTree = "<group>"; };
+ A6AF26790B965F2D00EDBA70 /* shade.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shade.cpp; sourceTree = "<group>"; };
+ A6AF267A0B965F2D00EDBA70 /* shade.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shade.h; sourceTree = "<group>"; };
+ A6AF267B0B965F2D00EDBA70 /* sphere_distort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sphere_distort.cpp; sourceTree = "<group>"; };
+ A6AF267C0B965F2D00EDBA70 /* sphere_distort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sphere_distort.h; sourceTree = "<group>"; };
+ A6AF267D0B965F2D00EDBA70 /* stretch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stretch.cpp; sourceTree = "<group>"; };
+ A6AF267E0B965F2D00EDBA70 /* stretch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stretch.h; sourceTree = "<group>"; };
+ A6AF267F0B965F2D00EDBA70 /* supersample.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = supersample.cpp; sourceTree = "<group>"; };
+ A6AF26800B965F2D00EDBA70 /* supersample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = supersample.h; sourceTree = "<group>"; };
+ A6AF26810B965F2D00EDBA70 /* timeloop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = timeloop.cpp; sourceTree = "<group>"; };
+ A6AF26820B965F2D00EDBA70 /* timeloop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timeloop.h; sourceTree = "<group>"; };
+ A6AF26830B965F2D00EDBA70 /* translate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = translate.cpp; sourceTree = "<group>"; };
+ A6AF26840B965F2D00EDBA70 /* translate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = translate.h; sourceTree = "<group>"; };
+ A6AF26850B965F2D00EDBA70 /* twirl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = twirl.cpp; sourceTree = "<group>"; };
+ A6AF26860B965F2D00EDBA70 /* twirl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = twirl.h; sourceTree = "<group>"; };
+ A6AF26870B965F2D00EDBA70 /* unlyr_std.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unlyr_std.nsh; sourceTree = "<group>"; };
+ A6AF26880B965F2D00EDBA70 /* warp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = warp.cpp; sourceTree = "<group>"; };
+ A6AF26890B965F2D00EDBA70 /* warp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = warp.h; sourceTree = "<group>"; };
+ A6AF268A0B965F2D00EDBA70 /* xorpattern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xorpattern.cpp; sourceTree = "<group>"; };
+ A6AF268B0B965F2D00EDBA70 /* xorpattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xorpattern.h; sourceTree = "<group>"; };
+ A6AF268C0B965F2D00EDBA70 /* zoom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = zoom.cpp; sourceTree = "<group>"; };
+ A6AF268D0B965F2D00EDBA70 /* zoom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zoom.h; sourceTree = "<group>"; };
+ A6AF268E0B965F2D00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF268F0B965F2D00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF26900B965F2D00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF26930B965F2D00EDBA70 /* libmod_bmp_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_bmp_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF26940B965F2D00EDBA70 /* libmod_bmp_la-mptr_bmp.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_bmp_la-mptr_bmp.Plo"; sourceTree = "<group>"; };
+ A6AF26950B965F2D00EDBA70 /* libmod_bmp_la-trgt_bmp.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_bmp_la-trgt_bmp.Plo"; sourceTree = "<group>"; };
+ A6AF26970B965F2D00EDBA70 /* libmod_bmp.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_bmp.0.0.0.so; sourceTree = "<group>"; };
+ A6AF26980B965F2D00EDBA70 /* libmod_bmp.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_bmp.0.so; sourceTree = "<group>"; };
+ A6AF26990B965F2D00EDBA70 /* libmod_bmp.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_bmp.la; sourceTree = "<group>"; };
+ A6AF269A0B965F2D00EDBA70 /* libmod_bmp.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_bmp.lai; sourceTree = "<group>"; };
+ A6AF269B0B965F2D00EDBA70 /* libmod_bmp.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_bmp.so; sourceTree = "<group>"; };
+ A6AF269C0B965F2D00EDBA70 /* libmod_bmp_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_bmp_la-main.o"; sourceTree = "<group>"; };
+ A6AF269D0B965F2D00EDBA70 /* libmod_bmp_la-mptr_bmp.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_bmp_la-mptr_bmp.o"; sourceTree = "<group>"; };
+ A6AF269E0B965F2D00EDBA70 /* libmod_bmp_la-trgt_bmp.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_bmp_la-trgt_bmp.o"; sourceTree = "<group>"; };
+ A6AF269F0B965F2D00EDBA70 /* libmod_bmp.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_bmp.la; sourceTree = "<group>"; };
+ A6AF26A00B965F2D00EDBA70 /* libmod_bmp_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_bmp_la-main.lo"; sourceTree = "<group>"; };
+ A6AF26A10B965F2D00EDBA70 /* libmod_bmp_la-mptr_bmp.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_bmp_la-mptr_bmp.lo"; sourceTree = "<group>"; };
+ A6AF26A20B965F2D00EDBA70 /* libmod_bmp_la-trgt_bmp.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_bmp_la-trgt_bmp.lo"; sourceTree = "<group>"; };
+ A6AF26A30B965F2D00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF26A40B965F2D00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF26A50B965F2D00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF26A60B965F2D00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF26A70B965F2D00EDBA70 /* mod_bmp.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_bmp.nsh; sourceTree = "<group>"; };
+ A6AF26A80B965F2D00EDBA70 /* mptr_bmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mptr_bmp.cpp; sourceTree = "<group>"; };
+ A6AF26A90B965F2D00EDBA70 /* mptr_bmp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mptr_bmp.h; sourceTree = "<group>"; };
+ A6AF26AA0B965F2D00EDBA70 /* trgt_bmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = trgt_bmp.cpp; sourceTree = "<group>"; };
+ A6AF26AB0B965F2D00EDBA70 /* trgt_bmp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trgt_bmp.h; sourceTree = "<group>"; };
+ A6AF26AC0B965F2D00EDBA70 /* unmod_bmp.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_bmp.nsh; sourceTree = "<group>"; };
+ A6AF26AF0B965F2D00EDBA70 /* libmod_dv_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_dv_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF26B00B965F2D00EDBA70 /* libmod_dv_la-trgt_dv.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_dv_la-trgt_dv.Plo"; sourceTree = "<group>"; };
+ A6AF26B20B965F2D00EDBA70 /* libmod_dv.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_dv.0.0.0.so; sourceTree = "<group>"; };
+ A6AF26B30B965F2D00EDBA70 /* libmod_dv.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_dv.0.so; sourceTree = "<group>"; };
+ A6AF26B40B965F2D00EDBA70 /* libmod_dv.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_dv.la; sourceTree = "<group>"; };
+ A6AF26B50B965F2D00EDBA70 /* libmod_dv.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_dv.lai; sourceTree = "<group>"; };
+ A6AF26B60B965F2D00EDBA70 /* libmod_dv.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_dv.so; sourceTree = "<group>"; };
+ A6AF26B70B965F2D00EDBA70 /* libmod_dv_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_dv_la-main.o"; sourceTree = "<group>"; };
+ A6AF26B80B965F2D00EDBA70 /* libmod_dv_la-trgt_dv.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_dv_la-trgt_dv.o"; sourceTree = "<group>"; };
+ A6AF26B90B965F2D00EDBA70 /* libmod_dv.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_dv.la; sourceTree = "<group>"; };
+ A6AF26BA0B965F2D00EDBA70 /* libmod_dv_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_dv_la-main.lo"; sourceTree = "<group>"; };
+ A6AF26BB0B965F2D00EDBA70 /* libmod_dv_la-trgt_dv.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_dv_la-trgt_dv.lo"; sourceTree = "<group>"; };
+ A6AF26BC0B965F2D00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF26BD0B965F2D00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF26BE0B965F2D00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF26BF0B965F2D00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF26C00B965F2D00EDBA70 /* mod_dv.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_dv.nsh; sourceTree = "<group>"; };
+ A6AF26C10B965F2D00EDBA70 /* trgt_dv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = trgt_dv.cpp; sourceTree = "<group>"; };
+ A6AF26C20B965F2D00EDBA70 /* trgt_dv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trgt_dv.h; sourceTree = "<group>"; };
+ A6AF26C30B965F2D00EDBA70 /* unmod_dv.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_dv.nsh; sourceTree = "<group>"; };
+ A6AF26C60B965F2D00EDBA70 /* libmod_ffmpeg_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_ffmpeg_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF26C70B965F2D00EDBA70 /* libmod_ffmpeg_la-mptr_ffmpeg.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_ffmpeg_la-mptr_ffmpeg.Plo"; sourceTree = "<group>"; };
+ A6AF26C80B965F2D00EDBA70 /* libmod_ffmpeg_la-trgt_ffmpeg.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_ffmpeg_la-trgt_ffmpeg.Plo"; sourceTree = "<group>"; };
+ A6AF26CA0B965F2D00EDBA70 /* libmod_ffmpeg.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_ffmpeg.0.0.0.so; sourceTree = "<group>"; };
+ A6AF26CB0B965F2D00EDBA70 /* libmod_ffmpeg.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_ffmpeg.0.so; sourceTree = "<group>"; };
+ A6AF26CC0B965F2D00EDBA70 /* libmod_ffmpeg.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_ffmpeg.la; sourceTree = "<group>"; };
+ A6AF26CD0B965F2D00EDBA70 /* libmod_ffmpeg.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_ffmpeg.lai; sourceTree = "<group>"; };
+ A6AF26CE0B965F2D00EDBA70 /* libmod_ffmpeg.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_ffmpeg.so; sourceTree = "<group>"; };
+ A6AF26CF0B965F2D00EDBA70 /* libmod_ffmpeg_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_ffmpeg_la-main.o"; sourceTree = "<group>"; };
+ A6AF26D00B965F2D00EDBA70 /* libmod_ffmpeg_la-mptr_ffmpeg.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_ffmpeg_la-mptr_ffmpeg.o"; sourceTree = "<group>"; };
+ A6AF26D10B965F2D00EDBA70 /* libmod_ffmpeg_la-trgt_ffmpeg.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_ffmpeg_la-trgt_ffmpeg.o"; sourceTree = "<group>"; };
+ A6AF26D20B965F2D00EDBA70 /* libmod_ffmpeg.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_ffmpeg.la; sourceTree = "<group>"; };
+ A6AF26D30B965F2D00EDBA70 /* libmod_ffmpeg_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_ffmpeg_la-main.lo"; sourceTree = "<group>"; };
+ A6AF26D40B965F2D00EDBA70 /* libmod_ffmpeg_la-mptr_ffmpeg.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_ffmpeg_la-mptr_ffmpeg.lo"; sourceTree = "<group>"; };
+ A6AF26D50B965F2D00EDBA70 /* libmod_ffmpeg_la-trgt_ffmpeg.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_ffmpeg_la-trgt_ffmpeg.lo"; sourceTree = "<group>"; };
+ A6AF26D60B965F2D00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF26D70B965F2D00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF26D80B965F2D00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF26D90B965F2D00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF26DA0B965F2D00EDBA70 /* mod_ffmpeg.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_ffmpeg.nsh; sourceTree = "<group>"; };
+ A6AF26DB0B965F2D00EDBA70 /* mptr_ffmpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mptr_ffmpeg.cpp; sourceTree = "<group>"; };
+ A6AF26DC0B965F2D00EDBA70 /* mptr_ffmpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mptr_ffmpeg.h; sourceTree = "<group>"; };
+ A6AF26DD0B965F2D00EDBA70 /* trgt_ffmpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = trgt_ffmpeg.cpp; sourceTree = "<group>"; };
+ A6AF26DE0B965F2D00EDBA70 /* trgt_ffmpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trgt_ffmpeg.h; sourceTree = "<group>"; };
+ A6AF26DF0B965F2D00EDBA70 /* unmod_ffmpeg.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_ffmpeg.nsh; sourceTree = "<group>"; };
+ A6AF26E20B965F2D00EDBA70 /* libmod_filter_la-blur.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-blur.Plo"; sourceTree = "<group>"; };
+ A6AF26E30B965F2D00EDBA70 /* libmod_filter_la-colorcorrect.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-colorcorrect.Plo"; sourceTree = "<group>"; };
+ A6AF26E40B965F2D00EDBA70 /* libmod_filter_la-halftone.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-halftone.Plo"; sourceTree = "<group>"; };
+ A6AF26E50B965F2D00EDBA70 /* libmod_filter_la-halftone2.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-halftone2.Plo"; sourceTree = "<group>"; };
+ A6AF26E60B965F2D00EDBA70 /* libmod_filter_la-halftone3.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-halftone3.Plo"; sourceTree = "<group>"; };
+ A6AF26E70B965F2D00EDBA70 /* libmod_filter_la-lumakey.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-lumakey.Plo"; sourceTree = "<group>"; };
+ A6AF26E80B965F2D00EDBA70 /* libmod_filter_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF26E90B965F2D00EDBA70 /* libmod_filter_la-radialblur.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-radialblur.Plo"; sourceTree = "<group>"; };
+ A6AF26EB0B965F2D00EDBA70 /* libmod_filter.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_filter.0.0.0.so; sourceTree = "<group>"; };
+ A6AF26EC0B965F2D00EDBA70 /* libmod_filter.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_filter.0.so; sourceTree = "<group>"; };
+ A6AF26ED0B965F2D00EDBA70 /* libmod_filter.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_filter.la; sourceTree = "<group>"; };
+ A6AF26EE0B965F2D00EDBA70 /* libmod_filter.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_filter.lai; sourceTree = "<group>"; };
+ A6AF26EF0B965F2D00EDBA70 /* libmod_filter.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_filter.so; sourceTree = "<group>"; };
+ A6AF26F00B965F2D00EDBA70 /* libmod_filter_la-blur.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_filter_la-blur.o"; sourceTree = "<group>"; };
+ A6AF26F10B965F2D00EDBA70 /* libmod_filter_la-colorcorrect.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_filter_la-colorcorrect.o"; sourceTree = "<group>"; };
+ A6AF26F20B965F2D00EDBA70 /* libmod_filter_la-halftone.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_filter_la-halftone.o"; sourceTree = "<group>"; };
+ A6AF26F30B965F2D00EDBA70 /* libmod_filter_la-halftone2.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_filter_la-halftone2.o"; sourceTree = "<group>"; };
+ A6AF26F40B965F2D00EDBA70 /* libmod_filter_la-halftone3.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_filter_la-halftone3.o"; sourceTree = "<group>"; };
+ A6AF26F50B965F2D00EDBA70 /* libmod_filter_la-lumakey.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_filter_la-lumakey.o"; sourceTree = "<group>"; };
+ A6AF26F60B965F2D00EDBA70 /* libmod_filter_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_filter_la-main.o"; sourceTree = "<group>"; };
+ A6AF26F70B965F2D00EDBA70 /* libmod_filter_la-radialblur.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_filter_la-radialblur.o"; sourceTree = "<group>"; };
+ A6AF26F80B965F2D00EDBA70 /* blur.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = blur.cpp; sourceTree = "<group>"; };
+ A6AF26F90B965F2D00EDBA70 /* blur.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = blur.h; sourceTree = "<group>"; };
+ A6AF26FA0B965F2D00EDBA70 /* colorcorrect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = colorcorrect.cpp; sourceTree = "<group>"; };
+ A6AF26FB0B965F2D00EDBA70 /* colorcorrect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = colorcorrect.h; sourceTree = "<group>"; };
+ A6AF26FC0B965F2D00EDBA70 /* halftone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = halftone.cpp; sourceTree = "<group>"; };
+ A6AF26FD0B965F2D00EDBA70 /* halftone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = halftone.h; sourceTree = "<group>"; };
+ A6AF26FE0B965F2D00EDBA70 /* halftone2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = halftone2.cpp; sourceTree = "<group>"; };
+ A6AF26FF0B965F2D00EDBA70 /* halftone2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = halftone2.h; sourceTree = "<group>"; };
+ A6AF27000B965F2D00EDBA70 /* halftone3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = halftone3.cpp; sourceTree = "<group>"; };
+ A6AF27010B965F2D00EDBA70 /* halftone3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = halftone3.h; sourceTree = "<group>"; };
+ A6AF27020B965F2D00EDBA70 /* libmod_filter.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_filter.la; sourceTree = "<group>"; };
+ A6AF27030B965F2D00EDBA70 /* libmod_filter_la-blur.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-blur.lo"; sourceTree = "<group>"; };
+ A6AF27040B965F2D00EDBA70 /* libmod_filter_la-colorcorrect.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-colorcorrect.lo"; sourceTree = "<group>"; };
+ A6AF27050B965F2D00EDBA70 /* libmod_filter_la-halftone.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-halftone.lo"; sourceTree = "<group>"; };
+ A6AF27060B965F2D00EDBA70 /* libmod_filter_la-halftone2.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-halftone2.lo"; sourceTree = "<group>"; };
+ A6AF27070B965F2D00EDBA70 /* libmod_filter_la-halftone3.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-halftone3.lo"; sourceTree = "<group>"; };
+ A6AF27080B965F2D00EDBA70 /* libmod_filter_la-lumakey.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-lumakey.lo"; sourceTree = "<group>"; };
+ A6AF27090B965F2D00EDBA70 /* libmod_filter_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-main.lo"; sourceTree = "<group>"; };
+ A6AF270A0B965F2D00EDBA70 /* libmod_filter_la-radialblur.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_filter_la-radialblur.lo"; sourceTree = "<group>"; };
+ A6AF270B0B965F2D00EDBA70 /* lumakey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lumakey.cpp; sourceTree = "<group>"; };
+ A6AF270C0B965F2D00EDBA70 /* lumakey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lumakey.h; sourceTree = "<group>"; };
+ A6AF270D0B965F2D00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF270E0B965F2D00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF270F0B965F2D00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF27100B965F2D00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF27110B965F2D00EDBA70 /* mod_filter.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_filter.nsh; sourceTree = "<group>"; };
+ A6AF27120B965F2D00EDBA70 /* radialblur.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = radialblur.cpp; sourceTree = "<group>"; };
+ A6AF27130B965F2D00EDBA70 /* radialblur.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = radialblur.h; sourceTree = "<group>"; };
+ A6AF27140B965F2D00EDBA70 /* unmod_filter.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_filter.nsh; sourceTree = "<group>"; };
+ A6AF27170B965F2D00EDBA70 /* libmod_geometry_la-checkerboard.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-checkerboard.Plo"; sourceTree = "<group>"; };
+ A6AF27180B965F2D00EDBA70 /* libmod_geometry_la-circle.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-circle.Plo"; sourceTree = "<group>"; };
+ A6AF27190B965F2D00EDBA70 /* libmod_geometry_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF271A0B965F2D00EDBA70 /* libmod_geometry_la-outline.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-outline.Plo"; sourceTree = "<group>"; };
+ A6AF271B0B965F2D00EDBA70 /* libmod_geometry_la-rectangle.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-rectangle.Plo"; sourceTree = "<group>"; };
+ A6AF271C0B965F2D00EDBA70 /* libmod_geometry_la-region.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-region.Plo"; sourceTree = "<group>"; };
+ A6AF271D0B965F2D00EDBA70 /* libmod_geometry_la-star.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-star.Plo"; sourceTree = "<group>"; };
+ A6AF271F0B965F2D00EDBA70 /* libmod_geometry.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_geometry.0.0.0.so; sourceTree = "<group>"; };
+ A6AF27200B965F2D00EDBA70 /* libmod_geometry.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_geometry.0.so; sourceTree = "<group>"; };
+ A6AF27210B965F2D00EDBA70 /* libmod_geometry.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_geometry.la; sourceTree = "<group>"; };
+ A6AF27220B965F2D00EDBA70 /* libmod_geometry.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_geometry.lai; sourceTree = "<group>"; };
+ A6AF27230B965F2D00EDBA70 /* libmod_geometry.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_geometry.so; sourceTree = "<group>"; };
+ A6AF27240B965F2D00EDBA70 /* libmod_geometry_la-checkerboard.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_geometry_la-checkerboard.o"; sourceTree = "<group>"; };
+ A6AF27250B965F2D00EDBA70 /* libmod_geometry_la-circle.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_geometry_la-circle.o"; sourceTree = "<group>"; };
+ A6AF27260B965F2D00EDBA70 /* libmod_geometry_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_geometry_la-main.o"; sourceTree = "<group>"; };
+ A6AF27270B965F2D00EDBA70 /* libmod_geometry_la-outline.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_geometry_la-outline.o"; sourceTree = "<group>"; };
+ A6AF27280B965F2D00EDBA70 /* libmod_geometry_la-rectangle.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_geometry_la-rectangle.o"; sourceTree = "<group>"; };
+ A6AF27290B965F2D00EDBA70 /* libmod_geometry_la-region.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_geometry_la-region.o"; sourceTree = "<group>"; };
+ A6AF272A0B965F2D00EDBA70 /* libmod_geometry_la-star.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_geometry_la-star.o"; sourceTree = "<group>"; };
+ A6AF272B0B965F2D00EDBA70 /* checkerboard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = checkerboard.cpp; sourceTree = "<group>"; };
+ A6AF272C0B965F2D00EDBA70 /* checkerboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = checkerboard.h; sourceTree = "<group>"; };
+ A6AF272D0B965F2D00EDBA70 /* circle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = circle.cpp; sourceTree = "<group>"; };
+ A6AF272E0B965F2D00EDBA70 /* circle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = circle.h; sourceTree = "<group>"; };
+ A6AF272F0B965F2D00EDBA70 /* libmod_geometry.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_geometry.la; sourceTree = "<group>"; };
+ A6AF27300B965F2D00EDBA70 /* libmod_geometry_la-checkerboard.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-checkerboard.lo"; sourceTree = "<group>"; };
+ A6AF27310B965F2D00EDBA70 /* libmod_geometry_la-circle.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-circle.lo"; sourceTree = "<group>"; };
+ A6AF27320B965F2D00EDBA70 /* libmod_geometry_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-main.lo"; sourceTree = "<group>"; };
+ A6AF27330B965F2D00EDBA70 /* libmod_geometry_la-outline.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-outline.lo"; sourceTree = "<group>"; };
+ A6AF27340B965F2D00EDBA70 /* libmod_geometry_la-rectangle.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-rectangle.lo"; sourceTree = "<group>"; };
+ A6AF27350B965F2D00EDBA70 /* libmod_geometry_la-region.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-region.lo"; sourceTree = "<group>"; };
+ A6AF27360B965F2D00EDBA70 /* libmod_geometry_la-star.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_geometry_la-star.lo"; sourceTree = "<group>"; };
+ A6AF27370B965F2D00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF27380B965F2D00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF27390B965F2D00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF273A0B965F2D00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF273B0B965F2D00EDBA70 /* mod_geometry.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_geometry.nsh; sourceTree = "<group>"; };
+ A6AF273C0B965F2D00EDBA70 /* outline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = outline.cpp; sourceTree = "<group>"; };
+ A6AF273D0B965F2D00EDBA70 /* outline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = outline.h; sourceTree = "<group>"; };
+ A6AF273E0B965F2D00EDBA70 /* rectangle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rectangle.cpp; sourceTree = "<group>"; };
+ A6AF273F0B965F2D00EDBA70 /* rectangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rectangle.h; sourceTree = "<group>"; };
+ A6AF27400B965F2D00EDBA70 /* region.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = region.cpp; sourceTree = "<group>"; };
+ A6AF27410B965F2D00EDBA70 /* region.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = region.h; sourceTree = "<group>"; };
+ A6AF27420B965F2D00EDBA70 /* star.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = star.cpp; sourceTree = "<group>"; };
+ A6AF27430B965F2D00EDBA70 /* star.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = star.h; sourceTree = "<group>"; };
+ A6AF27440B965F2D00EDBA70 /* unmod_geometry.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_geometry.nsh; sourceTree = "<group>"; };
+ A6AF27470B965F2D00EDBA70 /* libmod_gif_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gif_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF27480B965F2D00EDBA70 /* libmod_gif_la-trgt_gif.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gif_la-trgt_gif.Plo"; sourceTree = "<group>"; };
+ A6AF274A0B965F2D00EDBA70 /* libmod_gif.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_gif.0.0.0.so; sourceTree = "<group>"; };
+ A6AF274B0B965F2D00EDBA70 /* libmod_gif.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_gif.0.so; sourceTree = "<group>"; };
+ A6AF274C0B965F2D00EDBA70 /* libmod_gif.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_gif.la; sourceTree = "<group>"; };
+ A6AF274D0B965F2D00EDBA70 /* libmod_gif.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_gif.lai; sourceTree = "<group>"; };
+ A6AF274E0B965F2D00EDBA70 /* libmod_gif.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_gif.so; sourceTree = "<group>"; };
+ A6AF274F0B965F2D00EDBA70 /* libmod_gif_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_gif_la-main.o"; sourceTree = "<group>"; };
+ A6AF27500B965F2D00EDBA70 /* libmod_gif_la-trgt_gif.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_gif_la-trgt_gif.o"; sourceTree = "<group>"; };
+ A6AF27510B965F2D00EDBA70 /* libmod_gif.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_gif.la; sourceTree = "<group>"; };
+ A6AF27520B965F2D00EDBA70 /* libmod_gif_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gif_la-main.lo"; sourceTree = "<group>"; };
+ A6AF27530B965F2D00EDBA70 /* libmod_gif_la-trgt_gif.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gif_la-trgt_gif.lo"; sourceTree = "<group>"; };
+ A6AF27540B965F2D00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF27550B965F2D00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF27560B965F2D00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF27570B965F2D00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF27580B965F2D00EDBA70 /* mod_gif.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_gif.nsh; sourceTree = "<group>"; };
+ A6AF27590B965F2D00EDBA70 /* trgt_gif.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = trgt_gif.cpp; sourceTree = "<group>"; };
+ A6AF275A0B965F2D00EDBA70 /* trgt_gif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trgt_gif.h; sourceTree = "<group>"; };
+ A6AF275B0B965F2D00EDBA70 /* unmod_gif.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_gif.nsh; sourceTree = "<group>"; };
+ A6AF275E0B965F2D00EDBA70 /* libmod_gradient_la-conicalgradient.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gradient_la-conicalgradient.Plo"; sourceTree = "<group>"; };
+ A6AF275F0B965F2D00EDBA70 /* libmod_gradient_la-curvegradient.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gradient_la-curvegradient.Plo"; sourceTree = "<group>"; };
+ A6AF27600B965F2D00EDBA70 /* libmod_gradient_la-lineargradient.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gradient_la-lineargradient.Plo"; sourceTree = "<group>"; };
+ A6AF27610B965F2D00EDBA70 /* libmod_gradient_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gradient_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF27620B965F2D00EDBA70 /* libmod_gradient_la-radialgradient.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gradient_la-radialgradient.Plo"; sourceTree = "<group>"; };
+ A6AF27630B965F2D00EDBA70 /* libmod_gradient_la-spiralgradient.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gradient_la-spiralgradient.Plo"; sourceTree = "<group>"; };
+ A6AF27650B965F2D00EDBA70 /* libmod_gradient.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_gradient.0.0.0.so; sourceTree = "<group>"; };
+ A6AF27660B965F2D00EDBA70 /* libmod_gradient.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_gradient.0.so; sourceTree = "<group>"; };
+ A6AF27670B965F2D00EDBA70 /* libmod_gradient.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_gradient.la; sourceTree = "<group>"; };
+ A6AF27680B965F2D00EDBA70 /* libmod_gradient.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_gradient.lai; sourceTree = "<group>"; };
+ A6AF27690B965F2D00EDBA70 /* libmod_gradient.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_gradient.so; sourceTree = "<group>"; };
+ A6AF276A0B965F2D00EDBA70 /* libmod_gradient_la-conicalgradient.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_gradient_la-conicalgradient.o"; sourceTree = "<group>"; };
+ A6AF276B0B965F2D00EDBA70 /* libmod_gradient_la-curvegradient.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_gradient_la-curvegradient.o"; sourceTree = "<group>"; };
+ A6AF276C0B965F2D00EDBA70 /* libmod_gradient_la-lineargradient.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_gradient_la-lineargradient.o"; sourceTree = "<group>"; };
+ A6AF276D0B965F2D00EDBA70 /* libmod_gradient_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_gradient_la-main.o"; sourceTree = "<group>"; };
+ A6AF276E0B965F2D00EDBA70 /* libmod_gradient_la-radialgradient.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_gradient_la-radialgradient.o"; sourceTree = "<group>"; };
+ A6AF276F0B965F2D00EDBA70 /* libmod_gradient_la-spiralgradient.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_gradient_la-spiralgradient.o"; sourceTree = "<group>"; };
+ A6AF27700B965F2D00EDBA70 /* conicalgradient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conicalgradient.cpp; sourceTree = "<group>"; };
+ A6AF27710B965F2D00EDBA70 /* conicalgradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conicalgradient.h; sourceTree = "<group>"; };
+ A6AF27720B965F2D00EDBA70 /* curvegradient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = curvegradient.cpp; sourceTree = "<group>"; };
+ A6AF27730B965F2D00EDBA70 /* curvegradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = curvegradient.h; sourceTree = "<group>"; };
+ A6AF27740B965F2D00EDBA70 /* libmod_gradient.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_gradient.la; sourceTree = "<group>"; };
+ A6AF27750B965F2D00EDBA70 /* libmod_gradient_la-conicalgradient.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gradient_la-conicalgradient.lo"; sourceTree = "<group>"; };
+ A6AF27760B965F2D00EDBA70 /* libmod_gradient_la-curvegradient.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gradient_la-curvegradient.lo"; sourceTree = "<group>"; };
+ A6AF27770B965F2D00EDBA70 /* libmod_gradient_la-lineargradient.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gradient_la-lineargradient.lo"; sourceTree = "<group>"; };
+ A6AF27780B965F2D00EDBA70 /* libmod_gradient_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gradient_la-main.lo"; sourceTree = "<group>"; };
+ A6AF27790B965F2D00EDBA70 /* libmod_gradient_la-radialgradient.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gradient_la-radialgradient.lo"; sourceTree = "<group>"; };
+ A6AF277A0B965F2D00EDBA70 /* libmod_gradient_la-spiralgradient.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_gradient_la-spiralgradient.lo"; sourceTree = "<group>"; };
+ A6AF277B0B965F2D00EDBA70 /* lineargradient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lineargradient.cpp; sourceTree = "<group>"; };
+ A6AF277C0B965F2D00EDBA70 /* lineargradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lineargradient.h; sourceTree = "<group>"; };
+ A6AF277D0B965F2D00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF277E0B965F2D00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF277F0B965F2D00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF27800B965F2D00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF27810B965F2D00EDBA70 /* mod_gradient.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_gradient.nsh; sourceTree = "<group>"; };
+ A6AF27820B965F2D00EDBA70 /* radialgradient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = radialgradient.cpp; sourceTree = "<group>"; };
+ A6AF27830B965F2D00EDBA70 /* radialgradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = radialgradient.h; sourceTree = "<group>"; };
+ A6AF27840B965F2D00EDBA70 /* spiralgradient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spiralgradient.cpp; sourceTree = "<group>"; };
+ A6AF27850B965F2D00EDBA70 /* spiralgradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spiralgradient.h; sourceTree = "<group>"; };
+ A6AF27860B965F2D00EDBA70 /* unmod_gradient.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_gradient.nsh; sourceTree = "<group>"; };
+ A6AF27890B965F2D00EDBA70 /* libmod_imagemagick_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_imagemagick_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF278A0B965F2D00EDBA70 /* libmod_imagemagick_la-mptr_imagemagick.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_imagemagick_la-mptr_imagemagick.Plo"; sourceTree = "<group>"; };
+ A6AF278B0B965F2D00EDBA70 /* libmod_imagemagick_la-trgt_imagemagick.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_imagemagick_la-trgt_imagemagick.Plo"; sourceTree = "<group>"; };
+ A6AF278C0B965F2D00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF278D0B965F2D00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF278E0B965F2D00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF278F0B965F2D00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF27900B965F2D00EDBA70 /* mod_imagemagick.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_imagemagick.nsh; sourceTree = "<group>"; };
+ A6AF27910B965F2D00EDBA70 /* mptr_imagemagick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mptr_imagemagick.cpp; sourceTree = "<group>"; };
+ A6AF27920B965F2D00EDBA70 /* mptr_imagemagick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mptr_imagemagick.h; sourceTree = "<group>"; };
+ A6AF27930B965F2D00EDBA70 /* trgt_imagemagick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = trgt_imagemagick.cpp; sourceTree = "<group>"; };
+ A6AF27940B965F2D00EDBA70 /* trgt_imagemagick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trgt_imagemagick.h; sourceTree = "<group>"; };
+ A6AF27950B965F2D00EDBA70 /* unmod_imagemagick.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_imagemagick.nsh; sourceTree = "<group>"; };
+ A6AF27980B965F2D00EDBA70 /* libmod_jpeg_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_jpeg_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF27990B965F2D00EDBA70 /* libmod_jpeg_la-mptr_jpeg.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_jpeg_la-mptr_jpeg.Plo"; sourceTree = "<group>"; };
+ A6AF279A0B965F2D00EDBA70 /* libmod_jpeg_la-trgt_jpeg.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_jpeg_la-trgt_jpeg.Plo"; sourceTree = "<group>"; };
+ A6AF279C0B965F2D00EDBA70 /* libmod_jpeg.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_jpeg.0.0.0.so; sourceTree = "<group>"; };
+ A6AF279D0B965F2D00EDBA70 /* libmod_jpeg.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_jpeg.0.so; sourceTree = "<group>"; };
+ A6AF279E0B965F2D00EDBA70 /* libmod_jpeg.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_jpeg.la; sourceTree = "<group>"; };
+ A6AF279F0B965F2D00EDBA70 /* libmod_jpeg.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_jpeg.lai; sourceTree = "<group>"; };
+ A6AF27A00B965F2D00EDBA70 /* libmod_jpeg.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_jpeg.so; sourceTree = "<group>"; };
+ A6AF27A10B965F2D00EDBA70 /* libmod_jpeg_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_jpeg_la-main.o"; sourceTree = "<group>"; };
+ A6AF27A20B965F2D00EDBA70 /* libmod_jpeg_la-mptr_jpeg.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_jpeg_la-mptr_jpeg.o"; sourceTree = "<group>"; };
+ A6AF27A30B965F2D00EDBA70 /* libmod_jpeg_la-trgt_jpeg.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_jpeg_la-trgt_jpeg.o"; sourceTree = "<group>"; };
+ A6AF27A40B965F2D00EDBA70 /* libmod_jpeg.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_jpeg.la; sourceTree = "<group>"; };
+ A6AF27A50B965F2D00EDBA70 /* libmod_jpeg_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_jpeg_la-main.lo"; sourceTree = "<group>"; };
+ A6AF27A60B965F2D00EDBA70 /* libmod_jpeg_la-mptr_jpeg.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_jpeg_la-mptr_jpeg.lo"; sourceTree = "<group>"; };
+ A6AF27A70B965F2D00EDBA70 /* libmod_jpeg_la-trgt_jpeg.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_jpeg_la-trgt_jpeg.lo"; sourceTree = "<group>"; };
+ A6AF27A80B965F2D00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF27A90B965F2D00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF27AA0B965F2D00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF27AB0B965F2D00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF27AC0B965F2D00EDBA70 /* mod_jpeg.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_jpeg.nsh; sourceTree = "<group>"; };
+ A6AF27AD0B965F2D00EDBA70 /* mptr_jpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mptr_jpeg.cpp; sourceTree = "<group>"; };
+ A6AF27AE0B965F2D00EDBA70 /* mptr_jpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mptr_jpeg.h; sourceTree = "<group>"; };
+ A6AF27AF0B965F2D00EDBA70 /* trgt_jpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = trgt_jpeg.cpp; sourceTree = "<group>"; };
+ A6AF27B00B965F2D00EDBA70 /* trgt_jpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trgt_jpeg.h; sourceTree = "<group>"; };
+ A6AF27B10B965F2D00EDBA70 /* unmod_jpeg.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_jpeg.nsh; sourceTree = "<group>"; };
+ A6AF27B40B965F2D00EDBA70 /* libmod_libavcodec_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_libavcodec_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF27B50B965F2D00EDBA70 /* libmod_libavcodec_la-mptr.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_libavcodec_la-mptr.Plo"; sourceTree = "<group>"; };
+ A6AF27B60B965F2D00EDBA70 /* libmod_libavcodec_la-trgt_av.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_libavcodec_la-trgt_av.Plo"; sourceTree = "<group>"; };
+ A6AF27B80B965F2D00EDBA70 /* 4xm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = 4xm.c; sourceTree = "<group>"; };
+ A6AF27B90B965F2D00EDBA70 /* a52dec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = a52dec.c; sourceTree = "<group>"; };
+ A6AF27BA0B965F2D00EDBA70 /* ac3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ac3.h; sourceTree = "<group>"; };
+ A6AF27BB0B965F2D00EDBA70 /* ac3dec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ac3dec.c; sourceTree = "<group>"; };
+ A6AF27BC0B965F2D00EDBA70 /* ac3enc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ac3enc.c; sourceTree = "<group>"; };
+ A6AF27BD0B965F2D00EDBA70 /* ac3tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ac3tab.h; sourceTree = "<group>"; };
+ A6AF27BE0B965F2D00EDBA70 /* adpcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adpcm.c; sourceTree = "<group>"; };
+ A6AF27BF0B965F2D00EDBA70 /* allcodecs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = allcodecs.c; sourceTree = "<group>"; };
+ A6AF27C00B965F2D00EDBA70 /* amr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = amr.c; sourceTree = "<group>"; };
+ A6AF27C10B965F2D00EDBA70 /* apiexample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = apiexample.c; sourceTree = "<group>"; };
+ A6AF27C20B965F2D00EDBA70 /* asv1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asv1.c; sourceTree = "<group>"; };
+ A6AF27C30B965F2D00EDBA70 /* avcodec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = avcodec.c; sourceTree = "<group>"; };
+ A6AF27C40B965F2D00EDBA70 /* avcodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avcodec.h; sourceTree = "<group>"; };
+ A6AF27C50B965F2D00EDBA70 /* bswap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bswap.h; sourceTree = "<group>"; };
+ A6AF27C60B965F2D00EDBA70 /* cabac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cabac.c; sourceTree = "<group>"; };
+ A6AF27C70B965F2D00EDBA70 /* cabac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cabac.h; sourceTree = "<group>"; };
+ A6AF27C80B965F2D00EDBA70 /* cljr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cljr.c; sourceTree = "<group>"; };
+ A6AF27C90B965F2D00EDBA70 /* common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = common.c; sourceTree = "<group>"; };
+ A6AF27CA0B965F2D00EDBA70 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
+ A6AF27CB0B965F2D00EDBA70 /* cyuv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cyuv.c; sourceTree = "<group>"; };
+ A6AF27CC0B965F2D00EDBA70 /* dct-test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "dct-test.c"; sourceTree = "<group>"; };
+ A6AF27CD0B965F2D00EDBA70 /* Doxyfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Doxyfile; sourceTree = "<group>"; };
+ A6AF27CE0B965F2D00EDBA70 /* dpcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dpcm.c; sourceTree = "<group>"; };
+ A6AF27CF0B965F2D00EDBA70 /* dsputil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dsputil.c; sourceTree = "<group>"; };
+ A6AF27D00B965F2E00EDBA70 /* dsputil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dsputil.h; sourceTree = "<group>"; };
+ A6AF27D10B965F2E00EDBA70 /* dv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dv.c; sourceTree = "<group>"; };
+ A6AF27D20B965F2E00EDBA70 /* dvdata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dvdata.h; sourceTree = "<group>"; };
+ A6AF27D30B965F2E00EDBA70 /* error_resilience.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = error_resilience.c; sourceTree = "<group>"; };
+ A6AF27D40B965F2E00EDBA70 /* eval.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = eval.c; sourceTree = "<group>"; };
+ A6AF27D50B965F2E00EDBA70 /* faad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = faad.c; sourceTree = "<group>"; };
+ A6AF27D60B965F2E00EDBA70 /* fastmemcpy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fastmemcpy.h; sourceTree = "<group>"; };
+ A6AF27D70B965F2E00EDBA70 /* fdctref.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fdctref.c; sourceTree = "<group>"; };
+ A6AF27D80B965F2E00EDBA70 /* fft-test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "fft-test.c"; sourceTree = "<group>"; };
+ A6AF27D90B965F2E00EDBA70 /* fft.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fft.c; sourceTree = "<group>"; };
+ A6AF27DA0B965F2E00EDBA70 /* ffv1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffv1.c; sourceTree = "<group>"; };
+ A6AF27DB0B965F2E00EDBA70 /* golomb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = golomb.c; sourceTree = "<group>"; };
+ A6AF27DC0B965F2E00EDBA70 /* golomb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = golomb.h; sourceTree = "<group>"; };
+ A6AF27DD0B965F2E00EDBA70 /* h263.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = h263.c; sourceTree = "<group>"; };
+ A6AF27DE0B965F2E00EDBA70 /* h263data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = h263data.h; sourceTree = "<group>"; };
+ A6AF27DF0B965F2E00EDBA70 /* h263dec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = h263dec.c; sourceTree = "<group>"; };
+ A6AF27E00B965F2E00EDBA70 /* h264.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = h264.c; sourceTree = "<group>"; };
+ A6AF27E10B965F2E00EDBA70 /* h264data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = h264data.h; sourceTree = "<group>"; };
+ A6AF27E20B965F2E00EDBA70 /* huffyuv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = huffyuv.c; sourceTree = "<group>"; };
+ A6AF27E40B965F2E00EDBA70 /* cputest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cputest.c; sourceTree = "<group>"; };
+ A6AF27E50B965F2E00EDBA70 /* dsputil_mmx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dsputil_mmx.c; sourceTree = "<group>"; };
+ A6AF27E60B965F2E00EDBA70 /* dsputil_mmx_avg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dsputil_mmx_avg.h; sourceTree = "<group>"; };
+ A6AF27E70B965F2E00EDBA70 /* dsputil_mmx_rnd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dsputil_mmx_rnd.h; sourceTree = "<group>"; };
+ A6AF27E80B965F2E00EDBA70 /* fdct_mmx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fdct_mmx.c; sourceTree = "<group>"; };
+ A6AF27E90B965F2E00EDBA70 /* fft_sse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fft_sse.c; sourceTree = "<group>"; };
+ A6AF27EA0B965F2E00EDBA70 /* idct_mmx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = idct_mmx.c; sourceTree = "<group>"; };
+ A6AF27EB0B965F2E00EDBA70 /* mmx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mmx.h; sourceTree = "<group>"; };
+ A6AF27EC0B965F2E00EDBA70 /* motion_est_mmx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = motion_est_mmx.c; sourceTree = "<group>"; };
+ A6AF27ED0B965F2E00EDBA70 /* mpegvideo_mmx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegvideo_mmx.c; sourceTree = "<group>"; };
+ A6AF27EE0B965F2E00EDBA70 /* mpegvideo_mmx_template.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegvideo_mmx_template.c; sourceTree = "<group>"; };
+ A6AF27EF0B965F2E00EDBA70 /* simple_idct_mmx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = simple_idct_mmx.c; sourceTree = "<group>"; };
+ A6AF27F00B965F2E00EDBA70 /* imgconvert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = imgconvert.c; sourceTree = "<group>"; };
+ A6AF27F10B965F2E00EDBA70 /* imgconvert_template.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgconvert_template.h; sourceTree = "<group>"; };
+ A6AF27F20B965F2E00EDBA70 /* imgresample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = imgresample.c; sourceTree = "<group>"; };
+ A6AF27F30B965F2E00EDBA70 /* indeo3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = indeo3.c; sourceTree = "<group>"; };
+ A6AF27F40B965F2E00EDBA70 /* indeo3data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = indeo3data.h; sourceTree = "<group>"; };
+ A6AF27F50B965F2E00EDBA70 /* interplayvideo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = interplayvideo.c; sourceTree = "<group>"; };
+ A6AF27F60B965F2E00EDBA70 /* jfdctfst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jfdctfst.c; sourceTree = "<group>"; };
+ A6AF27F70B965F2E00EDBA70 /* jfdctint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jfdctint.c; sourceTree = "<group>"; };
+ A6AF27F80B965F2E00EDBA70 /* jrevdct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jrevdct.c; sourceTree = "<group>"; };
+ A6AF27FA0B965F2E00EDBA70 /* a52.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = a52.h; sourceTree = "<group>"; };
+ A6AF27FB0B965F2E00EDBA70 /* a52_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = a52_internal.h; sourceTree = "<group>"; };
+ A6AF27FC0B965F2E00EDBA70 /* a52_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = a52_util.h; sourceTree = "<group>"; };
+ A6AF27FD0B965F2E00EDBA70 /* bit_allocate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bit_allocate.c; sourceTree = "<group>"; };
+ A6AF27FE0B965F2E00EDBA70 /* bitstream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bitstream.c; sourceTree = "<group>"; };
+ A6AF27FF0B965F2E00EDBA70 /* bitstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bitstream.h; sourceTree = "<group>"; };
+ A6AF28000B965F2E00EDBA70 /* crc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crc.c; sourceTree = "<group>"; };
+ A6AF28010B965F2E00EDBA70 /* downmix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = downmix.c; sourceTree = "<group>"; };
+ A6AF28020B965F2E00EDBA70 /* imdct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = imdct.c; sourceTree = "<group>"; };
+ A6AF28030B965F2E00EDBA70 /* mm_accel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mm_accel.h; sourceTree = "<group>"; };
+ A6AF28040B965F2E00EDBA70 /* parse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = parse.c; sourceTree = "<group>"; };
+ A6AF28050B965F2E00EDBA70 /* resample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resample.c; sourceTree = "<group>"; };
+ A6AF28060B965F2E00EDBA70 /* resample_c.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resample_c.c; sourceTree = "<group>"; };
+ A6AF28070B965F2E00EDBA70 /* resample_mmx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resample_mmx.c; sourceTree = "<group>"; };
+ A6AF28080B965F2E00EDBA70 /* tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tables.h; sourceTree = "<group>"; };
+ A6AF280A0B965F2E00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF280B0B965F2E00EDBA70 /* mangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mangle.h; sourceTree = "<group>"; };
+ A6AF280C0B965F2E00EDBA70 /* postprocess.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = postprocess.c; sourceTree = "<group>"; };
+ A6AF280D0B965F2E00EDBA70 /* postprocess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = postprocess.h; sourceTree = "<group>"; };
+ A6AF280E0B965F2E00EDBA70 /* postprocess_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = postprocess_internal.h; sourceTree = "<group>"; };
+ A6AF280F0B965F2E00EDBA70 /* postprocess_template.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = postprocess_template.c; sourceTree = "<group>"; };
+ A6AF28100B965F2E00EDBA70 /* mace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mace.c; sourceTree = "<group>"; };
+ A6AF28110B965F2E00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF28120B965F2E00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF28130B965F2E00EDBA70 /* mdct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mdct.c; sourceTree = "<group>"; };
+ A6AF28140B965F2E00EDBA70 /* mdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mdec.c; sourceTree = "<group>"; };
+ A6AF28150B965F2E00EDBA70 /* mem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mem.c; sourceTree = "<group>"; };
+ A6AF28160B965F2E00EDBA70 /* mjpeg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mjpeg.c; sourceTree = "<group>"; };
+ A6AF28170B965F2E00EDBA70 /* motion_est.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = motion_est.c; sourceTree = "<group>"; };
+ A6AF28180B965F2E00EDBA70 /* motion_est_template.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = motion_est_template.c; sourceTree = "<group>"; };
+ A6AF28190B965F2E00EDBA70 /* motion_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = motion_test.c; sourceTree = "<group>"; };
+ A6AF281A0B965F2E00EDBA70 /* mp3lameaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp3lameaudio.c; sourceTree = "<group>"; };
+ A6AF281B0B965F2E00EDBA70 /* mpeg12.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpeg12.c; sourceTree = "<group>"; };
+ A6AF281C0B965F2E00EDBA70 /* mpeg12data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpeg12data.h; sourceTree = "<group>"; };
+ A6AF281D0B965F2E00EDBA70 /* mpeg4data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpeg4data.h; sourceTree = "<group>"; };
+ A6AF281E0B965F2E00EDBA70 /* mpegaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudio.c; sourceTree = "<group>"; };
+ A6AF281F0B965F2E00EDBA70 /* mpegaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegaudio.h; sourceTree = "<group>"; };
+ A6AF28200B965F2E00EDBA70 /* mpegaudiodec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudiodec.c; sourceTree = "<group>"; };
+ A6AF28210B965F2E00EDBA70 /* mpegaudiodectab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegaudiodectab.h; sourceTree = "<group>"; };
+ A6AF28220B965F2E00EDBA70 /* mpegaudiotab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegaudiotab.h; sourceTree = "<group>"; };
+ A6AF28230B965F2E00EDBA70 /* mpegvideo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegvideo.c; sourceTree = "<group>"; };
+ A6AF28240B965F2E00EDBA70 /* mpegvideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegvideo.h; sourceTree = "<group>"; };
+ A6AF28250B965F2E00EDBA70 /* msmpeg4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = msmpeg4.c; sourceTree = "<group>"; };
+ A6AF28260B965F2E00EDBA70 /* msmpeg4data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msmpeg4data.h; sourceTree = "<group>"; };
+ A6AF28270B965F2E00EDBA70 /* oggvorbis.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = oggvorbis.c; sourceTree = "<group>"; };
+ A6AF28280B965F2E00EDBA70 /* oggvorbis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oggvorbis.h; sourceTree = "<group>"; };
+ A6AF28290B965F2E00EDBA70 /* opts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = opts.c; sourceTree = "<group>"; };
+ A6AF282A0B965F2E00EDBA70 /* pcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pcm.c; sourceTree = "<group>"; };
+ A6AF282B0B965F2E00EDBA70 /* ra144.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ra144.c; sourceTree = "<group>"; };
+ A6AF282C0B965F2E00EDBA70 /* ra144.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ra144.h; sourceTree = "<group>"; };
+ A6AF282D0B965F2E00EDBA70 /* ra288.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ra288.c; sourceTree = "<group>"; };
+ A6AF282E0B965F2E00EDBA70 /* ra288.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ra288.h; sourceTree = "<group>"; };
+ A6AF282F0B965F2E00EDBA70 /* ratecontrol.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ratecontrol.c; sourceTree = "<group>"; };
+ A6AF28300B965F2E00EDBA70 /* raw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = raw.c; sourceTree = "<group>"; };
+ A6AF28310B965F2E00EDBA70 /* resample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resample.c; sourceTree = "<group>"; };
+ A6AF28320B965F2E00EDBA70 /* roqvideo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = roqvideo.c; sourceTree = "<group>"; };
+ A6AF28330B965F2E00EDBA70 /* rv10.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rv10.c; sourceTree = "<group>"; };
+ A6AF28340B965F2E00EDBA70 /* simple_idct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = simple_idct.c; sourceTree = "<group>"; };
+ A6AF28350B965F2E00EDBA70 /* simple_idct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simple_idct.h; sourceTree = "<group>"; };
+ A6AF28360B965F2E00EDBA70 /* svq1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svq1.c; sourceTree = "<group>"; };
+ A6AF28370B965F2E00EDBA70 /* svq1_cb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = svq1_cb.h; sourceTree = "<group>"; };
+ A6AF28380B965F2E00EDBA70 /* svq1_vlc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = svq1_vlc.h; sourceTree = "<group>"; };
+ A6AF28390B965F2E00EDBA70 /* svq3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svq3.c; sourceTree = "<group>"; };
+ A6AF283A0B965F2E00EDBA70 /* utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utils.c; sourceTree = "<group>"; };
+ A6AF283B0B965F2E00EDBA70 /* vcr1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vcr1.c; sourceTree = "<group>"; };
+ A6AF283C0B965F2E00EDBA70 /* vp3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vp3.c; sourceTree = "<group>"; };
+ A6AF283D0B965F2E00EDBA70 /* vp3data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vp3data.h; sourceTree = "<group>"; };
+ A6AF283E0B965F2E00EDBA70 /* wmadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wmadata.h; sourceTree = "<group>"; };
+ A6AF283F0B965F2E00EDBA70 /* wmadec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wmadec.c; sourceTree = "<group>"; };
+ A6AF28400B965F2E00EDBA70 /* wmv2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wmv2.c; sourceTree = "<group>"; };
+ A6AF28410B965F2E00EDBA70 /* xan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xan.c; sourceTree = "<group>"; };
+ A6AF28420B965F2E00EDBA70 /* xvmcvideo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xvmcvideo.c; sourceTree = "<group>"; };
+ A6AF28440B965F2E00EDBA70 /* 4xm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = 4xm.c; sourceTree = "<group>"; };
+ A6AF28450B965F2E00EDBA70 /* allformats.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = allformats.c; sourceTree = "<group>"; };
+ A6AF28460B965F2E00EDBA70 /* amr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = amr.c; sourceTree = "<group>"; };
+ A6AF28470B965F2E00EDBA70 /* asf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asf.c; sourceTree = "<group>"; };
+ A6AF28480B965F2E00EDBA70 /* au.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = au.c; sourceTree = "<group>"; };
+ A6AF28490B965F2E00EDBA70 /* audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = audio.c; sourceTree = "<group>"; };
+ A6AF284A0B965F2E00EDBA70 /* avformat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avformat.h; sourceTree = "<group>"; };
+ A6AF284B0B965F2E00EDBA70 /* avi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avi.h; sourceTree = "<group>"; };
+ A6AF284C0B965F2E00EDBA70 /* avidec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = avidec.c; sourceTree = "<group>"; };
+ A6AF284D0B965F2E00EDBA70 /* avienc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = avienc.c; sourceTree = "<group>"; };
+ A6AF284E0B965F2E00EDBA70 /* avio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = avio.c; sourceTree = "<group>"; };
+ A6AF284F0B965F2E00EDBA70 /* avio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avio.h; sourceTree = "<group>"; };
+ A6AF28500B965F2E00EDBA70 /* aviobuf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aviobuf.c; sourceTree = "<group>"; };
+ A6AF28510B965F2E00EDBA70 /* barpainet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = barpainet.c; sourceTree = "<group>"; };
+ A6AF28520B965F2E00EDBA70 /* barpainet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = barpainet.h; sourceTree = "<group>"; };
+ A6AF28530B965F2E00EDBA70 /* beosaudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = beosaudio.cpp; sourceTree = "<group>"; };
+ A6AF28540B965F2E00EDBA70 /* crc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crc.c; sourceTree = "<group>"; };
+ A6AF28550B965F2E00EDBA70 /* cutils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cutils.c; sourceTree = "<group>"; };
+ A6AF28560B965F2E00EDBA70 /* dv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dv.c; sourceTree = "<group>"; };
+ A6AF28570B965F2E00EDBA70 /* dv1394.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dv1394.c; sourceTree = "<group>"; };
+ A6AF28580B965F2E00EDBA70 /* dv1394.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dv1394.h; sourceTree = "<group>"; };
+ A6AF28590B965F2E00EDBA70 /* dvcore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dvcore.c; sourceTree = "<group>"; };
+ A6AF285A0B965F2E00EDBA70 /* dvcore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dvcore.h; sourceTree = "<group>"; };
+ A6AF285B0B965F2E00EDBA70 /* ffm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffm.c; sourceTree = "<group>"; };
+ A6AF285C0B965F2E00EDBA70 /* file.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = file.c; sourceTree = "<group>"; };
+ A6AF285D0B965F2E00EDBA70 /* flvdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = flvdec.c; sourceTree = "<group>"; };
+ A6AF285E0B965F2E00EDBA70 /* flvenc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = flvenc.c; sourceTree = "<group>"; };
+ A6AF285F0B965F2E00EDBA70 /* framehook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = framehook.c; sourceTree = "<group>"; };
+ A6AF28600B965F2E00EDBA70 /* framehook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = framehook.h; sourceTree = "<group>"; };
+ A6AF28610B965F2E00EDBA70 /* gif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gif.c; sourceTree = "<group>"; };
+ A6AF28620B965F2E00EDBA70 /* gifdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gifdec.c; sourceTree = "<group>"; };
+ A6AF28630B965F2E00EDBA70 /* grab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = grab.c; sourceTree = "<group>"; };
+ A6AF28640B965F2E00EDBA70 /* http.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = http.c; sourceTree = "<group>"; };
+ A6AF28650B965F2E00EDBA70 /* idroq.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = idroq.c; sourceTree = "<group>"; };
+ A6AF28660B965F2E00EDBA70 /* img.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = img.c; sourceTree = "<group>"; };
+ A6AF28670B965F2E00EDBA70 /* ipmovie.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ipmovie.c; sourceTree = "<group>"; };
+ A6AF28680B965F2E00EDBA70 /* jpeg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jpeg.c; sourceTree = "<group>"; };
+ A6AF28690B965F2E00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF286A0B965F2E00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF286B0B965F2E00EDBA70 /* mov.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mov.c; sourceTree = "<group>"; };
+ A6AF286C0B965F2E00EDBA70 /* movenc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = movenc.c; sourceTree = "<group>"; };
+ A6AF286D0B965F2E00EDBA70 /* mp3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp3.c; sourceTree = "<group>"; };
+ A6AF286E0B965F2E00EDBA70 /* mpeg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpeg.c; sourceTree = "<group>"; };
+ A6AF286F0B965F2E00EDBA70 /* mpegts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegts.c; sourceTree = "<group>"; };
+ A6AF28700B965F2E00EDBA70 /* mpegts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegts.h; sourceTree = "<group>"; };
+ A6AF28710B965F2E00EDBA70 /* mpegtsenc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegtsenc.c; sourceTree = "<group>"; };
+ A6AF28720B965F2E00EDBA70 /* mpjpeg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpjpeg.c; sourceTree = "<group>"; };
+ A6AF28730B965F2E00EDBA70 /* nut.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nut.c; sourceTree = "<group>"; };
+ A6AF28740B965F2E00EDBA70 /* ogg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ogg.c; sourceTree = "<group>"; };
+ A6AF28750B965F2E00EDBA70 /* os_support.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = os_support.c; sourceTree = "<group>"; };
+ A6AF28760B965F2E00EDBA70 /* os_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = os_support.h; sourceTree = "<group>"; };
+ A6AF28770B965F2E00EDBA70 /* png.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = png.c; sourceTree = "<group>"; };
+ A6AF28780B965F2E00EDBA70 /* pnm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pnm.c; sourceTree = "<group>"; };
+ A6AF28790B965F2E00EDBA70 /* psxstr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = psxstr.c; sourceTree = "<group>"; };
+ A6AF287A0B965F2E00EDBA70 /* raw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = raw.c; sourceTree = "<group>"; };
+ A6AF287B0B965F2E00EDBA70 /* rm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rm.c; sourceTree = "<group>"; };
+ A6AF287C0B965F2E00EDBA70 /* rtp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rtp.c; sourceTree = "<group>"; };
+ A6AF287D0B965F2E00EDBA70 /* rtp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rtp.h; sourceTree = "<group>"; };
+ A6AF287E0B965F2E00EDBA70 /* rtpproto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rtpproto.c; sourceTree = "<group>"; };
+ A6AF287F0B965F2E00EDBA70 /* rtsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rtsp.c; sourceTree = "<group>"; };
+ A6AF28800B965F2E00EDBA70 /* rtsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rtsp.h; sourceTree = "<group>"; };
+ A6AF28810B965F2E00EDBA70 /* rtspcodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rtspcodes.h; sourceTree = "<group>"; };
+ A6AF28820B965F2E00EDBA70 /* swf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = swf.c; sourceTree = "<group>"; };
+ A6AF28830B965F2E00EDBA70 /* tcp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tcp.c; sourceTree = "<group>"; };
+ A6AF28840B965F2E00EDBA70 /* udp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = udp.c; sourceTree = "<group>"; };
+ A6AF28850B965F2E00EDBA70 /* utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utils.c; sourceTree = "<group>"; };
+ A6AF28860B965F2E00EDBA70 /* wav.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wav.c; sourceTree = "<group>"; };
+ A6AF28870B965F2E00EDBA70 /* wc3movie.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wc3movie.c; sourceTree = "<group>"; };
+ A6AF28880B965F2E00EDBA70 /* yuv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yuv.c; sourceTree = "<group>"; };
+ A6AF28890B965F2E00EDBA70 /* yuv4mpeg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yuv4mpeg.c; sourceTree = "<group>"; };
+ A6AF288A0B965F2E00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF288B0B965F2E00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF288C0B965F2E00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF288D0B965F2E00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF288E0B965F2E00EDBA70 /* mod_libavcodec.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_libavcodec.nsh; sourceTree = "<group>"; };
+ A6AF288F0B965F2E00EDBA70 /* mptr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mptr.cpp; sourceTree = "<group>"; };
+ A6AF28900B965F2E00EDBA70 /* mptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mptr.h; sourceTree = "<group>"; };
+ A6AF28910B965F2E00EDBA70 /* trgt_av.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = trgt_av.cpp; sourceTree = "<group>"; };
+ A6AF28920B965F2E00EDBA70 /* trgt_av.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trgt_av.h; sourceTree = "<group>"; };
+ A6AF28930B965F2E00EDBA70 /* unmod_libavcodec.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_libavcodec.nsh; sourceTree = "<group>"; };
+ A6AF28960B965F2E00EDBA70 /* libmod_noise_la-distort.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_noise_la-distort.Plo"; sourceTree = "<group>"; };
+ A6AF28970B965F2E00EDBA70 /* libmod_noise_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_noise_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF28980B965F2E00EDBA70 /* libmod_noise_la-noise.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_noise_la-noise.Plo"; sourceTree = "<group>"; };
+ A6AF28990B965F2E00EDBA70 /* libmod_noise_la-random.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_noise_la-random.Plo"; sourceTree = "<group>"; };
+ A6AF289B0B965F2E00EDBA70 /* libmod_noise.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_noise.0.0.0.so; sourceTree = "<group>"; };
+ A6AF289C0B965F2E00EDBA70 /* libmod_noise.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_noise.0.so; sourceTree = "<group>"; };
+ A6AF289D0B965F2E00EDBA70 /* libmod_noise.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_noise.la; sourceTree = "<group>"; };
+ A6AF289E0B965F2E00EDBA70 /* libmod_noise.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_noise.lai; sourceTree = "<group>"; };
+ A6AF289F0B965F2E00EDBA70 /* libmod_noise.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_noise.so; sourceTree = "<group>"; };
+ A6AF28A00B965F2E00EDBA70 /* libmod_noise_la-distort.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_noise_la-distort.o"; sourceTree = "<group>"; };
+ A6AF28A10B965F2E00EDBA70 /* libmod_noise_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_noise_la-main.o"; sourceTree = "<group>"; };
+ A6AF28A20B965F2E00EDBA70 /* libmod_noise_la-noise.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_noise_la-noise.o"; sourceTree = "<group>"; };
+ A6AF28A30B965F2E00EDBA70 /* libmod_noise_la-random.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_noise_la-random.o"; sourceTree = "<group>"; };
+ A6AF28A40B965F2E00EDBA70 /* distort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = distort.cpp; sourceTree = "<group>"; };
+ A6AF28A50B965F2E00EDBA70 /* distort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = distort.h; sourceTree = "<group>"; };
+ A6AF28A60B965F2E00EDBA70 /* libmod_noise.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_noise.la; sourceTree = "<group>"; };
+ A6AF28A70B965F2E00EDBA70 /* libmod_noise_la-distort.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_noise_la-distort.lo"; sourceTree = "<group>"; };
+ A6AF28A80B965F2E00EDBA70 /* libmod_noise_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_noise_la-main.lo"; sourceTree = "<group>"; };
+ A6AF28A90B965F2E00EDBA70 /* libmod_noise_la-noise.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_noise_la-noise.lo"; sourceTree = "<group>"; };
+ A6AF28AA0B965F2E00EDBA70 /* libmod_noise_la-random.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_noise_la-random.lo"; sourceTree = "<group>"; };
+ A6AF28AB0B965F2E00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF28AC0B965F2E00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF28AD0B965F2E00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF28AE0B965F2E00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF28AF0B965F2E00EDBA70 /* mod_noise.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_noise.nsh; sourceTree = "<group>"; };
+ A6AF28B00B965F2E00EDBA70 /* noise.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = noise.cpp; sourceTree = "<group>"; };
+ A6AF28B10B965F2E00EDBA70 /* noise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = noise.h; sourceTree = "<group>"; };
+ A6AF28B20B965F2E00EDBA70 /* random.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = random.cpp; sourceTree = "<group>"; };
+ A6AF28B30B965F2E00EDBA70 /* random.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = random.h; sourceTree = "<group>"; };
+ A6AF28B40B965F2E00EDBA70 /* unmod_noise.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_noise.nsh; sourceTree = "<group>"; };
+ A6AF28B70B965F2E00EDBA70 /* libmod_openexr_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_openexr_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF28B80B965F2E00EDBA70 /* libmod_openexr_la-mptr_openexr.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_openexr_la-mptr_openexr.Plo"; sourceTree = "<group>"; };
+ A6AF28B90B965F2E00EDBA70 /* libmod_openexr_la-trgt_openexr.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_openexr_la-trgt_openexr.Plo"; sourceTree = "<group>"; };
+ A6AF28BA0B965F2E00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF28BB0B965F2E00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF28BC0B965F2E00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF28BD0B965F2E00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF28BE0B965F2E00EDBA70 /* mod_openexr.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_openexr.nsh; sourceTree = "<group>"; };
+ A6AF28BF0B965F2E00EDBA70 /* mptr_openexr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mptr_openexr.cpp; sourceTree = "<group>"; };
+ A6AF28C00B965F2E00EDBA70 /* mptr_openexr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mptr_openexr.h; sourceTree = "<group>"; };
+ A6AF28C10B965F2E00EDBA70 /* trgt_openexr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = trgt_openexr.cpp; sourceTree = "<group>"; };
+ A6AF28C20B965F2E00EDBA70 /* trgt_openexr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trgt_openexr.h; sourceTree = "<group>"; };
+ A6AF28C30B965F2E00EDBA70 /* unmod_openexr.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_openexr.nsh; sourceTree = "<group>"; };
+ A6AF28C60B965F2E00EDBA70 /* libmod_particle_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_particle_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF28C70B965F2E00EDBA70 /* libmod_particle_la-plant.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_particle_la-plant.Plo"; sourceTree = "<group>"; };
+ A6AF28C80B965F2E00EDBA70 /* libmod_particle_la-random.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_particle_la-random.Plo"; sourceTree = "<group>"; };
+ A6AF28CA0B965F2E00EDBA70 /* libmod_particle.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_particle.0.0.0.so; sourceTree = "<group>"; };
+ A6AF28CB0B965F2E00EDBA70 /* libmod_particle.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_particle.0.so; sourceTree = "<group>"; };
+ A6AF28CC0B965F2E00EDBA70 /* libmod_particle.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_particle.la; sourceTree = "<group>"; };
+ A6AF28CD0B965F2E00EDBA70 /* libmod_particle.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_particle.lai; sourceTree = "<group>"; };
+ A6AF28CE0B965F2E00EDBA70 /* libmod_particle.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_particle.so; sourceTree = "<group>"; };
+ A6AF28CF0B965F2E00EDBA70 /* libmod_particle_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_particle_la-main.o"; sourceTree = "<group>"; };
+ A6AF28D00B965F2E00EDBA70 /* libmod_particle_la-plant.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_particle_la-plant.o"; sourceTree = "<group>"; };
+ A6AF28D10B965F2E00EDBA70 /* libmod_particle_la-random.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_particle_la-random.o"; sourceTree = "<group>"; };
+ A6AF28D20B965F2E00EDBA70 /* libmod_particle.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_particle.la; sourceTree = "<group>"; };
+ A6AF28D30B965F2E00EDBA70 /* libmod_particle_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_particle_la-main.lo"; sourceTree = "<group>"; };
+ A6AF28D40B965F2E00EDBA70 /* libmod_particle_la-plant.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_particle_la-plant.lo"; sourceTree = "<group>"; };
+ A6AF28D50B965F2E00EDBA70 /* libmod_particle_la-random.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_particle_la-random.lo"; sourceTree = "<group>"; };
+ A6AF28D60B965F2E00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF28D70B965F2E00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF28D80B965F2E00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF28D90B965F2E00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF28DA0B965F2E00EDBA70 /* mod_particle.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_particle.nsh; sourceTree = "<group>"; };
+ A6AF28DB0B965F2E00EDBA70 /* plant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = plant.cpp; sourceTree = "<group>"; };
+ A6AF28DC0B965F2E00EDBA70 /* plant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plant.h; sourceTree = "<group>"; };
+ A6AF28DD0B965F2E00EDBA70 /* random.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = random.cpp; sourceTree = "<group>"; };
+ A6AF28DE0B965F2E00EDBA70 /* random.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = random.h; sourceTree = "<group>"; };
+ A6AF28DF0B965F2E00EDBA70 /* unmod_particle.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_particle.nsh; sourceTree = "<group>"; };
+ A6AF28E20B965F2E00EDBA70 /* libmod_png_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_png_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF28E30B965F2E00EDBA70 /* libmod_png_la-mptr_png.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_png_la-mptr_png.Plo"; sourceTree = "<group>"; };
+ A6AF28E40B965F2E00EDBA70 /* libmod_png_la-trgt_png.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_png_la-trgt_png.Plo"; sourceTree = "<group>"; };
+ A6AF28E60B965F2E00EDBA70 /* libmod_png.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_png.0.0.0.so; sourceTree = "<group>"; };
+ A6AF28E70B965F2E00EDBA70 /* libmod_png.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_png.0.so; sourceTree = "<group>"; };
+ A6AF28E80B965F2E00EDBA70 /* libmod_png.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_png.la; sourceTree = "<group>"; };
+ A6AF28E90B965F2E00EDBA70 /* libmod_png.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_png.lai; sourceTree = "<group>"; };
+ A6AF28EA0B965F2E00EDBA70 /* libmod_png.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_png.so; sourceTree = "<group>"; };
+ A6AF28EB0B965F2E00EDBA70 /* libmod_png_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_png_la-main.o"; sourceTree = "<group>"; };
+ A6AF28EC0B965F2E00EDBA70 /* libmod_png_la-mptr_png.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_png_la-mptr_png.o"; sourceTree = "<group>"; };
+ A6AF28ED0B965F2E00EDBA70 /* libmod_png_la-trgt_png.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_png_la-trgt_png.o"; sourceTree = "<group>"; };
+ A6AF28EE0B965F2E00EDBA70 /* libmod_png.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_png.la; sourceTree = "<group>"; };
+ A6AF28EF0B965F2E00EDBA70 /* libmod_png_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_png_la-main.lo"; sourceTree = "<group>"; };
+ A6AF28F00B965F2E00EDBA70 /* libmod_png_la-mptr_png.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_png_la-mptr_png.lo"; sourceTree = "<group>"; };
+ A6AF28F10B965F2E00EDBA70 /* libmod_png_la-trgt_png.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_png_la-trgt_png.lo"; sourceTree = "<group>"; };
+ A6AF28F20B965F2E00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF28F30B965F2E00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF28F40B965F2E00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF28F50B965F2E00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF28F60B965F2E00EDBA70 /* mod_png.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_png.nsh; sourceTree = "<group>"; };
+ A6AF28F70B965F2E00EDBA70 /* mptr_png.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mptr_png.cpp; sourceTree = "<group>"; };
+ A6AF28F80B965F2E00EDBA70 /* mptr_png.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mptr_png.h; sourceTree = "<group>"; };
+ A6AF28F90B965F2E00EDBA70 /* trgt_png.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = trgt_png.cpp; sourceTree = "<group>"; };
+ A6AF28FA0B965F2E00EDBA70 /* trgt_png.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trgt_png.h; sourceTree = "<group>"; };
+ A6AF28FB0B965F2E00EDBA70 /* unmod_png.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_png.nsh; sourceTree = "<group>"; };
+ A6AF28FE0B965F2E00EDBA70 /* libmod_ppm_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_ppm_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF28FF0B965F2E00EDBA70 /* libmod_ppm_la-mptr_ppm.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_ppm_la-mptr_ppm.Plo"; sourceTree = "<group>"; };
+ A6AF29000B965F2E00EDBA70 /* libmod_ppm_la-trgt_ppm.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_ppm_la-trgt_ppm.Plo"; sourceTree = "<group>"; };
+ A6AF29020B965F2E00EDBA70 /* libmod_ppm.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_ppm.0.0.0.so; sourceTree = "<group>"; };
+ A6AF29030B965F2E00EDBA70 /* libmod_ppm.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_ppm.0.so; sourceTree = "<group>"; };
+ A6AF29040B965F2E00EDBA70 /* libmod_ppm.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_ppm.la; sourceTree = "<group>"; };
+ A6AF29050B965F2E00EDBA70 /* libmod_ppm.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_ppm.lai; sourceTree = "<group>"; };
+ A6AF29060B965F2E00EDBA70 /* libmod_ppm.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_ppm.so; sourceTree = "<group>"; };
+ A6AF29070B965F2E00EDBA70 /* libmod_ppm_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_ppm_la-main.o"; sourceTree = "<group>"; };
+ A6AF29080B965F2E00EDBA70 /* libmod_ppm_la-mptr_ppm.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_ppm_la-mptr_ppm.o"; sourceTree = "<group>"; };
+ A6AF29090B965F2E00EDBA70 /* libmod_ppm_la-trgt_ppm.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_ppm_la-trgt_ppm.o"; sourceTree = "<group>"; };
+ A6AF290A0B965F2E00EDBA70 /* libmod_ppm.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_ppm.la; sourceTree = "<group>"; };
+ A6AF290B0B965F2E00EDBA70 /* libmod_ppm_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_ppm_la-main.lo"; sourceTree = "<group>"; };
+ A6AF290C0B965F2E00EDBA70 /* libmod_ppm_la-mptr_ppm.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_ppm_la-mptr_ppm.lo"; sourceTree = "<group>"; };
+ A6AF290D0B965F2E00EDBA70 /* libmod_ppm_la-trgt_ppm.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_ppm_la-trgt_ppm.lo"; sourceTree = "<group>"; };
+ A6AF290E0B965F2E00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF290F0B965F2E00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF29100B965F2E00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF29110B965F2E00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF29120B965F2E00EDBA70 /* mod_ppm.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_ppm.nsh; sourceTree = "<group>"; };
+ A6AF29130B965F2E00EDBA70 /* mptr_ppm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mptr_ppm.cpp; sourceTree = "<group>"; };
+ A6AF29140B965F2E00EDBA70 /* mptr_ppm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mptr_ppm.h; sourceTree = "<group>"; };
+ A6AF29150B965F2E00EDBA70 /* trgt_mpg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = trgt_mpg.cpp; sourceTree = "<group>"; };
+ A6AF29160B965F2E00EDBA70 /* trgt_mpg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trgt_mpg.h; sourceTree = "<group>"; };
+ A6AF29170B965F2E00EDBA70 /* trgt_ppm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = trgt_ppm.cpp; sourceTree = "<group>"; };
+ A6AF29180B965F2E00EDBA70 /* trgt_ppm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trgt_ppm.h; sourceTree = "<group>"; };
+ A6AF29190B965F2E00EDBA70 /* unmod_ppm.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_ppm.nsh; sourceTree = "<group>"; };
+ A6AF291C0B965F2E00EDBA70 /* libmod_yuv420p_la-main.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_yuv420p_la-main.Plo"; sourceTree = "<group>"; };
+ A6AF291D0B965F2E00EDBA70 /* libmod_yuv420p_la-trgt_yuv.Plo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_yuv420p_la-trgt_yuv.Plo"; sourceTree = "<group>"; };
+ A6AF291F0B965F2E00EDBA70 /* libmod_yuv420p.0.0.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_yuv420p.0.0.0.so; sourceTree = "<group>"; };
+ A6AF29200B965F2E00EDBA70 /* libmod_yuv420p.0.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_yuv420p.0.so; sourceTree = "<group>"; };
+ A6AF29210B965F2E00EDBA70 /* libmod_yuv420p.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_yuv420p.la; sourceTree = "<group>"; };
+ A6AF29220B965F2E00EDBA70 /* libmod_yuv420p.lai */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_yuv420p.lai; sourceTree = "<group>"; };
+ A6AF29230B965F2E00EDBA70 /* libmod_yuv420p.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = libmod_yuv420p.so; sourceTree = "<group>"; };
+ A6AF29240B965F2E00EDBA70 /* libmod_yuv420p_la-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_yuv420p_la-main.o"; sourceTree = "<group>"; };
+ A6AF29250B965F2E00EDBA70 /* libmod_yuv420p_la-trgt_yuv.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "libmod_yuv420p_la-trgt_yuv.o"; sourceTree = "<group>"; };
+ A6AF29260B965F2E00EDBA70 /* libmod_yuv420p.la */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmod_yuv420p.la; sourceTree = "<group>"; };
+ A6AF29270B965F2E00EDBA70 /* libmod_yuv420p_la-main.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_yuv420p_la-main.lo"; sourceTree = "<group>"; };
+ A6AF29280B965F2E00EDBA70 /* libmod_yuv420p_la-trgt_yuv.lo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "libmod_yuv420p_la-trgt_yuv.lo"; sourceTree = "<group>"; };
+ A6AF29290B965F2E00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF292A0B965F2E00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF292B0B965F2E00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF292C0B965F2E00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF292D0B965F2E00EDBA70 /* mod_yuv420p.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mod_yuv420p.nsh; sourceTree = "<group>"; };
+ A6AF292E0B965F2E00EDBA70 /* trgt_yuv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = trgt_yuv.cpp; sourceTree = "<group>"; };
+ A6AF292F0B965F2E00EDBA70 /* trgt_yuv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trgt_yuv.h; sourceTree = "<group>"; };
+ A6AF29300B965F2E00EDBA70 /* unmod_yuv420p.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = unmod_yuv420p.nsh; sourceTree = "<group>"; };
+ A6AF29320B965F2E00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF29330B965F2E00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF29340B965F2E00EDBA70 /* mptr_mplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mptr_mplayer.cpp; sourceTree = "<group>"; };
+ A6AF29350B965F2E00EDBA70 /* mptr_mplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mptr_mplayer.h; sourceTree = "<group>"; };
+ A6AF29360B965F2E00EDBA70 /* synfig_modules.cfg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = synfig_modules.cfg; sourceTree = "<group>"; };
+ A6AF29370B965F2E00EDBA70 /* synfig_modules.cfg.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = synfig_modules.cfg.in; sourceTree = "<group>"; };
+ A6AF29380B965F2E00EDBA70 /* template.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = template.nsh; sourceTree = "<group>"; };
+ A6AF29390B965F2E00EDBA70 /* untemplate.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = untemplate.nsh; sourceTree = "<group>"; };
+ A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = activepoint.cpp; sourceTree = "<group>"; };
+ A6AF29CB0B965F2E00EDBA70 /* activepoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = activepoint.h; sourceTree = "<group>"; };
+ A6AF29CC0B965F2E00EDBA70 /* angle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = angle.h; sourceTree = "<group>"; };
+ A6AF29CD0B965F2E00EDBA70 /* blinepoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = blinepoint.cpp; sourceTree = "<group>"; };
+ A6AF29CE0B965F2E00EDBA70 /* blinepoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = blinepoint.h; sourceTree = "<group>"; };
+ A6AF29CF0B965F2E00EDBA70 /* blur.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = blur.cpp; sourceTree = "<group>"; };
+ A6AF29D00B965F2E00EDBA70 /* blur.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = blur.h; sourceTree = "<group>"; };
+ A6AF29D10B965F2E00EDBA70 /* canvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = canvas.cpp; sourceTree = "<group>"; };
+ A6AF29D20B965F2E00EDBA70 /* canvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = canvas.h; sourceTree = "<group>"; };
+ A6AF29D30B965F2E00EDBA70 /* canvasbase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = canvasbase.h; sourceTree = "<group>"; };
+ A6AF29D40B965F2E00EDBA70 /* color.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = color.cpp; sourceTree = "<group>"; };
+ A6AF29D50B965F2E00EDBA70 /* color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = color.h; sourceTree = "<group>"; };
+ A6AF29D60B965F2E00EDBA70 /* context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = context.cpp; sourceTree = "<group>"; };
+ A6AF29D70B965F2E00EDBA70 /* context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = context.h; sourceTree = "<group>"; };
+ A6AF29D80B965F2E00EDBA70 /* curve_helper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = curve_helper.cpp; sourceTree = "<group>"; };
+ A6AF29D90B965F2E00EDBA70 /* curve_helper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = curve_helper.h; sourceTree = "<group>"; };
+ A6AF29DA0B965F2E00EDBA70 /* curveset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = curveset.cpp; sourceTree = "<group>"; };
+ A6AF29DB0B965F2E00EDBA70 /* curveset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = curveset.h; sourceTree = "<group>"; };
+ A6AF29DC0B965F2E00EDBA70 /* distance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = distance.cpp; sourceTree = "<group>"; };
+ A6AF29DD0B965F2E00EDBA70 /* distance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = distance.h; sourceTree = "<group>"; };
+ A6AF29DE0B965F2E00EDBA70 /* exception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = exception.cpp; sourceTree = "<group>"; };
+ A6AF29DF0B965F2E00EDBA70 /* exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = exception.h; sourceTree = "<group>"; };
+ A6AF29E00B965F2E00EDBA70 /* gamma.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gamma.cpp; sourceTree = "<group>"; };
+ A6AF29E10B965F2E00EDBA70 /* gamma.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gamma.h; sourceTree = "<group>"; };
+ A6AF29E20B965F2E00EDBA70 /* general.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = general.h; sourceTree = "<group>"; };
+ A6AF29E30B965F2E00EDBA70 /* gradient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gradient.cpp; sourceTree = "<group>"; };
+ A6AF29E40B965F2E00EDBA70 /* gradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gradient.h; sourceTree = "<group>"; };
+ A6AF29E50B965F2E00EDBA70 /* guid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = guid.cpp; sourceTree = "<group>"; };
+ A6AF29E60B965F2E00EDBA70 /* guid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = guid.h; sourceTree = "<group>"; };
+ A6AF29E70B965F2E00EDBA70 /* guidset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = guidset.h; sourceTree = "<group>"; };
+ A6AF29E80B965F2E00EDBA70 /* importer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = importer.cpp; sourceTree = "<group>"; };
+ A6AF29E90B965F2E00EDBA70 /* importer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = importer.h; sourceTree = "<group>"; };
+ A6AF29EA0B965F2E00EDBA70 /* interpolation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = interpolation.h; sourceTree = "<group>"; };
+ A6AF29EB0B965F2E00EDBA70 /* keyframe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = keyframe.cpp; sourceTree = "<group>"; };
+ A6AF29EC0B965F2E00EDBA70 /* keyframe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keyframe.h; sourceTree = "<group>"; };
+ A6AF29ED0B965F2E00EDBA70 /* layer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layer.cpp; sourceTree = "<group>"; };
+ A6AF29EE0B965F2E00EDBA70 /* layer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layer.h; sourceTree = "<group>"; };
+ A6AF29EF0B965F2E00EDBA70 /* layer_bitmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layer_bitmap.cpp; sourceTree = "<group>"; };
+ A6AF29F00B965F2E00EDBA70 /* layer_bitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layer_bitmap.h; sourceTree = "<group>"; };
+ A6AF29F10B965F2E00EDBA70 /* layer_composite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layer_composite.cpp; sourceTree = "<group>"; };
+ A6AF29F20B965F2E00EDBA70 /* layer_composite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layer_composite.h; sourceTree = "<group>"; };
+ A6AF29F30B965F2E00EDBA70 /* layer_mime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layer_mime.cpp; sourceTree = "<group>"; };
+ A6AF29F40B965F2E00EDBA70 /* layer_mime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layer_mime.h; sourceTree = "<group>"; };
+ A6AF29F50B965F2E00EDBA70 /* layer_motionblur.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layer_motionblur.cpp; sourceTree = "<group>"; };
+ A6AF29F60B965F2E00EDBA70 /* layer_motionblur.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layer_motionblur.h; sourceTree = "<group>"; };
+ A6AF29F70B965F2E00EDBA70 /* layer_pastecanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layer_pastecanvas.cpp; sourceTree = "<group>"; };
+ A6AF29F80B965F2E00EDBA70 /* layer_pastecanvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layer_pastecanvas.h; sourceTree = "<group>"; };
+ A6AF29F90B965F2E00EDBA70 /* layer_polygon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layer_polygon.cpp; sourceTree = "<group>"; };
+ A6AF29FA0B965F2E00EDBA70 /* layer_polygon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layer_polygon.h; sourceTree = "<group>"; };
+ A6AF29FB0B965F2E00EDBA70 /* layer_shape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layer_shape.cpp; sourceTree = "<group>"; };
+ A6AF29FC0B965F2E00EDBA70 /* layer_shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layer_shape.h; sourceTree = "<group>"; };
+ A6AF29FD0B965F2E00EDBA70 /* layer_solidcolor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layer_solidcolor.cpp; sourceTree = "<group>"; };
+ A6AF29FE0B965F2E00EDBA70 /* layer_solidcolor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layer_solidcolor.h; sourceTree = "<group>"; };
+ A6AF2A440B965F2F00EDBA70 /* listimporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = listimporter.cpp; sourceTree = "<group>"; };
+ A6AF2A450B965F2F00EDBA70 /* listimporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = listimporter.h; sourceTree = "<group>"; };
+ A6AF2A460B965F2F00EDBA70 /* loadcanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = loadcanvas.cpp; sourceTree = "<group>"; };
+ A6AF2A470B965F2F00EDBA70 /* loadcanvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = loadcanvas.h; sourceTree = "<group>"; };
+ A6AF2A480B965F2F00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF2A490B965F2F00EDBA70 /* main.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = main.h; sourceTree = "<group>"; };
+ A6AF2A4D0B965F2F00EDBA70 /* module.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = module.cpp; sourceTree = "<group>"; };
+ A6AF2A4E0B965F2F00EDBA70 /* module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = module.h; sourceTree = "<group>"; };
+ A6AF2A4F0B965F2F00EDBA70 /* mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mutex.cpp; sourceTree = "<group>"; };
+ A6AF2A500B965F2F00EDBA70 /* mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mutex.h; sourceTree = "<group>"; };
+ A6AF2A510B965F2F00EDBA70 /* node.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = node.cpp; sourceTree = "<group>"; };
+ A6AF2A520B965F2F00EDBA70 /* node.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = node.h; sourceTree = "<group>"; };
+ A6AF2A530B965F2F00EDBA70 /* palette.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = palette.cpp; sourceTree = "<group>"; };
+ A6AF2A540B965F2F00EDBA70 /* palette.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = palette.h; sourceTree = "<group>"; };
+ A6AF2A550B965F2F00EDBA70 /* paramdesc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = paramdesc.cpp; sourceTree = "<group>"; };
+ A6AF2A560B965F2F00EDBA70 /* paramdesc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = paramdesc.h; sourceTree = "<group>"; };
+ A6AF2A570B965F2F00EDBA70 /* pch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pch.h; sourceTree = "<group>"; };
+ A6AF2A580B965F2F00EDBA70 /* polynomial_root.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = polynomial_root.cpp; sourceTree = "<group>"; };
+ A6AF2A590B965F2F00EDBA70 /* polynomial_root.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = polynomial_root.h; sourceTree = "<group>"; };
+ A6AF2A5D0B965F2F00EDBA70 /* nodebase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nodebase.h; sourceTree = "<group>"; };
+ A6AF2A5E0B965F2F00EDBA70 /* nodebase.px */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = nodebase.px; sourceTree = "<group>"; };
+ A6AF2A5F0B965F2F00EDBA70 /* proto.m4 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = proto.m4; sourceTree = "<group>"; };
+ A6AF2A600B965F2F00EDBA70 /* protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = protocol.h; sourceTree = "<group>"; };
+ A6AF2A610B965F2F00EDBA70 /* real.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = real.h; sourceTree = "<group>"; };
+ A6AF2A620B965F2F00EDBA70 /* rect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rect.cpp; sourceTree = "<group>"; };
+ A6AF2A630B965F2F00EDBA70 /* rect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rect.h; sourceTree = "<group>"; };
+ A6AF2A640B965F2F00EDBA70 /* renddesc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = renddesc.cpp; sourceTree = "<group>"; };
+ A6AF2A650B965F2F00EDBA70 /* renddesc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = renddesc.h; sourceTree = "<group>"; };
+ A6AF2A660B965F2F00EDBA70 /* render.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = render.cpp; sourceTree = "<group>"; };
+ A6AF2A670B965F2F00EDBA70 /* render.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = render.h; sourceTree = "<group>"; };
+ A6AF2A680B965F2F00EDBA70 /* savecanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = savecanvas.cpp; sourceTree = "<group>"; };
+ A6AF2A690B965F2F00EDBA70 /* savecanvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = savecanvas.h; sourceTree = "<group>"; };
+ A6AF2A6A0B965F2F00EDBA70 /* segment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = segment.h; sourceTree = "<group>"; };
+ A6AF2A6B0B965F2F00EDBA70 /* smartfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smartfile.h; sourceTree = "<group>"; };
+ A6AF2A6C0B965F2F00EDBA70 /* string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = string.h; sourceTree = "<group>"; };
+ A6AF2A6D0B965F2F00EDBA70 /* string_decl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = string_decl.h; sourceTree = "<group>"; };
+ A6AF2A6E0B965F2F00EDBA70 /* surface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = surface.cpp; sourceTree = "<group>"; };
+ A6AF2A6F0B965F2F00EDBA70 /* surface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = surface.h; sourceTree = "<group>"; };
+ A6AF2A700B965F2F00EDBA70 /* surfacenew.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = surfacenew.cpp; sourceTree = "<group>"; };
+ A6AF2A710B965F2F00EDBA70 /* surfacenew.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = surfacenew.h; sourceTree = "<group>"; };
+ A6AF2A720B965F2F00EDBA70 /* synfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = synfig.h; sourceTree = "<group>"; };
+ A6AF2A730B965F2F00EDBA70 /* synfig.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = synfig.nsh; sourceTree = "<group>"; };
+ A6AF2A740B965F2F00EDBA70 /* target.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = target.cpp; sourceTree = "<group>"; };
+ A6AF2A750B965F2F00EDBA70 /* target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = target.h; sourceTree = "<group>"; };
+ A6AF2A760B965F2F00EDBA70 /* target_multi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = target_multi.cpp; sourceTree = "<group>"; };
+ A6AF2A770B965F2F00EDBA70 /* target_multi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = target_multi.h; sourceTree = "<group>"; };
+ A6AF2A780B965F2F00EDBA70 /* target_null.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = target_null.cpp; sourceTree = "<group>"; };
+ A6AF2A790B965F2F00EDBA70 /* target_null.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = target_null.h; sourceTree = "<group>"; };
+ A6AF2A7A0B965F2F00EDBA70 /* target_null_tile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = target_null_tile.cpp; sourceTree = "<group>"; };
+ A6AF2A7B0B965F2F00EDBA70 /* target_null_tile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = target_null_tile.h; sourceTree = "<group>"; };
+ A6AF2A7C0B965F2F00EDBA70 /* target_scanline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = target_scanline.cpp; sourceTree = "<group>"; };
+ A6AF2A7D0B965F2F00EDBA70 /* target_scanline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = target_scanline.h; sourceTree = "<group>"; };
+ A6AF2A7E0B965F2F00EDBA70 /* target_tile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = target_tile.cpp; sourceTree = "<group>"; };
+ A6AF2A7F0B965F2F00EDBA70 /* target_tile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = target_tile.h; sourceTree = "<group>"; };
+ A6AF2A800B965F2F00EDBA70 /* time.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = time.cpp; sourceTree = "<group>"; };
+ A6AF2A810B965F2F00EDBA70 /* time.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = time.h; sourceTree = "<group>"; };
+ A6AF2A820B965F2F00EDBA70 /* timepointcollect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = timepointcollect.cpp; sourceTree = "<group>"; };
+ A6AF2A830B965F2F00EDBA70 /* timepointcollect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timepointcollect.h; sourceTree = "<group>"; };
+ A6AF2A840B965F2F00EDBA70 /* transform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = transform.cpp; sourceTree = "<group>"; };
+ A6AF2A850B965F2F00EDBA70 /* transform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = transform.h; sourceTree = "<group>"; };
+ A6AF2A860B965F2F00EDBA70 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = "<group>"; };
+ A6AF2A870B965F2F00EDBA70 /* uniqueid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uniqueid.cpp; sourceTree = "<group>"; };
+ A6AF2A880B965F2F00EDBA70 /* uniqueid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uniqueid.h; sourceTree = "<group>"; };
+ A6AF2A890B965F2F00EDBA70 /* value.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = value.cpp; sourceTree = "<group>"; };
+ A6AF2A8A0B965F2F00EDBA70 /* value.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = value.h; sourceTree = "<group>"; };
+ A6AF2A8B0B965F2F00EDBA70 /* valuenode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode.cpp; sourceTree = "<group>"; };
+ A6AF2A8C0B965F2F00EDBA70 /* valuenode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode.h; sourceTree = "<group>"; };
+ A6AF2A8D0B965F2F00EDBA70 /* valuenode_animated.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_animated.cpp; sourceTree = "<group>"; };
+ A6AF2A8E0B965F2F00EDBA70 /* valuenode_animated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_animated.h; sourceTree = "<group>"; };
+ A6AF2A8F0B965F2F00EDBA70 /* valuenode_bline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_bline.cpp; sourceTree = "<group>"; };
+ A6AF2A900B965F2F00EDBA70 /* valuenode_bline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_bline.h; sourceTree = "<group>"; };
+ A6AF2A910B965F2F00EDBA70 /* valuenode_composite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_composite.cpp; sourceTree = "<group>"; };
+ A6AF2A920B965F2F00EDBA70 /* valuenode_composite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_composite.h; sourceTree = "<group>"; };
+ A6AF2A930B965F2F00EDBA70 /* valuenode_const.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_const.cpp; sourceTree = "<group>"; };
+ A6AF2A940B965F2F00EDBA70 /* valuenode_const.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_const.h; sourceTree = "<group>"; };
+ A6AF2A950B965F2F00EDBA70 /* valuenode_dynamiclist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_dynamiclist.cpp; sourceTree = "<group>"; };
+ A6AF2A960B965F2F00EDBA70 /* valuenode_dynamiclist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_dynamiclist.h; sourceTree = "<group>"; };
+ A6AF2A970B965F2F00EDBA70 /* valuenode_gradientrotate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_gradientrotate.cpp; sourceTree = "<group>"; };
+ A6AF2A980B965F2F00EDBA70 /* valuenode_gradientrotate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_gradientrotate.h; sourceTree = "<group>"; };
+ A6AF2A990B965F2F00EDBA70 /* valuenode_linear.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_linear.cpp; sourceTree = "<group>"; };
+ A6AF2A9A0B965F2F00EDBA70 /* valuenode_linear.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_linear.h; sourceTree = "<group>"; };
+ A6AF2A9B0B965F2F00EDBA70 /* valuenode_radialcomposite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_radialcomposite.cpp; sourceTree = "<group>"; };
+ A6AF2A9C0B965F2F00EDBA70 /* valuenode_radialcomposite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_radialcomposite.h; sourceTree = "<group>"; };
+ A6AF2A9D0B965F2F00EDBA70 /* valuenode_reference.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_reference.cpp; sourceTree = "<group>"; };
+ A6AF2A9E0B965F2F00EDBA70 /* valuenode_reference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_reference.h; sourceTree = "<group>"; };
+ A6AF2A9F0B965F2F00EDBA70 /* valuenode_scale.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_scale.cpp; sourceTree = "<group>"; };
+ A6AF2AA00B965F2F00EDBA70 /* valuenode_scale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_scale.h; sourceTree = "<group>"; };
+ A6AF2AA10B965F2F00EDBA70 /* valuenode_segcalctangent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_segcalctangent.cpp; sourceTree = "<group>"; };
+ A6AF2AA20B965F2F00EDBA70 /* valuenode_segcalctangent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_segcalctangent.h; sourceTree = "<group>"; };
+ A6AF2AA30B965F2F00EDBA70 /* valuenode_segcalcvertex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_segcalcvertex.cpp; sourceTree = "<group>"; };
+ A6AF2AA40B965F2F00EDBA70 /* valuenode_segcalcvertex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_segcalcvertex.h; sourceTree = "<group>"; };
+ A6AF2AA50B965F2F00EDBA70 /* valuenode_sine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_sine.cpp; sourceTree = "<group>"; };
+ A6AF2AA60B965F2F00EDBA70 /* valuenode_sine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_sine.h; sourceTree = "<group>"; };
+ A6AF2AA70B965F2F00EDBA70 /* valuenode_stripes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_stripes.cpp; sourceTree = "<group>"; };
+ A6AF2AA80B965F2F00EDBA70 /* valuenode_stripes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_stripes.h; sourceTree = "<group>"; };
+ A6AF2AA90B965F2F00EDBA70 /* valuenode_subtract.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_subtract.cpp; sourceTree = "<group>"; };
+ A6AF2AAA0B965F2F00EDBA70 /* valuenode_subtract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_subtract.h; sourceTree = "<group>"; };
+ A6AF2AAB0B965F2F00EDBA70 /* valuenode_timedswap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_timedswap.cpp; sourceTree = "<group>"; };
+ A6AF2AAC0B965F2F00EDBA70 /* valuenode_timedswap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_timedswap.h; sourceTree = "<group>"; };
+ A6AF2AAD0B965F2F00EDBA70 /* valuenode_twotone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valuenode_twotone.cpp; sourceTree = "<group>"; };
+ A6AF2AAE0B965F2F00EDBA70 /* valuenode_twotone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valuenode_twotone.h; sourceTree = "<group>"; };
+ A6AF2AAF0B965F2F00EDBA70 /* vector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vector.h; sourceTree = "<group>"; };
+ A6AF2AB00B965F2F00EDBA70 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
+ A6AF2AB10B965F2F00EDBA70 /* waypoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = waypoint.cpp; sourceTree = "<group>"; };
+ A6AF2AB20B965F2F00EDBA70 /* waypoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = waypoint.h; sourceTree = "<group>"; };
+ A6AF2AB30B965F2F00EDBA70 /* template.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = template.cpp; sourceTree = "<group>"; };
+ A6AF2AB40B965F2F00EDBA70 /* template.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = template.h; sourceTree = "<group>"; };
+ A6AF2AB70B965F2F00EDBA70 /* synfig-main.Po */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "synfig-main.Po"; sourceTree = "<group>"; };
+ A6AF2AB90B965F2F00EDBA70 /* synfig */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = synfig; sourceTree = "<group>"; };
+ A6AF2ABA0B965F2F00EDBA70 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ A6AF2ABB0B965F2F00EDBA70 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ A6AF2ABC0B965F2F00EDBA70 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
+ A6AF2ABD0B965F2F00EDBA70 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = "<group>"; };
+ A6AF2ABE0B965F2F00EDBA70 /* synfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = synfig; sourceTree = "<group>"; };
+ A6AF2ABF0B965F2F00EDBA70 /* synfig-main.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = "synfig-main.o"; sourceTree = "<group>"; };
+ A6AF2AC00B965F2F00EDBA70 /* tool.nsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tool.nsh; sourceTree = "<group>"; };
+ A6AF2F4E0B965FEF00EDBA70 /* libxml++.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "libxml++.framework"; path = "../../../Library/Frameworks/libxml++.framework"; sourceTree = SOURCE_ROOT; };
+ A6AF2F4F0B965FEF00EDBA70 /* sigc++.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "sigc++.framework"; path = "../../../Library/Frameworks/sigc++.framework"; sourceTree = SOURCE_ROOT; };
+ A6AF30B90B966C1800EDBA70 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config.h; path = "synfig-core.xcodeproj/config.h"; sourceTree = SOURCE_ROOT; };
+ A6AF30E30B966F6D00EDBA70 /* synfig */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = synfig; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ A6AF20D90B965ED900EDBA70 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A6AF2F500B965FEF00EDBA70 /* libxml++.framework in Frameworks */,
+ A6AF2F510B965FEF00EDBA70 /* sigc++.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A6AF30E10B966F6D00EDBA70 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A6AF30E60B966F9A00EDBA70 /* synfig.framework in Frameworks */,
+ A6AF32370B96714900EDBA70 /* sigc++.framework in Frameworks */,
+ A6AF323A0B96714D00EDBA70 /* libxml++.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ A6AF11960B965E2E00EDBA70 = {
+ isa = PBXGroup;
+ children = (
+ A6AF25F50B965F2D00EDBA70 /* Sources */,
+ A6AF2F4D0B965FC900EDBA70 /* Frameworks and Libraries */,
+ A6AF20DC0B965ED900EDBA70 /* Products */,
+ A6AF20DD0B965ED900EDBA70 /* synfig-Info.plist */,
+ );
+ sourceTree = "<group>";
+ };
+ A6AF20DC0B965ED900EDBA70 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF20DB0B965ED900EDBA70 /* synfig.framework */,
+ A6AF30E30B966F6D00EDBA70 /* synfig */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ A6AF25F50B965F2D00EDBA70 /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF30B90B966C1800EDBA70 /* config.h */,
+ A6AF25F90B965F2D00EDBA70 /* modules */,
+ A6AF293A0B965F2E00EDBA70 /* synfig */,
+ A6AF2AB30B965F2F00EDBA70 /* template.cpp */,
+ A6AF2AB40B965F2F00EDBA70 /* template.h */,
+ A6AF2AB50B965F2F00EDBA70 /* tool */,
+ );
+ name = Sources;
+ path = src;
+ sourceTree = "<group>";
+ };
+ A6AF25F90B965F2D00EDBA70 /* modules */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF25FA0B965F2D00EDBA70 /* example */,
+ A6AF260A0B965F2D00EDBA70 /* lyr_freetype */,
+ A6AF26210B965F2D00EDBA70 /* lyr_std */,
+ A6AF268E0B965F2D00EDBA70 /* Makefile */,
+ A6AF268F0B965F2D00EDBA70 /* Makefile.am */,
+ A6AF26900B965F2D00EDBA70 /* Makefile.in */,
+ A6AF26910B965F2D00EDBA70 /* mod_bmp */,
+ A6AF26AD0B965F2D00EDBA70 /* mod_dv */,
+ A6AF26C40B965F2D00EDBA70 /* mod_ffmpeg */,
+ A6AF26E00B965F2D00EDBA70 /* mod_filter */,
+ A6AF27150B965F2D00EDBA70 /* mod_geometry */,
+ A6AF27450B965F2D00EDBA70 /* mod_gif */,
+ A6AF275C0B965F2D00EDBA70 /* mod_gradient */,
+ A6AF27870B965F2D00EDBA70 /* mod_imagemagick */,
+ A6AF27960B965F2D00EDBA70 /* mod_jpeg */,
+ A6AF27B20B965F2D00EDBA70 /* mod_libavcodec */,
+ A6AF28940B965F2E00EDBA70 /* mod_noise */,
+ A6AF28B50B965F2E00EDBA70 /* mod_openexr */,
+ A6AF28C40B965F2E00EDBA70 /* mod_particle */,
+ A6AF28E00B965F2E00EDBA70 /* mod_png */,
+ A6AF28FC0B965F2E00EDBA70 /* mod_ppm */,
+ A6AF291A0B965F2E00EDBA70 /* mod_yuv420p */,
+ A6AF29310B965F2E00EDBA70 /* mptr_mplayer */,
+ A6AF29360B965F2E00EDBA70 /* synfig_modules.cfg */,
+ A6AF29370B965F2E00EDBA70 /* synfig_modules.cfg.in */,
+ A6AF29380B965F2E00EDBA70 /* template.nsh */,
+ A6AF29390B965F2E00EDBA70 /* untemplate.nsh */,
+ );
+ path = modules;
+ sourceTree = "<group>";
+ };
+ A6AF25FA0B965F2D00EDBA70 /* example */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF25FB0B965F2D00EDBA70 /* .deps */,
+ A6AF26000B965F2D00EDBA70 /* filledrect.cpp */,
+ A6AF26010B965F2D00EDBA70 /* filledrect.h */,
+ A6AF26020B965F2D00EDBA70 /* main.cpp */,
+ A6AF26030B965F2D00EDBA70 /* Makefile */,
+ A6AF26040B965F2D00EDBA70 /* Makefile.am */,
+ A6AF26050B965F2D00EDBA70 /* Makefile.in */,
+ A6AF26060B965F2D00EDBA70 /* metaballs.cpp */,
+ A6AF26070B965F2D00EDBA70 /* metaballs.h */,
+ A6AF26080B965F2D00EDBA70 /* simplecircle.cpp */,
+ A6AF26090B965F2D00EDBA70 /* simplecircle.h */,
+ );
+ path = example;
+ sourceTree = "<group>";
+ };
+ A6AF25FB0B965F2D00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF25FC0B965F2D00EDBA70 /* libexample_la-filledrect.Plo */,
+ A6AF25FD0B965F2D00EDBA70 /* libexample_la-main.Plo */,
+ A6AF25FE0B965F2D00EDBA70 /* libexample_la-metaballs.Plo */,
+ A6AF25FF0B965F2D00EDBA70 /* libexample_la-simplecircle.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF260A0B965F2D00EDBA70 /* lyr_freetype */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF260B0B965F2D00EDBA70 /* .deps */,
+ A6AF260E0B965F2D00EDBA70 /* .libs */,
+ A6AF26160B965F2D00EDBA70 /* liblyr_freetype.la */,
+ A6AF26170B965F2D00EDBA70 /* liblyr_freetype_la-lyr_freetype.lo */,
+ A6AF26180B965F2D00EDBA70 /* liblyr_freetype_la-main.lo */,
+ A6AF26190B965F2D00EDBA70 /* lyr_freetype.cpp */,
+ A6AF261A0B965F2D00EDBA70 /* lyr_freetype.h */,
+ A6AF261B0B965F2D00EDBA70 /* lyr_freetype.nsh */,
+ A6AF261C0B965F2D00EDBA70 /* main.cpp */,
+ A6AF261D0B965F2D00EDBA70 /* Makefile */,
+ A6AF261E0B965F2D00EDBA70 /* Makefile.am */,
+ A6AF261F0B965F2D00EDBA70 /* Makefile.in */,
+ A6AF26200B965F2D00EDBA70 /* unlyr_freetype.nsh */,
+ );
+ path = lyr_freetype;
+ sourceTree = "<group>";
+ };
+ A6AF260B0B965F2D00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF260C0B965F2D00EDBA70 /* liblyr_freetype_la-lyr_freetype.Plo */,
+ A6AF260D0B965F2D00EDBA70 /* liblyr_freetype_la-main.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF260E0B965F2D00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF260F0B965F2D00EDBA70 /* liblyr_freetype.0.0.0.so */,
+ A6AF26100B965F2D00EDBA70 /* liblyr_freetype.0.so */,
+ A6AF26110B965F2D00EDBA70 /* liblyr_freetype.la */,
+ A6AF26120B965F2D00EDBA70 /* liblyr_freetype.lai */,
+ A6AF26130B965F2D00EDBA70 /* liblyr_freetype.so */,
+ A6AF26140B965F2D00EDBA70 /* liblyr_freetype_la-lyr_freetype.o */,
+ A6AF26150B965F2D00EDBA70 /* liblyr_freetype_la-main.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF26210B965F2D00EDBA70 /* lyr_std */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26220B965F2D00EDBA70 /* .deps */,
+ A6AF26360B965F2D00EDBA70 /* .libs */,
+ A6AF264F0B965F2D00EDBA70 /* bevel.cpp */,
+ A6AF26500B965F2D00EDBA70 /* bevel.h */,
+ A6AF26510B965F2D00EDBA70 /* booleancurve.cpp */,
+ A6AF26520B965F2D00EDBA70 /* booleancurve.h */,
+ A6AF26530B965F2D00EDBA70 /* clamp.cpp */,
+ A6AF26540B965F2D00EDBA70 /* clamp.h */,
+ A6AF26550B965F2D00EDBA70 /* import.cpp */,
+ A6AF26560B965F2D00EDBA70 /* import.h */,
+ A6AF26570B965F2D00EDBA70 /* insideout.cpp */,
+ A6AF26580B965F2D00EDBA70 /* insideout.h */,
+ A6AF26590B965F2D00EDBA70 /* julia.cpp */,
+ A6AF265A0B965F2D00EDBA70 /* julia.h */,
+ A6AF265B0B965F2D00EDBA70 /* liblyr_std.la */,
+ A6AF265C0B965F2D00EDBA70 /* liblyr_std_la-bevel.lo */,
+ A6AF265D0B965F2D00EDBA70 /* liblyr_std_la-booleancurve.lo */,
+ A6AF265E0B965F2D00EDBA70 /* liblyr_std_la-clamp.lo */,
+ A6AF265F0B965F2D00EDBA70 /* liblyr_std_la-import.lo */,
+ A6AF26600B965F2D00EDBA70 /* liblyr_std_la-insideout.lo */,
+ A6AF26610B965F2D00EDBA70 /* liblyr_std_la-julia.lo */,
+ A6AF26620B965F2D00EDBA70 /* liblyr_std_la-main.lo */,
+ A6AF26630B965F2D00EDBA70 /* liblyr_std_la-mandelbrot.lo */,
+ A6AF26640B965F2D00EDBA70 /* liblyr_std_la-rotate.lo */,
+ A6AF26650B965F2D00EDBA70 /* liblyr_std_la-shade.lo */,
+ A6AF26660B965F2D00EDBA70 /* liblyr_std_la-sphere_distort.lo */,
+ A6AF26670B965F2D00EDBA70 /* liblyr_std_la-stretch.lo */,
+ A6AF26680B965F2D00EDBA70 /* liblyr_std_la-supersample.lo */,
+ A6AF26690B965F2D00EDBA70 /* liblyr_std_la-timeloop.lo */,
+ A6AF266A0B965F2D00EDBA70 /* liblyr_std_la-translate.lo */,
+ A6AF266B0B965F2D00EDBA70 /* liblyr_std_la-twirl.lo */,
+ A6AF266C0B965F2D00EDBA70 /* liblyr_std_la-warp.lo */,
+ A6AF266D0B965F2D00EDBA70 /* liblyr_std_la-xorpattern.lo */,
+ A6AF266E0B965F2D00EDBA70 /* liblyr_std_la-zoom.lo */,
+ A6AF266F0B965F2D00EDBA70 /* lyr_std.nsh */,
+ A6AF26700B965F2D00EDBA70 /* main.cpp */,
+ A6AF26710B965F2D00EDBA70 /* Makefile */,
+ A6AF26720B965F2D00EDBA70 /* Makefile.am */,
+ A6AF26730B965F2D00EDBA70 /* Makefile.in */,
+ A6AF26740B965F2D00EDBA70 /* mandelbrot.cpp */,
+ A6AF26750B965F2D00EDBA70 /* mandelbrot.h */,
+ A6AF26760B965F2D00EDBA70 /* radialgradient.cpp */,
+ A6AF26770B965F2D00EDBA70 /* rotate.cpp */,
+ A6AF26780B965F2D00EDBA70 /* rotate.h */,
+ A6AF26790B965F2D00EDBA70 /* shade.cpp */,
+ A6AF267A0B965F2D00EDBA70 /* shade.h */,
+ A6AF267B0B965F2D00EDBA70 /* sphere_distort.cpp */,
+ A6AF267C0B965F2D00EDBA70 /* sphere_distort.h */,
+ A6AF267D0B965F2D00EDBA70 /* stretch.cpp */,
+ A6AF267E0B965F2D00EDBA70 /* stretch.h */,
+ A6AF267F0B965F2D00EDBA70 /* supersample.cpp */,
+ A6AF26800B965F2D00EDBA70 /* supersample.h */,
+ A6AF26810B965F2D00EDBA70 /* timeloop.cpp */,
+ A6AF26820B965F2D00EDBA70 /* timeloop.h */,
+ A6AF26830B965F2D00EDBA70 /* translate.cpp */,
+ A6AF26840B965F2D00EDBA70 /* translate.h */,
+ A6AF26850B965F2D00EDBA70 /* twirl.cpp */,
+ A6AF26860B965F2D00EDBA70 /* twirl.h */,
+ A6AF26870B965F2D00EDBA70 /* unlyr_std.nsh */,
+ A6AF26880B965F2D00EDBA70 /* warp.cpp */,
+ A6AF26890B965F2D00EDBA70 /* warp.h */,
+ A6AF268A0B965F2D00EDBA70 /* xorpattern.cpp */,
+ A6AF268B0B965F2D00EDBA70 /* xorpattern.h */,
+ A6AF268C0B965F2D00EDBA70 /* zoom.cpp */,
+ A6AF268D0B965F2D00EDBA70 /* zoom.h */,
+ );
+ path = lyr_std;
+ sourceTree = "<group>";
+ };
+ A6AF26220B965F2D00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26230B965F2D00EDBA70 /* liblyr_std_la-bevel.Plo */,
+ A6AF26240B965F2D00EDBA70 /* liblyr_std_la-booleancurve.Plo */,
+ A6AF26250B965F2D00EDBA70 /* liblyr_std_la-clamp.Plo */,
+ A6AF26260B965F2D00EDBA70 /* liblyr_std_la-import.Plo */,
+ A6AF26270B965F2D00EDBA70 /* liblyr_std_la-insideout.Plo */,
+ A6AF26280B965F2D00EDBA70 /* liblyr_std_la-julia.Plo */,
+ A6AF26290B965F2D00EDBA70 /* liblyr_std_la-main.Plo */,
+ A6AF262A0B965F2D00EDBA70 /* liblyr_std_la-mandelbrot.Plo */,
+ A6AF262B0B965F2D00EDBA70 /* liblyr_std_la-rotate.Plo */,
+ A6AF262C0B965F2D00EDBA70 /* liblyr_std_la-shade.Plo */,
+ A6AF262D0B965F2D00EDBA70 /* liblyr_std_la-sphere_distort.Plo */,
+ A6AF262E0B965F2D00EDBA70 /* liblyr_std_la-stretch.Plo */,
+ A6AF262F0B965F2D00EDBA70 /* liblyr_std_la-supersample.Plo */,
+ A6AF26300B965F2D00EDBA70 /* liblyr_std_la-timeloop.Plo */,
+ A6AF26310B965F2D00EDBA70 /* liblyr_std_la-translate.Plo */,
+ A6AF26320B965F2D00EDBA70 /* liblyr_std_la-twirl.Plo */,
+ A6AF26330B965F2D00EDBA70 /* liblyr_std_la-warp.Plo */,
+ A6AF26340B965F2D00EDBA70 /* liblyr_std_la-xorpattern.Plo */,
+ A6AF26350B965F2D00EDBA70 /* liblyr_std_la-zoom.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF26360B965F2D00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26370B965F2D00EDBA70 /* liblyr_std.0.0.0.so */,
+ A6AF26380B965F2D00EDBA70 /* liblyr_std.0.so */,
+ A6AF26390B965F2D00EDBA70 /* liblyr_std.la */,
+ A6AF263A0B965F2D00EDBA70 /* liblyr_std.lai */,
+ A6AF263B0B965F2D00EDBA70 /* liblyr_std.so */,
+ A6AF263C0B965F2D00EDBA70 /* liblyr_std_la-bevel.o */,
+ A6AF263D0B965F2D00EDBA70 /* liblyr_std_la-booleancurve.o */,
+ A6AF263E0B965F2D00EDBA70 /* liblyr_std_la-clamp.o */,
+ A6AF263F0B965F2D00EDBA70 /* liblyr_std_la-import.o */,
+ A6AF26400B965F2D00EDBA70 /* liblyr_std_la-insideout.o */,
+ A6AF26410B965F2D00EDBA70 /* liblyr_std_la-julia.o */,
+ A6AF26420B965F2D00EDBA70 /* liblyr_std_la-main.o */,
+ A6AF26430B965F2D00EDBA70 /* liblyr_std_la-mandelbrot.o */,
+ A6AF26440B965F2D00EDBA70 /* liblyr_std_la-rotate.o */,
+ A6AF26450B965F2D00EDBA70 /* liblyr_std_la-shade.o */,
+ A6AF26460B965F2D00EDBA70 /* liblyr_std_la-sphere_distort.o */,
+ A6AF26470B965F2D00EDBA70 /* liblyr_std_la-stretch.o */,
+ A6AF26480B965F2D00EDBA70 /* liblyr_std_la-supersample.o */,
+ A6AF26490B965F2D00EDBA70 /* liblyr_std_la-timeloop.o */,
+ A6AF264A0B965F2D00EDBA70 /* liblyr_std_la-translate.o */,
+ A6AF264B0B965F2D00EDBA70 /* liblyr_std_la-twirl.o */,
+ A6AF264C0B965F2D00EDBA70 /* liblyr_std_la-warp.o */,
+ A6AF264D0B965F2D00EDBA70 /* liblyr_std_la-xorpattern.o */,
+ A6AF264E0B965F2D00EDBA70 /* liblyr_std_la-zoom.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF26910B965F2D00EDBA70 /* mod_bmp */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26920B965F2D00EDBA70 /* .deps */,
+ A6AF26960B965F2D00EDBA70 /* .libs */,
+ A6AF269F0B965F2D00EDBA70 /* libmod_bmp.la */,
+ A6AF26A00B965F2D00EDBA70 /* libmod_bmp_la-main.lo */,
+ A6AF26A10B965F2D00EDBA70 /* libmod_bmp_la-mptr_bmp.lo */,
+ A6AF26A20B965F2D00EDBA70 /* libmod_bmp_la-trgt_bmp.lo */,
+ A6AF26A30B965F2D00EDBA70 /* main.cpp */,
+ A6AF26A40B965F2D00EDBA70 /* Makefile */,
+ A6AF26A50B965F2D00EDBA70 /* Makefile.am */,
+ A6AF26A60B965F2D00EDBA70 /* Makefile.in */,
+ A6AF26A70B965F2D00EDBA70 /* mod_bmp.nsh */,
+ A6AF26A80B965F2D00EDBA70 /* mptr_bmp.cpp */,
+ A6AF26A90B965F2D00EDBA70 /* mptr_bmp.h */,
+ A6AF26AA0B965F2D00EDBA70 /* trgt_bmp.cpp */,
+ A6AF26AB0B965F2D00EDBA70 /* trgt_bmp.h */,
+ A6AF26AC0B965F2D00EDBA70 /* unmod_bmp.nsh */,
+ );
+ path = mod_bmp;
+ sourceTree = "<group>";
+ };
+ A6AF26920B965F2D00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26930B965F2D00EDBA70 /* libmod_bmp_la-main.Plo */,
+ A6AF26940B965F2D00EDBA70 /* libmod_bmp_la-mptr_bmp.Plo */,
+ A6AF26950B965F2D00EDBA70 /* libmod_bmp_la-trgt_bmp.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF26960B965F2D00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26970B965F2D00EDBA70 /* libmod_bmp.0.0.0.so */,
+ A6AF26980B965F2D00EDBA70 /* libmod_bmp.0.so */,
+ A6AF26990B965F2D00EDBA70 /* libmod_bmp.la */,
+ A6AF269A0B965F2D00EDBA70 /* libmod_bmp.lai */,
+ A6AF269B0B965F2D00EDBA70 /* libmod_bmp.so */,
+ A6AF269C0B965F2D00EDBA70 /* libmod_bmp_la-main.o */,
+ A6AF269D0B965F2D00EDBA70 /* libmod_bmp_la-mptr_bmp.o */,
+ A6AF269E0B965F2D00EDBA70 /* libmod_bmp_la-trgt_bmp.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF26AD0B965F2D00EDBA70 /* mod_dv */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26AE0B965F2D00EDBA70 /* .deps */,
+ A6AF26B10B965F2D00EDBA70 /* .libs */,
+ A6AF26B90B965F2D00EDBA70 /* libmod_dv.la */,
+ A6AF26BA0B965F2D00EDBA70 /* libmod_dv_la-main.lo */,
+ A6AF26BB0B965F2D00EDBA70 /* libmod_dv_la-trgt_dv.lo */,
+ A6AF26BC0B965F2D00EDBA70 /* main.cpp */,
+ A6AF26BD0B965F2D00EDBA70 /* Makefile */,
+ A6AF26BE0B965F2D00EDBA70 /* Makefile.am */,
+ A6AF26BF0B965F2D00EDBA70 /* Makefile.in */,
+ A6AF26C00B965F2D00EDBA70 /* mod_dv.nsh */,
+ A6AF26C10B965F2D00EDBA70 /* trgt_dv.cpp */,
+ A6AF26C20B965F2D00EDBA70 /* trgt_dv.h */,
+ A6AF26C30B965F2D00EDBA70 /* unmod_dv.nsh */,
+ );
+ path = mod_dv;
+ sourceTree = "<group>";
+ };
+ A6AF26AE0B965F2D00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26AF0B965F2D00EDBA70 /* libmod_dv_la-main.Plo */,
+ A6AF26B00B965F2D00EDBA70 /* libmod_dv_la-trgt_dv.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF26B10B965F2D00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26B20B965F2D00EDBA70 /* libmod_dv.0.0.0.so */,
+ A6AF26B30B965F2D00EDBA70 /* libmod_dv.0.so */,
+ A6AF26B40B965F2D00EDBA70 /* libmod_dv.la */,
+ A6AF26B50B965F2D00EDBA70 /* libmod_dv.lai */,
+ A6AF26B60B965F2D00EDBA70 /* libmod_dv.so */,
+ A6AF26B70B965F2D00EDBA70 /* libmod_dv_la-main.o */,
+ A6AF26B80B965F2D00EDBA70 /* libmod_dv_la-trgt_dv.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF26C40B965F2D00EDBA70 /* mod_ffmpeg */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26C50B965F2D00EDBA70 /* .deps */,
+ A6AF26C90B965F2D00EDBA70 /* .libs */,
+ A6AF26D20B965F2D00EDBA70 /* libmod_ffmpeg.la */,
+ A6AF26D30B965F2D00EDBA70 /* libmod_ffmpeg_la-main.lo */,
+ A6AF26D40B965F2D00EDBA70 /* libmod_ffmpeg_la-mptr_ffmpeg.lo */,
+ A6AF26D50B965F2D00EDBA70 /* libmod_ffmpeg_la-trgt_ffmpeg.lo */,
+ A6AF26D60B965F2D00EDBA70 /* main.cpp */,
+ A6AF26D70B965F2D00EDBA70 /* Makefile */,
+ A6AF26D80B965F2D00EDBA70 /* Makefile.am */,
+ A6AF26D90B965F2D00EDBA70 /* Makefile.in */,
+ A6AF26DA0B965F2D00EDBA70 /* mod_ffmpeg.nsh */,
+ A6AF26DB0B965F2D00EDBA70 /* mptr_ffmpeg.cpp */,
+ A6AF26DC0B965F2D00EDBA70 /* mptr_ffmpeg.h */,
+ A6AF26DD0B965F2D00EDBA70 /* trgt_ffmpeg.cpp */,
+ A6AF26DE0B965F2D00EDBA70 /* trgt_ffmpeg.h */,
+ A6AF26DF0B965F2D00EDBA70 /* unmod_ffmpeg.nsh */,
+ );
+ path = mod_ffmpeg;
+ sourceTree = "<group>";
+ };
+ A6AF26C50B965F2D00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26C60B965F2D00EDBA70 /* libmod_ffmpeg_la-main.Plo */,
+ A6AF26C70B965F2D00EDBA70 /* libmod_ffmpeg_la-mptr_ffmpeg.Plo */,
+ A6AF26C80B965F2D00EDBA70 /* libmod_ffmpeg_la-trgt_ffmpeg.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF26C90B965F2D00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26CA0B965F2D00EDBA70 /* libmod_ffmpeg.0.0.0.so */,
+ A6AF26CB0B965F2D00EDBA70 /* libmod_ffmpeg.0.so */,
+ A6AF26CC0B965F2D00EDBA70 /* libmod_ffmpeg.la */,
+ A6AF26CD0B965F2D00EDBA70 /* libmod_ffmpeg.lai */,
+ A6AF26CE0B965F2D00EDBA70 /* libmod_ffmpeg.so */,
+ A6AF26CF0B965F2D00EDBA70 /* libmod_ffmpeg_la-main.o */,
+ A6AF26D00B965F2D00EDBA70 /* libmod_ffmpeg_la-mptr_ffmpeg.o */,
+ A6AF26D10B965F2D00EDBA70 /* libmod_ffmpeg_la-trgt_ffmpeg.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF26E00B965F2D00EDBA70 /* mod_filter */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26E10B965F2D00EDBA70 /* .deps */,
+ A6AF26EA0B965F2D00EDBA70 /* .libs */,
+ A6AF26F80B965F2D00EDBA70 /* blur.cpp */,
+ A6AF26F90B965F2D00EDBA70 /* blur.h */,
+ A6AF26FA0B965F2D00EDBA70 /* colorcorrect.cpp */,
+ A6AF26FB0B965F2D00EDBA70 /* colorcorrect.h */,
+ A6AF26FC0B965F2D00EDBA70 /* halftone.cpp */,
+ A6AF26FD0B965F2D00EDBA70 /* halftone.h */,
+ A6AF26FE0B965F2D00EDBA70 /* halftone2.cpp */,
+ A6AF26FF0B965F2D00EDBA70 /* halftone2.h */,
+ A6AF27000B965F2D00EDBA70 /* halftone3.cpp */,
+ A6AF27010B965F2D00EDBA70 /* halftone3.h */,
+ A6AF27020B965F2D00EDBA70 /* libmod_filter.la */,
+ A6AF27030B965F2D00EDBA70 /* libmod_filter_la-blur.lo */,
+ A6AF27040B965F2D00EDBA70 /* libmod_filter_la-colorcorrect.lo */,
+ A6AF27050B965F2D00EDBA70 /* libmod_filter_la-halftone.lo */,
+ A6AF27060B965F2D00EDBA70 /* libmod_filter_la-halftone2.lo */,
+ A6AF27070B965F2D00EDBA70 /* libmod_filter_la-halftone3.lo */,
+ A6AF27080B965F2D00EDBA70 /* libmod_filter_la-lumakey.lo */,
+ A6AF27090B965F2D00EDBA70 /* libmod_filter_la-main.lo */,
+ A6AF270A0B965F2D00EDBA70 /* libmod_filter_la-radialblur.lo */,
+ A6AF270B0B965F2D00EDBA70 /* lumakey.cpp */,
+ A6AF270C0B965F2D00EDBA70 /* lumakey.h */,
+ A6AF270D0B965F2D00EDBA70 /* main.cpp */,
+ A6AF270E0B965F2D00EDBA70 /* Makefile */,
+ A6AF270F0B965F2D00EDBA70 /* Makefile.am */,
+ A6AF27100B965F2D00EDBA70 /* Makefile.in */,
+ A6AF27110B965F2D00EDBA70 /* mod_filter.nsh */,
+ A6AF27120B965F2D00EDBA70 /* radialblur.cpp */,
+ A6AF27130B965F2D00EDBA70 /* radialblur.h */,
+ A6AF27140B965F2D00EDBA70 /* unmod_filter.nsh */,
+ );
+ path = mod_filter;
+ sourceTree = "<group>";
+ };
+ A6AF26E10B965F2D00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26E20B965F2D00EDBA70 /* libmod_filter_la-blur.Plo */,
+ A6AF26E30B965F2D00EDBA70 /* libmod_filter_la-colorcorrect.Plo */,
+ A6AF26E40B965F2D00EDBA70 /* libmod_filter_la-halftone.Plo */,
+ A6AF26E50B965F2D00EDBA70 /* libmod_filter_la-halftone2.Plo */,
+ A6AF26E60B965F2D00EDBA70 /* libmod_filter_la-halftone3.Plo */,
+ A6AF26E70B965F2D00EDBA70 /* libmod_filter_la-lumakey.Plo */,
+ A6AF26E80B965F2D00EDBA70 /* libmod_filter_la-main.Plo */,
+ A6AF26E90B965F2D00EDBA70 /* libmod_filter_la-radialblur.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF26EA0B965F2D00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF26EB0B965F2D00EDBA70 /* libmod_filter.0.0.0.so */,
+ A6AF26EC0B965F2D00EDBA70 /* libmod_filter.0.so */,
+ A6AF26ED0B965F2D00EDBA70 /* libmod_filter.la */,
+ A6AF26EE0B965F2D00EDBA70 /* libmod_filter.lai */,
+ A6AF26EF0B965F2D00EDBA70 /* libmod_filter.so */,
+ A6AF26F00B965F2D00EDBA70 /* libmod_filter_la-blur.o */,
+ A6AF26F10B965F2D00EDBA70 /* libmod_filter_la-colorcorrect.o */,
+ A6AF26F20B965F2D00EDBA70 /* libmod_filter_la-halftone.o */,
+ A6AF26F30B965F2D00EDBA70 /* libmod_filter_la-halftone2.o */,
+ A6AF26F40B965F2D00EDBA70 /* libmod_filter_la-halftone3.o */,
+ A6AF26F50B965F2D00EDBA70 /* libmod_filter_la-lumakey.o */,
+ A6AF26F60B965F2D00EDBA70 /* libmod_filter_la-main.o */,
+ A6AF26F70B965F2D00EDBA70 /* libmod_filter_la-radialblur.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF27150B965F2D00EDBA70 /* mod_geometry */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27160B965F2D00EDBA70 /* .deps */,
+ A6AF271E0B965F2D00EDBA70 /* .libs */,
+ A6AF272B0B965F2D00EDBA70 /* checkerboard.cpp */,
+ A6AF272C0B965F2D00EDBA70 /* checkerboard.h */,
+ A6AF272D0B965F2D00EDBA70 /* circle.cpp */,
+ A6AF272E0B965F2D00EDBA70 /* circle.h */,
+ A6AF272F0B965F2D00EDBA70 /* libmod_geometry.la */,
+ A6AF27300B965F2D00EDBA70 /* libmod_geometry_la-checkerboard.lo */,
+ A6AF27310B965F2D00EDBA70 /* libmod_geometry_la-circle.lo */,
+ A6AF27320B965F2D00EDBA70 /* libmod_geometry_la-main.lo */,
+ A6AF27330B965F2D00EDBA70 /* libmod_geometry_la-outline.lo */,
+ A6AF27340B965F2D00EDBA70 /* libmod_geometry_la-rectangle.lo */,
+ A6AF27350B965F2D00EDBA70 /* libmod_geometry_la-region.lo */,
+ A6AF27360B965F2D00EDBA70 /* libmod_geometry_la-star.lo */,
+ A6AF27370B965F2D00EDBA70 /* main.cpp */,
+ A6AF27380B965F2D00EDBA70 /* Makefile */,
+ A6AF27390B965F2D00EDBA70 /* Makefile.am */,
+ A6AF273A0B965F2D00EDBA70 /* Makefile.in */,
+ A6AF273B0B965F2D00EDBA70 /* mod_geometry.nsh */,
+ A6AF273C0B965F2D00EDBA70 /* outline.cpp */,
+ A6AF273D0B965F2D00EDBA70 /* outline.h */,
+ A6AF273E0B965F2D00EDBA70 /* rectangle.cpp */,
+ A6AF273F0B965F2D00EDBA70 /* rectangle.h */,
+ A6AF27400B965F2D00EDBA70 /* region.cpp */,
+ A6AF27410B965F2D00EDBA70 /* region.h */,
+ A6AF27420B965F2D00EDBA70 /* star.cpp */,
+ A6AF27430B965F2D00EDBA70 /* star.h */,
+ A6AF27440B965F2D00EDBA70 /* unmod_geometry.nsh */,
+ );
+ path = mod_geometry;
+ sourceTree = "<group>";
+ };
+ A6AF27160B965F2D00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27170B965F2D00EDBA70 /* libmod_geometry_la-checkerboard.Plo */,
+ A6AF27180B965F2D00EDBA70 /* libmod_geometry_la-circle.Plo */,
+ A6AF27190B965F2D00EDBA70 /* libmod_geometry_la-main.Plo */,
+ A6AF271A0B965F2D00EDBA70 /* libmod_geometry_la-outline.Plo */,
+ A6AF271B0B965F2D00EDBA70 /* libmod_geometry_la-rectangle.Plo */,
+ A6AF271C0B965F2D00EDBA70 /* libmod_geometry_la-region.Plo */,
+ A6AF271D0B965F2D00EDBA70 /* libmod_geometry_la-star.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF271E0B965F2D00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF271F0B965F2D00EDBA70 /* libmod_geometry.0.0.0.so */,
+ A6AF27200B965F2D00EDBA70 /* libmod_geometry.0.so */,
+ A6AF27210B965F2D00EDBA70 /* libmod_geometry.la */,
+ A6AF27220B965F2D00EDBA70 /* libmod_geometry.lai */,
+ A6AF27230B965F2D00EDBA70 /* libmod_geometry.so */,
+ A6AF27240B965F2D00EDBA70 /* libmod_geometry_la-checkerboard.o */,
+ A6AF27250B965F2D00EDBA70 /* libmod_geometry_la-circle.o */,
+ A6AF27260B965F2D00EDBA70 /* libmod_geometry_la-main.o */,
+ A6AF27270B965F2D00EDBA70 /* libmod_geometry_la-outline.o */,
+ A6AF27280B965F2D00EDBA70 /* libmod_geometry_la-rectangle.o */,
+ A6AF27290B965F2D00EDBA70 /* libmod_geometry_la-region.o */,
+ A6AF272A0B965F2D00EDBA70 /* libmod_geometry_la-star.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF27450B965F2D00EDBA70 /* mod_gif */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27460B965F2D00EDBA70 /* .deps */,
+ A6AF27490B965F2D00EDBA70 /* .libs */,
+ A6AF27510B965F2D00EDBA70 /* libmod_gif.la */,
+ A6AF27520B965F2D00EDBA70 /* libmod_gif_la-main.lo */,
+ A6AF27530B965F2D00EDBA70 /* libmod_gif_la-trgt_gif.lo */,
+ A6AF27540B965F2D00EDBA70 /* main.cpp */,
+ A6AF27550B965F2D00EDBA70 /* Makefile */,
+ A6AF27560B965F2D00EDBA70 /* Makefile.am */,
+ A6AF27570B965F2D00EDBA70 /* Makefile.in */,
+ A6AF27580B965F2D00EDBA70 /* mod_gif.nsh */,
+ A6AF27590B965F2D00EDBA70 /* trgt_gif.cpp */,
+ A6AF275A0B965F2D00EDBA70 /* trgt_gif.h */,
+ A6AF275B0B965F2D00EDBA70 /* unmod_gif.nsh */,
+ );
+ path = mod_gif;
+ sourceTree = "<group>";
+ };
+ A6AF27460B965F2D00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27470B965F2D00EDBA70 /* libmod_gif_la-main.Plo */,
+ A6AF27480B965F2D00EDBA70 /* libmod_gif_la-trgt_gif.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF27490B965F2D00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF274A0B965F2D00EDBA70 /* libmod_gif.0.0.0.so */,
+ A6AF274B0B965F2D00EDBA70 /* libmod_gif.0.so */,
+ A6AF274C0B965F2D00EDBA70 /* libmod_gif.la */,
+ A6AF274D0B965F2D00EDBA70 /* libmod_gif.lai */,
+ A6AF274E0B965F2D00EDBA70 /* libmod_gif.so */,
+ A6AF274F0B965F2D00EDBA70 /* libmod_gif_la-main.o */,
+ A6AF27500B965F2D00EDBA70 /* libmod_gif_la-trgt_gif.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF275C0B965F2D00EDBA70 /* mod_gradient */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF275D0B965F2D00EDBA70 /* .deps */,
+ A6AF27640B965F2D00EDBA70 /* .libs */,
+ A6AF27700B965F2D00EDBA70 /* conicalgradient.cpp */,
+ A6AF27710B965F2D00EDBA70 /* conicalgradient.h */,
+ A6AF27720B965F2D00EDBA70 /* curvegradient.cpp */,
+ A6AF27730B965F2D00EDBA70 /* curvegradient.h */,
+ A6AF27740B965F2D00EDBA70 /* libmod_gradient.la */,
+ A6AF27750B965F2D00EDBA70 /* libmod_gradient_la-conicalgradient.lo */,
+ A6AF27760B965F2D00EDBA70 /* libmod_gradient_la-curvegradient.lo */,
+ A6AF27770B965F2D00EDBA70 /* libmod_gradient_la-lineargradient.lo */,
+ A6AF27780B965F2D00EDBA70 /* libmod_gradient_la-main.lo */,
+ A6AF27790B965F2D00EDBA70 /* libmod_gradient_la-radialgradient.lo */,
+ A6AF277A0B965F2D00EDBA70 /* libmod_gradient_la-spiralgradient.lo */,
+ A6AF277B0B965F2D00EDBA70 /* lineargradient.cpp */,
+ A6AF277C0B965F2D00EDBA70 /* lineargradient.h */,
+ A6AF277D0B965F2D00EDBA70 /* main.cpp */,
+ A6AF277E0B965F2D00EDBA70 /* Makefile */,
+ A6AF277F0B965F2D00EDBA70 /* Makefile.am */,
+ A6AF27800B965F2D00EDBA70 /* Makefile.in */,
+ A6AF27810B965F2D00EDBA70 /* mod_gradient.nsh */,
+ A6AF27820B965F2D00EDBA70 /* radialgradient.cpp */,
+ A6AF27830B965F2D00EDBA70 /* radialgradient.h */,
+ A6AF27840B965F2D00EDBA70 /* spiralgradient.cpp */,
+ A6AF27850B965F2D00EDBA70 /* spiralgradient.h */,
+ A6AF27860B965F2D00EDBA70 /* unmod_gradient.nsh */,
+ );
+ path = mod_gradient;
+ sourceTree = "<group>";
+ };
+ A6AF275D0B965F2D00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF275E0B965F2D00EDBA70 /* libmod_gradient_la-conicalgradient.Plo */,
+ A6AF275F0B965F2D00EDBA70 /* libmod_gradient_la-curvegradient.Plo */,
+ A6AF27600B965F2D00EDBA70 /* libmod_gradient_la-lineargradient.Plo */,
+ A6AF27610B965F2D00EDBA70 /* libmod_gradient_la-main.Plo */,
+ A6AF27620B965F2D00EDBA70 /* libmod_gradient_la-radialgradient.Plo */,
+ A6AF27630B965F2D00EDBA70 /* libmod_gradient_la-spiralgradient.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF27640B965F2D00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27650B965F2D00EDBA70 /* libmod_gradient.0.0.0.so */,
+ A6AF27660B965F2D00EDBA70 /* libmod_gradient.0.so */,
+ A6AF27670B965F2D00EDBA70 /* libmod_gradient.la */,
+ A6AF27680B965F2D00EDBA70 /* libmod_gradient.lai */,
+ A6AF27690B965F2D00EDBA70 /* libmod_gradient.so */,
+ A6AF276A0B965F2D00EDBA70 /* libmod_gradient_la-conicalgradient.o */,
+ A6AF276B0B965F2D00EDBA70 /* libmod_gradient_la-curvegradient.o */,
+ A6AF276C0B965F2D00EDBA70 /* libmod_gradient_la-lineargradient.o */,
+ A6AF276D0B965F2D00EDBA70 /* libmod_gradient_la-main.o */,
+ A6AF276E0B965F2D00EDBA70 /* libmod_gradient_la-radialgradient.o */,
+ A6AF276F0B965F2D00EDBA70 /* libmod_gradient_la-spiralgradient.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF27870B965F2D00EDBA70 /* mod_imagemagick */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27880B965F2D00EDBA70 /* .deps */,
+ A6AF278C0B965F2D00EDBA70 /* main.cpp */,
+ A6AF278D0B965F2D00EDBA70 /* Makefile */,
+ A6AF278E0B965F2D00EDBA70 /* Makefile.am */,
+ A6AF278F0B965F2D00EDBA70 /* Makefile.in */,
+ A6AF27900B965F2D00EDBA70 /* mod_imagemagick.nsh */,
+ A6AF27910B965F2D00EDBA70 /* mptr_imagemagick.cpp */,
+ A6AF27920B965F2D00EDBA70 /* mptr_imagemagick.h */,
+ A6AF27930B965F2D00EDBA70 /* trgt_imagemagick.cpp */,
+ A6AF27940B965F2D00EDBA70 /* trgt_imagemagick.h */,
+ A6AF27950B965F2D00EDBA70 /* unmod_imagemagick.nsh */,
+ );
+ path = mod_imagemagick;
+ sourceTree = "<group>";
+ };
+ A6AF27880B965F2D00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27890B965F2D00EDBA70 /* libmod_imagemagick_la-main.Plo */,
+ A6AF278A0B965F2D00EDBA70 /* libmod_imagemagick_la-mptr_imagemagick.Plo */,
+ A6AF278B0B965F2D00EDBA70 /* libmod_imagemagick_la-trgt_imagemagick.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF27960B965F2D00EDBA70 /* mod_jpeg */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27970B965F2D00EDBA70 /* .deps */,
+ A6AF279B0B965F2D00EDBA70 /* .libs */,
+ A6AF27A40B965F2D00EDBA70 /* libmod_jpeg.la */,
+ A6AF27A50B965F2D00EDBA70 /* libmod_jpeg_la-main.lo */,
+ A6AF27A60B965F2D00EDBA70 /* libmod_jpeg_la-mptr_jpeg.lo */,
+ A6AF27A70B965F2D00EDBA70 /* libmod_jpeg_la-trgt_jpeg.lo */,
+ A6AF27A80B965F2D00EDBA70 /* main.cpp */,
+ A6AF27A90B965F2D00EDBA70 /* Makefile */,
+ A6AF27AA0B965F2D00EDBA70 /* Makefile.am */,
+ A6AF27AB0B965F2D00EDBA70 /* Makefile.in */,
+ A6AF27AC0B965F2D00EDBA70 /* mod_jpeg.nsh */,
+ A6AF27AD0B965F2D00EDBA70 /* mptr_jpeg.cpp */,
+ A6AF27AE0B965F2D00EDBA70 /* mptr_jpeg.h */,
+ A6AF27AF0B965F2D00EDBA70 /* trgt_jpeg.cpp */,
+ A6AF27B00B965F2D00EDBA70 /* trgt_jpeg.h */,
+ A6AF27B10B965F2D00EDBA70 /* unmod_jpeg.nsh */,
+ );
+ path = mod_jpeg;
+ sourceTree = "<group>";
+ };
+ A6AF27970B965F2D00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27980B965F2D00EDBA70 /* libmod_jpeg_la-main.Plo */,
+ A6AF27990B965F2D00EDBA70 /* libmod_jpeg_la-mptr_jpeg.Plo */,
+ A6AF279A0B965F2D00EDBA70 /* libmod_jpeg_la-trgt_jpeg.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF279B0B965F2D00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF279C0B965F2D00EDBA70 /* libmod_jpeg.0.0.0.so */,
+ A6AF279D0B965F2D00EDBA70 /* libmod_jpeg.0.so */,
+ A6AF279E0B965F2D00EDBA70 /* libmod_jpeg.la */,
+ A6AF279F0B965F2D00EDBA70 /* libmod_jpeg.lai */,
+ A6AF27A00B965F2D00EDBA70 /* libmod_jpeg.so */,
+ A6AF27A10B965F2D00EDBA70 /* libmod_jpeg_la-main.o */,
+ A6AF27A20B965F2D00EDBA70 /* libmod_jpeg_la-mptr_jpeg.o */,
+ A6AF27A30B965F2D00EDBA70 /* libmod_jpeg_la-trgt_jpeg.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF27B20B965F2D00EDBA70 /* mod_libavcodec */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27B30B965F2D00EDBA70 /* .deps */,
+ A6AF27B70B965F2D00EDBA70 /* libavcodec */,
+ A6AF28430B965F2E00EDBA70 /* libavformat */,
+ A6AF288A0B965F2E00EDBA70 /* main.cpp */,
+ A6AF288B0B965F2E00EDBA70 /* Makefile */,
+ A6AF288C0B965F2E00EDBA70 /* Makefile.am */,
+ A6AF288D0B965F2E00EDBA70 /* Makefile.in */,
+ A6AF288E0B965F2E00EDBA70 /* mod_libavcodec.nsh */,
+ A6AF288F0B965F2E00EDBA70 /* mptr.cpp */,
+ A6AF28900B965F2E00EDBA70 /* mptr.h */,
+ A6AF28910B965F2E00EDBA70 /* trgt_av.cpp */,
+ A6AF28920B965F2E00EDBA70 /* trgt_av.h */,
+ A6AF28930B965F2E00EDBA70 /* unmod_libavcodec.nsh */,
+ );
+ path = mod_libavcodec;
+ sourceTree = "<group>";
+ };
+ A6AF27B30B965F2D00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27B40B965F2D00EDBA70 /* libmod_libavcodec_la-main.Plo */,
+ A6AF27B50B965F2D00EDBA70 /* libmod_libavcodec_la-mptr.Plo */,
+ A6AF27B60B965F2D00EDBA70 /* libmod_libavcodec_la-trgt_av.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF27B70B965F2D00EDBA70 /* libavcodec */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27B80B965F2D00EDBA70 /* 4xm.c */,
+ A6AF27B90B965F2D00EDBA70 /* a52dec.c */,
+ A6AF27BA0B965F2D00EDBA70 /* ac3.h */,
+ A6AF27BB0B965F2D00EDBA70 /* ac3dec.c */,
+ A6AF27BC0B965F2D00EDBA70 /* ac3enc.c */,
+ A6AF27BD0B965F2D00EDBA70 /* ac3tab.h */,
+ A6AF27BE0B965F2D00EDBA70 /* adpcm.c */,
+ A6AF27BF0B965F2D00EDBA70 /* allcodecs.c */,
+ A6AF27C00B965F2D00EDBA70 /* amr.c */,
+ A6AF27C10B965F2D00EDBA70 /* apiexample.c */,
+ A6AF27C20B965F2D00EDBA70 /* asv1.c */,
+ A6AF27C30B965F2D00EDBA70 /* avcodec.c */,
+ A6AF27C40B965F2D00EDBA70 /* avcodec.h */,
+ A6AF27C50B965F2D00EDBA70 /* bswap.h */,
+ A6AF27C60B965F2D00EDBA70 /* cabac.c */,
+ A6AF27C70B965F2D00EDBA70 /* cabac.h */,
+ A6AF27C80B965F2D00EDBA70 /* cljr.c */,
+ A6AF27C90B965F2D00EDBA70 /* common.c */,
+ A6AF27CA0B965F2D00EDBA70 /* common.h */,
+ A6AF27CB0B965F2D00EDBA70 /* cyuv.c */,
+ A6AF27CC0B965F2D00EDBA70 /* dct-test.c */,
+ A6AF27CD0B965F2D00EDBA70 /* Doxyfile */,
+ A6AF27CE0B965F2D00EDBA70 /* dpcm.c */,
+ A6AF27CF0B965F2D00EDBA70 /* dsputil.c */,
+ A6AF27D00B965F2E00EDBA70 /* dsputil.h */,
+ A6AF27D10B965F2E00EDBA70 /* dv.c */,
+ A6AF27D20B965F2E00EDBA70 /* dvdata.h */,
+ A6AF27D30B965F2E00EDBA70 /* error_resilience.c */,
+ A6AF27D40B965F2E00EDBA70 /* eval.c */,
+ A6AF27D50B965F2E00EDBA70 /* faad.c */,
+ A6AF27D60B965F2E00EDBA70 /* fastmemcpy.h */,
+ A6AF27D70B965F2E00EDBA70 /* fdctref.c */,
+ A6AF27D80B965F2E00EDBA70 /* fft-test.c */,
+ A6AF27D90B965F2E00EDBA70 /* fft.c */,
+ A6AF27DA0B965F2E00EDBA70 /* ffv1.c */,
+ A6AF27DB0B965F2E00EDBA70 /* golomb.c */,
+ A6AF27DC0B965F2E00EDBA70 /* golomb.h */,
+ A6AF27DD0B965F2E00EDBA70 /* h263.c */,
+ A6AF27DE0B965F2E00EDBA70 /* h263data.h */,
+ A6AF27DF0B965F2E00EDBA70 /* h263dec.c */,
+ A6AF27E00B965F2E00EDBA70 /* h264.c */,
+ A6AF27E10B965F2E00EDBA70 /* h264data.h */,
+ A6AF27E20B965F2E00EDBA70 /* huffyuv.c */,
+ A6AF27E30B965F2E00EDBA70 /* i386 */,
+ A6AF27F00B965F2E00EDBA70 /* imgconvert.c */,
+ A6AF27F10B965F2E00EDBA70 /* imgconvert_template.h */,
+ A6AF27F20B965F2E00EDBA70 /* imgresample.c */,
+ A6AF27F30B965F2E00EDBA70 /* indeo3.c */,
+ A6AF27F40B965F2E00EDBA70 /* indeo3data.h */,
+ A6AF27F50B965F2E00EDBA70 /* interplayvideo.c */,
+ A6AF27F60B965F2E00EDBA70 /* jfdctfst.c */,
+ A6AF27F70B965F2E00EDBA70 /* jfdctint.c */,
+ A6AF27F80B965F2E00EDBA70 /* jrevdct.c */,
+ A6AF27F90B965F2E00EDBA70 /* liba52 */,
+ A6AF28090B965F2E00EDBA70 /* libpostproc */,
+ A6AF28100B965F2E00EDBA70 /* mace.c */,
+ A6AF28110B965F2E00EDBA70 /* Makefile */,
+ A6AF28120B965F2E00EDBA70 /* Makefile.am */,
+ A6AF28130B965F2E00EDBA70 /* mdct.c */,
+ A6AF28140B965F2E00EDBA70 /* mdec.c */,
+ A6AF28150B965F2E00EDBA70 /* mem.c */,
+ A6AF28160B965F2E00EDBA70 /* mjpeg.c */,
+ A6AF28170B965F2E00EDBA70 /* motion_est.c */,
+ A6AF28180B965F2E00EDBA70 /* motion_est_template.c */,
+ A6AF28190B965F2E00EDBA70 /* motion_test.c */,
+ A6AF281A0B965F2E00EDBA70 /* mp3lameaudio.c */,
+ A6AF281B0B965F2E00EDBA70 /* mpeg12.c */,
+ A6AF281C0B965F2E00EDBA70 /* mpeg12data.h */,
+ A6AF281D0B965F2E00EDBA70 /* mpeg4data.h */,
+ A6AF281E0B965F2E00EDBA70 /* mpegaudio.c */,
+ A6AF281F0B965F2E00EDBA70 /* mpegaudio.h */,
+ A6AF28200B965F2E00EDBA70 /* mpegaudiodec.c */,
+ A6AF28210B965F2E00EDBA70 /* mpegaudiodectab.h */,
+ A6AF28220B965F2E00EDBA70 /* mpegaudiotab.h */,
+ A6AF28230B965F2E00EDBA70 /* mpegvideo.c */,
+ A6AF28240B965F2E00EDBA70 /* mpegvideo.h */,
+ A6AF28250B965F2E00EDBA70 /* msmpeg4.c */,
+ A6AF28260B965F2E00EDBA70 /* msmpeg4data.h */,
+ A6AF28270B965F2E00EDBA70 /* oggvorbis.c */,
+ A6AF28280B965F2E00EDBA70 /* oggvorbis.h */,
+ A6AF28290B965F2E00EDBA70 /* opts.c */,
+ A6AF282A0B965F2E00EDBA70 /* pcm.c */,
+ A6AF282B0B965F2E00EDBA70 /* ra144.c */,
+ A6AF282C0B965F2E00EDBA70 /* ra144.h */,
+ A6AF282D0B965F2E00EDBA70 /* ra288.c */,
+ A6AF282E0B965F2E00EDBA70 /* ra288.h */,
+ A6AF282F0B965F2E00EDBA70 /* ratecontrol.c */,
+ A6AF28300B965F2E00EDBA70 /* raw.c */,
+ A6AF28310B965F2E00EDBA70 /* resample.c */,
+ A6AF28320B965F2E00EDBA70 /* roqvideo.c */,
+ A6AF28330B965F2E00EDBA70 /* rv10.c */,
+ A6AF28340B965F2E00EDBA70 /* simple_idct.c */,
+ A6AF28350B965F2E00EDBA70 /* simple_idct.h */,
+ A6AF28360B965F2E00EDBA70 /* svq1.c */,
+ A6AF28370B965F2E00EDBA70 /* svq1_cb.h */,
+ A6AF28380B965F2E00EDBA70 /* svq1_vlc.h */,
+ A6AF28390B965F2E00EDBA70 /* svq3.c */,
+ A6AF283A0B965F2E00EDBA70 /* utils.c */,
+ A6AF283B0B965F2E00EDBA70 /* vcr1.c */,
+ A6AF283C0B965F2E00EDBA70 /* vp3.c */,
+ A6AF283D0B965F2E00EDBA70 /* vp3data.h */,
+ A6AF283E0B965F2E00EDBA70 /* wmadata.h */,
+ A6AF283F0B965F2E00EDBA70 /* wmadec.c */,
+ A6AF28400B965F2E00EDBA70 /* wmv2.c */,
+ A6AF28410B965F2E00EDBA70 /* xan.c */,
+ A6AF28420B965F2E00EDBA70 /* xvmcvideo.c */,
+ );
+ path = libavcodec;
+ sourceTree = "<group>";
+ };
+ A6AF27E30B965F2E00EDBA70 /* i386 */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27E40B965F2E00EDBA70 /* cputest.c */,
+ A6AF27E50B965F2E00EDBA70 /* dsputil_mmx.c */,
+ A6AF27E60B965F2E00EDBA70 /* dsputil_mmx_avg.h */,
+ A6AF27E70B965F2E00EDBA70 /* dsputil_mmx_rnd.h */,
+ A6AF27E80B965F2E00EDBA70 /* fdct_mmx.c */,
+ A6AF27E90B965F2E00EDBA70 /* fft_sse.c */,
+ A6AF27EA0B965F2E00EDBA70 /* idct_mmx.c */,
+ A6AF27EB0B965F2E00EDBA70 /* mmx.h */,
+ A6AF27EC0B965F2E00EDBA70 /* motion_est_mmx.c */,
+ A6AF27ED0B965F2E00EDBA70 /* mpegvideo_mmx.c */,
+ A6AF27EE0B965F2E00EDBA70 /* mpegvideo_mmx_template.c */,
+ A6AF27EF0B965F2E00EDBA70 /* simple_idct_mmx.c */,
+ );
+ path = i386;
+ sourceTree = "<group>";
+ };
+ A6AF27F90B965F2E00EDBA70 /* liba52 */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF27FA0B965F2E00EDBA70 /* a52.h */,
+ A6AF27FB0B965F2E00EDBA70 /* a52_internal.h */,
+ A6AF27FC0B965F2E00EDBA70 /* a52_util.h */,
+ A6AF27FD0B965F2E00EDBA70 /* bit_allocate.c */,
+ A6AF27FE0B965F2E00EDBA70 /* bitstream.c */,
+ A6AF27FF0B965F2E00EDBA70 /* bitstream.h */,
+ A6AF28000B965F2E00EDBA70 /* crc.c */,
+ A6AF28010B965F2E00EDBA70 /* downmix.c */,
+ A6AF28020B965F2E00EDBA70 /* imdct.c */,
+ A6AF28030B965F2E00EDBA70 /* mm_accel.h */,
+ A6AF28040B965F2E00EDBA70 /* parse.c */,
+ A6AF28050B965F2E00EDBA70 /* resample.c */,
+ A6AF28060B965F2E00EDBA70 /* resample_c.c */,
+ A6AF28070B965F2E00EDBA70 /* resample_mmx.c */,
+ A6AF28080B965F2E00EDBA70 /* tables.h */,
+ );
+ path = liba52;
+ sourceTree = "<group>";
+ };
+ A6AF28090B965F2E00EDBA70 /* libpostproc */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF280A0B965F2E00EDBA70 /* Makefile */,
+ A6AF280B0B965F2E00EDBA70 /* mangle.h */,
+ A6AF280C0B965F2E00EDBA70 /* postprocess.c */,
+ A6AF280D0B965F2E00EDBA70 /* postprocess.h */,
+ A6AF280E0B965F2E00EDBA70 /* postprocess_internal.h */,
+ A6AF280F0B965F2E00EDBA70 /* postprocess_template.c */,
+ );
+ path = libpostproc;
+ sourceTree = "<group>";
+ };
+ A6AF28430B965F2E00EDBA70 /* libavformat */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF28440B965F2E00EDBA70 /* 4xm.c */,
+ A6AF28450B965F2E00EDBA70 /* allformats.c */,
+ A6AF28460B965F2E00EDBA70 /* amr.c */,
+ A6AF28470B965F2E00EDBA70 /* asf.c */,
+ A6AF28480B965F2E00EDBA70 /* au.c */,
+ A6AF28490B965F2E00EDBA70 /* audio.c */,
+ A6AF284A0B965F2E00EDBA70 /* avformat.h */,
+ A6AF284B0B965F2E00EDBA70 /* avi.h */,
+ A6AF284C0B965F2E00EDBA70 /* avidec.c */,
+ A6AF284D0B965F2E00EDBA70 /* avienc.c */,
+ A6AF284E0B965F2E00EDBA70 /* avio.c */,
+ A6AF284F0B965F2E00EDBA70 /* avio.h */,
+ A6AF28500B965F2E00EDBA70 /* aviobuf.c */,
+ A6AF28510B965F2E00EDBA70 /* barpainet.c */,
+ A6AF28520B965F2E00EDBA70 /* barpainet.h */,
+ A6AF28530B965F2E00EDBA70 /* beosaudio.cpp */,
+ A6AF28540B965F2E00EDBA70 /* crc.c */,
+ A6AF28550B965F2E00EDBA70 /* cutils.c */,
+ A6AF28560B965F2E00EDBA70 /* dv.c */,
+ A6AF28570B965F2E00EDBA70 /* dv1394.c */,
+ A6AF28580B965F2E00EDBA70 /* dv1394.h */,
+ A6AF28590B965F2E00EDBA70 /* dvcore.c */,
+ A6AF285A0B965F2E00EDBA70 /* dvcore.h */,
+ A6AF285B0B965F2E00EDBA70 /* ffm.c */,
+ A6AF285C0B965F2E00EDBA70 /* file.c */,
+ A6AF285D0B965F2E00EDBA70 /* flvdec.c */,
+ A6AF285E0B965F2E00EDBA70 /* flvenc.c */,
+ A6AF285F0B965F2E00EDBA70 /* framehook.c */,
+ A6AF28600B965F2E00EDBA70 /* framehook.h */,
+ A6AF28610B965F2E00EDBA70 /* gif.c */,
+ A6AF28620B965F2E00EDBA70 /* gifdec.c */,
+ A6AF28630B965F2E00EDBA70 /* grab.c */,
+ A6AF28640B965F2E00EDBA70 /* http.c */,
+ A6AF28650B965F2E00EDBA70 /* idroq.c */,
+ A6AF28660B965F2E00EDBA70 /* img.c */,
+ A6AF28670B965F2E00EDBA70 /* ipmovie.c */,
+ A6AF28680B965F2E00EDBA70 /* jpeg.c */,
+ A6AF28690B965F2E00EDBA70 /* Makefile */,
+ A6AF286A0B965F2E00EDBA70 /* Makefile.am */,
+ A6AF286B0B965F2E00EDBA70 /* mov.c */,
+ A6AF286C0B965F2E00EDBA70 /* movenc.c */,
+ A6AF286D0B965F2E00EDBA70 /* mp3.c */,
+ A6AF286E0B965F2E00EDBA70 /* mpeg.c */,
+ A6AF286F0B965F2E00EDBA70 /* mpegts.c */,
+ A6AF28700B965F2E00EDBA70 /* mpegts.h */,
+ A6AF28710B965F2E00EDBA70 /* mpegtsenc.c */,
+ A6AF28720B965F2E00EDBA70 /* mpjpeg.c */,
+ A6AF28730B965F2E00EDBA70 /* nut.c */,
+ A6AF28740B965F2E00EDBA70 /* ogg.c */,
+ A6AF28750B965F2E00EDBA70 /* os_support.c */,
+ A6AF28760B965F2E00EDBA70 /* os_support.h */,
+ A6AF28770B965F2E00EDBA70 /* png.c */,
+ A6AF28780B965F2E00EDBA70 /* pnm.c */,
+ A6AF28790B965F2E00EDBA70 /* psxstr.c */,
+ A6AF287A0B965F2E00EDBA70 /* raw.c */,
+ A6AF287B0B965F2E00EDBA70 /* rm.c */,
+ A6AF287C0B965F2E00EDBA70 /* rtp.c */,
+ A6AF287D0B965F2E00EDBA70 /* rtp.h */,
+ A6AF287E0B965F2E00EDBA70 /* rtpproto.c */,
+ A6AF287F0B965F2E00EDBA70 /* rtsp.c */,
+ A6AF28800B965F2E00EDBA70 /* rtsp.h */,
+ A6AF28810B965F2E00EDBA70 /* rtspcodes.h */,
+ A6AF28820B965F2E00EDBA70 /* swf.c */,
+ A6AF28830B965F2E00EDBA70 /* tcp.c */,
+ A6AF28840B965F2E00EDBA70 /* udp.c */,
+ A6AF28850B965F2E00EDBA70 /* utils.c */,
+ A6AF28860B965F2E00EDBA70 /* wav.c */,
+ A6AF28870B965F2E00EDBA70 /* wc3movie.c */,
+ A6AF28880B965F2E00EDBA70 /* yuv.c */,
+ A6AF28890B965F2E00EDBA70 /* yuv4mpeg.c */,
+ );
+ path = libavformat;
+ sourceTree = "<group>";
+ };
+ A6AF28940B965F2E00EDBA70 /* mod_noise */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF28950B965F2E00EDBA70 /* .deps */,
+ A6AF289A0B965F2E00EDBA70 /* .libs */,
+ A6AF28A40B965F2E00EDBA70 /* distort.cpp */,
+ A6AF28A50B965F2E00EDBA70 /* distort.h */,
+ A6AF28A60B965F2E00EDBA70 /* libmod_noise.la */,
+ A6AF28A70B965F2E00EDBA70 /* libmod_noise_la-distort.lo */,
+ A6AF28A80B965F2E00EDBA70 /* libmod_noise_la-main.lo */,
+ A6AF28A90B965F2E00EDBA70 /* libmod_noise_la-noise.lo */,
+ A6AF28AA0B965F2E00EDBA70 /* libmod_noise_la-random.lo */,
+ A6AF28AB0B965F2E00EDBA70 /* main.cpp */,
+ A6AF28AC0B965F2E00EDBA70 /* Makefile */,
+ A6AF28AD0B965F2E00EDBA70 /* Makefile.am */,
+ A6AF28AE0B965F2E00EDBA70 /* Makefile.in */,
+ A6AF28AF0B965F2E00EDBA70 /* mod_noise.nsh */,
+ A6AF28B00B965F2E00EDBA70 /* noise.cpp */,
+ A6AF28B10B965F2E00EDBA70 /* noise.h */,
+ A6AF28B20B965F2E00EDBA70 /* random.cpp */,
+ A6AF28B30B965F2E00EDBA70 /* random.h */,
+ A6AF28B40B965F2E00EDBA70 /* unmod_noise.nsh */,
+ );
+ path = mod_noise;
+ sourceTree = "<group>";
+ };
+ A6AF28950B965F2E00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF28960B965F2E00EDBA70 /* libmod_noise_la-distort.Plo */,
+ A6AF28970B965F2E00EDBA70 /* libmod_noise_la-main.Plo */,
+ A6AF28980B965F2E00EDBA70 /* libmod_noise_la-noise.Plo */,
+ A6AF28990B965F2E00EDBA70 /* libmod_noise_la-random.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF289A0B965F2E00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF289B0B965F2E00EDBA70 /* libmod_noise.0.0.0.so */,
+ A6AF289C0B965F2E00EDBA70 /* libmod_noise.0.so */,
+ A6AF289D0B965F2E00EDBA70 /* libmod_noise.la */,
+ A6AF289E0B965F2E00EDBA70 /* libmod_noise.lai */,
+ A6AF289F0B965F2E00EDBA70 /* libmod_noise.so */,
+ A6AF28A00B965F2E00EDBA70 /* libmod_noise_la-distort.o */,
+ A6AF28A10B965F2E00EDBA70 /* libmod_noise_la-main.o */,
+ A6AF28A20B965F2E00EDBA70 /* libmod_noise_la-noise.o */,
+ A6AF28A30B965F2E00EDBA70 /* libmod_noise_la-random.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF28B50B965F2E00EDBA70 /* mod_openexr */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF28B60B965F2E00EDBA70 /* .deps */,
+ A6AF28BA0B965F2E00EDBA70 /* main.cpp */,
+ A6AF28BB0B965F2E00EDBA70 /* Makefile */,
+ A6AF28BC0B965F2E00EDBA70 /* Makefile.am */,
+ A6AF28BD0B965F2E00EDBA70 /* Makefile.in */,
+ A6AF28BE0B965F2E00EDBA70 /* mod_openexr.nsh */,
+ A6AF28BF0B965F2E00EDBA70 /* mptr_openexr.cpp */,
+ A6AF28C00B965F2E00EDBA70 /* mptr_openexr.h */,
+ A6AF28C10B965F2E00EDBA70 /* trgt_openexr.cpp */,
+ A6AF28C20B965F2E00EDBA70 /* trgt_openexr.h */,
+ A6AF28C30B965F2E00EDBA70 /* unmod_openexr.nsh */,
+ );
+ path = mod_openexr;
+ sourceTree = "<group>";
+ };
+ A6AF28B60B965F2E00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF28B70B965F2E00EDBA70 /* libmod_openexr_la-main.Plo */,
+ A6AF28B80B965F2E00EDBA70 /* libmod_openexr_la-mptr_openexr.Plo */,
+ A6AF28B90B965F2E00EDBA70 /* libmod_openexr_la-trgt_openexr.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF28C40B965F2E00EDBA70 /* mod_particle */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF28C50B965F2E00EDBA70 /* .deps */,
+ A6AF28C90B965F2E00EDBA70 /* .libs */,
+ A6AF28D20B965F2E00EDBA70 /* libmod_particle.la */,
+ A6AF28D30B965F2E00EDBA70 /* libmod_particle_la-main.lo */,
+ A6AF28D40B965F2E00EDBA70 /* libmod_particle_la-plant.lo */,
+ A6AF28D50B965F2E00EDBA70 /* libmod_particle_la-random.lo */,
+ A6AF28D60B965F2E00EDBA70 /* main.cpp */,
+ A6AF28D70B965F2E00EDBA70 /* Makefile */,
+ A6AF28D80B965F2E00EDBA70 /* Makefile.am */,
+ A6AF28D90B965F2E00EDBA70 /* Makefile.in */,
+ A6AF28DA0B965F2E00EDBA70 /* mod_particle.nsh */,
+ A6AF28DB0B965F2E00EDBA70 /* plant.cpp */,
+ A6AF28DC0B965F2E00EDBA70 /* plant.h */,
+ A6AF28DD0B965F2E00EDBA70 /* random.cpp */,
+ A6AF28DE0B965F2E00EDBA70 /* random.h */,
+ A6AF28DF0B965F2E00EDBA70 /* unmod_particle.nsh */,
+ );
+ path = mod_particle;
+ sourceTree = "<group>";
+ };
+ A6AF28C50B965F2E00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF28C60B965F2E00EDBA70 /* libmod_particle_la-main.Plo */,
+ A6AF28C70B965F2E00EDBA70 /* libmod_particle_la-plant.Plo */,
+ A6AF28C80B965F2E00EDBA70 /* libmod_particle_la-random.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF28C90B965F2E00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF28CA0B965F2E00EDBA70 /* libmod_particle.0.0.0.so */,
+ A6AF28CB0B965F2E00EDBA70 /* libmod_particle.0.so */,
+ A6AF28CC0B965F2E00EDBA70 /* libmod_particle.la */,
+ A6AF28CD0B965F2E00EDBA70 /* libmod_particle.lai */,
+ A6AF28CE0B965F2E00EDBA70 /* libmod_particle.so */,
+ A6AF28CF0B965F2E00EDBA70 /* libmod_particle_la-main.o */,
+ A6AF28D00B965F2E00EDBA70 /* libmod_particle_la-plant.o */,
+ A6AF28D10B965F2E00EDBA70 /* libmod_particle_la-random.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF28E00B965F2E00EDBA70 /* mod_png */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF28E10B965F2E00EDBA70 /* .deps */,
+ A6AF28E50B965F2E00EDBA70 /* .libs */,
+ A6AF28EE0B965F2E00EDBA70 /* libmod_png.la */,
+ A6AF28EF0B965F2E00EDBA70 /* libmod_png_la-main.lo */,
+ A6AF28F00B965F2E00EDBA70 /* libmod_png_la-mptr_png.lo */,
+ A6AF28F10B965F2E00EDBA70 /* libmod_png_la-trgt_png.lo */,
+ A6AF28F20B965F2E00EDBA70 /* main.cpp */,
+ A6AF28F30B965F2E00EDBA70 /* Makefile */,
+ A6AF28F40B965F2E00EDBA70 /* Makefile.am */,
+ A6AF28F50B965F2E00EDBA70 /* Makefile.in */,
+ A6AF28F60B965F2E00EDBA70 /* mod_png.nsh */,
+ A6AF28F70B965F2E00EDBA70 /* mptr_png.cpp */,
+ A6AF28F80B965F2E00EDBA70 /* mptr_png.h */,
+ A6AF28F90B965F2E00EDBA70 /* trgt_png.cpp */,
+ A6AF28FA0B965F2E00EDBA70 /* trgt_png.h */,
+ A6AF28FB0B965F2E00EDBA70 /* unmod_png.nsh */,
+ );
+ path = mod_png;
+ sourceTree = "<group>";
+ };
+ A6AF28E10B965F2E00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF28E20B965F2E00EDBA70 /* libmod_png_la-main.Plo */,
+ A6AF28E30B965F2E00EDBA70 /* libmod_png_la-mptr_png.Plo */,
+ A6AF28E40B965F2E00EDBA70 /* libmod_png_la-trgt_png.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF28E50B965F2E00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF28E60B965F2E00EDBA70 /* libmod_png.0.0.0.so */,
+ A6AF28E70B965F2E00EDBA70 /* libmod_png.0.so */,
+ A6AF28E80B965F2E00EDBA70 /* libmod_png.la */,
+ A6AF28E90B965F2E00EDBA70 /* libmod_png.lai */,
+ A6AF28EA0B965F2E00EDBA70 /* libmod_png.so */,
+ A6AF28EB0B965F2E00EDBA70 /* libmod_png_la-main.o */,
+ A6AF28EC0B965F2E00EDBA70 /* libmod_png_la-mptr_png.o */,
+ A6AF28ED0B965F2E00EDBA70 /* libmod_png_la-trgt_png.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF28FC0B965F2E00EDBA70 /* mod_ppm */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF28FD0B965F2E00EDBA70 /* .deps */,
+ A6AF29010B965F2E00EDBA70 /* .libs */,
+ A6AF290A0B965F2E00EDBA70 /* libmod_ppm.la */,
+ A6AF290B0B965F2E00EDBA70 /* libmod_ppm_la-main.lo */,
+ A6AF290C0B965F2E00EDBA70 /* libmod_ppm_la-mptr_ppm.lo */,
+ A6AF290D0B965F2E00EDBA70 /* libmod_ppm_la-trgt_ppm.lo */,
+ A6AF290E0B965F2E00EDBA70 /* main.cpp */,
+ A6AF290F0B965F2E00EDBA70 /* Makefile */,
+ A6AF29100B965F2E00EDBA70 /* Makefile.am */,
+ A6AF29110B965F2E00EDBA70 /* Makefile.in */,
+ A6AF29120B965F2E00EDBA70 /* mod_ppm.nsh */,
+ A6AF29130B965F2E00EDBA70 /* mptr_ppm.cpp */,
+ A6AF29140B965F2E00EDBA70 /* mptr_ppm.h */,
+ A6AF29150B965F2E00EDBA70 /* trgt_mpg.cpp */,
+ A6AF29160B965F2E00EDBA70 /* trgt_mpg.h */,
+ A6AF29170B965F2E00EDBA70 /* trgt_ppm.cpp */,
+ A6AF29180B965F2E00EDBA70 /* trgt_ppm.h */,
+ A6AF29190B965F2E00EDBA70 /* unmod_ppm.nsh */,
+ );
+ path = mod_ppm;
+ sourceTree = "<group>";
+ };
+ A6AF28FD0B965F2E00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF28FE0B965F2E00EDBA70 /* libmod_ppm_la-main.Plo */,
+ A6AF28FF0B965F2E00EDBA70 /* libmod_ppm_la-mptr_ppm.Plo */,
+ A6AF29000B965F2E00EDBA70 /* libmod_ppm_la-trgt_ppm.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF29010B965F2E00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF29020B965F2E00EDBA70 /* libmod_ppm.0.0.0.so */,
+ A6AF29030B965F2E00EDBA70 /* libmod_ppm.0.so */,
+ A6AF29040B965F2E00EDBA70 /* libmod_ppm.la */,
+ A6AF29050B965F2E00EDBA70 /* libmod_ppm.lai */,
+ A6AF29060B965F2E00EDBA70 /* libmod_ppm.so */,
+ A6AF29070B965F2E00EDBA70 /* libmod_ppm_la-main.o */,
+ A6AF29080B965F2E00EDBA70 /* libmod_ppm_la-mptr_ppm.o */,
+ A6AF29090B965F2E00EDBA70 /* libmod_ppm_la-trgt_ppm.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF291A0B965F2E00EDBA70 /* mod_yuv420p */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF291B0B965F2E00EDBA70 /* .deps */,
+ A6AF291E0B965F2E00EDBA70 /* .libs */,
+ A6AF29260B965F2E00EDBA70 /* libmod_yuv420p.la */,
+ A6AF29270B965F2E00EDBA70 /* libmod_yuv420p_la-main.lo */,
+ A6AF29280B965F2E00EDBA70 /* libmod_yuv420p_la-trgt_yuv.lo */,
+ A6AF29290B965F2E00EDBA70 /* main.cpp */,
+ A6AF292A0B965F2E00EDBA70 /* Makefile */,
+ A6AF292B0B965F2E00EDBA70 /* Makefile.am */,
+ A6AF292C0B965F2E00EDBA70 /* Makefile.in */,
+ A6AF292D0B965F2E00EDBA70 /* mod_yuv420p.nsh */,
+ A6AF292E0B965F2E00EDBA70 /* trgt_yuv.cpp */,
+ A6AF292F0B965F2E00EDBA70 /* trgt_yuv.h */,
+ A6AF29300B965F2E00EDBA70 /* unmod_yuv420p.nsh */,
+ );
+ path = mod_yuv420p;
+ sourceTree = "<group>";
+ };
+ A6AF291B0B965F2E00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF291C0B965F2E00EDBA70 /* libmod_yuv420p_la-main.Plo */,
+ A6AF291D0B965F2E00EDBA70 /* libmod_yuv420p_la-trgt_yuv.Plo */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF291E0B965F2E00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF291F0B965F2E00EDBA70 /* libmod_yuv420p.0.0.0.so */,
+ A6AF29200B965F2E00EDBA70 /* libmod_yuv420p.0.so */,
+ A6AF29210B965F2E00EDBA70 /* libmod_yuv420p.la */,
+ A6AF29220B965F2E00EDBA70 /* libmod_yuv420p.lai */,
+ A6AF29230B965F2E00EDBA70 /* libmod_yuv420p.so */,
+ A6AF29240B965F2E00EDBA70 /* libmod_yuv420p_la-main.o */,
+ A6AF29250B965F2E00EDBA70 /* libmod_yuv420p_la-trgt_yuv.o */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF29310B965F2E00EDBA70 /* mptr_mplayer */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF29320B965F2E00EDBA70 /* main.cpp */,
+ A6AF29330B965F2E00EDBA70 /* Makefile.am */,
+ A6AF29340B965F2E00EDBA70 /* mptr_mplayer.cpp */,
+ A6AF29350B965F2E00EDBA70 /* mptr_mplayer.h */,
+ );
+ path = mptr_mplayer;
+ sourceTree = "<group>";
+ };
+ A6AF293A0B965F2E00EDBA70 /* synfig */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF29CB0B965F2E00EDBA70 /* activepoint.h */,
+ A6AF29CC0B965F2E00EDBA70 /* angle.h */,
+ A6AF29CE0B965F2E00EDBA70 /* blinepoint.h */,
+ A6AF29D00B965F2E00EDBA70 /* blur.h */,
+ A6AF29D20B965F2E00EDBA70 /* canvas.h */,
+ A6AF29D30B965F2E00EDBA70 /* canvasbase.h */,
+ A6AF29D50B965F2E00EDBA70 /* color.h */,
+ A6AF29D70B965F2E00EDBA70 /* context.h */,
+ A6AF29D90B965F2E00EDBA70 /* curve_helper.h */,
+ A6AF29DB0B965F2E00EDBA70 /* curveset.h */,
+ A6AF29DD0B965F2E00EDBA70 /* distance.h */,
+ A6AF29DF0B965F2E00EDBA70 /* exception.h */,
+ A6AF29E10B965F2E00EDBA70 /* gamma.h */,
+ A6AF29E20B965F2E00EDBA70 /* general.h */,
+ A6AF29E40B965F2E00EDBA70 /* gradient.h */,
+ A6AF29E60B965F2E00EDBA70 /* guid.h */,
+ A6AF29E70B965F2E00EDBA70 /* guidset.h */,
+ A6AF29E90B965F2E00EDBA70 /* importer.h */,
+ A6AF29EA0B965F2E00EDBA70 /* interpolation.h */,
+ A6AF29EC0B965F2E00EDBA70 /* keyframe.h */,
+ A6AF29EE0B965F2E00EDBA70 /* layer.h */,
+ A6AF29F00B965F2E00EDBA70 /* layer_bitmap.h */,
+ A6AF29F20B965F2E00EDBA70 /* layer_composite.h */,
+ A6AF29F40B965F2E00EDBA70 /* layer_mime.h */,
+ A6AF29F60B965F2E00EDBA70 /* layer_motionblur.h */,
+ A6AF29F80B965F2E00EDBA70 /* layer_pastecanvas.h */,
+ A6AF29FA0B965F2E00EDBA70 /* layer_polygon.h */,
+ A6AF29FC0B965F2E00EDBA70 /* layer_shape.h */,
+ A6AF29FE0B965F2E00EDBA70 /* layer_solidcolor.h */,
+ A6AF2A450B965F2F00EDBA70 /* listimporter.h */,
+ A6AF2A470B965F2F00EDBA70 /* loadcanvas.h */,
+ A6AF2A490B965F2F00EDBA70 /* main.h */,
+ A6AF2A4E0B965F2F00EDBA70 /* module.h */,
+ A6AF2A500B965F2F00EDBA70 /* mutex.h */,
+ A6AF2A520B965F2F00EDBA70 /* node.h */,
+ A6AF2A540B965F2F00EDBA70 /* palette.h */,
+ A6AF2A560B965F2F00EDBA70 /* paramdesc.h */,
+ A6AF2A590B965F2F00EDBA70 /* polynomial_root.h */,
+ A6AF2A600B965F2F00EDBA70 /* protocol.h */,
+ A6AF2A610B965F2F00EDBA70 /* real.h */,
+ A6AF2A630B965F2F00EDBA70 /* rect.h */,
+ A6AF2A650B965F2F00EDBA70 /* renddesc.h */,
+ A6AF2A670B965F2F00EDBA70 /* render.h */,
+ A6AF2A690B965F2F00EDBA70 /* savecanvas.h */,
+ A6AF2A6A0B965F2F00EDBA70 /* segment.h */,
+ A6AF2A6B0B965F2F00EDBA70 /* smartfile.h */,
+ A6AF2A6C0B965F2F00EDBA70 /* string.h */,
+ A6AF2A6D0B965F2F00EDBA70 /* string_decl.h */,
+ A6AF2A6F0B965F2F00EDBA70 /* surface.h */,
+ A6AF2A720B965F2F00EDBA70 /* synfig.h */,
+ A6AF2A750B965F2F00EDBA70 /* target.h */,
+ A6AF2A770B965F2F00EDBA70 /* target_multi.h */,
+ A6AF2A790B965F2F00EDBA70 /* target_null.h */,
+ A6AF2A7B0B965F2F00EDBA70 /* target_null_tile.h */,
+ A6AF2A7D0B965F2F00EDBA70 /* target_scanline.h */,
+ A6AF2A7F0B965F2F00EDBA70 /* target_tile.h */,
+ A6AF2A810B965F2F00EDBA70 /* time.h */,
+ A6AF2A830B965F2F00EDBA70 /* timepointcollect.h */,
+ A6AF2A850B965F2F00EDBA70 /* transform.h */,
+ A6AF2A860B965F2F00EDBA70 /* types.h */,
+ A6AF2A880B965F2F00EDBA70 /* uniqueid.h */,
+ A6AF2A8A0B965F2F00EDBA70 /* value.h */,
+ A6AF2A8C0B965F2F00EDBA70 /* valuenode.h */,
+ A6AF2A8E0B965F2F00EDBA70 /* valuenode_animated.h */,
+ A6AF2A900B965F2F00EDBA70 /* valuenode_bline.h */,
+ A6AF2A920B965F2F00EDBA70 /* valuenode_composite.h */,
+ A6AF2A940B965F2F00EDBA70 /* valuenode_const.h */,
+ A6AF2A960B965F2F00EDBA70 /* valuenode_dynamiclist.h */,
+ A6AF2A980B965F2F00EDBA70 /* valuenode_gradientrotate.h */,
+ A6AF2A9A0B965F2F00EDBA70 /* valuenode_linear.h */,
+ A6AF2A9C0B965F2F00EDBA70 /* valuenode_radialcomposite.h */,
+ A6AF2A9E0B965F2F00EDBA70 /* valuenode_reference.h */,
+ A6AF2AA00B965F2F00EDBA70 /* valuenode_scale.h */,
+ A6AF2AA20B965F2F00EDBA70 /* valuenode_segcalctangent.h */,
+ A6AF2AA40B965F2F00EDBA70 /* valuenode_segcalcvertex.h */,
+ A6AF2AA60B965F2F00EDBA70 /* valuenode_sine.h */,
+ A6AF2AA80B965F2F00EDBA70 /* valuenode_stripes.h */,
+ A6AF2AAA0B965F2F00EDBA70 /* valuenode_subtract.h */,
+ A6AF2AAC0B965F2F00EDBA70 /* valuenode_timedswap.h */,
+ A6AF2AAE0B965F2F00EDBA70 /* valuenode_twotone.h */,
+ A6AF2AAF0B965F2F00EDBA70 /* vector.h */,
+ A6AF2AB00B965F2F00EDBA70 /* version.h */,
+ A6AF2AB20B965F2F00EDBA70 /* waypoint.h */,
+ A6AF29CA0B965F2E00EDBA70 /* activepoint.cpp */,
+ A6AF29CD0B965F2E00EDBA70 /* blinepoint.cpp */,
+ A6AF29CF0B965F2E00EDBA70 /* blur.cpp */,
+ A6AF29D10B965F2E00EDBA70 /* canvas.cpp */,
+ A6AF29D40B965F2E00EDBA70 /* color.cpp */,
+ A6AF29D60B965F2E00EDBA70 /* context.cpp */,
+ A6AF29D80B965F2E00EDBA70 /* curve_helper.cpp */,
+ A6AF29DA0B965F2E00EDBA70 /* curveset.cpp */,
+ A6AF29DC0B965F2E00EDBA70 /* distance.cpp */,
+ A6AF29DE0B965F2E00EDBA70 /* exception.cpp */,
+ A6AF29E00B965F2E00EDBA70 /* gamma.cpp */,
+ A6AF29E30B965F2E00EDBA70 /* gradient.cpp */,
+ A6AF29E50B965F2E00EDBA70 /* guid.cpp */,
+ A6AF29E80B965F2E00EDBA70 /* importer.cpp */,
+ A6AF29EB0B965F2E00EDBA70 /* keyframe.cpp */,
+ A6AF29ED0B965F2E00EDBA70 /* layer.cpp */,
+ A6AF29EF0B965F2E00EDBA70 /* layer_bitmap.cpp */,
+ A6AF29F10B965F2E00EDBA70 /* layer_composite.cpp */,
+ A6AF29F30B965F2E00EDBA70 /* layer_mime.cpp */,
+ A6AF29F50B965F2E00EDBA70 /* layer_motionblur.cpp */,
+ A6AF29F70B965F2E00EDBA70 /* layer_pastecanvas.cpp */,
+ A6AF29F90B965F2E00EDBA70 /* layer_polygon.cpp */,
+ A6AF29FB0B965F2E00EDBA70 /* layer_shape.cpp */,
+ A6AF29FD0B965F2E00EDBA70 /* layer_solidcolor.cpp */,
+ A6AF2A440B965F2F00EDBA70 /* listimporter.cpp */,
+ A6AF2A460B965F2F00EDBA70 /* loadcanvas.cpp */,
+ A6AF2A480B965F2F00EDBA70 /* main.cpp */,
+ A6AF2A4D0B965F2F00EDBA70 /* module.cpp */,
+ A6AF2A4F0B965F2F00EDBA70 /* mutex.cpp */,
+ A6AF2A510B965F2F00EDBA70 /* node.cpp */,
+ A6AF2A530B965F2F00EDBA70 /* palette.cpp */,
+ A6AF2A550B965F2F00EDBA70 /* paramdesc.cpp */,
+ A6AF2A570B965F2F00EDBA70 /* pch.h */,
+ A6AF2A580B965F2F00EDBA70 /* polynomial_root.cpp */,
+ A6AF2A5A0B965F2F00EDBA70 /* proto */,
+ A6AF2A620B965F2F00EDBA70 /* rect.cpp */,
+ A6AF2A640B965F2F00EDBA70 /* renddesc.cpp */,
+ A6AF2A660B965F2F00EDBA70 /* render.cpp */,
+ A6AF2A680B965F2F00EDBA70 /* savecanvas.cpp */,
+ A6AF2A6E0B965F2F00EDBA70 /* surface.cpp */,
+ A6AF2A700B965F2F00EDBA70 /* surfacenew.cpp */,
+ A6AF2A710B965F2F00EDBA70 /* surfacenew.h */,
+ A6AF2A730B965F2F00EDBA70 /* synfig.nsh */,
+ A6AF2A740B965F2F00EDBA70 /* target.cpp */,
+ A6AF2A760B965F2F00EDBA70 /* target_multi.cpp */,
+ A6AF2A780B965F2F00EDBA70 /* target_null.cpp */,
+ A6AF2A7A0B965F2F00EDBA70 /* target_null_tile.cpp */,
+ A6AF2A7C0B965F2F00EDBA70 /* target_scanline.cpp */,
+ A6AF2A7E0B965F2F00EDBA70 /* target_tile.cpp */,
+ A6AF2A800B965F2F00EDBA70 /* time.cpp */,
+ A6AF2A820B965F2F00EDBA70 /* timepointcollect.cpp */,
+ A6AF2A840B965F2F00EDBA70 /* transform.cpp */,
+ A6AF2A870B965F2F00EDBA70 /* uniqueid.cpp */,
+ A6AF2A890B965F2F00EDBA70 /* value.cpp */,
+ A6AF2A8B0B965F2F00EDBA70 /* valuenode.cpp */,
+ A6AF2A8D0B965F2F00EDBA70 /* valuenode_animated.cpp */,
+ A6AF2A8F0B965F2F00EDBA70 /* valuenode_bline.cpp */,
+ A6AF2A910B965F2F00EDBA70 /* valuenode_composite.cpp */,
+ A6AF2A930B965F2F00EDBA70 /* valuenode_const.cpp */,
+ A6AF2A950B965F2F00EDBA70 /* valuenode_dynamiclist.cpp */,
+ A6AF2A970B965F2F00EDBA70 /* valuenode_gradientrotate.cpp */,
+ A6AF2A990B965F2F00EDBA70 /* valuenode_linear.cpp */,
+ A6AF2A9B0B965F2F00EDBA70 /* valuenode_radialcomposite.cpp */,
+ A6AF2A9D0B965F2F00EDBA70 /* valuenode_reference.cpp */,
+ A6AF2A9F0B965F2F00EDBA70 /* valuenode_scale.cpp */,
+ A6AF2AA10B965F2F00EDBA70 /* valuenode_segcalctangent.cpp */,
+ A6AF2AA30B965F2F00EDBA70 /* valuenode_segcalcvertex.cpp */,
+ A6AF2AA50B965F2F00EDBA70 /* valuenode_sine.cpp */,
+ A6AF2AA70B965F2F00EDBA70 /* valuenode_stripes.cpp */,
+ A6AF2AA90B965F2F00EDBA70 /* valuenode_subtract.cpp */,
+ A6AF2AAB0B965F2F00EDBA70 /* valuenode_timedswap.cpp */,
+ A6AF2AAD0B965F2F00EDBA70 /* valuenode_twotone.cpp */,
+ A6AF2AB10B965F2F00EDBA70 /* waypoint.cpp */,
+ );
+ path = synfig;
+ sourceTree = "<group>";
+ };
+ A6AF2A5A0B965F2F00EDBA70 /* proto */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF2A5D0B965F2F00EDBA70 /* nodebase.h */,
+ A6AF2A5E0B965F2F00EDBA70 /* nodebase.px */,
+ A6AF2A5F0B965F2F00EDBA70 /* proto.m4 */,
+ );
+ path = proto;
+ sourceTree = "<group>";
+ };
+ A6AF2AB50B965F2F00EDBA70 /* tool */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF2AB60B965F2F00EDBA70 /* .deps */,
+ A6AF2AB80B965F2F00EDBA70 /* .libs */,
+ A6AF2ABA0B965F2F00EDBA70 /* main.cpp */,
+ A6AF2ABB0B965F2F00EDBA70 /* Makefile */,
+ A6AF2ABC0B965F2F00EDBA70 /* Makefile.am */,
+ A6AF2ABD0B965F2F00EDBA70 /* Makefile.in */,
+ A6AF2ABE0B965F2F00EDBA70 /* synfig */,
+ A6AF2ABF0B965F2F00EDBA70 /* synfig-main.o */,
+ A6AF2AC00B965F2F00EDBA70 /* tool.nsh */,
+ );
+ path = tool;
+ sourceTree = "<group>";
+ };
+ A6AF2AB60B965F2F00EDBA70 /* .deps */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF2AB70B965F2F00EDBA70 /* synfig-main.Po */,
+ );
+ path = .deps;
+ sourceTree = "<group>";
+ };
+ A6AF2AB80B965F2F00EDBA70 /* .libs */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF2AB90B965F2F00EDBA70 /* synfig */,
+ );
+ path = .libs;
+ sourceTree = "<group>";
+ };
+ A6AF2F4D0B965FC900EDBA70 /* Frameworks and Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ A6AF2F4E0B965FEF00EDBA70 /* libxml++.framework */,
+ A6AF2F4F0B965FEF00EDBA70 /* sigc++.framework */,
+ );
+ name = "Frameworks and Libraries";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ A6AF30F10B96707300EDBA70 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A6AF30FE0B96709600EDBA70 /* activepoint.h in Headers */,
+ A6AF30FF0B96709600EDBA70 /* angle.h in Headers */,
+ A6AF31000B96709600EDBA70 /* blinepoint.h in Headers */,
+ A6AF31010B96709600EDBA70 /* blur.h in Headers */,
+ A6AF31020B96709600EDBA70 /* canvas.h in Headers */,
+ A6AF31030B96709600EDBA70 /* canvasbase.h in Headers */,
+ A6AF31040B96709600EDBA70 /* color.h in Headers */,
+ A6AF31050B96709600EDBA70 /* context.h in Headers */,
+ A6AF31060B96709600EDBA70 /* curve_helper.h in Headers */,
+ A6AF31070B96709600EDBA70 /* curveset.h in Headers */,
+ A6AF31080B96709600EDBA70 /* distance.h in Headers */,
+ A6AF31090B96709600EDBA70 /* exception.h in Headers */,
+ A6AF310A0B96709600EDBA70 /* gamma.h in Headers */,
+ A6AF310B0B96709600EDBA70 /* general.h in Headers */,
+ A6AF310C0B96709600EDBA70 /* gradient.h in Headers */,
+ A6AF310D0B96709600EDBA70 /* guid.h in Headers */,
+ A6AF310E0B96709600EDBA70 /* guidset.h in Headers */,
+ A6AF310F0B96709600EDBA70 /* importer.h in Headers */,
+ A6AF31100B96709600EDBA70 /* interpolation.h in Headers */,
+ A6AF31110B96709600EDBA70 /* keyframe.h in Headers */,
+ A6AF31120B96709600EDBA70 /* layer.h in Headers */,
+ A6AF31130B96709600EDBA70 /* layer_bitmap.h in Headers */,
+ A6AF31140B96709600EDBA70 /* layer_composite.h in Headers */,
+ A6AF31150B96709600EDBA70 /* layer_mime.h in Headers */,
+ A6AF31160B96709600EDBA70 /* layer_motionblur.h in Headers */,
+ A6AF31170B96709600EDBA70 /* layer_pastecanvas.h in Headers */,
+ A6AF31180B96709600EDBA70 /* layer_polygon.h in Headers */,
+ A6AF31190B96709600EDBA70 /* layer_shape.h in Headers */,
+ A6AF311A0B96709600EDBA70 /* layer_solidcolor.h in Headers */,
+ A6AF311B0B96709600EDBA70 /* listimporter.h in Headers */,
+ A6AF311C0B96709600EDBA70 /* loadcanvas.h in Headers */,
+ A6AF311D0B96709600EDBA70 /* main.h in Headers */,
+ A6AF311E0B96709600EDBA70 /* module.h in Headers */,
+ A6AF311F0B96709600EDBA70 /* mutex.h in Headers */,
+ A6AF31200B96709600EDBA70 /* node.h in Headers */,
+ A6AF31210B96709600EDBA70 /* palette.h in Headers */,
+ A6AF31220B96709600EDBA70 /* paramdesc.h in Headers */,
+ A6AF31230B96709600EDBA70 /* polynomial_root.h in Headers */,
+ A6AF31240B96709600EDBA70 /* protocol.h in Headers */,
+ A6AF31250B96709600EDBA70 /* real.h in Headers */,
+ A6AF31260B96709600EDBA70 /* rect.h in Headers */,
+ A6AF31270B96709600EDBA70 /* renddesc.h in Headers */,
+ A6AF31280B96709600EDBA70 /* render.h in Headers */,
+ A6AF31290B96709600EDBA70 /* savecanvas.h in Headers */,
+ A6AF312A0B96709600EDBA70 /* segment.h in Headers */,
+ A6AF312B0B96709600EDBA70 /* smartfile.h in Headers */,
+ A6AF312C0B96709600EDBA70 /* string.h in Headers */,
+ A6AF312D0B96709600EDBA70 /* string_decl.h in Headers */,
+ A6AF312E0B96709600EDBA70 /* surface.h in Headers */,
+ A6AF312F0B96709600EDBA70 /* synfig.h in Headers */,
+ A6AF31300B96709600EDBA70 /* target.h in Headers */,
+ A6AF31310B96709600EDBA70 /* target_multi.h in Headers */,
+ A6AF31320B96709600EDBA70 /* target_null.h in Headers */,
+ A6AF31330B96709600EDBA70 /* target_null_tile.h in Headers */,
+ A6AF31340B96709600EDBA70 /* target_scanline.h in Headers */,
+ A6AF31350B96709600EDBA70 /* target_tile.h in Headers */,
+ A6AF31360B96709600EDBA70 /* time.h in Headers */,
+ A6AF31370B96709600EDBA70 /* timepointcollect.h in Headers */,
+ A6AF31380B96709600EDBA70 /* transform.h in Headers */,
+ A6AF31390B96709600EDBA70 /* types.h in Headers */,
+ A6AF313A0B96709600EDBA70 /* uniqueid.h in Headers */,
+ A6AF313B0B96709600EDBA70 /* value.h in Headers */,
+ A6AF313C0B96709600EDBA70 /* valuenode.h in Headers */,
+ A6AF313D0B96709600EDBA70 /* valuenode_animated.h in Headers */,
+ A6AF313E0B96709600EDBA70 /* valuenode_bline.h in Headers */,
+ A6AF313F0B96709600EDBA70 /* valuenode_composite.h in Headers */,
+ A6AF31400B96709600EDBA70 /* valuenode_const.h in Headers */,
+ A6AF31410B96709600EDBA70 /* valuenode_dynamiclist.h in Headers */,
+ A6AF31420B96709600EDBA70 /* valuenode_gradientrotate.h in Headers */,
+ A6AF31430B96709600EDBA70 /* valuenode_linear.h in Headers */,
+ A6AF31440B96709600EDBA70 /* valuenode_radialcomposite.h in Headers */,
+ A6AF31450B96709600EDBA70 /* valuenode_reference.h in Headers */,
+ A6AF31460B96709600EDBA70 /* valuenode_scale.h in Headers */,
+ A6AF31470B96709600EDBA70 /* valuenode_segcalctangent.h in Headers */,
+ A6AF31480B96709600EDBA70 /* valuenode_segcalcvertex.h in Headers */,
+ A6AF31490B96709600EDBA70 /* valuenode_sine.h in Headers */,
+ A6AF314A0B96709600EDBA70 /* valuenode_stripes.h in Headers */,
+ A6AF314B0B96709600EDBA70 /* valuenode_subtract.h in Headers */,
+ A6AF314C0B96709600EDBA70 /* valuenode_timedswap.h in Headers */,
+ A6AF314D0B96709600EDBA70 /* valuenode_twotone.h in Headers */,
+ A6AF314E0B96709600EDBA70 /* vector.h in Headers */,
+ A6AF314F0B96709600EDBA70 /* version.h in Headers */,
+ A6AF31500B96709600EDBA70 /* waypoint.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ A6AF20DA0B965ED900EDBA70 /* Synfig Framework */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A6AF20DE0B965ED900EDBA70 /* Build configuration list for PBXNativeTarget "Synfig Framework" */;
+ buildPhases = (
+ A6AF30F10B96707300EDBA70 /* Headers */,
+ A6AF20D80B965ED900EDBA70 /* Sources */,
+ A6AF20D90B965ED900EDBA70 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "Synfig Framework";
+ productName = synfig;
+ productReference = A6AF20DB0B965ED900EDBA70 /* synfig.framework */;
+ productType = "com.apple.product-type.framework";
+ };
+ A6AF30E20B966F6D00EDBA70 /* Synfig Tool */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A6AF30EC0B966FD100EDBA70 /* Build configuration list for PBXNativeTarget "Synfig Tool" */;
+ buildPhases = (
+ A6AF30E00B966F6D00EDBA70 /* Sources */,
+ A6AF30E10B966F6D00EDBA70 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ A6AF30EA0B966FB200EDBA70 /* PBXTargetDependency */,
+ );
+ name = "Synfig Tool";
+ productName = "Synfig Tool";
+ productReference = A6AF30E30B966F6D00EDBA70 /* synfig */;
+ productType = "com.apple.product-type.tool";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ A6AF11980B965E2E00EDBA70 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = A6AF11990B965E2E00EDBA70 /* Build configuration list for PBXProject "synfig-core" */;
+ hasScannedForEncodings = 0;
+ mainGroup = A6AF11960B965E2E00EDBA70;
+ productRefGroup = A6AF20DC0B965ED900EDBA70 /* Products */;
+ projectDirPath = "";
+ targets = (
+ A6AF20DA0B965ED900EDBA70 /* Synfig Framework */,
+ A6AF30E20B966F6D00EDBA70 /* Synfig Tool */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ A6AF20D80B965ED900EDBA70 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A6AF2E570B965F2F00EDBA70 /* activepoint.cpp in Sources */,
+ A6AF2E5A0B965F2F00EDBA70 /* blinepoint.cpp in Sources */,
+ A6AF2E5C0B965F2F00EDBA70 /* blur.cpp in Sources */,
+ A6AF2E5E0B965F2F00EDBA70 /* canvas.cpp in Sources */,
+ A6AF2E610B965F2F00EDBA70 /* color.cpp in Sources */,
+ A6AF2E630B965F2F00EDBA70 /* context.cpp in Sources */,
+ A6AF2E650B965F2F00EDBA70 /* curve_helper.cpp in Sources */,
+ A6AF2E670B965F2F00EDBA70 /* curveset.cpp in Sources */,
+ A6AF2E690B965F2F00EDBA70 /* distance.cpp in Sources */,
+ A6AF2E6B0B965F2F00EDBA70 /* exception.cpp in Sources */,
+ A6AF2E6D0B965F2F00EDBA70 /* gamma.cpp in Sources */,
+ A6AF2E700B965F2F00EDBA70 /* gradient.cpp in Sources */,
+ A6AF2E720B965F2F00EDBA70 /* guid.cpp in Sources */,
+ A6AF2E750B965F2F00EDBA70 /* importer.cpp in Sources */,
+ A6AF2E780B965F2F00EDBA70 /* keyframe.cpp in Sources */,
+ A6AF2E7A0B965F2F00EDBA70 /* layer.cpp in Sources */,
+ A6AF2E7C0B965F2F00EDBA70 /* layer_bitmap.cpp in Sources */,
+ A6AF2E7E0B965F2F00EDBA70 /* layer_composite.cpp in Sources */,
+ A6AF2E800B965F2F00EDBA70 /* layer_mime.cpp in Sources */,
+ A6AF2E820B965F2F00EDBA70 /* layer_motionblur.cpp in Sources */,
+ A6AF2E840B965F2F00EDBA70 /* layer_pastecanvas.cpp in Sources */,
+ A6AF2E860B965F2F00EDBA70 /* layer_polygon.cpp in Sources */,
+ A6AF2E880B965F2F00EDBA70 /* layer_shape.cpp in Sources */,
+ A6AF2E8A0B965F2F00EDBA70 /* layer_solidcolor.cpp in Sources */,
+ A6AF2ED10B965F2F00EDBA70 /* listimporter.cpp in Sources */,
+ A6AF2ED30B965F2F00EDBA70 /* loadcanvas.cpp in Sources */,
+ A6AF2ED50B965F2F00EDBA70 /* main.cpp in Sources */,
+ A6AF2EDA0B965F2F00EDBA70 /* module.cpp in Sources */,
+ A6AF2EDC0B965F2F00EDBA70 /* mutex.cpp in Sources */,
+ A6AF2EDE0B965F2F00EDBA70 /* node.cpp in Sources */,
+ A6AF2EE00B965F2F00EDBA70 /* palette.cpp in Sources */,
+ A6AF2EE20B965F2F00EDBA70 /* paramdesc.cpp in Sources */,
+ A6AF2EE50B965F2F00EDBA70 /* polynomial_root.cpp in Sources */,
+ A6AF2EEE0B965F2F00EDBA70 /* rect.cpp in Sources */,
+ A6AF2EF00B965F2F00EDBA70 /* renddesc.cpp in Sources */,
+ A6AF2EF20B965F2F00EDBA70 /* render.cpp in Sources */,
+ A6AF2EF40B965F2F00EDBA70 /* savecanvas.cpp in Sources */,
+ A6AF2EFA0B965F2F00EDBA70 /* surface.cpp in Sources */,
+ A6AF2F000B965F2F00EDBA70 /* target.cpp in Sources */,
+ A6AF2F020B965F2F00EDBA70 /* target_multi.cpp in Sources */,
+ A6AF2F040B965F2F00EDBA70 /* target_null.cpp in Sources */,
+ A6AF2F060B965F2F00EDBA70 /* target_null_tile.cpp in Sources */,
+ A6AF2F080B965F2F00EDBA70 /* target_scanline.cpp in Sources */,
+ A6AF2F0A0B965F2F00EDBA70 /* target_tile.cpp in Sources */,
+ A6AF2F0C0B965F2F00EDBA70 /* time.cpp in Sources */,
+ A6AF2F0E0B965F2F00EDBA70 /* timepointcollect.cpp in Sources */,
+ A6AF2F100B965F2F00EDBA70 /* transform.cpp in Sources */,
+ A6AF2F130B965F2F00EDBA70 /* uniqueid.cpp in Sources */,
+ A6AF2F150B965F2F00EDBA70 /* value.cpp in Sources */,
+ A6AF2F170B965F2F00EDBA70 /* valuenode.cpp in Sources */,
+ A6AF2F190B965F2F00EDBA70 /* valuenode_animated.cpp in Sources */,
+ A6AF2F1B0B965F2F00EDBA70 /* valuenode_bline.cpp in Sources */,
+ A6AF2F1D0B965F2F00EDBA70 /* valuenode_composite.cpp in Sources */,
+ A6AF2F1F0B965F2F00EDBA70 /* valuenode_const.cpp in Sources */,
+ A6AF2F210B965F2F00EDBA70 /* valuenode_dynamiclist.cpp in Sources */,
+ A6AF2F230B965F2F00EDBA70 /* valuenode_gradientrotate.cpp in Sources */,
+ A6AF2F250B965F2F00EDBA70 /* valuenode_linear.cpp in Sources */,
+ A6AF2F270B965F2F00EDBA70 /* valuenode_radialcomposite.cpp in Sources */,
+ A6AF2F290B965F2F00EDBA70 /* valuenode_reference.cpp in Sources */,
+ A6AF2F2B0B965F2F00EDBA70 /* valuenode_scale.cpp in Sources */,
+ A6AF2F2D0B965F2F00EDBA70 /* valuenode_segcalctangent.cpp in Sources */,
+ A6AF2F2F0B965F2F00EDBA70 /* valuenode_segcalcvertex.cpp in Sources */,
+ A6AF2F310B965F2F00EDBA70 /* valuenode_sine.cpp in Sources */,
+ A6AF2F330B965F2F00EDBA70 /* valuenode_stripes.cpp in Sources */,
+ A6AF2F350B965F2F00EDBA70 /* valuenode_subtract.cpp in Sources */,
+ A6AF2F370B965F2F00EDBA70 /* valuenode_timedswap.cpp in Sources */,
+ A6AF2F390B965F2F00EDBA70 /* valuenode_twotone.cpp in Sources */,
+ A6AF2F3D0B965F2F00EDBA70 /* waypoint.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A6AF30E00B966F6D00EDBA70 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A6AF30E50B966F9300EDBA70 /* main.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ A6AF30EA0B966FB200EDBA70 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A6AF20DA0B965ED900EDBA70 /* Synfig Framework */;
+ targetProxy = A6AF30E90B966FB200EDBA70 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ A6AF119A0B965E2E00EDBA70 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = NO;
+ GCC_PREPROCESSOR_DEFINITIONS = HAVE_CONFIG_H;
+ HEADER_SEARCH_PATHS = (
+ $SRCROOT/src,
+ "$SRCROOT/synfig-core.xcodeproj",
+ );
+ OTHER_CPLUSPLUSFLAGS = (
+ "$(OTHER_CFLAGS)",
+ "-fpermissive",
+ );
+ USER_HEADER_SEARCH_PATHS = "";
+ };
+ name = Debug;
+ };
+ A6AF119B0B965E2E00EDBA70 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = YES;
+ GCC_PREPROCESSOR_DEFINITIONS = HAVE_CONFIG_H;
+ HEADER_SEARCH_PATHS = (
+ $SRCROOT/src,
+ "$SRCROOT/synfig-core.xcodeproj",
+ );
+ OTHER_CPLUSPLUSFLAGS = (
+ "$(OTHER_CFLAGS)",
+ "-fpermissive",
+ );
+ USER_HEADER_SEARCH_PATHS = "";
+ };
+ name = Release;
+ };
+ A6AF20DF0B965ED900EDBA70 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+ );
+ FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../Library/Frameworks\"";
+ FRAMEWORK_VERSION = A;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "";
+ INFOPLIST_FILE = "synfig-Info.plist";
+ INSTALL_PATH = "$(HOME)/Library/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
+ );
+ LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/src/synfig/.libs\"";
+ OTHER_LDFLAGS = "";
+ PREBINDING = NO;
+ PRODUCT_NAME = synfig;
+ ZERO_LINK = YES;
+ };
+ name = Debug;
+ };
+ A6AF20E00B965ED900EDBA70 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = (
+ i386,
+ ppc,
+ );
+ COPY_PHASE_STRIP = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+ );
+ FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../Library/Frameworks\"";
+ FRAMEWORK_VERSION = A;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "";
+ INFOPLIST_FILE = "synfig-Info.plist";
+ INSTALL_PATH = "$(HOME)/Library/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
+ );
+ LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/src/synfig/.libs\"";
+ OTHER_LDFLAGS = "";
+ PREBINDING = NO;
+ PRODUCT_NAME = synfig;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ A6AF30ED0B966FD100EDBA70 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+ );
+ FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../Library/Frameworks\"";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = "$(HOME)/bin";
+ PREBINDING = NO;
+ PRODUCT_NAME = synfig;
+ ZERO_LINK = YES;
+ };
+ name = Debug;
+ };
+ A6AF30EE0B966FD100EDBA70 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+ );
+ FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../Library/Frameworks\"";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ INSTALL_PATH = "$(HOME)/bin";
+ PREBINDING = NO;
+ PRODUCT_NAME = synfig;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ A6AF11990B965E2E00EDBA70 /* Build configuration list for PBXProject "synfig-core" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A6AF119A0B965E2E00EDBA70 /* Debug */,
+ A6AF119B0B965E2E00EDBA70 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A6AF20DE0B965ED900EDBA70 /* Build configuration list for PBXNativeTarget "Synfig Framework" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A6AF20DF0B965ED900EDBA70 /* Debug */,
+ A6AF20E00B965ED900EDBA70 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A6AF30EC0B966FD100EDBA70 /* Build configuration list for PBXNativeTarget "Synfig Tool" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A6AF30ED0B966FD100EDBA70 /* Debug */,
+ A6AF30EE0B966FD100EDBA70 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = A6AF11980B965E2E00EDBA70 /* Project object */;
+}
--- /dev/null
+[./ChangeLog]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./ETL.spec]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./ETL.kdevprj]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./INSTALL]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./Makefile.am]
+files=./aclocal.m4,./config.status,./README,./configure,./config.log,./ETL.spec,./INSTALL,./ChangeLog,./ETL.kdevprj,./bootstrap,
+sub_dirs=test,config,ETL.pbproj,include,
+type=normal
+
+[./README]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./aclocal.m4]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./bootstrap]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./config.log]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./config.status]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./configure]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[ChangeLog]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[Config for BinMakefileAm]
+addcxxflags=
+bin_program=synfig
+cflags=
+cppflags=
+cxxflags=\s-O1
+ldadd=
+ldflags=\s\s
+libtool_dir=./libtool/
+path_to_bin_program=./src/tool
+
+[ETL.pbproj/Makefile.am]
+files=
+sub_dirs=
+type=normal
+
+[General]
+AMChanged=false
+author=darco
+configure_args=\s--build=i386-linux --host=i386-linux --target=i386-linux\s
+debug_args=-v -v -v --version
+dir_where_make_will_be_called=./
+email=darco@voria.net
+execute_args=-v -v -v --version
+kdevprj_version=1.3
+lfv_open_groups=
+make_options=\s-j2 -l 2 -j 2
+makefiles=./Makefile.am,include/Makefile.am,ETL.pbproj/Makefile.am,config/Makefile.am,config/pkg-support/Makefile.am,config/pkg-support/devel-resources/Makefile.am,test/Makefile.am,src/modules/trgt_bmp/Makefile.am,src/modules/Makefile.am,src/Makefile.am,src/modules/trgt_gif/Makefile.am,src/modules/lyr_std/Makefile.am,src/modules/example/Makefile.am,src/synfig/Makefile.am,src/tool/Makefile.am,Makefile.am,src/modules/trgt_ppm/Makefile.am,src/modules/trgt_mpg/Makefile.am,src/modules/mod_ffmpeg/Makefile.am,src/modules/mptr_mplayer/Makefile.am,src/modules/trgt_dv/Makefile.am,src/modules/mod_imagemagick/Makefile.am
+modifyMakefiles=true
+project_name=Synfig
+project_type=normal_empty
+short_info=
+sub_dir=
+version=
+version_control=CVS
+workspace=1
+
+[INSTALL]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[LFV Groups]
+GNU=AUTHORS,COPYING,ChangeLog,INSTALL,README,TODO,NEWS,
+Headers=*.h,*.hxx,*.hpp,*.H,
+Others=*,
+Sources=*.cpp,*.c,*.cc,*.C,*.cxx,*.ec,*.ecpp,*.lxx,*.l++,*.ll,*.l,
+Translations=*.ts,*.po,
+User Interface=*.ui,*.kdevdlg,*.rc,
+groups=Headers,Sources,GNU,Translations,User Interface,Others
+
+[Makefile.am]
+dist=true
+files=bootstrap,ChangeLog,INSTALL,Makefile.am,README,synfig.kdevprj,synfig-config.in
+install=false
+install_location=
+sub_dirs=src,config
+type=DATA
+
+[README]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[bootstrap]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/ETL.m4]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/Makefile.am]
+files=config/depcomp,config/configure.ac,config/config.guess,config/install-sh,config/config.sub,config/missing,config/cxx_macros.m4,config/project.spec.in,config/mkinstalldirs,config/sdl.m4,config/build.cfg,config/libxml.m4,config/ETL.m4,config/synfig.m4
+sub_dirs=pkg-support,
+type=normal
+
+[config/build.cfg]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/config.guess]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/config.sub]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/configure.ac]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/cxx_macros.m4]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/depcomp]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/install-sh]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/libxml.m4]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/missing]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/mkinstalldirs]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/pkg-support/ETL-devel.info]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/pkg-support/Makefile.am]
+files=config/pkg-support/ETL-devel.info,
+sub_dirs=devel-resources,
+type=normal
+
+[config/pkg-support/devel-resources/Makefile.am]
+files=config/pkg-support/devel-resources/ReadMe.txt,config/pkg-support/devel-resources/install.sh,config/pkg-support/devel-resources/Welcome.txt,
+sub_dirs=
+type=normal
+
+[config/pkg-support/devel-resources/ReadMe.txt]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/pkg-support/devel-resources/Welcome.txt]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/pkg-support/devel-resources/install.sh]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/project.spec.in]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/sdl.m4]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/synfig.m4]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[include/Makefile.am]
+files=include/ipc,include/_bit_rotate.h,include/_fastangle_tables.h,include/_clock_system.h,include/angle,include/clock,include/fixed,include/_rwlock.h,include/_thread.h,include/etl_profile.h.in~,include/etl_profile.h.in,include/_curve.h,include/_trivial.h,include/etl_profile.h,include/surface,include/_mutex_win32.h,include/_clock_gettimeofday.h,include/handle,include/_clock_base.h,include/_smach.h,include/_fixed.h,include/_condition.h,include/random,include/thread,include/stamp-h.in,include/stamp-h1,include/_surface.h,include/_fastangle.h,include/_mutex_pthreads.h,include/_handle.h,include/_random.h,include/_angle.h,include/etl_config.h,
+sub_dirs=
+type=normal
+
+[include/_angle.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_bit_rotate.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_clock_base.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_clock_gettimeofday.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_clock_system.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_condition.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_curve.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_fastangle.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_fastangle_tables.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_fixed.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_handle.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_mutex_pthreads.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_mutex_win32.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_random.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_rwlock.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_smach.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_surface.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_thread.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/_trivial.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/angle]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[include/clock]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[include/etl_config.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/etl_profile.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[include/etl_profile.h.in]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[include/etl_profile.h.in~]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[include/fixed]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[include/handle]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[include/ipc]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[include/random]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[include/stamp-h.in]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[include/stamp-h1]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[include/surface]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[include/thread]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[synfig-config.in]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[synfig.kdevprj]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[src/Makefile.am]
+dist=true
+files=src/Makefile.am,src/template.cpp,src/template.h
+install=false
+install_location=
+sub_dirs=modules,synfig,tool
+type=static_library
+
+[src/modules/Makefile.am]
+dist=true
+files=src/modules/Makefile.am
+install=false
+install_location=
+sub_dirs=trgt_bmp,trgt_gif,lyr_std,example,trgt_ppm,trgt_mpg,mod_ffmpeg,mptr_mplayer,trgt_dv,mod_imagemagick
+type=DATA
+
+[src/modules/example/Makefile.am]
+dist=true
+files=src/modules/example/main.cpp,src/modules/example/Makefile.am
+install=false
+install_location=
+sharedlib_LDFLAGS=-version-info 0:0:1
+sharedlib_rootname=example
+sub_dirs=
+type=DATA
+
+[src/modules/example/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/lyr_std/Makefile.am]
+dist=true
+files=src/modules/lyr_std/checkerboard.cpp,src/modules/lyr_std/checkerboard.h,src/modules/lyr_std/main.cpp,src/modules/lyr_std/Makefile.am,src/modules/lyr_std/mandelbrot.cpp,src/modules/lyr_std/mandelbrot.h,src/modules/lyr_std/solidcolor.cpp,src/modules/lyr_std/solidcolor.h,src/modules/lyr_std/zoom.cpp,src/modules/lyr_std/zoom.h,src/modules/lyr_std/circle.h,src/modules/lyr_std/circle.cpp,src/modules/lyr_std/blur.cpp,src/modules/lyr_std/blur.h,src/modules/lyr_std/import.cpp,src/modules/lyr_std/import.h,src/modules/lyr_std/polygon.cpp,src/modules/lyr_std/polygon.h
+install=false
+install_location=
+sharedlib_LDFLAGS=-version-info 0:0:1
+sharedlib_rootname=lyr_std
+sub_dirs=
+type=static_library
+
+[src/modules/lyr_std/blur.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/lyr_std/blur.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/lyr_std/checkerboard.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/lyr_std/checkerboard.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/lyr_std/circle.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/lyr_std/circle.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/lyr_std/import.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/lyr_std/import.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/lyr_std/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/lyr_std/mandelbrot.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/lyr_std/mandelbrot.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/lyr_std/polygon.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/lyr_std/polygon.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/lyr_std/solidcolor.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/lyr_std/solidcolor.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/lyr_std/zoom.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/lyr_std/zoom.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/mod_ffmpeg/Makefile.am]
+files=src/modules/mod_ffmpeg/main.cpp,src/modules/mod_ffmpeg/mptr_ffmpeg.cpp,src/modules/mod_ffmpeg/mptr_ffmpeg.h,src/modules/mod_ffmpeg/trgt_ffmpeg.cpp,src/modules/mod_ffmpeg/trgt_ffmpeg.h
+sharedlib_LDFLAGS=-version-info 0:0:0
+sharedlib_rootname=mod_ffmpeg
+sub_dirs=
+type=static_library
+
+[src/modules/mod_ffmpeg/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/mod_ffmpeg/mptr_ffmpeg.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/mod_ffmpeg/mptr_ffmpeg.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/mod_ffmpeg/trgt_ffmpeg.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/mod_ffmpeg/trgt_ffmpeg.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/mod_imagemagick/Makefile.am]
+dist=true
+files=src/modules/mod_imagemagick/main.cpp,src/modules/mod_imagemagick/mptr_imagemagick.cpp,src/modules/mod_imagemagick/mptr_imagemagick.h,src/modules/mod_imagemagick/Makefile.am,src/modules/mod_imagemagick/trgt_imagemagick.cpp,src/modules/mod_imagemagick/trgt_imagemagick.h
+install=false
+install_location=
+sharedlib_LDFLAGS=-version-info 0:0:0
+sharedlib_rootname=mod_imagemagick
+sub_dirs=
+type=static_library
+
+[src/modules/mod_imagemagick/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/mod_imagemagick/mptr_imagemagick.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/mod_imagemagick/mptr_imagemagick.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/mod_imagemagick/trgt_imagemagick.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/mod_imagemagick/trgt_imagemagick.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/mptr_mplayer/Makefile.am]
+dist=true
+files=src/modules/mptr_mplayer/main.cpp,src/modules/mptr_mplayer/mptr_mplayer.cpp,src/modules/mptr_mplayer/Makefile.am,src/modules/mptr_mplayer/mptr_mplayer.h
+install=false
+install_location=
+sharedlib_LDFLAGS=-version-info 0:0:0
+sharedlib_rootname=mptr_mplayer
+sub_dirs=
+type=DATA
+
+[src/modules/mptr_mplayer/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/mptr_mplayer/mptr_mplayer.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/mptr_mplayer/mptr_mplayer.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/trgt_bmp/Makefile.am]
+dist=true
+files=src/modules/trgt_bmp/main.cpp,src/modules/trgt_bmp/trgt_bmp.cpp,src/modules/trgt_bmp/Makefile.am,src/modules/trgt_bmp/trgt_bmp.h
+install=false
+install_location=
+sharedlib_LDFLAGS=-version-info 0:0:1
+sharedlib_rootname=trgt_bmp
+sub_dirs=
+type=DATA
+
+[src/modules/trgt_bmp/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/trgt_bmp/trgt_bmp.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/trgt_bmp/trgt_bmp.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/trgt_dv/Makefile.am]
+dist=true
+files=src/modules/trgt_dv/main.cpp,src/modules/trgt_dv/trgt_dv.cpp,src/modules/trgt_dv/trgt_dv.h,src/modules/trgt_dv/Makefile.am
+install=false
+install_location=
+sharedlib_LDFLAGS=-version-info 0:0:0
+sharedlib_rootname=trgt_dv
+sub_dirs=
+type=DATA
+
+[src/modules/trgt_dv/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/trgt_dv/trgt_dv.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/trgt_dv/trgt_dv.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/trgt_gif/Makefile.am]
+dist=true
+files=src/modules/trgt_gif/main.cpp,src/modules/trgt_gif/Makefile.am,src/modules/trgt_gif/trgt_gif.cpp,src/modules/trgt_gif/trgt_gif.h
+install=false
+install_location=
+sharedlib_LDFLAGS=-version-info 0:0:1
+sharedlib_rootname=trgt_gif
+sub_dirs=
+type=static_library
+
+[src/modules/trgt_gif/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/trgt_gif/trgt_gif.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/trgt_gif/trgt_gif.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/trgt_mpg/Makefile.am]
+dist=true
+files=src/modules/trgt_mpg/main.cpp,src/modules/trgt_mpg/Makefile.am,src/modules/trgt_mpg/trgt_mpg.cpp,src/modules/trgt_mpg/trgt_mpg.h
+install=false
+install_location=
+sharedlib_LDFLAGS=-version-info 0:0:1
+sharedlib_rootname=trgt_mpg
+sub_dirs=
+type=static_library
+
+[src/modules/trgt_mpg/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/trgt_mpg/trgt_mpg.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/trgt_mpg/trgt_mpg.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/trgt_ppm/Makefile.am]
+dist=true
+files=src/modules/trgt_ppm/Makefile.am,src/modules/trgt_ppm/main.cpp,src/modules/trgt_ppm/trgt_ppm.cpp,src/modules/trgt_ppm/trgt_ppm.h,src/modules/trgt_ppm/mptr_ppm.cpp,src/modules/trgt_ppm/mptr_ppm.h,src/modules/trgt_ppm/trgt_mpg.h,src/modules/trgt_ppm/trgt_mpg.cpp
+install=false
+install_location=
+sub_dirs=
+type=static_library
+
+[src/modules/trgt_ppm/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/trgt_ppm/mptr_ppm.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/trgt_ppm/mptr_ppm.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/trgt_ppm/trgt_mpg.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/trgt_ppm/trgt_mpg.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/modules/trgt_ppm/trgt_ppm.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/modules/trgt_ppm/trgt_ppm.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/Makefile.am]
+dist=true
+files=src/synfig/animate.cpp,src/synfig/animate.h,src/synfig/color.cpp,src/synfig/color.h,src/synfig/general.h,src/synfig/layer.cpp,src/synfig/layer.h,src/synfig/main.cpp,src/synfig/Makefile.am,src/synfig/modules.cpp,src/synfig/modules.h,src/synfig/pch.h,src/synfig/renddesc.h,src/synfig/render.cpp,src/synfig/render.h,src/synfig/synfig.h,src/synfig/target.cpp,src/synfig/target.h,src/synfig/vector.h,src/synfig/bmplayer.cpp,src/synfig/bmplayer.h,src/synfig/importer.cpp,src/synfig/importer.h,src/synfig/surface.cpp,src/synfig/surface.h,src/synfig/datatype.h,src/synfig/datatype.cpp,src/synfig/canvas.cpp,src/synfig/canvas.h,src/synfig/loadcanvas.cpp,src/synfig/loadcanvas.h,src/synfig/savecanvas.cpp,src/synfig/savecanvas.h
+install=false
+install_location=
+sharedlib_LDFLAGS=-version-info 0:0:1
+sharedlib_rootname=synfig
+sub_dirs=
+type=static_library
+
+[src/synfig/animate.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/animate.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/bmplayer.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/bmplayer.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/canvas.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/canvas.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/color.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/color.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/datatype.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/datatype.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/general.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/importer.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/importer.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/layer.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/layer.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/loadcanvas.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/loadcanvas.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/modules.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/modules.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/pch.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/renddesc.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/render.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/render.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/savecanvas.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/savecanvas.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/synfig.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/surface.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/surface.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/target.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/synfig/target.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/synfig/vector.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/template.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/template.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/tool/Makefile.am]
+dist=true
+files=src/tool/main.cpp,src/tool/Makefile.am
+install=false
+install_location=
+sharedlib_LDFLAGS=-version-info 0:0:1
+sharedlib_rootname=tool
+sub_dirs=
+type=DATA
+
+[src/tool/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[test/Makefile.am]
+files=test/random.cpp,test/angle,test/clock,test/fixed,test/smach,test/smach.cpp,test/handle.cpp,test/handle,test/clock.cpp,test/angle.cpp,test/random,test/fixed.cpp,
+sub_dirs=
+type=normal
+
+[test/angle]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[test/angle.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[test/clock]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[test/clock.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[test/fixed]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[test/fixed.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[test/handle]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[test/handle.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[test/random]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[test/random.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[test/smach]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[test/smach.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
--- /dev/null
+# Anjuta Version 1.2.2
+Compatibility Level: 1
+
+<PROJECT_DESCRIPTION_START>
+
+<PROJECT_DESCRIPTION_END>
+<CONFIG_PROGS_START>
+<CONFIG_PROGS_END>
+<CONFIG_LIBS_START>
+<CONFIG_LIBS_END>
+<CONFIG_HEADERS_START>
+<CONFIG_HEADERS_END>
+<CONFIG_CHARACTERISTICS_START>
+<CONFIG_CHARACTERISTICS_END>
+<CONFIG_LIB_FUNCS_START>
+<CONFIG_LIB_FUNCS_END>
+<CONFIG_ADDITIONAL_START>
+<CONFIG_ADDITIONAL_END>
+<CONFIG_FILES_START>
+<CONFIG_FILES_END>
+<MAKEFILE_AM_START>
+<MAKEFILE_AM_END>
+
+props.file.type=project
+
+anjuta.version=1.2.2
+anjuta.compatibility.level=1
+
+project.name=synfig
+project.type=GENERIC
+project.target.type=EXECUTABLE
+project.version=0.60.00
+project.author=Robert B. Quattlebaum Jr
+project.source.target=src/tool/synfig
+project.has.gettext=0
+project.gui.command=
+project.programming.language=C++
+project.excluded.modules= intl
+
+project.config.extra.modules.before=
+project.config.extra.modules.after=
+project.config.blocked=1
+project.config.disable.overwriting=1 1 1 1 1 1 1 1 1
+
+project.menu.entry=synfig Version 0.60.00
+project.menu.group=Application
+project.menu.comment=synfig Version 0.60.00
+project.menu.icon=
+project.menu.need.terminal=0
+
+project.configure.options=--enable-warnings=maximum --enable-static=no CXX="g++ -march=athlon -msse -mfpmath=sse"
+anjuta.program.arguments=
+preferences.build.option.jobs=0
+preferences.build.option.silent=0
+preferences.build.option.autosave=0
+preferences.make=make
+preferences.build.option.keep.going=0
+preferences.build.option.warn.undef=0
+preferences.autoformat.custom.style= -i8 -sc -bli0 -bl0 -cbi0 -ss
+preferences.indent.opening=0
+preferences.autoformat.disable=0
+preferences.indent.automatic=1
+preferences.use.tabs=1
+preferences.indent.size=4
+preferences.tabsize=4
+preferences.indent.closing=0
+
+module.include.name=.
+module.include.type=
+module.include.files=\
+ synfig.pbproj/config.h\
+ synfig.pbproj/etl_profile.h\
+ src/modules/lyr_std/bezier.h\
+ src/modules/lyr_std/blur.h\
+ src/modules/lyr_std/checkerboard.h\
+ src/modules/lyr_std/circle.h\
+ src/modules/lyr_std/image.h\
+ src/modules/lyr_std/import.h\
+ src/modules/lyr_std/mandelbrot.h\
+ src/modules/lyr_std/polygon.h\
+ src/modules/lyr_std/region.h\
+ src/modules/lyr_std/solidcolor.h\
+ src/modules/lyr_std/supersample.h\
+ src/modules/lyr_std/translate.h\
+ src/modules/lyr_std/zoom.h\
+ src/modules/mod_ffmpeg/mptr_ffmpeg.h\
+ src/modules/mod_ffmpeg/trgt_ffmpeg.h\
+ src/modules/mptr_mplayer/mptr_mplayer.h\
+ src/modules/trgt_bmp/trgt_bmp.h\
+ src/modules/trgt_dv/trgt_dv.h\
+ src/modules/trgt_gif/trgt_gif.h\
+ src/modules/trgt_mpg/trgt_mpg.h\
+ src/modules/trgt_ppm/mptr_ppm.h\
+ src/modules/trgt_ppm/trgt_mpg.h\
+ src/modules/trgt_ppm/trgt_ppm.h\
+ src/modules/mod_imagemagick/trgt_imagemagick.h\
+ src/modules/mod_imagemagick/mptr_imagemagick.h\
+ src/modules/lyr_freetype/lyr_freetype.h\
+ src/template.h\
+ src/synfig/animate.h\
+ src/synfig/bmplayer.h\
+ src/synfig/color.h\
+ src/synfig/general.h\
+ src/synfig/importer.h\
+ src/synfig/layer.h\
+ src/synfig/modules.h\
+ src/synfig/pch.h\
+ src/synfig/renddesc.h\
+ src/synfig/render.h\
+ src/synfig/synfig.h\
+ src/synfig/surface.h\
+ src/synfig/target.h\
+ src/synfig/vector.h\
+ src/synfig/datatype.h\
+ src/synfig/canvas.h\
+ src/synfig/loadcanvas.h\
+ src/synfig/savecanvas.h
+
+module.source.name=.
+module.source.type=
+module.source.files=\
+ src/modules/example/main.cpp\
+ src/modules/lyr_std/bezier.cpp\
+ src/modules/lyr_std/blur.cpp\
+ src/modules/lyr_std/checkerboard.cpp\
+ src/modules/lyr_std/circle.cpp\
+ src/modules/lyr_std/image.cpp\
+ src/modules/lyr_std/import.cpp\
+ src/modules/lyr_std/main.cpp\
+ src/modules/lyr_std/mandelbrot.cpp\
+ src/modules/lyr_std/polygon.cpp\
+ src/modules/lyr_std/region.cpp\
+ src/modules/lyr_std/solidcolor.cpp\
+ src/modules/lyr_std/supersample.cpp\
+ src/modules/lyr_std/translate.cpp\
+ src/modules/lyr_std/zoom.cpp\
+ src/modules/mod_ffmpeg/main.cpp\
+ src/modules/mod_ffmpeg/mptr_ffmpeg.cpp\
+ src/modules/mod_ffmpeg/trgt_ffmpeg.cpp\
+ src/modules/mptr_mplayer/main.cpp\
+ src/modules/mptr_mplayer/mptr_mplayer.cpp\
+ src/modules/trgt_bmp/main.cpp\
+ src/modules/trgt_bmp/trgt_bmp.cpp\
+ src/modules/trgt_dv/main.cpp\
+ src/modules/trgt_dv/trgt_dv.cpp\
+ src/modules/trgt_gif/main.cpp\
+ src/modules/trgt_gif/trgt_gif.cpp\
+ src/modules/trgt_mpg/main.cpp\
+ src/modules/trgt_mpg/trgt_mpg.cpp\
+ src/modules/trgt_ppm/main.cpp\
+ src/modules/trgt_ppm/mptr_ppm.cpp\
+ src/modules/trgt_ppm/trgt_mpg.cpp\
+ src/modules/trgt_ppm/trgt_ppm.cpp\
+ src/modules/mod_imagemagick/mptr_imagemagick.cpp\
+ src/modules/mod_imagemagick/main.cpp\
+ src/modules/mod_imagemagick/trgt_imagemagick.cpp\
+ src/modules/lyr_freetype/main.cpp\
+ src/modules/lyr_freetype/lyr_freetype.cpp\
+ src/template.cpp\
+ src/synfig/animate.cpp\
+ src/synfig/bmplayer.cpp\
+ src/synfig/color.cpp\
+ src/synfig/importer.cpp\
+ src/synfig/layer.cpp\
+ src/synfig/main.cpp\
+ src/synfig/modules.cpp\
+ src/synfig/render.cpp\
+ src/synfig/surface.cpp\
+ src/synfig/target.cpp\
+ src/synfig/datatype.cpp\
+ src/synfig/canvas.cpp\
+ src/synfig/loadcanvas.cpp\
+ src/synfig/savecanvas.cpp\
+ src/tool/main.cpp
+
+module.pixmap.name=.
+module.pixmap.type=
+module.pixmap.files=
+
+module.data.name=.
+module.data.type=
+module.data.files=
+
+module.help.name=.
+module.help.type=
+module.help.files=
+
+module.doc.name=.
+module.doc.type=
+module.doc.files=\
+ ChangeLog\
+ INSTALL\
+ README
+
+module.po.files=
+
+compiler.options.supports=
+compiler.options.include.paths=\
+ .\
+ ..
+compiler.options.library.paths=
+compiler.options.libraries=
+compiler.options.libraries.selected=
+compiler.options.defines=\
+ HAVE_CONFIG_H
+compiler.options.defines.selected=
+compiler.options.warning.buttons=0 0 1 1 0 1 0 0 0 0 0 0 0 1 0 0
+compiler.options.optimize.buttons=0 0 1 0
+compiler.options.other.buttons=1 0
+compiler.options.other.c.flags=
+compiler.options.other.l.flags=
+compiler.options.other.l.libs=
+
+project.src.paths=
--- /dev/null
+#!/bin/sh
+
+#OPTIONS="--disable-optimization --enable-debug"
+
+OPTIONS="--enable-optimization=1 --disable-debug"
+#OPTIONS="$OPTIONS --enable-timelimit=120"
+
+[ -e configure ] || ./bootstrap || exit 0
+
+[ -d win32build ] && rm -fr win32build
+
+mkdir win32build
+
+cd win32build
+
+../configure --host=mingw32 --prefix=C:/PROGRA~1/Synfig $OPTIONS || exit 0
+
+make package
+
+
--- /dev/null
+; example2.nsi
+;
+; This script is based on example1.nsi, but it remember the directory,
+; has uninstall support and (optionally) installs start menu shortcuts.
+;
+; It will install makensisw.exe into a directory that the user selects,
+
+!include "MUI.nsh"
+
+;--------------------------------
+
+; The name of the installer
+Name "@PACKAGE_NAME@ @PACKAGE_VERSION@"
+
+!define PRODUCT_WEB_SITE "http://www.synfig.com/"
+
+; The file to write
+OutFile "@PACKAGE_TARNAME@-@PACKAGE_VERSION@.exe"
+
+; The default installation directory
+InstallDir $PROGRAMFILES\@PACKAGE_TARNAME@
+
+!define VERSION_MAJ "@VERSION_MAJ@"
+!define VERSION_MIN "@VERSION_MIN@"
+!define VERSION_REV "@VERSION_REV@"
+
+!define SYNFIG_REG_KEY "Software\@PACKAGE_TARNAME@\@API_VERSION@"
+!define SYNFIG_UNINSTALL_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\@PACKAGE_TARNAME@"
+!define SYNFIG_UNINSTALL_EXE "uninstall-@PACKAGE_TARNAME@.exe"
+
+!define MUI_ABORTWARNING
+
+;--------------------------------
+
+; Pages
+
+#Page components
+#Page directory
+#Page instfiles
+
+#UninstPage uninstConfirm
+#UninstPage instfiles
+
+;CustomGuiInit
+
+!insertmacro MUI_PAGE_WELCOME
+!insertmacro MUI_PAGE_LICENSE "@srcdir@\COPYING"
+#!insertmacro MUI_PAGE_LICENSE "@srcdir@\alphalicense.txt"
+;Page custom PageReinstall ; PageLeaveReinstall
+!insertmacro MUI_PAGE_COMPONENTS
+!insertmacro MUI_PAGE_DIRECTORY
+!insertmacro MUI_PAGE_INSTFILES
+
+!insertmacro MUI_UNPAGE_CONFIRM
+!insertmacro MUI_UNPAGE_COMPONENTS
+!insertmacro MUI_UNPAGE_INSTFILES
+
+!insertmacro MUI_LANGUAGE "English"
+
+;--------------------------------
+
+; The stuff to install
+Section ""
+
+ SectionIn RO
+
+ ; Set output path to the installation directory.
+ SetOutPath $INSTDIR\bin
+
+ ; Put file there
+
+ CreateDirectory "$INSTDIR\etc"
+ Delete $INSTDIR\etc\synfig_modules.cfg
+
+ ; Write the installation path into the registry
+ WriteRegStr HKLM "${SYNFIG_REG_KEY}" "Path" "$INSTDIR"
+ WriteRegStr HKLM "${SYNFIG_REG_KEY}" "Version" "@PACKAGE_VERSION@"
+
+ ; Write the uninstall keys for Windows
+ WriteRegStr HKLM "${SYNFIG_UNINSTALL_KEY}" "DisplayName" "@PACKAGE_NAME@"
+ WriteRegStr HKLM "${SYNFIG_UNINSTALL_KEY}" "DisplayVersion" "@PACKAGE_VERSION@"
+ WriteRegStr HKLM "${SYNFIG_UNINSTALL_KEY}" "UninstallString" '"$INSTDIR\${SYNFIG_UNINSTALL_EXE}"'
+ WriteRegDWORD HKLM "${SYNFIG_UNINSTALL_KEY}" "NoModify" 1
+ WriteRegDWORD HKLM "${SYNFIG_UNINSTALL_KEY}" "NoRepair" 1
+ WriteUninstaller "${SYNFIG_UNINSTALL_EXE}"
+
+SectionEnd
+
+; Optional section (can be disabled by the user)
+Section "Start Menu Shortcuts"
+
+ SetShellVarContext All
+ CreateDirectory "$SMPROGRAMS\Voria"
+ CreateShortCut "$SMPROGRAMS\Voria\Uninstall Synfig Core.lnk" "$INSTDIR\uninstall-@PACKAGE_TARNAME@.exe" "" "$INSTDIR\uninstall-@PACKAGE_TARNAME@.exe" 0
+
+SectionEnd
+
+
+;--------------------------------
+
+; Uninstaller
+
+Section "Uninstall"
+
+ ; Remove registry keys
+ DeleteRegKey HKLM "${SYNFIG_REG_KEY}"
+ DeleteRegKey HKLM "${SYNFIG_UNINSTALL_KEY}"
+
+ ; Remove files and uninstaller
+ Delete $INSTDIR\uninstall-@PACKAGE_TARNAME@.exe
+ Delete $INSTDIR\etc\synfig_modules.cfg
+ RMDir "$INSTDIR\bin"
+ RMDir "$INSTDIR\etc"
+ RMDir "$INSTDIR"
+
+SectionEnd
+
+Section "un.Start Menu Shortcuts"
+
+ ; Remove shortcuts, if any
+ SetShellVarContext All
+ Delete "$SMPROGRAMS\Voria\Uninstall Synfig Core.lnk"
+ RMDir "$SMPROGRAMS\Voria"
+
+SectionEnd
+
+!include @srcdir@\src\synfig\synfig.nsh
+!include @srcdir@\src\tool\tool.nsh
+
+Section "Examples"
+ SetOutPath $INSTDIR\examples
+ File "@srcdir@\examples\*.sifz"
+
+ SetShellVarContext All
+ CreateDirectory "$SMPROGRAMS\Voria"
+ CreateShortCut "$SMPROGRAMS\Voria\Examples.lnk" "$INSTDIR\examples" "" "$INSTDIR\examples" 0
+SectionEnd
+
+Section "un.Examples"
+ Delete "$INSTDIR\examples\*.sifz"
+ RMDir "$INSTDIR\examples"
+
+ SetShellVarContext All
+ Delete "$SMPROGRAMS\Voria\Examples.lnk"
+ RMDir "$SMPROGRAMS\Voria"
+SectionEnd
+
+SectionGroup "PlugIns"
+SectionGroup "Layers"
+!include "@srcdir@\src\modules\lyr_std\lyr_std.nsh"
+!include "@srcdir@\src\modules\mod_filter\mod_filter.nsh"
+!include "@srcdir@\src\modules\mod_gradient\mod_gradient.nsh"
+!include "@srcdir@\src\modules\mod_noise\mod_noise.nsh"
+!include "@srcdir@\src\modules\mod_particle\mod_particle.nsh"
+!include "@srcdir@\src\modules\mod_geometry\mod_geometry.nsh"
+!include "@srcdir@\src\modules\lyr_freetype\lyr_freetype.nsh"
+SectionGroupEnd
+SectionGroup "Render Targets"
+!include "@srcdir@\src\modules\mod_bmp\mod_bmp.nsh"
+!include "@srcdir@\src\modules\mod_dv\mod_dv.nsh"
+!include "@srcdir@\src\modules\mod_ffmpeg\mod_ffmpeg.nsh"
+!include "@srcdir@\src\modules\mod_gif\mod_gif.nsh"
+!include "@srcdir@\src\modules\mod_imagemagick\mod_imagemagick.nsh"
+!include "@srcdir@\src\modules\mod_jpeg\mod_jpeg.nsh"
+!include "@srcdir@\src\modules\mod_openexr\mod_openexr.nsh"
+!include "@srcdir@\src\modules\mod_png\mod_png.nsh"
+!include "@srcdir@\src\modules\mod_ppm\mod_ppm.nsh"
+!include "@srcdir@\src\modules\mod_yuv420p\mod_yuv420p.nsh"
+SectionGroupEnd
+SectionGroupEnd
+
+SectionGroup "un.PlugIns"
+SectionGroup "un.Layers"
+!include "@srcdir@\src\modules\lyr_std\unlyr_std.nsh"
+!include "@srcdir@\src\modules\lyr_freetype\unlyr_freetype.nsh"
+!include "@srcdir@\src\modules\mod_filter\unmod_filter.nsh"
+!include "@srcdir@\src\modules\mod_gradient\unmod_gradient.nsh"
+!include "@srcdir@\src\modules\mod_noise\unmod_noise.nsh"
+!include "@srcdir@\src\modules\mod_particle\unmod_particle.nsh"
+!include "@srcdir@\src\modules\mod_geometry\unmod_geometry.nsh"
+SectionGroupEnd
+SectionGroup "un.Render Targets"
+!include "@srcdir@\src\modules\mod_bmp\unmod_bmp.nsh"
+!include "@srcdir@\src\modules\mod_dv\unmod_dv.nsh"
+!include "@srcdir@\src\modules\mod_ffmpeg\unmod_ffmpeg.nsh"
+!include "@srcdir@\src\modules\mod_gif\unmod_gif.nsh"
+!include "@srcdir@\src\modules\mod_imagemagick\unmod_imagemagick.nsh"
+!include "@srcdir@\src\modules\mod_jpeg\unmod_jpeg.nsh"
+!include "@srcdir@\src\modules\mod_openexr\unmod_openexr.nsh"
+!include "@srcdir@\src\modules\mod_png\unmod_png.nsh"
+!include "@srcdir@\src\modules\mod_ppm\unmod_ppm.nsh"
+!include "@srcdir@\src\modules\mod_yuv420p\unmod_yuv420p.nsh"
+SectionGroupEnd
+SectionGroupEnd
+
+Function .onInit
+ ; Get installer location
+ ReadRegStr $R0 HKLM "${SYNFIG_UNINSTALL_KEY}" "UninstallString"
+; IfErrors 0 +2
+; ReadRegStr $R0 HKCU "${SYNFIG_UNINSTALL_KEY}" "UninstallString"
+
+ StrCmp $R0 "" done
+
+ ; Get current installed version
+ ReadRegStr $R1 HKLM "${SYNFIG_UNINSTALL_KEY}" "DisplayVersion"
+; IfErrors 0 +2
+; ReadRegStr $R1 HKCU "${SYNFIG_UNINSTALL_KEY}" "DisplayVersion"
+
+; StrCmp $R1 ${PRODUCT_VERSION} done
+
+ MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION "A previous version of @PACKAGE_NAME@ appears to be installed. Would you like to uninstall it first?" IDNO done IDCANCEL abortInstall
+
+ ; Run the uninstaller
+
+ ClearErrors
+ ; CopyFiles "$R0" $TEMP
+ ExecWait '$R0 _?=$INSTDIR'
+ IfErrors no_remove_uninstaller
+ Delete $R0
+ RMDir $INSTDIR
+
+no_remove_uninstaller:
+; Delete "$TEMP\$R0"
+
+ ; Check that the user completed the uninstallation by examining the registry
+ ReadRegStr $R0 HKLM "${SYNFIG_UNINSTALL_KEY}" "UninstallString"
+ StrCmp $R0 "" done abortInstall
+ ReadRegStr $R0 HKCU "${SYNFIG_UNINSTALL_KEY}" "UninstallString"
+ StrCmp $R0 "" done abortInstall
+
+abortInstall:
+ MessageBox MB_OK|MB_ICONEXCLAMATION "Unable to uninstall previous version of @PACKAGE_NAME@"
+ Abort
+
+done:
+ BringToFront
+
+FunctionEnd