fortplot_markers.f90 Source File


Source Code

module fortplot_markers
    !! Shared marker utilities following DRY principles
    !! Eliminates code duplication between PNG and PDF backends
    use, intrinsic :: iso_fortran_env, only: wp => real64
    implicit none
    
    private
    public :: get_marker_size, validate_marker_style, get_default_marker
    public :: MARKER_CIRCLE, MARKER_SQUARE, MARKER_DIAMOND, MARKER_CROSS, MARKER_PLUS, MARKER_STAR
    public :: MARKER_TRIANGLE_UP, MARKER_TRIANGLE_DOWN, MARKER_PENTAGON, MARKER_HEXAGON
    public :: MARKER_DIAMOND_SMALL
    
    ! Marker style constants - pyplot compatible
    character(len=*), parameter :: MARKER_CIRCLE = 'o'
    character(len=*), parameter :: MARKER_SQUARE = 's' 
    character(len=*), parameter :: MARKER_DIAMOND = 'D'
    character(len=*), parameter :: MARKER_DIAMOND_SMALL = 'd'
    character(len=*), parameter :: MARKER_CROSS = 'x'
    character(len=*), parameter :: MARKER_PLUS = '+'
    character(len=*), parameter :: MARKER_STAR = '*'
    character(len=*), parameter :: MARKER_TRIANGLE_UP = '^'
    character(len=*), parameter :: MARKER_TRIANGLE_DOWN = 'v'
    character(len=*), parameter :: MARKER_PENTAGON = 'p'
    character(len=*), parameter :: MARKER_HEXAGON = 'h'
    
    ! Marker size constants - centralized for consistency
    real(wp), parameter :: SIZE_CIRCLE = 5.0_wp
    real(wp), parameter :: SIZE_SQUARE = 6.0_wp
    real(wp), parameter :: SIZE_DIAMOND = 6.0_wp
    real(wp), parameter :: SIZE_CROSS = 5.0_wp
    real(wp), parameter :: SIZE_PLUS = 5.0_wp
    real(wp), parameter :: SIZE_STAR = 7.0_wp
    real(wp), parameter :: SIZE_TRIANGLE = 6.0_wp
    real(wp), parameter :: SIZE_PENTAGON = 7.0_wp
    real(wp), parameter :: SIZE_HEXAGON = 7.0_wp

contains

    pure function get_marker_size(style) result(size)
        !! Get standardized marker size for given style
        !! Eliminates magic number duplication across backends
        character(len=*), intent(in) :: style
        real(wp) :: size
        
        select case (trim(style))
        case (MARKER_CIRCLE)
            size = SIZE_CIRCLE
        case (MARKER_SQUARE)
            size = SIZE_SQUARE
        case (MARKER_DIAMOND, MARKER_DIAMOND_SMALL)
            size = SIZE_DIAMOND
        case (MARKER_CROSS)
            size = SIZE_CROSS
        case (MARKER_PLUS)
            size = SIZE_PLUS
        case (MARKER_STAR)
            size = SIZE_STAR
        case (MARKER_TRIANGLE_UP, MARKER_TRIANGLE_DOWN)
            size = SIZE_TRIANGLE
        case (MARKER_PENTAGON)
            size = SIZE_PENTAGON
        case (MARKER_HEXAGON)
            size = SIZE_HEXAGON
        case default
            size = SIZE_CIRCLE  ! Default fallback
        end select
    end function get_marker_size

    pure function validate_marker_style(style) result(is_valid)
        !! Validate if marker style is supported
        character(len=*), intent(in) :: style
        logical :: is_valid
        
        select case (trim(style))
        case (MARKER_CIRCLE, MARKER_SQUARE, MARKER_DIAMOND, MARKER_DIAMOND_SMALL, MARKER_CROSS, &
              MARKER_PLUS, MARKER_STAR, MARKER_TRIANGLE_UP, MARKER_TRIANGLE_DOWN, &
              MARKER_PENTAGON, MARKER_HEXAGON)
            is_valid = .true.
        case default
            is_valid = .false.
        end select
    end function validate_marker_style
    
    pure function get_default_marker() result(marker)
        !! Get default marker style
        character(len=1) :: marker
        marker = MARKER_CIRCLE
    end function get_default_marker

end module fortplot_markers