static void SFDCleanupAnchorClasses(SplineFont *sf) { AnchorClass *ac; AnchorPoint *ap; int i, j, scnt; #define S_MAX 100 uint32 scripts[S_MAX]; int merge=0; for ( ac = sf->anchor; ac!=NULL; ac=ac->next ) { if ( ((AnchorClass1 *) ac)->script_lang_index==0xffff ) { scnt = 0; for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL ) { for ( ap = sf->glyphs[i]->anchor; ap!=NULL && ap->anchor!=ac; ap=ap->next ); if ( ap!=NULL && scnt<S_MAX ) { uint32 script = SCScriptFromUnicode(sf->glyphs[i]); if ( script==0 ) continue; for ( j=0; j<scnt; ++j ) if ( scripts[j]==script ) break; if ( j==scnt ) scripts[scnt++] = script; } } ((AnchorClass1 *) ac)->script_lang_index = SFAddScriptIndex((SplineFont1 *) sf,scripts,scnt); } if ( ((AnchorClass1 *) ac)->merge_with == 0xffff ) ((AnchorClass1 *) ac)->merge_with = ++merge; } #undef S_MAX }
static void SFGuessScriptList(SplineFont1 *sf) { uint32_t scripts[32], script; int i, scnt=0, j; for (i=0; i<sf->sf.glyphcnt; ++i) if (sf->sf.glyphs[i] != NULL) { script=SCScriptFromUnicode(sf->sf.glyphs[i]); if (script != 0 && script != DEFAULT_SCRIPT) { for (j=scnt-1; j >= 0; --j) if (scripts[j]==script) break; if (j<0) { scripts[scnt++]=script; if (scnt >= 32) break; } } } if (scnt==0) scripts[scnt++]=CHR('l', 'a', 't', 'n'); /* order scripts */ for (i=0; i<scnt-1; ++i) for (j=i+1; j<scnt; ++j) { if (scripts[i]>scripts[j]) { script=scripts[i]; scripts[i]=scripts[j]; scripts[j]=script; } } if (sf->sf.cidmaster) sf=(SplineFont1 *) sf->sf.cidmaster; else if (sf->sf.mm != NULL) sf=(SplineFont1 *) sf->sf.mm->normal; if (sf->script_lang != NULL) return; sf->script_lang=calloc(2, sizeof(struct script_record *)); sf->script_lang[0]=calloc(scnt+1, sizeof(struct script_record)); sf->sli_cnt=1; for (j=0; j<scnt; ++j) { sf->script_lang[0][j].script=scripts[j]; sf->script_lang[0][j].langs=malloc(2*sizeof(uint32_t)); sf->script_lang[0][j].langs[0]=DEFAULT_LANG; sf->script_lang[0][j].langs[1]=0; } sf->script_lang[1]=NULL; }
static OTLookup *CreateMacLookup(SplineFont1 *sf,ASM1 *sm) { OTLookup *otl=chunkalloc(sizeof(OTLookup)); int i, ch; char *pt, *start; SplineChar *sc; otl->features=chunkalloc(sizeof(FeatureScriptLangList)); if (sm->sm.type==asm_kern) { otl->lookup_type=kern_statemachine; otl->next=sf->sf.gsplookups[1]; sf->sf.gsplookups[1]=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.gsplookups[0]; sf->sf.gsplookups[0]=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 BaseLang_FinishEdit(GGadget *g, int r, int c, int wasnew) { if ( wasnew && c==0 ) { BaseLangDlg *b = GDrawGetUserData(GGadgetGetWindow(g)); int rows, cols = GMatrixEditGetColCnt(g); struct matrix_data *md = GMatrixEditGet(g,&rows); uint32 lang = TagFromString(md[r*cols+0].u.md_str); int gid; SplineChar *sc; DBounds bnd, scb; memset(&bnd,0,sizeof(bnd)); for ( gid=0; gid<b->sf->glyphcnt; ++gid ) if ( (sc=b->sf->glyphs[gid])!=NULL ) { if ( lang==CHR('E','N','G',' ') && (sc->unicodeenc<0 || sc->unicodeenc>127)) /* English just uses ASCII */; else if ( b->script==CHR('l','a','t','n') && (sc->unicodeenc<0 || sc->unicodeenc>255) && lang!=CHR('V','I','T',' ') ) /* Most languages in latin script only use one accent per */ /* letter. So latin1 should provide a reasonable bounding */ /* box. Vietnamese is an exception. */; else if ( SCScriptFromUnicode(sc)!=b->script ) /* Not interesting */; else { SplineCharFindBounds(sc,&scb); if ( bnd.minx==bnd.maxx ) bnd = scb; else { if ( scb.minx<bnd.minx ) bnd.minx = scb.minx; if ( scb.miny<bnd.miny ) bnd.miny = scb.miny; if ( scb.maxx>bnd.maxx ) bnd.maxx = scb.maxx; if ( scb.maxy>bnd.maxy ) bnd.maxy = scb.maxy; } } } if ( b->vertical ) { md[r*cols+1].u.md_ival = floor(bnd.minx); md[r*cols+2].u.md_ival = ceil(bnd.maxx); } else { md[r*cols+1].u.md_ival = floor(bnd.miny); md[r*cols+2].u.md_ival = ceil(bnd.maxy); } } }
void MMKern(SplineFont *sf,SplineChar *first,SplineChar *second,int diff, struct lookup_subtable *sub,KernPair *oldkp) { MMSet *mm = sf->mm; KernPair *kp; int i; /* If the user creates a kern pair in one font of a multiple master set */ /* then we should create the same kern pair in all the others. Similarly */ /* if s/he modifies a kern pair in the weighted version then apply that */ /* mod to all the others */ if ( mm==NULL ) return; if ( sf==mm->normal || oldkp==NULL ) { for ( i= -1; i<mm->instance_count; ++i ) { SplineFont *cur = i==-1 ? mm->normal : mm->instances[i]; SplineChar *psc, *ssc; if ( cur==sf ) /* Done in caller */ continue; psc = cur->glyphs[first->orig_pos]; ssc = cur->glyphs[second->orig_pos]; if ( psc==NULL || ssc==NULL ) /* Should never happen*/ continue; for ( kp = psc->kerns; kp!=NULL && kp->sc!=ssc; kp = kp->next ); /* No mm support for vertical kerns */ if ( kp==NULL ) { kp = chunkalloc(sizeof(KernPair)); if ( oldkp!=NULL ) *kp = *oldkp; else { kp->off = diff; if ( sub==NULL ) sub = SFSubTableFindOrMake(cur, CHR('k','e','r','n'), SCScriptFromUnicode(psc), gpos_pair); kp->subtable = sub; } kp->sc = ssc; kp->next = psc->kerns; psc->kerns = kp; } else kp->off += diff; } } }
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