Raster-specific drawing utility functions
This module provides low-level drawing primitives for raster graphics including antialiased lines, markers, shapes, and geometric functions.
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
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)
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.
Author: fortplot contributors
Convert floating-point color value [0,1] to byte [0,255]
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in) | :: | color_val |
Calculate minimum distance from point to line segment
Type | Intent | Optional | 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 |
Integer part of floating-point number
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in) | :: | x |
Fractional part of floating-point number
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in) | :: | x |
Reverse fractional part (1 - fractional part)
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in) | :: | x |
Alpha blend a pixel with existing pixel data
Type | Intent | Optional | 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 |
Draw antialiased line using distance-based approach
Type | Intent | Optional | 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 |
Draw filled circle with antialiasing
Type | Intent | Optional | 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 |
Draw circle outline with antialiasing
Type | Intent | Optional | 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 |
Draw circle with separate edge and face colors
Type | Intent | Optional | 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 |
Draw square marker with separate edge and face colors
Type | Intent | Optional | 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 |
Draw diamond marker with separate edge and face colors
Type | Intent | Optional | 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 |
Draw X-shaped marker
Type | Intent | Optional | 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 |
Draw filled quadrilateral using scanline algorithm
Type | Intent | Optional | 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 |