diff --git a/ChangeLog b/ChangeLog index 173ba43..7586cd5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-01-23 Fred Kiefer + + * Headers/cairo/CairoFaceInfo.h, + * Source/cairo/CairoFaceInfo.m, + * Source/cairo/CairoFontEnumerator.m, + * Source/cairo/CairoFontInfo.m: + Rewrite of all cairo font handling to work with exported cairo + functions and enumerate fonts with the font config library. + 2006-01-14 Richard Frith-Macdonald * Source/gsc/GSContext.m: diff --git a/Headers/cairo/CairoFaceInfo.h b/Headers/cairo/CairoFaceInfo.h index 46273e3..525d124 100644 --- a/Headers/cairo/CairoFaceInfo.h +++ b/Headers/cairo/CairoFaceInfo.h @@ -5,6 +5,9 @@ * August 31, 2003 * Written by Banlu Kemiyatorn * Base on code by Alexander Malmberg + * Rewrite: Fred Kiefer + * Date: Jan 2006 + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -23,54 +26,35 @@ #ifndef CAIROFACEINFO_H #define CAIROFACEINFO_H #include -#include +#include @interface CairoFaceInfo : NSObject { int _weight; unsigned int _traits; - cairo_font_slant_t _c_slant; - cairo_font_weight_t _c_weight; cairo_font_face_t *_fontFace; + FcPattern *_pattern; - NSString *_faceName; NSString *_familyName; - NSString *_displayName; - NSString *_cairoName; } -- (id) initWithName: (NSString *)name - familyName: (NSString *)familyName - displayName: (NSString *)displayName - cairoName: (NSString *)cairoName - weight: (int)weight - traits: (unsigned int)traits - cairoSlant: (cairo_font_slant_t)cairoSlant - cairoWeight: (cairo_font_weight_t)cairoWeight; -- (unsigned int) cacheSize; +- (id) initWithfamilyName: (NSString *)familyName + weight: (int)weight + traits: (unsigned int)traits + pattern: (FcPattern *)pattern; -- (cairo_font_weight_t) cairoWeight; -- (void) setCairoWeight: (cairo_font_weight_t) weight; -- (cairo_font_slant_t) cairoSlant; -- (void) setCairoSlant: (cairo_font_slant_t) slant; +- (unsigned int) cacheSize; - (int) weight; - (void) setWeight: (int)weight; - (unsigned int) traits; - (void) setTraits: (unsigned int)traits; -- (NSString *) displayName; -- (void) setDisplayName: (NSString *)name; - (NSString *) familyName; - (void) setFamilyName: (NSString *)name; -- (NSString *) name; -- (void) setName: (NSString *)name; -- (const char *) cairoCName; -- (void) setCairoName: (NSString *)name; + - (cairo_font_face_t *)fontFace; - - @end #endif diff --git a/Source/cairo/CairoFaceInfo.m b/Source/cairo/CairoFaceInfo.m index 2db93d7..c91f722 100644 --- a/Source/cairo/CairoFaceInfo.m +++ b/Source/cairo/CairoFaceInfo.m @@ -5,6 +5,9 @@ * August 31, 2003 * Written by Banlu Kemiyatorn * Base on original code of Alex Malmberg + * Rewrite: Fred Kiefer + * Date: Jan 2006 + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -26,23 +29,17 @@ @ implementation CairoFaceInfo -- (id) initWithName: (NSString *)name - familyName: (NSString *)familyName - displayName: (NSString *)displayName - cairoName: (NSString *)cairoName - weight: (int)weight - traits: (unsigned int)traits - cairoSlant: (cairo_font_slant_t)cairoSlant - cairoWeight: (cairo_font_weight_t)cairoWeight +- (id) initWithfamilyName: (NSString *)familyName + weight: (int)weight + traits: (unsigned int)traits + pattern: (FcPattern *)pattern { - [self setName: name]; + _pattern = pattern; + FcPatternReference(_pattern); + [self setFamilyName: familyName]; - [self setDisplayName: displayName]; - [self setCairoName: cairoName]; [self setWeight: weight]; [self setTraits: traits]; - [self setCairoSlant: cairoSlant]; - [self setCairoWeight: cairoWeight]; return self; } @@ -53,10 +50,10 @@ { cairo_font_face_destroy(_fontFace); } + FcPatternDestroy(_pattern); + RELEASE(_familyName); - RELEASE(_faceName); - RELEASE(_displayName); - RELEASE(_cairoName); + [super dealloc]; } @@ -65,41 +62,11 @@ ASSIGN(_familyName, name); } -- (void) setName: (NSString *)name -{ - ASSIGN(_faceName, name); -} - -- (void) setDisplayName: (NSString *)name -{ - ASSIGN(_displayName, name); -} - -- (const char *) cairoCName -{ - return [_cairoName lossyCString]; -} - -- (void) setCairoName: (NSString *)name -{ - ASSIGN(_cairoName, name); -} - - (NSString *)familyName { return _familyName; } -- (NSString *) name -{ - return _faceName; -} - -- (NSString *) displayName -{ - return _displayName; -} - - (int) weight { return _weight; @@ -115,26 +82,6 @@ return _traits; } -- (cairo_font_weight_t) cairoWeight -{ - return _c_weight; -} - -- (cairo_font_slant_t) cairoSlant -{ - return _c_slant; -} - -- (void) setCairoWeight: (cairo_font_weight_t)weight -{ - _c_weight = weight; -} - -- (void) setCairoSlant: (cairo_font_slant_t)slant -{ - _c_slant = slant; -} - - (void) setTraits: (unsigned int)traits { _traits = traits; @@ -145,18 +92,27 @@ return 257; } -extern cairo_font_face_t * -_cairo_toy_font_face_create(const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight); - - (cairo_font_face_t *)fontFace { if (!_fontFace) { - // FIXME: This function is not exported by cairo - _fontFace = _cairo_toy_font_face_create([_cairoName cString], - _c_slant, _c_weight); + FcResult result; + FcPattern *resolved; + + FcConfigSubstitute (NULL, _pattern, FcMatchPattern); + FcDefaultSubstitute(_pattern); + resolved = FcFontMatch(NULL, _pattern, &result); + + _fontFace = cairo_ft_font_face_create_for_pattern(resolved); + FcPatternDestroy(resolved); + + if ((!_fontFace) || (cairo_font_face_status(_fontFace) != CAIRO_STATUS_SUCCESS)) + { + NSLog(@"Creating a font face failed %@", _familyName); + cairo_font_face_destroy(_fontFace); + _fontFace = NULL; + return NULL; + } } return _fontFace; diff --git a/Source/cairo/CairoFontEnumerator.m b/Source/cairo/CairoFontEnumerator.m index c5e0783..b6668aa 100644 --- a/Source/cairo/CairoFontEnumerator.m +++ b/Source/cairo/CairoFontEnumerator.m @@ -5,6 +5,9 @@ * August 31, 2003 * Written by Banlu Kemiyatorn * Base on original code of Alex Malmberg + * Rewrite: Fred Kiefer + * Date: Jan 2006 + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -54,102 +57,149 @@ NSMutableDictionary * __allFonts; return face; } +// Make a GNUStep style font descriptor from a FcPattern +static NSArray *faFromFc(FcPattern *pat) +{ + int weight, slant, spacing, nsweight; + unsigned int nstraits = 0; + char *family; + NSMutableString *name, *style; + + if (FcPatternGetInteger(pat, FC_WEIGHT, 0, &weight) != FcResultMatch || + FcPatternGetInteger(pat, FC_SLANT, 0, &slant) != FcResultMatch || + FcPatternGetString(pat, FC_FAMILY, 0, (FcChar8 **)&family) != FcResultMatch) + return nil; + + if (FcPatternGetInteger(pat, FC_SPACING, 0, &spacing) == FcResultMatch) + if (spacing==FC_MONO || spacing==FC_CHARCELL) + nstraits |= NSFixedPitchFontMask; + + name = [NSMutableString stringWithCapacity: 100]; + style = [NSMutableString stringWithCapacity: 100]; + [name appendString: [NSString stringWithUTF8String: family]]; + + switch (weight) + { + case FC_WEIGHT_LIGHT: + [style appendString: @"Light"]; + nsweight = 3; + break; + case FC_WEIGHT_MEDIUM: + nsweight = 6; + break; + case FC_WEIGHT_DEMIBOLD: + [style appendString: @"Demibold"]; + nsweight = 7; + break; + case FC_WEIGHT_BOLD: + [style appendString: @"Bold"]; + nsweight = 9; + nstraits |= NSBoldFontMask; + break; + case FC_WEIGHT_BLACK: + [style appendString: @"Black"]; + nsweight = 12; + nstraits |= NSBoldFontMask; + break; + default: + nsweight = 6; + } + + switch (slant) + { + case FC_SLANT_ROMAN: + break; + case FC_SLANT_ITALIC: + [style appendString: @"Italic"]; + nstraits |= NSItalicFontMask; + break; + case FC_SLANT_OBLIQUE: + [style appendString: @"Oblique"]; + nstraits |= NSItalicFontMask; + break; + } + + if ([style length] > 0) + { + [name appendString: @"-"]; + [name appendString: style]; + } + else + { + [style appendString: @"Roman"]; + } + + return [NSArray arrayWithObjects: name, + style, + [NSNumber numberWithInt: nsweight], + [NSNumber numberWithUnsignedInt: nstraits], + nil]; +} + - (void) enumerateFontsAndFamilies { - static BOOL done = NO; + int i; + NSMutableDictionary *fcxft_allFontFamilies = [[NSMutableDictionary alloc] init]; + NSMutableDictionary *fcxft_allFonts = [[NSMutableDictionary alloc] init]; + NSMutableArray *fcxft_allFontNames = [[NSMutableArray alloc] init]; - if (!done) + FcPattern *pat = FcPatternCreate(); + FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_SLANT, FC_WEIGHT, NULL); + FcFontSet *fs = FcFontList(NULL, pat, os); + + FcPatternDestroy(pat); + FcObjectSetDestroy(os); + + for (i=0; i < fs->nfont; i++) { - NSArray *fontDef; - NSMutableArray *fontDefs; - CairoFaceInfo *aFace; + char *family; - __allFonts = [[NSMutableDictionary alloc] init]; - allFontFamilies =[[NSMutableDictionary alloc] init]; + if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **)&family) == FcResultMatch) + { + NSArray *fontArray; - fontDefs =[NSMutableArray arrayWithCapacity:10]; - [allFontFamilies setObject: fontDefs forKey:@"Helvetica"]; + if ((fontArray = faFromFc(fs->fonts[i]))) + { + NSString *familyString; + NSMutableArray *familyArray; + CairoFaceInfo *aFont; + NSString *name = [fontArray objectAtIndex: 0]; - fontDef =[NSArray arrayWithObjects: @"Helvetica", @"Medium", - [NSNumber numberWithInt: 5], - [NSNumber numberWithUnsignedInt:0], nil]; - [fontDefs addObject:fontDef]; - aFace = [[CairoFaceInfo alloc] initWithName: @"Medium" - familyName: @"Helvetica" - displayName: @"Helvetica" - cairoName: @"serif" - weight: 5 - traits: 0 - cairoSlant: CAIRO_FONT_SLANT_NORMAL - cairoWeight: CAIRO_FONT_WEIGHT_NORMAL]; - [__allFonts setObject: aFace forKey: @"Helvetica"]; - RELEASE(aFace); - - fontDef =[NSArray arrayWithObjects: @"Helvetica-Bold", @"Bold", - [NSNumber numberWithInt: 9], - [NSNumber numberWithUnsignedInt:NSBoldFontMask], - nil]; - [fontDefs addObject:fontDef]; - aFace = [[CairoFaceInfo alloc] initWithName: @"Bold" - familyName: @"Helvetica" - displayName: @"Helvetica Bold" - cairoName: @"serif" - weight: 9 - traits: NSBoldFontMask - cairoSlant: CAIRO_FONT_SLANT_NORMAL - cairoWeight: CAIRO_FONT_WEIGHT_BOLD]; - [__allFonts setObject: aFace forKey: @"Helvetica-Bold"]; - RELEASE(aFace); - - fontDef =[NSArray arrayWithObjects: @"Helvetica-Oblique", @"Oblique", - [NSNumber numberWithInt: 5], - [NSNumber numberWithUnsignedInt:NSItalicFontMask], - nil]; - [fontDefs addObject:fontDef]; - aFace = [[CairoFaceInfo alloc] initWithName: @"Oblique" - familyName: @"Helvetica" - displayName: @"Helvetica Oblique" - cairoName: @"serif" - weight: 5 - traits: NSItalicFontMask - cairoSlant: CAIRO_FONT_SLANT_OBLIQUE - cairoWeight: CAIRO_FONT_WEIGHT_NORMAL]; - [__allFonts setObject: aFace forKey: @"Helvetica-Oblique"]; - RELEASE(aFace); - - fontDefs =[NSMutableArray arrayWithCapacity:10]; - [allFontFamilies setObject: fontDefs forKey:@"Courier"]; - - fontDef =[NSArray arrayWithObjects: @"Courier", @"Medium", - [NSNumber numberWithInt: 5], - [NSNumber numberWithUnsignedInt:NSFixedPitchFontMask], - nil]; - [fontDefs addObject:fontDef]; - aFace = [[CairoFaceInfo alloc] initWithName: @"Medium" - familyName: @"Courier" - displayName: @"Courier" - cairoName: @"Courier" - weight: 5 - traits: NSFixedPitchFontMask - cairoSlant: CAIRO_FONT_SLANT_NORMAL - cairoWeight: CAIRO_FONT_WEIGHT_NORMAL]; - [__allFonts setObject: aFace forKey: @"Courier"]; - RELEASE(aFace); - - ASSIGN(allFontNames, [__allFonts allKeys]); - done = YES; + familyString = [NSString stringWithUTF8String: family]; + if (!(familyArray = [fcxft_allFontFamilies objectForKey: familyString])) + { + NSDebugLog(@"Found font family %@", familyString); + familyArray = [[NSMutableArray alloc] init]; + [fcxft_allFontFamilies setObject: familyArray forKey: familyString]; + RELEASE(familyArray); + } + NSDebugLog(@"fc enumerator: adding font: %@", name); + [familyArray addObject: fontArray]; + [fcxft_allFontNames addObject: name]; + aFont = [[CairoFaceInfo alloc] initWithfamilyName: familyString + weight: [[fontArray objectAtIndex: 2] intValue] + traits: [[fontArray objectAtIndex: 3] unsignedIntValue] + pattern: fs->fonts[i]]; + [fcxft_allFonts setObject: aFont forKey: name]; + RELEASE(aFont); + } + } } - //NSLog (@"%@", allFontNames); + FcFontSetDestroy (fs); + + allFontNames = fcxft_allFontNames; + allFontFamilies = fcxft_allFontFamilies; + __allFonts = fcxft_allFonts; } - (NSString *) defaultSystemFontName { - return @"Helvetica"; + return @"Adobe Helvetica"; } - (NSString *) defaultBoldSystemFontName { - return @"Helvetica-Bold"; + return @"Adobe Helvetica-Bold"; } - (NSString *) defaultFixedPitchFontName diff --git a/Source/cairo/CairoFontInfo.m b/Source/cairo/CairoFontInfo.m index 2eac913..18ee423 100644 --- a/Source/cairo/CairoFontInfo.m +++ b/Source/cairo/CairoFontInfo.m @@ -154,35 +154,6 @@ return YES; } -// FIXME: This function is not exported by Cairo. The parameters have changed in recent cairo!!! -extern -cairo_status_t -_cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, - const char *utf8, - cairo_glyph_t **glyphs, - int *num_glyphs); - -static -BOOL _cairo_extents_for_text(cairo_scaled_font_t *scaled_font, const char *utf8, - cairo_text_extents_t *ctext) -{ - cairo_glyph_t *glyphs = NULL; - int num_glyphs; - cairo_status_t status; - - status = _cairo_scaled_font_text_to_glyphs(scaled_font, utf8, - &glyphs, &num_glyphs); - if (glyphs) - { - cairo_scaled_font_glyph_extents(scaled_font, glyphs, num_glyphs, ctext); - free(glyphs); - - return YES; - } - - return NO; -} - static BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph, cairo_text_extents_t *ctext) @@ -192,8 +163,9 @@ BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph, // FIXME: This is wrong for none ASCII characters! str[0] = glyph; str[1] = 0; - - return _cairo_extents_for_text(scaled_font, str, ctext); + + cairo_scaled_font_text_extents(scaled_font, str, ctext); + return cairo_scaled_font_status(scaled_font) == CAIRO_STATUS_SUCCESS; } - (NSSize) advancementForGlyph: (NSGlyph)glyph @@ -236,7 +208,8 @@ BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph, { cairo_text_extents_t ctext; - if (_cairo_extents_for_text(_scaled, [string UTF8String], &ctext)) + cairo_scaled_font_text_extents(_scaled, [string UTF8String], &ctext); + if (cairo_scaled_font_status(_scaled) == CAIRO_STATUS_SUCCESS) { return ctext.width; }