Example #1
0
void FVOutline(FontViewBase *fv, real width) {
    StrokeInfo si;
    SplineSet *temp, *spl;
    int i, cnt=0, changed, gid;
    SplineChar *sc;
    int layer = fv->active_layer;

    for ( i=0; i<fv->map->enccount; ++i )
	if ( (gid=fv->map->map[i])!=-1 && (sc=fv->sf->glyphs[gid])!=NULL &&
		fv->selected[i] && sc->layers[layer].splines )
	    ++cnt;
    ff_progress_start_indicator(10,_("Outlining glyphs"),_("Outlining glyphs"),0,cnt,1);

    memset(&si,0,sizeof(si));
    si.removeexternal = true;
    si.radius = width;
    /*si.removeoverlapifneeded = true;*/

    SFUntickAll(fv->sf);
    for ( i=0; i<fv->map->enccount; ++i )
	if ( (gid=fv->map->map[i])!=-1 && (sc=fv->sf->glyphs[gid])!=NULL && fv->selected[i] &&
		sc->layers[layer].splines && !sc->ticked ) {
	    sc->ticked = true;
	    SCPreserveLayer(sc,layer,false);
	    temp = SplineSetStroke(sc->layers[layer].splines,&si,sc->layers[layer].order2);
	    for ( spl=sc->layers[layer].splines; spl->next!=NULL; spl=spl->next );
	    spl->next = temp;
	    SplineSetsCorrect(sc->layers[layer].splines,&changed);
	    SCCharChangedUpdate(sc,layer);
	    if ( !ff_progress_next())
    break;
	}
    ff_progress_end_indicator();
}
Example #2
0
/*  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 );
}
Example #3
0
static int FtpURLAndTempFile(const char *url,FILE **to,FILE *from) {
    struct sockaddr_in addr, data_addr;
    char *host, *filename, *username, *password;
    int port;
    FILE *ret;
    char buffer[300];
    int soc, data;
    int datalen, len;
    char *databuf, *cmd;

    if ( from==NULL ) {
	snprintf(buffer,sizeof(buffer),_("Downloading from %s"), url);
	*to = NULL;
    } else
	snprintf(buffer,sizeof(buffer),_("Uploading to %s"), url);

    if ( strncasecmp(url,"ftp://",6)!=0 ) {
	ff_post_error(_("Could not parse URL"),_("Got something else when expecting an ftp URL"));
return( false );
    }
    filename = decomposeURL(url, &host, &port, &username, &password);

    ff_progress_start_indicator(0,_("Font Download..."),buffer,
	    _("Resolving host"),1,1);
    ff_progress_enable_stop(false);
    ff_progress_allow_events();
    ff_progress_allow_events();

    if ( !findFTPhost(&addr, host, port)) {
	ff_progress_end_indicator();
	ff_post_error(_("Could not find host"),_("Could not find \"%s\"\nAre you connected to the internet?"), host );
	free( host ); free( filename );
return( false );
    }
    soc = makeConnection(&addr);
    if ( soc==-1 ) {
	ff_progress_end_indicator();
	ff_post_error(_("Could not connect to host"),_("Could not connect to \"%s\"."), host );
	free( host ); free( filename );
return( false );
    }

    datalen = 8*8*1024;
    databuf = malloc(datalen+1);
    cmd = databuf;

    ChangeLine2_8(_("Logging in..."));
    if ( getresponse(soc,databuf,datalen) == -1 ) {		/* ftp servers say "Hi" when then connect */
	ff_progress_end_indicator();
	ff_post_error(_("Could not connect to host"),_("Could not connect to \"%s\"."), host );
	free( host ); free( filename ); free(username); free(password);
	close( soc );
return( false );
    }
    free( host );

    if ( username==NULL ) {
	username=copy("anonymous");
	if ( password==NULL )
	    password=copy("FontForge");
    } else if ( password==NULL )
	password = copy("");
    
    sprintf(cmd,"USER %s\r\n", username);
    if ( ftpsendr(soc,cmd,databuf,datalen)== -1 ) {
	ff_progress_end_indicator();
	close( soc ); free(filename); free(databuf); free(username); free(password);
return( false );
    }
    sprintf(cmd,"PASS %s\r\n", password);
    free(username); free(password);
    if ( ftpsendr(soc,cmd,databuf,datalen)<=0 ) {
	ff_progress_end_indicator();
	LogError(_("Bad Username/Password\n"));
	close( soc ); free(filename); free(databuf);
return( false );
    }

    if ( ftpsendr(soc,"TYPE I\r\n",databuf,datalen)==-1 ) {	/* Binary */
	ff_progress_end_indicator();
	close( soc ); free(filename); free(databuf);
return( false );
    }

    if ( from==NULL )
	ChangeLine2_8(_("Requesting font..."));
    else
	ChangeLine2_8(_("Transmitting font..."));
	
    if ( ftpsendpassive(soc,&data_addr,databuf,datalen)<= 0 ) {
	ff_progress_end_indicator();
	close( soc ); free(filename); free(databuf);
return( false );
    }
    if (( data = socket(PF_INET,SOCK_STREAM,0))==-1 ||
	    connect(data,(struct sockaddr *) &data_addr,sizeof(data_addr))== -1 ) {
	ff_progress_end_indicator();
	if ( data!=-1 )
	    close(data);
	close( soc ); free(filename); free(databuf);
	LogError(_("FTP passive Data Connect failed\n"));
return( 0 );
    }

    if ( from==NULL ) {
	sprintf(cmd,"RETR %s\r\n", filename);
	if ( ftpsendr(soc,cmd, databuf, datalen)<=0 ) {
	    ff_progress_end_indicator();
	    ff_post_error(_("Could not download data"),_("Could not find file.") );
	    close(data);
	    close( soc ); free(filename); free(databuf);
return( false );
	}

	ChangeLine2_8(_("Downloading font..."));

	ret = tmpfile();

	while ((len = read(data,databuf,datalen))>0 ) {
	    fwrite(databuf,1,len,ret);
	}
	*to = ret;
	rewind(ret);
    } else {
	sprintf(cmd,"STOR %s\r\n", filename);
	if ( ftpsendr(soc,cmd, databuf, datalen)<=0 ) {
	    ff_progress_end_indicator();
	    ff_post_error(_("Could not download data"),_("Could not find file.") );
	    close(data);
	    close( soc ); free(filename); free(databuf);
return( false );
	}

	ChangeLine2_8(_("Uploading font..."));

	rewind(from);
	while ((len = fread(databuf,1,datalen,from))>0 ) {
	    if ( (len = write(data,databuf,len))<0 )
	break;
	}
	ret = NULL;
    }
    ff_progress_end_indicator();
    close( soc ); close( data );
    free( databuf );
    free( filename );
    if ( len==-1 ) {
	ff_post_error(_("Could not transmit data"),_("Could not transmit data.") );
	if ( ret!=NULL ) fclose(ret);
return( false );
    }
return( true );
}
Example #4
0
static FILE *HttpURLToTempFile(const char *url, void *_lock) {
    pthread_mutex_t *lock = _lock;
    struct sockaddr_in addr;
    char *pt, *host, *filename, *username, *password;
    int port;
    FILE *ret;
    char buffer[300];
    int first, code;
    int soc;
    int datalen, len;
    char *databuf;

    snprintf(buffer,sizeof(buffer),_("Downloading from %s"), url);

    if ( strncasecmp(url,"http://",7)!=0 ) {
	if ( lock!=NULL )
	    pthread_mutex_lock(lock);
	ff_post_error(_("Could not parse URL"),_("Got something else when expecting an http URL"));
	if ( lock!=NULL )
	    pthread_mutex_unlock(lock);
return( NULL );
    }
    if ( lock!=NULL )
	pthread_mutex_lock(lock);
    filename = decomposeURL(url, &host, &port, &username, &password);
    /* I don't support username/passwords for http */
    free( username ); free( password );
    if ( lock!=NULL )
	pthread_mutex_unlock(lock);

    if ( lock==NULL ) {
	ff_progress_start_indicator(0,_("Font Download..."),buffer,
		_("Resolving host"),1,1);
	ff_progress_enable_stop(false);
	ff_progress_allow_events();
	ff_progress_allow_events();
    }

    /* This routine contains it's own lock */
    if ( !findHTTPhost(&addr, host, port)) {
	if ( lock==NULL )
	    ff_progress_end_indicator();
	else
	    pthread_mutex_lock(lock);
	ff_post_error(_("Could not find host"),_("Could not find \"%s\"\nAre you connected to the internet?"), host );
	free( host ); free( filename );
	if ( lock!=NULL )
	    pthread_mutex_unlock(lock);
return( false );
    }
    soc = makeConnection(&addr);
    if ( soc==-1 ) {
	if ( lock==NULL )
	    ff_progress_end_indicator();
	else
	    pthread_mutex_lock(lock);
	ff_post_error(_("Could not connect to host"),_("Could not connect to \"%s\"."), host );
	free( host ); free( filename );
	if ( lock!=NULL )
	    pthread_mutex_unlock(lock);
return( false );
    }

    if ( lock!=NULL )
	pthread_mutex_lock(lock);
    datalen = 8*8*1024;
    databuf = malloc(datalen+1);
    if ( lock!=NULL )
	pthread_mutex_unlock(lock);
    else
	ChangeLine2_8(_("Requesting font..."));

    sprintf( databuf,"GET %s HTTP/1.1\r\n"
	"Host: %s\r\n"
	"User-Agent: FontForge\r\n"
	"Connection: close\r\n\r\n", filename, host );
    if ( write(soc,databuf,strlen(databuf))==-1 ) {
	if ( lock==NULL )
	    ff_progress_end_indicator();
	if ( lock!=NULL )
	    pthread_mutex_lock(lock);
	ff_post_error(_("Could not send request"),_("Could not send request to \"%s\"."), host );
	close( soc );
	free( databuf );
	free( host ); free( filename );
	free( host ); free( filename );
	if ( lock!=NULL )
	    pthread_mutex_unlock(lock);
return( NULL );
    }

    if ( lock==NULL )
	ChangeLine2_8(_("Downloading font..."));

    if ( lock!=NULL )
	pthread_mutex_lock(lock);
    ret = tmpfile();
    if ( lock!=NULL )
	pthread_mutex_unlock(lock);

    first = 1;
    code = 404;
    while ((len = read(soc,databuf,datalen))>0 ) {
	if ( first ) {
	    databuf[len] = '\0';
	    sscanf(databuf,"HTTP/%*f %d", &code );
	    first = 0;
	    /* check for redirects */
	    if ( code>=300 && code<399 && (pt=strstr(databuf,"Location: "))!=NULL ) {
		char *newurl = pt + strlen("Location: ");
		pt = strchr(newurl,'\r');
		if ( *pt )
		    *pt = '\0';
		close( soc );
		if ( lock!=NULL )
		    pthread_mutex_lock(lock);
		fclose(ret);
		free(host); free( filename );
		free(databuf);
		if ( lock!=NULL )
		    pthread_mutex_unlock(lock);
		ret = URLToTempFile(newurl,lock);
return( ret );
	    }
	    pt = strstr(databuf,"Content-Length: ");
	    if ( lock==NULL && pt!=NULL ) {
		pt += strlen( "Content-Length: ");
		ff_progress_change_total(strtol(pt,NULL,10));
	    }
	    pt = strstr(databuf,"\r\n\r\n");
	    if ( pt!=NULL ) {
		pt += strlen("\r\n\r\n");
		fwrite(pt,1,len-(pt-databuf),ret);
		if ( lock==NULL )
		    ff_progress_increment(len-(pt-databuf));
	    }
	} else {
	    fwrite(databuf,1,len,ret);
	    if ( lock==NULL )
		ff_progress_increment(len);
	}
    }
    if ( lock==NULL )
	ff_progress_end_indicator();
    close( soc );
    free( databuf );
    if ( lock!=NULL )
	pthread_mutex_lock(lock);
    free( host ); free( filename );
    if ( len==-1 ) {
	ff_post_error(_("Could not download data"),_("Could not download data.") );
	fclose(ret);
	ret = NULL;
    } else if ( code<200 || code>299 ) {
	ff_post_error(_("Could not download data"),_("HTTP return code: %d."), code );
	fclose(ret);
	ret = NULL;
    } else
	rewind(ret);
    if ( lock!=NULL )
	pthread_mutex_unlock(lock);
return( ret );
}