fortplot_raster_drawing Module

Raster-specific drawing utility functions

This module provides low-level drawing primitives for raster graphics including antialiased lines, markers, shapes, and geometric functions.

Pixel Coordinate System Conventions

The module uses a 1-based coordinate system consistent with Fortran arrays: - Pixel (1,1) is at the top-left corner - x-coordinates increase rightward, y-coordinates increase downward - All coordinates are internally converted using nint() for consistency

Antialiasing Approach

All drawing functions use distance-based antialiasing: - Calculate exact distance from pixel center to geometric shape - Alpha value derived from distance: alpha = 1.0 - max(0, distance - radius/half_width) - Sub-pixel accuracy maintained through real-valued intermediate calculations - Final pixel blending uses consistent coordinate rounding (nint)

Line-Marker Coordinate Alignment

Critical design principle: Lines and markers must align precisely at data points. Both line drawing (draw_line_distance_aa) and marker positioning use identical coordinate rounding via nint() in blend_pixel to prevent visual misalignment. This addresses the centering issue where markers appeared offset from line endpoints.

Color Representation

  • Input colors: real values in range [0.0, 1.0]
  • Storage: signed bytes representing unsigned values [0, 255]
  • Conversion: color_to_byte handles proper range mapping and byte encoding
  • Alpha blending: standard over-operation with clamped alpha values

Author: fortplot contributors



Functions

public function color_to_byte(color_val) result(byte_val)

Convert floating-point color value [0,1] to byte [0,255]

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: color_val

Return Value integer(kind=1)

public function distance_point_to_line_segment(px, py, x1, y1, x2, y2) result(distance)

Calculate minimum distance from point to line segment

Read more…

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: px
real(kind=wp), intent(in) :: py
real(kind=wp), intent(in) :: x1
real(kind=wp), intent(in) :: y1
real(kind=wp), intent(in) :: x2
real(kind=wp), intent(in) :: y2

Return Value real(kind=wp)

public function ipart(x) result(i)

Integer part of floating-point number

Read more…

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: x

Return Value integer

public function fpart(x) result(f)

Fractional part of floating-point number

Read more…

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: x

Return Value real(kind=wp)

public function rfpart(x) result(rf)

Reverse fractional part (1 - fractional part)

Read more…

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: x

Return Value real(kind=wp)


Subroutines

public subroutine blend_pixel(image_data, img_w, img_h, x, y, alpha, new_r, new_g, new_b)

Alpha blend a pixel with existing pixel data

Read more…

Arguments

Type IntentOptional Attributes Name
integer(kind=1), intent(inout) :: image_data(:)
integer, intent(in) :: img_w
integer, intent(in) :: img_h
real(kind=wp), intent(in) :: x
real(kind=wp), intent(in) :: y
real(kind=wp), intent(in) :: alpha
real(kind=wp), intent(in) :: new_r
real(kind=wp), intent(in) :: new_g
real(kind=wp), intent(in) :: new_b

public subroutine draw_line_distance_aa(image_data, img_w, img_h, x0, y0, x1, y1, r, g, b, width)

Draw antialiased line using distance-based approach

Read more…

Arguments

Type IntentOptional Attributes Name
integer(kind=1), intent(inout) :: image_data(:)
integer, intent(in) :: img_w
integer, intent(in) :: img_h
real(kind=wp), intent(in) :: x0
real(kind=wp), intent(in) :: y0
real(kind=wp), intent(in) :: x1
real(kind=wp), intent(in) :: y1
real(kind=wp), intent(in) :: r
real(kind=wp), intent(in) :: g
real(kind=wp), intent(in) :: b
real(kind=wp), intent(in) :: width

public subroutine draw_circle_antialiased(image_data, img_w, img_h, cx, cy, radius, r, g, b)

Draw filled circle with antialiasing

Read more…

Arguments

Type IntentOptional Attributes Name
integer(kind=1), intent(inout) :: image_data(:)
integer, intent(in) :: img_w
integer, intent(in) :: img_h
real(kind=wp), intent(in) :: cx
real(kind=wp), intent(in) :: cy
real(kind=wp), intent(in) :: radius
real(kind=wp), intent(in) :: r
real(kind=wp), intent(in) :: g
real(kind=wp), intent(in) :: b

public subroutine draw_circle_outline_antialiased(image_data, img_w, img_h, cx, cy, radius, r, g, b)

Draw circle outline with antialiasing

Read more…

Arguments

Type IntentOptional Attributes Name
integer(kind=1), intent(inout) :: image_data(:)
integer, intent(in) :: img_w
integer, intent(in) :: img_h
real(kind=wp), intent(in) :: cx
real(kind=wp), intent(in) :: cy
real(kind=wp), intent(in) :: radius
real(kind=wp), intent(in) :: r
real(kind=wp), intent(in) :: g
real(kind=wp), intent(in) :: b

public subroutine draw_circle_with_edge_face(image_data, img_w, img_h, cx, cy, radius, edge_r, edge_g, edge_b, edge_alpha, face_r, face_g, face_b, face_alpha)

Draw circle with separate edge and face colors

Read more…

Arguments

Type IntentOptional Attributes Name
integer(kind=1), intent(inout) :: image_data(:)
integer, intent(in) :: img_w
integer, intent(in) :: img_h
real(kind=wp), intent(in) :: cx
real(kind=wp), intent(in) :: cy
real(kind=wp), intent(in) :: radius
real(kind=wp), intent(in) :: edge_r
real(kind=wp), intent(in) :: edge_g
real(kind=wp), intent(in) :: edge_b
real(kind=wp), intent(in) :: edge_alpha
real(kind=wp), intent(in) :: face_r
real(kind=wp), intent(in) :: face_g
real(kind=wp), intent(in) :: face_b
real(kind=wp), intent(in) :: face_alpha

public subroutine draw_square_with_edge_face(image_data, img_w, img_h, cx, cy, size, edge_r, edge_g, edge_b, edge_alpha, face_r, face_g, face_b, face_alpha)

Draw square marker with separate edge and face colors

Arguments

Type IntentOptional Attributes Name
integer(kind=1), intent(inout) :: image_data(:)
integer, intent(in) :: img_w
integer, intent(in) :: img_h
real(kind=wp), intent(in) :: cx
real(kind=wp), intent(in) :: cy
real(kind=wp), intent(in) :: size
real(kind=wp), intent(in) :: edge_r
real(kind=wp), intent(in) :: edge_g
real(kind=wp), intent(in) :: edge_b
real(kind=wp), intent(in) :: edge_alpha
real(kind=wp), intent(in) :: face_r
real(kind=wp), intent(in) :: face_g
real(kind=wp), intent(in) :: face_b
real(kind=wp), intent(in) :: face_alpha

public subroutine draw_diamond_with_edge_face(image_data, img_w, img_h, cx, cy, size, edge_r, edge_g, edge_b, edge_alpha, face_r, face_g, face_b, face_alpha)

Draw diamond marker with separate edge and face colors

Arguments

Type IntentOptional Attributes Name
integer(kind=1), intent(inout) :: image_data(:)
integer, intent(in) :: img_w
integer, intent(in) :: img_h
real(kind=wp), intent(in) :: cx
real(kind=wp), intent(in) :: cy
real(kind=wp), intent(in) :: size
real(kind=wp), intent(in) :: edge_r
real(kind=wp), intent(in) :: edge_g
real(kind=wp), intent(in) :: edge_b
real(kind=wp), intent(in) :: edge_alpha
real(kind=wp), intent(in) :: face_r
real(kind=wp), intent(in) :: face_g
real(kind=wp), intent(in) :: face_b
real(kind=wp), intent(in) :: face_alpha

public subroutine draw_x_marker(image_data, img_w, img_h, cx, cy, size, edge_r, edge_g, edge_b)

Draw X-shaped marker

Arguments

Type IntentOptional Attributes Name
integer(kind=1), intent(inout) :: image_data(:)
integer, intent(in) :: img_w
integer, intent(in) :: img_h
real(kind=wp), intent(in) :: cx
real(kind=wp), intent(in) :: cy
real(kind=wp), intent(in) :: size
real(kind=wp), intent(in) :: edge_r
real(kind=wp), intent(in) :: edge_g
real(kind=wp), intent(in) :: edge_b

public subroutine draw_filled_quad_raster(image_data, img_w, img_h, x_quad, y_quad, r, g, b)

Draw filled quadrilateral using scanline algorithm

Read more…

Arguments

Type IntentOptional Attributes Name
integer(kind=1), intent(inout) :: image_data(:)
integer, intent(in) :: img_w
integer, intent(in) :: img_h
real(kind=wp), intent(in) :: x_quad(4)
real(kind=wp), intent(in) :: y_quad(4)
real(kind=wp), intent(in) :: r
real(kind=wp), intent(in) :: g
real(kind=wp), intent(in) :: b