static int KP_ChangeSize(GGadget *g, GEvent *e) { if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) { KPData *kpd = GDrawGetUserData(GGadgetGetWindow(g)); int newsize = (intpt) (GGadgetGetListItemSelected(g)->userdata); BDFFont *temp; if ( newsize==kpd->bdf->pixelsize ) return( true ); temp = SplineFontPieceMeal(kpd->sf,kpd->layer,newsize,72,true,NULL); BDFFontFree(kpd->bdf); kpd->bdf = temp; KP_Resize(kpd); KPV_Resize(kpd); } return( true ); }
static int FNT_Load(FILE *fnt,SplineFont *sf) { struct fntheader fntheader; struct v3chars charinfo[258]; /* Max size */ int i, j, k, ch; uint32 base = ftell(fnt); char *pt, *spt, *temp; BDFFont *bdf; BDFChar *bdfc; memset(&fntheader,0,sizeof(fntheader)); fntheader.version = lgetushort(fnt); if ( fntheader.version != 0x200 && fntheader.version != 0x300 ) return( false ); fntheader.filesize = lgetlong(fnt); for ( i=0; i<60; ++i ) fntheader.copyright[i] = getc(fnt); fntheader.copyright[i] = '\0'; for ( --i; i>=0 && fntheader.copyright[i]==' '; --i ) fntheader.copyright[i] = '\0'; fntheader.type = lgetushort(fnt); if ( fntheader.type & (FNT_TYPE_VECTOR|FNT_TYPE_MEMORY|FNT_TYPE_DEVICE)) return( false ); fntheader.pointsize = lgetushort(fnt); fntheader.vertres = lgetushort(fnt); fntheader.hortres = lgetushort(fnt); fntheader.ascent = lgetushort(fnt); fntheader.internal_leading = lgetushort(fnt); fntheader.external_leading = lgetushort(fnt); fntheader.italic = getc(fnt); fntheader.underline = getc(fnt); fntheader.strikeout = getc(fnt); fntheader.weight = lgetushort(fnt); fntheader.charset = getc(fnt); fntheader.width = lgetushort(fnt); fntheader.height = lgetushort(fnt); fntheader.pitchfamily = getc(fnt); fntheader.avgwidth = lgetushort(fnt); fntheader.maxwidth = lgetushort(fnt); fntheader.firstchar = getc(fnt); fntheader.lastchar = getc(fnt); fntheader.defchar = getc(fnt); fntheader.breakchar = getc(fnt); fntheader.widthbytes = lgetushort(fnt); fntheader.deviceoffset = lgetlong(fnt); fntheader.faceoffset = lgetlong(fnt); fntheader.bitspointer = lgetlong(fnt); fntheader.bitsoffset = lgetlong(fnt); (void) getc(fnt); /* Not documented in the v2 spec but seems to be present */ if ( fntheader.version == 0x300 ) { fntheader.flags = lgetlong(fnt); if ( fntheader.flags & (FNT_FLAGS_ABCFIXED|FNT_FLAGS_ABCPROP|FNT_FLAGS_16COLOR|FNT_FLAGS_256COLOR|FNT_FLAGS_RGBCOLOR)) return( false ); fntheader.aspace = lgetushort(fnt); fntheader.bspace = lgetushort(fnt); fntheader.cspace = lgetushort(fnt); fntheader.coloroffset = lgetlong(fnt); for ( i=0; i<16; ++i ) /* Freetype thinks this is 4 */ (void) getc(fnt); } memset(charinfo,0,sizeof(charinfo)); for ( i=fntheader.firstchar; i<=fntheader.lastchar+2; ++i ) { charinfo[i].width = lgetushort(fnt); if ( fntheader.version==0x200 ) charinfo[i].offset = lgetushort(fnt); else charinfo[i].offset = lgetlong(fnt); } /* Set the font names and the pfminfo structure */ sf->pfminfo.pfmset = true; if ( fntheader.copyright[0]!='\0' ) { free(sf->copyright); sf->copyright = copy(fntheader.copyright); } free(sf->weight); sf->weight = copy( fntheader.weight<=100 ? "Thin" : fntheader.weight<=200 ? "Extralight" : fntheader.weight<=300 ? "Light" : fntheader.weight<=400 ? "Normal" : fntheader.weight<=500 ? "Medium" : fntheader.weight<=600 ? "Demibold" : fntheader.weight<=700 ? "Bold" : fntheader.weight<=800 ? "Heavy" : fntheader.weight<=900 ? "Black" : "Nord" ); sf->pfminfo.weight = fntheader.weight; sf->pfminfo.panose[2] = fntheader.weight/100 + 1; fseek(fnt,base+fntheader.faceoffset,SEEK_SET); for ( i=0; (ch=getc(fnt))!=EOF && ch!=0; ++i ); free(sf->familyname); sf->familyname = malloc(i+2); fseek(fnt,base+fntheader.faceoffset,SEEK_SET); for ( i=0; (ch=getc(fnt))!=EOF && ch!=0; ++i ) sf->familyname[i] = ch; sf->familyname[i] = '\0'; temp = malloc(i+50); strcpy(temp,sf->familyname); if ( fntheader.weight<=300 || fntheader.weight>500 ) { strcat(temp," "); strcat(temp,sf->weight); } if ( fntheader.italic ) strcat(temp," Italic"); free(sf->fullname); sf->fullname = temp; free(sf->fontname); sf->fontname = copy(sf->fullname); for ( pt=spt=sf->fontname; *spt; ++spt ) if ( *spt!=' ' ) *pt++ = *spt; *pt = '\0'; sf->pfminfo.pfmfamily = fntheader.pitchfamily; sf->pfminfo.panose[0] = 2; if ( (fntheader.pitchfamily&FNT_FAMILY_MASK)==FNT_FAMILY_SCRIPT ) sf->pfminfo.panose[0] = 3; sf->pfminfo.width = 5; /* No info about condensed/extended */ sf->pfminfo.panose[3] = 3; if ( !(fntheader.pitchfamily&FNT_PITCH_VARIABLE ) ) sf->pfminfo.panose[3] = 9; sf->pfminfo.linegap = (sf->ascent+sf->descent)*fntheader.external_leading/fntheader.height; if ( fntheader.italic ) sf->italicangle = 11.25; bdf = calloc(1,sizeof(BDFFont)); bdf->sf = sf; bdf->glyphcnt = sf->glyphcnt; bdf->glyphmax = sf->glyphmax; bdf->res = fntheader.vertres; bdf->pixelsize = rint(fntheader.pointsize*fntheader.vertres/72.27); bdf->glyphs = calloc(sf->glyphmax,sizeof(BDFChar *)); bdf->ascent = rint(.8*bdf->pixelsize); /* shouldn't use typographical ascent */ bdf->descent = bdf->pixelsize-bdf->ascent; for ( i=fntheader.firstchar; i<=fntheader.lastchar; ++i ) if ( charinfo[i].width!=0 ) { int gid = SFMakeChar(sf,sf->map,i)->orig_pos; if ( gid>=bdf->glyphcnt ) { if ( gid>=bdf->glyphmax ) bdf->glyphs = realloc(bdf->glyphs,(bdf->glyphmax=sf->glyphmax)*sizeof(BDFChar *)); memset(bdf->glyphs+bdf->glyphcnt,0,(sf->glyphcnt-bdf->glyphcnt)*sizeof(BDFChar *)); bdf->glyphcnt = sf->glyphcnt; } bdf->glyphs[gid] = bdfc = chunkalloc(sizeof(BDFChar)); memset( bdfc,'\0',sizeof( BDFChar )); bdfc->xmin = 0; bdfc->xmax = charinfo[i].width-1; bdfc->ymin = fntheader.ascent-fntheader.height; bdfc->ymax = fntheader.ascent-1; bdfc->width = charinfo[i].width; bdfc->vwidth = bdf->pixelsize; bdfc->bytes_per_line = (bdfc->xmax>>3)+1; bdfc->bitmap = calloc(bdfc->bytes_per_line*fntheader.height,sizeof(uint8)); bdfc->orig_pos = gid; bdfc->sc = sf->glyphs[gid]; bdfc->sc->widthset = true; fseek(fnt,base+charinfo[i].offset,SEEK_SET); for ( j=0; j<bdfc->bytes_per_line; ++j ) { for ( k=0; k<fntheader.height; ++k ) bdfc->bitmap[k*bdfc->bytes_per_line+j] = getc(fnt); } BCCompressBitmap(bdfc); if ( feof(fnt) ) { BDFFontFree(bdf); return( false ); } }