@@ -956,7 +956,7 @@ impl EmittingState {
956956 }
957957
958958 /// Figure out if we need to push a space into the text content right now.
959- fn is_space_needed ( & mut self , x0 : i32 , cur_font_num : Option < FontNum > ) -> bool {
959+ fn is_space_needed ( & self , x0 : i32 , cur_font_num : Option < FontNum > ) -> bool {
960960 // We never want a leading space.
961961 if self . current_content . is_empty ( ) {
962962 return false ;
@@ -1554,19 +1554,100 @@ impl EmittingState {
15541554 } ) ;
15551555 }
15561556 } else {
1557+ // Ideally, the vast majority of the time we are using
1558+ // handle_text_and_glyphs and not this function, outside of
1559+ // canvases. But sometimes we get spare glyphs outside of the canvas
1560+ // context. We can use our glyph-mapping infrastructure to try to
1561+ // translate them to Unicode, hoping for the best that the naive
1562+ // inversion suffices.
1563+
15571564 self . set_up_for_font ( xs[ 0 ] , font_num, common) ;
15581565
15591566 let fi = a_ok_or ! (
15601567 self . fonts. get( & font_num) ;
15611568 [ "undeclared font {} in glyph run" , font_num]
15621569 ) ;
15631570
1564- tt_warning ! (
1565- common. status,
1566- "TODO HANDLE glyph_run OUTSIDE OF CANVAS: {} {:?}" ,
1567- fi. rel_url,
1568- glyphs
1569- ) ;
1571+ // Super lame! Ideally we could just hold a long-lived mutable
1572+ // borrow of `fd`, but that gets treated as a long-lived mutable
1573+ // borrow of `self` which basically makes all other pieces of state
1574+ // inaccessible. So we need to keep on looking up into
1575+ // `self.font_data`, and even then we need to avoid functions that
1576+ // operation on `&mut self` because `fi` is a long-lived *immutable*
1577+ // borrow of `self`. I don't think we can avoid this without doing
1578+ // some significant rearranging of the data structures to allow the
1579+ // different pieces to be borrowed separately.
1580+
1581+ let mut ch_str_buf = [ 0u8 ; 4 ] ;
1582+
1583+ for ( idx, glyph) in glyphs. iter ( ) . copied ( ) . enumerate ( ) {
1584+ let mc = {
1585+ let fd = self . font_data . get ( & fi. fd_key ) . unwrap ( ) ;
1586+ fd. lookup_mapping ( glyph)
1587+ } ;
1588+
1589+ if let Some ( mc) = mc {
1590+ let ( mut ch, need_alt) = match mc {
1591+ MapEntry :: Direct ( c) => ( c, false ) ,
1592+ MapEntry :: SubSuperScript ( c, _) => ( c, true ) ,
1593+ MapEntry :: MathGrowingVariant ( c, _, _) => ( c, true ) ,
1594+ } ;
1595+
1596+ let alt_index = if need_alt {
1597+ let fd = self . font_data . get_mut ( & fi. fd_key ) . unwrap ( ) ;
1598+ let map = fd. request_alternative ( glyph, ch) ;
1599+ ch = map. usv ;
1600+ Some ( map. alternate_map_index )
1601+ } else {
1602+ None
1603+ } ;
1604+
1605+ // For later: we could select the "default" font at an outer
1606+ // level and only emit tags as needed in here.
1607+ let font_sel = fi. selection_style_text ( alt_index) ;
1608+
1609+ // Stringify the character so that we can use html_escape in
1610+ // case it's a `<` or whatever.
1611+ let ch_as_str = ch. encode_utf8 ( & mut ch_str_buf) ;
1612+
1613+ // XXX this is (part of) push_space_if_needed
1614+ if self . is_space_needed ( xs[ idx] , Some ( font_num) ) {
1615+ self . current_content . push ( ' ' ) ;
1616+ }
1617+
1618+ write ! ( self . current_content, "<span style=\" {}\" >" , font_sel) . unwrap ( ) ;
1619+ html_escape:: encode_text_to_string ( ch_as_str, & mut self . current_content ) ;
1620+ write ! ( self . current_content, "</span>" ) . unwrap ( ) ;
1621+ } else {
1622+ tt_warning ! (
1623+ common. status,
1624+ "unable to reverse-map glyph {} in font `{}` (face {})" ,
1625+ glyph,
1626+ fi. rel_url,
1627+ fi. face_index
1628+ ) ;
1629+ }
1630+
1631+ // Jump through the hoops needed by automatic space insertion:
1632+
1633+ let gm = {
1634+ let fd = self . font_data . get ( & fi. fd_key ) . unwrap ( ) ;
1635+ fd. lookup_metrics ( glyphs[ idx] , fi. size )
1636+ } ;
1637+
1638+ let advance = match gm {
1639+ Some ( gm) => gm. advance ,
1640+ None => 0 ,
1641+ } ;
1642+
1643+ // XXX this is fn update_content_pos():
1644+ self . last_content_x = xs[ idx] + advance;
1645+
1646+ let cur_space_width = self . maybe_get_font_space_width ( Some ( font_num) ) ;
1647+ if cur_space_width. is_some ( ) {
1648+ self . last_content_space_width = cur_space_width;
1649+ }
1650+ }
15701651 }
15711652
15721653 Ok ( ( ) )
0 commit comments