static void category_index (gpointer key, gpointer value, gpointer user_data) { gchar *category = key; GList *operations = value; GList *iter; gboolean comma; if (!strcmp (category, "hidden")) return; g_print ("<a name='cat_%s'></a><h3>%s</h3>\n", category, category); g_print ("<div class='category'>\n"); for (iter=operations, comma=FALSE;iter;iter = g_list_next (iter)) { GeglOperationClass *klass = iter->data; const char *categories = gegl_operation_class_get_key (klass, "categories"); if (categories && strstr (categories, "hidden")) continue; g_print ("%s<a href='#op_%s'>%s</a>\n", comma?"":"", klass->name, klass->name); comma = TRUE; } g_print ("<div style='clear:both;'></div></div>\n"); }
/* Builds a GList of the class structures of all subtypes of type. */ static GList * gimp_get_subtype_classes (GType type, GList *classes) { GeglOperationClass *klass; GType *ops; const gchar *categories; guint n_ops; gint i; if (! type) return classes; klass = GEGL_OPERATION_CLASS (g_type_class_ref (type)); ops = g_type_children (type, &n_ops); categories = gegl_operation_class_get_key (klass, "categories"); if (! gimp_gegl_tool_operation_blacklisted (klass->name, categories)) classes = g_list_prepend (classes, klass); for (i = 0; i < n_ops; i++) classes = gimp_get_subtype_classes (ops[i], classes); if (ops) g_free (ops); return classes; }
/* Calls the prepare function on the operation that extends this base class */ void gegl_operation_prepare (GeglOperation *self) { GeglOperationClass *klass; g_return_if_fail (GEGL_IS_OPERATION (self)); klass = GEGL_OPERATION_GET_CLASS (self); /* build OpenCL kernel */ if (!klass->cl_data) { const gchar *cl_source = gegl_operation_class_get_key (klass, "cl-source"); if (cl_source) { char *name = strdup (klass->name); const char *kernel_name[] = {name, NULL}; char *k; for (k=name; *k; k++) switch (*k) { case ' ': case ':': case '-': *k = '_'; break; } klass->cl_data = gegl_cl_compile_and_build (cl_source, kernel_name); free (name); } } if (klass->prepare) klass->prepare (self); }
const gchar * gegl_operation_get_key (const gchar *operation_name, const gchar *key_name) { GType type; GObjectClass *klass; const gchar *ret = NULL; type = gegl_operation_gtype_from_name (operation_name); if (!type) { return NULL; } klass = g_type_class_ref (type); ret = gegl_operation_class_get_key (GEGL_OPERATION_CLASS (klass), key_name); g_type_class_unref (klass); return ret; }
static void category_menu_index (gpointer key, gpointer value, gpointer user_data) { gchar *category = key; GList *operations = value; GList *iter; if (!strcmp (category, "hidden")) return; for (iter=operations;iter;iter = g_list_next (iter)) { GeglOperationClass *klass = iter->data; const char *categories = gegl_operation_class_get_key (klass, "categories"); if (!categories || strstr (categories, "hidden")) continue; g_print ("<li><a href='#op_%s'>%s</a></li>\n", klass->name, klass->name); } }
gint main (gint argc, gchar **argv) { GList *operations; GList *iter; gboolean first = TRUE; gegl_init (&argc, &argv); g_object_set (gegl_config (), "application-license", "GPL3", NULL); operations = gegl_operations (); g_print ("window.opdb=[\n"); for (iter=operations;iter;iter = g_list_next (iter)) { GeglOperationClass *klass = iter->data; const char *name = gegl_operation_class_get_key (klass, "name"); const char *categoris = gegl_operation_class_get_key (klass, "categories"); if (first) first = FALSE; else g_print (","); g_print ("{'op':'%s'\n", name); if (klass->compat_name) g_print (",'compat-op':'%s'\n", klass->compat_name); if (klass->opencl_support) g_print (",'opencl-support':'true'\n"); g_print (",'parent':'%s'\n", g_type_name (g_type_parent(G_OBJECT_CLASS_TYPE(klass)))); { char *image = operation_to_path (name); if (g_file_test (image, G_FILE_TEST_EXISTS)) g_print (",'image':'%s'\n", image); g_free (image); } { gchar *commandline = g_strdup_printf ( "sh -c \"(cd " TOP_SRCDIR ";grep -r '\\\"%s\\\"' operations) | grep operations | grep -v '~:' | grep '\\\"name\\\"' | cut -f 1 -d ':'\"", name); gchar *output = NULL; if (g_spawn_command_line_sync (commandline, &output, NULL, NULL, NULL)) { if (strlen(output)) { output[strlen(output)-1] = 0; g_print ( ",'source':'https://git.gnome.org/browse/gegl/tree/%s'\n", output); } g_free (output); } g_free (commandline); } if (categoris) { const gchar *ptr = categoris; gboolean first = TRUE; g_print (",'categories':["); while (ptr && *ptr) { gchar category[64]=""; gint i=0; while (*ptr && *ptr!=':' && i<63) { category[i++]=*(ptr++); category[i]='\0'; } if (*ptr==':') ptr++; { if (first) first = FALSE; else g_print (","); g_print ("'%s'", category); } } g_print ("]\n"); } json_list_properties (G_OBJECT_CLASS_TYPE (klass), name); json_list_pads (G_OBJECT_CLASS_TYPE (klass), name); { guint nkeys; gchar **keys = gegl_operation_list_keys (name, &nkeys); if (keys) { for (gint i = 0; keys[i]; i++) { const gchar *value = gegl_operation_get_key (name, keys[i]); if (g_str_equal (keys[i], "categories") || g_str_equal (keys[i], "cl-source") || g_str_equal (keys[i], "source") || g_str_equal (keys[i], "name") ) continue; g_print (",\"%s\":\"", keys[i]); json_escape_string (value); g_print ("\"\n"); } g_free (keys); } } g_print (" }\n"); } g_print ("]\n"); return 0; }
static gboolean process_operations (GType type) { GType *operations; gboolean result = TRUE; guint count; gint i; operations = g_type_children (type, &count); if (!operations) { g_free (operations); return TRUE; } for (i = 0; i < count; i++) { GeglOperationClass *operation_class; const gchar *image, *xml, *name; gboolean matches; operation_class = g_type_class_ref (operations[i]); image = gegl_operation_class_get_key (operation_class, "reference-image"); xml = gegl_operation_class_get_key (operation_class, "reference-composition"); name = gegl_operation_class_get_key (operation_class, "name"); if (name == NULL) { result = result && process_operations (operations[i]); continue; } matches = g_regex_match (regex, name, 0, NULL) && !g_regex_match (exc_regex, name, 0, NULL); if (xml && matches) { GeglNode *composition; if (output_all) g_printf ("%s\n", name); else if (image) g_printf ("%s: ", name); /* more information will follow if we're testing */ composition = gegl_node_new_from_xml (xml, data_dir); if (!composition) { g_printf ("FAIL\n Composition graph is flawed\n"); result = FALSE; } else if (image || output_all) { gchar *output_path = operation_to_path (name, FALSE); GeglNode *output = gegl_node_new_child (composition, "operation", "gegl:png-save", "compression", 9, "path", output_path, NULL); gegl_node_link (composition, output); gegl_node_process (output); g_object_unref (composition); /* don't test if run with --all */ if (!output_all && image) result = test_operation (name, image, output_path) && result; g_free (output_path); } } /* if we are running with --all and the operation doesn't have a composition, use standard composition and images, don't test */ else if (output_all && matches && !(g_type_is_a (operations[i], GEGL_TYPE_OPERATION_SINK) || g_type_is_a (operations[i], GEGL_TYPE_OPERATION_TEMPORAL))) { g_printf ("%s\n", name); standard_output (name); } result = process_operations (operations[i]) && result; } g_free (operations); return result; }
gint main (gint argc, gchar **argv) { GList *operations; GList *iter; GHashTable *categories = NULL; gegl_init (&argc, &argv); operations = gegl_operations (); /* Collect categories */ categories = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); for (iter=operations;iter;iter = g_list_next (iter)) { GeglOperationClass *klass = iter->data; const char *categoris = gegl_operation_class_get_key (klass, "categories"); const gchar *ptr = categoris; while (ptr && *ptr) { gchar category[64]=""; gint i=0; while (*ptr && *ptr!=':' && i<63) { category[i++]=*(ptr++); category[i]='\0'; } if (*ptr==':') ptr++; { GList *items = g_hash_table_lookup (categories, category); g_hash_table_insert (categories, g_strdup (category), g_list_append (items, klass)); } } } g_print ("%s", html_top); #if 0 g_print ("<div id='toc'>\n<ul>\n"); g_print ("<li><a href='index.html'>GEGL</a></li><li> </li>\n"); g_print ("<li><a href='index.html#Documentation'>Documentation</a></li>\n"); g_print ("<li><a href='index.html#Glossary'> Glossary</a></li>\n"); g_print ("<li><a href='operations.html#'> Operations</a></li>\n"); g_print ("<li><a href='api.html'> API reference</a></li>\n"); g_print ("<li><a href=''> </a></li>\n"); g_print ("<li><a href='#Categories'>Categories</a></li>\n"); g_print ("<li><a href=''> </a></li>\n"); /*category_menu_item ("All", NULL, NULL); g_hash_table_foreach (categories, category_menu_item, NULL);*/ /*border: 0.1em dashed rgb(210,210,210); */ //category_menu_index("All", operations, NULL); g_print ("</ul>\n</div>\n"); #endif g_print ("<h1>GEGL operation reference</h1>"); g_print ("<p>Image processing operations are shared objects (plug-ins) loaded when GEGL initializes. " "This page is generated from information registered by the plug-ins themselves.</p>" "<a name='Categories'><h2>Categories</h2></a><p>A plug-in can " "belong in multiple categories. Below is indexes broken down into the various available categories.</p>"); category_index ("All", operations, NULL); /* create menus for each of the categories */ g_hash_table_foreach (categories, category_index, NULL); /* list all operations */ g_print ("<table>\n"); for (iter=operations;iter;iter = g_list_next (iter)) { GeglOperationClass *klass = iter->data; const char *categoris = gegl_operation_class_get_key (klass, "categories"); const char *description = gegl_operation_class_get_key (klass, "description"); const char *name = gegl_operation_class_get_key (klass, "name"); if (categoris && strstr (categoris, "hidden")) continue; g_print ("<tr>\n <td colspan='1'> </td>\n <td class='op_name' colspan='4'><a name='op_%s'>%s</a></td>\n</tr>\n", klass->name, klass->name); if (name) { char *image = operation_to_path (name); if (g_file_test (image, G_FILE_TEST_EXISTS)) g_print ("<tr>\n <td colspan='1'> </td>\n <td colspan='4'><img style='float:right;padding-left:1.5em;' src='%s' />", image); else g_print ("<tr>\n <td colspan='1'> </td>\n"); if (description) g_print ("%s\n", description); g_print ("</td></tr>\n"); g_free (image); } else if (description) g_print ("<tr>\n <td colspan='1'> </td>\n <td class='op_description' colspan='4'>%s</td>\n</tr>\n", description); list_properties (G_OBJECT_CLASS_TYPE (klass), 2, TRUE); } g_print ("</table>\n"); g_print ("%s", html_bottom); g_list_free (operations); gegl_exit (); return 0; }