Skip to content

Commit

Permalink
Add support for board flipping and Dockerfile
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasfarias committed Apr 11, 2021
1 parent 5e36efd commit 7e72cd9
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 18 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/release_tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ jobs:
- name: Checkout
uses: actions/checkout@v2

- name: Test
uses: actions-rs/cargo@v1
with:
command: test

- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "c2g"
version = "0.2.1"
version = "0.3.0"
authors = ["Tomas Farias <[email protected]>"]
edition = "2018"

Expand Down
13 changes: 13 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM rust:1.50 as builder

WORKDIR /build

COPY . .

RUN cargo build --release

FROM scratch

COPY --from=builder /build/target/release/c2g /c2g

CMD ["/c2g"]
10 changes: 9 additions & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ impl<'a> Chess2Gif<'a> {
.default_value("chess.gif")
.help("Write GIF to file"),
)
.arg(
Arg::with_name("flip")
.long("flip")
.takes_value(false)
.help("By default, white appears at the bottom, use this flag to flip the board"),
)
.arg(
Arg::with_name("size")
.short("s")
Expand Down Expand Up @@ -117,9 +123,11 @@ impl<'a> Chess2Gif<'a> {
.try_into()
.expect("Invalid light color");

let flip = matches.is_present("flip");

Ok(Chess2Gif {
pgn: pgn,
giffer: PGNGiffer::new(pieces_path, font_path, size, output, 100, dark, light)?,
giffer: PGNGiffer::new(pieces_path, font_path, flip, size, output, 100, dark, light)?,
})
}

Expand Down
49 changes: 40 additions & 9 deletions src/drawer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,15 @@ pub enum DrawerError {
pub struct BoardDrawer {
svgs: SVGForest,
size: u32,
flip: bool,
dark: Rgba<u8>,
light: Rgba<u8>,
}

impl BoardDrawer {
pub fn new(
piece_path: &str,
flip: bool,
font: &str,
size: u32,
dark: [u8; 4],
Expand All @@ -172,6 +174,7 @@ impl BoardDrawer {
Ok(BoardDrawer {
svgs: svgs,
size: size,
flip: flip,
dark: image::Rgba(dark),
light: image::Rgba(light),
})
Expand Down Expand Up @@ -241,8 +244,14 @@ impl BoardDrawer {
log::debug!("Initializing {:?} in {:?}", piece, square);
self.draw_piece(&square, &piece.role, piece.color, false, &mut board)?;
}

self.draw_ranks(2, 6, &mut board)?;

if self.flip == true {
imageops::flip_horizontal_in_place(&mut board);
imageops::flip_vertical_in_place(&mut board);
}

Ok(board)
}

Expand All @@ -253,7 +262,7 @@ impl BoardDrawer {
img: &mut RgbaImage,
) -> Result<(), DrawerError> {
for n in from..to {
let square = Square::new(n * 8);
let square = Square::new((n * 8) + (self.flip as u32 * 7));
self.draw_square(&square, img)?;
}

Expand Down Expand Up @@ -306,20 +315,30 @@ impl BoardDrawer {
}
};

if self.flip == true {
imageops::flip_horizontal_in_place(img);
imageops::flip_vertical_in_place(img);
}

Ok(())
}

pub fn draw_square(&mut self, square: &Square, img: &mut RgbaImage) -> Result<(), DrawerError> {
log::debug!("Drawing square: {}", square);
let pixmap = self.square_pixmap(self.square_size(), self.square_size(), square)?;
let square_img = ImageBuffer::from_raw(pixmap.width(), pixmap.height(), pixmap.take())
let mut square_img = ImageBuffer::from_raw(pixmap.width(), pixmap.height(), pixmap.take())
.ok_or(DrawerError::ImageTooBig {
image: format!("{}x{} square", self.square_size(), self.square_size()),
})?;

let x = self.square_size() * u32::from(square.file());
let y = self.size - self.square_size() * (u32::from(square.rank()) + 1);

if self.flip == true {
imageops::flip_vertical_in_place(&mut square_img);
imageops::flip_horizontal_in_place(&mut square_img);
}

imageops::overlay(img, &square_img, x, y);

Ok(())
Expand All @@ -343,7 +362,13 @@ impl BoardDrawer {
log::debug!("Piece coordinates: ({}, {})", x, y);

let height = self.square_size();
let resized_piece = self.piece_image(color, square, role, height, height)?;
let mut resized_piece = self.piece_image(color, square, role, height, height)?;

if self.flip == true {
imageops::flip_vertical_in_place(&mut resized_piece);
imageops::flip_horizontal_in_place(&mut resized_piece);
}

imageops::replace(img, &resized_piece, x, y);

Ok(())
Expand Down Expand Up @@ -421,8 +446,10 @@ impl BoardDrawer {
true => pixmap.fill(self.dark_color()),
false => pixmap.fill(self.light_color()),
};
if utils::has_coordinate(square) {
if square.rank() == Rank::First {
if utils::has_coordinate(square, self.flip) {
if (square.rank() == Rank::First && self.flip == false)
|| (square.rank() == Rank::Eighth && self.flip == true)
{
let file_pixmap = self.coordinate_pixmap(
square.file().char(),
square,
Expand All @@ -443,7 +470,9 @@ impl BoardDrawer {
);
}

if square.file() == File::A {
if (square.file() == File::A && self.flip == false)
|| (square.file() == File::H && self.flip == true)
{
let rank_pixmap = self.coordinate_pixmap(
square.rank().char(),
square,
Expand All @@ -470,7 +499,8 @@ mod tests {
fn test_square_image() {
let dark: [u8; 4] = [249, 100, 100, 1];
let light: [u8; 4] = [255, 253, 253, 1];
let mut drawer = BoardDrawer::new("some/path/".to_string(), None, 80, dark, light).unwrap();
let mut drawer =
BoardDrawer::new("some/path/", false, "roboto.ttf", 80, dark, light).unwrap();

let square = Square::new(0); // A1 is dark
let expected = ImageBuffer::from_pixel(10, 10, image::Rgba(dark));
Expand All @@ -485,7 +515,7 @@ mod tests {
fn test_sizes() {
let dark: [u8; 4] = [249, 100, 100, 1];
let light: [u8; 4] = [255, 253, 253, 1];
let drawer = BoardDrawer::new("some/path/".to_string(), None, 80, dark, light).unwrap();
let drawer = BoardDrawer::new("some/path/", false, "roboto.ttf", 80, dark, light).unwrap();

assert_eq!(drawer.size(), 80);
assert_eq!(drawer.square_size(), 10);
Expand All @@ -495,7 +525,8 @@ mod tests {
fn test_square_pixmap() {
let dark: [u8; 4] = [249, 100, 100, 1];
let light: [u8; 4] = [255, 253, 253, 1];
let mut drawer = BoardDrawer::new("some/path/".to_string(), None, 80, dark, light).unwrap();
let mut drawer =
BoardDrawer::new("some/path/", false, "roboto.ttf", 80, dark, light).unwrap();

let mut pixmap = Pixmap::new(10, 10).unwrap();
let square = Square::new(9); // B2 is dark
Expand Down
3 changes: 2 additions & 1 deletion src/giffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ impl<'a> PGNGiffer<'a> {
pub fn new(
pieces_path: &str,
font_path: &str,
flip: bool,
board_size: u32,
output_path: &str,
ms_delay: u16,
Expand All @@ -49,7 +50,7 @@ impl<'a> PGNGiffer<'a> {
fs::File::create(output_path).map_err(|source| GifferError::CreateOutput { source })?;
let buffer = BufWriter::with_capacity(1000, file);

let drawer = BoardDrawer::new(pieces_path, font_path, board_size as u32, dark, light)
let drawer = BoardDrawer::new(pieces_path, flip, font_path, board_size as u32, dark, light)
.map_err(|source| GifferError::DrawerError { source: source })?;

let mut encoder = Encoder::new(buffer, drawer.size() as u16, drawer.size() as u16, &[])
Expand Down
24 changes: 19 additions & 5 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use shakmaty::{File, Rank, Square};

pub fn has_coordinate(s: &Square) -> bool {
if s.rank() == Rank::First || s.file() == File::A {
pub fn has_coordinate(s: &Square, flip: bool) -> bool {
if (s.rank() == Rank::First || s.file() == File::A) && flip == false {
true
} else if (s.rank() == Rank::Eighth || s.file() == File::H) && flip == true {
true
} else {
false
Expand All @@ -15,12 +17,24 @@ mod tests {
#[test]
fn test_has_coordinate() {
let square = Square::new(0); // A1
assert!(has_coordinate(&square));
assert!(has_coordinate(&square, false));

let square = Square::new(9); // B2
assert!(!has_coordinate(&square));
assert!(!has_coordinate(&square, false));

let square = Square::new(56); // A8
assert!(has_coordinate(&square));
assert!(has_coordinate(&square, false));
}

#[test]
fn test_has_coordinate_flip() {
let square = Square::new(0); // A1
assert!(!has_coordinate(&square, true));

let square = Square::new(7); // H1
assert!(has_coordinate(&square, true));

let square = Square::new(63); // H8
assert!(has_coordinate(&square, true));
}
}

0 comments on commit 7e72cd9

Please sign in to comment.