cmake_minimum_required(VERSION 3.31.6)
project(CompositorWindows VERSION 0.1.4 LANGUAGES C CXX)
option(COMPOSITOR_ASAN "Instrument native code with MSVC AddressSanitizer" OFF)
if(COMPOSITOR_ASAN)
  add_compile_options(/fsanitize=address /Zi)
  add_link_options(/INCREMENTAL:NO /DEBUG)
endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 11)
find_package(Qt6 6.8.3 EXACT REQUIRED COMPONENTS Core Gui Widgets Test Concurrent)
find_package(Python3 3.11 REQUIRED COMPONENTS Interpreter)
include(CTest)
# Windows searches System32 before PATH for imported DLLs. Keep the locked
# codecs and ORT runtime beside every development executable, as packaging does.
file(READ "${CMAKE_SOURCE_DIR}/dependencies/imaging/lock.json" imaging_lock)
string(JSON imaging_binary_count LENGTH "${imaging_lock}" binaries)
math(EXPR imaging_binary_last "${imaging_binary_count}-1")
set(imaging_runtime_files)
foreach(index RANGE ${imaging_binary_last})
  string(JSON binary_path GET "${imaging_lock}" binaries ${index} path)
  string(JSON expected_hash GET "${imaging_lock}" binaries ${index} sha256)
  set(binary_file "${CMAKE_SOURCE_DIR}/dependencies/imaging/${binary_path}")
  file(SHA256 "${binary_file}" actual_hash)
  if(NOT actual_hash STREQUAL expected_hash)
    message(FATAL_ERROR "Locked imaging runtime checksum mismatch: ${binary_path}")
  endif()
  list(APPEND imaging_runtime_files "${binary_file}")
endforeach()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIG>")
add_custom_target(deploy_imaging_runtime
  COMMAND "${CMAKE_COMMAND}" "-DIMAGING_ROOT=${CMAKE_SOURCE_DIR}/dependencies/imaging" "-DRUNTIME_DESTINATION=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
    -P "${CMAKE_SOURCE_DIR}/scripts/deploy-imaging-runtime.cmake"
  VERBATIM)
add_library(compositor_core src/core/Document.cpp src/core/CompositeCache.cpp)
target_include_directories(compositor_core PUBLIC src)
target_compile_definitions(compositor_core PUBLIC NOMINMAX WIN32_LEAN_AND_MEAN)
target_compile_options(compositor_core PRIVATE /W4 /permissive- /utf-8)
target_link_libraries(compositor_core PUBLIC ole32)
set(UPSTREAM_C_MODULES AdjustPixels BrushPixels ContentFill HealPixels LensPixels LevelsPixels NoisePixels WandPixels)
set(UPSTREAM_C_SOURCES)
foreach(module IN LISTS UPSTREAM_C_MODULES)
  list(APPEND UPSTREAM_C_SOURCES src/graphics/upstream/${module}.c)
endforeach()
add_library(compositor_graphics ${UPSTREAM_C_SOURCES} src/graphics/PixelAlgorithms.cpp src/graphics/BrushCoverage.cpp src/graphics/D3D11BrushCoverage.cpp)
target_include_directories(compositor_graphics PUBLIC src)
target_compile_definitions(compositor_graphics PRIVATE _USE_MATH_DEFINES PUBLIC NOMINMAX WIN32_LEAN_AND_MEAN)
target_compile_options(compositor_graphics PRIVATE /W4 /WX /utf-8)
target_link_libraries(compositor_graphics PUBLIC d3d11 d3dcompiler dxgi)
target_sources(compositor_graphics PRIVATE src/graphics/BrushSession.cpp)
target_sources(compositor_graphics PRIVATE src/graphics/GrowingBrushSession.cpp)
target_sources(compositor_graphics PRIVATE src/graphics/StackRenderer.cpp)
target_sources(compositor_graphics PRIVATE src/graphics/Downsample.cpp src/graphics/SamplingSource.cpp)
target_sources(compositor_graphics PRIVATE src/graphics/ParallelBatch.cpp)
target_link_libraries(compositor_graphics PUBLIC compositor_core)
add_library(compositor_filters src/filters/PixelFilters.cpp)
add_library(compositor_layers src/layers/LayerOperations.cpp)
target_link_libraries(compositor_layers PUBLIC compositor_core compositor_graphics)
target_compile_options(compositor_layers PRIVATE /W4 /utf-8)
target_link_libraries(compositor_filters PUBLIC compositor_core compositor_graphics)
target_compile_options(compositor_filters PRIVATE /W4 /utf-8)
add_library(compositor_render src/render/SoftwareRenderer.cpp)
add_library(compositor_editing src/editing/Selection.cpp src/editing/PixelEdits.cpp)
target_sources(compositor_editing PRIVATE src/editing/Shapes.cpp src/editing/DocumentGeometry.cpp)
target_sources(compositor_editing PRIVATE src/editing/SelectionGesture.cpp)
target_sources(compositor_editing PRIVATE src/editing/GradientPreview.cpp)
target_link_libraries(compositor_editing PUBLIC Qt6::Core)
add_library(compositor_transform src/editing_transform/TransformGeometry.cpp src/editing_transform/Distortion.cpp src/editing_transform/PixelTransform.cpp)
add_library(compositor_retouch src/retouch/RetouchSession.cpp)
target_link_libraries(compositor_retouch PUBLIC compositor_graphics compositor_core compositor_render)
target_compile_options(compositor_retouch PRIVATE /W4 /WX /utf-8)
target_link_libraries(compositor_transform PUBLIC compositor_core compositor_editing)
target_link_libraries(compositor_editing PUBLIC compositor_graphics)
target_link_libraries(compositor_editing PUBLIC compositor_core d2d1 windowscodecs ole32)
target_compile_options(compositor_editing PRIVATE /W4 /utf-8)
target_link_libraries(compositor_render PUBLIC compositor_core compositor_graphics)
add_library(compositor_effects src/effects/Adjustments.cpp)
add_library(compositor_effects_tools src/effects_tools/Levels.cpp src/effects_tools/Hue.cpp src/effects_tools/Curves.cpp src/effects_tools/Color.cpp)
target_link_libraries(compositor_effects_tools PUBLIC compositor_core compositor_graphics Qt6::Core)
target_compile_options(compositor_effects_tools PRIVATE /W4 /utf-8)
target_link_libraries(compositor_effects PUBLIC compositor_graphics Qt6::Core)
target_compile_options(compositor_effects PRIVATE /W4 /utf-8)
target_link_libraries(compositor_render PUBLIC compositor_effects)
add_library(compositor_imaging src/imaging/wic_codec.cpp src/imaging/project_png.cpp src/imaging/heif_codec.cpp src/imaging/subject_matte.cpp)
target_sources(compositor_imaging PRIVATE src/imaging/subject_input.cpp)
add_executable(subject_input_tests tests/imaging/input_resize42/InputResizeTests.cpp)
target_compile_definitions(subject_input_tests PRIVATE SUBJECT_INPUT_PRODUCTION_ONLY)
target_include_directories(subject_input_tests PRIVATE src/imaging)
target_link_libraries(subject_input_tests PRIVATE compositor_imaging)
foreach(case identity down_even down_odd up_small mixed_wide mixed_tall thin_wide thin_tall alpha_down alpha_up constant transparent padded_stride cancel_before cancel_validation cancel_resample budget_reject invalid_premultiplication invalid_stride source_unchanged maximum_axis_memory dimension_preflight)
  add_test(NAME subject_input.${case} COMMAND "${Python3_EXECUTABLE}"
    "${CMAKE_SOURCE_DIR}/tests/imaging/input_resize42/run-case.py"
    --executable $<TARGET_FILE:subject_input_tests> --case ${case}
    --fixtures "${CMAKE_SOURCE_DIR}/tests/imaging/input_resize42/fixtures-02"
    --output-root "${CMAKE_BINARY_DIR}/subject-input-evidence")
  set_tests_properties(subject_input.${case} PROPERTIES TIMEOUT 150)
endforeach()
target_sources(compositor_imaging PRIVATE src/imaging/stream_export.cpp)
target_sources(compositor_render PRIVATE src/core/DocumentExport.cpp)
target_link_libraries(compositor_render PUBLIC compositor_imaging)
target_include_directories(compositor_imaging PUBLIC src PRIVATE dependencies/imaging/install/include)
target_link_directories(compositor_imaging PUBLIC dependencies/imaging/install/lib)
target_compile_definitions(compositor_imaging PUBLIC NOMINMAX WIN32_LEAN_AND_MEAN)
target_compile_options(compositor_imaging PRIVATE /W4 /utf-8)
target_link_libraries(compositor_imaging PUBLIC windowscodecs ole32 oleaut32 propsys heif de265)
target_sources(compositor_imaging PRIVATE src/imaging/onnx_subject_provider.cpp)
target_include_directories(compositor_imaging PRIVATE dependencies/imaging/onnxruntime-win-x64-1.30.0/include)
target_link_directories(compositor_imaging PUBLIC dependencies/imaging/onnxruntime-win-x64-1.30.0/lib)
target_link_libraries(compositor_imaging PUBLIC onnxruntime bcrypt)
add_library(compositor_persistence src/persistence/ProjectStore.cpp src/persistence/WicProjectCodec.cpp)
target_link_libraries(compositor_persistence PUBLIC compositor_core compositor_imaging Qt6::Core)
target_compile_options(compositor_persistence PRIVATE /W4 /utf-8)
add_library(compositor_platform src/platform/DisplayProfile.cpp src/platform/DisplayProfileWatcher.cpp)
target_include_directories(compositor_platform PUBLIC src)
target_compile_definitions(compositor_platform PUBLIC NOMINMAX WIN32_LEAN_AND_MEAN)
target_compile_options(compositor_platform PRIVATE /W4 /WX /utf-8)
target_link_libraries(compositor_platform PUBLIC d2d1 d3d11 dxgi dxguid mscms bcrypt gdi32 user32 advapi32 Qt6::Core)
add_library(compositor_ui src/ui/NativeCanvas.cpp src/ui/MainWindow.cpp src/ui/FileActions.cpp src/ui/BrushActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/EditorIcons.cpp)
target_sources(compositor_ui PRIVATE src/ui/VisualStyle.cpp)
qt_add_resources(compositor_ui visual_assets PREFIX "/" FILES assets/fonts/InterVariable.ttf assets/icons/chevron-down.png assets/icons/chevron-up.png)
target_sources(compositor_ui PRIVATE src/ui/CanvasPresentation.cpp)
target_sources(compositor_ui PRIVATE src/ui/CanvasAccessibility.cpp)
target_sources(compositor_ui PRIVATE src/ui/ProjectOpenDialog.cpp)
target_sources(compositor_ui PRIVATE src/ui/WorkspaceDropQueue.cpp src/ui/LayerAccessibility.cpp)
target_sources(compositor_ui PRIVATE src/ui/VirtualImageDrop.cpp)
target_sources(compositor_ui PRIVATE src/ui/ProjectLayerCopyJob.cpp src/ui/LevelsPreviewHistogram.cpp)
target_sources(compositor_ui PRIVATE src/ui/DocumentPreview.cpp)
target_sources(compositor_ui PRIVATE src/ui/AppearanceActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/SubjectPanel.cpp)
target_sources(compositor_ui PRIVATE src/ui/BrushAppearanceActions.cpp src/graphics/CloneCursorPreview.cpp)
target_sources(compositor_ui PRIVATE src/ui/EditPanelActions.cpp src/ui/ProjectChrome.cpp)
target_sources(compositor_ui PRIVATE src/ui/UpdatePanel.cpp src/ui/UpdateActions.cpp)
target_link_libraries(compositor_ui PUBLIC shell32 uuid dwmapi)
target_link_libraries(compositor_ui PUBLIC compositor_platform)
target_sources(compositor_ui PRIVATE src/ui/AdjustmentActions.cpp src/ui/AdjustmentDialog.cpp)
target_sources(compositor_ui PRIVATE src/ui/SelectionActions.cpp src/ui/SelectionCursors.cpp)
target_sources(compositor_ui PRIVATE src/ui/WandActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/PaletteDialog.cpp src/ui/PaletteActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/PaletteSwatches.cpp)
target_sources(compositor_ui PRIVATE src/ui/RetouchActions.cpp)
target_link_libraries(compositor_ui PUBLIC compositor_retouch)
target_link_libraries(compositor_ui PUBLIC compositor_editing)
target_sources(compositor_ui PRIVATE src/ui/FilterActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/NativeChecks.cpp)
target_sources(compositor_ui PRIVATE src/ui/LayerActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/LayerMergeJob.cpp src/ui/MergeActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/LayerPanel.cpp src/ui/MaskActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/TransformActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/TransformSessionActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/DrawingActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/GradientActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/KeyboardActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/ProjectActions.cpp src/ui/ProjectToolState.cpp src/ui/ImportActions.cpp src/ui/BrushPointerActions.cpp)
target_sources(compositor_ui PRIVATE src/ui/CommandActions.cpp src/ui/CommandRegistry.cpp)
target_sources(compositor_ui PRIVATE src/ui/AdjustmentAdvancedControls.cpp)
target_link_libraries(compositor_ui PUBLIC compositor_effects_tools)
target_link_libraries(compositor_ui PUBLIC compositor_transform)
target_link_libraries(compositor_ui PUBLIC compositor_layers)
target_link_libraries(compositor_ui PUBLIC compositor_filters)
target_sources(compositor_ui PRIVATE src/imaging/SubjectDialog.cpp)
target_link_libraries(compositor_ui PUBLIC compositor_render compositor_graphics compositor_imaging compositor_persistence Qt6::Widgets Qt6::Test d3d11 dxgi d2d1)
target_compile_options(compositor_ui PRIVATE /W4 /permissive- /utf-8)
target_compile_definitions(compositor_ui PRIVATE COMPOSITOR_SOURCE_ROOT="${CMAKE_SOURCE_DIR}")
target_link_libraries(compositor_ui PUBLIC Qt6::Concurrent)
add_executable(Compositor WIN32 src/main.cpp)
target_sources(Compositor PRIVATE src/resources.rc)
target_link_options(Compositor PRIVATE "/MANIFESTINPUT:${CMAKE_SOURCE_DIR}/src/app.manifest")
target_link_libraries(Compositor PRIVATE compositor_ui Qt6::Test)
add_library(compositor_update src/update/Updater.cpp)
target_include_directories(compositor_update PUBLIC src)
target_compile_definitions(compositor_update PUBLIC NOMINMAX WIN32_LEAN_AND_MEAN)
target_compile_options(compositor_update PRIVATE /W4 /utf-8)
target_link_libraries(compositor_update PUBLIC Qt6::Core bcrypt winhttp)
target_link_libraries(compositor_ui PUBLIC compositor_update)
add_executable(CompositorUpdater src/update/UpdaterMain.cpp)
target_link_libraries(CompositorUpdater PRIVATE compositor_update)
add_executable(CompositorLauncher WIN32 src/update/LauncherMain.cpp)
target_sources(CompositorLauncher PRIVATE src/resources.rc)
target_link_options(CompositorLauncher PRIVATE "/MANIFESTINPUT:${CMAKE_SOURCE_DIR}/src/app.manifest")
target_link_libraries(CompositorLauncher PRIVATE compositor_update shell32 user32)
if(BUILD_TESTING)
add_executable(window_chrome_tests tests/window_chrome/WindowChromeTests.cpp)
target_link_libraries(window_chrome_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(window_chrome_tests PRIVATE /W4 /WX /utf-8)
add_executable(accessibility_witness tests/accessibility/AccessibilityWitness.cpp)
target_link_libraries(accessibility_witness PRIVATE compositor_ui Qt6::Test uiautomationcore ole32 oleaut32)
target_compile_definitions(accessibility_witness PRIVATE UNICODE _UNICODE)
target_compile_options(accessibility_witness PRIVATE /W4 /WX /utf-8)
add_executable(accessibility_visibility_tests tests/accessibility/VisibilityAccessibilityTests.cpp)
add_executable(project_chrome_witness tests/project_chrome/ProjectChromeWitness.cpp)
add_executable(update_panel_tests tests/update_ui/UpdatePanelTests.cpp)
add_executable(update_window_tests tests/update_ui/UpdateWindowTests.cpp)
target_link_libraries(update_window_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(update_window_tests PRIVATE /W4 /WX /utf-8)
add_executable(project_tab_provider_tests tests/project_chrome/ProjectTabProviderTests.cpp)
target_link_libraries(project_tab_provider_tests PRIVATE compositor_ui Qt6::Test)
foreach(case selection pending_selection identity_lifetime)
  add_test(NAME project_tabs.${case} COMMAND project_tab_provider_tests ${case})
  set_tests_properties(project_tabs.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
target_link_libraries(update_panel_tests PRIVATE compositor_ui compositor_update Qt6::Test)
target_compile_options(update_panel_tests PRIVATE /W4 /WX /utf-8)
target_link_libraries(project_chrome_witness PRIVATE compositor_ui Qt6::Test uiautomationcore ole32 oleaut32)
target_compile_definitions(project_chrome_witness PRIVATE UNICODE _UNICODE)
target_compile_options(project_chrome_witness PRIVATE /W4 /WX /utf-8)
add_executable(layer_dock_width_tests tests/project_chrome/LayerDockWidthTests.cpp)
target_link_libraries(layer_dock_width_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(layer_dock_width_tests PRIVATE /W4 /WX /utf-8)
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/evidence/project-chrome")
foreach(case default_width restored_width resize_is_saved width_bounds restart_write restart_read)
  if(case MATCHES "^restart_")
    set(settings_name restart)
  else()
    set(settings_name ${case})
  endif()
  add_test(NAME project_chrome.${case} COMMAND layer_dock_width_tests ${case} "${CMAKE_BINARY_DIR}/evidence/project-chrome/settings-${settings_name}" "${CMAKE_BINARY_DIR}/evidence/project-chrome/${case}.json")
  set_tests_properties(project_chrome.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
set_tests_properties(project_chrome.restart_read PROPERTIES DEPENDS project_chrome.restart_write)
target_link_libraries(accessibility_visibility_tests PRIVATE compositor_ui uiautomationcore ole32 oleaut32)
target_compile_definitions(accessibility_visibility_tests PRIVATE UNICODE _UNICODE)
target_compile_options(accessibility_visibility_tests PRIVATE /W4 /WX /utf-8)
add_executable(layer_action_accessibility_tests tests/layer_action_accessibility/LayerActionAccessibilityTests.cpp)
add_executable(pending_layer_selection_tests tests/layer_pending_selection/PendingLayerSelectionTests.cpp)
foreach(target layer_action_accessibility_tests pending_layer_selection_tests)
  target_link_libraries(${target} PRIVATE compositor_ui Qt6::Test uiautomationcore ole32 oleaut32)
  target_compile_definitions(${target} PRIVATE UNICODE _UNICODE)
  target_compile_options(${target} PRIVATE /W4 /WX /utf-8)
endforeach()
add_executable(import_commit_failure_tests tests/drop_sequence/ImportCommitFailureTests.cpp)
add_executable(project_layer_drop_tests tests/project_layer_drop/ProjectLayerDropTests.cpp)
target_link_libraries(project_layer_drop_tests PRIVATE compositor_ui Qt6::Test)
target_compile_definitions(project_layer_drop_tests PRIVATE PROJECT_LAYER_DROP_AFTER)
target_compile_options(project_layer_drop_tests PRIVATE /W4 /WX /utf-8)
foreach(case dock_file_targets_current toolbox_file_targets_current layer_existing_tab_copy layer_new_target_copy layer_canvas_point layer_group_graph_and_mask layer_same_project_rejected layer_alt_and_mask_rejected layer_source_destroyed_rejected layer_target_busy_rejected layer_pending_gradient_rejected layer_duplicate_document_ids multiple_rows_keep_order_and_edits multiple_rows_new_projects serialized_mime_retains_session_identity removed_source_layer_rejected external_clipping_is_baked destroyed_window_stops_layer_job)
  add_test(NAME project_layer_drop.${case} COMMAND project_layer_drop_tests ${case})
  set_tests_properties(project_layer_drop.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
target_link_libraries(import_commit_failure_tests PRIVATE compositor_ui)
target_compile_options(import_commit_failure_tests PRIVATE /W4 /WX /utf-8)
foreach(case allocation_sweep stale_result)
  add_test(NAME imports.commit_${case} COMMAND import_commit_failure_tests ${case})
endforeach()
add_executable(control_gap_tests tests/control_gaps/ControlGapTests.cpp)
add_executable(layer_copy_commit_tests tests/control_gaps/LayerCopyCommitTests.cpp)
target_link_libraries(layer_copy_commit_tests PRIVATE compositor_ui)
target_compile_options(layer_copy_commit_tests PRIVATE /W4 /WX /utf-8)
foreach(case allocation_sweep empty_allocation_sweep stale_result)
  add_test(NAME layer_copy.commit_${case} COMMAND layer_copy_commit_tests ${case})
  set_tests_properties(layer_copy.commit_${case} PROPERTIES TIMEOUT 30)
endforeach()
add_executable(layer_copy_commit_before_tests tests/control_gaps/LayerCopyCommitTests.cpp)
target_link_libraries(layer_copy_commit_before_tests PRIVATE compositor_ui)
target_compile_definitions(layer_copy_commit_before_tests PRIVATE LAYER_COPY_COMMIT_BEFORE=1)
target_compile_options(layer_copy_commit_before_tests PRIVATE /W4 /WX /utf-8)
add_executable(property_control_tests tests/property_controls/PropertyControlsTests.cpp)
target_include_directories(property_control_tests PRIVATE src)
target_link_libraries(property_control_tests PRIVATE Qt6::Widgets Qt6::Test)
target_compile_options(property_control_tests PRIVATE /W4 /WX /utf-8)
foreach(case typing_refresh shift_steps control_one_step clamping_readonly return_focus escape_focus track_ltr track_rtl track_inverted knob_drag)
  add_test(NAME property_controls.${case} COMMAND property_control_tests ${case})
  set_tests_properties(property_controls.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(property_control_before_tests tests/property_controls/PropertyControlsTests.cpp)
add_executable(property_ui_tests tests/property_controls/PropertyUiTests.cpp)
target_link_libraries(property_ui_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(property_ui_tests PRIVATE /W4 /WX /utf-8)
foreach(case transform_typing opacity_track_history brush_field_focus)
  add_test(NAME property_ui.${case} COMMAND property_ui_tests ${case})
  set_tests_properties(property_ui.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(shape_ui_tests tests/shape_ui/ShapeUiTests.cpp)
target_link_libraries(shape_ui_tests PRIVATE compositor_ui)
foreach(case shape_insert_sibling shape_insert_folder shape_insert_nested_child shape_fractional_anchor shape_center_square shape_kind_change_cancels shape_radius_limit shape_radius_frozen shape_draft_immutable shape_click_noop shape_history_selection)
  add_test(NAME shape.ui.${case} COMMAND shape_ui_tests ${case})
  set_tests_properties(shape.ui.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(crop_ui_tests tests/crop_ui/CropUiTests.cpp)
target_link_libraries(crop_ui_tests PRIVATE compositor_ui)
foreach(case crop_fresh_entry_fullframe_free crop_cancel_retains_document crop_pending_dimensions crop_square_corner_hit crop_control_disables_snap crop_eight_dip_snap_distance crop_invalid_drag_keeps_last_valid crop_entire_edge_hit crop_apply_once)
  add_test(NAME crop.ui.${case} COMMAND crop_ui_tests ${case})
  set_tests_properties(crop.ui.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(native_shape_witness tests/shape_ui/NativeShapeWitness.cpp)
target_link_libraries(native_shape_witness PRIVATE compositor_ui)
add_executable(native_crop_witness tests/crop_ui/NativeCropWitness.cpp)
target_link_libraries(native_crop_witness PRIVATE compositor_ui)
add_executable(native_snap_witness tests/crop_ui/NativeSnapWitness.cpp)
target_link_libraries(native_snap_witness PRIVATE compositor_ui)
add_executable(native_expanded_crop_witness tests/crop_ui/NativeExpandedCropWitness.cpp)
target_link_libraries(native_expanded_crop_witness PRIVATE compositor_ui)
add_executable(crop_escape_tests tests/crop_ui/CropEscapeTests.cpp)
target_link_libraries(crop_escape_tests PRIVATE compositor_ui)
add_test(NAME crop.escape COMMAND crop_escape_tests)
set_tests_properties(crop.escape PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
add_executable(crop_viewport_tests tests/crop_ui/CropViewportTests.cpp)
target_link_libraries(crop_viewport_tests PRIVATE compositor_ui)
foreach(case negative_fractional_phase union_intersection_phase rotated_mask_clip_stack global_adjustment_origin immutable_live_source large_bounded_surface empty_and_invalid_requests)
  add_test(NAME crop.viewport_${case} COMMAND crop_viewport_tests ${case})
  set_tests_properties(crop.viewport_${case} PROPERTIES TIMEOUT 30)
endforeach()
add_executable(sparse_selection_tests tests/sparse_selection/SparseSelectionTests.cpp)
add_executable(sparse_selection_budget_tests tests/sparse_selection/SparseSelectionBudgetTests.cpp)
target_link_libraries(sparse_selection_budget_tests PRIVATE compositor_editing compositor_transform Qt6::Core)
target_compile_options(sparse_selection_budget_tests PRIVATE /W4 /WX /utf-8)
add_test(NAME sparse_selection.affine_allocation_budget COMMAND sparse_selection_budget_tests)
set_tests_properties(sparse_selection.affine_allocation_budget PROPERTIES TIMEOUT 30)
add_executable(sparse_selection_ui_tests tests/sparse_selection/SparseSelectionUiTests.cpp)
add_executable(brush_appearance_tests tests/brush_appearance_controls/BrushAppearanceTests.cpp)
add_executable(adjustment_accessibility_tests tests/adjustment_accessibility/AdjustmentAccessibilityTests.cpp)
target_link_libraries(adjustment_accessibility_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(adjustment_accessibility_tests PRIVATE /W4 /WX /utf-8)
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/adjustment-accessibility-results")
foreach(case levels_handle_names levels_histogram_help levels_channel_name levels_sampler_keyboard levels_auto_keyboard curves_selected_coordinates curves_remove_keyboard curves_reset_keyboard)
  add_test(NAME adjustment_accessibility.${case} COMMAND adjustment_accessibility_tests ${case} "${CMAKE_BINARY_DIR}/adjustment-accessibility-results/${case}.json")
  set_tests_properties(adjustment_accessibility.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(levels_handle_accessibility_tests tests/adjustment_accessibility/LevelsHandleAccessibilityTests.cpp)
target_link_libraries(levels_handle_accessibility_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(levels_handle_accessibility_tests PRIVATE /W4 /WX /utf-8)
foreach(case values actions keyboard channel lifetime)
  add_test(NAME levels_handle_accessibility.${case} COMMAND levels_handle_accessibility_tests ${case} "${CMAKE_BINARY_DIR}/adjustment-accessibility-results/handle-${case}.json")
  set_tests_properties(levels_handle_accessibility.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(clone_preview_tests tests/clone_preview/ClonePreviewTests.cpp)
target_link_libraries(clone_preview_tests PRIVATE compositor_ui)
target_compile_options(clone_preview_tests PRIVATE /W4 /WX /utf-8)
foreach(case raw_current_appearance_ignored all_layers_composite transformed_raw_source one_click_tip_exact cache_snapshot_invalidation live_preview_identity large_canvas_bounded_roi fractional_ceil_sampling invalid_bounds_and_missing_source)
  add_test(NAME clone_preview.${case} COMMAND clone_preview_tests ${case})
  set_tests_properties(clone_preview.${case} PROPERTIES TIMEOUT 60)
endforeach()
add_executable(clone_cursor_ui_tests tests/clone_preview/CloneCursorUiTests.cpp)
target_link_libraries(clone_cursor_ui_tests PRIVATE compositor_ui)
target_compile_options(clone_cursor_ui_tests PRIVATE /W4 /WX /utf-8)
foreach(case without_source_crosshair with_source_hidden alt_source_crosshair leave_restores_arrow)
  add_test(NAME clone_cursor.${case} COMMAND clone_cursor_ui_tests ${case})
  set_tests_properties(clone_cursor.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(native_clone_preview_witness tests/clone_preview/NativeClonePreviewWitness.cpp)
target_link_libraries(native_clone_preview_witness PRIVATE compositor_ui)
add_executable(core_brush_performance tests/brush_performance/CoreBrushPerformance.cpp)
target_link_libraries(core_brush_performance PRIVATE compositor_render compositor_graphics Qt6::Core psapi)
target_compile_options(core_brush_performance PRIVATE /W4 /WX /utf-8)
add_executable(native_brush_performance tests/brush_performance/NativeBrushPerformance.cpp)
target_link_libraries(native_brush_performance PRIVATE compositor_ui Qt6::Test dwmapi psapi)
target_compile_options(native_brush_performance PRIVATE /W4 /WX /utf-8)
target_compile_options(native_clone_preview_witness PRIVATE /W4 /WX /utf-8)
add_executable(native_sparse_selection_witness tests/sparse_selection/NativeSparseSelectionWitness.cpp)
target_link_libraries(native_sparse_selection_witness PRIVATE compositor_ui)
target_compile_options(native_sparse_selection_witness PRIVATE /W4 /WX /utf-8)
add_executable(panel_followup_tests tests/panel_followups/PanelFollowupTests.cpp)
add_executable(subject_mask_tests tests/panel_followups/SubjectMaskTests.cpp)
target_link_libraries(subject_mask_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(subject_mask_tests PRIVATE /W4 /WX /utf-8)
foreach(case mask_once current_mask aggregate_budget)
  add_test(NAME subject_mask.${case} COMMAND subject_mask_tests ${case})
  set_tests_properties(subject_mask.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 60)
endforeach()
target_link_libraries(panel_followup_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(panel_followup_tests PRIVATE /W4 /WX /utf-8)
foreach(case subject_nonmodal subject_canvas_preview subject_preview_toggle subject_cancel subject_apply subject_ranges subject_shift_step gradient_picker_app gradient_working_cancel gradient_working_apply gradient_parent_cancel gradient_parent_apply gradient_canvas_sample gradient_endpoint_exclusion)
  add_test(NAME panel_followup.${case} COMMAND panel_followup_tests ${case})
  set_tests_properties(panel_followup.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 60)
endforeach()
add_executable(subject_dialog_tests tests/imaging/subject_dialog_checks.cpp)
target_link_libraries(subject_dialog_tests PRIVATE compositor_ui)
target_include_directories(subject_dialog_tests PRIVATE src/imaging)
add_test(NAME imaging.subject_dialog_compatibility COMMAND subject_dialog_tests "${CMAKE_SOURCE_DIR}/dependencies/imaging/model/birefnet-lite.onnx" "${CMAKE_SOURCE_DIR}/evidence/imaging/astronaut.png")
set_tests_properties(imaging.subject_dialog_compatibility PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 60)
target_link_libraries(brush_appearance_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(brush_appearance_tests PRIVATE /W4 /WX /utf-8)
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/brush-appearance-results")
foreach(case brush_sliders heal_sliders clone_sliders smear_sliders slider_project_isolation tip_family_retention layer_percent_commit layer_percent_escape layer_percent_focus_loss layer_percent_invalid layer_percent_clamp layer_percent_arrows layer_percent_target_guard layer_percent_text_keys brush_mode_selector brush_rail_remembers brush_shortcuts_explicit brush_mode_project_isolation)
  add_test(NAME brush_appearance.${case} COMMAND brush_appearance_tests ${case} "${CMAKE_BINARY_DIR}/brush-appearance-results/${case}.json")
  set_tests_properties(brush_appearance.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
target_link_libraries(sparse_selection_ui_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(sparse_selection_ui_tests PRIVATE /W4 /WX /utf-8)
foreach(case all_inverse_undo marquee_history clipped_brush empty_brush)
  add_test(NAME sparse_selection_ui.${case} COMMAND sparse_selection_ui_tests ${case})
  set_tests_properties(sparse_selection_ui.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
target_link_libraries(sparse_selection_tests PRIVATE compositor_editing compositor_transform compositor_render compositor_graphics Qt6::Core)
target_compile_options(sparse_selection_tests PRIVATE /W4 /WX /utf-8)
foreach(case small_roi present_empty antialias_mapping move_out_back inverse fill_small_blank gradient_small_blank brush_small_blank copy_roi pixel_move)
  add_test(NAME sparse_selection.${case} COMMAND sparse_selection_tests ${case})
  set_tests_properties(sparse_selection.${case} PROPERTIES TIMEOUT 30)
endforeach()
target_include_directories(property_control_before_tests PRIVATE src)
target_link_libraries(property_control_before_tests PRIVATE Qt6::Widgets Qt6::Test)
target_compile_definitions(property_control_before_tests PRIVATE FROZEN_CONTROLS=1)
target_compile_options(property_control_before_tests PRIVATE /W4 /WX /utf-8)
add_executable(blend_preview_tests tests/blend_preview/BlendPreviewTests.cpp)
add_executable(nonmodal_lifecycle_tests tests/nonmodal_lifecycle/LifecycleTests.cpp)
target_link_libraries(nonmodal_lifecycle_tests PRIVATE compositor_ui Qt6::Test)
foreach(case filter_undo_metadata_apply hue_undo_metadata_apply filter_undo_removed_overlay hue_undo_removed_overlay redo_target_restores_preview levels_history_blocked save_canonical_filter close_blocked_filter stale_pixels_discard_apply explicit_import_filter)
  add_test(NAME nonmodal_lifecycle.${case} COMMAND nonmodal_lifecycle_tests ${case})
  set_tests_properties(nonmodal_lifecycle.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(live_adjustment_lifecycle_tests tests/nonmodal_lifecycle/LiveLifecycleTests.cpp)
target_link_libraries(live_adjustment_lifecycle_tests PRIVATE compositor_ui Qt6::Test)
foreach(case created_layer_survives_cancel created_layer_apply_separate_edit existing_edit_blocks_document_history live_import_cancel live_import_apply)
  add_test(NAME live_adjustment_lifecycle.${case} COMMAND live_adjustment_lifecycle_tests ${case})
  set_tests_properties(live_adjustment_lifecycle.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(nonmodal_edit_tests tests/nonmodal_edit/NonmodalEditTests.cpp)
target_link_libraries(nonmodal_edit_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(nonmodal_edit_tests PRIVATE /W4 /WX /utf-8)
foreach(case adjustment_reduced_preview_full_apply levels_reduced_preview_full_apply worker_cancel_no_late_result palette_visible_preview filter_mask_placed_unchanged filter_solid_mask_unchanged filter_mask_pretrim_order property_step_and_slider adjustment_nonmodal filter_nonmodal adjustment_canvas_preview adjustment_preview_toggle adjustment_apply_undo adjustment_close_cancel adjustment_position levels_canvas_original_sample hue_canvas_sample hue_canvas_target filter_canvas_preview filter_apply_undo filter_preview_checkbox filter_mask_growth pending_edit_guards existing_live_preview_cancel latest_preview_wins)
  add_test(NAME nonmodal_edit.${case} COMMAND nonmodal_edit_tests ${case})
  set_tests_properties(nonmodal_edit.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(filter_preview_tests tests/filter_preview/FilterPreviewTests.cpp)
target_link_libraries(filter_preview_tests PRIVATE compositor_filters)
target_compile_options(filter_preview_tests PRIVATE /W4 /WX /utf-8)
foreach(case nearest_rgba_odd nearest_rgba_portrait capped_blur_nearest full_apply_unchanged cancellation)
  add_test(NAME filter_preview.${case} COMMAND filter_preview_tests ${case})
  set_tests_properties(filter_preview.${case} PROPERTIES TIMEOUT 30)
endforeach()
target_link_libraries(blend_preview_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(blend_preview_tests PRIVATE /W4 /WX /utf-8)
foreach(case hover_cancel commit_once noop_preserves_redo target_guard)
  add_test(NAME blend_preview.${case} COMMAND blend_preview_tests ${case})
  set_tests_properties(blend_preview.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(transform_inspector_tests tests/transform_inspector/InspectorTests.cpp)
target_link_libraries(transform_inspector_tests PRIVATE compositor_ui)
target_compile_options(transform_inspector_tests PRIVATE /W4 /WX /utf-8)
foreach(case inspector_numeric_cancel inspector_multiple_fields_one_apply inspector_sampling_mask_scope inspector_flip_cancel inspector_group_scale_scope inspector_mask_scale_reference inspector_floating_scale_reference inspector_live_rounded_shape)
  add_test(NAME transform_inspector.${case} COMMAND transform_inspector_tests ${case})
  set_tests_properties(transform_inspector.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
target_link_libraries(control_gap_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(control_gap_tests PRIVATE /W4 /WX /utf-8)
foreach(case palette_retarget_apply palette_retarget_cancel palette_same_target_reset copy_duplicate_title copy_new_title_collision copy_cancel background_mask_target background_existing_target background_cancel)
  add_test(NAME control_gaps.${case} COMMAND control_gap_tests ${case})
  set_tests_properties(control_gaps.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 120)
endforeach()
add_executable(large_preview_before_predicates tests/large_document_preview/BeforeWitness.cpp)
add_executable(levels_preview_tests tests/levels_preview/HistogramTests.cpp)
target_link_libraries(levels_preview_tests PRIVATE compositor_ui)
target_compile_options(levels_preview_tests PRIVATE /W4 /WX /utf-8)
add_executable(levels_preview_ui_tests tests/levels_preview/HistogramUiTests.cpp)
target_link_libraries(levels_preview_ui_tests PRIVATE compositor_ui)
target_compile_options(levels_preview_ui_tests PRIVATE /W4 /WX /utf-8)
add_test(NAME levels_preview.ordinary_levels_preview_cap_auto_apply COMMAND levels_preview_ui_tests)
set_tests_properties(levels_preview.ordinary_levels_preview_cap_auto_apply PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 90)
foreach(case cap_at_8000 odd_portrait_grid source_row_major_fractional capped_selection_mapping native_streaming_order_preserved input_immutable_no_flatten cancellation)
  add_test(NAME levels_preview.${case} COMMAND levels_preview_tests ${case})
  set_tests_properties(levels_preview.${case} PROPERTIES TIMEOUT 30)
endforeach()
target_link_libraries(large_preview_before_predicates PRIVATE compositor_ui)
add_test(NAME large_preview.original_predicates COMMAND large_preview_before_predicates)
set_tests_properties(large_preview.original_predicates PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 90)
add_executable(large_preview_tests tests/large_document_preview/PreviewTests.cpp)
target_link_libraries(large_preview_tests PRIVATE compositor_ui)
target_compile_options(large_preview_tests PRIVATE /W4 /WX /utf-8)
foreach(case fitted_geometry small_thumbnail_identity histogram_small_source_budget histogram_full_tile_order histogram_rotated_reduced_alignment histogram_masks_clips_adjustment histogram_transparent_and_invalid histogram_cancellation original_pixel_sampling adjustment_dialog_source_grid adjustment_dialog_live_levels adjustment_dialog_cancel)
  add_test(NAME large_preview.${case} COMMAND large_preview_tests ${case})
  set_tests_properties(large_preview.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 90)
endforeach()
add_executable(large_filter_ui_tests tests/large_document_preview/FilterUiTests.cpp)
target_link_libraries(large_filter_ui_tests PRIVATE compositor_ui)
target_compile_options(large_filter_ui_tests PRIVATE /W4 /WX /utf-8)
foreach(case filter_lens_30000_apply filter_gaussian_30000_apply filter_30000_cancel)
  add_test(NAME large_preview.${case} COMMAND large_filter_ui_tests ${case})
  set_tests_properties(large_preview.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 90)
endforeach()
add_executable(drop_sequence_tests tests/drop_sequence/DropSequenceTests.cpp)
target_link_libraries(drop_sequence_tests PRIVATE compositor_ui Qt6::Test)
add_executable(native_virtual_drop_witness tests/virtual_drop/NativeVirtualDropWitness.cpp)
add_executable(virtual_drop_negotiation_tests tests/virtual_drop/NegotiationContracts.cpp)
add_executable(virtual_drop_integration_tests tests/virtual_drop/IntegrationContracts.cpp)
add_executable(virtual_drop_queue_tests tests/virtual_drop/QueueCompletionContracts.cpp)
foreach(target native_virtual_drop_witness virtual_drop_negotiation_tests virtual_drop_integration_tests virtual_drop_queue_tests)
  target_link_libraries(${target} PRIVATE compositor_ui)
  target_compile_options(${target} PRIVATE /W4 /WX /utf-8)
endforeach()
foreach(case request_completion_order completion_releases_temporary_storage cancel_waits_for_active_import cancel_pending_request destroyed_queue_discards_callback empty_request_completes empty_error_keeps_fifo_order)
  add_test(NAME virtual_drop_queue.${case} COMMAND "${CMAKE_COMMAND}"
    "-DEXECUTABLE=$<TARGET_FILE:virtual_drop_queue_tests>" "-DCASE=${case}"
    "-DEVIDENCE_ROOT=${CMAKE_BINARY_DIR}/virtual-drop-queue-evidence" -DOUTPUT_DIRECTORY=TRUE
    -P "${CMAKE_SOURCE_DIR}/tests/run-evidence-case.cmake")
  set_tests_properties(virtual_drop_queue.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
endforeach()
target_compile_definitions(drop_sequence_tests PRIVATE DROP_SEQUENCE_AFTER)
target_compile_options(drop_sequence_tests PRIVATE /W4 /WX /utf-8)
foreach(case mixed_image_project_order images_have_separate_undo pending_ui_drop_rejected busy_ui_bitmap_rejected project_error_then_image_then_project external_mixed_items_create_ordered_tabs active_import_prevents_tab_close accepted_payload_waits_for_gradient accepted_bitmap_retains_temporary_copy cancelled_waiting_payload_releases_lifetime cancel_button_stops_remaining_items closed_captured_destination_skips_images deferred_requests_remain_fifo image_error_does_not_consume_later_project destroyed_window_stops_deferred_callbacks nonselected_tab_captures_destination)
  add_test(NAME drop_sequence.${case} COMMAND drop_sequence_tests ${case})
  set_tests_properties(drop_sequence.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(gradient_before_predicates tests/gradient_preview/BeforeWitness.cpp)
target_link_libraries(gradient_before_predicates PRIVATE compositor_editing compositor_graphics)
add_test(NAME gradient.preview_original_predicates COMMAND gradient_before_predicates)
add_executable(gradient_preview_tests tests/gradient_preview/GradientPreviewTests.cpp)
target_link_libraries(gradient_preview_tests PRIVATE compositor_editing compositor_graphics)
target_compile_options(gradient_preview_tests PRIVATE /W4 /WX /utf-8)
foreach(case source_linear source_radial source_reverse_opacity source_transparent immutable_redrag click_empty_selection source_mask transformed_half_selection scaled_large_canvas wide_lazy_source mask_small_grid_large_image unplaced_mask_expansion preserves_outside_canvas commit_history_cancel)
  add_test(NAME gradient.preview_${case} COMMAND gradient_preview_tests ${case})
endforeach()
add_executable(project_reopen_tests tests/project_reopen/ProjectReopenTests.cpp)
add_executable(project_open_batch_tests tests/project_open_batch/ProjectOpenBatchTests.cpp)
target_link_libraries(project_open_batch_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(project_open_batch_tests PRIVATE /W4 /WX /utf-8)
foreach(case drop_order drop_existing drop_pending_guard drop_mixed_failure batch_empty batch_order batch_existing batch_mixed_failure batch_all_fail batch_pending_guard batch_busy_guard batch_error_reentrancy welcome_fresh_session welcome_failure_preserves_session welcome_project_then_image_skipped package_policy native_options themed_picker)
  add_test(NAME project_open_batch.${case} COMMAND project_open_batch_tests ${case})
  set_tests_properties(project_open_batch.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
target_link_libraries(project_reopen_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(project_reopen_tests PRIVATE /W4 /WX /utf-8)
foreach(case same_active other_tab case_unicode_dot_alias junction_alias distinct_directories pending_gradient busy_guard failed_load)
  add_test(NAME project_reopen.${case} COMMAND project_reopen_tests ${case})
  set_tests_properties(project_reopen.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(display_profile_watcher_tests tests/display_profile_watcher/DisplayProfileWatcherTests.cpp)
target_link_libraries(display_profile_watcher_tests PRIVATE compositor_platform)
target_compile_options(display_profile_watcher_tests PRIVATE /W4 /WX /utf-8)
foreach(case rearm_thread missing_ancestor delete_recreate bounded_burst teardown unavailable default_read_only)
  add_test(NAME display_profile_watcher.${case} COMMAND display_profile_watcher_tests ${case})
  set_tests_properties(display_profile_watcher.${case} PROPERTIES TIMEOUT 30)
endforeach()
add_executable(display_profile_tests tests/display_profile/DisplayProfileTests.cpp)
add_executable(native_display_profile_tests tests/display_profile/NativeDisplayProfileTests.cpp)
target_link_libraries(native_display_profile_tests PRIVATE compositor_ui mscms)
target_link_libraries(display_profile_tests PRIVATE compositor_platform)
target_compile_options(display_profile_tests PRIVATE /W4 /WX /utf-8)
foreach(case srgb_identity linear_profile invalid_fallback tile_budget monitor_discovery icc_validation profile_switch)
  add_test(NAME display_profile.${case} COMMAND display_profile_tests ${case} "${CMAKE_SOURCE_DIR}/tests/display_profile/fixtures/linear-rgb.icc")
endforeach()
add_executable(downsample_tests tests/downsample/DownsampleTests.cpp)
target_link_libraries(downsample_tests PRIVATE compositor_graphics Qt6::Core Qt6::Gui)
add_test(NAME graphics.downsample_source COMMAND downsample_tests production "${CMAKE_SOURCE_DIR}/evidence/graphics/downsample-integrated")
add_executable(downsample_contract_tests tests/downsample/DownsampleContractTests.cpp)
target_link_libraries(downsample_contract_tests PRIVATE compositor_graphics)
add_test(NAME graphics.downsample_contracts COMMAND downsample_contract_tests)
add_executable(reduced_source_tests tests/downsample/ReducedSourceTests.cpp)
target_link_libraries(reduced_source_tests PRIVATE compositor_graphics)
add_test(NAME graphics.reduced_sources COMMAND reduced_source_tests)
add_executable(selection_gesture_tests tests/selection_gesture/SelectionGestureTests.cpp)
target_link_libraries(selection_gesture_tests PRIVATE compositor_editing)
foreach(case polygon_corners click_history marquee_rounding centered_programmatic ellipse option_marquee fresh_shift stationary_modifiers polygon_closure quarter_pixel mode_and_interrupt empty_noop move_axis autoscroll geometry_equality)
  add_test(NAME selection_gesture.${case} COMMAND selection_gesture_tests ${case})
endforeach()
add_executable(selection_event_tests tests/selection_gesture/SelectionEventTests.cpp)
target_link_libraries(selection_event_tests PRIVATE compositor_ui)
foreach(case option_marquee fresh_shift_marquee polygon_click_close canonical_draft polygon_backspace_enter polygon_doubleclick stationary_shift focus_retention move_click_and_axis repeated_outline_noop autoscroll_events)
  add_test(NAME selection_events.${case} COMMAND selection_event_tests ${case})
  set_tests_properties(selection_events.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(selection_followup_tests tests/selection_gesture/SelectionFollowupTests.cpp)
target_link_libraries(selection_followup_tests PRIVATE compositor_ui)
foreach(case undo_redo_draft escape_mode_reset expand_range wand_replace)
  add_test(NAME selection_followup.${case} COMMAND selection_followup_tests ${case})
  set_tests_properties(selection_followup.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(decoder_adversarial_tests tests/imaging/DecoderAdversarialTests.cpp src/ui/ImportActions.cpp)
add_executable(imaging_longpath_tests tests/imaging/LongPathTests.cpp)
target_link_libraries(imaging_longpath_tests PRIVATE compositor_imaging Qt6::Core)
foreach(case rgba_roundtrip gray_roundtrip stream_copy_cancel namespace_rules)
  add_test(NAME imaging.longpath_${case} COMMAND imaging_longpath_tests ${case})
  set_tests_properties(imaging.longpath_${case} PROPERTIES TIMEOUT 60)
endforeach()
target_link_libraries(decoder_adversarial_tests PRIVATE compositor_core compositor_imaging Qt6::Concurrent Qt6::Core psapi)
target_compile_options(decoder_adversarial_tests PRIVATE /W4 /WX /utf-8)
add_test(NAME imaging.adversarial_decoders COMMAND decoder_adversarial_tests "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/evidence/imaging/adversarial")
set_tests_properties(imaging.adversarial_decoders PROPERTIES TIMEOUT 180)
add_executable(export_ui_tests tests/export_stream/ExportUiTests.cpp)
target_link_libraries(export_ui_tests PRIVATE compositor_ui)
add_test(NAME export.ui COMMAND export_ui_tests)
set_tests_properties(export.ui PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 90)
add_executable(layer_panel_tests tests/layer_panel/LayerPanelSourceTests.cpp)
target_link_libraries(layer_panel_tests PRIVATE compositor_ui)
foreach(case thumbnail_shapes thumbnail_layer_placement thumbnail_mask_edge thumbnail_cache visibility_swipe panel_cursors source_cursor_conflict)
  add_test(NAME layer_panel.${case} COMMAND layer_panel_tests ${case})
  set_tests_properties(layer_panel.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
set_tests_properties(layer_panel.source_cursor_conflict PROPERTIES LABELS "parity;known_failure")
add_executable(export_stream_tests tests/export_stream/ExportStreamTests.cpp)
target_link_libraries(export_stream_tests PRIVATE compositor_render compositor_imaging Qt6::Core psapi)
target_compile_options(export_stream_tests PRIVATE /W4 /utf-8)
foreach(case extent_guard row_png canonical_partition jpeg_matte_preview cancel_atomic row_failure_atomic copy_atomic large_blank large_narrow)
  add_test(NAME export_stream.${case} COMMAND export_stream_tests ${case})
  set_tests_properties(export_stream.${case} PROPERTIES TIMEOUT 90)
endforeach()
set_tests_properties(export_stream.large_blank export_stream.large_narrow PROPERTIES LABELS "large_export")
add_executable(process_save_tests tests/persistence/ProcessSaveTests.cpp)
target_link_libraries(process_save_tests PRIVATE compositor_persistence)
add_test(NAME persistence.process_termination COMMAND process_save_tests "${CMAKE_SOURCE_DIR}/evidence/persistence")
set_tests_properties(persistence.process_termination PROPERTIES TIMEOUT 90)
add_executable(command_ui_tests tests/command_ui/CommandRegistryTests.cpp src/ui/CommandRegistry.cpp)
target_include_directories(command_ui_tests PRIVATE src)
target_link_libraries(command_ui_tests PRIVATE Qt6::Widgets Qt6::Test)
foreach(case source_predicates layer_eligibility pending_preparation stale_activation preparation_error text_shortcuts text_menu_routes catalog_manifest registration)
  add_test(NAME command_ui.${case} COMMAND command_ui_tests ${case})
  set_tests_properties(command_ui.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 20)
endforeach()
add_executable(command_integrated_tests tests/command_ui/IntegratedCommandTests.cpp)
target_link_libraries(command_integrated_tests PRIVATE compositor_ui)
foreach(case registered_actions pending_gradient_undo blocked_layers import_busy blank_hidden_transform text_focus transform_draft)
  add_test(NAME command_integrated.${case} COMMAND command_integrated_tests ${case})
  set_tests_properties(command_integrated.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(preview_sampling_tests tests/tiled_parity/PreviewSamplingTests.cpp)
target_link_libraries(preview_sampling_tests PRIVATE compositor_render compositor_graphics)
add_test(NAME graphics.preview_sampling COMMAND preview_sampling_tests)
add_executable(sampling_reuse_tests tests/sampling_reuse42/SamplingReuseTests.cpp)
add_executable(sampling_reference_capture tests/sampling_reuse42/ReferenceCapture.cpp)
target_link_libraries(sampling_reference_capture PRIVATE compositor_graphics Qt6::Core)
target_compile_options(sampling_reference_capture PRIVATE /W4 /WX /utf-8)
target_link_libraries(sampling_reuse_tests PRIVATE compositor_render compositor_graphics)
target_compile_options(sampling_reuse_tests PRIVATE /W4 /WX /utf-8)
foreach(case unchanged halo isolation eviction lifetime brush)
  add_test(NAME graphics.sampling_reuse_${case} COMMAND sampling_reuse_tests ${case})
endforeach()
add_executable(viewport_damage_tests tests/sampling_reuse42/ViewportDamageTests.cpp)
target_link_libraries(viewport_damage_tests PRIVATE compositor_render compositor_graphics)
target_compile_options(viewport_damage_tests PRIVATE /W4 /WX /utf-8)
foreach(case image mask rotated growth dependent)
  add_test(NAME graphics.viewport_damage_${case} COMMAND viewport_damage_tests ${case})
endforeach()
add_executable(tiled_parity_tests tests/tiled_parity/TiledLayerParityTests.cpp)
target_link_libraries(tiled_parity_tests PRIVATE compositor_ui)
add_executable(workspace_tests tests/workspace_tests.cpp)
target_link_libraries(workspace_tests PRIVATE compositor_ui)
add_test(NAME ui.workspace COMMAND workspace_tests)
set_tests_properties(ui.workspace PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
add_executable(brush_pointer_tests tests/brush_pointer_ui/BrushPointerTests.cpp)
target_link_libraries(brush_pointer_tests PRIVATE compositor_ui)
add_test(NAME ui.brush_pointer COMMAND brush_pointer_tests)
set_tests_properties(ui.brush_pointer PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
add_executable(import_ui_tests tests/import_ui/ImportUiTests.cpp)
target_link_libraries(import_ui_tests PRIVATE compositor_ui Qt6::Test)
add_test(NAME imports.ui COMMAND import_ui_tests)
set_tests_properties(imports.ui PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 90)
add_executable(session_state_tests tests/session_state/ProjectToolStateTests.cpp)
add_executable(remembered_settings_tests tests/session_state/RememberedSettingsTests.cpp)
target_link_libraries(remembered_settings_tests PRIVATE compositor_ui Qt6::Test)
foreach(case lasso_return crop_ratio amounts_independent pixel_apply_cancel adjustment_apply_cancel control_tab_isolation)
  add_test(NAME remembered_settings.${case} COMMAND remembered_settings_tests ${case})
  set_tests_properties(remembered_settings.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 45)
endforeach()
add_executable(remembered_filter_tests tests/session_state/RememberedFilterTests.cpp)
target_link_libraries(remembered_filter_tests PRIVATE compositor_ui Qt6::Test)
foreach(case pixel_family_bundle neutral_commits curves_grain gradient_palette live_independence crop_apply_ratio crop_full_frame_create amount_controls background_remembering)
  add_test(NAME remembered_filter.${case} COMMAND remembered_filter_tests ${case})
  set_tests_properties(remembered_filter.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 45)
endforeach()
target_link_libraries(session_state_tests PRIVATE compositor_ui)
foreach(case source_defaults tab_isolation control_signals continuity_local brush_family_tips)
  add_test(NAME session_state.${case} COMMAND session_state_tests ${case})
  set_tests_properties(session_state.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(keyboard_ui_tests tests/keyboard_ui/KeyboardUiTests.cpp)
target_link_libraries(keyboard_ui_tests PRIVATE compositor_ui)
add_test(NAME ui.keyboard COMMAND keyboard_ui_tests)
set_tests_properties(ui.keyboard PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
add_executable(growing_brush_tests tests/graphics/GrowingBrushSessionTests.cpp)
target_link_libraries(growing_brush_tests PRIVATE compositor_graphics)
foreach(case unchanged_grid blank_30000 growth_padding_masks transformed_growth selection_cancel_mask atomic_budget immutable_history empty_erase_noop gpu_equivalence invalid_sample viewport_image viewport_transformed viewport_mask region_row_copies small_source_growth)
  add_test(NAME growing_brush.${case} COMMAND growing_brush_tests ${case})
endforeach()
add_executable(viewport_tests tests/graphics/CanvasViewportTests.cpp)
target_link_libraries(viewport_tests PRIVATE compositor_core)
add_test(NAME graphics.viewport COMMAND viewport_tests)
add_executable(native_viewport_tests tests/graphics/NativeViewportTests.cpp)
target_link_libraries(native_viewport_tests PRIVATE compositor_ui)
add_executable(viewport_sampling_tests tests/viewport_sampling/ViewportSamplingTests.cpp)
target_link_libraries(viewport_sampling_tests PRIVATE compositor_render compositor_graphics)
add_test(NAME graphics.physical_viewport_cache COMMAND viewport_sampling_tests)
add_executable(physical_viewport_tests tests/viewport_sampling/PhysicalViewportTests.cpp)
target_link_libraries(physical_viewport_tests PRIVATE compositor_ui)
add_executable(native_pixel_grid_tests tests/viewport_sampling/NativePixelGridTests.cpp)
target_link_libraries(native_pixel_grid_tests PRIVATE compositor_ui)
add_executable(interaction_tests tests/interaction_tests.cpp)
target_link_libraries(interaction_tests PRIVATE compositor_ui)
add_test(NAME ui.pending_interactions COMMAND interaction_tests)
set_tests_properties(ui.pending_interactions PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
add_executable(layer_ui_tests tests/layers/LayerUiTests.cpp)
target_link_libraries(layer_ui_tests PRIVATE compositor_ui)
add_test(NAME layers.ui COMMAND layer_ui_tests)
set_tests_properties(layers.ui PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
add_executable(palette_tests tests/palette_tests.cpp src/ui/PaletteDialog.cpp)
target_link_libraries(palette_tests PRIVATE compositor_effects_tools Qt6::Widgets Qt6::Test)
add_test(NAME palette.controls COMMAND palette_tests)
set_tests_properties(palette.controls PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
add_executable(core_cache_tests tests/core_cache_tests.cpp)
target_link_libraries(core_cache_tests PRIVATE compositor_render)
foreach(case blank_30000 identity_fastpath normal_equivalence offscreen_invalidation bounded_eviction metadata_and_hidden_source full_after_partial lod_large_content scaled_renderer_contract scaled_grain_partition outside_and_rejections blank_culling lod_offscreen_invalidation unsupported_blank_adjustment)
  add_test(NAME cache.${case} COMMAND core_cache_tests ${case})
endforeach()
add_executable(transform_ui_tests tests/editing_transform/TransformUiTests.cpp)
target_link_libraries(transform_ui_tests PRIVATE compositor_ui)
add_test(NAME transform.ui COMMAND transform_ui_tests)
set_tests_properties(transform.ui PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
add_executable(retouch_ui_tests tests/retouch/RetouchUiTests.cpp)
target_link_libraries(retouch_ui_tests PRIVATE compositor_ui)
add_test(NAME retouch.ui COMMAND retouch_ui_tests)
set_tests_properties(retouch.ui PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
add_executable(retouch_tests tests/retouch/RetouchSessionTests.cpp)
target_link_libraries(retouch_tests PRIVATE compositor_retouch)
add_test(NAME retouch.cpu COMMAND retouch_tests)
add_test(NAME retouch.warp COMMAND retouch_tests "${CMAKE_SOURCE_DIR}/shaders/BrushCoverage.hlsl")
add_executable(retouch_extent_tests tests/retouch_extent/ExtentAfterWitness.cpp)
add_executable(retouch_sparse_tests tests/retouch_extent/SparseDocumentTests.cpp)
add_executable(retouch_sparse_preview_tests tests/retouch_extent/SparsePreviewTests.cpp)
add_executable(retouch_sparse_ui_tests tests/retouch_extent/SparseRetouchUiTests.cpp)
target_link_libraries(retouch_sparse_ui_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(retouch_sparse_ui_tests PRIVATE /W4 /WX /utf-8)
foreach(case clone blur smudge liquify heal_content heal_texture heal_proximity clone_all)
  add_test(NAME retouch_sparse_ui.${case} COMMAND retouch_sparse_ui_tests ${case})
  set_tests_properties(retouch_sparse_ui.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 60)
endforeach()
target_link_libraries(retouch_sparse_preview_tests PRIVATE compositor_retouch compositor_editing)
target_compile_options(retouch_sparse_preview_tests PRIVATE /W4 /WX /utf-8)
foreach(case smudge_preview liquify_preview clone_composite mask_edge invalid_source)
  add_test(NAME retouch_sparse.${case} COMMAND retouch_sparse_preview_tests ${case})
  set_tests_properties(retouch_sparse.${case} PROPERTIES TIMEOUT 60)
endforeach()
target_link_libraries(retouch_sparse_tests PRIVATE compositor_retouch compositor_editing)
target_compile_options(retouch_sparse_tests PRIVATE /W4 /WX /utf-8)
foreach(case clone blur heal_content heal_texture heal_proximity smudge liquify)
  add_test(NAME retouch_sparse.${case} COMMAND retouch_sparse_tests ${case})
  set_tests_properties(retouch_sparse.${case} PROPERTIES TIMEOUT 60)
endforeach()
target_link_libraries(retouch_extent_tests PRIVATE compositor_retouch)
target_compile_options(retouch_extent_tests PRIVATE /W4 /WX /utf-8)
add_test(NAME retouch.extent COMMAND "${CMAKE_COMMAND}" "-DWITNESS=$<TARGET_FILE:retouch_extent_tests>" "-DEVIDENCE_ROOT=${CMAKE_SOURCE_DIR}/evidence/retouch-extent-integrated" -P "${CMAKE_SOURCE_DIR}/tests/retouch_extent/run_witness.cmake")
set_tests_properties(retouch.extent PROPERTIES TIMEOUT 60)
add_executable(retouch_growth_tests tests/retouch_extent/GrowthContracts.cpp)
target_link_libraries(retouch_growth_tests PRIVATE compositor_retouch)
target_compile_options(retouch_growth_tests PRIVATE /W4 /WX /utf-8)
add_test(NAME retouch.growth_cpu COMMAND retouch_growth_tests)
add_test(NAME retouch.growth_warp COMMAND retouch_growth_tests "${CMAKE_SOURCE_DIR}/shaders/BrushCoverage.hlsl")
set_tests_properties(retouch.growth_cpu retouch.growth_warp PROPERTIES TIMEOUT 120)
add_executable(distortion_tests tests/editing_transform/DistortionTests.cpp)
target_link_libraries(distortion_tests PRIVATE compositor_transform)
add_test(NAME transform.distortion COMMAND distortion_tests)
add_executable(pixel_transform_tests tests/editing_transform/PixelTransformTests.cpp)
target_link_libraries(pixel_transform_tests PRIVATE compositor_transform)
add_test(NAME transform.selected_pixels COMMAND pixel_transform_tests)
add_executable(adjustment_dialog_tests tests/effects_tools/adjustment_dialog_tests.cpp)
target_link_libraries(adjustment_dialog_tests PRIVATE compositor_ui)
foreach(case levels_cancel curves_apply hue_targeting live_levels_input live_folder_insert preview_off_apply levels_sampler_apply hue_colorize_reset)
  add_test(NAME dialogs.${case} COMMAND adjustment_dialog_tests ${case})
  set_tests_properties(dialogs.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
endforeach()
add_executable(effects_tools_tests tests/effects_tools/effects_tools_tests.cpp src/ui/AdjustmentAdvancedControls.cpp)
target_link_libraries(effects_tools_tests PRIVATE compositor_effects_tools Qt6::Widgets Qt6::Test)
foreach(case levels_normalization_handles levels_histogram_weights levels_histogram_display levels_auto_modes levels_sample_calibration levels_original_sampler levels_json_preservation levels_widget_controls hue_band_weights hue_sample_range hue_target_drag hue_json_spectrum curves_graph_drag curves_json color_hex_hsb color_sample_ring hue_widget_controls curves_widget_controls)
  add_test(NAME effects_tools.${case} COMMAND effects_tools_tests ${case})
  set_tests_properties(effects_tools.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
endforeach()
add_executable(transform_tests tests/editing_transform/TransformGeometryTests.cpp)
target_link_libraries(transform_tests PRIVATE compositor_transform)
add_test(NAME transform.geometry COMMAND transform_tests)
add_executable(layer_tests tests/layers/layer_checks.cpp)
target_link_libraries(layer_tests PRIVATE compositor_layers)
foreach(case hierarchy grouping moves_duplicate clipping bake_delete multi_history copy_graph merge)
  add_test(NAME layers.${case} COMMAND layer_tests ${case})
endforeach()
add_executable(merge_cancellation_tests tests/merge_cancellation/MergeContracts.cpp)
target_link_libraries(merge_cancellation_tests PRIVATE compositor_layers compositor_render compositor_effects)
target_compile_options(merge_cancellation_tests PRIVATE /W4 /WX /utf-8)
foreach(case bounded_render cancel_after_first budget_before_render renderer_failure invalid_dimensions exact_opaque exact_trim exact_grain)
  add_test(NAME merge_cancellation.${case} COMMAND merge_cancellation_tests ${case})
endforeach()
add_executable(merge_async_ui_tests tests/merge_async/MergeAsyncUiTests.cpp)
target_link_libraries(merge_async_ui_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(merge_async_ui_tests PRIVATE /W4 /WX /utf-8)
foreach(case async_commit cancel_button cancel_retry heartbeat busy_guards stale_document destroy_pending destroy_running failure_recovers)
  add_test(NAME merge_async.${case} COMMAND merge_async_ui_tests ${case})
  set_tests_properties(merge_async.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(filter_tests tests/filters/filter_checks.cpp)
target_link_libraries(filter_tests PRIVATE compositor_filters)
add_test(NAME filters.functional COMMAND filter_tests)
add_library(cancellation_kernel_reference STATIC tests/filters/kernel-reference/NoisePixels.c tests/filters/kernel-reference/LensPixels.c tests/filters/kernel-reference/ContentFill.c)
target_include_directories(cancellation_kernel_reference PRIVATE src/graphics/upstream)
target_compile_definitions(cancellation_kernel_reference PRIVATE noise_add=noise_add_reference lens_distort=lens_distort_reference content_fill=content_fill_reference)
target_compile_options(cancellation_kernel_reference PRIVATE /W4 /WX /utf-8)
add_executable(cancellation_kernel_tests tests/filters/KernelEquivalence.cpp)
target_include_directories(cancellation_kernel_tests PRIVATE src/graphics/upstream)
target_link_libraries(cancellation_kernel_tests PRIVATE compositor_graphics cancellation_kernel_reference)
target_compile_options(cancellation_kernel_tests PRIVATE /W4 /WX /utf-8)
add_test(NAME cancellation.kernel_equivalence COMMAND cancellation_kernel_tests)
add_executable(filter_cancellation_tests tests/filters/CancellationTests.cpp)
target_link_libraries(filter_cancellation_tests PRIVATE compositor_filters)
target_compile_options(filter_cancellation_tests PRIVATE /W4 /WX /utf-8)
foreach(case noise_stop lens_stop fill_stop noise_throw lens_throw fill_throw noise_filter lens_filter fill_filter)
  add_test(NAME cancellation.${case} COMMAND filter_cancellation_tests ${case})
endforeach()
# Release-only timings run manually while other builds/tests are idle. ASAN does
# not use this latency threshold; it runs the deterministic cancellation cases.
add_executable(filter_cancellation_latency tests/filters/CancellationLatencyWitness.cpp)
target_link_libraries(filter_cancellation_latency PRIVATE compositor_filters)
target_compile_options(filter_cancellation_latency PRIVATE /W4 /WX /utf-8)
add_library(adjustment_cancellation_reference STATIC tests/filters/adjustment-reference/AdjustmentReference.cpp)
target_link_libraries(adjustment_cancellation_reference PUBLIC compositor_graphics Qt6::Core)
target_compile_options(adjustment_cancellation_reference PRIVATE /W4 /WX /utf-8)
add_executable(adjustment_cancellation_tests tests/filters/AdjustmentCancellationContracts.cpp)
target_link_libraries(adjustment_cancellation_tests PRIVATE compositor_effects adjustment_cancellation_reference)
target_compile_options(adjustment_cancellation_tests PRIVATE /W4 /WX /utf-8)
add_test(NAME cancellation.adjustment_contracts COMMAND adjustment_cancellation_tests)
add_test(NAME cancellation.adjustment_current_contracts COMMAND adjustment_cancellation_tests --correct-levels-oracle)
add_executable(adjustment_cancellation_latency tests/filters/AdjustmentCancellationLatencyWitness.cpp)
target_link_libraries(adjustment_cancellation_latency PRIVATE compositor_effects)
target_compile_options(adjustment_cancellation_latency PRIVATE /W4 /WX /utf-8)
add_executable(adjustment_panel_cancellation tests/filters/AdjustmentPanelCancellationWitness.cpp)
target_link_libraries(adjustment_panel_cancellation PRIVATE compositor_ui Qt6::Test)
target_compile_options(adjustment_panel_cancellation PRIVATE /W4 /WX /utf-8)
foreach(case grain_close hsv_close grain_destroy)
  add_test(NAME cancellation.adjustment_panel_${case} COMMAND adjustment_panel_cancellation ${case} --lifecycle)
  set_tests_properties(cancellation.adjustment_panel_${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(palette_swatch_tests tests/palette_swatches/PaletteSwatchTests.cpp)
target_link_libraries(palette_swatch_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(palette_swatch_tests PRIVATE /W4 /WX /utf-8)
foreach(case layout_overlap rounded_hit_region labels_tooltips colors picker_apply_cancel swap_reset mask_palette mask_chooser_nonmodal mask_target_closes_picker stroke_disabled project_restore eyedropper_refresh)
  add_test(NAME palette_swatches.${case} COMMAND "${CMAKE_COMMAND}" "-DEXECUTABLE=$<TARGET_FILE:palette_swatch_tests>" "-DCASE=${case}" "-DEVIDENCE_ROOT=${CMAKE_BINARY_DIR}/palette-swatch-results" -DOUTPUT_DIRECTORY=ON -P "${CMAKE_SOURCE_DIR}/tests/run-evidence-case.cmake")
  set_tests_properties(palette_swatches.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 75)
endforeach()
add_executable(live_levels_histogram_tests tests/live_levels_histogram/LiveLevelsHistogramTests.cpp)
target_link_libraries(live_levels_histogram_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(live_levels_histogram_tests PRIVATE /W4 /WX /utf-8)
foreach(case landscape_odd portrait_odd boundary_8000 small_control alpha_weighted row_major_fractional input_scope_selection composite_before_reduce)
  add_test(NAME live_levels_histogram.${case} COMMAND "${CMAKE_COMMAND}" "-DEXECUTABLE=$<TARGET_FILE:live_levels_histogram_tests>" "-DCASE=${case}" "-DEVIDENCE_ROOT=${CMAKE_BINARY_DIR}/live-levels-histogram-results" -P "${CMAKE_SOURCE_DIR}/tests/live_levels_histogram/run-case.cmake")
  set_tests_properties(live_levels_histogram.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 75)
endforeach()
add_executable(import_draft_tests tests/import_drafts/ImportDraftTests.cpp)
add_executable(live_histogram_resource_tests tests/live_levels_histogram/HistogramResourceTests.cpp)
target_link_libraries(live_histogram_resource_tests PRIVATE compositor_ui)
target_compile_options(live_histogram_resource_tests PRIVATE /W4 /WX /utf-8)
foreach(case large_sparse large_blank cancellation full_stack full_histogram_retained partial_right_tile)
  add_test(NAME live_histogram_resource.${case} COMMAND live_histogram_resource_tests ${case})
  set_tests_properties(live_histogram_resource.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 60)
endforeach()
target_link_libraries(import_draft_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(import_draft_tests PRIVATE /W4 /WX /utf-8)
foreach(case gradient_accept gradient_picker_cancel polygon_accept polygon_picker_cancel crop_accept crop_picker_cancel transform_accept transform_picker_cancel brush_focus_cancel freehand_focus_cancel)
  add_test(NAME import_drafts.${case} COMMAND import_draft_tests ${case})
  set_tests_properties(import_drafts.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
endforeach()
add_executable(toolbar_layout_tests tests/brush_appearance_controls/ToolbarLayoutTests.cpp)
target_link_libraries(toolbar_layout_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(toolbar_layout_tests PRIVATE /W4 /WX /utf-8)
foreach(case brush_minimum brush_1280 brush_1500 heal_minimum heal_1280 heal_1500 clone_minimum clone_1280 clone_1500 smear_minimum smear_1280 smear_1500)
  add_test(NAME toolbar_layout.${case} COMMAND toolbar_layout_tests ${case} "${CMAKE_BINARY_DIR}/toolbar-layout-${case}.json")
  set_tests_properties(toolbar_layout.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 60)
endforeach()
add_executable(native_levels_uia tests/adjustment_accessibility/NativeLevelsUiaWitness.cpp)
target_link_libraries(native_levels_uia PRIVATE compositor_ui Qt6::Test uiautomationcore ole32 oleaut32)
target_compile_options(native_levels_uia PRIVATE /W4 /WX /utf-8)
add_executable(selection_overlay_tests tests/selection_animation/SelectionOverlayContracts.cpp)
target_link_libraries(selection_overlay_tests PRIVATE compositor_ui)
target_compile_options(selection_overlay_tests PRIVATE /W4 /WX /utf-8)
foreach(case geometry_transform geometry_curves geometry_holes geometry_invalid timer_lifecycle)
  add_test(NAME selection_overlay.${case} COMMAND selection_overlay_tests ${case})
  set_tests_properties(selection_overlay.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 60)
endforeach()
add_executable(native_selection_animation_witness tests/selection_animation/NativeSelectionAnimationWitness.cpp)
add_executable(native_selection_outside_witness tests/selection_animation/NativeSelectionOutsideWitness.cpp)
foreach(target native_selection_animation_witness native_selection_outside_witness)
  target_link_libraries(${target} PRIVATE compositor_ui)
  target_compile_options(${target} PRIVATE /W4 /WX /utf-8)
endforeach()
add_executable(adjustment_source_tests tests/adjustment_source/AdjustmentSourceTests.cpp)
target_link_libraries(adjustment_source_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(adjustment_source_tests PRIVATE /W4 /WX /utf-8)
foreach(case global_live clipped_curve hue_mask persistence curves_image blend_coverage editor_hsv editor_levels editor_curves editor_exposure editor_gradient_map editor_grain legacy_hsv)
  add_test(NAME adjustment_source.${case} COMMAND "${CMAKE_COMMAND}" "-DEXECUTABLE=$<TARGET_FILE:adjustment_source_tests>" "-DCASE=${case}" "-DEVIDENCE_ROOT=${CMAKE_BINARY_DIR}/adjustment-source-results" -P "${CMAKE_SOURCE_DIR}/tests/adjustment_source/run-case.cmake")
  set_tests_properties(adjustment_source.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 60)
endforeach()
add_executable(layer_item_commit_tests tests/adjustment_source/LayerItemCommitTests.cpp)
add_executable(adjustment_initial_metadata_tests tests/adjustment_source/InitialMetadataTests.cpp)
target_link_libraries(adjustment_initial_metadata_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(adjustment_initial_metadata_tests PRIVATE /W4 /WX /utf-8)
add_test(NAME adjustment_initial_metadata.exposure_optional COMMAND "${CMAKE_COMMAND}" "-DEXECUTABLE=$<TARGET_FILE:adjustment_initial_metadata_tests>" -DCASE=exposure_optional "-DEVIDENCE_ROOT=${CMAKE_BINARY_DIR}/adjustment-initial-metadata-results" -P "${CMAKE_SOURCE_DIR}/tests/run-evidence-case.cmake")
set_tests_properties(adjustment_initial_metadata.exposure_optional PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 75)
target_link_libraries(layer_item_commit_tests PRIVATE compositor_ui Qt6::Test)
target_compile_options(layer_item_commit_tests PRIVATE /W4 /WX /utf-8)
foreach(case checkbox_repeated rename_repeated rapid_toggles owner_switch deleted_target busy_guards)
  add_test(NAME layer_item_commit.${case} COMMAND layer_item_commit_tests ${case})
  set_tests_properties(layer_item_commit.${case} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 60)
endforeach()
add_test(NAME parity.gaussian_source_test_conflict COMMAND filter_tests --source-parity)
set_tests_properties(parity.gaussian_source_test_conflict PROPERTIES LABELS "parity;known_failure")
add_executable(editing_tests tests/editing/editing_tests.cpp)
target_link_libraries(editing_tests PRIVATE compositor_editing compositor_graphics)
foreach(case drag_box geometry_combine coverage_aa empty_move_inverse mapping_transforms fill_clear_crop fill_growth_mask selected_immutable_invert uniform_mask_fill_invert copy_current_merged copy_lasso selection_history invalid_inputs scaled_selection_clear gradient_linear gradient_radial gradient_reverse_transparent gradient_mask_preview bitmap_outline expand_contract shape_rectangle_ellipse shape_rounded_style shape_redraw_mask shape_preview canvas_anchors canvas_units canvas_extension canvas_allocation_free crop_geometry crop_snapping crop_commit image_resize image_resolution_only image_rotated_hidden flip_canvas flip_layer_masks flip_group transformed_outline)
  add_test(NAME editing.${case} COMMAND editing_tests ${case})
endforeach()
add_executable(effects_tests tests/effects/effects_tests.cpp)
target_link_libraries(effects_tests PRIVATE compositor_effects)
add_executable(foreground_quality_tests tests/imaging/quality_native.cpp)
target_include_directories(foreground_quality_tests PRIVATE src/imaging)
target_link_libraries(foreground_quality_tests PRIVATE compositor_imaging psapi)
foreach(case identity_handles exposure_formula curves_alpha gradient_endpoints grain_global_tiles hsv_primary_alpha hsv_bands_colorize selected_immutable_tiles malformed_json levels_opaque_order levels_partial_alpha_selection)
  add_test(NAME effects.${case} COMMAND effects_tests ${case})
endforeach()
add_test(NAME parity.levels_source_test_conflict COMMAND effects_tests levels_upstream_conflict)
set_tests_properties(parity.levels_source_test_conflict PROPERTIES LABELS "parity;known_failure")
add_executable(stack_renderer_tests tests/graphics/StackRendererTests.cpp)
add_executable(live_mask_source_tests tests/live_mask_source/LiveMaskSourceTests.cpp)
target_link_libraries(live_mask_source_tests PRIVATE compositor_layers compositor_render compositor_persistence Qt6::Core)
target_compile_options(live_mask_source_tests PRIVATE /W4 /WX /utf-8)
foreach(case clipping_color option_stack hidden_source persistence_bake moved_chain)
  add_test(NAME source_live_mask.${case} COMMAND "${CMAKE_COMMAND}"
    "-DEXECUTABLE=$<TARGET_FILE:live_mask_source_tests>" "-DCASE=${case}"
    "-DEVIDENCE_ROOT=${CMAKE_BINARY_DIR}/live-mask-source-evidence"
    -P "${CMAKE_SOURCE_DIR}/tests/live_mask_source/run-case.cmake")
  set_tests_properties(source_live_mask.${case} PROPERTIES TIMEOUT 35)
endforeach()
target_link_libraries(stack_renderer_tests PRIVATE compositor_graphics)
add_test(NAME graphics.stack_renderer COMMAND stack_renderer_tests)
add_executable(brush_session_tests tests/graphics/BrushSessionTests.cpp)
target_link_libraries(brush_session_tests PRIVATE compositor_graphics)
add_test(NAME graphics.brush_session COMMAND brush_session_tests "${CMAKE_SOURCE_DIR}/shaders/BrushCoverage.hlsl")
add_executable(persistence_tests tests/persistence/persistence_tests.cpp)
target_link_libraries(persistence_tests PRIVATE compositor_persistence)
foreach(case blank_roundtrip raster_mask_roundtrip legacy_version_gates malformed_metadata graph_boundaries rollback_faults crash_recovery allocation_preflight hostile_journal reparse_rejection real_png_exchange)
  add_test(NAME persistence.${case} COMMAND persistence_tests ${case})
endforeach()
add_executable(pixel_algorithm_tests tests/graphics/PixelAlgorithmsTests.cpp)
target_link_libraries(pixel_algorithm_tests PRIVATE compositor_graphics)
add_test(NAME graphics.upstream_c_algorithms COMMAND pixel_algorithm_tests)
add_executable(brush_coverage_tests tests/graphics/BrushCoverageTests.cpp)
target_link_libraries(brush_coverage_tests PRIVATE compositor_graphics)
add_test(NAME graphics.brush_cpu_warp COMMAND brush_coverage_tests "${CMAKE_SOURCE_DIR}/shaders/BrushCoverage.hlsl" "${CMAKE_BINARY_DIR}/evidence/brush")
add_executable(core_tests tests/core_tests.cpp)
target_link_libraries(core_tests PRIVATE compositor_render)
add_executable(history_allocation_tests tests/history/AllocationFailureTests.cpp)
target_link_libraries(history_allocation_tests PRIVATE compositor_core)
target_compile_options(history_allocation_tests PRIVATE /W4 /WX /utf-8)
foreach(case begin end nested_end trim_end undo redo cancel noop)
  add_test(NAME history.allocation_${case} COMMAND history_allocation_tests ${case})
endforeach()
foreach(case transform_fractional_inverse immutable_tiles premultiplied_contract normal_alpha_exact dodge_burn_alpha all_blends_alpha render_tile_partition mask_and_hidden_clip history_save_noop_redo history_nested_cancel history_unique_retention selection_absent_empty reject_invalid_document wide_narrow_image)
  add_test(NAME core.${case} COMMAND core_tests ${case})
endforeach()
endif()
install(TARGETS Compositor RUNTIME DESTINATION .)
# Target-only builds must deploy the same pinned runtime as complete builds.
get_property(compositor_targets DIRECTORY PROPERTY BUILDSYSTEM_TARGETS)
foreach(target IN LISTS compositor_targets)
  get_target_property(target_type ${target} TYPE)
  if(target_type STREQUAL "EXECUTABLE")
    add_dependencies(${target} deploy_imaging_runtime)
  endif()
endforeach()

# Root integration proposal. This file does not configure itself.
# ParallelBatch.cpp is already a source of compositor_graphics.
add_library(brush_cpu_reference OBJECT tests/brush_cpu_batch/reference41/BrushCoverage.cpp)
target_compile_definitions(brush_cpu_reference PRIVATE compositor=reference_compositor)
target_compile_options(brush_cpu_reference PRIVATE /W4 /WX /utf-8)
add_executable(brush_cpu_batch_tests
  tests/brush_cpu_batch/BatchContracts.cpp
  src/graphics/BrushCoverage.cpp
  src/graphics/ParallelBatch.cpp
  $<TARGET_OBJECTS:brush_cpu_reference>)
target_include_directories(brush_cpu_batch_tests PRIVATE src tests/brush_cpu_batch)
target_compile_definitions(brush_cpu_batch_tests PRIVATE
  COMPOSITOR_BRUSH_BATCH_TESTING NOMINMAX WIN32_LEAN_AND_MEAN)
target_compile_options(brush_cpu_batch_tests PRIVATE /W4 /WX /utf-8)
target_link_libraries(brush_cpu_batch_tests PRIVATE Qt6::Core)
foreach(case hard_analytic_batch soft_tail_replace_commit odd_rotated_clipped_tiles
    explicit_worker_counts floating_environment whole_batch_preflight
    null_duplicate_and_limits worker_exception_joins_and_recovers bounded_concurrent_calls
    executor_nested_and_validation row_range_odd_tails batch_count_exact_boundary
    real_800px_two_strokes)
  add_test(NAME brush_cpu_batch.${case} COMMAND "${CMAKE_COMMAND}"
    "-DEXECUTABLE=$<TARGET_FILE:brush_cpu_batch_tests>" "-DCASE=${case}"
    "-DEVIDENCE_ROOT=${CMAKE_SOURCE_DIR}/evidence/graphics/brush-cpu-batch/integrated"
    -P "${CMAKE_SOURCE_DIR}/tests/brush_cpu_batch/run-case.cmake")
  set_tests_properties(brush_cpu_batch.${case} PROPERTIES TIMEOUT 250)
endforeach()


if(BUILD_TESTING)
  include(tests/PortExpansionTests.cmake)
endif()
