mknfonts-0.5/ 40775 764 764 0 7545302051 11260 5ustar alexalexmknfonts-0.5/.cvsignore100664 764 764 32 7545300611 13310 0ustar alexalexmknfonts.gdt mknfonts.gpr mknfonts-0.5/GNUmakefile100664 764 764 563 7545302016 13414 0ustar alexalexinclude $(GNUSTEP_MAKEFILES)/common.make TOOL_NAME = mknfonts PACKAGE_NAME = mknfonts CVS_MODULE_NAME = mknfonts CVS_OPTIONS = -d /opt/cvsroot VERSION = 0.5 ADDITIONAL_OBJCFLAGS += -Wall -O2 ADDITIONAL_INCLUDE_DIRS += `freetype-config --cflags` ADDITIONAL_LDFLAGS += `freetype-config --libs` mknfonts_OBJC_FILES = mknfonts.m include $(GNUSTEP_MAKEFILES)/tool.make mknfonts-0.5/mknfonts.m100664 764 764 17035 7545301336 13425 0ustar alexalex/* copyright 2002 Alexander Malmberg */ #include #include #include #include #include #include #include #include FT_FREETYPE_H static FT_Library ftlib; /* from GNUstep's core/back/Source/art/ftfont.m GNU LGPL:ed */ #define NSBoldFontMask 0 #define NSItalicFontMask 0 #define NSCondensedFontMask 0 static int traits_from_string(NSString *s, unsigned int *traits, unsigned int *weight) { static struct { NSString *str; unsigned int trait; int weight; } suffix[] = { /* TODO */ {@"Ultralight" ,0 , 1}, {@"Thin" ,0 , 2}, {@"Light" ,0 , 3}, {@"Extralight" ,0 , 3}, {@"Book" ,0 , 4}, {@"Regular" ,0 , 5}, {@"Plain" ,0 , 5}, {@"Display" ,0 , 5}, {@"Roman" ,0 , 5}, {@"Semilight" ,0 , 5}, {@"Medium" ,0 , 6}, {@"Demi" ,0 , 7}, {@"Demibold" ,0 , 7}, {@"Semi" ,0 , 8}, {@"Semibold" ,0 , 8}, {@"Bold" ,NSBoldFontMask , 9}, {@"Extra" ,NSBoldFontMask ,10}, {@"Extrabold" ,NSBoldFontMask ,10}, {@"Heavy" ,NSBoldFontMask ,11}, {@"Heavyface" ,NSBoldFontMask ,11}, {@"Ultrabold" ,NSBoldFontMask ,12}, {@"Black" ,NSBoldFontMask ,12}, {@"Ultra" ,NSBoldFontMask ,13}, {@"Ultrablack" ,NSBoldFontMask ,13}, {@"Fat" ,NSBoldFontMask ,13}, {@"Extrablack" ,NSBoldFontMask ,14}, {@"Obese" ,NSBoldFontMask ,14}, {@"Nord" ,NSBoldFontMask ,14}, {@"Italic" ,NSItalicFontMask ,-1}, {@"Oblique" ,NSItalicFontMask ,-1}, {@"Cond" ,NSCondensedFontMask ,-1}, {@"Condensed" ,NSCondensedFontMask ,-1}, {nil,0,-1} }; int i; *traits = 0; // printf("do '%@'\n", s); while ([s length] > 0) { // printf(" got '%@'\n", s); if ([s hasSuffix: @"-"] || [s hasSuffix: @" "]) { // printf(" do -\n"); s = [s substringToIndex: [s length] - 1]; continue; } for (i = 0; suffix[i].str; i++) { if (![s hasSuffix: suffix[i].str]) continue; // printf(" found '%@'\n", suffix[i].str); if (suffix[i].weight != -1) *weight = suffix[i].weight; (*traits) |= suffix[i].trait; s = [s substringToIndex: [s length] - [suffix[i].str length]]; break; } if (!suffix[i].str) break; } // printf("end up with '%@'\n", s); return [s length]; } @interface FaceInfo : NSObject { @public NSString *postScriptName; NSString *familyName; NSString *faceName; NSMutableArray *files; } -(BOOL) collectFaceInfo; -(NSDictionary *) faceInfoDictionary; @end @implementation FaceInfo - init { self=[super init]; files=[[NSMutableArray alloc] init]; return self; } -(void) dealloc { DESTROY(files); [super dealloc]; } -(NSString *) description { return [NSString stringWithFormat: @"", postScriptName,familyName,faceName,files]; } -(BOOL) collectFaceInfo { FT_Face face; int i; const char *psname; int foo,bar; for (i=1;i<[files count];i++) { NSString *f; f=[files objectAtIndex: i]; if ([[f pathExtension] isEqualToString: @"pfa"] || [[f pathExtension] isEqualToString: @"pfb"]) { [f retain]; [files removeObject: f]; [files insertObject: f atIndex: 0]; [f release]; } } if (FT_New_Face(ftlib,[[files objectAtIndex: 0] cString],0,&face)) { fprintf(stderr,"unable to open %@, ignoring\n",[files objectAtIndex: 0]); return NO; } for (i=1;i<[files count];i++) { if (FT_Attach_File(face,[[files objectAtIndex: i] cString])) { fprintf(stderr,"warning: unable to attach %@\n",[files objectAtIndex: i]); } } psname=FT_Get_Postscript_Name(face); if (!psname) { fprintf(stderr,"couldn't get postscript name for %@, ignoring\n",[files objectAtIndex: 0]); return NO; } postScriptName=[[NSString alloc] initWithCString: psname]; familyName=[[NSString alloc] initWithCString: face->family_name]; faceName=[[NSString alloc] initWithCString: face->style_name]; if (traits_from_string(faceName,&foo,&bar)) { fprintf(stderr,"warning: couldn't fully parse '%@' (%@)\n",faceName,postScriptName); } FT_Done_Face(face); return YES; } -(NSDictionary *) faceInfoDictionary { return [NSDictionary dictionaryWithObjectsAndKeys: files,@"Files", postScriptName,@"PostScriptName", faceName,@"Name", nil]; } @end static NSArray *group_files(NSArray *files) { NSSet *combine_set=[NSSet setWithObjects: @"pfa",@"pfb",@"afm",@"pfm",nil]; NSMutableDictionary *groups; NSArray *a; int i; groups=[[NSMutableDictionary alloc] init]; for (i=0;i<[files count];i++) { NSString *f=[files objectAtIndex: i]; NSString *key; FaceInfo *fa; if ([combine_set containsObject: [f pathExtension]]) key=[f stringByDeletingPathExtension]; else key=f; fa=[groups objectForKey: key]; if (!fa) { fa=[[[FaceInfo alloc] init] autorelease]; [groups setObject: fa forKey: key]; } [fa->files addObject: f]; } a=[groups allValues]; DESTROY(groups); return a; } int main(int argc, char **argv) { CREATE_AUTORELEASE_POOL(arp); NSMutableArray *files; NSArray *groups; int i; NSMutableDictionary *families; files=[[NSMutableArray alloc] init]; for (i=1;ifamilyName]; if (!ma) { ma=[[[NSMutableArray alloc] init] autorelease]; [families setObject: ma forKey: fi->familyName]; } [ma addObject: fi]; } } DESTROY(groups); { NSFileManager *fm=[NSFileManager defaultManager]; NSEnumerator *e; NSString *family; int i,c,j; NSMutableDictionary *family_info; NSMutableArray *faces; NSArray *faceinfos; FaceInfo *fi; NSString *path; e=[families keyEnumerator]; while ((family=[e nextObject])) { family_info=[[NSMutableDictionary alloc] init]; faces=[[NSMutableArray alloc] init]; [family_info setObject: faces forKey: @"Faces"]; path=[family stringByAppendingPathExtension: @"nfont"]; [fm createDirectoryAtPath: path attributes: nil]; faceinfos=[families objectForKey: family]; for (c=[faceinfos count],i=0;ifiles count];j++) { [fm movePath: [fi->files objectAtIndex: j] toPath: [path stringByAppendingPathComponent: [[fi->files objectAtIndex: j] lastPathComponent]] handler: nil]; } } [family_info writeToFile: [path stringByAppendingPathComponent: @"FontInfo.plist"] atomically: NO]; DESTROY(faces); DESTROY(family_info); } } DESTROY(families); DESTROY(arp); return 0; }