Class: Okab::EmbeddedFont
- Inherits:
-
Object
- Object
- Okab::EmbeddedFont
- Defined in:
- lib/okab/font.rb,
sig/okab.rbs
Instance Attribute Summary collapse
-
#document ⇒ Document
readonly
Returns the value of attribute document.
-
#font ⇒ Font
readonly
Returns the value of attribute font.
-
#subset ⇒ Boolean
readonly
Returns the value of attribute subset.
Instance Method Summary collapse
- #base_name(data) ⇒ String
- #characters ⇒ Hash[Integer, [String, Integer]]
- #encode(string) ⇒ String
-
#encode_glyph(glyph, unicode:) ⇒ String
Preserve glyph IDs produced by an external shaper instead of shaping the source text a second time when a vector display list is embedded.
- #face ⇒ Alhena::Font
- #glyph_ids ⇒ Array[Integer]
-
#initialize(document, font, subset: true) ⇒ EmbeddedFont
constructor
A new instance of EmbeddedFont.
- #measure(text, size:) ⇒ Float
- #subset_font ⇒ [String, Alhena::Font, Hash[Integer, Integer], bool]
Constructor Details
#initialize(document, font, subset: true) ⇒ EmbeddedFont
Returns a new instance of EmbeddedFont.
29 30 31 32 |
# File 'lib/okab/font.rb', line 29 def initialize(document, font, subset: true) @document, @font, @subset = document, font, !!subset @cid_by_character, @characters = {}, {0 => ["\u0000", 0]} end |
Instance Attribute Details
#document ⇒ Document (readonly)
Returns the value of attribute document.
27 28 29 |
# File 'lib/okab/font.rb', line 27 def document @document end |
#font ⇒ Font (readonly)
Returns the value of attribute font.
27 28 29 |
# File 'lib/okab/font.rb', line 27 def font @font end |
#subset ⇒ Boolean (readonly)
Returns the value of attribute subset.
27 28 29 |
# File 'lib/okab/font.rb', line 27 def subset @subset end |
Instance Method Details
#base_name(data) ⇒ String
98 99 100 101 102 |
# File 'lib/okab/font.rb', line 98 def base_name(data) prefix = Digest::SHA256.hexdigest(data).upcase[0, 6].tr("0-9", "A-J") family = face.family.to_s.gsub(/[^A-Za-z0-9]/, "") "#{prefix}+#{family.empty? ? 'EmbeddedFont' : family}" end |
#characters ⇒ Hash[Integer, [String, Integer]]
96 |
# File 'lib/okab/font.rb', line 96 def characters = @characters |
#encode(string) ⇒ String
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/okab/font.rb', line 37 def encode(string) codepoints = string.codepoints cids = [] codepoints.each_with_index do |codepoint, index| next if variation_selector?(codepoint) selector = variation_selector?(codepoints[index + 1]) ? codepoints[index + 1] : nil glyph = face.glyph_id(codepoint, variation_selector: selector) glyph = face.glyph_id(codepoint) if glyph.zero? && selector character = [codepoint, *([selector] if selector)].pack("U*") key = [character, glyph] cid = @cid_by_character[key] unless cid cid = @characters.length raise ArgumentError, "a PDF font cannot encode more than 65,535 characters" if cid > 65_535 @cid_by_character[key] = cid @characters[cid] = [character, glyph] end cids << cid end cids.pack("n*") end |
#encode_glyph(glyph, unicode:) ⇒ String
Preserve glyph IDs produced by an external shaper instead of shaping the source text a second time when a vector display list is embedded.
63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/okab/font.rb', line 63 def encode_glyph(glyph, unicode:) raise ArgumentError, "invalid glyph ID" unless glyph.is_a?(Integer) && glyph.between?(0, face.glyph_count - 1) raise ArgumentError, "glyph text must be valid UTF-8" unless unicode.is_a?(String) && unicode.encoding == Encoding::UTF_8 && unicode.valid_encoding? key = [unicode, glyph] cid = @cid_by_character[key] unless cid cid = @characters.length raise ArgumentError, "a PDF font cannot encode more than 65,535 characters" if cid > 65_535 @cid_by_character[key] = cid @characters[cid] = [unicode.empty? ? "\uFFFD" : unicode, glyph] end [cid].pack("n") end |
#face ⇒ Alhena::Font
34 |
# File 'lib/okab/font.rb', line 34 def face = @font.face |
#glyph_ids ⇒ Array[Integer]
77 78 79 |
# File 'lib/okab/font.rb', line 77 def glyph_ids @characters.values.map(&:last).uniq end |
#measure(text, size:) ⇒ Float
35 |
# File 'lib/okab/font.rb', line 35 def measure(text, size:) = @font.measure(text, size: size) |
#subset_font ⇒ [String, Alhena::Font, Hash[Integer, Integer], bool]
81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/okab/font.rb', line 81 def subset_font if face.cff? raise Alhena::UnsupportedFont, "CID CFF embedding requires subset: true" unless @subset data = Alhena::Subset.build_cid(face, @characters.values.map(&:last)) return [data, face, {}, true] end selected = @subset ? glyph_ids : (0...face.glyph_count).to_a data = Alhena::Subset.build(face, selected) subset_face = Alhena::Font.new(data) old_ids = Alhena::Subset.closure(face, [0, *selected].uniq) [data, subset_face, old_ids.each_with_index.to_h, false] end |