def getfont(self): if self._font is None: if self.fontfilename is not None: with config.open(self.fontfilename, [config.format.type1]) as fontfile: t1font = t1file.from_PF_bytes(fontfile.read()) assert self.basepsname == t1font.name, "corrupt MAP file" try: with config.open(os.path.splitext(self.fontfilename)[0], [config.format.afm], ascii=True) as metricfile: self._font = font.T1font(t1font, afmfile.AFMfile(metricfile)) except EnvironmentError: try: # fallback by using the pfm instead of the afm font metric # (in all major TeX distributions there is no pfm file format defined by kpsewhich, but # we can use the type1 format and search for the file including the expected suffix) with config.open( "%s.pfm" % os.path.splitext(self.fontfilename)[0], [config.format.type1]) as metricfile: self._font = font.T1font( t1font, pfmfile.PFMfile(metricfile, t1font)) except EnvironmentError: # we need to continue without any metric file self._font = font.T1font(t1font) else: # builtin font with config.open(self.basepsname, [config.format.afm], ascii=True) as metricfile: self._font = font.T1builtinfont( self.basepsname, afmfile.AFMfile(metricfile)) return self._font
def __init__(self, name, c, q, d, tfmconv, pyxconv, debug=0): self.name = name self.q = q # desired size of font (fix_word) in TeX points self.d = d # design size of font (fix_word) in TeX points self.tfmconv = tfmconv # conversion factor from tfm units to dvi units self.pyxconv = pyxconv # conversion factor from dvi units to PostScript points with config.open(self.name, [config.format.tfm]) as file: self.TFMfile = tfmfile.TFMfile(file, debug) # We only check for equality of font checksums if none of them # is zero. The case c == 0 happend in some VF files and # according to the VFtoVP documentation, paragraph 40, a check # is only performed if TFMfile.checksum > 0. Anyhow, being # more generous here seems to be reasonable if self.TFMfile.checksum != c and self.TFMfile.checksum > 0 and c > 0: raise TeXFontError("check sums do not agree: %d vs. %d" % (self.TFMfile.checksum, c)) # Check whether the given design size matches the one defined in the tfm file if abs(self.TFMfile.designsize - d) > 4: # XXX: why the deviation? raise TeXFontError("design sizes do not agree: %d vs. %d" % (self.TFMfile.designsize, d)) #if q < 0 or q > 134217728: # raise TeXFontError("font '%s' not loaded: bad scale" % self.name) if d < 0 or d > 134217728: raise TeXFontError("font '%s' not loaded: bad design size" % self.name)
def getencoding(self): if self._encoding is _marker: if self.encodingfilename is not None: with config.open(self.encodingfilename, [config.format.tex_ps_header]) as encodingfile: ef = encfile.ENCfile(encodingfile.read().decode("ascii", errors="surrogateescape")) assert ef.name == "/%s" % self.reencodefont self._encoding = ef.vector else: self._encoding = None return self._encoding
def getfont(self): if self._font is None: if self.fontfilename is not None: with config.open(self.fontfilename, [config.format.type1]) as fontfile: t1font = t1file.from_PF_bytes(fontfile.read()) assert self.basepsname == t1font.name, "corrupt MAP file" try: with config.open(os.path.splitext(self.fontfilename)[0], [config.format.afm], ascii=True) as metricfile: self._font = font.T1font(t1font, afmfile.AFMfile(metricfile)) except EnvironmentError: try: # fallback by using the pfm instead of the afm font metric # (in all major TeX distributions there is no pfm file format defined by kpsewhich, but # we can use the type1 format and search for the file including the expected suffix) with config.open("%s.pfm" % os.path.splitext(self.fontfilename)[0], [config.format.type1]) as metricfile: self._font = font.T1font(t1font, pfmfile.PFMfile(metricfile, t1font)) except EnvironmentError: # we need to continue without any metric file self._font = font.T1font(t1font) else: # builtin font with config.open(self.basepsname, [config.format.afm], ascii=True) as metricfile: self._font = font.T1builtinfont(self.basepsname, afmfile.AFMfile(metricfile)) return self._font
def definefont(self, cmdnr, num, c, q, d, fontname): # cmdnr: type of fontdef command (only used for debugging output) # c: checksum # q: scaling factor (fix_word) # Note that q is actually s in large parts of the documentation. # d: design size (fix_word) # check whether it's a virtual font by trying to open it. if this fails, it is an ordinary TeX font try: with config.open(fontname, [config.format.vf]) as fontfile: afont = texfont.virtualfont(fontname, fontfile, c, q/self.tfmconv, d/self.tfmconv, self.tfmconv, self.pyxconv, self.debug>1) except EnvironmentError: afont = texfont.TeXfont(fontname, c, q/self.tfmconv, d/self.tfmconv, self.tfmconv, self.pyxconv, self.debug>1) self.fonts[num] = afont if self.debug: self.debugfile.write("%d: fntdef%d %i: %s\n" % (self.filepos, cmdnr, num, fontname))
def readfontmap(filenames): """ read font map from filename (without path) """ fontmap = {} for filename in filenames: with config.open(filename, [config.format.fontmap, config.format.dvips_config], ascii=True) as mapfile: lineno = 0 for line in mapfile.readlines(): lineno += 1 line = line.rstrip() if not (line=="" or line[0] in (" ", "%", "*", ";" , "#")): try: fm = MAPline(line) except (ParseError, UnsupportedPSFragment) as e: logger.warning("Ignoring line %i in mapping file '%s': %s" % (lineno, filename, e)) except UnsupportedFontFormat as e: pass else: fontmap[fm.texname] = fm return fontmap
def definefont(self, cmdnr, num, c, q, d, fontname): # cmdnr: type of fontdef command (only used for debugging output) # c: checksum # q: scaling factor (fix_word) # Note that q is actually s in large parts of the documentation. # d: design size (fix_word) # check whether it's a virtual font by trying to open it. if this fails, it is an ordinary TeX font try: with config.open(fontname, [config.format.vf]) as fontfile: afont = texfont.virtualfont(fontname, fontfile, c, q / self.tfmconv, d / self.tfmconv, self.tfmconv, self.pyxconv, self.debug > 1) except EnvironmentError: afont = texfont.TeXfont(fontname, c, q / self.tfmconv, d / self.tfmconv, self.tfmconv, self.pyxconv, self.debug > 1) self.fonts[num] = afont if self.debug: self.debugfile.write("%d: fntdef%d %i: %s\n" % (self.filepos, cmdnr, num, fontname))
def __init__(self, file, scale, tfmconv, pyxconv, debug=0): self.scale = scale self.tfmconv = tfmconv self.pyxconv = pyxconv self.debug = debug self.fonts = {} # used fonts self.widths = {} # widths of defined chars self.chardefs = {} # dvi chunks for defined chars afile = reader.bytesreader(file.read()) cmd = afile.readuchar() if cmd == _VF_PRE: if afile.readuchar() != _VF_ID: raise VFError comment = afile.read(afile.readuchar()) self.cs = afile.readuint32() self.ds = afile.readuint32() else: raise VFError while True: cmd = afile.readuchar() if cmd >= _VF_FNTDEF1234 and cmd < _VF_FNTDEF1234 + 4: # font definition if cmd == _VF_FNTDEF1234: num = afile.readuchar() elif cmd == _VF_FNTDEF1234 + 1: num = afile.readuint16() elif cmd == _VF_FNTDEF1234 + 2: num = afile.readuint24() elif cmd == _VF_FNTDEF1234 + 3: num = afile.readint32() c = afile.readint32() s = afile.readint32( ) # relative scaling used for font (fix_word) d = afile.readint32() # design size of font fontname = afile.read(afile.readuchar() + afile.readuchar()).decode("ascii") # rescaled size of font: s is relative to the scaling # of the virtual font itself. Note that realscale has # to be a fix_word (like s) # XXX: check rounding reals = int(round(self.scale * (16 * self.ds / 16777216) * s)) # print ("defining font %s -- VF scale: %g, VF design size: %d, relative font size: %d => real size: %d" % # (fontname, self.scale, self.ds, s, reals) # ) from pyx import config from . import texfont try: with config.open(fontname, [config.format.vf]) as fontfile: self.fonts[num] = texfont.virtualfont( fontname, fontfile, c, reals, d, self.tfmconv, self.pyxconv, self.debug > 1) except EnvironmentError: self.fonts[num] = texfont.TeXfont(fontname, c, reals, d, self.tfmconv, self.pyxconv, self.debug > 1) elif cmd == _VF_LONG_CHAR: # character packet (long form) pl = afile.readuint32() # packet length cc = afile.readuint32( ) # char code (assumed unsigned, but anyhow only 0 <= cc < 255 is actually used) tfm = afile.readuint24() # character width dvi = afile.read(pl) # dvi code of character self.widths[cc] = tfm self.chardefs[cc] = dvi elif cmd < _VF_LONG_CHAR: # character packet (short form) cc = afile.readuchar() # char code tfm = afile.readuint24() # character width dvi = afile.read(cmd) self.widths[cc] = tfm self.chardefs[cc] = dvi elif cmd == _VF_POST: break else: raise VFError
import sys sys.path.insert(0, "../..") from pyx import * from pyx.config import open, format from pyx.font import T1font from pyx.font.t1file import from_PF_bytes from pyx.font.afmfile import AFMfile f = T1font(from_PF_bytes(open("cmr10", [format.type1]).read()), AFMfile(open("cmr10", [format.afm], ascii=True))) c = canvas.canvas() def show(x_pt, y_pt, text, size_pt, **kwargs): t = f.text_pt(x_pt, y_pt, text, size_pt, **kwargs) c.insert(t) c.stroke(t.bbox().rect(), [style.linewidth(0)]) show(0, 0, "Hello, World!", 10) show(0, -30, "Hello, World!", 10, spaced_pt=5) show(0, -60, "Hello, World!", 10, spaced_pt=10) show(0, -90, "Hello, World!", 10, kerning=True) show(200, 0, "Hello, World!", 25) show(200, -30, "Hello, World!", 25, spaced_pt=5) show(200, -60, "Hello, World!", 25, spaced_pt=10) show(200, -90, "Hello, World!", 25, kerning=True)
import sys; sys.path.insert(0, "../..") from pyx import * from pyx.config import open, format from pyx.font import T1font from pyx.font.t1file import from_PF_bytes from pyx.font.afmfile import AFMfile f = T1font(from_PF_bytes(open("cmr10", [format.type1]).read()), AFMfile(open("cmr10", [format.afm], ascii=True))) c = canvas.canvas() def show(x_pt, y_pt, text, size_pt, **kwargs): t = f.text_pt(x_pt, y_pt, text, size_pt, **kwargs) c.insert(t) c.stroke(t.bbox().rect(), [style.linewidth(0)]) show(0, 0, "Hello, World!", 10) show(0, -30, "Hello, World!", 10, spaced_pt=5) show(0, -60, "Hello, World!", 10, spaced_pt=10) show(0, -90, "Hello, World!", 10, kerning=True) show(200, 0, "Hello, World!", 25) show(200, -30, "Hello, World!", 25, spaced_pt=5) show(200, -60, "Hello, World!", 25, spaced_pt=10) show(200, -90, "Hello, World!", 25, kerning=True) c.writeEPSfile() c.writeEPSfile("font_direct_text_as_path", write_text_as_path=True) c.writePDFfile(write_compress=False)
def __init__(self, file, scale, tfmconv, pyxconv, debug=0): self.scale = scale self.tfmconv = tfmconv self.pyxconv = pyxconv self.debug = debug self.fonts = {} # used fonts self.widths = {} # widths of defined chars self.chardefs = {} # dvi chunks for defined chars afile = reader.bytesreader(file.read()) cmd = afile.readuchar() if cmd == _VF_PRE: if afile.readuchar() != _VF_ID: raise VFError comment = afile.read(afile.readuchar()) self.cs = afile.readuint32() self.ds = afile.readuint32() else: raise VFError while True: cmd = afile.readuchar() if cmd >= _VF_FNTDEF1234 and cmd < _VF_FNTDEF1234 + 4: # font definition if cmd == _VF_FNTDEF1234: num = afile.readuchar() elif cmd == _VF_FNTDEF1234+1: num = afile.readuint16() elif cmd == _VF_FNTDEF1234+2: num = afile.readuint24() elif cmd == _VF_FNTDEF1234+3: num = afile.readint32() c = afile.readint32() s = afile.readint32() # relative scaling used for font (fix_word) d = afile.readint32() # design size of font fontname = afile.read(afile.readuchar() + afile.readuchar()).decode("ascii") # rescaled size of font: s is relative to the scaling # of the virtual font itself. Note that realscale has # to be a fix_word (like s) # XXX: check rounding reals = int(round(self.scale * (16*self.ds/16777216) * s)) # print ("defining font %s -- VF scale: %g, VF design size: %d, relative font size: %d => real size: %d" % # (fontname, self.scale, self.ds, s, reals) # ) from pyx import config from . import texfont try: with config.open(fontname, [config.format.vf]) as fontfile: self.fonts[num] = texfont.virtualfont(fontname, fontfile, c, reals, d, self.tfmconv, self.pyxconv, self.debug>1) except EnvironmentError: self.fonts[num] = texfont.TeXfont(fontname, c, reals, d, self.tfmconv, self.pyxconv, self.debug>1) elif cmd == _VF_LONG_CHAR: # character packet (long form) pl = afile.readuint32() # packet length cc = afile.readuint32() # char code (assumed unsigned, but anyhow only 0 <= cc < 255 is actually used) tfm = afile.readuint24() # character width dvi = afile.read(pl) # dvi code of character self.widths[cc] = tfm self.chardefs[cc] = dvi elif cmd < _VF_LONG_CHAR: # character packet (short form) cc = afile.readuchar() # char code tfm = afile.readuint24() # character width dvi = afile.read(cmd) self.widths[cc] = tfm self.chardefs[cc] = dvi elif cmd == _VF_POST: break else: raise VFError