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.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +175 -0
- data/Rakefile +8 -0
- data/examples/rugl_text.rb +127 -0
- data/examples/stagecraft_text.rb +71 -0
- data/lib/freetype/atlas.rb +127 -0
- data/lib/freetype/bitmap.rb +46 -0
- data/lib/freetype/charset.rb +13 -0
- data/lib/freetype/data/joyo_kanji.txt +1 -0
- data/lib/freetype/errors.rb +20 -0
- data/lib/freetype/face/rasterization.rb +78 -0
- data/lib/freetype/face.rb +186 -0
- data/lib/freetype/glyph.rb +20 -0
- data/lib/freetype/harfbuzz.rb +10 -0
- data/lib/freetype/image.rb +29 -0
- data/lib/freetype/library.rb +95 -0
- data/lib/freetype/metrics.rb +17 -0
- data/lib/freetype/native/structs.rb +73 -0
- data/lib/freetype/native.rb +102 -0
- data/lib/freetype/pool.rb +79 -0
- data/lib/freetype/text_run.rb +120 -0
- data/lib/freetype/version.rb +5 -0
- data/lib/freetype.rb +25 -0
- metadata +89 -0
|
@@ -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
|
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: []
|