Skip to content

Commit 7bacfb3

Browse files
committed
initial commit
0 parents  commit 7bacfb3

39 files changed

+3962
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
/Cargo.lock

Cargo.toml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[workspace]
2+
members = [
3+
"pixman-sys",
4+
"pixman",
5+
]
6+
resolver = "2"

pixman-sys/Cargo.toml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
authors = ["Christian Meissl <[email protected]>"]
3+
description = "Pixman is a low-level software library for pixel manipulation, providing features such as image compositing and trapezoid rasterization."
4+
edition = "2021"
5+
license = "MIT"
6+
name = "pixman-sys"
7+
rust-version = "1.65.0"
8+
version = "0.1.0"
9+
10+
[dependencies]
11+
12+
[build-dependencies]
13+
bindgen = "0.68"
14+
pkg-config = "0.3"

pixman-sys/build.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use std::{env, path::PathBuf};
2+
3+
fn main() {
4+
let library = pkg_config::probe_library("pixman-1").unwrap();
5+
6+
let bindings = bindgen::Builder::default()
7+
.clang_args(
8+
library
9+
.include_paths
10+
.iter()
11+
.map(|path| format!("-I{}", path.to_string_lossy())),
12+
)
13+
.header("src/wrapper.h")
14+
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
15+
.generate()
16+
.expect("Unable to generate bindings");
17+
18+
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
19+
bindings
20+
.write_to_file(out_path.join("bindings.rs"))
21+
.expect("Couldn't write bindings!");
22+
}

pixman-sys/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![allow(non_upper_case_globals)]
2+
#![allow(non_camel_case_types)]
3+
#![allow(non_snake_case)]
4+
5+
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

pixman-sys/src/wrapper.h

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include <pixman.h>

pixman/Cargo.toml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
authors = ["Christian Meissl <[email protected]>"]
3+
description = "Pixman is a low-level software library for pixel manipulation, providing features such as image compositing and trapezoid rasterization."
4+
edition = "2021"
5+
license = "MIT"
6+
name = "pixman"
7+
rust-version = "1.65.0"
8+
version = "0.1.0"
9+
10+
[dependencies]
11+
pixman-sys = {version = "0.1.0", path = "../pixman-sys"}
12+
13+
[dev-dependencies]
14+
image = "0.24.7"

pixman/examples/alpha.rs

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
use pixman::{Fixed, FormatCode, GradientStop, Image, Operation, Point, Repeat, Transform};
2+
3+
const WIDTH: usize = 400;
4+
const HEIGHT: usize = 200;
5+
6+
pub fn main() {
7+
let stops = [
8+
GradientStop::new(0, [0x0000, 0x0000, 0x0000, 0x0000]),
9+
GradientStop::new(1, [0xffff, 0x0000, 0x1111, 0xffff]),
10+
];
11+
12+
let p1 = Point::from((0f64, 0f64));
13+
let p2 = Point::from((WIDTH as f64, 0f64));
14+
15+
let transform = Transform::new([
16+
[Fixed::ONE, Fixed::ZERO, Fixed::ZERO],
17+
[Fixed::ZERO, Fixed::ONE, Fixed::ZERO],
18+
[Fixed::ZERO, Fixed::ZERO, Fixed::ONE],
19+
]);
20+
21+
let mut alpha = [0x4f00004fu32; WIDTH * HEIGHT]; /* pale blue */
22+
let mut alpha_img = Image::from_bits(
23+
FormatCode::A8R8G8B8,
24+
WIDTH,
25+
HEIGHT,
26+
&mut alpha,
27+
WIDTH * 4,
28+
false,
29+
)
30+
.unwrap();
31+
32+
let mut dest = [0xffffff00u32; WIDTH * HEIGHT]; /* yellow */
33+
let mut dest_img = Image::from_bits(
34+
FormatCode::A8R8G8B8,
35+
WIDTH,
36+
HEIGHT,
37+
&mut dest,
38+
WIDTH * 4,
39+
false,
40+
)
41+
.unwrap();
42+
43+
let mut src = [0xffff0000; WIDTH * HEIGHT];
44+
let mut src_img = Image::from_bits(
45+
FormatCode::A8R8G8B8,
46+
WIDTH,
47+
HEIGHT,
48+
&mut src,
49+
WIDTH * 4,
50+
false,
51+
)
52+
.unwrap();
53+
54+
let mut grad_img = Image::linear_gradient(p1, p2, &stops).unwrap();
55+
grad_img.set_transform(transform).unwrap();
56+
grad_img.set_repeat(Repeat::Pad);
57+
58+
alpha_img.composite(
59+
Operation::Over,
60+
&grad_img,
61+
None,
62+
0,
63+
0,
64+
0,
65+
0,
66+
0,
67+
0,
68+
(10 * WIDTH) as u16,
69+
HEIGHT as u16,
70+
);
71+
72+
src_img.set_alpha_map(Some(&alpha_img), 10, 10);
73+
74+
dest_img.composite(
75+
Operation::Over,
76+
&src_img,
77+
None,
78+
0,
79+
0,
80+
0,
81+
0,
82+
0,
83+
0,
84+
(10 * WIDTH) as u16,
85+
HEIGHT as u16,
86+
);
87+
88+
let mut out_img = Image::new(
89+
FormatCode::A8B8G8R8,
90+
dest_img.width(),
91+
dest_img.height(),
92+
false,
93+
)
94+
.unwrap();
95+
out_img.composite(
96+
Operation::Src,
97+
&dest_img,
98+
None,
99+
0,
100+
0,
101+
0,
102+
0,
103+
0,
104+
0,
105+
dest_img.width() as u16,
106+
dest_img.height() as u16,
107+
);
108+
109+
let out_data = out_img.data().unwrap();
110+
let image_buffer = image::ImageBuffer::<image::Rgba<u8>, _>::from_raw(
111+
out_img.width() as u32,
112+
out_img.height() as u32,
113+
out_data,
114+
)
115+
.unwrap();
116+
image_buffer
117+
.save_with_format("out.png", image::ImageFormat::Png)
118+
.unwrap();
119+
}

pixman/examples/checkerboard.rs

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
use pixman::{Color, Filter, FormatCode, Image, Operation, Repeat};
2+
3+
const WIDTH: usize = 400;
4+
const HEIGHT: usize = 400;
5+
const TILE_SIZE: usize = 25;
6+
7+
pub fn main() {
8+
let mut checkerboard = Image::new(FormatCode::A8R8G8B8, WIDTH, HEIGHT, false).unwrap();
9+
let mut destination = Image::new(FormatCode::A8R8G8B8, WIDTH, HEIGHT, false).unwrap();
10+
11+
// let transform = Transform::new([
12+
// [-1.96830, -1.82250, 512.12250],
13+
// [0.00000, -7.29000, 1458.00000],
14+
// [0.00000, -0.00911, 0.59231],
15+
// ]);
16+
17+
for i in 0..(HEIGHT / TILE_SIZE) {
18+
for j in 0..(WIDTH / TILE_SIZE) {
19+
let u = (j + 1) as f64 / (WIDTH / TILE_SIZE) as f64;
20+
let v = (i + 1) as f64 / (HEIGHT / TILE_SIZE) as f64;
21+
let black = Color::new(0, 0, 0, 0xffff);
22+
let white = Color::new(
23+
(v * 0xffff as f64) as u16,
24+
(u * 0xffff as f64) as u16,
25+
((1.0 - (u as f64)) * 0xffff as f64) as u16,
26+
0xffff,
27+
);
28+
29+
let c = if (j & 1) != (i & 1) { black } else { white };
30+
31+
let fill = Image::solid_fill(c).unwrap();
32+
33+
checkerboard.composite(
34+
Operation::Src,
35+
&fill,
36+
None,
37+
0,
38+
0,
39+
0,
40+
0,
41+
(j * TILE_SIZE) as i16,
42+
(i * TILE_SIZE) as i16,
43+
TILE_SIZE as u16,
44+
TILE_SIZE as u16,
45+
);
46+
}
47+
}
48+
49+
// NOTE: The transform from the original demo completely breaks the image
50+
// checkerboard.set_transform(transform).unwrap();
51+
checkerboard.set_filter(Filter::Best, &[]).unwrap();
52+
checkerboard.set_repeat(Repeat::None);
53+
54+
destination.composite(
55+
Operation::Src,
56+
&checkerboard,
57+
None,
58+
0,
59+
0,
60+
0,
61+
0,
62+
0,
63+
0,
64+
WIDTH as u16,
65+
HEIGHT as u16,
66+
);
67+
68+
let mut out_img = Image::new(
69+
FormatCode::A8B8G8R8,
70+
destination.width(),
71+
destination.height(),
72+
false,
73+
)
74+
.unwrap();
75+
out_img.composite(
76+
Operation::Src,
77+
&destination,
78+
None,
79+
0,
80+
0,
81+
0,
82+
0,
83+
0,
84+
0,
85+
destination.width() as u16,
86+
destination.height() as u16,
87+
);
88+
89+
let out_data = out_img.data().unwrap();
90+
let image_buffer = image::ImageBuffer::<image::Rgba<u8>, _>::from_raw(
91+
out_img.width() as u32,
92+
out_img.height() as u32,
93+
out_data,
94+
)
95+
.unwrap();
96+
image_buffer
97+
.save_with_format("out.png", image::ImageFormat::Png)
98+
.unwrap();
99+
}

0 commit comments

Comments
 (0)