diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e9bea3780..46cc9493bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,923 +1,931 @@ project(krita) message(STATUS "Using CMake version: ${CMAKE_VERSION}") cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR) set(MIN_QT_VERSION 5.9.0) set(MIN_FRAMEWORKS_VERSION 5.44.0) set( CMAKE_CXX_STANDARD 11 ) set( CMAKE_CXX_STANDARD_REQUIRED ON ) if (POLICY CMP0002) cmake_policy(SET CMP0002 OLD) endif() if (POLICY CMP0017) cmake_policy(SET CMP0017 NEW) endif () if (POLICY CMP0022) cmake_policy(SET CMP0022 OLD) endif () if (POLICY CMP0026) cmake_policy(SET CMP0026 OLD) endif() if (POLICY CMP0042) cmake_policy(SET CMP0042 NEW) endif() if (POLICY CMP0046) cmake_policy(SET CMP0046 OLD) endif () if (POLICY CMP0059) cmake_policy(SET CMP0059 OLD) endif() if (POLICY CMP0063) cmake_policy(SET CMP0063 OLD) endif() if (POLICY CMP0054) cmake_policy(SET CMP0054 OLD) endif() if (POLICY CMP0064) cmake_policy(SET CMP0064 OLD) endif() if (POLICY CMP0071) cmake_policy(SET CMP0071 OLD) endif() if (APPLE) set(APPLE_SUPPRESS_X11_WARNING TRUE) set(KDE_SKIP_RPATH_SETTINGS TRUE) set(CMAKE_MACOSX_RPATH 1) set(BUILD_WITH_INSTALL_RPATH 1) add_definitions(-mmacosx-version-min=10.12 -Wno-macro-redefined -Wno-deprecated-register) endif() if (CMAKE_COMPILER_IS_GNUCXX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9 AND NOT WIN32) add_compile_options($<$:-Wno-suggest-override> -Wextra -Wno-class-memaccess) endif() ###################### ####################### ## Constants defines ## ####################### ###################### # define common versions of Krita applications, used to generate kritaversion.h # update these version for every release: set(KRITA_VERSION_STRING "4.3.1-alpha") # Major version: 3 for 3.x, 4 for 4.x, etc. set(KRITA_STABLE_VERSION_MAJOR 4) # Minor version: 0 for 4.0, 1 for 4.1, etc. set(KRITA_STABLE_VERSION_MINOR 3) # Bugfix release version, or 0 for before the first stable release set(KRITA_VERSION_RELEASE 1) # the 4th digit, really only used for the Windows installer: # - [Pre-]Alpha: Starts from 0, increment 1 per release # - Beta: Starts from 50, increment 1 per release # - Stable: Set to 100, bump to 101 if emergency update is needed set(KRITA_VERSION_REVISION 0) set(KRITA_ALPHA 1) # uncomment only for Alpha #set(KRITA_BETA 1) # uncomment only for Beta #set(KRITA_RC 1) # uncomment only for RC if(NOT DEFINED KRITA_ALPHA AND NOT DEFINED KRITA_BETA AND NOT DEFINED KRITA_RC) set(KRITA_STABLE 1) # do not edit endif() message(STATUS "Krita version: ${KRITA_VERSION_STRING}") # Define the generic version of the Krita libraries here # This makes it easy to advance it when the next Krita release comes. # 14 was the last GENERIC_KRITA_LIB_VERSION_MAJOR of the previous Krita series # (2.x) so we're starting with 15 in 3.x series, 16 in 4.x series if(KRITA_STABLE_VERSION_MAJOR EQUAL 4) math(EXPR GENERIC_KRITA_LIB_VERSION_MAJOR "${KRITA_STABLE_VERSION_MINOR} + 16") else() # let's make sure we won't forget to update the "16" message(FATAL_ERROR "Reminder: please update offset == 16 used to compute GENERIC_KRITA_LIB_VERSION_MAJOR to something bigger") endif() set(GENERIC_KRITA_LIB_VERSION "${GENERIC_KRITA_LIB_VERSION_MAJOR}.0.0") set(GENERIC_KRITA_LIB_SOVERSION "${GENERIC_KRITA_LIB_VERSION_MAJOR}") LIST (APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules") LIST (APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/kde_macro") # fetch git revision for the current build set(KRITA_GIT_SHA1_STRING "") set(KRITA_GIT_BRANCH_STRING "") include(GetGitRevisionDescription) get_git_head_hash(GIT_SHA1) get_git_branch(GIT_BRANCH) if(GIT_SHA1) string(SUBSTRING ${GIT_SHA1} 0 7 GIT_SHA1) set(KRITA_GIT_SHA1_STRING ${GIT_SHA1}) if(GIT_BRANCH) set(KRITA_GIT_BRANCH_STRING ${GIT_BRANCH}) else() set(KRITA_GIT_BRANCH_STRING "(detached HEAD)") endif() endif() # create test make targets enable_testing() # collect list of broken tests, empty here to start fresh with each cmake run set(KRITA_BROKEN_TESTS "" CACHE INTERNAL "KRITA_BROKEN_TESTS") ############ ############# ## Options ## ############# ############ include(FeatureSummary) if (WIN32) option(USE_DRMINGW "Support the Dr. Mingw crash handler (only on windows)" ON) add_feature_info("Dr. Mingw" USE_DRMINGW "Enable the Dr. Mingw crash handler") if (MINGW) option(USE_MINGW_HARDENING_LINKER "Enable DEP (NX), ASLR and high-entropy ASLR linker flags (mingw-w64)" ON) add_feature_info("Linker Security Flags" USE_MINGW_HARDENING_LINKER "Enable DEP (NX), ASLR and high-entropy ASLR linker flags") if (USE_MINGW_HARDENING_LINKER) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--dynamicbase -Wl,--nxcompat -Wl,--disable-auto-image-base") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--dynamicbase -Wl,--nxcompat -Wl,--disable-auto-image-base") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--dynamicbase -Wl,--nxcompat -Wl,--disable-auto-image-base") if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") # Enable high-entropy ASLR for 64-bit # The image base has to be >4GB for HEASLR to be enabled. # The values used here are kind of arbitrary. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--high-entropy-va -Wl,--image-base,0x140000000") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--high-entropy-va -Wl,--image-base,0x180000000") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--high-entropy-va -Wl,--image-base,0x180000000") endif ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") else (USE_MINGW_HARDENING_LINKER) message(WARNING "Linker Security Flags not enabled!") endif (USE_MINGW_HARDENING_LINKER) endif (MINGW) endif () option(HIDE_SAFE_ASSERTS "Don't show message box for \"safe\" asserts, just ignore them automatically and dump a message to the terminal." ON) configure_file(config-hide-safe-asserts.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-hide-safe-asserts.h) add_feature_info("Hide Safe Asserts" HIDE_SAFE_ASSERTS "Don't show message box for \"safe\" asserts, just ignore them automatically and dump a message to the terminal.") option(USE_LOCK_FREE_HASH_TABLE "Use lock free hash table instead of blocking." ON) configure_file(config-hash-table-implementaion.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-hash-table-implementaion.h) add_feature_info("Lock free hash table" USE_LOCK_FREE_HASH_TABLE "Use lock free hash table instead of blocking.") option(FOUNDATION_BUILD "A Foundation build is a binary release build that can package some extra things like color themes. Linux distributions that build and install Krita into a default system location should not define this option to true." OFF) add_feature_info("Foundation Build" FOUNDATION_BUILD "A Foundation build is a binary release build that can package some extra things like color themes. Linux distributions that build and install Krita into a default system location should not define this option to true.") option(KRITA_ENABLE_BROKEN_TESTS "Enable tests that are marked as broken" OFF) add_feature_info("Enable Broken Tests" KRITA_ENABLE_BROKEN_TESTS "Runs broken test when \"make test\" is invoked (use -DKRITA_ENABLE_BROKEN_TESTS=ON to enable).") option(LIMIT_LONG_TESTS "Run long running unittests in a limited quick mode" ON) configure_file(config-limit-long-tests.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-limit-long-tests.h) add_feature_info("Limit long tests" LIMIT_LONG_TESTS "Run long running unittests in a limited quick mode") option(ENABLE_PYTHON_2 "Enables the compiler to look for Python 2.7 instead of Python 3. Some packaged scripts are not compatible with Python 2 and this should only be used if you really have to use 2.7." OFF) option(BUILD_KRITA_QT_DESIGNER_PLUGINS "Build Qt Designer plugins for Krita widgets" OFF) add_feature_info("Build Qt Designer plugins" BUILD_KRITA_QT_DESIGNER_PLUGINS "Builds Qt Designer plugins for Krita widgets (use -DBUILD_KRITA_QT_DESIGNER_PLUGINS=ON to enable).") include(MacroJPEG) ######################################################### ## Look for Python3 It is also searched by KF5, ## ## so we should request the correct version in advance ## ######################################################### function(TestCompileLinkPythonLibs OUTPUT_VARNAME) include(CheckCXXSourceCompiles) set(CMAKE_REQUIRED_INCLUDES ${PYTHON_INCLUDE_PATH}) set(CMAKE_REQUIRED_LIBRARIES ${PYTHON_LIBRARIES}) if (MINGW) set(CMAKE_REQUIRED_DEFINITIONS -D_hypot=hypot) endif (MINGW) unset(${OUTPUT_VARNAME} CACHE) CHECK_CXX_SOURCE_COMPILES(" #include int main(int argc, char *argv[]) { Py_InitializeEx(0); }" ${OUTPUT_VARNAME}) endfunction() if(MINGW) if(ENABLE_PYTHON_2) message(FATAL_ERROR "Python 2.7 is not supported on Windows at the moment.") else(ENABLE_PYTHON_2) find_package(PythonInterp 3.8 EXACT) find_package(PythonLibs 3.8 EXACT) endif(ENABLE_PYTHON_2) if (PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND) if(ENABLE_PYTHON_2) find_package(PythonLibrary 2.7) else(ENABLE_PYTHON_2) find_package(PythonLibrary 3.8) endif(ENABLE_PYTHON_2) TestCompileLinkPythonLibs(CAN_USE_PYTHON_LIBS) if (NOT CAN_USE_PYTHON_LIBS) message(FATAL_ERROR "Compiling with Python library failed, please check whether the architecture is correct. Python will be disabled.") endif (NOT CAN_USE_PYTHON_LIBS) endif (PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND) else(MINGW) if(ENABLE_PYTHON_2) find_package(PythonInterp 2.7) find_package(PythonLibrary 2.7) else(ENABLE_PYTHON_2) find_package(PythonInterp 3.0) find_package(PythonLibrary 3.0) endif(ENABLE_PYTHON_2) endif(MINGW) ######################## ######################### ## Look for KDE and Qt ## ######################### ######################## find_package(ECM 5.22 REQUIRED NOMODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(ECMOptionalAddSubdirectory) include(ECMAddAppIcon) include(ECMSetupVersion) include(ECMMarkNonGuiExecutable) include(ECMGenerateHeaders) include(GenerateExportHeader) include(ECMMarkAsTest) include(ECMInstallIcons) include(CMakePackageConfigHelpers) include(WriteBasicConfigVersionFile) include(CheckFunctionExists) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings) # do not reorder to be alphabetical: this is the order in which the frameworks # depend on each other. find_package(KF5 ${MIN_FRAMEWORKS_VERSION} REQUIRED COMPONENTS Config WidgetsAddons Completion CoreAddons GuiAddons I18n ItemModels ItemViews WindowSystem ) find_package(Qt5 ${MIN_QT_VERSION} REQUIRED COMPONENTS Core Gui Widgets Xml Network PrintSupport Svg Test Concurrent ) if (ANDROID) find_package(Qt5 ${MIN_QT_VERSION} REQUIRED COMPONENTS AndroidExtras ) endif() if (WIN32) set(CMAKE_REQUIRED_INCLUDES ${Qt5Core_INCLUDE_DIRS}) set(CMAKE_REQUIRED_LIBRARIES ${Qt5Core_LIBRARIES}) CHECK_CXX_SOURCE_COMPILES(" #include int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_MSWindowsUseWinTabAPI); } " QT_HAS_WINTAB_SWITCH ) unset(CMAKE_REQUIRED_INCLUDES) unset(CMAKE_REQUIRED_LIBRARIES) option(USE_QT_TABLET_WINDOWS "Do not use Krita's forked Wintab and Windows Ink support on Windows, but leave everything to Qt." ON) add_feature_info("Use Qt's Windows Tablet Support" USE_QT_TABLET_WINDOWS "Do not use Krita's forked Wintab and Windows Ink support on Windows, but leave everything to Qt.") configure_file(config_use_qt_tablet_windows.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config_use_qt_tablet_windows.h) endif () set(CMAKE_REQUIRED_INCLUDES ${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS}) set(CMAKE_REQUIRED_LIBRARIES ${Qt5Core_LIBRARIES} ${Qt5Gui_LIBRARIES}) CHECK_CXX_SOURCE_COMPILES(" #include int main(int argc, char *argv[]) { QSurfaceFormat fmt; fmt.setColorSpace(QSurfaceFormat::scRGBColorSpace); fmt.setColorSpace(QSurfaceFormat::bt2020PQColorSpace); } " HAVE_HDR ) configure_file(config-hdr.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-hdr.h) CHECK_CXX_SOURCE_COMPILES(" #include int main(int argc, char *argv[]) { QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round); QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor); QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); } " HAVE_HIGH_DPI_SCALE_FACTOR_ROUNDING_POLICY ) configure_file(config-high-dpi-scale-factor-rounding-policy.h.in ${CMAKE_CURRENT_BINARY_DIR}/config-high-dpi-scale-factor-rounding-policy.h) if (WIN32) CHECK_CXX_SOURCE_COMPILES(" #include int main(int argc, char *argv[]) { QWindowsWindowFunctions::setHasBorderInFullScreenDefault(true); } " HAVE_SET_HAS_BORDER_IN_FULL_SCREEN_DEFAULT ) configure_file(config-set-has-border-in-full-screen-default.h.in ${CMAKE_CURRENT_BINARY_DIR}/config-set-has-border-in-full-screen-default.h) endif (WIN32) unset(CMAKE_REQUIRED_INCLUDES) unset(CMAKE_REQUIRED_LIBRARIES) include (MacroAddFileDependencies) include (MacroBoolTo01) include (MacroEnsureOutOfSourceBuild) macro_ensure_out_of_source_build("Compiling Krita inside the source directory is not possible. Please refer to the build instruction https://community.kde.org/Krita#Build_Instructions") # Note: OPTIONAL_COMPONENTS does not seem to be reliable # (as of ECM 5.15.0, CMake 3.2) find_package(Qt5Multimedia ${MIN_QT_VERSION}) set_package_properties(Qt5Multimedia PROPERTIES DESCRIPTION "Qt multimedia integration" URL "https://www.qt.io/" TYPE OPTIONAL PURPOSE "Optionally used to provide sound support for animations") macro_bool_to_01(Qt5Multimedia_FOUND HAVE_QT_MULTIMEDIA) configure_file(config-qtmultimedia.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-qtmultimedia.h ) if (NOT APPLE) find_package(Qt5Quick ${MIN_QT_VERSION}) set_package_properties(Qt5Quick PROPERTIES DESCRIPTION "QtQuick" URL "https://www.qt.io/" TYPE OPTIONAL PURPOSE "Optionally used for the touch gui for Krita") macro_bool_to_01(Qt5Quick_FOUND HAVE_QT_QUICK) find_package(Qt5QuickWidgets ${MIN_QT_VERSION}) set_package_properties(Qt5QuickWidgets PROPERTIES DESCRIPTION "QtQuickWidgets" URL "https://www.qt.io/" TYPE OPTIONAL PURPOSE "Optionally used for the touch gui for Krita") endif() if (NOT WIN32 AND NOT APPLE AND NOT ANDROID) find_package(Qt5 ${MIN_QT_VERSION} REQUIRED X11Extras) find_package(Qt5DBus ${MIN_QT_VERSION}) set(HAVE_DBUS ${Qt5DBus_FOUND}) set_package_properties(Qt5DBus PROPERTIES DESCRIPTION "Qt DBUS integration" URL "https://www.qt.io/" TYPE OPTIONAL PURPOSE "Optionally used to provide a dbus api on Linux") find_package(KF5Crash ${MIN_FRAMEWORKS_VERSION}) macro_bool_to_01(KF5Crash_FOUND HAVE_KCRASH) set_package_properties(KF5Crash PROPERTIES DESCRIPTION "KDE's Crash Handler" URL "https://api.kde.org/frameworks-api/frameworks5-apidocs/kcrash/html/index.html" TYPE OPTIONAL PURPOSE "Optionally used to provide crash reporting on Linux") find_package(X11 REQUIRED COMPONENTS Xinput) set(HAVE_X11 TRUE) add_definitions(-DHAVE_X11) else() set(HAVE_DBUS FALSE) set(HAVE_X11 FALSE) endif() add_definitions( -DQT_USE_QSTRINGBUILDER -DQT_STRICT_ITERATORS -DQT_NO_SIGNALS_SLOTS_KEYWORDS -DQT_NO_URL_CAST_FROM_STRING -DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS ) #if (${Qt5_VERSION} VERSION_GREATER "5.14.0" ) # add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x50F00) #elseif (${Qt5_VERSION} VERSION_GREATER "5.13.0" ) # add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x50E00) #elseif (${Qt5_VERSION} VERSION_GREATER "5.12.0" ) # add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x50D00) #elseif (${Qt5_VERSION} VERSION_GREATER "5.11.0" ) # add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x50C00) #if(${Qt5_VERSION} VERSION_GREATER "5.10.0" ) # add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x50B00) #if(${Qt5_VERSION} VERSION_GREATER "5.9.0" ) # add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x50A00) #else() add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x50900) #endif() add_definitions(-DQT_DEPRECATED_WARNINGS) add_definitions(-DTRANSLATION_DOMAIN=\"krita\") # # The reason for this mode is that the Debug mode disable inlining # if(CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fext-numeric-literals") endif() option(KRITA_DEVS "For Krita developers. This modifies the DEBUG build type to use -O3 -g, while still enabling Q_ASSERT. This is necessary because the Qt5 cmake modules normally append QT_NO_DEBUG to any build type that is not labeled Debug") if (KRITA_DEVS) set(CMAKE_CXX_FLAGS_DEBUG "-O3 -g" CACHE STRING "" FORCE) endif() if(UNIX) set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};m") endif() if(WIN32) if(MSVC) # C4522: 'class' : multiple assignment operators specified set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -wd4522") endif() endif() # KDECompilerSettings adds the `--export-all-symbols` linker flag. # We don't really need it. if(MINGW) string(REPLACE "-Wl,--export-all-symbols" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") string(REPLACE "-Wl,--export-all-symbols" "" CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}") endif(MINGW) if(MINGW) # Hack CMake's variables to tell AR to create thin archives to reduce unnecessary writes. # Source of definition: https://github.com/Kitware/CMake/blob/v3.14.1/Modules/Platform/Windows-GNU.cmake#L128 # Thin archives: https://sourceware.org/binutils/docs/binutils/ar.html#index-thin-archives macro(mingw_use_thin_archive lang) foreach(rule CREATE_SHARED_MODULE CREATE_SHARED_LIBRARY LINK_EXECUTABLE) string(REGEX REPLACE "( [^ T]+) " "\\1T " CMAKE_${lang}_${rule} "${CMAKE_${lang}_${rule}}") endforeach() endmacro() mingw_use_thin_archive(CXX) endif(MINGW) # enable exceptions globally kde_enable_exceptions() set(KRITA_DEFAULT_TEST_DATA_DIR ${CMAKE_SOURCE_DIR}/sdk/tests/data/) macro(macro_add_unittest_definitions) add_definitions(-DFILES_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/data/") add_definitions(-DFILES_OUTPUT_DIR="${CMAKE_CURRENT_BINARY_DIR}") add_definitions(-DFILES_DEFAULT_DATA_DIR="${KRITA_DEFAULT_TEST_DATA_DIR}") add_definitions(-DSYSTEM_RESOURCES_DATA_DIR="${CMAKE_SOURCE_DIR}/krita/data/") endmacro() # overcome some platform incompatibilities if(WIN32) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/winquirks) add_definitions(-D_USE_MATH_DEFINES) add_definitions(-DNOMINMAX) set(WIN32_PLATFORM_NET_LIBS ws2_32.lib netapi32.lib) endif() # set custom krita plugin installdir if (ANDROID) # use default ABI if (NOT ANDROID_ABI) set (ANDROID_ABI armeabi-v7a) endif() set (ANDROID_SDK_ROOT $ENV{ANDROID_SDK_ROOT}) set (KRITA_PLUGIN_INSTALL_DIR ${LIB_INSTALL_DIR}) # set (DATA_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/assets) else() set (KRITA_PLUGIN_INSTALL_DIR ${LIB_INSTALL_DIR}/kritaplugins) endif() ########################### ############################ ## Required dependencies ## ############################ ########################### # FIXME: Still hardcoded if (ANDROID) set (Boost_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/i/${ANDROID_ABI}/include/boost-1_69) set (Boost_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/i/${ANDROID_ABI}/lib) set (KF5_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/kf5/kde/install/lib) endif() find_package(PNG REQUIRED) list (APPEND ANDROID_EXTRA_LIBS ${PNG_LIBRARY}) if (APPLE) # this is not added correctly on OSX -- see https://forum.kde.org/viewtopic.php?f=139&t=101867&p=221242#p221242 include_directories(SYSTEM ${PNG_INCLUDE_DIR}) endif() add_definitions(-DBOOST_ALL_NO_LIB) find_package(Boost 1.55 REQUIRED COMPONENTS system) include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) ## ## Test for GNU Scientific Library ## find_package(GSL) set_package_properties(GSL PROPERTIES URL "https://www.gnu.org/software/gsl" TYPE RECOMMENDED PURPOSE "Required by Krita's Transform tool.") macro_bool_to_01(GSL_FOUND HAVE_GSL) configure_file(config-gsl.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-gsl.h ) if (GSL_FOUND) list (APPEND ANDROID_EXTRA_LIBS ${GSL_LIBRARIES} ${GSL_CBLAS_LIBRARIES}) endif() ########################### ############################ ## Optional dependencies ## ############################ ########################### find_package(ZLIB) set_package_properties(ZLIB PROPERTIES DESCRIPTION "Compression library" URL "https://www.zlib.net/" TYPE OPTIONAL PURPOSE "Optionally used by the G'Mic and the PSD plugins") macro_bool_to_01(ZLIB_FOUND HAVE_ZLIB) find_package(OpenEXR) set_package_properties(OpenEXR PROPERTIES DESCRIPTION "High dynamic-range (HDR) image file format" URL "https://www.openexr.com" TYPE OPTIONAL PURPOSE "Required by the Krita OpenEXR filter") macro_bool_to_01(OPENEXR_FOUND HAVE_OPENEXR) set(LINK_OPENEXR_LIB) if(OPENEXR_FOUND) include_directories(SYSTEM ${OPENEXR_INCLUDE_DIRS}) set(LINK_OPENEXR_LIB ${OPENEXR_LIBRARIES}) add_definitions(${OPENEXR_DEFINITIONS}) endif() find_package(TIFF) set_package_properties(TIFF PROPERTIES DESCRIPTION "TIFF Library and Utilities" URL "http://www.libtiff.org" TYPE OPTIONAL PURPOSE "Required by the Krita TIFF filter") if (TIFF_FOUND) list (APPEND ANDROID_EXTRA_LIBS ${TIFF_LIBRARY}) endif() find_package(JPEG) set_package_properties(JPEG PROPERTIES DESCRIPTION "Free library for JPEG image compression. Note: libjpeg8 is NOT supported." URL "https://www.libjpeg-turbo.org" TYPE OPTIONAL PURPOSE "Required by the Krita JPEG filter") if (JPEG_FOUND) list (APPEND ANDROID_EXTRA_LIBS ${JPEG_LIBRARY}) endif() find_package(GIF) set_package_properties(GIF PROPERTIES DESCRIPTION "Library for loading and saving gif files." URL "http://giflib.sourceforge.net/" TYPE OPTIONAL PURPOSE "Required by the Krita GIF filter") if (GIF_FOUND) list (APPEND ANDROID_EXTRA_LIBS ${GIF_LIBRARY}) endif() find_package(HEIF "1.3.0") set_package_properties(HEIF PROPERTIES DESCRIPTION "Library for loading and saving heif files." URL "https://github.com/strukturag/libheif" TYPE OPTIONAL PURPOSE "Required by the Krita HEIF filter") find_package(OpenJPEG "2.3.0") set_package_properties(OpenJPEG PROPERTIES DESCRIPTION "Library for loading and saving jp2000 files." URL "https://www.openjpeg.org/" TYPE OPTIONAL PURPOSE "Required by the Krita JP2000 filter") set(LIBRAW_MIN_VERSION "0.16") find_package(LibRaw ${LIBRAW_MIN_VERSION}) set_package_properties(LibRaw PROPERTIES DESCRIPTION "Library to decode RAW images" URL "https://www.libraw.org/" TYPE OPTIONAL PURPOSE "Required to build the raw import plugin") find_package(FFTW3) set_package_properties(FFTW3 PROPERTIES DESCRIPTION "A fast, free C FFT library" URL "http://www.fftw.org/" TYPE OPTIONAL PURPOSE "Required by the Krita for fast convolution operators and some G'Mic features") macro_bool_to_01(FFTW3_FOUND HAVE_FFTW3) if (FFTW3_FOUND) list (APPEND ANDROID_EXTRA_LIBS ${FFTW3_LIBRARY}) endif() find_package(OCIO) set_package_properties(OCIO PROPERTIES DESCRIPTION "The OpenColorIO Library" URL "https://www.opencolorio.org" TYPE OPTIONAL PURPOSE "Required by the Krita LUT docker") macro_bool_to_01(OCIO_FOUND HAVE_OCIO) set_package_properties(PythonLibrary PROPERTIES DESCRIPTION "Python Library" URL "https://www.python.org" TYPE OPTIONAL PURPOSE "Required by the Krita PyQt plugin") macro_bool_to_01(PYTHONLIBS_FOUND HAVE_PYTHONLIBS) find_package(SIP "4.19.13") set_package_properties(SIP PROPERTIES DESCRIPTION "Support for generating SIP Python bindings" URL "https://www.riverbankcomputing.com/software/sip/download" TYPE OPTIONAL PURPOSE "Required by the Krita PyQt plugin") macro_bool_to_01(SIP_FOUND HAVE_SIP) find_package(PyQt5 "5.6.0") set_package_properties(PyQt5 PROPERTIES DESCRIPTION "Python bindings for Qt5." URL "https://www.riverbankcomputing.com/software/pyqt/download5" TYPE OPTIONAL PURPOSE "Required by the Krita PyQt plugin") macro_bool_to_01(PYQT5_FOUND HAVE_PYQT5) +find_package(LibMyPaint) +set_package_properties(LibMyPaint PROPERTIES + DESCRIPTION "MyPaint brush engine API for C/C++" + TYPE OPTIONAL + PURPOSE "Required for the mypaint brush engine") +if(LIBMYPAINT_VERSION VERSION_LESS "1.4.0") + message(WARNING "Please update libmypaint to version above 1.4.0 as lower versions are known to crash") +endif() ## ## Look for OpenGL ## # TODO: see if there is a better check for QtGui being built with opengl support (and thus the QOpenGL* classes) if(Qt5Gui_OPENGL_IMPLEMENTATION) message(STATUS "Found QtGui OpenGL support") else() message(FATAL_ERROR "Did NOT find QtGui OpenGL support. Check your Qt configuration. You cannot build Krita without Qt OpenGL support.") endif() ## ## Test for eigen3 ## find_package(Eigen3 3.0 REQUIRED) set_package_properties(Eigen3 PROPERTIES DESCRIPTION "C++ template library for linear algebra" URL "http://eigen.tuxfamily.org" TYPE REQUIRED) ## ## Test for exiv2 ## find_package(LibExiv2 0.16 REQUIRED) if (ANDROID) list (APPEND ANDROID_EXTRA_LIBS ${LibExiv2_LIBRARIES}) # because libexiv2 depends on libexpat and it is installed in the same folder get_filename_component (_base_dir ${LibExiv2_LIBRARIES} DIRECTORY) list (APPEND ANDROID_EXTRA_LIBS ${_base_dir}/libexpat.so) endif() ## ## Test for lcms ## find_package(LCMS2 2.4 REQUIRED) set_package_properties(LCMS2 PROPERTIES DESCRIPTION "LittleCMS Color management engine" URL "http://www.littlecms.com" TYPE REQUIRED PURPOSE "Will be used for color management and is necessary for Krita") if(LCMS2_FOUND) if(NOT ${LCMS2_VERSION} VERSION_LESS 2040 ) set(HAVE_LCMS24 TRUE) endif() set(HAVE_REQUIRED_LCMS_VERSION TRUE) set(HAVE_LCMS2 TRUE) endif() list (APPEND ANDROID_EXTRA_LIBS ${LCMS2_LIBRARIES}) ## ## Test for Vc ## set(OLD_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules ) set(HAVE_VC FALSE) if (NOT ${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm") if(NOT MSVC) find_package(Vc 1.1.0) set_package_properties(Vc PROPERTIES DESCRIPTION "Portable, zero-overhead SIMD library for C++" URL "https://github.com/VcDevel/Vc" TYPE OPTIONAL PURPOSE "Required by the Krita for vectorization") macro_bool_to_01(Vc_FOUND HAVE_VC) endif() endif() configure_file(config-vc.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-vc.h ) if(HAVE_VC) message(STATUS "Vc found!") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/vc") include (VcMacros) if(Vc_COMPILER_IS_CLANG) set(ADDITIONAL_VC_FLAGS "-ffp-contract=fast") if(NOT WIN32) set(ADDITIONAL_VC_FLAGS "${ADDITIONAL_VC_FLAGS} -fPIC") endif() elseif (NOT MSVC) set(ADDITIONAL_VC_FLAGS "-fabi-version=0 -ffp-contract=fast") if(NOT WIN32) set(ADDITIONAL_VC_FLAGS "${ADDITIONAL_VC_FLAGS} -fPIC") endif() endif() macro(ko_compile_for_all_implementations_no_scalar _objs _src) vc_compile_for_all_implementations(${_objs} ${_src} FLAGS ${ADDITIONAL_VC_FLAGS} ONLY SSE2 SSSE3 SSE4_1 AVX AVX2+FMA+BMI2) endmacro() macro(ko_compile_for_all_implementations _objs _src) vc_compile_for_all_implementations(${_objs} ${_src} FLAGS ${ADDITIONAL_VC_FLAGS} ONLY Scalar SSE2 SSSE3 SSE4_1 AVX AVX2+FMA+BMI2) endmacro() endif() set(CMAKE_MODULE_PATH ${OLD_CMAKE_MODULE_PATH} ) add_definitions(${QT_DEFINITIONS} ${QT_QTDBUS_DEFINITIONS}) ## ## Test endianness ## include (TestBigEndian) test_big_endian(CMAKE_WORDS_BIGENDIAN) ## ## Test for qt-poppler ## find_package(Poppler COMPONENTS Qt5) set_package_properties(Poppler PROPERTIES DESCRIPTION "A PDF rendering library" URL "https://poppler.freedesktop.org/" TYPE OPTIONAL PURPOSE "Required by the Krita PDF filter.") ## ## Test for quazip ## find_package(QuaZip 0.6) set_package_properties(QuaZip PROPERTIES DESCRIPTION "A library for reading and writing zip files" URL "https://stachenov.github.io/quazip/" TYPE REQUIRED PURPOSE "Needed for reading and writing KRA and ORA files" ) # FIXME: better way to do this? list (APPEND ANDROID_EXTRA_LIBS ${QUAZIP_LIBRARIES} ${EXPAT_LIBRARY} ${KF5_LIBRARIES}/libKF5Completion.so ${KF5_LIBRARIES}/libKF5WindowSystem.so ${KF5_LIBRARIES}/libKF5WidgetsAddons.so ${KF5_LIBRARIES}/libKF5ItemViews.so ${KF5_LIBRARIES}/libKF5ItemModels.so ${KF5_LIBRARIES}/libKF5GuiAddons.so ${KF5_LIBRARIES}/libKF5I18n.so ${KF5_LIBRARIES}/libKF5CoreAddons.so ${KF5_LIBRARIES}/libKF5ConfigGui.so ${KF5_LIBRARIES}/libKF5ConfigCore.so) ## ## Test for Atomics ## include(CheckAtomic) ############################ ############################# ## Add Krita helper macros ## ############################# ############################ include(MacroKritaAddBenchmark) #################### ##################### ## Define includes ## ##################### #################### # for config.h and includes (if any?) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/interfaces ) add_subdirectory(libs) add_subdirectory(plugins) if (BUILD_TESTING) add_subdirectory(benchmarks) endif() add_subdirectory(krita) configure_file(KoConfig.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/KoConfig.h ) configure_file(config_convolution.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config_convolution.h) configure_file(config-ocio.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-ocio.h ) check_function_exists(powf HAVE_POWF) configure_file(config-powf.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-powf.h) if(WIN32) include(${CMAKE_CURRENT_LIST_DIR}/packaging/windows/installer/ConfigureInstallerNsis.cmake) endif() message("\nBroken tests:") foreach(tst ${KRITA_BROKEN_TESTS}) message(" * ${tst}") endforeach() feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/po OR EXISTS ${CMAKE_CURRENT_BINARY_DIR}/po ) find_package(KF5I18n CONFIG REQUIRED) ki18n_install(po) endif() if(DEFINED QTANDROID_EXPORTED_TARGET AND NOT TARGET "create-apk") set (_CMAKE_ANDROID_DIR "${ECM_DIR}/../toolchain") list(LENGTH QTANDROID_EXPORTED_TARGET targetsCount) include(${_CMAKE_ANDROID_DIR}/ECMAndroidDeployQt.cmake) math(EXPR last "${targetsCount}-1") foreach(idx RANGE 0 ${last}) list(GET QTANDROID_EXPORTED_TARGET ${idx} exportedTarget) list(GET ANDROID_APK_DIR ${idx} APK_DIR) if(APK_DIR AND NOT EXISTS "${ANDROID_APK_DIR}/AndroidManifest.xml" AND IS_ABSOLUTE ANDROID_APK_DIR) message(FATAL_ERROR "Cannot find ${APK_DIR}/AndroidManifest.xml according to ANDROID_APK_DIR. ${ANDROID_APK_DIR} ${exportedTarget}") elseif(NOT APK_DIR) get_filename_component(_qt5Core_install_prefix "${Qt5Core_DIR}/../../../" ABSOLUTE) set(APK_DIR "${_qt5Core_install_prefix}/src/android/templates/") endif() ecm_androiddeployqt("${exportedTarget}" "${ECM_ADDITIONAL_FIND_ROOT_PATH}") set_target_properties(create-apk-${exportedTarget} PROPERTIES ANDROID_APK_DIR "${APK_DIR}") endforeach() elseif(ANDROID) message(STATUS "You can export a target by specifying -DQTANDROID_EXPORTED_TARGET= and -DANDROID_APK_DIR=") endif() diff --git a/cmake/modules/FindLibMyPaint.cmake b/cmake/modules/FindLibMyPaint.cmake new file mode 100644 index 0000000000..cd2736dc4c --- /dev/null +++ b/cmake/modules/FindLibMyPaint.cmake @@ -0,0 +1,27 @@ +#For finding LibMyPaint library in the system + +include(LibFindMacros) +libfind_pkg_check_modules(MYPAINT_PKGCONF libmypaint) + +find_path(LIBMYPAINT_INCLUDE_DIR + NAMES mypaint-config.h + /usr/include + /usr/local/include + /sw/include + /opt/local/include + ${MYPAINT_PKGCONF_INCLUDE_DIRS} + ${MYPAINT_PKGCONF_INCLUDEDIR} + PATH_SUFFIXES libmypaint +) + +find_library(LIBMYPAINT_LIBRARY + NAMES libmypaint mypaint + HINTS ${MYPAINT_PKGCONF_LIBRARY_DIRS} ${MYPAINT_PKGCONF_LIBDIR} + DOC "Libraries to link against for mypaint brush engine Support" +) + +string(REGEX MATCH "(.*)/libmypaint.so" LIBMYPAINT_LIBRARIES ${LIBMYPAINT_LIBRARY}) + +set(LIBMYPAINT_LIBRARIES ${CMAKE_MATCH_1}) +set(LIBMYPAINT_FOUND ${MYPAINT_PKGCONF_FOUND}) +set(LIBMYPAINT_VERSION ${MYPAINT_PKGCONF_VERSION}) diff --git a/krita/pics/paintops/mypaintbrush.png b/krita/pics/paintops/mypaintbrush.png new file mode 100644 index 0000000000..af5f166d19 Binary files /dev/null and b/krita/pics/paintops/mypaintbrush.png differ diff --git a/krita/pics/paintops/paintops-icons.qrc b/krita/pics/paintops/paintops-icons.qrc index 535ed480f5..968c88f82b 100644 --- a/krita/pics/paintops/paintops-icons.qrc +++ b/krita/pics/paintops/paintops-icons.qrc @@ -1,37 +1,38 @@ dark_bristlebrush.svg dark_clonebrush.svg dark_colorsmudge.svg dark_curvebrush.svg dark_deformbrush.svg dark_dynabrush.svg dark_filterbrush.svg dark_gridbrush.svg dark_hatchingbrush.svg dark_particlebrush.svg dark_pixelbrush.svg dark_quickbrush.svg dark_shapebrush.svg dark_sketchbrush.svg dark_spraybrush.svg dark_tangentnormal.svg light_bristlebrush.svg light_clonebrush.svg light_colorsmudge.svg light_curvebrush.svg light_deformbrush.svg light_dynabrush.svg light_filterbrush.svg light_gridbrush.svg light_hatchingbrush.svg light_particlebrush.svg light_pixelbrush.svg light_quickbrush.svg light_shapebrush.svg light_sketchbrush.svg light_spraybrush.svg light_tangentnormal.svg + mypaintbrush.png diff --git a/libs/global/KisUsageLogger.cpp b/libs/global/KisUsageLogger.cpp index 4f6b6a5eea..d1303060e8 100644 --- a/libs/global/KisUsageLogger.cpp +++ b/libs/global/KisUsageLogger.cpp @@ -1,259 +1,259 @@ /* * Copyright (c) 2019 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "KisUsageLogger.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include Q_GLOBAL_STATIC(KisUsageLogger, s_instance) const QString KisUsageLogger::s_sectionHeader("================================================================================\n"); struct KisUsageLogger::Private { bool active {false}; QFile logFile; QFile sysInfoFile; }; KisUsageLogger::KisUsageLogger() : d(new Private) { d->logFile.setFileName(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/krita.log"); d->sysInfoFile.setFileName(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/krita-sysinfo.log"); rotateLog(); d->logFile.open(QFile::Append | QFile::Text); d->sysInfoFile.open(QFile::WriteOnly | QFile::Text); } KisUsageLogger::~KisUsageLogger() { if (d->active) { close(); } } void KisUsageLogger::initialize() { s_instance->d->active = true; QString systemInfo = basicSystemInfo(); s_instance->d->sysInfoFile.write(systemInfo.toUtf8()); } QString KisUsageLogger::basicSystemInfo() { QString systemInfo; // NOTE: This is intentionally not translated! // Krita version info systemInfo.append("Krita\n"); systemInfo.append("\n Version: ").append(KritaVersionWrapper::versionString(true)); systemInfo.append("\n Languages: ").append(KLocalizedString::languages().join(", ")); systemInfo.append("\n Hidpi: ").append(QCoreApplication::testAttribute(Qt::AA_EnableHighDpiScaling) ? "true" : "false"); systemInfo.append("\n\n"); systemInfo.append("Qt\n"); systemInfo.append("\n Version (compiled): ").append(QT_VERSION_STR); systemInfo.append("\n Version (loaded): ").append(qVersion()); systemInfo.append("\n\n"); // OS information systemInfo.append("OS Information\n"); systemInfo.append("\n Build ABI: ").append(QSysInfo::buildAbi()); systemInfo.append("\n Build CPU: ").append(QSysInfo::buildCpuArchitecture()); systemInfo.append("\n CPU: ").append(QSysInfo::currentCpuArchitecture()); systemInfo.append("\n Kernel Type: ").append(QSysInfo::kernelType()); systemInfo.append("\n Kernel Version: ").append(QSysInfo::kernelVersion()); systemInfo.append("\n Pretty Productname: ").append(QSysInfo::prettyProductName()); systemInfo.append("\n Product Type: ").append(QSysInfo::productType()); systemInfo.append("\n Product Version: ").append(QSysInfo::productVersion()); #ifdef Q_OS_LINUX systemInfo.append("\n Desktop: ").append(qgetenv("XDG_CURRENT_DESKTOP")); #endif systemInfo.append("\n\n"); return systemInfo; } void KisUsageLogger::close() { log("CLOSING SESSION"); s_instance->d->active = false; s_instance->d->logFile.flush(); s_instance->d->logFile.close(); s_instance->d->sysInfoFile.flush(); s_instance->d->sysInfoFile.close(); } void KisUsageLogger::log(const QString &message) { if (!s_instance->d->active) return; if (!s_instance->d->logFile.isOpen()) return; s_instance->d->logFile.write(QDateTime::currentDateTime().toString(Qt::RFC2822Date).toUtf8()); s_instance->d->logFile.write(": "); write(message); } void KisUsageLogger::write(const QString &message) { if (!s_instance->d->active) return; if (!s_instance->d->logFile.isOpen()) return; s_instance->d->logFile.write(message.toUtf8()); s_instance->d->logFile.write("\n"); s_instance->d->logFile.flush(); } void KisUsageLogger::writeSysInfo(const QString &message) { if (!s_instance->d->active) return; if (!s_instance->d->sysInfoFile.isOpen()) return; s_instance->d->sysInfoFile.write(message.toUtf8()); s_instance->d->sysInfoFile.write("\n"); s_instance->d->sysInfoFile.flush(); } void KisUsageLogger::writeHeader() { - Q_ASSERT(s_instance->d->sysInfoFile.isOpen()); +// Q_ASSERT(s_instance->d->sysInfoFile.isOpen()); s_instance->d->logFile.write(s_sectionHeader.toUtf8()); QString sessionHeader = QString("SESSION: %1. Executing %2\n\n") .arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date)) .arg(qApp->arguments().join(' ')); s_instance->d->logFile.write(sessionHeader.toUtf8()); QString KritaAndQtVersion; KritaAndQtVersion.append("Krita Version: ").append(KritaVersionWrapper::versionString(true)) .append(", Qt version compiled: ").append(QT_VERSION_STR) .append(", loaded: ").append(qVersion()) .append(". Process ID: ") .append(QString::number(qApp->applicationPid())).append("\n"); KritaAndQtVersion.append("-- -- -- -- -- -- -- --\n"); s_instance->d->logFile.write(KritaAndQtVersion.toUtf8()); s_instance->d->logFile.flush(); log(QString("Style: %1. Available styles: %2") .arg(qApp->style()->objectName(), QStyleFactory::keys().join(", "))); } QString KisUsageLogger::screenInformation() { QList screens = qApp->screens(); QString info; info.append("Display Information"); info.append("\nNumber of screens: ").append(QString::number(screens.size())); for (int i = 0; i < screens.size(); ++i ) { QScreen *screen = screens[i]; info.append("\n\tScreen: ").append(QString::number(i)); info.append("\n\t\tName: ").append(screen->name()); info.append("\n\t\tDepth: ").append(QString::number(screen->depth())); info.append("\n\t\tScale: ").append(QString::number(screen->devicePixelRatio())); info.append("\n\t\tResolution in pixels: ").append(QString::number(screen->geometry().width())) .append("x") .append(QString::number(screen->geometry().height())); info.append("\n\t\tManufacturer: ").append(screen->manufacturer()); info.append("\n\t\tModel: ").append(screen->model()); info.append("\n\t\tRefresh Rate: ").append(QString::number(screen->refreshRate())); } info.append("\n"); return info; } void KisUsageLogger::rotateLog() { if (d->logFile.exists()) { { // Check for CLOSING SESSION d->logFile.open(QFile::ReadOnly); QString log = QString::fromUtf8(d->logFile.readAll()); if (!log.split(s_sectionHeader).last().contains("CLOSING SESSION")) { log.append("\nKRITA DID NOT CLOSE CORRECTLY\n"); QString crashLog = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QStringLiteral("/kritacrash.log"); if (QFileInfo(crashLog).exists()) { QFile f(crashLog); f.open(QFile::ReadOnly); QString crashes = QString::fromUtf8(f.readAll()); f.close(); QStringList crashlist = crashes.split("-------------------"); log.append(QString("\nThere were %1 crashes in total in the crash log.\n").arg(crashlist.size())); if (crashes.size() > 0) { log.append(crashlist.last()); } } d->logFile.close(); d->logFile.open(QFile::WriteOnly); d->logFile.write(log.toUtf8()); } d->logFile.flush(); d->logFile.close(); } { // Rotate d->logFile.open(QFile::ReadOnly); QString log = QString::fromUtf8(d->logFile.readAll()); int sectionCount = log.count(s_sectionHeader); int nextSectionIndex = log.indexOf(s_sectionHeader, s_sectionHeader.length()); while(sectionCount >= s_maxLogs) { log = log.remove(0, log.indexOf(s_sectionHeader, nextSectionIndex)); nextSectionIndex = log.indexOf(s_sectionHeader, s_sectionHeader.length()); sectionCount = log.count(s_sectionHeader); } d->logFile.close(); d->logFile.open(QFile::WriteOnly); d->logFile.write(log.toUtf8()); d->logFile.flush(); d->logFile.close(); } } } diff --git a/libs/image/brushengine/kis_paintop_preset.cpp b/libs/image/brushengine/kis_paintop_preset.cpp index 59d3f0aa2c..fe0843c16a 100644 --- a/libs/image/brushengine/kis_paintop_preset.cpp +++ b/libs/image/brushengine/kis_paintop_preset.cpp @@ -1,425 +1,428 @@ /* This file is part of the KDE project * Copyright (C) Boudewijn Rempt , (C) 2008 * Copyright (C) Sven Langkamp , (C) 2009 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include "kis_paintop_registry.h" #include "kis_painter.h" #include #include "kis_paint_device.h" #include "kis_image.h" #include "kis_paintop_settings_update_proxy.h" #include #include struct Q_DECL_HIDDEN KisPaintOpPreset::Private { Private() : settings(0), dirtyPreset(false) { } KisPaintOpSettingsSP settings; bool dirtyPreset; QScopedPointer updateProxy; }; KisPaintOpPreset::KisPaintOpPreset() : KoResource(QString()) , m_d(new Private) { } KisPaintOpPreset::KisPaintOpPreset(const QString & fileName) : KoResource(fileName) , m_d(new Private) { } KisPaintOpPreset::~KisPaintOpPreset() { delete m_d; } KisPaintOpPresetSP KisPaintOpPreset::clone() const { KisPaintOpPresetSP preset(new KisPaintOpPreset()); if (settings()) { preset->setSettings(settings()); // the settings are cloned inside! } preset->setDirty(isDirty()); // only valid if we could clone the settings preset->setValid(settings()); preset->setPaintOp(paintOp()); preset->setName(name()); preset->setImage(image()); preset->settings()->setPreset(KisPaintOpPresetWSP(preset)); Q_ASSERT(preset->valid()); return preset; } void KisPaintOpPreset::setDirty(bool value) { m_d->dirtyPreset = value; } bool KisPaintOpPreset::isDirty() const { return m_d->dirtyPreset; } void KisPaintOpPreset::setPaintOp(const KoID & paintOp) { Q_ASSERT(m_d->settings); m_d->settings->setProperty("paintop", paintOp.id()); } KoID KisPaintOpPreset::paintOp() const { Q_ASSERT(m_d->settings); return KoID(m_d->settings->getString("paintop")); } void KisPaintOpPreset::setOptionsWidget(KisPaintOpConfigWidget* widget) { if (m_d->settings) { m_d->settings->setOptionsWidget(widget); if (widget) { widget->setConfigurationSafe(m_d->settings); } } } void KisPaintOpPreset::setSettings(KisPaintOpSettingsSP settings) { Q_ASSERT(settings); Q_ASSERT(!settings->getString("paintop", QString()).isEmpty()); DirtyStateSaver dirtyStateSaver(this); KisPaintOpConfigWidget *oldOptionsWidget = 0; if (m_d->settings) { oldOptionsWidget = m_d->settings->optionsWidget(); m_d->settings->setOptionsWidget(0); m_d->settings->setPreset(0); m_d->settings = 0; } if (settings) { m_d->settings = settings->clone(); m_d->settings->setPreset(KisPaintOpPresetWSP(this)); if (oldOptionsWidget) { oldOptionsWidget->setConfigurationSafe(m_d->settings); m_d->settings->setOptionsWidget(oldOptionsWidget); } } setValid(m_d->settings); if (m_d->updateProxy) { m_d->updateProxy->notifyUniformPropertiesChanged(); m_d->updateProxy->notifySettingsChanged(); } } KisPaintOpSettingsSP KisPaintOpPreset::settings() const { Q_ASSERT(m_d->settings); Q_ASSERT(!m_d->settings->getString("paintop", QString()).isEmpty()); return m_d->settings; } bool KisPaintOpPreset::load() { dbgImage << "Load preset " << filename(); setValid(false); if (filename().isEmpty()) { return false; } QIODevice *dev = 0; QByteArray ba; if (filename().startsWith("bundle://")) { QString bn = filename().mid(9); int pos = bn.lastIndexOf(":"); QString fn = bn.right(bn.size() - pos - 1); bn = bn.left(pos); QScopedPointer resourceStore(KoStore::createStore(bn, KoStore::Read, "application/x-krita-resourcebundle", KoStore::Zip)); if (!resourceStore || resourceStore->bad()) { warnKrita << "Could not open store on bundle" << bn; return false; } if (resourceStore->isOpen()) resourceStore->close(); if (!resourceStore->open(fn)) { warnKrita << "Could not open preset" << fn << "in bundle" << bn; return false; } ba = resourceStore->device()->readAll(); dev = new QBuffer(&ba); resourceStore->close(); } else { dev = new QFile(filename()); if (dev->size() == 0) { delete dev; return false; } if (!dev->open(QIODevice::ReadOnly)) { warnKrita << "Can't open file " << filename(); delete dev; return false; } } - bool res = loadFromDevice(dev); + bool res = false; + + res = loadFromDevice(dev); + delete dev; setValid(res); setDirty(false); return res; } bool KisPaintOpPreset::loadFromDevice(QIODevice *dev) { QImageReader reader(dev, "PNG"); QString version = reader.text("version"); QString preset = reader.text("preset"); dbgImage << version; if (version != "2.2") { return false; } QImage img; if (!reader.read(&img)) { dbgImage << "Fail to decode PNG"; return false; } //Workaround for broken presets //Presets was saved with nested cdata section preset.replace(""); preset.replace("]]>", ""); QDomDocument doc; if (!doc.setContent(preset)) { return false; } fromXML(doc.documentElement()); if (!m_d->settings) { return false; } setValid(true); setImage(img); return true; } bool KisPaintOpPreset::save() { if (filename().isEmpty()) return false; QString paintopid = m_d->settings->getString("paintop", QString()); if (paintopid.isEmpty()) return false; QFile f(filename()); f.open(QFile::WriteOnly); return saveToDevice(&f); } void KisPaintOpPreset::toXML(QDomDocument& doc, QDomElement& elt) const { QString paintopid = m_d->settings->getString("paintop", QString()); elt.setAttribute("paintopid", paintopid); elt.setAttribute("name", name()); // sanitize the settings bool hasTexture = m_d->settings->getBool("Texture/Pattern/Enabled"); if (!hasTexture) { Q_FOREACH (const QString & key, m_d->settings->getProperties().keys()) { if (key.startsWith("Texture") && key != "Texture/Pattern/Enabled") { m_d->settings->removeProperty(key); } } } m_d->settings->toXML(doc, elt); } void KisPaintOpPreset::fromXML(const QDomElement& presetElt) { setName(presetElt.attribute("name")); QString paintopid = presetElt.attribute("paintopid"); if (paintopid.isEmpty()) { dbgImage << "No paintopid attribute"; setValid(false); return; } if (KisPaintOpRegistry::instance()->get(paintopid) == 0) { dbgImage << "No paintop " << paintopid; setValid(false); return; } KoID id(paintopid, QString()); KisPaintOpSettingsSP settings = KisPaintOpRegistry::instance()->settings(id); if (!settings) { setValid(false); warnKrita << "Could not load settings for preset" << paintopid; return; } settings->fromXML(presetElt); // sanitize the settings bool hasTexture = settings->getBool("Texture/Pattern/Enabled"); if (!hasTexture) { Q_FOREACH (const QString & key, settings->getProperties().keys()) { if (key.startsWith("Texture") && key != "Texture/Pattern/Enabled") { settings->removeProperty(key); } } } setSettings(settings); } bool KisPaintOpPreset::saveToDevice(QIODevice *dev) const { QImageWriter writer(dev, "PNG"); QDomDocument doc; QDomElement root = doc.createElement("Preset"); toXML(doc, root); doc.appendChild(root); writer.setText("version", "2.2"); writer.setText("preset", doc.toString()); QImage img; if (image().isNull()) { img = QImage(1, 1, QImage::Format_RGB32); } else { img = image(); } m_d->dirtyPreset = false; KoResource::saveToDevice(dev); return writer.write(img); } KisPaintopSettingsUpdateProxy* KisPaintOpPreset::updateProxy() const { if (!m_d->updateProxy) { m_d->updateProxy.reset(new KisPaintopSettingsUpdateProxy()); } return m_d->updateProxy.data(); } KisPaintopSettingsUpdateProxy* KisPaintOpPreset::updateProxyNoCreate() const { return m_d->updateProxy.data(); } QList KisPaintOpPreset::uniformProperties() { return m_d->settings->uniformProperties(m_d->settings); } bool KisPaintOpPreset::hasMaskingPreset() const { return m_d->settings && m_d->settings->hasMaskingSettings(); } KisPaintOpPresetSP KisPaintOpPreset::createMaskingPreset() const { KisPaintOpPresetSP result; if (m_d->settings && m_d->settings->hasMaskingSettings()) { result = new KisPaintOpPreset(); result->setSettings(m_d->settings->createMaskingSettings()); if (!result->valid()) { result.clear(); } } return result; } KisPaintOpPreset::UpdatedPostponer::UpdatedPostponer(KisPaintOpPreset *preset) : m_updateProxy(preset->updateProxyNoCreate()) { if (m_updateProxy) { m_updateProxy->postponeSettingsChanges(); } } KisPaintOpPreset::UpdatedPostponer::~UpdatedPostponer() { if (m_updateProxy) { m_updateProxy->unpostponeSettingsChanges(); } } diff --git a/libs/ui/KisApplication.cpp b/libs/ui/KisApplication.cpp index e269e61ac6..dd815eaed6 100644 --- a/libs/ui/KisApplication.cpp +++ b/libs/ui/KisApplication.cpp @@ -1,972 +1,973 @@ /* * Copyright (C) 1998, 1999 Torben Weis * Copyright (C) 2012 Boudewijn Rempt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KisApplication.h" #include #ifdef Q_OS_WIN #include #include #endif #ifdef Q_OS_MACOS #include "osx.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "KoConfig.h" #include #include #include #include "thememanager.h" #include "KisPrintJob.h" #include "KisDocument.h" #include "KisMainWindow.h" #include "KisAutoSaveRecoveryDialog.h" #include "KisPart.h" #include #include "kis_md5_generator.h" #include "kis_splash_screen.h" #include "kis_config.h" #include "flake/kis_shape_selection.h" #include #include #include #include #include #include #include #include "kisexiv2/kis_exiv2.h" #include "KisApplicationArguments.h" #include #include "kis_action_registry.h" #include #include #include #include "kis_image_barrier_locker.h" #include "opengl/kis_opengl.h" #include "kis_spin_box_unit_manager.h" #include "kis_document_aware_spin_box_unit_manager.h" #include "KisViewManager.h" #include "kis_workspace_resource.h" #include #include #include #include "widgets/KisScreenColorPicker.h" #include "KisDlgInternalColorSelector.h" #include #include #include "kis_file_layer.h" #include "kis_group_layer.h" #include "kis_node_commands_adapter.h" namespace { const QTime appStartTime(QTime::currentTime()); } class KisApplication::Private { public: Private() {} QPointer splashScreen; KisAutoSaveRecoveryDialog *autosaveDialog {0}; QPointer mainWindow; // The first mainwindow we create on startup bool batchRun {false}; QVector earlyRemoteArguments; }; class KisApplication::ResetStarting { public: ResetStarting(KisSplashScreen *splash, int fileCount) : m_splash(splash) , m_fileCount(fileCount) { } ~ResetStarting() { if (m_splash) { m_splash->hide(); } } QPointer m_splash; int m_fileCount; }; KisApplication::KisApplication(const QString &key, int &argc, char **argv) : QtSingleApplication(key, argc, argv) , d(new Private) { #ifdef Q_OS_MACOS setMouseCoalescingEnabled(false); #endif QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath()); setApplicationDisplayName("Krita"); setApplicationName("krita"); // Note: Qt docs suggest we set this, but if we do, we get resource paths of the form of krita/krita, which is weird. // setOrganizationName("krita"); setOrganizationDomain("krita.org"); QString version = KritaVersionWrapper::versionString(true); setApplicationVersion(version); setWindowIcon(KisIconUtils::loadIcon("krita")); if (qgetenv("KRITA_NO_STYLE_OVERRIDE").isEmpty()) { QStringList styles = QStringList() << "breeze" << "fusion" << "plastique"; if (!styles.contains(style()->objectName().toLower())) { Q_FOREACH (const QString & style, styles) { if (!setStyle(style)) { qDebug() << "No" << style << "available."; } else { qDebug() << "Set style" << style; break; } } } } else { qDebug() << "Style override disabled, using" << style()->objectName(); } } #if defined(Q_OS_WIN) && defined(ENV32BIT) typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); LPFN_ISWOW64PROCESS fnIsWow64Process; BOOL isWow64() { BOOL bIsWow64 = FALSE; //IsWow64Process is not available on all supported versions of Windows. //Use GetModuleHandle to get a handle to the DLL that contains the function //and GetProcAddress to get a pointer to the function if available. fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress( GetModuleHandle(TEXT("kernel32")),"IsWow64Process"); if(0 != fnIsWow64Process) { if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) { //handle error } } return bIsWow64; } #endif void KisApplication::initializeGlobals(const KisApplicationArguments &args) { int dpiX = args.dpiX(); int dpiY = args.dpiY(); if (dpiX > 0 && dpiY > 0) { KoDpi::setDPI(dpiX, dpiY); } } void KisApplication::addResourceTypes() { // qDebug() << "addResourceTypes();"; // All Krita's resource types KoResourcePaths::addResourceType("markers", "data", "/styles/"); KoResourcePaths::addResourceType("kis_pics", "data", "/pics/"); KoResourcePaths::addResourceType("kis_images", "data", "/images/"); KoResourcePaths::addResourceType("metadata_schema", "data", "/metadata/schemas/"); KoResourcePaths::addResourceType("kis_brushes", "data", "/brushes/"); + KoResourcePaths::addResourceType("mypaint_brushes", "data", "/mypaint-data/"); KoResourcePaths::addResourceType("kis_taskset", "data", "/taskset/"); KoResourcePaths::addResourceType("kis_taskset", "data", "/taskset/"); KoResourcePaths::addResourceType("gmic_definitions", "data", "/gmic/"); KoResourcePaths::addResourceType("kis_resourcebundles", "data", "/bundles/"); KoResourcePaths::addResourceType("kis_defaultpresets", "data", "/defaultpresets/"); KoResourcePaths::addResourceType("kis_paintoppresets", "data", "/paintoppresets/"); KoResourcePaths::addResourceType("kis_workspaces", "data", "/workspaces/"); KoResourcePaths::addResourceType("kis_windowlayouts", "data", "/windowlayouts/"); KoResourcePaths::addResourceType("kis_sessions", "data", "/sessions/"); KoResourcePaths::addResourceType("psd_layer_style_collections", "data", "/asl"); KoResourcePaths::addResourceType("ko_patterns", "data", "/patterns/", true); KoResourcePaths::addResourceType("ko_gradients", "data", "/gradients/"); KoResourcePaths::addResourceType("ko_gradients", "data", "/gradients/", true); KoResourcePaths::addResourceType("ko_palettes", "data", "/palettes/", true); KoResourcePaths::addResourceType("kis_shortcuts", "data", "/shortcuts/"); KoResourcePaths::addResourceType("kis_actions", "data", "/actions"); KoResourcePaths::addResourceType("kis_actions", "data", "/pykrita"); KoResourcePaths::addResourceType("icc_profiles", "data", "/color/icc"); KoResourcePaths::addResourceType("icc_profiles", "data", "/profiles/"); KoResourcePaths::addResourceType("ko_effects", "data", "/effects/"); KoResourcePaths::addResourceType("tags", "data", "/tags/"); KoResourcePaths::addResourceType("templates", "data", "/templates"); KoResourcePaths::addResourceType("pythonscripts", "data", "/pykrita"); KoResourcePaths::addResourceType("symbols", "data", "/symbols"); KoResourcePaths::addResourceType("preset_icons", "data", "/preset_icons"); KoResourcePaths::addResourceType("ko_gamutmasks", "data", "/gamutmasks/", true); // // Extra directories to look for create resources. (Does anyone actually use that anymore?) // KoResourcePaths::addResourceDir("ko_gradients", "/usr/share/create/gradients/gimp"); // KoResourcePaths::addResourceDir("ko_gradients", QDir::homePath() + QString("/.create/gradients/gimp")); // KoResourcePaths::addResourceDir("ko_patterns", "/usr/share/create/patterns/gimp"); // KoResourcePaths::addResourceDir("ko_patterns", QDir::homePath() + QString("/.create/patterns/gimp")); // KoResourcePaths::addResourceDir("kis_brushes", "/usr/share/create/brushes/gimp"); // KoResourcePaths::addResourceDir("kis_brushes", QDir::homePath() + QString("/.create/brushes/gimp")); // KoResourcePaths::addResourceDir("ko_palettes", "/usr/share/create/swatches"); // KoResourcePaths::addResourceDir("ko_palettes", QDir::homePath() + QString("/.create/swatches")); // Make directories for all resources we can save, and tags QDir d; d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/tags/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/asl/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/bundles/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/brushes/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/gradients/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/paintoppresets/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/palettes/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/patterns/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/taskset/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/workspaces/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/input/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/pykrita/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/symbols/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/color-schemes/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/preset_icons/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/preset_icons/tool_icons/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/preset_icons/emblem_icons/"); d.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/gamutmasks/"); } void KisApplication::loadResources() { // qDebug() << "loadResources();"; setSplashScreenLoadingText(i18n("Loading Resources...")); processEvents(); KoResourceServerProvider::instance(); setSplashScreenLoadingText(i18n("Loading Brush Presets...")); processEvents(); KisResourceServerProvider::instance(); setSplashScreenLoadingText(i18n("Loading Brushes...")); processEvents(); KisBrushServer::instance()->brushServer(); setSplashScreenLoadingText(i18n("Loading Bundles...")); processEvents(); KisResourceBundleServerProvider::instance(); } void KisApplication::loadResourceTags() { // qDebug() << "loadResourceTags()"; KoResourceServerProvider::instance()->patternServer()->loadTags(); KoResourceServerProvider::instance()->gradientServer()->loadTags(); KoResourceServerProvider::instance()->paletteServer()->loadTags(); KoResourceServerProvider::instance()->svgSymbolCollectionServer()->loadTags(); KisBrushServer::instance()->brushServer()->loadTags(); KisResourceServerProvider::instance()->workspaceServer()->loadTags(); KisResourceServerProvider::instance()->layerStyleCollectionServer()->loadTags(); KisResourceBundleServerProvider::instance()->resourceBundleServer()->loadTags(); KisResourceServerProvider::instance()->paintOpPresetServer()->loadTags(); KisResourceServerProvider::instance()->paintOpPresetServer()->clearOldSystemTags(); } void KisApplication::loadPlugins() { // qDebug() << "loadPlugins();"; KoShapeRegistry* r = KoShapeRegistry::instance(); r->add(new KisShapeSelectionFactory()); KoColorSpaceRegistry::instance(); KisActionRegistry::instance(); KisFilterRegistry::instance(); KisGeneratorRegistry::instance(); KisPaintOpRegistry::instance(); KoToolRegistry::instance(); KoDockRegistry::instance(); } void KisApplication::loadGuiPlugins() { // XXX_EXIV: make the exiv io backends real plugins setSplashScreenLoadingText(i18n("Loading Plugins Exiv/IO...")); processEvents(); // qDebug() << "loading exiv2"; KisExiv2::initialize(); } bool KisApplication::start(const KisApplicationArguments &args) { KisConfig cfg(false); #if defined(Q_OS_WIN) #ifdef ENV32BIT if (isWow64() && !cfg.readEntry("WarnedAbout32Bits", false)) { QMessageBox::information(0, i18nc("@title:window", "Krita: Warning"), i18n("You are running a 32 bits build on a 64 bits Windows.\n" "This is not recommended.\n" "Please download and install the x64 build instead.")); cfg.writeEntry("WarnedAbout32Bits", true); } #endif #endif QString opengl = cfg.canvasState(); if (opengl == "OPENGL_NOT_TRIED" ) { cfg.setCanvasState("TRY_OPENGL"); } else if (opengl != "OPENGL_SUCCESS" && opengl != "TRY_OPENGL") { cfg.setCanvasState("OPENGL_FAILED"); } setSplashScreenLoadingText(i18n("Initializing Globals")); processEvents(); initializeGlobals(args); const bool doNewImage = args.doNewImage(); const bool doTemplate = args.doTemplate(); const bool exportAs = args.exportAs(); const bool exportSequence = args.exportSequence(); const QString exportFileName = args.exportFileName(); d->batchRun = (exportAs || exportSequence || !exportFileName.isEmpty()); const bool needsMainWindow = (!exportAs && !exportSequence); // only show the mainWindow when no command-line mode option is passed bool showmainWindow = (!exportAs && !exportSequence); // would be !batchRun; const bool showSplashScreen = !d->batchRun && qEnvironmentVariableIsEmpty("NOSPLASH"); if (showSplashScreen && d->splashScreen) { d->splashScreen->show(); d->splashScreen->repaint(); processEvents(); } KoHashGeneratorProvider::instance()->setGenerator("MD5", new KisMD5Generator()); KConfigGroup group(KSharedConfig::openConfig(), "theme"); Digikam::ThemeManager themeManager; themeManager.setCurrentTheme(group.readEntry("Theme", "Krita dark")); ResetStarting resetStarting(d->splashScreen, args.filenames().count()); // remove the splash when done Q_UNUSED(resetStarting); // Make sure we can save resources and tags setSplashScreenLoadingText(i18n("Adding resource types")); processEvents(); addResourceTypes(); // Load the plugins loadPlugins(); // Load all resources loadResources(); // Load all the tags loadResourceTags(); // Load the gui plugins loadGuiPlugins(); KisPart *kisPart = KisPart::instance(); if (needsMainWindow) { // show a mainWindow asap, if we want that setSplashScreenLoadingText(i18n("Loading Main Window...")); processEvents(); bool sessionNeeded = true; auto sessionMode = cfg.sessionOnStartup(); if (!args.session().isEmpty()) { sessionNeeded = !kisPart->restoreSession(args.session()); } else if (sessionMode == KisConfig::SOS_ShowSessionManager) { showmainWindow = false; sessionNeeded = false; kisPart->showSessionManager(); } else if (sessionMode == KisConfig::SOS_PreviousSession) { KConfigGroup sessionCfg = KSharedConfig::openConfig()->group("session"); const QString &sessionName = sessionCfg.readEntry("previousSession"); sessionNeeded = !kisPart->restoreSession(sessionName); } if (sessionNeeded) { kisPart->startBlankSession(); } if (!args.windowLayout().isEmpty()) { KoResourceServer * rserver = KisResourceServerProvider::instance()->windowLayoutServer(); KisWindowLayoutResource* windowLayout = rserver->resourceByName(args.windowLayout()); if (windowLayout) { windowLayout->applyLayout(); } } if (showmainWindow) { d->mainWindow = kisPart->currentMainwindow(); if (!args.workspace().isEmpty()) { KoResourceServer * rserver = KisResourceServerProvider::instance()->workspaceServer(); KisWorkspaceResource* workspace = rserver->resourceByName(args.workspace()); if (workspace) { d->mainWindow->restoreWorkspace(workspace); } } if (args.canvasOnly()) { d->mainWindow->viewManager()->switchCanvasOnly(true); } if (args.fullScreen()) { d->mainWindow->showFullScreen(); } } else { d->mainWindow = kisPart->createMainWindow(); } } short int numberOfOpenDocuments = 0; // number of documents open // Check for autosave files that can be restored, if we're not running a batchrun (test) if (!d->batchRun) { checkAutosaveFiles(); } setSplashScreenLoadingText(QString()); // done loading, so clear out label processEvents(); //configure the unit manager KisSpinBoxUnitManagerFactory::setDefaultUnitManagerBuilder(new KisDocumentAwareSpinBoxUnitManagerBuilder()); connect(this, &KisApplication::aboutToQuit, &KisSpinBoxUnitManagerFactory::clearUnitManagerBuilder); //ensure the builder is destroyed when the application leave. //the new syntax slot syntax allow to connect to a non q_object static method. // Create a new image, if needed if (doNewImage) { KisDocument *doc = args.createDocumentFromArguments(); if (doc) { kisPart->addDocument(doc); d->mainWindow->addViewAndNotifyLoadingCompleted(doc); } } // Get the command line arguments which we have to parse int argsCount = args.filenames().count(); if (argsCount > 0) { // Loop through arguments for (int argNumber = 0; argNumber < argsCount; argNumber++) { QString fileName = args.filenames().at(argNumber); // are we just trying to open a template? if (doTemplate) { // called in mix with batch options? ignore and silently skip if (d->batchRun) { continue; } if (createNewDocFromTemplate(fileName, d->mainWindow)) { ++numberOfOpenDocuments; } // now try to load } else { if (exportAs) { QString outputMimetype = KisMimeDatabase::mimeTypeForFile(exportFileName, false); if (outputMimetype == "application/octetstream") { dbgKrita << i18n("Mimetype not found, try using the -mimetype option") << endl; return false; } KisDocument *doc = kisPart->createDocument(); doc->setFileBatchMode(d->batchRun); bool result = doc->openUrl(QUrl::fromLocalFile(fileName)); if (!result) { errKrita << "Could not load " << fileName << ":" << doc->errorMessage(); QTimer::singleShot(0, this, SLOT(quit())); return false; } if (exportFileName.isEmpty()) { errKrita << "Export destination is not specified for" << fileName << "Please specify export destination with --export-filename option"; QTimer::singleShot(0, this, SLOT(quit())); return false; } qApp->processEvents(); // For vector layers to be updated doc->setFileBatchMode(true); if (!doc->exportDocumentSync(QUrl::fromLocalFile(exportFileName), outputMimetype.toLatin1())) { errKrita << "Could not export " << fileName << "to" << exportFileName << ":" << doc->errorMessage(); } QTimer::singleShot(0, this, SLOT(quit())); return true; } else if (exportSequence) { KisDocument *doc = kisPart->createDocument(); doc->setFileBatchMode(d->batchRun); doc->openUrl(QUrl::fromLocalFile(fileName)); qApp->processEvents(); // For vector layers to be updated if (!doc->image()->animationInterface()->hasAnimation()) { errKrita << "This file has no animation." << endl; QTimer::singleShot(0, this, SLOT(quit())); return false; } doc->setFileBatchMode(true); int sequenceStart = 0; KisAsyncAnimationFramesSaveDialog exporter(doc->image(), doc->image()->animationInterface()->fullClipRange(), exportFileName, sequenceStart, false, 0); exporter.setBatchMode(d->batchRun); KisAsyncAnimationFramesSaveDialog::Result result = exporter.regenerateRange(0); if (result == KisAsyncAnimationFramesSaveDialog::RenderFailed) { errKrita << i18n("Failed to render animation frames!") << endl; } QTimer::singleShot(0, this, SLOT(quit())); return true; } else if (d->mainWindow) { if (fileName.endsWith(".bundle")) { d->mainWindow->installBundle(fileName); } else { KisMainWindow::OpenFlags flags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None; if (d->mainWindow->openDocument(QUrl::fromLocalFile(fileName), flags)) { // Normal case, success numberOfOpenDocuments++; } } } } } } //add an image as file-layer if (!args.fileLayer().isEmpty()){ if (d->mainWindow->viewManager()->image()){ KisFileLayer *fileLayer = new KisFileLayer(d->mainWindow->viewManager()->image(), "", args.fileLayer(), KisFileLayer::None, d->mainWindow->viewManager()->image()->nextLayerName(), OPACITY_OPAQUE_U8); QFileInfo fi(fileLayer->path()); if (fi.exists()){ KisNodeCommandsAdapter adapter(d->mainWindow->viewManager()); adapter.addNode(fileLayer, d->mainWindow->viewManager()->activeNode()->parent(), d->mainWindow->viewManager()->activeNode()); } else{ QMessageBox::warning(nullptr, i18nc("@title:window", "Krita:Warning"), i18n("Cannot add %1 as a file layer: the file does not exist.", fileLayer->path())); } } else if (this->isRunning()){ QMessageBox::warning(nullptr, i18nc("@title:window", "Krita:Warning"), i18n("Cannot add the file layer: no document is open.\n\n" "You can create a new document using the --new-image option, or you can open an existing file.\n\n" "If you instead want to add the file layer to a document in an already running instance of Krita, check the \"Allow only one instance of Krita\" checkbox in the settings (Settings -> General -> Window).")); } else { QMessageBox::warning(nullptr, i18nc("@title:window", "Krita: Warning"), i18n("Cannot add the file layer: no document is open.\n" "You can either create a new file using the --new-image option, or you can open an existing file.")); } } // fixes BUG:369308 - Krita crashing on splash screen when loading. // trying to open a file before Krita has loaded can cause it to hang and crash if (d->splashScreen) { d->splashScreen->displayLinks(true); d->splashScreen->displayRecentFiles(true); } Q_FOREACH(const QByteArray &message, d->earlyRemoteArguments) { executeRemoteArguments(message, d->mainWindow); } KisUsageLogger::writeSysInfo(KisUsageLogger::screenInformation()); // not calling this before since the program will quit there. return true; } KisApplication::~KisApplication() { } void KisApplication::setSplashScreen(QWidget *splashScreen) { d->splashScreen = qobject_cast(splashScreen); } void KisApplication::setSplashScreenLoadingText(QString textToLoad) { if (d->splashScreen) { //d->splashScreen->loadingLabel->setText(textToLoad); d->splashScreen->setLoadingText(textToLoad); d->splashScreen->repaint(); } } void KisApplication::hideSplashScreen() { if (d->splashScreen) { // hide the splashscreen to see the dialog d->splashScreen->hide(); } } bool KisApplication::notify(QObject *receiver, QEvent *event) { try { return QApplication::notify(receiver, event); } catch (std::exception &e) { qWarning("Error %s sending event %i to object %s", e.what(), event->type(), qPrintable(receiver->objectName())); } catch (...) { qWarning("Error sending event %i to object %s", event->type(), qPrintable(receiver->objectName())); } return false; } void KisApplication::executeRemoteArguments(QByteArray message, KisMainWindow *mainWindow) { KisApplicationArguments args = KisApplicationArguments::deserialize(message); const bool doTemplate = args.doTemplate(); const bool doNewImage = args.doNewImage(); const int argsCount = args.filenames().count(); bool documentCreated = false; // Create a new image, if needed if (doNewImage) { KisDocument *doc = args.createDocumentFromArguments(); if (doc) { KisPart::instance()->addDocument(doc); d->mainWindow->addViewAndNotifyLoadingCompleted(doc); } } if (argsCount > 0) { // Loop through arguments for (int argNumber = 0; argNumber < argsCount; ++argNumber) { QString filename = args.filenames().at(argNumber); // are we just trying to open a template? if (doTemplate) { documentCreated |= createNewDocFromTemplate(filename, mainWindow); } else if (QFile(filename).exists()) { KisMainWindow::OpenFlags flags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None; documentCreated |= mainWindow->openDocument(QUrl::fromLocalFile(filename), flags); } } } //add an image as file-layer if called in another process and singleApplication is enabled if (!args.fileLayer().isEmpty()){ if (argsCount > 0 && !documentCreated){ //arg was passed but document was not created so don't add the file layer. QMessageBox::warning(mainWindow, i18nc("@title:window", "Krita:Warning"), i18n("Couldn't open file %1",args.filenames().at(argsCount - 1))); } else if (mainWindow->viewManager()->image()){ KisFileLayer *fileLayer = new KisFileLayer(mainWindow->viewManager()->image(), "", args.fileLayer(), KisFileLayer::None, mainWindow->viewManager()->image()->nextLayerName(), OPACITY_OPAQUE_U8); QFileInfo fi(fileLayer->path()); if (fi.exists()){ KisNodeCommandsAdapter adapter(d->mainWindow->viewManager()); adapter.addNode(fileLayer, d->mainWindow->viewManager()->activeNode()->parent(), d->mainWindow->viewManager()->activeNode()); } else{ QMessageBox::warning(mainWindow, i18nc("@title:window", "Krita:Warning"), i18n("Cannot add %1 as a file layer: the file does not exist.", fileLayer->path())); } } else { QMessageBox::warning(mainWindow, i18nc("@title:window", "Krita:Warning"), i18n("Cannot add the file layer: no document is open.")); } } } void KisApplication::remoteArguments(QByteArray message, QObject *socket) { Q_UNUSED(socket); // check if we have any mainwindow KisMainWindow *mw = qobject_cast(qApp->activeWindow()); if (!mw && KisPart::instance()->mainWindows().size() > 0) { mw = KisPart::instance()->mainWindows().first(); } if (!mw) { d->earlyRemoteArguments << message; return; } executeRemoteArguments(message, mw); } void KisApplication::fileOpenRequested(const QString &url) { KisMainWindow *mainWindow = KisPart::instance()->mainWindows().first(); if (mainWindow) { KisMainWindow::OpenFlags flags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None; mainWindow->openDocument(QUrl::fromLocalFile(url), flags); } } void KisApplication::checkAutosaveFiles() { if (d->batchRun) return; #ifdef Q_OS_WIN QDir dir = QDir::temp(); #else QDir dir = QDir::home(); #endif // Check for autosave files from a previous run. There can be several, and // we want to offer a restore for every one. Including a nice thumbnail! // Hidden autosave files QStringList filters = QStringList() << QString(".krita-*-*-autosave.kra"); // all autosave files for our application QStringList autosaveFiles = dir.entryList(filters, QDir::Files | QDir::Hidden); // Visible autosave files filters = QStringList() << QString("krita-*-*-autosave.kra"); autosaveFiles += dir.entryList(filters, QDir::Files); // Allow the user to make their selection if (autosaveFiles.size() > 0) { if (d->splashScreen) { // hide the splashscreen to see the dialog d->splashScreen->hide(); } d->autosaveDialog = new KisAutoSaveRecoveryDialog(autosaveFiles, activeWindow()); QDialog::DialogCode result = (QDialog::DialogCode) d->autosaveDialog->exec(); if (result == QDialog::Accepted) { QStringList filesToRecover = d->autosaveDialog->recoverableFiles(); Q_FOREACH (const QString &autosaveFile, autosaveFiles) { if (!filesToRecover.contains(autosaveFile)) { KisUsageLogger::log(QString("Removing autosave file %1").arg(dir.absolutePath() + "/" + autosaveFile)); QFile::remove(dir.absolutePath() + "/" + autosaveFile); } } autosaveFiles = filesToRecover; } else { autosaveFiles.clear(); } if (autosaveFiles.size() > 0) { QList autosaveUrls; Q_FOREACH (const QString &autoSaveFile, autosaveFiles) { const QUrl url = QUrl::fromLocalFile(dir.absolutePath() + QLatin1Char('/') + autoSaveFile); autosaveUrls << url; } if (d->mainWindow) { Q_FOREACH (const QUrl &url, autosaveUrls) { KisMainWindow::OpenFlags flags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None; d->mainWindow->openDocument(url, flags | KisMainWindow::RecoveryFile); } } } // cleanup delete d->autosaveDialog; d->autosaveDialog = nullptr; } } bool KisApplication::createNewDocFromTemplate(const QString &fileName, KisMainWindow *mainWindow) { QString templatePath; const QUrl templateUrl = QUrl::fromLocalFile(fileName); if (QFile::exists(fileName)) { templatePath = templateUrl.toLocalFile(); dbgUI << "using full path..."; } else { QString desktopName(fileName); const QString templatesResourcePath = QStringLiteral("templates/"); QStringList paths = KoResourcePaths::findAllResources("data", templatesResourcePath + "*/" + desktopName); if (paths.isEmpty()) { paths = KoResourcePaths::findAllResources("data", templatesResourcePath + desktopName); } if (paths.isEmpty()) { QMessageBox::critical(0, i18nc("@title:window", "Krita"), i18n("No template found for: %1", desktopName)); } else if (paths.count() > 1) { QMessageBox::critical(0, i18nc("@title:window", "Krita"), i18n("Too many templates found for: %1", desktopName)); } else { templatePath = paths.at(0); } } if (!templatePath.isEmpty()) { QUrl templateBase; templateBase.setPath(templatePath); KDesktopFile templateInfo(templatePath); QString templateName = templateInfo.readUrl(); QUrl templateURL; templateURL.setPath(templateBase.adjusted(QUrl::RemoveFilename|QUrl::StripTrailingSlash).path() + '/' + templateName); if (templateURL.scheme().isEmpty()) { templateURL.setScheme("file"); } KisMainWindow::OpenFlags batchFlags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None; if (mainWindow->openDocument(templateURL, KisMainWindow::Import | batchFlags)) { dbgUI << "Template loaded..."; return true; } else { QMessageBox::critical(0, i18nc("@title:window", "Krita"), i18n("Template %1 failed to load.", templateURL.toDisplayString())); } } return false; } void KisApplication::resetConfig() { KIS_ASSERT_RECOVER_RETURN(qApp->thread() == QThread::currentThread()); KSharedConfigPtr config = KSharedConfig::openConfig(); config->markAsClean(); // find user settings file const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); QString kritarcPath = configPath + QStringLiteral("/kritarc"); QFile kritarcFile(kritarcPath); if (kritarcFile.exists()) { if (kritarcFile.open(QFile::ReadWrite)) { QString backupKritarcPath = kritarcPath + QStringLiteral(".backup"); QFile backupKritarcFile(backupKritarcPath); if (backupKritarcFile.exists()) { backupKritarcFile.remove(); } QMessageBox::information(0, i18nc("@title:window", "Krita"), i18n("Krita configurations reset!\n\n" "Backup file was created at: %1\n\n" "Restart Krita for changes to take effect.", backupKritarcPath), QMessageBox::Ok, QMessageBox::Ok); // clear file kritarcFile.rename(backupKritarcPath); kritarcFile.close(); } else { QMessageBox::warning(0, i18nc("@title:window", "Krita"), i18n("Failed to clear %1\n\n" "Please make sure no other program is using the file and try again.", kritarcPath), QMessageBox::Ok, QMessageBox::Ok); } } // reload from disk; with the user file settings cleared, // this should load any default configuration files shipping with the program config->reparseConfiguration(); config->sync(); // Restore to default workspace KConfigGroup cfg = KSharedConfig::openConfig()->group("MainWindow"); QString currentWorkspace = cfg.readEntry("CurrentWorkspace", "Default"); KoResourceServer *rserver = KisResourceServerProvider::instance()->workspaceServer(); KisWorkspaceResource *workspace = rserver->resourceByName(currentWorkspace); if (workspace) { d->mainWindow->restoreWorkspace(workspace); } } void KisApplication::askresetConfig() { bool ok = QMessageBox::question(0, i18nc("@title:window", "Krita"), i18n("Do you want to clear the settings file?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes; if (ok) { resetConfig(); } } diff --git a/libs/widgetutils/KoResourcePaths.cpp b/libs/widgetutils/KoResourcePaths.cpp index 7cc3b4a3c5..d4434189a9 100644 --- a/libs/widgetutils/KoResourcePaths.cpp +++ b/libs/widgetutils/KoResourcePaths.cpp @@ -1,602 +1,606 @@ /* * Copyright (c) 2015 Boudewijn Rempt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "KoResourcePaths.h" #include #include #include #include #include #include #include #include #include #include #include "kis_debug.h" Q_GLOBAL_STATIC(KoResourcePaths, s_instance) static QString cleanup(const QString &path) { return QDir::cleanPath(path); } static QStringList cleanup(const QStringList &pathList) { QStringList cleanedPathList; Q_FOREACH(const QString &path, pathList) { cleanedPathList << cleanup(path); } return cleanedPathList; } static QString cleanupDirs(const QString &path) { return QDir::cleanPath(path) + QDir::separator(); } static QStringList cleanupDirs(const QStringList &pathList) { QStringList cleanedPathList; Q_FOREACH(const QString &path, pathList) { cleanedPathList << cleanupDirs(path); } return cleanedPathList; } void appendResources(QStringList *dst, const QStringList &src, bool eliminateDuplicates) { Q_FOREACH (const QString &resource, src) { QString realPath = QDir::cleanPath(resource); if (!eliminateDuplicates || !dst->contains(realPath)) { *dst << realPath; } } } #ifdef Q_OS_WIN static const Qt::CaseSensitivity cs = Qt::CaseInsensitive; #else static const Qt::CaseSensitivity cs = Qt::CaseSensitive; #endif #ifdef Q_OS_MACOS #include #include #include #endif QString getInstallationPrefix() { #ifdef Q_OS_MACOS QString appPath = qApp->applicationDirPath(); dbgResources << "1" << appPath; appPath.chop(QString("MacOS/").length()); dbgResources << "2" << appPath; bool makeInstall = QDir(appPath + "/../../../share/kritaplugins").exists(); bool inBundle = QDir(appPath + "/Resources/kritaplugins").exists(); dbgResources << "3. After make install" << makeInstall; dbgResources << "4. In Bundle" << inBundle; QString bundlePath; if (inBundle) { bundlePath = appPath + "/"; } else if (makeInstall) { appPath.chop(QString("Contents/").length()); bundlePath = appPath + "/../../"; } else { qFatal("Cannot calculate the bundle path from the app path"); } dbgResources << ">>>>>>>>>>>" << bundlePath; return bundlePath; #else #ifdef Q_OS_QWIN QDir appdir(qApp->applicationDirPath()); // Corrects for mismatched case errors in path (qtdeclarative fails to load) wchar_t buffer[1024]; QString absolute = appdir.absolutePath(); DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024); rv = ::GetLongPathName(buffer, buffer, 1024); QString correctedPath((QChar *)buffer); appdir.setPath(correctedPath); appdir.cdUp(); return appdir.canonicalPath(); #else #ifdef Q_OS_ANDROID // qApp->applicationDirPath() isn't writable and android system won't allow // any files other than libraries return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/"; #else return qApp->applicationDirPath() + "/../"; #endif #endif #endif } class Q_DECL_HIDDEN KoResourcePaths::Private { public: QMap absolutes; // For each resource type, the list of absolute paths, from most local (most priority) to most global QMap relatives; // Same with relative paths QMutex relativesMutex; QMutex absolutesMutex; QStringList aliases(const QString &type) { QStringList r; QStringList a; relativesMutex.lock(); if (relatives.contains(type)) { r += relatives[type]; } relativesMutex.unlock(); dbgResources << "\trelatives" << r; absolutesMutex.lock(); if (absolutes.contains(type)) { a += absolutes[type]; } dbgResources << "\tabsolutes" << a; absolutesMutex.unlock(); return r + a; } QStandardPaths::StandardLocation mapTypeToQStandardPaths(const QString &type) { if (type == "tmp") { return QStandardPaths::TempLocation; } else if (type == "appdata") { return QStandardPaths::AppDataLocation; } else if (type == "data") { return QStandardPaths::AppDataLocation; } else if (type == "cache") { return QStandardPaths::CacheLocation; } else if (type == "locale") { return QStandardPaths::AppDataLocation; } else { return QStandardPaths::AppDataLocation; } } }; KoResourcePaths::KoResourcePaths() : d(new Private) { } KoResourcePaths::~KoResourcePaths() { } QString KoResourcePaths::getApplicationRoot() { return getInstallationPrefix(); } void KoResourcePaths::addResourceType(const char *type, const char *basetype, const QString &relativeName, bool priority) { s_instance->addResourceTypeInternal(QString::fromLatin1(type), QString::fromLatin1(basetype), relativeName, priority); } void KoResourcePaths::addResourceDir(const char *type, const QString &dir, bool priority) { s_instance->addResourceDirInternal(QString::fromLatin1(type), dir, priority); } QString KoResourcePaths::findResource(const char *type, const QString &fileName) { return cleanup(s_instance->findResourceInternal(QString::fromLatin1(type), fileName)); } QStringList KoResourcePaths::findDirs(const char *type) { return cleanupDirs(s_instance->findDirsInternal(QString::fromLatin1(type))); } QStringList KoResourcePaths::findAllResources(const char *type, const QString &filter, SearchOptions options) { return cleanup(s_instance->findAllResourcesInternal(QString::fromLatin1(type), filter, options)); } QStringList KoResourcePaths::resourceDirs(const char *type) { return cleanupDirs(s_instance->resourceDirsInternal(QString::fromLatin1(type))); } QString KoResourcePaths::saveLocation(const char *type, const QString &suffix, bool create) { return cleanupDirs(s_instance->saveLocationInternal(QString::fromLatin1(type), suffix, create)); } QString KoResourcePaths::locate(const char *type, const QString &filename) { return cleanup(s_instance->locateInternal(QString::fromLatin1(type), filename)); } QString KoResourcePaths::locateLocal(const char *type, const QString &filename, bool createDir) { return cleanup(s_instance->locateLocalInternal(QString::fromLatin1(type), filename, createDir)); } void KoResourcePaths::addResourceTypeInternal(const QString &type, const QString &basetype, const QString &relativename, bool priority) { Q_UNUSED(basetype); if (relativename.isEmpty()) return; QString copy = relativename; Q_ASSERT(basetype == "data"); if (!copy.endsWith(QLatin1Char('/'))) { copy += QLatin1Char('/'); } d->relativesMutex.lock(); QStringList &rels = d->relatives[type]; // find or insert if (!rels.contains(copy, cs)) { if (priority) { rels.prepend(copy); } else { rels.append(copy); } } d->relativesMutex.unlock(); dbgResources << "addResourceType: type" << type << "basetype" << basetype << "relativename" << relativename << "priority" << priority << d->relatives[type]; } void KoResourcePaths::addResourceDirInternal(const QString &type, const QString &absdir, bool priority) { if (absdir.isEmpty() || type.isEmpty()) return; // find or insert entry in the map QString copy = absdir; if (copy.at(copy.length() - 1) != QLatin1Char('/')) { copy += QLatin1Char('/'); } d->absolutesMutex.lock(); QStringList &paths = d->absolutes[type]; if (!paths.contains(copy, cs)) { if (priority) { paths.prepend(copy); } else { paths.append(copy); } } d->absolutesMutex.unlock(); dbgResources << "addResourceDir: type" << type << "absdir" << absdir << "priority" << priority << d->absolutes[type]; } QString KoResourcePaths::findResourceInternal(const QString &type, const QString &fileName) { QStringList aliases = d->aliases(type); dbgResources<< "aliases" << aliases << getApplicationRoot(); QString resource = QStandardPaths::locate(QStandardPaths::AppDataLocation, fileName, QStandardPaths::LocateFile); if (resource.isEmpty()) { Q_FOREACH (const QString &alias, aliases) { resource = QStandardPaths::locate(d->mapTypeToQStandardPaths(type), alias + '/' + fileName, QStandardPaths::LocateFile); dbgResources << "\t1" << resource; if (QFile::exists(resource)) { continue; } } } if (resource.isEmpty() || !QFile::exists(resource)) { QString approot = getApplicationRoot(); Q_FOREACH (const QString &alias, aliases) { resource = approot + "/share/" + alias + '/' + fileName; dbgResources << "\t2" << resource; if (QFile::exists(resource)) { continue; } } } if (resource.isEmpty() || !QFile::exists(resource)) { QString approot = getApplicationRoot(); Q_FOREACH (const QString &alias, aliases) { resource = approot + "/share/krita/" + alias + '/' + fileName; dbgResources << "\t3" << resource; if (QFile::exists(resource)) { continue; } } } if (resource.isEmpty() || !QFile::exists(resource)) { QString extraResourceDirs = qgetenv("EXTRA_RESOURCE_DIRS"); if (!extraResourceDirs.isEmpty()) { Q_FOREACH(const QString &extraResourceDir, extraResourceDirs.split(':', QString::SkipEmptyParts)) { if (aliases.isEmpty()) { resource = extraResourceDir + '/' + fileName; dbgResources<< "\t4" << resource; if (QFile::exists(resource)) { continue; } } else { Q_FOREACH (const QString &alias, aliases) { resource = extraResourceDir + '/' + alias + '/' + fileName; dbgResources<< "\t4" << resource; if (QFile::exists(resource)) { continue; } } } } } } dbgResources<< "findResource: type" << type << "filename" << fileName << "resource" << resource; Q_ASSERT(!resource.isEmpty()); return resource; } QStringList filesInDir(const QString &startdir, const QString & filter, bool recursive) { dbgResources << "filesInDir: startdir" << startdir << "filter" << filter << "recursive" << recursive; QStringList result; // First the entries in this path QStringList nameFilters; nameFilters << filter; const QStringList fileNames = QDir(startdir).entryList(nameFilters, QDir::Files | QDir::CaseSensitive, QDir::Name); dbgResources << "\tFound:" << fileNames.size() << ":" << fileNames; Q_FOREACH (const QString &fileName, fileNames) { QString file = startdir + '/' + fileName; result << file; } // And then everything underneath, if recursive is specified if (recursive) { const QStringList entries = QDir(startdir).entryList(QDir::Dirs | QDir::NoDotAndDotDot); Q_FOREACH (const QString &subdir, entries) { dbgResources << "\tGoing to look in subdir" << subdir << "of" << startdir; result << filesInDir(startdir + '/' + subdir, filter, recursive); } } return result; } QStringList KoResourcePaths::findDirsInternal(const QString &type) { QStringList aliases = d->aliases(type); dbgResources << type << aliases << d->mapTypeToQStandardPaths(type); QStringList dirs; QStringList standardDirs = QStandardPaths::locateAll(d->mapTypeToQStandardPaths(type), "", QStandardPaths::LocateDirectory); appendResources(&dirs, standardDirs, true); Q_FOREACH (const QString &alias, aliases) { QStringList aliasDirs = QStandardPaths::locateAll(d->mapTypeToQStandardPaths(type), alias + '/', QStandardPaths::LocateDirectory); appendResources(&dirs, aliasDirs, true); #ifdef Q_OS_MACOS dbgResources << "MAC:" << getApplicationRoot(); QStringList bundlePaths; bundlePaths << getApplicationRoot() + "/share/krita/" + alias; bundlePaths << getApplicationRoot() + "/../share/krita/" + alias; dbgResources << "bundlePaths" << bundlePaths; appendResources(&dirs, bundlePaths, true); Q_ASSERT(!dirs.isEmpty()); #endif QStringList fallbackPaths; fallbackPaths << getApplicationRoot() + "/share/" + alias; fallbackPaths << getApplicationRoot() + "/share/krita/" + alias; appendResources(&dirs, fallbackPaths, true); } dbgResources << "findDirs: type" << type << "resource" << dirs; return dirs; } QStringList KoResourcePaths::findAllResourcesInternal(const QString &type, const QString &_filter, SearchOptions options) const { dbgResources << "====================================================="; dbgResources << type << _filter << QStandardPaths::standardLocations(d->mapTypeToQStandardPaths(type)); bool recursive = options & KoResourcePaths::Recursive; dbgResources << "findAllResources: type" << type << "filter" << _filter << "recursive" << recursive; QStringList aliases = d->aliases(type); QString filter = _filter; // In cases where the filter is like "color-schemes/*.colors" instead of "*.kpp", used with unregistered resource types if (filter.indexOf('*') > 0) { aliases << filter.split('*').first(); filter = '*' + filter.split('*')[1]; dbgResources << "Split up alias" << aliases << "filter" << filter; } QStringList resources; if (aliases.isEmpty()) { QStringList standardResources = QStandardPaths::locateAll(d->mapTypeToQStandardPaths(type), filter, QStandardPaths::LocateFile); dbgResources << "standardResources" << standardResources; appendResources(&resources, standardResources, true); dbgResources << "1" << resources; } QString extraResourceDirs = qgetenv("EXTRA_RESOURCE_DIRS"); dbgResources << "extraResourceDirs" << extraResourceDirs; if (!extraResourceDirs.isEmpty()) { Q_FOREACH(const QString &extraResourceDir, extraResourceDirs.split(':', QString::SkipEmptyParts)) { if (aliases.isEmpty()) { appendResources(&resources, filesInDir(extraResourceDir + '/' + type, filter, recursive), true); } else { Q_FOREACH (const QString &alias, aliases) { appendResources(&resources, filesInDir(extraResourceDir + '/' + alias + '/', filter, recursive), true); } } } } dbgResources << "\tresources from qstandardpaths:" << resources.size(); Q_FOREACH (const QString &alias, aliases) { dbgResources << "\t\talias:" << alias; QStringList dirs; QFileInfo dirInfo(alias); if (dirInfo.exists() && dirInfo.isDir() && dirInfo.isAbsolute()) { dirs << alias; } else { dirs << QStandardPaths::locateAll(d->mapTypeToQStandardPaths(type), alias, QStandardPaths::LocateDirectory) << getInstallationPrefix() + "share/" + alias + "/" << getInstallationPrefix() + "share/krita/" + alias + "/"; } + if(_filter.endsWith("*.myb")) { + dirs << "/usr/share"; + } + Q_FOREACH (const QString &dir, dirs) { appendResources(&resources, filesInDir(dir, filter, recursive), true); } } dbgResources << "\tresources also from aliases:" << resources.size(); // if the original filter is "input/*", we only want share/input/* and share/krita/input/* here, but not // share/*. therefore, use _filter here instead of filter which was split into alias and "*". QFileInfo fi(_filter); QStringList prefixResources; prefixResources << filesInDir(getInstallationPrefix() + "share/" + fi.path(), fi.fileName(), false); prefixResources << filesInDir(getInstallationPrefix() + "share/krita/" + fi.path(), fi.fileName(), false); appendResources(&resources, prefixResources, true); dbgResources << "\tresources from installation:" << resources.size(); dbgResources << "====================================================="; return resources; } QStringList KoResourcePaths::resourceDirsInternal(const QString &type) { QStringList resourceDirs; QStringList aliases = d->aliases(type); Q_FOREACH (const QString &alias, aliases) { QStringList aliasDirs; aliasDirs << QStandardPaths::locateAll(d->mapTypeToQStandardPaths(type), alias, QStandardPaths::LocateDirectory); aliasDirs << getInstallationPrefix() + "share/" + alias + "/" << QStandardPaths::locateAll(d->mapTypeToQStandardPaths(type), alias, QStandardPaths::LocateDirectory); aliasDirs << getInstallationPrefix() + "share/krita/" + alias + "/" << QStandardPaths::locateAll(d->mapTypeToQStandardPaths(type), alias, QStandardPaths::LocateDirectory); appendResources(&resourceDirs, aliasDirs, true); } dbgResources << "resourceDirs: type" << type << resourceDirs; return resourceDirs; } QString KoResourcePaths::saveLocationInternal(const QString &type, const QString &suffix, bool create) { QStringList aliases = d->aliases(type); QString path; if (aliases.size() > 0) { path = QStandardPaths::writableLocation(d->mapTypeToQStandardPaths(type)) + '/' + aliases.first(); } else { path = QStandardPaths::writableLocation(d->mapTypeToQStandardPaths(type)); if (!path.endsWith("krita")) { path += "/krita"; } if (!suffix.isEmpty()) { path += "/" + suffix; } } QDir d(path); if (!d.exists() && create) { d.mkpath(path); } dbgResources << "saveLocation: type" << type << "suffix" << suffix << "create" << create << "path" << path; return path; } QString KoResourcePaths::locateInternal(const QString &type, const QString &filename) { QStringList aliases = d->aliases(type); QStringList locations; if (aliases.isEmpty()) { locations << QStandardPaths::locate(d->mapTypeToQStandardPaths(type), filename, QStandardPaths::LocateFile); } Q_FOREACH (const QString &alias, aliases) { locations << QStandardPaths::locate(d->mapTypeToQStandardPaths(type), (alias.endsWith('/') ? alias : alias + '/') + filename, QStandardPaths::LocateFile); } dbgResources << "locate: type" << type << "filename" << filename << "locations" << locations; if (locations.size() > 0) { return locations.first(); } else { return ""; } } QString KoResourcePaths::locateLocalInternal(const QString &type, const QString &filename, bool createDir) { QString path = saveLocationInternal(type, "", createDir); dbgResources << "locateLocal: type" << type << "filename" << filename << "CreateDir" << createDir << "path" << path; return path + '/' + filename; } diff --git a/plugins/paintops/CMakeLists.txt b/plugins/paintops/CMakeLists.txt index cf3377e38b..ac734b49de 100644 --- a/plugins/paintops/CMakeLists.txt +++ b/plugins/paintops/CMakeLists.txt @@ -1,18 +1,22 @@ include_directories(libpaintop) add_subdirectory( libpaintop ) add_subdirectory( defaultpresets ) add_subdirectory( defaultpaintops ) add_subdirectory( hairy ) add_subdirectory( deform ) add_subdirectory( curvebrush ) add_subdirectory( spray ) add_subdirectory( filterop ) add_subdirectory( experiment ) add_subdirectory( particle ) add_subdirectory( gridbrush ) add_subdirectory( hatching) add_subdirectory( sketch ) add_subdirectory( colorsmudge ) add_subdirectory( roundmarker ) add_subdirectory( tangentnormal ) + +if(LIBMYPAINT_FOUND) + add_subdirectory( mypaint ) +endif() diff --git a/plugins/paintops/mypaint/CMakeLists.txt b/plugins/paintops/mypaint/CMakeLists.txt new file mode 100644 index 0000000000..de87ca2abc --- /dev/null +++ b/plugins/paintops/mypaint/CMakeLists.txt @@ -0,0 +1,31 @@ +add_subdirectory(tests) +add_subdirectory(brushes) + +if(LIBMYPAINT_FOUND) + include_directories(${LIBMYPAINT_INCLUDE_DIR}) + link_directories(${LIBMYPAINT_LIBRARIES}) +endif() + +set(kritamypaintop_SOURCES + my_paintop_plugin.cpp + kis_my_paintop.cpp + kis_my_paintop_option.cpp + kis_my_paintop_settings.cpp + kis_my_paintop_settings_widget.cpp + kis_mypaint_surface.cpp + kis_mypaint_brush.cpp + kis_my_paintop_factory.cpp +) + +#ki18n_wrap_ui(kritasketchpaintop_SOURCES wdgsketchoptions.ui ) + +add_library(kritamypaintop MODULE ${kritamypaintop_SOURCES}) + +target_link_libraries(kritamypaintop kritalibpaintop mypaint) + +install(TARGETS kritamypaintop DESTINATION ${KRITA_PLUGIN_INSTALL_DIR}) + + +########### install files ############### + +install( FILES krita-mypaint.png DESTINATION ${DATA_INSTALL_DIR}/krita/images) diff --git a/plugins/paintops/mypaint/brushes/CMakeLists.txt b/plugins/paintops/mypaint/brushes/CMakeLists.txt new file mode 100644 index 0000000000..6387f5e666 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/CMakeLists.txt @@ -0,0 +1,73 @@ +install (FILES +blending_knife.myb +bulk_prev.png +coarse_bulk_2_prev.png +impressionism.myb +knife_prev.png +modelling.myb +puantilism2_prev.png +smudge.myb +blending_knife_prev.png +calligraphy.myb +coarse_bulk_3.myb +impressionism_prev.png +long_grass.myb +modelling_prev.png +puantilism.myb +smudge+paint.myb +blend+paint.myb +calligraphy_prev.png +coarse_bulk_3_prev.png +ink_blot.myb +long_grass_prev.png +pencil.myb +puantilism_prev.png +smudge+paint_prev.png +blend+paint_prev.png +charcoal.myb +dry_brush.myb +ink_blot_prev.png +marker_fat.myb +pencil_prev.png +rounded.myb +smudge_prev.png +blur.myb +charcoal_prev.png +dry_brush_prev.png +ink_eraser.myb +marker_fat_prev.png +pen.myb +rounded_prev.png +textured_ink.myb +blur_prev.png +imp_blending.myb +ink_eraser_prev.png +marker_small.myb +pen_prev.png +short_grass.myb +textured_ink_prev.png +brush.myb +coarse_bulk_1.myb +imp_blending_prev.png +kabura.myb +marker_small_prev.png +pointy_ink.myb +short_grass_prev.png +wet_knife.myb +brush_prev.png +coarse_bulk_1_prev.png +imp_details.myb +kabura_prev.png +modelling2.myb +pointy_ink_prev.png +slow_ink.myb +wet_knife_prev.png +bulk.myb +coarse_bulk_2.myb +imp_details_prev.png +knife.myb +modelling2_prev.png +puantilism2.myb +slow_ink_prev.png + + DESTINATION ${DATA_INSTALL_DIR}/krita/mypaint-data) diff --git a/plugins/paintops/mypaint/brushes/blend+paint.myb b/plugins/paintops/mypaint/brushes/blend+paint.myb new file mode 100644 index 0000000000..b6ce32f86f --- /dev/null +++ b/plugins/paintops/mypaint/brushes/blend+paint.myb @@ -0,0 +1,199 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "", + "settings": { + "anti_aliasing": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 54.45, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.69, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 0.85, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.222222, + 0.0 + ], + [ + 0.324074, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.6, + "inputs": {} + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.9, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.12, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/blend+paint_prev.png b/plugins/paintops/mypaint/brushes/blend+paint_prev.png new file mode 100644 index 0000000000..6c3cbf02fb Binary files /dev/null and b/plugins/paintops/mypaint/brushes/blend+paint_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/blending_knife.myb b/plugins/paintops/mypaint/brushes/blending_knife.myb new file mode 100644 index 0000000000..141b6a1043 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/blending_knife.myb @@ -0,0 +1,263 @@ +{ + "comment": "MyPaint brush file", + "group": "oil", + "parent_brush_name": "classic/blending_knife", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 5.51, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.44, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": { + "tilt_ascension": [ + [ + -180.0, + -180.0 + ], + [ + 180.0, + 180.0 + ] + ] + } + }, + "elliptical_dab_ratio": { + "base_value": 5.02, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.8, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 0.9, + "inputs": { + "speed1": [ + [ + 0.0, + 0.028571 + ], + [ + 4.0, + -0.2 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 1.04, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.046296, + 0.71875 + ], + [ + 0.154321, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.1, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 3.15, + "inputs": { + "pressure": [ + [ + 0.0, + 0.958333 + ], + [ + 1.0, + 2.0 + ] + ], + "speed1": [ + [ + 0.0, + -0.916667 + ], + [ + 3.7, + -2.0 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 2.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 1.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.21, + "inputs": { + "pressure": [ + [ + 0.0, + -0.326667 + ], + [ + 1.0, + 0.49 + ] + ], + "tilt_declination": [ + [ + 0.0, + 0.0 + ], + [ + 90.0, + 0.49 + ] + ] + } + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 5.5, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 10.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/blending_knife_prev.png b/plugins/paintops/mypaint/brushes/blending_knife_prev.png new file mode 100644 index 0000000000..94afbe85bf Binary files /dev/null and b/plugins/paintops/mypaint/brushes/blending_knife_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/blur.myb b/plugins/paintops/mypaint/brushes/blur.myb new file mode 100644 index 0000000000..518ed4db2c --- /dev/null +++ b/plugins/paintops/mypaint/brushes/blur.myb @@ -0,0 +1,223 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/blur", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 5.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 5.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.6, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + -0.4 + ] + ] + } + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.7, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + -0.4 + ] + ], + "speed1": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.2 + ] + ] + } + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 0.4, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.0, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.0, + "inputs": {} + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 1.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": -6.69, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/blur_prev.png b/plugins/paintops/mypaint/brushes/blur_prev.png new file mode 100644 index 0000000000..8ef1543a3e Binary files /dev/null and b/plugins/paintops/mypaint/brushes/blur_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/brush.myb b/plugins/paintops/mypaint/brushes/brush.myb new file mode 100644 index 0000000000..f18af6878d --- /dev/null +++ b/plugins/paintops/mypaint/brushes/brush.myb @@ -0,0 +1,245 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/brush", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 5.82, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.51, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 70.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.89, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": { + "pressure": [ + [ + 0.0, + -0.989583 + ], + [ + 0.38253, + -0.59375 + ], + [ + 0.656627, + 0.041667 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.44, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.015, + 0.0 + ], + [ + 0.069277, + 0.9375 + ], + [ + 0.25, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 1.01, + "inputs": { + "pressure": [ + [ + 0.0, + -1.86375 + ], + [ + 0.237952, + -1.42 + ], + [ + 0.5, + -0.355 + ], + [ + 0.76506, + 1.42 + ], + [ + 1.0, + 2.13 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 4.47, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 2.48, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 2.87, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/brush_prev.png b/plugins/paintops/mypaint/brushes/brush_prev.png new file mode 100644 index 0000000000..6dcd52b7a5 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/brush_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/bulk.myb b/plugins/paintops/mypaint/brushes/bulk.myb new file mode 100644 index 0000000000..7db1a633e4 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/bulk.myb @@ -0,0 +1,210 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/bulk", + "settings": { + "anti_aliasing": { + "base_value": 1.37, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 2.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.19, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.38, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.052469, + 0.625 + ], + [ + 0.166667, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 3.59, + "inputs": {} + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/bulk_prev.png b/plugins/paintops/mypaint/brushes/bulk_prev.png new file mode 100644 index 0000000000..d4f42371e7 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/bulk_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/calligraphy.myb b/plugins/paintops/mypaint/brushes/calligraphy.myb new file mode 100644 index 0000000000..3cd1441740 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/calligraphy.myb @@ -0,0 +1,241 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/calligraphy", + "settings": { + "anti_aliasing": { + "base_value": 3.53, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 2.2, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 45.92, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 5.46, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.74, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.05 + ] + ], + "speed1": [ + [ + 0.0, + -0.0 + ], + [ + 1.0, + -0.09 + ] + ] + } + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.0, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.015, + 0.0 + ], + [ + 0.015, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.02, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.5 + ] + ], + "speed1": [ + [ + 0.0, + -0.0 + ], + [ + 1.0, + -0.21 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.65, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.8, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 2.87, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/calligraphy_prev.png b/plugins/paintops/mypaint/brushes/calligraphy_prev.png new file mode 100644 index 0000000000..a6e4301936 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/calligraphy_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/charcoal.myb b/plugins/paintops/mypaint/brushes/charcoal.myb new file mode 100644 index 0000000000..f4d9df8683 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/charcoal.myb @@ -0,0 +1,213 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "", + "settings": { + "anti_aliasing": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.6354166666666666, + "inputs": {} + }, + "color_s": { + "base_value": 0.8807339449541285, + "inputs": {} + }, + "color_v": { + "base_value": 0.42745098039215684, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 5.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.2, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 1.6, + "inputs": { + "pressure": [ + [ + 0, + 0 + ], + [ + 1.0, + -1.4 + ] + ] + } + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 0.4, + "inputs": { + "pressure": [ + [ + 0, + 0 + ], + [ + 1.0, + 0.4 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.0, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0, + 0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 0.7, + "inputs": {} + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 2.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/charcoal_prev.png b/plugins/paintops/mypaint/brushes/charcoal_prev.png new file mode 100644 index 0000000000..4755cdec1c Binary files /dev/null and b/plugins/paintops/mypaint/brushes/charcoal_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/coarse_bulk_1.myb b/plugins/paintops/mypaint/brushes/coarse_bulk_1.myb new file mode 100644 index 0000000000..ebf414e502 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/coarse_bulk_1.myb @@ -0,0 +1,191 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/coarse_bulk_1", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 50.42, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.52, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 10.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.66, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 0.59, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.0, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 1.5, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 0.95, + "inputs": {} + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/coarse_bulk_1_prev.png b/plugins/paintops/mypaint/brushes/coarse_bulk_1_prev.png new file mode 100644 index 0000000000..4f4ea5c602 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/coarse_bulk_1_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/coarse_bulk_2.myb b/plugins/paintops/mypaint/brushes/coarse_bulk_2.myb new file mode 100644 index 0000000000..7c00b339ab --- /dev/null +++ b/plugins/paintops/mypaint/brushes/coarse_bulk_2.myb @@ -0,0 +1,202 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/coarse_bulk_2", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 2.6, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 80.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.59, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 10.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.66, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 0.99, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 1.55, + "inputs": { + "random": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.95 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/coarse_bulk_2_prev.png b/plugins/paintops/mypaint/brushes/coarse_bulk_2_prev.png new file mode 100644 index 0000000000..e034a97171 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/coarse_bulk_2_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/coarse_bulk_3.myb b/plugins/paintops/mypaint/brushes/coarse_bulk_3.myb new file mode 100644 index 0000000000..9e8f6c1019 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/coarse_bulk_3.myb @@ -0,0 +1,191 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/coarse_bulk_3", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 3.32, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 15.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.45, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 1.09, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.63, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.5, + "inputs": {} + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/coarse_bulk_3_prev.png b/plugins/paintops/mypaint/brushes/coarse_bulk_3_prev.png new file mode 100644 index 0000000000..d49f92ec3e Binary files /dev/null and b/plugins/paintops/mypaint/brushes/coarse_bulk_3_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/dry_brush.myb b/plugins/paintops/mypaint/brushes/dry_brush.myb new file mode 100644 index 0000000000..c3dd829b14 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/dry_brush.myb @@ -0,0 +1,224 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "", + "settings": { + "anti_aliasing": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.2, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.4 + ] + ] + } + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 0.8, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.2 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.0, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.1, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 0.6, + "inputs": { + "speed2": [ + [ + 0.0, + 0.042857 + ], + [ + 4.0, + -0.3 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 2.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/dry_brush_prev.png b/plugins/paintops/mypaint/brushes/dry_brush_prev.png new file mode 100644 index 0000000000..173562124a Binary files /dev/null and b/plugins/paintops/mypaint/brushes/dry_brush_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/imp_blending.myb b/plugins/paintops/mypaint/brushes/imp_blending.myb new file mode 100644 index 0000000000..16aa0bb4c0 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/imp_blending.myb @@ -0,0 +1,359 @@ +{ + "comment": "MyPaint brush file", + "group": "smudge", + "parent_brush_name": "classic/imp_blending", + "settings": { + "anti_aliasing": { + "base_value": 0.64, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": { + "custom": [ + [ + -2.0, + -0.04 + ], + [ + 2.0, + 0.04 + ] + ] + } + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": { + "stroke": [ + [ + 0.0, + 0.0 + ], + [ + 0.87963, + 0.02 + ], + [ + 1.0, + 0.0 + ] + ] + } + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + -10.0 + ], + [ + 1.0, + 10.0 + ] + ] + } + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": { + "tilt_declination": [ + [ + 0.0, + 4.41 + ], + [ + 90.0, + 0.0 + ] + ] + } + }, + "dabs_per_actual_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 80.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 0.0, + "inputs": { + "direction": [ + [ + 0.0, + 0.0 + ], + [ + 180.0, + 180.0 + ] + ] + } + }, + "elliptical_dab_ratio": { + "base_value": 7.1, + "inputs": { + "speed1": [ + [ + 0.0, + -0.668571 + ], + [ + 4.0, + 4.68 + ] + ], + "stroke": [ + [ + 0.0, + -0.4 + ], + [ + 1.0, + 0.4 + ] + ], + "tilt_declination": [ + [ + 0.0, + 3.636875 + ], + [ + 90.0, + -7.59 + ] + ] + } + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.8, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.6, + "inputs": { + "tilt_declination": [ + [ + 0.0, + 0.0 + ], + [ + 45.0, + 0.0 + ], + [ + 90.0, + 0.63 + ] + ] + } + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.166667, + 0.75 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.067901, + 0.78125 + ], + [ + 0.185185, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.0, + "inputs": { + "pressure": [ + [ + 0.0, + -2.0 + ], + [ + 0.401235, + 0.0 + ], + [ + 1.0, + 0.0 + ] + ], + "tilt_declination": [ + [ + 0.0, + 0.0 + ], + [ + 45.0, + 0.0 + ], + [ + 90.0, + -1.6 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 1.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.0, + "inputs": { + "stroke": [ + [ + 0.0, + 1.0 + ], + [ + 1.0, + -1.0 + ] + ] + } + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 6.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 10.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.2, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/imp_blending_prev.png b/plugins/paintops/mypaint/brushes/imp_blending_prev.png new file mode 100644 index 0000000000..e7a7bbd9f3 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/imp_blending_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/imp_details.myb b/plugins/paintops/mypaint/brushes/imp_details.myb new file mode 100644 index 0000000000..aaf3a1f707 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/imp_details.myb @@ -0,0 +1,398 @@ +{ + "comment": "MyPaint brush file", + "group": "impressionism", + "parent_brush_name": "classic/imp_details", + "settings": { + "anti_aliasing": { + "base_value": 0.48, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": { + "custom": [ + [ + -2.0, + -0.02 + ], + [ + 2.0, + 0.02 + ] + ] + } + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": { + "stroke": [ + [ + 0.0, + 0.0 + ], + [ + 0.87963, + 0.02 + ], + [ + 1.0, + 0.0 + ] + ] + } + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + -10.0 + ], + [ + 1.0, + 10.0 + ] + ] + } + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": { + "tilt_declination": [ + [ + 0.0, + 4.41 + ], + [ + 90.0, + 0.0 + ] + ] + } + }, + "dabs_per_actual_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 80.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 0.0, + "inputs": { + "direction": [ + [ + 0.0, + 0.0 + ], + [ + 180.0, + 180.0 + ] + ] + } + }, + "elliptical_dab_ratio": { + "base_value": 7.1, + "inputs": { + "speed1": [ + [ + 0.0, + -0.668571 + ], + [ + 4.0, + 4.68 + ] + ], + "stroke": [ + [ + 0.0, + -0.4 + ], + [ + 1.0, + 0.4 + ] + ], + "tilt_declination": [ + [ + 0.0, + 3.636875 + ], + [ + 90.0, + -7.59 + ] + ] + } + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.8, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.09, + "inputs": { + "pressure": [ + [ + 0.0, + -0.653333 + ], + [ + 0.379268, + -0.459375 + ], + [ + 0.747561, + 0.18375 + ], + [ + 1.0, + 0.98 + ] + ], + "tilt_declination": [ + [ + 0.0, + 0.0 + ], + [ + 45.0, + 0.0 + ], + [ + 90.0, + 0.63 + ] + ] + } + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.166667, + 0.75 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.067901, + 0.78125 + ], + [ + 0.185185, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.0, + "inputs": { + "pressure": [ + [ + 0.0, + -2.0 + ], + [ + 0.401235, + 0.0 + ], + [ + 1.0, + 0.0 + ] + ], + "tilt_declination": [ + [ + 0.0, + 0.0 + ], + [ + 45.0, + 0.0 + ], + [ + 90.0, + -1.6 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.9, + "inputs": { + "pressure": [ + [ + 0.0, + 0.510417 + ], + [ + 1.0, + -1.0 + ] + ], + "stroke": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "smudge_length": { + "base_value": 0.0, + "inputs": { + "stroke": [ + [ + 0.0, + 1.0 + ], + [ + 1.0, + -1.0 + ] + ] + } + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 6.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 10.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.2, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/imp_details_prev.png b/plugins/paintops/mypaint/brushes/imp_details_prev.png new file mode 100644 index 0000000000..fe7c08a4d7 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/imp_details_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/impressionism.myb b/plugins/paintops/mypaint/brushes/impressionism.myb new file mode 100644 index 0000000000..68f16e3b24 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/impressionism.myb @@ -0,0 +1,380 @@ +{ + "comment": "MyPaint brush file", + "group": "impressionism", + "parent_brush_name": "classic/impressionism", + "settings": { + "anti_aliasing": { + "base_value": 0.66, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": { + "custom": [ + [ + -2.0, + -0.04 + ], + [ + 2.0, + 0.04 + ] + ] + } + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": { + "stroke": [ + [ + 0.0, + 0.0 + ], + [ + 0.87963, + 0.02 + ], + [ + 1.0, + 0.0 + ] + ] + } + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + -10.0 + ], + [ + 1.0, + 10.0 + ] + ] + } + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": { + "tilt_declination": [ + [ + 0.0, + 4.41 + ], + [ + 90.0, + 0.0 + ] + ] + } + }, + "dabs_per_actual_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 80.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 0.0, + "inputs": { + "direction": [ + [ + 0.0, + 0.0 + ], + [ + 180.0, + 180.0 + ] + ] + } + }, + "elliptical_dab_ratio": { + "base_value": 7.1, + "inputs": { + "speed1": [ + [ + 0.0, + -0.668571 + ], + [ + 4.0, + 4.68 + ] + ], + "stroke": [ + [ + 0.0, + -0.4 + ], + [ + 1.0, + 0.4 + ] + ], + "tilt_declination": [ + [ + 0.0, + 3.636875 + ], + [ + 90.0, + -7.59 + ] + ] + } + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.8, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.6, + "inputs": { + "tilt_declination": [ + [ + 0.0, + 0.0 + ], + [ + 45.0, + 0.0 + ], + [ + 90.0, + 0.63 + ] + ] + } + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.166667, + 0.75 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.067901, + 0.78125 + ], + [ + 0.185185, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.0, + "inputs": { + "pressure": [ + [ + 0.0, + -2.0 + ], + [ + 0.401235, + 0.0 + ], + [ + 1.0, + 0.0 + ] + ], + "tilt_declination": [ + [ + 0.0, + 0.0 + ], + [ + 45.0, + 0.0 + ], + [ + 90.0, + -1.6 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.9, + "inputs": { + "pressure": [ + [ + 0.0, + 0.510417 + ], + [ + 1.0, + -1.0 + ] + ], + "stroke": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "smudge_length": { + "base_value": 0.0, + "inputs": { + "stroke": [ + [ + 0.0, + 1.0 + ], + [ + 1.0, + -1.0 + ] + ] + } + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 6.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 10.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.2, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/impressionism_prev.png b/plugins/paintops/mypaint/brushes/impressionism_prev.png new file mode 100644 index 0000000000..a1ee05f091 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/impressionism_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/ink_blot.myb b/plugins/paintops/mypaint/brushes/ink_blot.myb new file mode 100644 index 0000000000..aa843165b5 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/ink_blot.myb @@ -0,0 +1,191 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/ink_blot", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 3.32, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 15.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.28, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.17, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.13, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.63, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.5, + "inputs": {} + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/ink_blot_prev.png b/plugins/paintops/mypaint/brushes/ink_blot_prev.png new file mode 100644 index 0000000000..ee03eb35c5 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/ink_blot_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/ink_eraser.myb b/plugins/paintops/mypaint/brushes/ink_eraser.myb new file mode 100644 index 0000000000..e8527ba0f9 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/ink_eraser.myb @@ -0,0 +1,241 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "", + "settings": { + "anti_aliasing": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 2.2, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 1.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.5, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.05 + ] + ], + "speed1": [ + [ + 0.0, + -0.0 + ], + [ + 1.0, + -0.09 + ] + ] + } + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.0, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.015, + 0.0 + ], + [ + 0.025, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.16, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.5 + ] + ], + "speed1": [ + [ + 0.0, + -0.0 + ], + [ + 1.0, + -0.21 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.65, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.8, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 2.87, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/ink_eraser_prev.png b/plugins/paintops/mypaint/brushes/ink_eraser_prev.png new file mode 100644 index 0000000000..9fa0507773 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/ink_eraser_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/kabura.myb b/plugins/paintops/mypaint/brushes/kabura.myb new file mode 100644 index 0000000000..499f273adb --- /dev/null +++ b/plugins/paintops/mypaint/brushes/kabura.myb @@ -0,0 +1,266 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/kabura", + "settings": { + "anti_aliasing": { + "base_value": 0.93, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 2.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 3.24, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 48.87, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.43, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.29, + "inputs": { + "pressure": [ + [ + 0.0, + -0.989583 + ], + [ + 0.38253, + -0.59375 + ], + [ + 0.656627, + 0.041667 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.29, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.015, + 0.0 + ], + [ + 0.069277, + 0.9375 + ], + [ + 0.25, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 0.92, + "inputs": { + "pressure": [ + [ + 0.0, + -0.7875 + ], + [ + 0.237952, + -0.6 + ], + [ + 0.5, + -0.15 + ], + [ + 0.76506, + 0.6 + ], + [ + 1.0, + 0.9 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 10.0, + "inputs": { + "speed1": [ + [ + 0.0, + -1.428571 + ], + [ + 4.0, + 10.0 + ] + ], + "speed2": [ + [ + 0.0, + -1.428571 + ], + [ + 4.0, + 10.0 + ] + ] + } + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 2.87, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/kabura_prev.png b/plugins/paintops/mypaint/brushes/kabura_prev.png new file mode 100644 index 0000000000..a21b1f53df Binary files /dev/null and b/plugins/paintops/mypaint/brushes/kabura_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/knife.myb b/plugins/paintops/mypaint/brushes/knife.myb new file mode 100644 index 0000000000..126e25a7b3 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/knife.myb @@ -0,0 +1,202 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/knife", + "settings": { + "anti_aliasing": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 5.75, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.99, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": { + "direction": [ + [ + 0.0, + 0.0 + ], + [ + 180.0, + 180.0 + ] + ] + } + }, + "elliptical_dab_ratio": { + "base_value": 6.52, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.8, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.9, + "inputs": {} + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.26, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/knife_prev.png b/plugins/paintops/mypaint/brushes/knife_prev.png new file mode 100644 index 0000000000..f39e5757a9 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/knife_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/long_grass.myb b/plugins/paintops/mypaint/brushes/long_grass.myb new file mode 100644 index 0000000000..d49235577e --- /dev/null +++ b/plugins/paintops/mypaint/brushes/long_grass.myb @@ -0,0 +1,358 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/long_grass", + "settings": { + "anti_aliasing": { + "base_value": 5.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + -0.05 + ], + [ + 1.0, + 0.05 + ] + ], + "stroke": [ + [ + 0.0, + -0.004687 + ], + [ + 1.0, + 0.004792 + ] + ] + } + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + -0.01 + ], + [ + 1.0, + 0.01 + ] + ] + } + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + -0.173333 + ], + [ + 1.0, + 0.26 + ] + ] + } + }, + "change_color_v": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + -0.09 + ], + [ + 1.0, + 0.09 + ] + ], + "stroke": [ + [ + 0.0, + -0.13 + ], + [ + 0.5, + 0.13 + ], + [ + 1.0, + -0.128646 + ] + ] + } + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 1.06, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 24.08, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": { + "direction": [ + [ + 0.0, + 0.0 + ], + [ + 78.896104, + 21.41 + ], + [ + 102.272727, + -21.41 + ], + [ + 180.0, + 0.0 + ] + ], + "random": [ + [ + 0.0, + -13.31 + ], + [ + 0.11039, + -1.525104 + ], + [ + 0.899351, + 1.66375 + ], + [ + 1.0, + 13.31 + ] + ] + } + }, + "elliptical_dab_ratio": { + "base_value": 3.81, + "inputs": { + "random": [ + [ + 0.0, + 2.575 + ], + [ + 0.092593, + 4.345313 + ], + [ + 1.0, + 5.15 + ] + ] + } + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.8, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 1.74, + "inputs": { + "pressure": [ + [ + 0.0, + -0.0 + ], + [ + 1.0, + -1.78 + ] + ], + "speed1": [ + [ + 0.0, + 0.0 + ], + [ + 4.0, + 0.2 + ] + ] + } + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.1, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.4 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.83, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.083333, + 0.68 + ], + [ + 1.0, + 0.68 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.8, + "inputs": { + "random": [ + [ + 0.0, + -0.11 + ], + [ + 1.0, + 0.11 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 2.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.2, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 5.96, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/long_grass_prev.png b/plugins/paintops/mypaint/brushes/long_grass_prev.png new file mode 100644 index 0000000000..7e864421cd Binary files /dev/null and b/plugins/paintops/mypaint/brushes/long_grass_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/marker_fat.myb b/plugins/paintops/mypaint/brushes/marker_fat.myb new file mode 100644 index 0000000000..509c7c2c96 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/marker_fat.myb @@ -0,0 +1,236 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/marker_fat", + "settings": { + "anti_aliasing": { + "base_value": 0.78, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 2.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 1.5, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 113.08, + "inputs": { + "tilt_ascension": [ + [ + -180.0, + -180.0 + ], + [ + 180.0, + 180.0 + ] + ] + } + }, + "elliptical_dab_ratio": { + "base_value": 10.0, + "inputs": { + "tilt_declination": [ + [ + 0.0, + -0.0 + ], + [ + 68.042169, + -9.0 + ], + [ + 90.0, + -9.0 + ] + ] + } + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 1.0, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.060241, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.48, + "inputs": { + "tilt_declination": [ + [ + 20.0, + -0.0 + ], + [ + 50.0, + -0.0 + ], + [ + 80.0, + -1.0 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 3.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/marker_fat_prev.png b/plugins/paintops/mypaint/brushes/marker_fat_prev.png new file mode 100644 index 0000000000..8c396c3f84 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/marker_fat_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/marker_small.myb b/plugins/paintops/mypaint/brushes/marker_small.myb new file mode 100644 index 0000000000..281d2c44bb --- /dev/null +++ b/plugins/paintops/mypaint/brushes/marker_small.myb @@ -0,0 +1,236 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/marker_small", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 2.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 113.08, + "inputs": { + "tilt_ascension": [ + [ + -180.0, + -180.0 + ], + [ + 180.0, + 180.0 + ] + ] + } + }, + "elliptical_dab_ratio": { + "base_value": 8.0, + "inputs": { + "tilt_declination": [ + [ + 0.0, + -0.0 + ], + [ + 68.042169, + -9.0 + ], + [ + 90.0, + -9.0 + ] + ] + } + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.8, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.060241, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 1.0, + "inputs": { + "tilt_declination": [ + [ + 20.0, + -0.0 + ], + [ + 50.0, + -0.0 + ], + [ + 80.0, + -0.8 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 3.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/marker_small_prev.png b/plugins/paintops/mypaint/brushes/marker_small_prev.png new file mode 100644 index 0000000000..7e9a2af0a7 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/marker_small_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/modelling.myb b/plugins/paintops/mypaint/brushes/modelling.myb new file mode 100644 index 0000000000..348f93e7ba --- /dev/null +++ b/plugins/paintops/mypaint/brushes/modelling.myb @@ -0,0 +1,260 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/modelling", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 4.02, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.71, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 0.8, + "inputs": { + "speed2": [ + [ + 0.0, + 0.28 + ], + [ + 0.518519, + 0.032083 + ], + [ + 1.888889, + -0.16625 + ], + [ + 4.0, + -0.28 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.52 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 1.1, + "inputs": { + "pressure": [ + [ + 0.0, + 0.326667 + ], + [ + 1.0, + -0.49 + ] + ], + "speed1": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.75 + ] + ], + "speed2": [ + [ + 0.0, + -0.15 + ], + [ + 4.0, + 1.05 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.25, + "inputs": { + "pressure": [ + [ + 0.0, + -0.0 + ], + [ + 0.290123, + -0.0375 + ], + [ + 0.645062, + -0.15 + ], + [ + 1.0, + -0.4 + ] + ] + } + }, + "smudge_length": { + "base_value": 0.3, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 1.24, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.1, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.61, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/modelling2.myb b/plugins/paintops/mypaint/brushes/modelling2.myb new file mode 100644 index 0000000000..3e08e7569f --- /dev/null +++ b/plugins/paintops/mypaint/brushes/modelling2.myb @@ -0,0 +1,373 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "", + "settings": { + "anti_aliasing": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.1836514917, + "inputs": {} + }, + "color_s": { + "base_value": 0.721940404399, + "inputs": {} + }, + "color_v": { + "base_value": 0.860303654536, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 3.67, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.79, + "inputs": { + "pressure": [ + [ + 0.0, + -0.25 + ], + [ + 0.133929, + -0.195312 + ], + [ + 0.223214, + -0.109375 + ], + [ + 0.342262, + -0.028646 + ], + [ + 0.5, + 0.0 + ], + [ + 1.0, + 0.0 + ] + ] + } + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + 0.0 + ], + [ + 0.164336, + 0.0 + ], + [ + 0.213287, + 0.19 + ], + [ + 0.265734, + 0.0 + ], + [ + 1.0, + 0.0 + ] + ] + } + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 0.43, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.0, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + -0.78 + ], + [ + 0.02381, + 0.0 + ], + [ + 0.061728, + 0.2275 + ], + [ + 0.732143, + 0.706875 + ], + [ + 1.0, + 0.78 + ] + ], + "speed1": [ + [ + 0.0, + -0.27 + ], + [ + 3.0, + -0.2475 + ] + ], + "speed2": [ + [ + 0.0, + -0.37 + ], + [ + 0.357143, + -0.23125 + ], + [ + 0.845238, + -0.131042 + ], + [ + 1.77381, + -0.034687 + ], + [ + 2.77381, + 0.0 + ], + [ + 4.0, + 0.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 0.2, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.404321, + -0.0875 + ], + [ + 1.0, + -0.42 + ] + ], + "speed1": [ + [ + 0.0, + -0.201429 + ], + [ + 4.0, + 1.41 + ] + ], + "speed2": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.42 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.53, + "inputs": { + "pressure": [ + [ + 0.0, + -0.0 + ], + [ + 0.299383, + -0.0125 + ], + [ + 0.5, + -0.0375 + ], + [ + 0.790123, + -0.110417 + ], + [ + 1.0, + -0.2 + ] + ], + "stroke": [ + [ + 0.0, + -0.65 + ], + [ + 0.132716, + -0.561979 + ], + [ + 0.358025, + -0.473958 + ], + [ + 0.648148, + -0.24375 + ], + [ + 0.87037, + 0.067708 + ], + [ + 1.0, + 0.446875 + ] + ] + } + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.63, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 0.98, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 5.22, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 10.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/modelling2_prev.png b/plugins/paintops/mypaint/brushes/modelling2_prev.png new file mode 100644 index 0000000000..5080e48747 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/modelling2_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/modelling_prev.png b/plugins/paintops/mypaint/brushes/modelling_prev.png new file mode 100644 index 0000000000..8317206774 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/modelling_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/pen.myb b/plugins/paintops/mypaint/brushes/pen.myb new file mode 100644 index 0000000000..6057896209 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/pen.myb @@ -0,0 +1,241 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/pen", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 2.2, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.9, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.05 + ] + ], + "speed1": [ + [ + 0.0, + -0.0 + ], + [ + 1.0, + -0.09 + ] + ] + } + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.015, + 0.0 + ], + [ + 0.015, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 0.96, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.5 + ] + ], + "speed1": [ + [ + 0.0, + -0.0 + ], + [ + 1.0, + -0.21 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.65, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.8, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 2.87, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/pen_prev.png b/plugins/paintops/mypaint/brushes/pen_prev.png new file mode 100644 index 0000000000..4db23d7ded Binary files /dev/null and b/plugins/paintops/mypaint/brushes/pen_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/pencil.myb b/plugins/paintops/mypaint/brushes/pencil.myb new file mode 100644 index 0000000000..28784348d6 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/pencil.myb @@ -0,0 +1,213 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/pencil", + "settings": { + "anti_aliasing": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 4.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.1, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.3 + ] + ] + } + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.5, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + -0.3 + ] + ] + } + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 0.7, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 0.2, + "inputs": {} + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 1.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/pencil_prev.png b/plugins/paintops/mypaint/brushes/pencil_prev.png new file mode 100644 index 0000000000..bdbea46791 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/pencil_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/pointy_ink.myb b/plugins/paintops/mypaint/brushes/pointy_ink.myb new file mode 100644 index 0000000000..d6e77be0b4 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/pointy_ink.myb @@ -0,0 +1,267 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/pointy_ink", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 2.2, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.8, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.65 + ] + ], + "speed1": [ + [ + 0.0, + 0.064687 + ], + [ + 1.0, + -0.09 + ] + ] + } + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.015, + 0.0 + ], + [ + 0.015, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 0.96, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 3.36 + ] + ], + "speed1": [ + [ + 0.0, + 0.14875 + ], + [ + 1.0, + -0.21 + ] + ], + "stroke": [ + [ + 0.0, + -0.62 + ], + [ + 0.157407, + -0.393958 + ], + [ + 0.29321, + -0.238958 + ], + [ + 0.5, + -0.148542 + ], + [ + 0.700617, + -0.064583 + ], + [ + 1.0, + 0.0 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 2.87, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 1.18, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 10.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/pointy_ink_prev.png b/plugins/paintops/mypaint/brushes/pointy_ink_prev.png new file mode 100644 index 0000000000..3fe0c7390b Binary files /dev/null and b/plugins/paintops/mypaint/brushes/pointy_ink_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/puantilism.myb b/plugins/paintops/mypaint/brushes/puantilism.myb new file mode 100644 index 0000000000..dd6db48ccc --- /dev/null +++ b/plugins/paintops/mypaint/brushes/puantilism.myb @@ -0,0 +1,346 @@ +{ + "comment": "MyPaint brush file", + "group": "oil", + "parent_brush_name": "classic/puantilism", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": { + "custom": [ + [ + -2.0, + -0.04 + ], + [ + 2.0, + 0.04 + ] + ] + } + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": { + "stroke": [ + [ + 0.0, + 0.0 + ], + [ + 0.87963, + 0.02 + ], + [ + 1.0, + 0.0 + ] + ] + } + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + -10.0 + ], + [ + 1.0, + 10.0 + ] + ] + } + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": { + "tilt_declination": [ + [ + 0.0, + 4.41 + ], + [ + 90.0, + 0.0 + ] + ] + } + }, + "dabs_per_actual_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 80.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 0.0, + "inputs": { + "direction": [ + [ + 0.0, + 0.0 + ], + [ + 180.0, + 180.0 + ] + ] + } + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": { + "tilt_declination": [ + [ + 0.0, + 6.11 + ], + [ + 90.0, + 0.0 + ] + ] + } + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.8, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 2.0, + "inputs": { + "tilt_declination": [ + [ + 0.0, + -0.0 + ], + [ + 45.0, + -0.0 + ], + [ + 90.0, + -0.83 + ] + ] + } + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.166667, + 0.75 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.067901, + 0.78125 + ], + [ + 0.185185, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 1.42, + "inputs": { + "pressure": [ + [ + 0.0, + -2.0 + ], + [ + 0.401235, + 0.0 + ], + [ + 1.0, + 0.0 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.9, + "inputs": { + "pressure": [ + [ + 0.0, + 0.510417 + ], + [ + 1.0, + -1.0 + ] + ], + "stroke": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "smudge_length": { + "base_value": 0.0, + "inputs": { + "stroke": [ + [ + 0.0, + 1.0 + ], + [ + 1.0, + -1.0 + ] + ] + } + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 6.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 10.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.2, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/puantilism2.myb b/plugins/paintops/mypaint/brushes/puantilism2.myb new file mode 100644 index 0000000000..5fc00294f2 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/puantilism2.myb @@ -0,0 +1,382 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/puantilism2", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": { + "custom": [ + [ + -2.0, + -0.04 + ], + [ + 2.0, + 0.04 + ] + ] + } + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + -0.21 + ], + [ + 1.0, + 0.21 + ] + ] + } + }, + "change_color_l": { + "base_value": 0.0, + "inputs": { + "stroke": [ + [ + 0.0, + 0.0 + ], + [ + 0.87963, + 0.02 + ], + [ + 1.0, + 0.0 + ] + ] + } + }, + "change_color_v": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + -0.1 + ], + [ + 1.0, + 0.1 + ] + ] + } + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + -10.0 + ], + [ + 1.0, + 10.0 + ] + ] + } + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": { + "tilt_declination": [ + [ + 0.0, + 4.41 + ], + [ + 90.0, + 0.0 + ] + ] + } + }, + "dabs_per_actual_radius": { + "base_value": 2.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 80.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 0.0, + "inputs": { + "tilt_ascension": [ + [ + -180.0, + -180.0 + ], + [ + 180.0, + 180.0 + ] + ] + } + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": { + "tilt_declination": [ + [ + 0.0, + 4.6 + ], + [ + 90.0, + -0.0 + ] + ] + } + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.8, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 1.06, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.57561, + 0.428958 + ], + [ + 1.0, + 1.42 + ] + ], + "tilt_declination": [ + [ + 0.0, + -0.0 + ], + [ + 45.0, + -0.0 + ], + [ + 90.0, + -0.83 + ] + ] + } + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.166667, + 0.75 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.067901, + 0.78125 + ], + [ + 0.185185, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.02, + "inputs": { + "pressure": [ + [ + 0.0, + -2.0 + ], + [ + 0.401235, + 0.0 + ], + [ + 1.0, + 0.0 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.9, + "inputs": { + "pressure": [ + [ + 0.0, + 0.510417 + ], + [ + 1.0, + -1.0 + ] + ], + "stroke": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "smudge_length": { + "base_value": 0.0, + "inputs": { + "stroke": [ + [ + 0.0, + 1.0 + ], + [ + 1.0, + -1.0 + ] + ] + } + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 6.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 10.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.2, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/puantilism2_prev.png b/plugins/paintops/mypaint/brushes/puantilism2_prev.png new file mode 100644 index 0000000000..14a4404224 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/puantilism2_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/puantilism_prev.png b/plugins/paintops/mypaint/brushes/puantilism_prev.png new file mode 100644 index 0000000000..c51c738669 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/puantilism_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/rounded.myb b/plugins/paintops/mypaint/brushes/rounded.myb new file mode 100644 index 0000000000..5295d7e0b2 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/rounded.myb @@ -0,0 +1,221 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "", + "settings": { + "anti_aliasing": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.116482286819, + "inputs": {} + }, + "color_s": { + "base_value": 1.0, + "inputs": {} + }, + "color_v": { + "base_value": 1.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 167.14, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 1.0, + "inputs": { + "custom": [ + [ + -2.0, + 0.0 + ], + [ + -0.703704, + 0.007292 + ], + [ + 0.469136, + 0.027083 + ], + [ + 2.0, + 0.1 + ] + ] + } + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 0.69, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 2.0, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 3.3, + "inputs": {} + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.08, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.06, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/rounded_prev.png b/plugins/paintops/mypaint/brushes/rounded_prev.png new file mode 100644 index 0000000000..3c63825863 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/rounded_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/short_grass.myb b/plugins/paintops/mypaint/brushes/short_grass.myb new file mode 100644 index 0000000000..1521fbec52 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/short_grass.myb @@ -0,0 +1,289 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/short_grass", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + -0.05 + ], + [ + 1.0, + 0.05 + ] + ], + "stroke": [ + [ + 0.0, + -0.004687 + ], + [ + 1.0, + 0.004792 + ] + ] + } + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + -0.01 + ], + [ + 1.0, + 0.01 + ] + ] + } + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": { + "random": [ + [ + 0.0, + -0.28 + ], + [ + 1.0, + 0.28 + ] + ], + "stroke": [ + [ + 0.0, + -0.23 + ], + [ + 0.5, + 0.23 + ], + [ + 1.0, + -0.227604 + ] + ] + } + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 3.24, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": { + "random": [ + [ + 0.0, + -36.46 + ], + [ + 0.11039, + -4.177708 + ], + [ + 0.899351, + 4.5575 + ], + [ + 1.0, + 36.46 + ] + ] + } + }, + "elliptical_dab_ratio": { + "base_value": 3.91, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.91, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 1.79, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + -1.4 + ] + ] + } + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 0.78, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.4 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.56, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.5, + "inputs": {} + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 2.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 5.96, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/short_grass_prev.png b/plugins/paintops/mypaint/brushes/short_grass_prev.png new file mode 100644 index 0000000000..c744c46fc0 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/short_grass_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/slow_ink.myb b/plugins/paintops/mypaint/brushes/slow_ink.myb new file mode 100644 index 0000000000..7452fa8f2c --- /dev/null +++ b/plugins/paintops/mypaint/brushes/slow_ink.myb @@ -0,0 +1,241 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/slow_ink", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 2.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.8, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.06 + ] + ], + "speed1": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + -0.1 + ] + ] + } + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.191358, + 0.0 + ], + [ + 0.200617, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 1.37, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.5 + ] + ], + "speed1": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + -0.3 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 8.64, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 1.44, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.11, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/slow_ink_prev.png b/plugins/paintops/mypaint/brushes/slow_ink_prev.png new file mode 100644 index 0000000000..cb35bd3c2c Binary files /dev/null and b/plugins/paintops/mypaint/brushes/slow_ink_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/smudge+paint.myb b/plugins/paintops/mypaint/brushes/smudge+paint.myb new file mode 100644 index 0000000000..bf747b66e9 --- /dev/null +++ b/plugins/paintops/mypaint/brushes/smudge+paint.myb @@ -0,0 +1,263 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "", + "settings": { + "anti_aliasing": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 2.66, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.32, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.4 + ] + ] + } + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 0.64, + "inputs": { + "speed1": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + -0.2 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.0, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.077381, + 0.197917 + ], + [ + 0.229167, + 0.385417 + ], + [ + 0.589286, + 0.510417 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.2, + "inputs": { + "pressure": [ + [ + 0.0, + 0.4 + ], + [ + 1.0, + -0.6 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 1.0 + ], + [ + 0.219136, + 1.0 + ], + [ + 0.333333, + 0.895833 + ], + [ + 0.5, + 0.510417 + ], + [ + 0.759259, + 0.15625 + ], + [ + 1.0, + -0.0 + ] + ] + } + }, + "smudge_length": { + "base_value": 0.28, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/smudge+paint_prev.png b/plugins/paintops/mypaint/brushes/smudge+paint_prev.png new file mode 100644 index 0000000000..3cd214c853 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/smudge+paint_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/smudge.myb b/plugins/paintops/mypaint/brushes/smudge.myb new file mode 100644 index 0000000000..876fdd194b --- /dev/null +++ b/plugins/paintops/mypaint/brushes/smudge.myb @@ -0,0 +1,213 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/smudge", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 2.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.2, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.4 + ] + ] + } + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": { + "speed1": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + -0.2 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.0, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 1.6, + "inputs": {} + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 1.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.35, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/smudge_prev.png b/plugins/paintops/mypaint/brushes/smudge_prev.png new file mode 100644 index 0000000000..23ece605cf Binary files /dev/null and b/plugins/paintops/mypaint/brushes/smudge_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/textured_ink.myb b/plugins/paintops/mypaint/brushes/textured_ink.myb new file mode 100644 index 0000000000..30588b50fc --- /dev/null +++ b/plugins/paintops/mypaint/brushes/textured_ink.myb @@ -0,0 +1,228 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/textured_ink", + "settings": { + "anti_aliasing": { + "base_value": 0.61, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input_slowness": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 6.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.0, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": {} + }, + "elliptical_dab_ratio": { + "base_value": 1.0, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 1.0, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.4 + ] + ] + } + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 0.2 + ] + ] + } + }, + "opaque_linearize": { + "base_value": 0.0, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.055556, + 0.895833 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.1, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 0.9, + "inputs": { + "speed2": [ + [ + 0.0, + 0.042857 + ], + [ + 4.0, + -0.3 + ] + ] + } + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 2.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 0.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/textured_ink_prev.png b/plugins/paintops/mypaint/brushes/textured_ink_prev.png new file mode 100644 index 0000000000..c334f13e70 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/textured_ink_prev.png differ diff --git a/plugins/paintops/mypaint/brushes/wet_knife.myb b/plugins/paintops/mypaint/brushes/wet_knife.myb new file mode 100644 index 0000000000..dfafb983cc --- /dev/null +++ b/plugins/paintops/mypaint/brushes/wet_knife.myb @@ -0,0 +1,221 @@ +{ + "comment": "MyPaint brush file", + "group": "", + "parent_brush_name": "classic/wet_knife", + "settings": { + "anti_aliasing": { + "base_value": 1.0, + "inputs": {} + }, + "change_color_h": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsl_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_hsv_s": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_l": { + "base_value": 0.0, + "inputs": {} + }, + "change_color_v": { + "base_value": 0.0, + "inputs": {} + }, + "color_h": { + "base_value": 0.0, + "inputs": {} + }, + "color_s": { + "base_value": 0.0, + "inputs": {} + }, + "color_v": { + "base_value": 0.0, + "inputs": {} + }, + "colorize": { + "base_value": 0.0, + "inputs": {} + }, + "custom_input": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "custom_input_slowness": { + "base_value": 0.71, + "inputs": {} + }, + "dabs_per_actual_radius": { + "base_value": 5.75, + "inputs": {} + }, + "dabs_per_basic_radius": { + "base_value": 0.0, + "inputs": {} + }, + "dabs_per_second": { + "base_value": 0.0, + "inputs": {} + }, + "direction_filter": { + "base_value": 2.99, + "inputs": {} + }, + "elliptical_dab_angle": { + "base_value": 90.0, + "inputs": { + "direction": [ + [ + 0.0, + 0.0 + ], + [ + 180.0, + 180.0 + ] + ] + } + }, + "elliptical_dab_ratio": { + "base_value": 6.52, + "inputs": {} + }, + "eraser": { + "base_value": 0.0, + "inputs": {} + }, + "hardness": { + "base_value": 0.8, + "inputs": {} + }, + "lock_alpha": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed": { + "base_value": 0.0, + "inputs": {} + }, + "offset_by_speed_slowness": { + "base_value": 1.0, + "inputs": {} + }, + "opaque": { + "base_value": 1.0, + "inputs": {} + }, + "opaque_linearize": { + "base_value": 0.9, + "inputs": {} + }, + "opaque_multiply": { + "base_value": 0.0, + "inputs": { + "pressure": [ + [ + 0.0, + 0.0 + ], + [ + 0.117284, + 0.635417 + ], + [ + 0.330247, + 0.9375 + ], + [ + 1.0, + 1.0 + ] + ] + } + }, + "radius_by_random": { + "base_value": 0.0, + "inputs": {} + }, + "radius_logarithmic": { + "base_value": 2.3, + "inputs": {} + }, + "restore_color": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking": { + "base_value": 0.0, + "inputs": {} + }, + "slow_tracking_per_dab": { + "base_value": 0.0, + "inputs": {} + }, + "smudge": { + "base_value": 1.0, + "inputs": {} + }, + "smudge_length": { + "base_value": 0.5, + "inputs": {} + }, + "smudge_radius_log": { + "base_value": 0.0, + "inputs": {} + }, + "speed1_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed1_slowness": { + "base_value": 0.04, + "inputs": {} + }, + "speed2_gamma": { + "base_value": 4.0, + "inputs": {} + }, + "speed2_slowness": { + "base_value": 0.8, + "inputs": {} + }, + "stroke_duration_logarithmic": { + "base_value": 4.0, + "inputs": {} + }, + "stroke_holdtime": { + "base_value": 0.0, + "inputs": {} + }, + "stroke_threshold": { + "base_value": 0.0, + "inputs": {} + }, + "tracking_noise": { + "base_value": 0.0, + "inputs": {} + } + }, + "version": 3 +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/brushes/wet_knife_prev.png b/plugins/paintops/mypaint/brushes/wet_knife_prev.png new file mode 100644 index 0000000000..2eb457a2b3 Binary files /dev/null and b/plugins/paintops/mypaint/brushes/wet_knife_prev.png differ diff --git a/plugins/paintops/mypaint/kis_my_paintop.cpp b/plugins/paintops/mypaint/kis_my_paintop.cpp new file mode 100644 index 0000000000..ed96f6021e --- /dev/null +++ b/plugins/paintops/mypaint/kis_my_paintop.cpp @@ -0,0 +1,84 @@ +#include "kis_my_paintop.h" + +#include "kis_paintop.h" +#include "kis_spacing_information.h" +#include "kis_my_paintop_settings.h" +#include +#include +#include +#include +#include + +#include +#include +#include + + +KisMyPaintOp::KisMyPaintOp(const KisPaintOpSettingsSP settings, KisPainter * painter, KisNodeSP node, KisImageSP image) + : KisPaintOp (painter) { + + m_node = node; + m_brush.reset(new KisMyPaintBrush()); + m_surface.reset(new KisMyPaintSurface(this->painter(), m_node)); + + m_brush->apply(settings); + + if(qRound(mypaint_brush_get_base_value(m_brush->brush(), MYPAINT_BRUSH_SETTING_ERASER))) { + + m_brush->setColor(this->painter()->backgroundColor()); + mypaint_brush_set_base_value(m_brush->brush(), MYPAINT_BRUSH_SETTING_ERASER, false); + } + else { + m_brush->setColor(this->painter()->paintColor()); + } + + m_settings = settings; + + dtime = -1; + m_radius = exp(3.3); +} + +KisMyPaintOp::~KisMyPaintOp() { + +// delete m_brush; +// delete m_surface; +} + +KisSpacingInformation KisMyPaintOp::paintAt(const KisPaintInformation& info) { + + if(!painter()) { + return KisSpacingInformation(1.0); + } + + if(dtime < 0) { + mypaint_brush_stroke_to(m_brush->brush(), m_surface->surface(), info.pos().x(), info.pos().y(), info.pressure(), + info.xTilt(), info.yTilt(), 1.0f); + + dtime = 0.015; + } + else { + dtime = (info.currentTime() - dtime)*0.001; + } + + mypaint_brush_stroke_to(m_brush->brush(), m_surface->surface(), info.pos().x(), info.pos().y(), info.pressure(), + info.xTilt(), info.yTilt(), dtime); + + dtime = info.currentTime(); + + const qreal lodScale = KisLodTransform::lodToScale(painter()->device()); + m_radius = exp(3.3)*lodScale; + return computeSpacing(info, lodScale); +} + +KisSpacingInformation KisMyPaintOp::updateSpacingImpl(const KisPaintInformation &info) const +{ + KisSpacingInformation spacingInfo = computeSpacing(info, m_radius*KisLodTransform::lodToScale(painter()->device())); + return spacingInfo; +} + +KisSpacingInformation KisMyPaintOp::computeSpacing(const KisPaintInformation &info, qreal lodScale) const { + + return KisPaintOpPluginUtils::effectiveSpacing(m_radius*2, m_radius*2, + false, 0.0, false, m_radius*2, + true, 1, lodScale, nullptr, nullptr, info); +} diff --git a/plugins/paintops/mypaint/kis_my_paintop.h b/plugins/paintops/mypaint/kis_my_paintop.h new file mode 100644 index 0000000000..fd6633e672 --- /dev/null +++ b/plugins/paintops/mypaint/kis_my_paintop.h @@ -0,0 +1,41 @@ +#ifndef KIS_MY_PAINTOP_H_ +#define KIS_MY_PAINTOP_H_ + +#include +#include +#include "kis_mypaint_surface.h" +#include "kis_mypaint_brush.h" + +#include + +class KisPainter; + + +class KisMyPaintOp : public KisPaintOp +{ + +public: + + KisMyPaintOp(const KisPaintOpSettingsSP settings, KisPainter * painter, KisNodeSP node, KisImageSP image); + ~KisMyPaintOp() override; + +protected: + + KisSpacingInformation paintAt(const KisPaintInformation& info) override; + + KisSpacingInformation updateSpacingImpl(const KisPaintInformation &info) const override; + + //KisTimingInformation updateTimingImpl(const KisPaintInformation &info) const override; + +private: + KisSpacingInformation computeSpacing(const KisPaintInformation &info, qreal lodScale) const; + +private: + QScopedPointer m_brush; + QScopedPointer m_surface; + KisPaintOpSettingsSP m_settings; + KisNodeSP m_node; + double dtime, m_radius; +}; + +#endif // KIS_MY_PAINTOP_H_ diff --git a/plugins/paintops/mypaint/kis_my_paintop_factory.cpp b/plugins/paintops/mypaint/kis_my_paintop_factory.cpp new file mode 100644 index 0000000000..1edd7fc90d --- /dev/null +++ b/plugins/paintops/mypaint/kis_my_paintop_factory.cpp @@ -0,0 +1,101 @@ +#include "kis_my_paintop_factory.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class KisMyPaintOpFactory::Private { + + public: + KoResourceServer *brushServer; + QMap brushes; +}; + +KisMyPaintOpFactory::KisMyPaintOpFactory() + : m_d(new Private) +{ + + m_d->brushServer = new KoResourceServerSimpleConstruction("mypaint_brushes", "*.myb"); + m_d->brushServer->loadResources(KoResourceServerProvider::blacklistFileNames(m_d->brushServer->fileNames(), m_d->brushServer->blackListedFiles())); +} + +KisMyPaintOpFactory::~KisMyPaintOpFactory() { + +// delete m_d->brushServer; +// delete m_d; +} + +KisPaintOp* KisMyPaintOpFactory::createOp(const KisPaintOpSettingsSP settings, KisPainter *painter, KisNodeSP node, KisImageSP image) { + + KisPaintOp* op = new KisMyPaintOp(settings, painter, node, image); + + Q_CHECK_PTR(op); + return op; +} + +KisPaintOpSettingsSP KisMyPaintOpFactory::settings() { + + KisPaintOpSettingsSP settings = new KisMyPaintOpSettings(); +// settings->setModelName(m_model); + return settings; +} + +KisPaintOpConfigWidget* KisMyPaintOpFactory::createConfigWidget(QWidget* parent) { + + return new KisMyPaintOpSettingsWidget(parent); +} + +QString KisMyPaintOpFactory::id() const { + + return "mypaintbrush"; +} + +QString KisMyPaintOpFactory::name() const { + + return "MyPaint"; +} + +QIcon KisMyPaintOpFactory::icon() { + + return KisIconUtils::loadIcon(id()); +} + +QString KisMyPaintOpFactory::category() const { + + return KisPaintOpFactory::categoryStable(); +} + +void KisMyPaintOpFactory::processAfterLoading() { + + KisPaintOpPresetResourceServer *paintOpServer = KisResourceServerProvider::instance()->paintOpPresetServer(); + + foreach(KisMyPaintBrush* brush, m_d->brushServer->resources()) { + + QFileInfo fileInfo(brush->filename()); + + KisPaintOpSettingsSP s = new KisMyPaintOpSettings(); + s->setProperty("paintop", id()); + s->setProperty("filename", brush->filename()); + s->setProperty("json_string", brush->getJsonData()); + s->setProperty(MYPAINT_DIAMETER, brush->getSize()); + + KisPaintOpPresetSP preset = new KisPaintOpPreset(); + preset->setName(fileInfo.baseName()); + preset->setSettings(s); + KoID paintOpID(id(), name()); + preset->setPaintOp(paintOpID); + preset->setValid(true); + preset->setImage(brush->image()); + + paintOpServer->addResource(preset, false); + } + +} + +#include "kis_my_paintop_factory.moc" diff --git a/plugins/paintops/mypaint/kis_my_paintop_factory.h b/plugins/paintops/mypaint/kis_my_paintop_factory.h new file mode 100644 index 0000000000..dd1d83eb22 --- /dev/null +++ b/plugins/paintops/mypaint/kis_my_paintop_factory.h @@ -0,0 +1,31 @@ +#ifndef KIS_MY_PAINTOP_FACTORY_H +#define KIS_MY_PAINTOP_FACTORY_H + +#include +#include + +class KisMyPaintOpFactory: public KisPaintOpFactory +{ + Q_OBJECT + +public: + + KisMyPaintOpFactory(); + virtual ~KisMyPaintOpFactory(); + + KisPaintOp* createOp(const KisPaintOpSettingsSP settings, KisPainter *painter, KisNodeSP node, KisImageSP image) override; + KisPaintOpSettingsSP settings() override; + KisPaintOpConfigWidget* createConfigWidget(QWidget* parent) override; + QString id() const override; + QString name() const override; + QIcon icon() override; + QString category() const override; + void processAfterLoading() override; + +private: + + class Private; + const QScopedPointer m_d; +}; + +#endif // KIS_MY_PAINTOP_FACTORY_H diff --git a/plugins/paintops/mypaint/kis_my_paintop_option.cpp b/plugins/paintops/mypaint/kis_my_paintop_option.cpp new file mode 100644 index 0000000000..bd82c79f69 --- /dev/null +++ b/plugins/paintops/mypaint/kis_my_paintop_option.cpp @@ -0,0 +1,3 @@ +#include "kis_my_paintop_option.h" + + diff --git a/plugins/paintops/mypaint/kis_my_paintop_option.h b/plugins/paintops/mypaint/kis_my_paintop_option.h new file mode 100644 index 0000000000..ee354ce375 --- /dev/null +++ b/plugins/paintops/mypaint/kis_my_paintop_option.h @@ -0,0 +1,33 @@ +#ifndef KIS_MY_PAINTOP_OPTION_H +#define KIS_MY_PAINTOP_OPTION_H + +#include +#include + +const QString MYPAINT_DIAMETER = "MyPaint/diameter"; + +class KisMyPaintOptionProperties: public KisPaintopPropertiesBase +{ +public: + int radius() const { + return diameter/2; + } + + void readOptionSettingImpl(const KisPropertiesConfiguration *settings) override { + + diameter = settings->getFloat(MYPAINT_DIAMETER); + diameter = qRound(diameter)==0 ? 40 : diameter; + } + + void writeOptionSettingImpl(KisPropertiesConfiguration *setting) const override { + + setting->setProperty(MYPAINT_DIAMETER, diameter); + } + + +public: + float diameter; + +}; + +#endif // KIS_MY_PAINTOP_OPTION_H diff --git a/plugins/paintops/mypaint/kis_my_paintop_settings.cpp b/plugins/paintops/mypaint/kis_my_paintop_settings.cpp new file mode 100644 index 0000000000..3f030dcb21 --- /dev/null +++ b/plugins/paintops/mypaint/kis_my_paintop_settings.cpp @@ -0,0 +1,87 @@ +#include + +#include +#include + +#include "kis_my_paintop_settings.h" +#include "kis_my_paintop_option.h" + +struct KisMyPaintOpSettings::Private +{ + //QList uniformProperties; +}; + + +KisMyPaintOpSettings::KisMyPaintOpSettings() + : KisOutlineGenerationPolicy(KisCurrentOutlineFetcher::SIZE_OPTION | + KisCurrentOutlineFetcher::ROTATION_OPTION), + m_d(new Private) +{ +} + +KisMyPaintOpSettings::~KisMyPaintOpSettings() +{ +} + +void KisMyPaintOpSettings::setPaintOpSize(qreal value) +{ + KisMyPaintOptionProperties op; + op.readOptionSettingImpl(this); + op.diameter = value; + op.writeOptionSettingImpl(this); +} + +qreal KisMyPaintOpSettings::paintOpSize() const +{ + KisMyPaintOptionProperties op; + op.readOptionSettingImpl(this); + return op.diameter; +} + +bool KisMyPaintOpSettings::paintIncremental() +{ + return false; +} + + +QPainterPath KisMyPaintOpSettings::brushOutline(const KisPaintInformation &info, const OutlineMode &mode, qreal alignForZoom) +{ + QPainterPath path; + + if (mode.isVisible) { + qreal finalScale = 1.0; + + KisMyPaintOptionProperties op; + op.readOptionSettingImpl(this); + qreal radius = 0.5 * op.diameter; + radius = radius > 3.5 ? radius : 3.5; + + QPainterPath realOutline; + realOutline.addEllipse(QPointF(), radius, radius); + + path = outlineFetcher()->fetchOutline(info, this, realOutline, mode, alignForZoom, finalScale); + + if (mode.showTiltDecoration) { + QPainterPath tiltLine = makeTiltIndicator(info, + realOutline.boundingRect().center(), + realOutline.boundingRect().width() * 0.5, + 3.0); + path.addPath(outlineFetcher()->fetchOutline(info, this, tiltLine, mode, alignForZoom, finalScale, 0.0, true, realOutline.boundingRect().center().x(), realOutline.boundingRect().center().y())); + } + } + + return path; +} + +#include +#include "kis_paintop_preset.h" +#include "kis_paintop_settings_update_proxy.h" +#include "kis_standard_uniform_properties_factory.h" + + +QList KisMyPaintOpSettings::uniformProperties(KisPaintOpSettingsSP settings) +{ + QList props; + //listWeakToStrong(m_d->uniformProperties); + return props; +} diff --git a/plugins/paintops/mypaint/kis_my_paintop_settings.h b/plugins/paintops/mypaint/kis_my_paintop_settings.h new file mode 100644 index 0000000000..b7ab6cff07 --- /dev/null +++ b/plugins/paintops/mypaint/kis_my_paintop_settings.h @@ -0,0 +1,44 @@ +#ifndef KIS_MY_PAINTOP_SETTINGS_H_ +#define KIS_MY_PAINTOP_SETTINGS_H_ + +#include + +#include +#include + +#include +#include "kis_my_paintop_settings_widget.h" + + +class KisMyPaintOpSettings : public KisOutlineGenerationPolicy +{ +public: + KisMyPaintOpSettings(); + ~KisMyPaintOpSettings() override; + + void setPaintOpSize(qreal value) override; + qreal paintOpSize() const override; + + QPainterPath brushOutline(const KisPaintInformation &info, const OutlineMode &mode, qreal alignForZoom) override; + + QString modelName() const override { + return "airbrush"; + } + + bool paintIncremental() override; + +protected: + + QList uniformProperties(KisPaintOpSettingsSP settings) override; + +private: + Q_DISABLE_COPY(KisMyPaintOpSettings) + + struct Private; + const QScopedPointer m_d; + +}; + +typedef KisSharedPtr KisMyPaintOpSettingsSP; + +#endif diff --git a/plugins/paintops/mypaint/kis_my_paintop_settings_widget.cpp b/plugins/paintops/mypaint/kis_my_paintop_settings_widget.cpp new file mode 100644 index 0000000000..eff36b52d1 --- /dev/null +++ b/plugins/paintops/mypaint/kis_my_paintop_settings_widget.cpp @@ -0,0 +1,33 @@ +#include "kis_my_paintop_settings_widget.h" + +#include "kis_my_paintop_settings.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +KisMyPaintOpSettingsWidget:: KisMyPaintOpSettingsWidget(QWidget* parent) + : KisPaintOpSettingsWidget(parent) +{ +} + +KisMyPaintOpSettingsWidget::~ KisMyPaintOpSettingsWidget() +{ +} + +KisPropertiesConfigurationSP KisMyPaintOpSettingsWidget::configuration() const +{ + KisMyPaintOpSettings* config = new KisMyPaintOpSettings(); + config->setOptionsWidget(const_cast(this)); + config->setProperty("paintop", "mypaintbrush"); // XXX: make this a const id string + writeConfiguration(config); + return config; +} diff --git a/plugins/paintops/mypaint/kis_my_paintop_settings_widget.h b/plugins/paintops/mypaint/kis_my_paintop_settings_widget.h new file mode 100644 index 0000000000..96bccbcb1d --- /dev/null +++ b/plugins/paintops/mypaint/kis_my_paintop_settings_widget.h @@ -0,0 +1,18 @@ +#ifndef KIS_MYPAINTOP_SETTINGS_WIDGET_H_ +#define KIS_MYPAINTOP_SETTINGS_WIDGET_H_ + +#include + +class KisMyPaintOpSettingsWidget : public KisPaintOpSettingsWidget +{ + Q_OBJECT + +public: + KisMyPaintOpSettingsWidget(QWidget* parent = 0); + ~KisMyPaintOpSettingsWidget() override; + + KisPropertiesConfigurationSP configuration() const override; + +}; + +#endif diff --git a/plugins/paintops/mypaint/kis_mypaint_brush.cpp b/plugins/paintops/mypaint/kis_mypaint_brush.cpp new file mode 100644 index 0000000000..d15f8f5f91 --- /dev/null +++ b/plugins/paintops/mypaint/kis_mypaint_brush.cpp @@ -0,0 +1,170 @@ +#include "kis_mypaint_brush.h" + +#include +#include +#include +#include +#include + +class KisMyPaintBrush::Private { + +public: + MyPaintBrush *m_brush; + QImage m_icon; + QByteArray m_json; + float diameter; +}; + +KisMyPaintBrush::KisMyPaintBrush(const QString &fileName) + : KoResource (fileName), m_d(new Private) { + + m_d->m_brush = mypaint_brush_new(); + mypaint_brush_from_defaults(m_d->m_brush); +} + +void KisMyPaintBrush::setColor(const KoColor color) { + + float hue, saturation, value; + qreal r, g, b; + + color.toQColor().getRgbF(&r ,&g ,&b); + RGBToHSV(r , g, b, &hue, &saturation, &value); + + mypaint_brush_set_base_value(m_d->m_brush, MYPAINT_BRUSH_SETTING_COLOR_H, (hue)/360); + mypaint_brush_set_base_value(m_d->m_brush, MYPAINT_BRUSH_SETTING_COLOR_S, (saturation)); + mypaint_brush_set_base_value(m_d->m_brush, MYPAINT_BRUSH_SETTING_COLOR_V, (value)); +} + +void KisMyPaintBrush::apply(KisPaintOpSettingsSP settings) { + +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC, -1.00); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_OPAQUE, 0.6); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_HARDNESS, 0.64); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_ERASER, false); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_SMUDGE, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_COLOR_H, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_COLOR_S, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_COLOR_V, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_COLORIZE, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_LOCK_ALPHA, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_SPEED1_GAMMA, 4.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_SPEED2_GAMMA, 4.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_ANTI_ALIASING, 1.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_RESTORE_COLOR, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_SLOW_TRACKING, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_SMUDGE_LENGTH, 0.5); +// //mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_SNAP_TO_PIXEL, false); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_CHANGE_COLOR_H, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_CHANGE_COLOR_L, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_CHANGE_COLOR_V, 0.185); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_TRACKING_NOISE, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_DABS_PER_SECOND, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_OFFSET_BY_SPEED, 0.17); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_OPAQUE_MULTIPLY, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_SPEED1_SLOWNESS, 0.09); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_SPEED2_SLOWNESS, 1.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_STROKE_HOLDTIME, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_DIRECTION_FILTER, 2.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_OFFSET_BY_RANDOM, 2.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_OPAQUE_LINEARIZE, 0.9); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_RADIUS_BY_RANDOM, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_STROKE_THRESHOLD, 0.0); +// //mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_PRESSURE_GAIN_LOG, false); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_SMUDGE_RADIUS_LOG, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_CHANGE_COLOR_HSL_S, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_CHANGE_COLOR_HSV_S, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_ELLIPTICAL_DAB_ANGLE, 90.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_ELLIPTICAL_DAB_RATIO, 1.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_CUSTOM_INPUT_SLOWNESS, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_DABS_PER_BASIC_RADIUS, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_SLOW_TRACKING_PER_DAB, 0.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_DABS_PER_ACTUAL_RADIUS, 2.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_OFFSET_BY_SPEED_SLOWNESS, 1.0); +// mypaint_brush_set_base_value(m_brush, MYPAINT_BRUSH_SETTING_STROKE_DURATION_LOGARITHMIC, 4.0); + + if(settings->getProperty("json_string").isNull()) { + mypaint_brush_from_defaults(m_d->m_brush); + } + else { + + QByteArray ba = settings->getProperty("json_string").toByteArray(); + mypaint_brush_from_string(m_d->m_brush, ba); + } + + float diameter = settings->getFloat(MYPAINT_DIAMETER); + diameter = qRound(diameter)==0 ? 40 : diameter; + mypaint_brush_set_base_value(m_d->m_brush, MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC, log(diameter/2)); + + mypaint_brush_new_stroke(m_d->m_brush); + +} + +MyPaintBrush* KisMyPaintBrush::brush() { + + return m_d->m_brush; +} + +bool KisMyPaintBrush::load() { + + dbgImage << "Load MyPaint Brush " << filename(); + setValid(false); + + if (filename().isEmpty()) { + return false; + } + + QIODevice *dev = 0; + QByteArray ba; + + dev = new QFile(filename()); + + if (dev->size() == 0) + { + delete dev; + return false; + } + + if (!dev->open(QIODevice::ReadOnly)) { + warnKrita << "Can't open file " << filename(); + delete dev; + return false; + } + + bool res = false; + res = loadFromDevice(dev); + + delete dev; + setValid(res); + + return res; +} + +bool KisMyPaintBrush::loadFromDevice(QIODevice *dev) { + + QFileInfo fileInfo(filename()); + m_d->m_icon.load(fileInfo.path() + '/' + fileInfo.baseName() + "_prev.png"); + + setImage(m_d->m_icon); + + QByteArray ba = dev->readAll(); + m_d->m_json = ba; + mypaint_brush_from_string(m_d->m_brush, ba); + m_d->diameter = 2*exp(mypaint_brush_get_base_value(m_d->m_brush, MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC)); + + return true; +} + +bool KisMyPaintBrush::save() { + + return false; +} + +QByteArray KisMyPaintBrush::getJsonData() { + + return m_d->m_json; +} + +float KisMyPaintBrush::getSize() { + + return m_d->diameter; +} diff --git a/plugins/paintops/mypaint/kis_mypaint_brush.h b/plugins/paintops/mypaint/kis_mypaint_brush.h new file mode 100644 index 0000000000..96af27eaa2 --- /dev/null +++ b/plugins/paintops/mypaint/kis_mypaint_brush.h @@ -0,0 +1,39 @@ +#ifndef KIS_MYPAINT_BRUSH_H +#define KIS_MYPAINT_BRUSH_H + +#include +#include +#include +#include +#include +#include + +class KisMyPaintBrush : public QObject, public KoResource +{ + Q_OBJECT + +public: + + KisMyPaintBrush(const QString &fileName=""); + virtual ~KisMyPaintBrush() {} ; + + void setColor(const KoColor color); + void apply(KisPaintOpSettingsSP settings); + MyPaintBrush* brush(); + + bool load() override; + bool loadFromDevice(QIODevice *dev) override; + bool save() override; + + QByteArray getJsonData(); + float getSize(); + +private: + + class Private; + Private* const m_d; +}; + +//Q_DECLARE_METATYPE(KisMyPaintBrush); + +#endif // KIS_MYPAINT_BRUSH_H diff --git a/plugins/paintops/mypaint/kis_mypaint_surface.cpp b/plugins/paintops/mypaint/kis_mypaint_surface.cpp new file mode 100644 index 0000000000..18454d9e22 --- /dev/null +++ b/plugins/paintops/mypaint/kis_mypaint_surface.cpp @@ -0,0 +1,456 @@ +#include "kis_mypaint_surface.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +//KisPainter* KisMyPaintSurface::m_painter=nullptr; +//KisNodeSP KisMyPaintSurface::m_node=nullptr; + +using namespace std; + +KisMyPaintSurface::KisMyPaintSurface(KisPainter *painter, KisNodeSP node) +{ + m_painter = painter; + m_node = node; + + m_surface = new MyPaintSurfaceInternal(); + mypaint_surface_init(m_surface); + m_surface->m_owner = this; + + m_surface->draw_dab = this->draw_dab; + m_surface->get_color = this->get_color; +} + +int KisMyPaintSurface::draw_dab(MyPaintSurface *self, float x, float y, float radius, float color_r, float color_g, + float color_b, float opaque, float hardness, float color_a, + float aspect_ratio, float angle, float lock_alpha, float colorize) { + + MyPaintSurfaceInternal *surface = static_cast(self); + return surface->m_owner->drawDabImpl(self, x, y, radius, color_r, color_g, + color_b, opaque, hardness, color_a, + aspect_ratio, angle, lock_alpha, colorize); +} + +void KisMyPaintSurface::get_color(MyPaintSurface *self, float x, float y, float radius, + float * color_r, float * color_g, float * color_b, float * color_a) { + + MyPaintSurfaceInternal *surface = static_cast(self); + surface->m_owner->getColorImpl(self, x, y, radius, color_r, color_g, color_b, color_a); +} + + +/*GIMP's draw_dab and get_color code*/ +int KisMyPaintSurface::drawDabImpl(MyPaintSurface *self, float x, float y, float radius, float color_r, float color_g, + float color_b, float opaque, float hardness, float color_a, + float aspect_ratio, float angle, float lock_alpha, float colorize) { + + + const float one_over_radius2 = 1.0f / (radius * radius); + const double angle_rad = angle / 360 * 2 * M_PI; + const float cs = cos(angle_rad); + const float sn = sin(angle_rad); + float normal_mode; + float segment1_slope; + float segment2_slope; + float r_aa_start; + + hardness = CLAMP (hardness, 0.0f, 1.0f); + segment1_slope = -(1.0f / hardness - 1.0f); + segment2_slope = -hardness / (1.0f - hardness); + aspect_ratio = max(1.0f, aspect_ratio); + + r_aa_start = radius - 1.0f; + r_aa_start = max(r_aa_start, 0.0f); + r_aa_start = (r_aa_start * r_aa_start) / aspect_ratio; + + normal_mode = opaque * (1.0f - colorize); + colorize = opaque * colorize; + + const KoColorSpace *colorSpace = painter()->device()->colorSpace(); + const QPoint pt = QPoint(x - radius - 1, y - radius - 1); + const QSize sz = QSize(2 * (radius+1), 2 * (radius+1)); + + const QRect dabRectAligned = QRect(pt, sz); + const QPointF center = QPointF(x, y); + + QColor color = QColor(color_r*255, color_g*255, color_b*255, color_a*255); + KisAlgebra2D::OuterCircle outer(center, radius); + + KisSequentialIterator it(painter()->device(), dabRectAligned); + + while(it.nextPixel()) { + + QPoint pt(it.x(), it.y()); + + //qreal value = outer.fadeSq(pt); + + if(outer.fadeSq(pt) > 1.0f) + continue; + + qreal rr, base_alpha, alpha, dst_alpha, r, g, b, a; + qreal opacity; + + if (radius < 3.0) { + rr = calculate_rr_antialiased (it.x(), it.y(), x, y, aspect_ratio, sn, cs, one_over_radius2, r_aa_start); + } + else { + rr = calculate_rr (it.x(), it.y(), x, y, aspect_ratio, sn, cs, one_over_radius2); + } + + //qDebug() << colorSpace; +// KoColor dstPixel(colorSpace); +// QColor dstQColor; + //colorSpace->toQColor(it.rawData(), &dstQColor); + + // memcpy(dstPixel.data(), it.rawData(), painter()->device()->pixelSize()); + // qDebug() << dstPixel; + //dstPixel.toQColor(&dstQColor); + //qDebug() << dstPixel.data()[0] << " " << dstPixel.data()[1] << " " << dstPixel.data()[2] << " " < 0.0f) { + + float src_term = (alpha * color_a) / a; + float dst_term = 1.0f - src_term; + r = color_r * src_term + r * dst_term; + g = color_g * src_term + g * dst_term; + b = color_b * src_term + b * dst_term; + } + + if (colorize > 0.0f && base_alpha > 0.0f) { + + alpha = base_alpha * colorize; + a = alpha + dst_alpha - alpha * dst_alpha; + + if (a > 0.0f) { + + float pixel_h, pixel_s, pixel_l, out_h, out_s, out_l; + float out_r = r, out_g = g, out_b = b; + + float src_term = alpha / a; + float dst_term = 1.0f - src_term; + + RGBToHSL(color_r, color_g, color_b, &pixel_h, &pixel_s, &pixel_l); + RGBToHSL(out_r, out_g, out_b, &out_h, &out_s, &out_l); + + out_h = pixel_h; + out_s = pixel_s; + + HSLToRGB(out_h, out_s, out_l, &out_r, &out_g, &out_b); + + r = (float)out_r * src_term + r * dst_term; + g = (float)out_g * src_term + g * dst_term; + b = (float)out_b * src_term + b * dst_term; + } + } + + //QColor paintColor = QColor(r*255,g*255,b*255,a*255); + // KoColor paintKolor(colorSpace); + it.rawData()[0] = b*255; + it.rawData()[1] = g*255; + it.rawData()[2] = r*255; + it.rawData()[3] = a*255; + + //paintKolor.fromQColor(paintColor); + + //memcpy(it.rawData(), paintKolor.data(), painter()->device()->pixelSize()); + } + + painter()->addDirtyRect(dabRectAligned); + return 1; +} + +void KisMyPaintSurface::getColorImpl(MyPaintSurface *self, float x, float y, float radius, + float * color_r, float * color_g, float * color_b, float * color_a) { + + if (radius < 1.0f) + radius = 1.0f; + + *color_r = 0.0f; + *color_g = 0.0f; + *color_b = 0.0f; + *color_a = 0.0f; + +// KoColor canvasColor; +// KisCrossDeviceColorPicker colorPicker(m_nodeDevice, canvasColor); + const KoColorSpace *colorSpace = painter()->device()->colorSpace(); + const QPoint pt = QPoint(x - radius, y - radius); + const QSize sz = QSize(2 * radius, 2 * radius); + + const QRect dabRectAligned = QRect(pt, sz); + const QPointF center = QPointF(x, y); + KisAlgebra2D::OuterCircle outer(center, radius); + + const float one_over_radius2 = 1.0f / (radius * radius); + float sum_weight = 0.0f; + float sum_r = 0.0f; + float sum_g = 0.0f; + float sum_b = 0.0f; + float sum_a = 0.0f; + + KisSequentialIterator it(painter()->device(), dabRectAligned); + KisRandomAccessorSP im = m_node->paintDevice()->createRandomAccessorNG(x, y); + + while(it.nextPixel()) { + + QPointF pt(it.x(), it.y()); + + if(outer.fadeSq(pt) > 1.0) + continue; + + /* pixel_weight == a standard dab with hardness = 0.5, aspect_ratio = 1.0, and angle = 0.0 */ + float yy = (it.y() + 0.5f - y); + float xx = (it.x() + 0.5f - x); + + float rr = (yy * yy + xx * xx) * one_over_radius2; + float pixel_weight = 0.0f; + if (rr <= 1.0f) + pixel_weight = 1.0f - rr; + +// QColor dstQColor; +// colorSpace->toQColor(it.rawData(), &dstQColor, colorSpace->profile()); + +// colorPicker.pickColor(it.x(), it.y(), canvasColor.data()); + + im->moveTo(it.x(), it.y()); +// colorSpace->toQColor(im->rawData(), &dstQColor); + + qreal r, g, b, a; +// dstQColor.getRgbF(&r, &g, &b, &a); + + b = im->rawData()[0]/(255.0f); + g = im->rawData()[1]/(255.0f); + r = im->rawData()[2]/(255.0f); + a = im->rawData()[3]/(255.0f); + + //qDebug() << r << " " << g << "" << b << " " << a; + + sum_r += pixel_weight * r; + sum_g += pixel_weight * g; + sum_b += pixel_weight * b; + sum_a += pixel_weight * a; + sum_weight += pixel_weight; + } + + if (sum_a > 0.0f && sum_weight > 0.0f) { + + sum_r /= sum_weight; + sum_g /= sum_weight; + sum_b /= sum_weight; + sum_a /= sum_weight; + + sum_r /= sum_a; + sum_g /= sum_a; + sum_b /= sum_a; + + *color_r = CLAMP(sum_r, 0.0f, 1.0f); + *color_g = CLAMP(sum_g, 0.0f, 1.0f); + *color_b = CLAMP(sum_b, 0.0f, 1.0f); + *color_a = CLAMP(sum_a, 0.0f, 1.0f); + } +} + +KisPainter* KisMyPaintSurface::painter() { + return m_painter; +} + +MyPaintSurface* KisMyPaintSurface::surface() { + return m_surface; +} + +/*mypaint code*/ +qreal KisMyPaintSurface::calculateOpacity(float angle, float hardness, float opaque, float x, float y, + float xp, float yp, float aspect_ratio, float radius) { + + qreal cs = cos(angle/360*2*M_PI); + qreal sn = sin(angle/360*2*M_PI); + + qreal dx = xp - x; + qreal dy = yp - y; + qreal dyr = (dy*cs-dx*sn)*aspect_ratio; + qreal dxr = (dy*sn+dx*cs); + qreal dd = (dyr*dyr + dxr*dxr) / (radius*radius); + qreal opa; + + if (dd > 1) + opa = 0; + else if (dd < hardness) + opa = dd + 1-(dd/hardness); + else + opa = hardness/(1-hardness)*(1-dd); + + qreal pixel_opacity = opa * opaque; + return pixel_opacity; +} + +inline float KisMyPaintSurface::calculate_rr (int xp, + int yp, + float x, + float y, + float aspect_ratio, + float sn, + float cs, + float one_over_radius2) { + + const float yy = (yp + 0.5f - y); + const float xx = (xp + 0.5f - x); + const float yyr=(yy*cs-xx*sn)*aspect_ratio; + const float xxr=yy*sn+xx*cs; + const float rr = (yyr*yyr + xxr*xxr) * one_over_radius2; + /* rr is in range 0.0..1.0*sqrt(2) */ + return rr; +} + +static inline float +calculate_r_sample (float x, float y, float aspect_ratio, float sn, float cs) { + + const float yyr=(y*cs-x*sn)*aspect_ratio; + const float xxr=y*sn+x*cs; + const float r = (yyr*yyr + xxr*xxr); + return r; +} + +static inline float +sign_point_in_line (float px, float py, float vx, float vy) { + + return (px - vx) * (-vy) - (vx) * (py - vy); +} + +static inline void +closest_point_to_line (float lx, float ly, float px, float py, float *ox, float *oy) { + + const float l2 = lx*lx + ly*ly; + const float ltp_dot = px*lx + py*ly; + const float t = ltp_dot / l2; + *ox = lx * t; + *oy = ly * t; +} + + +/* This works by taking the visibility at the nearest point + * and dividing by 1.0 + delta. + * + * - nearest point: point where the dab has more influence + * - farthest point: point at a fixed distance away from + * the nearest point + * - delta: how much occluded is the farthest point relative + * to the nearest point + */ +inline float KisMyPaintSurface::calculate_rr_antialiased (int xp, int yp, float x, float y, + float aspect_ratio, float sn, float cs, float one_over_radius2, + float r_aa_start) { + + /* calculate pixel position and borders in a way + * that the dab's center is always at zero */ + float pixel_right = x - (float)xp; + float pixel_bottom = y - (float)yp; + float pixel_center_x = pixel_right - 0.5f; + float pixel_center_y = pixel_bottom - 0.5f; + float pixel_left = pixel_right - 1.0f; + float pixel_top = pixel_bottom - 1.0f; + + float nearest_x, nearest_y; /* nearest to origin, but still inside pixel */ + float farthest_x, farthest_y; /* farthest from origin, but still inside pixel */ + float r_near, r_far, rr_near, rr_far; + float center_sign, rad_area_1, visibilityNear, delta, delta2; + + /* Dab's center is inside pixel? */ + if( pixel_left<0 && pixel_right>0 && + pixel_top<0 && pixel_bottom>0 ) + { + nearest_x = 0; + nearest_y = 0; + r_near = rr_near = 0; + } + else + { + closest_point_to_line( cs, sn, pixel_center_x, pixel_center_y, &nearest_x, &nearest_y ); + nearest_x = CLAMP( nearest_x, pixel_left, pixel_right ); + nearest_y = CLAMP( nearest_y, pixel_top, pixel_bottom ); + /* XXX: precision of "nearest" values could be improved + * by intersecting the line that goes from nearest_x/Y to 0 + * with the pixel's borders here, however the improvements + * would probably not justify the perdormance cost. + */ + r_near = calculate_r_sample( nearest_x, nearest_y, aspect_ratio, sn, cs ); + rr_near = r_near * one_over_radius2; + } + + /* out of dab's reach? */ + if( rr_near > 1.0f ) + return rr_near; + + /* check on which side of the dab's line is the pixel center */ + center_sign = sign_point_in_line( pixel_center_x, pixel_center_y, cs, -sn ); + + /* radius of a circle with area=1 + * A = pi * r * r + * r = sqrt(1/pi) + */ + rad_area_1 = sqrtf( 1.0f / M_PI ); + + /* center is below dab */ + if( center_sign < 0 ) + { + farthest_x = nearest_x - sn*rad_area_1; + farthest_y = nearest_y + cs*rad_area_1; + } + /* above dab */ + else + { + farthest_x = nearest_x + sn*rad_area_1; + farthest_y = nearest_y - cs*rad_area_1; + } + + r_far = calculate_r_sample( farthest_x, farthest_y, aspect_ratio, sn, cs ); + rr_far = r_far * one_over_radius2; + + /* check if we can skip heavier AA */ + if( r_far < r_aa_start ) + return (rr_far+rr_near) * 0.5f; + + /* calculate AA approximate */ + visibilityNear = 1.0f - rr_near; + delta = rr_far - rr_near; + delta2 = 1.0f + delta; + visibilityNear /= delta2; + + return 1.0f - visibilityNear; +} +/* -- end mypaint code */ + +inline float KisMyPaintSurface::calculate_alpha_for_rr (float rr, float hardness, float slope1, float slope2) { + + if (rr > 1.0f) + return 0.0f; + else if (rr <= hardness) + return 1.0f + rr * slope1; + else + return rr * slope2 - slope2; +} diff --git a/plugins/paintops/mypaint/kis_mypaint_surface.h b/plugins/paintops/mypaint/kis_mypaint_surface.h new file mode 100644 index 0000000000..f511818b96 --- /dev/null +++ b/plugins/paintops/mypaint/kis_mypaint_surface.h @@ -0,0 +1,72 @@ +#ifndef KIS_MYPAINT_SURFACE_H +#define KIS_MYPAINT_SURFACE_H + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +class KisMyPaintSurface +{ +public: + + struct MyPaintSurfaceInternal: public MyPaintSurface { + KisMyPaintSurface *m_owner; + }; + +public: + KisMyPaintSurface(KisPainter* painter, KisNodeSP node=nullptr); + + /** + * mypaint_surface_draw_dab: + * + * Draw a dab onto the surface. + */ + static int draw_dab(MyPaintSurface *self, float x, float y, float radius, + float color_r, float color_g, float color_b, float opaque, float hardness, + float color_a, float aspect_ratio, float angle, float lock_alpha, + float colorize); + + static void get_color(MyPaintSurface *self, float x, float y, float radius, + float * color_r, float * color_g, float * color_b, float * color_a); + + int drawDabImpl(MyPaintSurface *self, float x, float y, float radius, float color_r, float color_g, + float color_b, float opaque, float hardness, float color_a, + float aspect_ratio, float angle, float lock_alpha, float colorize); + + void getColorImpl(MyPaintSurface *self, float x, float y, float radius, + float * color_r, float * color_g, float * color_b, float * color_a); + + inline float + calculate_rr_antialiased (int xp, int yp, float x, float y, float aspect_ratio, + float sn, float cs, float one_over_radius2, float r_aa_start); + + inline float + calculate_alpha_for_rr (float rr, float hardness, float slope1, float slope2); + + inline float + calculate_rr (int xp, int yp, float x, float y, float aspect_ratio, + float sn, float cs, float one_over_radius2); + + + KisPainter* painter(); + void paint(KoColor *color, KoColor* bgColor); + qreal calculateOpacity(float angle, float hardness, float opaque, float x, float y, + float xp, float yp, float aspect_ratio, float radius); + + MyPaintSurface* surface(); + +private: + KisPainter *m_painter; + KisNodeSP m_node; + MyPaintSurfaceInternal *m_surface; +}; + +#endif // KIS_MYPAINT_SURFACE_H diff --git a/plugins/paintops/mypaint/krita-mypaint.png b/plugins/paintops/mypaint/krita-mypaint.png new file mode 100644 index 0000000000..8e0a1b77c7 Binary files /dev/null and b/plugins/paintops/mypaint/krita-mypaint.png differ diff --git a/plugins/paintops/mypaint/kritamypaintop.json b/plugins/paintops/mypaint/kritamypaintop.json new file mode 100644 index 0000000000..e5355b9358 --- /dev/null +++ b/plugins/paintops/mypaint/kritamypaintop.json @@ -0,0 +1,9 @@ +{ + "Id": "MyPaint Brush", + "Type": "Service", + "X-KDE-Library": "kritamypaintop", + "X-KDE-ServiceTypes": [ + "Krita/Paintop" + ], + "X-Krita-Version": "28" +} diff --git a/plugins/paintops/mypaint/my_paintop_plugin.cpp b/plugins/paintops/mypaint/my_paintop_plugin.cpp new file mode 100644 index 0000000000..7b69633d7e --- /dev/null +++ b/plugins/paintops/mypaint/my_paintop_plugin.cpp @@ -0,0 +1,33 @@ +#include "my_paintop_plugin.h" + +#include + +#include +#include + +#include +#include +#include "kis_my_paintop.h" +#include "kis_my_paintop_settings.h" +#include "kis_my_paintop_settings_widget.h" +#include "kis_simple_paintop_factory.h" +#include + +#include "kis_global.h" + +K_PLUGIN_FACTORY_WITH_JSON(MyPaintOpPluginFactory, "kritamypaintop.json", registerPlugin();) + + +MyPaintOpPlugin::MyPaintOpPlugin(QObject *parent, const QVariantList &) + : QObject(parent) +{ + KisPaintOpRegistry *r = KisPaintOpRegistry::instance(); + //r->add(new KisSimplePaintOpFactory("mypaintbrush", i18n("MyPaint"), KisPaintOpFactory::categoryStable() , "krita-mypaint.png", QString(), QStringList(), 6)); + r->add(new KisMyPaintOpFactory()); +} + +MyPaintOpPlugin::~MyPaintOpPlugin() +{ +} + +#include "my_paintop_plugin.moc" diff --git a/plugins/paintops/mypaint/my_paintop_plugin.h b/plugins/paintops/mypaint/my_paintop_plugin.h new file mode 100644 index 0000000000..2cef13a477 --- /dev/null +++ b/plugins/paintops/mypaint/my_paintop_plugin.h @@ -0,0 +1,18 @@ +#ifndef MY_PAINTOP_PLUGIN_H_ +#define MY_PAINTOP_PLUGIN_H_ + +#include +#include + +/** + * A plugin wrapper that adds the paintop factories to the paintop registry. + */ +class MyPaintOpPlugin : public QObject +{ + Q_OBJECT +public: + MyPaintOpPlugin(QObject *parent, const QVariantList &); + ~MyPaintOpPlugin() override; +}; + +#endif // MY_PAINTOP_PLUGIN_H_ diff --git a/plugins/paintops/mypaint/tests/CMakeLists.txt b/plugins/paintops/mypaint/tests/CMakeLists.txt new file mode 100644 index 0000000000..28dfd68107 --- /dev/null +++ b/plugins/paintops/mypaint/tests/CMakeLists.txt @@ -0,0 +1,19 @@ +########### next target ############### +set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) +include_directories( ${CMAKE_SOURCE_DIR}/.. ${CMAKE_SOURCE_DIR}/sdk/tests ) +include_directories(${LIBMYPAINT_INCLUDE_DIR}) +link_directories(${LIBMYPAINT_LIBRARIES}) + +macro_add_unittest_definitions() + +include(KritaAddBrokenUnitTest) + +ecm_add_test(kis_mypaintop_test.cpp ../kis_my_paintop_settings.cpp ../kis_mypaint_brush.cpp ../kis_mypaint_surface.cpp + TEST_NAME KisMyPaintOpTest + NAME_PREFIX plugins-kismypaintop- + LINK_LIBRARIES kritaimage kritamypaintop kritalibpaintop mypaint Qt5::Test) + +#krita_add_broken_unit_test(kis_embedded_pattern_manager_test.cpp +# NAME_PREFIX plugins-libpaintop- +# LINK_LIBRARIES kritaimage kritalibpaintop Qt5::Test) + diff --git a/plugins/paintops/mypaint/tests/data/draw_dab.png b/plugins/paintops/mypaint/tests/data/draw_dab.png new file mode 100644 index 0000000000..747fd7a650 Binary files /dev/null and b/plugins/paintops/mypaint/tests/data/draw_dab.png differ diff --git a/plugins/paintops/mypaint/tests/kis_mypaintop_test.cpp b/plugins/paintops/mypaint/tests/kis_mypaintop_test.cpp new file mode 100644 index 0000000000..b73c0133b0 --- /dev/null +++ b/plugins/paintops/mypaint/tests/kis_mypaintop_test.cpp @@ -0,0 +1,82 @@ +#include "kis_mypaintop_test.h" +#include +#include "qimage_based_test.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class KisMyPaintOpSettings; +KisMyPaintOpTest::KisMyPaintOpTest(): TestUtil::QImageBasedTest("MyPaintOp") +{ + +} + +void KisMyPaintOpTest::testDab() { + + KisImageSP image = createTrivialImage(new KisSurrogateUndoStore()); + image->initialRefreshGraph(); + + KisNodeSP paintNode = findNode(image->root(), "paint1"); + KisPainter gc(paintNode->paintDevice()); + + KisPaintDeviceSP dst = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb16()); + KisPainter painter(paintNode->paintDevice()); + + mypaint_brush_new(); + + QScopedPointer surface(new KisMyPaintSurface(&painter, paintNode)); + + surface->draw_dab(surface->surface(), 250, 250, 100, 0, 0, 1, 1, 0.8, 1, 1, 90, 0, 0); + + QImage img = paintNode->paintDevice()->convertToQImage(0, image->bounds().x(), image->bounds().y(), image->bounds().width(), image->bounds().height()); + QImage source(QString(FILES_DATA_DIR) + QDir::separator() + "draw_dab.png"); + + QVERIFY(img == source); +} + +void KisMyPaintOpTest::testGetColor() { + + KisImageSP image = createTrivialImage(new KisSurrogateUndoStore()); + image->initialRefreshGraph(); + + KisNodeSP paintNode = findNode(image->root(), "paint1"); + KisPainter gc(paintNode->paintDevice()); + + KisPaintDeviceSP dst = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb16()); + KisPainter painter(paintNode->paintDevice()); + + mypaint_brush_new(); + + QScopedPointer surface(new KisMyPaintSurface(&painter, paintNode)); + + surface->draw_dab(surface->surface(), 250, 250, 100, 0, 0, 1, 1, 0.8, 1, 1, 90, 0, 0); + + QImage img = paintNode->paintDevice()->convertToQImage(0, image->bounds().x(), image->bounds().y(), image->bounds().width(), image->bounds().height()); + QImage source(QString(FILES_DATA_DIR) + QDir::separator() + "draw_dab.png"); + + QVERIFY(img == source); + + float r = 0.0f; + float g = 0.0f; + float b = 0.0f; + float a = 0.0f; + + surface->get_color(surface->surface(), 250, 250, 100, &r, &g, &b, &a); + + QVERIFY(qFuzzyCompare((float)qRound(r), 0.0L)); + QVERIFY(qFuzzyCompare((float)qRound(g), 0.0L)); + QVERIFY(qFuzzyCompare((float)qRound(b), 1.0L)); + QVERIFY(qFuzzyCompare((float)qRound(a), 1.0L)); +} + +QTEST_MAIN(KisMyPaintOpTest) diff --git a/plugins/paintops/mypaint/tests/kis_mypaintop_test.h b/plugins/paintops/mypaint/tests/kis_mypaintop_test.h new file mode 100644 index 0000000000..1ff85f5032 --- /dev/null +++ b/plugins/paintops/mypaint/tests/kis_mypaintop_test.h @@ -0,0 +1,24 @@ +#ifndef KIS_MYPAINTOP_TEST_H +#define KIS_MYPAINTOP_TEST_H + +#include +#include +#include +#include +#include + +class KisMyPaintOpTest: public QObject, public TestUtil::QImageBasedTest +{ + Q_OBJECT +public: + KisMyPaintOpTest(); + virtual ~KisMyPaintOpTest() {} + +private Q_SLOTS: + void testDab(); + void testGetColor(); + +}; + +#include "kis_mypaintop_test.moc" +#endif // KIS_MYPAINTOP_TEST_H