// Copyright 2026 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
pub struct AvarMapping {
from_raw : Int
to_raw : Int
} derive(Eq, Show, ToJson)
///|
pub struct AvarSegmentMap {
mappings : Array[AvarMapping]
} derive(Eq, Show, ToJson)
///|
pub struct AvarTable {
axes : Array[AvarSegmentMap]
} derive(Eq, Show, ToJson)
///|
pub fn AvarTable::axis_count(self : AvarTable) -> Int {
self.axes.length()
}
///|
pub fn AvarTable::map_coords_16_16(self : AvarTable, coords : Array[Int]) -> Array[Int] {
let out = coords.copy()
let count = if out.length() < self.axes.length() { out.length() } else { self.axes.length() }
for i in 0.. Double {
if self.mappings.length() == 0 {
return value
}
if self.mappings.length() == 1 {
let only = self.mappings[0]
let from = f2dot14_to_double(only.from_raw)
let to = f2dot14_to_double(only.to_raw)
return value - from + to
}
for mapping in self.mappings {
let from = f2dot14_to_double(mapping.from_raw)
if value == from {
return f2dot14_to_double(mapping.to_raw)
}
}
let first = self.mappings[0]
let first_from = f2dot14_to_double(first.from_raw)
let first_to = f2dot14_to_double(first.to_raw)
if value < first_from {
return value - first_from + first_to
}
let last_idx = self.mappings.length() - 1
let last = self.mappings[last_idx]
let last_from = f2dot14_to_double(last.from_raw)
let last_to = f2dot14_to_double(last.to_raw)
if value > last_from {
return value - last_from + last_to
}
for i in 1.. Result[AvarTable, VarError] {
let version = read_u32(data, 0)
let axis_count = read_u16_int(data, 6)
match (version, axis_count) {
(Err(err), _) => Err(err)
(_, Err(err)) => Err(err)
(Ok(version), Ok(axis_count)) => {
let major = (version >> 16) & 0xFFFFU
if major < 1U || major > 2U {
return Err(InvalidFormat)
}
let mut offset = 8
let axes : Array[AvarSegmentMap] = []
for _ in 0.. return Err(err)
Ok(segment_count) => {
offset = offset + 2
let mappings : Array[AvarMapping] = []
for _ in 0.. return Err(err)
(_, Err(err)) => return Err(err)
(Ok(from_raw), Ok(to_raw)) => mappings.push(AvarMapping::{ from_raw, to_raw })
}
offset = offset + 4
}
mappings.sort_by((a, b) => a.from_raw - b.from_raw)
axes.push(AvarSegmentMap::{ mappings })
}
}
}
Ok(AvarTable::{ axes })
}
}
}