dterm-built-in-font 0.3.0

Built-in 8x8 font for dterm
Documentation
// Copyright (c) 2017, Marty Mills <daggerbot@gmail.com>
// This software is available under the terms of the zlib license.
// See COPYING.md for more information.

extern crate dcolor;
extern crate dimage;
extern crate dvec;

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;

use dcolor::Rgba;
use dimage::{png, Coord, Image};
use dvec::Vec2;

const IN_NAME: &'static str = "built-in-font.png";
const OUT_NAME: &'static str = "generated.rs";

const FONT_SIZE: Vec2<Coord> = Vec2 { x: 8, y: 8 };
const FONT_LAYOUT: Vec2<Coord> = Vec2 { x: 16, y: 16 };

const BLACK: Rgba<u8> = Rgba { r: 0, g: 0, b: 0, a: 0xff };
const WHITE: Rgba<u8> = Rgba { r: 0xff, g: 0xff, b: 0xff, a: 0xff };

fn main () {
    let expected_image_size = FONT_SIZE * FONT_LAYOUT;
    let n_glyphs = FONT_LAYOUT.x * FONT_LAYOUT.y;
    assert_eq!(n_glyphs, 256); // 256 chars in code page 437
    assert!(FONT_SIZE.x <= 8); // Must be packable into a byte

    let in_path = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()).join(IN_NAME);
    let out_path = PathBuf::from(env::var_os("OUT_DIR").unwrap()).join(OUT_NAME);

    let image = png::decode_file(&in_path).unwrap().conv_into::<Rgba<u8>>().unwrap();
    assert_eq!(image.size(), expected_image_size);

    let mut out_file = File::create(&out_path).unwrap();

    writeln!(out_file, "// This file was automatically generated. Do no modify.").unwrap();
    writeln!(out_file, "pub const FONT_SIZE: Vec2<i32> = Vec2 {{ x: {}, y: {} }};",
             FONT_SIZE.x, FONT_SIZE.y).unwrap();
    writeln!(out_file, "pub static FONT: [[u8; {}]; {}] = [", FONT_SIZE.y, n_glyphs).unwrap();

    for layout_y in 0..FONT_LAYOUT.y {
        for layout_x in 0..FONT_LAYOUT.x {
            let glyph_pos = FONT_SIZE * (layout_x, layout_y);

            write!(out_file, "    [").unwrap();

            for y in 0..FONT_SIZE.y {
                let mut byte = 0;

                for x in 0..FONT_SIZE.x {
                    byte <<= 1;

                    match image.pixel(glyph_pos + (x, y)) {
                        BLACK => (),
                        WHITE => { byte |= 1; },
                        _ => panic!("image is not monochromatic"),
                    }
                }

                write!(out_file, "{},", byte).unwrap();
            }

            writeln!(out_file, "],").unwrap();
        }
    }

    writeln!(out_file, "];").unwrap();
}