<commit_before>use std::borrow::Cow;

#[derive(Debug,Clone)]
pub struct SassRule<'a> {
    pub selectors: Vec<Event<'a>>,
    pub children: Vec<Event<'a>>,
}

impl<'a> SassRule<'a> {
    pub fn new() -> SassRule<'a> {
        SassRule {
            selectors: Vec::new(),
            children: Vec::new(),
        }
    }
}

#[derive(Debug,Clone)]
pub struct SassVariable<'a> {
    pub variable: Event<'a>,
}

#[derive(Debug,Clone)]
pub struct SassComment<'a> {
    pub comment: Event<'a>,
}

#[derive(PartialEq, Debug, Clone)]
pub enum State {
    OutsideRules,
    InVariable,
    InComment,
    InRule,
    InSelectors,
    InProperties,
    EndRule,
    Eof,
}

#[derive(Debug, Clone)]
pub enum Entity {
    Rule,
    Selectors
}

#[derive(Debug, Clone)]
pub enum Event<'a> {
    Start(Entity),
    End(Entity),
    Selector(Cow<'a, str>),
    Property(Cow<'a, str>, Cow<'a, str>),
    Variable(Cow<'a, str>, Cow<'a, str>),
    Comment(Cow<'a, str>),
    ChildRule(SassRule<'a>),
}

#[derive(Debug)]
pub enum TopLevelEvent<'a> {
    Rule(SassRule<'a>),
    Variable(SassVariable<'a>),
    Comment(SassComment<'a>),
}
<commit_msg>Make a more useful, nested debug format<commit_after>use std::borrow::Cow;
use std::fmt;

#[derive(Clone)]
pub struct SassRule<'a> {
    pub selectors: Vec<Event<'a>>,
    pub children: Vec<Event<'a>>,
}

impl<'a> SassRule<'a> {
    pub fn new() -> SassRule<'a> {
        SassRule {
            selectors: Vec::new(),
            children: Vec::new(),
        }
    }
}

impl<'a> fmt::Debug for SassRule<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let children = self.children.iter().map(|c| format!("{:?}", c)).collect::<Vec<_>>().connect("\n");
        let indented_children = children.split("\n").collect::<Vec<_>>().connect("\n  ");
        write!(f, "{:?} {{\n  {}\n}}", self.selectors, indented_children)
    }
}

#[derive(Debug,Clone)]
pub struct SassVariable<'a> {
    pub variable: Event<'a>,
}

#[derive(Debug,Clone)]
pub struct SassComment<'a> {
    pub comment: Event<'a>,
}

#[derive(PartialEq, Debug, Clone)]
pub enum State {
    OutsideRules,
    InVariable,
    InComment,
    InRule,
    InSelectors,
    InProperties,
    EndRule,
    Eof,
}

#[derive(Debug, Clone)]
pub enum Entity {
    Rule,
    Selectors
}

#[derive(Debug, Clone)]
pub enum Event<'a> {
    Start(Entity),
    End(Entity),
    Selector(Cow<'a, str>),
    Property(Cow<'a, str>, Cow<'a, str>),
    Variable(Cow<'a, str>, Cow<'a, str>),
    Comment(Cow<'a, str>),
    ChildRule(SassRule<'a>),
}

#[derive(Debug)]
pub enum TopLevelEvent<'a> {
    Rule(SassRule<'a>),
    Variable(SassVariable<'a>),
    Comment(SassComment<'a>),
}
<|endoftext|>


<commit_before>// Copyright (c) 2016, 2018 Nikita Pekin and the ferru contributors
// See the README.md file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fs;
use std::collections::HashMap;
use std::ffi::OsStr;
use std::path::{Path, PathBuf};

use config::Config;
use document;
use error::{Error, Result};
use template;
use util;

/// Reads all relevant files in the specified source directory, uses them to
/// generate a static website, and stores the resulting files in the specified
/// destination directory.
pub fn build(config: &Config) -> Result<()> {
    const DEFAULT_SOURCE_PATH: &'static str = "./";
    const DEFAULT_DEST_PATH: &'static str = "./_site/";

    // Get the source path opt.
    let source = config.source_directory.as_ref()
        .map(Path::new)
        .map_or_else(|| PathBuf::from(DEFAULT_SOURCE_PATH), Path::to_path_buf);
    if !source.exists() {
        return Err(Error::path_not_found(&source))
    }

    // Get the destination path opt.
    let dest = config.dest_directory.as_ref()
        .map(Path::new)
        .map_or_else(|| PathBuf::from(DEFAULT_DEST_PATH), Path::to_path_buf);

    debug!("Cleaning destination directory");
    if !dest.exists() {
        println!("Destination directory \"{}\" does not exist, creating.", dest.display());
    } else {
        println!("Cleaning destination directory \"{}\".", dest.display());
        try!(fs::remove_dir_all(&dest));
    }
    try!(fs::create_dir(&dest));

    // Load the templates.
    debug!("Loading templates");
    let templates = match template::load_templates_from_disk(&source.join("_templates"), |path| {
        !util::is_hidden(&path) &&
        path.extension().and_then(OsStr::to_str) == Some("tpl")
    }) {
        Ok(v) => v,
        Err(e) => {
            println!("Failed to read templates: {}", e);
            return Err(e);
        }
    };

    // Copy all non-template and non-document content.
    debug!("Copying static files");
    if source != dest {
        let is_static_file = |path: &Path| {
            !util::is_hidden(&path) &&
            path != dest &&
            !path.to_str().map_or(false, |path| path.contains("_posts")) &&
            !path.to_str().map_or(false, |path| path.contains("_templates"))
        };

        try!(util::copy_recursively(&source, &dest, is_static_file))
    }

    debug!("Loading documents from disk");
    let documents: HashMap<PathBuf, document::Document> = try!(document::load_documents_from_disk(&source.join("_posts"), |path| {
        !util::is_hidden(&path)
    }));

    debug!("Rendering documents");
    for (key, document) in documents.into_iter() {
        let new_dest = dest.join(&key);
        try!(document.render_to_file(&new_dest, &templates));
    }

    Ok(())
}
<commit_msg>impr: no longer remove dest dir itself<commit_after>// Copyright (c) 2016, 2018 Nikita Pekin and the ferru contributors
// See the README.md file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fs;
use std::collections::HashMap;
use std::ffi::OsStr;
use std::path::{Path, PathBuf};

use config::Config;
use document;
use error::{Error, Result};
use template;
use util;

/// Reads all relevant files in the specified source directory, uses them to
/// generate a static website, and stores the resulting files in the specified
/// destination directory.
pub fn build(config: &Config) -> Result<()> {
    const DEFAULT_SOURCE_PATH: &'static str = "./";
    const DEFAULT_DEST_PATH: &'static str = "./_site/";

    // Get the source path opt.
    let source = config.source_directory.as_ref()
        .map(Path::new)
        .map_or_else(|| PathBuf::from(DEFAULT_SOURCE_PATH), Path::to_path_buf);
    if !source.exists() {
        return Err(Error::path_not_found(&source))
    }

    // Get the destination path opt.
    let dest = config.dest_directory.as_ref()
        .map(Path::new)
        .map_or_else(|| PathBuf::from(DEFAULT_DEST_PATH), Path::to_path_buf);

    debug!("Cleaning destination directory");
    if !dest.exists() {
        println!("Destination directory \"{}\" does not exist, creating.", dest.display());
        fs::create_dir(&dest)?;
    } else {
        println!("Cleaning destination directory \"{}\".", dest.display());
        remove_dir_contents(&dest)?;
    }

    // Load the templates.
    debug!("Loading templates");
    let templates = match template::load_templates_from_disk(&source.join("_templates"), |path| {
        !util::is_hidden(&path) &&
        path.extension().and_then(OsStr::to_str) == Some("tpl")
    }) {
        Ok(v) => v,
        Err(e) => {
            println!("Failed to read templates: {}", e);
            return Err(e);
        }
    };

    // Copy all non-template and non-document content.
    debug!("Copying static files");
    if source != dest {
        let is_static_file = |path: &Path| {
            !util::is_hidden(&path) &&
            path != dest &&
            !path.to_str().map_or(false, |path| path.contains("_posts")) &&
            !path.to_str().map_or(false, |path| path.contains("_templates"))
        };

        try!(util::copy_recursively(&source, &dest, is_static_file))
    }

    debug!("Loading documents from disk");
    let documents: HashMap<PathBuf, document::Document> = try!(document::load_documents_from_disk(&source.join("_posts"), |path| {
        !util::is_hidden(&path)
    }));

    debug!("Rendering documents");
    for (key, document) in documents.into_iter() {
        let new_dest = dest.join(&key);
        try!(document.render_to_file(&new_dest, &templates));
    }

    Ok(())
}

fn remove_dir_contents(path: &Path) -> Result<()> {
    if path.is_dir() {
        for entry in fs::read_dir(path)? {
            let entry = entry?;
            let path = entry.path();
            if path.is_dir() {
                fs::remove_dir_all(path)?;
            } else {
                fs::remove_file(path)?;
            }
        }
    } else {
        warn!("Attempted to remove dir contents for a file path");
    }

    Ok(())
}
<|endoftext|>


<commit_before>//! Implements basic arithmetic operations in GF(2^8).

/// Multiply two elements of GF(2^8).
pub fn mul(e: u8, a: u8) -> u8 {
    if e == 0 || a == 0 {
        0
    } else {
        EXP[(LOG[e as usize] as usize +
             LOG[a as usize] as usize)%255]
    }
}

/// Divide one element of GF(2^8) by another.
pub fn div(e: u8, a: u8) -> u8 {
    if a == 0 {
        panic!("Divide by zero: {} / {}", e, a)
    }

    if e == 0 {
        return 0
    }

    let mut p = ((LOG[e as usize] as isize) -
                 (LOG[a as usize] as isize)) % 255;
    if p < 0 {
        p += 255
    }

    EXP[p as usize]
}

// 0x11b prime polynomial and 0x03 as generator
static EXP: [u8; 256] = [
    0x01, 0x03, 0x05, 0x0f, 0x11, 0x33, 0x55, 0xff, 0x1a, 0x2e, 0x72, 0x96,
    0xa1, 0xf8, 0x13, 0x35, 0x5f, 0xe1, 0x38, 0x48, 0xd8, 0x73, 0x95, 0xa4,
    0xf7, 0x02, 0x06, 0x0a, 0x1e, 0x22, 0x66, 0xaa, 0xe5, 0x34, 0x5c, 0xe4,
    0x37, 0x59, 0xeb, 0x26, 0x6a, 0xbe, 0xd9, 0x70, 0x90, 0xab, 0xe6, 0x31,
    0x53, 0xf5, 0x04, 0x0c, 0x14, 0x3c, 0x44, 0xcc, 0x4f, 0xd1, 0x68, 0xb8,
    0xd3, 0x6e, 0xb2, 0xcd, 0x4c, 0xd4, 0x67, 0xa9, 0xe0, 0x3b, 0x4d, 0xd7,
    0x62, 0xa6, 0xf1, 0x08, 0x18, 0x28, 0x78, 0x88, 0x83, 0x9e, 0xb9, 0xd0,
    0x6b, 0xbd, 0xdc, 0x7f, 0x81, 0x98, 0xb3, 0xce, 0x49, 0xdb, 0x76, 0x9a,
    0xb5, 0xc4, 0x57, 0xf9, 0x10, 0x30, 0x50, 0xf0, 0x0b, 0x1d, 0x27, 0x69,
    0xbb, 0xd6, 0x61, 0xa3, 0xfe, 0x19, 0x2b, 0x7d, 0x87, 0x92, 0xad, 0xec,
    0x2f, 0x71, 0x93, 0xae, 0xe9, 0x20, 0x60, 0xa0, 0xfb, 0x16, 0x3a, 0x4e,
    0xd2, 0x6d, 0xb7, 0xc2, 0x5d, 0xe7, 0x32, 0x56, 0xfa, 0x15, 0x3f, 0x41,
    0xc3, 0x5e, 0xe2, 0x3d, 0x47, 0xc9, 0x40, 0xc0, 0x5b, 0xed, 0x2c, 0x74,
    0x9c, 0xbf, 0xda, 0x75, 0x9f, 0xba, 0xd5, 0x64, 0xac, 0xef, 0x2a, 0x7e,
    0x82, 0x9d, 0xbc, 0xdf, 0x7a, 0x8e, 0x89, 0x80, 0x9b, 0xb6, 0xc1, 0x58,
    0xe8, 0x23, 0x65, 0xaf, 0xea, 0x25, 0x6f, 0xb1, 0xc8, 0x43, 0xc5, 0x54,
    0xfc, 0x1f, 0x21, 0x63, 0xa5, 0xf4, 0x07, 0x09, 0x1b, 0x2d, 0x77, 0x99,
    0xb0, 0xcb, 0x46, 0xca, 0x45, 0xcf, 0x4a, 0xde, 0x79, 0x8b, 0x86, 0x91,
    0xa8, 0xe3, 0x3e, 0x42, 0xc6, 0x51, 0xf3, 0x0e, 0x12, 0x36, 0x5a, 0xee,
    0x29, 0x7b, 0x8d, 0x8c, 0x8f, 0x8a, 0x85, 0x94, 0xa7, 0xf2, 0x0d, 0x17,
    0x39, 0x4b, 0xdd, 0x7c, 0x84, 0x97, 0xa2, 0xfd, 0x1c, 0x24, 0x6c, 0xb4,
    0xc7, 0x52, 0xf6, 0x01,
    ];

static LOG: [u8; 256] = [
    0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1a, 0xc6, 0x4b, 0xc7, 0x1b, 0x68,
    0x33, 0xee, 0xdf, 0x03, 0x64, 0x04, 0xe0, 0x0e, 0x34, 0x8d, 0x81, 0xef,
    0x4c, 0x71, 0x08, 0xc8, 0xf8, 0x69, 0x1c, 0xc1, 0x7d, 0xc2, 0x1d, 0xb5,
    0xf9, 0xb9, 0x27, 0x6a, 0x4d, 0xe4, 0xa6, 0x72, 0x9a, 0xc9, 0x09, 0x78,
    0x65, 0x2f, 0x8a, 0x05, 0x21, 0x0f, 0xe1, 0x24, 0x12, 0xf0, 0x82, 0x45,
    0x35, 0x93, 0xda, 0x8e, 0x96, 0x8f, 0xdb, 0xbd, 0x36, 0xd0, 0xce, 0x94,
    0x13, 0x5c, 0xd2, 0xf1, 0x40, 0x46, 0x83, 0x38, 0x66, 0xdd, 0xfd, 0x30,
    0xbf, 0x06, 0x8b, 0x62, 0xb3, 0x25, 0xe2, 0x98, 0x22, 0x88, 0x91, 0x10,
    0x7e, 0x6e, 0x48, 0xc3, 0xa3, 0xb6, 0x1e, 0x42, 0x3a, 0x6b, 0x28, 0x54,
    0xfa, 0x85, 0x3d, 0xba, 0x2b, 0x79, 0x0a, 0x15, 0x9b, 0x9f, 0x5e, 0xca,
    0x4e, 0xd4, 0xac, 0xe5, 0xf3, 0x73, 0xa7, 0x57, 0xaf, 0x58, 0xa8, 0x50,
    0xf4, 0xea, 0xd6, 0x74, 0x4f, 0xae, 0xe9, 0xd5, 0xe7, 0xe6, 0xad, 0xe8,
    0x2c, 0xd7, 0x75, 0x7a, 0xeb, 0x16, 0x0b, 0xf5, 0x59, 0xcb, 0x5f, 0xb0,
    0x9c, 0xa9, 0x51, 0xa0, 0x7f, 0x0c, 0xf6, 0x6f, 0x17, 0xc4, 0x49, 0xec,
    0xd8, 0x43, 0x1f, 0x2d, 0xa4, 0x76, 0x7b, 0xb7, 0xcc, 0xbb, 0x3e, 0x5a,
    0xfb, 0x60, 0xb1, 0x86, 0x3b, 0x52, 0xa1, 0x6c, 0xaa, 0x55, 0x29, 0x9d,
    0x97, 0xb2, 0x87, 0x90, 0x61, 0xbe, 0xdc, 0xfc, 0xbc, 0x95, 0xcf, 0xcd,
    0x37, 0x3f, 0x5b, 0xd1, 0x53, 0x39, 0x84, 0x3c, 0x41, 0xa2, 0x6d, 0x47,
    0x14, 0x2a, 0x9e, 0x5d, 0x56, 0xf2, 0xd3, 0xab, 0x44, 0x11, 0x92, 0xd9,
    0x23, 0x20, 0x2e, 0x89, 0xb4, 0x7c, 0xb8, 0x26, 0x77, 0x99, 0xe3, 0xa5,
    0x67, 0x4a, 0xed, 0xde, 0xc5, 0x31, 0xfe, 0x18, 0x0d, 0x63, 0x8c, 0x80,
    0xc0, 0xf7, 0x70, 0x07,
    ];

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_mul() {
        assert_eq!(mul(90, 21), 254);
    }

    #[test]
    fn test_mul_zero() {
        assert_eq!(mul(0, 21), 0);
    }

    #[test]
    fn test_div() {
        assert_eq!(div(90, 21), 189);
    }

    #[test]
    fn test_div_zero() {
        assert_eq!(div(0, 21), 0);
    }
}
<commit_msg>Syntax tidying<commit_after>//! Implements basic arithmetic operations in GF(2^8).

/// Multiply two elements of GF(2^8).
pub fn mul(e: u8, a: u8) -> u8 {
    if e == 0 || a == 0 {
        0
    } else {
        EXP[(LOG[e as usize] as usize +
             LOG[a as usize] as usize) % 255]
    }
}

/// Divide one element of GF(2^8) by another.
pub fn div(e: u8, a: u8) -> u8 {
    if a == 0 {
        panic!("Divide by zero: {} / {}", e, a)
    }

    if e == 0 {
        return 0
    }

    let mut p = (LOG[e as usize] as isize -
                 LOG[a as usize] as isize) % 255;
    if p < 0 {
        p += 255
    }

    EXP[p as usize]
}

// 0x11b prime polynomial and 0x03 as generator
static EXP: [u8; 256] = [
    0x01, 0x03, 0x05, 0x0f, 0x11, 0x33, 0x55, 0xff, 0x1a, 0x2e, 0x72, 0x96,
    0xa1, 0xf8, 0x13, 0x35, 0x5f, 0xe1, 0x38, 0x48, 0xd8, 0x73, 0x95, 0xa4,
    0xf7, 0x02, 0x06, 0x0a, 0x1e, 0x22, 0x66, 0xaa, 0xe5, 0x34, 0x5c, 0xe4,
    0x37, 0x59, 0xeb, 0x26, 0x6a, 0xbe, 0xd9, 0x70, 0x90, 0xab, 0xe6, 0x31,
    0x53, 0xf5, 0x04, 0x0c, 0x14, 0x3c, 0x44, 0xcc, 0x4f, 0xd1, 0x68, 0xb8,
    0xd3, 0x6e, 0xb2, 0xcd, 0x4c, 0xd4, 0x67, 0xa9, 0xe0, 0x3b, 0x4d, 0xd7,
    0x62, 0xa6, 0xf1, 0x08, 0x18, 0x28, 0x78, 0x88, 0x83, 0x9e, 0xb9, 0xd0,
    0x6b, 0xbd, 0xdc, 0x7f, 0x81, 0x98, 0xb3, 0xce, 0x49, 0xdb, 0x76, 0x9a,
    0xb5, 0xc4, 0x57, 0xf9, 0x10, 0x30, 0x50, 0xf0, 0x0b, 0x1d, 0x27, 0x69,
    0xbb, 0xd6, 0x61, 0xa3, 0xfe, 0x19, 0x2b, 0x7d, 0x87, 0x92, 0xad, 0xec,
    0x2f, 0x71, 0x93, 0xae, 0xe9, 0x20, 0x60, 0xa0, 0xfb, 0x16, 0x3a, 0x4e,
    0xd2, 0x6d, 0xb7, 0xc2, 0x5d, 0xe7, 0x32, 0x56, 0xfa, 0x15, 0x3f, 0x41,
    0xc3, 0x5e, 0xe2, 0x3d, 0x47, 0xc9, 0x40, 0xc0, 0x5b, 0xed, 0x2c, 0x74,
    0x9c, 0xbf, 0xda, 0x75, 0x9f, 0xba, 0xd5, 0x64, 0xac, 0xef, 0x2a, 0x7e,
    0x82, 0x9d, 0xbc, 0xdf, 0x7a, 0x8e, 0x89, 0x80, 0x9b, 0xb6, 0xc1, 0x58,
    0xe8, 0x23, 0x65, 0xaf, 0xea, 0x25, 0x6f, 0xb1, 0xc8, 0x43, 0xc5, 0x54,
    0xfc, 0x1f, 0x21, 0x63, 0xa5, 0xf4, 0x07, 0x09, 0x1b, 0x2d, 0x77, 0x99,
    0xb0, 0xcb, 0x46, 0xca, 0x45, 0xcf, 0x4a, 0xde, 0x79, 0x8b, 0x86, 0x91,
    0xa8, 0xe3, 0x3e, 0x42, 0xc6, 0x51, 0xf3, 0x0e, 0x12, 0x36, 0x5a, 0xee,
    0x29, 0x7b, 0x8d, 0x8c, 0x8f, 0x8a, 0x85, 0x94, 0xa7, 0xf2, 0x0d, 0x17,
    0x39, 0x4b, 0xdd, 0x7c, 0x84, 0x97, 0xa2, 0xfd, 0x1c, 0x24, 0x6c, 0xb4,
    0xc7, 0x52, 0xf6, 0x01,
    ];

static LOG: [u8; 256] = [
    0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1a, 0xc6, 0x4b, 0xc7, 0x1b, 0x68,
    0x33, 0xee, 0xdf, 0x03, 0x64, 0x04, 0xe0, 0x0e, 0x34, 0x8d, 0x81, 0xef,
    0x4c, 0x71, 0x08, 0xc8, 0xf8, 0x69, 0x1c, 0xc1, 0x7d, 0xc2, 0x1d, 0xb5,
    0xf9, 0xb9, 0x27, 0x6a, 0x4d, 0xe4, 0xa6, 0x72, 0x9a, 0xc9, 0x09, 0x78,
    0x65, 0x2f, 0x8a, 0x05, 0x21, 0x0f, 0xe1, 0x24, 0x12, 0xf0, 0x82, 0x45,
    0x35, 0x93, 0xda, 0x8e, 0x96, 0x8f, 0xdb, 0xbd, 0x36, 0xd0, 0xce, 0x94,
    0x13, 0x5c, 0xd2, 0xf1, 0x40, 0x46, 0x83, 0x38, 0x66, 0xdd, 0xfd, 0x30,
    0xbf, 0x06, 0x8b, 0x62, 0xb3, 0x25, 0xe2, 0x98, 0x22, 0x88, 0x91, 0x10,
    0x7e, 0x6e, 0x48, 0xc3, 0xa3, 0xb6, 0x1e, 0x42, 0x3a, 0x6b, 0x28, 0x54,
    0xfa, 0x85, 0x3d, 0xba, 0x2b, 0x79, 0x0a, 0x15, 0x9b, 0x9f, 0x5e, 0xca,
    0x4e, 0xd4, 0xac, 0xe5, 0xf3, 0x73, 0xa7, 0x57, 0xaf, 0x58, 0xa8, 0x50,
    0xf4, 0xea, 0xd6, 0x74, 0x4f, 0xae, 0xe9, 0xd5, 0xe7, 0xe6, 0xad, 0xe8,
    0x2c, 0xd7, 0x75, 0x7a, 0xeb, 0x16, 0x0b, 0xf5, 0x59, 0xcb, 0x5f, 0xb0,
    0x9c, 0xa9, 0x51, 0xa0, 0x7f, 0x0c, 0xf6, 0x6f, 0x17, 0xc4, 0x49, 0xec,
    0xd8, 0x43, 0x1f, 0x2d, 0xa4, 0x76, 0x7b, 0xb7, 0xcc, 0xbb, 0x3e, 0x5a,
    0xfb, 0x60, 0xb1, 0x86, 0x3b, 0x52, 0xa1, 0x6c, 0xaa, 0x55, 0x29, 0x9d,
    0x97, 0xb2, 0x87, 0x90, 0x61, 0xbe, 0xdc, 0xfc, 0xbc, 0x95, 0xcf, 0xcd,
    0x37, 0x3f, 0x5b, 0xd1, 0x53, 0x39, 0x84, 0x3c, 0x41, 0xa2, 0x6d, 0x47,
    0x14, 0x2a, 0x9e, 0x5d, 0x56, 0xf2, 0xd3, 0xab, 0x44, 0x11, 0x92, 0xd9,
    0x23, 0x20, 0x2e, 0x89, 0xb4, 0x7c, 0xb8, 0x26, 0x77, 0x99, 0xe3, 0xa5,
    0x67, 0x4a, 0xed, 0xde, 0xc5, 0x31, 0xfe, 0x18, 0x0d, 0x63, 0x8c, 0x80,
    0xc0, 0xf7, 0x70, 0x07,
    ];

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_mul() {
        assert_eq!(mul(90, 21), 254);
    }

    #[test]
    fn test_mul_zero() {
        assert_eq!(mul(0, 21), 0);
    }

    #[test]
    fn test_div() {
        assert_eq!(div(90, 21), 189);
    }

    #[test]
    fn test_div_zero() {
        assert_eq!(div(0, 21), 0);
    }
}
<|endoftext|>


<commit_before>//! Glyph caching

extern crate rusttype as rt;

use std::io;
use std::path::{Path};
use std::collections::hash_map::{ HashMap, Entry };
use graphics::character::{ CharacterCache, Character };
use graphics::types::{FontSize, Scalar};
use { gfx, Texture, TextureSettings };
use gfx::core::factory::CombinedError;

/// An enum to represent various possible run-time errors that may occur.
#[derive(Debug)]
pub enum Error {
    /// An error happened when creating a gfx texture.
    Texture(CombinedError),
    /// An io error happened when reading font files.
    IoError(io::Error),
}

impl From<CombinedError> for Error {
    fn from(tex_err: CombinedError) -> Self {
        Error::Texture(tex_err)
    }
}

impl From<io::Error> for Error {
    fn from(io_error: io::Error) -> Self {
        Error::IoError(io_error)
    }
}

/// A struct used for caching a rendered font.
pub struct GlyphCache<R, F> where R: gfx::Resources {
    /// The font.
    pub font: rt::Font<'static>,
    factory: F,
    // Maps from fontsize and character to offset, size and texture.
    data: HashMap<(FontSize, char), ([Scalar; 2], [Scalar; 2], Texture<R>)>
}

impl<R, F> GlyphCache<R, F> where R: gfx::Resources {
     /// Constructor for a GlyphCache.
    pub fn new<P>(font_path: P, factory: F) -> Result<Self, Error>
        where P: AsRef<Path>    {

        use std::io::Read;
        use std::fs::File;

        let mut file = try!(File::open(font_path));
        let mut file_buffer = Vec::new();
        try!(file.read_to_end(&mut file_buffer));

        let collection = rt::FontCollection::from_bytes(file_buffer);
        let font = collection.into_font().unwrap(); // only succeeds if collection consists of one font

        Ok(GlyphCache {
            font: font,
            factory: factory,
            data: HashMap::new(),
        })
    }
}

impl<R, F> CharacterCache for GlyphCache<R, F> where
    R: gfx::Resources,
    F: gfx::Factory<R>,
{
    type Texture = Texture<R>;

    fn character<'a>(
        &'a mut self,
        size: FontSize,
        ch: char
    ) -> Character<'a, Self::Texture> {
        let size = ((size as f32) * 1.333).round() as u32 ; // convert points to pixels

        match self.data.entry((size, ch)) {
            //returning `into_mut()' to get reference with 'a lifetime
            Entry::Occupied(v) => {
                let &mut (offset, size, ref texture) = v.into_mut();
                Character {
                    offset: offset,
                    size: size,
                    texture: texture
                }
            }
            Entry::Vacant(v) => {
                let glyph = self.font.glyph(ch).unwrap(); // this is only None for invalid GlyphIds, but char is converted to a Codepoint which must result in a glyph.
                let scale = rt::Scale::uniform(size as f32);
                let mut glyph = glyph.scaled(scale);

                // some fonts do not contain glyph zero as fallback, instead try U+FFFD.
                if glyph.id() == rt::GlyphId(0) && glyph.shape().is_none() {
                    glyph = self.font.glyph('\u{FFFD}').unwrap().scaled(scale);
                }

                let h_metrics = glyph.h_metrics();
                let bounding_box = glyph.exact_bounding_box().unwrap_or(rt::Rect{min: rt::Point{x: 0.0, y: 0.0}, max: rt::Point{x: 0.0, y: 0.0} });
                let glyph = glyph.positioned(rt::point(0.0, 0.0));
                let pixel_bounding_box = glyph.pixel_bounding_box().unwrap_or(rt::Rect{min: rt::Point{x: 0, y: 0}, max: rt::Point{x: 0, y: 0} });
                let pixel_bb_width = pixel_bounding_box.width();
                let pixel_bb_height = pixel_bounding_box.height();

                let mut image_buffer = Vec::<u8>::new();
                image_buffer.resize((pixel_bb_width * pixel_bb_height) as usize, 0);
                glyph.draw(|x, y, v| {
                   let pos = (x + y * (pixel_bb_width as u32)) as usize;
                   image_buffer[pos] = (255.0 * v) as u8;
                });

                let &mut (offset, size, ref texture) = v.insert((
                    [
                        bounding_box.min.x as Scalar,
                        -pixel_bounding_box.min.y as Scalar,
                    ],
                    [
                        h_metrics.advance_width as Scalar,
                        0 as Scalar,
                    ],
                    {
                        if pixel_bb_width == 0 || pixel_bb_height == 0 {
                            Texture::empty(&mut self.factory)
                                    .unwrap()
                        } else {
                            Texture::from_memory_alpha(
                                &mut self.factory,
                                &image_buffer,
                                pixel_bb_width as u32,
                                pixel_bb_height as u32,
                                &TextureSettings::new()
                            ).unwrap()
                        }
                    },
                ));
                Character {
                    offset: offset,
                    size: size,
                    texture: texture
                }
            }
        }
    }
}
<commit_msg>Return an error when no font is found, rather than panic<commit_after>//! Glyph caching

extern crate rusttype as rt;

use std::io;
use std::path::{Path};
use std::collections::hash_map::{ HashMap, Entry };
use graphics::character::{ CharacterCache, Character };
use graphics::types::{FontSize, Scalar};
use { gfx, Texture, TextureSettings };
use gfx::core::factory::CombinedError;

/// An enum to represent various possible run-time errors that may occur.
#[derive(Debug)]
pub enum Error {
    /// An error happened when creating a gfx texture.
    Texture(CombinedError),
    /// An io error happened when reading font files.
    IoError(io::Error),
    /// No font was found in the file.
    NoFont,
}

impl From<CombinedError> for Error {
    fn from(tex_err: CombinedError) -> Self {
        Error::Texture(tex_err)
    }
}

impl From<io::Error> for Error {
    fn from(io_error: io::Error) -> Self {
        Error::IoError(io_error)
    }
}

/// A struct used for caching a rendered font.
pub struct GlyphCache<R, F> where R: gfx::Resources {
    /// The font.
    pub font: rt::Font<'static>,
    factory: F,
    // Maps from fontsize and character to offset, size and texture.
    data: HashMap<(FontSize, char), ([Scalar; 2], [Scalar; 2], Texture<R>)>
}

impl<R, F> GlyphCache<R, F> where R: gfx::Resources {
     /// Constructor for a GlyphCache.
    pub fn new<P>(font_path: P, factory: F) -> Result<Self, Error>
        where P: AsRef<Path>    {

        use std::io::Read;
        use std::fs::File;

        let mut file = try!(File::open(font_path));
        let mut file_buffer = Vec::new();
        try!(file.read_to_end(&mut file_buffer));

        let collection = rt::FontCollection::from_bytes(file_buffer);
        let font = match collection.into_font() {
            Some(font) => font,
            None => return Err(Error::NoFont),
        };

        Ok(GlyphCache {
            font: font,
            factory: factory,
            data: HashMap::new(),
        })
    }
}

impl<R, F> CharacterCache for GlyphCache<R, F> where
    R: gfx::Resources,
    F: gfx::Factory<R>,
{
    type Texture = Texture<R>;

    fn character<'a>(
        &'a mut self,
        size: FontSize,
        ch: char
    ) -> Character<'a, Self::Texture> {
        let size = ((size as f32) * 1.333).round() as u32 ; // convert points to pixels

        match self.data.entry((size, ch)) {
            //returning `into_mut()' to get reference with 'a lifetime
            Entry::Occupied(v) => {
                let &mut (offset, size, ref texture) = v.into_mut();
                Character {
                    offset: offset,
                    size: size,
                    texture: texture
                }
            }
            Entry::Vacant(v) => {
                let glyph = self.font.glyph(ch).unwrap(); // this is only None for invalid GlyphIds, but char is converted to a Codepoint which must result in a glyph.
                let scale = rt::Scale::uniform(size as f32);
                let mut glyph = glyph.scaled(scale);

                // some fonts do not contain glyph zero as fallback, instead try U+FFFD.
                if glyph.id() == rt::GlyphId(0) && glyph.shape().is_none() {
                    glyph = self.font.glyph('\u{FFFD}').unwrap().scaled(scale);
                }

                let h_metrics = glyph.h_metrics();
                let bounding_box = glyph.exact_bounding_box().unwrap_or(rt::Rect{min: rt::Point{x: 0.0, y: 0.0}, max: rt::Point{x: 0.0, y: 0.0} });
                let glyph = glyph.positioned(rt::point(0.0, 0.0));
                let pixel_bounding_box = glyph.pixel_bounding_box().unwrap_or(rt::Rect{min: rt::Point{x: 0, y: 0}, max: rt::Point{x: 0, y: 0} });
                let pixel_bb_width = pixel_bounding_box.width();
                let pixel_bb_height = pixel_bounding_box.height();

                let mut image_buffer = Vec::<u8>::new();
                image_buffer.resize((pixel_bb_width * pixel_bb_height) as usize, 0);
                glyph.draw(|x, y, v| {
                   let pos = (x + y * (pixel_bb_width as u32)) as usize;
                   image_buffer[pos] = (255.0 * v) as u8;
                });

                let &mut (offset, size, ref texture) = v.insert((
                    [
                        bounding_box.min.x as Scalar,
                        -pixel_bounding_box.min.y as Scalar,
                    ],
                    [
                        h_metrics.advance_width as Scalar,
                        0 as Scalar,
                    ],
                    {
                        if pixel_bb_width == 0 || pixel_bb_height == 0 {
                            Texture::empty(&mut self.factory)
                                    .unwrap()
                        } else {
                            Texture::from_memory_alpha(
                                &mut self.factory,
                                &image_buffer,
                                pixel_bb_width as u32,
                                pixel_bb_height as u32,
                                &TextureSettings::new()
                            ).unwrap()
                        }
                    },
                ));
                Character {
                    offset: offset,
                    size: size,
                    texture: texture
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>//use std::cmp::min;
//const INF: i32 = 0x3f3f3f3f;

pub struct DisjointSets {
    parent: Vec<usize>
}

impl DisjointSets {
    pub fn new(size: usize) -> DisjointSets {
        DisjointSets { parent: (0..size).collect() }
    }

    pub fn find(&mut self, u: usize) -> usize {
        let pu = self.parent[u];
        if pu != u { self.parent[u] = self.find(pu); }
        self.parent[u]
    }

    // Returns true if u and v were previously in different sets.
    pub fn union(&mut self, u: usize, v: usize) -> bool {
        let (pu, pv) = (self.find(u), self.find(v));
        self.parent[pu] = pv;
        pu != pv
    }
}

pub struct Graph {
    pub first: Vec<Option<usize>>,
    pub next: Vec<Option<usize>>,
    pub endp: Vec<usize>,
}

impl Graph {
    pub fn new(vmax: usize, emax: usize) -> Graph {
        Graph {
            first: vec![None; vmax],
            next: Vec::with_capacity(emax),
            endp: Vec::with_capacity(emax)
        }
    }

    pub fn num_v(&self) -> usize { self.first.len() }
    pub fn num_e(&self) -> usize { self.next.len() }

    pub fn add_edge(&mut self, u: usize, v: usize) {
        self.next.push(self.first[u]);
        self.first[u] = Some(self.endp.len());
        self.endp.push(v);
    }

    pub fn add_undirected_edge(&mut self, u: usize, v: usize) {
        self.add_edge(u, v);
        self.add_edge(v, u);
    }

    // Assumes odd-numbered vertices correspond to predecessors' negations.
    // Logically equivalent forms: u || v, !u -> v, !v -> u
    pub fn add_two_sat_clause(&mut self, u: usize, v: usize) {
        self.add_edge(u^1, v);
        self.add_edge(v^1, u);
    }

    pub fn adj_list<'a>(&'a self, u: usize) -> AdjListIterator<'a> {
        AdjListIterator {
            graph: self,
            next_e: self.first[u]
        }
    }

    fn euler_helper(&self, u: usize, adj: &mut [AdjListIterator])
        -> ::std::collections::LinkedList<usize> {
        let mut edges = ::std::collections::LinkedList::new();
        if let Some((e, v)) = adj[u].next() {
            let mut tail_path = self.euler_helper(v, adj);
            if let Some((e2, v2)) = adj[u].next() {
                edges.push_back(e2);
                edges.append(&mut self.euler_helper(v2, adj));
            }
            edges.push_back(e);
            edges.append(&mut tail_path);
            assert_eq!(None, adj[u].next());
        }
        edges
    }

    // Finds an Euler path starting from u, assuming it exists, and that the
    // graph is directed.
    pub fn euler_path(&self, u: usize) -> ::std::collections::LinkedList<usize> {
        let mut adj_iters = (0..self.num_v()).map(|u| self.adj_list(u))
                            .collect::<Vec<_>>();
        self.euler_helper(u, &mut adj_iters)
    }
}

pub struct AdjListIterator<'a> {
    graph: &'a Graph,
    next_e: Option<usize>
}

impl<'a> Iterator for AdjListIterator<'a> {
    // Produces an outgoing edge and vertex.
    type Item = (usize, usize);

    fn next(&mut self) -> Option<Self::Item> {
        self.next_e.map( |e| {
            let v = self.graph.endp[e];
            self.next_e = self.graph.next[e];
            (e, v)
        })
    }
}

// Assumes graph is undirected.
pub fn min_spanning_tree(graph: &Graph, weights: &[i64]) -> Vec<usize> {
    assert_eq!(graph.num_e(), 2 * weights.len());
    let mut edges = (0..weights.len()).collect::<Vec<_>>();
    edges.sort_by_key(|&i| weights[i]);

    let mut components = DisjointSets::new(graph.num_v());
    edges.into_iter()
        .filter(|&e| components.union(graph.endp[2*e], graph.endp[2*e+1]))
        .collect()
}

#[derive(Clone)]
struct FlowVertex {
    lev: Option<usize>,
    cur: Option<usize> // TODO: consider making this an AdjListIterator
}

pub struct FlowEdge {
    pub flow: i64,
    pub cap: i64,
    pub cost: i64
}

pub struct FlowGraph {
    pub graph: Graph,
    vdata: Vec<FlowVertex>,
    pub edata: Vec<FlowEdge>,
}

impl FlowGraph {
    pub fn new(vmax: usize, emax: usize) -> FlowGraph {
        let data = FlowVertex { lev: None, cur: None };
        FlowGraph {
            graph: Graph::new(vmax, 2 * emax),
            vdata: vec![data; vmax],
            edata: Vec::with_capacity(2 * emax)
        }
    }

    pub fn add_edge(&mut self, a: usize, b: usize, cap: i64, cost: i64) {
        let data = FlowEdge { flow: 0, cap: cap, cost: cost };
        let rdata = FlowEdge { cost: -cost, ..data };
        self.edata.push(data);
        self.edata.push(rdata);
        self.graph.add_undirected_edge(a, b);
    }

    fn dfs(&mut self, u: usize, t: usize, f: i64) -> i64 {
        if u == t { return f; }
        let mut df = 0;

        while let Some(e) = self.vdata[u].cur {
            let v = self.graph.endp[e];
            if let (Some(lu), Some(lv)) = (self.vdata[u].lev, self.vdata[v].lev) {
                let rem_cap = self.edata[e].cap - self.edata[e].flow;
                if rem_cap > 0 && lv == lu + 1 {
                    let cf = self.dfs(v, t, ::std::cmp::min(rem_cap, f - df));
                    self.edata[e].flow += cf;
                    self.edata[e ^ 1].flow -= cf;
                    df += cf;
                    if df == f { break; }
                }
            }
            self.vdata[u].cur = self.graph.next[e];
        }
        return df;
    }

    fn bfs(&mut self, s: usize, t: usize) -> bool {
        for v in &mut self.vdata { v.lev = None; }
        let mut q = ::std::collections::VecDeque::<usize>::new();
        q.push_back(s);
        self.vdata[s].lev = Some(0);
        while let Some(u) = q.pop_front() {
            self.vdata[u].cur = self.graph.first[u];
            for (e, v) in self.graph.adj_list(u) {
                if self.vdata[v].lev == None && self.edata[e].flow < self.edata[e].cap {
                    q.push_back(v);
                    self.vdata[v].lev = Some(self.vdata[u].lev.unwrap() + 1);
                }
            }
        }
        self.vdata[t].lev != None
    }

    // Dinic's fast maximum flow: V^2E in general,
    // min(V^(2/3),sqrt(E))E on unit caps, sqrt(V)E on bipartite
    pub fn dinic(&mut self, s: usize, t: usize) -> i64 {
        let mut flow = 0;
        while self.bfs(s, t) {
            flow += self.dfs(s, t, 0x3f3f3f3f);
        }
        flow
    }

    pub fn min_cut(&self) -> Vec<usize> {
        (0..self.graph.num_e()).filter( |&e| {
            let u = self.graph.endp[e ^ 1];
            let v = self.graph.endp[e];
            self.vdata[u].lev.is_some() && self.vdata[v].lev.is_none()
        }).collect()
    }
}

// 2-vertex and 2-edge connected components
// should handle multiple-edges and self-loops
// USAGE: 1) new(); 2) add_edge(...); 3) compute_bcc();
// 4) use is_cut_vertex(vertex_index) or is_cut_edge(2 * edge_index)

#[derive(Clone)]
pub struct CCVertex {
    pub cc: usize,
    low: usize,
    vis: usize,
}

pub struct CCGraph<'a> {
    pub graph: &'a Graph,
    pub vdata: Vec<CCVertex>,
    pub vcc: Vec<usize>,
    pub n_cc: usize,
    pub n_vcc: usize,
    t: usize,
    verts: ::std::collections::VecDeque<usize>,
    //edges: ::std::collections::VecDeque<usize>
}

impl<'a> CCGraph<'a> {
    pub fn new(graph: &'a Graph) -> CCGraph {
        let data = CCVertex { cc: 0, low: 0, vis: 0 };
        let mut cc_graph = CCGraph {
            graph: graph,
            vdata: vec![data; graph.num_v()],
            vcc: vec![0; graph.num_e()],
            n_cc: 0,
            n_vcc: 0,
            t: 0,
            verts: ::std::collections::VecDeque::new(),
            //edges: ::std::collections::VecDeque::new()
        };
        for i in 0..graph.num_v() {
            if cc_graph.vdata[i].vis == 0 {
                cc_graph.scc(i);
            }
        }
        cc_graph
    }

    // SCCs form a DAG whose components are numbered in reverse topological order.
    fn scc(&mut self, u: usize) {
        self.t += 1;
        self.vdata[u].low = self.t;
        self.vdata[u].vis = self.t;
        self.verts.push_back(u);
        for (_, v) in self.graph.adj_list(u) {
            if self.vdata[v].vis == 0 { self.scc(v); }
            if self.vdata[v].cc == 0 {
                self.vdata[u].low = ::std::cmp::min(self.vdata[u].low, self.vdata[v].low);
            }
        }
        if self.vdata[u].vis <= self.vdata[u].low {
            self.n_cc += 1;
            while let Some(v) = self.verts.pop_back() {
                self.vdata[v].cc = self.n_cc;
                if v == u { break; }
            }
        }
    }

    pub fn two_sat_assign(&self) -> Option<Vec<bool>> {
        (0..self.graph.num_v()/2).map( |i| {
            let scc_true = self.vdata[2*i].cc;
            let scc_false = self.vdata[2*i+1].cc;
            if scc_true == scc_false { None } else { Some(scc_true < scc_false) }
        }).collect()
    }

    /*fn bcc(&mut self, u: usize, par: usize) {
        self.t += 1;
        self.vdata[u].low = self.t;
        self.vdata[u].vis = self.t;
        self.verts.push_back(u);
        for (e, v) in self.graph.adj_list(u) {
          if self.vdata[v] == None {
              self.edges.push_back(e);
              self.bcc(v, e);
              self.vdata[u].low = ::std::cmp::min(self.vdata[u].low, self.vdata[v].low);
              if self.vdata[u].vis <= self.vdata[v].low { // u is a cut vertex unless it's a one-child root
                  do {
                      let E = self.edges.top();
                      self.edges.pop_back();
                      vcc[E] = self.n_vcc;
                      vcc[E^1] = self.n_vcc;
                  } while e != E && e != (E^1);
                  self.n_vcc += 1;
              }
          }
          else if self.vdata[v].vis < self.vdata[u].vis && e != (par^1) {
              self.vdata[u].low = ::std::cmp::min(self.vdata[u].low, self.vdata[v].vis);
              self.edges.push_back(e);
          }
          else if v == u { // e is a self-loop
              self.vcc[e] = self.n_vcc;
              self.vcc[e ^ 1] = self.n_vcc;
              self.n_vcc += 1;
          }
        }
        if self.vdata[u].vis <= self.vdata[u].low { // par is a cut edge unless par==-1
            do { v = self.verts.top(); self.verts.pop_back(); self.vdata[v].cc = self.n_cc; }
            while (v != u);
            self.n_cc += 1;
        }
    }

    pub fn is_cut_vertex(&self, u: usize) -> bool {
        let vcc = self.vcc[self.graph.first[u]];
        for (e, _) in self.graph.adj_list(u) {
            if (self.vcc[e] != vcc) { return true; }
        }
        false
    }

    pub fn is_cut_edge(&self, e: usize) -> bool {
        let u = self.graph.endp[e ^ 1];
        let v = self.graph.endp[e];
        self.vdata[u].cc != self.vdata[v].cc
    }*/
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_euler()
    {
        let mut graph = Graph::new(3, 4);
        graph.add_edge(0, 1);
        graph.add_edge(1, 0);
        graph.add_edge(1, 2);
        graph.add_edge(2, 1);
        let euler = graph.euler_path(0).into_iter().collect::<Vec<_>>();
        assert_eq!(euler, vec![0, 2, 3, 1]);
    }

    #[test]
    fn test_min_spanning_tree()
    {
        let mut graph = Graph::new(3, 3);
        graph.add_undirected_edge(0, 1);
        graph.add_undirected_edge(1, 2);
        graph.add_undirected_edge(2, 0);
        let weights = [7, 3, 5];
        let mst = min_spanning_tree(&graph, &weights);
        assert_eq!(mst, vec![1, 2]);
    }

    #[test]
    fn test_basic_flow()
    {
        let mut graph = FlowGraph::new(3, 2);
        graph.add_edge(0, 1, 4, 1);
        graph.add_edge(1, 2, 3, 1);
        let flow = graph.dinic(0, 2);
        assert_eq!(flow, 3);
    }

    #[test]
    fn test_two_sat()
    {
        let mut graph = Graph::new(6, 8);
        let (x, y, z) = (0, 2, 4);

        graph.add_two_sat_clause(x, z);
        graph.add_two_sat_clause(y^1, z^1);
        graph.add_two_sat_clause(y, y);
        assert_eq!(CCGraph::new(&graph).two_sat_assign(),
                   Some(vec![true, true, false]));

        graph.add_two_sat_clause(z, z);
        assert_eq!(CCGraph::new(&graph).two_sat_assign(), None);
    }
}
<commit_msg>Simplified Euler path<commit_after>//use std::cmp::min;
//const INF: i32 = 0x3f3f3f3f;

pub struct DisjointSets {
    parent: Vec<usize>
}

impl DisjointSets {
    pub fn new(size: usize) -> DisjointSets {
        DisjointSets { parent: (0..size).collect() }
    }

    pub fn find(&mut self, u: usize) -> usize {
        let pu = self.parent[u];
        if pu != u { self.parent[u] = self.find(pu); }
        self.parent[u]
    }

    // Returns true if u and v were previously in different sets.
    pub fn union(&mut self, u: usize, v: usize) -> bool {
        let (pu, pv) = (self.find(u), self.find(v));
        self.parent[pu] = pv;
        pu != pv
    }
}

pub struct Graph {
    pub first: Vec<Option<usize>>,
    pub next: Vec<Option<usize>>,
    pub endp: Vec<usize>,
}

impl Graph {
    pub fn new(vmax: usize, emax: usize) -> Graph {
        Graph {
            first: vec![None; vmax],
            next: Vec::with_capacity(emax),
            endp: Vec::with_capacity(emax)
        }
    }

    pub fn num_v(&self) -> usize { self.first.len() }
    pub fn num_e(&self) -> usize { self.next.len() }

    pub fn add_edge(&mut self, u: usize, v: usize) {
        self.next.push(self.first[u]);
        self.first[u] = Some(self.endp.len());
        self.endp.push(v);
    }

    pub fn add_undirected_edge(&mut self, u: usize, v: usize) {
        self.add_edge(u, v);
        self.add_edge(v, u);
    }

    // Assumes odd-numbered vertices correspond to predecessors' negations.
    // Logically equivalent forms: u || v, !u -> v, !v -> u
    pub fn add_two_sat_clause(&mut self, u: usize, v: usize) {
        self.add_edge(u^1, v);
        self.add_edge(v^1, u);
    }

    pub fn adj_list<'a>(&'a self, u: usize) -> AdjListIterator<'a> {
        AdjListIterator {
            graph: self,
            next_e: self.first[u]
        }
    }

    fn euler_helper(&self, u: usize, adj: &mut [AdjListIterator], edges: &mut Vec<usize>) {
        while let Some((e, v)) = adj[u].next() {
            self.euler_helper(v, adj, edges);
            edges.push(e);
        }
    }

    // Finds an Euler path starting from u, assuming it exists, and that the
    // graph is directed.
    pub fn euler_path(&self, u: usize) -> Vec<usize> {
        let mut adj_iters = (0..self.num_v()).map(|u| self.adj_list(u))
                            .collect::<Vec<_>>();
        let mut edges = Vec::with_capacity(self.num_e());
        self.euler_helper(u, &mut adj_iters, &mut edges);
        edges.into_iter().rev().collect()
    }
}

pub struct AdjListIterator<'a> {
    graph: &'a Graph,
    next_e: Option<usize>
}

impl<'a> Iterator for AdjListIterator<'a> {
    // Produces an outgoing edge and vertex.
    type Item = (usize, usize);

    fn next(&mut self) -> Option<Self::Item> {
        self.next_e.map( |e| {
            let v = self.graph.endp[e];
            self.next_e = self.graph.next[e];
            (e, v)
        })
    }
}

// Assumes graph is undirected.
pub fn min_spanning_tree(graph: &Graph, weights: &[i64]) -> Vec<usize> {
    assert_eq!(graph.num_e(), 2 * weights.len());
    let mut edges = (0..weights.len()).collect::<Vec<_>>();
    edges.sort_by_key(|&i| weights[i]);

    let mut components = DisjointSets::new(graph.num_v());
    edges.into_iter()
        .filter(|&e| components.union(graph.endp[2*e], graph.endp[2*e+1]))
        .collect()
}

#[derive(Clone)]
struct FlowVertex {
    lev: Option<usize>,
    cur: Option<usize> // TODO: consider making this an AdjListIterator
}

pub struct FlowEdge {
    pub flow: i64,
    pub cap: i64,
    pub cost: i64
}

pub struct FlowGraph {
    pub graph: Graph,
    vdata: Vec<FlowVertex>,
    pub edata: Vec<FlowEdge>,
}

impl FlowGraph {
    pub fn new(vmax: usize, emax: usize) -> FlowGraph {
        let data = FlowVertex { lev: None, cur: None };
        FlowGraph {
            graph: Graph::new(vmax, 2 * emax),
            vdata: vec![data; vmax],
            edata: Vec::with_capacity(2 * emax)
        }
    }

    pub fn add_edge(&mut self, a: usize, b: usize, cap: i64, cost: i64) {
        let data = FlowEdge { flow: 0, cap: cap, cost: cost };
        let rdata = FlowEdge { cost: -cost, ..data };
        self.edata.push(data);
        self.edata.push(rdata);
        self.graph.add_undirected_edge(a, b);
    }

    fn dfs(&mut self, u: usize, t: usize, f: i64) -> i64 {
        if u == t { return f; }
        let mut df = 0;

        while let Some(e) = self.vdata[u].cur {
            let v = self.graph.endp[e];
            if let (Some(lu), Some(lv)) = (self.vdata[u].lev, self.vdata[v].lev) {
                let rem_cap = self.edata[e].cap - self.edata[e].flow;
                if rem_cap > 0 && lv == lu + 1 {
                    let cf = self.dfs(v, t, ::std::cmp::min(rem_cap, f - df));
                    self.edata[e].flow += cf;
                    self.edata[e ^ 1].flow -= cf;
                    df += cf;
                    if df == f { break; }
                }
            }
            self.vdata[u].cur = self.graph.next[e];
        }
        return df;
    }

    fn bfs(&mut self, s: usize, t: usize) -> bool {
        for v in &mut self.vdata { v.lev = None; }
        let mut q = ::std::collections::VecDeque::<usize>::new();
        q.push_back(s);
        self.vdata[s].lev = Some(0);
        while let Some(u) = q.pop_front() {
            self.vdata[u].cur = self.graph.first[u];
            for (e, v) in self.graph.adj_list(u) {
                if self.vdata[v].lev == None && self.edata[e].flow < self.edata[e].cap {
                    q.push_back(v);
                    self.vdata[v].lev = Some(self.vdata[u].lev.unwrap() + 1);
                }
            }
        }
        self.vdata[t].lev != None
    }

    // Dinic's fast maximum flow: V^2E in general,
    // min(V^(2/3),sqrt(E))E on unit caps, sqrt(V)E on bipartite
    pub fn dinic(&mut self, s: usize, t: usize) -> i64 {
        let mut flow = 0;
        while self.bfs(s, t) {
            flow += self.dfs(s, t, 0x3f3f3f3f);
        }
        flow
    }

    pub fn min_cut(&self) -> Vec<usize> {
        (0..self.graph.num_e()).filter( |&e| {
            let u = self.graph.endp[e ^ 1];
            let v = self.graph.endp[e];
            self.vdata[u].lev.is_some() && self.vdata[v].lev.is_none()
        }).collect()
    }
}

// 2-vertex and 2-edge connected components
// should handle multiple-edges and self-loops
// USAGE: 1) new(); 2) add_edge(...); 3) compute_bcc();
// 4) use is_cut_vertex(vertex_index) or is_cut_edge(2 * edge_index)

#[derive(Clone)]
pub struct CCVertex {
    pub cc: usize,
    low: usize,
    vis: usize,
}

pub struct CCGraph<'a> {
    pub graph: &'a Graph,
    pub vdata: Vec<CCVertex>,
    pub vcc: Vec<usize>,
    pub n_cc: usize,
    pub n_vcc: usize,
    t: usize,
    verts: ::std::collections::VecDeque<usize>,
    //edges: ::std::collections::VecDeque<usize>
}

impl<'a> CCGraph<'a> {
    pub fn new(graph: &'a Graph) -> CCGraph {
        let data = CCVertex { cc: 0, low: 0, vis: 0 };
        let mut cc_graph = CCGraph {
            graph: graph,
            vdata: vec![data; graph.num_v()],
            vcc: vec![0; graph.num_e()],
            n_cc: 0,
            n_vcc: 0,
            t: 0,
            verts: ::std::collections::VecDeque::new(),
            //edges: ::std::collections::VecDeque::new()
        };
        for i in 0..graph.num_v() {
            if cc_graph.vdata[i].vis == 0 {
                cc_graph.scc(i);
            }
        }
        cc_graph
    }

    // SCCs form a DAG whose components are numbered in reverse topological order.
    fn scc(&mut self, u: usize) {
        self.t += 1;
        self.vdata[u].low = self.t;
        self.vdata[u].vis = self.t;
        self.verts.push_back(u);
        for (_, v) in self.graph.adj_list(u) {
            if self.vdata[v].vis == 0 { self.scc(v); }
            if self.vdata[v].cc == 0 {
                self.vdata[u].low = ::std::cmp::min(self.vdata[u].low, self.vdata[v].low);
            }
        }
        if self.vdata[u].vis <= self.vdata[u].low {
            self.n_cc += 1;
            while let Some(v) = self.verts.pop_back() {
                self.vdata[v].cc = self.n_cc;
                if v == u { break; }
            }
        }
    }

    pub fn two_sat_assign(&self) -> Option<Vec<bool>> {
        (0..self.graph.num_v()/2).map( |i| {
            let scc_true = self.vdata[2*i].cc;
            let scc_false = self.vdata[2*i+1].cc;
            if scc_true == scc_false { None } else { Some(scc_true < scc_false) }
        }).collect()
    }

    /*fn bcc(&mut self, u: usize, par: usize) {
        self.t += 1;
        self.vdata[u].low = self.t;
        self.vdata[u].vis = self.t;
        self.verts.push_back(u);
        for (e, v) in self.graph.adj_list(u) {
          if self.vdata[v] == None {
              self.edges.push_back(e);
              self.bcc(v, e);
              self.vdata[u].low = ::std::cmp::min(self.vdata[u].low, self.vdata[v].low);
              if self.vdata[u].vis <= self.vdata[v].low { // u is a cut vertex unless it's a one-child root
                  do {
                      let E = self.edges.top();
                      self.edges.pop_back();
                      vcc[E] = self.n_vcc;
                      vcc[E^1] = self.n_vcc;
                  } while e != E && e != (E^1);
                  self.n_vcc += 1;
              }
          }
          else if self.vdata[v].vis < self.vdata[u].vis && e != (par^1) {
              self.vdata[u].low = ::std::cmp::min(self.vdata[u].low, self.vdata[v].vis);
              self.edges.push_back(e);
          }
          else if v == u { // e is a self-loop
              self.vcc[e] = self.n_vcc;
              self.vcc[e ^ 1] = self.n_vcc;
              self.n_vcc += 1;
          }
        }
        if self.vdata[u].vis <= self.vdata[u].low { // par is a cut edge unless par==-1
            do { v = self.verts.top(); self.verts.pop_back(); self.vdata[v].cc = self.n_cc; }
            while (v != u);
            self.n_cc += 1;
        }
    }

    pub fn is_cut_vertex(&self, u: usize) -> bool {
        let vcc = self.vcc[self.graph.first[u]];
        for (e, _) in self.graph.adj_list(u) {
            if (self.vcc[e] != vcc) { return true; }
        }
        false
    }

    pub fn is_cut_edge(&self, e: usize) -> bool {
        let u = self.graph.endp[e ^ 1];
        let v = self.graph.endp[e];
        self.vdata[u].cc != self.vdata[v].cc
    }*/
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_euler()
    {
        let mut graph = Graph::new(3, 4);
        graph.add_edge(0, 1);
        graph.add_edge(1, 0);
        graph.add_edge(1, 2);
        graph.add_edge(2, 1);
        assert_eq!(graph.euler_path(0), vec![0, 2, 3, 1]);
    }

    #[test]
    fn test_min_spanning_tree()
    {
        let mut graph = Graph::new(3, 3);
        graph.add_undirected_edge(0, 1);
        graph.add_undirected_edge(1, 2);
        graph.add_undirected_edge(2, 0);
        let weights = [7, 3, 5];
        let mst = min_spanning_tree(&graph, &weights);
        assert_eq!(mst, vec![1, 2]);
    }

    #[test]
    fn test_basic_flow()
    {
        let mut graph = FlowGraph::new(3, 2);
        graph.add_edge(0, 1, 4, 1);
        graph.add_edge(1, 2, 3, 1);
        let flow = graph.dinic(0, 2);
        assert_eq!(flow, 3);
    }

    #[test]
    fn test_two_sat()
    {
        let mut graph = Graph::new(6, 8);
        let (x, y, z) = (0, 2, 4);

        graph.add_two_sat_clause(x, z);
        graph.add_two_sat_clause(y^1, z^1);
        graph.add_two_sat_clause(y, y);
        assert_eq!(CCGraph::new(&graph).two_sat_assign(),
                   Some(vec![true, true, false]));

        graph.add_two_sat_clause(z, z);
        assert_eq!(CCGraph::new(&graph).two_sat_assign(), None);
    }
}
<|endoftext|>


<commit_before>use std::cell::{Cell, RefCell};
use std::ops::Deref;

use cairo;
use owning_ref::RcRef;

use attributes::Attribute;
use coord_units::CoordUnits;
use drawing_ctx::DrawingCtx;
use error::AttributeError;
use handle::RsvgHandle;
use length::{Length, LengthDir, LengthUnit};
use node::{NodeResult, NodeTrait, NodeType, RsvgNode};
use parsers::{parse_and_validate, ParseError};
use property_bag::PropertyBag;
use state::ColorInterpolationFilters;
use surface_utils::shared_surface::{SharedImageSurface, SurfaceType};

mod bounds;
use self::bounds::BoundsBuilder;

pub mod context;
use self::context::{FilterContext, FilterInput, FilterResult};

mod error;
use self::error::FilterError;

mod input;
use self::input::Input;

pub mod node;
use self::node::NodeFilter;

pub mod blend;
pub mod color_matrix;
pub mod component_transfer;
pub mod composite;
pub mod convolve_matrix;
pub mod displacement_map;
pub mod flood;
pub mod gaussian_blur;
pub mod image;
pub mod light;
pub mod merge;
pub mod morphology;
pub mod offset;
pub mod tile;
pub mod turbulence;

/// A filter primitive interface.
trait Filter: NodeTrait {
    /// Renders this filter primitive.
    ///
    /// If this filter primitive can't be rendered for whatever reason (for instance, a required
    /// property hasn't been provided), an error is returned.
    fn render(
        &self,
        node: &RsvgNode,
        ctx: &FilterContext,
        draw_ctx: &mut DrawingCtx,
    ) -> Result<FilterResult, FilterError>;

    /// Returns `true` if this filter primitive is affected by the `color-interpolation-filters`
    /// property.
    ///
    /// Primitives that do color blending (like `feComposite` or `feBlend`) should return `true`
    /// here, whereas primitives that don't (like `feOffset`) should return `false`.
    fn is_affected_by_color_interpolation_filters(&self) -> bool;
}

/// The base filter primitive node containing common properties.
struct Primitive {
    x: Cell<Option<Length>>,
    y: Cell<Option<Length>>,
    width: Cell<Option<Length>>,
    height: Cell<Option<Length>>,
    result: RefCell<Option<String>>,
}

/// The base node for filter primitives which accept input.
struct PrimitiveWithInput {
    base: Primitive,
    in_: RefCell<Option<Input>>,
}

impl Primitive {
    /// Constructs a new `Primitive` with empty properties.
    #[inline]
    fn new<T: Filter>() -> Primitive {
        Primitive {
            x: Cell::new(None),
            y: Cell::new(None),
            width: Cell::new(None),
            height: Cell::new(None),
            result: RefCell::new(None),
        }
    }

    /// Returns the `BoundsBuilder` for bounds computation.
    #[inline]
    fn get_bounds<'a>(&self, ctx: &'a FilterContext) -> BoundsBuilder<'a> {
        BoundsBuilder::new(
            ctx,
            self.x.get(),
            self.y.get(),
            self.width.get(),
            self.height.get(),
        )
    }
}

impl NodeTrait for Primitive {
    fn set_atts(&self, node: &RsvgNode, _: *const RsvgHandle, pbag: &PropertyBag) -> NodeResult {
        // With ObjectBoundingBox, only fractions and percents are allowed.
        let primitiveunits = node
            .get_parent()
            .and_then(|parent| {
                if parent.get_type() == NodeType::Filter {
                    Some(parent.with_impl(|f: &NodeFilter| f.primitiveunits.get()))
                } else {
                    None
                }
            }).unwrap_or(CoordUnits::UserSpaceOnUse);

        let no_units_allowed = primitiveunits == CoordUnits::ObjectBoundingBox;
        let check_units = |length: Length| {
            if !no_units_allowed {
                return Ok(length);
            }

            match length.unit {
                LengthUnit::Default | LengthUnit::Percent => Ok(length),
                _ => Err(AttributeError::Parse(ParseError::new(
                    "unit identifiers are not allowed with primitiveUnits set to objectBoundingBox",
                ))),
            }
        };
        let check_units_and_ensure_nonnegative =
            |length: Length| check_units(length).and_then(Length::check_nonnegative);

        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::X => self.x.set(Some(parse_and_validate(
                    "x",
                    value,
                    LengthDir::Horizontal,
                    check_units,
                )?)),
                Attribute::Y => self.y.set(Some(parse_and_validate(
                    "y",
                    value,
                    LengthDir::Vertical,
                    check_units,
                )?)),
                Attribute::Width => self.width.set(Some(parse_and_validate(
                    "width",
                    value,
                    LengthDir::Horizontal,
                    check_units_and_ensure_nonnegative,
                )?)),
                Attribute::Height => self.height.set(Some(parse_and_validate(
                    "height",
                    value,
                    LengthDir::Vertical,
                    check_units_and_ensure_nonnegative,
                )?)),
                Attribute::Result => *self.result.borrow_mut() = Some(value.to_string()),
                _ => (),
            }
        }

        Ok(())
    }
}

impl PrimitiveWithInput {
    /// Constructs a new `PrimitiveWithInput` with empty properties.
    #[inline]
    fn new<T: Filter>() -> PrimitiveWithInput {
        PrimitiveWithInput {
            base: Primitive::new::<T>(),
            in_: RefCell::new(None),
        }
    }

    /// Returns the input Cairo surface for this filter primitive.
    #[inline]
    fn get_input(
        &self,
        ctx: &FilterContext,
        draw_ctx: &mut DrawingCtx,
    ) -> Result<FilterInput, FilterError> {
        ctx.get_input(draw_ctx, self.in_.borrow().as_ref())
    }
}

impl NodeTrait for PrimitiveWithInput {
    fn set_atts(
        &self,
        node: &RsvgNode,
        handle: *const RsvgHandle,
        pbag: &PropertyBag,
    ) -> NodeResult {
        self.base.set_atts(node, handle, pbag)?;

        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::In => drop(self.in_.replace(Some(Input::parse(Attribute::In, value)?))),
                _ => (),
            }
        }

        Ok(())
    }
}

impl Deref for PrimitiveWithInput {
    type Target = Primitive;

    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.base
    }
}

/// Applies a filter and returns the resulting surface.
pub fn render(
    filter_node: &RsvgNode,
    node_being_filtered: &RsvgNode,
    source: &cairo::ImageSurface,
    draw_ctx: &mut DrawingCtx,
) -> cairo::ImageSurface {
    let filter_node = &*filter_node;
    assert_eq!(filter_node.get_type(), NodeType::Filter);
    assert!(!filter_node.is_in_error());

    // The source surface has multiple references. We need to copy it to a new surface to have a
    // unique reference to be able to safely access the pixel data.
    let source_surface = cairo::ImageSurface::create(
        cairo::Format::ARgb32,
        source.get_width(),
        source.get_height(),
    ).unwrap();
    {
        let cr = cairo::Context::new(&source_surface);
        cr.set_source_surface(source, 0f64, 0f64);
        cr.paint();
    }
    let source_surface = SharedImageSurface::new(source_surface, SurfaceType::SRgb).unwrap();

    let mut filter_ctx =
        FilterContext::new(filter_node, node_being_filtered, source_surface, draw_ctx);

    filter_node
        .children()
        // Skip nodes in error.
        .filter(|c| {
            let in_error = c.is_in_error();

            if in_error {
                rsvg_log!(
                    "(ignoring filter primitive {} because it is in error)",
                    c.get_human_readable_name()
                );
            }

            !in_error
        })
        // Check if the node wants linear RGB.
        .map(|c| {
            let linear_rgb = {
                let cascaded = c.get_cascaded_values();
                let values = cascaded.get();

                values.color_interpolation_filters == ColorInterpolationFilters::LinearRgb
            };

            (c, linear_rgb)
        })
        .filter_map(|(c, linear_rgb)| {
            let rr = RcRef::new(c).try_map(|c| {
                // Go through the filter primitives and see if the node is one of them.
                #[inline]
                fn as_filter<T: Filter>(x: &T) -> &Filter {
                    x
                }

                // Unfortunately it's not possible to downcast to a trait object. If we could
                // attach arbitrary data to nodes it would really help here. Previously that
                // arbitrary data was in form of RsvgCNodeImpl, but that was heavily tuned for
                // storing C pointers with all subsequent downsides.
                macro_rules! try_downcasting_to_filter {
                    ($c:expr; $($t:ty),+$(,)*) => ({
                        let mut filter = None;
                        $(
                            filter = filter.or_else(|| $c.get_impl::<$t>().map(as_filter));
                        )+
                        filter
                    })
                }

                let filter = try_downcasting_to_filter!(
                    c;
                    blend::Blend,
                    color_matrix::ColorMatrix,
                    component_transfer::ComponentTransfer,
                    composite::Composite,
                    convolve_matrix::ConvolveMatrix,
                    displacement_map::DisplacementMap,
                    flood::Flood,
                    gaussian_blur::GaussianBlur,
                    image::Image,
                    light::lighting::Lighting,
                    merge::Merge,
                    morphology::Morphology,
                    offset::Offset,
                    tile::Tile,
                    turbulence::Turbulence,
                );
                filter.ok_or(())
            }).ok();

            rr.map(|rr| (rr, linear_rgb))
        })
        .for_each(|(rr, linear_rgb)| {
            let mut render = |filter_ctx: &mut FilterContext| {
                if let Err(_) = rr.render(rr.owner(), filter_ctx, draw_ctx)
                    .and_then(|result| filter_ctx.store_result(result))
                {
                    // Filter::render() returned an error. Do nothing for now.
                }
            };

            if rr.is_affected_by_color_interpolation_filters() && linear_rgb {
                filter_ctx.with_linear_rgb(render);
            } else {
                render(&mut filter_ctx);
            }
        });

    filter_ctx
        .into_output()
        .expect("could not create an empty surface to return from a filter")
        .into_image_surface()
        .expect("could not convert filter output into an ImageSurface")
}
<commit_msg>Log errors from filter rendering<commit_after>use std::cell::{Cell, RefCell};
use std::ops::Deref;

use cairo;
use owning_ref::RcRef;

use attributes::Attribute;
use coord_units::CoordUnits;
use drawing_ctx::DrawingCtx;
use error::AttributeError;
use handle::RsvgHandle;
use length::{Length, LengthDir, LengthUnit};
use node::{NodeResult, NodeTrait, NodeType, RsvgNode};
use parsers::{parse_and_validate, ParseError};
use property_bag::PropertyBag;
use state::ColorInterpolationFilters;
use surface_utils::shared_surface::{SharedImageSurface, SurfaceType};

mod bounds;
use self::bounds::BoundsBuilder;

pub mod context;
use self::context::{FilterContext, FilterInput, FilterResult};

mod error;
use self::error::FilterError;

mod input;
use self::input::Input;

pub mod node;
use self::node::NodeFilter;

pub mod blend;
pub mod color_matrix;
pub mod component_transfer;
pub mod composite;
pub mod convolve_matrix;
pub mod displacement_map;
pub mod flood;
pub mod gaussian_blur;
pub mod image;
pub mod light;
pub mod merge;
pub mod morphology;
pub mod offset;
pub mod tile;
pub mod turbulence;

/// A filter primitive interface.
trait Filter: NodeTrait {
    /// Renders this filter primitive.
    ///
    /// If this filter primitive can't be rendered for whatever reason (for instance, a required
    /// property hasn't been provided), an error is returned.
    fn render(
        &self,
        node: &RsvgNode,
        ctx: &FilterContext,
        draw_ctx: &mut DrawingCtx,
    ) -> Result<FilterResult, FilterError>;

    /// Returns `true` if this filter primitive is affected by the `color-interpolation-filters`
    /// property.
    ///
    /// Primitives that do color blending (like `feComposite` or `feBlend`) should return `true`
    /// here, whereas primitives that don't (like `feOffset`) should return `false`.
    fn is_affected_by_color_interpolation_filters(&self) -> bool;
}

/// The base filter primitive node containing common properties.
struct Primitive {
    x: Cell<Option<Length>>,
    y: Cell<Option<Length>>,
    width: Cell<Option<Length>>,
    height: Cell<Option<Length>>,
    result: RefCell<Option<String>>,
}

/// The base node for filter primitives which accept input.
struct PrimitiveWithInput {
    base: Primitive,
    in_: RefCell<Option<Input>>,
}

impl Primitive {
    /// Constructs a new `Primitive` with empty properties.
    #[inline]
    fn new<T: Filter>() -> Primitive {
        Primitive {
            x: Cell::new(None),
            y: Cell::new(None),
            width: Cell::new(None),
            height: Cell::new(None),
            result: RefCell::new(None),
        }
    }

    /// Returns the `BoundsBuilder` for bounds computation.
    #[inline]
    fn get_bounds<'a>(&self, ctx: &'a FilterContext) -> BoundsBuilder<'a> {
        BoundsBuilder::new(
            ctx,
            self.x.get(),
            self.y.get(),
            self.width.get(),
            self.height.get(),
        )
    }
}

impl NodeTrait for Primitive {
    fn set_atts(&self, node: &RsvgNode, _: *const RsvgHandle, pbag: &PropertyBag) -> NodeResult {
        // With ObjectBoundingBox, only fractions and percents are allowed.
        let primitiveunits = node
            .get_parent()
            .and_then(|parent| {
                if parent.get_type() == NodeType::Filter {
                    Some(parent.with_impl(|f: &NodeFilter| f.primitiveunits.get()))
                } else {
                    None
                }
            }).unwrap_or(CoordUnits::UserSpaceOnUse);

        let no_units_allowed = primitiveunits == CoordUnits::ObjectBoundingBox;
        let check_units = |length: Length| {
            if !no_units_allowed {
                return Ok(length);
            }

            match length.unit {
                LengthUnit::Default | LengthUnit::Percent => Ok(length),
                _ => Err(AttributeError::Parse(ParseError::new(
                    "unit identifiers are not allowed with primitiveUnits set to objectBoundingBox",
                ))),
            }
        };
        let check_units_and_ensure_nonnegative =
            |length: Length| check_units(length).and_then(Length::check_nonnegative);

        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::X => self.x.set(Some(parse_and_validate(
                    "x",
                    value,
                    LengthDir::Horizontal,
                    check_units,
                )?)),
                Attribute::Y => self.y.set(Some(parse_and_validate(
                    "y",
                    value,
                    LengthDir::Vertical,
                    check_units,
                )?)),
                Attribute::Width => self.width.set(Some(parse_and_validate(
                    "width",
                    value,
                    LengthDir::Horizontal,
                    check_units_and_ensure_nonnegative,
                )?)),
                Attribute::Height => self.height.set(Some(parse_and_validate(
                    "height",
                    value,
                    LengthDir::Vertical,
                    check_units_and_ensure_nonnegative,
                )?)),
                Attribute::Result => *self.result.borrow_mut() = Some(value.to_string()),
                _ => (),
            }
        }

        Ok(())
    }
}

impl PrimitiveWithInput {
    /// Constructs a new `PrimitiveWithInput` with empty properties.
    #[inline]
    fn new<T: Filter>() -> PrimitiveWithInput {
        PrimitiveWithInput {
            base: Primitive::new::<T>(),
            in_: RefCell::new(None),
        }
    }

    /// Returns the input Cairo surface for this filter primitive.
    #[inline]
    fn get_input(
        &self,
        ctx: &FilterContext,
        draw_ctx: &mut DrawingCtx,
    ) -> Result<FilterInput, FilterError> {
        ctx.get_input(draw_ctx, self.in_.borrow().as_ref())
    }
}

impl NodeTrait for PrimitiveWithInput {
    fn set_atts(
        &self,
        node: &RsvgNode,
        handle: *const RsvgHandle,
        pbag: &PropertyBag,
    ) -> NodeResult {
        self.base.set_atts(node, handle, pbag)?;

        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::In => drop(self.in_.replace(Some(Input::parse(Attribute::In, value)?))),
                _ => (),
            }
        }

        Ok(())
    }
}

impl Deref for PrimitiveWithInput {
    type Target = Primitive;

    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.base
    }
}

/// Applies a filter and returns the resulting surface.
pub fn render(
    filter_node: &RsvgNode,
    node_being_filtered: &RsvgNode,
    source: &cairo::ImageSurface,
    draw_ctx: &mut DrawingCtx,
) -> cairo::ImageSurface {
    let filter_node = &*filter_node;
    assert_eq!(filter_node.get_type(), NodeType::Filter);
    assert!(!filter_node.is_in_error());

    // The source surface has multiple references. We need to copy it to a new surface to have a
    // unique reference to be able to safely access the pixel data.
    let source_surface = cairo::ImageSurface::create(
        cairo::Format::ARgb32,
        source.get_width(),
        source.get_height(),
    ).unwrap();
    {
        let cr = cairo::Context::new(&source_surface);
        cr.set_source_surface(source, 0f64, 0f64);
        cr.paint();
    }
    let source_surface = SharedImageSurface::new(source_surface, SurfaceType::SRgb).unwrap();

    let mut filter_ctx =
        FilterContext::new(filter_node, node_being_filtered, source_surface, draw_ctx);

    filter_node
        .children()
        // Skip nodes in error.
        .filter(|c| {
            let in_error = c.is_in_error();

            if in_error {
                rsvg_log!(
                    "(ignoring filter primitive {} because it is in error)",
                    c.get_human_readable_name()
                );
            }

            !in_error
        })
        // Check if the node wants linear RGB.
        .map(|c| {
            let linear_rgb = {
                let cascaded = c.get_cascaded_values();
                let values = cascaded.get();

                values.color_interpolation_filters == ColorInterpolationFilters::LinearRgb
            };

            (c, linear_rgb)
        }).filter_map(|(c, linear_rgb)| {
            let rr = RcRef::new(c)
                .try_map(|c| {
                    // Go through the filter primitives and see if the node is one of them.
                    #[inline]
                    fn as_filter<T: Filter>(x: &T) -> &Filter {
                        x
                    }

                    // Unfortunately it's not possible to downcast to a trait object. If we could
                    // attach arbitrary data to nodes it would really help here. Previously that
                    // arbitrary data was in form of RsvgCNodeImpl, but that was heavily tuned for
                    // storing C pointers with all subsequent downsides.
                    macro_rules! try_downcasting_to_filter {
                        ($c:expr; $($t:ty),+$(,)*) => ({
                            let mut filter = None;
                            $(
                                filter = filter.or_else(|| $c.get_impl::<$t>().map(as_filter));
                            )+
                            filter
                        })
                    }

                    let filter = try_downcasting_to_filter!(c;
                        blend::Blend,
                        color_matrix::ColorMatrix,
                        component_transfer::ComponentTransfer,
                        composite::Composite,
                        convolve_matrix::ConvolveMatrix,
                        displacement_map::DisplacementMap,
                        flood::Flood,
                        gaussian_blur::GaussianBlur,
                        image::Image,
                        light::lighting::Lighting,
                        merge::Merge,
                        morphology::Morphology,
                        offset::Offset,
                        tile::Tile,
                        turbulence::Turbulence,
                    );
                    filter.ok_or(())
                }).ok();

            rr.map(|rr| (rr, linear_rgb))
        }).for_each(|(rr, linear_rgb)| {
            let mut render = |filter_ctx: &mut FilterContext| {
                if let Err(err) = rr
                    .render(rr.owner(), filter_ctx, draw_ctx)
                    .and_then(|result| filter_ctx.store_result(result))
                {
                    rsvg_log!(
                        "(filter primitive {} returned an error: {})",
                        rr.owner().get_human_readable_name(),
                        err
                    );
                }
            };

            if rr.is_affected_by_color_interpolation_filters() && linear_rgb {
                filter_ctx.with_linear_rgb(render);
            } else {
                render(&mut filter_ctx);
            }
        });

    filter_ctx
        .into_output()
        .expect("could not create an empty surface to return from a filter")
        .into_image_surface()
        .expect("could not convert filter output into an ImageSurface")
}
<|endoftext|>


<commit_before>use byteorder::{BigEndian, ByteOrder};

pub struct IPv4Header<'a> {
    raw: &'a mut [u8],
    data: Data,
}

struct Data {
    version: u8,
    header_length: u8,
    total_length: u16,
    protocol: Protocol,
    source: u32,
    destination: u32,
}

#[derive(Debug, PartialEq)]
enum Protocol {
    TCP,
    UDP,
    OTHER,
}

impl<'a> IPv4Header<'a> {
    fn new(raw: &'a mut [u8]) -> IPv4Header<'a> {
        let data = IPv4Header::parse(raw);
        IPv4Header {
            raw: raw,
            data: data,
        }
    }

    fn parse(raw: &[u8]) -> Data {
        Data {
            version: raw[0] >> 4,
            header_length: (raw[0] & 0xf) << 2,
            total_length: BigEndian::read_u16(&raw[2..4]),
            protocol: match raw[9] {
                6 => Protocol::TCP,
                17 => Protocol::UDP,
                _ => Protocol::OTHER
            },
            source: BigEndian::read_u32(&raw[12..16]),
            destination: BigEndian::read_u32(&raw[16..20]),
        }
    }

    fn set_total_length(&mut self, total_length: u16) {
        self.data.total_length = total_length;
        BigEndian::write_u16(&mut self.raw[2..4], total_length);
    }

    fn set_source(&mut self, source: u32) {
        self.data.source = source;
        BigEndian::write_u32(&mut self.raw[12..16], source);
    }

    fn set_destination(&mut self, destination: u32) {
        self.data.destination = destination;
        BigEndian::write_u32(&mut self.raw[16..20], destination);
    }

    fn switch_source_and_destination(&mut self) {
        let source = self.data.source;
        let destination = self.data.destination;
        self.set_source(destination);
        self.set_destination(source);
    }

    fn set_checksum(&mut self, checksum: u16) {
        BigEndian::write_u16(&mut self.raw[10..12], checksum);
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io::Cursor;
    use byteorder::{BigEndian, WriteBytesExt};

    #[test]
    fn parse_packet_header() {
        let raw = create_header();
        let data = IPv4Header::parse(&raw[..]);
        assert_eq!(4, data.version);
        assert_eq!(20, data.header_length);
        assert_eq!(28, data.total_length);
        assert_eq!(Protocol::UDP, data.protocol);
        assert_eq!(0x12345678, data.source);
        assert_eq!(0x42424242, data.destination);
    }

    fn create_header() -> Vec<u8> {
        let mut raw: Vec<u8> = vec![];
        raw.reserve(20);
        raw.write_u8(4u8 << 4 | 5).unwrap(); // version_and_ihl
        raw.write_u8(0).unwrap(); //ToS
        raw.write_u16::<BigEndian>(28).unwrap(); // total length
        raw.write_u32::<BigEndian>(0).unwrap(); // id_flags_fragment_offset
        raw.write_u8(0).unwrap(); // TTL
        raw.write_u8(17).unwrap(); // protocol (UDP)
        raw.write_u16::<BigEndian>(0).unwrap(); // checksum
        raw.write_u32::<BigEndian>(0x12345678).unwrap(); // source address
        raw.write_u32::<BigEndian>(0x42424242).unwrap(); // destination address
        raw
    }

    #[test]
    fn edit_packet_header() {

    }
}
<commit_msg>More tests for IPv4Header<commit_after>use byteorder::{BigEndian, ByteOrder};

pub struct IPv4Header<'a> {
    raw: &'a mut [u8],
    data: Data,
}

struct Data {
    version: u8,
    header_length: u8,
    total_length: u16,
    protocol: Protocol,
    source: u32,
    destination: u32,
}

#[derive(Debug, PartialEq)]
enum Protocol {
    TCP,
    UDP,
    OTHER,
}

impl<'a> IPv4Header<'a> {
    fn new(raw: &'a mut [u8]) -> IPv4Header<'a> {
        let data = IPv4Header::parse(raw);
        IPv4Header {
            raw: raw,
            data: data,
        }
    }

    fn parse(raw: &[u8]) -> Data {
        Data {
            version: raw[0] >> 4,
            header_length: (raw[0] & 0xf) << 2,
            total_length: BigEndian::read_u16(&raw[2..4]),
            protocol: match raw[9] {
                6 => Protocol::TCP,
                17 => Protocol::UDP,
                _ => Protocol::OTHER
            },
            source: BigEndian::read_u32(&raw[12..16]),
            destination: BigEndian::read_u32(&raw[16..20]),
        }
    }

    fn set_total_length(&mut self, total_length: u16) {
        self.data.total_length = total_length;
        BigEndian::write_u16(&mut self.raw[2..4], total_length);
    }

    fn set_source(&mut self, source: u32) {
        self.data.source = source;
        BigEndian::write_u32(&mut self.raw[12..16], source);
    }

    fn set_destination(&mut self, destination: u32) {
        self.data.destination = destination;
        BigEndian::write_u32(&mut self.raw[16..20], destination);
    }

    fn switch_source_and_destination(&mut self) {
        let source = self.data.source;
        let destination = self.data.destination;
        self.set_source(destination);
        self.set_destination(source);
    }

    fn set_checksum(&mut self, checksum: u16) {
        BigEndian::write_u16(&mut self.raw[10..12], checksum);
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io::Cursor;
    use byteorder::{BigEndian, WriteBytesExt};

    fn create_header() -> Vec<u8> {
        let mut raw: Vec<u8> = vec![];
        raw.reserve(20);
        raw.write_u8(4u8 << 4 | 5).unwrap(); // version_and_ihl
        raw.write_u8(0).unwrap(); //ToS
        raw.write_u16::<BigEndian>(28).unwrap(); // total length
        raw.write_u32::<BigEndian>(0).unwrap(); // id_flags_fragment_offset
        raw.write_u8(0).unwrap(); // TTL
        raw.write_u8(17).unwrap(); // protocol (UDP)
        raw.write_u16::<BigEndian>(0).unwrap(); // checksum
        raw.write_u32::<BigEndian>(0x12345678).unwrap(); // source address
        raw.write_u32::<BigEndian>(0x42424242).unwrap(); // destination address
        raw
    }

    #[test]
    fn parse_packet_header() {
        let raw = create_header();
        let data = IPv4Header::parse(&raw[..]);
        assert_eq!(4, data.version);
        assert_eq!(20, data.header_length);
        assert_eq!(28, data.total_length);
        assert_eq!(Protocol::UDP, data.protocol);
        assert_eq!(0x12345678, data.source);
        assert_eq!(0x42424242, data.destination);
    }

    #[test]
    fn edit_packet_header() {
        let mut raw = create_header();
        let mut header = IPv4Header::new(&mut raw[..]);

        header.set_source(0x87654321);
        header.set_destination(0x24242424);
        header.set_total_length(42);
        assert_eq!(0x87654321, header.data.source);
        assert_eq!(0x24242424, header.data.destination);
        assert_eq!(42, header.data.total_length);

        // assert that the buffer has been modified
        let raw_source = BigEndian::read_u32(&header.raw[12..16]);
        let raw_destination = BigEndian::read_u32(&header.raw[16..20]);
        let raw_total_length = BigEndian::read_u16(&header.raw[2..4]);
        assert_eq!(0x87654321, raw_source);
        assert_eq!(0x24242424, raw_destination);
        assert_eq!(42, raw_total_length);

        header.switch_source_and_destination();

        assert_eq!(0x24242424, header.data.source);
        assert_eq!(0x87654321, header.data.destination);

        let raw_source = BigEndian::read_u32(&header.raw[12..16]);
        let raw_destination = BigEndian::read_u32(&header.raw[16..20]);
        assert_eq!(0x24242424, raw_source);
        assert_eq!(0x87654321, raw_destination);
    }
}
<|endoftext|>


<commit_before>#![feature(globs)]
extern crate scirust;
#[cfg(not(test))]
fn main(){
    use scirust::matrix::*;
    use scirust::linalg::*;
    let a = matrix_cw_f64(2,2, [1., 4., 2., 8.]);
    println!("{}", a);
    let b = vector_f64([3.0, 6.0]);
    let result = GaussElimination::new(&a, &b).solve();
    match result {
        Ok(x) => println!("{}", x),
        Err(e) => println!("{}", e),
    }
    let m = matrix_cw_c64(2,2, []);
    println!("{}", m);
}
<commit_msg>Bug in code with changed API.<commit_after>#![feature(globs)]
extern crate scirust;
#[cfg(not(test))]
fn main(){
    use scirust::api::*;
    let a = matrix_cw_f64(2,2, [1., 4., 2., 8.]);
    println!("{}", a);
    let b = vector_f64([3.0, 6.0]);
    let result = GaussElimination::new(&a, &b).solve();
    match result {
        Ok(x) => println!("{}", x),
        Err(e) => println!("{}", e),
    }
    let m = matrix_cw_c64(2,2, []);
    println!("{}", m);
}
<|endoftext|>


<commit_before>use std::mem;
use std::str::raw::c_str_to_static_slice;

use runtime::{Class, Messageable, Object, Sel, objc_msgSend};
use id::{Id, FromId};
use super::INSObject;

pub trait INSString : INSObject {
	fn as_str<'a>(&'a self) -> &'a str {
		let utf8_string = Sel::register("UTF8String");
		unsafe {
			let result = objc_msgSend(self.as_ptr(), utf8_string);
			c_str_to_static_slice(mem::transmute(result))
		}
	}
}

#[deriving(Clone)]
pub struct NSString {
	ptr: Id,
}

impl Messageable for NSString {
	unsafe fn as_ptr(&self) -> *Object {
		self.ptr.as_ptr()
	}
}

impl FromId for NSString {
	unsafe fn from_id(id: Id) -> NSString {
		NSString { ptr: id }
	}
}

impl INSObject for NSString { }

impl INSString for NSString { }

impl NSString {
	fn class() -> Class {
		Class::get("NSString")
	}

	pub fn from_str(string: &str) -> NSString {
		let class = NSString::class();
		let alloc = Sel::register("alloc");
		let init_with_bytes = Sel::register("initWithBytes:length:encoding:");
		let utf8_encoding = 4u;
		unsafe {
			let obj = objc_msgSend(class.as_ptr(), alloc);
			let obj = objc_msgSend(obj, init_with_bytes, string.as_ptr(),
				string.len(), utf8_encoding);
			FromId::from_retained_ptr(obj)
		}
	}
}
<commit_msg>Implemented Str for NSString.<commit_after>use std::mem;
use std::str::raw::c_str_to_static_slice;

use runtime::{Class, Messageable, Object, Sel, objc_msgSend};
use id::{Id, FromId};
use super::INSObject;

pub trait INSString : INSObject {
	fn as_str<'a>(&'a self) -> &'a str {
		let utf8_string = Sel::register("UTF8String");
		unsafe {
			let result = objc_msgSend(self.as_ptr(), utf8_string);
			c_str_to_static_slice(mem::transmute(result))
		}
	}
}

#[deriving(Clone)]
pub struct NSString {
	ptr: Id,
}

impl Messageable for NSString {
	unsafe fn as_ptr(&self) -> *Object {
		self.ptr.as_ptr()
	}
}

impl FromId for NSString {
	unsafe fn from_id(id: Id) -> NSString {
		NSString { ptr: id }
	}
}

impl INSObject for NSString { }

impl INSString for NSString { }

impl NSString {
	fn class() -> Class {
		Class::get("NSString")
	}

	pub fn from_str(string: &str) -> NSString {
		let class = NSString::class();
		let alloc = Sel::register("alloc");
		let init_with_bytes = Sel::register("initWithBytes:length:encoding:");
		let utf8_encoding = 4u;
		unsafe {
			let obj = objc_msgSend(class.as_ptr(), alloc);
			let obj = objc_msgSend(obj, init_with_bytes, string.as_ptr(),
				string.len(), utf8_encoding);
			FromId::from_retained_ptr(obj)
		}
	}
}

impl Str for NSString {
	fn as_slice<'a>(&'a self) -> &'a str {
		self.as_str()
	}
}
<|endoftext|>