diff options
Diffstat (limited to '')
-rw-r--r-- | plug-ins/gradient-flare/Makefile.am | 51 | ||||
-rw-r--r-- | plug-ins/gradient-flare/Makefile.in | 1117 | ||||
-rw-r--r-- | plug-ins/gradient-flare/README | 99 | ||||
-rw-r--r-- | plug-ins/gradient-flare/flares/Bright_Star | 18 | ||||
-rw-r--r-- | plug-ins/gradient-flare/flares/Classic | 18 | ||||
-rw-r--r-- | plug-ins/gradient-flare/flares/Default | 18 | ||||
-rw-r--r-- | plug-ins/gradient-flare/flares/Distant_Sun | 18 | ||||
-rw-r--r-- | plug-ins/gradient-flare/flares/GFlare_101 | 18 | ||||
-rw-r--r-- | plug-ins/gradient-flare/flares/GFlare_102 | 18 | ||||
-rw-r--r-- | plug-ins/gradient-flare/flares/Hidden_Planet | 18 | ||||
-rw-r--r-- | plug-ins/gradient-flare/flares/Makefile.am | 14 | ||||
-rw-r--r-- | plug-ins/gradient-flare/flares/Makefile.in | 811 | ||||
-rw-r--r-- | plug-ins/gradient-flare/gradient-flare.c | 5123 |
13 files changed, 7341 insertions, 0 deletions
diff --git a/plug-ins/gradient-flare/Makefile.am b/plug-ins/gradient-flare/Makefile.am new file mode 100644 index 0000000..f531be4 --- /dev/null +++ b/plug-ins/gradient-flare/Makefile.am @@ -0,0 +1,51 @@ +## Process this file with automake to produce Makefile.in + +if OS_WIN32 +mwindows = -mwindows +else +libm = -lm +endif + +libgimpui = $(top_builddir)/libgimp/libgimpui-$(GIMP_API_VERSION).la +libgimpconfig = $(top_builddir)/libgimpconfig/libgimpconfig-$(GIMP_API_VERSION).la +libgimpwidgets = $(top_builddir)/libgimpwidgets/libgimpwidgets-$(GIMP_API_VERSION).la +libgimp = $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la +libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la +libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la +libgimpmath = $(top_builddir)/libgimpmath/libgimpmath-$(GIMP_API_VERSION).la + +if HAVE_WINDRES +include $(top_srcdir)/build/windows/gimprc-plug-ins.rule +gradient_flare_RC = gradient-flare.rc.o +endif + +AM_LDFLAGS = $(mwindows) + +SUBDIRS = flares + +libexecdir = $(gimpplugindir)/plug-ins/gradient-flare + +libexec_PROGRAMS = gradient-flare + +gradient_flare_SOURCES = gradient-flare.c + +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + $(GTK_CFLAGS) \ + $(GEGL_CFLAGS) \ + -I$(includedir) + +LDADD = \ + $(libm) \ + $(libgimpui) \ + $(libgimpwidgets) \ + $(libgimpconfig) \ + $(libgimp) \ + $(libgimpcolor) \ + $(libgimpmath) \ + $(libgimpbase) \ + $(GTK_LIBS) \ + $(GEGL_LIBS) \ + $(RT_LIBS) \ + $(INTLLIBS) \ + $(gradient_flare_RC) diff --git a/plug-ins/gradient-flare/Makefile.in b/plug-ins/gradient-flare/Makefile.in new file mode 100644 index 0000000..6d6b258 --- /dev/null +++ b/plug-ins/gradient-flare/Makefile.in @@ -0,0 +1,1117 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Version resources for Microsoft Windows + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +libexec_PROGRAMS = gradient-flare$(EXEEXT) +subdir = plug-ins/gradient-flare +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/m4macros/alsa.m4 \ + $(top_srcdir)/m4macros/ax_compare_version.m4 \ + $(top_srcdir)/m4macros/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4macros/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4macros/ax_prog_cc_for_build.m4 \ + $(top_srcdir)/m4macros/ax_prog_perl_version.m4 \ + $(top_srcdir)/m4macros/detectcflags.m4 \ + $(top_srcdir)/m4macros/pythondev.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(libexecdir)" +PROGRAMS = $(libexec_PROGRAMS) +am_gradient_flare_OBJECTS = gradient-flare.$(OBJEXT) +gradient_flare_OBJECTS = $(am_gradient_flare_OBJECTS) +gradient_flare_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +gradient_flare_DEPENDENCIES = $(am__DEPENDENCIES_1) $(libgimpui) \ + $(libgimpwidgets) $(libgimpconfig) $(libgimp) $(libgimpcolor) \ + $(libgimpmath) $(libgimpbase) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(gradient_flare_RC) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/gradient-flare.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(gradient_flare_SOURCES) +DIST_SOURCES = $(gradient_flare_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build/windows/gimprc-plug-ins.rule \ + $(top_srcdir)/depcomp README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +AA_LIBS = @AA_LIBS@ +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +ALL_LINGUAS = @ALL_LINGUAS@ +ALSA_CFLAGS = @ALSA_CFLAGS@ +ALSA_LIBS = @ALSA_LIBS@ +ALTIVEC_EXTRA_CFLAGS = @ALTIVEC_EXTRA_CFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPSTREAM_UTIL = @APPSTREAM_UTIL@ +AR = @AR@ +AS = @AS@ +ATK_CFLAGS = @ATK_CFLAGS@ +ATK_LIBS = @ATK_LIBS@ +ATK_REQUIRED_VERSION = @ATK_REQUIRED_VERSION@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BABL_CFLAGS = @BABL_CFLAGS@ +BABL_LIBS = @BABL_LIBS@ +BABL_REQUIRED_VERSION = @BABL_REQUIRED_VERSION@ +BUG_REPORT_URL = @BUG_REPORT_URL@ +BUILD_EXEEXT = @BUILD_EXEEXT@ +BUILD_OBJEXT = @BUILD_OBJEXT@ +BZIP2_LIBS = @BZIP2_LIBS@ +CAIRO_CFLAGS = @CAIRO_CFLAGS@ +CAIRO_LIBS = @CAIRO_LIBS@ +CAIRO_PDF_CFLAGS = @CAIRO_PDF_CFLAGS@ +CAIRO_PDF_LIBS = @CAIRO_PDF_LIBS@ +CAIRO_PDF_REQUIRED_VERSION = @CAIRO_PDF_REQUIRED_VERSION@ +CAIRO_REQUIRED_VERSION = @CAIRO_REQUIRED_VERSION@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CC_VERSION = @CC_VERSION@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@ +CPP_FOR_BUILD = @CPP_FOR_BUILD@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DESKTOP_DATADIR = @DESKTOP_DATADIR@ +DESKTOP_FILE_VALIDATE = @DESKTOP_FILE_VALIDATE@ +DLLTOOL = @DLLTOOL@ +DOC_SHOOTER = @DOC_SHOOTER@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILE_AA = @FILE_AA@ +FILE_EXR = @FILE_EXR@ +FILE_HEIF = @FILE_HEIF@ +FILE_JP2_LOAD = @FILE_JP2_LOAD@ +FILE_JPEGXL = @FILE_JPEGXL@ +FILE_MNG = @FILE_MNG@ +FILE_PDF_SAVE = @FILE_PDF_SAVE@ +FILE_PS = @FILE_PS@ +FILE_WMF = @FILE_WMF@ +FILE_XMC = @FILE_XMC@ +FILE_XPM = @FILE_XPM@ +FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@ +FONTCONFIG_LIBS = @FONTCONFIG_LIBS@ +FONTCONFIG_REQUIRED_VERSION = @FONTCONFIG_REQUIRED_VERSION@ +FREETYPE2_REQUIRED_VERSION = @FREETYPE2_REQUIRED_VERSION@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +GDBUS_CODEGEN = @GDBUS_CODEGEN@ +GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@ +GDK_PIXBUF_CSOURCE = @GDK_PIXBUF_CSOURCE@ +GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@ +GDK_PIXBUF_REQUIRED_VERSION = @GDK_PIXBUF_REQUIRED_VERSION@ +GEGL = @GEGL@ +GEGL_CFLAGS = @GEGL_CFLAGS@ +GEGL_LIBS = @GEGL_LIBS@ +GEGL_MAJOR_MINOR_VERSION = @GEGL_MAJOR_MINOR_VERSION@ +GEGL_REQUIRED_VERSION = @GEGL_REQUIRED_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GEXIV2_CFLAGS = @GEXIV2_CFLAGS@ +GEXIV2_LIBS = @GEXIV2_LIBS@ +GEXIV2_REQUIRED_VERSION = @GEXIV2_REQUIRED_VERSION@ +GIMP_API_VERSION = @GIMP_API_VERSION@ +GIMP_APP_VERSION = @GIMP_APP_VERSION@ +GIMP_BINARY_AGE = @GIMP_BINARY_AGE@ +GIMP_COMMAND = @GIMP_COMMAND@ +GIMP_DATA_VERSION = @GIMP_DATA_VERSION@ +GIMP_FULL_NAME = @GIMP_FULL_NAME@ +GIMP_INTERFACE_AGE = @GIMP_INTERFACE_AGE@ +GIMP_MAJOR_VERSION = @GIMP_MAJOR_VERSION@ +GIMP_MICRO_VERSION = @GIMP_MICRO_VERSION@ +GIMP_MINOR_VERSION = @GIMP_MINOR_VERSION@ +GIMP_MKENUMS = @GIMP_MKENUMS@ +GIMP_MODULES = @GIMP_MODULES@ +GIMP_PACKAGE_REVISION = @GIMP_PACKAGE_REVISION@ +GIMP_PKGCONFIG_VERSION = @GIMP_PKGCONFIG_VERSION@ +GIMP_PLUGINS = @GIMP_PLUGINS@ +GIMP_PLUGIN_VERSION = @GIMP_PLUGIN_VERSION@ +GIMP_REAL_VERSION = @GIMP_REAL_VERSION@ +GIMP_RELEASE = @GIMP_RELEASE@ +GIMP_SYSCONF_VERSION = @GIMP_SYSCONF_VERSION@ +GIMP_TOOL_VERSION = @GIMP_TOOL_VERSION@ +GIMP_UNSTABLE = @GIMP_UNSTABLE@ +GIMP_USER_VERSION = @GIMP_USER_VERSION@ +GIMP_VERSION = @GIMP_VERSION@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GIO_UNIX_CFLAGS = @GIO_UNIX_CFLAGS@ +GIO_UNIX_LIBS = @GIO_UNIX_LIBS@ +GIO_WINDOWS_CFLAGS = @GIO_WINDOWS_CFLAGS@ +GIO_WINDOWS_LIBS = @GIO_WINDOWS_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_COMPILE_RESOURCES = @GLIB_COMPILE_RESOURCES@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GLIB_REQUIRED_VERSION = @GLIB_REQUIRED_VERSION@ +GMODULE_NO_EXPORT_CFLAGS = @GMODULE_NO_EXPORT_CFLAGS@ +GMODULE_NO_EXPORT_LIBS = @GMODULE_NO_EXPORT_LIBS@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GOBJECT_QUERY = @GOBJECT_QUERY@ +GREP = @GREP@ +GS_LIBS = @GS_LIBS@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +GTK_MAC_INTEGRATION_CFLAGS = @GTK_MAC_INTEGRATION_CFLAGS@ +GTK_MAC_INTEGRATION_LIBS = @GTK_MAC_INTEGRATION_LIBS@ +GTK_REQUIRED_VERSION = @GTK_REQUIRED_VERSION@ +GTK_UPDATE_ICON_CACHE = @GTK_UPDATE_ICON_CACHE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HARFBUZZ_CFLAGS = @HARFBUZZ_CFLAGS@ +HARFBUZZ_LIBS = @HARFBUZZ_LIBS@ +HARFBUZZ_REQUIRED_VERSION = @HARFBUZZ_REQUIRED_VERSION@ +HAVE_CXX14 = @HAVE_CXX14@ +HAVE_FINITE = @HAVE_FINITE@ +HAVE_ISFINITE = @HAVE_ISFINITE@ +HAVE_VFORK = @HAVE_VFORK@ +HOST_GLIB_COMPILE_RESOURCES = @HOST_GLIB_COMPILE_RESOURCES@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_REQUIRED_VERSION = @INTLTOOL_REQUIRED_VERSION@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +ISO_CODES_LOCALEDIR = @ISO_CODES_LOCALEDIR@ +ISO_CODES_LOCATION = @ISO_CODES_LOCATION@ +JPEG_LIBS = @JPEG_LIBS@ +JSON_GLIB_CFLAGS = @JSON_GLIB_CFLAGS@ +JSON_GLIB_LIBS = @JSON_GLIB_LIBS@ +JXL_CFLAGS = @JXL_CFLAGS@ +JXL_LIBS = @JXL_LIBS@ +JXL_THREADS_CFLAGS = @JXL_THREADS_CFLAGS@ +JXL_THREADS_LIBS = @JXL_THREADS_LIBS@ +LCMS_CFLAGS = @LCMS_CFLAGS@ +LCMS_LIBS = @LCMS_LIBS@ +LCMS_REQUIRED_VERSION = @LCMS_REQUIRED_VERSION@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ +LIBBACKTRACE_LIBS = @LIBBACKTRACE_LIBS@ +LIBHEIF_CFLAGS = @LIBHEIF_CFLAGS@ +LIBHEIF_LIBS = @LIBHEIF_LIBS@ +LIBHEIF_REQUIRED_VERSION = @LIBHEIF_REQUIRED_VERSION@ +LIBJXL_REQUIRED_VERSION = @LIBJXL_REQUIRED_VERSION@ +LIBLZMA_REQUIRED_VERSION = @LIBLZMA_REQUIRED_VERSION@ +LIBMYPAINT_CFLAGS = @LIBMYPAINT_CFLAGS@ +LIBMYPAINT_LIBS = @LIBMYPAINT_LIBS@ +LIBMYPAINT_REQUIRED_VERSION = @LIBMYPAINT_REQUIRED_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBPNG_REQUIRED_VERSION = @LIBPNG_REQUIRED_VERSION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ +LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ +LIBUNWIND_REQUIRED_VERSION = @LIBUNWIND_REQUIRED_VERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CURRENT_MINUS_AGE = @LT_CURRENT_MINUS_AGE@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +LT_VERSION_INFO = @LT_VERSION_INFO@ +LZMA_CFLAGS = @LZMA_CFLAGS@ +LZMA_LIBS = @LZMA_LIBS@ +MAIL = @MAIL@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MIME_INFO_CFLAGS = @MIME_INFO_CFLAGS@ +MIME_INFO_LIBS = @MIME_INFO_LIBS@ +MIME_TYPES = @MIME_TYPES@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MMX_EXTRA_CFLAGS = @MMX_EXTRA_CFLAGS@ +MNG_CFLAGS = @MNG_CFLAGS@ +MNG_LIBS = @MNG_LIBS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +MYPAINT_BRUSHES_CFLAGS = @MYPAINT_BRUSHES_CFLAGS@ +MYPAINT_BRUSHES_LIBS = @MYPAINT_BRUSHES_LIBS@ +NATIVE_GLIB_CFLAGS = @NATIVE_GLIB_CFLAGS@ +NATIVE_GLIB_LIBS = @NATIVE_GLIB_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENEXR_CFLAGS = @OPENEXR_CFLAGS@ +OPENEXR_LIBS = @OPENEXR_LIBS@ +OPENEXR_REQUIRED_VERSION = @OPENEXR_REQUIRED_VERSION@ +OPENJPEG_CFLAGS = @OPENJPEG_CFLAGS@ +OPENJPEG_LIBS = @OPENJPEG_LIBS@ +OPENJPEG_REQUIRED_VERSION = @OPENJPEG_REQUIRED_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGOCAIRO_CFLAGS = @PANGOCAIRO_CFLAGS@ +PANGOCAIRO_LIBS = @PANGOCAIRO_LIBS@ +PANGOCAIRO_REQUIRED_VERSION = @PANGOCAIRO_REQUIRED_VERSION@ +PATHSEP = @PATHSEP@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PERL_REQUIRED_VERSION = @PERL_REQUIRED_VERSION@ +PERL_VERSION = @PERL_VERSION@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PNG_CFLAGS = @PNG_CFLAGS@ +PNG_LIBS = @PNG_LIBS@ +POFILES = @POFILES@ +POPPLER_CFLAGS = @POPPLER_CFLAGS@ +POPPLER_DATA_CFLAGS = @POPPLER_DATA_CFLAGS@ +POPPLER_DATA_LIBS = @POPPLER_DATA_LIBS@ +POPPLER_DATA_REQUIRED_VERSION = @POPPLER_DATA_REQUIRED_VERSION@ +POPPLER_LIBS = @POPPLER_LIBS@ +POPPLER_REQUIRED_VERSION = @POPPLER_REQUIRED_VERSION@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +PYBIN_PATH = @PYBIN_PATH@ +PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@ +PYCAIRO_LIBS = @PYCAIRO_LIBS@ +PYGIMP_EXTRA_CFLAGS = @PYGIMP_EXTRA_CFLAGS@ +PYGTK_CFLAGS = @PYGTK_CFLAGS@ +PYGTK_CODEGEN = @PYGTK_CODEGEN@ +PYGTK_DEFSDIR = @PYGTK_DEFSDIR@ +PYGTK_LIBS = @PYGTK_LIBS@ +PYLINK_LIBS = @PYLINK_LIBS@ +PYTHON = @PYTHON@ +PYTHON2_REQUIRED_VERSION = @PYTHON2_REQUIRED_VERSION@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +RSVG_REQUIRED_VERSION = @RSVG_REQUIRED_VERSION@ +RT_LIBS = @RT_LIBS@ +SCREENSHOT_LIBS = @SCREENSHOT_LIBS@ +SED = @SED@ +SENDMAIL = @SENDMAIL@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKET_LIBS = @SOCKET_LIBS@ +SSE2_EXTRA_CFLAGS = @SSE2_EXTRA_CFLAGS@ +SSE4_1_EXTRA_CFLAGS = @SSE4_1_EXTRA_CFLAGS@ +SSE_EXTRA_CFLAGS = @SSE_EXTRA_CFLAGS@ +STRIP = @STRIP@ +SVG_CFLAGS = @SVG_CFLAGS@ +SVG_LIBS = @SVG_LIBS@ +SYMPREFIX = @SYMPREFIX@ +TIFF_LIBS = @TIFF_LIBS@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WEBKIT_CFLAGS = @WEBKIT_CFLAGS@ +WEBKIT_LIBS = @WEBKIT_LIBS@ +WEBKIT_REQUIRED_VERSION = @WEBKIT_REQUIRED_VERSION@ +WEBPDEMUX_CFLAGS = @WEBPDEMUX_CFLAGS@ +WEBPDEMUX_LIBS = @WEBPDEMUX_LIBS@ +WEBPMUX_CFLAGS = @WEBPMUX_CFLAGS@ +WEBPMUX_LIBS = @WEBPMUX_LIBS@ +WEBP_CFLAGS = @WEBP_CFLAGS@ +WEBP_LIBS = @WEBP_LIBS@ +WEBP_REQUIRED_VERSION = @WEBP_REQUIRED_VERSION@ +WEB_PAGE = @WEB_PAGE@ +WIN32_LARGE_ADDRESS_AWARE = @WIN32_LARGE_ADDRESS_AWARE@ +WINDRES = @WINDRES@ +WMF_CFLAGS = @WMF_CFLAGS@ +WMF_CONFIG = @WMF_CONFIG@ +WMF_LIBS = @WMF_LIBS@ +WMF_REQUIRED_VERSION = @WMF_REQUIRED_VERSION@ +XDG_EMAIL = @XDG_EMAIL@ +XFIXES_CFLAGS = @XFIXES_CFLAGS@ +XFIXES_LIBS = @XFIXES_LIBS@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_REQUIRED_VERSION = @XGETTEXT_REQUIRED_VERSION@ +XMC_CFLAGS = @XMC_CFLAGS@ +XMC_LIBS = @XMC_LIBS@ +XMKMF = @XMKMF@ +XMLLINT = @XMLLINT@ +XMU_LIBS = @XMU_LIBS@ +XPM_LIBS = @XPM_LIBS@ +XSLTPROC = @XSLTPROC@ +XVFB_RUN = @XVFB_RUN@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +Z_LIBS = @Z_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gimpdatadir = @gimpdatadir@ +gimpdir = @gimpdir@ +gimplocaledir = @gimplocaledir@ +gimpplugindir = @gimpplugindir@ +gimpsysconfdir = @gimpsysconfdir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = $(gimpplugindir)/plug-ins/gradient-flare +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +manpage_gimpdir = @manpage_gimpdir@ +mkdir_p = @mkdir_p@ +ms_librarian = @ms_librarian@ +mypaint_brushes_dir = @mypaint_brushes_dir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@OS_WIN32_TRUE@mwindows = -mwindows +@OS_WIN32_FALSE@libm = -lm +libgimpui = $(top_builddir)/libgimp/libgimpui-$(GIMP_API_VERSION).la +libgimpconfig = $(top_builddir)/libgimpconfig/libgimpconfig-$(GIMP_API_VERSION).la +libgimpwidgets = $(top_builddir)/libgimpwidgets/libgimpwidgets-$(GIMP_API_VERSION).la +libgimp = $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la +libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la +libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la +libgimpmath = $(top_builddir)/libgimpmath/libgimpmath-$(GIMP_API_VERSION).la +@HAVE_WINDRES_TRUE@GIMPPLUGINRC = $(top_builddir)/build/windows/gimp-plug-ins.rc +@HAVE_WINDRES_TRUE@gradient_flare_RC = gradient-flare.rc.o +AM_LDFLAGS = $(mwindows) +SUBDIRS = flares +gradient_flare_SOURCES = gradient-flare.c +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + $(GTK_CFLAGS) \ + $(GEGL_CFLAGS) \ + -I$(includedir) + +LDADD = \ + $(libm) \ + $(libgimpui) \ + $(libgimpwidgets) \ + $(libgimpconfig) \ + $(libgimp) \ + $(libgimpcolor) \ + $(libgimpmath) \ + $(libgimpbase) \ + $(GTK_LIBS) \ + $(GEGL_LIBS) \ + $(RT_LIBS) \ + $(INTLLIBS) \ + $(gradient_flare_RC) + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/build/windows/gimprc-plug-ins.rule $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu plug-ins/gradient-flare/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plug-ins/gradient-flare/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/build/windows/gimprc-plug-ins.rule $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libexecPROGRAMS: $(libexec_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-libexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libexecdir)" && rm -f $$files + +clean-libexecPROGRAMS: + @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +gradient-flare$(EXEEXT): $(gradient_flare_OBJECTS) $(gradient_flare_DEPENDENCIES) $(EXTRA_gradient_flare_DEPENDENCIES) + @rm -f gradient-flare$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gradient_flare_OBJECTS) $(gradient_flare_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gradient-flare.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(PROGRAMS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libexecdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libexecPROGRAMS clean-libtool \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/gradient-flare.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-libexecPROGRAMS + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/gradient-flare.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-libexecPROGRAMS + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-generic \ + clean-libexecPROGRAMS clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libexecPROGRAMS install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-libexecPROGRAMS + +.PRECIOUS: Makefile + + +# `windres` seems a very stupid tool and it breaks with double shlashes +# in parameter paths. Strengthen the rule a little. +@HAVE_WINDRES_TRUE@%.rc.o: +@HAVE_WINDRES_TRUE@ $(WINDRES) --define ORIGINALFILENAME_STR="$*$(EXEEXT)" \ +@HAVE_WINDRES_TRUE@ --define INTERNALNAME_STR="$*" \ +@HAVE_WINDRES_TRUE@ --define TOP_SRCDIR="`echo $(top_srcdir) | sed 's*//*/*'`" \ +@HAVE_WINDRES_TRUE@ -I"`echo $(top_srcdir)/app | sed 's%/\+%/%'`" \ +@HAVE_WINDRES_TRUE@ -I"`echo $(top_builddir)/app | sed 's%/\+%/%'`"\ +@HAVE_WINDRES_TRUE@ -I"`echo $(top_builddir) | sed 's%/\+%/%'`"\ +@HAVE_WINDRES_TRUE@ $(GIMPPLUGINRC) $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/plug-ins/gradient-flare/README b/plug-ins/gradient-flare/README new file mode 100644 index 0000000..92c1095 --- /dev/null +++ b/plug-ins/gradient-flare/README @@ -0,0 +1,99 @@ +========================================================================== + + GFlare plug-in ver 0.25 + + Eiichi Takamori <taka@ma1.seikyou.ne.jp> + +========================================================================== + + GFlare is a plug-in for GIMP. The name "GFlare" is short for +"Gradient Flare". It renders lense flare effect using custom +gradients. The basic idea is suggested by Marcelo Malheiros, +originally based on a 3DStudio MAX plug-in called LenZFX: + http://www.digimation.com/techsupp/lzfxfeat.htm + +INSTALL: + +1) Edit Makefile, if needed. + +2) Type "make install". + +3) Type "make install-data" if needed. (It copies sample gradients and + gflares under ~/.gimp) + +3) Add new entry to ~/.gimp/gimprc as + (gflare-path "${gimp_dir}/gflares:${gimp_data_dir}/gflares") + +3) Run GIMP. The menu path is <Image>/Filters/Effects/GFlare. + + +HOW TO USE IT: + + The document is not yet done. Try and see. + + Main Dialog: + - Preview + click on it changes the position of GFlare + - Settings page + - Center, Radius (pixel), Rotation (degree), Hue Rotation (degree) + - Vector Angle (degree) and Vector Length (percentage to Radius) + - adaptive supersampling ... same as "Blend tool" + - Selector page + - ListBox + - New, Edit, Copy, Delete buttons. Edit button invokes GFlare Editor. + + GFlare Editor: + - General page: + - Glow page: + - Rays page: + - Second Flares page: + + WARNING: This plug-in is in development stage, and the code is very +alpha. The GFlare datafile format may be changed in future version. + + Suggestions and ideas for user interface, flare algorithm, etc. are +very welcome. + + +KNOWN BUGS: + + There are still lots of bugs, of course. ;-) + They seem related to GTK, and I don't know exactly how I can fix them. + + * It warns at startup as: + ** WARNING **: file gdkwindow.c: line 422 (gdk_window_move_resize): "window != NULL" + If you are annoyed, accompanying "gtkviewport.c.patch" will shut up + the warning. + * Edit button remains prelighted when GFlare Editor dialog is done. + * Dialogs are not shown quickly at startup. + * Sometimes note tab labels are disappeared. + * Sometimes it crashes, but I don't know yet why it happens. + +TODO: + * Random hue scattering for Second Flares. + * Improve internal gradients. + * Currently number of Second Flares is fixed(30). + * Change opacity for one second flare dynamically, in inverse + proportion to the size of it. + * Reduce dialog size + * Add tweak ability "How to combine Glow, Rays, Second Flares in + what order" + + +CREDITS: + + Marcelo Marheiros and Federico Mena Quintero suggested a lot of +ideas. Very Thanks!! + + Marcelo made gradients whose names end with _1, _2, etc. The +gradients whose names end with _101, _102 etc. are mine. + + Quartic did awful Gradient Editor, and gradients PDB procedures. + + A fair proportion of this code was taken from: + + GIMP - The GNU Image Manipulation Program + Copyright (C) 1995 Spencer Kimball and Peter Mattis + + Gradient editor module copyight (C) 1996-1997 Federico Mena Quintero + federico@nuclecu.unam.mx diff --git a/plug-ins/gradient-flare/flares/Bright_Star b/plug-ins/gradient-flare/flares/Bright_Star new file mode 100644 index 0000000..e14ba49 --- /dev/null +++ b/plug-ins/gradient-flare/flares/Bright_Star @@ -0,0 +1,18 @@ +GIMP GFlare 0.25 +100.000000 NORMAL +100.000000 NORMAL +75.000000 SCREEN +Flare\040Glow\040Radial\0401 +%white +%white +75.000000 0.000000 0.000000 +Flare\040Rays\040Radial\0401 +%white +Flare\040Rays\040Size\0401 +100.000000 -75.000000 0.000000 +16 20.000000 +%blue_grad +%random +%random +16.000000 0.000000 13.600000 +POLYGON 6 1 diff --git a/plug-ins/gradient-flare/flares/Classic b/plug-ins/gradient-flare/flares/Classic new file mode 100644 index 0000000..81a7562 --- /dev/null +++ b/plug-ins/gradient-flare/flares/Classic @@ -0,0 +1,18 @@ +GIMP GFlare 0.25 +100.000000 NORMAL +40.000000 SCREEN +20.000000 SCREEN +Flare\040Glow\040Radial\0403 +%white +%white +85.000000 0.000000 0.000000 +%white_grad +%white +%random +125.000000 0.000000 0.000000 +85 60.000000 +Flare\040Glow\040Radial\0404 +%random +%random +20.000000 0.000000 0.000000 +CIRCLE 6 1 diff --git a/plug-ins/gradient-flare/flares/Default b/plug-ins/gradient-flare/flares/Default new file mode 100644 index 0000000..95e257f --- /dev/null +++ b/plug-ins/gradient-flare/flares/Default @@ -0,0 +1,18 @@ +GIMP GFlare 0.25 +95.300003 NORMAL +23.000000 ADDITION +20.900000 SCREEN +Radial\040Glow\0401 +%white +%white +100.000000 0.000000 -145.899994 +%white_grad +%white_grad +%random +70.400002 0.000000 0.000000 +21 87.300003 +Flare\040Radial\040103 +Flare\040Sizefac\040101 +%random +40.000000 0 0 +CIRCLE 6 1 diff --git a/plug-ins/gradient-flare/flares/Distant_Sun b/plug-ins/gradient-flare/flares/Distant_Sun new file mode 100644 index 0000000..9d71357 --- /dev/null +++ b/plug-ins/gradient-flare/flares/Distant_Sun @@ -0,0 +1,18 @@ +GIMP GFlare 0.25 +100.000000 NORMAL +90.000000 ADDITION +50.000000 SCREEN +Flare\040Radial\040102 +%white +%white +136.000000 0.000000 55.000000 +%yellow_grad +Flare\040Glow\040Angular\0401 +%random +110.000000 140.000000 -12.000000 +63 90.000000 +Flare\040Glow\040Radial\0404 +Flare\040Rays\040Size\0401 +%yellow_grad +30.000000 30.000000 40.000000 +POLYGON 6 1 diff --git a/plug-ins/gradient-flare/flares/GFlare_101 b/plug-ins/gradient-flare/flares/GFlare_101 new file mode 100644 index 0000000..ce064c6 --- /dev/null +++ b/plug-ins/gradient-flare/flares/GFlare_101 @@ -0,0 +1,18 @@ +GIMP GFlare 0.25 +100.000000 NORMAL +50.000000 NORMAL +35.500000 NORMAL +Flare\040Radial\040101 +%white +%white +100.000000 0.000000 0.000000 +%white_grad +%random +%random +100.000000 0.000000 0.000000 +40 50.000000 +Flare\040Glow\040Radial\0401 +%random +%random +40.000000 0 0 +CIRCLE 6 1 diff --git a/plug-ins/gradient-flare/flares/GFlare_102 b/plug-ins/gradient-flare/flares/GFlare_102 new file mode 100644 index 0000000..1540c2d --- /dev/null +++ b/plug-ins/gradient-flare/flares/GFlare_102 @@ -0,0 +1,18 @@ +GIMP GFlare 0.25 +100.000000 NORMAL +62.799999 NORMAL +37.900002 SCREEN +Flare\040Radial\040102 +%white +%white +100.000000 0.000000 -85.300003 +%red_grad +%random +%random +100.000000 0.000000 -155.899994 +40 20.000000 +Flare\040Radial\040102 +%random +Skyline +40.000000 0 0 +CIRCLE 6 3 diff --git a/plug-ins/gradient-flare/flares/Hidden_Planet b/plug-ins/gradient-flare/flares/Hidden_Planet new file mode 100644 index 0000000..ee5ec6a --- /dev/null +++ b/plug-ins/gradient-flare/flares/Hidden_Planet @@ -0,0 +1,18 @@ +GIMP GFlare 0.25 +100.000000 NORMAL +100.000000 NORMAL +100.000000 NORMAL +Flare\040Glow\040Radial\0402 +Flare\040Glow\040Angular\0401 +%white +100.000000 0.000000 0.000000 +Flare\040Rays\040Radial\0402 +%white +%white +50.000000 90.000000 0.000000 +2 85.000000 +%white +%white +%white +0.000000 0.000000 0.000000 +CIRCLE 6 1 diff --git a/plug-ins/gradient-flare/flares/Makefile.am b/plug-ins/gradient-flare/flares/Makefile.am new file mode 100644 index 0000000..930cf1f --- /dev/null +++ b/plug-ins/gradient-flare/flares/Makefile.am @@ -0,0 +1,14 @@ +## Process this file with automake to produce Makefile.in + +flaredir = $(gimpdatadir)/gflare + +flare_DATA = \ + Bright_Star \ + Classic \ + Distant_Sun \ + Default \ + GFlare_101 \ + GFlare_102 \ + Hidden_Planet + +EXTRA_DIST = $(flare_DATA) diff --git a/plug-ins/gradient-flare/flares/Makefile.in b/plug-ins/gradient-flare/flares/Makefile.in new file mode 100644 index 0000000..6689121 --- /dev/null +++ b/plug-ins/gradient-flare/flares/Makefile.in @@ -0,0 +1,811 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = plug-ins/gradient-flare/flares +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/m4macros/alsa.m4 \ + $(top_srcdir)/m4macros/ax_compare_version.m4 \ + $(top_srcdir)/m4macros/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4macros/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4macros/ax_prog_cc_for_build.m4 \ + $(top_srcdir)/m4macros/ax_prog_perl_version.m4 \ + $(top_srcdir)/m4macros/detectcflags.m4 \ + $(top_srcdir)/m4macros/pythondev.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(flaredir)" +DATA = $(flare_DATA) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +AA_LIBS = @AA_LIBS@ +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +ALL_LINGUAS = @ALL_LINGUAS@ +ALSA_CFLAGS = @ALSA_CFLAGS@ +ALSA_LIBS = @ALSA_LIBS@ +ALTIVEC_EXTRA_CFLAGS = @ALTIVEC_EXTRA_CFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPSTREAM_UTIL = @APPSTREAM_UTIL@ +AR = @AR@ +AS = @AS@ +ATK_CFLAGS = @ATK_CFLAGS@ +ATK_LIBS = @ATK_LIBS@ +ATK_REQUIRED_VERSION = @ATK_REQUIRED_VERSION@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BABL_CFLAGS = @BABL_CFLAGS@ +BABL_LIBS = @BABL_LIBS@ +BABL_REQUIRED_VERSION = @BABL_REQUIRED_VERSION@ +BUG_REPORT_URL = @BUG_REPORT_URL@ +BUILD_EXEEXT = @BUILD_EXEEXT@ +BUILD_OBJEXT = @BUILD_OBJEXT@ +BZIP2_LIBS = @BZIP2_LIBS@ +CAIRO_CFLAGS = @CAIRO_CFLAGS@ +CAIRO_LIBS = @CAIRO_LIBS@ +CAIRO_PDF_CFLAGS = @CAIRO_PDF_CFLAGS@ +CAIRO_PDF_LIBS = @CAIRO_PDF_LIBS@ +CAIRO_PDF_REQUIRED_VERSION = @CAIRO_PDF_REQUIRED_VERSION@ +CAIRO_REQUIRED_VERSION = @CAIRO_REQUIRED_VERSION@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CC_VERSION = @CC_VERSION@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@ +CPP_FOR_BUILD = @CPP_FOR_BUILD@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DESKTOP_DATADIR = @DESKTOP_DATADIR@ +DESKTOP_FILE_VALIDATE = @DESKTOP_FILE_VALIDATE@ +DLLTOOL = @DLLTOOL@ +DOC_SHOOTER = @DOC_SHOOTER@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILE_AA = @FILE_AA@ +FILE_EXR = @FILE_EXR@ +FILE_HEIF = @FILE_HEIF@ +FILE_JP2_LOAD = @FILE_JP2_LOAD@ +FILE_JPEGXL = @FILE_JPEGXL@ +FILE_MNG = @FILE_MNG@ +FILE_PDF_SAVE = @FILE_PDF_SAVE@ +FILE_PS = @FILE_PS@ +FILE_WMF = @FILE_WMF@ +FILE_XMC = @FILE_XMC@ +FILE_XPM = @FILE_XPM@ +FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@ +FONTCONFIG_LIBS = @FONTCONFIG_LIBS@ +FONTCONFIG_REQUIRED_VERSION = @FONTCONFIG_REQUIRED_VERSION@ +FREETYPE2_REQUIRED_VERSION = @FREETYPE2_REQUIRED_VERSION@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +GDBUS_CODEGEN = @GDBUS_CODEGEN@ +GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@ +GDK_PIXBUF_CSOURCE = @GDK_PIXBUF_CSOURCE@ +GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@ +GDK_PIXBUF_REQUIRED_VERSION = @GDK_PIXBUF_REQUIRED_VERSION@ +GEGL = @GEGL@ +GEGL_CFLAGS = @GEGL_CFLAGS@ +GEGL_LIBS = @GEGL_LIBS@ +GEGL_MAJOR_MINOR_VERSION = @GEGL_MAJOR_MINOR_VERSION@ +GEGL_REQUIRED_VERSION = @GEGL_REQUIRED_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GEXIV2_CFLAGS = @GEXIV2_CFLAGS@ +GEXIV2_LIBS = @GEXIV2_LIBS@ +GEXIV2_REQUIRED_VERSION = @GEXIV2_REQUIRED_VERSION@ +GIMP_API_VERSION = @GIMP_API_VERSION@ +GIMP_APP_VERSION = @GIMP_APP_VERSION@ +GIMP_BINARY_AGE = @GIMP_BINARY_AGE@ +GIMP_COMMAND = @GIMP_COMMAND@ +GIMP_DATA_VERSION = @GIMP_DATA_VERSION@ +GIMP_FULL_NAME = @GIMP_FULL_NAME@ +GIMP_INTERFACE_AGE = @GIMP_INTERFACE_AGE@ +GIMP_MAJOR_VERSION = @GIMP_MAJOR_VERSION@ +GIMP_MICRO_VERSION = @GIMP_MICRO_VERSION@ +GIMP_MINOR_VERSION = @GIMP_MINOR_VERSION@ +GIMP_MKENUMS = @GIMP_MKENUMS@ +GIMP_MODULES = @GIMP_MODULES@ +GIMP_PACKAGE_REVISION = @GIMP_PACKAGE_REVISION@ +GIMP_PKGCONFIG_VERSION = @GIMP_PKGCONFIG_VERSION@ +GIMP_PLUGINS = @GIMP_PLUGINS@ +GIMP_PLUGIN_VERSION = @GIMP_PLUGIN_VERSION@ +GIMP_REAL_VERSION = @GIMP_REAL_VERSION@ +GIMP_RELEASE = @GIMP_RELEASE@ +GIMP_SYSCONF_VERSION = @GIMP_SYSCONF_VERSION@ +GIMP_TOOL_VERSION = @GIMP_TOOL_VERSION@ +GIMP_UNSTABLE = @GIMP_UNSTABLE@ +GIMP_USER_VERSION = @GIMP_USER_VERSION@ +GIMP_VERSION = @GIMP_VERSION@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GIO_UNIX_CFLAGS = @GIO_UNIX_CFLAGS@ +GIO_UNIX_LIBS = @GIO_UNIX_LIBS@ +GIO_WINDOWS_CFLAGS = @GIO_WINDOWS_CFLAGS@ +GIO_WINDOWS_LIBS = @GIO_WINDOWS_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_COMPILE_RESOURCES = @GLIB_COMPILE_RESOURCES@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GLIB_REQUIRED_VERSION = @GLIB_REQUIRED_VERSION@ +GMODULE_NO_EXPORT_CFLAGS = @GMODULE_NO_EXPORT_CFLAGS@ +GMODULE_NO_EXPORT_LIBS = @GMODULE_NO_EXPORT_LIBS@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GOBJECT_QUERY = @GOBJECT_QUERY@ +GREP = @GREP@ +GS_LIBS = @GS_LIBS@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +GTK_MAC_INTEGRATION_CFLAGS = @GTK_MAC_INTEGRATION_CFLAGS@ +GTK_MAC_INTEGRATION_LIBS = @GTK_MAC_INTEGRATION_LIBS@ +GTK_REQUIRED_VERSION = @GTK_REQUIRED_VERSION@ +GTK_UPDATE_ICON_CACHE = @GTK_UPDATE_ICON_CACHE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HARFBUZZ_CFLAGS = @HARFBUZZ_CFLAGS@ +HARFBUZZ_LIBS = @HARFBUZZ_LIBS@ +HARFBUZZ_REQUIRED_VERSION = @HARFBUZZ_REQUIRED_VERSION@ +HAVE_CXX14 = @HAVE_CXX14@ +HAVE_FINITE = @HAVE_FINITE@ +HAVE_ISFINITE = @HAVE_ISFINITE@ +HAVE_VFORK = @HAVE_VFORK@ +HOST_GLIB_COMPILE_RESOURCES = @HOST_GLIB_COMPILE_RESOURCES@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_REQUIRED_VERSION = @INTLTOOL_REQUIRED_VERSION@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +ISO_CODES_LOCALEDIR = @ISO_CODES_LOCALEDIR@ +ISO_CODES_LOCATION = @ISO_CODES_LOCATION@ +JPEG_LIBS = @JPEG_LIBS@ +JSON_GLIB_CFLAGS = @JSON_GLIB_CFLAGS@ +JSON_GLIB_LIBS = @JSON_GLIB_LIBS@ +JXL_CFLAGS = @JXL_CFLAGS@ +JXL_LIBS = @JXL_LIBS@ +JXL_THREADS_CFLAGS = @JXL_THREADS_CFLAGS@ +JXL_THREADS_LIBS = @JXL_THREADS_LIBS@ +LCMS_CFLAGS = @LCMS_CFLAGS@ +LCMS_LIBS = @LCMS_LIBS@ +LCMS_REQUIRED_VERSION = @LCMS_REQUIRED_VERSION@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ +LIBBACKTRACE_LIBS = @LIBBACKTRACE_LIBS@ +LIBHEIF_CFLAGS = @LIBHEIF_CFLAGS@ +LIBHEIF_LIBS = @LIBHEIF_LIBS@ +LIBHEIF_REQUIRED_VERSION = @LIBHEIF_REQUIRED_VERSION@ +LIBJXL_REQUIRED_VERSION = @LIBJXL_REQUIRED_VERSION@ +LIBLZMA_REQUIRED_VERSION = @LIBLZMA_REQUIRED_VERSION@ +LIBMYPAINT_CFLAGS = @LIBMYPAINT_CFLAGS@ +LIBMYPAINT_LIBS = @LIBMYPAINT_LIBS@ +LIBMYPAINT_REQUIRED_VERSION = @LIBMYPAINT_REQUIRED_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBPNG_REQUIRED_VERSION = @LIBPNG_REQUIRED_VERSION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ +LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ +LIBUNWIND_REQUIRED_VERSION = @LIBUNWIND_REQUIRED_VERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CURRENT_MINUS_AGE = @LT_CURRENT_MINUS_AGE@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +LT_VERSION_INFO = @LT_VERSION_INFO@ +LZMA_CFLAGS = @LZMA_CFLAGS@ +LZMA_LIBS = @LZMA_LIBS@ +MAIL = @MAIL@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MIME_INFO_CFLAGS = @MIME_INFO_CFLAGS@ +MIME_INFO_LIBS = @MIME_INFO_LIBS@ +MIME_TYPES = @MIME_TYPES@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MMX_EXTRA_CFLAGS = @MMX_EXTRA_CFLAGS@ +MNG_CFLAGS = @MNG_CFLAGS@ +MNG_LIBS = @MNG_LIBS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +MYPAINT_BRUSHES_CFLAGS = @MYPAINT_BRUSHES_CFLAGS@ +MYPAINT_BRUSHES_LIBS = @MYPAINT_BRUSHES_LIBS@ +NATIVE_GLIB_CFLAGS = @NATIVE_GLIB_CFLAGS@ +NATIVE_GLIB_LIBS = @NATIVE_GLIB_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENEXR_CFLAGS = @OPENEXR_CFLAGS@ +OPENEXR_LIBS = @OPENEXR_LIBS@ +OPENEXR_REQUIRED_VERSION = @OPENEXR_REQUIRED_VERSION@ +OPENJPEG_CFLAGS = @OPENJPEG_CFLAGS@ +OPENJPEG_LIBS = @OPENJPEG_LIBS@ +OPENJPEG_REQUIRED_VERSION = @OPENJPEG_REQUIRED_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGOCAIRO_CFLAGS = @PANGOCAIRO_CFLAGS@ +PANGOCAIRO_LIBS = @PANGOCAIRO_LIBS@ +PANGOCAIRO_REQUIRED_VERSION = @PANGOCAIRO_REQUIRED_VERSION@ +PATHSEP = @PATHSEP@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PERL_REQUIRED_VERSION = @PERL_REQUIRED_VERSION@ +PERL_VERSION = @PERL_VERSION@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PNG_CFLAGS = @PNG_CFLAGS@ +PNG_LIBS = @PNG_LIBS@ +POFILES = @POFILES@ +POPPLER_CFLAGS = @POPPLER_CFLAGS@ +POPPLER_DATA_CFLAGS = @POPPLER_DATA_CFLAGS@ +POPPLER_DATA_LIBS = @POPPLER_DATA_LIBS@ +POPPLER_DATA_REQUIRED_VERSION = @POPPLER_DATA_REQUIRED_VERSION@ +POPPLER_LIBS = @POPPLER_LIBS@ +POPPLER_REQUIRED_VERSION = @POPPLER_REQUIRED_VERSION@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +PYBIN_PATH = @PYBIN_PATH@ +PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@ +PYCAIRO_LIBS = @PYCAIRO_LIBS@ +PYGIMP_EXTRA_CFLAGS = @PYGIMP_EXTRA_CFLAGS@ +PYGTK_CFLAGS = @PYGTK_CFLAGS@ +PYGTK_CODEGEN = @PYGTK_CODEGEN@ +PYGTK_DEFSDIR = @PYGTK_DEFSDIR@ +PYGTK_LIBS = @PYGTK_LIBS@ +PYLINK_LIBS = @PYLINK_LIBS@ +PYTHON = @PYTHON@ +PYTHON2_REQUIRED_VERSION = @PYTHON2_REQUIRED_VERSION@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +RSVG_REQUIRED_VERSION = @RSVG_REQUIRED_VERSION@ +RT_LIBS = @RT_LIBS@ +SCREENSHOT_LIBS = @SCREENSHOT_LIBS@ +SED = @SED@ +SENDMAIL = @SENDMAIL@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKET_LIBS = @SOCKET_LIBS@ +SSE2_EXTRA_CFLAGS = @SSE2_EXTRA_CFLAGS@ +SSE4_1_EXTRA_CFLAGS = @SSE4_1_EXTRA_CFLAGS@ +SSE_EXTRA_CFLAGS = @SSE_EXTRA_CFLAGS@ +STRIP = @STRIP@ +SVG_CFLAGS = @SVG_CFLAGS@ +SVG_LIBS = @SVG_LIBS@ +SYMPREFIX = @SYMPREFIX@ +TIFF_LIBS = @TIFF_LIBS@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WEBKIT_CFLAGS = @WEBKIT_CFLAGS@ +WEBKIT_LIBS = @WEBKIT_LIBS@ +WEBKIT_REQUIRED_VERSION = @WEBKIT_REQUIRED_VERSION@ +WEBPDEMUX_CFLAGS = @WEBPDEMUX_CFLAGS@ +WEBPDEMUX_LIBS = @WEBPDEMUX_LIBS@ +WEBPMUX_CFLAGS = @WEBPMUX_CFLAGS@ +WEBPMUX_LIBS = @WEBPMUX_LIBS@ +WEBP_CFLAGS = @WEBP_CFLAGS@ +WEBP_LIBS = @WEBP_LIBS@ +WEBP_REQUIRED_VERSION = @WEBP_REQUIRED_VERSION@ +WEB_PAGE = @WEB_PAGE@ +WIN32_LARGE_ADDRESS_AWARE = @WIN32_LARGE_ADDRESS_AWARE@ +WINDRES = @WINDRES@ +WMF_CFLAGS = @WMF_CFLAGS@ +WMF_CONFIG = @WMF_CONFIG@ +WMF_LIBS = @WMF_LIBS@ +WMF_REQUIRED_VERSION = @WMF_REQUIRED_VERSION@ +XDG_EMAIL = @XDG_EMAIL@ +XFIXES_CFLAGS = @XFIXES_CFLAGS@ +XFIXES_LIBS = @XFIXES_LIBS@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_REQUIRED_VERSION = @XGETTEXT_REQUIRED_VERSION@ +XMC_CFLAGS = @XMC_CFLAGS@ +XMC_LIBS = @XMC_LIBS@ +XMKMF = @XMKMF@ +XMLLINT = @XMLLINT@ +XMU_LIBS = @XMU_LIBS@ +XPM_LIBS = @XPM_LIBS@ +XSLTPROC = @XSLTPROC@ +XVFB_RUN = @XVFB_RUN@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +Z_LIBS = @Z_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gimpdatadir = @gimpdatadir@ +gimpdir = @gimpdir@ +gimplocaledir = @gimplocaledir@ +gimpplugindir = @gimpplugindir@ +gimpsysconfdir = @gimpsysconfdir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +manpage_gimpdir = @manpage_gimpdir@ +mkdir_p = @mkdir_p@ +ms_librarian = @ms_librarian@ +mypaint_brushes_dir = @mypaint_brushes_dir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +flaredir = $(gimpdatadir)/gflare +flare_DATA = \ + Bright_Star \ + Classic \ + Distant_Sun \ + Default \ + GFlare_101 \ + GFlare_102 \ + Hidden_Planet + +EXTRA_DIST = $(flare_DATA) +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu plug-ins/gradient-flare/flares/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plug-ins/gradient-flare/flares/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-flareDATA: $(flare_DATA) + @$(NORMAL_INSTALL) + @list='$(flare_DATA)'; test -n "$(flaredir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(flaredir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(flaredir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(flaredir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(flaredir)" || exit $$?; \ + done + +uninstall-flareDATA: + @$(NORMAL_UNINSTALL) + @list='$(flare_DATA)'; test -n "$(flaredir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(flaredir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(flaredir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-flareDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-flareDATA + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-flareDATA \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags-am uninstall uninstall-am uninstall-flareDATA + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/plug-ins/gradient-flare/gradient-flare.c b/plug-ins/gradient-flare/gradient-flare.c new file mode 100644 index 0000000..731d76e --- /dev/null +++ b/plug-ins/gradient-flare/gradient-flare.c @@ -0,0 +1,5123 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GFlare plug-in -- lense flare effect by using custom gradients + * Copyright (C) 1997 Eiichi Takamori <taka@ma1.sekyou.ne.jp> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * + * A fair proportion of this code was taken from GIMP & Script-fu + * copyrighted by Spencer Kimball and Peter Mattis, and from Gradient + * Editor copyrighted by Federico Mena Quintero. (See copyright notice + * below) Thanks for senior GIMP hackers!! + * + * GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * Gradient editor module copyight (C) 1996-1997 Federico Mena Quintero + * federico@nuclecu.unam.mx + */ + +#include "config.h" + +#include <string.h> +#include <stdlib.h> +#include <errno.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <glib/gstdio.h> + +#include <glib-object.h> + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include "libgimp/stdplugins-intl.h" + +/* #define DEBUG */ + +#ifdef DEBUG +#define DEBUG_PRINT(X) g_print X +#else +#define DEBUG_PRINT(X) +#endif + +#define LUMINOSITY(PIX) (GIMP_RGB_LUMINANCE (PIX[0], PIX[1], PIX[2]) + 0.5) + +#define RESPONSE_RESCAN 1 + +#define PLUG_IN_PROC "plug-in-gflare" +#define PLUG_IN_BINARY "gradient-flare" +#define PLUG_IN_ROLE "gimp-gradient-flare" + +#define GRADIENT_NAME_MAX 256 +#define GRADIENT_RESOLUTION 360 + +#define GFLARE_NAME_MAX 256 +#define GFLARE_FILE_HEADER "GIMP GFlare 0.25\n" +#define SFLARE_NUM 30 + +#define DLG_PREVIEW_WIDTH 256 +#define DLG_PREVIEW_HEIGHT 256 +#define DLG_PREVIEW_MASK GDK_EXPOSURE_MASK | \ + GDK_BUTTON_PRESS_MASK +#define DLG_LISTBOX_WIDTH 80 +#define DLG_LISTBOX_HEIGHT 40 + +#define ED_PREVIEW_WIDTH 256 +#define ED_PREVIEW_HEIGHT 256 + +#define GM_PREVIEW_WIDTH 80 +#define GM_PREVIEW_HEIGHT 16 + +#define SCALE_WIDTH 80 + +#ifndef OPAQUE +#define OPAQUE 255 +#endif +#define GRAY50 128 + +#define GRADIENT_CACHE_SIZE 32 + +#define CALC_GLOW 0x01 +#define CALC_RAYS 0x02 +#define CALC_SFLARE 0x04 + +typedef struct _Preview Preview; + +typedef gchar GradientName[GRADIENT_NAME_MAX]; + +typedef enum +{ + GF_NORMAL = 0, + GF_ADDITION, + GF_OVERLAY, + GF_SCREEN, + GF_NUM_MODES +} GFlareMode; + +typedef enum +{ + GF_CIRCLE = 0, + GF_POLYGON, + GF_NUM_SHAPES +} GFlareShape; + +typedef struct +{ + gchar *name; + gchar *filename; + gdouble glow_opacity; + GFlareMode glow_mode; + gdouble rays_opacity; + GFlareMode rays_mode; + gdouble sflare_opacity; + GFlareMode sflare_mode; + GradientName glow_radial; + GradientName glow_angular; + GradientName glow_angular_size; + gdouble glow_size; + gdouble glow_rotation; + gdouble glow_hue; + GradientName rays_radial; + GradientName rays_angular; + GradientName rays_angular_size; + gdouble rays_size; + gdouble rays_rotation; + gdouble rays_hue; + gint rays_nspikes; + gdouble rays_thickness; + GradientName sflare_radial; + GradientName sflare_sizefac; + GradientName sflare_probability; + gdouble sflare_size; + gdouble sflare_rotation; + gdouble sflare_hue; + GFlareShape sflare_shape; + gint sflare_nverts; + guint32 sflare_seed; + gboolean random_seed; +} GFlare; + +typedef struct +{ + FILE *fp; + gint error; +} GFlareFile; + + +typedef enum +{ + PAGE_SETTINGS, + PAGE_SELECTOR, + PAGE_GENERAL, + PAGE_GLOW, + PAGE_RAYS, + PAGE_SFLARE +} PageNum; + + +typedef struct +{ + gint init; + GFlare *gflare; + GtkWidget *shell; + Preview *preview; + struct + { + gdouble x0, y0, x1, y1; + } pwin; + gboolean update_preview; + GtkWidget *notebook; + GtkWidget *sizeentry; + GtkWidget *asupsample_frame; + GtkListStore *selector_list; + GtkTreeSelection *selection; + gint init_params_done; +} GFlareDialog; + +typedef void (* GFlareEditorCallback) (gint updated, gpointer data); + +typedef struct +{ + gint init; + gint run; + GFlareEditorCallback callback; + gpointer calldata; + GFlare *target_gflare; + GFlare *gflare; + GtkWidget *shell; + Preview *preview; + GtkWidget *notebook; + PageNum cur_page; + GtkWidget *polygon_entry; + GtkWidget *polygon_toggle; + gint init_params_done; +} GFlareEditor; + +typedef struct +{ + gdouble x0; + gdouble y0; + gdouble x1; + gdouble y1; +} CalcBounds; + +typedef struct +{ + gint init; + gint type; + GFlare *gflare; + gdouble xcenter; + gdouble ycenter; + gdouble radius; + gdouble rotation; + gdouble hue; + gdouble vangle; + gdouble vlength; + + gint glow_opacity; + CalcBounds glow_bounds; + guchar *glow_radial; + guchar *glow_angular; + guchar *glow_angular_size; + gdouble glow_radius; + gdouble glow_rotation; + + gint rays_opacity; + CalcBounds rays_bounds; + guchar *rays_radial; + guchar *rays_angular; + guchar *rays_angular_size; + gdouble rays_radius; + gdouble rays_rotation; + gdouble rays_spike_mod; + gdouble rays_thinness; + + gint sflare_opacity; + GList *sflare_list; + guchar *sflare_radial; + guchar *sflare_sizefac; + guchar *sflare_probability; + gdouble sflare_radius; + gdouble sflare_rotation; + GFlareShape sflare_shape; + gdouble sflare_angle; + gdouble sflare_factor; +} CalcParams; + +/* + * What's the difference between (structure) CalcParams and GFlare ? + * well, radius and lengths are actual length for CalcParams where + * they are typically 0 to 100 for GFlares, and angles are G_PI based + * (radian) for CalcParams where they are degree for GFlares. et cetra. + * This is because convenience for dialog processing and for calculating. + * these conversion is taken place in calc init routines. see below. + */ + +typedef struct +{ + gdouble xcenter; + gdouble ycenter; + gdouble radius; + CalcBounds bounds; +} CalcSFlare; + +typedef struct +{ + const Babl *format; + gint bpp; + gint is_color; + gint has_alpha; + gint x, y, w, h; /* mask bounds */ +} DrawableInfo; + +typedef struct _GradientMenu GradientMenu; +typedef void (* GradientMenuCallback) (const gchar *gradient_name, + gpointer data); +struct _GradientMenu +{ + GtkWidget *preview; + GtkWidget *combo; + GradientMenuCallback callback; + gpointer callback_data; + GradientName gradient_name; +}; + +typedef gint (* PreviewInitFunc) (Preview *preview, + gpointer data); +typedef void (* PreviewRenderFunc) (Preview *preview, + guchar *buffer, + gint y, + gpointer data); +typedef void (* PreviewDeinitFunc) (Preview *preview, + gpointer data); + +struct _Preview +{ + GtkWidget *widget; + gint width; + gint height; + PreviewInitFunc init_func; + gpointer init_data; + PreviewRenderFunc render_func; + gpointer render_data; + PreviewDeinitFunc deinit_func; + gpointer deinit_data; + guint timeout_tag; + guint idle_tag; + gint init_done; + gint current_y; + gint drawn_y; + guchar *buffer; + guchar *full_image_buffer; +}; + +typedef struct +{ + gint tag; + gint got_gradients; + gint current_y; + gint drawn_y; + PreviewRenderFunc render_func; + guchar *buffer; +} PreviewIdle; + +typedef struct _GradientCacheItem GradientCacheItem; + +struct _GradientCacheItem +{ + GradientCacheItem *next; + GradientCacheItem *prev; + GradientName name; + guchar values[4 * GRADIENT_RESOLUTION]; +}; + +typedef struct +{ + gint xcenter; + gint ycenter; + gdouble radius; + gdouble rotation; + gdouble hue; + gdouble vangle; + gdouble vlength; + gint use_asupsample; + gint asupsample_max_depth; + gdouble asupsample_threshold; + gchar gflare_name[GFLARE_NAME_MAX]; +} PluginValues; + + +typedef void (* QueryFunc) (GtkWidget *, + gpointer, + gpointer); + +/*** + *** Global Functions Prototypes + **/ + +static void plugin_query (void); +static void plugin_run (const gchar *name, + gint nparams, + const GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals); + +static GFlare * gflare_new_with_default (const gchar *new_name); +static GFlare * gflare_dup (const GFlare *src, + const gchar *new_name); +static void gflare_copy (GFlare *dest, + const GFlare *src); +static GFlare * gflare_load (const gchar *filename, + const gchar *name); +static void gflare_save (GFlare *gflare); +static void gflare_name_copy (gchar *dest, + const gchar *src); + +static gint gflares_list_insert (GFlare *gflare); +static GFlare * gflares_list_lookup (const gchar *name); +static gint gflares_list_index (GFlare *gflare); +static gint gflares_list_remove (GFlare *gflare); +static void gflares_list_load_all (void); +static void gflares_list_free_all (void); + +static void calc_init_params (GFlare *gflare, + gint calc_type, + gdouble xcenter, + gdouble ycenter, + gdouble radius, + gdouble rotation, + gdouble hue, + gdouble vangle, + gdouble vlength); +static gint calc_init_progress (void); +static void calc_deinit (void); +static void calc_glow_pix (guchar *dest_pix, + gdouble x, + gdouble y); +static void calc_rays_pix (guchar *dest_pix, + gdouble x, + gdouble y); +static void calc_sflare_pix (guchar *dest_pix, + gdouble x, + gdouble y, + guchar *src_pix); +static void calc_gflare_pix (guchar *dest_pix, + gdouble x, + gdouble y, + guchar *src_pix); + +static gboolean dlg_run (void); +static void dlg_preview_calc_window (void); +static void ed_preview_calc_window (void); +static GtkWidget * ed_mode_menu_new (GFlareMode *mode_var); + +static Preview * preview_new (gint width, + gint height, + PreviewInitFunc init_func, + gpointer init_data, + PreviewRenderFunc render_func, + gpointer render_data, + PreviewDeinitFunc deinit_func, + gpointer deinit_data); +static void preview_free (Preview *preview); +static void preview_render_start (Preview *preview); +static void preview_render_end (Preview *preview); +static void preview_rgba_to_rgb (guchar *dest, + gint x, + gint y, + guchar *src); + +static void gradient_menu_init (void); +static void gradient_menu_rescan (void); +static GradientMenu * gradient_menu_new (GradientMenuCallback callback, + gpointer callback_data, + const gchar *default_gradient_name); +static void gradient_name_copy (gchar *dest, + const gchar *src); +static void gradient_name_encode (gchar *dest, + const gchar *src); +static void gradient_name_decode (gchar *dest, + const gchar *src); +static void gradient_init (void); +static void gradient_free (void); +static gchar ** gradient_get_list (gint *num_gradients); +static void gradient_get_values (const gchar *gradient_name, + guchar *values, + gint nvalues); +static void gradient_cache_flush (void); + +/* *** INSERT-FILE-END *** */ + +/** +*** Variables +**/ + +const GimpPlugInInfo PLUG_IN_INFO = +{ + NULL, /* init_proc */ + NULL, /* quit_proc */ + plugin_query, /* query_proc */ + plugin_run, /* run_proc */ +}; + +PluginValues pvals = +{ + 128, /* xcenter */ + 128, /* ycenter */ + 100.0, /* radius */ + 0.0, /* rotation */ + 0.0, /* hue */ + 60.0, /* vangle */ + 400.0, /* vlength */ + FALSE, /* use_asupsample */ + 3, /* asupsample_max_depth */ + 0.2, /* asupsample_threshold */ + "Default" /* gflare_name */ +}; + +GFlare default_gflare = +{ + NULL, /* name */ + NULL, /* filename */ + 100, /* glow_opacity */ + GF_NORMAL, /* glow_mode */ + 100, /* rays_opacity */ + GF_NORMAL, /* rays_mode */ + 100, /* sflare_opacity */ + GF_NORMAL, /* sflare_mode */ + "%red_grad", /* glow_radial */ + "%white", /* glow_angular */ + "%white", /* glow_angular_size */ + 100.0, /* glow_size */ + 0.0, /* glow_rotation */ + 0.0, /* glow_hue */ + "%white_grad",/* rays_radial */ + "%random", /* rays_angular */ + "%random", /* rays_angular_size */ + 100.0, /* rays_size */ + 0.0, /* rays_rotation */ + 0.0, /* rays_hue */ + 40, /* rays_nspikes */ + 20.0, /* rays_thickness */ + "%white_grad",/* sflare_radial */ + "%random", /* sflare_sizefac */ + "%random", /* sflare_probability */ + 40.0, /* sflare_size */ + 0.0, /* sflare_rotation */ + 0.0, /* sflare_hue */ + GF_CIRCLE, /* sflare_shape */ + 6, /* sflare_nverts */ + 0, /* sflare_seed */ + TRUE, /* random_seed */ +}; + +/* These are keywords to be written to disk files specifying flares. */ +/* They are not translated since we want gflare files to be compatible + across languages. */ +static const gchar *gflare_modes[] = +{ + "NORMAL", + "ADDITION", + "OVERLAY", + "SCREEN" +}; + +static const gchar *gflare_shapes[] = +{ + "CIRCLE", + "POLYGON" +}; + +/* These are for menu entries, so they are translated. */ +static const gchar *gflare_menu_modes[] = +{ + N_("Normal"), + N_("Addition"), + N_("Overlay"), + N_("Screen") +}; + +static gint32 image_ID; +static gint32 drawable_ID; +static DrawableInfo dinfo; +static GFlareDialog *dlg = NULL; +static GFlareEditor *ed = NULL; +static GList *gflares_list = NULL; +static gint num_gflares = 0; +static gchar *gflare_path = NULL; +static CalcParams calc; +static GList *gradient_menus; +static gchar **gradient_names = NULL; +static gint num_gradient_names = 0; +static GradientCacheItem *gradient_cache_head = NULL; +static gint gradient_cache_count = 0; + + +static const gchar *internal_gradients[] = +{ + "%white", "%white_grad", "%red_grad", "%blue_grad", "%yellow_grad", "%random" +}; + +#ifdef DEBUG +static gint get_values_external_count = 0; +static clock_t get_values_external_clock = 0; +#endif + + +/** +*** +++ Static Functions Prototypes +**/ + +static void plugin_do (void); + +static void plugin_do_non_asupsample (GeglBuffer *src_buffer, + GeglBuffer *dest_buffer); +static void plugin_do_asupsample (GeglBuffer *src_buffer, + GeglBuffer *dest_buffer); +static void plugin_render_func (gdouble x, + gdouble y, + GimpRGB *color, + gpointer data); +static void plugin_put_pixel_func (gint ix, + gint iy, + GimpRGB *color, + gpointer data); +static void plugin_progress_func (gint y1, + gint y2, + gint curr_y, + gpointer data); + +static GFlare * gflare_new (void); +static void gflare_free (GFlare *gflare); +static void gflare_read_int (gint *intvar, + GFlareFile *gf); +static void gflare_read_double (gdouble *dblvar, + GFlareFile *gf); +static void gflare_read_gradient_name (gchar *name, + GFlareFile *gf); +static void gflare_read_shape (GFlareShape *shape, + GFlareFile *gf); +static void gflare_read_mode (GFlareMode *mode, + GFlareFile *gf); +static void gflare_write_gradient_name (gchar *name, + FILE *fp); + +static gint calc_sample_one_gradient (void); +static void calc_place_sflare (void); +static void calc_get_gradient (guchar *pix, + guchar *gradient, + gdouble pos); +static gdouble fmod_positive (gdouble x, + gdouble m); +static void calc_paint_func (guchar *dest, + guchar *src1, + guchar *src2, + gint opacity, + GFlareMode mode); +static void calc_combine (guchar *dest, + guchar *src1, + guchar *src2, + gint opacity); +static void calc_addition (guchar *dest, + guchar *src1, + guchar *src2); +static void calc_screen (guchar *dest, + guchar *src1, + guchar *src2); +static void calc_overlay (guchar *dest, + guchar *src1, + guchar *src2); + +static void dlg_setup_gflare (void); +static void dlg_preview_realize (GtkWidget *widget); +static gboolean dlg_preview_handle_event (GtkWidget *widget, + GdkEvent *event); +static void dlg_preview_update (void); +static gint dlg_preview_init_func (Preview *preview, + gpointer data); +static void dlg_preview_render_func (Preview *preview, + guchar *dest, + gint y, + gpointer data); +static void dlg_preview_deinit_func (Preview *preview, + gpointer data); +static void dlg_make_page_settings (GFlareDialog *dlg, + GtkWidget *notebook); +static void dlg_position_entry_callback (GtkWidget *widget, + gpointer data); +static void dlg_update_preview_callback (GtkWidget *widget, + gpointer data); +static void dlg_make_page_selector (GFlareDialog *dlg, + GtkWidget *notebook); + +static void dlg_selector_setup_listbox (void); +static void dlg_selector_list_item_callback (GtkTreeSelection *selection); + +static void dlg_selector_new_callback (GtkWidget *widget, + gpointer data); +static void dlg_selector_new_ok_callback (GtkWidget *widget, + const gchar *new_name, + gpointer data); + +static void dlg_selector_edit_callback (GtkWidget *widget, + gpointer data); +static void dlg_selector_edit_done_callback (gint updated, + gpointer data); + +static void dlg_selector_copy_callback (GtkWidget *widget, + gpointer data); +static void dlg_selector_copy_ok_callback (GtkWidget *widget, + const gchar *copy_name, + gpointer data); + +static void dlg_selector_delete_callback (GtkWidget *widget, + gpointer data); +static void dlg_selector_do_delete_callback (GtkWidget *widget, + gboolean delete, + gpointer data); + +static void ed_run (GtkWindow *parent, + GFlare *target_gflare, + GFlareEditorCallback callback, + gpointer calldata); +static void ed_destroy_callback (GtkWidget *widget, + GFlareEditor *ed); +static void ed_response (GtkWidget *widget, + gint response_id, + GFlareEditor *ed); +static void ed_make_page_general (GFlareEditor *ed, + GtkWidget *notebook); +static void ed_make_page_glow (GFlareEditor *ed, + GtkWidget *notebook); +static void ed_make_page_rays (GFlareEditor *ed, + GtkWidget *notebook); +static void ed_make_page_sflare (GFlareEditor *ed, + GtkWidget *notebook); +static void ed_put_gradient_menu (GtkWidget *table, + gint x, + gint y, + const gchar *caption, + GradientMenu *gm); +static void ed_mode_menu_callback (GtkWidget *widget, + gpointer data); +static void ed_gradient_menu_callback (const gchar *gradient_name, + gpointer data); +static void ed_shape_radio_callback (GtkWidget *widget, gpointer data); +static void ed_ientry_callback (GtkWidget *widget, gpointer data); +static void ed_page_map_callback (GtkWidget *widget, gpointer data); +static void ed_preview_update (void); +static gint ed_preview_init_func (Preview *preview, gpointer data); +static void ed_preview_deinit_func (Preview *preview, gpointer data); +static void ed_preview_render_func (Preview *preview, + guchar *buffer, gint y, gpointer data); +static void ed_preview_render_general (guchar *buffer, gint y); +static void ed_preview_render_glow (guchar *buffer, gint y); +static void ed_preview_render_rays (guchar *buffer, gint y); +static void ed_preview_render_sflare (guchar *buffer, gint y); + +static gint preview_render_start_2 (Preview *preview); +static gint preview_handle_idle (Preview *preview); + +static void gm_gradient_get_list (void); +static void gm_gradient_combo_fill (GradientMenu *gm, + const gchar *default_gradient); +static void gm_gradient_combo_callback (GtkWidget *widget, + gpointer data); +static void gm_preview_draw (GtkWidget *preview, + const gchar *gradient_name); +static void gm_combo_destroy_callback (GtkWidget *widget, + gpointer data); + +static void gradient_get_values_internal (const gchar *gradient_name, + guchar *values, gint nvalues); +static void gradient_get_blend (const guchar *fg, + const guchar *bg, + guchar *values, gint nvalues); +static void gradient_get_random (guchar *values, gint nvalues); +static void gradient_get_default (const gchar *name, + guchar *values, gint nvalues); +static void gradient_get_values_external (const gchar *gradient_name, + guchar *values, gint nvalues); +static void gradient_get_values_real_external (const gchar *gradient_name, + guchar *values, + gint nvalues, + gboolean reverse); +static GradientCacheItem *gradient_cache_lookup (const gchar *name, + gboolean *found); +static void gradient_cache_zorch (void); + +/* *** INSERT-FILE-END *** */ + + +/*************************************************************************/ +/** **/ +/** +++ Plug-in Interfaces **/ +/** **/ +/*************************************************************************/ + +MAIN () + +void +plugin_query (void) +{ + static const GimpParamDef args[]= + { + { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" }, + { GIMP_PDB_IMAGE, "image", "Input image (unused)" }, + { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" }, + { GIMP_PDB_STRING, "gflare-name", "The name of GFlare" }, + { GIMP_PDB_INT32, "xcenter", "X coordinate of center of GFlare" }, + { GIMP_PDB_INT32, "ycenter", "Y coordinate of center of GFlare" }, + { GIMP_PDB_FLOAT, "radius", "Radius of GFlare (pixel)" }, + { GIMP_PDB_FLOAT, "rotation", "Rotation of GFlare (degree)" }, + { GIMP_PDB_FLOAT, "hue", "Hue rotation of GFlare (degree)" }, + { GIMP_PDB_FLOAT, "vangle", "Vector angle for second flares (degree)" }, + { GIMP_PDB_FLOAT, "vlength", "Vector length for second flares (percentage to Radius)" }, + { GIMP_PDB_INT32, "use-asupsample", "Whether it uses or not adaptive supersampling while rendering (boolean)" }, + { GIMP_PDB_INT32, "asupsample-max-depth", "Max depth for adaptive supersampling"}, + { GIMP_PDB_FLOAT, "asupsample-threshold", "Threshold for adaptive supersampling"} + }; + + const gchar *help_string = + "This plug-in produces a lense flare effect using custom gradients. " + "In interactive call, the user can edit his/her own favorite lense flare " + "(GFlare) and render it. Edited gflare is saved automatically to " + "the folder in gflare-path, if it is defined in gimprc. " + "In non-interactive call, the user can only render one of GFlare " + "which has been stored in gflare-path already."; + + gimp_install_procedure (PLUG_IN_PROC, + N_("Produce a lense flare effect using gradients"), + help_string, + "Eiichi Takamori", + "Eiichi Takamori, and a lot of GIMP people", + "1997", + N_("_Gradient Flare..."), + "RGB*, GRAY*", + GIMP_PLUGIN, + G_N_ELEMENTS (args), 0, + args, NULL); + + gimp_plugin_menu_register (PLUG_IN_PROC, + "<Image>/Filters/Light and Shadow/Light"); +} + +void +plugin_run (const gchar *name, + gint nparams, + const GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals) +{ + static GimpParam values[2]; + GimpRunMode run_mode; + GimpPDBStatusType status = GIMP_PDB_SUCCESS; + gchar *path; + + INIT_I18N (); + gegl_init (NULL, NULL); + + *nreturn_vals = 1; + *return_vals = values; + + values[0].type = GIMP_PDB_STATUS; + values[0].data.d_status = status; + + run_mode = param[0].data.d_int32; + image_ID = param[1].data.d_image; + drawable_ID = param[2].data.d_drawable; + + dinfo.is_color = gimp_drawable_is_rgb (drawable_ID); + dinfo.has_alpha = gimp_drawable_has_alpha (drawable_ID); + + if (dinfo.is_color) + { + if (dinfo.has_alpha) + dinfo.format = babl_format ("R'G'B'A u8"); + else + dinfo.format = babl_format ("R'G'B' u8"); + } + else + { + if (dinfo.has_alpha) + dinfo.format = babl_format ("Y'A u8"); + else + dinfo.format = babl_format ("Y u8"); + } + + dinfo.bpp = babl_format_get_bytes_per_pixel (dinfo.format); + + if (! gimp_drawable_mask_intersect (drawable_ID, + &dinfo.x, &dinfo.y, &dinfo.w, &dinfo.h)) + return; + + /* + * Start gradient caching + */ + + gradient_init (); + + /* + * Parse gflare path from gimprc and load gflares + */ + + path = gimp_gimprc_query ("gflare-path"); + if (path) + { + gflare_path = g_filename_from_utf8 (path, -1, NULL, NULL, NULL); + g_free (path); + } + else + { + gchar *gimprc = gimp_personal_rc_file ("gimprc"); + gchar *full_path = gimp_config_build_data_path ("gflare"); + gchar *esc_path = g_strescape (full_path, NULL); + g_free (full_path); + + g_message (_("No %s in gimprc:\n" + "You need to add an entry like\n" + "(%s \"%s\")\n" + "to your %s file."), + "gflare-path", "gflare-path", + esc_path, gimp_filename_to_utf8 (gimprc)); + + g_free (gimprc); + g_free (esc_path); + } + + gflares_list_load_all (); + + switch (run_mode) + { + case GIMP_RUN_INTERACTIVE: + + /* Possibly retrieve data */ + gimp_get_data (PLUG_IN_PROC, &pvals); + + /* First acquire information with a dialog */ + if (! dlg_run ()) + return; + break; + + case GIMP_RUN_NONINTERACTIVE: + if (nparams != 14) + { + status = GIMP_PDB_CALLING_ERROR; + } + else + { + gflare_name_copy (pvals.gflare_name, param[3].data.d_string); + pvals.xcenter = param[4].data.d_int32; + pvals.ycenter = param[5].data.d_int32; + pvals.radius = param[6].data.d_float; + pvals.rotation = param[7].data.d_float; + pvals.hue = param[8].data.d_float; + pvals.vangle = param[9].data.d_float; + pvals.vlength = param[10].data.d_float; + pvals.use_asupsample = param[11].data.d_int32; + pvals.asupsample_max_depth = param[12].data.d_int32; + pvals.asupsample_threshold = param[13].data.d_float; + + if (pvals.radius <= 0) + status = GIMP_PDB_CALLING_ERROR; + } + break; + + case GIMP_RUN_WITH_LAST_VALS: + /* Possibly retrieve data */ + gimp_get_data (PLUG_IN_PROC, &pvals); + break; + + default: + break; + } + + if (status == GIMP_PDB_SUCCESS) + { + /* Make sure that the drawable is gray or RGB color */ + if (gimp_drawable_is_rgb (drawable_ID) || + gimp_drawable_is_gray (drawable_ID)) + { + gimp_progress_init (_("Gradient Flare")); + plugin_do (); + + if (run_mode != GIMP_RUN_NONINTERACTIVE) + gimp_displays_flush (); + + /* Store data */ + if (run_mode == GIMP_RUN_INTERACTIVE) + gimp_set_data (PLUG_IN_PROC, &pvals, sizeof (PluginValues)); + } + else + { + status = GIMP_PDB_EXECUTION_ERROR; + *nreturn_vals = 2; + values[1].type = GIMP_PDB_STRING; + values[1].data.d_string = _("Cannot operate on indexed color images."); + } + } + + values[0].data.d_status = status; + + /* + * Deinitialization + */ + gradient_free (); +} + +static void +plugin_do (void) +{ + GeglBuffer *src_buffer; + GeglBuffer *dest_buffer; + GFlare *gflare; + + gflare = gflares_list_lookup (pvals.gflare_name); + if (gflare == NULL) + { + /* FIXME */ + g_warning ("Not found %s\n", pvals.gflare_name); + return; + } + + /* Initialize calc params and gradients */ + calc_init_params (gflare, CALC_GLOW | CALC_RAYS | CALC_SFLARE, + pvals.xcenter, pvals.ycenter, + pvals.radius, pvals.rotation, pvals.hue, + pvals.vangle, pvals.vlength); + while (calc_init_progress ()) ; + + src_buffer = gimp_drawable_get_buffer (drawable_ID); + dest_buffer = gimp_drawable_get_shadow_buffer (drawable_ID); + + /* Render it ! */ + if (pvals.use_asupsample) + plugin_do_asupsample (src_buffer, dest_buffer); + else + plugin_do_non_asupsample (src_buffer, dest_buffer); + + g_object_unref (src_buffer); + g_object_unref (dest_buffer); + + gimp_progress_update (1.0); + + /* Clean up */ + calc_deinit (); + + gimp_drawable_merge_shadow (drawable_ID, TRUE); + gimp_drawable_update (drawable_ID, dinfo.x, dinfo.y, dinfo.w, dinfo.h); +} + +/* these routines should be almost rewritten anyway */ + +static void +plugin_do_non_asupsample (GeglBuffer *src_buffer, + GeglBuffer *dest_buffer) +{ + GeglBufferIterator *iter; + gint progress; + gint max_progress; + + progress = 0; + max_progress = dinfo.w * dinfo.h; + + iter = gegl_buffer_iterator_new (src_buffer, + GEGL_RECTANGLE (dinfo.x, dinfo.y, + dinfo.w, dinfo.h), 0, + dinfo.format, + GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2); + + gegl_buffer_iterator_add (iter, dest_buffer, + GEGL_RECTANGLE (dinfo.x, dinfo.y, + dinfo.w, dinfo.h), 0, + dinfo.format, + GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE); + + while (gegl_buffer_iterator_next (iter)) + { + const guchar *src_row = iter->items[0].data; + guchar *dest_row = iter->items[1].data; + gint row, y; + + for (row = 0, y = iter->items[0].roi.y; + row < iter->items[0].roi.height; + row++, y++) + { + const guchar *src = src_row; + guchar *dest = dest_row; + gint col, x; + + for (col = 0, x = iter->items[0].roi.x; + col < iter->items[0].roi.width; + col++, x++) + { + guchar src_pix[4]; + guchar dest_pix[4]; + gint b; + + for (b = 0; b < 3; b++) + src_pix[b] = dinfo.is_color ? src[b] : src[0]; + + src_pix[3] = dinfo.has_alpha ? src[dinfo.bpp - 1] : OPAQUE; + + calc_gflare_pix (dest_pix, x, y, src_pix); + + if (dinfo.is_color) + { + for (b = 0; b < 3; b++) + dest[b] = dest_pix[b]; + } + else + { + dest[0] = LUMINOSITY (dest_pix); + } + + if (dinfo.has_alpha) + dest[dinfo.bpp - 1] = dest_pix[3]; + + src += dinfo.bpp; + dest += dinfo.bpp; + } + + src_row += dinfo.bpp * iter->items[0].roi.width; + dest_row += dinfo.bpp * iter->items[1].roi.width; + } + + /* Update progress */ + progress += iter->items[0].roi.width * iter->items[0].roi.height; + gimp_progress_update ((double) progress / (double) max_progress); + } +} + +static void +plugin_do_asupsample (GeglBuffer *src_buffer, + GeglBuffer *dest_buffer) +{ + gimp_adaptive_supersample_area (dinfo.x, dinfo.y, + dinfo.x + dinfo.w - 1, dinfo.y + dinfo.h - 1, + pvals.asupsample_max_depth, + pvals.asupsample_threshold, + plugin_render_func, + src_buffer, + plugin_put_pixel_func, + dest_buffer, + plugin_progress_func, + NULL); +} + +/* + Adaptive supersampling callback functions + + These routines may look messy, since adaptive supersampling needs + pixel values in `double' (from 0.0 to 1.0) but calc_*_pix () returns + guchar values. */ + +static void +plugin_render_func (gdouble x, + gdouble y, + GimpRGB *color, + gpointer data) +{ + GeglBuffer *src_buffer = data; + guchar src_pix[4]; + guchar flare_pix[4]; + guchar src[4]; + gint b; + gint ix, iy; + + /* translate (0.5, 0.5) before convert to `int' so that it can surely + point the center of pixel */ + ix = floor (x + 0.5); + iy = floor (y + 0.5); + + gegl_buffer_sample (src_buffer, ix, iy, NULL, src, dinfo.format, + GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE); + + for (b = 0; b < 3; b++) + src_pix[b] = dinfo.is_color ? src[b] : src[0]; + src_pix[3] = dinfo.has_alpha ? src[dinfo.bpp - 1] : OPAQUE; + + calc_gflare_pix (flare_pix, x, y, src_pix); + + color->r = flare_pix[0] / 255.0; + color->g = flare_pix[1] / 255.0; + color->b = flare_pix[2] / 255.0; + color->a = flare_pix[3] / 255.0; +} + +static void +plugin_put_pixel_func (gint ix, + gint iy, + GimpRGB *color, + gpointer data) +{ + GeglBuffer *dest_buffer = data; + guchar dest[4]; + + if (dinfo.is_color) + { + dest[0] = color->r * 255; + dest[1] = color->g * 255; + dest[2] = color->b * 255; + } + else + { + dest[0] = gimp_rgb_luminance_uchar (color); + } + + if (dinfo.has_alpha) + dest[dinfo.bpp - 1] = color->a * 255; + + gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (ix, iy, 1, 1), 0, + dinfo.format, dest, GEGL_AUTO_ROWSTRIDE); +} + +static void +plugin_progress_func (gint y1, + gint y2, + gint curr_y, + gpointer data) +{ + gimp_progress_update ((double) curr_y / (double) (y2 - y1)); +} + +/*************************************************************************/ +/** **/ +/** +++ GFlare Routines **/ +/** **/ +/*************************************************************************/ + +/* + * These code are more or less based on Quartic's gradient.c, + * other gimp sources, and script-fu. + */ + +static GFlare * +gflare_new (void) +{ + GFlare *gflare = g_new0 (GFlare, 1); + + gflare->name = NULL; + gflare->filename = NULL; + + return gflare; +} + +static GFlare * +gflare_new_with_default (const gchar *new_name) +{ + return gflare_dup (&default_gflare, new_name); +} + +static GFlare * +gflare_dup (const GFlare *src, + const gchar *new_name) +{ + GFlare *dest = g_new0 (GFlare, 1); + + *dest = *src; + + dest->name = g_strdup (new_name); + dest->filename = NULL; + + return dest; +} + +static void +gflare_copy (GFlare *dest, + const GFlare *src) +{ + gchar *name, *filename; + + name = dest->name; + filename = dest->filename; + + *dest = *src; + + dest->name = name; + dest->filename =filename; +} + + +static void +gflare_free (GFlare *gflare) +{ + g_return_if_fail (gflare != NULL); + + g_free (gflare->name); + g_free (gflare->filename); + g_free (gflare); +} + +GFlare * +gflare_load (const gchar *filename, + const gchar *name) +{ + FILE *fp; + GFlareFile *gf; + GFlare *gflare; + gchar header[256]; + + g_return_val_if_fail (filename != NULL, NULL); + + fp = g_fopen (filename, "rb"); + if (!fp) + { + g_message (_("Failed to open GFlare file '%s': %s"), + gimp_filename_to_utf8 (filename), g_strerror (errno)); + return NULL; + } + + if (fgets (header, sizeof(header), fp) == NULL + || strcmp (header, GFLARE_FILE_HEADER) != 0) + { + g_warning (_("'%s' is not a valid GFlare file."), + gimp_filename_to_utf8 (filename)); + fclose (fp); + return NULL; + } + + gf = g_new (GFlareFile, 1); + gf->fp = fp; + gf->error = FALSE; + + gflare = gflare_new (); + gflare->name = g_strdup (name); + gflare->filename = g_strdup (filename); + + gflare_read_double (&gflare->glow_opacity, gf); + gflare_read_mode (&gflare->glow_mode, gf); + gflare_read_double (&gflare->rays_opacity, gf); + gflare_read_mode (&gflare->rays_mode, gf); + gflare_read_double (&gflare->sflare_opacity, gf); + gflare_read_mode (&gflare->sflare_mode, gf); + + gflare_read_gradient_name (gflare->glow_radial, gf); + gflare_read_gradient_name (gflare->glow_angular, gf); + gflare_read_gradient_name (gflare->glow_angular_size, gf); + gflare_read_double (&gflare->glow_size, gf); + gflare_read_double (&gflare->glow_rotation, gf); + gflare_read_double (&gflare->glow_hue, gf); + + gflare_read_gradient_name (gflare->rays_radial, gf); + gflare_read_gradient_name (gflare->rays_angular, gf); + gflare_read_gradient_name (gflare->rays_angular_size, gf); + gflare_read_double (&gflare->rays_size, gf); + gflare_read_double (&gflare->rays_rotation, gf); + gflare_read_double (&gflare->rays_hue, gf); + gflare_read_int (&gflare->rays_nspikes, gf); + gflare_read_double (&gflare->rays_thickness, gf); + + gflare_read_gradient_name (gflare->sflare_radial, gf); + gflare_read_gradient_name (gflare->sflare_sizefac, gf); + gflare_read_gradient_name (gflare->sflare_probability, gf); + gflare_read_double (&gflare->sflare_size, gf); + gflare_read_double (&gflare->sflare_hue, gf); + gflare_read_double (&gflare->sflare_rotation, gf); + gflare_read_shape (&gflare->sflare_shape, gf); + gflare_read_int (&gflare->sflare_nverts, gf); + gflare_read_int ((gint *) &gflare->sflare_seed, gf); + + if (gflare->sflare_seed == 0) + gflare->sflare_seed = g_random_int(); + + fclose (gf->fp); + + if (gf->error) + { + g_warning (_("invalid formatted GFlare file: %s\n"), filename); + g_free (gflare); + g_free (gf); + return NULL; + } + + g_free (gf); + + return gflare; +} + +static void +gflare_read_int (gint *intvar, + GFlareFile *gf) +{ + if (gf->error) + return; + + if (fscanf (gf->fp, "%d", intvar) != 1) + gf->error = TRUE; +} + +static void +gflare_read_double (gdouble *dblvar, + GFlareFile *gf) +{ + gchar buf[31]; + + if (gf->error) + return; + + if (fscanf (gf->fp, "%30s", buf) == 1) + *dblvar = g_ascii_strtod (buf, NULL); + else + gf->error = TRUE; +} + +static void +gflare_read_gradient_name (GradientName name, + GFlareFile *gf) +{ + gchar tmp[1024], dec[1024]; + + if (gf->error) + return; + + /* FIXME: this is buggy */ + + if (fscanf (gf->fp, "%1023s", tmp) == 1) + { + /* @GRADIENT_NAME */ + gradient_name_decode (dec, tmp); + gradient_name_copy (name, dec); + } + else + gf->error = TRUE; +} + +static void +gflare_read_shape (GFlareShape *shape, + GFlareFile *gf) +{ + gchar tmp[1024]; + gint i; + + if (gf->error) + return; + + if (fscanf (gf->fp, "%1023s", tmp) == 1) + { + for (i = 0; i < GF_NUM_SHAPES; i++) + if (strcmp (tmp, gflare_shapes[i]) == 0) + { + *shape = i; + return; + } + } + gf->error = TRUE; +} + +static void +gflare_read_mode (GFlareMode *mode, + GFlareFile *gf) +{ + gchar tmp[1024]; + gint i; + + if (gf->error) + return; + + if (fscanf (gf->fp, "%1023s", tmp) == 1) + { + for (i = 0; i < GF_NUM_MODES; i++) + if (strcmp (tmp, gflare_modes[i]) == 0) + { + *mode = i; + return; + } + } + gf->error = TRUE; +} + +static void +gflare_save (GFlare *gflare) +{ + FILE *fp; + gchar *path; + gchar buf[3][G_ASCII_DTOSTR_BUF_SIZE]; + static gboolean message_ok = FALSE; + + if (gflare->filename == NULL) + { + GList *list; + + if (gflare_path == NULL) + { + if (! message_ok) + { + gchar *gimprc = gimp_personal_rc_file ("gimprc"); + gchar *dir = gimp_personal_rc_file ("gflare"); + gchar *gflare_dir; + + gflare_dir = + g_strescape ("${gimp_dir}" G_DIR_SEPARATOR_S "gflare", NULL); + + g_message (_("GFlare '%s' is not saved. If you add a new entry " + "in '%s', like:\n" + "(gflare-path \"%s\")\n" + "and make a folder '%s', then you can save " + "your own GFlares into that folder."), + gflare->name, gimprc, gflare_dir, + gimp_filename_to_utf8 (dir)); + + g_free (gimprc); + g_free (gflare_dir); + g_free (dir); + + message_ok = TRUE; + } + + return; + } + + list = gimp_path_parse (gflare_path, 256, FALSE, NULL); + path = gimp_path_get_user_writable_dir (list); + gimp_path_free (list); + + if (! path) + path = g_strdup (gimp_directory ()); + + gflare->filename = g_build_filename (path, gflare->name, NULL); + + g_free (path); + } + + fp = g_fopen (gflare->filename, "wb"); + if (!fp) + { + g_message (_("Failed to write GFlare file '%s': %s"), + gimp_filename_to_utf8 (gflare->filename), g_strerror (errno)); + return; + } + + fprintf (fp, "%s", GFLARE_FILE_HEADER); + g_ascii_dtostr (buf[0], + G_ASCII_DTOSTR_BUF_SIZE, gflare->glow_opacity); + fprintf (fp, "%s %s\n", buf[0], gflare_modes[gflare->glow_mode]); + g_ascii_dtostr (buf[0], + G_ASCII_DTOSTR_BUF_SIZE, gflare->rays_opacity); + fprintf (fp, "%s %s\n", buf[0], gflare_modes[gflare->rays_mode]); + g_ascii_dtostr (buf[0], + G_ASCII_DTOSTR_BUF_SIZE, gflare->sflare_opacity); + fprintf (fp, "%s %s\n", buf[0], gflare_modes[gflare->sflare_mode]); + + gflare_write_gradient_name (gflare->glow_radial, fp); + gflare_write_gradient_name (gflare->glow_angular, fp); + gflare_write_gradient_name (gflare->glow_angular_size, fp); + g_ascii_dtostr (buf[0], + G_ASCII_DTOSTR_BUF_SIZE, gflare->glow_size); + g_ascii_dtostr (buf[1], + G_ASCII_DTOSTR_BUF_SIZE, gflare->glow_rotation); + g_ascii_dtostr (buf[2], + G_ASCII_DTOSTR_BUF_SIZE, gflare->glow_hue); + fprintf (fp, "%s %s %s\n", buf[0], buf[1], buf[2]); + + gflare_write_gradient_name (gflare->rays_radial, fp); + gflare_write_gradient_name (gflare->rays_angular, fp); + gflare_write_gradient_name (gflare->rays_angular_size, fp); + g_ascii_dtostr (buf[0], + G_ASCII_DTOSTR_BUF_SIZE, gflare->rays_size); + g_ascii_dtostr (buf[1], + G_ASCII_DTOSTR_BUF_SIZE, gflare->rays_rotation); + g_ascii_dtostr (buf[2], + G_ASCII_DTOSTR_BUF_SIZE, gflare->rays_hue); + fprintf (fp, "%s %s %s\n", buf[0], buf[1], buf[2]); + g_ascii_dtostr (buf[0], + G_ASCII_DTOSTR_BUF_SIZE, gflare->rays_thickness); + fprintf (fp, "%d %s\n", gflare->rays_nspikes, buf[0]); + + gflare_write_gradient_name (gflare->sflare_radial, fp); + gflare_write_gradient_name (gflare->sflare_sizefac, fp); + gflare_write_gradient_name (gflare->sflare_probability, fp); + g_ascii_dtostr (buf[0], + G_ASCII_DTOSTR_BUF_SIZE, gflare->sflare_size); + g_ascii_dtostr (buf[1], + G_ASCII_DTOSTR_BUF_SIZE, gflare->sflare_rotation); + g_ascii_dtostr (buf[2], + G_ASCII_DTOSTR_BUF_SIZE, gflare->sflare_hue); + fprintf (fp, "%s %s %s\n", buf[0], buf[1], buf[2]); + fprintf (fp, "%s %d %d\n", + gflare_shapes[gflare->sflare_shape], + gflare->sflare_nverts, gflare->sflare_seed); + + fclose (fp); +} + +static void +gflare_write_gradient_name (GradientName name, + FILE *fp) +{ + gchar enc[1024]; + + /* @GRADIENT_NAME */ + + /* encode white spaces and control characters (if any) */ + gradient_name_encode (enc, name); + + fprintf (fp, "%s\n", enc); +} + +static void +gflare_name_copy (gchar *dest, + const gchar *src) +{ + strncpy (dest, src, GFLARE_NAME_MAX - 1); + dest[GFLARE_NAME_MAX - 1] = '\0'; +} + +/*************************************************************************/ +/** **/ +/** +++ GFlares List **/ +/** **/ +/*************************************************************************/ + +static gint +gflare_compare (const GFlare *flare1, + const GFlare *flare2) +{ + return strcmp (flare1->name, flare2->name); +} + +static gint +gflares_list_insert (GFlare *gflare) +{ + num_gflares++; + gflares_list = g_list_insert_sorted (gflares_list, gflare, + (GCompareFunc) gflare_compare); + return gflares_list_index (gflare); +} + +static gint +gflare_compare_name (const GFlare *flare, + const gchar *name) +{ + return strcmp (flare->name, name); +} + +static GFlare * +gflares_list_lookup (const gchar *name) +{ + GList *llink; + llink = g_list_find_custom (gflares_list, name, + (GCompareFunc) gflare_compare_name); + return (llink) ? llink->data : NULL; +} + +static gint +gflares_list_index (GFlare *gflare) +{ + return g_list_index (gflares_list, gflare); +} + +static gint +gflares_list_remove (GFlare *gflare) +{ + GList *tmp; + gint n; + + n = 0; + tmp = gflares_list; + while (tmp) + { + if (tmp->data == gflare) + { + /* Found! */ + if (tmp->next == NULL) + num_gflares--; + gflares_list = g_list_remove (gflares_list, gflare); + return n; + } + tmp = tmp->next; + n++; + } + return -1; +} + +/* + * Load all gflares, which are founded in gflare-path-list, into gflares_list. + */ +static void +gflares_list_load_all (void) +{ + GList *path; + GList *list; + + /* Make sure to clear any existing gflares */ + gflares_list_free_all (); + + path = gimp_config_path_expand_to_files (gflare_path, NULL); + + for (list = path; list; list = g_list_next (list)) + { + GFileEnumerator *enumerator; + + enumerator = g_file_enumerate_children (list->data, + G_FILE_ATTRIBUTE_STANDARD_NAME "," + G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN "," + G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NONE, + NULL, NULL); + + if (enumerator) + { + GFileInfo *info; + + while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL))) + { + GFileType file_type = g_file_info_get_file_type (info); + + if (file_type == G_FILE_TYPE_REGULAR && + ! g_file_info_get_is_hidden (info)) + { + GFlare *gflare; + GFile *child; + gchar *filename; + gchar *basename; + + child = g_file_enumerator_get_child (enumerator, info); + + filename = g_file_get_path (child); + basename = g_file_get_basename (child); + + gflare = gflare_load (filename, basename); + + g_free (filename); + g_free (basename); + + if (gflare) + gflares_list_insert (gflare); + + g_object_unref (child); + } + + g_object_unref (info); + } + + g_object_unref (enumerator); + } + } + + g_list_free_full (path, (GDestroyNotify) g_object_unref); +} + +static void +gflares_list_free_all (void) +{ + g_list_free_full (gflares_list, (GDestroyNotify) gflare_free); + gflares_list = NULL; +} + +/*************************************************************************/ +/** **/ +/** +++ Calculator **/ +/** **/ +/*************************************************************************/ + + +/* + * These routines calculates pixel values of particular gflare, at + * specified point. The client which wants to get benefit from these + * calculation routines must call calc_init_params() first, and + * iterate calling calc_init_progress() until it returns FALSE. and + * must call calc_deinit() when job is done. + */ + +static void +calc_init_params (GFlare *gflare, + gint calc_type, + gdouble xcenter, + gdouble ycenter, + gdouble radius, + gdouble rotation, + gdouble hue, + gdouble vangle, + gdouble vlength) +{ + calc.type = calc_type; + calc.gflare = gflare; + calc.xcenter = xcenter; + calc.ycenter = ycenter; + calc.radius = radius; + calc.rotation = rotation * G_PI / 180.0; + calc.hue = hue; + calc.vangle = vangle * G_PI / 180.0; + calc.vlength = radius * vlength / 100.0; + calc.glow_radius = radius * gflare->glow_size / 100.0; + calc.rays_radius = radius * gflare->rays_size / 100.0; + calc.sflare_radius = radius * gflare->sflare_size / 100.0; + calc.glow_rotation = (rotation + gflare->glow_rotation) * G_PI / 180.0; + calc.rays_rotation = (rotation + gflare->rays_rotation) * G_PI / 180.0; + calc.sflare_rotation = (rotation + gflare->sflare_rotation) * G_PI / 180.0; + calc.glow_opacity = gflare->glow_opacity * 255 / 100.0; + calc.rays_opacity = gflare->rays_opacity * 255 / 100.0; + calc.sflare_opacity = gflare->sflare_opacity * 255 / 100.0; + + calc.glow_bounds.x0 = calc.xcenter - calc.glow_radius - 0.1; + calc.glow_bounds.x1 = calc.xcenter + calc.glow_radius + 0.1; + calc.glow_bounds.y0 = calc.ycenter - calc.glow_radius - 0.1; + calc.glow_bounds.y1 = calc.ycenter + calc.glow_radius + 0.1; + calc.rays_bounds.x0 = calc.xcenter - calc.rays_radius - 0.1; + calc.rays_bounds.x1 = calc.xcenter + calc.rays_radius + 0.1; + calc.rays_bounds.y0 = calc.ycenter - calc.rays_radius - 0.1; + calc.rays_bounds.y1 = calc.ycenter + calc.rays_radius + 0.1; + + /* Thanks to Marcelo Malheiros for this algorithm */ + calc.rays_thinness = log (gflare->rays_thickness / 100.0) / log(0.8); + + calc.rays_spike_mod = 1.0 / (2 * gflare->rays_nspikes); + + /* + Initialize part of sflare + The rest will be initialized in calc_sflare() + */ + calc.sflare_list = NULL; + calc.sflare_shape = gflare->sflare_shape; + if (calc.sflare_shape == GF_POLYGON) + { + calc.sflare_angle = 2 * G_PI / (2 * gflare->sflare_nverts); + calc.sflare_factor = 1.0 / cos (calc.sflare_angle); + } + + calc.glow_radial = NULL; + calc.glow_angular = NULL; + calc.glow_angular_size = NULL; + calc.rays_radial = NULL; + calc.rays_angular = NULL; + calc.rays_angular_size = NULL; + calc.sflare_radial = NULL; + calc.sflare_sizefac = NULL; + calc.sflare_probability = NULL; + + calc.init = TRUE; +} + +static int +calc_init_progress (void) +{ + if (calc_sample_one_gradient ()) + return TRUE; + calc_place_sflare (); + return FALSE; +} + +/* + Store samples of gradient into an array + this routine is called during Calc initialization + this code is very messy... :( */ +static int +calc_sample_one_gradient (void) +{ + static struct + { + guchar **values; + gint name_offset; + gint hue_offset; + gint gray; + } table[] = { + { + &calc.glow_radial, + G_STRUCT_OFFSET (GFlare, glow_radial), + G_STRUCT_OFFSET (GFlare, glow_hue), + FALSE + }, + { + &calc.glow_angular, + G_STRUCT_OFFSET (GFlare, glow_angular), + 0, + FALSE + }, + { + &calc.glow_angular_size, + G_STRUCT_OFFSET (GFlare, glow_angular_size), + 0, + TRUE + }, + { + &calc.rays_radial, + G_STRUCT_OFFSET (GFlare, rays_radial), + G_STRUCT_OFFSET (GFlare, rays_hue), + FALSE + }, + { + &calc.rays_angular, + G_STRUCT_OFFSET (GFlare, rays_angular), + 0, + FALSE + }, + { + &calc.rays_angular_size, + G_STRUCT_OFFSET (GFlare, rays_angular_size), + 0, + TRUE + }, + { + &calc.sflare_radial, + G_STRUCT_OFFSET (GFlare, sflare_radial), + G_STRUCT_OFFSET (GFlare, sflare_hue), + FALSE + }, + { + &calc.sflare_sizefac, + G_STRUCT_OFFSET (GFlare, sflare_sizefac), + 0, + TRUE + }, + { + &calc.sflare_probability, + G_STRUCT_OFFSET (GFlare, sflare_probability), + 0, + TRUE + } + }; + GFlare *gflare = calc.gflare; + GradientName *grad_name; + guchar *gradient; + gdouble hue_deg; + gint i, j, hue; + + for (i = 0; i < G_N_ELEMENTS (table); i++) + { + if (*(table[i].values) == NULL) + { + /* @GRADIENT_NAME */ + grad_name = (GradientName *) ((char*) gflare + table[i].name_offset); + gradient = *(table[i].values) = g_new (guchar, 4 * GRADIENT_RESOLUTION); + gradient_get_values (*grad_name, gradient, GRADIENT_RESOLUTION); + + /* + * Do hue rotation, if needed + */ + + if (table[i].hue_offset != 0) + { + hue_deg = calc.hue + *(gdouble *) ((char*) gflare + table[i].hue_offset); + hue = (gint) (hue_deg / 360.0 * 256.0) % 256; + if (hue < 0) + hue += 256; + g_assert (0 <= hue && hue < 256); + + if (hue > 0) + { + for (j = 0; j < GRADIENT_RESOLUTION; j++) + { + GimpRGB rgb; + GimpHSV hsv; + + rgb.r = (gdouble) gradient[j*4] / 255.0; + rgb.g = (gdouble) gradient[j*4+1] / 255.0; + rgb.b = (gdouble) gradient[j*4+2] / 255.0; + + gimp_rgb_to_hsv (&rgb, &hsv); + + hsv.h = (hsv.h + ((gdouble) hue / 255.0)); + if (hsv.h > 1.0) + hsv.h -= 1.0; + + gimp_hsv_to_rgb (&hsv, &rgb); + + gradient[j*4] = ROUND (rgb.r * 255.0); + gradient[j*4+1] = ROUND (rgb.g * 255.0); + gradient[j*4+2] = ROUND (rgb.b * 255.0); + } + } + } + + /* + * Grayfy gradient, if needed + */ + + if (table[i].gray) + { + for (j = 0; j < GRADIENT_RESOLUTION; j++) + /* the first byte is enough */ + gradient[j*4] = LUMINOSITY ((gradient + j*4)); + + } + + /* sampling of one gradient is done */ + return TRUE; + } + } + return FALSE; +} + +static void +calc_place_sflare (void) +{ + GFlare *gflare; + CalcSFlare *sflare; + gdouble prob[GRADIENT_RESOLUTION]; + gdouble sum, sum2; + gdouble pos; + gdouble rnd, sizefac; + int n; + int i; + GRand *gr; + + gr = g_rand_new (); + if ((calc.type & CALC_SFLARE) == 0) + return; + + gflare = calc.gflare; + + /* + Calc cumulative probability + */ + + sum = 0.0; + for (i = 0; i < GRADIENT_RESOLUTION; i++) + { + /* probability gradient was grayfied already */ + prob[i] = calc.sflare_probability[i*4]; + sum += prob[i]; + } + + if (sum == 0.0) + sum = 1.0; + + sum2 = 0; + for (i = 0; i < GRADIENT_RESOLUTION; i++) + { + sum2 += prob[i]; /* cumulation */ + prob[i] = sum2 / sum; + } + + g_rand_set_seed (gr, gflare->sflare_seed); + + for (n = 0; n < SFLARE_NUM; n++) + { + sflare = g_new (CalcSFlare, 1); + rnd = g_rand_double (gr); + for (i = 0; i < GRADIENT_RESOLUTION; i++) + if (prob[i] >= rnd) + break; + if (i >= GRADIENT_RESOLUTION) + i = GRADIENT_RESOLUTION - 1; + + /* sizefac gradient was grayfied already */ + sizefac = calc.sflare_sizefac[i*4] / 255.0; + sizefac = pow (sizefac, 5.0); + + pos = (double) (i - GRADIENT_RESOLUTION / 2) / GRADIENT_RESOLUTION; + sflare->xcenter = calc.xcenter + cos (calc.vangle) * calc.vlength * pos; + sflare->ycenter = calc.ycenter - sin (calc.vangle) * calc.vlength * pos; + sflare->radius = sizefac * calc.sflare_radius; /* FIXME */ + sflare->bounds.x0 = sflare->xcenter - sflare->radius - 1; + sflare->bounds.x1 = sflare->xcenter + sflare->radius + 1; + sflare->bounds.y0 = sflare->ycenter - sflare->radius - 1; + sflare->bounds.y1 = sflare->ycenter + sflare->radius + 1; + calc.sflare_list = g_list_append (calc.sflare_list, sflare); + } + + g_rand_free (gr); +} + +static void +calc_deinit (void) +{ + if (!calc.init) + { + g_warning("calc_deinit: not initialized"); + return; + } + + g_list_free_full (calc.sflare_list, (GDestroyNotify) g_free); + + g_free (calc.glow_radial); + g_free (calc.glow_angular); + g_free (calc.glow_angular_size); + g_free (calc.rays_radial); + g_free (calc.rays_angular); + g_free (calc.rays_angular_size); + g_free (calc.sflare_radial); + g_free (calc.sflare_sizefac); + g_free (calc.sflare_probability); + + calc.init = FALSE; +} + +/* + * Get sample value at specified position of a gradient + * + * gradient samples are stored into array at the time of + * calc_sample_one_gradients (), and it is now linear interpolated. + * + * INPUT: + * guchar gradient[4*GRADIENT_RESOLUTION] gradient array(RGBA) + * gdouble pos position (0<=pos<=1) + * OUTPUT: + * guchar pix[4] + */ +static void +calc_get_gradient (guchar *pix, guchar *gradient, gdouble pos) +{ + gint ipos; + gdouble frac; + gint i; + + if (pos < 0 || pos > 1) + { + pix[0] = pix[1] = pix[2] = pix[3] = 0; + return; + } + pos *= GRADIENT_RESOLUTION - 1.0001; + ipos = (gint) pos; frac = pos - ipos; + gradient += ipos * 4; + + for (i = 0; i < 4; i++) + { + pix[i] = gradient[i] * (1 - frac) + gradient[i+4] * frac; + } +} + +/* I need fmod to return always positive value */ +static gdouble +fmod_positive (gdouble x, gdouble m) +{ + return x - floor (x/m) * m; +} + +/* + * Calc glow's pixel (RGBA) value + * INPUT: + * gdouble x, y image coordinates + * OUTPUT: + * guchar pix[4] + */ +static void +calc_glow_pix (guchar *dest_pix, gdouble x, gdouble y) +{ + gdouble radius, angle; + gdouble angular_size; + guchar radial_pix[4], angular_pix[4], size_pix[4]; + gint i; + + if ((calc.type & CALC_GLOW) == 0 + || x < calc.glow_bounds.x0 || x > calc.glow_bounds.x1 + || y < calc.glow_bounds.y0 || y > calc.glow_bounds.y1) + { + memset (dest_pix, 0, 4); + return; + } + + x -= calc.xcenter; + y -= calc.ycenter; + radius = sqrt (x*x + y*y) / calc.glow_radius; + angle = (atan2 (-y, x) + calc.glow_rotation ) / (2 * G_PI); + angle = fmod_positive (angle, 1.0); + + calc_get_gradient (size_pix, calc.glow_angular_size, angle); + /* angular_size gradient was grayfied already */ + angular_size = size_pix[0] / 255.0; + radius /= (angular_size+0.0001); /* in case angular_size == 0.0 */ + if (radius < 0 || radius > 1) + { + memset (dest_pix, 0, 4); + return; + } + + calc_get_gradient (radial_pix, calc.glow_radial, radius); + calc_get_gradient (angular_pix, calc.glow_angular, angle); + + for (i = 0; i < 4; i++) + dest_pix[i] = radial_pix[i] * angular_pix[i] / 255; +} + +/* + * Calc rays's pixel (RGBA) value + * + */ +static void +calc_rays_pix (guchar *dest_pix, gdouble x, gdouble y) +{ + gdouble radius, angle; + gdouble angular_size; + gdouble spike_frac, spike_inten, spike_angle; + guchar radial_pix[4], angular_pix[4], size_pix[4]; + gint i; + + if ((calc.type & CALC_RAYS) == 0 + || x < calc.rays_bounds.x0 || x > calc.rays_bounds.x1 + || y < calc.rays_bounds.y0 || y > calc.rays_bounds.y1) + { + memset (dest_pix, 0, 4); + return; + } + + x -= calc.xcenter; + y -= calc.ycenter; + radius = sqrt (x*x + y*y) / calc.rays_radius; + angle = (atan2 (-y, x) + calc.rays_rotation ) / (2 * G_PI); + angle = fmod_positive (angle, 1.0); /* make sure 0 <= angle < 1.0 */ + spike_frac = fmod (angle, calc.rays_spike_mod * 2); + spike_angle = angle - spike_frac + calc.rays_spike_mod; + spike_frac = (angle - spike_angle) / calc.rays_spike_mod; + /* spike_frac is between -1.0 and 1.0 here (except round error...) */ + + spike_inten = pow (1.0 - fabs (spike_frac), calc.rays_thinness); + + calc_get_gradient (size_pix, calc.rays_angular_size, spike_angle); + /* angular_size gradient was grayfied already */ + angular_size = size_pix[0] / 255.0; + radius /= (angular_size+0.0001); /* in case angular_size == 0.0 */ + if(radius < 0 || radius > 1) + { + memset (dest_pix, 0, 4); + return; + } + + calc_get_gradient (radial_pix, calc.rays_radial, radius); + calc_get_gradient (angular_pix, calc.rays_angular, spike_angle); + + for (i = 0; i < 3; i++) + dest_pix[i] = radial_pix[i] * angular_pix[i] / 255; + dest_pix[3] = spike_inten * radial_pix[3] * angular_pix[3] / 255; +} + +/* + * Calc sflare's pixel (RGBA) value + * + * the sflare (second flares) are needed to be rendered one each + * sequentially, onto the source image, such as like usual layer + * operations. So the function takes src_pix as argument. glow, rays + * routines don't have src_pix as argument, because of convenience. + * + * @JAPANESE + * sflare $B$OJ#?t$N%U%l%"$r=g$K(B($B%l%$%dE*$K(B)$B$+$V$;$J$,$iIA2h$9$kI,MW$,(B + * $B$"$k$N$G!"$3$l$@$1(B src_pix $B$r0z?t$K$H$C$F(B paint_func $B$rE,MQ$9$k!#(B + * glow, rays $B$O4J0W2=$N$?$a$K$J$7!#(B + */ +void +calc_sflare_pix (guchar *dest_pix, gdouble x, gdouble y, guchar *src_pix) +{ + GList *list; + CalcSFlare *sflare; + gdouble sx, sy, th; + gdouble radius, angle; + guchar radial_pix[4], tmp_pix[4]; + + memcpy (dest_pix, src_pix, 4); + + if ((calc.type & CALC_SFLARE) == 0) + return; + + list = calc.sflare_list; + while (list) + { + sflare = list->data; + list = list->next; + + if (x < sflare->bounds.x0 || x > sflare->bounds.x1 + || y < sflare->bounds.y0 || y > sflare->bounds.y1) + continue; + sx = x - sflare->xcenter; + sy = y - sflare->ycenter; + radius = sqrt (sx * sx + sy * sy) / sflare->radius; + if (calc.sflare_shape == GF_POLYGON) + { + angle = atan2 (-sy, sx) - calc.vangle + calc.sflare_rotation; + th = fmod_positive (angle, calc.sflare_angle * 2) - calc.sflare_angle; + radius *= cos (th) * calc.sflare_factor; + } + if (radius < 0 || radius > 1) + continue; + + calc_get_gradient (radial_pix, calc.sflare_radial, radius); + memcpy (tmp_pix, dest_pix, 4); + calc_paint_func (dest_pix, tmp_pix, radial_pix, + calc.sflare_opacity, calc.gflare->sflare_mode); + } +} + +static void +calc_gflare_pix (guchar *dest_pix, gdouble x, gdouble y, guchar *src_pix) +{ + GFlare *gflare = calc.gflare; + guchar glow_pix[4], rays_pix[4]; + guchar tmp_pix[4]; + + memcpy (dest_pix, src_pix, 4); + + if (calc.type & CALC_GLOW) + { + memcpy (tmp_pix, dest_pix, 4); + calc_glow_pix (glow_pix, x, y); + calc_paint_func (dest_pix, tmp_pix, glow_pix, + calc.glow_opacity, gflare->glow_mode); + } + if (calc.type & CALC_RAYS) + { + memcpy (tmp_pix, dest_pix, 4); + calc_rays_pix (rays_pix, x, y); + calc_paint_func (dest_pix, tmp_pix, rays_pix, + calc.rays_opacity, gflare->rays_mode); + } + if (calc.type & CALC_SFLARE) + { + memcpy (tmp_pix, dest_pix, 4); + calc_sflare_pix (dest_pix, x, y, tmp_pix); + } +} + +/* + Paint func routines, such as Normal, Addition, ... + */ +static void +calc_paint_func (guchar *dest, guchar *src1, guchar *src2, gint opacity, + GFlareMode mode) +{ + guchar buf[4], *s=buf; + + if (src2[3] == 0 || opacity <= 0) + { + memcpy (dest, src1, 4); + return; + } + + switch (mode) + { + case GF_NORMAL: + s = src2; + break; + case GF_ADDITION: + calc_addition (s, src1, src2); + break; + case GF_OVERLAY: + calc_overlay (s, src1, src2); + break; + case GF_SCREEN: + calc_screen (s, src1, src2); + break; + default: + s = src2; + break; + } + calc_combine (dest, src1, s, opacity); +} + +static void +calc_combine (guchar *dest, guchar *src1, guchar *src2, gint opacity) +{ + gdouble s1_a, s2_a, new_a; + gdouble ratio, compl_ratio; + gint i; + + s1_a = src1[3] / 255.0; + s2_a = src2[3] * opacity / 65025.0; + new_a = s1_a + (1.0 - s1_a) * s2_a; + + if (new_a != 0.0) + ratio = s2_a / new_a; + else + ratio = 0.0; + + compl_ratio = 1.0 - ratio; + + for (i = 0; i < 3; i++) + dest[i] = src1[i] * compl_ratio + src2[i] * ratio; + + dest[3] = new_a * 255.0; +} + +static void +calc_addition (guchar *dest, guchar *src1, guchar *src2) +{ + gint tmp, i; + + for (i = 0; i < 3; i++) + { + tmp = src1[i] + src2[i]; + dest[i] = tmp <= 255 ? tmp: 255; + } + dest[3] = MIN (src1[3], src2[3]); +} + +static void +calc_screen (guchar *dest, guchar *src1, guchar *src2) +{ + gint i; + + for (i = 0; i < 3; i++) + { + dest[i] = 255 - ((255 - src1[i]) * (255 - src2[i])) / 255; + } + dest[3] = MIN (src1[3], src2[3]); +} + +static void +calc_overlay (guchar *dest, guchar *src1, guchar *src2) +{ + gint screen, mult, i; + + for (i = 0; i < 3; i++) + { + screen = 255 - ((255 - src1[i]) * (255 - src2[i])) / 255; + mult = (src1[i] * src2[i]) / 255; + dest[i] = (screen * src1[i] + mult * (255 - src1[i])) / 255; + } + dest[3] = MIN (src1[3], src2[3]); +} + +/*************************************************************************/ +/** **/ +/** Main Dialog **/ +/** +++ dlg **/ +/** **/ +/*************************************************************************/ + +/* + This is gflare main dialog, one which opens in first. + */ + +static gboolean +dlg_run (void) +{ + GeglBuffer *src_buffer; + GtkWidget *shell; + GtkWidget *hbox; + GtkWidget *vbox; + GtkWidget *frame; + GtkWidget *abox; + GtkWidget *button; + GtkWidget *notebook; + gboolean run = FALSE; + + gimp_ui_init (PLUG_IN_BINARY, TRUE); + + /* + * Init Main Dialog + */ + + dlg = g_new0 (GFlareDialog, 1); + dlg->init = TRUE; + dlg->update_preview = TRUE; + + gradient_menu_init (); /* FIXME: this should go elsewhere */ + dlg_setup_gflare (); + + g_assert (gflares_list != NULL); + g_assert (dlg->gflare != NULL); + g_assert (dlg->gflare->name != NULL); + + /* + * Dialog Shell + */ + + shell = dlg->shell = gimp_dialog_new (_("Gradient Flare"), PLUG_IN_ROLE, + NULL, 0, + gimp_standard_help_func, PLUG_IN_PROC, + + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_OK"), GTK_RESPONSE_OK, + + NULL); + + gtk_dialog_set_alternative_button_order (GTK_DIALOG (shell), + GTK_RESPONSE_OK, + GTK_RESPONSE_CANCEL, + -1); + + /* + * main hbox + */ + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 12); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (shell))), + hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + /* + * Preview + */ + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); + gtk_widget_show (vbox); + + abox = gtk_alignment_new (0.0, 0.0, 0.0, 0.0); + gtk_box_pack_start (GTK_BOX (vbox), abox, TRUE, TRUE, 0); + gtk_widget_show (abox); + + frame = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); + gtk_container_add (GTK_CONTAINER (abox), frame); + gtk_widget_show (frame); + + src_buffer = gimp_drawable_get_buffer (drawable_ID); + + dlg->preview = preview_new (DLG_PREVIEW_WIDTH, DLG_PREVIEW_HEIGHT, + dlg_preview_init_func, NULL, + dlg_preview_render_func, src_buffer, + dlg_preview_deinit_func, NULL); + gtk_widget_set_events (GTK_WIDGET (dlg->preview->widget), DLG_PREVIEW_MASK); + gtk_container_add (GTK_CONTAINER (frame), dlg->preview->widget); + + g_signal_connect (dlg->preview->widget, "realize", + G_CALLBACK (dlg_preview_realize), + NULL); + g_signal_connect (dlg->preview->widget, "event", + G_CALLBACK (dlg_preview_handle_event), + NULL); + + dlg_preview_calc_window (); + + button = gtk_check_button_new_with_mnemonic (_("A_uto update preview")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), + dlg->update_preview); + gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + g_signal_connect (button, "toggled", + G_CALLBACK (dlg_update_preview_callback), + &dlg->update_preview); + + /* + * Notebook + */ + + notebook = dlg->notebook = gtk_notebook_new (); + gtk_box_pack_start (GTK_BOX (hbox), notebook, TRUE, TRUE, 0); + gtk_widget_show (notebook); + + dlg_make_page_settings (dlg, notebook); + dlg_make_page_selector (dlg, notebook); + + gtk_widget_show (shell); + + /* + * Initialization done + */ + dlg->init = FALSE; + dlg_preview_update (); + + if (gimp_dialog_run (GIMP_DIALOG (shell)) == GTK_RESPONSE_OK) + { + gflare_name_copy (pvals.gflare_name, dlg->gflare->name); + + run = TRUE; + } + + g_object_unref (src_buffer); + + gtk_widget_destroy (shell); + + return run; +} + +static void +dlg_setup_gflare (void) +{ + dlg->gflare = gflares_list_lookup (pvals.gflare_name); + + if (!dlg->gflare) + { + dlg->gflare = gflares_list_lookup ("Default"); + if (!dlg->gflare) + { + g_warning (_("'Default' is created.")); + dlg->gflare = gflare_new_with_default (_("Default")); + gflares_list_insert (dlg->gflare); + } + } +} + +/***********************************/ +/** Main Dialog / Preview **/ +/***********************************/ + +/* + * Calculate preview's window, ie. translation of preview widget and + * drawable. + * + * x0, x1, y0, y1 are drawable coord, corresponding with top left + * corner of preview widget, etc. + */ +void +dlg_preview_calc_window (void) +{ + gint width = gimp_drawable_width (drawable_ID); + gint height = gimp_drawable_height (drawable_ID); + gint is_wide; + gdouble offx, offy; + + is_wide = ((double) DLG_PREVIEW_HEIGHT * width >= + (double) DLG_PREVIEW_WIDTH * height); + + if (is_wide) + { + offy = ((double) width * DLG_PREVIEW_HEIGHT / DLG_PREVIEW_WIDTH) / 2.0; + + dlg->pwin.x0 = 0; + dlg->pwin.x1 = width; + dlg->pwin.y0 = height / 2.0 - offy; + dlg->pwin.y1 = height / 2.0 + offy; + } + else + { + offx = ((double) height * DLG_PREVIEW_WIDTH / DLG_PREVIEW_HEIGHT) / 2.0; + + dlg->pwin.x0 = width / 2.0 - offx; + dlg->pwin.x1 = width / 2.0 + offx; + dlg->pwin.y0 = 0; + dlg->pwin.y1 = height; + } +} + +void +ed_preview_calc_window (void) +{ + gint width = gimp_drawable_width (drawable_ID); + gint height = gimp_drawable_height (drawable_ID); + gint is_wide; + gdouble offx, offy; + + is_wide = ((double) DLG_PREVIEW_HEIGHT * width >= + (double) DLG_PREVIEW_WIDTH * height); + + if (is_wide) + { + offy = ((double) width * DLG_PREVIEW_HEIGHT / DLG_PREVIEW_WIDTH) / 2.0; + + dlg->pwin.x0 = 0; + dlg->pwin.x1 = width; + dlg->pwin.y0 = height / 2.0 - offy; + dlg->pwin.y1 = height / 2.0 + offy; + } + else + { + offx = ((double) height * DLG_PREVIEW_WIDTH / DLG_PREVIEW_HEIGHT) / 2.0; + + dlg->pwin.x0 = width / 2.0 - offx; dlg->pwin.x1 = width / 2.0 + offx; + dlg->pwin.y0 = 0; + dlg->pwin.y1 = height; + } +} + +static void +dlg_preview_realize (GtkWidget *widget) +{ + GdkDisplay *display = gtk_widget_get_display (widget); + GdkCursor *cursor = gdk_cursor_new_for_display (display, GDK_CROSSHAIR); + + gdk_window_set_cursor (gtk_widget_get_window (widget), cursor); + gdk_cursor_unref (cursor); +} + +static gboolean +dlg_preview_handle_event (GtkWidget *widget, + GdkEvent *event) +{ + GdkEventButton *bevent; + gint bx, by, x, y; + + switch (event->type) + { + case GDK_BUTTON_PRESS: + bevent = (GdkEventButton *) event; + bx = bevent->x; + by = bevent->y; + + /* convert widget coord to drawable coord */ + x = dlg->pwin.x0 + (double) (dlg->pwin.x1 - dlg->pwin.x0) + * bx / DLG_PREVIEW_WIDTH; + y = dlg->pwin.y0 + (double) (dlg->pwin.y1 - dlg->pwin.y0) + * by / DLG_PREVIEW_HEIGHT; + + if ((x != pvals.xcenter || y != pvals.ycenter)) + { + if (x != pvals.xcenter) + { + pvals.xcenter = x; + gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (dlg->sizeentry), + 0, x); + } + if (y != pvals.ycenter) + { + pvals.ycenter = y; + gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (dlg->sizeentry), + 1, y); + } + dlg_preview_update (); + } + return TRUE; + default: + break; + } + return FALSE; +} + +static void +dlg_preview_update (void) +{ + if (!dlg->init && dlg->update_preview) + { + dlg->init_params_done = FALSE; + preview_render_start (dlg->preview); + } +} + +/* preview callbacks */ +static gint +dlg_preview_init_func (Preview *preview, gpointer data) +{ + /* call init_params first, and iterate init_progress while + it returns true */ + if (dlg->init_params_done == FALSE) + { + calc_init_params (dlg->gflare, + CALC_GLOW | CALC_RAYS | CALC_SFLARE, + pvals.xcenter, pvals.ycenter, + pvals.radius, pvals.rotation, pvals.hue, + pvals.vangle, pvals.vlength); + dlg->init_params_done = TRUE; + return TRUE; + } + return calc_init_progress (); +} + +/* render preview + do what "preview" means, ie. render lense flare effect onto drawable */ +static void +dlg_preview_render_func (Preview *preview, + guchar *dest, + gint y, + gpointer data) +{ + GeglBuffer *src_buffer = data; + gint width = gimp_drawable_width (drawable_ID); + gint height = gimp_drawable_height (drawable_ID); + gint x; + gint dx, dy; /* drawable x, y */ + guchar *src_row, *src; + guchar src_pix[4], dest_pix[4]; + gint b; + + dy = (dlg->pwin.y0 + + (gdouble) (dlg->pwin.y1 - dlg->pwin.y0) * y / DLG_PREVIEW_HEIGHT); + + if (dy < 0 || dy >= height) + { + memset (dest, GRAY50, 3 * DLG_PREVIEW_WIDTH); + return; + } + + src_row = g_new (guchar, dinfo.bpp * width); + + gegl_buffer_get (src_buffer, GEGL_RECTANGLE (0, dy, width, 1), 1.0, + dinfo.format, src_row, + GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); + + for (x = 0; x < DLG_PREVIEW_HEIGHT; x++) + { + dx = (dlg->pwin.x0 + + (double) (dlg->pwin.x1 - dlg->pwin.x0) * x / DLG_PREVIEW_WIDTH); + + if (dx < 0 || dx >= width) + { + for (b = 0; b < 3; b++) + *dest++ = GRAY50; + continue; + } + + /* Get drawable pix value */ + src = &src_row[dx * dinfo.bpp]; + + for (b = 0; b < 3; b++) + src_pix[b] = dinfo.is_color ? src[b] : src[0]; + src_pix[3] = dinfo.has_alpha ? src[dinfo.bpp - 1] : OPAQUE; + + /* Get GFlare pix value */ + + calc_gflare_pix (dest_pix, dx, dy, src_pix); + + /* Draw gray check if needed */ + preview_rgba_to_rgb (dest, x, y, dest_pix); + dest += 3; + } + + g_free (src_row); +} + +static void +dlg_preview_deinit_func (Preview *preview, gpointer data) +{ + if (dlg->init_params_done) + { + calc_deinit (); + dlg->init_params_done = TRUE; + } +} + +/*****************************************/ +/** Main Dialog / Settings Page **/ +/*****************************************/ + +static void +dlg_make_page_settings (GFlareDialog *dlg, + GtkWidget *notebook) +{ + GtkWidget *main_vbox; + GtkWidget *frame; + GtkWidget *center; + GtkWidget *chain; + GtkWidget *table; + GtkWidget *button; + GtkWidget *asup_table; + GtkObject *adj; + gdouble xres, yres; + gint row; + + main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12); + + frame = gimp_frame_new (_("Center")); + gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + gimp_image_get_resolution (image_ID, &xres, &yres); + + center = dlg->sizeentry = + gimp_coordinates_new (gimp_image_get_unit (image_ID), "%a", + TRUE, TRUE, 75, GIMP_SIZE_ENTRY_UPDATE_SIZE, + + FALSE, FALSE, + + _("_X:"), pvals.xcenter, xres, + -GIMP_MAX_IMAGE_SIZE, GIMP_MAX_IMAGE_SIZE, + 0, gimp_drawable_width (drawable_ID), + + _("_Y:"), pvals.ycenter, yres, + -GIMP_MAX_IMAGE_SIZE, GIMP_MAX_IMAGE_SIZE, + 0, gimp_drawable_height (drawable_ID)); + + chain = GTK_WIDGET (GIMP_COORDINATES_CHAINBUTTON (center)); + + gtk_container_add (GTK_CONTAINER (frame), center); + g_signal_connect (center, "value-changed", + G_CALLBACK (dlg_position_entry_callback), + NULL); + g_signal_connect (center, "refval-changed", + G_CALLBACK (dlg_position_entry_callback), + NULL); + gtk_widget_hide (chain); + gtk_widget_show (center); + + frame = gimp_frame_new (_("Parameters")); + gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (5, 3, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add (GTK_CONTAINER (frame), table); + gtk_widget_show (table); + + row = 0; + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("_Radius:"), SCALE_WIDTH, 6, + pvals.radius, 0.0, + gimp_drawable_width (drawable_ID) / 2, + 1.0, 10.0, 1, + FALSE, 0.0, GIMP_MAX_IMAGE_SIZE, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &pvals.radius); + g_signal_connect (adj, "value-changed", + G_CALLBACK (dlg_preview_update), + NULL); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("Ro_tation:"), SCALE_WIDTH, 6, + pvals.rotation, -180.0, 180.0, 1.0, 15.0, 1, + TRUE, 0, 0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &pvals.rotation); + g_signal_connect (adj, "value-changed", + G_CALLBACK (dlg_preview_update), + NULL); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("_Hue rotation:"), SCALE_WIDTH, 6, + pvals.hue, -180.0, 180.0, 1.0, 15.0, 1, + TRUE, 0, 0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &pvals.hue); + g_signal_connect (adj, "value-changed", + G_CALLBACK (dlg_preview_update), + NULL); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("Vector _angle:"), SCALE_WIDTH, 6, + pvals.vangle, 0.0, 359.0, 1.0, 15.0, 1, + TRUE, 0, 0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &pvals.vangle); + g_signal_connect (adj, "value-changed", + G_CALLBACK (dlg_preview_update), + NULL); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("Vector _length:"), SCALE_WIDTH, 6, + pvals.vlength, 1, 1000, 1.0, 10.0, 1, + FALSE, 1, GIMP_MAX_IMAGE_SIZE, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &pvals.vlength); + g_signal_connect (adj, "value-changed", + G_CALLBACK (dlg_preview_update), + NULL); + + /** + *** Asupsample settings + *** This code is stolen from gimp-0.99.x/app/blend.c + **/ + + /* asupsample frame */ + frame = dlg->asupsample_frame = gimp_frame_new (NULL); + gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + button = gtk_check_button_new_with_mnemonic (_("A_daptive supersampling")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), + pvals.use_asupsample); + gtk_frame_set_label_widget (GTK_FRAME (frame), button); + gtk_widget_show (button); + + asup_table = gtk_table_new (2, 3, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (asup_table), 6); + gtk_table_set_row_spacings (GTK_TABLE (asup_table), 6); + gtk_container_add (GTK_CONTAINER (frame), asup_table); + gtk_widget_show (asup_table); + + g_signal_connect (button, "toggled", + G_CALLBACK (gimp_toggle_button_update), + &pvals.use_asupsample); + + g_object_bind_property (button, "active", + asup_table, "sensitive", + G_BINDING_SYNC_CREATE); + + adj = gimp_scale_entry_new (GTK_TABLE (asup_table), 0, 0, + _("_Max depth:"), -1, 4, + pvals.asupsample_max_depth, + 1.0, 10.0, 1.0, 1.0, 0, + TRUE, 0.0, 0.0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_int_adjustment_update), + &pvals.asupsample_max_depth); + + adj = gimp_scale_entry_new (GTK_TABLE (asup_table), 0, 1, + _("_Threshold"), -1, 4, + pvals.asupsample_threshold, + 0.0, 4.0, 0.01, 0.01, 2, + TRUE, 0.0, 0.0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &pvals.asupsample_threshold); + + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), main_vbox, + gtk_label_new_with_mnemonic (_("_Settings"))); + gtk_widget_show (main_vbox); +} + +static void +dlg_position_entry_callback (GtkWidget *widget, gpointer data) +{ + gint x, y; + + x = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 0)); + y = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 1)); + + DEBUG_PRINT (("dlg_position_entry_callback\n")); + + if (pvals.xcenter != x || + pvals.ycenter != y) + { + pvals.xcenter = x; + pvals.ycenter = y; + + dlg_preview_update (); + } +} + +static void +dlg_update_preview_callback (GtkWidget *widget, + gpointer data) +{ + gimp_toggle_button_update (widget, data); + + dlg_preview_update (); +} + +/*****************************************/ +/** Main Dialog / Selector Page **/ +/*****************************************/ + +static void +dlg_make_page_selector (GFlareDialog *dlg, + GtkWidget *notebook) +{ + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *listbox; + GtkListStore *list; + GtkWidget *listview; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkWidget *button; + gint i; + + static struct + { + const gchar *label; + GCallback callback; + } + buttons[] = + { + { N_("_New"), G_CALLBACK (dlg_selector_new_callback) }, + { N_("_Edit"), G_CALLBACK (dlg_selector_edit_callback) }, + { N_("_Copy"), G_CALLBACK (dlg_selector_copy_callback) }, + { N_("_Delete"), G_CALLBACK (dlg_selector_delete_callback) } + }; + + DEBUG_PRINT (("dlg_make_page_selector\n")); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); + + /* + * List Box + */ + + listbox = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (listbox), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + gtk_widget_set_size_request (listbox, DLG_LISTBOX_WIDTH, DLG_LISTBOX_HEIGHT); + gtk_box_pack_start (GTK_BOX (vbox), listbox, TRUE, TRUE, 0); + + list = dlg->selector_list = gtk_list_store_new (2, + G_TYPE_STRING, + G_TYPE_POINTER); + listview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list)); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (listview), FALSE); + + gtk_container_add (GTK_CONTAINER (listbox), listview); + gtk_widget_show (listbox); + dlg->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (listview)); + gtk_tree_selection_set_mode (dlg->selection, GTK_SELECTION_BROWSE); + gtk_widget_show (listview); + g_signal_connect (dlg->selection, "changed", + G_CALLBACK (dlg_selector_list_item_callback), + NULL); + + renderer = gtk_cell_renderer_text_new (); + + /* Note: the title isn't shown, so it doesn't need to be translated. */ + column = gtk_tree_view_column_new_with_attributes ("GFlare", renderer, + "text", 0, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (listview), column); + + dlg_selector_setup_listbox (); + + /* + * The buttons for the possible listbox operations + */ + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + for (i = 0; i < G_N_ELEMENTS (buttons); i++) + { + button = gtk_button_new_with_mnemonic (gettext (buttons[i].label)); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); + gtk_widget_show (button); + + g_signal_connect (button, "clicked", + buttons[i].callback, + button); + } + + gtk_widget_show (vbox); + + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, + gtk_label_new_with_mnemonic (_("S_elector"))); + gtk_widget_show (vbox); +} + +/* + * Set up selector's listbox, according to gflares_list + */ +static void +dlg_selector_setup_listbox (void) +{ + GList *list; + GFlare *gflare; + gint n; + + list = gflares_list; + n = 0; + + while (list) + { + GtkTreeIter iter; + + gflare = list->data; + + /* + dlg->gflare should be valid (ie. not NULL) here. + */ + gtk_list_store_append (dlg->selector_list, &iter); + + gtk_list_store_set (dlg->selector_list, &iter, + 0, gflare->name, + 1, gflare, + -1); + if (gflare == dlg->gflare) + gtk_tree_selection_select_iter (dlg->selection, + &iter); + + list = list->next; + n++; + } +} + +static void +dlg_selector_list_item_callback (GtkTreeSelection *selection) +{ + GtkTreeIter iter; + + if (gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + gtk_tree_model_get (GTK_TREE_MODEL (dlg->selector_list), &iter, + 1, &dlg->gflare, -1); + } + + dlg_preview_update (); +} + +/* + * "New" button in Selector page + */ +static void +dlg_selector_new_callback (GtkWidget *widget, + gpointer data) +{ + GtkWidget *query_box; + + query_box = gimp_query_string_box (_("New Gradient Flare"), + gtk_widget_get_toplevel (widget), + gimp_standard_help_func, PLUG_IN_PROC, + _("Enter a name for the new GFlare"), + _("Unnamed"), + NULL, NULL, + dlg_selector_new_ok_callback, dlg); + gtk_widget_show (query_box); +} + +static void +dlg_selector_new_ok_callback (GtkWidget *widget, + const gchar *new_name, + gpointer data) +{ + GFlare *gflare; + GtkTreeIter iter; + gint pos; + + g_return_if_fail (new_name != NULL); + + if (gflares_list_lookup (new_name)) + { + g_message (_("The name '%s' is used already!"), new_name); + return; + } + + gflare = gflare_new_with_default (new_name); + + pos = gflares_list_insert (gflare); + + gtk_list_store_insert (dlg->selector_list, &iter, pos); + gtk_list_store_set (dlg->selector_list, &iter, + 0, gflare->name, + 1, gflare, + -1); + gtk_tree_selection_select_iter (dlg->selection, &iter); + + dlg->gflare = gflare; + dlg_preview_update (); +} + +/* + * "Edit" button in Selector page + */ +static void +dlg_selector_edit_callback (GtkWidget *widget, + gpointer data) +{ + preview_render_end (dlg->preview); + gtk_widget_set_sensitive (dlg->shell, FALSE); + ed_run (GTK_WINDOW (dlg->shell), + dlg->gflare, dlg_selector_edit_done_callback, NULL); +} + +static void +dlg_selector_edit_done_callback (gint updated, + gpointer data) +{ + gtk_widget_set_sensitive (dlg->shell, TRUE); + if (updated) + { + gflare_save (dlg->gflare); + } + dlg_preview_update (); +} + +/* + * "Copy" button in Selector page + */ +static void +dlg_selector_copy_callback (GtkWidget *widget, + gpointer data) +{ + GtkWidget *query_box; + gchar *name; + + name = g_strdup_printf ("%s copy", dlg->gflare->name); + + query_box = gimp_query_string_box (_("Copy Gradient Flare"), + gtk_widget_get_toplevel (widget), + gimp_standard_help_func, PLUG_IN_PROC, + _("Enter a name for the copied GFlare"), + name, + NULL, NULL, + dlg_selector_copy_ok_callback, dlg); + g_free (name); + + gtk_widget_show (query_box); +} + +static void +dlg_selector_copy_ok_callback (GtkWidget *widget, + const gchar *copy_name, + gpointer data) +{ + GFlare *gflare; + GtkTreeIter iter; + gint pos; + + g_return_if_fail (copy_name != NULL); + + if (gflares_list_lookup (copy_name)) + { + g_warning (_("The name '%s' is used already!"), copy_name); + return; + } + + gflare = gflare_dup (dlg->gflare, copy_name); + + pos = gflares_list_insert (gflare); + gtk_list_store_insert (dlg->selector_list, &iter, pos); + gtk_list_store_set (dlg->selector_list, &iter, + 0, gflare->name, + 1, gflare, + -1); + gtk_tree_selection_select_iter (dlg->selection, &iter); + + dlg->gflare = gflare; + gflare_save (dlg->gflare); + dlg_preview_update (); +} + +/* + * "Delete" button in Selector page + */ +static void +dlg_selector_delete_callback (GtkWidget *widget, + gpointer data) +{ + GtkWidget *dialog; + gchar *str; + + if (num_gflares <= 1) + { + g_message (_("Cannot delete!! There must be at least one GFlare.")); + return; + } + + gtk_widget_set_sensitive (dlg->shell, FALSE); + + str = g_strdup_printf (_("Are you sure you want to delete " + "\"%s\" from the list and from disk?"), + dlg->gflare->name); + + dialog = gimp_query_boolean_box (_("Delete Gradient Flare"), + dlg->shell, + gimp_standard_help_func, PLUG_IN_PROC, + GIMP_ICON_DIALOG_QUESTION, + str, + _("_Delete"), _("_Cancel"), + NULL, NULL, + dlg_selector_do_delete_callback, + NULL); + + g_free (str); + + gtk_widget_show (dialog); +} + +static void +dlg_selector_do_delete_callback (GtkWidget *widget, + gboolean delete, + gpointer data) +{ + GFlare *old_gflare; + GList *tmp; + gint i, new_i; + GtkTreeIter iter; + + gtk_widget_set_sensitive (dlg->shell, TRUE); + + if (!delete) + return; + + i = gflares_list_index (dlg->gflare); + + if (i >= 0) + { + /* Remove current gflare from gflares_list and free it */ + old_gflare = dlg->gflare; + gflares_list_remove (dlg->gflare); + dlg->gflare = NULL; + + /* Remove from listbox */ + if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (dlg->selector_list), + &iter, NULL, i)) + { + g_warning ("Unsynchronized lists. Bad things will happen!"); + return; + } + gtk_list_store_remove (dlg->selector_list, &iter); + + /* Calculate new position of gflare and select it */ + new_i = (i < num_gflares) ? i : num_gflares - 1; + if ((tmp = g_list_nth (gflares_list, new_i))) + dlg->gflare = tmp->data; + if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (dlg->selector_list), + &iter, NULL, i)) + { + g_warning ("Unsynchronized lists. Bad things will happen!"); + return; + } + gtk_tree_selection_select_iter (dlg->selection, + &iter); + + /* Delete old one from disk and memory */ + if (old_gflare->filename) + g_unlink (old_gflare->filename); + + gflare_free (old_gflare); + + /* Update */ + dlg_preview_update (); + } + else + { + g_warning (_("not found %s in gflares_list"), dlg->gflare->name); + } +} + +/*************************************************************************/ +/** **/ +/** GFlare Editor **/ +/** +++ ed **/ +/** **/ +/*************************************************************************/ + +/* + This is gflare editor dialog, one which opens by clicking + "Edit" button on the selector page in the main dialog. + */ + +static void +ed_run (GtkWindow *parent, + GFlare *target_gflare, + GFlareEditorCallback callback, + gpointer calldata) +{ + GtkWidget *shell; + GtkWidget *hbox; + GtkWidget *frame; + GtkWidget *abox; + GtkWidget *notebook; + + if (!ed) + ed = g_new0 (GFlareEditor, 1); + ed->init = TRUE; + ed->run = FALSE; + ed->target_gflare = target_gflare; + ed->gflare = gflare_dup (target_gflare, target_gflare->name); + ed->callback = callback; + ed->calldata = calldata; + + /* + * Dialog Shell + */ + ed->shell = + shell = gimp_dialog_new (_("Gradient Flare Editor"), PLUG_IN_ROLE, + GTK_WIDGET (parent), 0, + gimp_standard_help_func, PLUG_IN_PROC, + + _("_Rescan Gradients"), RESPONSE_RESCAN, + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_OK"), GTK_RESPONSE_OK, + + NULL); + + gtk_dialog_set_alternative_button_order (GTK_DIALOG (shell), + RESPONSE_RESCAN, + GTK_RESPONSE_OK, + GTK_RESPONSE_CANCEL, + -1); + + g_signal_connect (shell, "response", + G_CALLBACK (ed_response), + ed); + g_signal_connect (shell, "destroy", + G_CALLBACK (ed_destroy_callback), + ed); + + /* + * main hbox + */ + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 12); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (shell))), + hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + /* + * Preview + */ + + abox = gtk_alignment_new (0.0, 0.0, 0.0, 0.0); + gtk_box_pack_start (GTK_BOX (hbox), abox, FALSE, FALSE, 0); + gtk_widget_show (abox); + + frame = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); + gtk_container_add (GTK_CONTAINER (abox), frame); + gtk_widget_show (frame); + + ed->preview = preview_new (ED_PREVIEW_WIDTH, ED_PREVIEW_HEIGHT, + ed_preview_init_func, NULL, + ed_preview_render_func, NULL, + ed_preview_deinit_func, NULL); + gtk_widget_set_events (GTK_WIDGET (ed->preview->widget), DLG_PREVIEW_MASK); + gtk_container_add (GTK_CONTAINER (frame), ed->preview->widget); + g_signal_connect (ed->preview->widget, "event", + G_CALLBACK (dlg_preview_handle_event), + NULL); + ed_preview_calc_window (); + + /* + * Notebook + */ + notebook = ed->notebook = gtk_notebook_new (); + gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP); + gtk_box_pack_start (GTK_BOX (hbox), notebook, TRUE, TRUE, 0); + gtk_widget_show (notebook); + + ed_make_page_general (ed, notebook); + ed_make_page_glow (ed, notebook); + ed_make_page_rays (ed, notebook); + ed_make_page_sflare (ed, notebook); + + gtk_widget_show (shell); + + ed->init = FALSE; + ed_preview_update (); +} + +static void +ed_destroy_callback (GtkWidget *widget, + GFlareEditor *ed) +{ + preview_free (ed->preview); + gflare_free (ed->gflare); + if (ed->callback) + (*ed->callback) (ed->run, ed->calldata); +} + +static void +ed_response (GtkWidget *widget, + gint response_id, + GFlareEditor *ed) +{ + switch (response_id) + { + case RESPONSE_RESCAN: + ed->init = TRUE; + gradient_menu_rescan (); + ed->init = FALSE; + ed_preview_update (); + gtk_widget_queue_draw (ed->notebook); + break; + + case GTK_RESPONSE_OK: + ed->run = TRUE; + gflare_copy (ed->target_gflare, ed->gflare); + gtk_widget_destroy (ed->shell); + break; + + default: + gtk_widget_destroy (ed->shell); + break; + } +} + +static void +ed_make_page_general (GFlareEditor *ed, + GtkWidget *notebook) +{ + GFlare *gflare = ed->gflare; + GtkWidget *vbox; + GtkWidget *frame; + GtkWidget *table; + GtkWidget *combo; + GtkObject *adj; + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); + + /* Glow */ + + frame = gimp_frame_new (_("Glow Paint Options")); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (2, 3, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add (GTK_CONTAINER (frame), table); + gtk_widget_show (table); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 0, + _("Opacity:"), SCALE_WIDTH, 6, + gflare->glow_opacity, 0.0, 100.0, 1.0, 10.0, 1, + TRUE, 0, 0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &gflare->glow_opacity); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + combo = ed_mode_menu_new (&gflare->glow_mode); + gimp_table_attach_aligned (GTK_TABLE (table), 0, 1, + _("Paint mode:"), 0.0, 0.5, combo, 1, FALSE); + + /* Rays */ + + frame = gimp_frame_new (_("Rays Paint Options")); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (2, 3, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add (GTK_CONTAINER (frame), table); + gtk_widget_show (table); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 0, + _("Opacity:"), SCALE_WIDTH, 6, + gflare->rays_opacity, 0.0, 100.0, 1.0, 10.0, 1, + TRUE, 0, 0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &gflare->rays_opacity); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + combo = ed_mode_menu_new (&gflare->rays_mode); + gimp_table_attach_aligned (GTK_TABLE (table), 0, 1, + _("Paint mode:"), 0.0, 0.5, combo, 1, FALSE); + + /* Rays */ + + frame = gimp_frame_new (_("Second Flares Paint Options")); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (2, 3, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add (GTK_CONTAINER (frame), table); + gtk_widget_show (table); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 0, + _("Opacity:"), SCALE_WIDTH, 6, + gflare->sflare_opacity, 0.0, 100.0, 1.0, 10.0, 1, + TRUE, 0, 0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &gflare->sflare_opacity); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + combo = ed_mode_menu_new (&gflare->sflare_mode); + gimp_table_attach_aligned (GTK_TABLE (table), 0, 1, + _("Paint mode:"), 0.0, 0.5, combo, 1, FALSE); + + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, + gtk_label_new_with_mnemonic (_("_General"))); + g_signal_connect (vbox, "map", + G_CALLBACK (ed_page_map_callback), + (gpointer) PAGE_GENERAL); + gtk_widget_show (vbox); +} + +static void +ed_make_page_glow (GFlareEditor *ed, + GtkWidget *notebook) +{ + GFlare *gflare = ed->gflare; + GradientMenu *gm; + GtkWidget *vbox; + GtkWidget *frame; + GtkWidget *table; + GtkObject *adj; + gint row; + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); + + /* + * Gradient Menus + */ + + frame = gimp_frame_new (_("Gradients")); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (3, 3, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add (GTK_CONTAINER (frame), table); + + gm = gradient_menu_new ((GradientMenuCallback) &ed_gradient_menu_callback, + gflare->glow_radial, gflare->glow_radial); + ed_put_gradient_menu (table, 0, 0, _("Radial gradient:"), gm); + + gm = gradient_menu_new ((GradientMenuCallback) &ed_gradient_menu_callback, + gflare->glow_angular, gflare->glow_angular); + ed_put_gradient_menu (table, 0, 1, _("Angular gradient:"), gm); + + gm = gradient_menu_new ((GradientMenuCallback) &ed_gradient_menu_callback, + gflare->glow_angular_size, gflare->glow_angular_size); + ed_put_gradient_menu (table, 0, 2, _("Angular size gradient:"), gm); + + gtk_widget_show (table); + + /* + * Scales + */ + + frame = gimp_frame_new (_("Parameters")); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (3, 3, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add (GTK_CONTAINER (frame), table); + + row = 0; + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("Size (%):"), SCALE_WIDTH, 6, + gflare->glow_size, 0.0, 200.0, 1.0, 10.0, 1, + FALSE, 0, G_MAXINT, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &gflare->glow_size); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("Rotation:"), SCALE_WIDTH, 6, + gflare->glow_rotation, -180.0, 180.0, 1.0, 15.0, 1, + TRUE, 0, 0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &gflare->glow_rotation); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("Hue rotation:"), SCALE_WIDTH, 6, + gflare->glow_hue, -180.0, 180.0, 1.0, 15.0, 1, + TRUE, 0, 0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &gflare->glow_hue); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + gtk_widget_show (table); + + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, + gtk_label_new_with_mnemonic (_("G_low"))); + g_signal_connect (vbox, "map", + G_CALLBACK (ed_page_map_callback), + (gpointer) PAGE_GLOW); + gtk_widget_show (vbox); +} + +static void +ed_make_page_rays (GFlareEditor *ed, + GtkWidget *notebook) +{ + GFlare *gflare = ed->gflare; + GradientMenu *gm; + GtkWidget *vbox; + GtkWidget *frame; + GtkWidget *table; + GtkObject *adj; + gint row; + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); + + /* + * Gradient Menus + */ + + frame = gimp_frame_new (_("Gradients")); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (3, 3, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add (GTK_CONTAINER (frame), table); + + row = 0; + + gm = gradient_menu_new ((GradientMenuCallback) &ed_gradient_menu_callback, + gflare->rays_radial, gflare->rays_radial); + ed_put_gradient_menu (table, 0, row++, _("Radial gradient:"), gm); + + gm = gradient_menu_new ((GradientMenuCallback) &ed_gradient_menu_callback, + gflare->rays_angular, gflare->rays_angular); + ed_put_gradient_menu (table, 0, row++, _("Angular gradient:"), gm); + + gm = gradient_menu_new ((GradientMenuCallback) &ed_gradient_menu_callback, + gflare->rays_angular_size, gflare->rays_angular_size); + ed_put_gradient_menu (table, 0, row++, _("Angular size gradient:"), gm); + + gtk_widget_show (table); + + /* + * Scales + */ + + frame = gimp_frame_new (_("Parameters")); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (5, 3, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add (GTK_CONTAINER (frame), table); + + row = 0; + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("Size (%):"), SCALE_WIDTH, 6, + gflare->rays_size, 0.0, 200.0, 1.0, 10.0, 1, + FALSE, 0, G_MAXINT, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &gflare->rays_size); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("Rotation:"), SCALE_WIDTH, 6, + gflare->rays_rotation, + -180.0, 180.0, 1.0, 15.0, 1, + TRUE, 0, 0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &gflare->rays_rotation); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("Hue rotation:"), SCALE_WIDTH, 6, + gflare->rays_hue, -180.0, 180.0, 1.0, 15.0, 1, + TRUE, 0, 0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &gflare->rays_hue); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("# of Spikes:"), SCALE_WIDTH, 6, + gflare->rays_nspikes, 1, 300, 1.0, 10.0, 0, + FALSE, 0, G_MAXINT, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_int_adjustment_update), + &gflare->rays_nspikes); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("Spike thickness:"), SCALE_WIDTH, 6, + gflare->rays_thickness, 1.0, 100.0, 1.0, 10.0, 1, + FALSE, 0, GIMP_MAX_IMAGE_SIZE, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &gflare->rays_thickness); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + gtk_widget_show (table); + + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, + gtk_label_new_with_mnemonic (_("_Rays"))); + g_signal_connect (vbox, "map", + G_CALLBACK (ed_page_map_callback), + (gpointer) PAGE_RAYS); + gtk_widget_show (vbox); +} + +static void +ed_make_page_sflare (GFlareEditor *ed, + GtkWidget *notebook) +{ + GFlare *gflare = ed->gflare; + GradientMenu *gm; + GtkWidget *vbox; + GtkWidget *table; + GtkWidget *frame; + GtkWidget *shape_vbox; + GSList *shape_group = NULL; + GtkWidget *polygon_hbox; + GtkWidget *seed_hbox; + GtkWidget *toggle; + GtkWidget *label; + GtkWidget *seed; + GtkWidget *entry; + GtkObject *adj; + gchar buf[256]; + gint row; + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); + + /* + * Gradient Menus + */ + + frame = gimp_frame_new (_("Gradients")); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (3, 3, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add (GTK_CONTAINER (frame), table); + + gm = gradient_menu_new ((GradientMenuCallback) &ed_gradient_menu_callback, + gflare->sflare_radial, gflare->sflare_radial); + ed_put_gradient_menu (table, 0, 0, _("Radial gradient:"), gm); + + gm = gradient_menu_new ((GradientMenuCallback) &ed_gradient_menu_callback, + gflare->sflare_sizefac, gflare->sflare_sizefac); + ed_put_gradient_menu (table, 0, 1, _("Size factor gradient:"), gm); + + gm = gradient_menu_new ((GradientMenuCallback) &ed_gradient_menu_callback, + gflare->sflare_probability, gflare->sflare_probability); + ed_put_gradient_menu (table, 0, 2, _("Probability gradient:"), gm); + + gtk_widget_show (table); + + /* + * Scales + */ + + frame = gimp_frame_new (_("Parameters")); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (3, 3, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add (GTK_CONTAINER (frame), table); + + row = 0; + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("Size (%):"), SCALE_WIDTH, 6, + gflare->sflare_size, 0.0, 200.0, 1.0, 10.0, 1, + FALSE, 0, G_MAXINT, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &gflare->sflare_size); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("Rotation:"), SCALE_WIDTH, 6, + gflare->sflare_rotation, + -180.0, 180.0, 1.0, 15.0, 1, + TRUE, 0, 0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &gflare->sflare_rotation); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, + _("Hue rotation:"), SCALE_WIDTH, 6, + gflare->sflare_hue, -180.0, 180.0, 1.0, 15.0, 1, + TRUE, 0, 0, + NULL, NULL); + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_double_adjustment_update), + &gflare->sflare_hue); + g_signal_connect (adj, "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + gtk_widget_show (table); + + /* + * Shape Radio Button Frame + */ + + frame = gimp_frame_new (_("Shape of Second Flares")); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + shape_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); + gtk_container_add (GTK_CONTAINER (frame), shape_vbox); + gtk_widget_show (shape_vbox); + + toggle = gtk_radio_button_new_with_label (shape_group, _("Circle")); + shape_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (toggle)); + g_object_set_data (G_OBJECT (toggle), "gimp-item-data", + GINT_TO_POINTER (GF_CIRCLE)); + g_signal_connect (toggle, "toggled", + G_CALLBACK (ed_shape_radio_callback), + &gflare->sflare_shape); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), + gflare->sflare_shape == GF_CIRCLE); + gtk_box_pack_start (GTK_BOX (shape_vbox), toggle, FALSE, FALSE, 0); + gtk_widget_show (toggle); + + polygon_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (shape_vbox), polygon_hbox, FALSE, FALSE, 0); + gtk_widget_show (polygon_hbox); + + toggle = ed->polygon_toggle = + gtk_radio_button_new_with_label (shape_group, _("Polygon")); + shape_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (toggle)); + g_object_set_data (G_OBJECT (toggle), "gimp-item-data", + GINT_TO_POINTER (GF_POLYGON)); + g_signal_connect (toggle, "toggled", + G_CALLBACK (ed_shape_radio_callback), + &gflare->sflare_shape); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), + gflare->sflare_shape == GF_POLYGON); + gtk_box_pack_start (GTK_BOX (polygon_hbox), toggle, FALSE, FALSE, 0); + gtk_widget_show (toggle); + + entry = ed->polygon_entry = gtk_entry_new (); + gtk_entry_set_width_chars (GTK_ENTRY (entry), 4); + g_snprintf (buf, sizeof (buf), "%d", gflare->sflare_nverts); + gtk_entry_set_text (GTK_ENTRY (entry), buf); + g_signal_connect (entry, "changed", + G_CALLBACK (ed_ientry_callback), + &gflare->sflare_nverts); + gtk_box_pack_start (GTK_BOX (polygon_hbox), entry, FALSE, FALSE, 0); + gtk_widget_show (entry); + + g_object_bind_property (toggle, "active", + entry, "sensitive", + G_BINDING_SYNC_CREATE); + + /* + * Random Seed Entry + */ + + seed_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (vbox), seed_hbox, FALSE, FALSE, 0); + gtk_widget_show (seed_hbox); + + label = gtk_label_new (_("Random seed:")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_box_pack_start (GTK_BOX (seed_hbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + seed = gimp_random_seed_new (&gflare->sflare_seed, &gflare->random_seed); + gtk_box_pack_start (GTK_BOX (seed_hbox), seed, FALSE, TRUE, 0); + gtk_widget_show (seed); + + g_signal_connect (GIMP_RANDOM_SEED_SPINBUTTON_ADJ (seed), "value-changed", + G_CALLBACK (ed_preview_update), + NULL); + + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, + gtk_label_new_with_mnemonic (_("_Second Flares"))); + g_signal_connect (vbox, "map", + G_CALLBACK (ed_page_map_callback), + (gpointer) PAGE_SFLARE); + gtk_widget_show (vbox); +} + +GtkWidget * +ed_mode_menu_new (GFlareMode *mode_var) +{ + GtkWidget *combo = gimp_int_combo_box_new_array (GF_NUM_MODES, + gflare_menu_modes); + + gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), *mode_var, + G_CALLBACK (ed_mode_menu_callback), + mode_var); + + return combo; +} + +/* + puts gradient menu with caption into table + occupies 1 row and 3 cols in table + */ +static void +ed_put_gradient_menu (GtkWidget *table, + gint x, + gint y, + const gchar *caption, + GradientMenu *gm) +{ + GtkWidget *label; + + label = gtk_label_new (caption); + gtk_label_set_xalign (GTK_LABEL (label), 1.0); + gtk_widget_show (label); + + gtk_table_attach (GTK_TABLE (table), label, + x , x + 1, y, y + 1, + GTK_FILL, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), gm->preview, + x + 1, x + 2, y, y + 1, + 0, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), gm->combo, + x + 2, x + 3, y, y + 1, + 0, 0, 0, 0); +} + +static void +ed_mode_menu_callback (GtkWidget *widget, + gpointer data) +{ + gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), (gint *) data); + + ed_preview_update (); +} + +static void +ed_gradient_menu_callback (const gchar *gradient_name, + gpointer data) +{ + gchar *dest_string = data; + + /* @GRADIENT_NAME */ + gradient_name_copy (dest_string, gradient_name); + ed_preview_update (); +} + +static void +ed_shape_radio_callback (GtkWidget *widget, + gpointer data) +{ + gimp_radio_button_update (widget, data); + + ed_preview_update (); +} + +static void +ed_ientry_callback (GtkWidget *widget, + gpointer data) +{ + gint new_val; + + new_val = atoi (gtk_entry_get_text (GTK_ENTRY (widget))); + *(gint *)data = new_val; + + ed_preview_update (); +} + +/* + NOTE: This is hack, because this code depends on internal "map" + signal of changing pages of gtknotebook. + */ +static void +ed_page_map_callback (GtkWidget *widget, + gpointer data) +{ + gint page_num = GPOINTER_TO_INT (data); + + DEBUG_PRINT(("ed_page_map_callback\n")); + + ed->cur_page = page_num; + ed_preview_update (); +} + + +static void +ed_preview_update (void) +{ + if (ed->init) + return; + + ed->init_params_done = FALSE; + preview_render_start (ed->preview); +} + +static gint +ed_preview_init_func (Preview *preview, gpointer data) +{ + int type = 0; + + if (ed->init_params_done == FALSE) + { + switch (ed->cur_page) + { + case PAGE_GENERAL: + type = (CALC_GLOW | CALC_RAYS | CALC_SFLARE); + break; + case PAGE_GLOW: + type = CALC_GLOW; + break; + case PAGE_RAYS: + type = CALC_RAYS; + break; + case PAGE_SFLARE: + type = CALC_SFLARE; + break; + default: + g_warning ("ed_preview_edit_func: bad page"); + break; + } + calc_init_params (ed->gflare, type, + ED_PREVIEW_WIDTH/2, ED_PREVIEW_HEIGHT/2, + ED_PREVIEW_WIDTH/2, 0.0, 0.0, + pvals.vangle, pvals.vlength); + + ed->init_params_done = TRUE; + return TRUE; + } + return calc_init_progress (); +} + +static void +ed_preview_deinit_func (Preview *preview, gpointer data) +{ + if (ed->init_params_done) + { + calc_deinit (); + ed->init_params_done = FALSE; + } +} + +static void +ed_preview_render_func (Preview *preview, + guchar *buffer, + gint y, + gpointer data) +{ + switch (ed->cur_page) + { + case PAGE_GENERAL: + ed_preview_render_general (buffer, y); + break; + case PAGE_GLOW: + ed_preview_render_glow (buffer, y); + break; + case PAGE_RAYS: + ed_preview_render_rays (buffer, y); + break; + case PAGE_SFLARE: + ed_preview_render_sflare (buffer, y); + break; + default: + g_warning ("hmm, bad page in ed_preview_render_func ()"); + break; + } +} + +static void +ed_preview_render_general (guchar *buffer, gint y) +{ + int x, i; + guchar gflare_pix[4]; + static guchar src_pix[4] = {0, 0, 0, OPAQUE}; + int gflare_a; + + for (x = 0; x < ED_PREVIEW_WIDTH; x++) + { + calc_gflare_pix (gflare_pix, x, y, src_pix); + gflare_a = gflare_pix[3]; + + for (i = 0; i < 3; i++) + { + *buffer++ = gflare_pix[i] * gflare_a / 255; + } + } +} + +static void +ed_preview_render_glow (guchar *buffer, gint y) +{ + int x, i; + guchar pix[4]; + + for (x = 0; x < ED_PREVIEW_WIDTH; x++) + { + calc_glow_pix (pix, x, y); + for (i = 0; i < 3; i++) + *buffer++ = pix[i] * pix[3] / 255; + } +} + +static void +ed_preview_render_rays (guchar *buffer, gint y) +{ + int x, i; + guchar pix[4]; + + for (x = 0; x < ED_PREVIEW_WIDTH; x++) + { + calc_rays_pix (pix, x, y); + for (i = 0; i < 3; i++) + *buffer++ = pix[i] * pix[3] / 255; + } +} + +static void +ed_preview_render_sflare (guchar *buffer, gint y) +{ + int x, i; + guchar pix[4]; + static guchar src_pix[4] = {0, 0, 0, OPAQUE}; + + for (x = 0; x < ED_PREVIEW_WIDTH; x++) + { + calc_sflare_pix (pix, x, y, src_pix); + for (i = 0; i < 3; i++) + *buffer++ = pix[i] * pix[3] / 255; + } +} + +/*************************************************************************/ +/** **/ +/** +++ Preview **/ +/** **/ +/*************************************************************************/ + +/* + this is generic preview routines. + */ + + +/* + Routines to render the preview in background + */ +static Preview * +preview_new (gint width, + gint height, + PreviewInitFunc init_func, + gpointer init_data, + PreviewRenderFunc render_func, + gpointer render_data, + PreviewDeinitFunc deinit_func, + gpointer deinit_data) +{ + Preview *preview; + + preview = g_new0 (Preview, 1); + + preview->widget = gimp_preview_area_new (); + gtk_widget_set_size_request (preview->widget, width, height); + gtk_widget_show (preview->widget); + + preview->width = width; + preview->height = height; + preview->init_func = init_func; + preview->init_data = init_data; + preview->render_func = render_func; + preview->render_data = render_data; + preview->deinit_func = deinit_func; + preview->deinit_data = deinit_data; + preview->idle_tag = 0; + preview->buffer = g_new (guchar, width * 3); + preview->full_image_buffer = g_new (guchar, width * height * 3); + + return preview; +} + +static void +preview_free (Preview *preview) +{ + preview_render_end (preview); + /* not destroy preview->widget */ + g_free (preview->buffer); + g_free (preview->full_image_buffer); + g_free (preview); +} + +/* + Start rendering of the preview in background using an idle event. + If already started and not yet finished, stop it first. + */ +static void +preview_render_start (Preview *preview) +{ + preview_render_end (preview); + + preview->init_done = FALSE; + preview->current_y = 0; + preview->drawn_y = 0; + preview->timeout_tag = g_timeout_add (100, + (GSourceFunc) preview_render_start_2, + preview); +} + +static gint +preview_render_start_2 (Preview *preview) +{ + preview->timeout_tag = 0; + preview->idle_tag = g_idle_add ((GSourceFunc) preview_handle_idle, preview); + return FALSE; +} + +static void +preview_render_end (Preview *preview) +{ + if (preview->timeout_tag > 0) + { + g_source_remove (preview->timeout_tag); + preview->timeout_tag = 0; + } + if (preview->idle_tag > 0) + { + if (preview->deinit_func) + (*preview->deinit_func) (preview, preview->deinit_data); + + g_source_remove (preview->idle_tag); + preview->idle_tag = 0; + } +} + +/* + Handle an idle event. + Return FALSE if done, TRUE otherwise. + */ +static gboolean +preview_handle_idle (Preview *preview) +{ + gboolean done = FALSE; + + if (preview->init_done == FALSE) + { + if (preview->init_func && + (*preview->init_func) (preview, preview->init_data)) + return TRUE; + + preview->init_done = TRUE; + } + + if (preview->render_func) + (*preview->render_func) (preview, preview->buffer, preview->current_y, + preview->render_data); + else + memset (preview->buffer, 0, preview->width * 3); + + memcpy (preview->full_image_buffer + preview->width * 3 * preview->current_y, + preview->buffer, + preview->width * 3); + + if (++preview->current_y >= preview->height) + done = TRUE; + + if (done) + { + gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview->widget), + 0, 0, preview->width, preview->height, + GIMP_RGB_IMAGE, + preview->full_image_buffer, + preview->width * 3); + + preview->drawn_y = preview->current_y; + preview_render_end (preview); + return FALSE; + } + + return TRUE; +} + +/* + Convert RGBA to RGB with rendering gray check if needed. + (from nova.c) + input: guchar src[4] RGBA pixel + output: guchar dest[3] RGB pixel + */ + +static void +preview_rgba_to_rgb (guchar *dest, + gint x, + gint y, + guchar *src) +{ + gint src_a; + gint check; + gint b; + + src_a = src[3]; + + if (src_a == OPAQUE) /* full opaque */ + { + for (b = 0; b < 3; b++) + dest[b] = src[b]; + } + else + { + if ((x % (GIMP_CHECK_SIZE) < GIMP_CHECK_SIZE_SM) ^ + (y % (GIMP_CHECK_SIZE) < GIMP_CHECK_SIZE_SM)) + check = GIMP_CHECK_LIGHT * 255; + else + check = GIMP_CHECK_DARK * 255; + + if (src_a == 0) /* full transparent */ + { + for (b = 0; b < 3; b++) + dest[b] = check; + } + else + { + for (b = 0; b < 3; b++) + dest[b] = (src[b] * src_a + check * (OPAQUE-src_a)) / OPAQUE; + } + } +} + +/*************************************************************************/ +/** **/ +/** +++ Gradient Menu **/ +/** +++ gm **/ +/** **/ +/*************************************************************************/ + +static void +gradient_menu_init (void) +{ + gm_gradient_get_list (); + gradient_menus = NULL; +} + +static void +gradient_menu_rescan (void) +{ + GList *tmp; + GradientMenu *gm; + GtkTreeModel *model; + + /* Detach and destroy menus first */ + tmp = gradient_menus; + while (tmp) + { + gm = tmp->data; + tmp = tmp->next; + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (gm->combo)); + gtk_list_store_clear (GTK_LIST_STORE (model)); + } + + gm_gradient_get_list (); + + tmp = gradient_menus; + while (tmp) + { + gm = tmp->data; + tmp = tmp->next; + + gm_gradient_combo_fill (gm, gm->gradient_name); + } +} + +static GradientMenu * +gradient_menu_new (GradientMenuCallback callback, + gpointer callback_data, + const gchar *default_gradient_name) +{ + GradientMenu *gm = g_new (GradientMenu, 1); + + gm->callback = callback; + gm->callback_data = callback_data; + + gm->preview = gimp_preview_area_new (); + gtk_widget_set_size_request (gm->preview, + GM_PREVIEW_WIDTH, GM_PREVIEW_HEIGHT); + + gm->combo = g_object_new (GIMP_TYPE_INT_COMBO_BOX, NULL); + + g_signal_connect (gm->combo, "changed", + G_CALLBACK (gm_gradient_combo_callback), + gm); + + gm_gradient_combo_fill (gm, default_gradient_name); + + gtk_widget_show (gm->preview); + gtk_widget_show (gm->combo); + + g_signal_connect (gm->combo, "destroy", + G_CALLBACK (gm_combo_destroy_callback), + gm); + + gradient_menus = g_list_append (gradient_menus, gm); + + return gm; +} + +/* Local Functions */ + +static void +gm_gradient_get_list (void) +{ + int i; + + if (gradient_names) + { + for (i = 0; i < num_gradient_names; i++) + g_free (gradient_names[i]); + g_free (gradient_names); + } + + gradient_cache_flush (); /* to make sure */ + gradient_names = gradient_get_list (&num_gradient_names); +} + +static void +gm_gradient_combo_fill (GradientMenu *gm, + const gchar *default_gradient) +{ + gint active = 0; + gint i; + + for (i = 0; i < num_gradient_names; i++) + { + const gchar *name = gradient_names[i]; + + if (strcmp (name, default_gradient) == 0) + active = i; + + gimp_int_combo_box_append (GIMP_INT_COMBO_BOX (gm->combo), + GIMP_INT_STORE_VALUE, i, + GIMP_INT_STORE_LABEL, name, + -1); + } + + gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (gm->combo), active); +} + +static void +gm_gradient_combo_callback (GtkWidget *widget, + gpointer data) +{ + GradientMenu *gm = data; + const gchar *gradient_name; + gint index; + + if (! gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &index) || + index < 0 || + index >= num_gradient_names) + return; + + gradient_name = gradient_names[index]; + + DEBUG_PRINT(("gm_combo_callback\n")); + + gradient_name_copy (gm->gradient_name, gradient_name); + + gm_preview_draw (gm->preview, gradient_name); + + if (gm->callback) + (* gm->callback) (gradient_name, gm->callback_data); +} + +static void +gm_preview_draw (GtkWidget *preview, + const gchar *gradient_name) +{ + guchar values[GM_PREVIEW_WIDTH][4]; + gint nvalues = GM_PREVIEW_WIDTH; + gint row, irow, col; + guchar dest_row[GM_PREVIEW_WIDTH][3]; + guchar *dest; + guchar *src; + gint check, b; + guchar *dest_total_preview_buffer; + const gint alpha = 3; + + gradient_get_values (gradient_name, (guchar *)values, nvalues); + + dest_total_preview_buffer = g_new (guchar, + GM_PREVIEW_HEIGHT * GM_PREVIEW_WIDTH * 3); + + for (row = 0; row < GM_PREVIEW_HEIGHT; row += GIMP_CHECK_SIZE_SM) + { + for (col = 0; col < GM_PREVIEW_WIDTH; col++) + { + dest = dest_row[col]; + src = values[col]; + + if (src[alpha] == OPAQUE) + { + /* no alpha channel or opaque -- simple way */ + for (b = 0; b < alpha; b++) + dest[b] = src[b]; + } + else + { + /* more or less transparent */ + if((col % (GIMP_CHECK_SIZE) < GIMP_CHECK_SIZE_SM) ^ + (row % (GIMP_CHECK_SIZE) < GIMP_CHECK_SIZE_SM)) + { + check = GIMP_CHECK_LIGHT * 255; + } + else + { + check = GIMP_CHECK_DARK * 255; + } + + if (src[alpha] == 0) + { + /* full transparent -- check */ + for (b = 0; b < alpha; b++) + dest[b] = check; + } + else + { + /* middlemost transparent -- mix check and src */ + for (b = 0; b < alpha; b++) + dest[b] = (src[b] * src[alpha] + + check * (OPAQUE - src[alpha])) / OPAQUE; + } + } + } + + for (irow = 0; + irow < GIMP_CHECK_SIZE_SM && row + irow < GM_PREVIEW_HEIGHT; + irow++) + { + memcpy (dest_total_preview_buffer + (row+irow) * 3 * GM_PREVIEW_WIDTH, + dest_row, + GM_PREVIEW_WIDTH * 3); + } + } + + gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview), + 0, 0, GM_PREVIEW_WIDTH, GM_PREVIEW_HEIGHT, + GIMP_RGB_IMAGE, + (const guchar *) dest_total_preview_buffer, + GM_PREVIEW_WIDTH * 3); + + g_free (dest_total_preview_buffer); +} + +static void +gm_combo_destroy_callback (GtkWidget *w, + gpointer data) +{ + GradientMenu *gm = data; + gradient_menus = g_list_remove (gradient_menus, gm); +} + +/*************************************************************************/ +/** **/ +/** +++ Gradients **/ +/** **/ +/*************************************************************************/ + +/* + Manage both internal and external gradients: list up, cache, + sampling, etc. + + External gradients are cached. + */ + + +static void +gradient_name_copy (gchar *dest, + const gchar *src) +{ + strncpy (dest, src, GRADIENT_NAME_MAX - 1); + dest[GRADIENT_NAME_MAX - 1] = '\0'; +} + +/* + Translate SPACE to "\\040", etc. + */ +static void +gradient_name_encode (gchar *dest, + const gchar *src) +{ + gint cnt = GRADIENT_NAME_MAX - 1; + + while (*src && cnt--) + { + if (g_ascii_iscntrl (*src) || g_ascii_isspace (*src) || *src == '\\') + { + sprintf (dest, "\\%03o", *src++); + dest += 4; + } + else + *dest++ = *src++; + } + *dest = '\0'; +} + +/* + Translate "\\040" to SPACE, etc. + */ +static void +gradient_name_decode (gchar *dest, + const gchar *src) +{ + gint cnt = GRADIENT_NAME_MAX - 1; + guint tmp; + + while (*src && cnt--) + { + if (*src == '\\' && *(src+1) && *(src+2) && *(src+3)) + { + sscanf (src+1, "%3o", &tmp); + *dest++ = tmp; + src += 4; + } + else + *dest++ = *src++; + } + *dest = '\0'; +} + +static void +gradient_init (void) +{ + gradient_cache_head = NULL; + gradient_cache_count = 0; +} + +static void +gradient_free (void) +{ + gradient_cache_flush (); +} + +static gchar ** +gradient_get_list (gint *num_gradients) +{ + gchar **gradients; + gchar **external_gradients = NULL; + gint external_ngradients = 0; + gint i, n; + + gradient_cache_flush (); + external_gradients = gimp_gradients_get_list (NULL, &external_ngradients); + + *num_gradients = G_N_ELEMENTS (internal_gradients) + external_ngradients; + gradients = g_new (gchar *, *num_gradients); + + n = 0; + for (i = 0; i < G_N_ELEMENTS (internal_gradients); i++) + { + gradients[n++] = g_strdup (internal_gradients[i]); + } + for (i = 0; i < external_ngradients; i++) + { + gradients[n++] = g_strdup (external_gradients[i]); + } + + g_strfreev (external_gradients); + + return gradients; +} + +static void +gradient_get_values (const gchar *gradient_name, + guchar *values, + gint nvalues) +{ + /* + Criteria to distinguish internal and external is rather simple here. + It should be fixed later. + */ + if (gradient_name[0] == '%') + gradient_get_values_internal (gradient_name, values, nvalues); + else + gradient_get_values_external (gradient_name, values, nvalues); +} + +static void +gradient_get_values_internal (const gchar *gradient_name, + guchar *values, + gint nvalues) +{ + const guchar white[4] = { 255, 255, 255, 255 }; + const guchar white_trans[4] = { 255, 255, 255, 0 }; + const guchar red_trans[4] = { 255, 0, 0, 0 }; + const guchar blue_trans[4] = { 0, 0, 255, 0 }; + const guchar yellow_trans[4] = { 255, 255, 0, 0 }; + + /* + The internal gradients here are example -- + What kind of internals would be useful ? + */ + if(!strcmp(gradient_name, "%white")) + { + gradient_get_blend (white, white, values, nvalues); + } + else if(!strcmp(gradient_name, "%white_grad")) + { + gradient_get_blend (white, white_trans, values, nvalues); + } + else if (!strcmp (gradient_name, "%red_grad")) + { + gradient_get_blend (white, red_trans, values, nvalues); + } + else if (!strcmp (gradient_name, "%blue_grad")) + { + gradient_get_blend (white, blue_trans, values, nvalues); + } + else if (!strcmp (gradient_name, "%yellow_grad")) + { + gradient_get_blend (white, yellow_trans, values, nvalues); + } + else if (!strcmp (gradient_name, "%random")) + { + gradient_get_random (values, nvalues); + } + else + { + gradient_get_default (gradient_name, values, nvalues); + } +} + +static void +gradient_get_blend (const guchar *fg, + const guchar *bg, + guchar *values, + gint nvalues) +{ + gdouble x; + gint i; + gint j; + guchar *v = values; + + for (i = 0; i < nvalues; i++) + { + x = (double) i / nvalues; + for (j = 0; j < 4; j++) + *v++ = fg[j] * (1 - x) + bg[j] * x; + } +} + +static void +gradient_get_random (guchar *values, + gint nvalues) +{ + gint i; + gint j; + gint inten; + guchar *v = values; + + /* + This is really simple -- gaussian noise might be better + */ + for (i = 0; i < nvalues; i++) + { + inten = g_random_int_range (0, 256); + for (j = 0; j < 3; j++) + *v++ = inten; + *v++ = 255; + } +} + +static void +gradient_get_default (const gchar *name, + guchar *values, + gint nvalues) +{ + gdouble e[3]; + gdouble x; + gint i; + gint j; + guchar *v = values; + + /* + Create gradient by name + */ + name++; + for (j = 0; j < 3; j++) + e[j] = name[j] / 255.0; + + for (i = 0; i < nvalues; i++) + { + x = (double) i / nvalues; + for (j = 0; j < 3; j++) + *v++ = 255 * pow (x, e[j]); + *v++ = 255; + } +} + +/* + Caching gradients is really needed. It really takes 0.2 seconds each + time to resample an external gradient. (And this plug-in has + currently 6 gradient menus.) + + However, this caching routine is not too good. It picks up just + GRADIENT_RESOLUTION samples every time, and rescales it later. And + cached values are stored in guchar array. No accuracy. + */ +static void +gradient_get_values_external (const gchar *gradient_name, + guchar *values, + gint nvalues) +{ + GradientCacheItem *ci; + gboolean found; +#ifdef DEBUG + clock_t clk = clock (); +#endif + + g_return_if_fail (nvalues >= 2); + + ci = gradient_cache_lookup (gradient_name, &found); + if (!found) + { + /* FIXME: "reverse" hardcoded to FALSE. */ + gradient_get_values_real_external (gradient_name, ci->values, + GRADIENT_RESOLUTION, FALSE); + } + if (nvalues == GRADIENT_RESOLUTION) + { + memcpy (values, ci->values, 4 * GRADIENT_RESOLUTION); + } + else + { + double pos, frac; + int ipos; + int i, j; + + for (i = 0; i < nvalues; i++) + { + pos = ((double) i / (nvalues - 1)) * (GRADIENT_RESOLUTION - 1); + g_assert (0 <= pos && pos <= GRADIENT_RESOLUTION - 1); + ipos = (int) pos; frac = pos - ipos; + if (frac == 0.0) + { + memcpy (&values[4 * i], &ci->values[4 * ipos], 4); + } + else + for (j = 0; j < 4; j++) + values[4 * i + j] = ci->values[4 * ipos + j] * (1 - frac) + + ci->values[4 * (ipos + 1) + j] * frac; + } + } + +#ifdef DEBUG + get_values_external_clock += clock () - clk; + get_values_external_count ++; +#endif + +} + +static void +gradient_get_values_real_external (const gchar *gradient_name, + guchar *values, + gint nvalues, + gboolean reverse) +{ + gint n_tmp_values; + gdouble *tmp_values; + gint i; + gint j; + + gimp_gradient_get_uniform_samples (gradient_name, nvalues, reverse, + &n_tmp_values, &tmp_values); + + for (i = 0; i < nvalues; i++) + for (j = 0; j < 4; j++) + values[4 * i + j] = (guchar) (tmp_values[4 * i + j] * 255); + + g_free (tmp_values); +} + +void +gradient_cache_flush (void) +{ + GradientCacheItem *ci; + GradientCacheItem *tmp; + + ci = gradient_cache_head; + while (ci) + { + tmp = ci->next; + g_free (ci); + ci = tmp; + } + gradient_cache_head = NULL; + gradient_cache_count = 0; +} + +static GradientCacheItem * +gradient_cache_lookup (const gchar *name, + gboolean *found) +{ + GradientCacheItem *ci; + + ci = gradient_cache_head; + while (ci) + { + if (!strcmp (ci->name, name)) + break; + ci = ci->next; + } + if (ci) + { + *found = TRUE; + if (!ci->prev) + { + g_assert (ci == gradient_cache_head); + return ci; + } + ci->prev->next = ci->next; + if (ci->next) + ci->next->prev = ci->prev; + ci->next = gradient_cache_head; + gradient_cache_head->prev = ci; + gradient_cache_head = ci; + ci->prev = NULL; + return ci; + } + else + { + *found = FALSE; + while (gradient_cache_count >= GRADIENT_CACHE_SIZE) + gradient_cache_zorch(); + ci = g_new (GradientCacheItem, 1); + strncpy (ci->name, name, GRADIENT_NAME_MAX - 1); + ci->name[GRADIENT_NAME_MAX - 1] = '\0'; + ci->next = gradient_cache_head; + ci->prev = NULL; + if (gradient_cache_head) + gradient_cache_head->prev = ci; + gradient_cache_head = ci; + ++gradient_cache_count; + return ci; + } +} + +static void +gradient_cache_zorch (void) +{ + GradientCacheItem *ci = gradient_cache_head; + + while (ci && ci->next) + { + ci = ci->next; + } + if (ci) + { + g_assert (ci->next == NULL); + if (ci->prev) + ci->prev->next = NULL; + else + gradient_cache_head = NULL; + g_free (ci); + --gradient_cache_count; + } +} + +#ifdef DEBUG +void +gradient_report (void) +{ + double total = (double) get_values_external_clock / CLOCKS_PER_SEC; + + g_printerr ("gradient_get_values_external " + "%.2f sec. / %d times (ave %.2f sec.)\n", + total, + get_values_external_count, + total / get_values_external_count); +} +#endif |