static OTLookup *CreateLookup(SplineFont1 *sf,uint32 tag, int sli, int flags,enum possub_type type) { OTLookup *otl = XZALLOC(OTLookup); otl->lookup_type = type == pst_position ? gpos_single : type == pst_pair ? gpos_pair : type == pst_contextpos ? gpos_context : type == pst_chainpos ? gpos_contextchain : type == pst_substitution ? gsub_single : type == pst_alternate ? gsub_alternate : type == pst_multiple ? gsub_multiple : type == pst_ligature ? gsub_ligature : type == pst_contextsub ? gsub_context : type == pst_chainsub ? gsub_contextchain : ot_undef; if ( otl->lookup_type == ot_undef ) IError("Unknown lookup type"); if ( otl->lookup_type<gpos_single ) { otl->next = sf->sf.gsub_lookups; sf->sf.gsub_lookups = otl; } else { otl->next = sf->sf.gpos_lookups; sf->sf.gpos_lookups = otl; } otl->lookup_flags = flags; otl->features = FeaturesFromTagSli(tag,sli,sf); /* We will set the lookup_index after we've ordered the list */ /* We will set the lookup_name after we've assigned the index */ /* We will add subtables as we need them */ return( otl ); }
static void IkarusAddContour(SplineChar *sc,int npts,BasePoint *bps, uint8 *ptype, int nesting) { SplinePointList *spl; SplinePoint *last, *next; int i, cw; spl = XZALLOC(SplinePointList); spl->next = sc->layers[ly_fore].splines; sc->layers[ly_fore].splines = spl; spl->first = spl->last = last = SplinePointCreate(bps[0].x,bps[0].y); last->pointtype = ptype[npts-1]; last->nextcpdef = last->prevcpdef = true; for ( i=1; i<npts-1; ++i ) { next = SplinePointCreate(bps[i].x,bps[i].y); next->nextcpdef = next->prevcpdef = true; next->pointtype = ptype[i]; SplineMake3(last,next); last = next; } SplineMake3(last,spl->last); last = spl->first; for ( i=1; i<npts; ++i ) { SplineCharDefaultPrevCP(last); SplineCharDefaultNextCP(last); last=last->next->to; } cw = SplinePointListIsClockwise(spl)==1; if ( ((nesting&1) && cw) || (!(nesting&1) && !cw) ) SplineSetReverse(spl); }
static FeatureScriptLangList *FeaturesFromTagSli(uint32 tag,int sli,SplineFont1 *sf) { FeatureScriptLangList *fl; struct script_record *sr; struct scriptlanglist *cur, *last; int i; fl = XZALLOC(FeatureScriptLangList); fl->featuretag = tag; if ( sli==SLI_NESTED || sli<0 || sli>=sf->sli_cnt ) return( fl ); last = NULL; for ( sr = sf->script_lang[sli]; sr->script!=0; ++sr ) { cur = XZALLOC(struct scriptlanglist); cur->script = sr->script; for ( i=0; sr->langs[i]!=0; ++i ); cur->lang_cnt = i; if ( i>MAX_LANG ) cur->morelangs = malloc((i-MAX_LANG) * sizeof(uint32)); for ( i=0; sr->langs[i]!=0; ++i ) { if ( i<MAX_LANG ) cur->langs[i] = sr->langs[i]; else cur->morelangs[i-MAX_LANG] = sr->langs[i]; } if ( last==NULL ) fl->scripts = cur; else last->next = cur; last = cur; } return( fl ); }
static OTLookup *CreateMacLookup(SplineFont1 *sf,ASM1 *sm) { OTLookup *otl = XZALLOC(OTLookup); int i, ch; char *pt, *start; SplineChar *sc; otl->features = XZALLOC(FeatureScriptLangList); if ( sm->sm.type == asm_kern ) { otl->lookup_type = kern_statemachine; otl->next = sf->sf.gpos_lookups; sf->sf.gpos_lookups = otl; otl->features->featuretag = (sm->sm.flags&0x8000) ? CHR('v','k','r','n') : CHR('k','e','r','n'); } else { otl->lookup_type = sm->sm.type==asm_indic ? morx_indic : sm->sm.type==asm_context ? morx_context : morx_insert; otl->next = sf->sf.gsub_lookups; sf->sf.gsub_lookups = otl; otl->features->featuretag = (sm->feature<<16) | (sm->setting); otl->features->ismac = true; } otl->lookup_flags = 0; for ( i=4; i<sm->sm.class_cnt; ++i ) { for ( start=sm->sm.classes[i]; ; start = pt ) { while ( *start==' ' ) ++start; if ( *start=='\0' ) break; for ( pt=start ; *pt!='\0' && *pt!=' '; ++pt ); ch = *pt; *pt = '\0'; sc = SFGetChar(&sf->sf,-1,start); if ( sc!=NULL ) FListAppendScriptLang(otl->features,SCScriptFromUnicode(sc), DEFAULT_LANG); *pt = ch; } } /* We will set the lookup_index after we've ordered the list */ /* We will set the lookup_name after we've assigned the index */ /* We will add one subtable soon */ return( otl ); }
static void ACDisassociateLigatures(SplineFont1 *sf,AnchorClass1 *ac) { int gid,k; SplineFont1 *subsf; SplineChar *sc; AnchorPoint *ap, *lap; AnchorClass1 *lac; char *format; lac = XZALLOC(AnchorClass1); *lac = *ac; lac->ac.type = act_mklg; ac->ac.next = (AnchorClass *) lac; /* GT: Need to split some AnchorClasses into two classes, one for normal */ /* GT: base letters, and one for ligatures. So create a new AnchorClass */ /* GT: name for the ligature version */ format = _("Ligature %s"); lac->ac.name = malloc(strlen(ac->ac.name)+strlen(format)+1); sprintf( lac->ac.name, format, ac->ac.name ); k=0; do { subsf = sf->sf.subfontcnt==0 ? sf : (SplineFont1 *) (sf->sf.subfonts[k]); for ( gid=0; gid<subsf->sf.glyphcnt; ++gid ) if ( (sc=subsf->sf.glyphs[gid])!=NULL ) { for ( ap=sc->anchor; ap!=NULL; ap=ap->next ) { if ( ap->anchor!=(AnchorClass *) ac ) continue; if ( ap->type==at_mark ) { lap = XZALLOC(AnchorPoint); *lap = *ap; ap->next = lap; lap->anchor = (AnchorClass *) lac; } else if ( ap->type==at_baselig ) { ap->anchor = (AnchorClass *) lac; } } } ++k; } while ( k<sf->sf.subfontcnt ); }
static Group *_LoadGroupList(FILE *file, Group *parent, int expected_indent, struct gcontext *gc) { Group *g; char *n; int i, ch; Group **glist=NULL; int gmax = 0; if ( expected_indent!=gc->found_indent ) return( NULL ); n = loadString(file,gc); if ( n==NULL ) return( NULL ); g = XZALLOC(Group); g->parent = parent; g->name = n; if ( (ch = getc(file))==':' ) ch = getc(file); while ( ch==' ' ) ch = getc(file); if ( ch=='1' ) g->unique = true; else if ( ch!='0' ) return( NULL ); while ( (ch = getc(file))==' ' ); if ( ch=='"' ) { ungetc(ch,file); g->glyphs = loadString(file,gc); if ( g->glyphs==NULL ) return( NULL ); lineCountIndent(file,gc); } else if ( ch=='\n' || ch=='\r' ) { ungetc(ch,file); lineCountIndent(file,gc); for ( i=0 ;; ++i ) { if ( i>=gmax ) { gmax += 10; glist = realloc(glist,gmax*sizeof(Group *)); } glist[i] = _LoadGroupList(file, g, expected_indent+1, gc); if ( glist[i]==NULL ) break; } g->kid_cnt = i; if ( i!=0 ) { g->kids = malloc(i*sizeof(Group *)); memcpy(g->kids,glist,i*sizeof(Group *)); } } return( g ); }
Group *GroupCopy(Group *g) { int i; Group *gp; if ( g==NULL ) return( NULL ); gp = XZALLOC(Group); gp->name = copy(g->name); gp->glyphs = copy(g->glyphs); if ( g->kid_cnt!=0 ) { gp->kids = malloc((gp->kid_cnt=g->kid_cnt)*sizeof(Group *)); for ( i=0; i<g->kid_cnt; ++i ) { gp->kids[i] = GroupCopy(g->kids[i]); gp->kids[i]->parent = gp; } } return( gp ); }
/* * Allocate a new completion structure. */ Completion * completion_new (int fileflag) { Completion *cp = (Completion *) XZALLOC (Completion); cp->completions = gl_list_create_empty (GL_LINKED_LIST, completion_streq, NULL, (gl_listelement_dispose_fn) free, false); cp->matches = gl_list_create_empty (GL_LINKED_LIST, completion_streq, NULL, NULL, false); if (fileflag) { cp->path = astr_new (); cp->flags |= CFLAG_FILENAME; } return cp; }
static OTLookup *CreateACLookup(SplineFont1 *sf,AnchorClass1 *ac) { OTLookup *otl = XZALLOC(OTLookup); otl->lookup_type = ac->ac.type == act_mark ? gpos_mark2base : ac->ac.type == act_mkmk ? gpos_mark2mark : ac->ac.type == act_curs ? gpos_cursive : ac->ac.type == act_mklg ? gpos_mark2ligature : ot_undef; if ( otl->lookup_type == ot_undef ) IError("Unknown AnchorClass type"); otl->next = sf->sf.gpos_lookups; sf->sf.gpos_lookups = otl; otl->lookup_flags = ac->flags; otl->features = FeaturesFromTagSli(ac->feature_tag,ac->script_lang_index,sf); /* We will set the lookup_index after we've ordered the list */ /* We will set the lookup_name after we've assigned the index */ /* We will add one subtable soon */ return( otl ); }
/* * Save a reverse delta for doing undo. */ void undo_save (int type, Point pt, size_t osize, size_t size) { Undo *up; if (get_buffer_noundo (cur_bp) || undo_nosave) return; up = (Undo *) XZALLOC (Undo); up->type = type; up->n = pt.n; up->o = pt.o; if (!get_buffer_modified (cur_bp)) up->unchanged = true; if (type == UNDO_REPLACE_BLOCK) { Line * lp = get_buffer_pt (cur_bp).p; size_t n = get_buffer_pt (cur_bp).n; if (n > pt.n) do lp = get_line_prev (lp); while (--n > pt.n); else if (n < pt.n) do lp = get_line_next (lp); while (++n < pt.n); pt.p = lp; up->block.osize = osize; up->block.size = size; up->block.text = copy_text_block (pt, osize); } up->next = get_buffer_last_undop (cur_bp); set_buffer_last_undop (cur_bp, up); if (!doing_undo) set_buffer_next_undop (cur_bp, up); }
static int FNT_Load(FILE *fnt,SplineFont *sf) { struct fntheader fntheader; struct v3chars charinfo[258]; /* Max size */ int i, j, k, ch; uint32 base = ftell(fnt); char *pt, *spt, *temp; BDFFont *bdf; BDFChar *bdfc; memset(&fntheader,0,sizeof(fntheader)); fntheader.version = lgetushort(fnt); if ( fntheader.version != 0x200 && fntheader.version != 0x300 ) return( false ); fntheader.filesize = lgetlong(fnt); for ( i=0; i<60; ++i ) fntheader.copyright[i] = getc(fnt); fntheader.copyright[i] = '\0'; for ( --i; i>=0 && fntheader.copyright[i]==' '; --i ) fntheader.copyright[i] = '\0'; fntheader.type = lgetushort(fnt); if ( fntheader.type & (FNT_TYPE_VECTOR|FNT_TYPE_MEMORY|FNT_TYPE_DEVICE)) return( false ); fntheader.pointsize = lgetushort(fnt); fntheader.vertres = lgetushort(fnt); fntheader.hortres = lgetushort(fnt); fntheader.ascent = lgetushort(fnt); fntheader.internal_leading = lgetushort(fnt); fntheader.external_leading = lgetushort(fnt); fntheader.italic = getc(fnt); fntheader.underline = getc(fnt); fntheader.strikeout = getc(fnt); fntheader.weight = lgetushort(fnt); fntheader.charset = getc(fnt); fntheader.width = lgetushort(fnt); fntheader.height = lgetushort(fnt); fntheader.pitchfamily = getc(fnt); fntheader.avgwidth = lgetushort(fnt); fntheader.maxwidth = lgetushort(fnt); fntheader.firstchar = getc(fnt); fntheader.lastchar = getc(fnt); fntheader.defchar = getc(fnt); fntheader.breakchar = getc(fnt); fntheader.widthbytes = lgetushort(fnt); fntheader.deviceoffset = lgetlong(fnt); fntheader.faceoffset = lgetlong(fnt); fntheader.bitspointer = lgetlong(fnt); fntheader.bitsoffset = lgetlong(fnt); (void) getc(fnt); /* Not documented in the v2 spec but seems to be present */ if ( fntheader.version == 0x300 ) { fntheader.flags = lgetlong(fnt); if ( fntheader.flags & (FNT_FLAGS_ABCFIXED|FNT_FLAGS_ABCPROP|FNT_FLAGS_16COLOR|FNT_FLAGS_256COLOR|FNT_FLAGS_RGBCOLOR)) return( false ); fntheader.aspace = lgetushort(fnt); fntheader.bspace = lgetushort(fnt); fntheader.cspace = lgetushort(fnt); fntheader.coloroffset = lgetlong(fnt); for ( i=0; i<16; ++i ) /* Freetype thinks this is 4 */ (void) getc(fnt); } memset(charinfo,0,sizeof(charinfo)); for ( i=fntheader.firstchar; i<=fntheader.lastchar+2; ++i ) { charinfo[i].width = lgetushort(fnt); if ( fntheader.version==0x200 ) charinfo[i].offset = lgetushort(fnt); else charinfo[i].offset = lgetlong(fnt); } /* Set the font names and the pfminfo structure */ sf->pfminfo.pfmset = true; if ( fntheader.copyright[0]!='\0' ) sf->copyright = copy(fntheader.copyright); sf->weight = copy( fntheader.weight<=100 ? "Thin" : fntheader.weight<=200 ? "Extralight" : fntheader.weight<=300 ? "Light" : fntheader.weight<=400 ? "Normal" : fntheader.weight<=500 ? "Medium" : fntheader.weight<=600 ? "Demibold" : fntheader.weight<=700 ? "Bold" : fntheader.weight<=800 ? "Heavy" : fntheader.weight<=900 ? "Black" : "Nord" ); sf->pfminfo.weight = fntheader.weight; sf->pfminfo.panose[2] = fntheader.weight/100 + 1; fseek(fnt,base+fntheader.faceoffset,SEEK_SET); for ( i=0; (ch=getc(fnt))!=EOF && ch!=0; ++i ); sf->familyname = malloc(i+2); fseek(fnt,base+fntheader.faceoffset,SEEK_SET); for ( i=0; (ch=getc(fnt))!=EOF && ch!=0; ++i ) sf->familyname[i] = ch; sf->familyname[i] = '\0'; temp = malloc(i+50); strcpy(temp,sf->familyname); if ( fntheader.weight<=300 && fntheader.weight>500 ) { strcat(temp," "); strcat(temp,sf->weight); } if ( fntheader.italic ) strcat(temp," Italic"); sf->fullname = temp; sf->fontname = copy(sf->fullname); for ( pt=spt=sf->fontname; *spt; ++spt ) if ( *spt!=' ' ) *pt++ = *spt; *pt = '\0'; sf->pfminfo.pfmfamily = fntheader.pitchfamily; sf->pfminfo.panose[0] = 2; if ( (fntheader.pitchfamily&FNT_FAMILY_MASK)==FNT_FAMILY_SCRIPT ) sf->pfminfo.panose[0] = 3; sf->pfminfo.width = 5; /* No info about condensed/extended */ sf->pfminfo.panose[3] = 3; if ( !(fntheader.pitchfamily&FNT_PITCH_VARIABLE ) ) sf->pfminfo.panose[3] = 9; sf->pfminfo.linegap = (sf->ascent+sf->descent)*fntheader.external_leading/fntheader.height; if ( fntheader.italic ) sf->italicangle = 11.25; bdf = calloc(1,sizeof(BDFFont)); bdf->sf = sf; bdf->glyphcnt = sf->glyphcnt; bdf->glyphmax = sf->glyphmax; bdf->res = fntheader.vertres; bdf->pixelsize = rint(fntheader.pointsize*fntheader.vertres/72.27); bdf->glyphs = calloc(sf->glyphmax,sizeof(BDFChar *)); bdf->ascent = rint(.8*bdf->pixelsize); /* shouldn't use typographical ascent */ bdf->descent = bdf->pixelsize-bdf->ascent; for ( i=fntheader.firstchar; i<=fntheader.lastchar; ++i ) if ( charinfo[i].width!=0 ) { int gid = SFMakeChar(sf,sf->map,i)->orig_pos; if ( gid>=bdf->glyphcnt ) { if ( gid>=bdf->glyphmax ) bdf->glyphs = realloc(bdf->glyphs,(bdf->glyphmax=sf->glyphmax)*sizeof(BDFChar *)); memset(bdf->glyphs+bdf->glyphcnt,0,(sf->glyphcnt-bdf->glyphcnt)*sizeof(BDFChar *)); bdf->glyphcnt = sf->glyphcnt; } bdf->glyphs[gid] = bdfc = XZALLOC(BDFChar); memset( bdfc,'\0',sizeof( BDFChar )); bdfc->xmin = 0; bdfc->xmax = charinfo[i].width-1; bdfc->ymin = fntheader.ascent-fntheader.height; bdfc->ymax = fntheader.ascent-1; bdfc->width = charinfo[i].width; bdfc->vwidth = bdf->pixelsize; bdfc->bytes_per_line = (bdfc->xmax>>3)+1; bdfc->bitmap = calloc(bdfc->bytes_per_line*fntheader.height,sizeof(uint8)); bdfc->orig_pos = gid; bdfc->sc = sf->glyphs[gid]; bdfc->sc->widthset = true; fseek(fnt,base+charinfo[i].offset,SEEK_SET); for ( j=0; j<bdfc->bytes_per_line; ++j ) { for ( k=0; k<fntheader.height; ++k ) bdfc->bitmap[k*bdfc->bytes_per_line+j] = getc(fnt); } BCCompressBitmap(bdfc); if ( feof(fnt) ) return( false ); }
Marker * marker_new (void) { return (Marker *) XZALLOC (Marker); }