use stet_core::context::Context;
use stet_core::error::PsError;
use stet_engine::eval::parse_and_exec;
use crate::StetError;
use crate::embedded_resources;
struct NullWriter;
impl std::io::Write for NullWriter {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
pub fn create_initialized_context(
use_icc: bool,
suppress_output: bool,
) -> Result<Context, StetError> {
let mut ctx = Context::new();
ctx.exec_sync_fn = Some(stet_engine::eval::exec_sync);
stet_ops::build_system_dict(&mut ctx);
embedded_resources::register_all(&mut ctx.files);
ctx.font_resource_path = Some("Font".to_string());
if use_icc {
ctx.icc_cache
.load_cmyk_profile_bytes(embedded_resources::DEFAULT_CMYK_ICC);
}
if suppress_output {
ctx.stdout = Box::new(NullWriter);
}
run_init_scripts(&mut ctx)?;
Ok(ctx)
}
fn run_init_scripts(ctx: &mut Context) -> Result<(), StetError> {
let saved_d_stack = ctx.d_stack.clone();
ctx.d_stack.truncate(1);
let old_stdout = std::mem::replace(&mut ctx.stdout, Box::new(NullWriter));
ctx.initializing = true;
ctx.vm_alloc_mode = true;
let init_script = b"{(resources/Init/sysdict.ps) run} stopped { } if";
let exec_ok = match parse_and_exec(ctx, init_script) {
Ok(()) => true,
Err(PsError::Quit) => true,
Err(_) => false,
};
ctx.stdout = old_stdout;
if exec_ok && ctx.d_stack.len() >= 3 {
sync_context_after_init(ctx);
} else {
ctx.d_stack = saved_d_stack;
ctx.o_stack.clear();
ctx.e_stack.clear();
}
ctx.vm_alloc_mode = false;
ctx.initializing = false;
ctx.dicts.set_access(
ctx.systemdict,
stet_core::object::ObjFlags::ACCESS_READ_ONLY,
);
Ok(())
}
fn sync_context_after_init(ctx: &mut Context) {
use stet_core::dict::DictKey;
use stet_core::object::PsValue;
let sd = ctx.systemdict;
let lookup = |ctx: &Context, name: &[u8]| -> Option<stet_core::object::EntityId> {
let id = ctx.names.find(name)?;
let obj = ctx.dicts.get(sd, &DictKey::Name(id))?;
match obj.value {
PsValue::Dict(e) => Some(e),
_ => None,
}
};
if let Some(e) = lookup(ctx, b"$error") {
ctx.dollar_error = e;
}
if let Some(e) = lookup(ctx, b"errordict") {
ctx.errordict = e;
}
if let Some(e) = lookup(ctx, b"FontDirectory") {
ctx.font_directory = e;
}
if let Some(e) = lookup(ctx, b"userdict") {
ctx.userdict = e;
}
if let Some(e) = lookup(ctx, b"globaldict") {
ctx.globaldict = e;
}
}