fontconfig 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -312,12 +312,25 @@ static VALUE rb_config_get_application_fonts(VALUE self){
312
312
  return config_get_fonts(self, FcSetApplication);
313
313
  }
314
314
 
315
+ // FcFontSort -- Return list of matching fonts
316
+ static VALUE rb_config_font_sort(int argc, VALUE *argv, VALUE self){
317
+ VALUE pattern, trim;
318
+ rb_scan_args(argc, argv, "11", &pattern, &trim);
319
+ //charset - ignored.
320
+ if(!RTEST(pattern) || !is_fc_pattern(pattern)){
321
+ rb_raise(rb_eArgError, "pattern must be Fonconfig::Pattern");
322
+ }
323
+ FcResult res;
324
+ FcFontSet* set = FcFontSort(CONFIG_UNWRAP(self), pattern_unwrap(pattern), RTEST(trim), 0, &res);
325
+ return font_set_wrap(set);
326
+ }
315
327
 
316
328
  void Init_fontconfig_config(){
317
329
  rb_cFcConfig = rb_define_class_under(rb_cFontconfig, "Config", rb_cObject);
318
330
  rb_define_singleton_method(rb_cFcConfig, "new", rb_config_new, -1);
319
331
  rb_define_method(rb_cFcConfig, "parse_and_load", rb_config_parse_and_load, -1);
320
332
  rb_define_singleton_method(rb_cFcConfig, "filename", rb_config_filename, 1);
333
+ rb_define_singleton_method(rb_cFontconfig, "current_config", rb_config_get_current, 0);
321
334
  rb_define_singleton_method(rb_cFcConfig, "get_current", rb_config_get_current, 0);
322
335
  rb_define_method(rb_cFcConfig, "set_current!", rb_config_set_current, 0);
323
336
  rb_define_method(rb_cFcConfig, "up_to_date?", rb_config_up_to_date_p, 0);
@@ -348,10 +361,7 @@ void Init_fontconfig_config(){
348
361
  symScan = ID2SYM(rb_intern("scan"));
349
362
  rb_define_method(rb_cFcConfig, "substitute", rb_config_substitute, -1);
350
363
  rb_define_method(rb_cFcConfig, "substitute_with_pat", rb_config_substitute_with_pat, -1);
351
-
364
+ rb_define_method(rb_cFcConfig, "font_sort", rb_config_font_sort, -1);
352
365
 
353
366
  // FcConfigGetBlanks -- Get config blanks
354
- // FcFontSort -- Return list of matching fonts
355
-
356
- // FcConfigGetCache -- DEPRECATED used to return per-user cache filename
357
367
  }
@@ -0,0 +1,47 @@
1
+ //fontconfig internal
2
+
3
+
4
+
5
+ struct _FcPattern {
6
+ int num;
7
+ int size;
8
+ intptr_t elts_offset;
9
+ // FcRef ref;
10
+ int ref_here_dot_not_use;
11
+ };
12
+
13
+ typedef int FcObject;
14
+
15
+ typedef enum _FcValueBinding {
16
+ FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame
17
+ } FcValueBinding;
18
+
19
+ typedef struct _FcValueList {
20
+ struct _FcValueList *next;
21
+ FcValue value;
22
+ FcValueBinding binding;
23
+ } FcValueList, *FcValueListPtr;
24
+
25
+ typedef struct _FcPatternElt {
26
+ FcObject object;
27
+ FcValueList *values;
28
+ } FcPatternElt;
29
+
30
+ #define FcOffsetToPtr(b,o,t) ((t *) ((intptr_t) (b) + (o)))
31
+ #define FcEncodedOffsetMember(s,m,t) FcOffsetToPtr(s,FcOffsetDecode((s)->m), t)
32
+ #define FcIsEncodedOffset(p) ((((intptr_t) (p)) & 1) != 0)
33
+ #define FcPointerMember(s,m,t) (FcIsEncodedOffset((s)->m) ? \
34
+ FcEncodedOffsetMember (s,m,t) : \
35
+ (s)->m)
36
+ #define FcOffsetMember(s,m,t) FcOffsetToPtr(s,(s)->m,t)
37
+ #define FcPatternElts(p) FcOffsetMember(p,elts_offset,FcPatternElt)
38
+ #define FcPatternEltValues(pe) FcPointerMember(pe,values,FcValueList)
39
+
40
+ const char *
41
+ FcObjectName (FcObject object);
42
+ FcObject
43
+ FcObjectFromName (const char * name);
44
+ FcPatternElt *
45
+ FcPatternObjectFindElt (const FcPattern *p, FcObject object);
46
+
47
+ #define FcValueListNext(vl) FcPointerMember(vl,next,FcValueList)
@@ -96,6 +96,8 @@ static VALUE rb_pattern_add(int argc, VALUE *argv, VALUE self){
96
96
  case T_TRUE: val.type = FcTypeBool; val.u.b = 1; break;
97
97
  case T_FALSE: val.type = FcTypeBool; val.u.b = 0; break;
98
98
  case T_OBJECT:
99
+ case T_DATA:
100
+
99
101
  //TODO: increment object references?
100
102
  // ...
101
103
  // FcTypeMatrix: // m FcMatrix *
@@ -143,7 +145,7 @@ static VALUE rb_pattern_get(VALUE self, VALUE object, VALUE id){
143
145
  FcResult res = FcPatternGet(PATTERN_UNWRAP(self), RSTRING_PTR(object), FIX2INT(id), &val);
144
146
  if(res == FcResultMatch){
145
147
  VALUE r_res = fc_value_to_value(&val);
146
- // FcValueDestroy(val); // gives malloc error
148
+ // no need to free, ptr to internal mem
147
149
  return r_res;
148
150
  }
149
151
  if(res == FcResultNoMatch || res == FcResultNoId){
@@ -172,12 +174,63 @@ static VALUE rb_pattern_remove(VALUE self, VALUE object, VALUE id){
172
174
  return res? Qtrue : Qfalse;
173
175
  }
174
176
 
175
- rb_pattern_default_substitute(VALUE self){
177
+ static VALUE rb_pattern_default_substitute(VALUE self){
176
178
  FcDefaultSubstitute(PATTERN_UNWRAP(self));
177
179
  return self;
178
180
  }
179
181
 
180
182
 
183
+ #include "fc_internal.h"
184
+
185
+ static VALUE rb_pattern_each_key(VALUE self){
186
+ FcPattern* p = PATTERN_UNWRAP(self);
187
+ int i;
188
+ FcPatternElt* e;
189
+ for (i = 0; i < p->num; i++){
190
+ e = &FcPatternElts(p)[i];
191
+ //FIXME: return as symbols?
192
+ rb_yield(rb_str_new2(FcObjectName(e->object)));
193
+ }
194
+ return self;
195
+ }
196
+
197
+ static VALUE rb_pattern_has_key_p(VALUE self, VALUE key){
198
+ FcPattern* p = PATTERN_UNWRAP(self);
199
+ FcPatternElt* e = FcPatternObjectFindElt(p, FcObjectFromName (StringValuePtr(key)));
200
+ if(e){
201
+ return Qtrue;
202
+ }
203
+ return Qfalse;
204
+ }
205
+
206
+ static VALUE rb_pattern_get_keys(VALUE self){
207
+ FcPattern* p = PATTERN_UNWRAP(self);
208
+ VALUE res = rb_ary_new();
209
+ int i;
210
+ FcPatternElt* e;
211
+ for (i = 0; i < p->num; i++){
212
+ e = &FcPatternElts(p)[i];
213
+ rb_ary_push(res, rb_str_new2(FcObjectName(e->object)));
214
+ // FcValueListPrint (FcPatternEltValues(e));
215
+ }
216
+ return res;
217
+ }
218
+
219
+ static VALUE rb_pattern_each_key_value(VALUE self, VALUE key){
220
+ FcPattern* p = PATTERN_UNWRAP(self);
221
+ FcPatternElt* e = FcPatternObjectFindElt(p, FcObjectFromName (StringValuePtr(key)));
222
+ FcValueListPtr l;
223
+ if(e){
224
+ for (l = FcPatternEltValues(e); l; l = FcValueListNext(l)){
225
+ // FcValueCanonicalize(&l->value); - re allocates value pointers, do not need this
226
+ rb_yield(fc_value_to_value(&l->value));
227
+ }
228
+ }
229
+ return self;
230
+ }
231
+
232
+
233
+
181
234
  void Init_fontconfig_pattern(){
182
235
  rb_cFcPattern = rb_define_class_under(rb_cFontconfig, "Pattern", rb_cObject);
183
236
  rb_define_singleton_method(rb_cFcPattern, "new", rb_pattern_new, -1);
@@ -199,4 +252,9 @@ void Init_fontconfig_pattern(){
199
252
  rb_define_method(rb_cFcPattern, "debug_print", rb_pattern_debugprint, 0);
200
253
  rb_define_method(rb_cFcPattern, "default_substitute!", rb_pattern_default_substitute, 0);
201
254
 
255
+ rb_define_method(rb_cFcPattern, "keys", rb_pattern_get_keys, 0);
256
+ rb_define_method(rb_cFcPattern, "each_key", rb_pattern_each_key, 0);
257
+ rb_define_method(rb_cFcPattern, "each_value", rb_pattern_each_key_value, 1);
258
+ rb_define_method(rb_cFcPattern, "has_key?", rb_pattern_has_key_p, 1);
259
+
202
260
  }
@@ -23,10 +23,67 @@ module Fontconfig
23
23
  def delete!
24
24
  @pattern.delete(@key)
25
25
  end
26
+
27
+ def each &blk
28
+ @pattern.each_value @key, &blk
29
+ end
30
+
31
+ include Enumerable
26
32
  end
27
33
 
28
34
  def [](key)
35
+ key = key.to_s
36
+ return nil unless has_key?(key)
29
37
  return Proxy.new(self, key)
30
38
  end
39
+
40
+ def inspect
41
+ "#<#{self.class.name} #{self.format('%{=fcmatch}')}>"
42
+ end
43
+
44
+ alias :each :each_key
45
+ include Enumerable
46
+
47
+ def config_substitute! config=Fontconfig.current_config, kind=:font
48
+ #kind - :pattern, :font, :scan
49
+ unless config.substitute(self)
50
+ raise "cannot perform substitutions on pattern"
51
+ end
52
+ self
53
+ end
54
+
55
+ def prepare! config=Fontconfig.current_config, kind=:font
56
+ @prepared = true
57
+ config_substitute! config, kind
58
+ default_substitute!
59
+ self
60
+ end
61
+
62
+ def match config=Fontconfig.current_config
63
+ raise "unprepared pattern match" unless @prepared
64
+ config.font_match self
65
+ end
66
+
67
+ def filename
68
+ self[:filename].first
69
+ end
70
+ end
71
+
72
+
73
+ def self.pattern *args
74
+ Pattern.new *args
75
+ end
76
+
77
+ def self.prepared_pattern *args
78
+ self.pattern(*args).prepare!
79
+ end
80
+
81
+ def self.match *args
82
+ pat = if args.first.is_a? Pattern
83
+ args.first
84
+ else
85
+ self.prepared_pattern *args
86
+ end
87
+ current_config.font_match pat
31
88
  end
32
89
  end
@@ -1,3 +1,3 @@
1
1
  module Fontconfig
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -13,4 +13,8 @@ describe Fontconfig do
13
13
  subject.library_version.must_be :>, 0
14
14
  end
15
15
 
16
+ it "current_config" do
17
+ subject.current_config.must_be_instance_of Fontconfig::Config
18
+ end
19
+
16
20
  end
@@ -46,6 +46,42 @@ describe Fontconfig::Pattern do
46
46
  subject["familylang"][0].must_equal "en"
47
47
  end
48
48
 
49
+ describe "advanced" do
50
+ let(:key_type){ String }
51
+
52
+ it "each_key" do
53
+ n = 0
54
+ subject.each_key{|k|
55
+ k.must_be_kind_of key_type
56
+ n+=1
57
+ }
58
+ n.must_be :>, 0
59
+ end
60
+
61
+ it "each is each_key" do
62
+ subject.each{|k|
63
+ }
64
+ subject.to_a.sort.must_equal subject.keys.sort
65
+ end
66
+
67
+ it "keys" do
68
+ keys = subject.keys
69
+ keys.must_be_kind_of Array
70
+ keys.size.must_be :>,0
71
+ keys.each{|k|
72
+ k.must_be_kind_of key_type
73
+ }
74
+ end
75
+
76
+ it "each value for key" do
77
+ n = 0
78
+ subject.each_value("family"){|k|
79
+ n+=1
80
+ }
81
+ n.must_be :>, 0
82
+ end
83
+ end
84
+
49
85
  end
50
86
 
51
87
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fontconfig
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-17 00:00:00.000000000 Z
12
+ date: 2013-07-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: pkg-config
@@ -91,6 +91,7 @@ files:
91
91
  - ext/fontconfig/extconf.rb
92
92
  - ext/fontconfig/fc_config.c
93
93
  - ext/fontconfig/fc_fontset.c
94
+ - ext/fontconfig/fc_internal.h
94
95
  - ext/fontconfig/fc_objectset.c
95
96
  - ext/fontconfig/fc_pattern.c
96
97
  - ext/fontconfig/fontconfig.c
@@ -115,18 +116,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
116
  - - ! '>='
116
117
  - !ruby/object:Gem::Version
117
118
  version: '0'
118
- segments:
119
- - 0
120
- hash: -3843724065432744597
121
119
  required_rubygems_version: !ruby/object:Gem::Requirement
122
120
  none: false
123
121
  requirements:
124
122
  - - ! '>='
125
123
  - !ruby/object:Gem::Version
126
124
  version: '0'
127
- segments:
128
- - 0
129
- hash: -3843724065432744597
130
125
  requirements: []
131
126
  rubyforge_project:
132
127
  rubygems_version: 1.8.24
@@ -139,3 +134,4 @@ test_files:
139
134
  - spec/object_set_spec.rb
140
135
  - spec/pattern_spec.rb
141
136
  - spec/test_helper.rb
137
+ has_rdoc: