Class: TTFunk::Table::OS2

Inherits:
TTFunk::Table show all
Defined in:
lib/ttfunk/table/os2.rb

Overview

OS/2 and Windows Metrics (OS/2) table

Constant Summary collapse

CODE_PAGE_BITS =

Code page bits.

{
  1252 => 0,
  1250 => 1,
  1251 => 2,
  1253 => 3,
  1254 => 4,
  1255 => 5,
  1256 => 6,
  1257 => 7,
  1258 => 8,
  874 => 16,
  932 => 17,
  936 => 18,
  949 => 19,
  950 => 20,
  1361 => 21,
  10_000 => 29,
  869 => 48,
  866 => 49,
  865 => 50,
  864 => 51,
  863 => 52,
  862 => 53,
  861 => 54,
  860 => 55,
  857 => 56,
  855 => 57,
  852 => 58,
  775 => 59,
  737 => 60,
  708 => 61,
  850 => 62,
  437 => 63,
}.freeze
UNICODE_BLOCKS =

Unicode blocks.

{
  (0x0000..0x007F) => 0,
  (0x0080..0x00FF) => 1,
  (0x0100..0x017F) => 2,
  (0x0180..0x024F) => 3,
  (0x0250..0x02AF) => 4,
  (0x1D00..0x1D7F) => 4,
  (0x1D80..0x1DBF) => 4,
  (0x02B0..0x02FF) => 5,
  (0xA700..0xA71F) => 5,
  (0x0300..0x036F) => 6,
  (0x1DC0..0x1DFF) => 6,
  (0x0370..0x03FF) => 7,
  (0x2C80..0x2CFF) => 8,
  (0x0400..0x04FF) => 9,
  (0x0500..0x052F) => 9,
  (0x2DE0..0x2DFF) => 9,
  (0xA640..0xA69F) => 9,
  (0x0530..0x058F) => 10,
  (0x0590..0x05FF) => 11,
  (0xA500..0xA63F) => 12,
  (0x0600..0x06FF) => 13,
  (0x0750..0x077F) => 13,
  (0x07C0..0x07FF) => 14,
  (0x0900..0x097F) => 15,
  (0x0980..0x09FF) => 16,
  (0x0A00..0x0A7F) => 17,
  (0x0A80..0x0AFF) => 18,
  (0x0B00..0x0B7F) => 19,
  (0x0B80..0x0BFF) => 20,
  (0x0C00..0x0C7F) => 21,
  (0x0C80..0x0CFF) => 22,
  (0x0D00..0x0D7F) => 23,
  (0x0E00..0x0E7F) => 24,
  (0x0E80..0x0EFF) => 25,
  (0x10A0..0x10FF) => 26,
  (0x2D00..0x2D2F) => 26,
  (0x1B00..0x1B7F) => 27,
  (0x1100..0x11FF) => 28,
  (0x1E00..0x1EFF) => 29,
  (0x2C60..0x2C7F) => 29,
  (0xA720..0xA7FF) => 29,
  (0x1F00..0x1FFF) => 30,
  (0x2000..0x206F) => 31,
  (0x2E00..0x2E7F) => 31,
  (0x2070..0x209F) => 32,
  (0x20A0..0x20CF) => 33,
  (0x20D0..0x20FF) => 34,
  (0x2100..0x214F) => 35,
  (0x2150..0x218F) => 36,
  (0x2190..0x21FF) => 37,
  (0x27F0..0x27FF) => 37,
  (0x2900..0x297F) => 37,
  (0x2B00..0x2BFF) => 37,
  (0x2200..0x22FF) => 38,
  (0x2A00..0x2AFF) => 38,
  (0x27C0..0x27EF) => 38,
  (0x2980..0x29FF) => 38,
  (0x2300..0x23FF) => 39,
  (0x2400..0x243F) => 40,
  (0x2440..0x245F) => 41,
  (0x2460..0x24FF) => 42,
  (0x2500..0x257F) => 43,
  (0x2580..0x259F) => 44,
  (0x25A0..0x25FF) => 45,
  (0x2600..0x26FF) => 46,
  (0x2700..0x27BF) => 47,
  (0x3000..0x303F) => 48,
  (0x3040..0x309F) => 49,
  (0x30A0..0x30FF) => 50,
  (0x31F0..0x31FF) => 50,
  (0x3100..0x312F) => 51,
  (0x31A0..0x31BF) => 51,
  (0x3130..0x318F) => 52,
  (0xA840..0xA87F) => 53,
  (0x3200..0x32FF) => 54,
  (0x3300..0x33FF) => 55,
  (0xAC00..0xD7AF) => 56,
  (0xD800..0xDFFF) => 57,
  (0x10900..0x1091F) => 58,
  (0x4E00..0x9FFF) => 59,
  (0x2E80..0x2EFF) => 59,
  (0x2F00..0x2FDF) => 59,
  (0x2FF0..0x2FFF) => 59,
  (0x3400..0x4DBF) => 59,
  (0x20000..0x2A6DF) => 59,
  (0x3190..0x319F) => 59,
  (0xE000..0xF8FF) => 60,
  (0x31C0..0x31EF) => 61,
  (0xF900..0xFAFF) => 61,
  (0x2F800..0x2FA1F) => 61,
  (0xFB00..0xFB4F) => 62,
  (0xFB50..0xFDFF) => 63,
  (0xFE20..0xFE2F) => 64,
  (0xFE10..0xFE1F) => 65,
  (0xFE30..0xFE4F) => 65,
  (0xFE50..0xFE6F) => 66,
  (0xFE70..0xFEFF) => 67,
  (0xFF00..0xFFEF) => 68,
  (0xFFF0..0xFFFF) => 69,
  (0x0F00..0x0FFF) => 70,
  (0x0700..0x074F) => 71,
  (0x0780..0x07BF) => 72,
  (0x0D80..0x0DFF) => 73,
  (0x1000..0x109F) => 74,
  (0x1200..0x137F) => 75,
  (0x1380..0x139F) => 75,
  (0x2D80..0x2DDF) => 75,
  (0x13A0..0x13FF) => 76,
  (0x1400..0x167F) => 77,
  (0x1680..0x169F) => 78,
  (0x16A0..0x16FF) => 79,
  (0x1780..0x17FF) => 80,
  (0x19E0..0x19FF) => 80,
  (0x1800..0x18AF) => 81,
  (0x2800..0x28FF) => 82,
  (0xA000..0xA48F) => 83,
  (0xA490..0xA4CF) => 83,
  (0x1700..0x171F) => 84,
  (0x1720..0x173F) => 84,
  (0x1740..0x175F) => 84,
  (0x1760..0x177F) => 84,
  (0x10300..0x1032F) => 85,
  (0x10330..0x1034F) => 86,
  (0x10400..0x1044F) => 87,
  (0x1D000..0x1D0FF) => 88,
  (0x1D100..0x1D1FF) => 88,
  (0x1D200..0x1D24F) => 88,
  (0x1D400..0x1D7FF) => 89,
  (0xF0000..0xFFFFD) => 90,
  (0x100000..0x10FFFD) => 90,
  (0xFE00..0xFE0F) => 91,
  (0xE0100..0xE01EF) => 91,
  (0xE0000..0xE007F) => 92,
  (0x1900..0x194F) => 93,
  (0x1950..0x197F) => 94,
  (0x1980..0x19DF) => 95,
  (0x1A00..0x1A1F) => 96,
  (0x2C00..0x2C5F) => 97,
  (0x2D30..0x2D7F) => 98,
  (0x4DC0..0x4DFF) => 99,
  (0xA800..0xA82F) => 100,
  (0x10000..0x1007F) => 101,
  (0x10080..0x100FF) => 101,
  (0x10100..0x1013F) => 101,
  (0x10140..0x1018F) => 102,
  (0x10380..0x1039F) => 103,
  (0x103A0..0x103DF) => 104,
  (0x10450..0x1047F) => 105,
  (0x10480..0x104AF) => 106,
  (0x10800..0x1083F) => 107,
  (0x10A00..0x10A5F) => 108,
  (0x1D300..0x1D35F) => 109,
  (0x12000..0x123FF) => 110,
  (0x12400..0x1247F) => 110,
  (0x1D360..0x1D37F) => 111,
  (0x1B80..0x1BBF) => 112,
  (0x1C00..0x1C4F) => 113,
  (0x1C50..0x1C7F) => 114,
  (0xA880..0xA8DF) => 115,
  (0xA900..0xA92F) => 116,
  (0xA930..0xA95F) => 117,
  (0xAA00..0xAA5F) => 118,
  (0x10190..0x101CF) => 119,
  (0x101D0..0x101FF) => 120,
  (0x102A0..0x102DF) => 121,
  (0x10280..0x1029F) => 121,
  (0x10920..0x1093F) => 121,
  (0x1F030..0x1F09F) => 122,
  (0x1F000..0x1F02F) => 122,
}.freeze
UNICODE_MAX =

Indicates that font supports supplementary characters.

0xFFFF
UNICODE_RANGES =

Unicode block ranges.

UNICODE_BLOCKS.keys.sort_by(&:max).freeze
LOWERCASE_START =

Start chracter for average character width calculation.

'a'.ord
LOWERCASE_END =

End chracter for average character width calculation.

'z'.ord
LOWERCASE_COUNT =

Number of chracters for average character width calculation.

(LOWERCASE_END - LOWERCASE_START) + 1
CODEPOINT_SPACE =

Space character code point.

32
SPACE_GLYPH_MISSING_ERROR =

Error message for missing space character.

"Space glyph (0x#{CODEPOINT_SPACE.to_s(16)}) must be included in the font"
WEIGHT_SPACE =

Used to calculate the xAvgCharWidth field. From https://docs.microsoft.com/en-us/typography/opentype/spec/os2:

“When first defined, the specification was biased toward Basic Latin characters, and it was thought that the xAvgCharWidth value could be used to estimate the average length of lines of text. A formula for calculating xAvgCharWidth was provided using frequency-of-use weighting factors for lowercase letters a - z.”

The array below contains 26 weight values which correspond to the 26 letters in the Latin alphabet. Each weight is the relative frequency of that letter in the English language.

166
WEIGHT_LOWERCASE =

chracter weights for average character width calculation.

[
  64, 14, 27, 35, 100, 20, 14, 42, 63, 3, 6, 35, 20,
  56, 56, 17, 4, 49, 56, 71, 31, 10, 18, 3, 18, 2,
].freeze

Instance Attribute Summary collapse

Attributes inherited from TTFunk::Table

#file, #length, #offset

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from TTFunk::Table

#exists?, #initialize, #raw

Constructor Details

This class inherits a constructor from TTFunk::Table

Instance Attribute Details

#ascentInteger (readonly)

The typographic ascender for this font.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 100
100
def ascent
101
  @ascent
102
end

#ave_char_widthInteger (readonly)

Average weighted escapement.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 16
16
def ave_char_width
17
  @ave_char_width
18
end

#break_charInteger (readonly)

The Unicode code point, in UTF-16 encoding, of a character that can be used as a default break character.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 141
141
def break_char
142
  @break_char
143
end

#cap_heightInteger (readonly)

The distance between the baseline and the approximate height of uppercase letters.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 130
130
def cap_height
131
  @cap_height
132
end

#char_rangeInteger (readonly)

Unicode Character Range.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 80
80
def char_range
81
  @char_range
82
end

#code_page_rangeInteger (readonly)

Code Page Character Range.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 120
120
def code_page_range
121
  @code_page_range
122
end

#default_charInteger (readonly)

The Unicode code point, in UTF-16 encoding, of a character that can be used for a default glyph if a requested character is not supported in the font.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 136
136
def default_char
137
  @default_char
138
end

#descentInteger (readonly)

The typographic descender for this font.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 104
104
def descent
105
  @descent
106
end

#family_classInteger (readonly)

Font-family class and subclass.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 72
72
def family_class
73
  @family_class
74
end

#first_char_indexInteger (readonly)

The minimum Unicode index (character code) in this font.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 92
92
def first_char_index
93
  @first_char_index
94
end

#last_char_indexInteger (readonly)

The maximum Unicode index (character code) in this font.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 96
96
def last_char_index
97
  @last_char_index
98
end

#line_gapInteger (readonly)

The typographic line gap for this font.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 108
108
def line_gap
109
  @line_gap
110
end

#max_contextInteger (readonly)

The maximum length of a target glyph context for any feature in this font.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 146
146
def max_context
147
  @max_context
148
end

#panoseInteger (readonly)

PANOSE classification number.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 76
76
def panose
77
  @panose
78
end

#selectionInteger (readonly)

Font selection flags.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 88
88
def selection
89
  @selection
90
end

#typeInteger (readonly)

Type flags.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 28
28
def type
29
  @type
30
end

#vendor_idString (readonly)

Font Vendor Identification.

Returns:

  • (String)
Source Code
lib/ttfunk/table/os2.rb, line 84
84
def vendor_id
85
  @vendor_id
86
end

#versionInteger (readonly)

Table version.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 12
12
def version
13
  @version
14
end

#weight_classInteger (readonly)

Weight class.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 20
20
def weight_class
21
  @weight_class
22
end

#width_classInteger (readonly)

Width class.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 24
24
def width_class
25
  @width_class
26
end

#win_ascentInteger (readonly)

The “Windows ascender” metric.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 112
112
def win_ascent
113
  @win_ascent
114
end

#win_descentInteger (readonly)

The “Windows descender” metric.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 116
116
def win_descent
117
  @win_descent
118
end

#x_heightInteger (readonly)

The distance between the baseline and the approximate height of non-ascending lowercase letters.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 125
125
def x_height
126
  @x_height
127
end

#y_strikeout_positionInteger (readonly)

Strikeout position.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 68
68
def y_strikeout_position
69
  @y_strikeout_position
70
end

#y_strikeout_sizeInteger (readonly)

Strikeout size.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 64
64
def y_strikeout_size
65
  @y_strikeout_size
66
end

#y_subscript_x_offsetInteger (readonly)

Subscript x offset.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 40
40
def y_subscript_x_offset
41
  @y_subscript_x_offset
42
end

#y_subscript_x_sizeInteger (readonly)

Subscript horizontal font size.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 32
32
def y_subscript_x_size
33
  @y_subscript_x_size
34
end

#y_subscript_y_offsetInteger (readonly)

Subscript y offset.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 44
44
def y_subscript_y_offset
45
  @y_subscript_y_offset
46
end

#y_subscript_y_sizeInteger (readonly)

Subscript vertical font size.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 36
36
def y_subscript_y_size
37
  @y_subscript_y_size
38
end

#y_superscript_x_offsetInteger (readonly)

Superscript x offset.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 56
56
def y_superscript_x_offset
57
  @y_superscript_x_offset
58
end

#y_superscript_x_sizeInteger (readonly)

Superscript horizontal font size.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 48
48
def y_superscript_x_size
49
  @y_superscript_x_size
50
end

#y_superscript_y_offsetInteger (readonly)

Superscript y offset.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 60
60
def y_superscript_y_offset
61
  @y_superscript_y_offset
62
end

#y_superscript_y_sizeInteger (readonly)

Superscript vertical font size.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/os2.rb, line 52
52
def y_superscript_y_size
53
  @y_superscript_y_size
54
end

Class Method Details

.encode(os2, subset) ⇒ String

Encode table.

Source Code
lib/ttfunk/table/os2.rb, line 411
411
def encode(os2, subset)
412
  result = ''.b
413
  result << [
414
    os2.version, avg_char_width_for(os2, subset), os2.weight_class,
415
    os2.width_class, os2.type, os2.y_subscript_x_size,
416
    os2.y_subscript_y_size, os2.y_subscript_x_offset,
417
    os2.y_subscript_y_offset, os2.y_superscript_x_size,
418
    os2.y_superscript_y_size, os2.y_superscript_x_offset,
419
    os2.y_superscript_y_offset, os2.y_strikeout_size,
420
    os2.y_strikeout_position, os2.family_class,
421
  ].pack('n*')
422
423
  result << os2.panose
424
425
  new_char_range = unicode_blocks_for(os2, os2.char_range, subset)
426
  result << BinUtils
427
    .slice_int(
428
      new_char_range.value,
429
      bit_width: 32,
430
      slice_count: 4,
431
    )
432
    .pack('N*')
433
434
  result << os2.vendor_id
435
436
  new_cmap_table = subset.new_cmap_table[:charmap]
437
  code_points = new_cmap_table
438
    .keys
439
    .select { |k| (new_cmap_table[k][:new]).positive? }
440
    .sort
441
442
  # "This value depends on which character sets the font supports.
443
  # This field cannot represent supplementary character values
444
  # (codepoints greater than 0xFFFF). Fonts that support
445
  # supplementary characters should set the value in this field
446
  # to 0xFFFF."
447
  first_char_index = [code_points.first || 0, UNICODE_MAX].min
448
  last_char_index = [code_points.last || 0, UNICODE_MAX].min
449
450
  result << [
451
    os2.selection, first_char_index, last_char_index,
452
  ].pack('n*')
453
454
  if os2.version.positive?
455
    result << [
456
      os2.ascent, os2.descent, os2.line_gap,
457
      os2.win_ascent, os2.win_descent,
458
    ].pack('n*')
459
460
    result << BinUtils
461
      .slice_int(
462
        code_pages_for(subset).value,
463
        bit_width: 32,
464
        slice_count: 2,
465
      )
466
      .pack('N*')
467
468
    if os2.version > 1
469
      result << [
470
        os2.x_height, os2.cap_height, os2.default_char,
471
        os2.break_char, os2.max_context,
472
      ].pack('n*')
473
    end
474
  end
475
476
  result
477
end

Instance Method Details

#tagString

Table tag.

Returns:

  • (String)
Source Code
lib/ttfunk/table/os2.rb, line 400
400
def tag
401
  'OS/2'
402
end