freetype 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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