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
43 #define HEADER_FORMAT 10
46 * An array of filters used for the open/import and save dialogs.
48 static GtkFileFilter *filename_filters[10];
51 * This variable is used to track whether the save dialog has been closed
52 * so the guifile_save_as_wait() routine knows when to return to the main
55 static gboolean save_dialog_done;
60 #include FT_SFNT_NAMES_H
61 #include FT_TRUETYPE_TABLES_H
64 * Globals used for FreeType.
66 static FT_Library library;
70 * Globals used for importing OpenType fonts.
72 static gboolean ftinit = FALSE;
73 static gboolean otf_collection;
74 static gboolean otf_face_open;
75 static gint otf_select_done = 0;
76 static gchar *otf_fullpath;
79 * These are the widgets that will be needed for importing OpenType fonts.
81 static GtkWidget *otf_dialog;
82 static GtkWidget *otf_faces;
83 static GtkWidget *otf_platforms;
84 static GtkWidget *otf_encodings;
85 static GtkWidget *otf_point_size;
86 static GtkWidget *otf_hres;
87 static GtkWidget *otf_vres;
90 * List of platform IDs seen that is used when platforms are selected
91 * from OpenType fonts.
93 static gint16 platforms[32];
94 static gint nplatforms;
97 * List of encoding IDs seen that is used when encodings are selected
98 * from OpenType fonts.
100 static gint16 encodings[34];
101 static gint nencodings;
104 * Variables to hold the selected platform and encoding ID's.
106 static gint16 otf_pid_pos;
107 static gint16 otf_eid_pos;
109 #endif /* HAVE_FREETYPE */
114 * These are for importing fonts from the X server.
116 #define _XSRV_MAX_FONTS 32767
117 #define _XSRV_DEFAULT_FILTER "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"
119 static GtkWidget *xsrv_dialog;
120 static GtkWidget *xsrv_filter_text;
121 static GtkWidget *xsrv_selection_text;
122 static GtkWidget *xsrv_font_list;
123 static GtkWidget *xsrv_import;
126 * Because the grab dialog is shared amongst the editors, this tracks which
127 * editor has control of the font list.
129 static guint xsrv_active_editor;
131 #endif /* HAVE_XLIB */
134 * Widgets for dealing with exporting PSF fonts.
136 static GtkWidget *psf_export_frame;
137 static GtkWidget *psf_export_options;
140 * Widgets for selecting fonts from a Windows font archive.
142 static GtkWidget *fnt_dialog;
143 static GtkWidget *fnt_font_list;
144 static GtkWidget *fnt_load_button;
147 * This is a list of Windows fonts that have been selected. It assumes that
148 * the font file will never contain more than 32 fonts.
150 static gint fnt_selected[32];
151 static gint fnt_selected_count;
154 * A structure used to pass data to the load and cancel callbacks when dealing
155 * with FON/FNT fonts.
162 } _bdffnt_callback_data_t;
165 * This is used in a couple of cases to point at the active editor.
167 static gbdfed_editor_t *active_editor;
170 make_file_chooser_filters(void)
174 if (filename_filters[0] != NULL)
177 filename_filters[BDF_FORMAT] = gtk_file_filter_new();
178 gtk_file_filter_add_pattern(filename_filters[BDF_FORMAT],
181 filename_filters[CONSOLE_FORMAT] = gtk_file_filter_new();
182 gtk_file_filter_add_pattern(filename_filters[CONSOLE_FORMAT], "*");
184 filename_filters[PKGF_FORMAT] = gtk_file_filter_new();
185 gtk_file_filter_add_pattern(filename_filters[PKGF_FORMAT],
188 filename_filters[FNT_FORMAT] = gtk_file_filter_new();
189 gtk_file_filter_add_pattern(filename_filters[FNT_FORMAT],
190 "*.[FfEeDd][OoNnXxLl][NnTtEeLl]");
192 filename_filters[HEX_FORMAT] = gtk_file_filter_new();
193 gtk_file_filter_add_pattern(filename_filters[HEX_FORMAT],
196 filename_filters[PSF_FORMAT] = gtk_file_filter_new();
197 gtk_file_filter_add_pattern(filename_filters[PSF_FORMAT],
200 filename_filters[HEADER_FORMAT] = gtk_file_filter_new();
201 gtk_file_filter_add_pattern(filename_filters[HEADER_FORMAT],
206 * This one is basically for exporting unimap files that belong to PSF
209 filename_filters[PSFUNI_FORMAT] = gtk_file_filter_new();
210 gtk_file_filter_add_pattern(filename_filters[PSFUNI_FORMAT],
214 filename_filters[HBF_FORMAT] = gtk_file_filter_new();
215 gtk_file_filter_add_pattern(filename_filters[HBF_FORMAT],
220 filename_filters[OTF_FORMAT] = gtk_file_filter_new();
221 gtk_file_filter_add_pattern(filename_filters[OTF_FORMAT],
222 "*.[OoTt][Tt][FfCcEe]");
223 #endif /* HAVE_FREETYPE */
225 filename_filters[0] = (GtkFileFilter *) 1;
228 * Add a reference to all the filters so they don't cause a delayed crash
229 * when popping up the import dialog multiple times.
231 for (i = 1; i < 10; i++) {
232 if (filename_filters[i] != NULL)
233 g_object_ref(filename_filters[i]);
238 export_font(gchar *filename, gbdfed_editor_t *ed, gboolean copy_filename)
242 gboolean local_font = FALSE;
243 bdf_property_t vanity;
244 FontgridSelectionInfo sinfo;
246 font = fontgrid_get_font(FONTGRID(ed->fgrid));
249 * First, attempt to make a backup if they are specified.
251 if (options.backups) {
252 out = fopen(filename, "rb");
257 * Attempt to make a backup.
259 sprintf(buffer2, "%s.bak", filename);
264 * Don't return here because we want to save the font even if a
265 * backup can't be made.
267 if (rename(filename, buffer2))
268 guiutil_error_message(ed->shell,
269 "Backups: Unable to make a backup.");
274 * Try to open the file for writing. Only PSF needs binary.
276 out = (ed->export_format != PSF_FORMAT) ?
277 fopen(filename, "w") : fopen(filename, "wb");
280 if (ed->export_format == BDF_FORMAT)
281 sprintf(buffer2, "Save Font: Unable to write to %s.", filename);
283 sprintf(buffer2, "Export Font: Unable to write to %s.", filename);
284 guiutil_error_message(ed->shell, buffer2);
288 switch (ed->export_format) {
292 * We need to create a font with the default options so it
293 * can be written out as a skeleton.
295 font = bdf_new_font("unnamed",
296 options.font_opts.point_size,
297 options.font_opts.resolution_x,
298 options.font_opts.resolution_y,
299 options.font_opts.font_spacing,
300 options.font_opts.bits_per_pixel);
305 * Add a custom property if the font has been
307 if (font->modified || local_font == TRUE) {
308 sprintf(buffer2, "Edited with gbdfed %s.", GBDFED_VERSION);
309 vanity.name = "_GBDFED_INFO";
310 vanity.format = BDF_ATOM;
311 vanity.value.atom = buffer2;
312 bdf_add_font_property(font, &vanity);
314 bdf_save_font(out, font, &options.font_opts, 0, 0);
315 if (local_font == TRUE)
319 bdf_export_hex(out, font, &options.font_opts, 0, 0);
322 bdf_export_header(out, font, &options.font_opts, 0, 0);
325 sinfo.start = sinfo.end = 0;
326 (void) fontgrid_has_selection(FONTGRID(ed->fgrid), &sinfo);
327 if (sinfo.start == sinfo.end) {
328 sinfo.start = font->glyphs[0].encoding;
329 sinfo.end = font->glyphs[font->glyphs_used - 1].encoding;
331 switch (bdf_export_psf(out, font, &options.font_opts,
332 sinfo.start, sinfo.end)) {
337 sprintf(buffer1, "Export PSF: Invalid range %d-%d.\n",
338 sinfo.start, sinfo.end);
340 case BDF_PSF_CORRUPT_UTF8:
342 "Export PSF: Bad UTF-8 encountered in the mappings.");
347 * Something went wrong during the PSF export.
349 guiutil_error_message(ed->shell, buffer1);
355 * The rest of this only applies to BDF fonts and not PSF or HEX fonts.
356 * PSF and HEX fonts have their own extensions in the save dialog, but
357 * that does not affect the actual file name in the editor.
359 if (ed->export_format == BDF_FORMAT) {
362 * Copy the path and filename into the editor if specified.
369 ed->path = ed->file = 0;
370 ed->file = g_path_get_basename(filename);
371 ed->path = g_path_get_dirname(filename);
375 * Mark the font as being unmodified.
377 fontgrid_set_font_modified(FONTGRID(ed->fgrid), FALSE);
380 * Update the window title accordingly.
383 sprintf(buffer1, "%s - %s", g_get_prgname(), ed->file);
385 sprintf(buffer1, "%s - (unnamed%d)", g_get_prgname(), ed->id);
387 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
390 * Since the font was saved as BDF, it is no longer marked as being
393 ed->imported = FALSE;
400 really_save_font(guint ed_id)
402 gbdfed_editor_t *ed = editors + ed_id;
405 #if (GTK_MAJOR_VERSION >= 2 && GTK_MINOR_VERSION >= 10)
406 GtkRecentManager *recent;
409 fname = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(ed->save_dialog));
411 have = fopen(fname, "rb");
416 * Check to see if the user wishes to overwrite the existing font.
418 sprintf(buffer2, "Save Font: %s exists.\nDo you wish to overwrite?",
420 if (guiutil_yes_or_no(ed->shell, buffer2, TRUE) == FALSE) {
427 * If the write was successful, hide the dialog.
429 if (export_font(fname, ed, TRUE)) {
430 save_dialog_done = TRUE;
431 gtk_widget_hide(ed->save_dialog);
432 #if (GTK_MAJOR_VERSION >= 2 && GTK_MINOR_VERSION >= 10)
433 recent = gtk_recent_manager_get_default();
434 sprintf(buffer1, "file://%s", fname);
435 if (gtk_recent_manager_has_item(recent,
436 (const gchar *) buffer1) == FALSE)
437 gtk_recent_manager_add_item(recent,
438 (const gchar *) buffer1);
445 * This callback routine handles errors and updating the progress bar if
449 handle_import_messages(bdf_callback_struct_t *call_data, void *client_data)
451 if (call_data->reason == BDF_ERROR) {
452 sprintf(buffer1, "Import Font:%d: error: See the font messages.",
453 call_data->errlineno);
454 guiutil_error_message(GTK_WIDGET(client_data), buffer1);
458 /**************************************************************************
462 **************************************************************************/
465 load_bdf_font(gbdfed_editor_t *ed, const gchar *fullpath, const gchar *dir,
472 * Check to see if the file can be opened.
474 if ((in = fopen(fullpath, "rb")) == 0) {
475 sprintf(buffer1, "Import Font: Unable to open %s.", file);
476 guiutil_error_message(ed->shell, buffer1);
480 guiutil_busy_cursor(ed->shell, TRUE);
481 if (ed->open_dialog != NULL)
482 guiutil_busy_cursor(ed->open_dialog, TRUE);
484 font = bdf_load_font(in, &options.font_opts,
485 handle_import_messages, (void *) ed->shell);
487 guiutil_busy_cursor(ed->shell, FALSE);
488 if (ed->open_dialog != NULL)
489 guiutil_busy_cursor(ed->open_dialog, FALSE);
493 sprintf(buffer1, "Import Font: Unable to load %s.", file);
494 guiutil_error_message(ed->shell, buffer1);
499 if (ed->open_dialog != NULL)
500 gtk_widget_hide(ed->open_dialog);
503 * Delete the file and path names so they can be updated.
510 ed->file = ed->path = 0;
512 ed->file = strdup(file);
513 ed->path = strdup(dir);
516 * Update the window title.
519 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ed->file);
521 sprintf(buffer1, "%s - %s", g_get_prgname(), ed->file);
523 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
526 * Tell the glyphtest widget to remove references to the current font if
527 * it has any, and redraw.
530 glyphtest_remove_font(GLYPHTEST(glyphtest),
531 fontgrid_get_font(FONTGRID(ed->fgrid)));
533 fontgrid_set_font(FONTGRID(ed->fgrid), font, -1);
536 * Finally, update the font name field.
538 gtk_entry_set_text(GTK_ENTRY(ed->fontname),
539 fontgrid_get_font_name(FONTGRID(ed->fgrid)));
542 * Make sure the imported flag is cleared in this case.
544 ed->imported = FALSE;
547 /**************************************************************************
551 **************************************************************************/
554 load_console_font(gbdfed_editor_t *ed, gchar *fullpath, gchar *dot,
555 gchar *dir, gchar *file)
559 gint i, j, nfonts, len;
561 bdf_font_t *fonts[3];
564 * Check to see if the file can be opened.
566 if ((in = fopen(fullpath, "rb")) == 0) {
567 sprintf(buffer1, "Import Font: Unable to open %s.", fullpath);
568 guiutil_error_message(ed->shell, buffer1);
572 guiutil_busy_cursor(ed->shell, TRUE);
573 guiutil_busy_cursor(ed->open_dialog, TRUE);
575 i = bdf_load_console_font(in, &options.font_opts, 0, 0, fonts, &nfonts);
577 guiutil_busy_cursor(ed->shell, FALSE);
578 guiutil_busy_cursor(ed->open_dialog, FALSE);
584 * Free up any font structures that happened to be loaded.
586 for (j = 0; j < nfonts; j++)
587 bdf_free_font(fonts[j]);
589 sprintf(buffer1, "Import Font: %s not a console font.", fullpath);
590 guiutil_error_message(ed->shell, buffer1);
594 gtk_widget_hide(ed->open_dialog);
597 * Handle creation of the editors. In the case of some console fonts,
598 * there are three different sizes contained in the font.
600 for (i = 0; i < nfonts; i++) {
602 ep = editors + gbdfed_make_editor(0, FALSE);
607 * Erase the existing file and directory name in the "root"
614 ep->file = ep->path = 0;
617 * Tell the glyphtest widget to remove references to the current
618 * font, if it has any, and redraw.
621 glyphtest_remove_font(GLYPHTEST(glyphtest),
622 fontgrid_get_font(FONTGRID(ep->fgrid)));
626 * Make an XLFD name for the font using the filename. Run through the
627 * file name and change all occurences of '-' to '_' to avoid problems
628 * with '-' being the XLFD field separator.
630 for (j = 0, np = file; np < dot; np++, j++)
631 buffer2[j] = (*np != '-') ? *np : '_';
635 bdf_make_xlfd_name(fonts[i], "Unknown", buffer2);
636 bdf_update_properties_from_name(fonts[i]);
638 len = (gint) (dot - file);
641 * Create the default name for the font file.
646 sprintf(buffer1, "%.*s-16.bdf", len, file);
649 sprintf(buffer1, "%.*s-14.bdf", len, file);
652 sprintf(buffer1, "%.*s-08.bdf", len, file);
656 sprintf(buffer1, "%.*s.bdf", len, file);
659 * Set the filename for the editor.
661 ep->file = strdup(buffer1);
662 ep->path = strdup(dir);
665 * Set the new editor title.
667 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ep->file);
668 gtk_window_set_title(GTK_WINDOW(ep->shell), buffer1);
671 * Change the font in the editor.
673 fontgrid_set_font(FONTGRID(ep->fgrid), fonts[i], -1);
676 * Indicate the font was imported.
681 * Update the XLFD name.
683 gtk_entry_set_text(GTK_ENTRY(ep->fontname),
684 fontgrid_get_font_name(FONTGRID(ep->fgrid)));
688 /**************************************************************************
692 **************************************************************************/
695 load_pkgf_font(gbdfed_editor_t *ed, gchar *fullpath, gchar *dot,
696 gchar *dir, gchar *file)
704 * Check to see if the file can be opened.
706 if ((in = fopen(fullpath, "rb")) == 0) {
707 sprintf(buffer1, "Import Font: Unable to open %s.", file);
708 guiutil_error_message(ed->shell, buffer1);
712 guiutil_busy_cursor(ed->shell, TRUE);
713 guiutil_busy_cursor(ed->open_dialog, TRUE);
715 i = bdf_load_mf_font(in, &options.font_opts, 0, 0, &font);
717 guiutil_busy_cursor(ed->shell, FALSE);
718 guiutil_busy_cursor(ed->open_dialog, FALSE);
723 sprintf(buffer1, "Import Font: %s not a PK or GF font.", fullpath);
724 guiutil_error_message(ed->shell, buffer1);
728 gtk_widget_hide(ed->open_dialog);
731 * Make an XLFD name for the font using the filename. Run through the
732 * file name and change all occurences of '-' to '_' to avoid problems
733 * with '-' being the XLFD field separator.
735 for (i = 0, np = file; np < dot; np++, i++)
736 buffer2[i] = (*np != '-') ? *np : '_';
739 font->name = bdf_make_xlfd_name(font, "Unknown", buffer2);
740 bdf_update_properties_from_name(font);
743 * Now set up a file name.
745 sprintf(buffer1, "%.*s.bdf", (int) (dot - file), file);
748 * Delete the file and path names so they can be updated.
755 ed->file = strdup(buffer1);
756 ed->path = strdup(dir);
759 * Update the window title.
761 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ed->file);
762 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
765 * Tell the glyphtest widget to remove references to the current font if
766 * it has any, and redraw.
769 glyphtest_remove_font(GLYPHTEST(glyphtest),
770 fontgrid_get_font(FONTGRID(ed->fgrid)));
772 fontgrid_set_font(FONTGRID(ed->fgrid), font, -1);
775 * Indicate the font was imported.
780 * Finally, update the font name field.
782 gtk_entry_set_text(GTK_ENTRY(ed->fontname),
783 fontgrid_get_font_name(FONTGRID(ed->fgrid)));
786 /**************************************************************************
790 **************************************************************************/
793 * Toggles the "Ok" button on or off depending if there was a selection or
797 fnt_check_load_button(GtkWidget *w, gpointer data)
799 GtkTreeSelection *sel = GTK_TREE_SELECTION(data);
801 if (gtk_tree_selection_count_selected_rows(sel) == 0)
802 gtk_widget_set_sensitive(fnt_load_button, FALSE);
804 gtk_widget_set_sensitive(fnt_load_button, TRUE);
808 fnt_unselect_all(GtkWidget *w, gpointer data)
810 GtkTreeSelection *sel = GTK_TREE_SELECTION(data);
812 gtk_tree_selection_unselect_all(sel);
815 * Disable the Ok button since everything is unselected.
817 gtk_widget_set_sensitive(fnt_load_button, FALSE);
821 fnt_select_all(GtkWidget *w, gpointer data)
823 GtkTreeSelection *sel = GTK_TREE_SELECTION(data);
825 gtk_tree_selection_select_all(sel);
828 * Enable the Ok button since everything is unselected.
830 gtk_widget_set_sensitive(fnt_load_button, TRUE);
834 fnt_foreach_selected(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
839 id = gtk_tree_path_get_indices(path);
840 fnt_selected[fnt_selected_count++] = *id;
844 fnt_load_selected_fonts(GtkWidget *w, gpointer data)
846 gbdfed_editor_t *ep, *ed = editors + GPOINTER_TO_UINT(data);
847 GtkTreeSelection *sel =
848 gtk_tree_view_get_selection(GTK_TREE_VIEW(fnt_font_list));
852 _bdffnt_callback_data_t *cdata;
854 fnt_selected_count = 0;
856 if ((cdata = g_object_get_data(G_OBJECT(w),
857 "bdffnt_callback_data")) == NULL) {
859 * Big problem. Should never happen.
861 guiutil_error_message(editors[0].shell,
862 "BIG PROBLEM PASSING OPEN FON/FNT FONT!!!!");
867 * This collects all the selected indices from the list and puts them in
868 * the global fnt_selected array.
870 gtk_tree_selection_selected_foreach(sel, fnt_foreach_selected, NULL);
875 if (fnt_selected_count == 0)
879 * Hide the dialog that allowed selection of the fonts in the file.
881 gtk_widget_hide(fnt_dialog);
883 guiutil_busy_cursor(ed->shell, TRUE);
884 guiutil_busy_cursor(ed->open_dialog, TRUE);
886 fonts = (bdf_font_t **)
887 g_malloc(sizeof(bdf_font_t *) * fnt_selected_count);
888 for (loaded = TRUE, nfonts = 0;
889 nfonts < fnt_selected_count && loaded == TRUE;
892 * If the current font can't be loaded, then assume the rest are
893 * not available either.
895 if (bdffnt_load_font(cdata->font, fnt_selected[nfonts],
896 0, 0, &fonts[nfonts]) != 0) {
898 * It is easier to get the font name from the font than it is
899 * from the list store.
901 (void) bdffnt_get_facename(cdata->font, fnt_selected[nfonts], 0,
902 (unsigned char *) buffer1);
903 sprintf(buffer2, "Import Font: Unable to load %s from %s.",
904 buffer1, cdata->file);
905 guiutil_error_message(ed->shell, buffer2);
907 guiutil_busy_cursor(ed->shell, FALSE);
908 guiutil_busy_cursor(ed->open_dialog, FALSE);
914 guiutil_busy_cursor(ed->shell, FALSE);
915 guiutil_busy_cursor(ed->open_dialog, FALSE);
918 * If no fonts were loaded, then simply return with the open dialog still
919 * up, giving the user a chance to load another font.
927 * Hide the open dialog.
929 gtk_widget_hide(ed->open_dialog);
932 * Create the editors for the fonts that did get loaded.
934 for (i = 0; i < nfonts; i++) {
936 ep = editors + gbdfed_make_editor(0, FALSE);
941 * Erase the existing file and directory name in the "root"
948 ep->file = ep->path = 0;
951 * Tell the glyphtest widget to remove references to the current
952 * font, if it has any, and redraw.
955 glyphtest_remove_font(GLYPHTEST(glyphtest),
956 fontgrid_get_font(FONTGRID(ep->fgrid)));
960 * Make the BDF file name for the font.
962 sprintf(buffer1, "%.*s%d.bdf", (int) (cdata->dot - cdata->file),
963 cdata->file, fonts[i]->point_size);
965 ep->file = strdup(buffer1);
966 ep->path = strdup(cdata->dir);
969 * Set the new editor title.
971 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ep->file);
972 gtk_window_set_title(GTK_WINDOW(ep->shell), buffer1);
975 * Change the font in the editor.
977 fontgrid_set_font(FONTGRID(ep->fgrid), fonts[i], -1);
980 * Indicate the font was imported.
985 * Update the XLFD name.
987 gtk_entry_set_text(GTK_ENTRY(ep->fontname),
988 fontgrid_get_font_name(FONTGRID(ep->fgrid)));
993 bdffnt_close_font(cdata->font);
999 fnt_cancel(GtkWidget *w, gpointer data)
1001 _bdffnt_callback_data_t *cdata;
1004 * If the load callback stole the data already, this will be NULL.
1006 if ((cdata = g_object_get_data(G_OBJECT(w),
1007 "bdffnt_callback_data")) == NULL) {
1009 * Big problem. Should never happen.
1011 guiutil_error_message(editors[0].shell,
1012 "BIG PROBLEM PASSING OPEN FON/FNT FONT!!!!");
1016 g_free(cdata->file);
1018 bdffnt_close_font(cdata->font);
1020 gtk_widget_hide(fnt_dialog);
1024 fnt_row_activate(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col,
1027 fnt_load_selected_fonts(GTK_WIDGET(view), data);
1031 load_windows_font(gbdfed_editor_t *ed, gchar *fullpath, gchar *dot,
1032 gchar *dir, gchar *file)
1037 _bdffnt_callback_data_t *cdata;
1038 GtkWidget *button, *vbox, *hbox, *swin;
1039 GtkListStore *store;
1040 GtkTreeViewColumn *column;
1041 GtkCellRenderer *cell_renderer;
1042 GtkTreeSelection *sel;
1046 if (bdffnt_open_font(fullpath, &fnt) <= 0) {
1047 sprintf(buffer1, "Import Font: Unable to open %s.", file);
1048 guiutil_error_message(ed->shell, buffer1);
1053 nfonts = bdffnt_font_count(fnt);
1056 guiutil_busy_cursor(ed->shell, TRUE);
1057 guiutil_busy_cursor(ed->open_dialog, TRUE);
1059 if (bdffnt_load_font(fnt, 0, 0, 0, &font) != 0) {
1060 sprintf(buffer1, "Import Font: Unable to load %s.", file);
1061 guiutil_error_message(ed->shell, buffer1);
1064 guiutil_busy_cursor(ed->shell, FALSE);
1065 guiutil_busy_cursor(ed->open_dialog, FALSE);
1070 guiutil_busy_cursor(ed->shell, FALSE);
1071 guiutil_busy_cursor(ed->open_dialog, FALSE);
1073 gtk_widget_hide(ed->open_dialog);
1076 * Now set up a file name.
1078 sprintf(buffer1, "%.*s.bdf", (int) (dot - file), file);
1081 * Delete the file and path names so they can be updated.
1088 ed->file = strdup(buffer1);
1089 ed->path = strdup(dir);
1092 * Update the window title.
1094 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ed->file);
1095 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
1098 * Tell the glyphtest widget to remove references to the current font
1099 * if it has any, and redraw.
1102 glyphtest_remove_font(GLYPHTEST(glyphtest),
1103 fontgrid_get_font(FONTGRID(ed->fgrid)));
1105 fontgrid_set_font(FONTGRID(ed->fgrid), font, -1);
1108 * Indicate the font was imported.
1110 ed->imported = TRUE;
1113 * Finally, update the font name field.
1115 gtk_entry_set_text(GTK_ENTRY(ed->fontname),
1116 fontgrid_get_font_name(FONTGRID(ed->fgrid)));
1121 * More than one font was found. Present the dialog to choose the fonts.
1123 if (fnt_dialog == 0) {
1125 * Create a structure that will hold data needed by a couple callback
1128 cdata = g_malloc(sizeof(_bdffnt_callback_data_t));
1129 cdata->file = strdup(file);
1130 cdata->dir = strdup(dir);
1131 cdata->dot = cdata->file + (dot - file);
1134 fnt_dialog = gtk_dialog_new();
1135 gtk_window_set_title(GTK_WINDOW(fnt_dialog), "Windows Font Selection");
1137 g_object_set_data(G_OBJECT(fnt_dialog), "bdffnt_callback_data",
1140 (void) g_signal_connect(G_OBJECT(fnt_dialog), "delete_event",
1141 G_CALLBACK(fnt_cancel), 0);
1143 vbox = GTK_DIALOG(fnt_dialog)->vbox;
1144 hbox = GTK_DIALOG(fnt_dialog)->action_area;
1146 swin = gtk_scrolled_window_new(0, 0);
1147 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
1148 GTK_POLICY_AUTOMATIC,
1151 store = gtk_list_store_new(1, G_TYPE_STRING);
1152 fnt_font_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1153 g_object_unref(store);
1155 g_object_set_data(G_OBJECT(fnt_font_list), "bdffnt_callback_data",
1158 gtk_widget_set_size_request(fnt_font_list, -1, 160);
1160 cell_renderer = gtk_cell_renderer_text_new();
1161 column = gtk_tree_view_column_new_with_attributes("Fonts: 0",
1166 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
1167 gtk_tree_view_append_column(GTK_TREE_VIEW(fnt_font_list), column);
1168 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(fnt_font_list));
1170 (void) g_signal_connect(G_OBJECT(sel), "changed",
1171 G_CALLBACK(fnt_check_load_button),
1174 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE);
1176 (void) g_signal_connect(G_OBJECT(fnt_font_list), "row_activated",
1177 G_CALLBACK(fnt_row_activate),
1178 GUINT_TO_POINTER(ed->id));
1180 gtk_container_add(GTK_CONTAINER(swin), fnt_font_list);
1182 gtk_box_pack_start(GTK_BOX(vbox), swin, FALSE, FALSE, 0);
1184 button = gtk_button_new_with_label("Select All");
1186 (void) g_signal_connect(G_OBJECT(button), "clicked",
1187 G_CALLBACK(fnt_select_all),
1190 gtk_container_add(GTK_CONTAINER(hbox), button);
1192 button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
1194 (void) g_signal_connect(G_OBJECT(button), "clicked",
1195 G_CALLBACK(fnt_unselect_all),
1198 gtk_container_add(GTK_CONTAINER(hbox), button);
1200 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
1202 (void) g_signal_connect(G_OBJECT(button), "clicked",
1203 G_CALLBACK(fnt_cancel),
1204 GUINT_TO_POINTER(ed->id));
1206 gtk_container_add(GTK_CONTAINER(hbox), button);
1208 fnt_load_button = gtk_button_new_from_stock(GTK_STOCK_OK);
1211 * Here we store a bunch of data to the buttons that are necessary to
1212 * load FON/FNT fonts in the callback.
1214 g_object_set_data(G_OBJECT(fnt_load_button), "bdffnt_callback_data",
1216 g_object_set_data(G_OBJECT(button), "bdffnt_callback_data",
1219 (void) g_signal_connect(G_OBJECT(fnt_load_button), "clicked",
1220 G_CALLBACK(fnt_load_selected_fonts),
1221 GUINT_TO_POINTER(ed->id));
1223 gtk_container_add(GTK_CONTAINER(hbox), fnt_load_button);
1225 gtk_widget_show_all(vbox);
1226 gtk_widget_show_all(hbox);
1229 * Fill the CDATA item in with the latest info.
1231 cdata = g_object_get_data(G_OBJECT(fnt_load_button),
1232 "bdffnt_callback_data");
1233 cdata->file = strdup(file);
1234 cdata->dir = strdup(dir);
1235 cdata->dot = cdata->file + (dot - file);
1240 GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(fnt_font_list)));
1241 column = gtk_tree_view_get_column(GTK_TREE_VIEW(fnt_font_list), 0);
1242 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(fnt_font_list));
1245 * Set the number of fonts.
1247 sprintf(buffer1, "Fonts: %d", nfonts);
1248 gtk_tree_view_column_set_title(column, buffer1);
1251 * Clear the list and add the font names.
1253 gtk_list_store_clear(store);
1254 for (i = 0; i < nfonts; i++) {
1255 (void) bdffnt_get_facename(fnt, i, 0, (unsigned char *) buffer1);
1256 gtk_list_store_append(store, &iter);
1257 gtk_list_store_set(store, &iter, 0, buffer1, -1);
1261 * Force the first one to be selected by default.
1263 tpath = gtk_tree_path_new_from_indices(0, -1);
1264 gtk_tree_selection_select_path(sel, tpath);
1267 * Show the dialog and wait until the selection is done.
1269 guiutil_show_dialog_centered(fnt_dialog, ed->shell);
1272 * Force the user to interact with this dialog before doing anything else.
1274 gtk_window_set_modal(GTK_WINDOW(fnt_dialog), TRUE);
1277 /**************************************************************************
1281 **************************************************************************/
1283 #ifdef HAVE_FREETYPE
1286 choose_otf_encoding(GtkTreeSelection *selection, gpointer data)
1289 GtkTreeModel *model;
1294 * Get the row of the current selection.
1296 if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)
1298 tpath = gtk_tree_model_get_path(model, &iter);
1299 rows = gtk_tree_path_get_indices(tpath);
1300 otf_eid_pos = (gint16) rows[0];
1304 choose_otf_platform(GtkTreeSelection *selection, gpointer data)
1307 gint i, ncmaps, sel, *rows;
1308 gint16 pid, eid, lasteid;
1309 GtkTreeModel *model;
1310 GtkListStore *store;
1316 * Get the row of the current selection.
1318 if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)
1320 tpath = gtk_tree_model_get_path(model, &iter);
1321 rows = gtk_tree_path_get_indices(tpath);
1322 otf_pid_pos = (gint16) rows[0];
1325 * Clear the encoding list.
1327 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(otf_encodings)));
1328 gtk_list_store_clear(store);
1331 * Collect the list of encoding IDs and put their names in the encoding
1335 ncmaps = face->num_charmaps;
1336 for (lasteid = -1, sel = i = 0; i < ncmaps; i++) {
1337 pid = face->charmaps[i]->platform_id;
1338 eid = face->charmaps[i]->encoding_id;
1339 if (pid == platforms[otf_pid_pos] && eid != lasteid) {
1340 name = bdfotf_encoding_name(pid, eid);
1341 if (strcmp(name, "ISO10646") == 0)
1343 gtk_list_store_append(store, &iter);
1344 gtk_list_store_set(store, &iter, 0, name, -1);
1345 encodings[nencodings++] = eid;
1351 * Default the selection to the ISO10646 encoding.
1353 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(otf_encodings));
1354 tpath = gtk_tree_path_new_from_indices(sel, -1);
1355 gtk_tree_selection_select_path(selection, tpath);
1358 * Make sure the encoding is made visible.
1360 tview = gtk_tree_selection_get_tree_view(selection);
1361 gtk_tree_view_scroll_to_cell(tview, tpath, NULL, TRUE, 0.5, 0.5);
1365 choose_otf(GtkTreeSelection *selection, gpointer data)
1368 gint i, ncmaps, sel, row, *rows;
1369 gint16 pid, eid, lastpid;
1370 GtkTreeModel *model;
1371 GtkListStore *store;
1378 * This is called after the list is cleared as well, so return if there is
1381 if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)
1385 * Get the name of the face currently selected and it's index. This is
1386 * way more complicated than it should be.
1388 (void) memset((char *) &val, 0, sizeof(GValue));
1389 tpath = gtk_tree_model_get_path(model, &iter);
1390 rows = gtk_tree_path_get_indices(tpath);
1394 * Clear the platform list before trying to open the new face.
1396 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(otf_platforms)));
1397 gtk_list_store_clear(store);
1399 if (otf_collection) {
1402 if (FT_New_Face(library, otf_fullpath, row, &face)) {
1403 otf_face_open = FALSE;
1404 gtk_tree_selection_get_selected(selection, &model, &iter);
1405 gtk_tree_model_get_value(model, &iter, 0, &val);
1406 name = (gchar *) g_value_get_string(&val);
1408 "Import Font: Unable to open OpenType collection %s.",
1410 g_value_unset(&val);
1411 guiutil_error_message(active_editor->shell, buffer1);
1414 otf_face_open = TRUE;
1418 * Collect the list of platform IDs and put their names in the platform
1422 ncmaps = face->num_charmaps;
1423 for (lastpid = -1, sel = i = 0; i < ncmaps; i++) {
1424 pid = face->charmaps[i]->platform_id;
1425 eid = face->charmaps[i]->encoding_id;
1426 if (pid != lastpid) {
1428 * Add the platform name to the list. If the name happens to be
1429 * Microsoft, select it as the default.
1431 name = bdfotf_platform_name(pid);
1432 if (strcmp(name, "Microsoft") == 0)
1434 gtk_list_store_append(store, &iter);
1435 gtk_list_store_set(store, &iter, 0, name, -1);
1436 platforms[nplatforms++] = pid;
1442 * Select the default platform, which is hard-coded to be Microsoft at the
1445 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(otf_platforms));
1446 tpath = gtk_tree_path_new_from_indices(sel, -1);
1447 gtk_tree_selection_select_path(selection, tpath);
1450 * Make sure the platform is made visible.
1452 tview = gtk_tree_selection_get_tree_view(selection);
1453 gtk_tree_view_scroll_to_cell(tview, tpath, NULL, TRUE, 0.5, 0.5);
1457 otf_dialog_done(GtkWidget *w, gpointer data)
1459 otf_select_done = GPOINTER_TO_INT(data);
1460 gtk_widget_hide(otf_dialog);
1464 otf_reset_metrics(GtkWidget *w, gpointer data)
1466 gtk_spin_button_set_value(GTK_SPIN_BUTTON(otf_point_size),
1467 (gfloat) options.font_opts.point_size);
1468 gtk_spin_button_set_value(GTK_SPIN_BUTTON(otf_hres),
1469 (gfloat) options.font_opts.resolution_x);
1470 gtk_spin_button_set_value(GTK_SPIN_BUTTON(otf_vres),
1471 (gfloat) options.font_opts.resolution_y);
1475 * Synchronize the vertical resolution with the horizontal resolution.
1478 otf_sync_res(GtkWidget *w, GdkEventFocus *ev, gpointer data)
1483 b = GTK_SPIN_BUTTON(data);
1484 v = (gfloat) gtk_spin_button_get_value(b);
1486 if (v != (gfloat) gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)))
1487 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v);
1491 make_otf_import_dialog(void)
1493 GtkWidget *label, *vbox, *hbox, *button, *table, *swin;
1495 GtkListStore *store;
1496 GtkTreeViewColumn *column;
1497 GtkCellRenderer *cell_renderer;
1498 GtkTreeSelection *sel;
1501 otf_dialog = gtk_dialog_new();
1502 gtk_window_set_title(GTK_WINDOW(otf_dialog), "OpenType Selection");
1504 (void) g_signal_connect(G_OBJECT(otf_dialog), "delete_event",
1505 G_CALLBACK(gtk_widget_hide), 0);
1507 vbox = GTK_DIALOG(otf_dialog)->vbox;
1509 swin = gtk_scrolled_window_new(0, 0);
1510 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
1511 GTK_POLICY_AUTOMATIC,
1514 store = gtk_list_store_new(1, G_TYPE_STRING);
1515 otf_faces = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1516 g_object_unref(store);
1518 cell_renderer = gtk_cell_renderer_text_new();
1519 column = gtk_tree_view_column_new_with_attributes ("Faces",
1524 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
1525 gtk_tree_view_append_column (GTK_TREE_VIEW(otf_faces), column);
1527 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(otf_faces));
1528 gtk_tree_selection_set_mode(sel, GTK_SELECTION_BROWSE);
1530 (void) g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(choose_otf),
1534 * Set the size of the list explicitly to make enough space for
1535 * approximately five entries.
1537 gtk_widget_set_size_request(otf_faces, -1, 100);
1539 gtk_container_add(GTK_CONTAINER(swin), otf_faces);
1541 gtk_box_pack_start(GTK_BOX(vbox), swin, TRUE, TRUE, 0);
1544 * Create a table to hold the other two lists.
1546 table = gtk_table_new(1, 2, TRUE);
1548 swin = gtk_scrolled_window_new(0, 0);
1549 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
1550 GTK_POLICY_AUTOMATIC,
1553 store = gtk_list_store_new(1, G_TYPE_STRING);
1554 otf_platforms = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1555 g_object_unref(store);
1557 cell_renderer = gtk_cell_renderer_text_new();
1558 column = gtk_tree_view_column_new_with_attributes("Platforms",
1563 gtk_widget_set_size_request(otf_platforms, 200, 70);
1565 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
1566 gtk_tree_view_append_column(GTK_TREE_VIEW(otf_platforms), column);
1568 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(otf_platforms));
1569 gtk_tree_selection_set_mode(sel, GTK_SELECTION_BROWSE);
1571 (void) g_signal_connect(G_OBJECT(sel), "changed",
1572 G_CALLBACK(choose_otf_platform), NULL);
1574 gtk_container_add(GTK_CONTAINER(swin), otf_platforms);
1577 * Attach the platform list to the table.
1579 gtk_table_attach(GTK_TABLE(table), swin, 0, 1, 0, 1,
1580 GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
1582 swin = gtk_scrolled_window_new(0, 0);
1583 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
1584 GTK_POLICY_AUTOMATIC,
1587 store = gtk_list_store_new(1, G_TYPE_STRING);
1588 otf_encodings = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1589 g_object_unref(store);
1591 cell_renderer = gtk_cell_renderer_text_new();
1592 column = gtk_tree_view_column_new_with_attributes("Encodings",
1597 gtk_widget_set_size_request(otf_encodings, 200, 70);
1599 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
1600 gtk_tree_view_append_column(GTK_TREE_VIEW(otf_encodings), column);
1602 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(otf_encodings));
1603 gtk_tree_selection_set_mode(sel, GTK_SELECTION_BROWSE);
1605 (void) g_signal_connect(G_OBJECT(sel), "changed",
1606 G_CALLBACK(choose_otf_encoding), NULL);
1608 gtk_container_add(GTK_CONTAINER(swin), otf_encodings);
1611 * Attach the encodings list to the table.
1613 gtk_table_attach(GTK_TABLE(table), swin, 1, 2, 0, 1,
1614 GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
1616 gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
1619 * Make a table that will contain the point size and resolution
1622 table = gtk_table_new(3, 3, FALSE);
1625 * Make the spin button labels.
1627 label = gtk_label_new("Point Size:");
1628 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1629 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL,
1631 label = gtk_label_new("Horizontal Resolution:");
1632 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1633 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL,
1635 label = gtk_label_new("Vertical Resolution:");
1636 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1637 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL,
1641 * Make the spin buttons.
1643 adj = (GtkAdjustment *) gtk_adjustment_new(0.0, 4.0, 256.0, 1.0, 2.0, 0.0);
1644 otf_point_size = gtk_spin_button_new(adj, 1.0, 0);
1645 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(otf_point_size), TRUE);
1646 gtk_widget_set_size_request(otf_point_size, 100, -1);
1647 gtk_spin_button_set_value(GTK_SPIN_BUTTON(otf_point_size),
1648 (gfloat) options.font_opts.point_size);
1649 gtk_table_attach(GTK_TABLE(table), otf_point_size, 1, 2, 0, 1,
1650 GTK_FILL, GTK_FILL, 5, 5);
1652 adj = (GtkAdjustment *) gtk_adjustment_new(0.0, 72.0, 1200.0,
1654 otf_hres = gtk_spin_button_new(adj, 1.0, 0);
1655 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(otf_hres), TRUE);
1656 gtk_widget_set_size_request(otf_hres, 100, -1);
1657 gtk_spin_button_set_value(GTK_SPIN_BUTTON(otf_hres),
1658 (gfloat) options.font_opts.resolution_x);
1659 gtk_table_attach(GTK_TABLE(table), otf_hres, 1, 2, 1, 2,
1660 GTK_FILL, GTK_FILL, 5, 5);
1662 adj = (GtkAdjustment *) gtk_adjustment_new(0.0, 72.0, 1200.0,
1664 otf_vres = gtk_spin_button_new(adj, 1.0, 0);
1665 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(otf_vres), TRUE);
1666 gtk_widget_set_size_request(otf_vres, 100, -1);
1667 gtk_spin_button_set_value(GTK_SPIN_BUTTON(otf_vres),
1668 (gfloat) options.font_opts.resolution_y);
1669 (void) g_signal_connect(G_OBJECT(otf_vres), "focus-in-event",
1670 G_CALLBACK(otf_sync_res),
1671 (gpointer) otf_hres);
1672 (void) g_signal_connect(G_OBJECT(otf_hres), "focus-in-event",
1673 G_CALLBACK(otf_sync_res),
1674 (gpointer) otf_vres);
1675 gtk_table_attach(GTK_TABLE(table), otf_vres, 1, 2, 2, 3,
1676 GTK_FILL, GTK_FILL, 5, 5);
1679 * Make the reset button.
1681 label = gtk_button_new_with_label("Reset");
1682 (void) g_signal_connect(G_OBJECT(label), "clicked",
1683 G_CALLBACK(otf_reset_metrics), 0);
1684 gtk_table_attach(GTK_TABLE(table), label, 2, 3, 1, 2, GTK_FILL, GTK_FILL,
1688 * Do some fiddling to adjust the focus chain so the Reset button is at
1689 * the end instead of in the middle.
1691 fchain = g_list_append(NULL, (gpointer) otf_point_size);
1692 fchain = g_list_append(fchain, (gpointer) otf_hres);
1693 fchain = g_list_append(fchain, (gpointer) otf_vres);
1694 fchain = g_list_append(fchain, (gpointer) label);
1695 gtk_container_set_focus_chain(GTK_CONTAINER(table), fchain);
1696 g_list_free(fchain);
1698 gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, FALSE, 10);
1701 * Add the buttons at the bottom of the dialog.
1703 hbox = GTK_DIALOG(otf_dialog)->action_area;
1705 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
1706 gtk_container_add(GTK_CONTAINER(hbox), button);
1707 (void) g_signal_connect(G_OBJECT(button), "clicked",
1708 G_CALLBACK(otf_dialog_done),
1709 GINT_TO_POINTER(-1));
1710 button = gtk_button_new_from_stock(GTK_STOCK_OK);
1711 gtk_container_add(GTK_CONTAINER(hbox), button);
1712 (void) g_signal_connect(G_OBJECT(button), "clicked",
1713 G_CALLBACK(otf_dialog_done),
1714 GINT_TO_POINTER(1));
1716 gtk_widget_show_all(vbox);
1717 gtk_widget_show_all(hbox);
1721 load_otf_font(gbdfed_editor_t *ed, gchar *fullpath, gchar *dot,
1722 gchar *dir, gchar *file)
1725 gint32 psize, hres, vres;
1728 bdf_property_t prop;
1729 GtkListStore *store;
1733 otf_fullpath = fullpath;
1736 * Determine if this is an OT collection or just a normal font.
1738 np = dot + strlen(dot) - 1;
1739 otf_collection = (*np == 'c' || *np == 'C') ? TRUE : FALSE;
1742 * Initialize the FreeType engine once.
1745 if (FT_Init_FreeType(&library) != 0) {
1747 "Import Font: Unable to initialize the FreeType engine.");
1748 guiutil_error_message(ed->shell, buffer1);
1755 * Attempt to open the font or collection.
1757 if (FT_New_Face(library, fullpath, 0, &face)) {
1758 if (!otf_collection)
1759 sprintf(buffer1, "Import Font: Unable to open OpenType font '%s'.",
1763 "Import Font: Unable to open OpenType collection '%s'.",
1765 guiutil_error_message(ed->shell, buffer1);
1770 * Construct the dialog that will display various choices that will be
1771 * needed when loading the font.
1773 if (otf_dialog == 0)
1774 make_otf_import_dialog();
1777 * Clear the lists and reset the values.
1779 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(otf_faces)));
1780 gtk_list_store_clear(store);
1782 otf_face_open = TRUE;
1783 otf_collection = face->num_faces;
1786 if (otf_collection == 1) {
1787 if (bdfotf_get_english_string(face, BDFOTF_FULLNAME_STRING,
1789 (void) strcpy(buffer1, "Unknown");
1790 gtk_list_store_append(store, &iter);
1791 gtk_list_store_set(store, &iter, 0, buffer1, -1);
1793 otf_face_open = FALSE;
1795 for (i = 0; i < otf_collection; i++) {
1796 if (!FT_New_Face(library, fullpath, i, &face)) {
1797 if (bdfotf_get_english_string(face, BDFOTF_FULLNAME_STRING,
1799 sprintf(buffer1, "Unknown%d", i);
1801 gtk_list_store_append(store, &iter);
1802 gtk_list_store_set(store, &iter, 0, buffer1, -1);
1809 guiutil_show_dialog_centered(otf_dialog, ed->shell);
1812 * Force the user to interact with this dialog before doing anything else.
1814 gtk_window_set_modal(GTK_WINDOW(otf_dialog), TRUE);
1816 otf_select_done = 0;
1817 while (otf_select_done == 0)
1818 gtk_main_iteration();
1821 * Reinitialize various globals when we are done.
1826 if (otf_select_done < 0) {
1829 otf_face_open = FALSE;
1834 * Get the requested point size and resolutions.
1837 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(otf_point_size));
1839 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(otf_hres));
1841 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(otf_vres));
1843 guiutil_busy_cursor(ed->shell, TRUE);
1844 guiutil_busy_cursor(ed->open_dialog, TRUE);
1847 * Actually store the resolution and point size to the options so they
1848 * will be used for other imports. The setup dialog will unfortunately
1849 * assume this are the default values. May fix later so setup knows the
1852 options.font_opts.point_size = psize;
1853 options.font_opts.resolution_x = hres;
1854 options.font_opts.resolution_y = vres;
1857 * Actually load the font.
1859 res = bdfotf_load_font(face, platforms[otf_pid_pos],
1860 encodings[otf_eid_pos], &options.font_opts,
1863 guiutil_busy_cursor(ed->shell, FALSE);
1864 guiutil_busy_cursor(ed->open_dialog, FALSE);
1867 otf_face_open = FALSE;
1871 * Make an error message.
1873 sprintf(buffer1, "Import Font: Unable to load OpenType font %s.",
1875 guiutil_error_message(ed->shell, buffer1);
1880 * Hide the open dialog.
1882 gtk_widget_hide(ed->open_dialog);
1885 * Add the _OTF_FONTFILE property using the original filename.
1887 prop.name = "_OTF_FONTFILE";
1888 prop.format = BDF_ATOM;
1889 prop.value.atom = file;
1890 bdf_add_font_property(font, &prop);
1893 * Now set up a file name.
1895 sprintf(buffer1, "%.*s.bdf", dot - file, file);
1898 * Delete the file and path names so they can be updated.
1905 ed->file = strdup(buffer1);
1906 ed->path = strdup(dir);
1909 * Update the window title.
1911 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ed->file);
1912 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
1915 * Tell the glyphtest widget to remove references to
1916 * the current font if it has any, and redraw.
1919 glyphtest_remove_font(GLYPHTEST(glyphtest),
1920 fontgrid_get_font(FONTGRID(ed->fgrid)));
1922 fontgrid_set_font(FONTGRID(ed->fgrid), font, -1);
1925 * Indicate the font was imported.
1927 ed->imported = TRUE;
1930 * Finally, update the font name field.
1932 gtk_entry_set_text(GTK_ENTRY(ed->fontname),
1933 fontgrid_get_font_name(FONTGRID(ed->fgrid)));
1936 #endif /* HAVE_FREETYPE */
1940 /**************************************************************************
1944 **************************************************************************/
1947 load_hbf_font(gbdfed_editor_t *ed, gchar *fullpath, gchar *dot,
1948 gchar *dir, gchar *file)
1952 guiutil_busy_cursor(ed->shell, TRUE);
1953 guiutil_busy_cursor(ed->open_dialog, TRUE);
1955 font = bdf_load_hbf_font(fullpath, &options.font_opts, 0, 0);
1957 guiutil_busy_cursor(ed->shell, FALSE);
1958 guiutil_busy_cursor(ed->open_dialog, FALSE);
1961 * Check to see if the file can be opened.
1965 sprintf(buffer1, "Import Font: Unable to import %s.", file);
1966 guiutil_error_message(ed->shell, buffer1);
1970 gtk_widget_hide(ed->open_dialog);
1973 * Now set up a file name.
1975 sprintf(buffer1, "%.*s.bdf", (int) (dot - file), file);
1978 * Delete the file and path names so they can be updated.
1985 ed->file = strdup(buffer1);
1989 * Update the window title.
1991 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ed->file);
1992 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
1995 * Tell the glyphtest widget to remove references to
1996 * the current font if it has any, and redraw.
1999 glyphtest_remove_font(GLYPHTEST(glyphtest),
2000 fontgrid_get_font(FONTGRID(ed->fgrid)));
2002 fontgrid_set_font(FONTGRID(ed->fgrid), font, -1);
2005 * Indicate the font was imported.
2007 ed->imported = TRUE;
2010 * Finally, update the font name field.
2012 gtk_entry_set_text(GTK_ENTRY(ed->fontname),
2013 fontgrid_get_font_name(FONTGRID(ed->fgrid)));
2019 * This routine actually does the work of opening the font.
2022 really_open_font(guint ed_id)
2024 gbdfed_editor_t *ed = editors + ed_id;
2025 gchar *filename, *path, *file, *dot;
2027 #if (GTK_MAJOR_VERSION >= 2 && GTK_MINOR_VERSION >= 10)
2028 GtkRecentManager *recent;
2031 fs = GTK_FILE_CHOOSER(ed->open_dialog);
2032 filename = gtk_file_chooser_get_filename(fs);
2035 * Split the filename into path and file, locate the extension position in
2036 * the file name, and make a version of the name with no '-' characters
2037 * which are field separators in XLFD font names.
2039 file = g_path_get_basename(filename);
2040 path = g_path_get_dirname(filename);
2041 if ((dot = strrchr(file, '.')) == 0)
2042 dot = file + strlen(file);
2045 * If the last character of the filename is a slash, no file name was
2048 if (filename[strlen(filename) - 1] == G_DIR_SEPARATOR) {
2049 guiutil_error_message(ed->shell,
2050 "Import Font: No file name provided.");
2059 #if (GTK_MAJOR_VERSION >= 2 && GTK_MINOR_VERSION >= 10)
2060 recent = gtk_recent_manager_get_default();
2061 sprintf(buffer1, "file://%s", filename);
2062 if (gtk_recent_manager_has_item(recent,
2063 (const gchar *) buffer1) == FALSE)
2064 gtk_recent_manager_add_item(recent,
2065 (const gchar *) buffer1);
2068 switch (ed->import_format) {
2070 load_bdf_font(ed, (const gchar *) filename, (const gchar *) path,
2071 (const gchar *) file);
2073 case CONSOLE_FORMAT:
2074 load_console_font(ed, filename, dot, path, file);
2077 load_pkgf_font(ed, filename, dot, path, file);
2080 load_windows_font(ed, filename, dot, path, file);
2084 load_hbf_font(ed, filename, dot, path, file);
2087 #ifdef HAVE_FREETYPE
2089 load_otf_font(ed, filename, dot, path, file);
2091 #endif /* HAVE_FREETYPE */
2102 * In case the editor list changed, set the pointer to the editor again.
2104 ed = editors + ed_id;
2107 * Force the editor's info to be updated for the new font. This causes
2108 * it to change if it is already visible.
2110 guiedit_update_font_info(ed);
2114 make_file_dialog_title(guint type, gboolean save)
2119 case BDF_FORMAT: title = "BDF"; break;
2120 case CONSOLE_FORMAT: title = "Console"; break;
2121 case PKGF_FORMAT: title = "PK/GF"; break;
2122 case FNT_FORMAT: title = "Windows"; break;
2124 case HBF_FORMAT: title = "HBF"; break;
2126 case OTF_FORMAT: title = "TrueType"; break;
2127 case PSF_FORMAT: title = "PSF"; break;
2128 case HEX_FORMAT: title = "HEX"; break;
2129 case HEADER_FORMAT: title = "HEADER"; break;
2133 if (type == BDF_FORMAT)
2134 sprintf(buffer1, "Save %s Font", title);
2136 sprintf(buffer1, "Export %s Font", title);
2138 sprintf(buffer1, "Open %s Font", title);
2144 handle_open_response(GtkDialog *d, gint response, gpointer data)
2147 case GTK_RESPONSE_ACCEPT:
2148 really_open_font(GPOINTER_TO_UINT(data));
2150 case GTK_RESPONSE_CANCEL:
2151 gtk_widget_hide(GTK_WIDGET(d));
2157 update_open_dialog(gbdfed_editor_t *ed, guint type)
2161 if (ed->open_dialog == 0) {
2163 * Create the file chooser filters if they haven't already been
2166 make_file_chooser_filters();
2169 gtk_file_chooser_dialog_new(make_file_dialog_title(type, FALSE),
2170 GTK_WINDOW(ed->shell),
2171 GTK_FILE_CHOOSER_ACTION_OPEN,
2172 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
2173 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
2176 (void) g_signal_connect(G_OBJECT(ed->open_dialog), "response",
2177 G_CALLBACK(handle_open_response),
2178 GUINT_TO_POINTER(ed->id));
2179 (void) g_signal_connect(G_OBJECT(ed->open_dialog), "delete_event",
2180 G_CALLBACK(gtk_widget_hide), 0);
2181 } else if (ed->import_format != type)
2182 gtk_window_set_title(GTK_WINDOW(ed->open_dialog),
2183 make_file_dialog_title(type, FALSE));
2184 fs = GTK_FILE_CHOOSER(ed->open_dialog);
2187 * Set the file filter.
2189 gtk_file_chooser_set_filter(fs, filename_filters[type]);
2191 ed->import_format = type;
2194 * Set the initial path as a file if it exists. This is necessary to
2195 * force the open to occur in the directory where this font was last
2196 * saved, which might be different than the directory that is currently in
2197 * the open file selection dialog.
2199 if (ed->path != 0 && ed->path[0] == G_DIR_SEPARATOR)
2200 gtk_file_chooser_set_current_folder(fs, ed->path);
2204 hide_save_dialog(GtkWidget *w, gpointer data)
2207 save_dialog_done = TRUE;
2211 set_psf_option(GtkWidget *w, gpointer data)
2215 gchar *fname, *dot, *slash, *suff = 0;
2218 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(w))) {
2220 flags = BDF_PSF_UNIMAP|BDF_PSF_FONT;
2223 flags = BDF_PSF_FONT;
2226 flags = BDF_PSF_UNIMAP;
2230 if (flags == BDF_PSF_UNIMAP)
2232 * Have to change to the .uni suffix.
2235 else if (options.font_opts.psf_flags == BDF_PSF_UNIMAP)
2237 * Have to change back to the .psfu suffix.
2241 options.font_opts.psf_flags = flags;
2245 * Change the suffix on the filename in the entry area.
2247 fs = GTK_FILE_CHOOSER(g_object_get_data(G_OBJECT(w),
2248 "file-selection-dialog"));
2249 fname = gtk_file_chooser_get_filename(fs);
2252 if ((dot = (gchar *) strrchr(fname, '.')) != 0) {
2253 if ((slash = (gchar *) strrchr(fname, G_DIR_SEPARATOR)) == 0)
2255 dotpos = (gint) (dot - slash) - 1;
2258 * Copy the new extension in.
2260 (void) strcpy(dot, suff);
2264 if (*slash == G_DIR_SEPARATOR)
2267 gtk_file_chooser_set_current_name(fs, slash);
2273 handle_save_response(GtkDialog *d, gint response, gpointer data)
2276 case GTK_RESPONSE_ACCEPT:
2277 really_save_font(GPOINTER_TO_UINT(data));
2279 case GTK_RESPONSE_CANCEL:
2280 gtk_widget_hide(GTK_WIDGET(d));
2286 update_save_dialog(gbdfed_editor_t *ed, guint type)
2292 if (ed->save_dialog == 0) {
2294 * Create the file chooser filters if they haven't already been
2297 make_file_chooser_filters();
2300 gtk_file_chooser_dialog_new(make_file_dialog_title(type, TRUE),
2301 GTK_WINDOW(ed->shell),
2302 GTK_FILE_CHOOSER_ACTION_SAVE,
2303 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
2304 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
2307 vbox = GTK_DIALOG(ed->save_dialog)->vbox;
2309 psf_export_options = gtk_combo_box_new_text();
2311 * Since the flags have to be set in the save dialog, attach the
2312 * save dialog to the object so we can set the bits appropriately.
2314 g_object_set_data(G_OBJECT(psf_export_options),
2315 "file-selection-dialog",
2316 (gpointer) ed->save_dialog);
2317 (void) g_signal_connect(G_OBJECT(psf_export_options), "changed",
2318 G_CALLBACK(set_psf_option), 0);
2319 gtk_combo_box_append_text(GTK_COMBO_BOX(psf_export_options),
2320 "Font and Unicode Map");
2321 gtk_combo_box_append_text(GTK_COMBO_BOX(psf_export_options),
2323 gtk_combo_box_append_text(GTK_COMBO_BOX(psf_export_options),
2324 "Unicode Map Only");
2325 gtk_combo_box_set_active(GTK_COMBO_BOX(psf_export_options), 0);
2327 psf_export_frame = labcon_new_label_defaults("PSF Export Options:",
2328 psf_export_options, 0);
2330 (void) g_signal_connect(G_OBJECT(ed->save_dialog), "delete_event",
2331 G_CALLBACK(hide_save_dialog), 0);
2333 (void) g_signal_connect(G_OBJECT(ed->save_dialog), "response",
2334 G_CALLBACK(handle_save_response),
2335 GUINT_TO_POINTER(ed->id));
2337 gtk_widget_show_all(psf_export_frame);
2338 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(ed->save_dialog),
2340 } else if (ed->export_format != type)
2341 gtk_window_set_title(GTK_WINDOW(ed->save_dialog),
2342 make_file_dialog_title(type, TRUE));
2345 * Set the file filter.
2347 gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(ed->save_dialog),
2348 filename_filters[type]);
2351 ed->export_format = type;
2354 * Show or hide the PSF exporting options.
2356 if (type == PSF_FORMAT)
2357 gtk_widget_show(psf_export_frame);
2359 gtk_widget_hide(psf_export_frame);
2362 * Use the current path and filename as the default. This is done in case
2363 * the font was loaded from some directory other than the current default
2364 * in the file selection dialog for saving.
2367 sprintf(buffer1, "%s", ed->file);
2369 sprintf(buffer1, "unnamed%d.bdf", ed->id);
2371 if ((dot = (gchar *) strrchr(buffer1, '.'))) {
2372 if ((slash = (gchar *) strrchr(buffer1, G_DIR_SEPARATOR)) == 0)
2374 dotpos = (gint) (dot - slash) - 1;
2377 * If a PSF or HEX font is being exported, change the extension
2380 if (type == PSF_FORMAT)
2381 (void) strcpy(dot, ".psfu");
2382 else if (type == HEX_FORMAT)
2383 (void) strcpy(dot, ".hex");
2384 else if (type == HEADER_FORMAT)
2385 (void) strcpy(dot, ".h");
2390 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(ed->save_dialog),
2392 if (ed->path != 0 && ed->path[0] == G_DIR_SEPARATOR)
2393 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(ed->save_dialog),
2396 gtk_editable_set_position(GTK_EDITABLE(fs->selection_entry), dotpos);
2397 gtk_editable_select_region(GTK_EDITABLE(fs->selection_entry), 0, dotpos);
2402 guifile_import_bdf_font(GtkWidget *w, gpointer data)
2404 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2406 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2408 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2410 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2411 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2413 * If the current file was imported, then make sure to use the
2414 * Save As... dialog instead of just saving under the name that
2415 * was constructed when importing. The user won't know what the
2416 * default BDF file name of imported fonts look like.
2419 guifile_save_as_wait(w, data);
2421 guifile_save(w, data);
2426 update_open_dialog(ed, BDF_FORMAT);
2428 guiutil_show_dialog_centered(ed->open_dialog, ed->shell);
2432 guifile_import_console_font(GtkWidget *w, gpointer data)
2434 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2436 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2438 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2440 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2441 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2443 * If the current file was imported, then make sure to use the
2444 * Save As... dialog instead of just saving under the name that
2445 * was constructed when importing. The user won't know what the
2446 * default BDF file name of imported fonts look like.
2449 guifile_save_as_wait(w, data);
2451 guifile_save(w, data);
2456 update_open_dialog(ed, CONSOLE_FORMAT);
2458 guiutil_show_dialog_centered(ed->open_dialog, ed->shell);
2462 guifile_import_pkgf_font(GtkWidget *w, gpointer data)
2464 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2466 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2468 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2470 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2471 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2473 * If the current file was imported, then make sure to use the
2474 * Save As... dialog instead of just saving under the name that
2475 * was constructed when importing. The user won't know what the
2476 * default BDF file name of imported fonts look like.
2479 guifile_save_as_wait(w, data);
2481 guifile_save(w, data);
2486 update_open_dialog(ed, PKGF_FORMAT);
2488 guiutil_show_dialog_centered(ed->open_dialog, ed->shell);
2492 guifile_import_windows_font(GtkWidget *w, gpointer data)
2494 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2496 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2498 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2500 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2501 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2503 * If the current file was imported, then make sure to use the
2504 * Save As... dialog instead of just saving under the name that
2505 * was constructed when importing. The user won't know what the
2506 * default BDF file name of imported fonts look like.
2509 guifile_save_as_wait(w, data);
2511 guifile_save(w, data);
2516 update_open_dialog(ed, FNT_FORMAT);
2518 guiutil_show_dialog_centered(ed->open_dialog, ed->shell);
2524 guifile_import_hbf_font(GtkWidget *w, gpointer data)
2526 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2528 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2530 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2532 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2533 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2535 * If the current file was imported, then make sure to use the
2536 * Save As... dialog instead of just saving under the name that
2537 * was constructed when importing. The user won't know what the
2538 * default BDF file name of imported fonts look like.
2541 guifile_save_as_wait(w, data);
2543 guifile_save(w, data);
2548 update_open_dialog(ed, HBF_FORMAT);
2550 guiutil_show_dialog_centered(ed->open_dialog, ed->shell);
2555 #ifdef HAVE_FREETYPE
2558 guifile_import_otf_font(GtkWidget *w, gpointer data)
2560 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2562 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2564 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2566 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2567 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2569 * If the current file was imported, then make sure to use the
2570 * Save As... dialog instead of just saving under the name that
2571 * was constructed when importing. The user won't know what the
2572 * default BDF file name of imported fonts look like.
2575 guifile_save_as_wait(w, data);
2577 guifile_save(w, data);
2582 update_open_dialog(ed, OTF_FORMAT);
2584 guiutil_show_dialog_centered(ed->open_dialog, ed->shell);
2587 #endif /* HAVE_FREETYPE */
2589 /**************************************************************************
2593 **************************************************************************/
2597 * Only compile this in if it is being built for machine running X.
2601 xsrv_filter(GtkWidget *w, gpointer data)
2603 gchar *pattern, **fonts;
2605 GtkListStore *store;
2606 GtkTreeViewColumn *col;
2609 pattern = (gchar *) gtk_entry_get_text(GTK_ENTRY(xsrv_filter_text));
2611 fonts = XListFonts(GDK_DISPLAY(), pattern, _XSRV_MAX_FONTS, &nfonts);
2614 GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(xsrv_font_list)));
2615 col = gtk_tree_view_get_column(GTK_TREE_VIEW(xsrv_font_list), 0);
2618 * Update the label on the font list with the number of fonts.
2620 sprintf(buffer1, "Font List: %d", nfonts);
2621 gtk_tree_view_column_set_title(col, buffer1);
2623 gtk_list_store_clear(store);
2624 for (i = 0; i < nfonts; i++) {
2625 gtk_list_store_append(store, &iter);
2626 gtk_list_store_set(store, &iter, 0, fonts[i], -1);
2629 XFreeFontNames(fonts);
2633 xsrv_xlfd_filter(GtkWidget *w, gpointer data)
2635 gtk_entry_set_text(GTK_ENTRY(xsrv_filter_text), _XSRV_DEFAULT_FILTER);
2636 gtk_widget_activate(xsrv_filter_text);
2640 xsrv_select_font(GtkTreeSelection *sel, gpointer data)
2643 GtkTreeModel *model;
2646 if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
2647 gtk_tree_model_get (model, &iter, 0, &name, -1);
2648 gtk_entry_set_text(GTK_ENTRY(xsrv_selection_text), name);
2654 xsrv_clear_selection_text(GtkWidget *w, gpointer data)
2656 gtk_entry_set_text(GTK_ENTRY(xsrv_selection_text), "");
2660 xsrv_import_font(GtkWidget *w, gpointer data)
2662 gbdfed_editor_t *ed = editors + xsrv_active_editor;
2667 name = (gchar *) gtk_entry_get_text(GTK_ENTRY(xsrv_selection_text));
2668 if (strcmp(name, "") == 0) {
2669 guiutil_error_message(ed->shell,
2670 "Import Font: No font name provided.");
2674 guiutil_busy_cursor(ed->shell, TRUE);
2675 guiutil_busy_cursor(xsrv_dialog, TRUE);
2676 if ((xfont = XLoadQueryFont(GDK_DISPLAY(), name)) == 0) {
2677 guiutil_busy_cursor(ed->shell, FALSE);
2678 guiutil_busy_cursor(xsrv_dialog, FALSE);
2679 sprintf(buffer1, "Import Font: Unable to load server font %s.",
2681 guiutil_error_message(ed->shell, buffer1);
2685 font = bdf_load_server_font(GDK_DISPLAY(), xfont, name,
2686 &options.font_opts, 0, 0);
2687 guiutil_busy_cursor(ed->shell, FALSE);
2688 guiutil_busy_cursor(xsrv_dialog, FALSE);
2689 XFreeFont(GDK_DISPLAY(), xfont);
2692 sprintf(buffer1, "Import Font: Unable to import server font %s.",
2694 guiutil_error_message(ed->shell, buffer1);
2701 gtk_widget_hide(xsrv_dialog);
2707 ed->file = ed->path = 0;
2709 sprintf(buffer1, "%s - unnamed%d [modified]", g_get_prgname(),
2711 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
2714 * Tell the glyphtest widget to remove references to
2715 * the current font if it has any, and redraw.
2718 glyphtest_remove_font(GLYPHTEST(glyphtest),
2719 fontgrid_get_font(FONTGRID(ed->fgrid)));
2721 fontgrid_set_font(FONTGRID(ed->fgrid), font, -1);
2724 * Indicate the font was imported.
2726 ed->imported = TRUE;
2729 * Finally, update the font name field.
2731 gtk_entry_set_text(GTK_ENTRY(ed->fontname),
2732 fontgrid_get_font_name(FONTGRID(ed->fgrid)));
2736 xsrv_activate_font(GtkTreeView *view, GtkTreePath *path,
2737 GtkTreeViewColumn *col, gpointer data)
2739 xsrv_import_font(GTK_WIDGET(view), data);
2743 guifile_import_xserver_font(GtkWidget *w, gpointer data)
2745 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2746 GtkWidget *label, *hbox, *vbox, *text, *swin, *button;
2747 gchar *name, **fonts;
2749 GtkListStore *store;
2750 GtkTreeViewColumn *column;
2751 GtkCellRenderer *cell_renderer;
2752 GtkTreeSelection *sel;
2755 if (fontgrid_get_font_modified(FONTGRID(ed->fgrid))) {
2757 sprintf(buffer1, "Save Font: (unnamed%d) modified. Save?", ed->id);
2759 sprintf(buffer1, "Save Font: %s modified. Save?", ed->file);
2760 if (guiutil_yes_or_no(ed->shell, buffer1, TRUE)) {
2762 * If the current file was imported, then make sure to use the
2763 * Save As... dialog instead of just saving under the name that
2764 * was constructed when importing. The user won't know what the
2765 * default BDF file name of imported fonts look like.
2768 guifile_save_as_wait(w, data);
2770 guifile_save(w, data);
2775 xsrv_active_editor = ed->id;
2777 if (xsrv_dialog == 0) {
2778 xsrv_dialog = gtk_dialog_new();
2779 gtk_window_set_title(GTK_WINDOW(xsrv_dialog),
2780 "X Server Font Selection");
2781 (void) g_signal_connect(G_OBJECT(xsrv_dialog), "delete_event",
2782 G_CALLBACK(gtk_widget_hide), 0);
2784 vbox = GTK_DIALOG(xsrv_dialog)->vbox;
2785 hbox = GTK_DIALOG(xsrv_dialog)->action_area;
2787 label = gtk_label_new("Filter");
2788 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
2789 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
2791 text = xsrv_filter_text = gtk_entry_new();
2792 gtk_entry_set_text(GTK_ENTRY(text), _XSRV_DEFAULT_FILTER);
2793 (void) g_signal_connect(G_OBJECT(text), "activate",
2794 G_CALLBACK(xsrv_filter), 0);
2795 gtk_box_pack_start(GTK_BOX(vbox), text, TRUE, TRUE, 0);
2797 swin = gtk_scrolled_window_new(0, 0);
2798 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
2799 GTK_POLICY_AUTOMATIC,
2802 store = gtk_list_store_new(1, G_TYPE_STRING);
2803 xsrv_font_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
2804 g_object_unref(store);
2806 (void) g_signal_connect(G_OBJECT(xsrv_font_list), "row_activated",
2807 G_CALLBACK(xsrv_activate_font),
2808 GUINT_TO_POINTER(ed->id));
2810 cell_renderer = gtk_cell_renderer_text_new();
2811 column = gtk_tree_view_column_new_with_attributes ("Fonts Found: 0",
2816 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
2817 gtk_tree_view_append_column (GTK_TREE_VIEW(xsrv_font_list), column);
2820 * Force the list to have a certain width and height.
2822 gtk_widget_set_size_request(xsrv_font_list, 550, 200);
2824 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(xsrv_font_list));
2825 gtk_tree_selection_set_mode(sel, GTK_SELECTION_BROWSE);
2827 (void) g_signal_connect(G_OBJECT(sel), "changed",
2828 G_CALLBACK(xsrv_select_font), NULL);
2830 gtk_container_add(GTK_CONTAINER(swin), xsrv_font_list);
2832 gtk_box_pack_start(GTK_BOX(vbox), swin, TRUE, TRUE, 0);
2834 label = gtk_label_new("Selection");
2835 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
2836 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
2838 text = xsrv_selection_text = gtk_entry_new();
2839 (void) g_signal_connect(G_OBJECT(text), "activate",
2840 G_CALLBACK(xsrv_import_font),
2841 GUINT_TO_POINTER(ed->id));
2842 gtk_box_pack_start(GTK_BOX(vbox), text, TRUE, TRUE, 0);
2845 * Now add the buttons.
2847 button = xsrv_import = gtk_button_new_with_label("Import");
2848 (void) g_signal_connect(G_OBJECT(button), "clicked",
2849 G_CALLBACK(xsrv_import_font),
2850 GUINT_TO_POINTER(ed->id));
2851 gtk_container_add(GTK_CONTAINER(hbox), button);
2853 button = xsrv_import = gtk_button_new_with_label("Clear Selection");
2854 (void) g_signal_connect(G_OBJECT(button), "clicked",
2855 G_CALLBACK(xsrv_clear_selection_text), 0);
2856 gtk_container_add(GTK_CONTAINER(hbox), button);
2858 button = gtk_button_new_with_label("Filter");
2859 (void) g_signal_connect(G_OBJECT(button), "clicked",
2860 G_CALLBACK(xsrv_filter), 0);
2861 gtk_container_add(GTK_CONTAINER(hbox), button);
2863 button = gtk_button_new_with_label("XLFD Filter");
2864 (void) g_signal_connect(G_OBJECT(button), "clicked",
2865 G_CALLBACK(xsrv_xlfd_filter), 0);
2866 gtk_container_add(GTK_CONTAINER(hbox), button);
2868 button = gtk_button_new_with_label("Cancel");
2869 (void) g_signal_connect_object(G_OBJECT(button), "clicked",
2870 G_CALLBACK(gtk_widget_hide),
2871 (gpointer) xsrv_dialog,
2873 gtk_container_add(GTK_CONTAINER(hbox), button);
2875 gtk_widget_show_all(vbox);
2876 gtk_widget_show_all(hbox);
2880 GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(xsrv_font_list)));
2881 column = gtk_tree_view_get_column(GTK_TREE_VIEW(xsrv_font_list), 0);
2884 * Load the list of fonts using the current filter pattern. This needs to
2885 * be done each time in case the list of font paths has changed between
2888 name = (gchar *) gtk_entry_get_text(GTK_ENTRY(xsrv_filter_text));
2889 fonts = XListFonts(GDK_DISPLAY(), name, _XSRV_MAX_FONTS, &nfonts);
2892 * Update the label on the font list with the number of fonts.
2894 sprintf(buffer1, "Fonts Found: %d", nfonts);
2895 gtk_tree_view_column_set_title(column, buffer1);
2897 gtk_list_store_clear(store);
2898 for (i = 0; i < nfonts; i++) {
2899 gtk_list_store_append(store, &iter);
2900 gtk_list_store_set(store, &iter, 0, fonts[i], -1);
2903 XFreeFontNames(fonts);
2908 guiutil_show_dialog_centered(xsrv_dialog, ed->shell);
2912 #endif /* HAVE_XLIB */
2915 guifile_export_psf_font(GtkWidget *w, gpointer data)
2917 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2920 font = fontgrid_get_font(FONTGRID(ed->fgrid));
2923 * Only character cell and mono width fonts can be exported as PSF2.
2925 if (font->spacing == BDF_PROPORTIONAL) {
2927 "Export Font: Font cannot be saved as PSF because %s ",
2928 "the font has proportional width.");
2929 guiutil_error_message(ed->shell, buffer2);
2933 update_save_dialog(ed, PSF_FORMAT);
2935 guiutil_show_dialog_centered(ed->save_dialog, ed->shell);
2939 guifile_export_hex_font(GtkWidget *w, gpointer data)
2941 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2944 * No check is done for a "valid" HEX font because it actually pads the
2945 * output font into bitmaps of two sizes, the wider size twice as wide
2946 * as the narrower size.
2949 update_save_dialog(ed, HEX_FORMAT);
2951 guiutil_show_dialog_centered(ed->save_dialog, ed->shell);
2955 guifile_export_header_font(GtkWidget *w, gpointer data)
2957 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2960 * No check is done for a "valid" HEX font because it actually pads the
2961 * output font into bitmaps of two sizes, the wider size twice as wide
2962 * as the narrower size.
2965 update_save_dialog(ed, HEADER_FORMAT);
2967 guiutil_show_dialog_centered(ed->save_dialog, ed->shell);
2971 guifile_save_as(GtkWidget *w, gpointer data)
2973 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2975 update_save_dialog(ed, BDF_FORMAT);
2977 guiutil_show_dialog_centered(ed->save_dialog, ed->shell);
2981 guifile_save_as_wait(GtkWidget *w, gpointer data)
2983 save_dialog_done = FALSE;
2985 guifile_save_as(w, data);
2986 while (save_dialog_done == FALSE)
2987 gtk_main_iteration();
2991 guifile_save(GtkWidget *w, gpointer data)
2993 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
2996 * If this is a new font, then we need to show the file selection dialog.
2997 * Otherwise, simply write the font out.
2999 if (ed->path == 0 && ed->file == 0) {
3000 guifile_save_as(w, data);
3004 ed->export_format = BDF_FORMAT;
3005 sprintf(buffer1, "%s/%s", ed->path, ed->file);
3006 export_font(buffer1, ed, FALSE);
3010 guifile_new_editor(GtkWidget *w, gpointer data)
3014 n = gbdfed_make_editor(0, FALSE);
3016 gtk_widget_show_all(editors[n].shell);
3020 * A routine to load a BDF font directly.
3023 guifile_load_bdf_font(gbdfed_editor_t *ed, const gchar *fullpath)
3027 if (fullpath == NULL)
3030 file = g_path_get_basename(fullpath);
3031 dir = g_path_get_dirname(fullpath);
3032 load_bdf_font(ed, fullpath, dir, file);