<commit_before>//! This crate provides an iterator adaptor that yields sliding windows into the elements of the wrapped Iterator.
//!
//! Note that this adaptor does **NEVER** clone any element for huge speed gains.
//!
//! As a consequence it violates the Iterator protocol slightly. It is not possible to have two Windows into the data
//! available at the same time. This is checked during runtime. If this check fails, the Adaptor panicks in ```next()```.
//! More information can be found in the section [Panics](#panics).
//!
//! There are some options regarding the constructor for Storage, which allow reuse of an allocation.
//! Consult the [docs for Storage](struct.Storage.html) for details.
//!
//! Iterator element type is `Window<'a, Self::Item>`.
//!
//! Note: `Window<'a, Self::Item>` implements `iter()` and `iter_mut()`, which return Iterators over the elements of the `Window`.
//!
//! This iterator is *fused*.
//!
//! # Example:
//!
//! ```
//! use sliding_windows::IterExt;
//! use sliding_windows::Storage;
//!
//! let iter = 0..5;
//! let mut storage: Storage<u32> = Storage::new(3);
//! let windowed_iter = iter.sliding_windows(&mut storage);
//! let output: Vec<Vec<u32>> = windowed_iter.map(|x| x.iter().map(|&x| x).collect()).collect();
//! let expected: &[&[u32]] = &[&[0,1,2], &[1,2,3], &[2,3,4]];
//!
//! assert_eq!(output, expected);
//! ```
//!
//! It's also possible to reuse an allocation for `Storage` via the `Into` trait.
//!
//! # Example:
//!
//! ```
//! use sliding_windows::IterExt;
//! use sliding_windows::Storage;
//!
//! let previous_alloca = vec![0u32; 3]; // length doesn't have to be equal to window_size
//! let mut storage: Storage<u32> = Storage::from_vec(previous_alloca, 3);
//! let expected: &[&[u32]] = &[&[0,1,2], &[1,2,3], &[2,3,4]];
//!
//! // extra scope so that windowed_iter doesn't outlive storage.into() call
//! {
//!     let windowed_iter = (0..5).sliding_windows(&mut storage);
//!     let output: Vec<Vec<u32>> = windowed_iter.map(|x| x.iter().map(|&x| x).collect()).collect();
//!     assert_eq!(output, expected);
//! }
//!
//! let reusing_alloca: Vec<u32> = storage.into();
//! // keep using allocation of storage
//!
//! ```
//!
//! ### Panics:
//!
//! As this iterator reuses the allocation for the yielded `Window`, no two instances of `Window`
//! belonging to the same iterator may exist simultaneously. As noted above this is checked at runtime.
//!
//! ```
//! use sliding_windows::IterExt;
//! use sliding_windows::Storage;
//!
//! let mut storage: Storage<u32> = Storage::new(3);
//! let mut windowed_iter = (0..5).sliding_windows(&mut storage);
//!
//! // extra scope so that a doesn't live until the for loop
//! {
//!     let a = windowed_iter.next();
//!     //let b = windowed_iter.next(); => this would PANIC
//! }
//!
//! // looping for example is fine though
//! for _ in windowed_iter {
//!     // blah
//! }
//! ```
//!
//! # Mutable Window:
//!
//! There is an implementation of an Iterator over `&'a mut T` for `Window<'a, T>`. It can be obtained
//! by calling `iter_mut()`. For more information see [`Window<'a, T>`](struct.Window.html).
//!
//! However be aware that changes made to the items in the Window are persistent through calls to `next()`.

mod sliding_windows;
#[cfg(test)]
mod tests;

pub use sliding_windows::{
    Storage, Adaptor };

pub trait IterExt: Iterator {
    fn sliding_windows(self, storage: &mut Storage<Self::Item>)
        -> Adaptor<Self>
        where Self: Sized
    {
        Adaptor::new(self, storage)
    }
}

impl<T: ?Sized> IterExt for T where T: Iterator { }
<commit_msg>export Window and its Iterators<commit_after>//! This crate provides an iterator adaptor that yields sliding windows into the elements of the wrapped Iterator.
//!
//! Note that this adaptor does **NEVER** clone any element for huge speed gains.
//!
//! As a consequence it violates the Iterator protocol slightly. It is not possible to have two Windows into the data
//! available at the same time. This is checked during runtime. If this check fails, the Adaptor panicks in ```next()```.
//! More information can be found in the section [Panics](#panics).
//!
//! There are some options regarding the constructor for Storage, which allow reuse of an allocation.
//! Consult the [docs for Storage](struct.Storage.html) for details.
//!
//! Iterator element type is `Window<'a, Self::Item>`.
//!
//! Note: `Window<'a, Self::Item>` implements `iter()` and `iter_mut()`, which return Iterators over the elements of the `Window`.
//!
//! This iterator is *fused*.
//!
//! # Example:
//!
//! ```
//! use sliding_windows::IterExt;
//! use sliding_windows::Storage;
//!
//! let iter = 0..5;
//! let mut storage: Storage<u32> = Storage::new(3);
//! let windowed_iter = iter.sliding_windows(&mut storage);
//! let output: Vec<Vec<u32>> = windowed_iter.map(|x| x.iter().map(|&x| x).collect()).collect();
//! let expected: &[&[u32]] = &[&[0,1,2], &[1,2,3], &[2,3,4]];
//!
//! assert_eq!(output, expected);
//! ```
//!
//! It's also possible to reuse an allocation for `Storage` via the `Into` trait.
//!
//! # Example:
//!
//! ```
//! use sliding_windows::IterExt;
//! use sliding_windows::Storage;
//!
//! let previous_alloca = vec![0u32; 3]; // length doesn't have to be equal to window_size
//! let mut storage: Storage<u32> = Storage::from_vec(previous_alloca, 3);
//! let expected: &[&[u32]] = &[&[0,1,2], &[1,2,3], &[2,3,4]];
//!
//! // extra scope so that windowed_iter doesn't outlive storage.into() call
//! {
//!     let windowed_iter = (0..5).sliding_windows(&mut storage);
//!     let output: Vec<Vec<u32>> = windowed_iter.map(|x| x.iter().map(|&x| x).collect()).collect();
//!     assert_eq!(output, expected);
//! }
//!
//! let reusing_alloca: Vec<u32> = storage.into();
//! // keep using allocation of storage
//!
//! ```
//!
//! ### Panics:
//!
//! As this iterator reuses the allocation for the yielded `Window`, no two instances of `Window`
//! belonging to the same iterator may exist simultaneously. As noted above this is checked at runtime.
//!
//! ```
//! use sliding_windows::IterExt;
//! use sliding_windows::Storage;
//!
//! let mut storage: Storage<u32> = Storage::new(3);
//! let mut windowed_iter = (0..5).sliding_windows(&mut storage);
//!
//! // extra scope so that a doesn't live until the for loop
//! {
//!     let a = windowed_iter.next();
//!     //let b = windowed_iter.next(); => this would PANIC
//! }
//!
//! // looping for example is fine though
//! for _ in windowed_iter {
//!     // blah
//! }
//! ```
//!
//! # Mutable Window:
//!
//! There is an implementation of an Iterator over `&'a mut T` for `Window<'a, T>`. It can be obtained
//! by calling `iter_mut()`. For more information see [`Window<'a, T>`](struct.Window.html).
//!
//! However be aware that changes made to the items in the Window are persistent through calls to `next()`.

mod sliding_windows;
#[cfg(test)]
mod tests;

pub use sliding_windows::{
    Storage, Adaptor, Window, WindowIter, WindowIterMut};

pub trait IterExt: Iterator {
    fn sliding_windows(self, storage: &mut Storage<Self::Item>)
        -> Adaptor<Self>
        where Self: Sized
    {
        Adaptor::new(self, storage)
    }
}

impl<T: ?Sized> IterExt for T where T: Iterator { }
<|endoftext|>


<commit_before>// Copyright 2015 The Athena Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate cgmath;
#[macro_use]
extern crate gfx;
extern crate gfx_text;
extern crate gfx_texture;

use gfx::traits::*;
use std::cell::RefCell;
use std::rc::Rc;

mod render;
pub mod widget;

pub enum Event {
    MouseMoved([i32; 2]),
    MouseClick,
    Placeholder
}

pub struct Gui<R: gfx::Resources, F: gfx::Factory<R>> {
    root: widget::Layout<R>,
    render_data: Rc<RefCell<render::RenderData<R, F>>>
}

impl<R: gfx::Resources, F: gfx::Factory<R>> Gui<R, F> {
    pub fn root(&self) -> &widget::Layout<R> { &self.root }
    pub fn root_mut(&mut self) -> &mut widget::Layout<R> { &mut self.root }

    pub fn new<D: gfx::Device, FactorySpawner>(device: &mut D, root: widget::Layout<R>, spawner: FactorySpawner) -> Gui<R, F>
        where FactorySpawner: Fn(&mut D) -> F
    {
        Gui {
            root: root,
            render_data: Rc::new(RefCell::new(render::RenderData::new(device, spawner)))
        }
    }

    pub fn raise_event<S: gfx::Stream<R>>(&mut self, stream: &S, event: Event) {
        let (x, y) = stream.get_output().get_size();
        let area = render::RenderArea {
            position: [0, 0],
            size: [x as i32, y as i32]
        };

        self.root.raise_event(&event, &area);
    }

    pub fn render<S: gfx::Stream<R>>(
        &mut self,
        factory: &mut F, stream: &mut S)
    {
        // Set up a layout area to the whole screen
        let (x, y) = stream.get_output().get_size();
        let area = render::RenderArea {
            position: [0, 0],
            size: [x as i32, y as i32]
        };

        // Actually tell the root layout to render to the data
        let mut renderer = render::ConcreteRenderer::new(factory, stream, self.render_data.clone(), &area);
        self.root.render(&mut renderer, &area);
    }
}
<commit_msg>Add an option to replace the root of Gui<commit_after>// Copyright 2015 The Athena Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate cgmath;
#[macro_use]
extern crate gfx;
extern crate gfx_text;
extern crate gfx_texture;

use gfx::traits::*;
use std::cell::RefCell;
use std::rc::Rc;

mod render;
pub mod widget;

pub enum Event {
    MouseMoved([i32; 2]),
    MouseClick,
    Placeholder
}

pub struct Gui<R: gfx::Resources, F: gfx::Factory<R>> {
    root: widget::Layout<R>,
    render_data: Rc<RefCell<render::RenderData<R, F>>>
}

impl<R: gfx::Resources, F: gfx::Factory<R>> Gui<R, F> {
    pub fn root(&self) -> &widget::Layout<R> { &self.root }
    pub fn root_mut(&mut self) -> &mut widget::Layout<R> { &mut self.root }
    pub fn set_root(&mut self, root: widget::Layout<R>) { self.root = root; }

    pub fn new<D: gfx::Device, FactorySpawner>(device: &mut D, root: widget::Layout<R>, spawner: FactorySpawner) -> Gui<R, F>
        where FactorySpawner: Fn(&mut D) -> F
    {
        Gui {
            root: root,
            render_data: Rc::new(RefCell::new(render::RenderData::new(device, spawner)))
        }
    }

    pub fn raise_event<S: gfx::Stream<R>>(&mut self, stream: &S, event: Event) {
        let (x, y) = stream.get_output().get_size();
        let area = render::RenderArea {
            position: [0, 0],
            size: [x as i32, y as i32]
        };

        self.root.raise_event(&event, &area);
    }

    pub fn render<S: gfx::Stream<R>>(
        &mut self,
        factory: &mut F, stream: &mut S)
    {
        // Set up a layout area to the whole screen
        let (x, y) = stream.get_output().get_size();
        let area = render::RenderArea {
            position: [0, 0],
            size: [x as i32, y as i32]
        };

        // Actually tell the root layout to render to the data
        let mut renderer = render::ConcreteRenderer::new(factory, stream, self.render_data.clone(), &area);
        self.root.render(&mut renderer, &area);
    }
}
<|endoftext|>


<commit_before>//! ISO8601 is a parser library for the for [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) and partially RFC3339.
//!
//! Validity of a given date is not guaranteed, this parser will happily 2015.02.29 as a valid
//! date, even though 2015 was no leap year.

#![cfg_attr(feature = "dev", allow(unstable_features))]
#![cfg_attr(feature = "dev", feature(plugin))]
#![cfg_attr(feature = "dev", plugin(clippy))]

#[macro_use]
extern crate nom;
use nom::IResult::*;

#[macro_use]
mod helper;
pub mod parsers;

/// A date, can hold three different formats.
#[derive(Eq,PartialEq,Debug,Copy,Clone)]
pub enum Date {
    /// consists of year, month and day of month
    YMD{
        year:  i32,
        month: u32,
        day:   u32
    },
    /// consists of year, week and day of week
    Week{
        year:  i32,
        ww:    u32,
        d:     u32
    },
    /// consists of year and day of year
    Ordinal{
        year: i32,
        ddd: u32
    }
}

/// A time object
#[derive(Eq,PartialEq,Debug,Copy,Clone)]
pub struct Time {
    /// a 24th of a day
    pub hour: u32,
    /// 60 discrete parts of an hour
    pub minute: u32,
    /// a minute are 60 of these
    pub second: u32,
    /// everything after a `.`
    pub millisecond: u32,
    /// depends on where you're at
    pub tz_offset_hours: i32,
    pub tz_offset_minutes: i32,
}

/// Compound struct, hold Date and Time
///
/// duh!
#[derive(Eq,PartialEq,Debug,Copy,Clone)]
pub struct DateTime {
    pub date: Date,
    pub time: Time,
}

impl Time {
    pub fn set_tz(&self, tzo: (i32,i32)) -> Time {
        let mut t = self.clone();
        t.tz_offset_hours = tzo.0;
        t.tz_offset_hours = tzo.1;
        t
    }
}

/// Parses a date string.
///
/// A string can have either of the following formats:
///
/// 1. `2015-11-02` or `20151102`
/// 2. `2015-W45-01` or `2015W451`
/// 3. `2015-306` or `2015306`
///
pub fn date(string:&str) -> Result<Date,String> {
    if let Done(_,parsed) =  parsers::parse_date(string.as_bytes()){
        Ok(parsed)
    }
    else {
        Err(format!("Parser Error: {}", string))
    }
}

/// Parses a time string.
///
/// A string can have either of the following formats:
///
/// 1. `07:35:[00][.123]` or `0735[00][.123]`
/// 1. `07:35:[00][.123][(Z|(+|-)00:00)]`
/// 1. `0735[00][.123][(Z|(+|-)00:00)]`
/// 1. `0735[00][.123][(Z|(+|-)0000)]`
pub fn time(string:&str) -> Result<Time,String> {
    if let Done(_,parsed) =  parsers::parse_time(string.as_bytes()){
        Ok(parsed)
    }
    else {
        Err(format!("Parser Error: {}", string))
    }
}

/// This parses a datetime string.
///
/// A string can have either of the following formats:
///
/// *A Date* `T` *a time* ( see `date()` and `time()` )
///
pub fn datetime(string:&str) -> Result<DateTime,String> {
    if let Done(_left_overs,parsed) = parsers::parse_datetime(string.as_bytes()){
        Ok(parsed)
    }
    else {
        Err(format!("Parser Error: {}", string))
    }
}
<commit_msg>Formatting, wording and examples<commit_after>//! ISO8601 is a parser library for the [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) format
//! and partially RFC3339.
//!
//! Validity of a given date is not guaranteed, this parser will happily parse 2015.02.29 as a valid date,
//! even though 2015 was no leap year.

#![cfg_attr(feature = "dev", allow(unstable_features))]
#![cfg_attr(feature = "dev", feature(plugin))]
#![cfg_attr(feature = "dev", plugin(clippy))]

#[macro_use]
extern crate nom;
use nom::IResult::*;

#[macro_use]
mod helper;
pub mod parsers;

/// A date, can hold three different formats.
#[derive(Eq,PartialEq,Debug,Copy,Clone)]
pub enum Date {
    /// consists of year, month and day of month
    YMD{
        year:  i32,
        month: u32,
        day:   u32
    },
    /// consists of year, week and day of week
    Week{
        year:  i32,
        ww:    u32,
        d:     u32
    },
    /// consists of year and day of year
    Ordinal{
        year: i32,
        ddd: u32
    }
}

/// A time object
#[derive(Eq,PartialEq,Debug,Copy,Clone)]
pub struct Time {
    /// a 24th of a day
    pub hour: u32,
    /// 60 discrete parts of an hour
    pub minute: u32,
    /// a minute are 60 of these
    pub second: u32,
    /// everything after a `.`
    pub millisecond: u32,
    /// depends on where you're at
    pub tz_offset_hours: i32,
    pub tz_offset_minutes: i32,
}

/// Compound struct, hold Date and Time
///
/// duh!
#[derive(Eq,PartialEq,Debug,Copy,Clone)]
pub struct DateTime {
    pub date: Date,
    pub time: Time,
}

impl Time {
    pub fn set_tz(&self, tzo: (i32,i32)) -> Time {
        let mut t = self.clone();
        t.tz_offset_hours = tzo.0;
        t.tz_offset_hours = tzo.1;
        t
    }
}

/// Parses a date string.
///
/// A string can have one of the following formats:
///
/// * `2015-11-02` or `20151102`
/// * `2015-W45-01` or `2015W451`
/// * `2015-306` or `2015306`
///
/// ## Example
///
/// ```rust
/// let date = iso8601::date("2015-11-02").unwrap();
/// ```
pub fn date(string:&str) -> Result<Date,String> {
    if let Done(_,parsed) = parsers::parse_date(string.as_bytes()){
        Ok(parsed)
    }
    else {
        Err(format!("Parser Error: {}", string))
    }
}

/// Parses a time string.
///
/// A string can have one of the following formats:
///
/// * `07:35:[00][.123]` or `0735[00][.123]`
/// * `07:35:[00][.123][(Z|(+|-)00:00)]`
/// * `0735[00][.123][(Z|(+|-)00:00)]`
/// * `0735[00][.123][(Z|(+|-)0000)]`
///
/// ## Example
///
/// ```rust
/// let time = iso8601::time("21:56:42").unwrap();
/// ```
pub fn time(string:&str) -> Result<Time,String> {
    if let Done(_,parsed) = parsers::parse_time(string.as_bytes()){
        Ok(parsed)
    }
    else {
        Err(format!("Parser Error: {}", string))
    }
}

/// This parses a datetime string.
///
/// A datetime string is a combination of the valid formats for the date and time.
/// separated by a literal `T`.
/// See the respective functions for the correct format.
///
/// ## Example
///
/// ```rust
/// let dt = iso8601::datetime("2015-11-03T21:56").unwrap();
/// ```
pub fn datetime(string:&str) -> Result<DateTime,String> {
    if let Done(_left_overs,parsed) = parsers::parse_datetime(string.as_bytes()){
        Ok(parsed)
    }
    else {
        Err(format!("Parser Error: {}", string))
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

#![cfg_attr(feature = "futures-nightly", feature(pin))]

//! # **glib**, **gobject** and **gio** bindings for Rust
//!
//! This library contains
//!
//! - bindings to some essential GLib, GObject, GIO types and APIs,
//!
//! - common building blocks used in both handmade and machine generated
//! bindings to GTK+ and other GLib-based libraries.
//!
//! It is the foundation for higher level libraries with uniform Rusty (safe and
//! strongly typed) APIs. It avoids exposing GLib-specific data types where
//! possible and is not meant to provide comprehensive GLib bindings, which
//! would often amount to duplicating the Rust Standard Library or other utility
//! crates.
//!
//! The library is a work in progress: expect missing functionality and breaking
//! changes.
//!
//! # Dynamic typing
//!
//! Most types in the GLib family have type identifiers
//! ([`Type`](types/enum.Type.html)). Their corresponding Rust types implement
//! the [`StaticType`](types/trait.StaticType.html) trait.
//!
//! Dynamically typed [`Value`](value/index.html) can carry values of any `T:
//! StaticType`.
//!
//! [`Variant`](variant/index.html) can carry values of `T: StaticVariantType`.
//!
//! # Errors
//!
//! Errors are represented by [`Error`](error/struct.Error.html), which can
//! carry values from various [error
//! domains](error/trait.ErrorDomain.html#implementors) (such as
//! [`FileError`](enum.FileError.html)).
//!
//! # Objects
//!
//! Each class and interface has a corresponding smart pointer struct
//! representing an instance of that type (e.g. `Object` for `GObject`,
//! `gtk::Widget` for `GtkWidget`). They are reference counted and feature
//! interior mutability similarly to Rust's `Rc<RefCell<T>>` idiom.
//! Consequently, cloning objects is cheap and their methods never require
//! mutable borrows. Two smart pointers are equal iff they point to the same
//! object.
//!
//! The root of the object hierarchy is [`Object`](object/struct.Object.html).
//! Inheritance and subtyping is denoted with the [`IsA`](object/trait.IsA.html)
//! marker trait. The [`Cast`](object/trait.Cast.html) trait enables upcasting
//! and downcasting.
//!
//! Interfaces and non-leaf classes also have corresponding traits (e.g.
//! `ObjectExt` and `gtk::WidgetExt`), which are blanketly implemented for all
//! their subtypes.
//!
//! # Under the hood
//!
//! GLib-based libraries largely operate on pointers to various boxed or
//! reference counted structures so the bindings have to implement corresponding
//! smart pointers (wrappers), which encapsulate resource management and safety
//! checks. Such wrappers are defined via the
//! [`glib_wrapper!`](macro.glib_wrapper!.html) macro, which uses abstractions
//! defined in the [`wrapper`](wrapper/index.html), [`boxed`](boxed/index.html),
//! [`shared`](shared/index.html) and [`object`](object/index.html) modules.
//!
//! The [`translate`](translate/index.html) module defines and partly implements
//! conversions between high level Rust types (including the aforementioned
//! wrappers) and their FFI counterparts.

#![cfg_attr(feature = "cargo-clippy", allow(doc_markdown))]

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate glib_sys as ffi;
extern crate gobject_sys as gobject_ffi;

#[cfg(feature="futures")]
extern crate futures_core;
#[cfg(feature="futures")]
extern crate futures_executor;
#[cfg(feature="futures")]
extern crate futures_channel;
#[cfg(feature="futures")]
extern crate futures_util;
#[cfg(feature="futures-nightly")]
extern crate futures_stable;

use std::ffi::CStr;
pub use bytes::Bytes;
pub use string::String;
pub use closure::Closure;
pub use error::{Error, BoolError};
pub use file_error::FileError;
pub use object::{
    Cast,
    IsA,
    Object,
    ObjectExt,
    WeakRef,
};
pub use signal::{
    SignalHandlerId,
    signal_handler_block,
    signal_handler_unblock,
    signal_stop_emission,
    signal_stop_emission_by_name
};

pub use types::{
    StaticType,
    Type,
};
pub use value::{
    ToValue,
    ToSendValue,
    TypedValue,
    SendValue,
    Value,
    AnyValue,
    AnySendValue,
};
pub use variant::{
    StaticVariantType,
    ToVariant,
    Variant,
};
pub use variant_type::{
    VariantTy,
    VariantType,
};
pub use time_val::{
    TimeVal,
    get_current_time,
};
pub use enums::{
    UserDirectory,
    EnumClass,
    EnumValue,
    FlagsClass,
    FlagsValue,
    FlagsBuilder,
};

#[macro_use]
pub mod wrapper;
#[macro_use]
pub mod boxed;
#[macro_use]
pub mod shared;
#[macro_use]
pub mod object;

pub use auto::*;
pub use auto::functions::*;
#[cfg_attr(feature = "cargo-clippy", allow(let_and_return))]
#[cfg_attr(feature = "cargo-clippy", allow(let_unit_value))]
#[cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
#[allow(non_upper_case_globals)]
mod auto;

mod bytes;
mod string;
pub mod char;
pub use char::*;
mod checksum;
pub mod closure;
pub mod error;
mod enums;
mod file_error;
mod key_file;
pub mod prelude;
pub mod signal;
pub mod source;
pub use source::*;
mod time_val;
pub mod translate;
pub mod types;
mod utils;
pub use utils::*;
pub mod value;
pub mod variant;
mod variant_type;
mod main_context;
mod date_time;
mod date;
pub use date::Date;

#[cfg(feature="futures")]
mod main_context_futures;
#[cfg(feature="futures")]
mod source_futures;
#[cfg(feature="futures")]
pub use source_futures::*;
<commit_msg>Expose signal::signal_handler_disconnect<commit_after>// Copyright 2013-2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

#![cfg_attr(feature = "futures-nightly", feature(pin))]

//! # **glib**, **gobject** and **gio** bindings for Rust
//!
//! This library contains
//!
//! - bindings to some essential GLib, GObject, GIO types and APIs,
//!
//! - common building blocks used in both handmade and machine generated
//! bindings to GTK+ and other GLib-based libraries.
//!
//! It is the foundation for higher level libraries with uniform Rusty (safe and
//! strongly typed) APIs. It avoids exposing GLib-specific data types where
//! possible and is not meant to provide comprehensive GLib bindings, which
//! would often amount to duplicating the Rust Standard Library or other utility
//! crates.
//!
//! The library is a work in progress: expect missing functionality and breaking
//! changes.
//!
//! # Dynamic typing
//!
//! Most types in the GLib family have type identifiers
//! ([`Type`](types/enum.Type.html)). Their corresponding Rust types implement
//! the [`StaticType`](types/trait.StaticType.html) trait.
//!
//! Dynamically typed [`Value`](value/index.html) can carry values of any `T:
//! StaticType`.
//!
//! [`Variant`](variant/index.html) can carry values of `T: StaticVariantType`.
//!
//! # Errors
//!
//! Errors are represented by [`Error`](error/struct.Error.html), which can
//! carry values from various [error
//! domains](error/trait.ErrorDomain.html#implementors) (such as
//! [`FileError`](enum.FileError.html)).
//!
//! # Objects
//!
//! Each class and interface has a corresponding smart pointer struct
//! representing an instance of that type (e.g. `Object` for `GObject`,
//! `gtk::Widget` for `GtkWidget`). They are reference counted and feature
//! interior mutability similarly to Rust's `Rc<RefCell<T>>` idiom.
//! Consequently, cloning objects is cheap and their methods never require
//! mutable borrows. Two smart pointers are equal iff they point to the same
//! object.
//!
//! The root of the object hierarchy is [`Object`](object/struct.Object.html).
//! Inheritance and subtyping is denoted with the [`IsA`](object/trait.IsA.html)
//! marker trait. The [`Cast`](object/trait.Cast.html) trait enables upcasting
//! and downcasting.
//!
//! Interfaces and non-leaf classes also have corresponding traits (e.g.
//! `ObjectExt` and `gtk::WidgetExt`), which are blanketly implemented for all
//! their subtypes.
//!
//! # Under the hood
//!
//! GLib-based libraries largely operate on pointers to various boxed or
//! reference counted structures so the bindings have to implement corresponding
//! smart pointers (wrappers), which encapsulate resource management and safety
//! checks. Such wrappers are defined via the
//! [`glib_wrapper!`](macro.glib_wrapper!.html) macro, which uses abstractions
//! defined in the [`wrapper`](wrapper/index.html), [`boxed`](boxed/index.html),
//! [`shared`](shared/index.html) and [`object`](object/index.html) modules.
//!
//! The [`translate`](translate/index.html) module defines and partly implements
//! conversions between high level Rust types (including the aforementioned
//! wrappers) and their FFI counterparts.

#![cfg_attr(feature = "cargo-clippy", allow(doc_markdown))]

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate glib_sys as ffi;
extern crate gobject_sys as gobject_ffi;

#[cfg(feature="futures")]
extern crate futures_core;
#[cfg(feature="futures")]
extern crate futures_executor;
#[cfg(feature="futures")]
extern crate futures_channel;
#[cfg(feature="futures")]
extern crate futures_util;
#[cfg(feature="futures-nightly")]
extern crate futures_stable;

use std::ffi::CStr;
pub use bytes::Bytes;
pub use string::String;
pub use closure::Closure;
pub use error::{Error, BoolError};
pub use file_error::FileError;
pub use object::{
    Cast,
    IsA,
    Object,
    ObjectExt,
    WeakRef,
};
pub use signal::{
    SignalHandlerId,
    signal_handler_block,
    signal_handler_disconnect,
    signal_handler_unblock,
    signal_stop_emission,
    signal_stop_emission_by_name
};

pub use types::{
    StaticType,
    Type,
};
pub use value::{
    ToValue,
    ToSendValue,
    TypedValue,
    SendValue,
    Value,
    AnyValue,
    AnySendValue,
};
pub use variant::{
    StaticVariantType,
    ToVariant,
    Variant,
};
pub use variant_type::{
    VariantTy,
    VariantType,
};
pub use time_val::{
    TimeVal,
    get_current_time,
};
pub use enums::{
    UserDirectory,
    EnumClass,
    EnumValue,
    FlagsClass,
    FlagsValue,
    FlagsBuilder,
};

#[macro_use]
pub mod wrapper;
#[macro_use]
pub mod boxed;
#[macro_use]
pub mod shared;
#[macro_use]
pub mod object;

pub use auto::*;
pub use auto::functions::*;
#[cfg_attr(feature = "cargo-clippy", allow(let_and_return))]
#[cfg_attr(feature = "cargo-clippy", allow(let_unit_value))]
#[cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
#[allow(non_upper_case_globals)]
mod auto;

mod bytes;
mod string;
pub mod char;
pub use char::*;
mod checksum;
pub mod closure;
pub mod error;
mod enums;
mod file_error;
mod key_file;
pub mod prelude;
pub mod signal;
pub mod source;
pub use source::*;
mod time_val;
pub mod translate;
pub mod types;
mod utils;
pub use utils::*;
pub mod value;
pub mod variant;
mod variant_type;
mod main_context;
mod date_time;
mod date;
pub use date::Date;

#[cfg(feature="futures")]
mod main_context_futures;
#[cfg(feature="futures")]
mod source_futures;
#[cfg(feature="futures")]
pub use source_futures::*;
<|endoftext|>


<commit_before>#![crate_name = "bitmap"]
#![crate_type = "lib"]

use std::io;

/// Main bitmap structure
pub struct Bitmap {
    pub width:  uint,
    pub height: uint,
    pixels: Vec<u8>,
}

impl Bitmap {
    /// Set a pixel at x,y to a specified color
    /// # Arugments
    /// `x` - x coordinate
    /// `y` - y coordinate
    /// `color` - color values in the form (r, g, b)
    pub fn set_pixel(&mut self, x: uint, y: uint, color: (u8, u8, u8)) {
        // Calculate the byte offset for x
        let i = (self.height - y - 1) * (self.width * 3) + x * 3;

        // Note: Pixel order for bitmaps is (blue, green, red)
        let (r, g, b) = color;
        *self.pixels.get_mut(i + 0) = b;
        *self.pixels.get_mut(i + 1) = g;
        *self.pixels.get_mut(i + 2) = r;
    }

    /// Write the stored data to a file with given filename
    /// # Arguments
    /// `filename` - the file name to save the file to
    pub fn write_to_file(&self, filename: &str) -> io::IoResult<()> {
        static FILE_HEADER_SIZE:  u32 = 14;
        static BMP_INFO_SIZE:     u32 = 40;
        static TOTAL_HEADER_SIZE: u32 = FILE_HEADER_SIZE + BMP_INFO_SIZE;

        let image_size = (self.height * self.width*3 + self.height * (self.width % 4)) as u32;
        let file_size = image_size + TOTAL_HEADER_SIZE;

        // Bitmap file header
        let file_header: [u8, ..FILE_HEADER_SIZE] = [
            'B' as u8, 'M' as u8,
            file_size as u8, (file_size>>8) as u8, (file_size>>16) as u8, (file_size>>24) as u8,
            0, 0,
            0, 0,
            TOTAL_HEADER_SIZE as u8, 0, 0, 0
        ];
        // Bitmap information header
        let info_header: [u8, ..BMP_INFO_SIZE] = [
            BMP_INFO_SIZE as u8, 0, 0, 0,
            self.width as u8, (self.width>>8) as u8, (self.width>>16) as u8, (self.width>>24) as u8,
            self.height as u8, (self.height>>8) as u8, (self.height>>16) as u8, (self.height>>24) as u8,
            1, 0,
            24, 0,
            0, 0, 0, 0,
            image_size as u8, (image_size>>8) as u8, (image_size>>16) as u8, (image_size>>24) as u8,
            72, 0, 0, 0,
            72, 0, 0, 0,
            0, 0, 0, 0,
            0, 0, 0, 0
        ];

        // Set up the file writer
        let mut file = io::File::create(&Path::new(filename));

        // Write the bitmap headers to file
        try!(file.write(file_header));
        try!(file.write(info_header));

        // Write data to file
        file.write(self.pixels.as_slice())
    }

    /// Create a new bitmap
    /// # Arguments
    /// `width` - the width of the bitmap
    /// `height` - the height of the bitmap
    pub fn new(width: uint, height: uint) -> Bitmap {
        Bitmap {
            width:  width,
            height: height,
            pixels: Vec::from_elem(height * (width * 3 + width % 4), 0u8)
        }
    }
}
<commit_msg>Clean up documentation and conform closer to BMP format.<commit_after>#![crate_name = "bitmap"]
#![crate_type = "lib"]

use std::io;

/// Main bitmap structure
pub struct Bitmap {
    // The width of the bitmap in pixels, as an unsigned integer (4 bytes).
    width:  i32,

    // The height of the bitmap in pixels, as an unsigned integer (4 bytes).
    height: i32,

    // The pixel array, each row of the array is padded to 4 bytes in size.
    pixels: Vec<u8>,
}

impl Bitmap {
    /// Create a new blank (white) bitmap of a specified size.
    ///
    /// # Arguments
    /// `width` - The width of the bitmap.
    /// `height` - The height of the bitmap.
    pub fn new(width: i32, height: i32) -> Bitmap {
        Bitmap {
            width:  width,
            height: height,

            // Create a vector to store the pixels in, ensuring that it is padded to a multiple of 4
            // bytes of each row.
            pixels: Vec::from_elem((height * (width * 3 + width % 4)) as uint, 0xFFu8)
        }
    }

    /// Set a pixel at (x, y) to a specified color.
    ///
    /// # Arguments
    /// `x` - The x coordinate of the pixel.
    /// `y` - The y coordinate of the pixel.
    /// `color` - color values in the form (r, g, b).
    pub fn set_pixel(&mut self, x: i32, y: i32, color: (u8, u8, u8)) {
        // Calculate the byte offset for x
        let i = ((self.height - y - 1) * (self.width * 3) + x * 3) as uint;

        let (r, g, b) = color;
        // Note: Pixel order for bitmaps is (blue, green, red)
        *self.pixels.get_mut(i + 0) = b;
        *self.pixels.get_mut(i + 1) = g;
        *self.pixels.get_mut(i + 2) = r;
    }

    /// Write the stored data to a file with given filename.
    ///
    /// # Arguments
    /// `filename` - The filename of the target file.
    pub fn write_to_file(&self, filename: &str) -> io::IoResult<()> {
        static FILE_HEADER_SIZE:  u32 = 14;
        static BMP_INFO_SIZE:     u32 = 40;
        static TOTAL_HEADER_SIZE: u32 = FILE_HEADER_SIZE + BMP_INFO_SIZE;

        let image_size = (self.height * self.width*3 + self.height * (self.width % 4)) as u32;
        let file_size = image_size + TOTAL_HEADER_SIZE;

        // Bitmap file header
        let file_header: [u8, ..FILE_HEADER_SIZE] = [
            'B' as u8, 'M' as u8,
            file_size as u8, (file_size>>8) as u8, (file_size>>16) as u8, (file_size>>24) as u8,
            0, 0,
            0, 0,
            TOTAL_HEADER_SIZE as u8, 0, 0, 0
        ];
        // Bitmap information header
        let info_header: [u8, ..BMP_INFO_SIZE] = [
            BMP_INFO_SIZE as u8, 0, 0, 0,
            self.width as u8, (self.width>>8) as u8, (self.width>>16) as u8, (self.width>>24) as u8,
            self.height as u8, (self.height>>8) as u8, (self.height>>16) as u8, (self.height>>24) as u8,
            1, 0,
            24, 0,
            0, 0, 0, 0,
            image_size as u8, (image_size>>8) as u8, (image_size>>16) as u8, (image_size>>24) as u8,
            72, 0, 0, 0,
            72, 0, 0, 0,
            0, 0, 0, 0,
            0, 0, 0, 0
        ];

        // Set up the file writer
        let mut file = io::File::create(&Path::new(filename));

        // Write the bitmap headers to file
        try!(file.write(file_header));
        try!(file.write(info_header));

        // Write data to file
        file.write(self.pixels.as_slice())
    }

    /// Get the width of the bitmap.
    pub fn width(&self) -> i32 {
        self.width
    }

    /// Get the height of the bitmap.
    pub fn height(&self) -> i32 {
        self.height
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />

// SVG 1.1 (Second Edition)
// https://www.w3.org/TR/SVG/
<% data.new_style_struct("InheritedSVG",
                         inherited=True,
                         gecko_name="SVG") %>

// Section 10 - Text

${helpers.single_keyword("text-anchor",
                         "start middle end",
                         products="gecko",
                         animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG/text.html#TextAnchorProperty")}

// Section 11 - Painting: Filling, Stroking and Marker Symbols
${helpers.single_keyword("color-interpolation",
                         "srgb auto linearrgb",
                         products="gecko",
                         animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationProperty")}

${helpers.single_keyword("color-interpolation-filters", "linearrgb auto srgb",
                         products="gecko",
                         gecko_constant_prefix="NS_STYLE_COLOR_INTERPOLATION",
                         animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationFiltersProperty")}

${helpers.predefined_type(
    "fill", "SVGPaint",
    "::values::computed::SVGPaint::black()",
    products="gecko",
    animation_value_type="IntermediateSVGPaint",
    boxed=True,
    spec="https://www.w3.org/TR/SVG2/painting.html#SpecifyingFillPaint")}

${helpers.predefined_type("fill-opacity", "Opacity", "1.0",
                          products="gecko", animation_value_type="none",
                          spec="https://www.w3.org/TR/SVG11/painting.html#FillOpacityProperty")}

${helpers.single_keyword("fill-rule", "nonzero evenodd",
                         gecko_enum_prefix="StyleFillRule",
                         gecko_inexhaustive=True,
                         products="gecko", animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/painting.html#FillRuleProperty")}

${helpers.single_keyword("shape-rendering",
                         "auto optimizespeed crispedges geometricprecision",
                         products="gecko",
                         animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/painting.html#ShapeRenderingProperty")}

${helpers.predefined_type(
    "stroke", "SVGPaint",
    "Default::default()",
    products="gecko",
    animation_value_type="IntermediateSVGPaint",
    boxed=True,
    spec="https://www.w3.org/TR/SVG2/painting.html#SpecifyingStrokePaint")}

${helpers.predefined_type(
    "stroke-width", "LengthOrPercentageOrNumber",
    "Either::First(1.0)",
    "parse_non_negative",
    products="gecko",
    animation_value_type="ComputedValue",
    spec="https://www.w3.org/TR/SVG2/painting.html#StrokeWidth")}

${helpers.single_keyword("stroke-linecap", "butt round square",
                         products="gecko", animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/painting.html#StrokeLinecapProperty")}

${helpers.single_keyword("stroke-linejoin", "miter round bevel",
                         products="gecko", animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/painting.html#StrokeLinejoinProperty")}

${helpers.predefined_type("stroke-miterlimit", "Number", "4.0",
                          "parse_at_least_one", products="gecko",
                          animation_value_type="ComputedValue",
                          spec="https://www.w3.org/TR/SVG11/painting.html#StrokeMiterlimitProperty")}

${helpers.predefined_type("stroke-opacity", "Opacity", "1.0",
                          products="gecko", animation_value_type="ComputedValue",
                          spec="https://www.w3.org/TR/SVG11/painting.html#StrokeOpacityProperty")}

${helpers.predefined_type("stroke-dasharray",
                          "LengthOrPercentageOrNumber",
                          "Either::First(0.0)",
                          "parse_non_negative",
                          vector="True",
                          delegate_animate="True",
                          allow_empty="True",
                          products="gecko",
                          animation_value_type="ComputedValue",
                          space_separated_allowed="True",
                          spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing")}

${helpers.predefined_type(
    "stroke-dashoffset", "LengthOrPercentageOrNumber",
    "Either::First(0.0)",
    products="gecko",
    animation_value_type="ComputedValue",
    spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing")}

// Section 14 - Clipping, Masking and Compositing
${helpers.single_keyword("clip-rule", "nonzero evenodd",
                         products="gecko",
                         gecko_enum_prefix="StyleFillRule",
                         gecko_inexhaustive=True,
                         animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/masking.html#ClipRuleProperty")}

${helpers.predefined_type("marker-start", "UrlOrNone", "Either::Second(None_)",
                          products="gecko",
                          boxed="True" if product == "gecko" else "False",
                          animation_value_type="none",
                          spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")}

${helpers.predefined_type("marker-mid", "UrlOrNone", "Either::Second(None_)",
                          products="gecko",
                          boxed="True" if product == "gecko" else "False",
                          animation_value_type="none",
                          spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")}

${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)",
                          products="gecko",
                          boxed="True" if product == "gecko" else "False",
                          animation_value_type="none",
                          spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")}

<%helpers:longhand name="paint-order"
                   animation_value_type="none"
                   products="gecko"
                   spec="https://www.w3.org/TR/SVG2/painting.html#PaintOrder">

    use values::computed::ComputedValueAsSpecified;
    use std::fmt;
    use style_traits::ToCss;

    pub const NORMAL: u8 = 0;
    pub const FILL: u8 = 1;
    pub const STROKE: u8 = 2;
    pub const MARKERS: u8 = 3;

    // number of bits for each component
    pub const SHIFT: u8 = 2;
    // mask with above bits set
    pub const MASK: u8 = 0b11;
    // number of non-normal keyword values
    pub const COUNT: u8 = 3;
    // all keywords
    pub const ALL: [u8; 3] = [FILL, STROKE, MARKERS];

    /// Represented as a six-bit field, of 3 two-bit pairs
    ///
    /// Each pair can be set to FILL, STROKE, or MARKERS
    /// Lowest significant bit pairs are highest priority.
    ///  `normal` is the empty bitfield. The three pairs are
    /// never zero in any case other than `normal`.
    ///
    /// Higher priority values, i.e. the values specified first,
    /// will be painted first (and may be covered by paintings of lower priority)
    #[derive(PartialEq, Clone, Copy, Debug)]
    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
    pub struct SpecifiedValue(pub u8);

    pub mod computed_value {
        pub use super::SpecifiedValue as T;
    }

    pub fn get_initial_value() -> SpecifiedValue {
      SpecifiedValue(NORMAL)
    }

    impl SpecifiedValue {
        pub fn bits_at(&self, pos: u8) -> u8 {
            (self.0 >> pos * SHIFT) & MASK
        }
    }

    pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
        if let Ok(()) = input.try(|i| i.expect_ident_matching("normal")) {
            Ok(SpecifiedValue(0))
        } else {
            let mut value = 0;
            // bitfield representing what we've seen so far
            // bit 1 is fill, bit 2 is stroke, bit 3 is markers
            let mut seen = 0;
            let mut pos = 0;

            loop {

                let result = input.try(|i| {
                    match_ignore_ascii_case! { &i.expect_ident()?,
                        "fill" => Ok(FILL),
                        "stroke" => Ok(STROKE),
                        "markers" => Ok(MARKERS),
                        _ => Err(())
                    }
                });

                match result {
                    Ok(val) => {
                        if (seen & (1 << val)) != 0 {
                            // don't parse the same ident twice
                            return Err(())
                        } else {
                            value |= val << (pos * SHIFT);
                            seen |= 1 << val;
                            pos += 1;
                        }
                    }
                    Err(()) => break,
                }
            }

            if value == 0 {
                // couldn't find any keyword
                Err(())
            } else {
                // fill in rest
                for i in pos..COUNT {
                    for paint in &ALL {
                        // if not seen, set bit at position, mark as seen
                        if (seen & (1 << paint)) == 0 {
                            seen |= 1 << paint;
                            value |= paint << (i * SHIFT);
                            break;
                        }
                    }
                }

                Ok(SpecifiedValue(value))
            }
        }
    }

    impl ToCss for SpecifiedValue {
        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
            if self.0 == 0 {
                return dest.write_str("normal")
            }

            for pos in 0..COUNT {
                if pos != 0 {
                    dest.write_str(" ")?
                }
                match self.bits_at(pos) {
                    FILL => dest.write_str("fill")?,
                    STROKE => dest.write_str("stroke")?,
                    MARKERS => dest.write_str("markers")?,
                    _ => unreachable!(),
                }
            }
            Ok(())
        }
    }

    no_viewport_percentage!(SpecifiedValue);

    impl ComputedValueAsSpecified for SpecifiedValue { }
</%helpers:longhand>
<%helpers:vector_longhand name="-moz-context-properties"
                   animation_value_type="none"
                   products="gecko"
                   spec="Nonstandard (Internal-only)"
                   internal="True"
                   allow_empty="True">
    use values::CustomIdent;
    use values::computed::ComputedValueAsSpecified;

    no_viewport_percentage!(SpecifiedValue);

    impl ComputedValueAsSpecified for SpecifiedValue { }

    pub type SpecifiedValue = CustomIdent;

    pub mod computed_value {
        pub type T = super::SpecifiedValue;
    }

    pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
        let i = input.expect_ident()?;
        CustomIdent::from_ident(i, &["all", "none", "auto"])
    }
</%helpers:vector_longhand>
<commit_msg>Auto merge of #17227 - chenpighead:stylo-fill-opacity-animatable, r=boris<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />

// SVG 1.1 (Second Edition)
// https://www.w3.org/TR/SVG/
<% data.new_style_struct("InheritedSVG",
                         inherited=True,
                         gecko_name="SVG") %>

// Section 10 - Text

${helpers.single_keyword("text-anchor",
                         "start middle end",
                         products="gecko",
                         animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG/text.html#TextAnchorProperty")}

// Section 11 - Painting: Filling, Stroking and Marker Symbols
${helpers.single_keyword("color-interpolation",
                         "srgb auto linearrgb",
                         products="gecko",
                         animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationProperty")}

${helpers.single_keyword("color-interpolation-filters", "linearrgb auto srgb",
                         products="gecko",
                         gecko_constant_prefix="NS_STYLE_COLOR_INTERPOLATION",
                         animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationFiltersProperty")}

${helpers.predefined_type(
    "fill", "SVGPaint",
    "::values::computed::SVGPaint::black()",
    products="gecko",
    animation_value_type="IntermediateSVGPaint",
    boxed=True,
    spec="https://www.w3.org/TR/SVG2/painting.html#SpecifyingFillPaint")}

${helpers.predefined_type("fill-opacity", "Opacity", "1.0",
                          products="gecko", animation_value_type="ComputedValue",
                          spec="https://www.w3.org/TR/SVG11/painting.html#FillOpacityProperty")}

${helpers.single_keyword("fill-rule", "nonzero evenodd",
                         gecko_enum_prefix="StyleFillRule",
                         gecko_inexhaustive=True,
                         products="gecko", animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/painting.html#FillRuleProperty")}

${helpers.single_keyword("shape-rendering",
                         "auto optimizespeed crispedges geometricprecision",
                         products="gecko",
                         animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/painting.html#ShapeRenderingProperty")}

${helpers.predefined_type(
    "stroke", "SVGPaint",
    "Default::default()",
    products="gecko",
    animation_value_type="IntermediateSVGPaint",
    boxed=True,
    spec="https://www.w3.org/TR/SVG2/painting.html#SpecifyingStrokePaint")}

${helpers.predefined_type(
    "stroke-width", "LengthOrPercentageOrNumber",
    "Either::First(1.0)",
    "parse_non_negative",
    products="gecko",
    animation_value_type="ComputedValue",
    spec="https://www.w3.org/TR/SVG2/painting.html#StrokeWidth")}

${helpers.single_keyword("stroke-linecap", "butt round square",
                         products="gecko", animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/painting.html#StrokeLinecapProperty")}

${helpers.single_keyword("stroke-linejoin", "miter round bevel",
                         products="gecko", animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/painting.html#StrokeLinejoinProperty")}

${helpers.predefined_type("stroke-miterlimit", "Number", "4.0",
                          "parse_at_least_one", products="gecko",
                          animation_value_type="ComputedValue",
                          spec="https://www.w3.org/TR/SVG11/painting.html#StrokeMiterlimitProperty")}

${helpers.predefined_type("stroke-opacity", "Opacity", "1.0",
                          products="gecko", animation_value_type="ComputedValue",
                          spec="https://www.w3.org/TR/SVG11/painting.html#StrokeOpacityProperty")}

${helpers.predefined_type("stroke-dasharray",
                          "LengthOrPercentageOrNumber",
                          "Either::First(0.0)",
                          "parse_non_negative",
                          vector="True",
                          delegate_animate="True",
                          allow_empty="True",
                          products="gecko",
                          animation_value_type="ComputedValue",
                          space_separated_allowed="True",
                          spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing")}

${helpers.predefined_type(
    "stroke-dashoffset", "LengthOrPercentageOrNumber",
    "Either::First(0.0)",
    products="gecko",
    animation_value_type="ComputedValue",
    spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing")}

// Section 14 - Clipping, Masking and Compositing
${helpers.single_keyword("clip-rule", "nonzero evenodd",
                         products="gecko",
                         gecko_enum_prefix="StyleFillRule",
                         gecko_inexhaustive=True,
                         animation_value_type="discrete",
                         spec="https://www.w3.org/TR/SVG11/masking.html#ClipRuleProperty")}

${helpers.predefined_type("marker-start", "UrlOrNone", "Either::Second(None_)",
                          products="gecko",
                          boxed="True" if product == "gecko" else "False",
                          animation_value_type="none",
                          spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")}

${helpers.predefined_type("marker-mid", "UrlOrNone", "Either::Second(None_)",
                          products="gecko",
                          boxed="True" if product == "gecko" else "False",
                          animation_value_type="none",
                          spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")}

${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)",
                          products="gecko",
                          boxed="True" if product == "gecko" else "False",
                          animation_value_type="none",
                          spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")}

<%helpers:longhand name="paint-order"
                   animation_value_type="none"
                   products="gecko"
                   spec="https://www.w3.org/TR/SVG2/painting.html#PaintOrder">

    use values::computed::ComputedValueAsSpecified;
    use std::fmt;
    use style_traits::ToCss;

    pub const NORMAL: u8 = 0;
    pub const FILL: u8 = 1;
    pub const STROKE: u8 = 2;
    pub const MARKERS: u8 = 3;

    // number of bits for each component
    pub const SHIFT: u8 = 2;
    // mask with above bits set
    pub const MASK: u8 = 0b11;
    // number of non-normal keyword values
    pub const COUNT: u8 = 3;
    // all keywords
    pub const ALL: [u8; 3] = [FILL, STROKE, MARKERS];

    /// Represented as a six-bit field, of 3 two-bit pairs
    ///
    /// Each pair can be set to FILL, STROKE, or MARKERS
    /// Lowest significant bit pairs are highest priority.
    ///  `normal` is the empty bitfield. The three pairs are
    /// never zero in any case other than `normal`.
    ///
    /// Higher priority values, i.e. the values specified first,
    /// will be painted first (and may be covered by paintings of lower priority)
    #[derive(PartialEq, Clone, Copy, Debug)]
    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
    pub struct SpecifiedValue(pub u8);

    pub mod computed_value {
        pub use super::SpecifiedValue as T;
    }

    pub fn get_initial_value() -> SpecifiedValue {
      SpecifiedValue(NORMAL)
    }

    impl SpecifiedValue {
        pub fn bits_at(&self, pos: u8) -> u8 {
            (self.0 >> pos * SHIFT) & MASK
        }
    }

    pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
        if let Ok(()) = input.try(|i| i.expect_ident_matching("normal")) {
            Ok(SpecifiedValue(0))
        } else {
            let mut value = 0;
            // bitfield representing what we've seen so far
            // bit 1 is fill, bit 2 is stroke, bit 3 is markers
            let mut seen = 0;
            let mut pos = 0;

            loop {

                let result = input.try(|i| {
                    match_ignore_ascii_case! { &i.expect_ident()?,
                        "fill" => Ok(FILL),
                        "stroke" => Ok(STROKE),
                        "markers" => Ok(MARKERS),
                        _ => Err(())
                    }
                });

                match result {
                    Ok(val) => {
                        if (seen & (1 << val)) != 0 {
                            // don't parse the same ident twice
                            return Err(())
                        } else {
                            value |= val << (pos * SHIFT);
                            seen |= 1 << val;
                            pos += 1;
                        }
                    }
                    Err(()) => break,
                }
            }

            if value == 0 {
                // couldn't find any keyword
                Err(())
            } else {
                // fill in rest
                for i in pos..COUNT {
                    for paint in &ALL {
                        // if not seen, set bit at position, mark as seen
                        if (seen & (1 << paint)) == 0 {
                            seen |= 1 << paint;
                            value |= paint << (i * SHIFT);
                            break;
                        }
                    }
                }

                Ok(SpecifiedValue(value))
            }
        }
    }

    impl ToCss for SpecifiedValue {
        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
            if self.0 == 0 {
                return dest.write_str("normal")
            }

            for pos in 0..COUNT {
                if pos != 0 {
                    dest.write_str(" ")?
                }
                match self.bits_at(pos) {
                    FILL => dest.write_str("fill")?,
                    STROKE => dest.write_str("stroke")?,
                    MARKERS => dest.write_str("markers")?,
                    _ => unreachable!(),
                }
            }
            Ok(())
        }
    }

    no_viewport_percentage!(SpecifiedValue);

    impl ComputedValueAsSpecified for SpecifiedValue { }
</%helpers:longhand>
<%helpers:vector_longhand name="-moz-context-properties"
                   animation_value_type="none"
                   products="gecko"
                   spec="Nonstandard (Internal-only)"
                   internal="True"
                   allow_empty="True">
    use values::CustomIdent;
    use values::computed::ComputedValueAsSpecified;

    no_viewport_percentage!(SpecifiedValue);

    impl ComputedValueAsSpecified for SpecifiedValue { }

    pub type SpecifiedValue = CustomIdent;

    pub mod computed_value {
        pub type T = super::SpecifiedValue;
    }

    pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
        let i = input.expect_ident()?;
        CustomIdent::from_ident(i, &["all", "none", "auto"])
    }
</%helpers:vector_longhand>
<|endoftext|>


<commit_before>//! A build dependency for Cargo libraries to find system artifacts through the
//! `pkg-config` utility.
//!
//! This library will shell out to `pkg-config` as part of build scripts and
//! probe the system to determine how to link to a specified library. The
//! `Config` structure serves as a method of configuring how `pkg-config` is
//! invoked in a builder style.
//!
//! A number of environment variables are available to globally configure how
//! this crate will invoke `pkg-config`:
//!
//! * `PKG_CONFIG_ALLOW_CROSS` - if this variable is not set, then `pkg-config`
//!   will automatically be disabled for all cross compiles.
//! * `FOO_NO_PKG_CONFIG` - if set, this will disable running `pkg-config` when
//!   probing for the library named `foo`.
//!
//! There are also a number of environment variables which can configure how a
//! library is linked to (dynamically vs statically). These variables control
//! whether the `--static` flag is passed. Note that this behavior can be
//! overridden by configuring explicitly on `Config`. The variables are checked
//! in the following order:
//!
//! * `FOO_STATIC` - pass `--static` for the library `foo`
//! * `FOO_DYNAMIC` - do not pass `--static` for the library `foo`
//! * `PKG_CONFIG_ALL_STATIC` - pass `--static` for all libraries
//! * `PKG_CONFIG_ALL_DYNAMIC` - do not pass `--static` for all libraries
//!
//! After running `pkg-config` all appropriate Cargo metadata will be printed on
//! stdout if the search was successful.
//!
//! # Example
//!
//! Find the system library named `foo`.
//!
//! ```no_run
//! extern crate "pkg-config" as pkg_config;
//!
//! fn main() {
//!     pkg_config::find_library("foo").unwrap();
//! }
//! ```
//!
//! Configure how library `foo` is linked to.
//!
//! ```no_run
//! extern crate "pkg-config" as pkg_config;
//!
//! fn main() {
//!     pkg_config::Config::new().statik(true).find("foo").unwrap();
//! }
//! ```

#![doc(html_root_url = "http://alexcrichton.com/pkg-config-rs")]
#![feature(path, fs)]
#![cfg_attr(test, deny(warnings))]

use std::ascii::AsciiExt;
use std::env;
use std::str;
use std::path::{PathBuf, Path};
use std::process::Command;
use std::fs::PathExt;

pub fn target_supported() -> bool {
    env::var("HOST") == env::var("TARGET") ||
        env::var_os("PKG_CONFIG_ALLOW_CROSS").is_some()
}

#[derive(Clone)]
pub struct Config {
    statik: Option<bool>,
    atleast_version: Option<String>,
}

#[derive(Debug)]
pub struct Library {
    pub libs: Vec<String>,
    pub link_paths: Vec<PathBuf>,
    pub frameworks: Vec<String>,
    pub framework_paths: Vec<PathBuf>,
    pub include_paths: Vec<PathBuf>,
    _priv: (),
}

/// Simple shortcut for using all default options for finding a library.
pub fn find_library(name: &str) -> Result<Library, String> {
    Config::new().find(name)
}

impl Config {
    /// Creates a new set of configuration options which are all initially set
    /// to "blank".
    pub fn new() -> Config {
        Config {
            statik: None,
            atleast_version: None,
        }
    }

    /// Indicate whether the `--static` flag should be passed.
    ///
    /// This will override the inference from environment variables described in
    /// the crate documentation.
    pub fn statik(&mut self, statik: bool) -> &mut Config {
        self.statik = Some(statik);
        self
    }

    /// Indicate that the library must be at least version `vers`.
    pub fn atleast_version(&mut self, vers: &str) -> &mut Config {
        self.atleast_version = Some(vers.to_string());
        self
    }

    /// Run `pkg-config` to find the library `name`.
    ///
    /// This will use all configuration previously set to specify how
    /// `pkg-config` is run.
    pub fn find(&self, name: &str) -> Result<Library, String> {
        if env::var_os(&format!("{}_NO_PKG_CONFIG", envify(name))).is_some() {
            return Err(format!("pkg-config requested to be aborted for {}", name))
        } else if !target_supported() {
            return Err("pkg-config doesn't handle cross compilation. Use \
                        PKG_CONFIG_ALLOW_CROSS=1 to override".to_string());
        }

        let mut cmd = Command::new("pkg-config");
        let statik = self.statik.unwrap_or(infer_static(name));
        if statik {
            cmd.arg("--static");
        }
        cmd.arg("--libs").arg("--cflags")
           .env("PKG_CONFIG_ALLOW_SYSTEM_LIBS", "1");
        match self.atleast_version {
            Some(ref v) => { cmd.arg(&format!("{} >= {}", name, v)); }
            None => { cmd.arg(name); }
        }
        let out = try!(cmd.output().map_err(|e| {
            format!("failed to run `{:?}`: {}", cmd, e)
        }));
        let stdout = str::from_utf8(&out.stdout).unwrap();
        let stderr = str::from_utf8(&out.stderr).unwrap();
        if !out.status.success() {
            let mut msg = format!("`{:?}` did not exit successfully: {}", cmd,
                                  out.status);
            if stdout.len() > 0 {
                msg.push_str("\n--- stdout\n");
                msg.push_str(stdout);
            }
            if stderr.len() > 0 {
                msg.push_str("\n--- stderr\n");
                msg.push_str(stderr);
            }
            return Err(msg)
        }

        let mut ret = Library {
            libs: Vec::new(),
            link_paths: Vec::new(),
            include_paths: Vec::new(),
            frameworks: Vec::new(),
            framework_paths: Vec::new(),
            _priv: (),
        };
        let mut dirs = Vec::new();
        let parts = stdout.split(' ').filter(|l| l.len() > 2)
                          .map(|arg| (&arg[0..2], &arg[2..]))
                          .collect::<Vec<_>>();
        for &(flag, val) in parts.iter() {
            if flag == "-L" {
                println!("cargo:rustc-flags=-L native={}", val);
                dirs.push(PathBuf::new(val));
                ret.link_paths.push(PathBuf::new(val));
            } else if flag == "-F" {
                println!("cargo:rustc-flags=-L framework={}", val);
                ret.framework_paths.push(PathBuf::new(val));
            } else if flag == "-I" {
                ret.include_paths.push(PathBuf::new(val));
            }
        }
        for &(flag, val) in parts.iter() {
            if flag == "-l" {
                ret.libs.push(val.to_string());
                if statik && !is_system_lib(val, &dirs) {
                    println!("cargo:rustc-flags=-l static={}", val);
                } else {
                    println!("cargo:rustc-flags=-l {}", val);
                }
            }
        }
        let mut iter = stdout.split(' ');
        while let Some(part) = iter.next() {
            if part != "-framework" { continue }
            if let Some(lib) = iter.next() {
                println!("cargo:rustc-flags=-l framework={}", lib);
                ret.frameworks.push(lib.to_string());
            }
        }

        Ok(ret)
    }
}

fn infer_static(name: &str) -> bool {
    let name = envify(name);
    if env::var_os(&format!("{}_STATIC", name)).is_some() {
        true
    } else if env::var_os(&format!("{}_DYNAMIC", name)).is_some() {
        false
    } else if env::var_os("PKG_CONFIG_ALL_STATIC").is_some() {
        true
    } else if env::var_os("PKG_CONFIG_ALL_DYNAMIC").is_some() {
        false
    } else {
        false
    }
}

fn envify(name: &str) -> String {
    name.chars().map(|c| c.to_ascii_uppercase()).map(|c| if c == '-' {'_'} else {c})
        .collect()
}

fn is_system_lib(name: &str, dirs: &[PathBuf]) -> bool {
    let libname = format!("lib{}.a", name);
    let root = Path::new("/usr");
    !dirs.iter().any(|d| {
        !d.starts_with(root) && d.join(&libname).exists()
    })
}
<commit_msg>Update to rust master<commit_after>//! A build dependency for Cargo libraries to find system artifacts through the
//! `pkg-config` utility.
//!
//! This library will shell out to `pkg-config` as part of build scripts and
//! probe the system to determine how to link to a specified library. The
//! `Config` structure serves as a method of configuring how `pkg-config` is
//! invoked in a builder style.
//!
//! A number of environment variables are available to globally configure how
//! this crate will invoke `pkg-config`:
//!
//! * `PKG_CONFIG_ALLOW_CROSS` - if this variable is not set, then `pkg-config`
//!   will automatically be disabled for all cross compiles.
//! * `FOO_NO_PKG_CONFIG` - if set, this will disable running `pkg-config` when
//!   probing for the library named `foo`.
//!
//! There are also a number of environment variables which can configure how a
//! library is linked to (dynamically vs statically). These variables control
//! whether the `--static` flag is passed. Note that this behavior can be
//! overridden by configuring explicitly on `Config`. The variables are checked
//! in the following order:
//!
//! * `FOO_STATIC` - pass `--static` for the library `foo`
//! * `FOO_DYNAMIC` - do not pass `--static` for the library `foo`
//! * `PKG_CONFIG_ALL_STATIC` - pass `--static` for all libraries
//! * `PKG_CONFIG_ALL_DYNAMIC` - do not pass `--static` for all libraries
//!
//! After running `pkg-config` all appropriate Cargo metadata will be printed on
//! stdout if the search was successful.
//!
//! # Example
//!
//! Find the system library named `foo`.
//!
//! ```no_run
//! extern crate "pkg-config" as pkg_config;
//!
//! fn main() {
//!     pkg_config::find_library("foo").unwrap();
//! }
//! ```
//!
//! Configure how library `foo` is linked to.
//!
//! ```no_run
//! extern crate "pkg-config" as pkg_config;
//!
//! fn main() {
//!     pkg_config::Config::new().statik(true).find("foo").unwrap();
//! }
//! ```

#![doc(html_root_url = "http://alexcrichton.com/pkg-config-rs")]
#![feature(path)]
#![cfg_attr(test, deny(warnings))]

use std::ascii::AsciiExt;
use std::env;
use std::fs;
use std::path::{PathBuf, Path};
use std::process::Command;
use std::str;

pub fn target_supported() -> bool {
    env::var("HOST") == env::var("TARGET") ||
        env::var_os("PKG_CONFIG_ALLOW_CROSS").is_some()
}

#[derive(Clone)]
pub struct Config {
    statik: Option<bool>,
    atleast_version: Option<String>,
}

#[derive(Debug)]
pub struct Library {
    pub libs: Vec<String>,
    pub link_paths: Vec<PathBuf>,
    pub frameworks: Vec<String>,
    pub framework_paths: Vec<PathBuf>,
    pub include_paths: Vec<PathBuf>,
    _priv: (),
}

/// Simple shortcut for using all default options for finding a library.
pub fn find_library(name: &str) -> Result<Library, String> {
    Config::new().find(name)
}

impl Config {
    /// Creates a new set of configuration options which are all initially set
    /// to "blank".
    pub fn new() -> Config {
        Config {
            statik: None,
            atleast_version: None,
        }
    }

    /// Indicate whether the `--static` flag should be passed.
    ///
    /// This will override the inference from environment variables described in
    /// the crate documentation.
    pub fn statik(&mut self, statik: bool) -> &mut Config {
        self.statik = Some(statik);
        self
    }

    /// Indicate that the library must be at least version `vers`.
    pub fn atleast_version(&mut self, vers: &str) -> &mut Config {
        self.atleast_version = Some(vers.to_string());
        self
    }

    /// Run `pkg-config` to find the library `name`.
    ///
    /// This will use all configuration previously set to specify how
    /// `pkg-config` is run.
    pub fn find(&self, name: &str) -> Result<Library, String> {
        if env::var_os(&format!("{}_NO_PKG_CONFIG", envify(name))).is_some() {
            return Err(format!("pkg-config requested to be aborted for {}", name))
        } else if !target_supported() {
            return Err("pkg-config doesn't handle cross compilation. Use \
                        PKG_CONFIG_ALLOW_CROSS=1 to override".to_string());
        }

        let mut cmd = Command::new("pkg-config");
        let statik = self.statik.unwrap_or(infer_static(name));
        if statik {
            cmd.arg("--static");
        }
        cmd.arg("--libs").arg("--cflags")
           .env("PKG_CONFIG_ALLOW_SYSTEM_LIBS", "1");
        match self.atleast_version {
            Some(ref v) => { cmd.arg(&format!("{} >= {}", name, v)); }
            None => { cmd.arg(name); }
        }
        let out = try!(cmd.output().map_err(|e| {
            format!("failed to run `{:?}`: {}", cmd, e)
        }));
        let stdout = str::from_utf8(&out.stdout).unwrap();
        let stderr = str::from_utf8(&out.stderr).unwrap();
        if !out.status.success() {
            let mut msg = format!("`{:?}` did not exit successfully: {}", cmd,
                                  out.status);
            if stdout.len() > 0 {
                msg.push_str("\n--- stdout\n");
                msg.push_str(stdout);
            }
            if stderr.len() > 0 {
                msg.push_str("\n--- stderr\n");
                msg.push_str(stderr);
            }
            return Err(msg)
        }

        let mut ret = Library {
            libs: Vec::new(),
            link_paths: Vec::new(),
            include_paths: Vec::new(),
            frameworks: Vec::new(),
            framework_paths: Vec::new(),
            _priv: (),
        };
        let mut dirs = Vec::new();
        let parts = stdout.split(' ').filter(|l| l.len() > 2)
                          .map(|arg| (&arg[0..2], &arg[2..]))
                          .collect::<Vec<_>>();
        for &(flag, val) in parts.iter() {
            if flag == "-L" {
                println!("cargo:rustc-flags=-L native={}", val);
                dirs.push(PathBuf::new(val));
                ret.link_paths.push(PathBuf::new(val));
            } else if flag == "-F" {
                println!("cargo:rustc-flags=-L framework={}", val);
                ret.framework_paths.push(PathBuf::new(val));
            } else if flag == "-I" {
                ret.include_paths.push(PathBuf::new(val));
            }
        }
        for &(flag, val) in parts.iter() {
            if flag == "-l" {
                ret.libs.push(val.to_string());
                if statik && !is_system_lib(val, &dirs) {
                    println!("cargo:rustc-flags=-l static={}", val);
                } else {
                    println!("cargo:rustc-flags=-l {}", val);
                }
            }
        }
        let mut iter = stdout.split(' ');
        while let Some(part) = iter.next() {
            if part != "-framework" { continue }
            if let Some(lib) = iter.next() {
                println!("cargo:rustc-flags=-l framework={}", lib);
                ret.frameworks.push(lib.to_string());
            }
        }

        Ok(ret)
    }
}

fn infer_static(name: &str) -> bool {
    let name = envify(name);
    if env::var_os(&format!("{}_STATIC", name)).is_some() {
        true
    } else if env::var_os(&format!("{}_DYNAMIC", name)).is_some() {
        false
    } else if env::var_os("PKG_CONFIG_ALL_STATIC").is_some() {
        true
    } else if env::var_os("PKG_CONFIG_ALL_DYNAMIC").is_some() {
        false
    } else {
        false
    }
}

fn envify(name: &str) -> String {
    name.chars().map(|c| c.to_ascii_uppercase()).map(|c| if c == '-' {'_'} else {c})
        .collect()
}

fn is_system_lib(name: &str, dirs: &[PathBuf]) -> bool {
    let libname = format!("lib{}.a", name);
    let root = Path::new("/usr");
    !dirs.iter().any(|d| {
        !d.starts_with(root) && fs::metadata(&d.join(&libname)).is_ok()
    })
}
<|endoftext|>


<commit_before>
//! A semi-safe, semi-stateless wrapper around OpenGL 3.3 Core. This library provides various
//! utilities to make using OpenGL 3.3 safer. It uses rust's type system to encode some information
//! which helps prevent common errors. This library is primarily intended to be used for games,
//! but you can also use it to create other graphics applications.
//!
//! Some points to get started:
//!
//!  - Use [`gondola::run`] to launch your game.
//!  - Use a [`VertexBuffer`] to do basic drawing.
//!  - Use [`GameState::gen_input_manager`] to get access to keyboard/mouse state.
//!
//! [`GameState::gen_input_manager`]: struct.GameState.html#method.gen_input_manager
//! [`VertexBuffer`]:                 buffer/struct.VertexBuffer.html
//! [`gondola::run`]:                 fn.run.html

extern crate gl;
extern crate glutin;
extern crate png;
extern crate cable_math;
extern crate rusttype;
#[macro_use]
extern crate bitflags;
#[cfg(feature = "serialize")]
extern crate serde;

mod color;
mod matrix_stack;
mod input;

pub mod texture;
#[macro_use]
pub mod shader;
pub mod buffer;
pub mod util;
pub mod framebuffer;
pub mod font;
pub mod ui;

pub use color::*;
pub use input::*;
pub use matrix_stack::*;
pub use util::graphics;

use cable_math::Vec2;
use std::time::{Instant, Duration};
use std::sync::mpsc;

/// The most generic result type possible. Used in top-level
pub type GameResult<T> = Result<T, Box<std::error::Error>>;

/// Creates a new window and runs the given game in this window. This function does
/// not return until the game exits.
///
/// # Example
/// ```rust,no_run
/// extern crate gondola;
///
/// use gondola::{Game, GameResult, GameState, MatrixStack};
///
/// fn main() {
///     gondola::run::<Pong>();
/// }
///
/// struct Pong {
///     // All data neded for game is defined here
/// }
///
/// impl Game for Pong {
///     fn setup(state: &mut GameState) -> GameResult<Pong> {
///         Ok(Pong {})
///     }
///
///     fn update(&mut self, delta: u32, state: &mut GameState) {
///         // All logic goes here.
///     }
///
///     fn draw(&mut self, state: &GameState, mut mat_stack: &mut MatrixStack) {
///         // All rendering goes here
///     }
/// }
/// ```
pub fn run<T: Game + Sized>() {
    // Create window
    let window = glutin::Window::new().unwrap();
    unsafe {
        window.make_current().unwrap();
        gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);
    }
    window.set_title(T::name());

    // Set up game state
    let mut state = GameState::new();
    state.win_size = {
        let (width, height) = window.get_inner_size_pixels().unwrap();
        Vec2::new(width, height)
    };
    graphics::viewport(0, 0, state.win_size.x, state.win_size.y);

    let mut mat_stack = MatrixStack::new();

    // Set up game
    let mut game = match T::setup(&mut state) {
        Err(err) => {
            println!("Failed to launch game:\n{:#?}", err);
            panic!();
        },
        Ok(game) => game,
    };

    let mut delta: u64 = 16;

    'main_loop:
    loop {
        let start_time = Instant::now();

        // Events
        for event in window.poll_events() {
            match event {
                glutin::Event::Closed => break 'main_loop,
                glutin::Event::Resized(..) => {
                    let (width, height) = window.get_inner_size_pixels().unwrap();
                    if width != 0 && height != 0 {
                        state.win_size = Vec2::new(width, height);
                        graphics::viewport(0, 0, state.win_size.x, state.win_size.y);
                        game.on_resize(&state);
                    }
                }
                other => {
                    let custom_event = match other {
                        glutin::Event::MouseMoved(x, y) => {
                            let pos = Vec2::new(x as i32, y as i32);
                            let delta = pos - state.prev_cursor_pos;
                            state.prev_cursor_pos = pos;

                            // set_cursor_position creates mose-moved events, we want to ignore those
                            if state.cursor_state == CursorState::HiddenGrabbed {
                                let center = state.win_size / 2;
                                let center = Vec2::new(center.x as i32, center.y as i32);
                                if pos == center {
                                    continue;
                                }
                            }

                            Event::MouseMoved {
                                delta: delta,
                                pos: pos,
                            }
                        },

                        e => {
                            Event::GlutinEvent(e)
                        },
                    };

                    // Send events to receivers, and remove those which are unable to receive.
                    state.event_sinks.retain(|sink| {
                        sink.send(custom_event.clone()).is_ok()
                    });
                },
            }
        }

        // Input state changes
        for input_state_change in state.state_change_request_receiver.try_iter() {
            match input_state_change {
                StateRequest::ChangeCursorState(new_state) => {
                    state.cursor_state = new_state;

                    let glutin_cursor_state = match new_state {
                        CursorState::Normal => glutin::CursorState::Normal,
                        CursorState::Hidden => glutin::CursorState::Hide,
                        CursorState::HiddenGrabbed => glutin::CursorState::Hide,
                        CursorState::Grabbed => glutin::CursorState::Grab,
                    };
                    window.set_cursor_state(glutin_cursor_state).unwrap();
                },
            }
        }

        if state.cursor_state == CursorState::HiddenGrabbed {
            let center = state.win_size / 2;
            let center = Vec2::new(center.x as i32, center.y as i32);
            window.set_cursor_position(center.x, center.y).unwrap();
        }

        // Logic and rendering
        game.update(delta as u32, &mut state);
        game.draw(&state, &mut mat_stack);
        window.swap_buffers().unwrap();
        graphics::print_errors();

        if state.exit {
            break 'main_loop;
        }

        // Timing
        if let Some(target_delta) = state.target_delta {
            let target_delta = Duration::from_millis(target_delta as u64);
            let elapsed = start_time.elapsed();
            if elapsed < target_delta {
                std::thread::sleep(target_delta - elapsed); // This is not very precice :/
            }
        }
        let delta_dur = start_time.elapsed();
        delta = delta_dur.as_secs()*1000 + (delta_dur.subsec_nanos() as u64)/1000000;

        // Calculate average framerate
        state.frame_accumulator += 1;
        state.delta_accumulator += delta as u32;
        if state.delta_accumulator > 500 { // Update every half second
            let frames = state.frame_accumulator as f32;
            let time = (state.delta_accumulator as f32) * 0.001;

            state.average_framerate = frames / time;

            state.frame_accumulator = 0;
            state.delta_accumulator = 0;
        }
    }

    game.close();
}

/// General info about the currently running game. Passed as a parameter to
/// most [`Game`](trait.Game.html) methods.
pub struct GameState {
    /// The size of the window in which this game is running, in pixels.
    pub win_size: Vec2<u32>,
    /// If set to true the game will exit after rendering.
    pub exit: bool,
    /// The number of milliseconds per frame this game should aim to run at. Set to 16
    /// for 60 fps. If the main loop takes less time than this amount the game will
    /// sleep until a total of `target_delta` has ellapsed. If set to `None` the game will
    /// never sleep, and run as fast as possible.
    pub target_delta: Option<u32>,
    /// The number of frames that where displayed in the last second. This number is updated every
    /// half second. Note that this is only an average; it does not reflect rapid fluctuations of
    /// delta times.
    pub average_framerate: f32,

    // Used to calculate framerate
    frame_accumulator: u32,
    delta_accumulator: u32,

    event_sinks: Vec<mpsc::Sender<Event>>,
    state_change_request_receiver: mpsc::Receiver<StateRequest>,
    state_change_request_sender: mpsc::Sender<StateRequest>,

    prev_cursor_pos: Vec2<i32>,
    cursor_state: CursorState,
}

/// Used with [`gondola::run`](fn.run.html)
pub trait Game: Sized {
    /// Called before the main loop. Resources and initial state should be set up here.
    fn setup(state: &mut GameState) -> GameResult<Self>;
    /// Called once every frame, before drawing.
    fn update(&mut self, delta: u32, state: &mut GameState);
    /// Called once every frame, after updating.
    fn draw(&mut self, state: &GameState, mat_stack: &mut MatrixStack);

    /// Called whenever the game window is resized
    fn on_resize(&mut self, _state: &GameState) {}
    /// Called after the main game loop exists. This method is not called if the main
    /// loop `panic!`s.
    fn close(&mut self) {} // Most simple games dont need any special logic here

    fn name() -> &'static str { "Unnamed game (Override Game::name to change title)" }
}

impl GameState {
    fn new() -> GameState {
        let (state_change_request_sender, state_change_request_receiver) = mpsc::channel();

        GameState {
            win_size: Vec2::zero(),
            exit: false,
            target_delta: Some(15),

            average_framerate: -1.0,
            frame_accumulator: 0,
            delta_accumulator: 0,

            event_sinks: Vec::new(),
            state_change_request_receiver: state_change_request_receiver,
            state_change_request_sender: state_change_request_sender,

            prev_cursor_pos: Vec2::zero(),
            cursor_state: CursorState::Normal,
        }
    }

    /// Generates a new receiver for glutin events. All events not consumed by the
    /// game itself will be received by this receiver. Note that all receiver receive
    /// all events, there is no notion of event consumption.
    pub fn gen_event_receiver(&mut self) -> mpsc::Receiver<Event> {
        let (sender, receiver) = mpsc::channel();
        self.event_sinks.push(sender);
        receiver
    }

    /// Generates a new sender to transmit state change requests to the game core asynchronously.
    pub fn gen_request_sender(&self) -> mpsc::Sender<StateRequest> {
        self.state_change_request_sender.clone()
    }

    /// Creates a new input manager which can be used to access the state of input devices.
    pub fn gen_input_manager(&mut self) -> InputManager {
        let receiver = self.gen_event_receiver();
        let sender = self.gen_request_sender();
        InputManager::new(receiver, sender)
    }
}

/// Because glutin does not handle some things in a very elegant fashion we have to work around
/// some of its events with custom events.
#[derive(Debug, Clone)]
pub enum Event {
    GlutinEvent(glutin::Event),
    MouseMoved {
        delta: Vec2<i32>,
        pos: Vec2<i32>,
    },
}

#[derive(Debug, Clone)]
pub enum StateRequest {
    ChangeCursorState(CursorState),
}

<commit_msg>Improved mouse handling when not focused<commit_after>
//! A semi-safe, semi-stateless wrapper around OpenGL 3.3 Core. This library provides various
//! utilities to make using OpenGL 3.3 safer. It uses rust's type system to encode some information
//! which helps prevent common errors. This library is primarily intended to be used for games,
//! but you can also use it to create other graphics applications.
//!
//! Some points to get started:
//!
//!  - Use [`gondola::run`] to launch your game.
//!  - Use a [`VertexBuffer`] to do basic drawing.
//!  - Use [`GameState::gen_input_manager`] to get access to keyboard/mouse state.
//!
//! [`GameState::gen_input_manager`]: struct.GameState.html#method.gen_input_manager
//! [`VertexBuffer`]:                 buffer/struct.VertexBuffer.html
//! [`gondola::run`]:                 fn.run.html

extern crate gl;
extern crate glutin;
extern crate png;
extern crate cable_math;
extern crate rusttype;
#[macro_use]
extern crate bitflags;
#[cfg(feature = "serialize")]
extern crate serde;

mod color;
mod matrix_stack;
mod input;

pub mod texture;
#[macro_use]
pub mod shader;
pub mod buffer;
pub mod util;
pub mod framebuffer;
pub mod font;
pub mod ui;

pub use color::*;
pub use input::*;
pub use matrix_stack::*;
pub use util::graphics;

use cable_math::Vec2;
use std::time::{Instant, Duration};
use std::sync::mpsc;

/// The most generic result type possible. Used in top-level
pub type GameResult<T> = Result<T, Box<std::error::Error>>;

/// Creates a new window and runs the given game in this window. This function does
/// not return until the game exits.
///
/// # Example
/// ```rust,no_run
/// extern crate gondola;
///
/// use gondola::{Game, GameResult, GameState, MatrixStack};
///
/// fn main() {
///     gondola::run::<Pong>();
/// }
///
/// struct Pong {
///     // All data neded for game is defined here
/// }
///
/// impl Game for Pong {
///     fn setup(state: &mut GameState) -> GameResult<Pong> {
///         Ok(Pong {})
///     }
///
///     fn update(&mut self, delta: u32, state: &mut GameState) {
///         // All logic goes here.
///     }
///
///     fn draw(&mut self, state: &GameState, mut mat_stack: &mut MatrixStack) {
///         // All rendering goes here
///     }
/// }
/// ```
pub fn run<T: Game + Sized>() {
    // Create window
    let window = glutin::Window::new().unwrap();
    unsafe {
        window.make_current().unwrap();
        gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);
    }
    window.set_title(T::name());

    // Set up game state
    let mut state = GameState::new();
    state.win_size = {
        let (width, height) = window.get_inner_size_pixels().unwrap();
        Vec2::new(width, height)
    };
    graphics::viewport(0, 0, state.win_size.x, state.win_size.y);

    let mut mat_stack = MatrixStack::new();

    // Set up game
    let mut game = match T::setup(&mut state) {
        Err(err) => {
            println!("Failed to launch game:\n{:#?}", err);
            panic!();
        },
        Ok(game) => game,
    };

    let mut delta: u64 = 16;

    'main_loop:
    loop {
        let start_time = Instant::now();

        // Events
        for event in window.poll_events() {
            match event {
                glutin::Event::Closed => break 'main_loop,
                glutin::Event::Resized(..) => {
                    let (width, height) = window.get_inner_size_pixels().unwrap();
                    if width != 0 && height != 0 {
                        state.win_size = Vec2::new(width, height);
                        graphics::viewport(0, 0, state.win_size.x, state.win_size.y);
                        game.on_resize(&state);
                    }
                },
                glutin::Event::Focused(focused) => {
                    state.focused = focused;

                    if focused {
                        let glutin_cursor_state = match state.cursor_state {
                            CursorState::Normal => glutin::CursorState::Normal,
                            CursorState::Hidden => glutin::CursorState::Hide,
                            CursorState::HiddenGrabbed => glutin::CursorState::Hide,
                            CursorState::Grabbed => glutin::CursorState::Grab,
                        };
                        window.set_cursor_state(glutin_cursor_state).unwrap();
                    } else {
                        window.set_cursor_state(glutin::CursorState::Normal).unwrap();
                    }
                },
                other => {
                    let custom_event = match other {
                        glutin::Event::MouseMoved(x, y) => {
                            let pos = Vec2::new(x as i32, y as i32);
                            let mut delta = pos - state.prev_cursor_pos;
                            state.prev_cursor_pos = pos;

                            // set_cursor_position creates mose-moved events, we want to ignore those
                            if state.cursor_state == CursorState::HiddenGrabbed {
                                let center = state.win_size / 2;
                                let center = Vec2::new(center.x as i32, center.y as i32);
                                if pos == center {
                                    continue;
                                }

                                // The focused state is almost exclusively used to control the
                                // camera. When we don't have focus we don't want the camera to
                                // move even if the cursor is moving around above the screen.
                                // Because of this we just disable mouse deltas in that case.
                                if !state.focused {
                                    delta = Vec2::zero();
                                }
                            }

                            Event::MouseMoved { delta, pos }
                        },

                        // We usually dont want to create a custom event, so unless we have custom
                        // logic for a specific event type we just pass on the glutin event.
                        e => Event::GlutinEvent(e),
                    };

                    // Send events to receivers, and remove those which are unable to receive.
                    state.event_sinks.retain(|sink| {
                        sink.send(custom_event.clone()).is_ok()
                    });
                },
            }
        }

        // Input state changes
        for input_state_change in state.state_change_request_receiver.try_iter() {
            match input_state_change {
                StateRequest::ChangeCursorState(new_state) => {
                    state.cursor_state = new_state;

                    let glutin_cursor_state = match new_state {
                        CursorState::Normal => glutin::CursorState::Normal,
                        CursorState::Hidden => glutin::CursorState::Hide,
                        CursorState::HiddenGrabbed => glutin::CursorState::Hide,
                        CursorState::Grabbed => glutin::CursorState::Grab,
                    };
                    window.set_cursor_state(glutin_cursor_state).unwrap();
                },
            }
        }

        if state.cursor_state == CursorState::HiddenGrabbed && state.focused {
            let center = state.win_size / 2;
            let center = Vec2::new(center.x as i32, center.y as i32);
            window.set_cursor_position(center.x, center.y).unwrap();
        }

        // Logic and rendering
        game.update(delta as u32, &mut state);
        game.draw(&state, &mut mat_stack);
        window.swap_buffers().unwrap();
        graphics::print_errors();

        if state.exit {
            break 'main_loop;
        }

        // Timing
        if let Some(target_delta) = state.target_delta {
            let target_delta = Duration::from_millis(target_delta as u64);
            let elapsed = start_time.elapsed();
            if elapsed < target_delta {
                std::thread::sleep(target_delta - elapsed); // This is not very precice :/
            }
        }
        let delta_dur = start_time.elapsed();
        delta = delta_dur.as_secs()*1000 + (delta_dur.subsec_nanos() as u64)/1000000;

        // Calculate average framerate
        state.frame_accumulator += 1;
        state.delta_accumulator += delta as u32;
        if state.delta_accumulator > 500 { // Update every half second
            let frames = state.frame_accumulator as f32;
            let time = (state.delta_accumulator as f32) * 0.001;

            state.average_framerate = frames / time;

            state.frame_accumulator = 0;
            state.delta_accumulator = 0;
        }
    }

    game.close();
}

/// General info about the currently running game. Passed as a parameter to
/// most [`Game`](trait.Game.html) methods.
pub struct GameState {
    /// The size of the window in which this game is running, in pixels.
    pub win_size: Vec2<u32>,
    /// If set to true the game will exit after rendering.
    pub exit: bool,
    /// The number of milliseconds per frame this game should aim to run at. Set to 16
    /// for 60 fps. If the main loop takes less time than this amount the game will
    /// sleep until a total of `target_delta` has ellapsed. If set to `None` the game will
    /// never sleep, and run as fast as possible.
    pub target_delta: Option<u32>,
    /// The number of frames that where displayed in the last second. This number is updated every
    /// half second. Note that this is only an average; it does not reflect rapid fluctuations of
    /// delta times.
    pub average_framerate: f32,
    /// If true the game window currently has focus.
    pub focused: bool,

    // Used to calculate framerate
    frame_accumulator: u32,
    delta_accumulator: u32,

    event_sinks: Vec<mpsc::Sender<Event>>,
    state_change_request_receiver: mpsc::Receiver<StateRequest>,
    state_change_request_sender: mpsc::Sender<StateRequest>,

    prev_cursor_pos: Vec2<i32>,
    cursor_state: CursorState,
}

/// Used with [`gondola::run`](fn.run.html)
pub trait Game: Sized {
    /// Called before the main loop. Resources and initial state should be set up here.
    fn setup(state: &mut GameState) -> GameResult<Self>;
    /// Called once every frame, before drawing.
    fn update(&mut self, delta: u32, state: &mut GameState);
    /// Called once every frame, after updating.
    fn draw(&mut self, state: &GameState, mat_stack: &mut MatrixStack);

    /// Called whenever the game window is resized
    fn on_resize(&mut self, _state: &GameState) {}
    /// Called after the main game loop exists. This method is not called if the main
    /// loop `panic!`s.
    fn close(&mut self) {} // Most simple games dont need any special logic here

    fn name() -> &'static str { "Unnamed game (Override Game::name to change title)" }
}

impl GameState {
    fn new() -> GameState {
        let (state_change_request_sender, state_change_request_receiver) = mpsc::channel();

        GameState {
            win_size: Vec2::zero(),
            exit: false,
            target_delta: Some(15),

            average_framerate: -1.0,
            frame_accumulator: 0,
            delta_accumulator: 0,

            focused: false, // We get a Focused(true) event once the window opens

            event_sinks: Vec::new(),
            state_change_request_receiver: state_change_request_receiver,
            state_change_request_sender: state_change_request_sender,

            prev_cursor_pos: Vec2::zero(),
            cursor_state: CursorState::Normal,
        }
    }

    /// Generates a new receiver for glutin events. All events not consumed by the
    /// game itself will be received by this receiver. Note that all receiver receive
    /// all events, there is no notion of event consumption.
    pub fn gen_event_receiver(&mut self) -> mpsc::Receiver<Event> {
        let (sender, receiver) = mpsc::channel();
        self.event_sinks.push(sender);
        receiver
    }

    /// Generates a new sender to transmit state change requests to the game core asynchronously.
    pub fn gen_request_sender(&self) -> mpsc::Sender<StateRequest> {
        self.state_change_request_sender.clone()
    }

    /// Creates a new input manager which can be used to access the state of input devices.
    pub fn gen_input_manager(&mut self) -> InputManager {
        let receiver = self.gen_event_receiver();
        let sender = self.gen_request_sender();
        InputManager::new(receiver, sender)
    }
}

/// Because glutin does not handle some things in a very elegant fashion we have to work around
/// some of its events with custom events.
#[derive(Debug, Clone)]
pub enum Event {
    GlutinEvent(glutin::Event),
    MouseMoved {
        delta: Vec2<i32>,
        pos: Vec2<i32>,
    },
}

#[derive(Debug, Clone)]
pub enum StateRequest {
    ChangeCursorState(CursorState),
}

<|endoftext|>