freetype-ruby 1.0.0

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.
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FreeType
4
+ class TextRun
5
+ include Enumerable
6
+
7
+ Quad = Data.define(:x0, :y0, :x1, :y1, :u0, :v0, :u1, :v1)
8
+
9
+ attr_reader :quads
10
+
11
+ def self.layout(shaped, atlas)
12
+ new(layout_quads(shaped, atlas.entries))
13
+ end
14
+
15
+ def self.layout_quads(shaped, entries)
16
+ cursor_x = 0.0
17
+ cursor_y = 0.0
18
+ quads = []
19
+
20
+ glyph_pairs(shaped).each do |info, position|
21
+ entry = entries[glyph_id(info)]
22
+ if entry && entry.width.positive? && entry.height.positive?
23
+ offset_x = fixed(position, :x_offset)
24
+ offset_y = fixed(position, :y_offset)
25
+ x0 = cursor_x + offset_x + entry.bearing_x
26
+ y0 = cursor_y - offset_y - entry.bearing_y
27
+ quads << Quad.new(
28
+ x0: x0, y0: y0, x1: x0 + entry.width, y1: y0 + entry.height,
29
+ u0: entry.u0, v0: entry.v0, u1: entry.u1, v1: entry.v1
30
+ )
31
+ end
32
+ cursor_x += fixed(position, :x_advance)
33
+ cursor_y -= fixed(position, :y_advance)
34
+ end
35
+ quads.freeze
36
+ end
37
+
38
+ def self.glyph_pairs(shaped)
39
+ if shaped.respond_to?(:glyph_infos) && shaped.respond_to?(:glyph_positions)
40
+ return shaped.glyph_infos.zip(shaped.glyph_positions)
41
+ end
42
+
43
+ shaped.to_a.map do |pair|
44
+ unless pair.respond_to?(:to_ary) && pair.to_ary.length == 2
45
+ raise ArgumentError, "shaped glyphs must yield [info, position] pairs"
46
+ end
47
+
48
+ pair.to_ary
49
+ end
50
+ end
51
+
52
+ def self.glyph_id(info)
53
+ return Integer(info.glyph_id) if info.respond_to?(:glyph_id)
54
+ return Integer(info.codepoint) if info.respond_to?(:codepoint)
55
+ return Integer(info.fetch(:glyph_id)) if info.respond_to?(:fetch)
56
+
57
+ raise ArgumentError, "glyph info does not expose a glyph_id"
58
+ end
59
+
60
+ def self.fixed(position, field)
61
+ value = if position.respond_to?(field)
62
+ position.public_send(field)
63
+ elsif position.respond_to?(:fetch)
64
+ position.fetch(field)
65
+ else
66
+ raise ArgumentError, "glyph position does not expose #{field}"
67
+ end
68
+ FixedPoint.from_26_6(value)
69
+ end
70
+
71
+ private_class_method :layout_quads, :glyph_pairs, :glyph_id, :fixed
72
+
73
+ def initialize(quads)
74
+ @quads = quads
75
+ freeze
76
+ end
77
+
78
+ def each(&block)
79
+ quads.each(&block)
80
+ end
81
+
82
+ def [](index)
83
+ quads[index]
84
+ end
85
+
86
+ def length
87
+ quads.length
88
+ end
89
+
90
+ alias size length
91
+
92
+ def empty?
93
+ quads.empty?
94
+ end
95
+
96
+ def to_a
97
+ quads.dup
98
+ end
99
+
100
+ def to_packed
101
+ if quads.length > 16_384
102
+ raise RangeError, "u16 indices support at most 16384 text quads"
103
+ end
104
+
105
+ vertices = quads.flat_map do |quad|
106
+ [
107
+ quad.x0, quad.y0, quad.u0, quad.v0,
108
+ quad.x1, quad.y0, quad.u1, quad.v0,
109
+ quad.x1, quad.y1, quad.u1, quad.v1,
110
+ quad.x0, quad.y1, quad.u0, quad.v1
111
+ ]
112
+ end.pack("e*").freeze
113
+ indices = quads.each_index.flat_map do |index|
114
+ base = index * 4
115
+ [base, base + 1, base + 2, base, base + 2, base + 3]
116
+ end.pack("S<*").freeze
117
+ { vertices: vertices, indices: indices }.freeze
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FreeType
4
+ VERSION = "1.0.0"
5
+ end
data/lib/freetype.rb ADDED
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "freetype/version"
4
+ require_relative "freetype/errors"
5
+ require_relative "freetype/native"
6
+ require_relative "freetype/image"
7
+ require_relative "freetype/bitmap"
8
+ require_relative "freetype/metrics"
9
+ require_relative "freetype/glyph"
10
+ require_relative "freetype/face"
11
+ require_relative "freetype/library"
12
+ require_relative "freetype/charset"
13
+ require_relative "freetype/atlas"
14
+ require_relative "freetype/pool"
15
+
16
+ module FreeType
17
+ class << self
18
+ def open(&block)
19
+ Library.open(&block)
20
+ end
21
+ end
22
+ end
23
+
24
+ # Compatibility with the constant generated by early versions of the gem.
25
+ Freetype = FreeType unless defined?(Freetype)
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: freetype-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Yudai Takada
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: ffi
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '1.16'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '2'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '1.16'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '2'
32
+ description: |-
33
+ freetype provides safe, fixed-point-free Ruby APIs for loading fonts,
34
+ rasterizing glyphs, building GPU atlases, and laying out HarfBuzz output.
35
+ email:
36
+ - t.yudai92@gmail.com
37
+ executables: []
38
+ extensions: []
39
+ extra_rdoc_files: []
40
+ files:
41
+ - LICENSE.txt
42
+ - README.md
43
+ - Rakefile
44
+ - examples/rugl_text.rb
45
+ - examples/stagecraft_text.rb
46
+ - lib/freetype.rb
47
+ - lib/freetype/atlas.rb
48
+ - lib/freetype/bitmap.rb
49
+ - lib/freetype/charset.rb
50
+ - lib/freetype/data/joyo_kanji.txt
51
+ - lib/freetype/errors.rb
52
+ - lib/freetype/face.rb
53
+ - lib/freetype/face/rasterization.rb
54
+ - lib/freetype/glyph.rb
55
+ - lib/freetype/harfbuzz.rb
56
+ - lib/freetype/image.rb
57
+ - lib/freetype/library.rb
58
+ - lib/freetype/metrics.rb
59
+ - lib/freetype/native.rb
60
+ - lib/freetype/native/structs.rb
61
+ - lib/freetype/pool.rb
62
+ - lib/freetype/text_run.rb
63
+ - lib/freetype/version.rb
64
+ homepage: https://github.com/ydah/freetype
65
+ licenses:
66
+ - MIT
67
+ metadata:
68
+ homepage_uri: https://github.com/ydah/freetype
69
+ source_code_uri: https://github.com/ydah/freetype/tree/main
70
+ changelog_uri: https://github.com/ydah/freetype/releases
71
+ rubygems_mfa_required: 'true'
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: 3.2.0
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubygems_version: 4.0.6
87
+ specification_version: 4
88
+ summary: Ruby bindings for FreeType font rasterization
89
+ test_files: []