use bitflags::bitflags;
use otspec::types::*;
use otspec::Deserializer;
use otspec_macros::{tables, Deserialize, Serialize};
use std::collections::HashMap;
tables!(
ScriptListInternal {
[offset_base]
Counted(ScriptRecord) scriptRecords
}
ScriptRecord {
Tag scriptTag
Offset16(ScriptInternal) scriptOffset
}
ScriptInternal {
[offset_base]
Offset16(LangSys) defaultLangSys
Counted(LangSysRecord) langSysRecords
}
LangSysRecord {
Tag langSysTag
Offset16(LangSys) langSys
}
LangSys {
uint16 lookupOrderOffset uint16 requiredFeatureIndex
Counted(uint16) featureIndices
}
FeatureList {
[offset_base]
Counted(FeatureRecord) featureRecords
}
FeatureRecord {
Tag featureTag
Offset16(FeatureTable) feature
}
FeatureTable {
uint16 featureParamsOffset
Counted(uint16) lookupListIndices
}
LookupList {
[offset_base]
Counted(uint16) lookupOffsets
}
Lookup {
uint16 lookupType
LookupFlags lookupFlag
Counted(uint16) subtableOffsets
}
cvFeatureParams {
uint16 format
uint16 featUiLabelNameId
uint16 featUiTooltipTextNameId
uint16 sampleTextNameId
uint16 numNamedParameters
uint16 firstParamUiLabelNameId
}
sizeFeatureParams {
uint16 designSize
uint16 subfamilyIdentifier
uint16 subfamilyNameID
uint16 smallest
uint16 largest
}
);
#[derive(Debug, PartialEq)]
pub enum FeatureParams {
StylisticSet(uint16, uint16),
SizeFeature(sizeFeatureParams),
CharacterVariant(cvFeatureParams),
}
bitflags! {
#[derive(Serialize, Deserialize)]
pub struct LookupFlags: u16 {
const RIGHT_TO_LEFT = 0x0001;
const IGNORE_BASE_GLYPHS = 0x0002;
const IGNORE_LIGATURES = 0x0004;
const IGNORE_MARKS = 0x0008;
const USE_MARK_FILTERING_SET = 0x0010;
const MARK_ATTACHMENT_TYPE_MASK = 0xFF00;
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct ScriptList {
pub scripts: HashMap<Tag, Script>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct Script {
pub default_language_system: Option<LanguageSystem>,
pub language_systems: HashMap<Tag, LanguageSystem>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct LanguageSystem {
pub required_feature: Option<usize>,
pub feature_indices: Vec<usize>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_scriptlist_internal() {
let binary_scriptlist = vec![
0x00, 0x02, 0x61, 0x72, 0x61, 0x62, 0x00, 0x0E, 0x6C, 0x61, 0x74, 0x6E, 0x00, 0x40,
0x00, 0x0A, 0x00, 0x01, 0x55, 0x52, 0x44, 0x20, 0x00, 0x1E, 0x00, 0x00, 0xFF, 0xFF,
0x00, 0x07, 0x00, 0x01, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07,
0x00, 0x08, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x00, 0x07, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06,
0x00, 0x07, 0x00, 0x08,
];
let deserialized: ScriptListInternal = otspec::de::from_bytes(&binary_scriptlist).unwrap();
println!("Script list {:?}", deserialized);
}
}