Пример #1
0
/*  width of A, we'll also change that of À and Ä and ... */
void SCSynchronizeWidth(SplineChar *sc,real newwidth, real oldwidth) {
    struct splinecharlist *dlist;
    RefChar *r = HasUseMyMetrics(sc,ly_fore);
    int isprobablybase;

    sc->widthset = true;
    if( r!=NULL ) {
	if ( oldwidth==r->sc->width ) {
	    sc->width = r->sc->width;
return;
	}
	newwidth = r->sc->width;
    }
    if ( newwidth==oldwidth )
return;
    sc->width = newwidth;
    if ( !adjustwidth )
return;

    isprobablybase = true;
    if ( sc->unicodeenc==-1 || sc->unicodeenc>=0x10000 ||
	    !isalpha(sc->unicodeenc) || iscombining(sc->unicodeenc))
	isprobablybase = false;

    for ( dlist=sc->dependents; dlist!=NULL; dlist=dlist->next ) {
	RefChar *metrics = HasUseMyMetrics(dlist->sc,ly_fore);
	if ( metrics!=NULL && metrics->sc!=sc )
    continue;
	else if ( metrics==NULL && !isprobablybase )
    continue;
	if ( dlist->sc->width==oldwidth &&
		(metrics!=NULL)) {
	    SCSynchronizeWidth(dlist->sc,newwidth,oldwidth);
	    if ( !dlist->sc->changed ) {
		dlist->sc->changed = true;
	    }
	}
    }
}
Пример #2
0
static void DoChar(SplineChar *sc,CreateWidthData *wd, FontViewBase *fv,
	BDFChar *bc) {
    real transform[6];
    DBounds bb;
    IBounds ib;
    int width=0;
    BVTFunc bvts[2];
    BDFFont *bdf;
    RefChar *r = HasUseMyMetrics(sc,fv->active_layer);

    /* Can't change the horizontal or vertical advance if there's a "use my metrics" bit set */
    if ( r!=NULL && wd->wtype != wt_lbearing )
return;

    if ( wd->wtype == wt_width ) {
	if ( wd->type==st_set )
	    width = wd->setto;
	else if ( wd->type == st_incr )
	    width = sc->width + wd->increment;
	else
	    width = sc->width * wd->scale/100;
	sc->widthset = true;
	if ( width!=sc->width ) {
	    SCPreserveWidth(sc);
	    SCSynchronizeWidth(sc,width,sc->width,fv);
	}
    } else if ( wd->wtype == wt_lbearing ) {
	transform[0] = transform[3] = 1.0;
	transform[1] = transform[2] = transform[5] = 0;
	bvts[1].func = bvt_none;
	bvts[0].func = bvt_transmove; bvts[0].y = 0;
	if ( bc==NULL ) {
	    SplineCharFindBounds(sc,&bb);
	    if ( wd->type==st_set )
		transform[4] = wd->setto-bb.minx;
	    else if ( wd->type == st_incr )
		transform[4] = wd->increment;
	    else
		transform[4] = bb.minx*wd->scale/100 - bb.minx;
	} else {
	    double scale = (fv->sf->ascent+fv->sf->descent)/(double) (fv->active_bitmap->pixelsize);
	    BDFCharFindBounds(bc,&ib);
	    if ( wd->type==st_set )
		transform[4] = wd->setto-ib.minx*scale;
	    else if ( wd->type == st_incr )
		transform[4] = wd->increment;
	    else
		transform[4] = scale*ib.minx*wd->scale/100 - ib.minx;
	}
	if ( transform[4]!=0 ) {
	    FVTrans(fv,sc,transform,NULL,fvt_dontmovewidth);
	    bvts[0].x = transform[4];
	    for ( bdf = fv->sf->bitmaps; bdf!=NULL; bdf=bdf->next ) if ( bdf->glyphs[sc->orig_pos]!=NULL )
		BCTrans(bdf,bdf->glyphs[sc->orig_pos],bvts,fv);
	}
return;
    } else if ( wd->wtype == wt_rbearing ) {
	if ( bc==NULL ) {
	    SplineCharFindBounds(sc,&bb);
	    if ( wd->type==st_set )
		width = bb.maxx + wd->setto;
	    else if ( wd->type == st_incr )
		width = sc->width+wd->increment;
	    else
		width = (sc->width-bb.maxx) * wd->scale/100 + bb.maxx;
	} else {
	    double scale = (fv->sf->ascent+fv->sf->descent)/(double) (fv->active_bitmap->pixelsize);
	    BDFCharFindBounds(bc,&ib);
	    ++ib.maxx;
	    if ( wd->type==st_set )
		width = rint(ib.maxx*scale + wd->setto);
	    else if ( wd->type == st_incr )
		width = rint(sc->width+wd->increment);
	    else
		width = rint(scale * (bc->width-ib.maxx) * wd->scale/100 + ib.maxx*scale);
	}
	if ( width!=sc->width ) {
	    SCPreserveWidth(sc);
	    SCSynchronizeWidth(sc,width,sc->width,fv);
	}
    } else if ( wd->wtype == wt_bearings ) {
	transform[0] = transform[3] = 1.0;
	transform[1] = transform[2] = transform[5] = 0;
	bvts[1].func = bvt_none;
	bvts[0].func = bvt_transmove; bvts[0].y = 0;
	if ( bc==NULL ) {
	    SplineCharFindBounds(sc,&bb);
	    if ( wd->type==st_set ) {
		transform[4] = wd->setto-bb.minx;
		width = bb.maxx-bb.minx + 2*wd->setto;
	    } else if ( wd->type == st_incr ) {
		transform[4] = wd->increment;
		width += 2*wd->increment;
	    } else {
		transform[4] = bb.minx*wd->scale/100 - bb.minx;
		width = bb.maxx-bb.minx +
			(bb.minx + (sc->width-bb.maxx))*wd->scale/100;
	    }
	} else {
	    double scale = (fv->sf->ascent+fv->sf->descent)/(double) (fv->active_bitmap->pixelsize);
	    BDFCharFindBounds(bc,&ib);
	    ++ib.maxx;
	    if ( wd->type==st_set ) {
		transform[4] = wd->setto-ib.minx;
		width = (ib.maxx-ib.minx + 2*wd->setto);
	    } else if ( wd->type == st_incr ) {
		transform[4] = wd->increment;
		width += 2*wd->increment;
	    } else {
		transform[4] = ib.minx*wd->scale/100 - ib.minx;
		width = ib.maxx-ib.minx +
			(ib.minx + (bc->width-ib.maxx))*wd->scale/100;
	    }
	    transform[4] *= scale;
	    width = rint(width*scale);
	}
	if ( width!=sc->width ) {
	    SCPreserveWidth(sc);
	    SCSynchronizeWidth(sc,width,sc->width,fv);
	}
	if ( transform[4]!=0 ) {
	    FVTrans(fv,sc,transform,NULL,fvt_dontmovewidth);
	    bvts[0].x = transform[4];
	    for ( bdf = fv->sf->bitmaps; bdf!=NULL; bdf=bdf->next ) if ( bdf->glyphs[sc->orig_pos]!=NULL )
		BCTrans(bdf,bdf->glyphs[sc->orig_pos],bvts,fv);
	}
return;
    } else {
	if ( wd->type==st_set )
	    width = wd->setto;
	else if ( wd->type == st_incr )
	    width = sc->vwidth + wd->increment;
	else
	    width = sc->vwidth * wd->scale/100;
	if ( width!=sc->vwidth ) {
	    SCPreserveVWidth(sc);
	    sc->vwidth = width;
	}
    }
    SCCharChangedUpdate(sc,fv->active_layer);
}
Пример #3
0
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