@@ -352,10 +352,40 @@ def _read(self):
352352 Read one page from the file. Return True if successful,
353353 False if there were no more pages.
354354 """
355+ # Pages appear to start with the sequence
356+ # bop (begin of page)
357+ # xxx comment
358+ # <push, ..., pop> # if using chemformula
359+ # down
360+ # push
361+ # down
362+ # <push, push, xxx, right, xxx, pop, pop> # if using xcolor
363+ # down
364+ # push
365+ # down (possibly multiple)
366+ # push <= here, v is the baseline position.
367+ # etc.
368+ # (dviasm is useful to explore this structure.)
369+ # Thus, we use the vertical position at the first time the stack depth
370+ # reaches 3, while at least three "downs" have been executed (excluding
371+ # those popped out (corresponding to the chemformula preamble)), as the
372+ # baseline (the "down" count is necessary to handle xcolor).
373+ down_stack = [0 ]
355374 self ._baseline_v = None
356375 while True :
357376 byte = self .file .read (1 )[0 ]
358377 self ._dtable [byte ](self , byte )
378+ name = self ._dtable [byte ].__name__
379+ if name == "_push" :
380+ down_stack .append (down_stack [- 1 ])
381+ elif name == "_pop" :
382+ down_stack .pop ()
383+ elif name == "_down" :
384+ down_stack [- 1 ] += 1
385+ if (self ._baseline_v is None
386+ and len (getattr (self , "stack" , [])) == 3
387+ and down_stack [- 1 ] >= 4 ):
388+ self ._baseline_v = self .v
359389 if byte == 140 : # end of page
360390 return True
361391 if self .state is _dvistate .post_post : # end of file
@@ -488,8 +518,6 @@ def _fnt_num(self, new_f):
488518 @_dispatch (min = 239 , max = 242 , args = ('ulen1' ,))
489519 def _xxx (self , datalen ):
490520 special = self .file .read (datalen )
491- if special == b'matplotlibbaselinemarker' :
492- self ._baseline_v = self .v
493521 _log .debug (
494522 'Dvi._xxx: encountered special: %s' ,
495523 '' .join ([chr (ch ) if 32 <= ch < 127 else '<%02x>' % ch
0 commit comments