You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
2.9 KiB

4 years ago
  1. #
  2. # The Python Imaging Library
  3. # $Id$
  4. #
  5. # bitmap distribution font (bdf) file parser
  6. #
  7. # history:
  8. # 1996-05-16 fl created (as bdf2pil)
  9. # 1997-08-25 fl converted to FontFile driver
  10. # 2001-05-25 fl removed bogus __init__ call
  11. # 2002-11-20 fl robustification (from Kevin Cazabon, Dmitry Vasiliev)
  12. # 2003-04-22 fl more robustification (from Graham Dumpleton)
  13. #
  14. # Copyright (c) 1997-2003 by Secret Labs AB.
  15. # Copyright (c) 1997-2003 by Fredrik Lundh.
  16. #
  17. # See the README file for information on usage and redistribution.
  18. #
  19. from __future__ import print_function
  20. from . import Image, FontFile
  21. # --------------------------------------------------------------------
  22. # parse X Bitmap Distribution Format (BDF)
  23. # --------------------------------------------------------------------
  24. bdf_slant = {
  25. "R": "Roman",
  26. "I": "Italic",
  27. "O": "Oblique",
  28. "RI": "Reverse Italic",
  29. "RO": "Reverse Oblique",
  30. "OT": "Other"
  31. }
  32. bdf_spacing = {
  33. "P": "Proportional",
  34. "M": "Monospaced",
  35. "C": "Cell"
  36. }
  37. def bdf_char(f):
  38. # skip to STARTCHAR
  39. while True:
  40. s = f.readline()
  41. if not s:
  42. return None
  43. if s[:9] == b"STARTCHAR":
  44. break
  45. id = s[9:].strip().decode('ascii')
  46. # load symbol properties
  47. props = {}
  48. while True:
  49. s = f.readline()
  50. if not s or s[:6] == b"BITMAP":
  51. break
  52. i = s.find(b" ")
  53. props[s[:i].decode('ascii')] = s[i+1:-1].decode('ascii')
  54. # load bitmap
  55. bitmap = []
  56. while True:
  57. s = f.readline()
  58. if not s or s[:7] == b"ENDCHAR":
  59. break
  60. bitmap.append(s[:-1])
  61. bitmap = b"".join(bitmap)
  62. [x, y, l, d] = [int(p) for p in props["BBX"].split()]
  63. [dx, dy] = [int(p) for p in props["DWIDTH"].split()]
  64. bbox = (dx, dy), (l, -d-y, x+l, -d), (0, 0, x, y)
  65. try:
  66. im = Image.frombytes("1", (x, y), bitmap, "hex", "1")
  67. except ValueError:
  68. # deal with zero-width characters
  69. im = Image.new("1", (x, y))
  70. return id, int(props["ENCODING"]), bbox, im
  71. ##
  72. # Font file plugin for the X11 BDF format.
  73. class BdfFontFile(FontFile.FontFile):
  74. def __init__(self, fp):
  75. FontFile.FontFile.__init__(self)
  76. s = fp.readline()
  77. if s[:13] != b"STARTFONT 2.1":
  78. raise SyntaxError("not a valid BDF file")
  79. props = {}
  80. comments = []
  81. while True:
  82. s = fp.readline()
  83. if not s or s[:13] == b"ENDPROPERTIES":
  84. break
  85. i = s.find(b" ")
  86. props[s[:i].decode('ascii')] = s[i+1:-1].decode('ascii')
  87. if s[:i] in [b"COMMENT", b"COPYRIGHT"]:
  88. if s.find(b"LogicalFontDescription") < 0:
  89. comments.append(s[i+1:-1].decode('ascii'))
  90. while True:
  91. c = bdf_char(fp)
  92. if not c:
  93. break
  94. id, ch, (xy, dst, src), im = c
  95. if 0 <= ch < len(self.glyph):
  96. self.glyph[ch] = xy, dst, src, im