Add bin and edit workflow
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 9s

This commit is contained in:
2026-09-16 13:11:16 -06:00
parent c8ac4fcae5
commit 4cee170d66
17576 changed files with 895740 additions and 2 deletions
@@ -0,0 +1,158 @@
# frozen_string_literal: true
require_relative '../../reader'
module TTFunk
class Table
class Glyf
# Composite TrueType glyph.
class Compound
include Reader
# Flags bit 0: arg1 and arg2 are words.
ARG_1_AND_2_ARE_WORDS = 0x0001
# Flags bit 3: there is a simple scale for the component.
WE_HAVE_A_SCALE = 0x0008
# Flags bit 5: at least one more glyph after this one.
MORE_COMPONENTS = 0x0020
# Flags bit 6: the x direction will use a different scale from the
# y direction.
WE_HAVE_AN_X_AND_Y_SCALE = 0x0040
# Flags bit 7: there is a 2 by 2 transformation that will be used to
# scale the component.
WE_HAVE_A_TWO_BY_TWO = 0x0080
# Flags bit 8: following the last component are instructions for the
# composite character.
WE_HAVE_INSTRUCTIONS = 0x0100
# Glyph ID.
# @return [Integer]
attr_reader :id
# Binary serialization of this glyph.
# @return [String]
attr_reader :raw
# Number of contours in this glyph.
# @return [Integer]
attr_reader :number_of_contours
# Minimum x for coordinate.
# @return [Integer]
attr_reader :x_min
# Minimum y for coordinate.
# @return [Integer]
attr_reader :y_min
# Maximum x for coordinate.
# @return [Integer]
attr_reader :x_max
# Maximum y for coordinate.
# @return [Integer]
attr_reader :y_max
# IDs of compound glyphs.
attr_reader :glyph_ids
# Component glyph.
#
# @!attribute [rw] flags
# Component flag.
# @return [Integer]
# @!attribute [rw] glyph_index
# Glyph index of component.
# @return [Integer]
# @!attribute [rw] arg1
# x-offset for component or point number.
# @return [Integer]
# @!attribute [rw] arg2
# y-offset for component or point number.
# @return [Integer]
# @!attribute [rw] transform
# Transformation.
# @return []
Component = Struct.new(:flags, :glyph_index, :arg1, :arg2, :transform)
# @param id [Integer] glyph ID.
# @param raw [String]
def initialize(id, raw)
@id = id
@raw = raw
io = StringIO.new(raw)
@number_of_contours, @x_min, @y_min, @x_max, @y_max =
io.read(10).unpack('n*').map { |i|
BinUtils.twos_comp_to_int(i, bit_width: 16)
}
# Because TTFunk only cares about glyphs insofar as they (1) provide
# a bounding box for each glyph, and (2) can be rewritten into a
# font subset, we don't really care about the rest of the glyph data
# except as a whole. Thus, we don't actually decompose the glyph
# into it's parts--all we really care about are the locations within
# the raw string where the component glyph ids are stored, so that
# when we rewrite this glyph into a subset we can rewrite the
# component glyph-ids so they are correct for the subset.
@glyph_ids = []
@glyph_id_offsets = []
offset = 10 # 2 bytes for each of num-contours, min x/y, max x/y
loop do
flags, glyph_id = @raw[offset, 4].unpack('n*')
@glyph_ids << glyph_id
@glyph_id_offsets << (offset + 2)
break if (flags & MORE_COMPONENTS).zero?
offset += 4
offset +=
if (flags & ARG_1_AND_2_ARE_WORDS).zero?
2
else
4
end
if flags & WE_HAVE_A_TWO_BY_TWO != 0
offset += 8
elsif flags & WE_HAVE_AN_X_AND_Y_SCALE != 0
offset += 4
elsif flags & WE_HAVE_A_SCALE != 0
offset += 2
end
end
end
# Is this a composite glyph?
# @return [true]
def compound?
true
end
# Recode glyph.
#
# @param mapping [Hash{Integer => Integer}] a hash mapping old glyph IDs
# to new glyph IDs.
# @return [String]
def recode(mapping)
result = raw.dup
new_ids = glyph_ids.map { |id| mapping[id] }
new_ids.zip(@glyph_id_offsets).each do |new_id, offset|
result[offset, 2] = [new_id].pack('n')
end
result
end
end
end
end
end
@@ -0,0 +1,84 @@
# frozen_string_literal: true
module TTFunk
class Table
class Glyf
# TrueType-compatible representation of a CFF glyph.
class PathBased
# Glyph outline.
# @return [TTFunk::Table::Cff::Path]
attr_reader :path
# Glyph horizontal metrics.
# @return [TTFunk::Table::Hmtx::HorizontalMetric]
attr_reader :horizontal_metrics
# Minimum X.
# @return [Integer, Float]
attr_reader :x_min
# Minimum Y.
# @return [Integer, Float]
attr_reader :y_min
# Maximum X.
# @return [Integer, Float]
attr_reader :x_max
# Maximum Y.
# @return [Integer, Float]
attr_reader :y_max
# Left side bearing.
# @return [Integer, Float]
attr_reader :left_side_bearing
# Rigth side bearing.
# @return [Integer, Float]
attr_reader :right_side_bearing
# @param path [TTFunk::Table::Cff::Path]
# @param horizontal_metrics [TTFunk::Table::Hmtx::HorizontalMetric]
def initialize(path, horizontal_metrics)
@path = path
@horizontal_metrics = horizontal_metrics
@x_min = 0
@y_min = 0
@x_max = horizontal_metrics.advance_width
@y_max = 0
path.commands.each do |command|
cmd, x, y = command
next if cmd == :close
@x_min = x if x < @x_min
@x_max = x if x > @x_max
@y_min = y if y < @y_min
@y_max = y if y > @y_max
end
@left_side_bearing = horizontal_metrics.left_side_bearing
@right_side_bearing =
horizontal_metrics.advance_width -
@left_side_bearing -
(@x_max - @x_min)
end
# Number of contour.
#
# @return [Integer]
def number_of_contours
path.number_of_contours
end
# Is this glyph compound?
#
# @return [false]
def compound?
false
end
end
end
end
end
@@ -0,0 +1,89 @@
# frozen_string_literal: true
require_relative '../../reader'
module TTFunk
class Table
class Glyf
# Simple TrueType glyph
class Simple
# Glyph ID.
# @return [Integer]
attr_reader :id
# Binary serialization of this glyph.
# @return [String]
attr_reader :raw
# Number of contours in this glyph.
# @return [Integer]
attr_reader :number_of_contours
# Minimum x for coordinate.
# @return [Integer]
attr_reader :x_min
# Minimum y for coordinate.
# @return [Integer]
attr_reader :y_min
# Maximum x for coordinate.
# @return [Integer]
attr_reader :x_max
# Maximum y for coordinate.
# @return [Integer]
attr_reader :y_max
# Point indices for the last point of each contour.
# @return [Array<Integer>]
attr_reader :end_points_of_contours
# Total number of bytes for instructions.
# @return [Integer]
attr_reader :instruction_length
# Instruction byte code.
# @return [Array<Integer>]
attr_reader :instructions
# @param id [Integer] glyph ID.
# @param raw [String]
def initialize(id, raw)
@id = id
@raw = raw
io = StringIO.new(raw)
@number_of_contours, @x_min, @y_min, @x_max, @y_max =
io.read(10).unpack('n*').map { |i|
BinUtils.twos_comp_to_int(i, bit_width: 16)
}
@end_points_of_contours = io.read(number_of_contours * 2).unpack('n*')
@instruction_length = io.read(2).unpack1('n')
@instructions = io.read(instruction_length).unpack('C*')
end
# Is this glyph compound?
# @return [false]
def compound?
false
end
# Recode glyph.
#
# @param _mapping Unused, here for API compatibility.
# @return [String]
def recode(_mapping)
raw
end
# End point index of last contour.
# @return [Integer]
def end_point_of_last_contour
end_points_of_contours.last + 1
end
end
end
end
end