/* * GLOGO 1.2 * * A gimp plug-in to create the linux-logo includefile * * Copyright (C) 1998 Jens Ch. Restemeier * * 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 2 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * History: * 1.0 - first release * 1.1 - Clifford Wolf fixed some bugs, and sent me a nice script to build the three images * neccessary for a logo automagically... * 1.2 - fixed Makefile to use gimp-config * * Some documentation: * - The program installs into the Xtns menu of the toolbox * - The BW-image can be either indexed or grayscale * - grayscale: x<128 = 0, x=>128 = 1 * - indexed: color 0 = 0, color 1 = 1 * - 16-color image: the first 16 colors of a indexed image / grayscale * - 224-color image: the first 224 colors of a indexed image / grayscale * - the alpha-channel is not supported * * HOW-TO: * 1. create three images, or copy one image two times * 2. reduce one of them to 2 colors/grayscale, one to 16 colors and one to 224 colors * 3. select Xtns / Build Linux Logo * 4. select your images * 5. click OK * 6. enter/select a filename * 7. done ! * * - or - * 1. make one image and use the script-fu script... */ #include #include #include #include #include #include static void query (void); static void run (gchar * name, gint nparams, GParam * param, gint * nreturn_vals, GParam ** return_vals); static int run_dialog (); static void print_image (char *s, int i224, int i16, int ibw); /* * GIMP interface */ GPlugInInfo PLUG_IN_INFO = { NULL, /* init_proc */ NULL, /* quit_proc */ query, /* query_proc */ run, /* run_proc */ }; GParamDef args[] = { {PARAM_INT32, "run_mode", "Interactive, non-interactive"}, {PARAM_STRING, "filename", "The name of the file to load"}, {PARAM_DRAWABLE, "image2", "BW-image"}, {PARAM_DRAWABLE, "image16", "16-color image"}, {PARAM_DRAWABLE, "image224", "224-color image"}, }; gint nargs = sizeof (args) / sizeof (args[0]); MAIN () static void query () { gimp_install_procedure ( "extension_linux_logo", "create a linux-logo", "After all the discussion about beer-trinking penguins: A plug-in to create logos from GIMP !", "Jens Ch. Restemeier", "Jens Ch. Restemeier", "1998", "/Xtns/Build Linux Logo", NULL, PROC_EXTENSION, nargs, 0, args, NULL); } GParam values[2]; void run (gchar * name, gint nparams, GParam * param, gint * nreturn_vals, GParam ** return_vals) { GRunModeType run_mode; run_mode = param[0].data.d_int32; *nreturn_vals = 1; *return_vals = values; values[0].type = PARAM_STATUS; values[0].data.d_status = STATUS_CALLING_ERROR; if (strcmp (name, "extension_linux_logo") == 0) { switch (run_mode) { case RUN_NONINTERACTIVE: { gint32 pc; /* * check for valid parameters: * (Or can I trust GIMP ?) */ if (nparams != nargs) { *nreturn_vals = 1; values[0].data.d_status = STATUS_CALLING_ERROR; return; } for (pc = 0; pc < nargs; pc++) { if (args[pc].type != param[pc].type) { *nreturn_vals = 1; values[0].data.d_status = STATUS_CALLING_ERROR; return; } } print_image (param[1].data.d_string, param[2].data.d_drawable, param[3].data.d_drawable, param[4].data.d_drawable); *nreturn_vals = 1; values[0].data.d_status = STATUS_SUCCESS; return; } case RUN_INTERACTIVE: { if (run_dialog ()) { *nreturn_vals = 1; values[0].data.d_status = STATUS_SUCCESS; } else { *nreturn_vals = 1; values[0].data.d_status = STATUS_EXECUTION_ERROR; } return; } case RUN_WITH_LAST_VALS: { *nreturn_vals = 1; values[0].data.d_status = STATUS_CALLING_ERROR; return; } } } } GtkWidget *preview_bw, *preview_c16, *preview_c224; gint index_bw, index_c16, index_c224; int result; static void cb_cancel (GtkWidget * widget, gpointer data) { result = FALSE; gtk_main_quit (); } static void cb_save (GtkWidget * widget, gpointer data) { print_image (gtk_file_selection_get_filename (GTK_FILE_SELECTION ((GtkWidget *) data)), index_bw, index_c16, index_c224); result = TRUE; gtk_main_quit (); } static void cb_ok (GtkWidget * widget, gpointer data) { GtkWidget *file_select; file_select = gtk_file_selection_new ("Enter or select filename..."); gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_select)->ok_button), "clicked", (GtkSignalFunc) cb_save, (gpointer) file_select); gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_select)->cancel_button), "clicked", (GtkSignalFunc) cb_cancel, (gpointer) NULL); gtk_widget_show (file_select); } gint cs_func (gint32 image_id, gint32 drawable_id, gpointer data) { if (drawable_id == -1) return TRUE; return (gimp_drawable_indexed (drawable_id) || gimp_drawable_gray (drawable_id)) && (!gimp_drawable_has_alpha (drawable_id)); } void make_logo (gint32 id, unsigned char *data, unsigned char *palette, int n) { GDrawable *drawable; GPixelRgn pixel_rgn; guchar tmp[80 * 80]; if (gimp_drawable_gray (id)) { if (n == 2) { palette[0] = palette[1] = palette[2] = 0; palette[3] = palette[4] = palette[5] = 255; } else { int i; for (i = 0; i < n; i++) { palette[i * 3 + 0] = palette[i * 3 + 1] = palette[i * 3 + 2] = (256 * i) / n; } } } else { gint ncolors; guchar *pal; gint32 image_id; image_id = gimp_drawable_image_id (id); pal = gimp_image_get_cmap (image_id, &ncolors); memcpy (palette, pal, ncolors * 3); } drawable = gimp_drawable_get (id); gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, 80, 80, FALSE, FALSE); gimp_pixel_rgn_get_rect (&pixel_rgn, tmp, 0, 0, 80, 80); if (gimp_drawable_gray (id)) { int i; for (i = 0; i < 80 * 80; i++) { data[i] = (float) tmp[i] / (256.0 / (float) n); } } else { int i; for (i = 0; i < 80 * 80; i++) { data[i] = tmp[i] < n ? tmp[i] : 0; } } } void print_logo_c224 (FILE * f, gint32 id) { unsigned char data[80 * 80]; unsigned char palette[256 * 3]; int i; make_logo (id, data, palette, 224); fprintf (f, "#if LINUX_LOGO_COLORS == 214\n\n"); fprintf (f, "unsigned char linux_logo_red[] __initdata = {"); for (i = 0; i < 224; i++) { if (!(i % 16)) fprintf (f, "\n "); if (i < 223) { fprintf (f, "0x%2.2x, ", palette[3 * i + 0]); } else { fprintf (f, "0x%2.2x\n", palette[3 * i + 0]); } } fprintf (f, "};\n\n"); fprintf (f, "unsigned char linux_logo_green[] __initdata = {"); for (i = 0; i < 224; i++) { if (!(i % 16)) fprintf (f, "\n "); if (i < 223) { fprintf (f, "0x%2.2x, ", palette[3 * i + 1]); } else { fprintf (f, "0x%2.2x\n", palette[3 * i + 1]); } } fprintf (f, "};\n\n"); fprintf (f, "unsigned char linux_logo_blue[] __initdata = {"); for (i = 0; i < 224; i++) { if (!(i % 16)) fprintf (f, "\n "); if (i < 223) { fprintf (f, "0x%2.2x, ", palette[3 * i + 2]); } else { fprintf (f, "0x%2.2x\n", palette[3 * i + 2]); } } fprintf (f, "};\n\n"); fprintf (f, "unsigned char linux_logo[] __initdata = {"); for (i = 0; i < 80 * 80; i++) { if (!(i % 16)) fprintf (f, "\n "); if (i < ((80 * 80) - 1)) { fprintf (f, "0x%2.2x, ", data[i] + 32); } else { fprintf (f, "0x%2.2x\n", data[i] + 32); } } fprintf (f, "};\n\n"); fprintf (f, "#endif\n\n"); } void print_logo_c16 (FILE * f, gint32 id) { unsigned char data[80 * 80]; unsigned char palette[256 * 3]; int i, x, y; make_logo (id, data, palette, 16); fprintf (f, "#ifdef INCLUDE_LINUX_LOGO16\n\n"); fprintf (f, "unsigned char linux_logo16_red[] __initdata = {\n"); for (i = 0; i < 16; i++) { if (i < 15) { fprintf (f, "0x%2.2x, ", palette[3 * i + 0]); } else { fprintf (f, "0x%2.2x\n", palette[3 * i + 0]); } } fprintf (f, "};\n\n"); fprintf (f, "unsigned char linux_logo16_green[] __initdata = {\n"); for (i = 0; i < 16; i++) { if (i < 15) { fprintf (f, "0x%2.2x, ", palette[3 * i + 1]); } else { fprintf (f, "0x%2.2x\n", palette[3 * i + 1]); } } fprintf (f, "};\n\n"); fprintf (f, "unsigned char linux_logo16_blue[] __initdata = {\n"); for (i = 0; i < 16; i++) { if (i < 15) { fprintf (f, "0x%2.2x, ", palette[3 * i + 2]); } else { fprintf (f, "0x%2.2x\n", palette[3 * i + 2]); } } fprintf (f, "};\n\n"); fprintf (f, "unsigned char linux_logo16[] __initdata = {\n"); for (y = 0; y < 80; y++) { for (x = 0; x < 40; x++) { unsigned char w; w = data[y * 80 + x * 2 + 1] | data[y * 80 + x * 2] << 4; fprintf (f, "0x%2.2x", w); if (x < 39) { fprintf (f, ", "); } } if (y < 79) { fprintf (f, ",\n"); } else { fprintf (f, "\n"); } } fprintf (f, "};\n\n"); fprintf (f, "#endif\n\n"); } void print_logo_bw (FILE * f, gint32 id) { unsigned char data[80 * 80]; unsigned char palette[256 * 3]; int x, y, b; make_logo (id, data, palette, 2); fprintf (f, "#ifdef INCLUDE_LINUX_LOGOBW\n\n"); fprintf (f, "unsigned char linux_logo_bw[] __initdata = {\n"); for (y = 0; y < 80; y++) { for (x = 0; x < 10; x++) { unsigned char w; w = 0; for (b = 0; b < 8; b++) { w |= data[y * 80 + x * 8 + b] ? 0 : 128 >> b; } fprintf (f, "0x%2.2x", w); if (x < 9) { fprintf (f, ", "); } } if (y < 79) { fprintf (f, ",\n"); } else { fprintf (f, "\n"); } } fprintf (f, "};\n\n"); fprintf (f, "#endif\n\n"); } void print_image (char *s, int ibw, int i16, int i224) { FILE *f; f = fopen (s, "wt"); print_logo_c224 (f, i224); print_logo_c16 (f, i16); print_logo_bw (f, ibw); fclose (f); } void update_preview (GtkWidget * preview, gint32 num_colors, gint32 id) { unsigned char data[80 * 80]; unsigned char row[80 * 3]; unsigned char palette[256 * 3]; int i; make_logo (id, data, palette, num_colors); for (i = 0; i < 80; i++) { int j; for (j = 0; j < 80; j++) { row[j * 3 + 0] = palette[data[i * 80 + j] * 3 + 0]; row[j * 3 + 1] = palette[data[i * 80 + j] * 3 + 1]; row[j * 3 + 2] = palette[data[i * 80 + j] * 3 + 2]; } gtk_preview_draw_row (GTK_PREVIEW (preview), row, 0, i, 80); } gtk_widget_draw (preview, NULL); } void cb_menu_bw (gint32 id, gpointer data) { index_bw = id; update_preview (preview_bw, 2, index_bw); } void cb_menu_c16 (gint32 id, gpointer data) { index_c16 = id; update_preview (preview_c16, 16, index_c16); } void cb_menu_c224 (gint32 id, gpointer data) { index_c224 = id; update_preview (preview_c224, 224, index_c224); } int run_dialog () { GtkWidget *dialog; GtkWidget *label; GtkWidget *button; GtkWidget *omenu, *menu; GtkWidget *hbox, *vbox; GtkWidget *frame; guchar *color_cube; gchar **argv; gint argc; argc = 1; argv = g_new (gchar *, 1); argv[0] = g_strdup ("glogo"); gtk_init (&argc, &argv); gtk_rc_parse (gimp_gtkrc ()); gdk_set_use_xshm (gimp_use_xshm ()); gtk_preview_set_gamma (gimp_gamma ()); gtk_preview_set_install_cmap (gimp_install_cmap ()); color_cube = gimp_color_cube (); gtk_preview_set_color_cube (color_cube[0], color_cube[1], color_cube[2], color_cube[3]); gtk_widget_set_default_visual (gtk_preview_get_visual ()); gtk_widget_set_default_colormap (gtk_preview_get_cmap ()); index_bw = index_c16 = index_c224 = -1; dialog = gtk_dialog_new (); gtk_window_set_title (GTK_WINDOW (dialog), "GLOGO 1.1 - Build a Linux Logo"); gtk_signal_connect (GTK_OBJECT (dialog), "destroy", (GtkSignalFunc) cb_cancel, (gpointer) NULL); gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 5); gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5); /* menues and previews */ preview_c224 = gtk_preview_new (GTK_PREVIEW_COLOR); gtk_preview_size (GTK_PREVIEW (preview_c224), 80, 80); preview_c16 = gtk_preview_new (GTK_PREVIEW_COLOR); gtk_preview_size (GTK_PREVIEW (preview_c16), 80, 80); preview_bw = gtk_preview_new (GTK_PREVIEW_COLOR); gtk_preview_size (GTK_PREVIEW (preview_bw), 80, 80); frame = gtk_frame_new ("Select images:"); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, TRUE, TRUE, 0); gtk_widget_show (frame); vbox = gtk_vbox_new (FALSE, 2); gtk_container_add (GTK_CONTAINER (frame), vbox); gtk_widget_show (vbox); label = gtk_label_new ("224-color picture:"); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); gtk_widget_show (label); menu = gimp_drawable_menu_new ((GimpConstraintFunc) cs_func, (GimpMenuCallback) cb_menu_c224, NULL, 1); omenu = gtk_option_menu_new (); gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu); gtk_box_pack_start (GTK_BOX (vbox), omenu, TRUE, TRUE, 0); gtk_widget_show (omenu); label = gtk_label_new ("16-color picture:"); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); gtk_widget_show (label); menu = gimp_drawable_menu_new ((GimpConstraintFunc) cs_func, (GimpMenuCallback) cb_menu_c16, NULL, 0); omenu = gtk_option_menu_new (); gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu); gtk_box_pack_start (GTK_BOX (vbox), omenu, TRUE, TRUE, 0); gtk_widget_show (omenu); label = gtk_label_new ("BW picture:"); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); gtk_widget_show (label); menu = gimp_drawable_menu_new ((GimpConstraintFunc) cs_func, (GimpMenuCallback) cb_menu_bw, NULL, 0); omenu = gtk_option_menu_new (); gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu); gtk_box_pack_start (GTK_BOX (vbox), omenu, TRUE, TRUE, 0); gtk_widget_show (omenu); frame = gtk_frame_new ("Preview:"); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, TRUE, TRUE, 0); gtk_widget_show (frame); hbox = gtk_hbox_new (FALSE, 2); gtk_container_add (GTK_CONTAINER (frame), hbox); gtk_widget_show (hbox); vbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); gtk_widget_show (vbox); label = gtk_label_new ("224 color"); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (vbox), preview_c224, TRUE, TRUE, 0); gtk_widget_show (preview_c224); vbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); gtk_widget_show (vbox); label = gtk_label_new ("16 color"); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (vbox), preview_c16, TRUE, TRUE, 0); gtk_widget_show (preview_c16); vbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); gtk_widget_show (vbox); label = gtk_label_new ("BW"); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (vbox), preview_bw, TRUE, TRUE, 0); gtk_widget_show (preview_bw); /* OK and Cancel buttons */ button = gtk_button_new_with_label ("OK"); gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) cb_ok, (gpointer) NULL); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button, TRUE, TRUE, 0); gtk_widget_show (button); button = gtk_button_new_with_label ("Cancel"); gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) cb_cancel, (gpointer) NULL); gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), button, TRUE, TRUE, 0); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); gtk_widget_grab_default (button); gtk_widget_show (button); gtk_widget_show (dialog); result = FALSE; gtk_main (); gdk_flush (); return result; }