freetype 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 753294da701bc4144a7be8a3dead8f738b124cf2
4
- data.tar.gz: 36af82be6476778d84a738dbfedd136ece627ae6
3
+ metadata.gz: c36f62b7c9de44960d5c1610bdad80291833313e
4
+ data.tar.gz: 46b17c2d49414d9fdad8b8ea6072b342286aab00
5
5
  SHA512:
6
- metadata.gz: 1ea7b0f90ef2cfec35d4c2e5964334cc36bae5b1589d893a2552039dd604f0c439362d3e9e196898a9486ea101ee9b5a13fb454d45d75eb25673c28f098c3a8a
7
- data.tar.gz: 973d1397fc88fe29d576dfdbff4f02b72884386558a271ae0c04505f44a571bb09a0f82acd9d6570ecf6f94a80a0f0310bf5f185b8616ab85ad0bdd0aeb1fb6d
6
+ metadata.gz: 372d0d55f362b88693b72d12e17336319afea3b75a2a67d1eaedaaa235c02e775f86652e71764a4f5644b3451c98a3e23bced0ff7f31e4819866546877c936a3
7
+ data.tar.gz: 55ac0bd04129157365706a0a91ffe5aceea88e3c5f4108ffd0563a40e0e589bb8dd972c33ba0167540228c4962e66ec184eefc88b949543a1add02bacc5285b8
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # FreeType
2
2
 
3
+ [![Build Status](https://travis-ci.org/ksss/freetype.svg?branch=master)](https://travis-ci.org/ksss/freetype)
4
+
3
5
  FreeType is freetype wrapper using by ffi
4
6
 
5
7
  ## Installation
@@ -78,27 +80,15 @@ raise FreeType::Error.find(err) unless err == 0
78
80
 
79
81
  ```ruby
80
82
  require 'freetype/api'
83
+ # or require 'freetype'
81
84
 
82
85
  include FreeType::API
83
86
 
84
- Library.open do |lib|
85
- lib.face_open('font.ttf') do |face|
86
- face.set_char_size(0, 32 * 32, 300, 300)
87
- outline = face.outline('a')
88
- p outline.points #=> [#<FreeType::API::Outline tag=-1 x= 10 y=24>, ...]
89
- p face.kerning_unfitted('A', 'W') #=> #<FreeType::API::Vector x=-10 y=0>
90
- end
91
- end
92
- ```
93
-
94
- ### Use All
95
-
96
- ```ruby
97
- require 'freetype'
98
-
99
- FreeType::API::Library.open do |lib|
100
- face = FFI::MemoryPointer.new(:pointer)
101
- FreeType::C::FT_New_Face(lib.pointer, 'font.otf', 0, face)
87
+ Font.open('font.ttf') do |font|
88
+ font.set_char_size(0, 32 * 32, 300, 300)
89
+ outline = font.glyph('a').outline
90
+ p outline.points #=> [#<FreeType::API::Outline tag=-1 x= 10 y=24>, ...]
91
+ p font.kerning_unfitted('A', 'W') #=> #<FreeType::API::Vector x=-10 y=0>
102
92
  end
103
93
  ```
104
94
 
@@ -4,6 +4,22 @@ require 'freetype/error'
4
4
  module FreeType
5
5
  # high level API for freetype wrapping by FFI
6
6
  module API
7
+ def library_version
8
+ library = ::FFI::MemoryPointer.new(:pointer)
9
+ err = FreeType::C::FT_Init_FreeType(library)
10
+ raise FreeType::Error.find(err) unless err == 0
11
+
12
+ amajor = ::FFI::MemoryPointer.new(:int)
13
+ aminor = ::FFI::MemoryPointer.new(:int)
14
+ apatch = ::FFI::MemoryPointer.new(:int)
15
+ FreeType::C::FT_Library_Version(library.get_pointer(0), amajor, aminor, apatch)
16
+ "#{amajor.get_int(0)}.#{aminor.get_int(0)}.#{apatch.get_int(0)}"
17
+ ensure
18
+ err = FreeType::C::FT_Done_Library(library.get_pointer(0))
19
+ raise FreeType::Error.find(err) unless err == 0
20
+ end
21
+ module_function :library_version
22
+
7
23
  module IOInterface
8
24
  def open(*args)
9
25
  i = new(*args)
@@ -19,58 +35,30 @@ module FreeType
19
35
  end
20
36
  end
21
37
 
22
- class Library
38
+ class Font
23
39
  extend IOInterface
24
40
  include C
25
41
 
26
- def initialize
42
+ attr_reader :face
43
+ def initialize(font_path)
27
44
  @library = ::FFI::MemoryPointer.new(:pointer)
28
45
  err = FT_Init_FreeType(@library)
29
46
  raise FreeType::Error.find(err) unless err == 0
30
- end
31
-
32
- def face_open(font)
33
- Face.open(pointer, font) do |f|
34
- yield f
35
- end
36
- end
37
47
 
38
- def pointer
39
- @library.get_pointer(0)
40
- end
48
+ @font_path = font_path
41
49
 
42
- def version
43
- amajor = ::FFI::MemoryPointer.new(:int)
44
- aminor = ::FFI::MemoryPointer.new(:int)
45
- apatch = ::FFI::MemoryPointer.new(:int)
46
- FT_Library_Version(@library.get_pointer(0), amajor, aminor, apatch)
47
- "#{amajor.get_int(0)}.#{aminor.get_int(0)}.#{apatch.get_int(0)}"
50
+ f = ::FFI::MemoryPointer.new(:pointer)
51
+ err = FT_New_Face(@library.get_pointer(0), @font_path, 0, f)
52
+ raise FreeType::Error.find(err) unless err == 0
53
+ @face = FT_FaceRec.new(f.get_pointer(0))
48
54
  end
49
55
 
50
56
  def close
51
- err = FT_Done_Library(@library.get_pointer(0))
57
+ err = FT_Done_Face(@face)
52
58
  raise FreeType::Error.find(err) unless err == 0
53
- @library.free
54
- end
55
- end
56
59
 
57
- class Face
58
- extend IOInterface
59
- include C
60
-
61
- attr_reader :font_path
62
- def initialize(library, font_path)
63
- @library = library
64
- @font_path = font_path
65
- @outline = nil
66
- f = ::FFI::MemoryPointer.new(:pointer)
67
- err = FT_New_Face(@library, @font_path, 0, f)
60
+ err = FT_Done_Library(@library.get_pointer(0))
68
61
  raise FreeType::Error.find(err) unless err == 0
69
- @face = FT_FaceRec.new(f.get_pointer(0))
70
- end
71
-
72
- def raw
73
- @face
74
62
  end
75
63
 
76
64
  def select_charmap(enc_code)
@@ -122,11 +110,6 @@ module FreeType
122
110
  get_kerning(before_char, after_char, :FT_KERNING_UNSCALED)
123
111
  end
124
112
 
125
- def close
126
- err = FT_Done_Face(@face)
127
- raise FreeType::Error.find(err) unless err == 0
128
- end
129
-
130
113
  private
131
114
 
132
115
  def get_kerning(before_char, after_char, kerning_mode)
@@ -164,8 +147,8 @@ module FreeType
164
147
  @glyph = glyph
165
148
  end
166
149
 
167
- def raw
168
- @glyph
150
+ def [](key)
151
+ @glyph[key]
169
152
  end
170
153
 
171
154
  def metrics
@@ -176,7 +159,7 @@ module FreeType
176
159
  Outline.new(@glyph[:outline])
177
160
  end
178
161
 
179
- def space_width
162
+ def char_width
180
163
  @glyph[:metrics][:horiAdvance]
181
164
  end
182
165
  end
@@ -188,8 +171,8 @@ module FreeType
188
171
  @outline = outline
189
172
  end
190
173
 
191
- def raw
192
- @outline
174
+ def [](key)
175
+ @outline[key]
193
176
  end
194
177
 
195
178
  def points
@@ -212,76 +195,6 @@ module FreeType
212
195
  return [] if @outline[:n_points] == 0
213
196
  @outline[:tags].get_array_of_char(0, @outline[:n_points])
214
197
  end
215
-
216
- def to_svg_path
217
- end_ptd_of_counts = contours
218
- contours = []
219
- contour = []
220
- points.each.with_index do |point, index|
221
- contour << point
222
- if index == end_ptd_of_counts.first
223
- end_ptd_of_counts.shift
224
- contours << contour
225
- contour = []
226
- end
227
- end
228
-
229
- path = []
230
- contours.each do |contour|
231
- first_pt = contour.first
232
- last_pt = contour.last
233
- curve_pt = nil
234
- start = 0
235
- if first_pt.on_curve?
236
- curve_pt = nil
237
- start = 1
238
- else
239
- if last_pt.on_curve?
240
- first_pt = last_pt
241
- else
242
- first_pt = Point.new(0, (first_pt.x + last_pt.x) / 2, (first_pt.y + last_pt.y) / 2)
243
- end
244
- curve_pt = first_pt
245
- end
246
- path << ['M', first_pt.x, -first_pt.y]
247
-
248
- prev_pt = nil
249
- (start...contour.length).each do |j|
250
- pt = contour[j]
251
- prev_pt = if j == 0
252
- first_pt
253
- else
254
- contour[j - 1]
255
- end
256
-
257
- if prev_pt.on_curve? && pt.on_curve?
258
- path << ['L', pt.x, -pt.y]
259
- elsif prev_pt.on_curve? && !pt.on_curve?
260
- curve_pt = pt
261
- elsif !prev_pt.on_curve? && !pt.on_curve?
262
- path << ['Q', prev_pt.x, -prev_pt.y, (prev_pt.x + pt.x) / 2, -((prev_pt.y + pt.y) / 2)]
263
- curve_pt = pt
264
- elsif !prev_pt.on_curve? && pt.on_curve?
265
- path << ['Q', curve_pt.x, -curve_pt.y, pt.x, -pt.y]
266
- curve_pt = nil
267
- else
268
- raise
269
- end
270
- end
271
-
272
- next unless first_pt != last_pt
273
- if curve_pt
274
- path << ['Q', curve_pt.x, -curve_pt.y, first_pt.x, -first_pt.y]
275
- else
276
- path << ['L', first_pt.x, -first_pt.y]
277
- end
278
- end
279
- path << ['z'] if 0 < path.length
280
-
281
- path.map { |(command, *args)|
282
- "#{command}#{args.join(' ')}"
283
- }.join('')
284
- end
285
198
  end
286
199
 
287
200
  Point = Struct.new(:tag, :x, :y) do
@@ -3,98 +3,74 @@ require 'freetype/api'
3
3
  module FreeTypeApiTest
4
4
  include FreeType::API
5
5
 
6
- def libopen
7
- Library.open do |lib|
8
- ['data/Prida01.otf', 'data/Starjedi.ttf'].each do |font|
9
- lib.face_open(font) do |f|
10
- f.set_char_size(0, 0, 300, 300)
11
- yield f
12
- end
6
+ def font_open
7
+ ['data/Prida01.otf', 'data/Starjedi.ttf'].each do |font|
8
+ Font.open(font) do |f|
9
+ yield f, font
13
10
  end
14
11
  end
15
12
  end
16
13
 
17
- def test_Library(t)
18
- lib = nil
19
- ret = Library.open do |l|
20
- lib = l
14
+ def test_library_version(t)
15
+ v = FreeType::API.library_version
16
+ unless String === v
17
+ t.error 'return value was break'
18
+ end
19
+ unless /\A\d+.\d+.\d+\z/ =~ v
20
+ t.error "version format was break got #{v}"
21
+ end
22
+ end
21
23
 
22
- unless /\A\d+\.\d+\.\d+\z/.match l.version
23
- t.error "return value break got #{l.version}"
24
- end
24
+ def test_Font(t)
25
+ font = nil
26
+ ret = Font.open('data/Prida01.otf') do |f|
27
+ font = f
25
28
 
26
29
  :abc
27
30
  end
28
- if lib.nil?
31
+ if font.nil?
29
32
  t.error('cannot get FT_Library in `open` with block')
30
33
  end
31
34
  if ret != :abc
32
35
  t.error 'want to return last value in block'
33
36
  end
34
- end
35
37
 
36
- def test_Face(t)
37
- face = nil
38
- Library.open do |lib|
39
- ['data/Prida01.otf', 'data/Starjedi.ttf'].each do |font|
40
- lib.face_open(font) do |f|
41
- face = f
42
- if f.char_index('a') == 0
43
- t.error('ascii char not defined this font')
44
- end
45
- if f.char_index('㍿') != 0
46
- t.error("I don't know why set character was defined in font")
47
- end
48
-
49
- v = f.kerning('A', 'W')
50
- unless v
51
- t.error('#kerning return object was changed')
52
- end
53
- unless Fixnum === v.x && Fixnum === v.y
54
- t.error('Not vector object. Check spec for FT_Get_Kerning()')
55
- end
56
-
57
- if /darwin/ =~ RUBY_PLATFORM
58
- begin
59
- err = StringIO.new
60
- origerr = $stderr
61
- $stderr = err
62
- f.glyph('a')
63
- rescue FreeType::Error::Invalid_Size_Handle
64
- if err.string.empty?
65
- t.error('recommend warn miss?')
66
- end
67
- else
68
- t.error('check freetype spec')
69
- ensure
70
- $stderr = origerr
71
- end
72
- end
73
-
74
- f.set_char_size(0, 0, 300, 300)
75
-
76
- bbox = f.bbox
77
- unless BBox === bbox
78
- t.error('FreeType::API::Face#bbox return value was break')
79
- end
80
-
81
- unless Glyph === f.glyph('a')
82
- t.error 'return value was break'
83
- end
84
-
85
- # unless Glyph === f.notdef
86
- # t.error 'return value was break'
87
- # end
88
- end
38
+ font_open do |f, _font|
39
+ if f.char_index('a') == 0
40
+ t.error('ascii char not defined this font')
41
+ end
42
+ if f.char_index('㍿') != 0
43
+ t.error("I don't know why set character was defined in font")
44
+ end
45
+
46
+ v = f.kerning('A', 'W')
47
+ unless v
48
+ t.error('#kerning return object was changed')
49
+ end
50
+ unless Fixnum === v.x && Fixnum === v.y
51
+ t.error('Not vector object. Check spec for FT_Get_Kerning()')
52
+ end
53
+
54
+ f.set_char_size(0, 0, 300, 300)
55
+
56
+ bbox = f.bbox
57
+ unless BBox === bbox
58
+ t.error('FreeType::API::Face#bbox return value was break')
59
+ end
60
+
61
+ unless Glyph === f.glyph('a')
62
+ t.error 'return value was break'
63
+ end
64
+
65
+ unless Glyph === f.notdef
66
+ t.error 'return value was break'
89
67
  end
90
- end
91
- if face.nil?
92
- t.error('cannot get FT_Face in `open` with block')
93
68
  end
94
69
  end
95
70
 
96
71
  def test_glyph(t)
97
- libopen do |f|
72
+ font_open do |f|
73
+ f.set_char_size(0, 0, 300, 300)
98
74
  table = { 'a' => nil, 'b' => nil, 'c' => nil, 'd' => nil }
99
75
  table.each do |char, _|
100
76
  glyph = f.glyph(char)
@@ -104,8 +80,8 @@ module FreeTypeApiTest
104
80
  t.error 'return value was break'
105
81
  end
106
82
 
107
- space_width = glyph.space_width
108
- unless Fixnum === space_width
83
+ char_width = glyph.char_width
84
+ unless Fixnum === char_width
109
85
  t.error 'return value was break'
110
86
  end
111
87
 
@@ -118,7 +94,8 @@ module FreeTypeApiTest
118
94
  end
119
95
 
120
96
  def test_outline(t)
121
- libopen do |f|
97
+ font_open do |f|
98
+ f.set_char_size(0, 0, 300, 300)
122
99
  table = { 'a' => nil, 'b' => nil, 'c' => nil, 'd' => nil }
123
100
  table.each do |char, _|
124
101
  outline = f.glyph(char).outline
@@ -235,6 +235,9 @@ module FreeType
235
235
  # id = FT_Get_Char_Index(face, 'A'.ord) -> glyph id or 0 (undefined)
236
236
  attach_function :FT_Get_Char_Index, [:pointer, :ulong], :uint
237
237
 
238
+ # err = FT_Get_Glyph_Name(face, 0, buff, 32)
239
+ attach_function :FT_Get_Glyph_Name, [:pointer, :uint, :pointer, :uint], :FT_Error
240
+
238
241
  # v = FT_Vector.new
239
242
  # err = FT_Get_Kerning(face, before_id, id, :FT_KERNING_DEFAULT, v)
240
243
  # p v
@@ -12,11 +12,19 @@ module FFITest
12
12
 
13
13
  FONTS.each do |font|
14
14
  face = ::FFI::MemoryPointer.new(:pointer)
15
- err = FT_New_Face(library.get_pointer(0), font, 0, face)
16
- raise FreeType::Error.find(err) unless err == 0
17
-
18
- yield FT_FaceRec.new(face.get_pointer(0)), font
15
+ begin
16
+ err = FT_New_Face(library.get_pointer(0), font, 0, face)
17
+ raise FreeType::Error.find(err) unless err == 0
18
+
19
+ yield FT_FaceRec.new(face.get_pointer(0)), font
20
+ ensure
21
+ err = FT_Done_Face(face.get_pointer(0))
22
+ raise FreeType::Error.find(err) unless err == 0
23
+ end
19
24
  end
25
+ ensure
26
+ err = FT_Done_Library(library.get_pointer(0))
27
+ raise FreeType::Error.find(err) unless err == 0
20
28
  end
21
29
 
22
30
  def test_Library(t)
@@ -38,6 +46,12 @@ module FFITest
38
46
  unless a.all? { |i| Fixnum === i }
39
47
  t.error 'miss get values from FT_Library_Version()'
40
48
  end
49
+ t.log "freetype version: #{a.join('.')}"
50
+ ensure
51
+ err = FT_Done_Library(library.get_pointer(0))
52
+ if err != 0
53
+ t.error FreeType::Error.find(err).message
54
+ end
41
55
  end
42
56
 
43
57
  def test_Face(t)
@@ -53,24 +67,28 @@ module FFITest
53
67
  t.fatal FreeType::Error.find(err).message
54
68
  end
55
69
 
56
- face = FT_FaceRec.new(face.get_pointer(0))
57
- err = FT_Select_Charmap(face, :FT_ENCODING_UNICODE)
58
- if err != 0
59
- t.error FreeType::Error.find(err).message
70
+ begin
71
+ face = FT_FaceRec.new(face.get_pointer(0))
72
+ err = FT_Select_Charmap(face, :FT_ENCODING_UNICODE)
73
+ if err != 0
74
+ t.error FreeType::Error.find(err).message
75
+ end
76
+ ensure
77
+ err = FT_Done_Face(face)
78
+ if err != 0
79
+ t.error FreeType::Error.find(err).message
80
+ end
60
81
  end
61
82
  end
83
+ ensure
84
+ err = FT_Done_Library(library.get_pointer(0))
85
+ if err != 0
86
+ t.error FreeType::Error.find(err).message
87
+ end
62
88
  end
63
89
 
64
90
  def test_FT_Set_Char_Size(t)
65
91
  libopen do |face|
66
- if /darwin/ =~ RUBY_PLATFORM
67
- err = FT_Load_Char(face, 'a'.ord, FreeType::C::FT_LOAD_DEFAULT)
68
- e = FreeType::Error.find(err)
69
- unless FreeType::Error::Invalid_Size_Handle === e
70
- t.fatal 'check freetype spec'
71
- end
72
- end
73
-
74
92
  err = FT_Set_Char_Size(face, 0, 32, 300, 300)
75
93
  if err != 0
76
94
  t.error FreeType::Error.find(err).message
@@ -83,6 +101,19 @@ module FFITest
83
101
  end
84
102
  end
85
103
 
104
+ def test_FT_Get_Glyph_Name(t)
105
+ libopen do |face|
106
+ buff = FFI::MemoryPointer.new(:pointer)
107
+ err = FT_Get_Glyph_Name(face, 0, buff, 32)
108
+ if err != 0
109
+ t.error FreeType::Error.find(err).message
110
+ end
111
+ unless String === buff.get_string(0)
112
+ t.error 'May buffering miss?'
113
+ end
114
+ end
115
+ end
116
+
86
117
  def test_char(t)
87
118
  libopen do |face, _font|
88
119
  err = FT_Set_Char_Size(face, 0, 32, 300, 300)
@@ -1,3 +1,3 @@
1
1
  module FreeType
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: freetype
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ksss
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-12-16 00:00:00.000000000 Z
11
+ date: 2015-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi