2828from .flowable import Flowable , FlowableStyle , FlowableState , FlowableWidth
2929from .font import MissingGlyphException
3030from .hyphenator import Hyphenator
31- from .inline import InlineFlowableException
31+ from .inline import InlineFlowable , InlineFlowableException
3232from .layout import EndOfContainer , ContainerOverflow
3333from .number import NumberStyle , Label , format_number
3434from .strings import StringField
@@ -427,21 +427,29 @@ def lig_kern(chars, glyph_metrics=None):
427427 return get_glyph_metrics , lig_kern
428428
429429
430+ FALLBACK_STYLE = '_fallback_'
431+
432+
430433def handle_missing_glyphs (span , container ):
434+ if isinstance (span , InlineFlowable ):
435+ yield span
436+ return
431437 get_glyph , _ = create_lig_kern (span , container )
432438 string = []
433439 for char in span .text (container ):
434440 try :
435- get_glyph (char )
441+ if char not in '\n \t ' :
442+ get_glyph (char )
436443 string .append (char )
437444 except MissingGlyphException :
438445 if string :
439446 yield SingleStyledText ('' .join (string ), parent = span )
440447 string .clear ()
441- if span .parent .style == '_fallback_' :
448+ if span .parent .style == FALLBACK_STYLE :
442449 yield SingleStyledText ('?' , parent = span )
443450 else :
444- yield SingleStyledText (char , style = '_fallback_' , parent = span )
451+ fallback_span = SingleStyledText (char , style = FALLBACK_STYLE , parent = span )
452+ yield from handle_missing_glyphs (fallback_span , container )
445453 if string :
446454 yield SingleStyledText ('' .join (string ), parent = span )
447455
@@ -563,8 +571,10 @@ def next_word(self, container):
563571 else :
564572 if not self ._words :
565573 spans = self .paragraph .text (container ).wrapped_spans (container )
566- for _ in islice (spans , 0 , self .span_index ): pass
567- self ._words = self ._spans_to_words (spans )
574+ fixed_spans = (fixed_span for span in spans
575+ for fixed_span in handle_missing_glyphs (span , container ))
576+ for _ in islice (fixed_spans , 0 , self .span_index ): pass
577+ self ._words = self ._spans_to_words (fixed_spans )
568578 word = self ._words .send (container )
569579 return word
570580
@@ -574,22 +584,16 @@ def next_word(self, container):
574584 def _spans_to_words (self , spans ):
575585 # FIXME: this is an incomprehensible mess; refactor (with next_word)
576586 # There's a lot going on here: missing glyphs fallback, footnotes, ...
577- missing_glyphs_spans = None
587+ # e.g. first split spans into smaller spans if missing glyphs are encountered
578588 container = yield
579589 word = Word ()
580590 self .span_index -= 1
581591 while True :
582- if missing_glyphs_spans :
583- try :
584- span = next (missing_glyphs_spans )
585- except StopIteration :
586- missing_glyphs_spans = None
587- if not missing_glyphs_spans :
588- try :
589- span = next (spans )
590- self .span_index += 1
591- except StopIteration :
592- break
592+ try :
593+ span = next (spans )
594+ self .span_index += 1
595+ except StopIteration :
596+ break
593597 try :
594598 no_break_after = span .get_style ('no_break_after' , container )
595599 except KeyError : # InlineFlowable
@@ -626,15 +630,7 @@ def _spans_to_words(self, spans):
626630 if word and word [- 1 ].span is span :
627631 prev_glyphs_span = word .pop ()
628632 part = str (prev_glyphs_span ) + part
629- try :
630- glyphs = [get_glyph_metrics (char ) for char in part ]
631- except MissingGlyphException :
632- # FIXME: span annotations are lost here
633- rest = '' .join (char for _ , group in groups
634- for char in group )
635- rest_of_span = SingleStyledText (part + rest , parent = span )
636- missing_glyphs_spans = handle_missing_glyphs (rest_of_span , container )
637- break
633+ glyphs = [get_glyph_metrics (char ) for char in part ]
638634 glyphs = lig_kern (part , glyphs )
639635 glyphs_span = GlyphsSpan (span , lig_kern , glyphs )
640636 word .append (glyphs_span )
0 commit comments