summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/autotrace/output.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:24:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:24:48 +0000
commitcca66b9ec4e494c1d919bff0f71a820d8afab1fa (patch)
tree146f39ded1c938019e1ed42d30923c2ac9e86789 /src/3rdparty/autotrace/output.c
parentInitial commit. (diff)
downloadinkscape-upstream/1.2.2.tar.xz
inkscape-upstream/1.2.2.zip
Adding upstream version 1.2.2.upstream/1.2.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/3rdparty/autotrace/output.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/src/3rdparty/autotrace/output.c b/src/3rdparty/autotrace/output.c
new file mode 100644
index 0000000..ae44cde
--- /dev/null
+++ b/src/3rdparty/autotrace/output.c
@@ -0,0 +1,239 @@
+/* output.c: interface for output handlers
+
+ Copyright (C) 1999, 2000, 2001 Bernhard Herzog.
+ Copyright (C) 2003 Masatake YAMATO
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA. */
+
+/* TODO: Unify output codes and input codes. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* Def: HAVE_CONFIG_H */
+
+#include "autotrace.h"
+#include "private.h"
+#include "output.h"
+#include "xstd.h"
+#include "filename.h"
+#include <string.h>
+#include <glib.h>
+
+typedef struct _at_output_format_entry at_output_format_entry;
+struct _at_output_format_entry {
+ at_spline_writer writer;
+ const char *descr;
+ GDestroyNotify user_data_destroy_func;
+};
+
+static GHashTable *at_output_formats = NULL;
+static at_output_format_entry *at_output_format_new(const char *descr, at_output_func writer, gpointer user_data, GDestroyNotify user_data_destroy_func);
+static void at_output_format_free(at_output_format_entry * entry);
+
+/*
+ * Helper functions
+ */
+static void output_list_set(gpointer key, gpointer value, gpointer user_data);
+static void output_list_strlen(gpointer key, gpointer value, gpointer user_data);
+static void output_list_strcat(gpointer key, gpointer value, gpointer user_data);
+
+int at_output_init(void)
+{
+ if (at_output_formats)
+ return 1;
+
+ at_output_formats = g_hash_table_new_full(g_str_hash, (GEqualFunc) g_str_equal, g_free, (GDestroyNotify) at_output_format_free);
+ if (!at_output_formats)
+ return 0;
+ return 1;
+}
+
+static at_output_format_entry *at_output_format_new(const gchar * descr, at_output_func writer, gpointer user_data, GDestroyNotify user_data_destroy_func)
+{
+ at_output_format_entry *entry;
+ entry = g_malloc(sizeof(at_output_format_entry));
+ if (entry) {
+ entry->writer.func = writer;
+ entry->writer.data = user_data;
+ entry->descr = g_strdup(descr);
+ entry->user_data_destroy_func = user_data_destroy_func;
+ }
+ return entry;
+}
+
+static void at_output_format_free(at_output_format_entry * entry)
+{
+ g_free((gpointer) entry->descr);
+ if (entry->user_data_destroy_func)
+ entry->user_data_destroy_func(entry->writer.data);
+ g_free(entry);
+
+}
+
+int at_output_add_handler(const gchar * suffix, const gchar * description, at_output_func writer)
+{
+ return at_output_add_handler_full(suffix, description, writer, 0, NULL, NULL);
+}
+
+int at_output_add_handler_full(const gchar * suffix, const gchar * description, at_output_func writer, gboolean override, gpointer user_data, GDestroyNotify user_data_destroy_func)
+{
+ gchar *gsuffix;
+ const gchar *gdescription;
+ at_output_format_entry *old_entry;
+ at_output_format_entry *new_entry;
+
+ g_return_val_if_fail(suffix, 0);
+ g_return_val_if_fail(description, 0);
+ g_return_val_if_fail(writer, 0);
+
+ gsuffix = g_strdup((gchar *) suffix);
+ g_return_val_if_fail(gsuffix, 0);
+ gsuffix = g_ascii_strdown(gsuffix, strlen(gsuffix));
+
+ gdescription = (const gchar *)description;
+
+ old_entry = g_hash_table_lookup(at_output_formats, gsuffix);
+ if (old_entry && !override) {
+ g_free(gsuffix);
+ return 1;
+ }
+
+ new_entry = at_output_format_new(gdescription, writer, user_data, user_data_destroy_func);
+ g_return_val_if_fail(new_entry, 0);
+
+ g_hash_table_replace(at_output_formats, gsuffix, new_entry);
+ return 1;
+}
+
+at_spline_writer *at_output_get_handler(gchar * filename)
+{
+ char *ext = find_suffix(filename);
+ if (ext == NULL)
+ ext = "";
+
+ return at_output_get_handler_by_suffix(ext);
+}
+
+at_spline_writer *at_output_get_handler_by_suffix(const gchar * suffix)
+{
+ at_output_format_entry *format;
+ gchar *gsuffix;
+
+ if (!suffix || suffix[0] == '\0')
+ return NULL;
+
+ gsuffix = g_strdup(suffix);
+ g_return_val_if_fail(gsuffix, NULL);
+ gsuffix = g_ascii_strdown(gsuffix, strlen(gsuffix));
+ format = g_hash_table_lookup(at_output_formats, gsuffix);
+ g_free(gsuffix);
+
+ if (format)
+ return &(format->writer);
+ else
+ return NULL;
+}
+
+const char **at_output_list_new(void)
+{
+ char **list, **tmp;
+ gint format_count;
+ gint list_count;
+
+ format_count = g_hash_table_size(at_output_formats);
+ list_count = 2 * format_count;
+ list = g_new(gchar *, list_count + 1);
+ list[list_count] = NULL;
+
+ tmp = list;
+ g_hash_table_foreach(at_output_formats, output_list_set, &tmp);
+ return (const char **)list;
+}
+
+void at_output_list_free(const char **list)
+{
+ free((char **)list);
+}
+
+char *at_output_shortlist(void)
+{
+ gint length = 0, count;
+ char *list, *tmp;
+ g_hash_table_foreach(at_output_formats, output_list_strlen, &length);
+ count = g_hash_table_size(at_output_formats);
+
+ /* 2 for ", " */
+ length += (2 * count);
+ list = g_malloc(length + 1);
+ list[0] = '\0';
+
+ tmp = list;
+ g_hash_table_foreach(at_output_formats, output_list_strcat, &tmp);
+
+ /* remove final ", " */
+ g_return_val_if_fail(list[length - 2] == ',', NULL);
+ list[length - 2] = '\0';
+ return list;
+}
+
+static void output_list_set(gpointer key, gpointer value, gpointer user_data)
+{
+ at_output_format_entry *format = value;
+ const char ***list_ptr = user_data;
+ const char **list = *list_ptr;
+ list[0] = key;
+ list[1] = format->descr;
+ *list_ptr = &(list[2]);
+}
+
+static void output_list_strlen(gpointer key, gpointer value, gpointer user_data)
+{
+ gint *length;
+ g_return_if_fail(key);
+ g_return_if_fail(user_data);
+
+ length = user_data;
+ *length += strlen(key);
+}
+
+static void output_list_strcat(gpointer key, gpointer value, gpointer user_data)
+{
+ gchar **list_ptr;
+ gchar *list;
+ list_ptr = user_data;
+ list = *list_ptr;
+ strcat(list, key);
+ strcat(list, ", ");
+
+ /* 2 for ", " */
+ *list_ptr = list + strlen(key) + 2;
+}
+
+void at_spline_list_foreach(at_spline_list_type * list, AtSplineListForeachFunc func, gpointer user_data)
+{
+ unsigned i;
+ for (i = 0; i < AT_SPLINE_LIST_LENGTH(list); i++) {
+ func(list, AT_SPLINE_LIST_ELT(list, i), i, user_data);
+ }
+}
+
+void at_spline_list_array_foreach(at_spline_list_array_type * list_array, AtSplineListArrayForeachFunc func, gpointer user_data)
+{
+ unsigned i;
+ for (i = 0; i < AT_SPLINE_LIST_ARRAY_LENGTH(list_array); i++) {
+ func(list_array, AT_SPLINE_LIST_ARRAY_ELT(list_array, i), i, user_data);
+ }
+}