// 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 VarcTable {
version : Int
coverage_offset : Int
var_store_offset : Int
condition_list_offset : Int
axis_indices_offset : Int
glyph_records_offset : Int
data : Bytes
} derive(Show, ToJson)
///|
pub enum VarcCondition {
AxisRange(Int, Int, Int)
Value(Int, Int)
And(Array[VarcCondition])
Or(Array[VarcCondition])
Not(VarcCondition)
} derive(Show, ToJson)
struct CffIndex {
count : Int
off_size : Int
offsets : Array[Int]
data : Bytes
} derive(Show, ToJson)
fn validate_offset(offset : Int, length : Int) -> Result[Unit, VarError] {
if offset < 0 || offset > length {
return Err(UnexpectedEof)
}
Ok(())
}
fn parse_condition_at(
data : BytesView,
base : Int,
offset : Int,
depth : Int,
) -> Result[VarcCondition, VarError] {
if depth > 32 {
return Err(InvalidFormat)
}
if offset <= 0 {
return Err(InvalidFormat)
}
let pos = base + offset
if pos < 0 || pos + 2 > data.length() {
return Err(UnexpectedEof)
}
let format = read_u16_int(data, pos)
match format {
Err(err) => Err(err)
Ok(format) => {
if format == 1 {
let axis_index = read_u16_int(data, pos + 2)
let min_value = read_i16(data, pos + 4)
let max_value = read_i16(data, pos + 6)
match (axis_index, min_value, max_value) {
(Err(err), _, _) => Err(err)
(_, Err(err), _) => Err(err)
(_, _, Err(err)) => Err(err)
(Ok(axis_index), Ok(min_value), Ok(max_value)) =>
Ok(VarcCondition::AxisRange(axis_index, min_value, max_value))
}
} else if format == 2 {
let default_value = read_i16(data, pos + 2)
let var_idx = read_u32_int(data, pos + 4)
match (default_value, var_idx) {
(Err(err), _) => Err(err)
(_, Err(err)) => Err(err)
(Ok(default_value), Ok(var_idx)) =>
Ok(VarcCondition::Value(default_value, var_idx))
}
} else if format == 3 || format == 4 {
let count = read_u8_int(data, pos + 2)
match count {
Err(err) => Err(err)
Ok(count) => {
let list_base = pos + 3
let total = count * 3
if list_base < 0 || list_base + total > data.length() {
return Err(UnexpectedEof)
}
let conditions : Array[VarcCondition] = []
for i in 0.. return Err(err)
Ok(child_offset) => {
let child = match parse_condition_at(data, pos, child_offset, depth + 1) {
Err(err) => return Err(err)
Ok(value) => value
}
conditions.push(child)
}
}
}
if format == 3 {
Ok(VarcCondition::And(conditions))
} else {
Ok(VarcCondition::Or(conditions))
}
}
}
} else if format == 5 {
let child_offset = read_cff_offset(data, pos + 2, 3)
match child_offset {
Err(err) => Err(err)
Ok(child_offset) =>
match parse_condition_at(data, pos, child_offset, depth + 1) {
Err(err) => Err(err)
Ok(value) => Ok(VarcCondition::Not(value))
}
}
} else {
Err(InvalidFormat)
}
}
}
}
///|
pub fn VarcCondition::evaluate(
self : VarcCondition,
coords : Array[Int],
var_delta : ((Int) -> Double)?,
) -> Bool {
match self {
AxisRange(axis_index, min_value, max_value) => {
let coord = if axis_index >= 0 && axis_index < coords.length() {
coords[axis_index]
} else {
0
}
min_value <= coord && coord <= max_value
}
Value(default_value, var_idx) => {
let delta = match var_delta {
None => 0.0
Some(f) => f(var_idx)
}
(default_value.to_double() + delta) > 0.0
}
And(conditions) => {
for condition in conditions {
if !condition.evaluate(coords, var_delta) {
return false
}
}
true
}
Or(conditions) => {
for condition in conditions {
if condition.evaluate(coords, var_delta) {
return true
}
}
false
}
Not(condition) => !condition.evaluate(coords, var_delta)
}
}
fn read_cff_offset(data : BytesView, offset : Int, size : Int) -> Result[Int, VarError] {
if size <= 0 || size > 4 {
return Err(InvalidFormat)
}
if offset < 0 || offset + size > data.length() {
return Err(UnexpectedEof)
}
let mut value = 0
for i in 0.. Result[CffIndex, VarError] {
let count = read_u32_int(data, offset)
match count {
Err(err) => Err(err)
Ok(count) => {
if count < 0 {
return Err(InvalidFormat)
}
if count == 0 {
return Ok(CffIndex::{ count: 0, off_size: 0, offsets: [], data: Bytes::from_array([]) })
}
let off_size = read_u8_int(data, offset + 4)
match off_size {
Err(err) => Err(err)
Ok(off_size) => {
if off_size <= 0 || off_size > 4 {
return Err(InvalidFormat)
}
let mut pos = offset + 5
let offsets : Array[Int] = []
for _ in 0..<(count + 1) {
let value = read_cff_offset(data, pos, off_size)
match value {
Err(err) => return Err(err)
Ok(v) => offsets.push(v)
}
pos = pos + off_size
}
let data_start = pos
let last = offsets[offsets.length() - 1]
if last <= 0 {
return Err(InvalidFormat)
}
let data_len = last - 1
if data_len < 0 || data_start + data_len > data.length() {
return Err(UnexpectedEof)
}
let data_bytes = data[data_start:data_start + data_len].to_bytes()
Ok(CffIndex::{ count, off_size, offsets, data: data_bytes })
}
}
}
}
}
fn CffIndex::item_bytes(self : CffIndex, index : Int) -> Result[Bytes, VarError] {
if index < 0 || index >= self.count {
return Err(InvalidFormat)
}
if self.count == 0 {
return Ok(Bytes::from_array([]))
}
let start = self.offsets[index] - 1
let end = self.offsets[index + 1] - 1
if start < 0 || end < start || end > self.data.length() {
return Err(InvalidFormat)
}
Ok(self.data[start:end].to_bytes())
}
fn int8_from_byte_varc(value : Byte) -> Int {
let v = value.to_int()
if v >= 0x80 { v - 0x100 } else { v }
}
fn decode_tuple_values(data : BytesView) -> Result[Array[Int], VarError] {
let values : Array[Int] = []
let mut pos = 0
while pos < data.length() {
let control = data[pos].to_int()
pos = pos + 1
let run_count = (control & 0x3F) + 1
let mode = control & 0xC0
if mode == 0x80 {
for _ in 0.. data.length() {
return Err(UnexpectedEof)
}
for _ in 0.. return Err(err)
Ok(v) => values.push(v)
}
pos = pos + 2
}
} else if mode == 0xC0 {
let needed = run_count * 4
if pos + needed > data.length() {
return Err(UnexpectedEof)
}
for _ in 0.. return Err(err)
Ok(v) => values.push(v)
}
pos = pos + 4
}
} else {
if pos + run_count > data.length() {
return Err(UnexpectedEof)
}
for _ in 0.. Result[(Array[Int], Int), VarError] {
if count < 0 {
return Err(InvalidFormat)
}
let values : Array[Int] = []
let mut pos = 0
while values.length() < count {
if pos >= data.length() {
return Err(UnexpectedEof)
}
let control = data[pos].to_int()
pos = pos + 1
let run_count = (control & 0x3F) + 1
let mode = control & 0xC0
if mode == 0x80 {
for _ in 0.. data.length() {
return Err(UnexpectedEof)
}
for _ in 0.. return Err(err)
Ok(v) => {
if values.length() < count {
values.push(v)
}
}
}
pos = pos + 2
}
} else if mode == 0xC0 {
let needed = run_count * 4
if pos + needed > data.length() {
return Err(UnexpectedEof)
}
for _ in 0.. return Err(err)
Ok(v) => {
if values.length() < count {
values.push(v)
}
}
}
pos = pos + 4
}
} else {
if pos + run_count > data.length() {
return Err(UnexpectedEof)
}
for _ in 0.. Result[(UInt, Int), VarError] {
if offset < 0 || offset >= data.length() {
return Err(UnexpectedEof)
}
let b0 = data[offset].to_uint()
if b0 < 0x80U {
return Ok((b0, 1))
}
if b0 < 0xC0U {
if offset + 2 > data.length() {
return Err(UnexpectedEof)
}
let b1 = data[offset + 1].to_uint()
let value = ((b0 & 0x3FU) << 8) | b1
return Ok((value, 2))
}
if b0 < 0xE0U {
if offset + 3 > data.length() {
return Err(UnexpectedEof)
}
let b1 = data[offset + 1].to_uint()
let b2 = data[offset + 2].to_uint()
let value = ((b0 & 0x1FU) << 16) | (b1 << 8) | b2
return Ok((value, 3))
}
if b0 < 0xF0U {
if offset + 4 > data.length() {
return Err(UnexpectedEof)
}
let b1 = data[offset + 1].to_uint()
let b2 = data[offset + 2].to_uint()
let b3 = data[offset + 3].to_uint()
let value = ((b0 & 0x0FU) << 24) | (b1 << 16) | (b2 << 8) | b3
return Ok((value, 4))
}
if offset + 5 > data.length() {
return Err(UnexpectedEof)
}
let b1 = data[offset + 1].to_uint()
let b2 = data[offset + 2].to_uint()
let b3 = data[offset + 3].to_uint()
let b4 = data[offset + 4].to_uint()
let value = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4
Ok((value, 5))
}
fn coverage_index_varc(
data : BytesView,
offset : Int,
glyph : Int,
) -> Result[Int?, VarError] {
if glyph < 0 || glyph > 0xFFFF {
return Ok(None)
}
let format = read_u16_int(data, offset)
match format {
Err(err) => Err(err)
Ok(format) =>
if format == 1 {
coverage_format1_varc(data, offset, glyph)
} else if format == 2 {
coverage_format2_varc(data, offset, glyph)
} else {
Err(InvalidFormat)
}
}
}
fn coverage_format1_varc(
data : BytesView,
offset : Int,
glyph : Int,
) -> Result[Int?, VarError] {
if offset < 0 || offset + 4 > data.length() {
return Err(UnexpectedEof)
}
let count = read_u16_int(data, offset + 2)
match count {
Err(err) => Err(err)
Ok(count) => {
let list_offset = offset + 4
if list_offset < 0 || list_offset + count * 2 > data.length() {
return Err(UnexpectedEof)
}
for i in 0.. return Err(err)
Ok(value) => if value == glyph { return Ok(Some(i)) }
}
}
Ok(None)
}
}
}
fn coverage_format2_varc(
data : BytesView,
offset : Int,
glyph : Int,
) -> Result[Int?, VarError] {
if offset < 0 || offset + 4 > data.length() {
return Err(UnexpectedEof)
}
let count = read_u16_int(data, offset + 2)
match count {
Err(err) => Err(err)
Ok(count) => {
let record_offset = offset + 4
let record_size = 6
if record_offset < 0 || record_offset + count * record_size > data.length() {
return Err(UnexpectedEof)
}
for i in 0.. return Err(err)
(_, Err(err), _) => return Err(err)
(_, _, Err(err)) => return Err(err)
(Ok(start), Ok(end), Ok(start_index)) =>
if glyph >= start && glyph <= end {
return Ok(Some(start_index + (glyph - start)))
}
}
}
Ok(None)
}
}
}
///|
pub fn VarcTable::parse(data : BytesView) -> Result[VarcTable, VarError] {
let version = read_u32(data, 0)
let coverage_offset = read_u32_int(data, 4)
let var_store_offset = read_u32_int(data, 8)
let condition_list_offset = read_u32_int(data, 12)
let axis_indices_offset = read_u32_int(data, 16)
let glyph_records_offset = read_u32_int(data, 20)
match (
version,
coverage_offset,
var_store_offset,
condition_list_offset,
axis_indices_offset,
glyph_records_offset,
) {
(Err(err), _, _, _, _, _) => Err(err)
(_, Err(err), _, _, _, _) => Err(err)
(_, _, Err(err), _, _, _) => Err(err)
(_, _, _, Err(err), _, _) => Err(err)
(_, _, _, _, Err(err), _) => Err(err)
(_, _, _, _, _, Err(err)) => Err(err)
(Ok(version), Ok(coverage_offset), Ok(var_store_offset), Ok(condition_list_offset), Ok(axis_indices_offset), Ok(glyph_records_offset)) => {
let major = (version >> 16) & 0xFFFFU
if major != 1U {
return Err(InvalidFormat)
}
let length = data.length()
match validate_offset(coverage_offset, length) {
Err(err) => return Err(err)
Ok(_) => ()
}
match validate_offset(var_store_offset, length) {
Err(err) => return Err(err)
Ok(_) => ()
}
match validate_offset(condition_list_offset, length) {
Err(err) => return Err(err)
Ok(_) => ()
}
match validate_offset(axis_indices_offset, length) {
Err(err) => return Err(err)
Ok(_) => ()
}
match validate_offset(glyph_records_offset, length) {
Err(err) => return Err(err)
Ok(_) => ()
}
Ok(VarcTable::{
version: version.reinterpret_as_int(),
coverage_offset,
var_store_offset,
condition_list_offset,
axis_indices_offset,
glyph_records_offset,
data: data.to_bytes(),
})
}
}
}
///|
pub fn VarcTable::var_store(self : VarcTable) -> Result[MultiItemVariationStore?, VarError] {
if self.var_store_offset == 0 {
return Ok(None)
}
if self.var_store_offset < 0 || self.var_store_offset >= self.data.length() {
return Err(UnexpectedEof)
}
match MultiItemVariationStore::parse(self.data[self.var_store_offset:]) {
Err(err) => Err(err)
Ok(value) => Ok(Some(value))
}
}
///|
pub fn VarcTable::axis_indices(self : VarcTable, index : Int) -> Result[Array[Int], VarError] {
if self.axis_indices_offset == 0 {
return Err(InvalidFormat)
}
let idx = match parse_cff2_index(self.data[:], self.axis_indices_offset) {
Err(err) => return Err(err)
Ok(value) => value
}
let bytes = match idx.item_bytes(index) {
Err(err) => return Err(err)
Ok(value) => value
}
decode_tuple_values(bytes[:])
}
///|
pub fn VarcTable::glyph_record(
self : VarcTable,
glyph : Int,
) -> Result[Bytes?, VarError] {
if self.coverage_offset == 0 || self.glyph_records_offset == 0 {
return Ok(None)
}
let index = match coverage_index_varc(self.data[:], self.coverage_offset, glyph) {
Err(err) => return Err(err)
Ok(value) => value
}
match index {
None => Ok(None)
Some(index) => {
let records = match parse_cff2_index(self.data[:], self.glyph_records_offset) {
Err(err) => return Err(err)
Ok(value) => value
}
match records.item_bytes(index) {
Err(err) => Err(err)
Ok(value) => Ok(Some(value))
}
}
}
}
///|
pub fn VarcTable::conditions(self : VarcTable) -> Result[Array[VarcCondition], VarError] {
if self.condition_list_offset == 0 {
return Ok([])
}
let base = self.condition_list_offset
let count = read_u32_int(self.data[:], base)
match count {
Err(err) => Err(err)
Ok(count) => {
if count < 0 {
return Err(InvalidFormat)
}
let offsets_base = base + 4
let total = count * 4
if offsets_base < 0 || offsets_base + total > self.data.length() {
return Err(UnexpectedEof)
}
let conditions : Array[VarcCondition] = []
for i in 0.. return Err(err)
Ok(offset) => {
let condition = match parse_condition_at(self.data[:], base, offset, 0) {
Err(err) => return Err(err)
Ok(value) => value
}
conditions.push(condition)
}
}
}
Ok(conditions)
}
}
}