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); }
char *Decompress(char *name, int compression) { char *dir = getenv("TMPDIR"); char buf[1500]; char *tmpfile; if ( dir==NULL ) dir = P_tmpdir; tmpfile = galloc(strlen(dir)+strlen(GFileNameTail(name))+2); strcpy(tmpfile,dir); strcat(tmpfile,"/"); strcat(tmpfile,GFileNameTail(name)); *strrchr(tmpfile,'.') = '\0'; #if defined( _NO_SNPRINTF ) || defined( __VMS ) sprintf( buf, "%s < %s > %s", compressors[compression].decomp, name, tmpfile ); #else snprintf( buf, sizeof(buf), "%s < %s > %s", compressors[compression].decomp, name, tmpfile ); #endif if ( system(buf)==0 ) return( tmpfile ); free(tmpfile); return( NULL ); }
/* Builds up a menu containing the titles of all the unused recent files */ void MenuRecentBuild(GWindow base,struct gmenuitem *mi,GEvent *e) { int i, cnt, cnt1; FontViewBase *fv; GMenuItem *sub; if ( mi->sub!=NULL ) { GMenuItemArrayFree(mi->sub); mi->sub = NULL; } cnt = 0; for ( i=0; i<RECENT_MAX && RecentFiles[i]!=NULL; ++i ) { for ( fv=(FontViewBase *) fv_list; fv!=NULL; fv=fv->next ) if ( fv->sf->filename!=NULL && strcmp(fv->sf->filename,RecentFiles[i])==0 ) break; if ( fv==NULL ) ++cnt; } if ( cnt==0 ) { /* This can't happen */ return; } sub = calloc(cnt+1,sizeof(GMenuItem)); cnt1 = 0; for ( i=0; i<RECENT_MAX && RecentFiles[i]!=NULL; ++i ) { for ( fv=(FontViewBase *) fv_list; fv!=NULL; fv=fv->next ) if ( fv->sf->filename!=NULL && strcmp(fv->sf->filename,RecentFiles[i])==0 ) break; if ( fv==NULL ) { GMenuItem *mi = &sub[cnt1++]; mi->ti.userdata = RecentFiles[i]; mi->ti.bg = mi->ti.fg = COLOR_DEFAULT; mi->invoke = RecentSelect; mi->ti.text = def2u_copy(GFileNameTail(RecentFiles[i])); } } if ( cnt!=cnt1 ) IError( "Bad counts in MenuRecentBuild"); mi->sub = sub; }
static void _gio_file_statfile(GIOControl *gc,char *path) { GDirEntry *cur; struct stat statb; if ( stat(path,&statb)==-1 ) { _GIO_reporterror(gc,errno); } else { cur = (GDirEntry *) gcalloc(1,sizeof(GDirEntry)); cur->name = uc_copy(GFileNameTail(path)); cur->hasdir = cur->hasexe = cur->hasmode = cur->hassize = cur->hastime = true; cur->size = statb.st_size; cur->mode = statb.st_mode; cur->modtime = statb.st_mtime; cur->isdir = S_ISDIR(cur->mode); cur->isexe = !cur->isdir && (cur->mode & 0100); gc->iodata = cur; gc->direntrydata = true; gc->return_code = 200; gc->done = true; (gc->receivedata)(gc); } }
/* by LoadSplineFont (which does) and by RevertFile (which knows what it's doing) */ SplineFont *_ReadSplineFont(FILE *file,char *filename,enum openflags openflags) { SplineFont *sf; char ubuf[250], *temp; int fromsfd = false; int i; char *pt, *strippedname, *oldstrippedname, *tmpfile=NULL, *paren=NULL, *fullname=filename, *rparen; int len; int checked; int compression=0; int wasurl = false, nowlocal = true; if ( filename==NULL ) return( NULL ); strippedname = filename; pt = strrchr(filename,'/'); if ( pt==NULL ) pt = filename; /* Someone gave me a font "Nafees Nastaleeq(Updated).ttf" and complained */ /* that ff wouldn't open it */ /* Now someone will complain about "Nafees(Updated).ttc(fo(ob)ar)" */ if ( (paren = strrchr(pt,'('))!=NULL && (rparen = strrchr(paren,')'))!=NULL && rparen[1]=='\0' ) { strippedname = copy(filename); strippedname[paren-filename] = '\0'; } pt = strrchr(strippedname,'.'); i = -1; if ( pt!=NULL ) for ( i=0; compressors[i].ext!=NULL; ++i ) if ( strcmp(compressors[i].ext,pt)==0 ) break; oldstrippedname = strippedname; if ( i==-1 || compressors[i].ext==NULL ) i=-1; else { if ( file!=NULL ) { char *spuriousname = ForceFileToHaveName(file,compressors[i].ext); tmpfile = Decompress(spuriousname,i); fclose(file); file = NULL; unlink(spuriousname); free(spuriousname); } else tmpfile = Decompress(strippedname,i); if ( tmpfile!=NULL ) { strippedname = tmpfile; } else { ff_post_error(_("Decompress Failed!"),_("Decompress Failed!")); return( NULL ); } compression = i+1; if ( strippedname!=filename && paren!=NULL ) { fullname = galloc(strlen(strippedname)+strlen(paren)+1); strcpy(fullname,strippedname); strcat(fullname,paren); } else fullname = strippedname; } /* If there are no pfaedit windows, give them something to look at */ /* immediately. Otherwise delay a bit */ strcpy(ubuf,_("Loading font from ")); len = strlen(ubuf); if ( !wasurl || i==-1 ) /* If it wasn't compressed, or it wasn't an url, then the fullname is reasonable, else use the original name */ strncat(ubuf,temp = copy(GFileNameTail(fullname)),100); else strncat(ubuf,temp = copy(GFileNameTail(filename)),100); free(temp); ubuf[100+len] = '\0'; ff_progress_start_indicator(FontViewFirst()==NULL?0:10,_("Loading..."),ubuf,_("Reading Glyphs"),0,1); ff_progress_enable_stop(0); if ( file==NULL ) { file = fopen(strippedname,"rb"); nowlocal = true; } sf = NULL; checked = false; /* checked == false => not checked */ /* checked == 'u' => UFO */ /* checked == 't' => TTF/OTF */ /* checked == 'p' => pfb/general postscript */ /* checked == 'P' => pdf */ /* checked == 'c' => cff */ /* checked == 'S' => svg */ /* checked == 'f' => sfd */ /* checked == 'F' => sfdir */ /* checked == 'b' => bdf */ /* checked == 'i' => ikarus */ if ( file!=NULL ) { /* Try to guess the file type from the first few characters... */ int ch1 = getc(file); int ch2 = getc(file); int ch3 = getc(file); int ch4 = getc(file); int ch9, ch10; fseek(file, 98, SEEK_SET); ch9 = getc(file); ch10 = getc(file); rewind(file); if (( ch1==0 && ch2==1 && ch3==0 && ch4==0 ) || (ch1=='O' && ch2=='T' && ch3=='T' && ch4=='O') || (ch1=='t' && ch2=='r' && ch3=='u' && ch4=='e') || (ch1=='t' && ch2=='t' && ch3=='c' && ch4=='f') ) { sf = _SFReadTTF(file,0,openflags,fullname,NULL); checked = 't'; } else if (( ch1=='%' && ch2=='!' ) || ( ch1==0x80 && ch2=='\01' ) ) { /* PFB header */ sf = _SFReadPostscript(file,fullname); checked = 'p'; } else if ( ch1==1 && ch2==0 && ch3==4 ) { int len; fseek(file,0,SEEK_END); len = ftell(file); fseek(file,0,SEEK_SET); sf = _CFFParse(file,len,NULL); checked = 'c'; } /* Too hard to figure out a valid mark for a mac resource file */ if ( file!=NULL ) fclose(file); } if ( sf!=NULL ) /* good */; else if (( strmatch(fullname+strlen(fullname)-4, ".ttf")==0 || strmatch(fullname+strlen(strippedname)-4, ".ttc")==0 || strmatch(fullname+strlen(fullname)-4, ".gai")==0 || strmatch(fullname+strlen(fullname)-4, ".otf")==0 || strmatch(fullname+strlen(fullname)-4, ".otb")==0 ) && checked!='t') { sf = SFReadTTF(fullname,0,openflags); } else if ( strmatch(fullname+strlen(strippedname)-4, ".bin")==0 || strmatch(fullname+strlen(strippedname)-4, ".hqx")==0 || strmatch(fullname+strlen(strippedname)-6, ".dfont")==0 ) { sf = SFReadMacBinary(fullname,0,openflags); } else if ( (strmatch(fullname+strlen(fullname)-4, ".pfa")==0 || strmatch(fullname+strlen(fullname)-4, ".pfb")==0 || strmatch(fullname+strlen(fullname)-4, ".pf3")==0 || strmatch(fullname+strlen(fullname)-4, ".cid")==0 || strmatch(fullname+strlen(fullname)-4, ".gsf")==0 || strmatch(fullname+strlen(fullname)-4, ".pt3")==0 || strmatch(fullname+strlen(fullname)-3, ".ps")==0 ) && checked!='p' ) { sf = SFReadPostscript(fullname); } else if ( strmatch(fullname+strlen(fullname)-4, ".cff")==0 && checked!='c' ) { sf = CFFParse(fullname); } else { sf = SFReadMacBinary(fullname,0,openflags); } ff_progress_end_indicator(); if ( sf!=NULL ) { SplineFont *norm = sf->mm!=NULL ? sf->mm->normal : sf; if ( compression!=0 ) { free(sf->filename); *strrchr(oldstrippedname,'.') = '\0'; sf->filename = copy( oldstrippedname ); } if ( fromsfd ) sf->compression = compression; free( norm->origname ); if ( sf->chosenname!=NULL && strippedname==filename ) { norm->origname = galloc(strlen(filename)+strlen(sf->chosenname)+8); strcpy(norm->origname,filename); strcat(norm->origname,"("); strcat(norm->origname,sf->chosenname); strcat(norm->origname,")"); } else norm->origname = copy(filename); free( norm->chosenname ); norm->chosenname = NULL; if ( sf->mm!=NULL ) { int j; for ( j=0; j<sf->mm->instance_count; ++j ) { free(sf->mm->instances[j]->origname); sf->mm->instances[j]->origname = copy(norm->origname); } } } else if ( !GFileExists(filename) ) ff_post_error(_("Couldn't open font"),_("The requested file, %.100s, does not exist"),GFileNameTail(filename)); else if ( !GFileReadable(filename) ) ff_post_error(_("Couldn't open font"),_("You do not have permission to read %.100s"),GFileNameTail(filename)); else ff_post_error(_("Couldn't open font"),_("%.100s is not in a known format (or is so badly corrupted as to be unreadable)"),GFileNameTail(filename)); if ( oldstrippedname!=filename ) free(oldstrippedname); if ( fullname!=filename && fullname!=strippedname ) free(fullname); if ( tmpfile!=NULL ) { unlink(tmpfile); free(tmpfile); } if ( (openflags&of_fstypepermitted) && sf!=NULL && (sf->pfminfo.fstype&0xff)==0x0002 ) { /* Ok, they have told us from a script they have access to the font */ } else if ( !fromsfd && sf!=NULL && (sf->pfminfo.fstype&0xff)==0x0002 ) { char *buts[3]; buts[0] = _("_Yes"); buts[1] = _("_No"); buts[2] = NULL; if ( ff_ask(_("Restricted Font"),(const char **) buts,1,1,_("This font is marked with an FSType of 2 (Restricted\nLicense). That means it is not editable without the\npermission of the legal owner.\n\nDo you have such permission?"))==1 ) { SplineFontFree(sf); return( NULL ); } } return( sf ); }
static void _gio_file_dir(GIOControl *gc,char *path) { DIR *dir; struct dirent *ent; GDirEntry *head=NULL, *last=NULL, *cur; char *buffer, *ept, *temp; struct stat statb; dir = opendir(path); if ( dir==NULL ) { _GIO_reporterror(gc,errno); return; } buffer = (char *) malloc(strlen(path)+FILENAME_MAX+3); strcpy(buffer,path); ept = buffer+strlen(buffer); if ( ept[-1]!='/' ) *ept++ = '/'; while (( ent = readdir(dir))!=NULL ) { cur = (GDirEntry *) calloc(1,sizeof(GDirEntry)); cur->name = def2u_copy(ent->d_name); strcpy(ept,ent->d_name); stat(buffer,&statb); cur->hasdir = cur->hasexe = cur->hasmode = cur->hassize = cur->hastime = true; cur->size = statb.st_size; cur->mode = statb.st_mode; cur->modtime = statb.st_mtime; cur->isdir = S_ISDIR(cur->mode); cur->isexe = !cur->isdir && (cur->mode & 0100); temp = NULL; // Things go badly if we open a pipe or a device. So we don't. #ifdef __MINGW32__ //Symlinks behave differently on Windows and are transparent, so no S_ISLNK. if (S_ISREG(statb.st_mode) || S_ISDIR(statb.st_mode)) { #else if (S_ISREG(statb.st_mode) || S_ISDIR(statb.st_mode) || S_ISLNK(statb.st_mode)) { #endif // We look at the file and try to determine a MIME type. if ( (temp=GIOguessMimeType(buffer)) || (temp=GIOGetMimeType(buffer)) ) { cur->mimetype = u_copy(c_to_u(temp)); free(temp); } } if ( last==NULL ) head = last = cur; else { last->next = cur; last = cur; } } #if __CygWin /* Under cygwin we should give the user access to /cygdrive, even though */ /* a diropen("/") will not find it */ if ( strcmp(path,"/")==0 ) { cur = (GDirEntry *) calloc(1,sizeof(GDirEntry)); cur->name = def2u_copy("cygdrive"); strcpy(ept,"cygdrive"); stat(buffer,&statb); cur->hasdir = cur->hasexe = cur->hasmode = cur->hassize = cur->hastime = true; cur->size = statb.st_size; cur->mode = statb.st_mode; cur->modtime = statb.st_mtime; cur->isdir = S_ISDIR(cur->mode); cur->isexe = !cur->isdir && (cur->mode & 0100); if ( last==NULL ) head = last = cur; else { last->next = cur; last = cur; } } #endif closedir(dir); free(buffer); gc->iodata = head; gc->direntrydata = true; gc->return_code = 200; gc->done = true; (gc->receivedata)(gc); } static void _gio_file_statfile(GIOControl *gc,char *path) { GDirEntry *cur; struct stat statb; if ( stat(path,&statb)==-1 ) { _GIO_reporterror(gc,errno); } else { cur = (GDirEntry *) calloc(1,sizeof(GDirEntry)); cur->name = uc_copy(GFileNameTail(path)); cur->hasdir = cur->hasexe = cur->hasmode = cur->hassize = cur->hastime = true; cur->size = statb.st_size; cur->mode = statb.st_mode; cur->modtime = statb.st_mtime; cur->isdir = S_ISDIR(cur->mode); cur->isexe = !cur->isdir && (cur->mode & 0100); gc->iodata = cur; gc->direntrydata = true; gc->return_code = 200; gc->done = true; (gc->receivedata)(gc); } }