touchup_for_web.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #!/usr/bin/python
  2. #
  3. # Copyright 2015 Google Inc. All Rights Reserved.
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. """Post-build web fonts changes for Roboto."""
  17. import sys
  18. from fontTools import ttLib
  19. from nototools import font_data
  20. import temporary_touchups
  21. def apply_web_specific_fixes(font, unhinted, family_name):
  22. """Apply fixes needed for web fonts."""
  23. # set vertical metrics to old values
  24. hhea = font['hhea']
  25. hhea.ascent = 1900
  26. hhea.descent = -500
  27. os2 = font['OS/2']
  28. os2.sTypoAscender = 1536
  29. os2.sTypoDescender = -512
  30. os2.sTypoLineGap = 102
  31. os2.usWinAscent = 1946
  32. os2.usWinDescent = 512
  33. # correct anything else needed for both web and Chrome OS
  34. apply_web_cros_common_fixes(font, unhinted, family_name)
  35. def apply_web_cros_common_fixes(font, unhinted, family_name):
  36. """Apply fixes needed for web and CrOS targets"""
  37. subfamily_name = font_data.get_name_records(font)[2].encode('ASCII')
  38. assert(subfamily_name in
  39. ['Thin', 'Thin Italic',
  40. 'Light', 'Light Italic',
  41. 'Regular', 'Italic',
  42. 'Medium', 'Medium Italic',
  43. 'Bold', 'Bold Italic',
  44. 'Black', 'Black Italic'])
  45. if 'Condensed' in font_data.get_name_records(font)[1]:
  46. family_name += ' Condensed'
  47. full_name = family_name
  48. if subfamily_name != 'Regular':
  49. full_name += ' ' + subfamily_name
  50. # Family, subfamily names
  51. font_data.set_name_record(font, 16, family_name)
  52. style_map = ['Regular', 'Bold', 'Italic', 'Bold Italic']
  53. if subfamily_name in style_map:
  54. font_data.set_name_record(font, 1, family_name)
  55. else:
  56. weight = subfamily_name.split()[0]
  57. new_family_name = family_name
  58. if weight != 'Regular':
  59. new_family_name += ' ' + weight
  60. font_data.set_name_record(font, 1, new_family_name)
  61. # all weights outside regular and bold should only have subfamily
  62. # "Regular" or "Italic"
  63. italic = subfamily_name.endswith('Italic')
  64. font_data.set_name_record(font, 2, style_map[italic << 1])
  65. # Unique identifier and full name
  66. font_data.set_name_record(font, 3, full_name)
  67. font_data.set_name_record(font, 4, full_name)
  68. font_data.set_name_record(font, 18, None)
  69. # PostScript name
  70. font_data.set_name_record(
  71. font, 6, (family_name+'-'+subfamily_name).replace(' ', ''))
  72. # Copyright message
  73. font_data.set_name_record(
  74. font, 0, 'Copyright 2011 Google Inc. All Rights Reserved.')
  75. # hotpatch glyphs by swapping
  76. # https://github.com/google/roboto/issues/18
  77. glyf = font['glyf']
  78. glyf['chi'], glyf['chi.alt'] = glyf['chi.alt'], glyf['chi']
  79. # make glyph orders consistent for feature copying
  80. # https://github.com/google/roboto/issues/71
  81. glyph_order = font.getGlyphOrder()
  82. for i, glyph_name in enumerate(glyph_order):
  83. if glyph_name.endswith('.lnum'):
  84. new_name = glyph_name.replace('.lnum', '.pnum')
  85. glyph_order[i] = new_name
  86. font['glyf'][new_name] = font['glyf'][glyph_name]
  87. # append old name to glyph order so del succeeds
  88. glyph_order.append(glyph_name)
  89. del font['glyf'][glyph_name]
  90. # copy features from unhinted
  91. # https://github.com/google/roboto/pull/163
  92. for table in ['GDEF', 'GPOS', 'GSUB']:
  93. font[table] = unhinted[table]
  94. def correct_font(source_name, unhinted_name, target_font_name, family_name):
  95. """Corrects metrics and other meta information."""
  96. font = ttLib.TTFont(source_name)
  97. unhinted = ttLib.TTFont(unhinted_name)
  98. # apply web-specific fixes before shared, so that sub/family names are
  99. # correct for black weights and their bold bits will be set
  100. apply_web_specific_fixes(font, unhinted, family_name)
  101. temporary_touchups.apply_temporary_fixes(font, is_for_web=True)
  102. temporary_touchups.update_version_and_revision(font)
  103. font.save(target_font_name)
  104. def main(argv):
  105. """Correct the font specified in the command line."""
  106. correct_font(*argv[1:])
  107. if __name__ == "__main__":
  108. main(sys.argv)