Fix interpreter a bit; Arial fpgm now parses

This commit is contained in:
Patrick Walton 2017-02-24 12:19:32 -08:00
parent 88d1e3163d
commit 37736b27b9
4 changed files with 35 additions and 11 deletions

View File

@ -1,21 +1,38 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
extern crate clap;
extern crate euclid;
extern crate memmap;
extern crate pathfinder;
use clap::{App, Arg};
use memmap::{Mmap, Protection};
use pathfinder::charmap::CodepointRange;
use pathfinder::font::{Font, PointKind};
use pathfinder::hinting::Hinter;
use std::char;
use std::env;
fn main() {
let file = Mmap::open_path(env::args().nth(1).unwrap(), Protection::Read).unwrap();
let hint_arg = Arg::with_name("hint").short("H")
.long("hint")
.help("Apply hinting instructions");
let font_arg = Arg::with_name("FONT-FILE").help("Select the font file (`.ttf`, `.otf`, etc.)")
.required(true)
.index(1);
let matches = App::new("dump-outlines").arg(hint_arg).arg(font_arg).get_matches();
let file = Mmap::open_path(matches.value_of("FONT-FILE").unwrap(), Protection::Read).unwrap();
let mut buffer = vec![];
unsafe {
let font = Font::new(file.as_slice(), &mut buffer).unwrap();
let hinter = if matches.is_present("hint") {
Some(Hinter::new(&font).unwrap())
} else {
None
};
let codepoint_ranges = [CodepointRange::new('!' as u32, '~' as u32)];
let glyph_mapping = font.glyph_mapping_for_codepoint_ranges(&codepoint_ranges).unwrap();
for (glyph_index, (_, glyph_id)) in glyph_mapping.iter().enumerate() {

View File

@ -141,7 +141,7 @@ pub enum HintingParseError {
/// The instruction stream terminated abnormally.
UnexpectedEof,
/// An unexpected opcode was encountered.
UnknownOpcode,
UnknownOpcode(u8),
/// An unexpected value was encountered for `DistanceType`.
InvalidDistanceType,
}

View File

@ -137,8 +137,10 @@ pub enum Instruction<'a> {
Mdap(ShouldRound),
/// Move Indirect Absolute Point (0x3e-0x3f) (ttinst2.doc, 272-275)
Miap(ShouldRound),
/// Move Direct Relative Point (0xc0-0xdf) (ttinst2.doc, 276-283)
/// Move Direct Relative Point (0xc0-0xdf) (ttinst2.doc, 276-278)
Mdrp(SetRP0, ApplyMinimumDistance, ShouldRound, DistanceType),
/// Move Indirect Relative Point (0xe0-0xff) (ttinst2.doc, 279-283)
Mirp(SetRP0, ApplyMinimumDistance, ShouldRound, DistanceType),
/// Align Relative Point (0x3c) (ttinst2.doc, 284)
Alignrp,
/// Move Point to Intersection of Two Lines (0x0f) (ttinst2.doc, 286-288)
@ -277,13 +279,13 @@ impl<'a> Instruction<'a> {
}
0x41 | 0xb8...0xbf => {
let count = if op == 0x41 {
try!(get(data, pc).ok_or(HintingParseError::UnexpectedEof)) as usize * 2
try!(get(data, pc).ok_or(HintingParseError::UnexpectedEof)) as usize
} else {
((op as usize & 7) + 1) * 2
(op as usize & 7) + 1
};
if *pc + count <= data.len() {
let insn = Instruction::Pushw(&data[*pc..(*pc + count)]);
*pc += count;
if *pc + count * 2 <= data.len() {
let insn = Instruction::Pushw(&data[*pc..(*pc + count * 2)]);
*pc += count * 2;
Ok(insn)
} else {
Err(HintingParseError::UnexpectedEof)
@ -364,6 +366,12 @@ impl<'a> Instruction<'a> {
ShouldRound((op & 0b00100) != 0),
try!(DistanceType::parse(op & 0b00011))))
}
0xe0...0xff => {
Ok(Instruction::Mirp(SetRP0((op & 0b10000) != 0),
ApplyMinimumDistance((op & 0b01000) != 0),
ShouldRound((op & 0b00100) != 0),
try!(DistanceType::parse(op & 0b00011))))
}
0x3c => Ok(Instruction::Alignrp),
0x0f => Ok(Instruction::Isect),
0x27 => Ok(Instruction::Alignpts),
@ -422,7 +430,7 @@ impl<'a> Instruction<'a> {
0x4f => Ok(Instruction::Debug),
0x88 => Ok(Instruction::Getinfo),
0x91 => Ok(Instruction::Getvariation),
_ => Err(HintingParseError::UnknownOpcode),
_ => Err(HintingParseError::UnknownOpcode(op)),
}
}
}

View File

@ -25,7 +25,6 @@ impl<'a> ScriptInterpreter<'a> {
branch_targets: vec![],
};
try!(interpreter.populate_branch_targets());
println!("{:#?}", interpreter.branch_targets);
Ok(interpreter)
}