int _ExportEPS(FILE *eps,SplineChar *sc, int layer, int preview) { DBounds b; time_t now; struct tm *tm; int ret; char oldloc[24]; const char *author = GetAuthor(); strcpy( oldloc,setlocale(LC_NUMERIC,NULL) ); setlocale(LC_NUMERIC,"C"); fprintf( eps, "%%!PS-Adobe-3.0 EPSF-3.0\n" ); SplineCharLayerFindBounds(sc,layer,&b); fprintf( eps, "%%%%BoundingBox: %g %g %g %g\n", (double) b.minx, (double) b.miny, (double) b.maxx, (double) b.maxy ); fprintf( eps, "%%%%Pages: 0\n" ); fprintf( eps, "%%%%Title: %s from %s\n", sc->name, sc->parent->fontname ); fprintf( eps, "%%%%Creator: FontForge\n" ); if ( author!=NULL ) fprintf( eps, "%%%%Author: %s\n", author); time(&now); tm = localtime(&now); fprintf( eps, "%%%%CreationDate: %d:%02d %d-%d-%d\n", tm->tm_hour, tm->tm_min, tm->tm_mday, tm->tm_mon+1, 1900+tm->tm_year ); if ( sc->parent->multilayer ) { int ly, had_grad=0, had_pat=0; for ( ly=ly_fore; ly<sc->layer_cnt; ++ly ) { if ( sc->layers[ly].fill_brush.gradient!=NULL || sc->layers[ly].stroke_pen.brush.gradient!=NULL ) { had_grad = true; break; } if ( sc->layers[ly].fill_brush.gradient!=NULL || sc->layers[ly].stroke_pen.brush.gradient!=NULL ) had_pat = true; } if ( had_grad ) fprintf( eps, "%%%%LanguageLevel: 3\n" ); else if ( had_pat ) fprintf( eps, "%%%%LanguageLevel: 2\n" ); } fprintf( eps, "%%%%EndComments\n" ); if ( preview ) EpsGeneratePreview(eps,sc,layer,&b); fprintf( eps, "%%%%EndProlog\n" ); fprintf( eps, "%%%%Page \"%s\" 1\n", sc->name ); fprintf( eps, "gsave newpath\n" ); SC_PSDump((void (*)(int,void *)) fputc,eps,sc,true,false,layer); if ( sc->parent->multilayer ) fprintf( eps, "grestore\n" ); else if ( sc->parent->strokedfont ) fprintf( eps, "%g setlinewidth stroke grestore\n", (double) sc->parent->strokewidth ); else fprintf( eps, "fill grestore\n" ); fprintf( eps, "%%%%EOF\n" ); ret = !ferror(eps); setlocale(LC_NUMERIC,oldloc); return( ret ); }
static void ApplyChanges(WidthInfo *wi) { EncMap *map = wi->fv->map; uint8 *rsel = calloc(map->enccount,sizeof(char)); int i, width; real transform[6]; struct charone *ch; DBounds bb; for ( i=0; i<wi->real_rcnt; ++i ) { int gid = map->map[wi->right[i]->sc->orig_pos]; if ( gid!=-1 ) rsel[gid] = true; } transform[0] = transform[3] = 1.0; transform[1] = transform[2] = transform[5] = 0; for ( i=0; i<wi->real_rcnt; ++i ) { ch = wi->right[i]; transform[4] = ch->newl-ch->lbearing; if ( transform[4]!=0 ) { FVTrans(wi->fv,ch->sc,transform,rsel,false); SCCharChangedUpdate(ch->sc,ly_none); } } free(rsel); for ( i=0; i<wi->real_lcnt; ++i ) { ch = wi->left[i]; SplineCharLayerFindBounds(ch->sc,wi->layer,&bb); width = rint(bb.maxx + ch->newr); if ( width!=ch->sc->width ) { SCPreserveWidth(ch->sc); SCSynchronizeWidth(ch->sc,width,ch->sc->width,wi->fv); SCCharChangedUpdate(ch->sc,ly_none); } } }
int _ExportPDF(FILE *pdf,SplineChar *sc,int layer) { /* TODO: Note, maybe this routine can be combined with print.c dump_pdfprologue() */ DBounds b; time_t now; struct tm *tm; int ret; char oldloc[24]; int _objlocs[8], xrefloc, streamstart, streamlength, resid = 0, nextobj; int *objlocs = _objlocs; const char *author = GetAuthor(); int i; SFUntickAll(sc->parent); locale_t tmplocale; locale_t oldlocale; // Declare temporary locale storage. switch_to_c_locale(&tmplocale, &oldlocale); // Switch to the C locale temporarily and cache the old locale. fprintf( pdf, "%%PDF-1.4\n%%\201\342\202\203\n" ); /* Header comment + binary comment */ /* Every document contains a catalog which points to a page tree, which */ /* in our case, points to a single page */ objlocs[1] = ftell(pdf); fprintf( pdf, "1 0 obj\n << /Type /Catalog\n /Pages 2 0 R\n /PageMode /UseNone\n >>\nendobj\n" ); objlocs[2] = ftell(pdf); fprintf( pdf, "2 0 obj\n << /Type /Pages\n /Kids [ 3 0 R ]\n /Count 1\n >>\nendobj\n" ); /* And our single page points to its contents */ objlocs[3] = ftell(pdf); fprintf( pdf, "3 0 obj\n" ); fprintf( pdf, " << /Type /Page\n" ); fprintf( pdf, " /Parent 2 0 R\n" ); fprintf( pdf, " /Resources " ); if ( sc->parent->multilayer ) { resid = ftell(pdf); fprintf( pdf, "000000 0 R\n" ); } else fprintf( pdf, "<< >>\n" ); SplineCharLayerFindBounds(sc,layer,&b); fprintf( pdf, " /MediaBox [%g %g %g %g]\n", (double) b.minx, (double) b.miny, (double) b.maxx, (double) b.maxy ); fprintf( pdf, " /Contents 4 0 R\n" ); fprintf( pdf, " >>\n" ); fprintf( pdf, "endobj\n" ); /* And the contents are the interesting stuff */ objlocs[4] = ftell(pdf); fprintf( pdf, "4 0 obj\n" ); fprintf( pdf, " << /Length 5 0 R >> \n" ); fprintf( pdf, " stream \n" ); streamstart = ftell(pdf); SC_PSDump((void (*)(int,void *)) fputc,pdf,sc,true,true,layer); if ( sc->parent->multilayer ) /* Already filled or stroked */; else if ( sc->parent->strokedfont ) fprintf( pdf, "%g w S\n", (double) sc->parent->strokewidth ); else fprintf( pdf, "f\n" ); streamlength = ftell(pdf)-streamstart; fprintf( pdf, " endstream\n" ); fprintf( pdf, "endobj\n" ); objlocs[5] = ftell(pdf); fprintf( pdf, "5 0 obj\n" ); fprintf( pdf, " %d\n", (int) streamlength ); fprintf( pdf, "endobj\n" ); /* Optional Info dict */ objlocs[6] = ftell(pdf); fprintf( pdf, "6 0 obj\n" ); fprintf( pdf, " <<\n" ); fprintf( pdf, " /Creator (FontForge)\n" ); time(&now); tm = localtime(&now); fprintf( pdf, " /CreationDate (D:%04d%02d%02d%02d%02d%02d", 1900+tm->tm_year, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec ); #ifdef _NO_TZSET fprintf( pdf, "Z)\n" ); #else tzset(); if ( timezone==0 ) fprintf( pdf, "Z)\n" ); else { if ( timezone<0 ) /* fprintf bug - this is a kludge to print +/- in front of a %02d-padded value */ fprintf( pdf, "-" ); else fprintf( pdf, "+" ); fprintf( pdf, "%02d'%02d')\n", (int)(timezone/3600),(int)(timezone/60-(timezone/3600)*60) ); } #endif fprintf( pdf, " /Title (%s from %s)\n", sc->name, sc->parent->fontname ); if ( author!=NULL ) fprintf( pdf, " /Author (%s)\n", author ); fprintf( pdf, " >>\n" ); nextobj = 7; if ( sc->parent->multilayer ) { PI pi; int resobj; memset(&pi,0,sizeof(pi)); pi.out = pdf; pi.max_object = 100; pi.object_offsets = malloc(pi.max_object*sizeof(int)); memcpy(pi.object_offsets,objlocs,nextobj*sizeof(int)); pi.next_object = nextobj; resobj = PdfDumpGlyphResources(&pi,sc); nextobj = pi.next_object; objlocs = pi.object_offsets; fseek(pdf,resid,SEEK_SET); fprintf(pdf,"%06d", resobj ); fseek(pdf,0,SEEK_END); } xrefloc = ftell(pdf); fprintf( pdf, "xref\n" ); fprintf( pdf, " 0 %d\n", nextobj ); fprintf( pdf, "0000000000 65535 f \n" ); for ( i=1; i<nextobj; ++i ) fprintf( pdf, "%010d %05d n \n", (int) objlocs[i], 0 ); fprintf( pdf, "trailer\n" ); fprintf( pdf, " <<\n" ); fprintf( pdf, " /Size %d\n", nextobj ); fprintf( pdf, " /Root 1 0 R\n" ); fprintf( pdf, " /Info 6 0 R\n" ); fprintf( pdf, " >>\n" ); fprintf( pdf, "startxref\n" ); fprintf( pdf, "%d\n", (int) xrefloc ); fprintf( pdf, "%%%%EOF\n" ); if ( objlocs!=_objlocs ) free(objlocs); ret = !ferror(pdf); switch_to_old_locale(&tmplocale, &oldlocale); // Switch to the cached locale. return( ret ); }
void AutoWidth2(FontViewBase *fv,int separation,int min_side,int max_side, int chunk_height, int loop_cnt) { struct scriptlist { uint32 script; AW_Glyph *glyphs; int gcnt; } *scripts; int scnt, smax; int enc, gid, s, i; SplineFont *sf = fv->sf; SplineChar *sc; AW_Data all; if ( chunk_height <= 0 ) chunk_height = (sf->ascent + sf->descent)/100; if ( loop_cnt <= 0 ) loop_cnt = 4; scnt = 0; smax = 10; scripts = malloc(smax*sizeof(struct scriptlist)); for ( gid=0; gid<sf->glyphcnt; ++gid ) { if ( (sc = sf->glyphs[gid])!=NULL ) sc->ticked = false; } for ( enc=0; enc<fv->map->enccount; ++enc ) { if ( fv->selected[enc] && (gid=fv->map->map[enc])!=-1 && (sc = sf->glyphs[gid])!=NULL && ! sc->ticked && HasUseMyMetrics(sc,fv->active_layer)==NULL ) { /* If Use My Metrics is set, then we can't change the width (which we grab from a refchar) */ uint32 script; script = SCScriptFromUnicode(sc); for ( s=0; s<scnt; ++s ) { if ( scripts[s].script == script ) break; } if ( s==scnt ) { if ( scnt>=smax ) scripts = realloc(scripts,(smax+=10)*sizeof(struct scriptlist)); memset(&scripts[scnt],0,sizeof(struct scriptlist)); scripts[scnt].script = script; scripts[scnt].glyphs = calloc(sf->glyphcnt+1,sizeof(AW_Glyph)); ++scnt; } i = scripts[s].gcnt; scripts[s].glyphs[i].sc = sc; SplineCharLayerFindBounds(sc,fv->active_layer,&scripts[s].glyphs[i].bb); if ( scripts[s].glyphs[i].bb.minx<-16000 || scripts[s].glyphs[i].bb.maxx>16000 || scripts[s].glyphs[i].bb.miny<-16000 || scripts[s].glyphs[i].bb.maxy>16000 ) ff_post_notice(_("Glyph too big"),_("%s has a bounding box which is too big for this algorithm to work. Ignored."),sc->name); else ++scripts[s].gcnt; } } memset(&all,0,sizeof(all)); all.sf = sf; all.fv = fv; all.layer = fv->active_layer; all.normalize = true; all.sub_height = chunk_height; all.loop_cnt = loop_cnt; all.desired_separation = separation; all.min_sidebearing = min_side; all.max_sidebearing = max_side; for ( s=0; s<scnt; ++s ) { memset(&scripts[s].glyphs[scripts[s].gcnt], 0, sizeof(AW_Glyph)); all.glyphs = scripts[s].glyphs; all.gcnt = scripts[s].gcnt; aw2_handlescript(&all); free(all.glyphs); } <<<<<<< HEAD