2 * Copyright 2008 Department of Mathematical Sciences, New Mexico State University
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * DEPARTMENT OF MATHEMATICAL SCIENCES OR NEW MEXICO STATE UNIVERSITY BE
18 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 * These are formats that can appear in the editor for importing/loading and
35 #define CONSOLE_FORMAT 2
42 #define PSFUNI_FORMAT 9
45 * An array of filters used for the open/import and save dialogs.
47 static GtkFileFilter *filename_filters[10];
50 * This variable is used to track whether the save dialog has been closed
51 * so the guifile_save_as_wait() routine knows when to return to the main
54 static gboolean save_dialog_done;
59 #include FT_SFNT_NAMES_H
60 #include FT_TRUETYPE_TABLES_H
63 * Globals used for FreeType.
65 static FT_Library library;
69 * Globals used for importing OpenType fonts.
71 static gboolean ftinit = FALSE;
72 static gboolean otf_collection;
73 static gboolean otf_face_open;
74 static gint otf_select_done = 0;
75 static gchar *otf_fullpath;
78 * These are the widgets that will be needed for importing OpenType fonts.
80 static GtkWidget *otf_dialog;
81 static GtkWidget *otf_faces;
82 static GtkWidget *otf_platforms;
83 static GtkWidget *otf_encodings;
84 static GtkWidget *otf_point_size;
85 static GtkWidget *otf_hres;
86 static GtkWidget *otf_vres;
89 * List of platform IDs seen that is used when platforms are selected
90 * from OpenType fonts.
92 static gint16 platforms[32];
93 static gint nplatforms;
96 * List of encoding IDs seen that is used when encodings are selected
97 * from OpenType fonts.
99 static gint16 encodings[34];
100 static gint nencodings;
103 * Variables to hold the selected platform and encoding ID's.
105 static gint16 otf_pid_pos;
106 static gint16 otf_eid_pos;
108 #endif /* HAVE_FREETYPE */
113 * These are for importing fonts from the X server.
115 #define _XSRV_MAX_FONTS 32767
116 #define _XSRV_DEFAULT_FILTER "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"
118 static GtkWidget *xsrv_dialog;
119 static GtkWidget *xsrv_filter_text;
120 static GtkWidget *xsrv_selection_text;
121 static GtkWidget *xsrv_font_list;
122 static GtkWidget *xsrv_import;
125 * Because the grab dialog is shared amongst the editors, this tracks which
126 * editor has control of the font list.
128 static guint xsrv_active_editor;
130 #endif /* HAVE_XLIB */
133 * Widgets for dealing with exporting PSF fonts.
135 static GtkWidget *psf_export_frame;
136 static GtkWidget *psf_export_options;
139 * Widgets for selecting fonts from a Windows font archive.
141 static GtkWidget *fnt_dialog;
142 static GtkWidget *fnt_font_list;
143 static GtkWidget *fnt_load_button;
146 * This is a list of Windows fonts that have been selected. It assumes that
147 * the font file will never contain more than 32 fonts.
149 static gint fnt_selected[32];
150 static gint fnt_selected_count;
153 * A structure used to pass data to the load and cancel callbacks when dealing
154 * with FON/FNT fonts.
161 } _bdffnt_callback_data_t;
164 * This is used in a couple of cases to point at the active editor.
166 static gbdfed_editor_t *active_editor;
169 make_file_chooser_filters(void)
173 if (filename_filters[0] != NULL)
176 filename_filters[BDF_FORMAT] = gtk_file_filter_new();
177 gtk_file_filter_add_pattern(filename_filters[BDF_FORMAT],
180 filename_filters[CONSOLE_FORMAT] = gtk_file_filter_new();
181 gtk_file_filter_add_pattern(filename_filters[CONSOLE_FORMAT], "*");
183 filename_filters[PKGF_FORMAT] = gtk_file_filter_new();
184 gtk_file_filter_add_pattern(filename_filters[PKGF_FORMAT],
187 filename_filters[FNT_FORMAT] = gtk_file_filter_new();
188 gtk_file_filter_add_pattern(filename_filters[FNT_FORMAT],
189 "*.[FfEeDd][OoNnXxLl][NnTtEeLl]");
191 filename_filters[HEX_FORMAT] = gtk_file_filter_new();
192 gtk_file_filter_add_pattern(filename_filters[HEX_FORMAT],
195 filename_filters[PSF_FORMAT] = gtk_file_filter_new();
196 gtk_file_filter_add_pattern(filename_filters[PSF_FORMAT],
200 * This one is basically for exporting unimap files that belong to PSF
203 filename_filters[PSFUNI_FORMAT] = gtk_file_filter_new();
204 gtk_file_filter_add_pattern(filename_filters[PSFUNI_FORMAT],
208 filename_filters[HBF_FORMAT] = gtk_file_filter_new();
209 gtk_file_filter_add_pattern(filename_filters[HBF_FORMAT],
214 filename_filters[OTF_FORMAT] = gtk_file_filter_new();
215 gtk_file_filter_add_pattern(filename_filters[OTF_FORMAT],
216 "*.[OoTt][Tt][FfCcEe]");
217 #endif /* HAVE_FREETYPE */
219 filename_filters[0] = (GtkFileFilter *) 1;
222 * Add a reference to all the filters so they don't cause a delayed crash
223 * when popping up the import dialog multiple times.
225 for (i = 1; i < 10; i++) {
226 if (filename_filters[i] != NULL)
227 g_object_ref(filename_filters[i]);
232 export_font(gchar *filename, gbdfed_editor_t *ed, gboolean copy_filename)
236 gboolean local_font = FALSE;
237 bdf_property_t vanity;
238 FontgridSelectionInfo sinfo;
240 font = fontgrid_get_font(FONTGRID(ed->fgrid));
243 * First, attempt to make a backup if they are specified.
245 if (options.backups) {
246 out = fopen(filename, "rb");
251 * Attempt to make a backup.
253 sprintf(buffer2, "%s.bak", filename);
258 * Don't return here because we want to save the font even if a
259 * backup can't be made.
261 if (rename(filename, buffer2))
262 guiutil_error_message(ed->shell,
263 "Backups: Unable to make a backup.");
268 * Try to open the file for writing. Only PSF needs binary.
270 out = (ed->export_format != PSF_FORMAT) ?
271 fopen(filename, "w") : fopen(filename, "wb");
274 if (ed->export_format == BDF_FORMAT)
275 sprintf(buffer2, "Save Font: Unable to write to %s.", filename);
277 sprintf(buffer2, "Export Font: Unable to write to %s.", filename);
278 guiutil_error_message(ed->shell, buffer2);
282 switch (ed->export_format) {
286 * We need to create a font with the default options so it
287 * can be written out as a skeleton.
289 font = bdf_new_font("unnamed",
290 options.font_opts.point_size,
291 options.font_opts.resolution_x,
292 options.font_opts.resolution_y,
293 options.font_opts.font_spacing,
294 options.font_opts.bits_per_pixel);
299 * Add a custom property if the font has been
301 if (font->modified || local_font == TRUE) {
302 sprintf(buffer2, "Edited with gbdfed %s.", GBDFED_VERSION);
303 vanity.name = "_GBDFED_INFO";
304 vanity.format = BDF_ATOM;
305 vanity.value.atom = buffer2;
306 bdf_add_font_property(font, &vanity);
308 bdf_save_font(out, font, &options.font_opts, 0, 0);
309 if (local_font == TRUE)
313 bdf_export_hex(out, font, &options.font_opts, 0, 0);
316 sinfo.start = sinfo.end = 0;
317 (void) fontgrid_has_selection(FONTGRID(ed->fgrid), &sinfo);
318 if (sinfo.start == sinfo.end) {
319 sinfo.start = font->glyphs[0].encoding;
320 sinfo.end = font->glyphs[font->glyphs_used - 1].encoding;
322 switch (bdf_export_psf(out, font, &options.font_opts,
323 sinfo.start, sinfo.end)) {
328 sprintf(buffer1, "Export PSF: Invalid range %d-%d.\n",
329 sinfo.start, sinfo.end);
331 case BDF_PSF_CORRUPT_UTF8:
333 "Export PSF: Bad UTF-8 encountered in the mappings.");
338 * Something went wrong during the PSF export.
340 guiutil_error_message(ed->shell, buffer1);
346 * The rest of this only applies to BDF fonts and not PSF or HEX fonts.
347 * PSF and HEX fonts have their own extensions in the save dialog, but
348 * that does not affect the actual file name in the editor.
350 if (ed->export_format == BDF_FORMAT) {
353 * Copy the path and filename into the editor if specified.
360 ed->path = ed->file = 0;
361 ed->file = g_path_get_basename(filename);
362 ed->path = g_path_get_dirname(filename);
366 * Mark the font as being unmodified.
368 fontgrid_set_font_modified(FONTGRID(ed->fgrid), FALSE);
371 * Update the window title accordingly.
374 sprintf(buffer1, "%s - %s", g_get_prgname(), ed->file);
376 sprintf(buffer1, "%s - (unnamed%d)", g_get_prgname(), ed->id);
378 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
381 * Since the font was saved as BDF, it is no longer marked as being
384 ed->imported = FALSE;
391 really_save_font(guint ed_id)
393 gbdfed_editor_t *ed = editors + ed_id;
396 #if (GTK_MAJOR_VERSION >= 2 && GTK_MINOR_VERSION >= 10)
397 GtkRecentManager *recent;
400 fname = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(ed->save_dialog));
402 have = fopen(fname, "rb");
407 * Check to see if the user wishes to overwrite the existing font.
409 sprintf(buffer2, "Save Font: %s exists.\nDo you wish to overwrite?",
411 if (guiutil_yes_or_no(ed->shell, buffer2, TRUE) == FALSE) {
418 * If the write was successful, hide the dialog.
420 if (export_font(fname, ed, TRUE)) {
421 save_dialog_done = TRUE;
422 gtk_widget_hide(ed->save_dialog);
423 #if (GTK_MAJOR_VERSION >= 2 && GTK_MINOR_VERSION >= 10)
424 recent = gtk_recent_manager_get_default();
425 sprintf(buffer1, "file://%s", fname);
426 if (gtk_recent_manager_has_item(recent,
427 (const gchar *) buffer1) == FALSE)
428 gtk_recent_manager_add_item(recent,
429 (const gchar *) buffer1);
436 * This callback routine handles errors and updating the progress bar if
440 handle_import_messages(bdf_callback_struct_t *call_data, void *client_data)
442 if (call_data->reason == BDF_ERROR) {
443 sprintf(buffer1, "Import Font:%d: error: See the font messages.",
444 call_data->errlineno);
445 guiutil_error_message(GTK_WIDGET(client_data), buffer1);
449 /**************************************************************************
453 **************************************************************************/
456 load_bdf_font(gbdfed_editor_t *ed, const gchar *fullpath, const gchar *dir,
463 * Check to see if the file can be opened.
465 if ((in = fopen(fullpath, "rb")) == 0) {
466 sprintf(buffer1, "Import Font: Unable to open %s.", file);
467 guiutil_error_message(ed->shell, buffer1);
471 guiutil_busy_cursor(ed->shell, TRUE);
472 if (ed->open_dialog != NULL)
473 guiutil_busy_cursor(ed->open_dialog, TRUE);
475 font = bdf_load_font(in, &options.font_opts,
476 handle_import_messages, (void *) ed->shell);
478 guiutil_busy_cursor(ed->shell, FALSE);
479 if (ed->open_dialog != NULL)
480 guiutil_busy_cursor(ed->open_dialog, FALSE);
484 sprintf(buffer1, "Import Font: Unable to load %s.", file);
485 guiutil_error_message(ed->shell, buffer1);
490 if (ed->open_dialog != NULL)
491 gtk_widget_hide(ed->open_dialog);
494 * Delete the file and path names so they can be updated.
501 ed->file = ed->path = 0;
503 ed->file = strdup(file);
504 ed->path = strdup(dir);
507 * Update the window title.
510 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ed->file);
512 sprintf(buffer1, "%s - %s", g_get_prgname(), ed->file);
514 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
517 * Tell the glyphtest widget to remove references to the current font if
518 * it has any, and redraw.
521 glyphtest_remove_font(GLYPHTEST(glyphtest),
522 fontgrid_get_font(FONTGRID(ed->fgrid)));
524 fontgrid_set_font(FONTGRID(ed->fgrid), font, -1);
527 * Finally, update the font name field.
529 gtk_entry_set_text(GTK_ENTRY(ed->fontname),
530 fontgrid_get_font_name(FONTGRID(ed->fgrid)));
533 * Make sure the imported flag is cleared in this case.
535 ed->imported = FALSE;
538 /**************************************************************************
542 **************************************************************************/
545 load_console_font(gbdfed_editor_t *ed, gchar *fullpath, gchar *dot,
546 gchar *dir, gchar *file)
550 gint i, j, nfonts, len;
552 bdf_font_t *fonts[3];
555 * Check to see if the file can be opened.
557 if ((in = fopen(fullpath, "rb")) == 0) {
558 sprintf(buffer1, "Import Font: Unable to open %s.", fullpath);
559 guiutil_error_message(ed->shell, buffer1);
563 guiutil_busy_cursor(ed->shell, TRUE);
564 guiutil_busy_cursor(ed->open_dialog, TRUE);
566 i = bdf_load_console_font(in, &options.font_opts, 0, 0, fonts, &nfonts);
568 guiutil_busy_cursor(ed->shell, FALSE);
569 guiutil_busy_cursor(ed->open_dialog, FALSE);
575 * Free up any font structures that happened to be loaded.
577 for (j = 0; j < nfonts; j++)
578 bdf_free_font(fonts[j]);
580 sprintf(buffer1, "Import Font: %s not a console font.", fullpath);
581 guiutil_error_message(ed->shell, buffer1);
585 gtk_widget_hide(ed->open_dialog);
588 * Handle creation of the editors. In the case of some console fonts,
589 * there are three different sizes contained in the font.
591 for (i = 0; i < nfonts; i++) {
593 ep = editors + gbdfed_make_editor(0, FALSE);
598 * Erase the existing file and directory name in the "root"
605 ep->file = ep->path = 0;
608 * Tell the glyphtest widget to remove references to the current
609 * font, if it has any, and redraw.
612 glyphtest_remove_font(GLYPHTEST(glyphtest),
613 fontgrid_get_font(FONTGRID(ep->fgrid)));
617 * Make an XLFD name for the font using the filename. Run through the
618 * file name and change all occurences of '-' to '_' to avoid problems
619 * with '-' being the XLFD field separator.
621 for (j = 0, np = file; np < dot; np++, j++)
622 buffer2[j] = (*np != '-') ? *np : '_';
626 bdf_make_xlfd_name(fonts[i], "Unknown", buffer2);
627 bdf_update_properties_from_name(fonts[i]);
629 len = (gint) (dot - file);
632 * Create the default name for the font file.
637 sprintf(buffer1, "%.*s-16.bdf", len, file);
640 sprintf(buffer1, "%.*s-14.bdf", len, file);
643 sprintf(buffer1, "%.*s-08.bdf", len, file);
647 sprintf(buffer1, "%.*s.bdf", len, file);
650 * Set the filename for the editor.
652 ep->file = strdup(buffer1);
653 ep->path = strdup(dir);
656 * Set the new editor title.
658 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ep->file);
659 gtk_window_set_title(GTK_WINDOW(ep->shell), buffer1);
662 * Change the font in the editor.
664 fontgrid_set_font(FONTGRID(ep->fgrid), fonts[i], -1);
667 * Indicate the font was imported.
672 * Update the XLFD name.
674 gtk_entry_set_text(GTK_ENTRY(ep->fontname),
675 fontgrid_get_font_name(FONTGRID(ep->fgrid)));
679 /**************************************************************************
683 **************************************************************************/
686 load_pkgf_font(gbdfed_editor_t *ed, gchar *fullpath, gchar *dot,
687 gchar *dir, gchar *file)
695 * Check to see if the file can be opened.
697 if ((in = fopen(fullpath, "rb")) == 0) {
698 sprintf(buffer1, "Import Font: Unable to open %s.", file);
699 guiutil_error_message(ed->shell, buffer1);
703 guiutil_busy_cursor(ed->shell, TRUE);
704 guiutil_busy_cursor(ed->open_dialog, TRUE);
706 i = bdf_load_mf_font(in, &options.font_opts, 0, 0, &font);
708 guiutil_busy_cursor(ed->shell, FALSE);
709 guiutil_busy_cursor(ed->open_dialog, FALSE);
714 sprintf(buffer1, "Import Font: %s not a PK or GF font.", fullpath);
715 guiutil_error_message(ed->shell, buffer1);
719 gtk_widget_hide(ed->open_dialog);
722 * Make an XLFD name for the font using the filename. Run through the
723 * file name and change all occurences of '-' to '_' to avoid problems
724 * with '-' being the XLFD field separator.
726 for (i = 0, np = file; np < dot; np++, i++)
727 buffer2[i] = (*np != '-') ? *np : '_';
730 font->name = bdf_make_xlfd_name(font, "Unknown", buffer2);
731 bdf_update_properties_from_name(font);
734 * Now set up a file name.
736 sprintf(buffer1, "%.*s.bdf", (int) (dot - file), file);
739 * Delete the file and path names so they can be updated.
746 ed->file = strdup(buffer1);
747 ed->path = strdup(dir);
750 * Update the window title.
752 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ed->file);
753 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
756 * Tell the glyphtest widget to remove references to the current font if
757 * it has any, and redraw.
760 glyphtest_remove_font(GLYPHTEST(glyphtest),
761 fontgrid_get_font(FONTGRID(ed->fgrid)));
763 fontgrid_set_font(FONTGRID(ed->fgrid), font, -1);
766 * Indicate the font was imported.
771 * Finally, update the font name field.
773 gtk_entry_set_text(GTK_ENTRY(ed->fontname),
774 fontgrid_get_font_name(FONTGRID(ed->fgrid)));
777 /**************************************************************************
781 **************************************************************************/
784 * Toggles the "Ok" button on or off depending if there was a selection or
788 fnt_check_load_button(GtkWidget *w, gpointer data)
790 GtkTreeSelection *sel = GTK_TREE_SELECTION(data);
792 if (gtk_tree_selection_count_selected_rows(sel) == 0)
793 gtk_widget_set_sensitive(fnt_load_button, FALSE);
795 gtk_widget_set_sensitive(fnt_load_button, TRUE);
799 fnt_unselect_all(GtkWidget *w, gpointer data)
801 GtkTreeSelection *sel = GTK_TREE_SELECTION(data);
803 gtk_tree_selection_unselect_all(sel);
806 * Disable the Ok button since everything is unselected.
808 gtk_widget_set_sensitive(fnt_load_button, FALSE);
812 fnt_select_all(GtkWidget *w, gpointer data)
814 GtkTreeSelection *sel = GTK_TREE_SELECTION(data);
816 gtk_tree_selection_select_all(sel);
819 * Enable the Ok button since everything is unselected.
821 gtk_widget_set_sensitive(fnt_load_button, TRUE);
825 fnt_foreach_selected(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
830 id = gtk_tree_path_get_indices(path);
831 fnt_selected[fnt_selected_count++] = *id;
835 fnt_load_selected_fonts(GtkWidget *w, gpointer data)
837 gbdfed_editor_t *ep, *ed = editors + GPOINTER_TO_UINT(data);
838 GtkTreeSelection *sel =
839 gtk_tree_view_get_selection(GTK_TREE_VIEW(fnt_font_list));
843 _bdffnt_callback_data_t *cdata;
845 fnt_selected_count = 0;
847 if ((cdata = g_object_get_data(G_OBJECT(w),
848 "bdffnt_callback_data")) == NULL) {
850 * Big problem. Should never happen.
852 guiutil_error_message(editors[0].shell,
853 "BIG PROBLEM PASSING OPEN FON/FNT FONT!!!!");
858 * This collects all the selected indices from the list and puts them in
859 * the global fnt_selected array.
861 gtk_tree_selection_selected_foreach(sel, fnt_foreach_selected, NULL);
866 if (fnt_selected_count == 0)
870 * Hide the dialog that allowed selection of the fonts in the file.
872 gtk_widget_hide(fnt_dialog);
874 guiutil_busy_cursor(ed->shell, TRUE);
875 guiutil_busy_cursor(ed->open_dialog, TRUE);
877 fonts = (bdf_font_t **)
878 g_malloc(sizeof(bdf_font_t *) * fnt_selected_count);
879 for (loaded = TRUE, nfonts = 0;
880 nfonts < fnt_selected_count && loaded == TRUE;
883 * If the current font can't be loaded, then assume the rest are
884 * not available either.
886 if (bdffnt_load_font(cdata->font, fnt_selected[nfonts],
887 0, 0, &fonts[nfonts]) != 0) {
889 * It is easier to get the font name from the font than it is
890 * from the list store.
892 (void) bdffnt_get_facename(cdata->font, fnt_selected[nfonts], 0,
893 (unsigned char *) buffer1);
894 sprintf(buffer2, "Import Font: Unable to load %s from %s.",
895 buffer1, cdata->file);
896 guiutil_error_message(ed->shell, buffer2);
898 guiutil_busy_cursor(ed->shell, FALSE);
899 guiutil_busy_cursor(ed->open_dialog, FALSE);
905 guiutil_busy_cursor(ed->shell, FALSE);
906 guiutil_busy_cursor(ed->open_dialog, FALSE);
909 * If no fonts were loaded, then simply return with the open dialog still
910 * up, giving the user a chance to load another font.
918 * Hide the open dialog.
920 gtk_widget_hide(ed->open_dialog);
923 * Create the editors for the fonts that did get loaded.
925 for (i = 0; i < nfonts; i++) {
927 ep = editors + gbdfed_make_editor(0, FALSE);
932 * Erase the existing file and directory name in the "root"
939 ep->file = ep->path = 0;
942 * Tell the glyphtest widget to remove references to the current
943 * font, if it has any, and redraw.
946 glyphtest_remove_font(GLYPHTEST(glyphtest),
947 fontgrid_get_font(FONTGRID(ep->fgrid)));
951 * Make the BDF file name for the font.
953 sprintf(buffer1, "%.*s%d.bdf", (int) (cdata->dot - cdata->file),
954 cdata->file, fonts[i]->point_size);
956 ep->file = strdup(buffer1);
957 ep->path = strdup(cdata->dir);
960 * Set the new editor title.
962 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ep->file);
963 gtk_window_set_title(GTK_WINDOW(ep->shell), buffer1);
966 * Change the font in the editor.
968 fontgrid_set_font(FONTGRID(ep->fgrid), fonts[i], -1);
971 * Indicate the font was imported.
976 * Update the XLFD name.
978 gtk_entry_set_text(GTK_ENTRY(ep->fontname),
979 fontgrid_get_font_name(FONTGRID(ep->fgrid)));
984 bdffnt_close_font(cdata->font);
990 fnt_cancel(GtkWidget *w, gpointer data)
992 _bdffnt_callback_data_t *cdata;
995 * If the load callback stole the data already, this will be NULL.
997 if ((cdata = g_object_get_data(G_OBJECT(w),
998 "bdffnt_callback_data")) == NULL) {
1000 * Big problem. Should never happen.
1002 guiutil_error_message(editors[0].shell,
1003 "BIG PROBLEM PASSING OPEN FON/FNT FONT!!!!");
1007 g_free(cdata->file);
1009 bdffnt_close_font(cdata->font);
1011 gtk_widget_hide(fnt_dialog);
1015 fnt_row_activate(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col,
1018 fnt_load_selected_fonts(GTK_WIDGET(view), data);
1022 load_windows_font(gbdfed_editor_t *ed, gchar *fullpath, gchar *dot,
1023 gchar *dir, gchar *file)
1028 _bdffnt_callback_data_t *cdata;
1029 GtkWidget *button, *vbox, *hbox, *swin;
1030 GtkListStore *store;
1031 GtkTreeViewColumn *column;
1032 GtkCellRenderer *cell_renderer;
1033 GtkTreeSelection *sel;
1037 if (bdffnt_open_font(fullpath, &fnt) <= 0) {
1038 sprintf(buffer1, "Import Font: Unable to open %s.", file);
1039 guiutil_error_message(ed->shell, buffer1);
1044 nfonts = bdffnt_font_count(fnt);
1047 guiutil_busy_cursor(ed->shell, TRUE);
1048 guiutil_busy_cursor(ed->open_dialog, TRUE);
1050 if (bdffnt_load_font(fnt, 0, 0, 0, &font) != 0) {
1051 sprintf(buffer1, "Import Font: Unable to load %s.", file);
1052 guiutil_error_message(ed->shell, buffer1);
1055 guiutil_busy_cursor(ed->shell, FALSE);
1056 guiutil_busy_cursor(ed->open_dialog, FALSE);
1061 guiutil_busy_cursor(ed->shell, FALSE);
1062 guiutil_busy_cursor(ed->open_dialog, FALSE);
1064 gtk_widget_hide(ed->open_dialog);
1067 * Now set up a file name.
1069 sprintf(buffer1, "%.*s.bdf", (int) (dot - file), file);
1072 * Delete the file and path names so they can be updated.
1079 ed->file = strdup(buffer1);
1080 ed->path = strdup(dir);
1083 * Update the window title.
1085 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ed->file);
1086 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
1089 * Tell the glyphtest widget to remove references to the current font
1090 * if it has any, and redraw.
1093 glyphtest_remove_font(GLYPHTEST(glyphtest),
1094 fontgrid_get_font(FONTGRID(ed->fgrid)));
1096 fontgrid_set_font(FONTGRID(ed->fgrid), font, -1);
1099 * Indicate the font was imported.
1101 ed->imported = TRUE;
1104 * Finally, update the font name field.
1106 gtk_entry_set_text(GTK_ENTRY(ed->fontname),
1107 fontgrid_get_font_name(FONTGRID(ed->fgrid)));
1112 * More than one font was found. Present the dialog to choose the fonts.
1114 if (fnt_dialog == 0) {
1116 * Create a structure that will hold data needed by a couple callback
1119 cdata = g_malloc(sizeof(_bdffnt_callback_data_t));
1120 cdata->file = strdup(file);
1121 cdata->dir = strdup(dir);
1122 cdata->dot = cdata->file + (dot - file);
1125 fnt_dialog = gtk_dialog_new();
1126 gtk_window_set_title(GTK_WINDOW(fnt_dialog), "Windows Font Selection");
1128 g_object_set_data(G_OBJECT(fnt_dialog), "bdffnt_callback_data",
1131 (void) g_signal_connect(G_OBJECT(fnt_dialog), "delete_event",
1132 G_CALLBACK(fnt_cancel), 0);
1134 vbox = GTK_DIALOG(fnt_dialog)->vbox;
1135 hbox = GTK_DIALOG(fnt_dialog)->action_area;
1137 swin = gtk_scrolled_window_new(0, 0);
1138 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
1139 GTK_POLICY_AUTOMATIC,
1142 store = gtk_list_store_new(1, G_TYPE_STRING);
1143 fnt_font_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1144 g_object_unref(store);
1146 g_object_set_data(G_OBJECT(fnt_font_list), "bdffnt_callback_data",
1149 gtk_widget_set_size_request(fnt_font_list, -1, 160);
1151 cell_renderer = gtk_cell_renderer_text_new();
1152 column = gtk_tree_view_column_new_with_attributes("Fonts: 0",
1157 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
1158 gtk_tree_view_append_column(GTK_TREE_VIEW(fnt_font_list), column);
1159 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(fnt_font_list));
1161 (void) g_signal_connect(G_OBJECT(sel), "changed",
1162 G_CALLBACK(fnt_check_load_button),
1165 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE);
1167 (void) g_signal_connect(G_OBJECT(fnt_font_list), "row_activated",
1168 G_CALLBACK(fnt_row_activate),
1169 GUINT_TO_POINTER(ed->id));
1171 gtk_container_add(GTK_CONTAINER(swin), fnt_font_list);
1173 gtk_box_pack_start(GTK_BOX(vbox), swin, FALSE, FALSE, 0);
1175 button = gtk_button_new_with_label("Select All");
1177 (void) g_signal_connect(G_OBJECT(button), "clicked",
1178 G_CALLBACK(fnt_select_all),
1181 gtk_container_add(GTK_CONTAINER(hbox), button);
1183 button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
1185 (void) g_signal_connect(G_OBJECT(button), "clicked",
1186 G_CALLBACK(fnt_unselect_all),
1189 gtk_container_add(GTK_CONTAINER(hbox), button);
1191 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
1193 (void) g_signal_connect(G_OBJECT(button), "clicked",
1194 G_CALLBACK(fnt_cancel),
1195 GUINT_TO_POINTER(ed->id));
1197 gtk_container_add(GTK_CONTAINER(hbox), button);
1199 fnt_load_button = gtk_button_new_from_stock(GTK_STOCK_OK);
1202 * Here we store a bunch of data to the buttons that are necessary to
1203 * load FON/FNT fonts in the callback.
1205 g_object_set_data(G_OBJECT(fnt_load_button), "bdffnt_callback_data",
1207 g_object_set_data(G_OBJECT(button), "bdffnt_callback_data",
1210 (void) g_signal_connect(G_OBJECT(fnt_load_button), "clicked",
1211 G_CALLBACK(fnt_load_selected_fonts),
1212 GUINT_TO_POINTER(ed->id));
1214 gtk_container_add(GTK_CONTAINER(hbox), fnt_load_button);
1216 gtk_widget_show_all(vbox);
1217 gtk_widget_show_all(hbox);
1220 * Fill the CDATA item in with the latest info.
1222 cdata = g_object_get_data(G_OBJECT(fnt_load_button),
1223 "bdffnt_callback_data");
1224 cdata->file = strdup(file);
1225 cdata->dir = strdup(dir);
1226 cdata->dot = cdata->file + (dot - file);
1231 GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(fnt_font_list)));
1232 column = gtk_tree_view_get_column(GTK_TREE_VIEW(fnt_font_list), 0);
1233 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(fnt_font_list));
1236 * Set the number of fonts.
1238 sprintf(buffer1, "Fonts: %d", nfonts);
1239 gtk_tree_view_column_set_title(column, buffer1);
1242 * Clear the list and add the font names.
1244 gtk_list_store_clear(store);
1245 for (i = 0; i < nfonts; i++) {
1246 (void) bdffnt_get_facename(fnt, i, 0, (unsigned char *) buffer1);
1247 gtk_list_store_append(store, &iter);
1248 gtk_list_store_set(store, &iter, 0, buffer1, -1);
1252 * Force the first one to be selected by default.
1254 tpath = gtk_tree_path_new_from_indices(0, -1);
1255 gtk_tree_selection_select_path(sel, tpath);
1258 * Show the dialog and wait until the selection is done.
1260 guiutil_show_dialog_centered(fnt_dialog, ed->shell);
1263 * Force the user to interact with this dialog before doing anything else.
1265 gtk_window_set_modal(GTK_WINDOW(fnt_dialog), TRUE);
1268 /**************************************************************************
1272 **************************************************************************/
1274 #ifdef HAVE_FREETYPE
1277 choose_otf_encoding(GtkTreeSelection *selection, gpointer data)
1280 GtkTreeModel *model;
1285 * Get the row of the current selection.
1287 if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)
1289 tpath = gtk_tree_model_get_path(model, &iter);
1290 rows = gtk_tree_path_get_indices(tpath);
1291 otf_eid_pos = (gint16) rows[0];
1295 choose_otf_platform(GtkTreeSelection *selection, gpointer data)
1298 gint i, ncmaps, sel, *rows;
1299 gint16 pid, eid, lasteid;
1300 GtkTreeModel *model;
1301 GtkListStore *store;
1307 * Get the row of the current selection.
1309 if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)
1311 tpath = gtk_tree_model_get_path(model, &iter);
1312 rows = gtk_tree_path_get_indices(tpath);
1313 otf_pid_pos = (gint16) rows[0];
1316 * Clear the encoding list.
1318 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(otf_encodings)));
1319 gtk_list_store_clear(store);
1322 * Collect the list of encoding IDs and put their names in the encoding
1326 ncmaps = face->num_charmaps;
1327 for (lasteid = -1, sel = i = 0; i < ncmaps; i++) {
1328 pid = face->charmaps[i]->platform_id;
1329 eid = face->charmaps[i]->encoding_id;
1330 if (pid == platforms[otf_pid_pos] && eid != lasteid) {
1331 name = bdfotf_encoding_name(pid, eid);
1332 if (strcmp(name, "ISO10646") == 0)
1334 gtk_list_store_append(store, &iter);
1335 gtk_list_store_set(store, &iter, 0, name, -1);
1336 encodings[nencodings++] = eid;
1342 * Default the selection to the ISO10646 encoding.
1344 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(otf_encodings));
1345 tpath = gtk_tree_path_new_from_indices(sel, -1);
1346 gtk_tree_selection_select_path(selection, tpath);
1349 * Make sure the encoding is made visible.
1351 tview = gtk_tree_selection_get_tree_view(selection);
1352 gtk_tree_view_scroll_to_cell(tview, tpath, NULL, TRUE, 0.5, 0.5);
1356 choose_otf(GtkTreeSelection *selection, gpointer data)
1359 gint i, ncmaps, sel, row, *rows;
1360 gint16 pid, eid, lastpid;
1361 GtkTreeModel *model;
1362 GtkListStore *store;
1369 * This is called after the list is cleared as well, so return if there is
1372 if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)
1376 * Get the name of the face currently selected and it's index. This is
1377 * way more complicated than it should be.
1379 (void) memset((char *) &val, 0, sizeof(GValue));
1380 tpath = gtk_tree_model_get_path(model, &iter);
1381 rows = gtk_tree_path_get_indices(tpath);
1385 * Clear the platform list before trying to open the new face.
1387 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(otf_platforms)));
1388 gtk_list_store_clear(store);
1390 if (otf_collection) {
1393 if (FT_New_Face(library, otf_fullpath, row, &face)) {
1394 otf_face_open = FALSE;
1395 gtk_tree_selection_get_selected(selection, &model, &iter);
1396 gtk_tree_model_get_value(model, &iter, 0, &val);
1397 name = (gchar *) g_value_get_string(&val);
1399 "Import Font: Unable to open OpenType collection %s.",
1401 g_value_unset(&val);
1402 guiutil_error_message(active_editor->shell, buffer1);
1405 otf_face_open = TRUE;
1409 * Collect the list of platform IDs and put their names in the platform
1413 ncmaps = face->num_charmaps;
1414 for (lastpid = -1, sel = i = 0; i < ncmaps; i++) {
1415 pid = face->charmaps[i]->platform_id;
1416 eid = face->charmaps[i]->encoding_id;
1417 if (pid != lastpid) {
1419 * Add the platform name to the list. If the name happens to be
1420 * Microsoft, select it as the default.
1422 name = bdfotf_platform_name(pid);
1423 if (strcmp(name, "Microsoft") == 0)
1425 gtk_list_store_append(store, &iter);
1426 gtk_list_store_set(store, &iter, 0, name, -1);
1427 platforms[nplatforms++] = pid;
1433 * Select the default platform, which is hard-coded to be Microsoft at the
1436 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(otf_platforms));
1437 tpath = gtk_tree_path_new_from_indices(sel, -1);
1438 gtk_tree_selection_select_path(selection, tpath);
1441 * Make sure the platform is made visible.
1443 tview = gtk_tree_selection_get_tree_view(selection);
1444 gtk_tree_view_scroll_to_cell(tview, tpath, NULL, TRUE, 0.5, 0.5);
1448 otf_dialog_done(GtkWidget *w, gpointer data)
1450 otf_select_done = GPOINTER_TO_INT(data);
1451 gtk_widget_hide(otf_dialog);
1455 otf_reset_metrics(GtkWidget *w, gpointer data)
1457 gtk_spin_button_set_value(GTK_SPIN_BUTTON(otf_point_size),
1458 (gfloat) options.font_opts.point_size);
1459 gtk_spin_button_set_value(GTK_SPIN_BUTTON(otf_hres),
1460 (gfloat) options.font_opts.resolution_x);
1461 gtk_spin_button_set_value(GTK_SPIN_BUTTON(otf_vres),
1462 (gfloat) options.font_opts.resolution_y);
1466 * Synchronize the vertical resolution with the horizontal resolution.
1469 otf_sync_res(GtkWidget *w, GdkEventFocus *ev, gpointer data)
1474 b = GTK_SPIN_BUTTON(data);
1475 v = (gfloat) gtk_spin_button_get_value(b);
1477 if (v != (gfloat) gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)))
1478 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v);
1482 make_otf_import_dialog(void)
1484 GtkWidget *label, *vbox, *hbox, *button, *table, *swin;
1486 GtkListStore *store;
1487 GtkTreeViewColumn *column;
1488 GtkCellRenderer *cell_renderer;
1489 GtkTreeSelection *sel;
1492 otf_dialog = gtk_dialog_new();
1493 gtk_window_set_title(GTK_WINDOW(otf_dialog), "OpenType Selection");
1495 (void) g_signal_connect(G_OBJECT(otf_dialog), "delete_event",
1496 G_CALLBACK(gtk_widget_hide), 0);
1498 vbox = GTK_DIALOG(otf_dialog)->vbox;
1500 swin = gtk_scrolled_window_new(0, 0);
1501 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
1502 GTK_POLICY_AUTOMATIC,
1505 store = gtk_list_store_new(1, G_TYPE_STRING);
1506 otf_faces = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1507 g_object_unref(store);
1509 cell_renderer = gtk_cell_renderer_text_new();
1510 column = gtk_tree_view_column_new_with_attributes ("Faces",
1515 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
1516 gtk_tree_view_append_column (GTK_TREE_VIEW(otf_faces), column);
1518 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(otf_faces));
1519 gtk_tree_selection_set_mode(sel, GTK_SELECTION_BROWSE);
1521 (void) g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(choose_otf),
1525 * Set the size of the list explicitly to make enough space for
1526 * approximately five entries.
1528 gtk_widget_set_size_request(otf_faces, -1, 100);
1530 gtk_container_add(GTK_CONTAINER(swin), otf_faces);
1532 gtk_box_pack_start(GTK_BOX(vbox), swin, TRUE, TRUE, 0);
1535 * Create a table to hold the other two lists.
1537 table = gtk_table_new(1, 2, TRUE);
1539 swin = gtk_scrolled_window_new(0, 0);
1540 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
1541 GTK_POLICY_AUTOMATIC,
1544 store = gtk_list_store_new(1, G_TYPE_STRING);
1545 otf_platforms = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1546 g_object_unref(store);
1548 cell_renderer = gtk_cell_renderer_text_new();
1549 column = gtk_tree_view_column_new_with_attributes("Platforms",
1554 gtk_widget_set_size_request(otf_platforms, 200, 70);
1556 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
1557 gtk_tree_view_append_column(GTK_TREE_VIEW(otf_platforms), column);
1559 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(otf_platforms));
1560 gtk_tree_selection_set_mode(sel, GTK_SELECTION_BROWSE);
1562 (void) g_signal_connect(G_OBJECT(sel), "changed",
1563 G_CALLBACK(choose_otf_platform), NULL);
1565 gtk_container_add(GTK_CONTAINER(swin), otf_platforms);
1568 * Attach the platform list to the table.
1570 gtk_table_attach(GTK_TABLE(table), swin, 0, 1, 0, 1,
1571 GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
1573 swin = gtk_scrolled_window_new(0, 0);
1574 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
1575 GTK_POLICY_AUTOMATIC,
1578 store = gtk_list_store_new(1, G_TYPE_STRING);
1579 otf_encodings = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1580 g_object_unref(store);
1582 cell_renderer = gtk_cell_renderer_text_new();
1583 column = gtk_tree_view_column_new_with_attributes("Encodings",
1588 gtk_widget_set_size_request(otf_encodings, 200, 70);
1590 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
1591 gtk_tree_view_append_column(GTK_TREE_VIEW(otf_encodings), column);
1593 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(otf_encodings));
1594 gtk_tree_selection_set_mode(sel, GTK_SELECTION_BROWSE);
1596 (void) g_signal_connect(G_OBJECT(sel), "changed",
1597 G_CALLBACK(choose_otf_encoding), NULL);
1599 gtk_container_add(GTK_CONTAINER(swin), otf_encodings);
1602 * Attach the encodings list to the table.
1604 gtk_table_attach(GTK_TABLE(table), swin, 1, 2, 0, 1,
1605 GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
1607 gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
1610 * Make a table that will contain the point size and resolution
1613 table = gtk_table_new(3, 3, FALSE);
1616 * Make the spin button labels.
1618 label = gtk_label_new("Point Size:");
1619 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1620 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL,
1622 label = gtk_label_new("Horizontal Resolution:");
1623 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1624 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL,
1626 label = gtk_label_new("Vertical Resolution:");
1627 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1628 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL,
1632 * Make the spin buttons.
1634 adj = (GtkAdjustment *) gtk_adjustment_new(0.0, 4.0, 256.0, 1.0, 2.0, 0.0);
1635 otf_point_size = gtk_spin_button_new(adj, 1.0, 0);
1636 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(otf_point_size), TRUE);
1637 gtk_widget_set_size_request(otf_point_size, 100, -1);
1638 gtk_spin_button_set_value(GTK_SPIN_BUTTON(otf_point_size),
1639 (gfloat) options.font_opts.point_size);
1640 gtk_table_attach(GTK_TABLE(table), otf_point_size, 1, 2, 0, 1,
1641 GTK_FILL, GTK_FILL, 5, 5);
1643 adj = (GtkAdjustment *) gtk_adjustment_new(0.0, 72.0, 1200.0,
1645 otf_hres = gtk_spin_button_new(adj, 1.0, 0);
1646 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(otf_hres), TRUE);
1647 gtk_widget_set_size_request(otf_hres, 100, -1);
1648 gtk_spin_button_set_value(GTK_SPIN_BUTTON(otf_hres),
1649 (gfloat) options.font_opts.resolution_x);
1650 gtk_table_attach(GTK_TABLE(table), otf_hres, 1, 2, 1, 2,
1651 GTK_FILL, GTK_FILL, 5, 5);
1653 adj = (GtkAdjustment *) gtk_adjustment_new(0.0, 72.0, 1200.0,
1655 otf_vres = gtk_spin_button_new(adj, 1.0, 0);
1656 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(otf_vres), TRUE);
1657 gtk_widget_set_size_request(otf_vres, 100, -1);
1658 gtk_spin_button_set_value(GTK_SPIN_BUTTON(otf_vres),
1659 (gfloat) options.font_opts.resolution_y);
1660 (void) g_signal_connect(G_OBJECT(otf_vres), "focus-in-event",
1661 G_CALLBACK(otf_sync_res),
1662 (gpointer) otf_hres);
1663 (void) g_signal_connect(G_OBJECT(otf_hres), "focus-in-event",
1664 G_CALLBACK(otf_sync_res),
1665 (gpointer) otf_vres);
1666 gtk_table_attach(GTK_TABLE(table), otf_vres, 1, 2, 2, 3,
1667 GTK_FILL, GTK_FILL, 5, 5);
1670 * Make the reset button.
1672 label = gtk_button_new_with_label("Reset");
1673 (void) g_signal_connect(G_OBJECT(label), "clicked",
1674 G_CALLBACK(otf_reset_metrics), 0);
1675 gtk_table_attach(GTK_TABLE(table), label, 2, 3, 1, 2, GTK_FILL, GTK_FILL,
1679 * Do some fiddling to adjust the focus chain so the Reset button is at
1680 * the end instead of in the middle.
1682 fchain = g_list_append(NULL, (gpointer) otf_point_size);
1683 fchain = g_list_append(fchain, (gpointer) otf_hres);
1684 fchain = g_list_append(fchain, (gpointer) otf_vres);
1685 fchain = g_list_append(fchain, (gpointer) label);
1686 gtk_container_set_focus_chain(GTK_CONTAINER(table), fchain);
1687 g_list_free(fchain);
1689 gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, FALSE, 10);
1692 * Add the buttons at the bottom of the dialog.
1694 hbox = GTK_DIALOG(otf_dialog)->action_area;
1696 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
1697 gtk_container_add(GTK_CONTAINER(hbox), button);
1698 (void) g_signal_connect(G_OBJECT(button), "clicked",
1699 G_CALLBACK(otf_dialog_done),
1700 GINT_TO_POINTER(-1));
1701 button = gtk_button_new_from_stock(GTK_STOCK_OK);
1702 gtk_container_add(GTK_CONTAINER(hbox), button);
1703 (void) g_signal_connect(G_OBJECT(button), "clicked",
1704 G_CALLBACK(otf_dialog_done),
1705 GINT_TO_POINTER(1));
1707 gtk_widget_show_all(vbox);
1708 gtk_widget_show_all(hbox);
1712 load_otf_font(gbdfed_editor_t *ed, gchar *fullpath, gchar *dot,
1713 gchar *dir, gchar *file)
1716 gint32 psize, hres, vres;
1719 bdf_property_t prop;
1720 GtkListStore *store;
1724 otf_fullpath = fullpath;
1727 * Determine if this is an OT collection or just a normal font.
1729 np = dot + strlen(dot) - 1;
1730 otf_collection = (*np == 'c' || *np == 'C') ? TRUE : FALSE;
1733 * Initialize the FreeType engine once.
1736 if (FT_Init_FreeType(&library) != 0) {
1738 "Import Font: Unable to initialize the FreeType engine.");
1739 guiutil_error_message(ed->shell, buffer1);
1746 * Attempt to open the font or collection.
1748 if (FT_New_Face(library, fullpath, 0, &face)) {
1749 if (!otf_collection)
1750 sprintf(buffer1, "Import Font: Unable to open OpenType font '%s'.",
1754 "Import Font: Unable to open OpenType collection '%s'.",
1756 guiutil_error_message(ed->shell, buffer1);
1761 * Construct the dialog that will display various choices that will be
1762 * needed when loading the font.
1764 if (otf_dialog == 0)
1765 make_otf_import_dialog();
1768 * Clear the lists and reset the values.
1770 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(otf_faces)));
1771 gtk_list_store_clear(store);
1773 otf_face_open = TRUE;
1774 otf_collection = face->num_faces;
1777 if (otf_collection == 1) {
1778 if (bdfotf_get_english_string(face, BDFOTF_FULLNAME_STRING,
1780 (void) strcpy(buffer1, "Unknown");
1781 gtk_list_store_append(store, &iter);
1782 gtk_list_store_set(store, &iter, 0, buffer1, -1);
1784 otf_face_open = FALSE;
1786 for (i = 0; i < otf_collection; i++) {
1787 if (!FT_New_Face(library, fullpath, i, &face)) {
1788 if (bdfotf_get_english_string(face, BDFOTF_FULLNAME_STRING,
1790 sprintf(buffer1, "Unknown%d", i);
1792 gtk_list_store_append(store, &iter);
1793 gtk_list_store_set(store, &iter, 0, buffer1, -1);
1800 guiutil_show_dialog_centered(otf_dialog, ed->shell);
1803 * Force the user to interact with this dialog before doing anything else.
1805 gtk_window_set_modal(GTK_WINDOW(otf_dialog), TRUE);
1807 otf_select_done = 0;
1808 while (otf_select_done == 0)
1809 gtk_main_iteration();
1812 * Reinitialize various globals when we are done.
1817 if (otf_select_done < 0) {
1820 otf_face_open = FALSE;
1825 * Get the requested point size and resolutions.
1828 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(otf_point_size));
1830 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(otf_hres));
1832 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(otf_vres));
1834 guiutil_busy_cursor(ed->shell, TRUE);
1835 guiutil_busy_cursor(ed->open_dialog, TRUE);
1838 * Actually store the resolution and point size to the options so they
1839 * will be used for other imports. The setup dialog will unfortunately
1840 * assume this are the default values. May fix later so setup knows the
1843 options.font_opts.point_size = psize;
1844 options.font_opts.resolution_x = hres;
1845 options.font_opts.resolution_y = vres;
1848 * Actually load the font.
1850 res = bdfotf_load_font(face, platforms[otf_pid_pos],
1851 encodings[otf_eid_pos], &options.font_opts,
1854 guiutil_busy_cursor(ed->shell, FALSE);
1855 guiutil_busy_cursor(ed->open_dialog, FALSE);
1858 otf_face_open = FALSE;
1862 * Make an error message.
1864 sprintf(buffer1, "Import Font: Unable to load OpenType font %s.",
1866 guiutil_error_message(ed->shell, buffer1);
1871 * Hide the open dialog.
1873 gtk_widget_hide(ed->open_dialog);
1876 * Add the _OTF_FONTFILE property using the original filename.
1878 prop.name = "_OTF_FONTFILE";
1879 prop.format = BDF_ATOM;
1880 prop.value.atom = file;
1881 bdf_add_font_property(font, &prop);
1884 * Now set up a file name.
1886 sprintf(buffer1, "%.*s.bdf", dot - file, file);
1889 * Delete the file and path names so they can be updated.
1896 ed->file = strdup(buffer1);
1897 ed->path = strdup(dir);
1900 * Update the window title.
1902 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ed->file);
1903 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
1906 * Tell the glyphtest widget to remove references to
1907 * the current font if it has any, and redraw.
1910 glyphtest_remove_font(GLYPHTEST(glyphtest),
1911 fontgrid_get_font(FONTGRID(ed->fgrid)));
1913 fontgrid_set_font(FONTGRID(ed->fgrid), font, -1);
1916 * Indicate the font was imported.
1918 ed->imported = TRUE;
1921 * Finally, update the font name field.
1923 gtk_entry_set_text(GTK_ENTRY(ed->fontname),
1924 fontgrid_get_font_name(FONTGRID(ed->fgrid)));
1927 #endif /* HAVE_FREETYPE */
1931 /**************************************************************************
1935 **************************************************************************/
1938 load_hbf_font(gbdfed_editor_t *ed, gchar *fullpath, gchar *dot,
1939 gchar *dir, gchar *file)
1943 guiutil_busy_cursor(ed->shell, TRUE);
1944 guiutil_busy_cursor(ed->open_dialog, TRUE);
1946 font = bdf_load_hbf_font(fullpath, &options.font_opts, 0, 0);
1948 guiutil_busy_cursor(ed->shell, FALSE);
1949 guiutil_busy_cursor(ed->open_dialog, FALSE);
1952 * Check to see if the file can be opened.
1956 sprintf(buffer1, "Import Font: Unable to import %s.", file);
1957 guiutil_error_message(ed->shell, buffer1);
1961 gtk_widget_hide(ed->open_dialog);
1964 * Now set up a file name.
1966 sprintf(buffer1, "%.*s.bdf", (int) (dot - file), file);
1969 * Delete the file and path names so they can be updated.
1976 ed->file = strdup(buffer1);
1980 * Update the window title.
1982 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ed->file);
1983 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
1986 * Tell the glyphtest widget to remove references to
1987 * the current font if it has any, and redraw.
1990 glyphtest_remove_font(GLYPHTEST(glyphtest),
1991 fontgrid_get_font(FONTGRID(ed->fgrid)));
1993 fontgrid_set_font(FONTGRID(ed->fgrid), font, -1);
1996 * Indicate the font was imported.
1998 ed->imported = TRUE;
2001 * Finally, update the font name field.
2003 gtk_entry_set_text(GTK_ENTRY(ed->fontname),
2004 fontgrid_get_font_name(FONTGRID(ed->fgrid)));
2010 * This routine actually does the work of opening the font.
2013 really_open_font(guint ed_id)
2015 gbdfed_editor_t *ed = editors + ed_id;
2016 gchar *filename, *path, *file, *dot;
2018 #if (GTK_MAJOR_VERSION >= 2 && GTK_MINOR_VERSION >= 10)
2019 GtkRecentManager *recent;
2022 fs = GTK_FILE_CHOOSER(ed->open_dialog);
2023 filename = gtk_file_chooser_get_filename(fs);
2026 * Split the filename into path and file, locate the extension position in
2027 * the file name, and make a version of the name with no '-' characters
2028 * which are field separators in XLFD font names.
2030 file = g_path_get_basename(filename);
2031 path = g_path_get_dirname(filename);
2032 if ((dot = strrchr(file, '.')) == 0)
2033 dot = file + strlen(file);
2036 * If the last character of the filename is a slash, no file name was
2039 if (filename[strlen(filename) - 1] == G_DIR_SEPARATOR) {
2040 guiutil_error_message(ed->shell,
2041 "Import Font: No file name provided.");
2050 #if (GTK_MAJOR_VERSION >= 2 && GTK_MINOR_VERSION >= 10)
2051 recent = gtk_recent_manager_get_default();
2052 sprintf(buffer1, "file://%s", filename);
2053 if (gtk_recent_manager_has_item(recent,
2054 (const gchar *) buffer1) == FALSE)
2055 gtk_recent_manager_add_item(recent,
2056 (const gchar *) buffer1);
2059 switch (ed->import_format) {
2061 load_bdf_font(ed, (const gchar *) filename, (const gchar *) path,
2062 (const gchar *) file);
2064 case CONSOLE_FORMAT:
2065 load_console_font(ed, filename, dot, path, file);
2068 load_pkgf_font(ed, filename, dot, path, file);
2071 load_windows_font(ed, filename, dot, path, file);
2075 load_hbf_font(ed, filename, dot, path, file);
2078 #ifdef HAVE_FREETYPE
2080 load_otf_font(ed, filename, dot, path, file);
2082 #endif /* HAVE_FREETYPE */
2093 * In case the editor list changed, set the pointer to the editor again.
2095 ed = editors + ed_id;
2098 * Force the editor's info to be updated for the new font. This causes
2099 * it to change if it is already visible.
2101 guiedit_update_font_info(ed);
2105 make_file_dialog_title(guint type, gboolean save)
2110 case BDF_FORMAT: title = "BDF"; break;
2111 case CONSOLE_FORMAT: title = "Console"; break;
2112 case PKGF_FORMAT: title = "PK/GF"; break;
2113 case FNT_FORMAT: title = "Windows"; break;
2115 case HBF_FORMAT: title = "HBF"; break;
2117 case OTF_FORMAT: title = "TrueType"; break;
2118 case PSF_FORMAT: title = "PSF"; break;
2119 case HEX_FORMAT: title = "HEX"; break;
2123 if (type == BDF_FORMAT)
2124 sprintf(buffer1, "Save %s Font", title);
2126 sprintf(buffer1, "Export %s Font", title);
2128 sprintf(buffer1, "Open %s Font", title);
2134 handle_open_response(GtkDialog *d, gint response, gpointer data)
2137 case GTK_RESPONSE_ACCEPT:
2138 really_open_font(GPOINTER_TO_UINT(data));
2140 case GTK_RESPONSE_CANCEL:
2141 gtk_widget_hide(GTK_WIDGET(d));
2147 update_open_dialog(gbdfed_editor_t *ed, guint type)
2151 if (ed->open_dialog == 0) {
2153 * Create the file chooser filters if they haven't already been
2156 make_file_chooser_filters();
2159 gtk_file_chooser_dialog_new(make_file_dialog_title(type, FALSE),
2160 GTK_WINDOW(ed->shell),
2161 GTK_FILE_CHOOSER_ACTION_OPEN,
2162 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
2163 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
2166 (void) g_signal_connect(G_OBJECT(ed->open_dialog), "response",
2167 G_CALLBACK(handle_open_response),
2168 GUINT_TO_POINTER(ed->id));
2169 (void) g_signal_connect(G_OBJECT(ed->open_dialog), "delete_event",
2170 G_CALLBACK(gtk_widget_hide), 0);
2171 } else if (ed->import_format != type)
2172 gtk_window_set_title(GTK_WINDOW(ed->open_dialog),
2173 make_file_dialog_title(type, FALSE));
2174 fs = GTK_FILE_CHOOSER(ed->open_dialog);
2177 * Set the file filter.
2179 gtk_file_chooser_set_filter(fs, filename_filters[type]);
2181 ed->import_format = type;
2184 * Set the initial path as a file if it exists. This is necessary to
2185 * force the open to occur in the directory where this font was last
2186 * saved, which might be different than the directory that is currently in
2187 * the open file selection dialog.
2189 if (ed->path != 0 && ed->path[0] == G_DIR_SEPARATOR)
2190 gtk_file_chooser_set_current_folder(fs, ed->path);
2194 hide_save_dialog(GtkWidget *w, gpointer data)
2197 save_dialog_done = TRUE;
2201 set_psf_option(GtkWidget *w, gpointer data)
2205 gchar *fname, *dot, *slash, *suff = 0;
2208 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(w))) {
2210 flags = BDF_PSF_UNIMAP|BDF_PSF_FONT;
2213 flags = BDF_PSF_FONT;
2216 flags = BDF_PSF_UNIMAP;
2220 if (flags == BDF_PSF_UNIMAP)
2222 * Have to change to the .uni suffix.
2225 else if (options.font_opts.psf_flags == BDF_PSF_UNIMAP)
2227 * Have to change back to the .psfu suffix.
2231 options.font_opts.psf_flags = flags;
2235 * Change the suffix on the filename in the entry area.
2237 fs = GTK_FILE_CHOOSER(g_object_get_data(G_OBJECT(w),
2238 "file-selection-dialog"));
2239 fname = gtk_file_chooser_get_filename(fs);
2242 if ((dot = (gchar *) strrchr(fname, '.')) != 0) {
2243 if ((slash = (gchar *) strrchr(fname, G_DIR_SEPARATOR)) == 0)
2245 dotpos = (gint) (dot - slash) - 1;
2248 * Copy the new extension in.
2250 (void) strcpy(dot, suff);
2254 if (*slash == G_DIR_SEPARATOR)
2257 gtk_file_chooser_set_current_name(fs, slash);
2263 handle_save_response(GtkDialog *d, gint response, gpointer data)
2266 case GTK_RESPONSE_ACCEPT:
2267 really_save_font(GPOINTER_TO_UINT(data));
2269 case GTK_RESPONSE_CANCEL:
2270 gtk_widget_hide(GTK_WIDGET(d));
2276 update_save_dialog(gbdfed_editor_t *ed, guint type)
2282 if (ed->save_dialog == 0) {
2284 * Create the file chooser filters if they haven't already been
2287 make_file_chooser_filters();
2290 gtk_file_chooser_dialog_new(make_file_dialog_title(type, TRUE),
2291 GTK_WINDOW(ed->shell),
2292 GTK_FILE_CHOOSER_ACTION_SAVE,
2293 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
2294 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
2297 vbox = GTK_DIALOG(ed->save_dialog)->vbox;
2299 psf_export_options = gtk_combo_box_new_text();
2301 * Since the flags have to be set in the save dialog, attach the
2302 * save dialog to the object so we can set the bits appropriately.
2304 g_object_set_data(G_OBJECT(psf_export_options),
2305 "file-selection-dialog",
2306 (gpointer) ed->save_dialog);
2307 (void) g_signal_connect(G_OBJECT(psf_export_options), "changed",
2308 G_CALLBACK(set_psf_option), 0);
2309 gtk_combo_box_append_text(GTK_COMBO_BOX(psf_export_options),
2310 "Font and Unicode Map");
2311 gtk_combo_box_append_text(GTK_COMBO_BOX(psf_export_options),
2313 gtk_combo_box_append_text(GTK_COMBO_BOX(psf_export_options),
2314 "Unicode Map Only");
2315 gtk_combo_box_set_active(GTK_COMBO_BOX(psf_export_options), 0);
2317 psf_export_frame = labcon_new_label_defaults("PSF Export Options:",
2318 psf_export_options, 0);
2320 (void) g_signal_connect(G_OBJECT(ed->save_dialog), "delete_event",
2321 G_CALLBACK(hide_save_dialog), 0);
2323 (void) g_signal_connect(G_OBJECT(ed->save_dialog), "response",
2324 G_CALLBACK(handle_save_response),
2325 GUINT_TO_POINTER(ed->id));
2327 gtk_widget_show_all(psf_export_frame);
2328 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(ed->save_dialog),
2330 } else if (ed->export_format != type)
2331 gtk_window_set_title(GTK_WINDOW(ed->save_dialog),
2332 make_file_dialog_title(type, TRUE));
2335 * Set the file filter.
2337 gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(ed->save_dialog),
2338 filename_filters[type]);
2341 ed->export_format = type;
2344 * Show or hide the PSF exporting options.
2346 if (type == PSF_FORMAT)
2347 gtk_widget_show(psf_export_frame);
2349 gtk_widget_hide(psf_export_frame);
2352 * Use the current path and filename as the default. This is done in case
2353 * the font was loaded from some directory other than the current default
2354 * in the file selection dialog for saving.
2357 sprintf(buffer1, "%s", ed->file);
2359 sprintf(buffer1, "unnamed%d.bdf", ed->id);
2361 if ((dot = (gchar *) strrchr(buffer1, '.'))) {
2362 if ((slash = (gchar *) strrchr(buffer1, G_DIR_SEPARATOR)) == 0)
2364 dotpos = (gint) (dot - slash) - 1;
2367 * If a PSF or HEX font is being exported, change the extension
2370 if (type == PSF_FORMAT)
2371 (void) strcpy(dot, ".psfu");
2372 else if (type == HEX_FORMAT)
2373 (void) strcpy(dot, ".hex");
2378 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(ed->save_dialog),
2380 if (ed->path != 0 && ed->path[0] == G_DIR_SEPARATOR)
2381 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(ed->save_dialog),
2384 gtk_editable_set_position(GTK_EDITABLE(fs->selection_entry), dotpos);
2385 gtk_editable_select_region(GTK_EDITABLE(fs->selection_entry), 0, dotpos);
2390 guifile_import_bdf_font(GtkWidget *w, gpointer data)
2392 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2394 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2396 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2398 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2399 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2401 * If the current file was imported, then make sure to use the
2402 * Save As... dialog instead of just saving under the name that
2403 * was constructed when importing. The user won't know what the
2404 * default BDF file name of imported fonts look like.
2407 guifile_save_as_wait(w, data);
2409 guifile_save(w, data);
2414 update_open_dialog(ed, BDF_FORMAT);
2416 guiutil_show_dialog_centered(ed->open_dialog, ed->shell);
2420 guifile_import_console_font(GtkWidget *w, gpointer data)
2422 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2424 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2426 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2428 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2429 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2431 * If the current file was imported, then make sure to use the
2432 * Save As... dialog instead of just saving under the name that
2433 * was constructed when importing. The user won't know what the
2434 * default BDF file name of imported fonts look like.
2437 guifile_save_as_wait(w, data);
2439 guifile_save(w, data);
2444 update_open_dialog(ed, CONSOLE_FORMAT);
2446 guiutil_show_dialog_centered(ed->open_dialog, ed->shell);
2450 guifile_import_pkgf_font(GtkWidget *w, gpointer data)
2452 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2454 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2456 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2458 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2459 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2461 * If the current file was imported, then make sure to use the
2462 * Save As... dialog instead of just saving under the name that
2463 * was constructed when importing. The user won't know what the
2464 * default BDF file name of imported fonts look like.
2467 guifile_save_as_wait(w, data);
2469 guifile_save(w, data);
2474 update_open_dialog(ed, PKGF_FORMAT);
2476 guiutil_show_dialog_centered(ed->open_dialog, ed->shell);
2480 guifile_import_windows_font(GtkWidget *w, gpointer data)
2482 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2484 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2486 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2488 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2489 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2491 * If the current file was imported, then make sure to use the
2492 * Save As... dialog instead of just saving under the name that
2493 * was constructed when importing. The user won't know what the
2494 * default BDF file name of imported fonts look like.
2497 guifile_save_as_wait(w, data);
2499 guifile_save(w, data);
2504 update_open_dialog(ed, FNT_FORMAT);
2506 guiutil_show_dialog_centered(ed->open_dialog, ed->shell);
2512 guifile_import_hbf_font(GtkWidget *w, gpointer data)
2514 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2516 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2518 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2520 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2521 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2523 * If the current file was imported, then make sure to use the
2524 * Save As... dialog instead of just saving under the name that
2525 * was constructed when importing. The user won't know what the
2526 * default BDF file name of imported fonts look like.
2529 guifile_save_as_wait(w, data);
2531 guifile_save(w, data);
2536 update_open_dialog(ed, HBF_FORMAT);
2538 guiutil_show_dialog_centered(ed->open_dialog, ed->shell);
2543 #ifdef HAVE_FREETYPE
2546 guifile_import_otf_font(GtkWidget *w, gpointer data)
2548 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2550 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2552 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2554 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2555 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2557 * If the current file was imported, then make sure to use the
2558 * Save As... dialog instead of just saving under the name that
2559 * was constructed when importing. The user won't know what the
2560 * default BDF file name of imported fonts look like.
2563 guifile_save_as_wait(w, data);
2565 guifile_save(w, data);
2570 update_open_dialog(ed, OTF_FORMAT);
2572 guiutil_show_dialog_centered(ed->open_dialog, ed->shell);
2575 #endif /* HAVE_FREETYPE */
2577 /**************************************************************************
2581 **************************************************************************/
2585 * Only compile this in if it is being built for machine running X.
2589 xsrv_filter(GtkWidget *w, gpointer data)
2591 gchar *pattern, **fonts;
2593 GtkListStore *store;
2594 GtkTreeViewColumn *col;
2597 pattern = (gchar *) gtk_entry_get_text(GTK_ENTRY(xsrv_filter_text));
2599 fonts = XListFonts(GDK_DISPLAY(), pattern, _XSRV_MAX_FONTS, &nfonts);
2602 GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(xsrv_font_list)));
2603 col = gtk_tree_view_get_column(GTK_TREE_VIEW(xsrv_font_list), 0);
2606 * Update the label on the font list with the number of fonts.
2608 sprintf(buffer1, "Font List: %d", nfonts);
2609 gtk_tree_view_column_set_title(col, buffer1);
2611 gtk_list_store_clear(store);
2612 for (i = 0; i < nfonts; i++) {
2613 gtk_list_store_append(store, &iter);
2614 gtk_list_store_set(store, &iter, 0, fonts[i], -1);
2617 XFreeFontNames(fonts);
2621 xsrv_xlfd_filter(GtkWidget *w, gpointer data)
2623 gtk_entry_set_text(GTK_ENTRY(xsrv_filter_text), _XSRV_DEFAULT_FILTER);
2624 gtk_widget_activate(xsrv_filter_text);
2628 xsrv_select_font(GtkTreeSelection *sel, gpointer data)
2631 GtkTreeModel *model;
2634 if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
2635 gtk_tree_model_get (model, &iter, 0, &name, -1);
2636 gtk_entry_set_text(GTK_ENTRY(xsrv_selection_text), name);
2642 xsrv_clear_selection_text(GtkWidget *w, gpointer data)
2644 gtk_entry_set_text(GTK_ENTRY(xsrv_selection_text), "");
2648 xsrv_import_font(GtkWidget *w, gpointer data)
2650 gbdfed_editor_t *ed = editors + xsrv_active_editor;
2655 name = (gchar *) gtk_entry_get_text(GTK_ENTRY(xsrv_selection_text));
2656 if (strcmp(name, "") == 0) {
2657 guiutil_error_message(ed->shell,
2658 "Import Font: No font name provided.");
2662 guiutil_busy_cursor(ed->shell, TRUE);
2663 guiutil_busy_cursor(xsrv_dialog, TRUE);
2664 if ((xfont = XLoadQueryFont(GDK_DISPLAY(), name)) == 0) {
2665 guiutil_busy_cursor(ed->shell, FALSE);
2666 guiutil_busy_cursor(xsrv_dialog, FALSE);
2667 sprintf(buffer1, "Import Font: Unable to load server font %s.",
2669 guiutil_error_message(ed->shell, buffer1);
2673 font = bdf_load_server_font(GDK_DISPLAY(), xfont, name,
2674 &options.font_opts, 0, 0);
2675 guiutil_busy_cursor(ed->shell, FALSE);
2676 guiutil_busy_cursor(xsrv_dialog, FALSE);
2677 XFreeFont(GDK_DISPLAY(), xfont);
2680 sprintf(buffer1, "Import Font: Unable to import server font %s.",
2682 guiutil_error_message(ed->shell, buffer1);
2689 gtk_widget_hide(xsrv_dialog);
2695 ed->file = ed->path = 0;
2697 sprintf(buffer1, "%s - unnamed%d [modified]", g_get_prgname(),
2699 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
2702 * Tell the glyphtest widget to remove references to
2703 * the current font if it has any, and redraw.
2706 glyphtest_remove_font(GLYPHTEST(glyphtest),
2707 fontgrid_get_font(FONTGRID(ed->fgrid)));
2709 fontgrid_set_font(FONTGRID(ed->fgrid), font, -1);
2712 * Indicate the font was imported.
2714 ed->imported = TRUE;
2717 * Finally, update the font name field.
2719 gtk_entry_set_text(GTK_ENTRY(ed->fontname),
2720 fontgrid_get_font_name(FONTGRID(ed->fgrid)));
2724 xsrv_activate_font(GtkTreeView *view, GtkTreePath *path,
2725 GtkTreeViewColumn *col, gpointer data)
2727 xsrv_import_font(GTK_WIDGET(view), data);
2731 guifile_import_xserver_font(GtkWidget *w, gpointer data)
2733 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2734 GtkWidget *label, *hbox, *vbox, *text, *swin, *button;
2735 gchar *name, **fonts;
2737 GtkListStore *store;
2738 GtkTreeViewColumn *column;
2739 GtkCellRenderer *cell_renderer;
2740 GtkTreeSelection *sel;
2743 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2745 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2747 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2748 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2750 * If the current file was imported, then make sure to use the
2751 * Save As... dialog instead of just saving under the name that
2752 * was constructed when importing. The user won't know what the
2753 * default BDF file name of imported fonts look like.
2756 guifile_save_as_wait(w, data);
2758 guifile_save(w, data);
2763 xsrv_active_editor = ed->id;
2765 if (xsrv_dialog == 0) {
2766 xsrv_dialog = gtk_dialog_new();
2767 gtk_window_set_title(GTK_WINDOW(xsrv_dialog),
2768 "X Server Font Selection");
2769 (void) g_signal_connect(G_OBJECT(xsrv_dialog), "delete_event",
2770 G_CALLBACK(gtk_widget_hide), 0);
2772 vbox = GTK_DIALOG(xsrv_dialog)->vbox;
2773 hbox = GTK_DIALOG(xsrv_dialog)->action_area;
2775 label = gtk_label_new("Filter");
2776 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
2777 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
2779 text = xsrv_filter_text = gtk_entry_new();
2780 gtk_entry_set_text(GTK_ENTRY(text), _XSRV_DEFAULT_FILTER);
2781 (void) g_signal_connect(G_OBJECT(text), "activate",
2782 G_CALLBACK(xsrv_filter), 0);
2783 gtk_box_pack_start(GTK_BOX(vbox), text, TRUE, TRUE, 0);
2785 swin = gtk_scrolled_window_new(0, 0);
2786 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
2787 GTK_POLICY_AUTOMATIC,
2790 store = gtk_list_store_new(1, G_TYPE_STRING);
2791 xsrv_font_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
2792 g_object_unref(store);
2794 (void) g_signal_connect(G_OBJECT(xsrv_font_list), "row_activated",
2795 G_CALLBACK(xsrv_activate_font),
2796 GUINT_TO_POINTER(ed->id));
2798 cell_renderer = gtk_cell_renderer_text_new();
2799 column = gtk_tree_view_column_new_with_attributes ("Fonts Found: 0",
2804 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
2805 gtk_tree_view_append_column (GTK_TREE_VIEW(xsrv_font_list), column);
2808 * Force the list to have a certain width and height.
2810 gtk_widget_set_size_request(xsrv_font_list, 550, 200);
2812 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(xsrv_font_list));
2813 gtk_tree_selection_set_mode(sel, GTK_SELECTION_BROWSE);
2815 (void) g_signal_connect(G_OBJECT(sel), "changed",
2816 G_CALLBACK(xsrv_select_font), NULL);
2818 gtk_container_add(GTK_CONTAINER(swin), xsrv_font_list);
2820 gtk_box_pack_start(GTK_BOX(vbox), swin, TRUE, TRUE, 0);
2822 label = gtk_label_new("Selection");
2823 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
2824 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
2826 text = xsrv_selection_text = gtk_entry_new();
2827 (void) g_signal_connect(G_OBJECT(text), "activate",
2828 G_CALLBACK(xsrv_import_font),
2829 GUINT_TO_POINTER(ed->id));
2830 gtk_box_pack_start(GTK_BOX(vbox), text, TRUE, TRUE, 0);
2833 * Now add the buttons.
2835 button = xsrv_import = gtk_button_new_with_label("Import");
2836 (void) g_signal_connect(G_OBJECT(button), "clicked",
2837 G_CALLBACK(xsrv_import_font),
2838 GUINT_TO_POINTER(ed->id));
2839 gtk_container_add(GTK_CONTAINER(hbox), button);
2841 button = xsrv_import = gtk_button_new_with_label("Clear Selection");
2842 (void) g_signal_connect(G_OBJECT(button), "clicked",
2843 G_CALLBACK(xsrv_clear_selection_text), 0);
2844 gtk_container_add(GTK_CONTAINER(hbox), button);
2846 button = gtk_button_new_with_label("Filter");
2847 (void) g_signal_connect(G_OBJECT(button), "clicked",
2848 G_CALLBACK(xsrv_filter), 0);
2849 gtk_container_add(GTK_CONTAINER(hbox), button);
2851 button = gtk_button_new_with_label("XLFD Filter");
2852 (void) g_signal_connect(G_OBJECT(button), "clicked",
2853 G_CALLBACK(xsrv_xlfd_filter), 0);
2854 gtk_container_add(GTK_CONTAINER(hbox), button);
2856 button = gtk_button_new_with_label("Cancel");
2857 (void) g_signal_connect_object(G_OBJECT(button), "clicked",
2858 G_CALLBACK(gtk_widget_hide),
2859 (gpointer) xsrv_dialog,
2861 gtk_container_add(GTK_CONTAINER(hbox), button);
2863 gtk_widget_show_all(vbox);
2864 gtk_widget_show_all(hbox);
2868 GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(xsrv_font_list)));
2869 column = gtk_tree_view_get_column(GTK_TREE_VIEW(xsrv_font_list), 0);
2872 * Load the list of fonts using the current filter pattern. This needs to
2873 * be done each time in case the list of font paths has changed between
2876 name = (gchar *) gtk_entry_get_text(GTK_ENTRY(xsrv_filter_text));
2877 fonts = XListFonts(GDK_DISPLAY(), name, _XSRV_MAX_FONTS, &nfonts);
2880 * Update the label on the font list with the number of fonts.
2882 sprintf(buffer1, "Fonts Found: %d", nfonts);
2883 gtk_tree_view_column_set_title(column, buffer1);
2885 gtk_list_store_clear(store);
2886 for (i = 0; i < nfonts; i++) {
2887 gtk_list_store_append(store, &iter);
2888 gtk_list_store_set(store, &iter, 0, fonts[i], -1);
2891 XFreeFontNames(fonts);
2896 guiutil_show_dialog_centered(xsrv_dialog, ed->shell);
2900 #endif /* HAVE_XLIB */
2903 guifile_export_psf_font(GtkWidget *w, gpointer data)
2905 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2908 font = fontgrid_get_font(FONTGRID(ed->fgrid));
2911 * Only character cell and mono width fonts can be exported as PSF2.
2913 if (font->spacing == BDF_PROPORTIONAL) {
2915 "Export Font: Font cannot be saved as PSF because %s ",
2916 "the font has proportional width.");
2917 guiutil_error_message(ed->shell, buffer2);
2921 update_save_dialog(ed, PSF_FORMAT);
2923 guiutil_show_dialog_centered(ed->save_dialog, ed->shell);
2927 guifile_export_hex_font(GtkWidget *w, gpointer data)
2929 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2932 * No check is done for a "valid" HEX font because it actually pads the
2933 * output font into bitmaps of two sizes, the wider size twice as wide
2934 * as the narrower size.
2937 update_save_dialog(ed, HEX_FORMAT);
2939 guiutil_show_dialog_centered(ed->save_dialog, ed->shell);
2943 guifile_save_as(GtkWidget *w, gpointer data)
2945 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2947 update_save_dialog(ed, BDF_FORMAT);
2949 guiutil_show_dialog_centered(ed->save_dialog, ed->shell);
2953 guifile_save_as_wait(GtkWidget *w, gpointer data)
2955 save_dialog_done = FALSE;
2957 guifile_save_as(w, data);
2958 while (save_dialog_done == FALSE)
2959 gtk_main_iteration();
2963 guifile_save(GtkWidget *w, gpointer data)
2965 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2968 * If this is a new font, then we need to show the file selection dialog.
2969 * Otherwise, simply write the font out.
2971 if (ed->path == 0 && ed->file == 0) {
2972 guifile_save_as(w, data);
2976 ed->export_format = BDF_FORMAT;
2977 sprintf(buffer1, "%s/%s", ed->path, ed->file);
2978 export_font(buffer1, ed, FALSE);
2982 guifile_new_editor(GtkWidget *w, gpointer data)
2986 n = gbdfed_make_editor(0, FALSE);
2988 gtk_widget_show_all(editors[n].shell);
2992 * A routine to load a BDF font directly.
2995 guifile_load_bdf_font(gbdfed_editor_t *ed, const gchar *fullpath)
2999 if (fullpath == NULL)
3002 file = g_path_get_basename(fullpath);
3003 dir = g_path_get_dirname(fullpath);
3004 load_bdf_font(ed, fullpath, dir, file);