int main( int argc, char **argv ) { extern const char *source_modtime_str, *source_version_str; const char *load_prefs = getenv("FONTFORGE_LOADPREFS"); int i; extern int splash; int recover=1; GtkWidget *notices, *ffsplash; gchar *home_dir, *rc_path; struct argcontext args; #ifdef FONTFORGE_CONFIG_TYPE3 fprintf( stderr, "Copyright (c) 2000-2012 by George Williams.\n Executable based on sources from %s-ML.\n", source_modtime_str ); #else fprintf( stderr, "Copyright (c) 2000-2012 by George Williams.\n Executable based on sources from %s.\n", source_modtime_str ); #endif fprintf( stderr, " Library based on sources from %s.\n", library_version_configuration.library_source_modtime_string ); gtk_set_locale (); home_dir = (gchar*) g_get_home_dir(); rc_path = g_strdup_printf("%s/.fontforgerc", home_dir); gtk_rc_add_default_file(rc_path); g_free(rc_path); gtk_init (&argc, &argv); #if defined(SHAREDIR) add_pixmap_directory( SHAREDIR "/pixmaps"); #elif defined(PREFIX) add_pixmap_directory( PREFIX "/share/fontforge/pixmaps" ); #else add_pixmap_directory( "./pixmaps" ); #endif bind_textdomain_codeset("FontForge","UTF-8"); bindtextdomain("FontForge", getLocaleDir()); textdomain("FontForge"); #if defined(__Mac) /* Start X if they haven't already done so. Well... try anyway */ /* Must be before we change DYLD_LIBRARY_PATH or X won't start */ if ( uses_local_x(argc,argv) && getenv("DISPLAY")==NULL ) { system( "open /Applications/Utilities/X11.app/" ); setenv("DISPLAY",":0.0",0); } #endif FF_SetUiInterface(>k_ui_interface); FF_SetPrefsInterface(>k_prefs_interface); /*FF_SetSCInterface(>k_sc_interface);*/ /*FF_SetCVInterface(>k_cv_interface);*/ /*FF_SetBCInterface(>k_bc_interface);*/ FF_SetFVInterface(>k_fv_interface); /*FF_SetFIInterface(>k_fi_interface);*/ /*FF_SetMVInterface(>k_mv_interface);*/ /*FF_SetClipInterface(>k_clip_interface);*/ #ifndef _NO_PYTHON PythonUI_Init(); #endif InitSimpleStuff(); if ( load_prefs!=NULL && strcasecmp(load_prefs,"Always")==0 ) LoadPrefs(); if ( default_encoding==NULL ) default_encoding=FindOrMakeEncoding("ISO8859-1"); if ( default_encoding==NULL ) default_encoding=&custom; /* In case iconv is broken */ CheckIsScript(argc,argv); /* Will run the script and exit if it is a script */ /* If there is no UI, there is always a script */ /* and we will never return from the above */ if ( load_prefs==NULL || (strcasecmp(load_prefs,"Always")!=0 && /* Already loaded */ strcasecmp(load_prefs,"Never")!=0 )) LoadPrefs(); for ( i=1; i<argc; ++i ) { char *pt = argv[i]; if ( pt[0]=='-' && pt[1]=='-' ) ++pt; if ( strcmp(pt,"-nosplash")==0 ) splash = 0; else if ( strcmp(pt,"-recover")==0 && i<argc-1 ) { ++i; if ( strcmp(argv[i],"none")==0 ) recover=0; else if ( strcmp(argv[i],"clean")==0 ) recover= -1; else if ( strcmp(argv[i],"auto")==0 ) recover= 1; else if ( strcmp(argv[i],"inquire")==0 ) recover= 2; else { fprintf( stderr, "Invalid argument to -recover, must be none, auto, inquire or clean\n" ); dousage(); } } else if ( strcmp(pt,"-recover=none")==0 ) { recover = 0; } else if ( strcmp(pt,"-recover=clean")==0 ) { recover = -1; } else if ( strcmp(pt,"-recover=auto")==0 ) { recover = 1; } else if ( strcmp(pt,"-recover=inquire")==0 ) { recover = 2; } else if ( strcmp(pt,"-help")==0 ) dohelp(); else if ( strcmp(pt,"-usage")==0 ) dousage(); else if ( strcmp(pt,"-version")==0 ) doversion(source_version_str); else if ( strcmp(pt,"-library-status")==0 ) dolibrary(); } InitCursors(); #ifndef _NO_PYTHON PyFF_ProcessInitFiles(); #endif if ( splash ) { splashw = create_FontForgeSplash (); splash_window_tooltip_fun( splashw ); notices = lookup_widget(splashw,"Notices"); if ( notices!=NULL ) gtk_widget_hide(notices); ffsplash = lookup_widget(splashw,"ffsplash2"); if ( ffsplash!=NULL ) gtk_widget_hide(ffsplash); ffsplash = lookup_widget(splashw,"ffsplash3"); if ( ffsplash!=NULL ) gtk_widget_hide(ffsplash); gtk_window_set_position(GTK_WINDOW(splashw),GTK_WIN_POS_CENTER_ALWAYS); gtk_widget_show (splashw); ff_progress_allow_events(); gtk_timeout_add(1000,Splash_Changes,splashw); } gtk_timeout_add(30*1000,__DoAutoSaves,NULL); /* Check for autosave every 30 seconds */ args.argc = argc; args.argv = argv; args.recover = recover; gtk_timeout_add(100,ParseArgs,&args); /* Parse arguments within the main loop */ gtk_main (); return( 0 ); }
int fontforge_main( int argc, char **argv ) { extern const char *source_modtime_str; extern const char *source_version_str; const char *load_prefs = getenv("FONTFORGE_LOADPREFS"); int i; int recover=2; int any; int next_recent=0; GRect pos; GWindowAttrs wattrs; char *display = NULL; FontRequest rq; int ds, ld; int openflags=0; int doopen=0, quit_request=0; bool use_cairo = true; #if !(GLIB_CHECK_VERSION(2, 35, 0)) g_type_init(); #endif /* Must be done before we cache the current directory */ /* Change to HOME dir if specified on the commandline */ for ( i=1; i<argc; ++i ) { char *pt = argv[i]; if ( pt[0]=='-' && pt[1]=='-' ) ++pt; if (strcmp(pt,"-home")==0 || strncmp(pt,"-psn_",5)==0) { /* OK, I don't know what _-psn_ means, but to GW it means */ /* we've been started on the mac from the FontForge.app */ /* structure, and the current directory is (shudder) "/" */ if (getenv("HOME")!=NULL) chdir(getenv("HOME")); break; /* Done - Unnecessary to check more arguments */ } if (strcmp(pt,"-quiet")==0) quiet = 1; } if (!quiet) { fprintf( stderr, "Copyright (c) 2000-2014 by George Williams. See AUTHORS for Contributors.\n" ); fprintf( stderr, " License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n" ); fprintf( stderr, " with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.\n" ); fprintf( stderr, " Based on sources from %s" "-ML" #ifdef FREETYPE_HAS_DEBUGGER "-TtfDb" #endif #ifdef _NO_PYTHON "-NoPython" #endif #ifdef FONTFORGE_CONFIG_USE_DOUBLE "-D" #endif ".\n", FONTFORGE_MODTIME_STR ); fprintf( stderr, " Based on source from git with hash: %s\n", FONTFORGE_GIT_VERSION ); } #if defined(__Mac) /* Start X if they haven't already done so. Well... try anyway */ /* Must be before we change DYLD_LIBRARY_PATH or X won't start */ /* (osascript depends on a libjpeg which isn't found if we look in /sw/lib first */ int local_x = uses_local_x(argc,argv); if ( local_x==1 && getenv("DISPLAY")==NULL ) { /* Don't start X if we're just going to quit. */ /* if X exists, it isn't needed. If X doesn't exist it's wrong */ if ( !hasquit(argc,argv)) { /* This sequence is supposed to bring up an app without a window */ /* but X still opens an xterm */ system( "osascript -e 'tell application \"X11\" to launch'" ); system( "osascript -e 'tell application \"X11\" to activate'" ); } setenv("DISPLAY",":0.0",0); } else if ( local_x==1 && *getenv("DISPLAY")!='/' && strcmp(getenv("DISPLAY"),":0.0")!=0 && strcmp(getenv("DISPLAY"),":0")!=0 ) /* 10.5.7 uses a named socket or something "/tmp/launch-01ftWX:0" */ local_x = 0; #endif #if defined(__MINGW32__) if( getenv("DISPLAY")==NULL ) { putenv("DISPLAY=127.0.0.1:0.0"); } if( getenv("LC_ALL")==NULL ){ char lang[8]; char env[32]; if( GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, lang, 8) > 0 ){ strcpy(env, "LC_ALL="); strcat(env, lang); putenv(env); } } #endif FF_SetUiInterface(&gdraw_ui_interface); FF_SetPrefsInterface(&gdraw_prefs_interface); FF_SetSCInterface(&gdraw_sc_interface); FF_SetCVInterface(&gdraw_cv_interface); FF_SetBCInterface(&gdraw_bc_interface); FF_SetFVInterface(&gdraw_fv_interface); FF_SetFIInterface(&gdraw_fi_interface); FF_SetMVInterface(&gdraw_mv_interface); FF_SetClipInterface(&gdraw_clip_interface); #ifndef _NO_PYTHON PythonUI_Init(); #endif FindProgDir(argv[0]); InitSimpleStuff(); #if defined(__MINGW32__) { char path[MAX_PATH]; unsigned int len = GetModuleFileNameA(NULL, path, MAX_PATH); path[len] = '\0'; //The '.exe' must be removed as resources presumes it's not there. GResourceSetProg(GFileRemoveExtension(GFileNormalizePath(path))); } #else GResourceSetProg(argv[0]); #endif #if defined(__Mac) /* The mac seems to default to the "C" locale, LANG and LC_MESSAGES are not*/ /* defined. This means that gettext will not bother to look up any message*/ /* files -- even if we have a "C" or "POSIX" entry in the locale diretory */ /* Now if X11 gives us the command key, I want to force a rebinding to use */ /* Cmd rather than Control key -- more mac-like. But I can't do that if */ /* there is no locale. So I force a locale if there is none specified */ /* I force the US English locale, because that's the what the messages are */ /* by default so I'm changing as little as I can. I think. */ /* Now the locale command will treat a LANG which is "" as undefined, but */ /* gettext will not. So I don't bother to check for null strings or "C" */ /* or "POSIX". If they've mucked with the locale perhaps they know what */ /* they are doing */ { int did_keybindings = 0; int useCommandKey = get_mac_x11_prop("enable_key_equivalents") <= 0; if ( local_x && useCommandKey ) { hotkeySystemSetCanUseMacCommand( 1 ); /* Ok, we get the command key */ if ( getenv("LANG")==NULL && getenv("LC_MESSAGES")==NULL ) { setenv("LC_MESSAGES","en_US.UTF-8",0); } /* Can we find a set of keybindings designed for the mac with cmd key? */ bind_textdomain_codeset("Mac-FontForge-MenuShortCuts","UTF-8"); bindtextdomain("Mac-FontForge-MenuShortCuts", getLocaleDir()); if ( *dgettext("Mac-FontForge-MenuShortCuts","Flag0x10+")!='F' ) { GMenuSetShortcutDomain("Mac-FontForge-MenuShortCuts"); did_keybindings = 1; } } if ( !did_keybindings ) { /* Nope. we can't. Fall back to the normal stuff */ #endif GMenuSetShortcutDomain("FontForge-MenuShortCuts"); bind_textdomain_codeset("FontForge-MenuShortCuts","UTF-8"); bindtextdomain("FontForge-MenuShortCuts", getLocaleDir()); #if defined(__Mac) } } #endif bind_textdomain_codeset("FontForge","UTF-8"); bindtextdomain("FontForge", getLocaleDir()); textdomain("FontForge"); GResourceUseGetText(); { char shareDir[PATH_MAX]; char* sd = getShareDir(); strncpy( shareDir, sd, PATH_MAX ); shareDir[PATH_MAX-1] = '\0'; if(!sd) { strcpy( shareDir, SHAREDIR ); } char path[PATH_MAX]; snprintf(path, PATH_MAX, "%s%s", shareDir, "/pixmaps" ); GGadgetSetImageDir( path ); snprintf(path, PATH_MAX, "%s%s", shareDir, "/resources/fontforge.resource" ); GResourceAddResourceFile(path, GResourceProgramName,false); } hotkeysLoad(); // loadPrefsFiles(); Prefs_LoadDefaultPreferences(); if ( load_prefs!=NULL && strcasecmp(load_prefs,"Always")==0 ) LoadPrefs(); if ( default_encoding==NULL ) default_encoding=FindOrMakeEncoding("ISO8859-1"); if ( default_encoding==NULL ) default_encoding=&custom; /* In case iconv is broken */ // This no longer starts embedded Python unless control passes to the Python executors, // which exit independently rather than returning here. CheckIsScript(argc,argv); /* Will run the script and exit if it is a script */ /* If there is no UI, there is always a script */ /* and we will never return from the above */ if ( load_prefs==NULL || (strcasecmp(load_prefs,"Always")!=0 && /* Already loaded */ strcasecmp(load_prefs,"Never")!=0 )) LoadPrefs(); GrokNavigationMask(); for ( i=1; i<argc; ++i ) { char *pt = argv[i]; if ( pt[0]=='-' && pt[1]=='-' ) ++pt; if ( strcmp(pt,"-sync")==0 ) GResourceAddResourceString("Gdraw.Synchronize: true",argv[0]); else if ( strcmp(pt,"-depth")==0 && i<argc-1 ) AddR(argv[0],"Gdraw.Depth", argv[++i]); else if ( strcmp(pt,"-vc")==0 && i<argc-1 ) AddR(argv[0],"Gdraw.VisualClass", argv[++i]); else if ( (strcmp(pt,"-cmap")==0 || strcmp(pt,"-colormap")==0) && i<argc-1 ) AddR(argv[0],"Gdraw.Colormap", argv[++i]); else if ( (strcmp(pt,"-dontopenxdevices")==0) ) AddR(argv[0],"Gdraw.DontOpenXDevices", "true"); else if ( strcmp(pt,"-keyboard")==0 && i<argc-1 ) AddR(argv[0],"Gdraw.Keyboard", argv[++i]); else if ( strcmp(pt,"-display")==0 && i<argc-1 ) display = argv[++i]; # if MyMemory else if ( strcmp(pt,"-memory")==0 ) __malloc_debug(5); # endif else if ( strncmp(pt,"-usecairo",strlen("-usecairo"))==0 ) { if ( strcmp(pt,"-usecairo=no")==0 ) use_cairo = false; else use_cairo = true; GDrawEnableCairo(use_cairo); } else if ( strcmp(pt,"-nosplash")==0 ) splash = 0; else if ( strcmp(pt,"-quiet")==0 ) /* already checked for this earlier, no need to do it again */; else if ( strcmp(pt,"-unique")==0 ) unique = 1; else if ( strcmp(pt,"-forceuihidden")==0 ) cmdlinearg_forceUIHidden = 0; else if ( strcmp(pt,"-recover")==0 && i<argc-1 ) { ++i; if ( strcmp(argv[i],"none")==0 ) recover=0; else if ( strcmp(argv[i],"clean")==0 ) recover= -1; else if ( strcmp(argv[i],"auto")==0 ) recover= 1; else if ( strcmp(argv[i],"inquire")==0 ) recover= 2; else { fprintf( stderr, "Invalid argument to -recover, must be none, auto, inquire or clean\n" ); dousage(); } } else if ( strcmp(pt,"-recover=none")==0 ) { recover = 0; } else if ( strcmp(pt,"-recover=clean")==0 ) { recover = -1; } else if ( strcmp(pt,"-recover=auto")==0 ) { recover = 1; } else if ( strcmp(pt,"-recover=inquire")==0 ) { recover = 2; } else if ( strcmp(pt,"-docs")==0 ) dohelp(); else if ( strcmp(pt,"-help")==0 ) dousage(); else if ( strcmp(pt,"-version")==0 || strcmp(pt,"-v")==0 || strcmp(pt,"-V")==0 ) doversion(FONTFORGE_MODTIME_STR); else if ( strcmp(pt,"-quit")==0 ) quit_request = true; else if ( strcmp(pt,"-home")==0 ) /* already did a chdir earlier, don't need to do it again */; #if defined(__Mac) else if ( strncmp(pt,"-psn_",5)==0 ) { /* OK, I don't know what _-psn_ means, but to GW it means */ /* we've been started on the mac from the FontForge.app */ /* structure, and the current directory was (shudder) "/" */ /* (however, we changed to HOME earlier in main routine). */ unique = 1; listen_to_apple_events = true; // This has been problematic on Mavericks and later. } #endif } ensureDotFontForgeIsSetup(); #if defined(__MINGW32__) && !defined(_NO_LIBCAIRO) //Load any custom fonts for the user interface if (use_cairo) { char *system_load = getGResourceProgramDir(); char *user_load = getFontForgeUserDir(Data); char lbuf[MAX_PATH]; int lret; if (system_load != NULL) { //Follow the FontConfig APPSHAREFONTDIR location lret = snprintf(lbuf, MAX_PATH, "%s/../share/fonts", system_load); if (lret > 0 && lret < MAX_PATH) { WinLoadUserFonts(lbuf); } } if (user_load != NULL) { lret = snprintf(lbuf, MAX_PATH, "%s/%s", user_load, "ui-fonts"); if (lret > 0 && lret < MAX_PATH) { WinLoadUserFonts(lbuf); } free(user_load); } } #endif InitImageCache(); // This is in gtextinfo.c. It zeroes imagecache for us. atexit(&ClearImageCache); // We register the destructor, which is also in gtextinfo.c. GDrawCreateDisplays(display,argv[0]); atexit(&GDrawDestroyDisplays); // We register the destructor so that it runs even if we call exit without finishing this function. default_background = GDrawGetDefaultBackground(screen_display); InitToolIconClut(default_background); InitToolIcons(); InitCursors(); /** * we have to do a quick sniff of argv[] here to see if the user * wanted to skip loading these python init files. */ for ( i=1; i<argc; ++i ) { char *pt = argv[i]; if ( !strcmp(pt,"-SkipPythonInitFiles")) { ProcessPythonInitFiles = 0; } } #ifndef _NO_PYTHON /*# ifndef GWW_TEST*/ FontForge_InitializeEmbeddedPython(); /* !!!!!! debug (valgrind doesn't like python) */ /*# endif*/ #endif #ifndef _NO_PYTHON if( ProcessPythonInitFiles ) PyFF_ProcessInitFiles(); #endif /* the splash screen used not to have a title bar (wam_nodecor) */ /* but I found I needed to know how much the window manager moved */ /* the window around, which I can determine if I have a positioned */ /* decorated window created at the begining */ /* Actually I don't care any more */ wattrs.mask = wam_events|wam_cursor|wam_bordwidth|wam_backcol|wam_positioned|wam_utf8_wtitle|wam_isdlg; wattrs.event_masks = ~(1<<et_charup); wattrs.positioned = 1; wattrs.cursor = ct_pointer; wattrs.utf8_window_title = "FontForge"; wattrs.border_width = 2; wattrs.background_color = 0xffffff; wattrs.is_dlg = !listen_to_apple_events; pos.x = pos.y = 200; pos.width = splashimage.u.image->width; pos.height = splashimage.u.image->height-56; /* 54 */ GDrawBindSelection(NULL,sn_user1,"FontForge"); if ( unique && GDrawSelectionOwned(NULL,sn_user1)) { /* Different event handler, not a dialog */ wattrs.is_dlg = false; splashw = GDrawCreateTopWindow(NULL,&pos,request_e_h,NULL,&wattrs); PingOtherFontForge(argc,argv); } else { if ( quit_request ) exit( 0 ); splashw = GDrawCreateTopWindow(NULL,&pos,splash_e_h,NULL,&wattrs); } memset(&rq,0,sizeof(rq)); rq.utf8_family_name = SERIF_UI_FAMILIES; rq.point_size = 12; rq.weight = 400; splash_font = GDrawInstanciateFont(NULL,&rq); splash_font = GResourceFindFont("Splash.Font",splash_font); GDrawDecomposeFont(splash_font, &rq); rq.style = fs_italic; splash_italic = GDrawInstanciateFont(NULL,&rq); splash_italic = GResourceFindFont("Splash.ItalicFont",splash_italic); GDrawSetFont(splashw,splash_font); SplashLayout(); localsplash = splash; if ( localsplash && !listen_to_apple_events ) start_splash_screen(); // // The below call will initialize the fontconfig cache if required. // That can take a while the first time it happens. // GDrawWindowFontMetrics(splashw,splash_font,&as,&ds,&ld); fh = as+ds+ld; if ( AutoSaveFrequency>0 ) autosave_timer=GDrawRequestTimer(splashw,2*AutoSaveFrequency*1000,AutoSaveFrequency*1000,NULL); GDrawProcessPendingEvents(NULL); GDrawSetBuildCharHooks(BuildCharHook,InsCharHook); any = 0; if ( recover==-1 ) CleanAutoRecovery(); else if ( recover ) any = DoAutoRecoveryExtended( recover-1 ); openflags = 0; for ( i=1; i<argc; ++i ) { char buffer[1025]; char *pt = argv[i]; GDrawProcessPendingEvents(NULL); if ( pt[0]=='-' && pt[1]=='-' && pt[2]!='\0') ++pt; if ( strcmp(pt,"-new")==0 ) { FontNew(); any = 1; # if HANYANG } else if ( strcmp(pt,"-newkorean")==0 ) { MenuNewComposition(NULL,NULL,NULL); any = 1; # endif } else if ( !strcmp(pt,"-SkipPythonInitFiles")) { // already handled above. } else if ( strcmp(pt,"-last")==0 ) { if ( next_recent<RECENT_MAX && RecentFiles[next_recent]!=NULL ) if ( ViewPostScriptFont(RecentFiles[next_recent++],openflags)) any = 1; } else if ( strcmp(pt,"-sync")==0 || strcmp(pt,"-memory")==0 || strcmp(pt,"-nosplash")==0 || strcmp(pt,"-recover=none")==0 || strcmp(pt,"-recover=clean")==0 || strcmp(pt,"-recover=auto")==0 || strcmp(pt,"-dontopenxdevices")==0 || strcmp(pt,"-unique")==0 || strncmp(pt,"-usecairo",strlen("-usecairo"))==0 || strcmp(pt,"-home")==0 || strcmp(pt,"-quiet")==0 || strcmp(pt,"-forceuihidden")==0 ) /* Already done, needed to be before display opened */; else if ( strncmp(pt,"-psn_",5)==0 ) /* Already done */; else if ( (strcmp(pt,"-depth")==0 || strcmp(pt,"-vc")==0 || strcmp(pt,"-cmap")==0 || strcmp(pt,"-colormap")==0 || strcmp(pt,"-keyboard")==0 || strcmp(pt,"-display")==0 || strcmp(pt,"-recover")==0 ) && i<argc-1 ) ++i; /* Already done, needed to be before display opened */ else if ( strcmp(pt,"-allglyphs")==0 ) openflags |= of_all_glyphs_in_ttc; else if ( strcmp(pt,"-open")==0 ) doopen = true; else { printf("else argv[i]:%s\n", argv[i] ); if ( strstr(argv[i],"://")!=NULL ) { /* Assume an absolute URL */ strncpy(buffer,argv[i],sizeof(buffer)); buffer[sizeof(buffer)-1]= '\0'; } else GFileGetAbsoluteName(argv[i],buffer,sizeof(buffer)); if ( GFileIsDir(buffer) || (strstr(buffer,"://")!=NULL && buffer[strlen(buffer)-1]=='/')) { char *fname; fname = malloc(strlen(buffer)+strlen("/glyphs/contents.plist")+1); strcpy(fname,buffer); strcat(fname,"/glyphs/contents.plist"); if ( GFileExists(fname)) { /* It's probably a Unified Font Object directory */ free(fname); if ( ViewPostScriptFont(buffer,openflags) ) any = 1; } else { strcpy(fname,buffer); strcat(fname,"/font.props"); if ( GFileExists(fname)) { /* It's probably a sf dir collection */ free(fname); if ( ViewPostScriptFont(buffer,openflags) ) any = 1; } else { free(fname); if ( buffer[strlen(buffer)-1]!='/' ) { /* If dirname doesn't end in "/" we'll be looking in parent dir */ buffer[strlen(buffer)+1]='\0'; buffer[strlen(buffer)] = '/'; } fname = GetPostScriptFontName(buffer,false); if ( fname!=NULL ) ViewPostScriptFont(fname,openflags); any = 1; /* Even if we didn't get a font, don't bring up dlg again */ free(fname); } } } else if ( ViewPostScriptFont(buffer,openflags)!=0 ) any = 1; } } if ( !any && !doopen ) any = ReopenLastFonts(); collabclient_ensureClientBeacon(); collabclient_sniffForLocalServer(); #ifndef _NO_PYTHON PythonUI_namedpipe_Init(); #endif #if defined(__Mac) if ( listen_to_apple_events ) { install_apple_event_handlers(); install_mac_timer(); setup_cocoa_app(); // WARNING: See declaration of RunApplicationEventLoop() above as to // why you might not want to call that function anymore. // RunApplicationEventLoop(); } else #endif if ( doopen || !any ) _FVMenuOpen(NULL); GDrawEventLoop(NULL); GDrawDestroyDisplays(); #ifndef _NO_PYTHON /*# ifndef GWW_TEST*/ FontForge_FinalizeEmbeddedPython(); /* !!!!!! debug (valgrind doesn't like python) */ /*# endif*/ #endif // These free menu translations, mostly. BitmapViewFinishNonStatic(); MetricsViewFinishNonStatic(); CharViewFinishNonStatic(); FontViewFinishNonStatic(); ClearImageCache(); // This frees the contents of imagecache. hotkeysSave(); LastFonts_Save(); #ifndef _NO_LIBUNICODENAMES uninm_names_db_close(names_db); /* close this database before exiting */ uninm_blocks_db_close(blocks_db); #endif lt_dlexit(); return( 0 ); }
int fontforge_main( int argc, char **argv ) { extern const char *source_modtime_str; extern const char *source_version_str; const char *load_prefs = getenv("FONTFORGE_LOADPREFS"); int i; int recover=2; int any; int next_recent=0; GRect pos; GWindowAttrs wattrs; char *display = NULL; FontRequest rq; int ds, ld; int openflags=0; int doopen=0, quit_request=0; #if defined(__Mac) int local_x; #endif fprintf( stderr, "Copyright (c) 2000-2012 by George Williams.\n Executable based on sources from %s" "-ML" #ifdef FREETYPE_HAS_DEBUGGER "-TtfDb" #endif #ifdef _NO_PYTHON "-NoPython" #endif #ifdef FONTFORGE_CONFIG_USE_DOUBLE "-D" #endif ".\n", source_modtime_str ); fprintf( stderr, " Library based on sources from %s.\n", library_version_configuration.library_source_modtime_string ); /* Must be done before we cache the current directory */ /* Change to HOME dir if specified on the commandline */ for ( i=1; i<argc; ++i ) { char *pt = argv[i]; if ( pt[0]=='-' && pt[1]=='-' ) ++pt; #ifndef __Mac if (strcmp(pt,"-home")==0) { #else if (strcmp(pt,"-home")==0 || strncmp(pt,"-psn_",5)==0) { /* OK, I don't know what _-psn_ means, but to GW it means */ /* we've been started on the mac from the FontForge.app */ /* structure, and the current directory is (shudder) "/" */ #endif if (getenv("HOME")!=NULL) chdir(getenv("HOME")); break; /* Done - Unnecessary to check more arguments */ } } #if defined(__Mac) /* Start X if they haven't already done so. Well... try anyway */ /* Must be before we change DYLD_LIBRARY_PATH or X won't start */ /* (osascript depends on a libjpeg which isn't found if we look in /sw/lib first */ local_x = uses_local_x(argc,argv); if ( local_x==1 && getenv("DISPLAY")==NULL ) { /* Don't start X if we're just going to quit. */ /* if X exists, it isn't needed. If X doesn't exist it's wrong */ if ( !hasquit(argc,argv)) { #if 1 /* This sequence is supposed to bring up an app without a window */ /* but X still opens an xterm */ system( "osascript -e 'tell application \"X11\" to launch'" ); system( "osascript -e 'tell application \"X11\" to activate'" ); #else system( "open /Applications/Utilities/X11.app/" ); #endif } setenv("DISPLAY",":0.0",0); } else if ( local_x==1 && *getenv("DISPLAY")!='/' && strcmp(getenv("DISPLAY"),":0.0")!=0 && strcmp(getenv("DISPLAY"),":0")!=0 ) /* 10.5.7 uses a named socket or something "/tmp/launch-01ftWX:0" */ local_x = 0; #endif #if defined(__MINGW32__) if( getenv("DISPLAY")==NULL ) { putenv("DISPLAY=127.0.0.1:0.0"); } if( getenv("LC_ALL")==NULL ){ char lang[8]; char env[32]; if( GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, lang, 8) > 0 ){ strcpy(env, "LC_ALL="); strcat(env, lang); putenv(env); } } #endif FF_SetUiInterface(&gdraw_ui_interface); FF_SetPrefsInterface(&gdraw_prefs_interface); FF_SetSCInterface(&gdraw_sc_interface); FF_SetCVInterface(&gdraw_cv_interface); FF_SetBCInterface(&gdraw_bc_interface); FF_SetFVInterface(&gdraw_fv_interface); FF_SetFIInterface(&gdraw_fi_interface); FF_SetMVInterface(&gdraw_mv_interface); FF_SetClipInterface(&gdraw_clip_interface); #ifndef _NO_PYTHON PythonUI_Init(); #endif InitSimpleStuff(); FindProgDir(argv[0]); #if defined(__MINGW32__) { char path[MAX_PATH+4]; char *c = path; unsigned int len = GetModuleFileNameA(NULL, path, MAX_PATH); path[len] = '\0'; for(; *c; *c++) /* backslash to slash */ if(*c == '\\') *c = '/'; GResourceSetProg(path); } #else GResourceSetProg(argv[0]); #endif #if defined(__Mac) /* The mac seems to default to the "C" locale, LANG and LC_MESSAGES are not*/ /* defined. This means that gettext will not bother to look up any message*/ /* files -- even if we have a "C" or "POSIX" entry in the locale diretory */ /* Now if X11 gives us the command key, I want to force a rebinding to use */ /* Cmd rather than Control key -- more mac-like. But I can't do that if */ /* there is no locale. So I force a locale if there is none specified */ /* I force the US English locale, because that's the what the messages are */ /* by default so I'm changing as little as I can. I think. */ /* Now the locale command will treat a LANG which is "" as undefined, but */ /* gettext will not. So I don't bother to check for null strings or "C" */ /* or "POSIX". If they've mucked with the locale perhaps they know what */ /* they are doing */ { int did_keybindings = 0; if ( local_x && !get_mac_x11_prop("enable_key_equivalents") ) { /* Ok, we get the command key */ if ( getenv("LANG")==NULL && getenv("LC_MESSAGES")==NULL ) { setenv("LC_MESSAGES","en_US.UTF-8",0); } /* Can we find a set of keybindings designed for the mac with cmd key? */ bind_textdomain_codeset("Mac-FontForge-MenuShortCuts","UTF-8"); bindtextdomain("Mac-FontForge-MenuShortCuts", getLocaleDir()); if ( *dgettext("Mac-FontForge-MenuShortCuts","Flag0x10+")!='F' ) { GMenuSetShortcutDomain("Mac-FontForge-MenuShortCuts"); did_keybindings = 1; } } if ( !did_keybindings ) { /* Nope. we can't. Fall back to the normal stuff */ #endif GMenuSetShortcutDomain("FontForge-MenuShortCuts"); bind_textdomain_codeset("FontForge-MenuShortCuts","UTF-8"); bindtextdomain("FontForge-MenuShortCuts", getLocaleDir()); #if defined(__Mac) }} #endif bind_textdomain_codeset("FontForge","UTF-8"); bindtextdomain("FontForge", getLocaleDir()); textdomain("FontForge"); GResourceUseGetText(); #if defined(__MINGW32__) { size_t len = strlen(GResourceProgramDir); char* path = galloc(len + 64); strcpy(path, GResourceProgramDir); strcpy(path+len, "/share/fontforge/pixmaps"); /* PixmapDir */ GGadgetSetImageDir(path); strcpy(path+len, "/share/fontforge/resources/fontforge.resource"); /* Resource File */ GResourceAddResourceFile(path, GResourceProgramName, false); gfree(path); } #elif defined(SHAREDIR) GGadgetSetImageDir(SHAREDIR "/pixmaps"); GResourceAddResourceFile(SHAREDIR "/resources/fontforge.resource",GResourceProgramName,false); #endif hotkeysLoad(); if ( load_prefs!=NULL && strcasecmp(load_prefs,"Always")==0 ) LoadPrefs(); if ( default_encoding==NULL ) default_encoding=FindOrMakeEncoding("ISO8859-1"); if ( default_encoding==NULL ) default_encoding=&custom; /* In case iconv is broken */ CheckIsScript(argc,argv); /* Will run the script and exit if it is a script */ /* If there is no UI, there is always a script */ /* and we will never return from the above */ if ( load_prefs==NULL || (strcasecmp(load_prefs,"Always")!=0 && /* Already loaded */ strcasecmp(load_prefs,"Never")!=0 )) LoadPrefs(); GrokNavigationMask(); for ( i=1; i<argc; ++i ) { char *pt = argv[i]; if ( pt[0]=='-' && pt[1]=='-' ) ++pt; if ( strcmp(pt,"-sync")==0 ) GResourceAddResourceString("Gdraw.Synchronize: true",argv[0]); else if ( strcmp(pt,"-depth")==0 && i<argc-1 ) AddR(argv[0],"Gdraw.Depth", argv[++i]); else if ( strcmp(pt,"-vc")==0 && i<argc-1 ) AddR(argv[0],"Gdraw.VisualClass", argv[++i]); else if ( (strcmp(pt,"-cmap")==0 || strcmp(pt,"-colormap")==0) && i<argc-1 ) AddR(argv[0],"Gdraw.Colormap", argv[++i]); else if ( (strcmp(pt,"-dontopenxdevices")==0) ) AddR(argv[0],"Gdraw.DontOpenXDevices", "true"); else if ( strcmp(pt,"-keyboard")==0 && i<argc-1 ) AddR(argv[0],"Gdraw.Keyboard", argv[++i]); else if ( strcmp(pt,"-display")==0 && i<argc-1 ) display = argv[++i]; # if MyMemory else if ( strcmp(pt,"-memory")==0 ) __malloc_debug(5); # endif else if ( strncmp(pt,"-usecairo",strlen("-usecairo"))==0 ) { if ( strcmp(pt,"-usecairo=no")==0 ) GDrawEnableCairo(false); else GDrawEnableCairo(true); } else if ( strcmp(pt,"-nosplash")==0 ) splash = 0; else if ( strcmp(pt,"-unique")==0 ) unique = 1; else if ( strcmp(pt,"-recover")==0 && i<argc-1 ) { ++i; if ( strcmp(argv[i],"none")==0 ) recover=0; else if ( strcmp(argv[i],"clean")==0 ) recover= -1; else if ( strcmp(argv[i],"auto")==0 ) recover= 1; else if ( strcmp(argv[i],"inquire")==0 ) recover= 2; else { fprintf( stderr, "Invalid argument to -recover, must be none, auto, inquire or clean\n" ); dousage(); } } else if ( strcmp(pt,"-recover=none")==0 ) { recover = 0; } else if ( strcmp(pt,"-recover=clean")==0 ) { recover = -1; } else if ( strcmp(pt,"-recover=auto")==0 ) { recover = 1; } else if ( strcmp(pt,"-recover=inquire")==0 ) { recover = 2; } else if ( strcmp(pt,"-docs")==0 ) dohelp(); else if ( strcmp(pt,"-help")==0 ) dousage(); else if ( strcmp(pt,"-version")==0 ) doversion(source_version_str); else if ( strcmp(pt,"-quit")==0 ) quit_request = true; else if ( strcmp(pt,"-home")==0 ) /* already did a chdir earlier, don't need to do it again */; #if defined(__Mac) else if ( strncmp(pt,"-psn_",5)==0 ) { /* OK, I don't know what _-psn_ means, but to GW it means */ /* we've been started on the mac from the FontForge.app */ /* structure, and the current directory was (shudder) "/" */ /* (however, we changed to HOME earlier in main routine). */ unique = 1; listen_to_apple_events = true; } #endif } ensureDotFontForgeIsSetup(); GDrawCreateDisplays(display,argv[0]); default_background = GDrawGetDefaultBackground(screen_display); InitToolIconClut(default_background); InitToolIcons(); InitCursors(); #ifndef _NO_PYTHON PyFF_ProcessInitFiles(); #endif /* Wait until the UI has started, otherwise people who don't have consoles*/ /* open won't get our error messages, and it's an important one */ /* Scripting doesn't care about a mismatch, because scripting interpretation */ /* all lives in the library */ check_library_version(&exe_library_version_configuration,true,false); /* the splash screen used not to have a title bar (wam_nodecor) */ /* but I found I needed to know how much the window manager moved */ /* the window around, which I can determine if I have a positioned */ /* decorated window created at the begining */ /* Actually I don't care any more */ wattrs.mask = wam_events|wam_cursor|wam_bordwidth|wam_backcol|wam_positioned|wam_utf8_wtitle|wam_isdlg; wattrs.event_masks = ~(1<<et_charup); wattrs.positioned = 1; wattrs.cursor = ct_pointer; wattrs.utf8_window_title = "FontForge"; wattrs.border_width = 2; wattrs.background_color = 0xffffff; wattrs.is_dlg = !listen_to_apple_events; pos.x = pos.y = 200; pos.width = splashimage.u.image->width; pos.height = splashimage.u.image->height-56; /* 54 */ GDrawBindSelection(NULL,sn_user1,"FontForge"); if ( unique && GDrawSelectionOwned(NULL,sn_user1)) { /* Different event handler, not a dialog */ wattrs.is_dlg = false; splashw = GDrawCreateTopWindow(NULL,&pos,request_e_h,NULL,&wattrs); PingOtherFontForge(argc,argv); } else { if ( quit_request ) exit( 0 ); splashw = GDrawCreateTopWindow(NULL,&pos,splash_e_h,NULL,&wattrs); } memset(&rq,0,sizeof(rq)); rq.utf8_family_name = SERIF_UI_FAMILIES; rq.point_size = 12; rq.weight = 400; splash_font = GDrawInstanciateFont(NULL,&rq); splash_font = GResourceFindFont("Splash.Font",splash_font); GDrawDecomposeFont(splash_font, &rq); rq.style = fs_italic; splash_italic = GDrawInstanciateFont(NULL,&rq); splash_italic = GResourceFindFont("Splash.ItalicFont",splash_italic); GDrawSetFont(splashw,splash_font); GDrawWindowFontMetrics(splashw,splash_font,&as,&ds,&ld); fh = as+ds+ld; SplashLayout(); localsplash = splash; if ( localsplash && !listen_to_apple_events ) start_splash_screen(); if ( AutoSaveFrequency>0 ) autosave_timer=GDrawRequestTimer(splashw,2*AutoSaveFrequency*1000,AutoSaveFrequency*1000,NULL); GDrawProcessPendingEvents(NULL); GDrawSetBuildCharHooks(BuildCharHook,InsCharHook); any = 0; if ( recover==-1 ) CleanAutoRecovery(); else if ( recover ) any = DoAutoRecovery(recover-1); openflags = 0; for ( i=1; i<argc; ++i ) { char buffer[1025]; char *pt = argv[i]; GDrawProcessPendingEvents(NULL); if ( pt[0]=='-' && pt[1]=='-' ) ++pt; if ( strcmp(pt,"-new")==0 ) { FontNew(); any = 1; # if HANYANG } else if ( strcmp(pt,"-newkorean")==0 ) { MenuNewComposition(NULL,NULL,NULL); any = 1; # endif } else if ( strcmp(pt,"-last")==0 ) { if ( next_recent<RECENT_MAX && RecentFiles[next_recent]!=NULL ) if ( ViewPostScriptFont(RecentFiles[next_recent++],openflags)) any = 1; } else if ( strcmp(pt,"-sync")==0 || strcmp(pt,"-memory")==0 || strcmp(pt,"-nosplash")==0 || strcmp(pt,"-recover=none")==0 || strcmp(pt,"-recover=clean")==0 || strcmp(pt,"-recover=auto")==0 || strcmp(pt,"-dontopenxdevices")==0 || strcmp(pt,"-unique")==0 || strncmp(pt,"-usecairo",strlen("-usecairo"))==0 || strcmp(pt,"-home")==0 ) /* Already done, needed to be before display opened */; else if ( strncmp(pt,"-psn_",5)==0 ) /* Already done */; else if ( (strcmp(pt,"-depth")==0 || strcmp(pt,"-vc")==0 || strcmp(pt,"-cmap")==0 || strcmp(pt,"-colormap")==0 || strcmp(pt,"-keyboard")==0 || strcmp(pt,"-display")==0 || strcmp(pt,"-recover")==0 ) && i<argc-1 ) ++i; /* Already done, needed to be before display opened */ else if ( strcmp(pt,"-allglyphs")==0 ) openflags |= of_all_glyphs_in_ttc; else if ( strcmp(pt,"-open")==0 ) doopen = true; else { if ( strstr(argv[i],"://")!=NULL ) { /* Assume an absolute URL */ strncpy(buffer,argv[i],sizeof(buffer)); buffer[sizeof(buffer)-1]= '\0'; } else GFileGetAbsoluteName(argv[i],buffer,sizeof(buffer)); if ( GFileIsDir(buffer) || (strstr(buffer,"://")!=NULL && buffer[strlen(buffer)-1]=='/')) { char *fname; fname = galloc(strlen(buffer)+strlen("/glyphs/contents.plist")+1); strcpy(fname,buffer); strcat(fname,"/glyphs/contents.plist"); if ( GFileExists(fname)) { /* It's probably a Unified Font Object directory */ free(fname); if ( ViewPostScriptFont(buffer,openflags) ) any = 1; } else { strcpy(fname,buffer); strcat(fname,"/font.props"); if ( GFileExists(fname)) { /* It's probably a sf dir collection */ free(fname); if ( ViewPostScriptFont(buffer,openflags) ) any = 1; } else { free(fname); if ( buffer[strlen(buffer)-1]!='/' ) { /* If dirname doesn't end in "/" we'll be looking in parent dir */ buffer[strlen(buffer)+1]='\0'; buffer[strlen(buffer)] = '/'; } fname = GetPostScriptFontName(buffer,false); if ( fname!=NULL ) ViewPostScriptFont(fname,openflags); any = 1; /* Even if we didn't get a font, don't bring up dlg again */ free(fname); } } } else if ( ViewPostScriptFont(buffer,openflags)!=0 ) any = 1; } } if ( !any && !doopen ) any = ReopenLastFonts(); #if defined(__Mac) if ( listen_to_apple_events ) { install_apple_event_handlers(); install_mac_timer(); RunApplicationEventLoop(); } else #endif if ( doopen || !any ) MenuOpen(NULL,NULL,NULL); GDrawEventLoop(NULL); hotkeysSave(); uninm_names_db_close(names_db); lt_dlexit(); return( 0 ); }