1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
use crate::parser::{Stream, LazyArray};
use crate::{Font, TableName, GlyphId, HorizontalMetrics, Result, Error};
impl<'a> Font<'a> {
    
    pub fn glyph_hor_metrics(&self, glyph_id: GlyphId) -> Result<HorizontalMetrics> {
        self.check_glyph_id(glyph_id)?;
        let data = self.hmtx.ok_or_else(|| Error::TableMissing(TableName::HorizontalMetrics))?;
        let mut s = Stream::new(data);
        let number_of_hmetrics = self.number_of_hmetrics();
        if number_of_hmetrics == 0 {
            return Err(Error::NoHorizontalMetrics);
        }
        let glyph_id = glyph_id.0;
        let array: LazyArray<HorizontalMetrics> = s.read_array(number_of_hmetrics)?;
        if let Some(metrics) = array.get(glyph_id) {
            Ok(metrics)
        } else {
            
            
            
            
            if self.number_of_glyphs() < number_of_hmetrics {
                return Err(Error::NoHorizontalMetrics);
            }
            let count = self.number_of_glyphs() - number_of_hmetrics;
            let left_side_bearings: LazyArray<i16> = s.read_array(count)?;
            let left_side_bearing = left_side_bearings.get(glyph_id)
                .ok_or_else(|| Error::NoHorizontalMetrics)?;
            
            
            
            let last_metric = array.last().ok_or_else(|| Error::NoHorizontalMetrics)?;
            Ok(HorizontalMetrics {
                advance: last_metric.advance,
                left_side_bearing,
            })
        }
    }
}