4
Copyright (C) 2003 Free Software Foundation, Inc.
7
Written by Banlu Kemiyatorn <object at gmail dot com>
8
Base on original code of Alex Malmberg
9
Rewrite: Fred Kiefer <fredkiefer@gmx.de>
12
This file is part of GNUstep.
14
This library is free software; you can redistribute it and/or
15
modify it under the terms of the GNU Lesser General Public
16
License as published by the Free Software Foundation; either
17
version 2 of the License, or (at your option) any later version.
19
This library is distributed in the hope that it will be useful,
20
but WITHOUT ANY WARRANTY; without even the implied warranty of
21
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22
Lesser General Public License for more details.
24
You should have received a copy of the GNU Lesser General Public
25
License along with this library; see the file COPYING.LIB.
26
If not, see <http://www.gnu.org/licenses/> or write to the
27
Free Software Foundation, 51 Franklin Street, Fifth Floor,
28
Boston, MA 02110-1301, USA.
31
#include <Foundation/NSObject.h>
32
#include <Foundation/NSArray.h>
33
#include <Foundation/NSSet.h>
34
#include <Foundation/NSDictionary.h>
35
#include <Foundation/NSValue.h>
36
#include <Foundation/NSPathUtilities.h>
37
#include <Foundation/NSFileManager.h>
38
#include <Foundation/NSUserDefaults.h>
39
#include <Foundation/NSBundle.h>
40
#include <Foundation/NSDebug.h>
41
#include <GNUstepGUI/GSFontInfo.h>
42
#include <AppKit/NSAffineTransform.h>
43
#include <AppKit/NSBezierPath.h>
44
#include <AppKit/NSFontDescriptor.h>
46
#include "gsc/GSGState.h"
47
#include "fontconfig/FCFontEnumerator.h"
48
#include "fontconfig/FCFontInfo.h"
50
// Old versions of fontconfig don't have FC_WEIGHT_ULTRABLACK defined.
51
// Use the maximal value instead.
52
#ifndef FC_WEIGHT_ULTRABLACK
53
#define FC_WEIGHT_ULTRABLACK FC_WEIGHT_BLACK
56
@implementation FCFontEnumerator
58
NSMutableDictionary * __allFonts;
60
+ (FCFaceInfo *) fontWithName: (NSString *) name
64
face = [__allFonts objectForKey: name];
67
NSDebugLLog(@"NSFont", @"Font not found %@", name);
72
+ (Class) faceInfoClass
74
[self subclassResponsibility: _cmd];
78
// Make a GNUstep style font descriptor from a FcPattern
79
static NSArray *faFromFc(FcPattern *pat)
81
int weight, slant, spacing, nsweight;
82
unsigned int nstraits = 0;
84
NSMutableString *name, *style;
86
if (FcPatternGetInteger(pat, FC_WEIGHT, 0, &weight) != FcResultMatch
87
|| FcPatternGetInteger(pat, FC_SLANT, 0, &slant) != FcResultMatch
88
|| FcPatternGetString(pat, FC_FAMILY, 0, (FcChar8 **)&family)
92
if (FcPatternGetInteger(pat, FC_SPACING, 0, &spacing) == FcResultMatch)
93
if (spacing==FC_MONO || spacing==FC_CHARCELL)
94
nstraits |= NSFixedPitchFontMask;
96
name = [NSMutableString stringWithCapacity: 100];
97
style = [NSMutableString stringWithCapacity: 100];
98
[name appendString: [NSString stringWithUTF8String: family]];
102
case FC_WEIGHT_LIGHT:
103
[style appendString: @"Light"];
106
case FC_WEIGHT_MEDIUM:
109
case FC_WEIGHT_DEMIBOLD:
110
[style appendString: @"Demibold"];
114
[style appendString: @"Bold"];
116
nstraits |= NSBoldFontMask;
118
case FC_WEIGHT_BLACK:
119
[style appendString: @"Black"];
121
nstraits |= NSBoldFontMask;
131
case FC_SLANT_ITALIC:
132
[style appendString: @"Italic"];
133
nstraits |= NSItalicFontMask;
135
case FC_SLANT_OBLIQUE:
136
[style appendString: @"Oblique"];
137
nstraits |= NSItalicFontMask;
141
if ([style length] > 0)
143
[name appendString: @"-"];
144
[name appendString: style];
148
[style appendString: @"Roman"];
151
return [NSArray arrayWithObjects: name,
153
[NSNumber numberWithInt: nsweight],
154
[NSNumber numberWithUnsignedInt: nstraits],
158
- (void) enumerateFontsAndFamilies
161
NSMutableDictionary *fcxft_allFontFamilies = [NSMutableDictionary new];
162
NSMutableDictionary *fcxft_allFonts = [NSMutableDictionary new];
163
NSMutableArray *fcxft_allFontNames = [NSMutableArray new];
164
Class faceInfoClass = [[self class] faceInfoClass];
166
FcPattern *pat = FcPatternCreate();
167
FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_SLANT, FC_WEIGHT,
169
FcFontSet *fs = FcFontList(NULL, pat, os);
171
FcPatternDestroy(pat);
172
FcObjectSetDestroy(os);
174
for (i = 0; i < fs->nfont; i++)
178
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **)&family)
183
if ((fontArray = faFromFc(fs->fonts[i])))
185
NSString *familyString;
186
NSMutableArray *familyArray;
188
NSString *name = [fontArray objectAtIndex: 0];
190
familyString = [NSString stringWithUTF8String: family];
191
familyArray = [fcxft_allFontFamilies objectForKey: familyString];
192
if (familyArray == nil)
194
NSDebugLLog(@"NSFont", @"Found font family %@", familyString);
195
familyArray = [[NSMutableArray alloc] init];
196
[fcxft_allFontFamilies setObject: familyArray
197
forKey: familyString];
198
RELEASE(familyArray);
200
NSDebugLLog(@"NSFont", @"fc enumerator: adding font: %@", name);
201
[familyArray addObject: fontArray];
202
[fcxft_allFontNames addObject: name];
203
aFont = [[faceInfoClass alloc] initWithfamilyName: familyString
204
weight: [[fontArray objectAtIndex: 2] intValue]
205
traits: [[fontArray objectAtIndex: 3] unsignedIntValue]
206
pattern: fs->fonts[i]];
207
[fcxft_allFonts setObject: aFont forKey: name];
212
FcFontSetDestroy (fs);
214
allFontNames = fcxft_allFontNames;
215
allFontFamilies = fcxft_allFontFamilies;
216
__allFonts = fcxft_allFonts;
219
- (NSString *) defaultSystemFontName
221
if ([allFontNames containsObject: @"Bitstream Vera Sans"])
223
return @"Bitstream Vera Sans";
225
if ([allFontNames containsObject: @"FreeSans"])
229
if ([allFontNames containsObject: @"DejaVu Sans"])
231
return @"DejaVu Sans";
233
if ([allFontNames containsObject: @"Tahoma"])
237
if ([allFontNames containsObject: @"Arial"])
244
- (NSString *) defaultBoldSystemFontName
246
if ([allFontNames containsObject: @"Bitstream Vera Sans-Bold"])
248
return @"Bitstream Vera Sans-Bold";
250
if ([allFontNames containsObject: @"FreeSans-Bold"])
252
return @"FreeSans-Bold";
254
if ([allFontNames containsObject: @"DejaVu Sans-Bold"])
256
return @"DejaVu Sans-Bold";
258
if ([allFontNames containsObject: @"Tahoma-Bold"])
260
return @"Tahoma-Bold";
262
if ([allFontNames containsObject: @"Arial-Bold"])
264
return @"Arial-Bold";
266
return @"Helvetica-Bold";
269
- (NSString *) defaultFixedPitchFontName
271
if ([allFontNames containsObject: @"Bitstream Vera Sans Mono"])
273
return @"Bitstream Vera Sans Mono";
275
if ([allFontNames containsObject: @"FreeMono"])
279
if ([allFontNames containsObject: @"DejaVu Sans Mono"])
281
return @"DejaVu Sans Mono";
283
if ([allFontNames containsObject: @"Courier New"])
285
return @"Courier New";
291
* Overrides the implementation in GSFontInfo, and delegates the
292
* matching to Fontconfig.
294
- (NSArray *) matchingFontDescriptorsFor: (NSDictionary *)attributes
296
NSMutableArray *descriptors;
298
FcPattern *matchedpat, *pat;
299
FontconfigPatternGenerator *generator;
301
descriptors = [NSMutableArray array];
303
generator = [[FontconfigPatternGenerator alloc] init];
304
pat = [generator createPatternWithAttributes: attributes];
307
FcConfigSubstitute(NULL, pat, FcMatchPattern);
308
FcDefaultSubstitute(pat);
309
result = FcResultMatch;
310
matchedpat = FcFontMatch(NULL, pat, &result);
311
if (result != FcResultMatch)
313
NSLog(@"Warning, FcFontMatch failed with code: %d", result);
318
result = FcResultMatch;
319
fontSet = FcFontSort(NULL, matchedpat, FcFalse, NULL, &result);
320
if (result == FcResultMatch)
323
for (i=0; i<fontSet->nfont; i++)
325
FontconfigPatternParser *parser = [[FontconfigPatternParser alloc] init];
326
// FIXME: do we need to match this pattern?
327
FcPattern *matchingpat = fontSet->fonts[i];
328
NSDictionary *attribs = [parser attributesFromPattern: matchingpat];
331
[descriptors addObject: [NSFontDescriptor fontDescriptorWithFontAttributes: attribs]];
336
NSLog(@"ERROR! FcFontSort failed");
339
FcFontSetDestroy(fontSet);
340
FcPatternDestroy(matchedpat);
343
FcPatternDestroy(pat);
351
@implementation FontconfigPatternGenerator
353
- (void)addName: (NSString*)name
355
// FIXME: Fontconfig ignores PostScript names of fonts; we need
356
// https://bugs.freedesktop.org/show_bug.cgi?id=18095 fixed.
358
// This is a heuristic to try to 'parse' a PostScript font name,
359
// however, since they are just unique identifiers for fonts and
360
// don't need to follow any naming convention, this may fail
362
NSRange dash = [name rangeOfString: @"-"];
363
if (dash.location == NSNotFound)
365
FcPatternAddString(_pat, FC_FAMILY, (const FcChar8 *)[name UTF8String]);
369
NSString *weightAndSlant = [name substringFromIndex: dash.location + 1];
370
NSString *family = [name substringToIndex: dash.location];
372
FcPatternAddString(_pat, FC_FAMILY, (const FcChar8 *)[family UTF8String]);
374
if (NSNotFound != [weightAndSlant rangeOfString: @"Light"].location)
376
FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_LIGHT);
378
else if (NSNotFound != [weightAndSlant rangeOfString: @"Medium"].location)
380
FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_MEDIUM);
382
else if (NSNotFound != [weightAndSlant rangeOfString: @"Demibold"].location)
384
FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_DEMIBOLD);
386
else if (NSNotFound != [weightAndSlant rangeOfString: @"Bold"].location)
388
FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_BOLD);
390
else if (NSNotFound != [weightAndSlant rangeOfString: @"Black"].location)
392
FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_BLACK);
395
if (NSNotFound != [weightAndSlant rangeOfString: @"Italic"].location)
397
FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_ITALIC);
399
else if (NSNotFound != [weightAndSlant rangeOfString: @"Oblique"].location)
401
FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_OBLIQUE);
404
if (NSNotFound != [weightAndSlant rangeOfString: @"Condensed"].location)
406
FcPatternAddInteger(_pat, FC_WIDTH, FC_WIDTH_CONDENSED);
408
else if (NSNotFound != [weightAndSlant rangeOfString: @"Expanded"].location)
410
FcPatternAddInteger(_pat, FC_WIDTH, FC_WIDTH_EXPANDED);
415
- (void)addVisibleName: (NSString*)name
417
FcPatternAddString(_pat, FC_FULLNAME, (const FcChar8 *)[name UTF8String]);
420
- (void)addFamilyName: (NSString*)name
422
FcPatternAddString(_pat, FC_FAMILY, (const FcChar8 *)[name UTF8String]);
425
- (void)addStyleName: (NSString*)style
427
FcPatternAddString(_pat, FC_STYLE, (const FcChar8 *)[style UTF8String]);
430
- (void)addTraits: (NSDictionary*)traits
432
if ([traits objectForKey: NSFontSymbolicTrait])
434
NSFontSymbolicTraits symTraits = [[traits objectForKey: NSFontSymbolicTrait] intValue];
436
if (symTraits & NSFontItalicTrait)
438
// NOTE: May be overridden by NSFontSlantTrait
439
FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_ITALIC);
441
if (symTraits & NSFontBoldTrait)
443
// NOTE: May be overridden by NSFontWeightTrait
444
FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_BOLD);
446
if (symTraits & NSFontExpandedTrait)
448
// NOTE: May be overridden by NSFontWidthTrait
449
FcPatternAddInteger(_pat, FC_WIDTH, FC_WIDTH_EXPANDED);
451
if (symTraits & NSFontCondensedTrait)
453
// NOTE: May be overridden by NSFontWidthTrait
454
FcPatternAddInteger(_pat, FC_WIDTH, FC_WIDTH_CONDENSED);
456
if (symTraits & NSFontMonoSpaceTrait)
459
// If you run "fc-match :spacing=100", you get "DejaVu Sans" even though you would
460
// expect to get "DejaVu Sans Mono". So, we also add "monospace" as a weak family
461
// name to fix the problem.
462
FcPatternAddInteger(_pat, FC_SPACING, FC_MONO);
464
value.type = FcTypeString;
465
value.u.s = (FcChar8*)"monospace";
466
FcPatternAddWeak(_pat, FC_FAMILY, value, FcTrue);
468
if (symTraits & NSFontVerticalTrait)
470
// FIXME: What is this supposed to mean?
472
if (symTraits & NSFontUIOptimizedTrait)
474
// NOTE: Fontconfig can't express this
478
NSFontFamilyClass class = symTraits & NSFontFamilyClassMask;
479
char *addWeakFamilyName = NULL;
483
case NSFontUnknownClass:
484
case NSFontOrnamentalsClass:
485
case NSFontScriptsClass:
486
case NSFontSymbolicClass:
487
// FIXME: Is there some way to convey these to Fontconfig?
489
case NSFontOldStyleSerifsClass:
490
case NSFontTransitionalSerifsClass:
491
case NSFontModernSerifsClass:
492
case NSFontClarendonSerifsClass:
493
case NSFontSlabSerifsClass:
494
case NSFontFreeformSerifsClass:
495
addWeakFamilyName = "serif";
497
case NSFontSansSerifClass:
498
addWeakFamilyName = "sans";
501
if (addWeakFamilyName)
504
value.type = FcTypeString;
505
value.u.s = (const FcChar8 *)addWeakFamilyName;
506
FcPatternAddWeak(_pat, FC_FAMILY, value, FcTrue);
511
if ([traits objectForKey: NSFontWeightTrait])
514
* Scale: -1 is thinnest, 0 is normal, 1 is heaviest
516
double weight = [[traits objectForKey: NSFontWeightTrait] doubleValue];
519
weight = MAX(-1, MIN(1, weight));
522
fcWeight = FC_WEIGHT_THIN + ((weight + 1.0) * (FC_WEIGHT_NORMAL - FC_WEIGHT_THIN));
526
fcWeight = FC_WEIGHT_NORMAL + (weight * (FC_WEIGHT_ULTRABLACK - FC_WEIGHT_NORMAL));
528
FcPatternAddInteger(_pat, FC_WEIGHT, fcWeight);
531
if ([traits objectForKey: NSFontWidthTrait])
534
* Scale: -1 is most condensed, 0 is normal, 1 is most spread apart
536
double width = [[traits objectForKey: NSFontWidthTrait] doubleValue];
539
width = MAX(-1, MIN(1, width));
542
fcWidth = FC_WIDTH_ULTRACONDENSED + ((width + 1.0) * (FC_WIDTH_NORMAL - FC_WIDTH_ULTRACONDENSED));
546
fcWidth = FC_WIDTH_NORMAL + (width * (FC_WIDTH_ULTRAEXPANDED - FC_WIDTH_NORMAL));
548
FcPatternAddInteger(_pat, FC_WIDTH, fcWidth);
551
if ([traits objectForKey: NSFontSlantTrait])
554
* Scale: -1 is 30 degree counterclockwise slant, 0 is no slant, 1
555
* is 30 degree clockwise slant
557
double slant = [[traits objectForKey: NSFontSlantTrait] doubleValue];
559
// NOTE: Fontconfig can't express this as a scale
562
FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_ITALIC);
566
FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_ROMAN);
571
- (void)addSize: (NSNumber*)size
573
FcPatternAddDouble(_pat, FC_SIZE, [size doubleValue]);
576
- (void)addCharacterSet: (NSCharacterSet*)characterSet
578
if ([characterSet isKindOfClass: [FontconfigCharacterSet class]])
581
FcPatternAddCharSet(_pat, FC_CHARSET, [(FontconfigCharacterSet*)characterSet fontconfigCharSet]);
586
FcCharSet *fcSet = FcCharSetCreate();
588
for (plane=0; plane<=16; plane++)
590
if ([characterSet hasMemberInPlane: plane])
593
for (codePoint = plane<<16; codePoint <= 0xffff + (plane<<16); codePoint++)
595
if ([characterSet longCharacterIsMember: codePoint])
597
FcCharSetAddChar(fcSet, codePoint);
603
FcPatternAddCharSet(_pat, FC_CHARSET, fcSet);
604
FcCharSetDestroy(fcSet);
608
#define ADD_TO_PATTERN(key, handlerMethod, valueClass) \
610
id value = [_attributes objectForKey: key]; \
613
if ([value isKindOfClass: valueClass]) \
615
[self handlerMethod value]; \
619
NSLog(@"NSFontDescriptor: Ignoring invalid value %@ for attribute %@", value, key); \
624
- (void)addAttributes
626
ADD_TO_PATTERN(NSFontNameAttribute, addName:, [NSString class]);
627
ADD_TO_PATTERN(NSFontVisibleNameAttribute, addVisibleName:, [NSString class]);
628
ADD_TO_PATTERN(NSFontFamilyAttribute, addFamilyName:, [NSString class]);
629
ADD_TO_PATTERN(NSFontFaceAttribute, addStyleName:, [NSString class]);
630
ADD_TO_PATTERN(NSFontTraitsAttribute, addTraits:, [NSDictionary class]);
631
ADD_TO_PATTERN(NSFontSizeAttribute, addSize:, [NSNumber class]);
632
ADD_TO_PATTERN(NSFontCharacterSetAttribute, addCharacterSet:, [NSCharacterSet class]);
635
- (FcPattern *)createPatternWithAttributes: (NSDictionary *)attributes
637
_attributes = attributes;
638
_pat = FcPatternCreate();
639
[self addAttributes];
647
@implementation FontconfigPatternParser
649
- (NSString*)readFontconfigString: (const char *)key fromPattern: (FcPattern*)pat
651
unsigned char *string = NULL;
652
if (FcResultMatch == FcPatternGetString(pat, key, 0, &string))
656
return [NSString stringWithUTF8String: (const char *)string];
662
- (NSNumber*)readFontconfigInteger: (const char *)key fromPattern: (FcPattern*)pat
665
if (FcResultMatch == FcPatternGetInteger(pat, key, 0, &value))
667
return [NSNumber numberWithInt: value];
672
- (NSNumber*)readFontconfigDouble: (const char *)key fromPattern: (FcPattern*)pat
675
if (FcResultMatch == FcPatternGetDouble(pat, key, 0, &value))
677
return [NSNumber numberWithDouble: value];
684
- (NSString*)readNameFromPattern: (FcPattern*)pat
686
// FIXME: Hack which generates a PostScript-style name from the
687
// family name and style
689
NSString *family = [self readFontconfigString: FC_FAMILY fromPattern: pat];
690
NSString *style = [self readFontconfigString: FC_STYLE fromPattern: pat];
693
return [NSString stringWithFormat: @"%@-%@", family, style];
700
- (NSString*)readVisibleNameFromPattern: (FcPattern*)pat
702
// FIXME: try to get the localized one
703
return [self readFontconfigString: FC_FULLNAME fromPattern: pat];
705
- (NSString*)readFamilyNameFromPattern: (FcPattern*)pat
707
// FIXME: try to get the localized one
708
return [self readFontconfigString: FC_FAMILY fromPattern: pat];
710
- (NSString*)readStyleNameFromPattern: (FcPattern*)pat
712
// FIXME: try to get the localized one
713
return [self readFontconfigString: FC_STYLE fromPattern: pat];
715
- (NSDictionary*)readTraitsFromPattern: (FcPattern*)pat
717
NSMutableDictionary *traits = [NSMutableDictionary dictionary];
719
NSFontSymbolicTraits symTraits = 0;
722
if (FcResultMatch == FcPatternGetInteger(pat, FC_SLANT, 0, &value))
724
if (value == FC_SLANT_ITALIC)
726
symTraits |= NSFontItalicTrait;
729
if (FcResultMatch == FcPatternGetInteger(pat, FC_WEIGHT, 0, &value))
733
if (value >= FC_WEIGHT_BOLD)
735
symTraits |= NSFontBoldTrait;
738
if (value <= FC_WEIGHT_NORMAL)
740
weight = ((value - FC_WEIGHT_THIN) / (double)(FC_WEIGHT_NORMAL - FC_WEIGHT_THIN)) - 1.0;
744
weight = (value - FC_WEIGHT_NORMAL) / (double)(FC_WEIGHT_ULTRABLACK - FC_WEIGHT_NORMAL);
747
[traits setObject: [NSNumber numberWithDouble: weight]
748
forKey: NSFontWeightTrait];
750
if (FcResultMatch == FcPatternGetInteger(pat, FC_WIDTH, 0, &value))
754
if (value >= FC_WIDTH_EXPANDED)
756
symTraits |= NSFontExpandedTrait;
758
if (value <= FC_WIDTH_CONDENSED)
760
symTraits |= NSFontCondensedTrait;
763
if (value <= FC_WIDTH_NORMAL)
765
width = ((value - FC_WIDTH_ULTRACONDENSED) / (double)(FC_WIDTH_NORMAL - FC_WIDTH_ULTRACONDENSED)) - 1.0;
769
width = (value - FC_WIDTH_NORMAL) / (double)(FC_WIDTH_ULTRAEXPANDED - FC_WIDTH_NORMAL);
772
[traits setObject: [NSNumber numberWithDouble: width]
773
forKey: NSFontWidthTrait];
775
if (FcResultMatch == FcPatternGetInteger(pat, FC_SPACING, 0, &value))
777
if (value == FC_MONO || value == FC_CHARCELL)
779
symTraits |= NSFontMonoSpaceTrait;
785
[traits setObject: [NSNumber numberWithUnsignedInt: symTraits]
786
forKey: NSFontSymbolicTrait];
792
- (NSNumber*)readSizeFromPattern: (FcPattern*)pat
794
return [self readFontconfigDouble: FC_SIZE fromPattern: pat];
797
- (NSCharacterSet*)readCharacterSetFromPattern: (FcPattern*)pat
800
if (FcResultMatch == FcPatternGetCharSet(pat, FC_CHARSET, 0, &value))
802
return [[[FontconfigCharacterSet alloc] initWithFontconfigCharSet: value] autorelease];
807
#define READ_FROM_PATTERN(key, readMethod) \
809
id result = [self readMethod _pat]; \
812
[_attributes setObject: result \
817
- (void)parseAttributes
819
READ_FROM_PATTERN(NSFontNameAttribute, readNameFromPattern:);
820
READ_FROM_PATTERN(NSFontVisibleNameAttribute, readVisibleNameFromPattern:);
821
READ_FROM_PATTERN(NSFontFamilyAttribute, readFamilyNameFromPattern:);
822
READ_FROM_PATTERN(NSFontFaceAttribute, readStyleNameFromPattern:);
823
READ_FROM_PATTERN(NSFontTraitsAttribute, readTraitsFromPattern:);
824
READ_FROM_PATTERN(NSFontSizeAttribute, readSizeFromPattern:);
825
READ_FROM_PATTERN(NSFontCharacterSetAttribute, readCharacterSetFromPattern:);
828
- (NSDictionary*)attributesFromPattern: (FcPattern *)pat
830
_attributes = [NSMutableDictionary dictionary];
832
[self parseAttributes];
840
@implementation FontconfigCharacterSet
842
- (id)initWithFontconfigCharSet: (FcCharSet*)charset
844
if ((self = [super init]))
846
_charset = FcCharSetCopy(charset);
851
- (id)mutableCopyWithZone: (NSZone*)aZone
853
return [[NSMutableCharacterSet characterSetWithBitmapRepresentation:
854
[self bitmapRepresentation]] retain];
859
FcCharSetDestroy(_charset);
863
- (FcCharSet*)fontconfigCharSet
868
- (BOOL)characterIsMember: (unichar)c
870
return FcCharSetHasChar(_charset, c);
873
- (BOOL)longCharacterIsMember: (UTF32Char)c
875
return FcCharSetHasChar(_charset, c);
878
// FIXME: Implement for better performance
879
//- (NSData *)bitmapRepresentation