Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${command:cmake.launchTargetPath}",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
{
"name": "(Windows) Launch",
"type": "cppvsdbg",
Expand Down
10 changes: 10 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"cmake.coverageInfoFiles": [
"${workspaceFolder}/build/coverage_filtered.info"
],
Comment thread
royratcliffe marked this conversation as resolved.
// NOTE: The 'lcov' target is only defined when lcov is installed and the build type is Debug.
// In other configurations, "Run with coverage" may fail if this target is not available.
"cmake.postRunCoverageTarget": "lcov",
"testing.coverageToolbarEnabled": true,
"testing.defaultGutterClickAction": "runWithCoverage"
}
31 changes: 20 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
cmake_minimum_required(VERSION 3.25)
project(blit)

# Enable generation of compile_commands.json for tools like cppcheck and
# clang-tidy. This will allow these tools to understand the compilation
# commands and flags used for the project, which is good for accurate
# analysis and reporting.
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_library(blit
# Source files for the blit library.
${CMAKE_CURRENT_SOURCE_DIR}/src/blit/rop2.c
Expand All @@ -22,6 +28,7 @@ create_test_sourcelist(test_sources
test_driver.c
test/pat.c
test/left_shift_edge.c
test/extra_scan_count.c
)

# Add a test executable that links against the library.
Expand All @@ -34,16 +41,18 @@ target_link_libraries(test_runner PRIVATE blit)

add_test(NAME pat COMMAND test_runner test/pat)
add_test(NAME left_shift_edge COMMAND test_runner test/left_shift_edge)
add_test(NAME extra_scan_count COMMAND test_runner test/extra_scan_count)

# https://cmake.org/cmake/help/latest/module/FindDoxygen.html
# https://www.mcternan.me.uk/mscgen/
find_package(Doxygen OPTIONAL_COMPONENTS dot mscgen dia)
if(DOXYGEN_FOUND)
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE README.md)
set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
set(DOXYGEN_SOURCE_BROWSER YES)
set(DOXYGEN_EXCLUDE ${CMAKE_BINARY_DIR})
doxygen_add_docs(doxy ${CMAKE_SOURCE_DIR}
COMMENT "Generating API documentation with Doxygen"
)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(lcov)
if(LCOV)
# Add the necessary compiler and linker flags to enable code coverage analysis.
# Use generator expressions so coverage is only enabled for Debug configuration,
# which works for both single- and multi-config generators.
foreach(target IN ITEMS blit test_runner)
target_compile_options(${target} PRIVATE $<$<CONFIG:Debug>:--coverage>)
target_link_options(${target} PRIVATE $<$<CONFIG:Debug>:--coverage>)
endforeach()
endif()
include(doxy)
include(cppcheck)
22 changes: 22 additions & 0 deletions cmake/cppcheck.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Add custom commands for code analysis. Enable cppcheck for Debug build type.
# This will run cppcheck only when building the Debug configuration, using configuration-aware logic.
find_program(CPPCHECK cppcheck)
if(CPPCHECK)
add_custom_target(cppcheck
COMMAND $<$<CONFIG:Debug>:${CPPCHECK}>
$<$<CONFIG:Debug>:--project=${CMAKE_BINARY_DIR}/compile_commands.json>
$<$<CONFIG:Debug>:--output-file=${CMAKE_BINARY_DIR}/cppcheck_report.xml>
$<$<CONFIG:Debug>:--xml>
$<$<CONFIG:Debug>:--enable=all>
$<$<CONFIG:Debug>:--enable=warning,style,performance,portability,information>
$<$<CONFIG:Debug>:--suppressions-list=${CMAKE_SOURCE_DIR}/cppcheck_suppressions.txt>
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Running cppcheck for code analysis (Debug configuration only)"
# Use VERBATIM to ensure the command is executed as written.
# This is useful for handling paths with spaces or special characters.
VERBATIM
)
set_property(TARGET cppcheck PROPERTY FOLDER "Analysis")
Comment thread
royratcliffe marked this conversation as resolved.
else()
message(STATUS "Cppcheck not found; code analysis target will not be created")
endif()
13 changes: 13 additions & 0 deletions cmake/doxy.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# https://cmake.org/cmake/help/latest/module/FindDoxygen.html
# https://www.mcternan.me.uk/mscgen/
find_package(Doxygen OPTIONAL_COMPONENTS dot mscgen dia)
if(DOXYGEN_FOUND)
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE ${CMAKE_SOURCE_DIR}/README.md)
set(DOXYGEN_USE_MATHJAX YES)
set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
set(DOXYGEN_SOURCE_BROWSER YES)
set(DOXYGEN_EXCLUDE ${CMAKE_BINARY_DIR})
doxygen_add_docs(doxy ${CMAKE_SOURCE_DIR}
COMMENT "Generating API documentation with Doxygen"
)
endif()
46 changes: 46 additions & 0 deletions cmake/lcov.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Add custom commands for code coverage analysis. Enable lcov and genhtml if
# they are found. Only enable code coverage analysis for Debug build type, as it
# is typically used for development and testing. Code coverage analysis can add
# overhead to the build and runtime, so it is generally not recommended for
# Release builds.
#
# If lcov is found, add the coverage compiler and linker flags to enable code
# coverage analysis.
#
# Note that find_program will return the path to the executable if found, or
# NOTFOUND if not found. It will also cache the result, so subsequent calls will
# return the cached value. This allows us to check if lcov is available and
# conditionally add code coverage targets.
find_program(LCOV lcov)
if(LCOV)
# Add custom targets for code coverage analysis using lcov and genhtml.
# These targets will run the tests, capture coverage data, and generate an HTML report.
add_custom_target(ctest
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
DEPENDS test_runner
)
add_custom_target(lcov
COMMAND ${LCOV} --capture --directory . --output-file coverage.info
COMMAND ${LCOV} --remove coverage.info '/usr/*' '*/test*' --output-file coverage_filtered.info
Comment thread
royratcliffe marked this conversation as resolved.
DEPENDS ctest
)
set_property(TARGET lcov PROPERTY FOLDER "Analysis")

# If genhtml is found, add a custom target to generate an HTML report from the
# filtered coverage data. This will create a coverage_report directory with an
# index.html file that can be opened in a web browser to view the coverage report.
find_program(GENHTML genhtml)
if(GENHTML)
message(STATUS "lcov and genhtml found, code coverage targets will be available")
add_custom_target(genhtml
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${GENHTML} coverage_filtered.info --output-directory coverage_report
COMMAND ${CMAKE_COMMAND} -E echo "Coverage report generated in: ${CMAKE_BINARY_DIR}/coverage_report/index.html"
DEPENDS lcov
)
set_property(TARGET genhtml PROPERTY FOLDER "Analysis")
else()
message(STATUS "genhtml not found, HTML code coverage report target will not be available")
endif()
endif()
Empty file added cppcheck_suppressions.txt
Empty file.
14 changes: 7 additions & 7 deletions inc/blit/rgn1.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* \brief One-dimensional region structure.
* \details This header file defines the \c blit_rgn1 structure, which
* represents a one-dimensional region with an origin, extent, and source
* origin. It also provides inline functions for normalising, slipping, and
* origin. It also provides inline functions for normalising, moving, and
* clipping the region.
*/

Expand Down Expand Up @@ -40,7 +40,7 @@ struct blit_rgn1 {

/*!
* \brief Normalise a one-dimensional region.
* \details This function normalizes a one-dimensional region represented by the
* \details This function normalises a one-dimensional region represented by the
* \c blit_rgn1 structure. If the extent of the region is negative, it
* adjusts the origin and origin_source accordingly to ensure that the
* extent is non-negative.
Expand All @@ -62,18 +62,18 @@ static inline void blit_rgn1_norm(struct blit_rgn1 *rgn1) {
}

/*!
* \brief Slip a one-dimensional region into positive space.
* \brief Move a one-dimensional region into positive space.
* \details This function adjusts a one-dimensional region represented by the
* \c blit_rgn1 structure to ensure that both the origin and source origin are
* non-negative. If either the origin or source origin is negative, the region
* is "slipped" into positive space by adjusting the origins and reducing the
* is "moved" into positive space by adjusting the origins and reducing the
* extent accordingly. If the entire region is outside positive space, the
* function returns false.
* \param rgn1 Pointer to the \c blit_rgn1 structure to slip.
* \retval true if the region was successfully slipped into positive space.
* \param rgn1 Pointer to the \c blit_rgn1 structure to move.
* \retval true if the region was successfully moved into positive space.
* \retval false if the entire region is outside positive space.
*/
static inline bool blit_rgn1_slip(struct blit_rgn1 *rgn1) {
static inline bool blit_rgn1_move(struct blit_rgn1 *rgn1) {
int offset = rgn1->origin < 0
? (rgn1->origin < rgn1->origin_source ? -rgn1->origin
: -rgn1->origin_source)
Expand Down
26 changes: 18 additions & 8 deletions inc/blit/rop2.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,17 @@ enum blit_rop2 {
* \param y Pointer to the one-dimensional region structure for the y-axis.
* \param source Pointer to the source scan structure.
* \param rop2 The raster operation code.
* \return true if the operation was successful, false otherwise.
* \return The number of logic operations performed. This includes all
* operations performed on the destination scan space, including those
* that may not have resulted in a change to the pixel values (e.g.,
* operations that resulted in the same value being written back to the
* destination). It includes partial operations on the first and last
* bytes of each scanline, which may have been masked to only affect
* certain bits. The count reflects the total number of operations
* attempted based on the region and raster operation specified,
* regardless of the actual changes made to the pixel data.
*/
bool blit_rgn1_rop2(struct blit_scan *result, struct blit_rgn1 *x,
struct blit_rgn1 *y, const struct blit_scan *source,
enum blit_rop2 rop2);
int blit_rgn1_rop2(struct blit_scan *result, struct blit_rgn1 *x, struct blit_rgn1 *y, const struct blit_scan *source, enum blit_rop2 rop2);

/*!
* \brief Convenience inline function for performing raster operations.
Expand All @@ -98,10 +104,14 @@ bool blit_rgn1_rop2(struct blit_scan *result, struct blit_rgn1 *x,
* \param x_source The x-coordinate of the origin of the region in the source.
* \param y_source The y-coordinate of the origin of the region in the source.
* \param rop2 The raster operation code to apply.
* \return The number of logic operations performed.
*/
bool blit_rop2(struct blit_scan *result, const int x, const int y,
const int x_extent, const int y_extent,
const struct blit_scan *source, const int x_source,
const int y_source, enum blit_rop2 rop2);
int blit_rop2(struct blit_scan *result,
/* destination region */
const int x, const int y, const int x_extent, const int y_extent,
/* source region */
const struct blit_scan *source, const int x_source, const int y_source,
/* raster operation */
enum blit_rop2 rop2);

#endif /* __BLIT_ROP2_H__ */
Loading