fontisan 0.4.3 → 0.4.4
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 +4 -4
- data/lib/fontisan/ufo/compile/fvar.rb +109 -0
- data/lib/fontisan/ufo/compile.rb +1 -0
- data/lib/fontisan/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 46b8f1b8bf47cb6b91bc1871fc136e0077a7c2d18e99526161ae2ea4085c29d5
|
|
4
|
+
data.tar.gz: d374dea6fa7de74f605702da037e93fd6a94b8f5082459231b30223a7b8df86f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 83dc37f826b6f03c37c5ebbac2c8ed5022d0265684af16e308d6aa4b3993b04bd44d61fbd6b538106daf7dd4051c7f5894618856193cc4c60bef547338eaac6f
|
|
7
|
+
data.tar.gz: f85fc773fbc61b7fb7ea7a41b8b34a05f063584e0992a88e8d0b96d0a5abc73716b4d25df0e75e80388ef582066f5ac009752dbc623d832d76237b4d0ac0d877
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Fontisan
|
|
4
|
+
module Ufo
|
|
5
|
+
module Compile
|
|
6
|
+
# Builds the OpenType `fvar` (Font Variations) table from a
|
|
7
|
+
# list of axis definitions and named instances.
|
|
8
|
+
#
|
|
9
|
+
# @see https://learn.microsoft.com/en-us/typography/opentype/spec/fvar
|
|
10
|
+
module Fvar
|
|
11
|
+
VERSION_MAJOR = 1
|
|
12
|
+
VERSION_MINOR = 0
|
|
13
|
+
AXIS_SIZE = 20
|
|
14
|
+
INSTANCE_SIZE = 4 # + 4 per axis
|
|
15
|
+
FIXED_SHIFT = 16
|
|
16
|
+
FIXED_ONE = 1 << FIXED_SHIFT
|
|
17
|
+
|
|
18
|
+
# @param font [Fontisan::Ufo::Font]
|
|
19
|
+
# @param axes [Array<Hash>] axis definitions
|
|
20
|
+
# @param instances [Array<Hash>] named instance definitions
|
|
21
|
+
# @return [String, nil] fvar table bytes, or nil if no axes
|
|
22
|
+
def self.build(font, axes: nil, instances: nil)
|
|
23
|
+
axes ||= font.info.respond_to?(:axes) ? font.info.axes : nil
|
|
24
|
+
instances ||= font.info.respond_to?(:named_instances) ? font.info.named_instances : nil
|
|
25
|
+
|
|
26
|
+
axes ||= []
|
|
27
|
+
return nil if axes.empty?
|
|
28
|
+
|
|
29
|
+
axes_bytes = build_axes(axes)
|
|
30
|
+
instances_bytes = build_instances(instances || [], axes.size)
|
|
31
|
+
header = build_header(axes.size, axes_bytes, instances_bytes, instances)
|
|
32
|
+
header + axes_bytes + instances_bytes
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# ---------- header ----------
|
|
36
|
+
|
|
37
|
+
# Header is 16 bytes:
|
|
38
|
+
# majorVersion (2) + minorVersion (2) + axesArrayOffset (2)
|
|
39
|
+
# + reserved (2) + axisCount (2) + axisSize (2)
|
|
40
|
+
# + instanceCount (2) + instanceSize (2)
|
|
41
|
+
def self.build_header(axis_count, axes_bytes, _instances_bytes, instances)
|
|
42
|
+
axes_offset = 16
|
|
43
|
+
axes_offset + axes_bytes.bytesize
|
|
44
|
+
|
|
45
|
+
[
|
|
46
|
+
VERSION_MAJOR,
|
|
47
|
+
VERSION_MINOR,
|
|
48
|
+
axes_offset,
|
|
49
|
+
0, # reserved
|
|
50
|
+
axis_count,
|
|
51
|
+
AXIS_SIZE,
|
|
52
|
+
instances&.size || 0,
|
|
53
|
+
(instances&.size || 0).zero? ? 0 : (INSTANCE_SIZE + axis_count * 4),
|
|
54
|
+
].pack("nnnnnnnn")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# ---------- axes ----------
|
|
58
|
+
|
|
59
|
+
# Each axis record is 20 bytes:
|
|
60
|
+
# axisTag (4) + minValue (4) + defaultValue (4) + maxValue (4)
|
|
61
|
+
# + flags (2) + axisNameID (2)
|
|
62
|
+
def self.build_axes(axes)
|
|
63
|
+
io = +""
|
|
64
|
+
axes.each do |axis|
|
|
65
|
+
tag = (axis[:tag] || axis["tag"] || "wght").to_s.ljust(4, " ")[0, 4]
|
|
66
|
+
min = fixed_value(axis[:min] || axis["min"] || 100)
|
|
67
|
+
default = fixed_value(axis[:default] || axis["default"] || 400)
|
|
68
|
+
max = fixed_value(axis[:max] || axis["max"] || 900)
|
|
69
|
+
flags = axis[:flags] || axis["flags"] || 0
|
|
70
|
+
name_id = axis[:name_id] || axis["name_id"] || 0
|
|
71
|
+
|
|
72
|
+
io << tag
|
|
73
|
+
io << [min, default, max, flags, name_id].pack("NNNnn")
|
|
74
|
+
end
|
|
75
|
+
io
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# ---------- instances ----------
|
|
79
|
+
|
|
80
|
+
# Each instance record: subfamilyNameID (2) + flags (2) + per-axis coords
|
|
81
|
+
def self.build_instances(instances, axis_count)
|
|
82
|
+
return +"" if instances.empty?
|
|
83
|
+
|
|
84
|
+
io = +""
|
|
85
|
+
instances.each do |inst|
|
|
86
|
+
name_id = inst[:name_id] || inst["name_id"] || 0
|
|
87
|
+
flags = inst[:flags] || inst["flags"] || 0
|
|
88
|
+
coords = inst[:coords] || inst["coords"] || []
|
|
89
|
+
padded = coords.first(axis_count) + Array.new([axis_count - coords.size, 0].max, 0)
|
|
90
|
+
padded = padded.first(axis_count).map { |c| fixed_value(c) }
|
|
91
|
+
|
|
92
|
+
io << [name_id, flags].pack("nn")
|
|
93
|
+
io << padded.pack("N*")
|
|
94
|
+
end
|
|
95
|
+
io
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# ---------- helpers ----------
|
|
99
|
+
|
|
100
|
+
# Convert a float to OpenType Fixed 16.16 (int32).
|
|
101
|
+
def self.fixed_value(value)
|
|
102
|
+
(value.to_f * FIXED_ONE).to_i
|
|
103
|
+
end
|
|
104
|
+
private_class_method :build_header, :build_axes, :build_instances,
|
|
105
|
+
:fixed_value
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
data/lib/fontisan/ufo/compile.rb
CHANGED
|
@@ -33,6 +33,7 @@ module Fontisan
|
|
|
33
33
|
autoload :TtfCompiler, "fontisan/ufo/compile/ttf_compiler"
|
|
34
34
|
autoload :OtfCompiler, "fontisan/ufo/compile/otf_compiler"
|
|
35
35
|
autoload :Filters, "fontisan/ufo/compile/filters"
|
|
36
|
+
autoload :Fvar, "fontisan/ufo/compile/fvar"
|
|
36
37
|
autoload :Gpos, "fontisan/ufo/compile/gpos"
|
|
37
38
|
autoload :Head, "fontisan/ufo/compile/head"
|
|
38
39
|
autoload :Hhea, "fontisan/ufo/compile/hhea"
|
data/lib/fontisan/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fontisan
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -563,6 +563,7 @@ files:
|
|
|
563
563
|
- lib/fontisan/ufo/compile/filters/decompose_components.rb
|
|
564
564
|
- lib/fontisan/ufo/compile/filters/flatten_components.rb
|
|
565
565
|
- lib/fontisan/ufo/compile/filters/reverse_contour_direction.rb
|
|
566
|
+
- lib/fontisan/ufo/compile/fvar.rb
|
|
566
567
|
- lib/fontisan/ufo/compile/glyf_loca.rb
|
|
567
568
|
- lib/fontisan/ufo/compile/gpos.rb
|
|
568
569
|
- lib/fontisan/ufo/compile/head.rb
|