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); } }
/* * TODO:bitmap, reference have not been considered in this function * TODO:remove_unused may not be suitable to be done here */ void ffw_set_widths(int * width_list, int mapping_len, int stretch_narrow, int squeeze_wide, int remove_unused) { SplineFont * sf = cur_fv->sf; if(sf->onlybitmaps && cur_fv->active_bitmap != NULL && sf->bitmaps != NULL) { printf("TODO: width vs bitmap\n"); } memset(cur_fv->selected, 0, cur_fv->map->enccount); EncMap * map = cur_fv->map; int i; int imax = min(mapping_len, map->enccount); for(i = 0; i < imax; ++i) { /* * Do mess with it if the glyphs is not used. */ if(width_list[i] == -1) { cur_fv->selected[i] = 1; continue; } int j = map->map[i]; if(j == -1) continue; SplineChar * sc = sf->glyphs[j]; if(sc == NULL) continue; 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); } sc->width = width_list[i]; } for(; i < map->enccount; ++i) cur_fv->selected[i] = 1; if(remove_unused) FVDetachAndRemoveGlyphs(cur_fv); }
/* * 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); } }
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); } } }
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); }
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); }