Beispiel #1
0
void ffw_import_svg_glyph(int code, const char * filename, double ox, double oy, double width)
{
    int enc = SFFindSlot(cur_fv->sf, cur_fv->map, code, "");
    if(enc == -1)
        return;

    SplineChar * sc = SFMakeChar(cur_fv->sf, cur_fv->map, enc);

    memset(cur_fv->selected, 0, cur_fv->map->enccount);
    cur_fv->selected[enc] = 1;
    int ok = FVImportImages(cur_fv, (char*)filename, fv_svg, 0, -1);
    if(!ok)
        err("Import SVG glyph failed");

    // correct origin and width
    {
        int a = cur_fv->sf->ascent;
        int d = cur_fv->sf->descent;
        real transform[6];
        transform[0] = 1.0;
        transform[3] = 1.0;
        transform[1] = transform[2] = 0.0;
        transform[4] = -ox * (a+d);
        transform[5] = -oy * (a+d) + d;
        FVTrans(cur_fv, sc, transform, NULL, fvt_alllayers | fvt_dontmovewidth);

        SCSynchronizeWidth(sc, floor(width * (a+d) + 0.5), sc->width, cur_fv);
    }
}
Beispiel #2
0
/*
 * There is no check if a glyph with the same unicode exists!
 * TODO: let FontForge fill in the standard glyph name <- or maybe this might cause collision?
 */
void ffw_add_empty_char(int32_t unicode, int width)
{
    SplineChar * sc = SFMakeChar(cur_fv->sf, cur_fv->map, cur_fv->map->enccount);
    char buffer[400];
    SCSetMetaData(sc,
        strcopy(StdGlyphName(buffer, unicode,
                cur_fv->sf->uni_interp, cur_fv->sf->for_new_glyphs)),
        unicode, sc->comment);
    SCSynchronizeWidth(sc, width, sc->width, cur_fv);
}
Beispiel #3
0
/*
 * TODO:bitmap, reference have not been considered in this function
 */
void ffw_set_widths(int * width_list, int mapping_len,
        int stretch_narrow, int squeeze_wide)
{
    SplineFont * sf = cur_fv->sf;

    if(sf->onlybitmaps
            && cur_fv->active_bitmap != NULL
            && sf->bitmaps != NULL)
    {
        printf("TODO: width vs bitmap\n");
    }

    EncMap * map = cur_fv->map;
    int i;
    int imax = min(mapping_len, map->enccount);
    for(i = 0; i < imax; ++i)
    {
        /*
         * Don't mess with it if the glyphs is not used.
         */
        if(width_list[i] == -1)
        {
            continue;
        }

        int j = map->map[i];
        if(j == -1) continue;

        SplineChar * sc = sf->glyphs[j];
        if(sc == NULL)
        {
            sc = SFMakeChar(cur_fv->sf, cur_fv->map, j);
        }
        else if(((sc->width > EPS)
                && (((sc->width > width_list[i] + EPS) && (squeeze_wide))
                    || ((sc->width < width_list[i] - EPS) && (stretch_narrow)))))
        {
            real transform[6];
            transform[0] = ((double)width_list[i]) / (sc->width);
            transform[3] = 1.0;
            transform[1] = transform[2] = transform[4] = transform[5] = 0;
            FVTrans(cur_fv, sc, transform, NULL, fvt_alllayers | fvt_dontmovewidth);
        }

        SCSynchronizeWidth(sc, width_list[i], sc->width, cur_fv);
    }
}
Beispiel #4
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;
	    }
	}
    }
}
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);
	}
    }
}
Beispiel #6
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);
}
Beispiel #7
0
static void aw2_figure_all_sidebearing(AW_Data *all) {
    int i,j;
    AW_Glyph *me, *other;
    real transform[6], half;
    int width, changed;
    uint8 *rsel = calloc(all->fv->map->enccount,sizeof(char));
    real denom = (all->sf->ascent + all->sf->descent)/DENOM_FACTOR_OF_EMSIZE;
    int ldiff, rdiff;

    all->denom = denom;
    all->visual_separation = malloc(all->gcnt*all->gcnt*sizeof(int));
    for ( i=0; i<all->gcnt; ++i ) {
	int *vpt = all->visual_separation + i*all->gcnt;
	me = &all->glyphs[i];
	for ( j=0; j<all->gcnt; ++j ) {
	    other = &all->glyphs[j];
	    vpt[j] = aw2_bbox_separation(me,other,all);
	}
    }

    half = all->desired_separation/2;
    for ( i=0; i<all->gcnt; ++i ) {
	me = &all->glyphs[i];	
	me->lsb = me->rsb = half;
    }

    for ( j=0; j<all->loop_cnt; ++j ) {
	for ( i=0; i<all->gcnt; ++i )
	    aw2_figure_lsb(i,all);
	for ( i=0; i<all->gcnt; ++i )
	    aw2_figure_rsb(i,all);
	for ( i=0; i<all->gcnt; ++i ) {
	    AW_Glyph *me = &all->glyphs[i];
	    me->rsb = me->nrsb;
	    me->lsb = me->nlsb;
	}
    }
    free(all->visual_separation); all->visual_separation = NULL;

    if ( all->normalize ) {
	/* This is the dummy flat edge we added. We want the separation between */
	/*  two adjacent flat edges to be desired_separation */
	me = &all->glyphs[all->gcnt-1];
	if ( me->lsb+me->rsb != all->desired_separation && me->sc==NULL ) {
	    if ( me->lsb+me->rsb!=0 ) {
		ldiff = (all->desired_separation-(me->lsb+me->rsb)) * me->lsb/(me->lsb+me->rsb);
	    } else {
		ldiff = all->desired_separation/2;
	    }
	    rdiff = (all->desired_separation-(me->lsb+me->rsb)) - ldiff;
	    for ( i=0; (me = &all->glyphs[i])->sc!=NULL; ++i ) {
		me->lsb += ldiff;
		me->rsb += rdiff;
	    }
	}
    }

    transform[0] = transform[3] = 1.0;
    transform[1] = transform[2] = transform[5] = 0;
    for ( i=0; (me = &all->glyphs[i])->sc!=NULL; ++i ) {
	changed = 0;
	if ( me->lsb != me->bb.minx ) {
	    transform[4] = me->lsb-me->bb.minx;
	    FVTrans(all->fv,me->sc,transform,rsel,false);
	    changed = true;
	}
	width = me->lsb + me->rsb + rint(me->bb.maxx - me->bb.minx);
	if ( me->sc->width != width ) {
	    SCPreserveWidth(me->sc);
	    SCSynchronizeWidth(me->sc,width,me->sc->width,all->fv);
	    changed = true;
	}
	if ( changed )
	    SCCharChangedUpdate(me->sc,ly_none);
    }
    free(rsel);
}
Beispiel #8
0
/*
 * There is no check if a glyph with the same unicode exists!
 */
void ffw_add_empty_char(int32_t unicode, int width)
{
    SplineChar * sc = SFMakeChar(cur_fv->sf, cur_fv->map, cur_fv->map->enccount);
    SCSetMetaData(sc, sc->name, unicode, sc->comment);
    SCSynchronizeWidth(sc, width, sc->width, cur_fv);
}