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
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//! The [OS/2 and Windows metrics][1].
//!
//! [1]: https://www.microsoft.com/typography/otspec/os2.htm

use {Result, Tape, Value};

/// OS/2 and Windows metrics.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum WindowsMetrics {
    /// Version 3.
    Version3(WindowsMetrics3),
    /// Version 5.
    Version5(WindowsMetrics5),
}

table! {
    #[doc = "OS/2 and Windows metrics of version 3."]
    pub WindowsMetrics3 {
        version               (u16           ), // version
        average_char_width    (i16           ), // xAvgCharWidth
        weight_class          (u16           ), // usWeightClass
        width_class           (u16           ), // usWidthClass
        type_flags            (TypeFlags     ), // fsType
        subscript_x_size      (i16           ), // ySubscriptXSize
        subscript_y_size      (i16           ), // ySubscriptYSize
        subscript_x_offset    (i16           ), // ySubscriptXOffset
        subscript_y_offset    (i16           ), // ySubscriptYOffset
        superscript_x_size    (i16           ), // ySuperscriptXSize
        superscript_y_size    (i16           ), // ySuperscriptYSize
        superscript_x_offset  (i16           ), // ySuperscriptXOffset
        superscript_y_offset  (i16           ), // ySuperscriptYOffset
        strikeout_size        (i16           ), // yStrikeoutSize
        strikeout_position    (i16           ), // yStrikeoutPosition
        family_class          (i16           ), // sFamilyClass
        panose                ([u8; 10]      ), // panose
        unicode_range1        (u32           ), // ulUnicodeRange1
        unicode_range2        (u32           ), // ulUnicodeRange2
        unicode_range3        (u32           ), // ulUnicodeRange3
        unicode_range4        (u32           ), // ulUnicodeRange4
        vendor_id             ([i8; 4]       ), // achVendID
        selection_flags       (SelectionFlags), // fsSelection
        first_char_index      (u16           ), // usFirstCharIndex
        last_char_index       (u16           ), // usLastCharIndex
        typographic_ascender  (i16           ), // sTypoAscender
        typographic_descender (i16           ), // sTypoDescender
        typographic_line_gap  (i16           ), // sTypoLineGap
        windows_ascender      (u16           ), // usWinAscent
        windows_descender     (u16           ), // usWinDescent
        code_page_range1      (u32           ), // ulCodePageRange1
        code_page_range2      (u32           ), // ulCodePageRange2
        x_height              (i16           ), // sxHeight
        cap_height            (i16           ), // sCapHeight
        default_char          (u16           ), // usDefaultChar
        break_char            (u16           ), // usBreakChar
        max_context           (u16           ), // usMaxContext
    }
}

table! {
    #[doc = "OS/2 and Windows metrics of version 5."]
    pub WindowsMetrics5 {
        version               (u16           ), // version
        average_char_width    (i16           ), // xAvgCharWidth
        weight_class          (u16           ), // usWeightClass
        width_class           (u16           ), // usWidthClass
        type_flags            (TypeFlags     ), // fsType
        subscript_x_size      (i16           ), // ySubscriptXSize
        subscript_y_size      (i16           ), // ySubscriptYSize
        subscript_x_offset    (i16           ), // ySubscriptXOffset
        subscript_y_offset    (i16           ), // ySubscriptYOffset
        superscript_x_size    (i16           ), // ySuperscriptXSize
        superscript_y_size    (i16           ), // ySuperscriptYSize
        superscript_x_offset  (i16           ), // ySuperscriptXOffset
        superscript_y_offset  (i16           ), // ySuperscriptYOffset
        strikeout_size        (i16           ), // yStrikeoutSize
        strikeout_position    (i16           ), // yStrikeoutPosition
        family_class          (i16           ), // sFamilyClass
        panose                ([u8; 10]      ), // panose
        unicode_range1        (u32           ), // ulUnicodeRange1
        unicode_range2        (u32           ), // ulUnicodeRange2
        unicode_range3        (u32           ), // ulUnicodeRange3
        unicode_range4        (u32           ), // ulUnicodeRange4
        vendor_id             ([i8; 4]       ), // achVendID
        selection_flags       (SelectionFlags), // fsSelection
        first_char_index      (u16           ), // usFirstCharIndex
        last_char_index       (u16           ), // usLastCharIndex
        typographic_ascender  (i16           ), // sTypoAscender
        typographic_descender (i16           ), // sTypoDescender
        typographic_line_gap  (i16           ), // sTypoLineGap
        windows_ascender      (u16           ), // usWinAscent
        windows_descender     (u16           ), // usWinDescent
        code_page_range1      (u32           ), // ulCodePageRange1
        code_page_range2      (u32           ), // ulCodePageRange2
        x_height              (i16           ), // sxHeight
        cap_height            (i16           ), // sCapHeight
        default_char          (u16           ), // usDefaultChar
        break_char            (u16           ), // usBreakChar
        max_context           (u16           ), // usMaxContext

        lower_optical_point_size (u16), // usLowerOpticalPointSize
        upper_optical_point_size (u16), // usUpperOpticalPointSize
    }
}

flags! {
    #[doc = "Type flags."]
    pub TypeFlags(u16) {
        0b1111_1100_0000_0000 => is_invalid,
    }
}

flags! {
    #[doc = "Font-selection flags."]
    pub SelectionFlags(u16) {
        0b1111_1100_0000_0000 => is_invalid,
    }
}

impl Value for WindowsMetrics {
    fn read<T: Tape>(tape: &mut T) -> Result<Self> {
        Ok(match try!(tape.peek::<u16>()) {
            3 => WindowsMetrics::Version3(try!(tape.take())),
            5 => WindowsMetrics::Version5(try!(tape.take())),
            _ => raise!("found an unknown format of the OS/2 and Windows metrics"),
        })
    }
}