Skip to content

Commit

Permalink
fix missing unicode map entries
Browse files Browse the repository at this point in the history
  • Loading branch information
Andre Bogus committed Jul 22, 2020
1 parent d5c755f commit 0aa2bbc
Showing 1 changed file with 45 additions and 20 deletions.
65 changes: 45 additions & 20 deletions src/lib.rs
Expand Up @@ -459,7 +459,7 @@ impl<'a> PdfSimpleFont<'a> {
}
dlog!("{} = {} ({:?})", code, name, unicode);
if let Some(ref mut unicode_map) = unicode_map {
dlog!("{} {}", code, unicode_map[&(code as u32)]);
dlog!("{} {:?}", code, unicode_map.get(&(code as u32)));
}
code += 1;
}
Expand Down Expand Up @@ -710,7 +710,7 @@ impl<'a> PdfFont for PdfSimpleFont<'a> {
return *width;
} else {
dlog!("missing width for {} falling back to default_width {:?}", id, self.font);
return self.default_width.unwrap();
return self.default_width.unwrap_or_default();
}
}
/*fn decode(&self, chars: &[u8]) -> String {
Expand All @@ -721,12 +721,18 @@ impl<'a> PdfFont for PdfSimpleFont<'a> {
fn next_char(&self, iter: &mut Iter<u8>) -> Option<(CharCode, u8)> {
iter.next().map(|x| (*x as CharCode, 1))
}
fn decode_char(&self, char: CharCode) -> String {
let slice = [char as u8];
fn decode_char(&self, c: CharCode) -> String {
let slice = [c as u8];
if let Some(ref unicode_map) = self.unicode_map {
let s = unicode_map.get(&char);
let s = unicode_map.get(&c);
let s = match s {
None => { panic!("missing char {:?} in map {:?}", char, unicode_map)}
None => {
dlog!("missing char {:?} in map {:?}", c, unicode_map);
// if we don't have the char in the font's map, it may still
// be a "correct" unicode char, so return it. Otherwise return
// the UTF8 replacement char
[std::char::from_u32(c).unwrap_or_else(|| '\u{fffd}')].iter().collect::<String>()
}
Some(s) => { s.clone() }
};
return s
Expand All @@ -750,9 +756,10 @@ impl<'a> PdfFont for PdfType3Font<'a> {
fn get_width(&self, id: CharCode) -> f64 {
let width = self.widths.get(&id);
if let Some(width) = width {
return *width;
*width
} else {
panic!("missing width for {} {:?}", id, self.font);
dlog!("missing width for {} {:?}", id, self.font);
0.0
}
}
/*fn decode(&self, chars: &[u8]) -> String {
Expand All @@ -763,12 +770,18 @@ impl<'a> PdfFont for PdfType3Font<'a> {
fn next_char(&self, iter: &mut Iter<u8>) -> Option<(CharCode, u8)> {
iter.next().map(|x| (*x as CharCode, 1))
}
fn decode_char(&self, char: CharCode) -> String {
let slice = [char as u8];
fn decode_char(&self, c: CharCode) -> String {
let slice = [c as u8];
if let Some(ref unicode_map) = self.unicode_map {
let s = unicode_map.get(&char);
let s = unicode_map.get(&c);
let s = match s {
None => { panic!("missing char {:?} in map {:?}", char, unicode_map)}
None => {
dlog!("missing char {:?} in map {:?}", c, unicode_map);
// if we don't have the char in the font's map, it may still
// be a "correct" unicode char, so return it. Otherwise return
// the UTF8 replacement char
[std::char::from_u32(c).unwrap_or_else(|| '\u{fffd}')].iter().collect::<String>()
},
Some(s) => { s.clone() }
};
return s
Expand Down Expand Up @@ -1272,6 +1285,17 @@ pub enum ColorSpace {
ICCBased(Vec<u8>)
}

macro_rules! colorspace_arg {
($ok:ident, $e:expr, $($format:expr),*) => {
if let $ok(v) = $e {
v
} else {
dlog!($($format),*);
return ColorSpace::DeviceRGB
}
};
}

fn make_colorspace<'a>(doc: &'a Document, name: &[u8], resources: &'a Dictionary) -> ColorSpace {
match name {
b"DeviceGray" => ColorSpace::DeviceGray,
Expand All @@ -1280,12 +1304,12 @@ fn make_colorspace<'a>(doc: &'a Document, name: &[u8], resources: &'a Dictionary
b"Pattern" => ColorSpace::Pattern,
_ => {
let colorspaces: &Dictionary = get(&doc, resources, b"ColorSpace");
let cs = maybe_get_array(doc, colorspaces, &name[..]).unwrap_or_else(|| panic!("missing colorspace {:?}", &name[..]));
let cs_name = pdf_to_utf8(cs[0].as_name().expect("first arg must be a name"));
let cs = colorspace_arg!(Some, maybe_get_array(doc, colorspaces, &name[..]), "missing colorspace {:?}", &name[..]);
let cs_name = pdf_to_utf8(colorspace_arg!(Ok, cs[0].as_name(), "first arg must be a name"));
match cs_name.as_ref() {
"Separation" => {
let name = pdf_to_utf8(cs[1].as_name().expect("second arg must be a name"));
let alternate_space = pdf_to_utf8(cs[2].as_name().expect("second arg must be a name"));
let name = pdf_to_utf8(colorspace_arg!(Ok, cs[1].as_name(), "second arg must be a name"));
let alternate_space = pdf_to_utf8(colorspace_arg!(Ok, cs[2].as_name(), "second arg must be a name"));
let tint_transform = Box::new(Function::new(doc, maybe_deref(doc, &cs[3])));

dlog!("{:?} {:?} {:?}", name, alternate_space, tint_transform);
Expand All @@ -1298,15 +1322,15 @@ fn make_colorspace<'a>(doc: &'a Document, name: &[u8], resources: &'a Dictionary
ColorSpace::ICCBased(get_contents(stream))
}
"CalGray" => {
let dict = cs[1].as_dict().expect("second arg must be a dict");
let dict = colorspace_arg!(Ok, cs[1].as_dict(), "second arg must be a dict");
ColorSpace::CalGray(CalGray {
white_point: get(&doc, dict, b"WhitePoint"),
black_point: get(&doc, dict, b"BackPoint"),
gamma: get(&doc, dict, b"Gamma"),
})
}
"CalRGB" => {
let dict = cs[1].as_dict().expect("second arg must be a dict");
let dict = colorspace_arg!(Ok, cs[1].as_dict(), "second arg must be a dict");
ColorSpace::CalRGB(CalRGB {
white_point: get(&doc, dict, b"WhitePoint"),
black_point: get(&doc, dict, b"BackPoint"),
Expand All @@ -1315,7 +1339,7 @@ fn make_colorspace<'a>(doc: &'a Document, name: &[u8], resources: &'a Dictionary
})
}
"Lab" => {
let dict = cs[1].as_dict().expect("second arg must be a dict");
let dict = colorspace_arg!(Ok, cs[1].as_dict(), "second arg must be a dict");
ColorSpace::Lab(Lab {
white_point: get(&doc, dict, b"WhitePoint"),
black_point: get(&doc, dict, b"BackPoint"),
Expand All @@ -1326,7 +1350,8 @@ fn make_colorspace<'a>(doc: &'a Document, name: &[u8], resources: &'a Dictionary
ColorSpace::Pattern
}
_ => {
panic!("color_space {:?} {:?} {:?}", name, cs_name, cs)
dlog!("color_space {:?} {:?} {:?}", name, cs_name, cs);
ColorSpace::DeviceRGB
}
}
}
Expand Down

0 comments on commit 0aa2bbc

Please sign in to comment.