extern crate cairo;
#[macro_use] extern crate failure;
extern crate pango;
extern crate pangocairo;
extern crate rrecutils;
extern crate rsvg;
mod markup;
mod data;
use markup::Weight;
use std::{fs,io};
use rsvg::HandleExt;
const SCALE: i32 = 3;
fn draw_card(card: &data::Card) -> Result<(), failure::Error> {
use data::CardType::*;
let surf = cairo::ImageSurface::create(
cairo::Format::Rgb24,
4 * SCALE * 100,
1 * SCALE * 100,
).map_err(|e| format_err!("Unable to create Cairo surface: {:?}", e))?;
let ctx = cairo::Context::new(&surf);
ctx.scale(SCALE as f64, SCALE as f64);
ctx.set_source_rgb(1.0, 1.0, 1.0);
ctx.paint();
ctx.set_source_rgb(0.56, 0.56, 0.56);
ctx.rectangle(10.0, 10.0, 80.0, 80.0);
ctx.stroke();
ctx.move_to(105.0, 30.0);
ctx.line_to(105.0, 90.0);
ctx.stroke();
ctx.set_source_rgb(0.0, 0.0, 0.0);
ctx.move_to(100.0, 8.0);
let mut buf = markup::MarkupBuffer::new();
match card.card_type {
Weapon { ref weapon_type, .. } =>
buf.push(&format!("{} (Weapon, {:?})", card.name, weapon_type)),
Monster { ref hp, ref melee, ref ranged, ref arcane, ref defense, .. } => {
buf.push(&format!("{} (Beast ", card.name));
buf.markup().size(8).weight(Weight::Heavy).push("HP");
buf.push(&format!("{}", hp));
if let &Some(ref m) = melee {
buf.space();
buf.markup().size(8).weight(Weight::Heavy).push("M");
buf.push(m);
}
if let &Some(ref m) = ranged {
buf.space();
buf.markup().size(8).weight(Weight::Heavy).push("R");
buf.push(m);
}
if let &Some(ref m) = arcane {
buf.space();
buf.markup().size(8).weight(Weight::Heavy).push("A");
buf.push(m);
}
if let &Some(ref m) = defense {
buf.space();
buf.markup().size(8).weight(Weight::Heavy).push("D");
buf.push(m);
}
buf.push(")");
}
Generic { ref kind, .. } =>
buf.push(&format!("{} ({:?})", card.name, kind)),
};
buf.show_with_font(
&ctx,
markup::Font::new("Fira Sans").size(12).weight(Weight::Bold),
None,
)?;
ctx.move_to(115.0, 26.0);
let mut buf = markup::MarkupBuffer::new();
match card.card_type {
Weapon { ability, effect, .. } => {
buf.markup().weight(Weight::Bold).push(&format!("{}: ", ability));
buf.push(effect);
},
Monster { action, effect, .. } => {
buf.markup().weight(Weight::Bold).push(&format!("{}: ", action));
buf.push(effect);
},
Generic { effect, .. } => {
buf.push(effect);
},
};
buf.show_with_font(
&ctx,
markup::Font::new("Fira Sans").size(10),
Some(390 - 115)
)?;
let icon = rsvg::Handle::new_from_file(&card.icon)
.map_err(|_| format_err!("Error loading image: {}", card.icon))?;
ctx.translate(10.0, 10.0);
ctx.scale(0.9, 0.9);
icon.render_cairo(&ctx);
let path = format!("cards/{}_{}.png", card.type_name(), card.card_name());
let mut f = fs::File::create(&path)?;
println!("Writing to {}", path);
surf.write_to_png(&mut f)?;
Ok(())
}
fn run() -> Result<(), failure::Error> {
let mut f = io::BufReader::new(fs::File::open("cards.rec")?);
let recfile = rrecutils::Recfile::parse(&mut f)?;
for w in recfile.iter() {
if w.rec_type.is_some() {
let card = data::Card::from_record(w)?;
draw_card(&card)?;
}
}
Ok(())
}
fn main() {
run().unwrap();
}