Skip to content

Commit

Permalink
Merge pull request #50 from AnonMiraj/rafactor-modules
Browse files Browse the repository at this point in the history
Rafactor modules
  • Loading branch information
AnonMiraj authored Aug 22, 2024
2 parents 9662188 + f349fed commit c5d8875
Show file tree
Hide file tree
Showing 76 changed files with 4,986 additions and 5,291 deletions.
16 changes: 14 additions & 2 deletions .github/workflows/testing-ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Build and Test

on: [push, pull_request]
on: [push]


jobs:
Expand All @@ -27,11 +27,23 @@ jobs:
run: |
sudo apt-get update
sudo apt install -y gfortran-${GCC_V}
sudo apt install fonts-firacode
sudo apt-get install libcairo2
sudo update-alternatives --install /usr/bin/gfortran gfortran /usr/bin/gfortran-${GCC_V} 100
wget https://github.com/dmtrKovalenko/odiff/releases/download/v3.0.1/odiff-Linux-3.0.0-5826168c.tar.gz
tar zvxf odiff-Linux-3.0.0-5826168c.tar.gz
mv ./odiff-5826168c/bin/ODiffBin odiff
- name: Build and Test Linux
if: contains(matrix.os, 'ubuntu')
run: |
which gfortran
gfortran --version
fpm test
fpm test --flag '-DTESTING'
- name: Upload Artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: upload-artifact
path: .
101 changes: 89 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,93 @@
# FIG (Fortran Intuitive Graphics)
FIG is a Fortran library for that aims to provide intuitive graphics capabilities.
Currently It offers basic 2D primitives such as lines, circles, ellipsis, triangles, and rectangles for creating graphical representations within Fortran programs.
# FIG
FIG is a Fortran library designed to offer intuitive vector graphics capabilities.
It supports a variety of shapes, paths, and text, with output options including PNG, PPM, and SVG.

### Gallery:
Below are some examples of images created using FIG:
## Features
- **Shape Drawing**: Easily draw paths, shapes, and curves.
- **Styling**: Apply stroking, dashing, and other styles to shapes.
- **Text Support**: Render fonts and text with customizable attributes.
- **Export Options**: Save your graphics in PNG, PPM, or SVG formats.

| | |
|---|---|
| ![](./assets/Radial%20Lines.png) | ![](./assets/circles_pattern.png) |
| ![](./assets/rect.png) | ![](./assets/checker.png) |
| ![](./assets/triangles.png)| ![](./assets/cool_triangle_pattern.png)|
| ![](./assets/Smiley%20Face.png)| ![](./assets/fill_area.png)|
## Requirements
- A modern Fortran compiler (such as gfortran).
- `libcairo` and its dependencies for rendering. [Install libcairo](https://www.cairographics.org/download/).

## Example program

Here’s a simple example to get you started:
```fortran
program test_fig
use fig
implicit none
type(drawing) :: canva
type(circle) :: circ
call canva%init()
canva%background = FIG_COLOR_BLACK
circ%c%x = 0.5
circ%c%y = 0.5
circ%r = 25
circ%stroke_color = FIG_COLOR_TAN
circ%fill_color = FIG_COLOR_RED
circ%stroke_width = 3
call canva%add_shape(circ)
circ%r = 15
circ%stroke_color = FIG_COLOR_CYAN
circ%fill_color = FIG_COLOR_GRAY
circ%stroke_width = 2
call canva%add_shape(circ)
! Export the drawing to PNG and SVG formats
call draw_to_png(canva, 100, 100, "png_test")
call draw_to_svg(canva, 200, 300, "svg_test")
end program test_fig
```
result :

![](./test/expected/png_test.png)

**Note**: FIG uses relative coordinates by default. To use absolute coordinates, set `FIG_ABSOLUTE_COORDINATES = .true.`.

For a comprehensive list of shapes and their attributes, refer to the [Shapes source file](https://github.com/AnonMiraj/fig/blob/main/src/backends/fig_shapes.f90) and [Path source file](https://github.com/AnonMiraj/fig/blob/main/src/backends/fig_path_shape.f90).

## Gallery
Below are some examples of images created using FIG.

![Test All](./test/expected/test_all.png)

<details>
<summary>More Examples</summary>

![Radial Lines](./test/expected/radial_lines.svg)

![Circles Pattern](./test/expected/circles_pattern.png)

![Fortran Logo](./test/expected/fortran_logo.png)

![Checker Pattern](./test/expected/checker.png)

![Triangles](./test/expected/triangles.png)

![Cool Triangle Pattern](./test/expected/cool_triangle_pattern.png)
</details>

## fpm
To use fig within your own `fpm` project, add the following dependency to your project `fpm.toml` file:

```toml
[dependencies]
fig= {git = "https://github.com/AnonMiraj/fig" }
```


## To-Do List
- [ ] Add support for additional backends, making `cairo` optional.
- [ ] Implement gradient support.
- [ ] Add PNG file reading capability.
- [ ] Implement transformations (rotations, scaling, etc.).

you can generate them yourself using `fpm test`

4 changes: 0 additions & 4 deletions app/main.f90

This file was deleted.

Binary file removed assets/Radial Lines.png
Binary file not shown.
Binary file removed assets/Smiley Face.png
Binary file not shown.
Binary file removed assets/checker.png
Binary file not shown.
Binary file removed assets/circles_pattern.png
Binary file not shown.
Binary file removed assets/cool_triangle_pattern.png
Binary file not shown.
Binary file removed assets/fill_area.png
Binary file not shown.
Binary file removed assets/rect.png
Binary file not shown.
Binary file removed assets/triangles.png
Binary file not shown.
3 changes: 3 additions & 0 deletions fpm.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ source-form = "free"

[dependencies]
cairo-fortran = {git = "https://github.com/vmagnin/cairo-fortran" }

[preprocess]
[preprocess.cpp]
54 changes: 27 additions & 27 deletions src/backends/fig_canvas.f90
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
module fig_canvas
use fig_config
use fig_shapes
use fig_types
implicit none

type, abstract :: base_canvas
type(canvas_size) :: size
character(len=:), allocatable :: title
contains
procedure(canvas_draw_shape), deferred :: draw_shape
procedure :: init
end type base_canvas
use fig_config
use fig_shapes
use fig_types
implicit none

abstract interface
subroutine canvas_draw_shape(canva,sh)
import base_canvas, shape
class(base_canvas), intent(inout) :: canva
class(shape), intent(in) :: sh
end subroutine canvas_draw_shape
end interface
type, abstract :: base_canvas
type(canvas_size) :: size
character(len=:), allocatable :: title
contains
procedure(canvas_draw_shape), deferred :: draw_shape
procedure :: init
end type base_canvas

abstract interface
subroutine canvas_draw_shape(canva, sh)
import base_canvas, shape
class(base_canvas), intent(inout) :: canva
class(shape), intent(in) :: sh
end subroutine canvas_draw_shape
end interface

contains

subroutine init(this, width, height, title)
class(base_canvas), intent(inout) :: this
integer, intent(in) :: width, height
character(len=*), intent(in) :: title
subroutine init(this, width, height, title)
class(base_canvas), intent(inout) :: this
integer, intent(in) :: width, height
character(len=*), intent(in) :: title

this%size%width = width
this%size%height = height
this%title=title
this%size%width = width
this%size%height = height
this%title = title

end subroutine init
end subroutine init

end module fig_canvas
106 changes: 51 additions & 55 deletions src/backends/fig_drawing.f90
Original file line number Diff line number Diff line change
@@ -1,62 +1,58 @@
module fig_drawing
use fig_config
use fig_shapes
use fig_rgb
use fig_rgb_color_constants
implicit none

type :: drawing
type(shapeWrapper), allocatable :: shapes(:)
type(RGB) :: background = FIG_COLOR_BLANK
integer :: shape_count
contains
procedure :: add_shape
procedure :: set_background
procedure :: init
end type drawing

use fig_config
use fig_shapes
use fig_rgb
use fig_rgb_color_constants
implicit none

type, private :: shape_wrapper
class(shape), allocatable :: sh
end type

type :: drawing
type(shape_wrapper), allocatable :: shapes(:)
type(RGB) :: background = FIG_COLOR_BLANK
integer :: shape_count
contains
procedure :: add_shape
procedure :: init
end type drawing

contains

subroutine init(this)
class(drawing), intent(inout) :: this
this%shape_count = 0
allocate(this%shapes(0))
end subroutine init

subroutine set_background(this, bg_color)
class(drawing), intent(inout) :: this
type(RGB), intent(in), target :: bg_color
this%background=bg_color
end subroutine set_background

subroutine add_shape(this, s)
class(drawing), intent(inout) :: this
class(shape), intent(in), target :: s
integer :: new_size, i
type(shapeWrapper), allocatable :: temp(:)

if (this%shape_count >= size(this%shapes)) then
new_size = max(1, 2 * size(this%shapes))

if (this%shape_count > 0) then
allocate(temp(this%shape_count))
temp = this%shapes(1:this%shape_count)
endif

deallocate(this%shapes)
allocate(this%shapes(new_size))

if (this%shape_count > 0) then
this%shapes(1:this%shape_count) = temp
deallocate(temp)
endif

endif

this%shape_count = this%shape_count + 1
allocate(this%shapes(this%shape_count)%sh, source=s)
end subroutine add_shape
subroutine init(this)
class(drawing), intent(inout) :: this
this%shape_count = 0
allocate (this%shapes(0))
end subroutine init

subroutine add_shape(this, s)
class(drawing), intent(inout) :: this
class(shape), intent(in), target :: s
integer :: new_size
type(shape_wrapper), allocatable :: temp(:)

if (this%shape_count >= size(this%shapes)) then
new_size = max(1, 2*size(this%shapes))

if (this%shape_count > 0) then
allocate (temp(this%shape_count))
temp = this%shapes(1:this%shape_count)
end if

deallocate (this%shapes)
allocate (this%shapes(new_size))

if (this%shape_count > 0) then
this%shapes(1:this%shape_count) = temp
deallocate (temp)
end if

end if

this%shape_count = this%shape_count + 1
allocate (this%shapes(this%shape_count)%sh, source=s)
end subroutine add_shape

end module fig_drawing

Loading

0 comments on commit c5d8875

Please sign in to comment.