harfbuzz 0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 88bd6dee65ceba054a1ff2ba5b4329bfea310689
4
+ data.tar.gz: fc6e012e4e25a3f579cea5946f9e6a7afcd963e4
5
+ SHA512:
6
+ metadata.gz: 4ddabd5869af1957fbe68864b1bba1f0dba915b0392f6c66549645b5d3f34ae1c6c2bffd473d104443cdd383aabcfc763dba1a1b2ffd0c2ebe28fa19fc058b7c
7
+ data.tar.gz: 1d5ed18e405ae2c595d31403898facdc1722f28d268176799042cfb8f9aeb18b505bbf2dfb6eac83f0e86225472cdec2613199660dde863f1e4cb3c7d3014f9f
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in itinerary.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 John Labovitz
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ The Harfbuzz gem is a Ruby interface to the Harfbuzz text shaping engine. By using this gem, some input text, a font file, and a list of features, you can convert Unicode text to glyph descriptions that are ready to be rendered.
2
+
3
+ For more information about Harfbuzz itself, see [harfbuzz.org](http://harfbuzz.org).
4
+
5
+ For an example of use, see [example.rb](harfbuzz/examples/example.rb). From the base directory of this gem, you can run this example:
6
+
7
+ ruby examples/example.rb
8
+
9
+
10
+ ## Installation
11
+
12
+ You must have the Harfbuzz library available on your system. OS X users can use Homebrew to install it:
13
+
14
+ brew install harfbuzz
15
+
16
+ Once you've installed the Harfbuzz library, install this gem by the usual:
17
+
18
+ sudo gem install harfbuzz
19
+
20
+ or if you're using a Ruby installed in Homebrew, as a normal user:
21
+
22
+ gem install harfbuzz
23
+
24
+
25
+ ## Design philosophy
26
+
27
+ The Harfbuzz gem is composed of two layers: a low-level direct interface to Harfbuzz itself, and a high-level abstract interface that uses traditional Ruby objects and idioms.
28
+
29
+ The low-level interface is a one-to-one mapping of Harfbuzz C functions to Ruby methods, implemented using the [FFI](https://github.com/ffi/ffi) library. For example, the Harfbuzz C function `hb_version_string()` is available in Ruby as `Harfbuzz.hb_version_string`. However, as the low-level methods return C pointers wrapped in FFI objects, this layer is generally not useful to a Ruby programmer.
30
+
31
+ The high-level interface abstracts the C functions, structures, and pointers into Ruby objects. For example, the aftermentioned `hb_version_string()` function is more usefully available via `Harfbuzz.version_string`, which returns a Ruby string containing with the version of the Harfbuzz library.
32
+
33
+ Where appropriate, Ruby classes have been constructed to map to the concepts in Harfbuzz. Hence:
34
+
35
+ | C | Ruby
36
+ | ----------- | ----
37
+ | hb_blob_t | Harfbuzz::Blob
38
+ | hb_buffer_t | Harfbuzz::Buffer
39
+ | hb_face_t | Harfbuzz::Face
40
+ | hb_font_t | Harfbuzz::Font
41
+
42
+ The shaping method itself is in the base Harfbuzz module, as `Harfbuzz.shape(...)`.
43
+
44
+
45
+ ## Caveats & bugs
46
+
47
+ Only a small number of basic Harfbuzz functions are mapped to Ruby methods. More will be added as needed.
48
+
49
+ There is no documentation except this file and the example script.
50
+
51
+ There are no tests or specs.
52
+
53
+ Memory management may not be correct.
54
+
55
+
56
+ ## Feedback
57
+
58
+ As this is a new project, I'd love to hear your feedback. Email me at [johnl@johnlabovitz.com](mailto:johnl@johnlabovitz.com).
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require 'bundler'
2
+ Bundler.require
3
+ require 'bundler/gem_tasks'
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift 'lib'
4
+ require 'harfbuzz'
5
+
6
+ #
7
+ # Show some information about Harfbuzz
8
+ #
9
+
10
+ puts "Harfbuzz version: #{Harfbuzz.version_string}"
11
+ puts "Shapers: #{Harfbuzz.shapers.join(', ')}"
12
+
13
+ #
14
+ # Create a font to be used for shaping. To get the most of out this example, use an OpenType font.
15
+ #
16
+
17
+ face = Harfbuzz::Face.new(File.open('/Library/Fonts/ACaslonPro-Regular.otf', 'rb'))
18
+ font = Harfbuzz::Font.new(face)
19
+
20
+ #
21
+ # Create a buffer to hold the text and the resulting glyphs/positions.
22
+ #
23
+
24
+ buffer = Harfbuzz::Buffer.new
25
+
26
+ #
27
+ # Add some text to the buffer.
28
+ #
29
+
30
+ buffer.add_utf8('WAVE first.')
31
+
32
+ #
33
+ # Guess direction, script, & language from the text.
34
+ #
35
+
36
+ if true
37
+ buffer.guess_segment_properties
38
+ else
39
+ #FIXME: these functions are not yet bound
40
+ # hb_buffer_set_direction(buffer, hb_direction_from_string(direction, -1))
41
+ # hb_buffer_set_script(buffer, hb_script_from_string(script, -1))
42
+ # hb_buffer_set_language(buffer, hb_language_from_string(language, -1))
43
+ # hb_buffer_set_flags(buffer, shape_flags)
44
+ end
45
+
46
+ #
47
+ # Shape the text in the buffer using some interesting features.
48
+ #
49
+
50
+ Harfbuzz.shape(font, buffer, %w{+dlig +hlig})
51
+
52
+ #
53
+ # Normalize glyph clusters (FIXME: why?).
54
+ #
55
+
56
+ buffer.normalize_glyphs
57
+
58
+ #
59
+ # Iterate through the buffer, examining the glyphs & related positions.
60
+ #
61
+
62
+ glyph_infos = buffer.get_glyph_infos
63
+ glyph_positions = buffer.get_glyph_positions
64
+ buffer.length.times do |i|
65
+ info, position = glyph_infos[i], glyph_positions[i]
66
+ glyph_name = font.glyph_to_string(info[:codepoint])
67
+ puts "/%-10.10s %5u | mask: %04X | cluster: %2u | advance: %4u,%4u | offset: %4u,%4u" % [
68
+ glyph_name,
69
+ info[:codepoint],
70
+ info[:mask],
71
+ info[:cluster],
72
+ position[:x_advance], position[:y_advance],
73
+ position[:x_offset], position[:y_offset],
74
+ ]
75
+ end
data/harfbuzz.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ #encoding: utf-8
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'harfbuzz/version'
7
+
8
+ Gem::Specification.new do |s|
9
+ s.name = 'harfbuzz'
10
+ s.version = Harfbuzz::VERSION
11
+ s.summary = 'Ruby interface to the Harfbuzz text shaping engine'
12
+ s.author = 'John Labovitz'
13
+ s.email = 'johnl@johnlabovitz.com'
14
+ s.description = %q{
15
+ Harfbuzz is a Ruby interface to the Harfbuzz text shaping engine.
16
+ }
17
+ s.homepage = 'http://github.com/jslabovitz/harfbuzz-gem'
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_path = 'lib'
22
+
23
+ s.add_dependency 'ffi'
24
+
25
+ s.add_development_dependency 'bundler'
26
+ s.add_development_dependency 'rake'
27
+ end
data/lib/harfbuzz.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'ffi'
2
+
3
+ require 'harfbuzz/ffi_additions'
4
+
5
+ module Harfbuzz
6
+
7
+ extend FFI::Library
8
+
9
+ ffi_lib 'harfbuzz'
10
+
11
+ typedef :pointer, :hb_destroy_func_t
12
+ typedef :uint32, :hb_codepoint_t
13
+
14
+ attach_function :hb_version_string, [], :string
15
+ attach_function :hb_version, [:pointer, :pointer, :pointer], :void
16
+
17
+ def self.version_string
18
+ hb_version_string
19
+ end
20
+
21
+ def self.version
22
+ major_ptr = FFI::MemoryPointer.new(:uint, 1)
23
+ minor_ptr = FFI::MemoryPointer.new(:uint, 1)
24
+ micro_ptr = FFI::MemoryPointer.new(:uint, 1)
25
+ hb_version(major_ptr, minor_ptr, micro_ptr)
26
+ [
27
+ major_ptr.read_uint,
28
+ minor_ptr.read_uint,
29
+ micro_ptr.read_uint,
30
+ ]
31
+ end
32
+
33
+ end
34
+
35
+ require 'harfbuzz/base'
36
+ require 'harfbuzz/blob'
37
+ require 'harfbuzz/face'
38
+ require 'harfbuzz/font'
39
+ require 'harfbuzz/buffer'
40
+ require 'harfbuzz/shaping'
@@ -0,0 +1,17 @@
1
+ module Harfbuzz
2
+
3
+ class Base
4
+
5
+ def self.finalize(method, ptr)
6
+ proc {
7
+ Harfbuzz.send(method, ptr) unless ptr == 0
8
+ }
9
+ end
10
+
11
+ def define_finalizer(method, ptr)
12
+ ObjectSpace.define_finalizer(self, self.class.finalize(method, ptr))
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,41 @@
1
+ module Harfbuzz
2
+
3
+ typedef :pointer, :hb_blob_t
4
+
5
+ enum :hb_memory_mode_t, [
6
+ :HB_MEMORY_MODE_DUPLICATE,
7
+ :HB_MEMORY_MODE_READONLY,
8
+ :HB_MEMORY_MODE_WRITABLE,
9
+ :HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
10
+ ]
11
+
12
+ attach_function :hb_blob_create, [
13
+ :pointer, # data
14
+ :uint, # length
15
+ :hb_memory_mode_t, # mode,
16
+ :pointer, # user_data,
17
+ :hb_destroy_func_t, # destroy
18
+ ], :hb_blob_t
19
+ attach_function :hb_blob_get_length, [
20
+ :hb_blob_t, # blob
21
+ ], :uint
22
+ attach_function :hb_blob_destroy, [:hb_blob_t], :void
23
+
24
+ class Blob < Base
25
+
26
+ attr_reader :hb_blob
27
+
28
+ def initialize(data, mode=0, user_data=nil)
29
+ data_ptr = FFI::MemoryPointer.new(:char, data.size)
30
+ data_ptr.put_bytes(0, data)
31
+ @hb_blob = Harfbuzz.hb_blob_create(data_ptr, data.size, mode, user_data, nil)
32
+ define_finalizer(:hb_blob_destroy, @hb_blob)
33
+ end
34
+
35
+ def length
36
+ Harfbuzz.hb_blob_get_length(@hb_blob)
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,103 @@
1
+ module Harfbuzz
2
+
3
+ typedef :pointer, :hb_buffer_t
4
+ typedef :uint32, :hb_mask_t
5
+ typedef :int32, :hb_position_t
6
+
7
+ class GlyphInfo < FFI::Struct
8
+
9
+ layout \
10
+ :codepoint, :hb_codepoint_t,
11
+ :mask, :hb_mask_t,
12
+ :cluster, :uint32,
13
+ :var1, :uint32, # private
14
+ :var2, :uint32 # private
15
+
16
+ end
17
+
18
+ class GlyphPosition < FFI::Struct
19
+
20
+ layout \
21
+ :x_advance, :hb_position_t,
22
+ :y_advance, :hb_position_t,
23
+ :x_offset, :hb_position_t,
24
+ :y_offset, :hb_position_t,
25
+ :var, :uint32 # private
26
+
27
+ def inspect
28
+ "<#{self} %s>" % [
29
+ %w{x_advance y_advance x_offset y_offset}.map { |k|
30
+ "#{k} = #{self[k.to_sym].inspect}"
31
+ }.join(', ')
32
+ ]
33
+ end
34
+
35
+ end
36
+
37
+ attach_function :hb_buffer_create, [], :hb_buffer_t
38
+ attach_function :hb_buffer_add_utf8, [
39
+ :hb_buffer_t, # buffer
40
+ :pointer, # text
41
+ :int, # text_length
42
+ :uint, # item_offset
43
+ :int, # item_length
44
+ ], :void
45
+ attach_function :hb_buffer_guess_segment_properties, [:hb_buffer_t], :void
46
+ attach_function :hb_buffer_get_length, [:hb_buffer_t], :uint
47
+ attach_function :hb_buffer_get_glyph_infos, [
48
+ :hb_buffer_t, # buffer
49
+ :pointer, # length
50
+ ], GlyphInfo
51
+ attach_function :hb_buffer_get_glyph_positions, [
52
+ :hb_buffer_t, # buffer
53
+ :pointer, # length
54
+ ], GlyphPosition
55
+ attach_function :hb_buffer_normalize_glyphs, [:hb_buffer_t], :void
56
+
57
+ class Buffer < Base
58
+
59
+ attr_reader :hb_buffer
60
+
61
+ def initialize
62
+ @hb_buffer = Harfbuzz.hb_buffer_create
63
+ define_finalizer(:hb_buffer_destroy, @hb_buffer)
64
+ end
65
+
66
+ def add_utf8(text, offset=0, length=-1)
67
+ text_ptr = FFI::MemoryPointer.new(:char, text.bytesize)
68
+ text_ptr.put_bytes(0, text)
69
+ Harfbuzz.hb_buffer_add_utf8(@hb_buffer, text_ptr, text.bytesize, offset, length)
70
+ end
71
+
72
+ def guess_segment_properties
73
+ Harfbuzz.hb_buffer_guess_segment_properties(@hb_buffer)
74
+ end
75
+
76
+ def normalize_glyphs
77
+ Harfbuzz.hb_buffer_normalize_glyphs(@hb_buffer)
78
+ end
79
+
80
+ def length
81
+ Harfbuzz.hb_buffer_get_length(@hb_buffer)
82
+ end
83
+
84
+ def get_glyph_infos
85
+ length_ptr = FFI::MemoryPointer.new(:uint, 1)
86
+ info_ptr = Harfbuzz.hb_buffer_get_glyph_infos(@hb_buffer, length_ptr)
87
+ length = length_ptr.read_uint
88
+ length.times.map do |i|
89
+ GlyphInfo.new(info_ptr + (i * GlyphInfo.size))
90
+ end
91
+ end
92
+
93
+ def get_glyph_positions
94
+ length_ptr = FFI::MemoryPointer.new(:uint, 1)
95
+ positions_ptr = Harfbuzz.hb_buffer_get_glyph_positions(@hb_buffer, length_ptr)
96
+ length = length_ptr.read_uint
97
+ length.times.map do |i|
98
+ GlyphPosition.new(positions_ptr + (i * GlyphPosition.size))
99
+ end
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,46 @@
1
+ module Harfbuzz
2
+
3
+ typedef :pointer, :hb_face_t
4
+
5
+ attach_function :hb_face_create, [
6
+ :hb_blob_t, # blob
7
+ :uint, # index
8
+ ], :hb_face_t
9
+ attach_function :hb_face_get_index, [:hb_face_t], :uint
10
+ attach_function :hb_face_get_upem, [:hb_face_t], :uint
11
+ attach_function :hb_face_get_glyph_count, [:hb_face_t], :uint
12
+
13
+ class Face < Base
14
+
15
+ attr_reader :hb_face
16
+
17
+ def initialize(input, face_index=0)
18
+ blob = case input
19
+ when IO
20
+ Harfbuzz::Blob.new(input.read, :HB_MEMORY_MODE_READONLY)
21
+ when Blob
22
+ # use as-is
23
+ when String
24
+ Harfbuzz::Blob.new(input, :HB_MEMORY_MODE_READONLY)
25
+ else
26
+ raise "Unknown input type: #{input.class}"
27
+ end
28
+ @hb_face = Harfbuzz.hb_face_create(blob.hb_blob, face_index)
29
+ define_finalizer(:hb_buffer_destroy, @hb_face)
30
+ end
31
+
32
+ def index
33
+ Harfbuzz.hb_face_get_index(@hb_face)
34
+ end
35
+
36
+ def upem
37
+ Harfbuzz.hb_face_get_upem(@hb_face)
38
+ end
39
+
40
+ def glyph_count
41
+ Harfbuzz.hb_face_get_glyph_count(@hb_face)
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,30 @@
1
+ class FFI::Pointer
2
+
3
+ # after https://dzone.com/articles/getting-array-strings-char-ffi
4
+
5
+ def read_array_of_strings
6
+ elements = []
7
+ loc = self
8
+ until (element = loc.read_pointer).null?
9
+ elements << element.read_string
10
+ loc += FFI::Type::POINTER.size
11
+ end
12
+ elements
13
+ end
14
+
15
+ end
16
+
17
+ class FFI::MemoryPointer
18
+
19
+ # after http://zegoggl.es/2009/05/ruby-ffi-recipes.html
20
+
21
+ def self.from_array_of_strings(strings)
22
+ string_ptrs = strings.map { |s| FFI::MemoryPointer.from_string(s) } + [nil]
23
+ strings_ptr = new(:pointer, string_ptrs.length)
24
+ string_ptrs.each_with_index do |ptr, i|
25
+ strings_ptr[i].put_pointer(0, ptr)
26
+ end
27
+ strings_ptr
28
+ end
29
+
30
+ end
@@ -0,0 +1,68 @@
1
+ module Harfbuzz
2
+
3
+ typedef :pointer, :hb_font_t
4
+
5
+ attach_function :hb_font_create, [:hb_face_t], :hb_font_t
6
+ attach_function :hb_font_set_scale, [
7
+ :hb_font_t, # font
8
+ :int, # x_scale
9
+ :int, # y_scale
10
+ ], :void
11
+ attach_function :hb_ft_font_set_funcs, [:hb_font_t], :void
12
+ attach_function :hb_font_get_scale, [
13
+ :hb_font_t, # font
14
+ :pointer, # int *x_scale
15
+ :pointer, # int *y_scale
16
+ ], :void
17
+ attach_function :hb_font_get_ppem, [
18
+ :hb_font_t, # font
19
+ :pointer, # unsigned int *x_ppem
20
+ :pointer, # unsigned int *y_ppem
21
+ ], :void
22
+ attach_function :hb_font_glyph_to_string, [
23
+ :hb_font_t, # font
24
+ :hb_codepoint_t, # glyph
25
+ :pointer, # s
26
+ :uint, # size
27
+ ], :void
28
+
29
+ class Font < Base
30
+
31
+ attr_reader :hb_font
32
+
33
+ def initialize(face)
34
+ @hb_font = Harfbuzz.hb_font_create(face.hb_face)
35
+ Harfbuzz.hb_font_set_scale(@hb_font, face.upem, face.upem)
36
+ Harfbuzz.hb_ft_font_set_funcs(@hb_font)
37
+ define_finalizer(:hb_font_destroy, @hb_font)
38
+ end
39
+
40
+ def scale
41
+ x_scale_ptr = FFI::MemoryPointer.new(:int, 1)
42
+ y_scale_ptr = FFI::MemoryPointer.new(:int, 1)
43
+ Harfbuzz.hb_font_get_scale(@hb_font, x_scale_ptr, y_scale_ptr)
44
+ [
45
+ x_scale_ptr.read_int,
46
+ y_scale_ptr.read_int,
47
+ ]
48
+ end
49
+
50
+ def ppem
51
+ ppem_x_ptr = FFI::MemoryPointer.new(:uint, 1)
52
+ ppem_y_ptr = FFI::MemoryPointer.new(:uint, 1)
53
+ Harfbuzz.hb_font_get_ppem(@hb_font, ppem_x_ptr, ppem_y_ptr)
54
+ [
55
+ ppem_x_ptr.read_uint,
56
+ ppem_y_ptr.read_uint,
57
+ ]
58
+ end
59
+
60
+ def glyph_to_string(glyph)
61
+ string_ptr = FFI::MemoryPointer.new(:char, 20)
62
+ Harfbuzz.hb_font_glyph_to_string(@hb_font, glyph, string_ptr, 20)
63
+ string_ptr.get_string(0, 20)
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,75 @@
1
+ module Harfbuzz
2
+
3
+ typedef :uint32, :hb_tag_t
4
+
5
+ class Feature < FFI::Struct
6
+
7
+ layout \
8
+ :tag, :hb_tag_t,
9
+ :value, :uint32,
10
+ :start, :uint,
11
+ :end, :uint
12
+
13
+ end
14
+
15
+ # typedef Feature, :hb_feature_t
16
+
17
+ attach_function :hb_shape_list_shapers, [], :pointer
18
+ attach_function :hb_shape, [
19
+ :hb_font_t, # font
20
+ :hb_buffer_t, # buffer
21
+ :pointer, # features
22
+ :uint, # num_features
23
+ ], :void
24
+ attach_function :hb_shape_full, [
25
+ :hb_font_t, # font
26
+ :hb_buffer_t, # buffer
27
+ :pointer, # features
28
+ :uint, # num_features
29
+ :pointer, # shaper_list
30
+ ], :bool
31
+ attach_function :hb_feature_from_string, [
32
+ :pointer, # str
33
+ :int, # len
34
+ Feature.by_ref, # feature
35
+ ], :bool
36
+ attach_function :hb_feature_to_string, [
37
+ Feature.by_ref, # feature
38
+ :pointer, # buf
39
+ :uint, # size,
40
+ ], :void
41
+
42
+ def self.shapers
43
+ Harfbuzz.hb_shape_list_shapers.read_array_of_strings
44
+ end
45
+
46
+ def self.shape(font, buffer, features=nil, shapers=nil)
47
+ features_ptr, features_len = features_from_strings(features)
48
+ shapers_ptr = shapers ? FFI::MemoryPointer.from_array_of_strings(shapers) : nil
49
+ Harfbuzz.hb_shape_full(
50
+ font.hb_font,
51
+ buffer.hb_buffer,
52
+ features_ptr,
53
+ features_len,
54
+ shapers_ptr,
55
+ )
56
+ end
57
+
58
+ def self.features_from_strings(feature_strings)
59
+ features_len = feature_strings ? feature_strings.length : 0
60
+ if features_len > 0
61
+ features_ptr = FFI::MemoryPointer.new(Feature, features_len)
62
+ feature_strings.each_with_index do |feature_string, i|
63
+ feature_string_ptr = FFI::MemoryPointer.new(:char, feature_string.bytesize)
64
+ feature_string_ptr.put_bytes(0, feature_string)
65
+ feature_ptr = Feature.new(features_ptr + (i * Feature.size))
66
+ hb_feature_from_string(feature_string_ptr, feature_string.bytesize, feature_ptr) \
67
+ or raise "Can't get feature from string: #{feature_string.inspect}"
68
+ end
69
+ else
70
+ features_ptr = nil
71
+ end
72
+ [features_ptr, features_len]
73
+ end
74
+
75
+ end
@@ -0,0 +1,5 @@
1
+ module Harfbuzz
2
+
3
+ VERSION = '0.1'
4
+
5
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: harfbuzz
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - John Labovitz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: "\n Harfbuzz is a Ruby interface to the Harfbuzz text shaping engine.\n
56
+ \ "
57
+ email: johnl@johnlabovitz.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - examples/example.rb
68
+ - harfbuzz.gemspec
69
+ - lib/harfbuzz.rb
70
+ - lib/harfbuzz/base.rb
71
+ - lib/harfbuzz/blob.rb
72
+ - lib/harfbuzz/buffer.rb
73
+ - lib/harfbuzz/face.rb
74
+ - lib/harfbuzz/ffi_additions.rb
75
+ - lib/harfbuzz/font.rb
76
+ - lib/harfbuzz/shaping.rb
77
+ - lib/harfbuzz/version.rb
78
+ homepage: http://github.com/jslabovitz/harfbuzz-gem
79
+ licenses: []
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.4.8
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Ruby interface to the Harfbuzz text shaping engine
101
+ test_files: []