Exemplo n.º 1
0
EncMap *CompactEncMap(EncMap *map, SplineFont *sf) {
    int i, inuse, gid;
    int32 *newmap;

    for ( i=inuse=0; i<map->enccount ; ++i )
	if ( (gid = map->map[i])!=-1 && SCWorthOutputting(sf->glyphs[gid]))
	    ++inuse;
    newmap = galloc(inuse*sizeof(int32));
    for ( i=inuse=0; i<map->enccount ; ++i )
	if ( (gid = map->map[i])!=-1 && SCWorthOutputting(sf->glyphs[gid]))
	    newmap[inuse++] = gid;
    free(map->map);
    map->map = newmap;
    map->enccount = inuse;
    map->encmax = inuse;
    map->enc = &custom;
    memset(map->backmap,-1,sf->glyphcnt*sizeof(int));
    for ( i=inuse-1; i>=0; --i )
	if ( (gid=map->map[i])!=-1 )
	    map->backmap[gid] = i;
return( map );
}
Exemplo n.º 2
0
int ContourPtNumMatch(MMSet *mm, int gid) {
    SplineFont *sf;
    int i;

    if ( !mm->apple )
return( false );

    if ( gid>=mm->normal->glyphcnt )
return( false );
    if ( !SCWorthOutputting(mm->normal->glyphs[gid] ) ) {
	for ( i=0; i<mm->instance_count; ++i ) {
	    if ( gid>=mm->instances[i]->glyphcnt )
return( false );
	    if ( SCWorthOutputting(mm->instances[i]->glyphs[gid]))
return( false );
	}
return( true );		/* None is not worth outputting, and that's ok, they match */
    } else {
	for ( i=0; i<mm->instance_count; ++i ) {
	    if ( gid>=mm->instances[i]->glyphcnt )
return( false );
	    if ( !SCWorthOutputting(mm->instances[i]->glyphs[gid]))
return( false );
	}
	    /* All are worth outputting */
    }

    if ( mm->normal->glyphs[gid]->layers[ly_fore].refs!=NULL && mm->normal->glyphs[gid]->layers[ly_fore].splines!=NULL )
return( false );
    for ( i=0; i<mm->instance_count; ++i ) {
	if ( mm->instances[i]->glyphs[gid]->layers[ly_fore].refs!=NULL && mm->instances[i]->glyphs[gid]->layers[ly_fore].splines!=NULL )
return( false );
    }
    if ( mm->normal->glyphs[gid]->layers[ly_fore].refs!=NULL ) {
	RefChar *r;
	int cnt, c;
	for ( r=mm->normal->glyphs[gid]->layers[ly_fore].refs, cnt=0; r!=NULL; r=r->next )
	    ++cnt;
	for ( i=0; i<mm->instance_count; ++i ) {
	    for ( r=mm->instances[i]->glyphs[gid]->layers[ly_fore].refs, c=0; r!=NULL; r=r->next )
		++c;
	    if ( c!=cnt )
return( false );
	}
    }

    sf = NULL;
    if ( PtNumbersAreSet(mm->normal->glyphs[gid]) )
	sf = mm->normal;
    else {
	for ( i=0; i<mm->instance_count; ++i ) {
	    if ( PtNumbersAreSet(mm->instances[i]->glyphs[gid])) {
		sf = mm->instances[i];
	break;
	    }
	}
    }
    if ( sf==NULL )
	/* No instance has fixed points. Make sure all fonts are consistent */
return( AssignPtNumbers(mm,gid));

    if ( sf!=mm->normal && !MatchPoints(sf,mm->normal,gid))
return( false );
    for ( i=0; i<mm->instance_count; ++i ) if ( sf!=mm->instances[i] ) {
	if ( !MatchPoints(sf, mm->instances[i],gid) )
return( false );
    }
return( true );
}
Exemplo n.º 3
0
SplineChar *SCBuildDummy(SplineChar *dummy,SplineFont *sf,EncMap *map,int i) {
    static char namebuf[100];
    static Layer layers[2];

    memset(dummy,'\0',sizeof(*dummy));
    dummy->color = COLOR_DEFAULT;
    dummy->layer_cnt = 2;
    dummy->layers = layers;
    if ( sf->cidmaster!=NULL ) {
	/* CID fonts don't have encodings, instead we must look up the cid */
	if ( sf->cidmaster->loading_cid_map )
	    dummy->unicodeenc = -1;
	else
	    dummy->unicodeenc = CID2NameUni(FindCidMap(sf->cidmaster->cidregistry,sf->cidmaster->ordering,sf->cidmaster->supplement,sf->cidmaster),
		    i,namebuf,sizeof(namebuf));
    } else
	dummy->unicodeenc = UniFromEnc(i,map->enc);

    if ( sf->cidmaster!=NULL )
	dummy->name = namebuf;
    else if ( map->enc->psnames!=NULL && i<map->enc->char_cnt &&
	    map->enc->psnames[i]!=NULL )
	dummy->name = map->enc->psnames[i];
    else if ( dummy->unicodeenc==-1 )
	dummy->name = NULL;
    else
	dummy->name = (char *) StdGlyphName(namebuf,dummy->unicodeenc,sf->uni_interp,sf->for_new_glyphs);
    if ( dummy->name==NULL ) {
	/*if ( dummy->unicodeenc!=-1 || i<256 )
	    dummy->name = ".notdef";
	else*/ {
	    int j;
	    sprintf( namebuf, "NameMe.%d", i);
	    j=0;
	    while ( SFFindExistingSlot(sf,-1,namebuf)!=-1 )
		sprintf( namebuf, "NameMe.%d.%d", i, ++j);
	    dummy->name = namebuf;
	}
    }
    dummy->width = dummy->vwidth = sf->ascent+sf->descent;
    if ( dummy->unicodeenc>0 && dummy->unicodeenc<0x10000 &&
	    iscombining(dummy->unicodeenc)) {
	/* Mark characters should be 0 width */
	dummy->width = 0;
	/* Except in monospaced fonts on windows, where they should be the */
	/*  same width as everything else */
    }
    /* Actually, in a monospace font, all glyphs should be the same width */
    /*  whether mark or not */
    if ( sf->pfminfo.panose_set && sf->pfminfo.panose[3]==9 &&
	    sf->glyphcnt>0 ) {
	for ( i=sf->glyphcnt-1; i>=0; --i )
	    if ( SCWorthOutputting(sf->glyphs[i])) {
		dummy->width = sf->glyphs[i]->width;
	break;
	    }
    }
    dummy->parent = sf;
    dummy->orig_pos = 0xffff;
return( dummy );
}
Exemplo n.º 4
0
int IsntBDFChar(BDFChar *bdfc) {
    if ( bdfc==NULL )
return( true );

return( !SCWorthOutputting(bdfc->sc));
}
Exemplo n.º 5
0
static char *_MMBlendChar(MMSet *mm, int gid) {
    int i, j, worthit = -1;
    int all, any, any2, all2, anyend, allend, diff;
    SplineChar *sc;
    SplinePointList *spls[MmMax], *spl, *spllast;
    SplinePoint *tos[MmMax], *to;
    RefChar *refs[MmMax], *ref, *reflast;
    KernPair *kp0, *kptest, *kp, *kplast;
    StemInfo *hs[MmMax], *h, *hlast;
    real width;

    for ( i=0; i<mm->instance_count; ++i ) {
	if ( mm->instances[i]->layers[ly_fore].order2 )
return( _("One of the multiple master instances contains quadratic splines. It must be converted to cubic splines before it can be used in a multiple master") );
	if ( gid>=mm->instances[i]->glyphcnt )
return( _("The different instances of this mm have a different number of glyphs") );
	if ( SCWorthOutputting(mm->instances[i]->glyphs[gid]) ) {
	    if ( worthit == -1 ) worthit = true;
	    else if ( worthit != true )
return( _("This glyph is defined in one instance font but not in another") );
	} else {
	    if ( worthit == -1 ) worthit = false;
	    else if ( worthit != false )
return( _("This glyph is defined in one instance font but not in another") );
	}
    }

    sc = mm->normal->glyphs[gid];
    if ( sc!=NULL ) {
	SCClearContents(sc,ly_fore);
	KernPairsFree(sc->kerns);
	sc->kerns = NULL;
	KernPairsFree(sc->vkerns);
	sc->vkerns = NULL;
    }

    if ( !worthit )
return( 0 );

    if ( sc==NULL )
	sc = SFMakeGlyphLike(mm->normal,gid,mm->instances[0]);

	/* Blend references => blend transformation matrices */
    diff = false;
    any = false; all = true;
    for ( i=0; i<mm->instance_count; ++i ) {
	refs[i] = mm->instances[i]->glyphs[gid]->layers[ly_fore].refs;
	if ( refs[i]!=NULL ) any = true;
	else all = false;
    }
    reflast = NULL;
    while ( all ) {
	ref = RefCharCreate();
	*ref = *refs[0];
	ref->layers[0].splines = NULL;
	ref->next = NULL;
	memset(ref->transform,0,sizeof(ref->transform));
	ref->sc = mm->normal->glyphs[refs[0]->sc->orig_pos];
	for ( i=0; i<mm->instance_count; ++i ) {
	    if ( ref->sc->orig_pos!=refs[i]->sc->orig_pos )
		diff = true;
	    for ( j=0; j<6; ++j )
		ref->transform[j] += refs[i]->transform[j]*mm->defweights[i];
	}
	if ( reflast==NULL )
	    sc->layers[ly_fore].refs = ref;
	else
	    reflast->next = ref;
	reflast = ref;
	any = false; all = true;
	for ( i=0; i<mm->instance_count; ++i ) {
	    refs[i] = refs[i]->next;
	    if ( refs[i]!=NULL ) any = true;
	    else all = false;
	}
    }
    if ( any )
return( _("This glyph contains a different number of references in different instances") );
    if ( diff )
return( _("A reference in this glyph refers to a different encoding in different instances") );

	/* Blend Width */
    width = 0;
    for ( i=0; i<mm->instance_count; ++i )
	width += mm->instances[i]->glyphs[gid]->width*mm->defweights[i];
    sc->width = width;
    width = 0;
    for ( i=0; i<mm->instance_count; ++i )
	width += mm->instances[i]->glyphs[gid]->vwidth*mm->defweights[i];
    sc->vwidth = width;

	/* Blend Splines */
    any = false; all = true;
    for ( i=0; i<mm->instance_count; ++i ) {
	spls[i] = mm->instances[i]->glyphs[gid]->layers[ly_fore].splines;
	if ( spls[i]!=NULL ) any = true;
	else all = false;
    }
    spllast = NULL;
    while ( all ) {
	spl = chunkalloc(sizeof(SplinePointList));
	if ( spllast==NULL )
	    sc->layers[ly_fore].splines = spl;
	else
	    spllast->next = spl;
	spllast = spl;
	for ( i=0; i<mm->instance_count; ++i )
	    tos[i] = spls[i]->first;
	all2 = true;
	spl->last = NULL;
	while ( all2 ) {
	    to = chunkalloc(sizeof(SplinePoint));
	    to->nonextcp = tos[0]->nonextcp;
	    to->noprevcp = tos[0]->noprevcp;
	    to->nextcpdef = tos[0]->nextcpdef;
	    to->prevcpdef = tos[0]->prevcpdef;
	    to->pointtype = tos[0]->pointtype;
	    if ( tos[0]->hintmask!=NULL ) {
		to->hintmask = chunkalloc(sizeof(HintMask));
		memcpy(to->hintmask,tos[0]->hintmask,sizeof(HintMask));
	    }
	    for ( i=0; i<mm->instance_count; ++i ) {
		to->me.x += tos[i]->me.x*mm->defweights[i];
		to->me.y += tos[i]->me.y*mm->defweights[i];
		to->nextcp.x += tos[i]->nextcp.x*mm->defweights[i];
		to->nextcp.y += tos[i]->nextcp.y*mm->defweights[i];
		to->prevcp.x += tos[i]->prevcp.x*mm->defweights[i];
		to->prevcp.y += tos[i]->prevcp.y*mm->defweights[i];
	    }
	    if ( spl->last==NULL )
		spl->first = to;
	    else
		SplineMake3(spl->last,to);
	    spl->last = to;
	    any2 = false; all2 = true;
	    for ( i=0; i<mm->instance_count; ++i ) {
		if ( tos[i]->next==NULL ) tos[i] = NULL;
		else tos[i] = tos[i]->next->to;
		if ( tos[i]!=NULL ) any2 = true;
		else all2 = false;
	    }
	    if ( !all2 && any2 )
return( _("A contour in this glyph contains a different number of points in different instances") );
	    anyend = false; allend = true;
	    for ( i=0; i<mm->instance_count; ++i ) {
		if ( tos[i]==spls[i]->first ) anyend = true;
		else allend = false;
	    }
	    if ( allend ) {
		SplineMake3(spl->last,spl->first);
		spl->last = spl->first;
	break;
	    }
	    if ( anyend )
return( _("A contour in this glyph contains a different number of points in different instances") );
	}
	any = false; all = true;
	for ( i=0; i<mm->instance_count; ++i ) {
	    spls[i] = spls[i]->next;
	    if ( spls[i]!=NULL ) any = true;
	    else all = false;
	}
    }
    if ( any )
return( _("This glyph contains a different number of contours in different instances") );

	/* Blend hints */
    for ( j=0; j<2; ++j ) {
	any = false; all = true;
	for ( i=0; i<mm->instance_count; ++i ) {
	    hs[i] = j ? mm->instances[i]->glyphs[gid]->hstem : mm->instances[i]->glyphs[gid]->vstem;
	    if ( hs[i]!=NULL ) any = true;
	    else all = false;
	}
	hlast = NULL;
	while ( all ) {
	    h = chunkalloc(sizeof(StemInfo));
	    *h = *hs[0];
	    h->where = NULL;
	    h->next = NULL;
	    h->start = h->width = 0;
	    for ( i=0; i<mm->instance_count; ++i ) {
		h->start += hs[i]->start*mm->defweights[i];
		h->width += hs[i]->width*mm->defweights[i];
	    }
	    if ( hlast!=NULL )
		hlast->next = h;
	    else if ( j )
		sc->hstem = h;
	    else
		sc->vstem = h;
	    hlast = h;
	    any = false; all = true;
	    for ( i=0; i<mm->instance_count; ++i ) {
		hs[i] = hs[i]->next;
		if ( hs[i]!=NULL ) any = true;
		else all = false;
	    }
	}
	if ( any )
return( _("This glyph contains a different number of hints in different instances") );
    }

	/* Blend kernpairs */
    /* I'm not requiring ordered kerning pairs */
    /* I'm not bothering with vertical kerning */
    kp0 = mm->instances[0]->glyphs[gid]->kerns;
    kplast = NULL;
    while ( kp0!=NULL ) {
	int off = kp0->off*mm->defweights[0];
	for ( i=1; i<mm->instance_count; ++i ) {
	    for ( kptest=mm->instances[i]->glyphs[gid]->kerns; kptest!=NULL; kptest=kptest->next )
		if ( kptest->sc->orig_pos==kp0->sc->orig_pos )
	    break;
	    if ( kptest==NULL )
return( _("This glyph contains different kerning pairs in different instances") );
	    off += kptest->off*mm->defweights[i];
	}
	kp = chunkalloc(sizeof(KernPair));
	kp->sc = mm->normal->glyphs[kp0->sc->orig_pos];
	kp->off = off;
	kp->subtable = kp0->subtable;
	if ( kplast!=NULL )
	    kplast->next = kp;
	else
	    sc->kerns = kp;
	kplast = kp;
	kp0 = kp0->next;
    }
return( 0 );
}