/* Copyright (C) 2008 by George Williams */ /* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "fontforgegtk.h" # include # include # include # include # include "gwwvask.h" # include "support.h" # include # include # include # include # include # include # include # include # include # include extern NameList *force_names_when_opening; int default_font_filter_index=0; struct gwwv_filter *user_font_filters = NULL; struct gwwv_filter def_font_filters[] = { { N_("All Fonts"), "*.{" "pfa," "pfb," "pt3," "t42," "sfd," "ttf," "bdf," "otf," "otb," "cff," "cef," "gai," #ifndef _NO_LIBXML "svg," "ufo," #endif "pf3," "ttc," "gsf," "cid," "bin," "hqx," "dfont," "mf," "ik," "fon," "fnt," "pcf," "pmf," "*pk," "*gf," "pdb" "}" /* With any of these methods of compression */ "{.gz,.Z,.bz2,}"}, { N_("Outline Fonts"), "*.{" "pfa," "pfb," "pt3," "t42," "sfd," "ttf," "otf," "cff," "cef," "gai," #ifndef _NO_LIBXML "svg," "ufo," #endif "pf3," "ttc," "gsf," "cid," "bin," "hqx," "dfont," "mf," "ik" "}" "{.gz,.Z,.bz2,}"}, { N_("Bitmap Fonts"), "*.{" "bdf," "otb," "bin," "hqx," "fon," "fnt," "pcf," "pmf," "*pk," "*gf," "pdb" "}" "{.gz,.Z,.bz2,}"}, {NU_("ΤεΧ Bitmap Fonts"), "*{pk,gf}"}, {N_("PostScript"), "*.{pfa,pfb,t42,otf,cef,cff,gai,pf3,pt3,gsf,cid}{.gz,.Z,.bz2,}"}, {N_("TrueType"), "*.{ttf,t42,ttc}{.gz,.Z,.bz2,}"}, {N_("OpenType"), "*.{ttf,otf}{.gz,.Z,.bz2,}"}, {N_("Type1"), "*.{pfa,pfb,gsf,cid}{.gz,.Z,.bz2,}"}, {N_("Type2"), "*.{otf,cef,cff,gai}{.gz,.Z,.bz2,}"}, {N_("Type3"), "*.{pf3,pt3}{.gz,.Z,.bz2,}"}, #ifndef _NO_LIBXML {N_("SVG"), "*.svg{.gz,.Z,.bz2,}"}, #endif {N_("FontForge's SFD"), "*.sfd{.gz,.Z,.bz2,}"}, {N_("Backup SFD"), "*.sfd~"}, {N_("Extract from PDF"), "*.pdf{.gz,.Z,.bz2,}"}, {" ---- ", ""}, {N_("All Files"), "*"}, NULL }; static gboolean gwwv_file_pattern_matcher(const GtkFileFilterInfo *info, gpointer data) { char *pattern = (char *) data; return( gwwv_wild_match(pattern, info->filename, TRUE)); } static void find_fonts_callback(GtkFileChooser *dialog) { GSList *files = gtk_file_chooser_get_filenames(dialog); GSList *test; int len, cnt, i; char ***fonts, *pt, *text; if ( files==NULL || (cnt = g_slist_length(files))==0 ) gtk_widget_set_tooltip_text(GTK_WIDGET(dialog),""); else { fonts = gcalloc(cnt,sizeof(char **)); cnt = len = 0; for ( test=files; test!=NULL; test=test->next, ++cnt) { fonts[cnt] = GetFontNames((char *) (test->data)); if ( fonts[cnt]!=NULL ) { len += 4*strlen((char *) (test->data))+1; /* allow space for utf8 conversion */ for ( i=0; fonts[cnt][i]!=NULL; ++i ) len += strlen( fonts[cnt][i])+2; } } pt = text = galloc(len+10); cnt = 0; for ( test=files; test!=NULL; test=test->next, ++cnt) { if ( fonts[cnt]!=NULL ) { /* If there is only one file selected, don't bother to name it */ if ( cnt!=0 || test->next!=NULL ) { gsize junk; char *temp = g_filename_to_utf8(GFileNameTail( (char *) (test->data) ), -1, &junk, &junk, NULL); strcpy(pt,temp); g_free(temp); pt += strlen(pt); *pt++ = '\n'; } for ( i=0; fonts[cnt][i]!=NULL; ++i ) { *pt++ = ' '; strcpy(pt,fonts[cnt][i]); free(fonts[cnt][i]); pt += strlen(pt); *pt ++ = '\n'; } free(fonts[cnt]); } } if ( pt>text && pt[-1]=='\n' ) pt[-1]='\0'; else *pt = '\0'; free(fonts); if ( *text=='\0' ) gtk_widget_set_tooltip_text(GTK_WIDGET(dialog), "???"); else { gtk_widget_set_tooltip_text(GTK_WIDGET(dialog), text); } free(text); } for ( test=files; test!=NULL; test=test->next) g_free(test->data); g_slist_free(files); } static void RememberCurrentFilter(GtkFileFilter *filter) { int i, k; const char *name; if ( filter==NULL ) return; name = gtk_file_filter_get_name(filter); if ( name==NULL ) return; for ( i=0; def_font_filters[i].name!=NULL; ++i ) { if ( strcmp(name,_(def_font_filters[i].name))== 0 ) { if ( *def_font_filters[i].wild!='\0' ) default_font_filter_index = i; return; } } if ( user_font_filters!=NULL ) { for ( k=0; user_font_filters[k].name!=NULL; ++i, ++k ) { if ( strcmp(name,_(user_font_filters[k].name))== 0 ) { default_font_filter_index = k; return; } } } } char *FVOpenFont(const char *title, const char *def_name, int mult ) { GtkWidget *dialog; char *filename = NULL; GtkFileFilter *filter, *standard, *first; int ans, i,k; if ( mult ) dialog = gtk_file_chooser_dialog_new (title, NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, GTK_STOCK_NEW, -100, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); else dialog = gtk_file_chooser_dialog_new (title, NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER( dialog ), mult ); g_object_set(G_OBJECT(dialog),"show-hidden",TRUE,NULL); if ( def_name!=NULL ) { char *pt = strrchr( def_name,'/'); if ( pt!=NULL ) { char *dir = copyn(def_name,pt-def_name); gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( dialog ), dir ); gtk_file_chooser_set_current_name( GTK_FILE_CHOOSER( dialog ), pt+1 ); free(dir); } else gtk_file_chooser_set_current_name( GTK_FILE_CHOOSER( dialog ), def_name ); } standard = first = NULL; for ( i=0; def_font_filters[i].name!=NULL; ++i ) { filter = gtk_file_filter_new(); /* GTK's gtk_file_filter_add_pattern doesn't handled {} wildcards */ /* and I depend on those. So I use my own patern matcher */ gtk_file_filter_add_custom( filter,GTK_FILE_FILTER_FILENAME, gwwv_file_pattern_matcher, (gpointer) def_font_filters[i].wild, NULL); gtk_file_filter_set_name( filter,_(def_font_filters[i].name) ); gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( dialog ), filter ); if ( i==default_font_filter_index ) standard = filter; if ( first==NULL ) first = filter; } if ( user_font_filters!=NULL ) { for ( k=0; user_font_filters[k].name!=NULL; ++i, ++k ) { filter = gtk_file_filter_new(); gtk_file_filter_add_custom( filter,GTK_FILE_FILTER_FILENAME, gwwv_file_pattern_matcher, (gpointer) user_font_filters[k].wild, NULL); gtk_file_filter_set_name( filter,_(user_font_filters[k].name) ); gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( dialog ), filter ); if ( i==default_font_filter_index ) standard = filter; } } if ( standard==NULL ) standard = first; if ( standard!=NULL ) gtk_file_chooser_set_filter( GTK_FILE_CHOOSER( dialog ), standard ); /* New Filter button, Recent files list */ if ( RecentFiles[0]!=NULL ) { } g_signal_connect(G_OBJECT (dialog), "selection-changed", G_CALLBACK (find_fonts_callback), NULL); filename = NULL; ans = gtk_dialog_run (GTK_DIALOG (dialog)); if ( ans == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); RememberCurrentFilter(gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog))); } else if ( ans == -100 ) FontNew(); /* And return NULL */ gtk_widget_destroy (dialog); return( filename ); }