From e56b950cb2bbb8425a943b16add53e7d0629696b Mon Sep 17 00:00:00 2001 From: lauchmelder Date: Mon, 3 Mar 2025 18:04:52 +0100 Subject: [PATCH] correct cmap algorithm --- src/font/character_map.rs | 1 + src/font/maximum_profile.rs | 2 +- src/font/search.rs | 27 +++++++++++++++++++++++---- src/font/table_directory.rs | 2 ++ 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/font/character_map.rs b/src/font/character_map.rs index 0bf1c22..9e1ec41 100644 --- a/src/font/character_map.rs +++ b/src/font/character_map.rs @@ -67,6 +67,7 @@ impl SegmentToDelta { debug!("First endcode that is >={c} has index {index} (={})", self.end_code[index]); if self.start_code[index] > c { + error!("Start code belonging to this index ({}) is too big", self.start_code[index]); return None } diff --git a/src/font/maximum_profile.rs b/src/font/maximum_profile.rs index d10e430..7070726 100644 --- a/src/font/maximum_profile.rs +++ b/src/font/maximum_profile.rs @@ -55,7 +55,7 @@ impl FontTable for MaximumProfile { debug!("maxp table version: {:#08x}", version); match version { - 0x00005000 => todo!(), + 0x00005000 => Ok(MaximumProfile::V0_5(deserialize(reader.by_ref())?)), 0x00010000 => Ok(MaximumProfile::V1_0(deserialize(reader.by_ref())?)), _ => { return Err(bincode::ErrorKind::Custom("Invalid maxp table version".into()).into()); } } diff --git a/src/font/search.rs b/src/font/search.rs index 0d22f3e..787ddfb 100644 --- a/src/font/search.rs +++ b/src/font/search.rs @@ -17,14 +17,28 @@ impl SearchParameters { for level in 1..=self.entry_selector { let end_code = array[index]; - if end_code == target { + if end_code >= target && array[index - 1] < target { + debug!("binary search found result"); return Some(index); } + let mut correction = (self.search_range >> (level + 2)) as usize; + if correction == 0 { + correction = 1; + } + if end_code < target { - index += (self.search_range >> (level + 2)) as usize; + index += correction; + debug!("considered endcode smaller than target, setting index to {index}"); } else { - index -= (self.search_range >> (level + 2)) as usize; + let new_index = index - correction; + if correction == 1 && array[new_index] < target { + debug!("no more candidates"); + return Some(index); + } + + index = new_index; + debug!("considered endcode larger than target, setting index to {index}"); } } @@ -38,7 +52,12 @@ impl SearchParameters { if target > array[(self.search_range as usize >> 1) - 1] { debug!("{}", array[(self.search_range as usize >> 1) - 1]); - todo!() + + for i in (self.search_range as usize >> 1)..array.len() { + if array[i] >= target { + return Some(i); + } + } } self.binary_search(array, target) diff --git a/src/font/table_directory.rs b/src/font/table_directory.rs index 0319c85..ec2764c 100644 --- a/src/font/table_directory.rs +++ b/src/font/table_directory.rs @@ -1,6 +1,7 @@ use std::{collections::HashMap, fs::File, io::{BufReader, Read, Seek, SeekFrom}}; use bincode::Result; +use log::debug; use serde::Deserialize; use crate::font::deserialize; @@ -25,6 +26,7 @@ pub struct TableDirectory(pub HashMap); impl TableDirectory { pub fn new(reader: &mut R) -> Result { let header: TableDirectoryHeader = deserialize(reader.by_ref())?; + debug!("{header:#x?}"); let mut tables: HashMap = HashMap::with_capacity(header.num_tables as usize); reader.seek_relative(3 * size_of::() as i64)?;