@@ -230,6 +230,7 @@ def __init__(self, filename, dpi):
230
230
self .dpi = dpi
231
231
self .fonts = {}
232
232
self .state = _dvistate .pre
233
+ self ._missing_font = None
233
234
234
235
def __enter__ (self ):
235
236
"""Context manager enter method, does nothing."""
@@ -337,6 +338,8 @@ def _read(self):
337
338
while True :
338
339
byte = self .file .read (1 )[0 ]
339
340
self ._dtable [byte ](self , byte )
341
+ if self ._missing_font :
342
+ raise self ._missing_font
340
343
name = self ._dtable [byte ].__name__
341
344
if name == "_push" :
342
345
down_stack .append (down_stack [- 1 ])
@@ -364,11 +367,15 @@ def _arg(self, nbytes, signed=False):
364
367
@_dispatch (min = 0 , max = 127 , state = _dvistate .inpage )
365
368
def _set_char_immediate (self , char ):
366
369
self ._put_char_real (char )
370
+ if isinstance (self .fonts [self .f ], FileNotFoundError ):
371
+ return
367
372
self .h += self .fonts [self .f ]._width_of (char )
368
373
369
374
@_dispatch (min = 128 , max = 131 , state = _dvistate .inpage , args = ('olen1' ,))
370
375
def _set_char (self , char ):
371
376
self ._put_char_real (char )
377
+ if isinstance (self .fonts [self .f ], FileNotFoundError ):
378
+ return
372
379
self .h += self .fonts [self .f ]._width_of (char )
373
380
374
381
@_dispatch (132 , state = _dvistate .inpage , args = ('s4' , 's4' ))
@@ -382,7 +389,9 @@ def _put_char(self, char):
382
389
383
390
def _put_char_real (self , char ):
384
391
font = self .fonts [self .f ]
385
- if font ._vf is None :
392
+ if isinstance (font , FileNotFoundError ):
393
+ self ._missing_font = font
394
+ elif font ._vf is None :
386
395
self .text .append (Text (self .h , self .v , font , char ,
387
396
font ._width_of (char )))
388
397
else :
@@ -486,7 +495,16 @@ def _fnt_def(self, k, c, s, d, a, l):
486
495
def _fnt_def_real (self , k , c , s , d , a , l ):
487
496
n = self .file .read (a + l )
488
497
fontname = n [- l :].decode ('ascii' )
489
- tfm = _tfmfile (fontname )
498
+ try :
499
+ tfm = _tfmfile (fontname )
500
+ except FileNotFoundError as exc :
501
+ # Explicitly allow defining missing fonts for Vf support; we only
502
+ # register an error when trying to load a glyph from a missing font
503
+ # and throw that error in Dvi._read. For Vf, _finalize_packet
504
+ # checks whether a missing glyph has been used, and in that case
505
+ # skips the glyph definition.
506
+ self .fonts [k ] = exc
507
+ return
490
508
if c != 0 and tfm .checksum != 0 and c != tfm .checksum :
491
509
raise ValueError ('tfm checksum mismatch: %s' % n )
492
510
try :
@@ -712,12 +730,14 @@ def _init_packet(self, pl):
712
730
self .h , self .v , self .w , self .x , self .y , self .z = 0 , 0 , 0 , 0 , 0 , 0
713
731
self .stack , self .text , self .boxes = [], [], []
714
732
self .f = self ._first_font
733
+ self ._missing_font = None
715
734
return self .file .tell () + pl
716
735
717
736
def _finalize_packet (self , packet_char , packet_width ):
718
- self ._chars [packet_char ] = Page (
719
- text = self .text , boxes = self .boxes , width = packet_width ,
720
- height = None , descent = None )
737
+ if not self ._missing_font : # Otherwise we don't have full glyph definition.
738
+ self ._chars [packet_char ] = Page (
739
+ text = self .text , boxes = self .boxes , width = packet_width ,
740
+ height = None , descent = None )
721
741
self .state = _dvistate .outer
722
742
723
743
def _pre (self , i , x , cs , ds ):
0 commit comments