Compare commits
81 commits
mia
...
dev-upgrad
Author | SHA1 | Date | |
---|---|---|---|
|
6b41659178 | ||
|
186c98308e | ||
|
7c500a096a | ||
|
bd4c7789cf | ||
|
3eff75d56e | ||
|
da699f124e | ||
|
1204a3be85 | ||
|
9e6b7e94c0 | ||
|
ad02d39f44 | ||
|
d914ad72b5 | ||
|
055aa379e5 | ||
|
97792e15a8 | ||
|
4a874de442 | ||
|
5d14137710 | ||
|
d252dcf32d | ||
|
4f351b8b4a | ||
|
c4e0f40370 | ||
|
05c0ba0e46 | ||
|
e4e04c9e87 | ||
|
81160b2ec0 | ||
|
bf28e7efc3 | ||
|
c2c44f1ad2 | ||
|
5dd201bc2d | ||
|
3663d118b6 | ||
|
60a722db31 | ||
|
d65643ddee | ||
|
fbca222295 | ||
|
3225ae39f4 | ||
|
888be0607f | ||
|
4200b85fb4 | ||
|
0b8b286767 | ||
|
139132a964 | ||
|
4a3689d6e7 | ||
|
248e69a9b6 | ||
|
46474e0319 | ||
|
50544cf749 | ||
|
e9a68f22b9 | ||
|
d6ddea0f65 | ||
|
2bbed6c5a0 | ||
|
592250eeaa | ||
|
8f40ca44ce | ||
|
f776db2d2b | ||
|
f9ffc46bf6 | ||
|
019e68147e | ||
|
f733297499 | ||
|
4c6d370d51 | ||
|
b7c640d061 | ||
|
2c06f03f5b | ||
|
1819fc8d8b | ||
|
ba54e8d12f | ||
|
c76e410d30 | ||
|
bb2cfb1fcd | ||
|
9abcc03202 | ||
|
837d5a41d7 | ||
|
875456c803 | ||
|
9ddecfdd46 | ||
|
70f27eae4b | ||
|
8d2ef3fca7 | ||
|
48869ae0ad | ||
|
b00285cf71 | ||
|
c6c9e05406 | ||
|
fc1a78aeca | ||
|
38bb1790ab | ||
|
fff08c4650 | ||
|
163d57d6a2 | ||
|
6266867586 | ||
|
4431f678ce | ||
|
419386aadd | ||
|
c4cce28766 | ||
|
1ae2f60b9a | ||
|
b6eebcd7ef | ||
|
bf55264e6d | ||
|
34575a9786 | ||
|
69310d40ae | ||
|
657d9d5149 | ||
|
043a45cf91 | ||
|
ad15c53fb1 | ||
|
841a35a6fd | ||
|
ee7dc6af4e | ||
|
77da2436c5 | ||
|
7be2325629 |
367 changed files with 46641 additions and 23581 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -5,6 +5,7 @@
|
|||
*.bz2
|
||||
*.cache
|
||||
*.dep
|
||||
*.db
|
||||
*.dll
|
||||
*.dmg
|
||||
*.exe
|
||||
|
@ -14,6 +15,7 @@
|
|||
*.ilk
|
||||
*.log
|
||||
*.manifest
|
||||
!src/dpi_aware.manifest
|
||||
*.mkv
|
||||
*.mo
|
||||
*.ncb
|
||||
|
@ -86,3 +88,4 @@ vendor/luajit/src/lj_vm.s
|
|||
vendor/luajit/src/luajit
|
||||
|
||||
.nuget
|
||||
.vs
|
||||
|
|
80
.travis.yml
80
.travis.yml
|
@ -1,5 +1,5 @@
|
|||
sudo: required
|
||||
dist: trusty
|
||||
dist: bionic
|
||||
language: cpp
|
||||
|
||||
git:
|
||||
|
@ -8,58 +8,68 @@ git:
|
|||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.kitware.com/ubuntu/ bionic main'
|
||||
key_url: 'https://apt.kitware.com/keys/kitware-archive-latest.asc'
|
||||
packages:
|
||||
- libasound2-dev
|
||||
- libfftw3-dev
|
||||
- libhunspell-dev
|
||||
- yasm
|
||||
- libfribidi-dev
|
||||
- libass-dev
|
||||
- libicu-dev
|
||||
- luarocks
|
||||
- g++-5
|
||||
- cmake
|
||||
- build-essential
|
||||
- libboost-all-dev
|
||||
- libffms2-dev
|
||||
- libfontconfig1-dev
|
||||
- libopenal-dev
|
||||
- libuchardet-dev
|
||||
- libwxgtk3.0-dev
|
||||
- portaudio19-dev
|
||||
- libpulse-dev
|
||||
- autopoint
|
||||
- libgtest-dev
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- compiler: gcc
|
||||
env: BOOST_VERSION=55
|
||||
- compiler: gcc
|
||||
env: BOOST_VERSION=60
|
||||
before_install:
|
||||
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 60 --slave /usr/bin/g++ g++ /usr/bin/g++-5 --slave /usr/bin/gcov gcov /usr/bin/gcov-5
|
||||
- {}
|
||||
- env: BUILD_SUIT=autotools
|
||||
|
||||
install:
|
||||
# Can't install these via the apt addon due to the whitelist
|
||||
- sudo apt-get install -y -qq libffms2-dev libwxgtk3.0-dev libuchardet-dev
|
||||
|
||||
- sudo pip install cpp-coveralls
|
||||
- sudo luarocks install busted > /dev/null
|
||||
- sudo luarocks install moonscript > /dev/null
|
||||
- sudo luarocks install uuid > /dev/null
|
||||
|
||||
- git submodule --quiet init
|
||||
- git submodule --quiet update vendor/googletest
|
||||
|
||||
- cd vendor
|
||||
- rm -rf boost
|
||||
- wget http://sourceforge.net/projects/boost/files/boost/1.${BOOST_VERSION}.0/boost_1_${BOOST_VERSION}_0.tar.bz2/download
|
||||
- tar xjf download
|
||||
- mv boost_1_${BOOST_VERSION}_0 boost
|
||||
- cd boost
|
||||
- ./bootstrap.sh
|
||||
- ./b2 -j3 -layout=system threading=multi cxxflags=-std=c++11 link=shared variant=release --without-python --without-iostreams --without-serialization --without-graph --without-log --without-math --without-signals --without-test --without-wave --without-mpi --without-program_options --without-graph_parallel --without-context --without-coroutine --without-random --without-timer --without-date_time
|
||||
- cd ../..
|
||||
# Remove the CMake provided by travis
|
||||
- sudo rm -rf /usr/local/cmake*
|
||||
- if [ "$BUILD_SUIT" = "autotools" ]; then
|
||||
sudo pip install -U cpp-coveralls;
|
||||
git submodule --quiet init;
|
||||
git submodule --quiet update vendor/googletest;
|
||||
else
|
||||
pushd /usr/src/googletest;
|
||||
sudo cmake .;
|
||||
sudo make install -j2;
|
||||
popd;
|
||||
fi
|
||||
|
||||
script:
|
||||
- export CPATH=$(pwd)/vendor/boost
|
||||
- export LD_LIBRARY_PATH=$(pwd)/vendor/boost/stage/lib:$LD_LIBRARY_PATH
|
||||
- export CPPFLAGS="-fprofile-arcs -ftest-coverage"
|
||||
- export LIBS="-lgcov"
|
||||
- autoreconf -if
|
||||
- ./configure BOOST_LDFLAGS="-L$(pwd)/vendor/boost/stage/lib" --enable-debug || cat config.log
|
||||
- make -j3 all test
|
||||
- coveralls --exclude vendor --exclude src --exclude build --exclude tools --exclude libaegisub/windows > /dev/null
|
||||
- if [ "$BUILD_SUIT" = "autotools" ]; then
|
||||
export CPPFLAGS="-fprofile-arcs -ftest-coverage";
|
||||
export LIBS="-lgcov";
|
||||
./autogen.sh;
|
||||
./configure --enable-debug agi_cv_with_openal=yes || cat config.log;
|
||||
make -j2;
|
||||
make test || travis_terminate 1;
|
||||
coveralls --exclude vendor --exclude src --exclude build --exclude tools --exclude libaegisub/windows > /dev/null;
|
||||
else
|
||||
./build/version.sh .;
|
||||
mkdir build-dir;
|
||||
cd build-dir;
|
||||
cmake -DCMAKE_CXX_FLAGS='-Wall -Wextra -Wno-unused-parameter -pedantic' -DCMAKE_C_FLAGS='-Wall' -DWITH_STARTUPLOG=ON -DWITH_TEST=ON ..;
|
||||
make -j2;
|
||||
make test || travis_terminate 1;
|
||||
fi
|
||||
|
||||
notifications:
|
||||
email:
|
||||
|
|
78
CMakeLists.test.txt
Normal file
78
CMakeLists.test.txt
Normal file
|
@ -0,0 +1,78 @@
|
|||
if(UNIX)
|
||||
add_executable(aegisub-lua EXCLUDE_FROM_ALL
|
||||
automation/tests/aegisub.cpp
|
||||
)
|
||||
target_include_directories(aegisub-lua PRIVATE ${Boost_INCLUDE_DIRS})
|
||||
target_link_directories(aegisub-lua PRIVATE ${Boost_LIBRARY_DIRS})
|
||||
target_link_libraries(aegisub-lua libaegisub luabins luajit ${Boost_LIBRARIES} ${ICU_LIBRARIES})
|
||||
add_custom_target(test-automation
|
||||
COMMAND sh -c "$(luarocks path); ${PROJECT_BINARY_DIR}/aegisub-lua tests/busted.lua -p moon tests/modules"
|
||||
VERBATIM
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/automation"
|
||||
)
|
||||
add_dependencies(test-automation aegisub-lua)
|
||||
else()
|
||||
add_custom_target(test-automation)
|
||||
endif()
|
||||
|
||||
find_package(GTest)
|
||||
if(GTEST_FOUND)
|
||||
add_executable(gtest-run EXCLUDE_FROM_ALL
|
||||
tests/tests/access.cpp
|
||||
tests/tests/audio.cpp
|
||||
tests/tests/cajun.cpp
|
||||
tests/tests/calltip_provider.cpp
|
||||
tests/tests/character_count.cpp
|
||||
tests/tests/color.cpp
|
||||
tests/tests/dialogue_lexer.cpp
|
||||
tests/tests/format.cpp
|
||||
tests/tests/fs.cpp
|
||||
tests/tests/hotkey.cpp
|
||||
tests/tests/iconv.cpp
|
||||
tests/tests/ifind.cpp
|
||||
tests/tests/karaoke_matcher.cpp
|
||||
tests/tests/keyframe.cpp
|
||||
tests/tests/line_iterator.cpp
|
||||
tests/tests/line_wrap.cpp
|
||||
tests/tests/mru.cpp
|
||||
tests/tests/option.cpp
|
||||
tests/tests/path.cpp
|
||||
tests/tests/signals.cpp
|
||||
tests/tests/split.cpp
|
||||
tests/tests/syntax_highlight.cpp
|
||||
tests/tests/thesaurus.cpp
|
||||
tests/tests/time.cpp
|
||||
tests/tests/type_name.cpp
|
||||
tests/tests/util.cpp
|
||||
tests/tests/uuencode.cpp
|
||||
tests/tests/vfr.cpp
|
||||
tests/tests/word_split.cpp
|
||||
tests/support/main.cpp
|
||||
tests/support/util.cpp
|
||||
)
|
||||
target_compile_definitions(gtest-run PRIVATE CMAKE_BUILD)
|
||||
target_include_directories(gtest-run PRIVATE tests/support ${GTEST_INCLUDE_DIRS})
|
||||
target_link_libraries(gtest-run libaegisub ${Boost_LIBRARIES} ${ICU_LIBRARIES} ${GTEST_LIBRARIES})
|
||||
if(MSVC)
|
||||
set_target_properties(gtest-run PROPERTIES COMPILE_FLAGS "/Yu${PROJECT_SOURCE_DIR}/tests/support/tests_pre.h" COMPILE_FLAGS "/FI${PROJECT_SOURCE_DIR}/tests/support/tests_pre.h")
|
||||
else()
|
||||
target_compile_options(gtest-run PRIVATE -include "${PROJECT_SOURCE_DIR}/tests/support/tests_pre.h")
|
||||
endif()
|
||||
if(WIN32)
|
||||
add_custom_target(test-aegisub
|
||||
COMMAND "${PROJECT_SOURCE_DIR}/tests/setup.bat"
|
||||
COMMAND gtest-run
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/tests"
|
||||
)
|
||||
else()
|
||||
add_custom_target(test-aegisub
|
||||
COMMAND "${PROJECT_SOURCE_DIR}/tests/setup.sh"
|
||||
COMMAND gtest-run
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/tests"
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
add_custom_target(test-aegisub)
|
||||
endif()
|
||||
|
||||
add_custom_target(test DEPENDS test-automation test-aegisub)
|
809
CMakeLists.txt
Normal file
809
CMakeLists.txt
Normal file
|
@ -0,0 +1,809 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
|
||||
project(Aegisub)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
include_directories("build")
|
||||
include_directories("libaegisub/include")
|
||||
include_directories("vendor/luajit/src")
|
||||
|
||||
add_library(libaegisub STATIC
|
||||
libaegisub/common/parser.cpp
|
||||
libaegisub/ass/dialogue_parser.cpp
|
||||
libaegisub/ass/time.cpp
|
||||
libaegisub/ass/uuencode.cpp
|
||||
libaegisub/audio/provider.cpp
|
||||
libaegisub/audio/provider_convert.cpp
|
||||
libaegisub/audio/provider_dummy.cpp
|
||||
libaegisub/audio/provider_hd.cpp
|
||||
libaegisub/audio/provider_lock.cpp
|
||||
libaegisub/audio/provider_pcm.cpp
|
||||
libaegisub/audio/provider_ram.cpp
|
||||
libaegisub/common/cajun/elements.cpp
|
||||
libaegisub/common/cajun/reader.cpp
|
||||
libaegisub/common/cajun/writer.cpp
|
||||
libaegisub/lua/modules/lfs.cpp
|
||||
libaegisub/lua/modules/re.cpp
|
||||
libaegisub/lua/modules/unicode.cpp
|
||||
libaegisub/lua/modules/lpeg.c
|
||||
libaegisub/lua/modules.cpp
|
||||
libaegisub/lua/script_reader.cpp
|
||||
libaegisub/lua/utils.cpp
|
||||
libaegisub/common/calltip_provider.cpp
|
||||
libaegisub/common/character_count.cpp
|
||||
libaegisub/common/charset.cpp
|
||||
libaegisub/common/charset_6937.cpp
|
||||
libaegisub/common/charset_conv.cpp
|
||||
libaegisub/common/color.cpp
|
||||
libaegisub/common/file_mapping.cpp
|
||||
libaegisub/common/format.cpp
|
||||
libaegisub/common/fs.cpp
|
||||
libaegisub/common/hotkey.cpp
|
||||
libaegisub/common/io.cpp
|
||||
libaegisub/common/json.cpp
|
||||
libaegisub/common/kana_table.cpp
|
||||
libaegisub/common/karaoke_matcher.cpp
|
||||
libaegisub/common/keyframe.cpp
|
||||
libaegisub/common/line_iterator.cpp
|
||||
libaegisub/common/log.cpp
|
||||
libaegisub/common/mru.cpp
|
||||
libaegisub/common/option.cpp
|
||||
libaegisub/common/option_value.cpp
|
||||
libaegisub/common/path.cpp
|
||||
libaegisub/common/thesaurus.cpp
|
||||
libaegisub/common/util.cpp
|
||||
libaegisub/common/vfr.cpp
|
||||
libaegisub/common/ycbcr_conv.cpp
|
||||
libaegisub/common/dispatch.cpp
|
||||
)
|
||||
if(UNIX)
|
||||
target_sources(libaegisub PRIVATE
|
||||
libaegisub/unix/access.cpp
|
||||
libaegisub/unix/fs.cpp
|
||||
libaegisub/unix/log.cpp
|
||||
libaegisub/unix/path.cpp
|
||||
libaegisub/unix/util.cpp
|
||||
)
|
||||
set_property(
|
||||
SOURCE libaegisub/unix/path.cpp
|
||||
PROPERTY COMPILE_DEFINITIONS
|
||||
P_DATA="${CMAKE_INSTALL_PREFIX}/share/aegisub/"
|
||||
)
|
||||
elseif(WIN32)
|
||||
target_sources(libaegisub PRIVATE
|
||||
libaegisub/windows/access.cpp
|
||||
libaegisub/windows/charset_conv_win.cpp
|
||||
libaegisub/windows/fs.cpp
|
||||
libaegisub/windows/lagi_pre.cpp
|
||||
libaegisub/windows/log_win.cpp
|
||||
libaegisub/windows/path_win.cpp
|
||||
libaegisub/windows/util_win.cpp
|
||||
)
|
||||
endif()
|
||||
set_target_properties(libaegisub PROPERTIES PREFIX "")
|
||||
target_compile_definitions(libaegisub PRIVATE CMAKE_BUILD)
|
||||
|
||||
add_library(luabins STATIC
|
||||
vendor/luabins/src/fwrite.c
|
||||
vendor/luabins/src/load.c
|
||||
vendor/luabins/src/luabins.c
|
||||
vendor/luabins/src/luainternals.c
|
||||
vendor/luabins/src/save.c
|
||||
vendor/luabins/src/savebuffer.c
|
||||
vendor/luabins/src/write.c
|
||||
)
|
||||
|
||||
add_executable(luajit-minilua vendor/luajit/src/host/minilua.c)
|
||||
if(NOT WIN32)
|
||||
target_link_libraries(luajit-minilua m)
|
||||
endif()
|
||||
if(WIN32)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen/buildvm_arch.h
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen
|
||||
COMMAND luajit-minilua ../dynasm/dynasm.lua -LN -D WIN -D JIT -D FFI -D P64 -o gen/buildvm_arch.h vm_x86.dasc
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
else()
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen/buildvm_arch.h
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen
|
||||
COMMAND luajit-minilua ../dynasm/dynasm.lua -LN -D WIN -D JIT -D FFI -o gen/buildvm_arch.h vm_x86.dasc
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen/buildvm_arch.h
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen
|
||||
COMMAND luajit-minilua ../dynasm/dynasm.lua -D P64 -D JIT -D FFI -D FPU -D HFABI -D VER= -o gen/buildvm_arch.h vm_x86.dasc
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
else()
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen/buildvm_arch.h
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen
|
||||
COMMAND luajit-minilua ../dynasm/dynasm.lua -D JIT -D FFI -D FPU -D HFABI -D VER= -o gen/buildvm_arch.h vm_x86.dasc
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/src/libresrc/default_config.cpp ${PROJECT_SOURCE_DIR}/src/libresrc/default_config.h
|
||||
DEPENDS ${PROJECT_SOURCE_DIR}/src/libresrc/default_config_platform.json
|
||||
COMMAND luajit-minilua ../../tools/respack.lua manifest.respack default_config.cpp default_config.h
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/libresrc
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/src/libresrc/bitmap.cpp ${PROJECT_SOURCE_DIR}/src/libresrc/bitmap.h
|
||||
COMMAND luajit-minilua ../../tools/respack.lua manifest.respack ../libresrc/bitmap.cpp ../libresrc/bitmap.h
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bitmaps
|
||||
)
|
||||
|
||||
add_executable(luajit-buildvm
|
||||
vendor/luajit/src/host/buildvm.c
|
||||
vendor/luajit/src/host/buildvm_asm.c
|
||||
vendor/luajit/src/host/buildvm_peobj.c
|
||||
vendor/luajit/src/host/buildvm_lib.c
|
||||
vendor/luajit/src/host/buildvm_fold.c
|
||||
|
||||
vendor/luajit/src/gen/buildvm_arch.h
|
||||
)
|
||||
target_compile_definitions(luajit-buildvm PRIVATE LUAJIT_ENABLE_LUA52COMPAT)
|
||||
target_include_directories(luajit-buildvm PRIVATE vendor/luajit/src vendor/luajit/src/gen)
|
||||
if(UNIX)
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/vendor/luajit/src/lj_vm.s
|
||||
COMMAND luajit-buildvm -m elfasm -o lj_vm.s
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
elseif(MSVC)
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/vendor/luajit/src/lj_vm.obj
|
||||
COMMAND luajit-buildvm -m peobj -o lj_vm.obj
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen/lj_ffdef.h
|
||||
COMMAND luajit-buildvm -m ffdef -o gen/lj_ffdef.h lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen/lj_bcdef.h
|
||||
COMMAND luajit-buildvm -m bcdef -o gen/lj_bcdef.h lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen/lj_folddef.h
|
||||
COMMAND luajit-buildvm -m folddef -o gen/lj_folddef.h lj_opt_fold.c
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen/lj_recdef.h
|
||||
COMMAND luajit-buildvm -m recdef -o gen/lj_recdef.h lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen/lj_libdef.h
|
||||
COMMAND luajit-buildvm -m libdef -o gen/lj_libdef.h lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/vendor/luajit/src/jit/vmdef.lua
|
||||
COMMAND luajit-buildvm -m vmdef -o jit/vmdef.lua lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
|
||||
add_library(luajit STATIC
|
||||
vendor/luajit/src/lib_base.c
|
||||
vendor/luajit/src/lib_math.c
|
||||
vendor/luajit/src/lib_bit.c
|
||||
vendor/luajit/src/lib_string.c
|
||||
vendor/luajit/src/lib_table.c
|
||||
vendor/luajit/src/lib_io.c
|
||||
vendor/luajit/src/lib_os.c
|
||||
vendor/luajit/src/lib_package.c
|
||||
vendor/luajit/src/lib_debug.c
|
||||
vendor/luajit/src/lib_jit.c
|
||||
vendor/luajit/src/lib_ffi.c
|
||||
vendor/luajit/src/lj_gc.c
|
||||
vendor/luajit/src/lj_err.c
|
||||
vendor/luajit/src/lj_char.c
|
||||
vendor/luajit/src/lj_bc.c
|
||||
vendor/luajit/src/lj_obj.c
|
||||
vendor/luajit/src/lj_buf.c
|
||||
vendor/luajit/src/lj_str.c
|
||||
vendor/luajit/src/lj_tab.c
|
||||
vendor/luajit/src/lj_func.c
|
||||
vendor/luajit/src/lj_udata.c
|
||||
vendor/luajit/src/lj_meta.c
|
||||
vendor/luajit/src/lj_debug.c
|
||||
vendor/luajit/src/lj_state.c
|
||||
vendor/luajit/src/lj_dispatch.c
|
||||
vendor/luajit/src/lj_vmevent.c
|
||||
vendor/luajit/src/lj_vmmath.c
|
||||
vendor/luajit/src/lj_strscan.c
|
||||
vendor/luajit/src/lj_strfmt.c
|
||||
vendor/luajit/src/lj_strfmt_num.c
|
||||
vendor/luajit/src/lj_api.c
|
||||
vendor/luajit/src/lj_profile.c
|
||||
vendor/luajit/src/lj_lex.c
|
||||
vendor/luajit/src/lj_parse.c
|
||||
vendor/luajit/src/lj_bcread.c
|
||||
vendor/luajit/src/lj_bcwrite.c
|
||||
vendor/luajit/src/lj_load.c
|
||||
vendor/luajit/src/lj_ir.c
|
||||
vendor/luajit/src/lj_opt_mem.c
|
||||
vendor/luajit/src/lj_opt_fold.c
|
||||
vendor/luajit/src/lj_opt_narrow.c
|
||||
vendor/luajit/src/lj_opt_dce.c
|
||||
vendor/luajit/src/lj_opt_loop.c
|
||||
vendor/luajit/src/lj_opt_split.c
|
||||
vendor/luajit/src/lj_opt_sink.c
|
||||
vendor/luajit/src/lj_mcode.c
|
||||
vendor/luajit/src/lj_snap.c
|
||||
vendor/luajit/src/lj_record.c
|
||||
vendor/luajit/src/lj_crecord.c
|
||||
vendor/luajit/src/lj_ffrecord.c
|
||||
vendor/luajit/src/lj_asm.c
|
||||
vendor/luajit/src/lj_trace.c
|
||||
vendor/luajit/src/lj_gdbjit.c
|
||||
vendor/luajit/src/lj_ctype.c
|
||||
vendor/luajit/src/lj_cdata.c
|
||||
vendor/luajit/src/lj_cconv.c
|
||||
vendor/luajit/src/lj_ccall.c
|
||||
vendor/luajit/src/lj_ccallback.c
|
||||
vendor/luajit/src/lj_carith.c
|
||||
vendor/luajit/src/lj_clib.c
|
||||
vendor/luajit/src/lj_cparse.c
|
||||
vendor/luajit/src/lj_lib.c
|
||||
vendor/luajit/src/lj_alloc.c
|
||||
vendor/luajit/src/lib_aux.c
|
||||
vendor/luajit/src/lib_init.c
|
||||
|
||||
vendor/luajit/src/gen/lj_ffdef.h
|
||||
vendor/luajit/src/gen/lj_bcdef.h
|
||||
vendor/luajit/src/gen/lj_folddef.h
|
||||
vendor/luajit/src/gen/lj_recdef.h
|
||||
vendor/luajit/src/gen/lj_libdef.h
|
||||
vendor/luajit/src/jit/vmdef.lua
|
||||
)
|
||||
target_compile_definitions(luajit PRIVATE LUAJIT_ENABLE_LUA52COMPAT)
|
||||
target_include_directories(luajit PRIVATE vendor/luajit/src/gen)
|
||||
if(MSVC)
|
||||
target_sources(luajit PRIVATE vendor/luajit/src/lj_vm.obj)
|
||||
else()
|
||||
target_sources(luajit PRIVATE vendor/luajit/src/lj_vm.s)
|
||||
set_property(SOURCE vendor/luajit/src/lj_vm.s PROPERTY LANGUAGE C)
|
||||
target_link_libraries(luajit ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
add_library(resrc STATIC
|
||||
src/libresrc/bitmap.cpp
|
||||
src/libresrc/default_config.cpp
|
||||
src/libresrc/libresrc.cpp
|
||||
)
|
||||
|
||||
add_library(csri STATIC
|
||||
vendor/csri/lib/list.c
|
||||
vendor/csri/lib/wrap.c
|
||||
vendor/csri/subhelp/logging.c
|
||||
)
|
||||
target_include_directories(csri PRIVATE "vendor/csri/include")
|
||||
if(WIN32)
|
||||
target_include_directories(csri PRIVATE "vendor/csri/lib/win32")
|
||||
target_sources(csri PRIVATE vendor/csri/lib/win32/enumerate.c)
|
||||
else()
|
||||
target_include_directories(csri PRIVATE "vendor/csri/lib/posix")
|
||||
target_sources(csri PRIVATE vendor/csri/lib/posix/enumerate.c)
|
||||
endif()
|
||||
|
||||
add_executable(Aegisub WIN32
|
||||
src/command/app.cpp
|
||||
src/command/audio.cpp
|
||||
src/command/automation.cpp
|
||||
src/command/command.cpp
|
||||
src/command/edit.cpp
|
||||
src/command/grid.cpp
|
||||
src/command/help.cpp
|
||||
src/command/keyframe.cpp
|
||||
src/command/recent.cpp
|
||||
src/command/subtitle.cpp
|
||||
src/command/time.cpp
|
||||
src/command/timecode.cpp
|
||||
src/command/tool.cpp
|
||||
src/command/video.cpp
|
||||
src/command/vis_tool.cpp
|
||||
src/dialog_about.cpp
|
||||
src/dialog_align.cpp
|
||||
src/dialog_attachments.cpp
|
||||
src/dialog_automation.cpp
|
||||
src/dialog_autosave.cpp
|
||||
src/dialog_colorpicker.cpp
|
||||
src/dialog_detached_video.cpp
|
||||
src/dialog_dummy_video.cpp
|
||||
src/dialog_export.cpp
|
||||
src/dialog_export_ebu3264.cpp
|
||||
src/dialog_fonts_collector.cpp
|
||||
src/dialog_jumpto.cpp
|
||||
src/dialog_kara_timing_copy.cpp
|
||||
src/dialog_log.cpp
|
||||
src/dialog_paste_over.cpp
|
||||
src/dialog_progress.cpp
|
||||
src/dialog_properties.cpp
|
||||
src/dialog_resample.cpp
|
||||
src/dialog_search_replace.cpp
|
||||
src/dialog_selected_choices.cpp
|
||||
src/dialog_selection.cpp
|
||||
src/dialog_shift_times.cpp
|
||||
src/dialog_spellchecker.cpp
|
||||
src/dialog_style_editor.cpp
|
||||
src/dialog_style_manager.cpp
|
||||
src/dialog_styling_assistant.cpp
|
||||
src/dialog_text_import.cpp
|
||||
src/dialog_timing_processor.cpp
|
||||
src/dialog_translation.cpp
|
||||
src/dialog_video_details.cpp
|
||||
src/dialog_video_properties.cpp
|
||||
src/subtitle_format.cpp
|
||||
src/subtitle_format_ass.cpp
|
||||
src/subtitle_format_ebu3264.cpp
|
||||
src/subtitle_format_encore.cpp
|
||||
src/subtitle_format_microdvd.cpp
|
||||
src/subtitle_format_mkv.cpp
|
||||
src/subtitle_format_srt.cpp
|
||||
src/subtitle_format_ssa.cpp
|
||||
src/subtitle_format_transtation.cpp
|
||||
src/subtitle_format_ttxt.cpp
|
||||
src/subtitle_format_txt.cpp
|
||||
src/visual_tool.cpp
|
||||
src/visual_tool_clip.cpp
|
||||
src/visual_tool_cross.cpp
|
||||
src/visual_tool_drag.cpp
|
||||
src/visual_tool_rotatexy.cpp
|
||||
src/visual_tool_rotatez.cpp
|
||||
src/visual_tool_scale.cpp
|
||||
src/visual_tool_vector_clip.cpp
|
||||
src/MatroskaParser.c
|
||||
src/aegisublocale.cpp
|
||||
src/ass_attachment.cpp
|
||||
src/ass_dialogue.cpp
|
||||
src/ass_entry.cpp
|
||||
src/ass_export_filter.cpp
|
||||
src/ass_exporter.cpp
|
||||
src/ass_file.cpp
|
||||
src/ass_karaoke.cpp
|
||||
src/ass_override.cpp
|
||||
src/ass_parser.cpp
|
||||
src/ass_style.cpp
|
||||
src/ass_style_storage.cpp
|
||||
src/async_video_provider.cpp
|
||||
src/audio_box.cpp
|
||||
src/audio_colorscheme.cpp
|
||||
src/audio_controller.cpp
|
||||
src/audio_display.cpp
|
||||
src/audio_karaoke.cpp
|
||||
src/audio_marker.cpp
|
||||
src/audio_player.cpp
|
||||
src/audio_provider_factory.cpp
|
||||
src/audio_renderer.cpp
|
||||
src/audio_renderer_spectrum.cpp
|
||||
src/audio_renderer_waveform.cpp
|
||||
src/audio_timing_dialogue.cpp
|
||||
src/audio_timing_karaoke.cpp
|
||||
src/auto4_base.cpp
|
||||
src/auto4_lua.cpp
|
||||
src/auto4_lua_assfile.cpp
|
||||
src/auto4_lua_dialog.cpp
|
||||
src/auto4_lua_progresssink.cpp
|
||||
src/base_grid.cpp
|
||||
src/charset_detect.cpp
|
||||
src/colorspace.cpp
|
||||
src/colour_button.cpp
|
||||
src/compat.cpp
|
||||
src/context.cpp
|
||||
src/export_fixstyle.cpp
|
||||
src/export_framerate.cpp
|
||||
src/fft.cpp
|
||||
src/font_file_lister.cpp
|
||||
src/frame_main.cpp
|
||||
src/gl_text.cpp
|
||||
src/gl_wrap.cpp
|
||||
src/grid_column.cpp
|
||||
src/help_button.cpp
|
||||
src/hotkey.cpp
|
||||
src/hotkey_data_view_model.cpp
|
||||
src/image_position_picker.cpp
|
||||
src/initial_line_state.cpp
|
||||
src/main.cpp
|
||||
src/menu.cpp
|
||||
src/mkv_wrap.cpp
|
||||
src/pen.cpp
|
||||
src/persist_location.cpp
|
||||
src/preferences.cpp
|
||||
src/preferences_base.cpp
|
||||
src/project.cpp
|
||||
src/resolution_resampler.cpp
|
||||
src/search_replace_engine.cpp
|
||||
src/selection_controller.cpp
|
||||
src/spellchecker.cpp
|
||||
src/spline.cpp
|
||||
src/spline_curve.cpp
|
||||
src/string_codec.cpp
|
||||
src/subs_controller.cpp
|
||||
src/subs_edit_box.cpp
|
||||
src/subs_edit_ctrl.cpp
|
||||
src/subs_preview.cpp
|
||||
src/subtitles_provider.cpp
|
||||
src/subtitles_provider_libass.cpp
|
||||
src/text_file_reader.cpp
|
||||
src/text_file_writer.cpp
|
||||
src/text_selection_controller.cpp
|
||||
src/thesaurus.cpp
|
||||
src/timeedit_ctrl.cpp
|
||||
src/toggle_bitmap.cpp
|
||||
src/toolbar.cpp
|
||||
src/tooltip_manager.cpp
|
||||
src/utils.cpp
|
||||
src/validators.cpp
|
||||
src/vector2d.cpp
|
||||
src/version.cpp
|
||||
src/video_box.cpp
|
||||
src/video_controller.cpp
|
||||
src/video_display.cpp
|
||||
src/video_frame.cpp
|
||||
src/video_out_gl.cpp
|
||||
src/video_provider_cache.cpp
|
||||
src/video_provider_dummy.cpp
|
||||
src/video_provider_manager.cpp
|
||||
src/video_provider_yuv4mpeg.cpp
|
||||
src/video_slider.cpp
|
||||
src/visual_feature.cpp
|
||||
)
|
||||
target_link_libraries(Aegisub ${CMAKE_DL_LIBS} libaegisub luabins luajit resrc csri)
|
||||
target_compile_definitions(Aegisub PRIVATE CMAKE_BUILD)
|
||||
|
||||
set(WITH_BUILD_CREDIT OFF CACHE BOOL "Whether show build credit in about dialog")
|
||||
if(WITH_BUILD_CREDIT)
|
||||
set(BUILD_CREDIT "" CACHE STRING "Build credit shown in about dialog")
|
||||
target_compile_definitions(Aegisub PRIVATE "BUILD_CREDIT=${BUILD_CREDIT}")
|
||||
else()
|
||||
unset(BUILD_CREDIT CACHE)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
set_target_properties(libaegisub PROPERTIES COMPILE_FLAGS "/Yu${PROJECT_SOURCE_DIR}/libaegisub/lagi_pre.h" COMPILE_FLAGS "/FI${PROJECT_SOURCE_DIR}/libaegisub/lagi_pre.h")
|
||||
else()
|
||||
target_compile_options(libaegisub PRIVATE -include "${PROJECT_SOURCE_DIR}/libaegisub/lagi_pre.h")
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
add_definitions("/DNOMINMAX /MP /DINITGUID")
|
||||
set_target_properties(Aegisub PROPERTIES COMPILE_FLAGS "/Yu${PROJECT_SOURCE_DIR}/src/agi_pre.h" COMPILE_FLAGS "/FI${PROJECT_SOURCE_DIR}/src/agi_pre.h")
|
||||
target_link_libraries(Aegisub Usp10)
|
||||
#target_sources(Aegisub PRIVATE src/res/res.rc src/res/strings.rc src/crash_writer_minidump.cpp)
|
||||
target_sources(Aegisub PRIVATE src/res/res.rc src/res/strings.rc src/crash_writer.cpp src/dpi_aware.manifest)
|
||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Aegisub)
|
||||
else()
|
||||
target_sources(Aegisub PRIVATE src/crash_writer.cpp)
|
||||
target_compile_options(Aegisub PRIVATE -include "${PROJECT_SOURCE_DIR}/src/agi_pre.h")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_sources(Aegisub PRIVATE src/font_file_lister_gdi.cpp)
|
||||
else()
|
||||
find_package(Fontconfig REQUIRED)
|
||||
target_include_directories(Aegisub PRIVATE ${Fontconfig_INCLUDE_DIRS})
|
||||
target_link_libraries(Aegisub ${Fontconfig_LIBRARIES})
|
||||
target_sources(Aegisub PRIVATE src/font_file_lister_fontconfig.cpp)
|
||||
endif()
|
||||
|
||||
find_package(ass REQUIRED)
|
||||
target_include_directories(Aegisub PRIVATE ${ass_INCLUDE_DIRS})
|
||||
target_link_libraries(Aegisub ${ass_LIBRARIES})
|
||||
|
||||
find_package(Boost REQUIRED chrono filesystem locale regex system thread)
|
||||
target_include_directories(libaegisub PRIVATE ${Boost_INCLUDE_DIRS})
|
||||
target_include_directories(Aegisub PRIVATE ${Boost_INCLUDE_DIRS})
|
||||
target_link_directories(Aegisub PRIVATE ${Boost_LIBRARY_DIRS})
|
||||
target_link_libraries(Aegisub ${Boost_LIBRARIES})
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
target_include_directories(Aegisub PRIVATE ${OPENGL_INCLUDE_DIR})
|
||||
target_link_libraries(Aegisub ${OPENGL_LIBRARIES})
|
||||
|
||||
find_package(Iconv REQUIRED)
|
||||
target_compile_definitions(libaegisub PRIVATE "HAVE_ICONV")
|
||||
target_include_directories(libaegisub PRIVATE ${Iconv_INCLUDE_DIRS})
|
||||
target_link_libraries(libaegisub ${Iconv_LIBRARIES})
|
||||
if(NOT Iconv_IS_BUILT_IN)
|
||||
target_compile_definitions(libaegisub PRIVATE "AGI_ICONV_CONST")
|
||||
endif()
|
||||
|
||||
find_package(ICU REQUIRED uc dt in)
|
||||
target_include_directories(libaegisub PRIVATE ${ICU_INCLUDE_DIRS})
|
||||
target_include_directories(Aegisub PRIVATE ${ICU_INCLUDE_DIRS})
|
||||
target_link_libraries(Aegisub ${ICU_LIBRARIES})
|
||||
|
||||
find_package(wxWidgets REQUIRED adv base core gl stc xml)
|
||||
include(${wxWidgets_USE_FILE})
|
||||
target_link_libraries(Aegisub ${wxWidgets_LIBRARIES})
|
||||
|
||||
find_package(ZLIB REQUIRED)
|
||||
target_include_directories(Aegisub PRIVATE ${ZLIB_INCLUDE_DIRS})
|
||||
target_link_libraries(Aegisub ${ZLIB_LIBRARIES})
|
||||
|
||||
set(WITH_ALSA ON CACHE BOOL "Enable ALSA support")
|
||||
if(WITH_ALSA)
|
||||
find_package(ALSA)
|
||||
if(NOT ALSA_FOUND)
|
||||
set(WITH_ALSA OFF CACHE BOOL "Enable ALSA support" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_ALSA)
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_ALSA")
|
||||
target_include_directories(Aegisub PRIVATE ${ALSA_INCLUDE_DIRS})
|
||||
target_link_libraries(Aegisub ${ALSA_LIBRARIES})
|
||||
target_sources(Aegisub PRIVATE src/audio_player_alsa.cpp)
|
||||
endif()
|
||||
|
||||
set(WITH_AVISYNTH ON CACHE BOOL "Enable AviSynth support")
|
||||
if(WITH_AVISYNTH)
|
||||
find_package(AviSynth)
|
||||
if(NOT AviSynth_FOUND)
|
||||
set(WITH_AVISYNTH OFF CACHE BOOL "Enable AviSynth support" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_AVISYNTH)
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_AVISYNTH" "AVS_LINKAGE_DLLIMPORT")
|
||||
target_include_directories(Aegisub PRIVATE ${AviSynth_INCLUDE_DIRS})
|
||||
target_link_libraries(Aegisub Vfw32 ${AviSynth_LIBRARIES})
|
||||
target_sources(Aegisub PRIVATE src/audio_provider_avs.cpp src/avisynth_wrap.cpp src/video_provider_avs.cpp)
|
||||
endif()
|
||||
|
||||
set(WITH_CSRI ON CACHE BOOL "Enable CSRI support")
|
||||
if(WITH_CSRI)
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_CSRI")
|
||||
target_include_directories(Aegisub PRIVATE "${PROJECT_SOURCE_DIR}/vendor/csri/include")
|
||||
target_sources(Aegisub PRIVATE src/subtitles_provider_csri.cpp)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_DIRECTSOUND")
|
||||
target_link_libraries(Aegisub dsound)
|
||||
target_sources(Aegisub PRIVATE src/audio_player_dsound.cpp src/audio_player_dsound2.cpp)
|
||||
set(WITH_DIRECTSOUND ON)
|
||||
else()
|
||||
set(WITH_DIRECTSOUND OFF)
|
||||
endif()
|
||||
|
||||
set(WITH_FFMS2 ON CACHE BOOL "Enable FFMS2 support")
|
||||
if(WITH_FFMS2)
|
||||
find_package(FFMS2)
|
||||
if(NOT FFMS2_FOUND)
|
||||
set(WITH_FFMS2 OFF CACHE BOOL "Enable FFMS2 support" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_FFMS2)
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_FFMS2")
|
||||
target_include_directories(Aegisub PRIVATE ${FFMS2_INCLUDE_DIRS})
|
||||
target_link_libraries(Aegisub ${FFMS2_LIBRARIES})
|
||||
target_sources(Aegisub PRIVATE src/audio_provider_ffmpegsource.cpp src/ffmpegsource_common.cpp src/video_provider_ffmpegsource.cpp)
|
||||
else()
|
||||
message(SEND_ERROR
|
||||
"No supported video/audio reader interface was enabled.\n"
|
||||
"You will not be able to open any video or audio files in Aegisub unless you install a supported video/audio provider.\n"
|
||||
"You will however still be able to open \"dummy\" video, ie. a blank, virtual video clip with subtitles overlaid.\n"
|
||||
"Currently we only support one video/audio provider on non-Windows systems:\n"
|
||||
" - FFMS2\n"
|
||||
" * http://github.com/FFMS/ffms2\n"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(WITH_FFTW3 ON CACHE BOOL "Enable fftw support")
|
||||
if(WITH_FFTW3)
|
||||
find_package(FFTW)
|
||||
if(NOT FFTW_FOUND)
|
||||
set(WITH_FFTW3 OFF CACHE BOOL "Enable fftw support" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_FFTW3)
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_FFTW3")
|
||||
target_include_directories(Aegisub PRIVATE ${FFTW_INCLUDES})
|
||||
target_link_libraries(Aegisub ${FFTW_LIBRARIES})
|
||||
endif()
|
||||
|
||||
set(WITH_HUNSPELL ON CACHE BOOL "Enable Hunspell support")
|
||||
if(WITH_HUNSPELL)
|
||||
find_package(Hunspell)
|
||||
if(NOT HUNSPELL_FOUND)
|
||||
set(WITH_HUNSPELL OFF CACHE BOOL "Enable Hunspell support" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_HUNSPELL)
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_HUNSPELL")
|
||||
target_include_directories(Aegisub PRIVATE ${HUNSPELL_INCLUDE_DIR})
|
||||
target_link_libraries(Aegisub ${HUNSPELL_LIBRARIES})
|
||||
target_sources(Aegisub PRIVATE src/spellchecker_hunspell.cpp)
|
||||
if(HUNSPELL_HAS_STRING_API)
|
||||
target_compile_definitions(Aegisub PRIVATE "HUNSPELL_HAS_STRING_API")
|
||||
endif(HUNSPELL_HAS_STRING_API)
|
||||
endif()
|
||||
|
||||
set(WITH_LIBPULSE ON CACHE BOOL "Enable PulseAudio support")
|
||||
if(WITH_LIBPULSE)
|
||||
find_package(PulseAudio)
|
||||
if(NOT PULSEAUDIO_FOUND)
|
||||
set(WITH_LIBPULSE OFF CACHE BOOL "Enable PulseAudio support" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_LIBPULSE)
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_LIBPULSE")
|
||||
target_include_directories(Aegisub PRIVATE ${PULSEAUDIO_INCLUDE_DIR})
|
||||
target_link_libraries(Aegisub ${PULSEAUDIO_LIBRARY})
|
||||
target_sources(Aegisub PRIVATE src/audio_player_pulse.cpp)
|
||||
endif()
|
||||
|
||||
set(WITH_OPENAL ON CACHE BOOL "Enable OpenAL support")
|
||||
if(WITH_OPENAL)
|
||||
find_package(OpenAL)
|
||||
if(NOT OPENAL_FOUND)
|
||||
set(WITH_OPENAL OFF CACHE BOOL "Enable OpenAL support" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_OPENAL)
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_OPENAL")
|
||||
target_include_directories(Aegisub PRIVATE ${OPENAL_INCLUDE_DIR})
|
||||
target_link_libraries(Aegisub ${OPENAL_LIBRARY})
|
||||
target_sources(Aegisub PRIVATE src/audio_player_openal.cpp)
|
||||
endif()
|
||||
|
||||
set(WITH_OSS OFF CACHE BOOL "Enable OSS support")
|
||||
if(WITH_OSS)
|
||||
find_package(OSS)
|
||||
if(NOT OSS_FOUND)
|
||||
set(WITH_OSS OFF CACHE BOOL "Enable OSS support" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_OSS)
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_OSS")
|
||||
target_include_directories(Aegisub PRIVATE ${OSS_INCLUDE_DIRS})
|
||||
target_sources(Aegisub PRIVATE src/audio_player_oss.cpp)
|
||||
endif()
|
||||
|
||||
set(WITH_PORTAUDIO ON CACHE BOOL "Enable PortAudio support")
|
||||
if(WITH_PORTAUDIO)
|
||||
find_package(PortAudio)
|
||||
if(NOT PortAudio_FOUND)
|
||||
set(WITH_PORTAUDIO OFF CACHE BOOL "Enable PortAudio support" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_PORTAUDIO)
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_PORTAUDIO")
|
||||
target_include_directories(Aegisub PRIVATE ${PortAudio_INCLUDE_DIRS})
|
||||
target_link_libraries(Aegisub ${PortAudio_LIBRARIES})
|
||||
target_sources(Aegisub PRIVATE src/audio_player_portaudio.cpp)
|
||||
endif()
|
||||
|
||||
set(WITH_STARTUPLOG OFF CACHE BOOL "Enable startup log")
|
||||
if(WITH_STARTUPLOG)
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_STARTUPLOG")
|
||||
endif()
|
||||
|
||||
set(WITH_UCHARDET ON CACHE BOOL "Enable uchardet support")
|
||||
if(WITH_UCHARDET)
|
||||
find_package(uchardet)
|
||||
if(NOT uchardet_FOUND)
|
||||
set(WITH_UCHARDET OFF CACHE BOOL "Enable uchardet support" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_UCHARDET)
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_UCHARDET")
|
||||
target_include_directories(Aegisub PRIVATE ${uchardet_INCLUDE_DIRS})
|
||||
target_link_libraries(Aegisub ${uchardet_LIBRARIES})
|
||||
endif()
|
||||
|
||||
set(WITH_UPDATE_CHECKER OFF)
|
||||
if(WITH_UPDATE_CHECKER)
|
||||
set(UPDATE_CHECKER_SERVER "\"updates.aegisub.org\"" CACHE STRING "Server for the update checker")
|
||||
set(UPDATE_CHECKER_BASE_URL "\"/trunk\"" CACHE STRING "Base path for the update checker")
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_UPDATE_CHECKER" "UPDATE_CHECKER_SERVER=${UPDATE_CHECKER_SERVER}" "UPDATE_CHECKER_BASE_URL=${UPDATE_CHECKER_BASE_URL}")
|
||||
target_link_libraries(Aegisub ${Boost_asio_LIBRARY})
|
||||
target_sources(Aegisub PRIVATE src/dialog_version_check.cpp)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(DEFAULT_PLAYER_AUDIO DirectSound)
|
||||
configure_file("src/libresrc/default_config_win.json" "${PROJECT_SOURCE_DIR}/src/libresrc/default_config_platform.json" COPYONLY)
|
||||
else()
|
||||
if(WITH_LIBPULSE)
|
||||
set(DEFAULT_PLAYER_AUDIO "PulseAudio" CACHE STRING "Default audio player")
|
||||
elseif(WITH_ALSA)
|
||||
set(DEFAULT_PLAYER_AUDIO "ALSA" CACHE STRING "Default audio player")
|
||||
elseif(WITH_OPENAL)
|
||||
set(DEFAULT_PLAYER_AUDIO "OpenAL" CACHE STRING "Default audio player")
|
||||
elseif(WITH_PORTAUDIO)
|
||||
set(DEFAULT_PLAYER_AUDIO "PortAudio" CACHE STRING "Default audio player")
|
||||
elseif(WITH_OSS)
|
||||
set(DEFAULT_PLAYER_AUDIO "OSS" CACHE STRING "Default audio player")
|
||||
else()
|
||||
message(SEND_ERROR
|
||||
"No supported audio player interface was enabled.\n"
|
||||
"If you want audio support in Aegisub you need to install one of these libraries:\n"
|
||||
" - PulseAudio\n"
|
||||
" * http://pulseaudio.org/\n"
|
||||
" - ALSA (Linux only)\n"
|
||||
" * http://www.alsa-project.org/\n"
|
||||
" - PortAudio (version 19 only)\n"
|
||||
" * http://www.portaudio.com/\n"
|
||||
"\n"
|
||||
)
|
||||
set(DEFAULT_PLAYER_AUDIO "NONE" CACHE STRING "Default audio player")
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/src/libresrc/default_config_platform.json
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/src/libresrc/default_config_win.json ${PROJECT_SOURCE_DIR}/src/libresrc/default_config_platform.json
|
||||
)
|
||||
configure_file("src/libresrc/default_config_platform.json.in" "${PROJECT_SOURCE_DIR}/src/libresrc/default_config_platform.json" @ONLY)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
set(AEGISUB_COMMAND "aegisub" CACHE STRING "The executable name of Aegisub")
|
||||
set_target_properties(Aegisub PROPERTIES OUTPUT_NAME "${AEGISUB_COMMAND}")
|
||||
configure_file("packages/desktop/aegisub.desktop.template.in" "aegisub.desktop" @ONLY)
|
||||
install(FILES "${CMAKE_BINARY_DIR}/aegisub.desktop" DESTINATION "share/applications")
|
||||
install(FILES "packages/desktop/16x16.png" DESTINATION "share/icons/hicolor/16x16/apps" RENAME aegisub.png)
|
||||
install(FILES "packages/desktop/22x22.png" DESTINATION "share/icons/hicolor/22x22/apps" RENAME aegisub.png)
|
||||
install(FILES "packages/desktop/24x24.png" DESTINATION "share/icons/hicolor/24x24/apps" RENAME aegisub.png)
|
||||
install(FILES "packages/desktop/32x32.png" DESTINATION "share/icons/hicolor/32x32/apps" RENAME aegisub.png)
|
||||
install(FILES "packages/desktop/48x48.png" DESTINATION "share/icons/hicolor/48x48/apps" RENAME aegisub.png)
|
||||
install(FILES "packages/desktop/64x64.png" DESTINATION "share/icons/hicolor/64x64/apps" RENAME aegisub.png)
|
||||
install(FILES "packages/desktop/scalable.svg" DESTINATION "share/icons/hicolor/scalable/apps" RENAME aegisub.svg)
|
||||
endif()
|
||||
install(TARGETS Aegisub DESTINATION bin)
|
||||
|
||||
set(WITH_TEST OFF CACHE BOOL "Enable unit tests")
|
||||
if(WITH_TEST)
|
||||
include("CMakeLists.test.txt")
|
||||
endif()
|
||||
|
||||
message(STATUS "\n"
|
||||
"Configure settings\n"
|
||||
" Install prefix: ${CMAKE_INSTALL_PREFIX}\n"
|
||||
" CFLAGS ${CMAKE_C_FLAGS}\n"
|
||||
" CXXFLAGS ${CMAKE_CXX_FLAGS}\n"
|
||||
"\n"
|
||||
"Default Settings\n"
|
||||
" Audio Player: ${DEFAULT_PLAYER_AUDIO}\n"
|
||||
"\n"
|
||||
"Audio Players\n"
|
||||
" ALSA: ${WITH_ALSA}\n"
|
||||
" DirectSound: ${WITH_DIRECTSOUND}\n"
|
||||
" DirectSound-old: ${WITH_DIRECTSOUND}\n"
|
||||
" OpenAL: ${WITH_OPENAL}\n"
|
||||
" OSS: ${WITH_OSS}\n"
|
||||
" PortAudio: ${WITH_PORTAUDIO}\n"
|
||||
" PulseAudio: ${WITH_LIBPULSE}\n"
|
||||
"\n"
|
||||
"Misc Packages\n"
|
||||
" AviSynth: ${WITH_AVISYNTH}\n"
|
||||
" CSRI: ${WITH_CSRI}\n"
|
||||
" FFMS2: ${WITH_FFMS2}\n"
|
||||
" FFTW3: ${WITH_FFTW3}\n"
|
||||
" Hunspell: ${WITH_HUNSPELL}\n"
|
||||
" uchardet: ${WITH_UCHARDET}\n"
|
||||
" LuaJIT: bundled\n"
|
||||
"\n"
|
||||
"Options\n"
|
||||
" Startup log: ${WITH_STARTUPLOG}\n"
|
||||
" Update checker: ${WITH_UPDATE_CHECKER}\n"
|
||||
" Tests: ${WITH_TEST}\n"
|
||||
"\n"
|
||||
)
|
|
@ -54,6 +54,7 @@ P_BINDIR = @bindir@
|
|||
P_DATAROOT = @datarootdir@
|
||||
P_LOCALE = @localedir@
|
||||
|
||||
P_APPDATA = @P_APPDATA@
|
||||
P_DESKTOP = @P_DESKTOP@
|
||||
P_ICON = @P_ICON@
|
||||
P_DATA = $(P_DATAROOT)/aegisub/
|
||||
|
|
95
README.md
95
README.md
|
@ -1,85 +1,40 @@
|
|||
[![Build Status](https://travis-ci.org/wangqr/Aegisub.svg?branch=dev)](https://travis-ci.org/wangqr/Aegisub)
|
||||
|
||||
# Aegisub
|
||||
|
||||
For binaries and general information [see the homepage](http://www.aegisub.org).
|
||||
|
||||
The bug tracker can be found at http://devel.aegisub.org.
|
||||
The bug tracker can be found at https://github.com/Aegisub/Aegisub/issues .
|
||||
|
||||
Support is available on [the forums](http://forum.aegisub.org) or [on IRC](irc://irc.rizon.net/aegisub).
|
||||
Support is available on IRC ( irc://irc.rizon.net/aegisub ).
|
||||
|
||||
## Building Aegisub
|
||||
|
||||
### Windows
|
||||
|
||||
Prerequisites:
|
||||
|
||||
1. Visual Studio 2015 (the free Community edition is good enough)
|
||||
2. The June 2010 DirectX SDK (the final release before DirectSound was dropped)
|
||||
3. [Yasm](http://yasm.tortall.net/) installed to somewhere on your path.
|
||||
|
||||
There are a few optional dependencies:
|
||||
|
||||
1. msgfmt, to build the translations
|
||||
2. WinRAR, to build the portable installer
|
||||
3. InnoSetup, to build the regular installer
|
||||
|
||||
All other dependencies are either stored in the repository or are included as submodules.
|
||||
1. CMake 3.14 or later (or you can use an older version by editing the first line in CMakeLists.txt, and download the missing `cmake/FindFontconfig.cmake` from [here](https://gitlab.kitware.com/cmake/cmake/blob/master/Modules/FindFontconfig.cmake)),
|
||||
2. Any compiling toolchain supported by CMake,
|
||||
3. All required dependencies, namely `libass`, `Boost`(with ICU support), `OpenGL`, `libicu`, `wxWidgets`, `zlib`. Additionally, `libiconv` is required on non-POSIX systems. `fontconfig` is required on non-Windows systems.
|
||||
4. Any optional dependencies, namely `ALSA`, `FFMS2`, `FFTW`, `Hunspell`, `OpenAL`, `uchardet`.
|
||||
|
||||
Building:
|
||||
|
||||
1. Clone Aegisub's repository recursively to fetch it and all submodules: `git clone --recursive git@github.com:Aegisub/Aegisub.git` This will take quite a while and requires about 2.5 GB of disk space.
|
||||
2. Open Aegisub.sln
|
||||
3. Build the BuildTasks project.
|
||||
4. Build the entire solution.
|
||||
|
||||
You should now have a `bin` directory in your Aegisub directory which contains `aegisub32d.exe`, along with a pile of other files.
|
||||
|
||||
The Aegisub installer includes some files not built as part of Aegisub (such as Avisynth and VSFilter), so for a fully functional copy of Aegisub you now need to copy all of the files from an installed copy of Aegisub into your `bin` directory (and don't overwrite any of the files already there).
|
||||
You'll also either need to copy the `automation` directory into the `bin` directory, or edit your automation search paths to include the `automation` directory in the source tree.
|
||||
|
||||
After building the solution once, you'll want to switch to the Debug-MinDep configuration, which skips checking if the dependencies are out of date, as that takes a while.
|
||||
|
||||
### OS X
|
||||
|
||||
A vaguely recent version of Xcode and the corresponding command-line tools are required.
|
||||
Nothing older than Xcode 5 has been tested recently, but it is likely that some later versions of Xcode 4 are good enough.
|
||||
|
||||
For personal usage, you can use homebrew to install almost all of Aegisub's dependencies:
|
||||
|
||||
brew install autoconf ffmpeg freetype gettext ffms2 fftw fribidi libass m4
|
||||
brew install --devel --with-gc64 luajit
|
||||
brew install --HEAD icu4c
|
||||
brew link --force icu4c
|
||||
brew link --force gettext
|
||||
brew install --HEAD --c++11 --with-icu4c boost
|
||||
|
||||
wxWidgets is located in vendor/wxWidgets, and can be built like so:
|
||||
|
||||
CPPFLAGS="$CPPFLAGS -D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=1" \
|
||||
./configure --disable-aboutdlg --disable-animatectrl --disable-aui --disable-any \
|
||||
--disable-bannerwindow --disable-base64 --disable-calendar --disable-caret \
|
||||
--disable-cmdline --disable-colourpicker --disable-compat28 --disable-config \
|
||||
--disable-constraints --disable-datepick --disable-dctransform --disable-debugreport \
|
||||
--disable-dialupman --disable-docview --disable-filehistory --disable-finddlg \
|
||||
--disable-fs_archive --disable-fs_inet --disable-fs_zip --disable-fsvolume \
|
||||
--disable-fswatcher --disable-gif --disable-help --disable-html --disable-ipc \
|
||||
--disable-joystick --disable-jpeg --disable-largefile --disable-markup --disable-mdi \
|
||||
--disable-mediactrl --disable-metafiles --disable-miniframe --disable-notifmsg \
|
||||
--disable-numberdlg --disable-pcx --disable-pnm --disable-postscript \
|
||||
--disable-prefseditor --disable-printarch --disable-progressdlg --disable-propgrid \
|
||||
--disable-protocol --disable-protocols --disable-rearrangectrl --disable-ribbon \
|
||||
--disable-richtext --disable-richtooltip --disable-snglinst --disable-sockets \
|
||||
--disable-sockets --disable-sound --disable-splash --disable-splines \
|
||||
--disable-std_iostreams --disable-svg --disable-tarstream --disable-tiff \
|
||||
--disable-tipdlg --disable-tipwindow --disable-url --disable-webkit --disable-webview \
|
||||
--disable-wizarddlg --disable-xrc \
|
||||
--enable-geometry --enable-imaglist --enable-listctrl --enable-stc --with-cocoa \
|
||||
--with-libpng=yes --with-macosx-version-min=10.9 \
|
||||
--with-opengl \
|
||||
--without-libjpeg --without-libtiff --without-regex \
|
||||
&& make
|
||||
|
||||
Once the dependencies are installed, build Aegisub with `autoreconf && ./configure --with-wxdir=/path/to/Aegisub/vendor/wxWidgets && make && make osx-bundle`.
|
||||
`autoreconf` should be skipped if you are building from a source tarball rather than `git`.
|
||||
1. If you decided to build from source:
|
||||
```shell
|
||||
git clone https://github.com/wangqr/Aegisub.git # No --recursive is needed
|
||||
cd Aegisub
|
||||
./build/version.sh . # This will generate build/git_version.h
|
||||
```
|
||||
2. Make an empty directory to hold build outputs:
|
||||
```shell
|
||||
mkdir build-dir
|
||||
```
|
||||
3. Build the project using CMake. Use either cmake-gui, or the command line:
|
||||
```shell
|
||||
cd build-dir
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
|
||||
## Updating Moonscript
|
||||
|
||||
|
@ -95,4 +50,4 @@ The file is now ready for use, to be placed in `automation/include` within the A
|
|||
## License
|
||||
|
||||
All files in this repository are licensed under various GPL-compatible BSD-style licenses; see LICENCE and the individual source files for more information.
|
||||
The official Windows and OS X builds are GPLv2 due to including fftw3.
|
||||
The official Windows build is GPLv2 due to including fftw3.
|
||||
|
|
|
@ -39,7 +39,7 @@ search = (re, str, start) ->
|
|||
res = regex.search re, str, str\len(), start
|
||||
return unless res != nil
|
||||
first, last = res[0], res[1]
|
||||
ffi.C.free res
|
||||
ffi.gc(res, ffi.C.free)
|
||||
first, last
|
||||
|
||||
replace = (re, replacement, str, max_count) ->
|
||||
|
|
|
@ -53,7 +53,7 @@ int main(int argc, char **argv) {
|
|||
agi::log::log = new agi::log::LogSink;
|
||||
|
||||
// Init lua state
|
||||
lua_State *L = lua_open();
|
||||
lua_State *L = luaL_newstate();
|
||||
if (!L) {
|
||||
fprintf(stderr, "Failed to create Lua state\n");
|
||||
return 1;
|
||||
|
|
|
@ -40,3 +40,11 @@ Returns: 2 values, all numbers.
|
|||
2. End of the selection, in milliseconds.
|
||||
|
||||
---
|
||||
|
||||
Setting the main frame's status bar text
|
||||
|
||||
function aegisub.set_status_bar_text(text)
|
||||
|
||||
Returns: 0 values
|
||||
|
||||
---
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
<AdditionalLibraryDirectories Condition="'$(Platform)'=='Win32'">$(DXSDK_DIR)\Lib\x86</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories Condition="'$(Platform)'=='x64'">$(DXSDK_DIR)\Lib\x64</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<!-- Update git_version.h -->
|
||||
|
|
20
cmake/FindAviSynth.cmake
Normal file
20
cmake/FindAviSynth.cmake
Normal file
|
@ -0,0 +1,20 @@
|
|||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_AviSynth QUIET AviSynth)
|
||||
find_path(AviSynth_INCLUDE_DIRS
|
||||
NAMES avisynth.h
|
||||
HINTS ${PC_AviSynth_INCLUDE_DIRS}
|
||||
)
|
||||
find_library(AviSynth_LIBRARIES
|
||||
NAMES avisynth
|
||||
PATH_SUFFIXES c_api
|
||||
HINTS ${PC_AviSynth_LIBRARY_DIRS}
|
||||
)
|
||||
set(AviSynth_VERSION ${PC_AviSynth_VERSION})
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(AviSynth
|
||||
FOUND_VAR AviSynth_FOUND
|
||||
REQUIRED_VARS
|
||||
AviSynth_LIBRARIES
|
||||
AviSynth_INCLUDE_DIRS
|
||||
VERSION_VAR AviSynth_VERSION
|
||||
)
|
19
cmake/FindFFMS2.cmake
Normal file
19
cmake/FindFFMS2.cmake
Normal file
|
@ -0,0 +1,19 @@
|
|||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_FFMS2 QUIET ffms2)
|
||||
find_path(FFMS2_INCLUDE_DIRS
|
||||
NAMES ffms.h ffmscompat.h
|
||||
HINTS ${PC_FFMS2_INCLUDE_DIRS}
|
||||
)
|
||||
find_library(FFMS2_LIBRARIES
|
||||
NAMES ffms2
|
||||
HINTS ${PC_FFMS2_LIBRARY_DIRS}
|
||||
)
|
||||
set(FFMS2_VERSION ${PC_FFMS2_VERSION})
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(FFMS2
|
||||
FOUND_VAR FFMS2_FOUND
|
||||
REQUIRED_VARS
|
||||
FFMS2_LIBRARIES
|
||||
FFMS2_INCLUDE_DIRS
|
||||
VERSION_VAR FFMS2_VERSION
|
||||
)
|
119
cmake/FindFFTW.cmake
Normal file
119
cmake/FindFFTW.cmake
Normal file
|
@ -0,0 +1,119 @@
|
|||
# - Find the FFTW library
|
||||
#
|
||||
# Usage:
|
||||
# find_package(FFTW [REQUIRED] [QUIET] )
|
||||
#
|
||||
# It sets the following variables:
|
||||
# FFTW_FOUND ... true if fftw is found on the system
|
||||
# FFTW_LIBRARIES ... full path to fftw library
|
||||
# FFTW_INCLUDES ... fftw include directory
|
||||
#
|
||||
# The following variables will be checked by the function
|
||||
# FFTW_USE_STATIC_LIBS ... if true, only static libraries are found
|
||||
# FFTW_ROOT ... if set, the libraries are exclusively searched
|
||||
# under this path
|
||||
# FFTW_LIBRARY ... fftw library to use
|
||||
# FFTW_INCLUDE_DIR ... fftw include directory
|
||||
#
|
||||
|
||||
#If environment variable FFTWDIR is specified, it has same effect as FFTW_ROOT
|
||||
if( NOT FFTW_ROOT AND ENV{FFTWDIR} )
|
||||
set( FFTW_ROOT $ENV{FFTWDIR} )
|
||||
endif()
|
||||
|
||||
# Check if we can use PkgConfig
|
||||
find_package(PkgConfig QUIET)
|
||||
|
||||
#Determine from PKG
|
||||
if( PKG_CONFIG_FOUND AND NOT FFTW_ROOT )
|
||||
pkg_check_modules( PKG_FFTW QUIET "fftw3" )
|
||||
endif()
|
||||
|
||||
#Check whether to search static or dynamic libs
|
||||
set( CMAKE_FIND_LIBRARY_SUFFIXES_SAV ${CMAKE_FIND_LIBRARY_SUFFIXES} )
|
||||
|
||||
if( ${FFTW_USE_STATIC_LIBS} )
|
||||
set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX} )
|
||||
else()
|
||||
set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX} )
|
||||
endif()
|
||||
|
||||
if( FFTW_ROOT )
|
||||
|
||||
#find libs
|
||||
find_library(
|
||||
FFTW_LIB
|
||||
NAMES "fftw3"
|
||||
PATHS ${FFTW_ROOT}
|
||||
PATH_SUFFIXES "lib" "lib64"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
find_library(
|
||||
FFTWF_LIB
|
||||
NAMES "fftw3f"
|
||||
PATHS ${FFTW_ROOT}
|
||||
PATH_SUFFIXES "lib" "lib64"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
find_library(
|
||||
FFTWL_LIB
|
||||
NAMES "fftw3l"
|
||||
PATHS ${FFTW_ROOT}
|
||||
PATH_SUFFIXES "lib" "lib64"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
#find includes
|
||||
find_path(
|
||||
FFTW_INCLUDES
|
||||
NAMES "fftw3.h"
|
||||
PATHS ${FFTW_ROOT}
|
||||
PATH_SUFFIXES "include"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
else()
|
||||
|
||||
find_library(
|
||||
FFTW_LIB
|
||||
NAMES "fftw3"
|
||||
PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR}
|
||||
)
|
||||
|
||||
find_library(
|
||||
FFTWF_LIB
|
||||
NAMES "fftw3f"
|
||||
PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR}
|
||||
)
|
||||
|
||||
|
||||
find_library(
|
||||
FFTWL_LIB
|
||||
NAMES "fftw3l"
|
||||
PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR}
|
||||
)
|
||||
|
||||
find_path(
|
||||
FFTW_INCLUDES
|
||||
NAMES "fftw3.h"
|
||||
PATHS ${PKG_FFTW_INCLUDE_DIRS} ${INCLUDE_INSTALL_DIR}
|
||||
)
|
||||
|
||||
endif( FFTW_ROOT )
|
||||
|
||||
set(FFTW_LIBRARIES ${FFTW_LIB} ${FFTWF_LIB})
|
||||
|
||||
if(FFTWL_LIB)
|
||||
set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTWL_LIB})
|
||||
endif()
|
||||
|
||||
set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAV} )
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(FFTW DEFAULT_MSG
|
||||
FFTW_INCLUDES FFTW_LIBRARIES)
|
||||
|
||||
mark_as_advanced(FFTW_INCLUDES FFTW_LIBRARIES FFTW_LIB FFTWF_LIB FFTWL_LIB)
|
||||
|
64
cmake/FindHunspell.cmake
Normal file
64
cmake/FindHunspell.cmake
Normal file
|
@ -0,0 +1,64 @@
|
|||
# - Try to find Hunspell
|
||||
# Once done this will define
|
||||
#
|
||||
# HUNSPELL_FOUND - system has Hunspell
|
||||
# HUNSPELL_INCLUDE_DIR - the Hunspell include directory
|
||||
# HUNSPELL_LIBRARIES - Link these to use Hunspell
|
||||
# HUNSPELL_HAS_STRING_API - Hunspell has vector<string> api (>=1.5.1)
|
||||
#
|
||||
# Redistribution and use of this file is allowed according to the terms of the
|
||||
# MIT license. For details see the file COPYING-CMAKE-MODULES.
|
||||
|
||||
|
||||
# use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
|
||||
pkg_check_modules(HUNSPELL_PKG QUIET hunspell)
|
||||
|
||||
FIND_PATH(HUNSPELL_INCLUDE_DIR NAMES hunspell.h
|
||||
PATHS
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
HINTS
|
||||
${HUNSPELL_PKG_INCLUDE_DIRS} # Generated by pkg-config
|
||||
PATH_SUFFIXES hunspell
|
||||
)
|
||||
|
||||
FIND_LIBRARY(HUNSPELL_LIBRARIES NAMES hunspell-1.7 hunspell-1.6 hunspell-1.5 hunspell-1.4 hunspell-1.3 hunspell-1.2 hunspell ${HUNSPELL_PKG_LIBRARIES}
|
||||
PATHS
|
||||
/usr/local
|
||||
/usr
|
||||
HINTS
|
||||
${HUNSPELL_PKG_LIBRARY_DIRS} # Generated by pkg-config
|
||||
PATH_SUFFIXES
|
||||
lib64
|
||||
lib
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Hunspell DEFAULT_MSG HUNSPELL_LIBRARIES HUNSPELL_INCLUDE_DIR )
|
||||
|
||||
add_library(hunspell UNKNOWN IMPORTED)
|
||||
set_target_properties(hunspell PROPERTIES IMPORTED_LOCATION ${HUNSPELL_LIBRARIES} INTERFACE_INCLUDE_DIRECTORIES ${HUNSPELL_INCLUDE_DIR})
|
||||
if (NOT BUILD_SHARED_LIBS)
|
||||
# At least statically compiled hunspell 1.7.0 requires HUNSPELL_STATIC
|
||||
# For other versions, it should not hurt
|
||||
set_target_properties(hunspell PROPERTIES INTERFACE_COMPILE_DEFINITIONS HUNSPELL_STATIC)
|
||||
endif ()
|
||||
|
||||
if (HUNSPELL_FOUND)
|
||||
try_compile(HUNSPELL_HAS_STRING_API "${CMAKE_BINARY_DIR}/hunspell_string_api"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/hunspell_string_api.cpp"
|
||||
LINK_LIBRARIES ${HUNSPELL_LIBRARIES}
|
||||
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${HUNSPELL_INCLUDE_DIR}")
|
||||
if (HUNSPELL_HAS_STRING_API)
|
||||
message(STATUS "Hunspell has string API")
|
||||
else(HUNSPELL_HAS_STRING_API)
|
||||
message(STATUS "Hunspell does not have string API")
|
||||
endif(HUNSPELL_HAS_STRING_API)
|
||||
endif(HUNSPELL_FOUND)
|
||||
|
||||
# show the HUNSPELL_INCLUDE_DIR and HUNSPELL_LIBRARIES variables only in the advanced view
|
||||
MARK_AS_ADVANCED(HUNSPELL_INCLUDE_DIR HUNSPELL_LIBRARIES HUNSPELL_HAS_STRING_API)
|
14
cmake/FindOSS.cmake
Normal file
14
cmake/FindOSS.cmake
Normal file
|
@ -0,0 +1,14 @@
|
|||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_oss QUIET oss)
|
||||
find_path(OSS_INCLUDE_DIRS
|
||||
NAMES sys/soundcard.h
|
||||
HINTS ${PC_oss_INCLUDE_DIRS}
|
||||
)
|
||||
set(OSS_VERSION ${PC_ass_VERSION})
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(OSS
|
||||
FOUND_VAR OSS_FOUND
|
||||
REQUIRED_VARS
|
||||
OSS_INCLUDE_DIRS
|
||||
VERSION_VAR OSS_VERSION
|
||||
)
|
19
cmake/FindPortAudio.cmake
Normal file
19
cmake/FindPortAudio.cmake
Normal file
|
@ -0,0 +1,19 @@
|
|||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_portaudio QUIET portaudio-2.0)
|
||||
find_path(PortAudio_INCLUDE_DIRS
|
||||
NAMES portaudio.h
|
||||
HINTS ${PC_portaudio_INCLUDE_DIRS}
|
||||
)
|
||||
find_library(PortAudio_LIBRARIES
|
||||
NAMES portaudio
|
||||
HINTS ${PC_portaudio_LIBRARY_DIRS}
|
||||
)
|
||||
set(PortAudio_VERSION ${PC_portaudio_VERSION})
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(PortAudio
|
||||
FOUND_VAR PortAudio_FOUND
|
||||
REQUIRED_VARS
|
||||
PortAudio_LIBRARIES
|
||||
PortAudio_INCLUDE_DIRS
|
||||
VERSION_VAR PortAudio_VERSION
|
||||
)
|
70
cmake/FindPulseAudio.cmake
Normal file
70
cmake/FindPulseAudio.cmake
Normal file
|
@ -0,0 +1,70 @@
|
|||
# Try to find the PulseAudio library
|
||||
#
|
||||
# Once done this will define:
|
||||
#
|
||||
# PULSEAUDIO_FOUND - system has the PulseAudio library
|
||||
# PULSEAUDIO_INCLUDE_DIR - the PulseAudio include directory
|
||||
# PULSEAUDIO_LIBRARY - the libraries needed to use PulseAudio
|
||||
# PULSEAUDIO_MAINLOOP_LIBRARY - the libraries needed to use PulsAudio Mainloop
|
||||
#
|
||||
# The minimum required version of PulseAudio can be specified using the
|
||||
# standard syntax, e.g. find_package(PulseAudio 1.0)
|
||||
|
||||
# Copyright (c) 2008, Matthias Kretz, <kretz@kde.org>
|
||||
# Copyright (c) 2009, Marcus Hufgard, <Marcus.Hufgard@hufgard.de>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
# Support PULSEAUDIO_MINIMUM_VERSION for compatibility:
|
||||
if(NOT PulseAudio_FIND_VERSION)
|
||||
set(PulseAudio_FIND_VERSION "${PULSEAUDIO_MINIMUM_VERSION}")
|
||||
endif(NOT PulseAudio_FIND_VERSION)
|
||||
|
||||
# the minimum version of PulseAudio we require
|
||||
if(NOT PulseAudio_FIND_VERSION)
|
||||
set(PulseAudio_FIND_VERSION "0.9.9")
|
||||
endif(NOT PulseAudio_FIND_VERSION)
|
||||
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_PULSEAUDIO QUIET libpulse>=${PulseAudio_FIND_VERSION})
|
||||
pkg_check_modules(PC_PULSEAUDIO_MAINLOOP QUIET libpulse-mainloop-glib)
|
||||
|
||||
find_path(PULSEAUDIO_INCLUDE_DIR pulse/pulseaudio.h
|
||||
HINTS
|
||||
${PC_PULSEAUDIO_INCLUDEDIR}
|
||||
${PC_PULSEAUDIO_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(PULSEAUDIO_LIBRARY NAMES pulse libpulse
|
||||
HINTS
|
||||
${PC_PULSEAUDIO_LIBDIR}
|
||||
${PC_PULSEAUDIO_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
find_library(PULSEAUDIO_MAINLOOP_LIBRARY NAMES pulse-mainloop pulse-mainloop-glib libpulse-mainloop-glib
|
||||
HINTS
|
||||
${PC_PULSEAUDIO_LIBDIR}
|
||||
${PC_PULSEAUDIO_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
# Store the version number in the cache, so we don't have to search every time again:
|
||||
if (PULSEAUDIO_INCLUDE_DIR AND NOT PULSEAUDIO_VERSION)
|
||||
|
||||
# get PulseAudio's version from its version.h, and compare it with our minimum version
|
||||
file(STRINGS "${PULSEAUDIO_INCLUDE_DIR}/pulse/version.h" pulse_version_h
|
||||
REGEX ".*pa_get_headers_version\\(\\).*"
|
||||
)
|
||||
string(REGEX REPLACE ".*pa_get_headers_version\\(\\)\ \\(\"([0-9]+\\.[0-9]+\\.[0-9]+)[^\"]*\"\\).*" "\\1"
|
||||
_PULSEAUDIO_VERSION "${pulse_version_h}")
|
||||
|
||||
set(PULSEAUDIO_VERSION "${_PULSEAUDIO_VERSION}" CACHE STRING "Version number of PulseAudio" FORCE)
|
||||
endif (PULSEAUDIO_INCLUDE_DIR AND NOT PULSEAUDIO_VERSION)
|
||||
|
||||
# Use the new extended syntax of find_package_handle_standard_args(), which also handles version checking:
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(PulseAudio REQUIRED_VARS PULSEAUDIO_LIBRARY PULSEAUDIO_INCLUDE_DIR
|
||||
VERSION_VAR PULSEAUDIO_VERSION )
|
||||
|
||||
mark_as_advanced(PULSEAUDIO_INCLUDE_DIR PULSEAUDIO_LIBRARY PULSEAUDIO_MAINLOOP_LIBRARY)
|
20
cmake/Findass.cmake
Normal file
20
cmake/Findass.cmake
Normal file
|
@ -0,0 +1,20 @@
|
|||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_ass QUIET libass)
|
||||
find_path(ass_INCLUDE_DIRS
|
||||
NAMES ass/ass.h ass/ass_types.h
|
||||
PATH_SUFFIXES libass
|
||||
HINTS ${PC_ass_INCLUDE_DIRS}
|
||||
)
|
||||
find_library(ass_LIBRARIES
|
||||
NAMES ass
|
||||
HINTS ${PC_ass_LIBRARY_DIRS}
|
||||
)
|
||||
set(ass_VERSION ${PC_ass_VERSION})
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(ass
|
||||
FOUND_VAR ass_FOUND
|
||||
REQUIRED_VARS
|
||||
ass_LIBRARIES
|
||||
ass_INCLUDE_DIRS
|
||||
VERSION_VAR ass_VERSION
|
||||
)
|
20
cmake/Finduchardet.cmake
Normal file
20
cmake/Finduchardet.cmake
Normal file
|
@ -0,0 +1,20 @@
|
|||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_uchardet QUIET uchardet)
|
||||
find_path(uchardet_INCLUDE_DIRS
|
||||
NAMES uchardet/uchardet.h
|
||||
HINTS ${PC_uchardet_INCLUDE_DIRS}
|
||||
)
|
||||
find_library(uchardet_LIBRARIES
|
||||
NAMES uchardet
|
||||
PATH_SUFFIXES build/src
|
||||
HINTS ${PC_uchardet_LIBRARY_DIRS}
|
||||
)
|
||||
set(uchardet_VERSION ${PC_uchardet_VERSION})
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(uchardet
|
||||
FOUND_VAR uchardet_FOUND
|
||||
REQUIRED_VARS
|
||||
uchardet_LIBRARIES
|
||||
uchardet_INCLUDE_DIRS
|
||||
VERSION_VAR uchardet_VERSION
|
||||
)
|
10
cmake/hunspell_string_api.cpp
Normal file
10
cmake/hunspell_string_api.cpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include <hunspell/hunspell.hxx>
|
||||
#include <string>
|
||||
|
||||
int main() {
|
||||
Hunspell hunspell(NULL, NULL);
|
||||
std::string word = "";
|
||||
hunspell.suggest(word);
|
||||
hunspell.spell(word);
|
||||
return 0;
|
||||
}
|
25
configure.ac
25
configure.ac
|
@ -54,6 +54,13 @@ AEGISUB_CATALOG="aegisub"
|
|||
AC_SUBST(AEGISUB_CATALOG)
|
||||
AC_DEFINE_UNQUOTED([AEGISUB_CATALOG], ["${AEGISUB_CATALOG}"], [Name of the Aegisub gettext catalog])
|
||||
|
||||
# Handle location of appdata files: https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#spec-component-location
|
||||
AC_ARG_WITH(appdata-dir,
|
||||
AS_HELP_STRING([--with-appdata-dir=PATH],[appdata file locations [PREFIX/share/metainfo]]))
|
||||
|
||||
P_APPDATA=${with_appdata_dir:-$datarootdir/metainfo}
|
||||
AC_SUBST(P_APPDATA)
|
||||
|
||||
# Handle location of desktop files: http://freedesktop.org/wiki/Specifications/desktop-entry-spec
|
||||
AC_ARG_WITH(desktop-dir,
|
||||
AS_HELP_STRING([--with-desktop-dir=PATH],[desktop file locations [PREFIX/share/applications]]))
|
||||
|
@ -133,20 +140,18 @@ AS_IF([test x$build_darwin != xyes], [
|
|||
AC_ARG_ENABLE(compiler-flags, AS_HELP_STRING([--disable-compiler-flags],[Disable *all* additional compiler flags. [no]]))
|
||||
|
||||
AS_IF([test x$enable_compiler_flags != xno], [
|
||||
CFLAGS="$CFLAGS -Wall -Wextra -Wno-unused-parameter -std=gnu99 -pipe -g"
|
||||
CXXFLAGS="$CXXFLAGS -Wall -Wextra -Wno-unused-parameter -fno-strict-aliasing -pipe -g"
|
||||
CFLAGS="$CFLAGS -Wall -Wextra -Wno-unused-parameter"
|
||||
CXXFLAGS="$CXXFLAGS -Wall -Wextra -Wno-unused-parameter -fno-strict-aliasing"
|
||||
AC_C_FLAG([-std=gnu99])
|
||||
AC_CXX_FLAG([-std=c++11])
|
||||
AC_CXX_FLAG([-Wno-c++11-narrowing])
|
||||
AC_CXX_FLAG([-Wno-narrowing])
|
||||
AC_C_FLAG([-Wno-unused-local-typedefs])
|
||||
AC_CXX_FLAG([-Wno-unused-local-typedefs])
|
||||
|
||||
# -O* messes with debugging.
|
||||
AS_IF([test x$enable_debug = xyes], [
|
||||
CFLAGS="$CFLAGS -O0"
|
||||
CXXFLAGS="$CXXFLAGS -O0"
|
||||
], [
|
||||
CFLAGS="$CFLAGS -O3"
|
||||
CXXFLAGS="$CXXFLAGS -O3"
|
||||
CFLAGS="$CFLAGS -O0 -g"
|
||||
CXXFLAGS="$CXXFLAGS -O0 -g"
|
||||
])
|
||||
])
|
||||
|
||||
|
@ -426,7 +431,7 @@ AS_IF([test x$with_system_luajit != xno], [
|
|||
])
|
||||
|
||||
AS_IF([test $with_system_luajit = no],
|
||||
[AC_SUBST([LUAJIT_CFLAGS], ['-I$(TOP)vendor/luajit/include'])
|
||||
[AC_SUBST([LUAJIT_CFLAGS], ['-I$(TOP)vendor/luajit/src'])
|
||||
AC_SUBST([LUAJIT_LIBS], ['$(TOP)vendor/luajit/src/libluajit.a'])])
|
||||
|
||||
# We also need a Lua binary to run part of the build system
|
||||
|
@ -505,6 +510,7 @@ AC_PCH_FLAG([-fpch-preprocess])
|
|||
# Internationalisation support
|
||||
##############################
|
||||
AM_GNU_GETTEXT([external])
|
||||
AM_GNU_GETTEXT_VERSION([0.19.7])
|
||||
|
||||
################
|
||||
# Update checker
|
||||
|
@ -564,6 +570,7 @@ DEFAULT_PLAYER_AUDIO=${DEFAULT_PLAYER_AUDIO:-NONE}
|
|||
# Files that need substitution.
|
||||
AC_CONFIG_FILES([
|
||||
packages/desktop/aegisub.desktop.template
|
||||
packages/desktop/aegisub.appdata.xml.template
|
||||
src/libresrc/default_config_platform.json
|
||||
tools/osx-bundle.sed
|
||||
Makefile.inc
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <algorithm>
|
||||
|
||||
namespace agi {
|
||||
Time::Time(int time) : time(util::mid(0, time, 10 * 60 * 60 * 1000 - 1)) { }
|
||||
Time::Time(int time) : time(util::mid(0, time, 10 * 60 * 60 * 1000 - 6)) { }
|
||||
|
||||
Time::Time(std::string const& text) {
|
||||
int after_decimal = -1;
|
||||
|
@ -56,29 +56,39 @@ Time::Time(std::string const& text) {
|
|||
time = (time * 60 + current) * 1000;
|
||||
|
||||
// Limit to the valid range
|
||||
time = util::mid(0, time, 10 * 60 * 60 * 1000 - 1);
|
||||
time = util::mid(0, time, 10 * 60 * 60 * 1000 - 6);
|
||||
}
|
||||
|
||||
std::string Time::GetAssFormatted(bool msPrecision) const {
|
||||
int ass_time = msPrecision ? time : int(*this);
|
||||
std::string ret(10 + msPrecision, ':');
|
||||
ret[0] = '0' + GetTimeHours();
|
||||
ret[2] = '0' + (time % (60 * 60 * 1000)) / (60 * 1000 * 10);
|
||||
ret[3] = '0' + (time % (10 * 60 * 1000)) / (60 * 1000);
|
||||
ret[5] = '0' + (time % (60 * 1000)) / (1000 * 10);
|
||||
ret[6] = '0' + (time % (10 * 1000)) / 1000;
|
||||
ret[0] = '0' + ass_time / 3600000;
|
||||
ret[2] = '0' + (ass_time % (60 * 60 * 1000)) / (60 * 1000 * 10);
|
||||
ret[3] = '0' + (ass_time % (10 * 60 * 1000)) / (60 * 1000);
|
||||
ret[5] = '0' + (ass_time % (60 * 1000)) / (1000 * 10);
|
||||
ret[6] = '0' + (ass_time % (10 * 1000)) / 1000;
|
||||
ret[7] = '.';
|
||||
ret[8] = '0' + (time % 1000) / 100;
|
||||
ret[9] = '0' + (time % 100) / 10;
|
||||
ret[8] = '0' + (ass_time % 1000) / 100;
|
||||
ret[9] = '0' + (ass_time % 100) / 10;
|
||||
if (msPrecision)
|
||||
ret[10] = '0' + time % 10;
|
||||
ret[10] = '0' + ass_time % 10;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Time::GetTimeHours() const { return time / 3600000; }
|
||||
int Time::GetTimeMinutes() const { return (time % 3600000) / 60000; }
|
||||
int Time::GetTimeSeconds() const { return (time % 60000) / 1000; }
|
||||
int Time::GetTimeMiliseconds() const { return (time % 1000); }
|
||||
int Time::GetTimeCentiseconds() const { return (time % 1000) / 10; }
|
||||
std::string Time::GetSrtFormatted() const {
|
||||
std::string ret(12, ':');
|
||||
ret[0] = '0';
|
||||
ret[1] = '0' + time / 3600000;
|
||||
ret[3] = '0' + (time % (60 * 60 * 1000)) / (60 * 1000 * 10);
|
||||
ret[4] = '0' + (time % (10 * 60 * 1000)) / (60 * 1000);
|
||||
ret[6] = '0' + (time % (60 * 1000)) / (1000 * 10);
|
||||
ret[7] = '0' + (time % (10 * 1000)) / 1000;
|
||||
ret[8] = ',';
|
||||
ret[9] = '0' + (time % 1000) / 100;
|
||||
ret[10] = '0' + (time % 100) / 10;
|
||||
ret[11] = '0' + time % 10;
|
||||
return ret;
|
||||
}
|
||||
|
||||
SmpteFormatter::SmpteFormatter(vfr::Framerate fps, char sep)
|
||||
: fps(std::move(fps))
|
||||
|
|
|
@ -41,14 +41,14 @@ public:
|
|||
|
||||
void FillBuffer(void *buf, int64_t start, int64_t count64) const override {
|
||||
auto count = static_cast<size_t>(count64);
|
||||
assert(count == count64);
|
||||
assert(count64 >= 0 && count == static_cast<uint64_t>(count64));
|
||||
|
||||
src_buf.resize(count * src_bytes_per_sample * channels);
|
||||
source->GetAudio(src_buf.data(), start, count);
|
||||
|
||||
auto dest = static_cast<int16_t*>(buf);
|
||||
|
||||
for (int64_t i = 0; i < count * channels; ++i) {
|
||||
for (size_t i = 0; i < count * channels; ++i) {
|
||||
int64_t sample = 0;
|
||||
|
||||
// 8 bits per sample is assumed to be unsigned with a bias of 127,
|
||||
|
@ -85,7 +85,7 @@ public:
|
|||
|
||||
void FillBuffer(void *buf, int64_t start, int64_t count64) const override {
|
||||
auto count = static_cast<size_t>(count64);
|
||||
assert(count == count64);
|
||||
assert(count64 >= 0 && count == static_cast<uint64_t>(count64));
|
||||
|
||||
src_buf.resize(count * channels);
|
||||
source->GetAudio(&src_buf[0], start, count);
|
||||
|
@ -119,7 +119,7 @@ public:
|
|||
|
||||
void FillBuffer(void *buf, int64_t start, int64_t count64) const override {
|
||||
auto count = static_cast<size_t>(count64);
|
||||
assert(count == count64);
|
||||
assert(count64 >= 0 && count == static_cast<uint64_t>(count64));
|
||||
|
||||
src_buf.resize(count * src_channels);
|
||||
source->GetAudio(&src_buf[0], start, count);
|
||||
|
|
|
@ -77,7 +77,7 @@ void RAMAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const
|
|||
break;
|
||||
}
|
||||
|
||||
const int i = (start * bytes_per_sample) >> CacheBits;
|
||||
const size_t i = (start * bytes_per_sample) >> CacheBits;
|
||||
const int start_offset = (start * bytes_per_sample) & (CacheBlockSize-1);
|
||||
const int read_size = std::min<int>(bytes_remaining, CacheBlockSize - start_offset);
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ struct utext_deleter {
|
|||
};
|
||||
using utext_ptr = std::unique_ptr<UText, utext_deleter>;
|
||||
|
||||
UChar32 ass_special_chars[] = {'n', 'N', 'h'};
|
||||
|
||||
icu::BreakIterator& get_break_iterator(const char *ptr, size_t len) {
|
||||
static std::unique_ptr<icu::BreakIterator> bi;
|
||||
static std::once_flag token;
|
||||
|
@ -65,10 +67,25 @@ size_t count_in_range(Iterator begin, Iterator end, int mask) {
|
|||
UChar32 c;
|
||||
int i = 0;
|
||||
U8_NEXT_UNSAFE(begin + pos, i, c);
|
||||
if ((U_GET_GC_MASK(c) & mask) == 0)
|
||||
if ((U_GET_GC_MASK(c) & mask) == 0) {
|
||||
if (mask & U_GC_Z_MASK && pos != 0) {
|
||||
UChar32 *result = std::find(std::begin(ass_special_chars), std::end(ass_special_chars), c);
|
||||
if (result != std::end(ass_special_chars)) {
|
||||
UChar32 c2;
|
||||
i = 0;
|
||||
U8_PREV_UNSAFE(begin + pos, i, c2);
|
||||
if (c2 != (UChar32) '\\')
|
||||
++count;
|
||||
else if (!(mask & U_GC_P_MASK))
|
||||
--count;
|
||||
}
|
||||
else
|
||||
++count;
|
||||
}
|
||||
|
||||
else
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
|
|
@ -29,37 +29,44 @@ namespace agi { namespace charset {
|
|||
std::string Detect(agi::fs::path const& file) {
|
||||
agi::read_file_mapping fp(file);
|
||||
|
||||
// FIXME: It is an empty file. Treat as ascii
|
||||
if (fp.size() == 0) return "ascii";
|
||||
|
||||
// FIXME: Dirty hack for Matroska. These 4 bytes are the magic
|
||||
// number of EBML which is used by mkv and webm
|
||||
if (fp.size() >= 4) {
|
||||
const char* buf = fp.read(0, 4);
|
||||
if (!strncmp(buf, "\x1a\x45\xdf\xa3", 4))
|
||||
return "binary";
|
||||
}
|
||||
|
||||
#ifdef WITH_UCHARDET
|
||||
agi::scoped_holder<uchardet_t> ud(uchardet_new(), uchardet_delete);
|
||||
for (uint64_t offset = 0; offset < fp.size(); ) {
|
||||
auto read = std::min<uint64_t>(65536, fp.size() - offset);
|
||||
auto buf = fp.read(offset, read);
|
||||
uchardet_handle_data(ud, buf, read);
|
||||
offset += read;
|
||||
}
|
||||
uchardet_data_end(ud);
|
||||
std::string encoding = uchardet_get_charset(ud);
|
||||
return encoding.empty() ? "binary" : encoding;
|
||||
#else
|
||||
|
||||
// Look for utf-8 BOM
|
||||
if (fp.size() >= 3) {
|
||||
const char* buf = fp.read(0, 3);
|
||||
if (!strncmp(buf, "\xef\xbb\xbf", 3))
|
||||
return "utf-8";
|
||||
}
|
||||
|
||||
// If it's over 100 MB it's either binary or big enough that we won't
|
||||
// be able to do anything useful with it anyway
|
||||
if (fp.size() > 100 * 1024 * 1024)
|
||||
return "binary";
|
||||
|
||||
uint64_t binaryish = 0;
|
||||
|
||||
#ifdef WITH_UCHARDET
|
||||
agi::scoped_holder<uchardet_t> ud(uchardet_new(), uchardet_delete);
|
||||
for (uint64_t offset = 0; offset < fp.size(); ) {
|
||||
auto read = std::min<uint64_t>(4096, fp.size() - offset);
|
||||
auto buf = fp.read(offset, read);
|
||||
uchardet_handle_data(ud, buf, read);
|
||||
uchardet_data_end(ud);
|
||||
if (*uchardet_get_charset(ud))
|
||||
return uchardet_get_charset(ud);
|
||||
|
||||
offset += read;
|
||||
|
||||
// A dumb heuristic to detect binary files
|
||||
for (size_t i = 0; i < read; ++i) {
|
||||
if ((unsigned char)buf[i] < 32 && (buf[i] != '\r' && buf[i] != '\n' && buf[i] != '\t'))
|
||||
++binaryish;
|
||||
}
|
||||
|
||||
if (binaryish > offset / 8)
|
||||
return "binary";
|
||||
}
|
||||
return uchardet_get_charset(ud);
|
||||
#else
|
||||
auto read = std::min<uint64_t>(4096, fp.size());
|
||||
auto read = std::min<uint64_t>(65536, fp.size());
|
||||
auto buf = fp.read(0, read);
|
||||
for (size_t i = 0; i < read; ++i) {
|
||||
if ((unsigned char)buf[i] < 32 && (buf[i] != '\r' && buf[i] != '\n' && buf[i] != '\t'))
|
||||
|
|
|
@ -366,7 +366,7 @@ size_t IconvWrapper::RequiredBufferSize(std::string const& str) {
|
|||
}
|
||||
|
||||
size_t IconvWrapper::RequiredBufferSize(const char* src, size_t srcLen) {
|
||||
char buff[512];
|
||||
char buff[65536];
|
||||
size_t charsWritten = 0;
|
||||
size_t res;
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ void tagless_find_helper::map_range(size_t &s, size_t &e) {
|
|||
// match
|
||||
for (auto const& block : blocks) {
|
||||
// Any blocks before start are irrelevant as they're included in `start`
|
||||
if (block.second < s) continue;
|
||||
if (block.second <= start) continue;
|
||||
// Skip over blocks at the very beginning of the match
|
||||
// < should only happen if the cursor was within an override block
|
||||
// when the user started a search
|
||||
|
|
|
@ -28,16 +28,14 @@ public:
|
|||
Time(std::string const& text);
|
||||
|
||||
/// Get millisecond, rounded to centisecond precision
|
||||
operator int() const { return time / 10 * 10; }
|
||||
|
||||
int GetTimeHours() const; ///< Get the hours portion of this time
|
||||
int GetTimeMinutes() const; ///< Get the minutes portion of this time
|
||||
int GetTimeSeconds() const; ///< Get the seconds portion of this time
|
||||
int GetTimeMiliseconds() const; ///< Get the miliseconds portion of this time
|
||||
int GetTimeCentiseconds() const; ///< Get the centiseconds portion of this time
|
||||
// Always round up for 5ms because the range is [start, stop)
|
||||
operator int() const { return (time + 5) - (time + 5) % 10; }
|
||||
|
||||
/// Return the time as a string
|
||||
/// @param ms Use milliseconds precision, for non-ASS formats
|
||||
std::string GetAssFormatted(bool ms=false) const;
|
||||
|
||||
/// Return the time as a string
|
||||
std::string GetSrtFormatted() const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace agi {
|
|||
DEFINE_FS_EXCEPTION(FileNotFound, FileNotAccessible, "File not found: ");
|
||||
|
||||
/// An error of some unknown type has occured
|
||||
DEFINE_EXCEPTION(FileSystemUnknownError, FileSystemError);;
|
||||
DEFINE_EXCEPTION(FileSystemUnknownError, FileSystemError);
|
||||
|
||||
/// The path exists, but isn't a file
|
||||
DEFINE_FS_EXCEPTION(NotAFile, FileNotAccessible, "Path is not a file (and should be): ");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifdef __cplusplus
|
||||
#ifndef _WIN32
|
||||
#if !defined(_WIN32) && !defined(CMAKE_BUILD)
|
||||
#include "../acconf.h"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -2334,7 +2334,7 @@ static int matchl (lua_State *L) {
|
|||
}
|
||||
|
||||
|
||||
static struct luaL_reg pattreg[] = {
|
||||
static struct luaL_Reg pattreg[] = {
|
||||
{"match", matchl},
|
||||
{"print", printpat_l},
|
||||
{"locale", locale_l},
|
||||
|
@ -2360,7 +2360,7 @@ static struct luaL_reg pattreg[] = {
|
|||
};
|
||||
|
||||
|
||||
static struct luaL_reg metapattreg[] = {
|
||||
static struct luaL_Reg metapattreg[] = {
|
||||
{"__add", union_l},
|
||||
{"__pow", star_l},
|
||||
{"__sub", diff_l},
|
||||
|
|
|
@ -10,15 +10,26 @@ DESKTOP_FILE_INSTALLED = $(DESTDIR)$(P_DESKTOP)/$(notdir $(DESKTOP_FILE))
|
|||
|
||||
DISTCLEANFILES += $(DESKTOP_FILE)
|
||||
|
||||
APPDATA_FILE := $(d)aegisub.appdata.xml
|
||||
APPDATA_FILE_PO := $(d)../../po
|
||||
APPDATA_FILE_INSTALLED = $(DESTDIR)$(P_APPDATA)/$(notdir $(APPDATA_FILE))
|
||||
|
||||
DISTCLEANFILES += $(APPDATA_FILE)
|
||||
|
||||
%.desktop: %.desktop.template $(DESKTOP_FILE_PO)
|
||||
intltool-merge --quiet --desktop-style $(DESKTOP_FILE_PO) $< $@
|
||||
$(AM_V_GEN)$(BIN_MSGFMT) --desktop --template $< -o $@ $(DESKTOP_FILE_PO)
|
||||
|
||||
%.appdata.xml: %.appdata.xml.template $(APPDATA_FILE_PO)
|
||||
intltool-merge --quiet --xml-style $(APPDATA_FILE_PO) $< $@
|
||||
|
||||
$(ICONS_INSTALLED)png: $(d)%.png ; $(MKDIR_INSTALL)
|
||||
$(ICONS_INSTALLED)svg: $(d)%.svg ; $(MKDIR_INSTALL)
|
||||
$(DESKTOP_FILE_INSTALLED): $(DESKTOP_FILE) ; $(MKDIR_INSTALL)
|
||||
$(APPDATA_FILE_INSTALLED): $(APPDATA_FILE) ; $(MKDIR_INSTALL)
|
||||
|
||||
ifneq (yes, $(BUILD_DARWIN))
|
||||
install: \
|
||||
$(APPDATA_FILE_INSTALLED) \
|
||||
$(DESKTOP_FILE_INSTALLED) \
|
||||
$(patsubst %.png, $(ICONS_INSTALLED)png, $(patsubst %.svg, $(ICONS_INSTALLED)svg, $(notdir $(ICONS))))
|
||||
endif
|
||||
|
|
58
packages/desktop/aegisub.appdata.xml.template.in
Normal file
58
packages/desktop/aegisub.appdata.xml.template.in
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>aegisub.desktop</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>BSD-3-Clause AND MIT AND MPL-1.1</project_license>
|
||||
<_name>Aegisub</_name>
|
||||
<_summary>A free, cross-platform open source tool for creating and modifying subtitles</_summary>
|
||||
<description>
|
||||
<_p>Aegisub is a free, cross-platform open source tool for creating and modifying subtitles. Aegisub makes it quick and easy to time subtitles to audio, and features many powerful tools for styling them, including a built-in real-time video preview.</_p>
|
||||
<_p>Aegisub was originally created as a tool to make typesetting, particularly in anime fansubs, a less painful experience. At the time of the start of the project, many other programs that supported the Advanced Substation Alpha format lacked (and in many cases, still lack; development on several competing programs have since been dropped for various reasons completely unrelated to Aegisub) many vital functions, or were too buggy and/or unreliable to be really useful.</_p>
|
||||
<_p>Since then, Aegisub has grown into a fully fledged, highly customizable subtitle editor. It features a lot of convenient tools to help you with timing, typesetting, editing and translating subtitles, as well as a powerful scripting environment called Automation (originally mostly intended for creating karaoke effects, Automation can now be used much else, including creating macros and various other convenient tools).</_p>
|
||||
<_p>Some highlights of Aegisub:</_p>
|
||||
<ul>
|
||||
<_li>Simple and intuitive yet powerful interface for editing subtitles</_li>
|
||||
<_li>Support for many formats and character sets</_li>
|
||||
<_li>Powerful video mode</_li>
|
||||
<_li>Visual typesetting tools</_li>
|
||||
<_li>Intuitive and customizable audio timing mode</_li>
|
||||
<_li>Fully scriptable through the Automation module</_li>
|
||||
</ul>
|
||||
</description>
|
||||
<launchable type="desktop-id">aegisub.desktop</launchable>
|
||||
<kudos>
|
||||
<kudo>HiDpiIcon</kudo>
|
||||
<kudo>HighContrast</kudo>
|
||||
<kudo>UserDocs</kudo>
|
||||
</kudos>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<_caption>Typesetting</_caption>
|
||||
<image>http://static.aegisub.org/img/screenshots/unix/typesetting-efc51b7a.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<_caption>Audio video</_caption>
|
||||
<image>http://static.aegisub.org/img/screenshots/unix/audio-video-f1f81fc2.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<_caption>Audio timing</_caption>
|
||||
<image>http://static.aegisub.org/img/screenshots/unix/audio-timing-1d8fce7e.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<developer_name>Aegisub Group</developer_name>
|
||||
<url type="bugtracker">https://github.com/Aegisub/Aegisub/issues</url>
|
||||
<url type="faq">http://docs.aegisub.org/manual/FAQ</url>
|
||||
<url type="help">http://docs.aegisub.org</url>
|
||||
<url type="homepage">http://www.aegisub.org</url>
|
||||
<url type="translate">https://sites.google.com/site/rockytdrontransifex/aegisub</url>
|
||||
<content_rating type="oars-1.0">
|
||||
<content_attribute id="social-info">mild</content_attribute>
|
||||
</content_rating>
|
||||
<translation type="gettext">aegisub</translation>
|
||||
<provides>
|
||||
<binary>aegisub</binary>
|
||||
</provides>
|
||||
<releases>
|
||||
<release version="3.2.2" date="2014-12-08"/>
|
||||
</releases>
|
||||
</component>
|
|
@ -1,10 +1,10 @@
|
|||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
_Name=Aegisub
|
||||
_GenericName=Subtitle Editor
|
||||
_Comment=Create and edit subtitles for film and videos.
|
||||
Exec=@AEGISUB_COMMAND@ %f
|
||||
Name=Aegisub
|
||||
GenericName=Subtitle Editor
|
||||
Comment=Create and edit subtitles for film and videos.
|
||||
Exec=env GDK_BACKEND=x11 @AEGISUB_COMMAND@ %f
|
||||
TryExec=@AEGISUB_COMMAND@
|
||||
Icon=aegisub
|
||||
Terminal=false
|
||||
|
|
|
@ -64,6 +64,11 @@ Root: HKLM; Subkey: "SOFTWARE\Classes\Applications\aegisub{#ARCH}.exe\SupportedT
|
|||
Root: HKLM; Subkey: "SOFTWARE\Classes\Applications\aegisub{#ARCH}.exe\SupportedTypes"; ValueType: string; ValueName: ".wav"; ValueData: ""; Flags: uninsdeletekey
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\Applications\aegisub{#ARCH}.exe\SupportedTypes"; ValueType: string; ValueName: ".ogg"; ValueData: ""; Flags: uninsdeletekey
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\Applications\aegisub{#ARCH}.exe\SupportedTypes"; ValueType: string; ValueName: ".avs"; ValueData: ""; Flags: uninsdeletekey
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\Applications\aegisub{#ARCH}.exe\SupportedTypes"; ValueType: string; ValueName: ".opus"; ValueData: ""; Flags: uninsdeletekey
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\Applications\aegisub{#ARCH}.exe\SupportedTypes"; ValueType: string; ValueName: ".h264"; ValueData: ""; Flags: uninsdeletekey
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\Applications\aegisub{#ARCH}.exe\SupportedTypes"; ValueType: string; ValueName: ".hevc"; ValueData: ""; Flags: uninsdeletekey
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\Applications\aegisub{#ARCH}.exe\SupportedTypes"; ValueType: string; ValueName: ".eac3"; ValueData: ""; Flags: uninsdeletekey
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\Applications\aegisub{#ARCH}.exe\SupportedTypes"; ValueType: string; ValueName: ".webm"; ValueData: ""; Flags: uninsdeletekey
|
||||
; Class for general subtitle formats
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\Aegisub.Subtitle.1"; ValueType: string; ValueName: ""; ValueData: "Aegisub subtitle file"; Flags: uninsdeletekey
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\Aegisub.Subtitle.1"; ValueType: dword; ValueName: "EditFlags"; ValueData: $af0; Flags: uninsdeletekey
|
||||
|
@ -195,4 +200,8 @@ Root: HKLM; Subkey: "SOFTWARE\Classes\.m4a\OpenWithProgids"; ValueType: string;
|
|||
Root: HKLM; Subkey: "SOFTWARE\Classes\.wav\OpenWithProgids"; ValueType: string; ValueName: "Aegisub.Audio.1"; Flags: uninsdeletevalue
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\.ogg\OpenWithProgids"; ValueType: string; ValueName: "Aegisub.Media.1"; Flags: uninsdeletevalue
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\.avs\OpenWithProgids"; ValueType: string; ValueName: "Aegisub.Video.1"; Flags: uninsdeletevalue
|
||||
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\.opus\OpenWithProgids"; ValueType: string; ValueName: "Aegisub.Audio.1"; Flags: uninsdeletevalue
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\.h264\OpenWithProgids"; ValueType: string; ValueName: "Aegisub.Video.1"; Flags: uninsdeletevalue
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\.hevc\OpenWithProgids"; ValueType: string; ValueName: "Aegisub.Video.1"; Flags: uninsdeletevalue
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\.eac3\OpenWithProgids"; ValueType: string; ValueName: "Aegisub.Audio.1"; Flags: uninsdeletevalue
|
||||
Root: HKLM; Subkey: "SOFTWARE\Classes\.webm\OpenWithProgids"; ValueType: string; ValueName: "Aegisub.Media.1"; Flags: uninsdeletevalue
|
||||
|
|
|
@ -46,6 +46,12 @@ do
|
|||
| maybe_append
|
||||
done
|
||||
|
||||
if which xmlstarlet >/dev/null 2>&1 && which jq >/dev/null 2>&1; then
|
||||
for i in 'name' 'summary' 'p' 'li' 'caption'; do
|
||||
xmlstarlet sel -t -v "//_$i" ../packages/desktop/aegisub.appdata.xml.template.in | jq -R .
|
||||
done | nl -v0 -w1 -s'|' | sed -re 's/^/aegisub.appdata.xml|/' | maybe_append
|
||||
fi
|
||||
|
||||
grep '^_[A-Za-z0-9]*=.*' ../packages/win_installer/fragment_strings.iss.in | while read line
|
||||
do
|
||||
echo "$line" \
|
||||
|
|
|
@ -66,6 +66,7 @@ src_OBJ := \
|
|||
$(d)help_button.o \
|
||||
$(d)hotkey.o \
|
||||
$(d)hotkey_data_view_model.o \
|
||||
$(d)image_position_picker.o \
|
||||
$(d)initial_line_state.o \
|
||||
$(d)main.o \
|
||||
$(d)menu.o \
|
||||
|
@ -188,14 +189,13 @@ endif
|
|||
#####################
|
||||
# SOURCE-LEVEL CFLAGS
|
||||
#####################
|
||||
$(d)MatroskaParser.o_FLAGS := -Wno-sometimes-uninitialized
|
||||
$(d)audio_player.o_FLAGS := $(CFLAGS_ALSA) $(CFLAGS_PORTAUDIO) $(CFLAGS_LIBPULSE) $(CFLAGS_OPENAL)
|
||||
$(d)audio_provider_factory.o_FLAGS := $(CFLAGS_FFMS2)
|
||||
$(d)auto4_base.o_FLAGS := $(CFLAGS_FREETYPE)
|
||||
$(d)charset_detect.o_FLAGS := -D_X86_
|
||||
$(d)font_file_lister_fontconfig.o_FLAGS := $(CFLAGS_FONTCONFIG)
|
||||
$(d)subtitles_provider.o_FLAGS := $(CFLAGS_LIBASS)
|
||||
$(d)subtitles_provider_libass.o_FLAGS := $(CFLAGS_LIBASS) -Wno-c++11-narrowing
|
||||
$(d)subtitles_provider_libass.o_FLAGS := $(CFLAGS_LIBASS) -Wno-narrowing
|
||||
$(d)text_file_reader.o_FLAGS := -D_X86_
|
||||
$(d)video_provider_manager.o_FLAGS := $(CFLAGS_FFMS2)
|
||||
$(d)auto4_lua.o_FLAGS := $(CFLAGS_LUA)
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#if !defined(_WIN32) && !defined(CMAKE_BUILD)
|
||||
#include "../acconf.h"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ class AssStyle final : public AssEntry, public AssEntryListHook {
|
|||
public:
|
||||
std::string name = "Default"; ///< Name of the style; must be case-insensitively unique within a file despite being case-sensitive
|
||||
std::string font = "Arial"; ///< Font face name
|
||||
double fontsize = 20.; ///< Font size
|
||||
double fontsize = 48.; ///< Font size
|
||||
|
||||
agi::Color primary{ 255, 255, 255 }; ///< Default text color
|
||||
agi::Color secondary{ 255, 0, 0 }; ///< Text color for not-yet-reached karaoke syllables
|
||||
|
|
|
@ -129,10 +129,9 @@ END_EVENT_TABLE()
|
|||
void AudioBox::OnMouseWheel(wxMouseEvent &evt) {
|
||||
if (!ForwardMouseWheelEvent(audioDisplay, evt))
|
||||
return;
|
||||
|
||||
bool zoom = evt.CmdDown() != OPT_GET("Audio/Wheel Default to Zoom")->GetBool();
|
||||
if (!zoom) {
|
||||
int amount = -evt.GetWheelRotation() * GetClientSize().GetWidth() / (evt.GetWheelDelta() * 3);
|
||||
int amount = -evt.GetWheelRotation();
|
||||
// If the user did a horizontal scroll the amount should be inverted
|
||||
// for it to be natural.
|
||||
if (evt.GetWheelAxis() == 1) amount = -amount;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
AudioColorScheme::AudioColorScheme(int prec, std::string const& scheme_name, int audio_rendering_style)
|
||||
: palette((3<<prec) + 3)
|
||||
, factor(1<<prec)
|
||||
, factor((size_t)1<<prec)
|
||||
{
|
||||
std::string opt_base = "Colour/Schemes/" + scheme_name + "/";
|
||||
switch (static_cast<AudioRenderingStyle>(audio_rendering_style))
|
||||
|
|
|
@ -128,8 +128,9 @@ public:
|
|||
/// Get the current Selection colour
|
||||
wxColour Selection() const { return focused ? sel_focused_colour : sel_colour; }
|
||||
};
|
||||
}
|
||||
|
||||
class AudioDisplayScrollbar final : public AudioDisplayInteractionObject {
|
||||
class AudioDisplay::AudioDisplayScrollbar final : public AudioDisplayInteractionObject {
|
||||
static const int height = 15;
|
||||
static const int min_width = 10;
|
||||
|
||||
|
@ -267,9 +268,9 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
const int AudioDisplayScrollbar::min_width;
|
||||
const int AudioDisplay::AudioDisplayScrollbar::min_width;
|
||||
|
||||
class AudioDisplayTimeline final : public AudioDisplayInteractionObject {
|
||||
class AudioDisplay::AudioDisplayTimeline final : public AudioDisplayInteractionObject {
|
||||
int duration = 0; ///< Total duration in ms
|
||||
double ms_per_pixel = 1.0; ///< Milliseconds per pixel
|
||||
int pixel_left = 0; ///< Leftmost visible pixel (i.e. scroll position)
|
||||
|
@ -478,6 +479,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
class AudioStyleRangeMerger final : public AudioRenderingStyleRanges {
|
||||
typedef std::map<int, AudioRenderingStyle> style_map;
|
||||
public:
|
||||
|
|
|
@ -47,11 +47,6 @@ class AudioRenderer;
|
|||
class AudioRendererBitmapProvider;
|
||||
class TimeRange;
|
||||
|
||||
// Helper classes used in implementation of the audio display
|
||||
namespace {
|
||||
class AudioDisplayScrollbar;
|
||||
class AudioDisplayTimeline;
|
||||
}
|
||||
class AudioDisplayInteractionObject;
|
||||
class AudioMarkerInteractionObject;
|
||||
|
||||
|
@ -79,9 +74,11 @@ class AudioDisplay: public wxWindow {
|
|||
agi::AudioProvider *provider = nullptr;
|
||||
|
||||
/// Scrollbar helper object
|
||||
class AudioDisplayScrollbar;
|
||||
std::unique_ptr<AudioDisplayScrollbar> scrollbar;
|
||||
|
||||
/// Timeline helper object
|
||||
class AudioDisplayTimeline;
|
||||
std::unique_ptr<AudioDisplayTimeline> timeline;
|
||||
|
||||
/// The interaction object for the last-dragged audio marker
|
||||
|
|
|
@ -280,8 +280,7 @@ void AudioKaraoke::OnMouse(wxMouseEvent &event) {
|
|||
split_area->Refresh(false);
|
||||
scroll_timer.Start(50);
|
||||
split_area->CaptureMouse();
|
||||
wxTimerEvent evt;
|
||||
OnScrollTimer(evt);
|
||||
OnScrollTimer();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -317,7 +316,7 @@ void AudioKaraoke::OnMouse(wxMouseEvent &event) {
|
|||
split_area->Refresh(false);
|
||||
}
|
||||
|
||||
void AudioKaraoke::OnScrollTimer(wxTimerEvent &) {
|
||||
void AudioKaraoke::OnScrollTimer() {
|
||||
scroll_x += scroll_dir * char_width * 3;
|
||||
|
||||
int max_scroll = rendered_line.GetWidth() + 20 - split_area->GetClientSize().GetWidth();
|
||||
|
@ -329,6 +328,10 @@ void AudioKaraoke::OnScrollTimer(wxTimerEvent &) {
|
|||
split_area->Refresh(false);
|
||||
}
|
||||
|
||||
void AudioKaraoke::OnScrollTimer(wxTimerEvent&) {
|
||||
OnScrollTimer();
|
||||
}
|
||||
|
||||
void AudioKaraoke::LoadFromLine() {
|
||||
scroll_x = 0;
|
||||
scroll_timer.Stop();
|
||||
|
|
|
@ -142,6 +142,7 @@ class AudioKaraoke final : public wxWindow {
|
|||
void OnPaint(wxPaintEvent &event);
|
||||
void OnSize(wxSizeEvent &event);
|
||||
void OnAudioOpened(agi::AudioProvider *provider);
|
||||
void OnScrollTimer();
|
||||
void OnScrollTimer(wxTimerEvent& event);
|
||||
|
||||
public:
|
||||
|
|
|
@ -40,13 +40,25 @@
|
|||
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
||||
#ifdef WITH_ALSA
|
||||
std::unique_ptr<AudioPlayer> CreateAlsaPlayer(agi::AudioProvider *providers, wxWindow *window);
|
||||
#endif
|
||||
#ifdef WITH_DIRECTSOUND
|
||||
std::unique_ptr<AudioPlayer> CreateDirectSoundPlayer(agi::AudioProvider *providers, wxWindow *window);
|
||||
std::unique_ptr<AudioPlayer> CreateDirectSound2Player(agi::AudioProvider *providers, wxWindow *window);
|
||||
#endif
|
||||
#ifdef WITH_OPENAL
|
||||
std::unique_ptr<AudioPlayer> CreateOpenALPlayer(agi::AudioProvider *providers, wxWindow *window);
|
||||
#endif
|
||||
#ifdef WITH_PORTAUDIO
|
||||
std::unique_ptr<AudioPlayer> CreatePortAudioPlayer(agi::AudioProvider *providers, wxWindow *window);
|
||||
#endif
|
||||
#ifdef WITH_LIBPULSE
|
||||
std::unique_ptr<AudioPlayer> CreatePulseAudioPlayer(agi::AudioProvider *providers, wxWindow *window);
|
||||
#endif
|
||||
#ifdef WITH_OSS
|
||||
std::unique_ptr<AudioPlayer> CreateOSSPlayer(agi::AudioProvider *providers, wxWindow *window);
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
struct factory {
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
#include <mmsystem.h>
|
||||
#include <dsound.h>
|
||||
#include <cguid.h>
|
||||
|
||||
namespace {
|
||||
class DirectSoundPlayer;
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include <mmsystem.h>
|
||||
#include <process.h>
|
||||
#include <dsound.h>
|
||||
#include <cguid.h>
|
||||
|
||||
namespace {
|
||||
class DirectSoundPlayer2Thread;
|
||||
|
|
|
@ -144,7 +144,7 @@ void FFmpegSourceAudioProvider::LoadAudio(agi::fs::path const& filename) {
|
|||
// update access time of index file so it won't get cleaned away
|
||||
agi::fs::Touch(CacheName);
|
||||
|
||||
AudioSource = FFMS_CreateAudioSource(filename.string().c_str(), TrackNumber, Index, -1, &ErrInfo);
|
||||
AudioSource = FFMS_CreateAudioSource(filename.string().c_str(), TrackNumber, Index, FFMS_DELAY_FIRST_VIDEO_TRACK, &ErrInfo);
|
||||
if (!AudioSource)
|
||||
throw agi::AudioProviderError(std::string("Failed to open audio track: ") + ErrInfo.Buffer);
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ void AudioSpectrumRenderer::RecreateCache()
|
|||
|
||||
if (provider)
|
||||
{
|
||||
size_t block_count = (size_t)((provider->GetNumSamples() + (size_t)(1<<derivation_dist) - 1) >> derivation_dist);
|
||||
size_t block_count = (size_t)((provider->GetNumSamples() + ((size_t)1<<derivation_dist) - 1) >> derivation_dist);
|
||||
cache = agi::make_unique<AudioSpectrumCache>(block_count, this);
|
||||
|
||||
#ifdef WITH_FFTW3
|
||||
|
@ -170,7 +170,7 @@ void AudioSpectrumRenderer::FillBlock(size_t block_index, float *block)
|
|||
assert(cache);
|
||||
assert(block);
|
||||
|
||||
int64_t first_sample = ((int64_t)block_index) << derivation_dist;
|
||||
int64_t first_sample = (((int64_t)block_index) << derivation_dist) - ((int64_t)1 << derivation_size);
|
||||
provider->GetAudio(&audio_scratch[0], first_sample, 2 << derivation_size);
|
||||
|
||||
#ifdef WITH_FFTW3
|
||||
|
@ -181,7 +181,7 @@ void AudioSpectrumRenderer::FillBlock(size_t block_index, float *block)
|
|||
double scale_factor = 9 / sqrt(2 << (derivation_size + 1));
|
||||
|
||||
fftw_complex *o = dft_output;
|
||||
for (size_t si = 1<<derivation_size; si > 0; --si)
|
||||
for (size_t si = (size_t)1<<derivation_size; si > 0; --si)
|
||||
{
|
||||
*block++ = log10( sqrt(o[0][0] * o[0][0] + o[0][1] * o[0][1]) * scale_factor + 1 );
|
||||
o++;
|
||||
|
|
|
@ -390,7 +390,7 @@ int AudioTimingControllerKaraoke::MoveMarker(KaraokeMarker *marker, int new_posi
|
|||
void AudioTimingControllerKaraoke::AnnounceChanges(int syl) {
|
||||
if (syl < 0) return;
|
||||
|
||||
if (syl == cur_syl || syl == cur_syl + 1) {
|
||||
if (static_cast<unsigned>(syl) == cur_syl || static_cast<unsigned>(syl) == cur_syl + 1) {
|
||||
AnnounceUpdatedPrimaryRange();
|
||||
AnnounceUpdatedStyleRanges();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "audio_timing.h"
|
||||
#include "command/command.h"
|
||||
#include "compat.h"
|
||||
#include "frame_main.h"
|
||||
#include "include/aegisub/context.h"
|
||||
#include "options.h"
|
||||
#include "project.h"
|
||||
|
@ -52,6 +53,7 @@
|
|||
#include "video_controller.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <libaegisub/dispatch.h>
|
||||
#include <libaegisub/format.h>
|
||||
#include <libaegisub/lua/ffi.h>
|
||||
#include <libaegisub/lua/modules.h>
|
||||
|
@ -270,6 +272,19 @@ namespace {
|
|||
return 2;
|
||||
}
|
||||
|
||||
int lua_set_status_text(lua_State *L)
|
||||
{
|
||||
const agi::Context *c = get_context(L);
|
||||
if (!c || !c->frame) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
std::string text = check_string(L, 1);
|
||||
lua_pop(L, 1);
|
||||
agi::dispatch::Main().Async([=] { c->frame->StatusTimeout(to_wx(text)); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int project_properties(lua_State *L)
|
||||
{
|
||||
const agi::Context *c = get_context(L);
|
||||
|
@ -473,6 +488,7 @@ namespace {
|
|||
set_field<get_translation>(L, "gettext");
|
||||
set_field<project_properties>(L, "project_properties");
|
||||
set_field<lua_get_audio_selection>(L, "get_audio_selection");
|
||||
set_field<lua_set_status_text>(L, "set_status_text");
|
||||
|
||||
// store aegisub table to globals
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
|
|
|
@ -744,8 +744,8 @@ namespace Automation4 {
|
|||
, can_modify(can_modify)
|
||||
, can_set_undo(can_set_undo)
|
||||
{
|
||||
for (auto& line : ass->Info)
|
||||
lines.push_back(nullptr);
|
||||
// for (auto& line : ass->Info) lines.push_back(nullptr);
|
||||
lines.insert(lines.end(), ass->Info.size(), nullptr);
|
||||
for (auto& line : ass->Styles)
|
||||
lines.push_back(&line);
|
||||
for (auto& line : ass->Events)
|
||||
|
|
751
src/avisynth.h
751
src/avisynth.h
|
@ -1,751 +0,0 @@
|
|||
// Avisynth v2.5. Copyright 2002 Ben Rudiak-Gould et al.
|
||||
// http://www.avisynth.org
|
||||
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
|
||||
// http://www.gnu.org/copyleft/gpl.html .
|
||||
//
|
||||
// Linking Avisynth statically or dynamically with other modules is making a
|
||||
// combined work based on Avisynth. Thus, the terms and conditions of the GNU
|
||||
// General Public License cover the whole combination.
|
||||
//
|
||||
// As a special exception, the copyright holders of Avisynth give you
|
||||
// permission to link Avisynth with independent modules that communicate with
|
||||
// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
|
||||
// terms of these independent modules, and to copy and distribute the
|
||||
// resulting combined work under terms of your choice, provided that
|
||||
// every copy of the combined work is accompanied by a complete copy of
|
||||
// the source code of Avisynth (the version of Avisynth used to produce the
|
||||
// combined work), being distributed under the terms of the GNU General
|
||||
// Public License plus this exception. An independent module is a module
|
||||
// which is not derived from or based on Avisynth, such as 3rd-party filters,
|
||||
// import and export plugins, or graphical user interfaces.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef __AVISYNTH_H__
|
||||
#define __AVISYNTH_H__
|
||||
|
||||
enum { AVISYNTH_INTERFACE_VERSION = 3 };
|
||||
|
||||
|
||||
/* Define all types necessary for interfacing with avisynth.dll
|
||||
Moved from internal.h */
|
||||
|
||||
// Win32 API macros, notably the types BYTE, DWORD, ULONG, etc.
|
||||
#include <windef.h>
|
||||
|
||||
// COM interface macros
|
||||
#include <objbase.h>
|
||||
|
||||
|
||||
// Raster types used by VirtualDub & Avisynth
|
||||
#define in64 (__int64)(unsigned short)
|
||||
typedef unsigned long Pixel; // this will break on 64-bit machines!
|
||||
typedef unsigned long Pixel32;
|
||||
typedef unsigned char Pixel8;
|
||||
typedef long PixCoord;
|
||||
typedef long PixDim;
|
||||
typedef long PixOffset;
|
||||
|
||||
|
||||
/* Compiler-specific crap */
|
||||
|
||||
// Tell MSVC to stop precompiling here
|
||||
#ifdef _MSC_VER
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
// Set up debugging macros for MS compilers; for others, step down to the
|
||||
// standard <assert.h> interface
|
||||
#ifdef _MSC_VER
|
||||
#include <crtdbg.h>
|
||||
#else
|
||||
#define _RPT0(a,b) ((void)0)
|
||||
#define _RPT1(a,b,c) ((void)0)
|
||||
#define _RPT2(a,b,c,d) ((void)0)
|
||||
#define _RPT3(a,b,c,d,e) ((void)0)
|
||||
#define _RPT4(a,b,c,d,e,f) ((void)0)
|
||||
|
||||
#define _ASSERTE(x) assert(x)
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// I had problems with Premiere wanting 1-byte alignment for its structures,
|
||||
// so I now set the Avisynth struct alignment explicitly here.
|
||||
#pragma pack(push,8)
|
||||
|
||||
#define FRAME_ALIGN 16
|
||||
// Default frame alignment is 16 bytes, to help P4, when using SSE2
|
||||
|
||||
// The VideoInfo struct holds global information about a clip (i.e.
|
||||
// information that does not depend on the frame number). The GetVideoInfo
|
||||
// method in IClip returns this struct.
|
||||
|
||||
// Audio Sample information
|
||||
typedef float SFLOAT;
|
||||
|
||||
enum {SAMPLE_INT8 = 1<<0,
|
||||
SAMPLE_INT16 = 1<<1,
|
||||
SAMPLE_INT24 = 1<<2, // Int24 is a very stupid thing to code, but it's supported by some hardware.
|
||||
SAMPLE_INT32 = 1<<3,
|
||||
SAMPLE_FLOAT = 1<<4};
|
||||
|
||||
enum {
|
||||
PLANAR_Y=1<<0,
|
||||
PLANAR_U=1<<1,
|
||||
PLANAR_V=1<<2,
|
||||
PLANAR_ALIGNED=1<<3,
|
||||
PLANAR_Y_ALIGNED=PLANAR_Y|PLANAR_ALIGNED,
|
||||
PLANAR_U_ALIGNED=PLANAR_U|PLANAR_ALIGNED,
|
||||
PLANAR_V_ALIGNED=PLANAR_V|PLANAR_ALIGNED,
|
||||
};
|
||||
|
||||
struct VideoInfo {
|
||||
int width, height; // width=0 means no video
|
||||
unsigned fps_numerator, fps_denominator;
|
||||
int num_frames;
|
||||
// This is more extensible than previous versions. More properties can be added seeminglesly.
|
||||
|
||||
// Colorspace properties.
|
||||
enum {
|
||||
CS_BGR = 1<<28,
|
||||
CS_YUV = 1<<29,
|
||||
CS_INTERLEAVED = 1<<30,
|
||||
CS_PLANAR = 1<<31
|
||||
};
|
||||
|
||||
// Specific colorformats
|
||||
enum { CS_UNKNOWN = 0,
|
||||
CS_BGR24 = 1<<0 | CS_BGR | CS_INTERLEAVED,
|
||||
CS_BGR32 = 1<<1 | CS_BGR | CS_INTERLEAVED,
|
||||
CS_YUY2 = 1<<2 | CS_YUV | CS_INTERLEAVED,
|
||||
CS_YV12 = 1<<3 | CS_YUV | CS_PLANAR, // y-v-u, planar
|
||||
CS_I420 = 1<<4 | CS_YUV | CS_PLANAR, // y-u-v, planar
|
||||
CS_IYUV = 1<<4 | CS_YUV | CS_PLANAR // same as above
|
||||
};
|
||||
int pixel_type; // changed to int as of 2.5
|
||||
|
||||
|
||||
int audio_samples_per_second; // 0 means no audio
|
||||
int sample_type; // as of 2.5
|
||||
__int64 num_audio_samples; // changed as of 2.5
|
||||
int nchannels; // as of 2.5
|
||||
|
||||
// Imagetype properties
|
||||
|
||||
int image_type;
|
||||
|
||||
enum {
|
||||
IT_BFF = 1<<0,
|
||||
IT_TFF = 1<<1,
|
||||
IT_FIELDBASED = 1<<2
|
||||
};
|
||||
|
||||
// useful functions of the above
|
||||
bool HasVideo() const { return (width!=0); }
|
||||
bool HasAudio() const { return (audio_samples_per_second!=0); }
|
||||
bool IsRGB() const { return !!(pixel_type&CS_BGR); }
|
||||
bool IsRGB24() const { return (pixel_type&CS_BGR24)==CS_BGR24; } // Clear out additional properties
|
||||
bool IsRGB32() const { return (pixel_type & CS_BGR32) == CS_BGR32 ; }
|
||||
bool IsYUV() const { return !!(pixel_type&CS_YUV ); }
|
||||
bool IsYUY2() const { return (pixel_type & CS_YUY2) == CS_YUY2; }
|
||||
bool IsYV12() const { return ((pixel_type & CS_YV12) == CS_YV12)||((pixel_type & CS_I420) == CS_I420); }
|
||||
bool IsColorSpace(int c_space) const { return ((pixel_type & c_space) == c_space); }
|
||||
bool Is(int property) const { return ((pixel_type & property)==property ); }
|
||||
bool IsPlanar() const { return !!(pixel_type & CS_PLANAR); }
|
||||
bool IsFieldBased() const { return !!(image_type & IT_FIELDBASED); }
|
||||
bool IsParityKnown() const { return ((image_type & IT_FIELDBASED)&&(image_type & (IT_BFF|IT_TFF))); }
|
||||
bool IsBFF() const { return !!(image_type & IT_BFF); }
|
||||
bool IsTFF() const { return !!(image_type & IT_TFF); }
|
||||
|
||||
bool IsVPlaneFirst() const {return ((pixel_type & CS_YV12) == CS_YV12); } // Don't use this
|
||||
int BytesFromPixels(int pixels) const { return pixels * (BitsPerPixel()>>3); } // Will not work on planar images, but will return only luma planes
|
||||
int RowSize() const { return BytesFromPixels(width); } // Also only returns first plane on planar images
|
||||
int BMPSize() const { if (IsPlanar()) {int p = height * ((RowSize()+3) & ~3); p+=p>>1; return p; } return height * ((RowSize()+3) & ~3); }
|
||||
__int64 AudioSamplesFromFrames(__int64 frames) const { return (fps_numerator && HasVideo()) ? ((__int64)(frames) * audio_samples_per_second * fps_denominator / fps_numerator) : 0; }
|
||||
int FramesFromAudioSamples(__int64 samples) const { return (fps_denominator && HasAudio()) ? (int)((samples * (__int64)fps_numerator)/((__int64)fps_denominator * (__int64)audio_samples_per_second)) : 0; }
|
||||
__int64 AudioSamplesFromBytes(__int64 bytes) const { return HasAudio() ? bytes / BytesPerAudioSample() : 0; }
|
||||
__int64 BytesFromAudioSamples(__int64 samples) const { return samples * BytesPerAudioSample(); }
|
||||
int AudioChannels() const { return nchannels; }
|
||||
int SampleType() const{ return sample_type;}
|
||||
bool IsSampleType(int testtype) const{ return !!(sample_type&testtype);}
|
||||
int SamplesPerSecond() const { return audio_samples_per_second; }
|
||||
int BytesPerAudioSample() const { return nchannels*BytesPerChannelSample();}
|
||||
void SetFieldBased(bool isfieldbased) { if (isfieldbased) image_type|=IT_FIELDBASED; else image_type&=~IT_FIELDBASED; }
|
||||
void Set(int property) { image_type|=property; }
|
||||
void Clear(int property) { image_type&=~property; }
|
||||
|
||||
int BitsPerPixel() const {
|
||||
switch (pixel_type) {
|
||||
case CS_BGR24:
|
||||
return 24;
|
||||
case CS_BGR32:
|
||||
return 32;
|
||||
case CS_YUY2:
|
||||
return 16;
|
||||
case CS_YV12:
|
||||
case CS_I420:
|
||||
return 12;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int BytesPerChannelSample() const {
|
||||
switch (sample_type) {
|
||||
case SAMPLE_INT8:
|
||||
return sizeof(signed char);
|
||||
case SAMPLE_INT16:
|
||||
return sizeof(signed short);
|
||||
case SAMPLE_INT24:
|
||||
return 3;
|
||||
case SAMPLE_INT32:
|
||||
return sizeof(signed int);
|
||||
case SAMPLE_FLOAT:
|
||||
return sizeof(SFLOAT);
|
||||
default:
|
||||
_ASSERTE("Sample type not recognized!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// useful mutator
|
||||
void SetFPS(unsigned numerator, unsigned denominator) {
|
||||
if ((numerator == 0) || (denominator == 0)) {
|
||||
fps_numerator = 0;
|
||||
fps_denominator = 1;
|
||||
}
|
||||
else {
|
||||
unsigned x=numerator, y=denominator;
|
||||
while (y) { // find gcd
|
||||
unsigned t = x%y; x = y; y = t;
|
||||
}
|
||||
fps_numerator = numerator/x;
|
||||
fps_denominator = denominator/x;
|
||||
}
|
||||
}
|
||||
|
||||
// Range protected multiply-divide of FPS
|
||||
void MulDivFPS(unsigned multiplier, unsigned divisor) {
|
||||
unsigned __int64 numerator = UInt32x32To64(fps_numerator, multiplier);
|
||||
unsigned __int64 denominator = UInt32x32To64(fps_denominator, divisor);
|
||||
|
||||
unsigned __int64 x=numerator, y=denominator;
|
||||
while (y) { // find gcd
|
||||
unsigned __int64 t = x%y; x = y; y = t;
|
||||
}
|
||||
numerator /= x; // normalize
|
||||
denominator /= x;
|
||||
|
||||
unsigned __int64 temp = numerator | denominator; // Just looking top bit
|
||||
unsigned u = 0;
|
||||
while (temp & 0xffffffff80000000) { // or perhaps > 16777216*2
|
||||
temp = Int64ShrlMod32(temp, 1);
|
||||
u++;
|
||||
}
|
||||
if (u) { // Scale to fit
|
||||
const unsigned round = 1 << (u-1);
|
||||
SetFPS( (unsigned)Int64ShrlMod32(numerator + round, u),
|
||||
(unsigned)Int64ShrlMod32(denominator + round, u) );
|
||||
}
|
||||
else {
|
||||
fps_numerator = (unsigned)numerator;
|
||||
fps_denominator = (unsigned)denominator;
|
||||
}
|
||||
}
|
||||
|
||||
// Test for same colorspace
|
||||
bool IsSameColorspace(const VideoInfo& vi) const {
|
||||
if (vi.pixel_type == pixel_type) return TRUE;
|
||||
if (IsYV12() && vi.IsYV12()) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// VideoFrameBuffer holds information about a memory block which is used
|
||||
// for video data. For efficiency, instances of this class are not deleted
|
||||
// when the refcount reaches zero; instead they're stored in a linked list
|
||||
// to be reused. The instances are deleted when the corresponding AVS
|
||||
// file is closed.
|
||||
|
||||
class VideoFrameBuffer {
|
||||
BYTE* const data;
|
||||
const int data_size;
|
||||
// sequence_number is incremented every time the buffer is changed, so
|
||||
// that stale views can tell they're no longer valid.
|
||||
long sequence_number;
|
||||
|
||||
friend class VideoFrame;
|
||||
friend class Cache;
|
||||
friend class ScriptEnvironment;
|
||||
long refcount;
|
||||
|
||||
public:
|
||||
VideoFrameBuffer(int size);
|
||||
VideoFrameBuffer();
|
||||
~VideoFrameBuffer();
|
||||
|
||||
const BYTE* GetReadPtr() const { return data; }
|
||||
BYTE* GetWritePtr() { ++sequence_number; return data; }
|
||||
int GetDataSize() { return data_size; }
|
||||
int GetSequenceNumber() { return sequence_number; }
|
||||
int GetRefcount() { return refcount; }
|
||||
};
|
||||
|
||||
|
||||
class IClip;
|
||||
class PClip;
|
||||
class PVideoFrame;
|
||||
class IScriptEnvironment;
|
||||
class AVSValue;
|
||||
|
||||
|
||||
// VideoFrame holds a "window" into a VideoFrameBuffer. Operator new
|
||||
// is overloaded to recycle class instances.
|
||||
|
||||
class VideoFrame {
|
||||
int refcount;
|
||||
VideoFrameBuffer* const vfb;
|
||||
const int offset, pitch, row_size, height, offsetU, offsetV, pitchUV; // U&V offsets are from top of picture.
|
||||
|
||||
friend class PVideoFrame;
|
||||
void AddRef() { InterlockedIncrement((long *)&refcount); }
|
||||
void Release() { if (refcount==1) InterlockedDecrement(&vfb->refcount); InterlockedDecrement((long *)&refcount); }
|
||||
|
||||
friend class ScriptEnvironment;
|
||||
friend class Cache;
|
||||
|
||||
VideoFrame(VideoFrameBuffer* _vfb, int _offset, int _pitch, int _row_size, int _height);
|
||||
VideoFrame(VideoFrameBuffer* _vfb, int _offset, int _pitch, int _row_size, int _height, int _offsetU, int _offsetV, int _pitchUV);
|
||||
|
||||
void* operator new(size_t size);
|
||||
// TESTME: OFFSET U/V may be switched to what could be expected from AVI standard!
|
||||
public:
|
||||
int GetPitch() const { return pitch; }
|
||||
int GetPitch(int plane) const { switch (plane) {case PLANAR_U: case PLANAR_V: return pitchUV;} return pitch; }
|
||||
int GetRowSize() const { return row_size; }
|
||||
int GetRowSize(int plane) const {
|
||||
switch (plane) {
|
||||
case PLANAR_U: case PLANAR_V: if (pitchUV) return row_size>>1; else return 0;
|
||||
case PLANAR_U_ALIGNED: case PLANAR_V_ALIGNED:
|
||||
if (pitchUV) {
|
||||
int r = ((row_size+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)) )>>1; // Aligned rowsize
|
||||
if (r<=pitchUV)
|
||||
return r;
|
||||
return row_size>>1;
|
||||
} else return 0;
|
||||
case PLANAR_Y_ALIGNED:
|
||||
int r = (row_size+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)); // Aligned rowsize
|
||||
if (r<=pitch)
|
||||
return r;
|
||||
return row_size;
|
||||
}
|
||||
return row_size; }
|
||||
int GetHeight() const { return height; }
|
||||
int GetHeight(int plane) const { switch (plane) {case PLANAR_U: case PLANAR_V: if (pitchUV) return height>>1; return 0;} return height; }
|
||||
|
||||
// generally you shouldn't use these three
|
||||
VideoFrameBuffer* GetFrameBuffer() const { return vfb; }
|
||||
int GetOffset() const { return offset; }
|
||||
int GetOffset(int plane) const { switch (plane) {case PLANAR_U: return offsetU;case PLANAR_V: return offsetV;default: return offset;}; }
|
||||
|
||||
// in plugins use env->SubFrame()
|
||||
VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height) const;
|
||||
VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int pitchUV) const;
|
||||
|
||||
|
||||
const BYTE* GetReadPtr() const { return vfb->GetReadPtr() + offset; }
|
||||
const BYTE* GetReadPtr(int plane) const { return vfb->GetReadPtr() + GetOffset(plane); }
|
||||
|
||||
bool IsWritable() const { return (refcount == 1 && vfb->refcount == 1); }
|
||||
|
||||
BYTE* GetWritePtr() const {
|
||||
if (vfb->GetRefcount()>1) {
|
||||
_ASSERT(FALSE);
|
||||
//throw AvisynthError("Internal Error - refcount was more than one!");
|
||||
}
|
||||
return IsWritable() ? (vfb->GetWritePtr() + offset) : 0;
|
||||
}
|
||||
|
||||
BYTE* GetWritePtr(int plane) const {
|
||||
if (plane==PLANAR_Y) {
|
||||
if (vfb->GetRefcount()>1) {
|
||||
_ASSERT(FALSE);
|
||||
// throw AvisynthError("Internal Error - refcount was more than one!");
|
||||
}
|
||||
return IsWritable() ? vfb->GetWritePtr() + GetOffset(plane) : 0;
|
||||
}
|
||||
return vfb->data + GetOffset(plane);
|
||||
}
|
||||
|
||||
~VideoFrame() { InterlockedDecrement(&vfb->refcount); }
|
||||
};
|
||||
|
||||
enum {
|
||||
CACHE_NOTHING=0,
|
||||
CACHE_RANGE=1,
|
||||
CACHE_ALL=2,
|
||||
CACHE_AUDIO=3,
|
||||
CACHE_AUDIO_NONE=4
|
||||
};
|
||||
|
||||
// Base class for all filters.
|
||||
class IClip {
|
||||
friend class PClip;
|
||||
friend class AVSValue;
|
||||
int refcnt;
|
||||
void AddRef() { InterlockedIncrement((long *)&refcnt); }
|
||||
void Release() { InterlockedDecrement((long *)&refcnt); if (!refcnt) delete this; }
|
||||
public:
|
||||
IClip() : refcnt(0) {}
|
||||
|
||||
virtual int __stdcall GetVersion() { return AVISYNTH_INTERFACE_VERSION; }
|
||||
|
||||
virtual PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) = 0;
|
||||
virtual bool __stdcall GetParity(int n) = 0; // return field parity if field_based, else parity of first field in frame
|
||||
virtual void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) = 0; // start and count are in samples
|
||||
virtual void __stdcall SetCacheHints(int cachehints,int frame_range) = 0 ; // We do not pass cache requests upwards, only to the next filter.
|
||||
virtual const VideoInfo& __stdcall GetVideoInfo() = 0;
|
||||
virtual __stdcall ~IClip() {}
|
||||
};
|
||||
|
||||
|
||||
// smart pointer to IClip
|
||||
class PClip {
|
||||
|
||||
IClip* p;
|
||||
|
||||
IClip* GetPointerWithAddRef() const { if (p) p->AddRef(); return p; }
|
||||
friend class AVSValue;
|
||||
friend class VideoFrame;
|
||||
|
||||
void Init(IClip* x) {
|
||||
if (x) x->AddRef();
|
||||
p=x;
|
||||
}
|
||||
void Set(IClip* x) {
|
||||
if (x) x->AddRef();
|
||||
if (p) p->Release();
|
||||
p=x;
|
||||
}
|
||||
|
||||
public:
|
||||
PClip() { p = 0; }
|
||||
PClip(const PClip& x) { Init(x.p); }
|
||||
PClip(IClip* x) { Init(x); }
|
||||
void operator=(IClip* x) { Set(x); }
|
||||
void operator=(const PClip& x) { Set(x.p); }
|
||||
|
||||
IClip* operator->() const { return p; }
|
||||
|
||||
// useful in conditional expressions
|
||||
operator void*() const { return p; }
|
||||
bool operator!() const { return !p; }
|
||||
|
||||
~PClip() { if (p) p->Release(); }
|
||||
};
|
||||
|
||||
|
||||
// smart pointer to VideoFrame
|
||||
class PVideoFrame {
|
||||
|
||||
VideoFrame* p;
|
||||
|
||||
void Init(VideoFrame* x) {
|
||||
if (x) x->AddRef();
|
||||
p=x;
|
||||
}
|
||||
void Set(VideoFrame* x) {
|
||||
if (x) x->AddRef();
|
||||
if (p) p->Release();
|
||||
p=x;
|
||||
}
|
||||
|
||||
public:
|
||||
PVideoFrame() { p = 0; }
|
||||
PVideoFrame(const PVideoFrame& x) { Init(x.p); }
|
||||
PVideoFrame(VideoFrame* x) { Init(x); }
|
||||
void operator=(VideoFrame* x) { Set(x); }
|
||||
void operator=(const PVideoFrame& x) { Set(x.p); }
|
||||
|
||||
VideoFrame* operator->() const { return p; }
|
||||
|
||||
// for conditional expressions
|
||||
operator void*() const { return p; }
|
||||
bool operator!() const { return !p; }
|
||||
|
||||
~PVideoFrame() { if (p) p->Release();}
|
||||
};
|
||||
|
||||
|
||||
class AVSValue {
|
||||
public:
|
||||
|
||||
AVSValue() { type = 'v'; }
|
||||
AVSValue(IClip* c) { type = 'c'; clip = c; if (c) c->AddRef(); }
|
||||
AVSValue(const PClip& c) { type = 'c'; clip = c.GetPointerWithAddRef(); }
|
||||
AVSValue(bool b) { type = 'b'; boolean = b; }
|
||||
AVSValue(int i) { type = 'i'; integer = i; }
|
||||
// AVSValue(__int64 l) { type = 'l'; longlong = l; }
|
||||
AVSValue(float f) { type = 'f'; floating_pt = f; }
|
||||
AVSValue(double f) { type = 'f'; floating_pt = float(f); }
|
||||
AVSValue(const char* s) { type = 's'; string = s; }
|
||||
AVSValue(const AVSValue* a, int size) { type = 'a'; array = a; array_size = size; }
|
||||
AVSValue(const AVSValue& v) { Assign(&v, true); }
|
||||
|
||||
~AVSValue() { if (IsClip() && clip) clip->Release(); }
|
||||
AVSValue& operator=(const AVSValue& v) { Assign(&v, false); return *this; }
|
||||
|
||||
// Note that we transparently allow 'int' to be treated as 'float'.
|
||||
// There are no int<->bool conversions, though.
|
||||
|
||||
bool Defined() const { return type != 'v'; }
|
||||
bool IsClip() const { return type == 'c'; }
|
||||
bool IsBool() const { return type == 'b'; }
|
||||
bool IsInt() const { return type == 'i'; }
|
||||
// bool IsLong() const { return (type == 'l'|| type == 'i'); }
|
||||
bool IsFloat() const { return type == 'f' || type == 'i'; }
|
||||
bool IsString() const { return type == 's'; }
|
||||
bool IsArray() const { return type == 'a'; }
|
||||
|
||||
PClip AsClip() const { _ASSERTE(IsClip()); return IsClip()?clip:0; }
|
||||
bool AsBool() const { _ASSERTE(IsBool()); return boolean; }
|
||||
int AsInt() const { _ASSERTE(IsInt()); return integer; }
|
||||
// int AsLong() const { _ASSERTE(IsLong()); return longlong; }
|
||||
const char* AsString() const { _ASSERTE(IsString()); return IsString()?string:0; }
|
||||
double AsFloat() const { _ASSERTE(IsFloat()); return IsInt()?integer:floating_pt; }
|
||||
|
||||
bool AsBool(bool def) const { _ASSERTE(IsBool()||!Defined()); return IsBool() ? boolean : def; }
|
||||
int AsInt(int def) const { _ASSERTE(IsInt()||!Defined()); return IsInt() ? integer : def; }
|
||||
double AsFloat(double def) const { _ASSERTE(IsFloat()||!Defined()); return IsInt() ? integer : type=='f' ? floating_pt : def; }
|
||||
const char* AsString(const char* def) const { _ASSERTE(IsString()||!Defined()); return IsString() ? string : def; }
|
||||
|
||||
int ArraySize() const { _ASSERTE(IsArray()); return IsArray()?array_size:1; }
|
||||
|
||||
const AVSValue& operator[](int index) const {
|
||||
_ASSERTE(IsArray() && index>=0 && index<array_size);
|
||||
return (IsArray() && index>=0 && index<array_size) ? array[index] : *this;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
short type; // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, or 'l'ong
|
||||
short array_size;
|
||||
union {
|
||||
IClip* clip;
|
||||
bool boolean;
|
||||
int integer;
|
||||
float floating_pt;
|
||||
const char* string;
|
||||
const AVSValue* array;
|
||||
// __int64 longlong;
|
||||
};
|
||||
|
||||
void Assign(const AVSValue* src, bool init) {
|
||||
if (src->IsClip() && src->clip)
|
||||
src->clip->AddRef();
|
||||
if (!init && IsClip() && clip)
|
||||
clip->Release();
|
||||
// make sure this copies the whole struct!
|
||||
//((__int32*)this)[0] = ((__int32*)src)[0];
|
||||
//((__int32*)this)[1] = ((__int32*)src)[1];
|
||||
memcpy(this, src, sizeof(AVSValue));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// instantiable null filter
|
||||
class GenericVideoFilter : public IClip {
|
||||
protected:
|
||||
PClip child;
|
||||
VideoInfo vi;
|
||||
public:
|
||||
GenericVideoFilter(PClip _child) : child(_child) { vi = child->GetVideoInfo(); }
|
||||
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) { return child->GetFrame(n, env); }
|
||||
void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) { child->GetAudio(buf, start, count, env); }
|
||||
const VideoInfo& __stdcall GetVideoInfo() { return vi; }
|
||||
bool __stdcall GetParity(int n) { return child->GetParity(n); }
|
||||
void __stdcall SetCacheHints(int cachehints,int frame_range) { } ; // We do not pass cache requests upwards, only to the next filter.
|
||||
};
|
||||
|
||||
|
||||
class AvisynthError /* exception */ {
|
||||
public:
|
||||
const char* const msg;
|
||||
AvisynthError(const char* _msg) : msg(_msg) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* Helper classes useful to plugin authors */
|
||||
|
||||
class AlignPlanar : public GenericVideoFilter
|
||||
{
|
||||
public:
|
||||
AlignPlanar(PClip _clip);
|
||||
static PClip Create(PClip clip);
|
||||
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class FillBorder : public GenericVideoFilter
|
||||
{
|
||||
public:
|
||||
FillBorder(PClip _clip);
|
||||
static PClip Create(PClip clip);
|
||||
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ConvertAudio : public GenericVideoFilter
|
||||
/**
|
||||
* Helper class to convert audio to any format
|
||||
**/
|
||||
{
|
||||
public:
|
||||
ConvertAudio(PClip _clip, int prefered_format);
|
||||
void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env);
|
||||
void __stdcall SetCacheHints(int cachehints,int frame_range); // We do pass cache requests upwards, to the cache!
|
||||
|
||||
static PClip Create(PClip clip, int sample_type, int prefered_type);
|
||||
static AVSValue __cdecl Create_float(AVSValue args, void*, IScriptEnvironment*);
|
||||
static AVSValue __cdecl Create_32bit(AVSValue args, void*, IScriptEnvironment*);
|
||||
static AVSValue __cdecl Create_24bit(AVSValue args, void*, IScriptEnvironment*);
|
||||
static AVSValue __cdecl Create_16bit(AVSValue args, void*, IScriptEnvironment*);
|
||||
static AVSValue __cdecl Create_8bit(AVSValue args, void*, IScriptEnvironment*);
|
||||
virtual ~ConvertAudio();
|
||||
|
||||
private:
|
||||
void convertToFloat(char* inbuf, float* outbuf, char sample_type, int count);
|
||||
void convertToFloat_3DN(char* inbuf, float* outbuf, char sample_type, int count);
|
||||
void convertToFloat_SSE(char* inbuf, float* outbuf, char sample_type, int count);
|
||||
void convertToFloat_SSE2(char* inbuf, float* outbuf, char sample_type, int count);
|
||||
void convertFromFloat(float* inbuf, void* outbuf, char sample_type, int count);
|
||||
void convertFromFloat_3DN(float* inbuf, void* outbuf, char sample_type, int count);
|
||||
void convertFromFloat_SSE(float* inbuf, void* outbuf, char sample_type, int count);
|
||||
void convertFromFloat_SSE2(float* inbuf, void* outbuf, char sample_type, int count);
|
||||
|
||||
__inline int Saturate_int8(float n);
|
||||
__inline short Saturate_int16(float n);
|
||||
__inline int Saturate_int24(float n);
|
||||
__inline int Saturate_int32(float n);
|
||||
|
||||
char src_format;
|
||||
char dst_format;
|
||||
int src_bps;
|
||||
char *tempbuffer;
|
||||
SFLOAT *floatbuffer;
|
||||
int tempbuffer_size;
|
||||
};
|
||||
|
||||
|
||||
// For GetCPUFlags. These are backwards-compatible with those in VirtualDub.
|
||||
enum {
|
||||
/* slowest CPU to support extension */
|
||||
CPUF_FORCE = 0x01, // N/A
|
||||
CPUF_FPU = 0x02, // 386/486DX
|
||||
CPUF_MMX = 0x04, // P55C, K6, PII
|
||||
CPUF_INTEGER_SSE = 0x08, // PIII, Athlon
|
||||
CPUF_SSE = 0x10, // PIII, Athlon XP/MP
|
||||
CPUF_SSE2 = 0x20, // PIV, Hammer
|
||||
CPUF_3DNOW = 0x40, // K6-2
|
||||
CPUF_3DNOW_EXT = 0x80, // Athlon
|
||||
CPUF_X86_64 = 0xA0, // Hammer (note: equiv. to 3DNow + SSE2, which only Hammer
|
||||
// will have anyway)
|
||||
CPUF_SSE3 = 0x100, // Some P4 & Athlon 64.
|
||||
};
|
||||
#define MAX_INT 0x7fffffff
|
||||
#define MIN_INT -0x7fffffff
|
||||
|
||||
|
||||
|
||||
class IScriptEnvironment {
|
||||
public:
|
||||
virtual __stdcall ~IScriptEnvironment() {}
|
||||
|
||||
virtual /*static*/ long __stdcall GetCPUFlags() = 0;
|
||||
|
||||
virtual char* __stdcall SaveString(const char* s, int length = -1) = 0;
|
||||
virtual char* __stdcall Sprintf(const char* fmt, ...) = 0;
|
||||
// note: val is really a va_list; I hope everyone typedefs va_list to a pointer
|
||||
virtual char* __stdcall VSprintf(const char* fmt, void* val) = 0;
|
||||
|
||||
__declspec(noreturn) virtual void __stdcall ThrowError(const char* fmt, ...) = 0;
|
||||
|
||||
class NotFound /*exception*/ {}; // thrown by Invoke and GetVar
|
||||
|
||||
typedef AVSValue (__cdecl *ApplyFunc)(AVSValue args, void* user_data, IScriptEnvironment* env);
|
||||
|
||||
virtual void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data) = 0;
|
||||
virtual bool __stdcall FunctionExists(const char* name) = 0;
|
||||
virtual AVSValue __stdcall Invoke(const char* name, const AVSValue args, const char** arg_names=0) = 0;
|
||||
|
||||
virtual AVSValue __stdcall GetVar(const char* name) = 0;
|
||||
virtual bool __stdcall SetVar(const char* name, const AVSValue& val) = 0;
|
||||
virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) = 0;
|
||||
|
||||
virtual void __stdcall PushContext(int level=0) = 0;
|
||||
virtual void __stdcall PopContext() = 0;
|
||||
|
||||
// align should be 4 or 8
|
||||
virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, int align=FRAME_ALIGN) = 0;
|
||||
|
||||
virtual bool __stdcall MakeWritable(PVideoFrame* pvf) = 0;
|
||||
|
||||
virtual /*static*/ void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) = 0;
|
||||
|
||||
typedef void (__cdecl *ShutdownFunc)(void* user_data, IScriptEnvironment* env);
|
||||
virtual void __stdcall AtExit(ShutdownFunc function, void* user_data) = 0;
|
||||
|
||||
virtual void __stdcall CheckVersion(int version = AVISYNTH_INTERFACE_VERSION) = 0;
|
||||
|
||||
virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) = 0;
|
||||
|
||||
virtual int __stdcall SetMemoryMax(int mem) = 0;
|
||||
|
||||
virtual int __stdcall SetWorkingDir(const char * newdir) = 0;
|
||||
|
||||
virtual void* __stdcall ManageCache(int key, void* data) = 0;
|
||||
|
||||
enum PlanarChromaAlignmentMode {
|
||||
PlanarChromaAlignmentOff,
|
||||
PlanarChromaAlignmentOn,
|
||||
PlanarChromaAlignmentTest };
|
||||
|
||||
virtual bool __stdcall PlanarChromaAlignment(PlanarChromaAlignmentMode key) = 0;
|
||||
|
||||
virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) = 0;
|
||||
};
|
||||
|
||||
|
||||
// avisynth.dll exports this; it's a way to use it as a library, without
|
||||
// writing an AVS script or without going through AVIFile.
|
||||
IScriptEnvironment* __stdcall CreateScriptEnvironment(int version = AVISYNTH_INTERFACE_VERSION);
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif //__AVISYNTH_H__
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
#ifdef WITH_AVISYNTH
|
||||
#include "avisynth_wrap.h"
|
||||
|
||||
#include "avisynth.h"
|
||||
#include <avisynth.h>
|
||||
#include "options.h"
|
||||
|
||||
#include <mutex>
|
||||
|
|
BIN
src/bitmaps/button/button_align_16.png
Normal file
BIN
src/bitmaps/button/button_align_16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 353 B |
BIN
src/bitmaps/button/button_align_24.png
Normal file
BIN
src/bitmaps/button/button_align_24.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 571 B |
BIN
src/bitmaps/button/button_align_32.png
Normal file
BIN
src/bitmaps/button/button_align_32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 690 B |
BIN
src/bitmaps/button/button_align_48.png
Normal file
BIN
src/bitmaps/button/button_align_48.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
src/bitmaps/button/button_align_64.png
Normal file
BIN
src/bitmaps/button/button_align_64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 547 B |
|
@ -51,6 +51,11 @@ button/bugtracker_button_24.png
|
|||
button/bugtracker_button_32.png
|
||||
button/bugtracker_button_48.png
|
||||
button/bugtracker_button_64.png
|
||||
button/button_align_16.png
|
||||
button/button_align_24.png
|
||||
button/button_align_32.png
|
||||
button/button_align_48.png
|
||||
button/button_align_64.png
|
||||
button/button_audio_commit_16.png
|
||||
button/button_audio_commit_24.png
|
||||
button/button_audio_commit_32.png
|
||||
|
|
|
@ -150,8 +150,11 @@ public:
|
|||
}
|
||||
|
||||
// Remove old entries until we're under the max size
|
||||
for (auto it = age.rbegin(); size > max_size && it != age.rend(); )
|
||||
KillMacroBlock(**it++);
|
||||
while (size > max_size) {
|
||||
// When size > 0, age should never be empty
|
||||
assert(!age.empty());
|
||||
KillMacroBlock(*age.back());
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Obtain a data block from the cache
|
||||
|
|
|
@ -18,9 +18,13 @@
|
|||
|
||||
#include "dialogs.h"
|
||||
|
||||
#if BOOST_VERSION >= 106900
|
||||
#include <boost/gil.hpp>
|
||||
#else
|
||||
#include <boost/gil/gil_all.hpp>
|
||||
#endif
|
||||
|
||||
AGI_DEFINE_EVENT(EVT_COLOR, agi::Color);
|
||||
AGI_DEFINE_EVENT(EVT_COLOR, agi::Color)
|
||||
|
||||
ColourButton::ColourButton(wxWindow *parent, wxSize const& size, bool alpha, agi::Color col, wxValidator const& validator)
|
||||
: wxButton(parent, -1, "", wxDefaultPosition, wxSize(size.GetWidth() + 6, size.GetHeight() + 6), 0, validator)
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
/// Emitted by ColourButton when the user picks a new color, with the chosen
|
||||
/// color set to the event payload
|
||||
AGI_DECLARE_EVENT(EVT_COLOR, agi::Color);
|
||||
AGI_DECLARE_EVENT(EVT_COLOR, agi::Color)
|
||||
|
||||
/// A button which displays a currently-selected color and lets the user pick
|
||||
/// a new color when clicked
|
||||
|
@ -43,6 +43,12 @@ public:
|
|||
|
||||
/// Get the currently selected color
|
||||
agi::Color GetColor() { return colour; }
|
||||
|
||||
void SetColor(agi::Color color)
|
||||
{
|
||||
colour = color;
|
||||
UpdateBitmap();
|
||||
}
|
||||
};
|
||||
|
||||
struct ColorValidator final : public wxValidator {
|
||||
|
|
|
@ -80,7 +80,7 @@ struct audio_open final : public Command {
|
|||
STR_HELP("Open an audio file")
|
||||
|
||||
void operator()(agi::Context *c) override {
|
||||
auto str = from_wx(_("Audio Formats") + " (*.aac,*.ac3,*.ape,*.dts,*.flac,*.m4a,*.mka,*.mp3,*.mp4,*.ogg,*.w64,*.wav,*.wma)|*.aac;*.ac3;*.ape;*.dts;*.flac;*.m4a;*.mka;*.mp3;*.mp4;*.ogg;*.w64;*.wav;*.wma|"
|
||||
auto str = from_wx(_("Audio Formats") + " (*.aac,*.ac3,*.ape,*.dts,*.eac3,*.flac,*.m4a,*.mka,*.mp3,*.mp4,*.ogg,*.opus,*.w64,*.wav,*.wma)|*.aac;*.ac3;*.ape;*.dts;*.eac3;*.flac;*.m4a;*.mka;*.mp3;*.mp4;*.ogg;*.opus;*.w64;*.wav;*.wma|"
|
||||
+ _("Video Formats") + " (*.asf,*.avi,*.avs,*.d2v,*.m2ts,*.m4v,*.mkv,*.mov,*.mp4,*.mpeg,*.mpg,*.ogm,*.webm,*.wmv,*.ts)|*.asf;*.avi;*.avs;*.d2v;*.m2ts;*.m4v;*.mkv;*.mov;*.mp4;*.mpeg;*.mpg;*.ogm;*.webm;*.wmv;*.ts|"
|
||||
+ _("All Files") + " (*.*)|*.*");
|
||||
auto filename = OpenFileSelector(_("Open Audio File"), "Path/Last/Audio", "", "", str, c->parent);
|
||||
|
|
|
@ -35,10 +35,10 @@ namespace agi { struct Context; }
|
|||
#define CMD_TYPE(a) int Type() const override { using namespace cmd; return a; }
|
||||
|
||||
#define CMD_ICON(icon) wxBitmap Icon(int size, wxLayoutDirection dir = wxLayout_LeftToRight) const override { \
|
||||
if (size == 64) return GETIMAGEDIR(icon##_64, dir); \
|
||||
if (size == 48) return GETIMAGEDIR(icon##_48, dir); \
|
||||
if (size == 32) return GETIMAGEDIR(icon##_32, dir); \
|
||||
if (size == 24) return GETIMAGEDIR(icon##_24, dir); \
|
||||
if (size >= 64) return GETIMAGEDIR(icon##_64, dir); \
|
||||
if (size >= 48) return GETIMAGEDIR(icon##_48, dir); \
|
||||
if (size >= 32) return GETIMAGEDIR(icon##_32, dir); \
|
||||
if (size >= 24) return GETIMAGEDIR(icon##_24, dir); \
|
||||
return GETIMAGEDIR(icon##_16, dir); \
|
||||
}
|
||||
|
||||
|
|
|
@ -697,8 +697,8 @@ static void duplicate_lines(agi::Context *c, int shift) {
|
|||
new_diag->Start = c->videoController->TimeAtFrame(cur_frame, agi::vfr::START);
|
||||
}
|
||||
else {
|
||||
old_diag->Start = c->videoController->TimeAtFrame(cur_frame + 1, agi::vfr::START);
|
||||
new_diag->End = c->videoController->TimeAtFrame(cur_frame, agi::vfr::END);
|
||||
old_diag->End = c->videoController->TimeAtFrame(cur_frame, agi::vfr::END);
|
||||
new_diag->Start = c->videoController->TimeAtFrame(cur_frame + 1, agi::vfr::START);
|
||||
}
|
||||
|
||||
/// @todo also split \t and \move?
|
||||
|
|
|
@ -59,7 +59,7 @@ struct help_bugs final : public Command {
|
|||
throw c->parent;
|
||||
}
|
||||
}
|
||||
wxLaunchDefaultBrowser("http://devel.aegisub.org/", wxBROWSER_NEW_WINDOW);
|
||||
wxLaunchDefaultBrowser("https://github.com/Aegisub/Aegisub/issues", wxBROWSER_NEW_WINDOW);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -75,18 +75,6 @@ struct help_contents final : public Command {
|
|||
}
|
||||
};
|
||||
|
||||
struct help_forums final : public Command {
|
||||
CMD_NAME("help/forums")
|
||||
CMD_ICON(forums_button)
|
||||
STR_MENU("&Forums")
|
||||
STR_DISP("Forums")
|
||||
STR_HELP("Visit Aegisub's forums")
|
||||
|
||||
void operator()(agi::Context *) override {
|
||||
wxLaunchDefaultBrowser("http://forum.aegisub.org/", wxBROWSER_NEW_WINDOW);
|
||||
}
|
||||
};
|
||||
|
||||
struct help_irc final : public Command {
|
||||
CMD_NAME("help/irc")
|
||||
CMD_ICON(irc_button)
|
||||
|
@ -128,7 +116,6 @@ namespace cmd {
|
|||
void init_help() {
|
||||
reg(agi::make_unique<help_bugs>());
|
||||
reg(agi::make_unique<help_contents>());
|
||||
reg(agi::make_unique<help_forums>());
|
||||
reg(agi::make_unique<help_irc>());
|
||||
reg(agi::make_unique<help_video>());
|
||||
reg(agi::make_unique<help_website>());
|
||||
|
|
|
@ -235,6 +235,18 @@ struct time_snap_scene final : public validate_video_loaded {
|
|||
}
|
||||
};
|
||||
|
||||
struct time_align_subtitle_to_point final : public validate_video_loaded {
|
||||
CMD_NAME("time/align")
|
||||
CMD_ICON(button_align)
|
||||
STR_MENU("Align subtitle to video")
|
||||
STR_DISP("Align subtitle to video")
|
||||
STR_HELP("Align subtitle to video by key points")
|
||||
void operator()(agi::Context* c) override {
|
||||
c->videoController->Stop();
|
||||
ShowAlignToVideoDialog(c);
|
||||
}
|
||||
};
|
||||
|
||||
struct time_add_lead_both final : public Command {
|
||||
CMD_NAME("time/lead/both")
|
||||
STR_MENU("Add lead in and out")
|
||||
|
@ -393,6 +405,7 @@ namespace cmd {
|
|||
reg(agi::make_unique<time_snap_end_video>());
|
||||
reg(agi::make_unique<time_snap_scene>());
|
||||
reg(agi::make_unique<time_snap_start_video>());
|
||||
reg(agi::make_unique<time_align_subtitle_to_point>());
|
||||
reg(agi::make_unique<time_start_decrease>());
|
||||
reg(agi::make_unique<time_start_increase>());
|
||||
}
|
||||
|
|
|
@ -564,7 +564,7 @@ struct video_open final : public Command {
|
|||
STR_HELP("Open a video file")
|
||||
|
||||
void operator()(agi::Context *c) override {
|
||||
auto str = from_wx(_("Video Formats") + " (*.asf,*.avi,*.avs,*.d2v,*.m2ts,*.m4v,*.mkv,*.mov,*.mp4,*.mpeg,*.mpg,*.ogm,*.webm,*.wmv,*.ts,*.y4m,*.yuv)|*.asf;*.avi;*.avs;*.d2v;*.m2ts;*.m4v;*.mkv;*.mov;*.mp4;*.mpeg;*.mpg;*.ogm;*.webm;*.wmv;*.ts;*.y4m;*.yuv|"
|
||||
auto str = from_wx(_("Video Formats") + " (*.asf,*.avi,*.avs,*.d2v,*.h264,*.hevc,*.m2ts,*.m4v,*.mkv,*.mov,*.mp4,*.mpeg,*.mpg,*.ogm,*.webm,*.wmv,*.ts,*.y4m,*.yuv)|*.asf;*.avi;*.avs;*.d2v;*.h264;*.hevc;*.m2ts;*.m4v;*.mkv;*.mov;*.mp4;*.mpeg;*.mpg;*.ogm;*.webm;*.wmv;*.ts;*.y4m;*.yuv|"
|
||||
+ _("All Files") + " (*.*)|*.*");
|
||||
auto filename = OpenFileSelector(_("Open video file"), "Path/Last/Video", "", "", str, c->parent);
|
||||
if (!filename.empty())
|
||||
|
|
|
@ -49,10 +49,11 @@ void ShowAboutDialog(wxWindow *parent) {
|
|||
|
||||
// Generate about string
|
||||
wxString aboutString = wxString("Aegisub ") + GetAegisubShortVersionString() + ".\n"
|
||||
"Copyright (c) 2005-2014 Rodrigo Braz Monteiro, Niels Martin Hansen, Thomas Goyne et al.\n\n"
|
||||
"Copyright (c) 2005-2019 Rodrigo Braz Monteiro, Niels Martin Hansen, Thomas Goyne et al.\n\n"
|
||||
"Programmers:\n"
|
||||
" Alysson Souza e Silva\n"
|
||||
" Amar Takhar\n"
|
||||
" Charlie Jiang\n"
|
||||
" Dan Donovan\n"
|
||||
" Daniel Moscoviter\n"
|
||||
" David Conrad\n"
|
||||
|
@ -67,6 +68,7 @@ void ShowAboutDialog(wxWindow *parent) {
|
|||
" Muhammad Lukman Nasaruddin\n"
|
||||
" Niels Martin Hansen\n"
|
||||
" Patryk Pomykalski\n"
|
||||
" Qirui Wang\n"
|
||||
" Ravi Pinjala\n"
|
||||
" Rodrigo Braz Monteiro\n"
|
||||
" Simone Cociancich\n"
|
||||
|
@ -129,7 +131,7 @@ void ShowAboutDialog(wxWindow *parent) {
|
|||
wxChar copySymbol = 0xA9;
|
||||
aboutString.Replace("(c)", wxString(copySymbol));
|
||||
|
||||
wxTextCtrl *textctrl = new wxTextCtrl(&d, -1, aboutString, wxDefaultPosition, wxSize(-1, 200), wxTE_MULTILINE | wxTE_READONLY | wxBORDER_NONE);
|
||||
wxTextCtrl *textctrl = new wxTextCtrl(&d, -1, aboutString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxBORDER_NONE);
|
||||
|
||||
wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
MainSizer->Add(new wxStaticBitmap(&d, -1, GETIMAGE(splash)), 0, wxCENTER, 0);
|
||||
|
|
378
src/dialog_align.cpp
Normal file
378
src/dialog_align.cpp
Normal file
|
@ -0,0 +1,378 @@
|
|||
// Copyright (c) 2019, Charlie Jiang
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Aegisub Project http://www.aegisub.org/
|
||||
|
||||
#include "ass_dialogue.h"
|
||||
#include "ass_file.h"
|
||||
#include "compat.h"
|
||||
#include "dialog_manager.h"
|
||||
#include "format.h"
|
||||
#include "include/aegisub/context.h"
|
||||
#include "video_frame.h"
|
||||
#include "libresrc/libresrc.h"
|
||||
#include "options.h"
|
||||
#include "project.h"
|
||||
#include "selection_controller.h"
|
||||
#include "video_controller.h"
|
||||
#include "async_video_provider.h"
|
||||
#include "colour_button.h"
|
||||
#include "image_position_picker.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <libaegisub/ass/time.h>
|
||||
#include <libaegisub/vfr.h>
|
||||
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/textctrl.h>
|
||||
#if BOOST_VERSION >= 106900
|
||||
#include <boost/gil.hpp>
|
||||
#else
|
||||
#include <boost/gil/gil_all.hpp>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
class DialogAlignToVideo final : public wxDialog {
|
||||
agi::Context* context;
|
||||
AsyncVideoProvider* provider;
|
||||
|
||||
wxImage preview_image;
|
||||
VideoFrame current_frame;
|
||||
int current_n_frame;
|
||||
|
||||
ImagePositionPicker* preview_frame;
|
||||
ColourButton* selected_color;
|
||||
wxTextCtrl* selected_x;
|
||||
wxTextCtrl* selected_y;
|
||||
wxTextCtrl* selected_tolerance;
|
||||
|
||||
void update_from_textbox();
|
||||
void update_from_textbox(wxCommandEvent&);
|
||||
|
||||
bool check_exists(int pos, int x, int y, int* lrud, double* orig, unsigned char tolerance);
|
||||
void process(wxCommandEvent&);
|
||||
public:
|
||||
DialogAlignToVideo(agi::Context* context);
|
||||
~DialogAlignToVideo();
|
||||
};
|
||||
|
||||
DialogAlignToVideo::DialogAlignToVideo(agi::Context* context)
|
||||
: wxDialog(context->parent, -1, _("Align subtitle to video by key point"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxMAXIMIZE_BOX | wxRESIZE_BORDER)
|
||||
, context(context), provider(context->project->VideoProvider())
|
||||
{
|
||||
auto add_with_label = [&](wxSizer * sizer, wxString const& label, wxWindow * ctrl) {
|
||||
sizer->Add(new wxStaticText(this, -1, label), 0, wxLEFT | wxRIGHT | wxCENTER, 3);
|
||||
sizer->Add(ctrl, 1, wxLEFT);
|
||||
};
|
||||
|
||||
auto tolerance = OPT_GET("Tool/Align to Video/Tolerance")->GetInt();
|
||||
auto maximized = OPT_GET("Tool/Align to Video/Maximized")->GetBool();
|
||||
|
||||
current_n_frame = context->videoController->GetFrameN();
|
||||
current_frame = *context->project->VideoProvider()->GetFrame(current_n_frame, 0, true);
|
||||
preview_image = GetImage(current_frame);
|
||||
|
||||
preview_frame = new ImagePositionPicker(this, preview_image, [&](int x, int y, unsigned char r, unsigned char g, unsigned char b) -> void {
|
||||
selected_x->ChangeValue(wxString::Format(wxT("%i"), x));
|
||||
selected_y->ChangeValue(wxString::Format(wxT("%i"), y));
|
||||
|
||||
selected_color->SetColor(agi::Color(r, g, b));
|
||||
});
|
||||
selected_color = new ColourButton(this, wxSize(55, 16), true, agi::Color("FFFFFF"));
|
||||
selected_color->SetToolTip(_("The key color to be followed."));
|
||||
selected_x = new wxTextCtrl(this, -1, "0");
|
||||
selected_x->SetToolTip(_("The x coord of the key point."));
|
||||
selected_y = new wxTextCtrl(this, -1, "0");
|
||||
selected_y->SetToolTip(_("The y coord of the key point."));
|
||||
selected_tolerance = new wxTextCtrl(this, -1, wxString::Format(wxT("%i"), int(tolerance)));
|
||||
selected_tolerance->SetToolTip(_("Max tolerance of the color."));
|
||||
|
||||
selected_x->Bind(wxEVT_TEXT, &DialogAlignToVideo::update_from_textbox, this);
|
||||
selected_y->Bind(wxEVT_TEXT, &DialogAlignToVideo::update_from_textbox, this);
|
||||
update_from_textbox();
|
||||
|
||||
wxFlexGridSizer* right_sizer = new wxFlexGridSizer(4, 2, 5, 5);
|
||||
add_with_label(right_sizer, _("X"), selected_x);
|
||||
add_with_label(right_sizer, _("Y"), selected_y);
|
||||
add_with_label(right_sizer, _("Color"), selected_color);
|
||||
add_with_label(right_sizer, _("Tolerance"), selected_tolerance);
|
||||
right_sizer->AddGrowableCol(1, 1);
|
||||
|
||||
wxSizer* main_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
main_sizer->Add(preview_frame, 1, (wxALL & ~wxRIGHT) | wxEXPAND, 5);
|
||||
main_sizer->Add(right_sizer, 0, wxALIGN_LEFT, 5);
|
||||
|
||||
wxSizer* dialog_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
dialog_sizer->Add(main_sizer, wxSizerFlags(1).Border(wxALL & ~wxBOTTOM).Expand());
|
||||
dialog_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL), wxSizerFlags().Right().Border());
|
||||
SetSizerAndFit(dialog_sizer);
|
||||
SetSize(1024, 700);
|
||||
CenterOnParent();
|
||||
|
||||
Bind(wxEVT_BUTTON, &DialogAlignToVideo::process, this, wxID_OK);
|
||||
SetIcon(GETICON(button_align_16));
|
||||
if (maximized)
|
||||
wxDialog::Maximize(true);
|
||||
}
|
||||
|
||||
DialogAlignToVideo::~DialogAlignToVideo()
|
||||
{
|
||||
long lt;
|
||||
if (!selected_tolerance->GetValue().ToLong(<))
|
||||
return;
|
||||
if (lt < 0 || lt > 255)
|
||||
return;
|
||||
|
||||
OPT_SET("Tool/Align to Video/Tolerance")->SetInt(lt);
|
||||
}
|
||||
|
||||
void rgb2lab(unsigned char r, unsigned char g, unsigned char b, double* lab)
|
||||
{
|
||||
double R = static_cast<double>(r) / 255.0;
|
||||
double G = static_cast<double>(g) / 255.0;
|
||||
double B = static_cast<double>(b) / 255.0;
|
||||
double X = 0.412453 * R + 0.357580 * G + 0.180423 * B;
|
||||
double Y = 0.212671 * R + 0.715160 * G + 0.072169 * B;
|
||||
double Z = 0.019334 * R + 0.119193 * G + 0.950227 * B;
|
||||
double xr = X / 0.950456, yr = Y / 1.000, zr = Z / 1.088854;
|
||||
|
||||
if (yr > 0.008856) {
|
||||
lab[0] = 116.0 * pow(yr, 1.0 / 3.0) - 16.0;
|
||||
}
|
||||
else {
|
||||
lab[0] = 903.3 * yr;
|
||||
}
|
||||
|
||||
double fxr, fyr, fzr;
|
||||
if (xr > 0.008856)
|
||||
fxr = pow(xr, 1.0 / 3.0);
|
||||
else
|
||||
fxr = 7.787 * xr + 16.0 / 116.0;
|
||||
|
||||
if (yr > 0.008856)
|
||||
fyr = pow(yr, 1.0 / 3.0);
|
||||
else
|
||||
fyr = 7.787 * yr + 16.0 / 116.0;
|
||||
|
||||
if (zr > 0.008856)
|
||||
fzr = pow(zr, 1.0 / 3.0);
|
||||
else
|
||||
fzr = 7.787 * zr + 16.0 / 116.0;
|
||||
|
||||
lab[1] = 500.0 * (fxr - fyr);
|
||||
lab[2] = 200.0 * (fyr - fzr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool check_point(boost::gil::pixel<unsigned char, T> & pixel, double orig[3], unsigned char tolerance)
|
||||
{
|
||||
double lab[3];
|
||||
// in pixel: B,G,R
|
||||
rgb2lab(pixel[2], pixel[1], pixel[0], lab);
|
||||
auto diff = sqrt(pow(lab[0] - orig[0], 2) + pow(lab[1] - orig[1], 2) + pow(lab[2] - orig[2], 2));
|
||||
return diff < tolerance;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool calculate_point(boost::gil::image_view<T> view, int x, int y, double orig[3], unsigned char tolerance, int* ret)
|
||||
{
|
||||
auto origin = *view.at(x, y);
|
||||
if (!check_point(origin, orig, tolerance))
|
||||
return false;
|
||||
auto w = view.width();
|
||||
auto h = view.height();
|
||||
int l = x, r = x, u = y, d = y;
|
||||
for (int i = x + 1; i < w; i++)
|
||||
{
|
||||
auto p = *view.at(i, y);
|
||||
if (!check_point(p, orig, tolerance))
|
||||
{
|
||||
r = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = x - 1; i >= 0; i--)
|
||||
{
|
||||
auto p = *view.at(i, y);
|
||||
if (!check_point(p, orig, tolerance))
|
||||
{
|
||||
l = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = y + 1; i < h; i++)
|
||||
{
|
||||
auto p = *view.at(x, i);
|
||||
if (!check_point(p, orig, tolerance))
|
||||
{
|
||||
d = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = y - 1; i >= 0; i--)
|
||||
{
|
||||
auto p = *view.at(x, i);
|
||||
if (!check_point(p, orig, tolerance))
|
||||
{
|
||||
u = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret[0] = l;
|
||||
ret[1] = r;
|
||||
ret[2] = u;
|
||||
ret[3] = d;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DialogAlignToVideo::process(wxCommandEvent & evt)
|
||||
{
|
||||
auto n_frames = provider->GetFrameCount();
|
||||
auto w = provider->GetWidth();
|
||||
auto h = provider->GetHeight();
|
||||
|
||||
long lx, ly, lt;
|
||||
if (!selected_x->GetValue().ToLong(&lx) || !selected_y->GetValue().ToLong(&ly) || !selected_tolerance->GetValue().ToLong(<))
|
||||
{
|
||||
wxMessageBox(_("Bad x or y position or tolerance value!"));
|
||||
evt.Skip();
|
||||
return;
|
||||
}
|
||||
if (lx < 0 || ly < 0 || lx >= w || ly >= h)
|
||||
{
|
||||
wxMessageBox(wxString::Format(_("Bad x or y position! Require: 0 <= x < %i, 0 <= y < %i"), w, h));
|
||||
evt.Skip();
|
||||
return;
|
||||
}
|
||||
if (lt < 0 || lt > 255)
|
||||
{
|
||||
wxMessageBox(_("Bad tolerance value! Require: 0 <= torlerance <= 255"));
|
||||
evt.Skip();
|
||||
return;
|
||||
}
|
||||
int x = int(lx), y = int(ly);
|
||||
unsigned char tolerance = (unsigned char)(lt);
|
||||
|
||||
auto color = selected_color->GetColor();
|
||||
auto r = color.r;
|
||||
auto b = color.b;
|
||||
auto g = color.g;
|
||||
double lab[3];
|
||||
rgb2lab(r, g, b, lab);
|
||||
|
||||
int pos = current_n_frame;
|
||||
auto frame = provider->GetFrame(pos, -1, true);
|
||||
auto view = interleaved_view(frame->width, frame->height, reinterpret_cast<boost::gil::bgra8_pixel_t*>(frame->data.data()), frame->pitch);
|
||||
if (frame->flipped)
|
||||
y = frame->height - y;
|
||||
int lrud[4];
|
||||
calculate_point(view, x, y, lab, tolerance, lrud);
|
||||
|
||||
// find forward
|
||||
#define CHECK_EXISTS_POS check_exists(pos, x, y, lrud, lab, tolerance)
|
||||
while (pos >= 0)
|
||||
{
|
||||
if (CHECK_EXISTS_POS)
|
||||
pos -= 2;
|
||||
else break;
|
||||
}
|
||||
pos++;
|
||||
pos = std::max(0, pos);
|
||||
auto left = CHECK_EXISTS_POS ? pos : pos + 1;
|
||||
|
||||
pos = current_n_frame;
|
||||
while (pos < n_frames)
|
||||
{
|
||||
if (CHECK_EXISTS_POS)
|
||||
pos += 2;
|
||||
else break;
|
||||
}
|
||||
pos--;
|
||||
pos = std::min(pos, n_frames - 1);
|
||||
auto right = CHECK_EXISTS_POS ? pos : pos - 1;
|
||||
|
||||
auto timecode = context->project->Timecodes();
|
||||
auto line = context->selectionController->GetActiveLine();
|
||||
line->Start = timecode.TimeAtFrame(left, agi::vfr::Time::START);
|
||||
line->End = timecode.TimeAtFrame(right, agi::vfr::Time::END); // exclusive
|
||||
context->ass->Commit(_("Align to video by key point"), AssFile::COMMIT_DIAG_TIME);
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool DialogAlignToVideo::check_exists(int pos, int x, int y, int* lrud, double* orig, unsigned char tolerance)
|
||||
{
|
||||
auto frame = provider->GetFrame(pos, -1, true);
|
||||
auto view = interleaved_view(frame->width, frame->height, reinterpret_cast<boost::gil::bgra8_pixel_t*>(frame->data.data()), frame->pitch);
|
||||
if (frame->flipped)
|
||||
y = frame->height - y;
|
||||
int actual[4];
|
||||
if (!calculate_point(view, x, y, orig, tolerance, actual)) return false;
|
||||
int dl = abs(actual[0] - lrud[0]);
|
||||
int dr = abs(actual[1] - lrud[1]);
|
||||
int du = abs(actual[2] - lrud[2]);
|
||||
int dd = abs(actual[3] - lrud[3]);
|
||||
|
||||
return dl <= 5 && dr <= 5 && du <= 5 && dd <= 5;
|
||||
}
|
||||
|
||||
void DialogAlignToVideo::update_from_textbox()
|
||||
{
|
||||
long lx, ly;
|
||||
int w = preview_image.GetWidth(), h = preview_image.GetHeight();
|
||||
if (!selected_x->GetValue().ToLong(&lx) || !selected_y->GetValue().ToLong(&ly))
|
||||
return;
|
||||
|
||||
if (lx < 0 || ly < 0 || lx >= w || ly >= h)
|
||||
return;
|
||||
int x = int(lx);
|
||||
int y = int(ly);
|
||||
auto r = preview_image.GetRed(x, y);
|
||||
auto g = preview_image.GetGreen(x, y);
|
||||
auto b = preview_image.GetBlue(x, y);
|
||||
selected_color->SetColor(agi::Color(r, g, b));
|
||||
}
|
||||
|
||||
void DialogAlignToVideo::update_from_textbox(wxCommandEvent & evt)
|
||||
{
|
||||
update_from_textbox();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ShowAlignToVideoDialog(agi::Context * c)
|
||||
{
|
||||
c->dialog->Show<DialogAlignToVideo>(c);
|
||||
}
|
|
@ -143,7 +143,7 @@ void DialogAutosave::Populate(std::map<wxString, AutosaveFile> &files_map, std::
|
|||
|
||||
auto it = files_map.find(name);
|
||||
if (it == files_map.end())
|
||||
it = files_map.insert({name, AutosaveFile{name}}).first;
|
||||
it = files_map.insert({name, AutosaveFile{name, std::vector<Version>()}}).first;
|
||||
it->second.versions.push_back(Version{wxFileName(directory, fn).GetFullPath(), date, agi::wxformat(name_fmt, date.Format())});
|
||||
} while (dir.GetNext(&fn));
|
||||
}
|
||||
|
|
|
@ -557,9 +557,9 @@ DialogColorPicker::DialogColorPicker(wxWindow *parent, agi::Color initial_color,
|
|||
wxString modes[] = { _("RGB/R"), _("RGB/G"), _("RGB/B"), _("HSL/L"), _("HSV/H") };
|
||||
colorspace_choice = new wxChoice(this, -1, wxDefaultPosition, wxDefaultSize, 5, modes);
|
||||
|
||||
wxSize colorinput_size = GetTextExtent(" &H10117B& ");
|
||||
colorinput_size.SetHeight(-1);
|
||||
wxSize colorinput_labelsize(40, -1);
|
||||
ass_input = new wxTextCtrl(this, -1);
|
||||
wxSize colorinput_size = ass_input->GetSizeFromTextSize(GetTextExtent(wxS("&H10117B&")));
|
||||
ass_input->SetInitialSize(colorinput_size);
|
||||
|
||||
wxSizer *rgb_box = new wxStaticBoxSizer(wxHORIZONTAL, this, _("RGB color"));
|
||||
wxSizer *hsl_box = new wxStaticBoxSizer(wxVERTICAL, this, _("HSL color"));
|
||||
|
@ -568,7 +568,7 @@ DialogColorPicker::DialogColorPicker(wxWindow *parent, agi::Color initial_color,
|
|||
for (auto& elem : rgb_input)
|
||||
elem = new wxSpinCtrl(this, -1, "", wxDefaultPosition, colorinput_size, wxSP_ARROW_KEYS, 0, 255);
|
||||
|
||||
ass_input = new wxTextCtrl(this, -1, "", wxDefaultPosition, colorinput_size);
|
||||
// ass_input = new wxTextCtrl(this, -1, "", wxDefaultPosition, colorinput_size);
|
||||
html_input = new wxTextCtrl(this, -1, "", wxDefaultPosition, colorinput_size);
|
||||
alpha_input = new wxSpinCtrl(this, -1, "", wxDefaultPosition, colorinput_size, wxSP_ARROW_KEYS, 0, 255);
|
||||
|
||||
|
|
|
@ -72,19 +72,22 @@ static ResolutionShortcut resolutions[] = {
|
|||
{"704x396 (SD widescreen)", 704, 396},
|
||||
{"640x352 (SD widescreen MOD16)", 640, 352},
|
||||
{"704x400 (SD widescreen MOD16)", 704, 400},
|
||||
{"1024x576 (SuperPAL widescreen)", 1024, 576},
|
||||
{"1280x720 (HD 720p)", 1280, 720},
|
||||
{"1920x1080 (HD 1080p)", 1920, 1080},
|
||||
{"1024x576 (SuperPAL widescreen)", 1024, 576}
|
||||
{"1920x1080 (FHD 1080p)", 1920, 1080},
|
||||
{"2560x1440 (QHD 1440p)", 2560, 1440},
|
||||
{"3840x2160 (4K UHD 2160p)", 3840, 2160},
|
||||
};
|
||||
|
||||
wxSpinCtrl *spin_ctrl(wxWindow *parent, int min, int max, int *value) {
|
||||
auto ctrl = new wxSpinCtrl(parent, -1, "", wxDefaultPosition, wxSize(50, -1), wxSP_ARROW_KEYS, min, max, *value);
|
||||
auto ctrl = new wxSpinCtrl(parent, -1, "", wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, min, max, *value);
|
||||
ctrl->SetValidator(wxGenericValidator(value));
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
// FIXME: change the misleading function name, this is TextCtrl in fact
|
||||
wxControl *spin_ctrl(wxWindow *parent, double min, double max, double *value) {
|
||||
return new wxTextCtrl(parent, -1, "", wxDefaultPosition, wxSize(50, -1), 0, DoubleValidator(value, min, max));
|
||||
return new wxTextCtrl(parent, -1, "", wxDefaultPosition, wxDefaultSize, 0, DoubleValidator(value, min, max));
|
||||
}
|
||||
|
||||
wxComboBox *resolution_shortcuts(wxWindow *parent, int width, int height) {
|
||||
|
|
|
@ -125,7 +125,7 @@ DialogExport::DialogExport(agi::Context *c)
|
|||
wxButton *btn_none = new wxButton(&d, -1, _("Select &None"), wxDefaultPosition, wxSize(80, -1));
|
||||
|
||||
btn_up->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) { swap(filter_list, filter_list->GetSelection() - 1, 0); });
|
||||
btn_down->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) { swap(filter_list, filter_list->GetSelection() - 1, 0); });
|
||||
btn_down->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) { swap(filter_list, filter_list->GetSelection(), 1); });
|
||||
btn_all->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) { SetAll(true); });
|
||||
btn_none->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) { SetAll(false); });
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ int ShowEbuExportConfigurationDialog(wxWindow *owner, EbuExportSettings &s) {
|
|||
wxRadioBox *tv_standard_box = new wxRadioBox(&d, -1, _("TV standard"), wxDefaultPosition, wxDefaultSize, 6, tv_standards, 0, wxRA_SPECIFY_ROWS);
|
||||
|
||||
wxTextCtrl *timecode_offset_entry = new wxTextCtrl(&d, -1, "00:00:00:00");
|
||||
timecode_offset_entry->SetInitialSize(timecode_offset_entry->GetSizeFromTextSize(timecode_offset_entry->GetTextExtent(wxS("00:00:00:00"))));
|
||||
wxCheckBox *inclusive_end_times_check = new wxCheckBox(&d, -1, _("Out-times are inclusive"));
|
||||
|
||||
wxString text_encodings[] = {
|
||||
|
@ -129,7 +130,8 @@ int ShowEbuExportConfigurationDialog(wxWindow *owner, EbuExportSettings &s) {
|
|||
_("Skip lines that are too long")
|
||||
};
|
||||
|
||||
wxSpinCtrl *max_line_length_ctrl = new wxSpinCtrl(&d, -1, wxString(), wxDefaultPosition, wxSize(65, -1));
|
||||
wxSpinCtrl *max_line_length_ctrl = new wxSpinCtrl(&d, -1, wxString());
|
||||
max_line_length_ctrl->SetInitialSize(max_line_length_ctrl->GetSizeFromTextSize(max_line_length_ctrl->GetTextExtent(wxS("00"))));
|
||||
wxComboBox *wrap_mode_ctrl = new wxComboBox(&d, -1, wrap_modes[0], wxDefaultPosition, wxDefaultSize, 4, wrap_modes, wxCB_DROPDOWN | wxCB_READONLY);
|
||||
wxCheckBox *translate_alignments_check = new wxCheckBox(&d, -1, _("Translate alignments"));
|
||||
|
||||
|
|
|
@ -400,7 +400,11 @@ void DialogFontsCollector::OnAddText(ValueEvent<color_str_pair> &event) {
|
|||
auto const& utf8 = str.second.utf8_str();
|
||||
collection_log->AppendTextRaw(utf8.data(), utf8.length());
|
||||
if (str.first) {
|
||||
#if wxCHECK_VERSION (3, 1, 0)
|
||||
collection_log->StartStyling(pos);
|
||||
#else
|
||||
collection_log->StartStyling(pos, 31);
|
||||
#endif
|
||||
collection_log->SetStyling(utf8.length(), str.first);
|
||||
}
|
||||
collection_log->GotoPos(pos + utf8.length());
|
||||
|
@ -415,8 +419,7 @@ void DialogFontsCollector::OnCollectionComplete(wxThreadEvent &) {
|
|||
if (path.Decode("?script") == "?script")
|
||||
collection_mode->Enable(2, false);
|
||||
|
||||
wxCommandEvent evt;
|
||||
OnRadio(evt);
|
||||
UpdateControls();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -108,8 +108,8 @@ DialogProperties::DialogProperties(agi::Context *c)
|
|||
TopSizer->Add(TopSizerGrid,1,wxALL | wxEXPAND,0);
|
||||
|
||||
// Resolution box
|
||||
ResX = new wxTextCtrl(&d,-1,"",wxDefaultPosition,wxSize(50,20),0,IntValidator(c->ass->GetScriptInfoAsInt("PlayResX")));
|
||||
ResY = new wxTextCtrl(&d,-1,"",wxDefaultPosition,wxSize(50,20),0,IntValidator(c->ass->GetScriptInfoAsInt("PlayResY")));
|
||||
ResX = new wxTextCtrl(&d,-1,"",wxDefaultPosition,wxDefaultSize,0,IntValidator(c->ass->GetScriptInfoAsInt("PlayResX")));
|
||||
ResY = new wxTextCtrl(&d,-1,"",wxDefaultPosition,wxDefaultSize,0,IntValidator(c->ass->GetScriptInfoAsInt("PlayResY")));
|
||||
|
||||
wxButton *FromVideo = new wxButton(&d,-1,_("From &video"));
|
||||
if (!c->project->VideoProvider())
|
||||
|
@ -173,7 +173,7 @@ DialogProperties::DialogProperties(agi::Context *c)
|
|||
}
|
||||
|
||||
void DialogProperties::AddProperty(wxSizer *sizer, wxString const& label, std::string const& property) {
|
||||
wxTextCtrl *ctrl = new wxTextCtrl(&d, -1, to_wx(c->ass->GetScriptInfo(property)), wxDefaultPosition, wxSize(200, 20));
|
||||
wxTextCtrl *ctrl = new wxTextCtrl(&d, -1, to_wx(c->ass->GetScriptInfo(property)));
|
||||
sizer->Add(new wxStaticText(&d, -1, label), wxSizerFlags().Center().Left());
|
||||
sizer->Add(ctrl, wxSizerFlags(1).Expand());
|
||||
properties.push_back({property, ctrl});
|
||||
|
|
|
@ -112,7 +112,7 @@ DialogResample::DialogResample(agi::Context *c, ResampleSettings &settings)
|
|||
|
||||
// Create all controls and set validators
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
margin_ctrl[i] = new wxSpinCtrl(&d, -1, "0", wxDefaultPosition, wxSize(50, -1), wxSP_ARROW_KEYS, -9999, 9999, 0);
|
||||
margin_ctrl[i] = new wxSpinCtrl(&d, -1, "0", wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -9999, 9999, 0);
|
||||
margin_ctrl[i]->SetValidator(wxGenericValidator(&settings.margin[i]));
|
||||
}
|
||||
|
||||
|
@ -122,12 +122,12 @@ DialogResample::DialogResample(agi::Context *c, ResampleSettings &settings)
|
|||
margin_ctrl[RIGHT]->Enable(false);
|
||||
margin_ctrl[BOTTOM]->Enable(false);
|
||||
|
||||
source_x = new wxSpinCtrl(&d, -1, "", wxDefaultPosition, wxSize(50, -1), wxSP_ARROW_KEYS, 1, INT_MAX);
|
||||
source_y = new wxSpinCtrl(&d, -1, "", wxDefaultPosition, wxSize(50, -1), wxSP_ARROW_KEYS, 1, INT_MAX);
|
||||
source_x = new wxSpinCtrl(&d, -1, "", wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, INT_MAX);
|
||||
source_y = new wxSpinCtrl(&d, -1, "", wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, INT_MAX);
|
||||
source_matrix = new wxComboBox(&d, -1, "", wxDefaultPosition,
|
||||
wxDefaultSize, to_wx(MatrixNames()), wxCB_READONLY);
|
||||
dest_x = new wxSpinCtrl(&d, -1, "", wxDefaultPosition, wxSize(50, -1), wxSP_ARROW_KEYS, 1, INT_MAX);
|
||||
dest_y = new wxSpinCtrl(&d, -1, "", wxDefaultPosition, wxSize(50, -1), wxSP_ARROW_KEYS, 1, INT_MAX);
|
||||
dest_x = new wxSpinCtrl(&d, -1, "", wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, INT_MAX);
|
||||
dest_y = new wxSpinCtrl(&d, -1, "", wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, INT_MAX);
|
||||
dest_matrix = new wxComboBox(&d, -1, "", wxDefaultPosition, wxDefaultSize,
|
||||
to_wx(MatrixNames()), wxCB_READONLY);
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ DialogStyleEditor::DialogStyleEditor(wxWindow *parent, AssStyle *style, agi::Con
|
|||
|
||||
auto num_text_ctrl = [&](double *value, double min, double max, double step) -> wxSpinCtrlDouble * {
|
||||
auto scd = new wxSpinCtrlDouble(this, -1, "", wxDefaultPosition,
|
||||
wxSize(75, -1), wxSP_ARROW_KEYS, min, max, *value, step);
|
||||
wxDefaultSize, wxSP_ARROW_KEYS, min, max, *value, step);
|
||||
scd->SetValidator(DoubleSpinValidator(value));
|
||||
scd->Bind(wxEVT_SPINCTRLDOUBLE, [=](wxSpinDoubleEvent &evt) {
|
||||
evt.Skip();
|
||||
|
@ -197,10 +197,12 @@ DialogStyleEditor::DialogStyleEditor(wxWindow *parent, AssStyle *style, agi::Con
|
|||
new ColourButton(this, wxSize(55, 16), true, style->outline, ColorValidator(&work->outline)),
|
||||
new ColourButton(this, wxSize(55, 16), true, style->shadow, ColorValidator(&work->shadow))
|
||||
};
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int i = 0; i < 3; i++) {
|
||||
margin[i] = new wxSpinCtrl(this, -1, std::to_wstring(style->Margin[i]),
|
||||
wxDefaultPosition, wxSize(60, -1),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxSP_ARROW_KEYS, 0, 9999, style->Margin[i]);
|
||||
margin[i]->SetInitialSize(margin[i]->GetSizeFromTextSize(GetTextExtent(wxS("0000"))));
|
||||
}
|
||||
|
||||
Alignment = new wxRadioBox(this, -1, _("Alignment"), wxDefaultPosition, wxDefaultSize, 9, alignValues, 3, wxRA_SPECIFY_COLS);
|
||||
auto Outline = num_text_ctrl(&work->outline_w, 0.0, 1000.0, 0.1);
|
||||
|
|
|
@ -144,8 +144,8 @@ DialogTimingProcessor::DialogTimingProcessor(agi::Context *c)
|
|||
d.SetIcon(GETICON(timing_processor_toolbutton_16));
|
||||
|
||||
// Read options
|
||||
leadIn = OPT_GET("Audio/Lead/IN")->GetInt();
|
||||
leadOut = OPT_GET("Audio/Lead/OUT")->GetInt();
|
||||
leadIn = OPT_GET("Tool/Timing Post Processor/Lead/IN")->GetInt();
|
||||
leadOut = OPT_GET("Tool/Timing Post Processor/Lead/OUT")->GetInt();
|
||||
beforeStart = OPT_GET("Tool/Timing Post Processor/Threshold/Key Start Before")->GetInt();
|
||||
beforeEnd = OPT_GET("Tool/Timing Post Processor/Threshold/Key End Before")->GetInt();
|
||||
afterStart = OPT_GET("Tool/Timing Post Processor/Threshold/Key Start After")->GetInt();
|
||||
|
@ -305,8 +305,8 @@ void DialogTimingProcessor::UpdateControls() {
|
|||
void DialogTimingProcessor::OnApply(wxCommandEvent &) {
|
||||
d.TransferDataFromWindow();
|
||||
// Save settings
|
||||
OPT_SET("Audio/Lead/IN")->SetInt(leadIn);
|
||||
OPT_SET("Audio/Lead/OUT")->SetInt(leadOut);
|
||||
OPT_SET("Tool/Timing Post Processor/Lead/IN")->SetInt(leadIn);
|
||||
OPT_SET("Tool/Timing Post Processor/Lead/OUT")->SetInt(leadOut);
|
||||
OPT_SET("Tool/Timing Post Processor/Threshold/Key Start Before")->SetInt(beforeStart);
|
||||
OPT_SET("Tool/Timing Post Processor/Threshold/Key Start After")->SetInt(afterStart);
|
||||
OPT_SET("Tool/Timing Post Processor/Threshold/Key End Before")->SetInt(beforeEnd);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "format.h"
|
||||
#include "help_button.h"
|
||||
#include "libresrc/libresrc.h"
|
||||
#include "options.h"
|
||||
#include "persist_location.h"
|
||||
#include "project.h"
|
||||
#include "subs_edit_ctrl.h"
|
||||
|
@ -57,7 +58,8 @@ static void add_hotkey(wxSizer *sizer, wxWindow *parent, const char *command, wx
|
|||
|
||||
// Skip over override blocks, comments, and whitespace between blocks
|
||||
static bool bad_block(std::unique_ptr<AssDialogueBlock> &block) {
|
||||
return block->GetType() != AssBlockType::PLAIN || boost::all(block->GetText(), boost::is_space());
|
||||
bool is_whitespace = boost::all(block->GetText(), boost::is_space());
|
||||
return block->GetType() != AssBlockType::PLAIN || (is_whitespace && OPT_GET("Tool/Translation Assistant/Skip Whitespace")->GetBool());
|
||||
}
|
||||
|
||||
DialogTranslation::DialogTranslation(agi::Context *c)
|
||||
|
@ -95,7 +97,11 @@ DialogTranslation::DialogTranslation(agi::Context *c)
|
|||
translated_text->SetMarginWidth(1, 0);
|
||||
translated_text->SetFocus();
|
||||
translated_text->Bind(wxEVT_CHAR_HOOK, &DialogTranslation::OnKeyDown, this);
|
||||
#if wxCHECK_VERSION (3, 1, 0)
|
||||
translated_text->CmdKeyAssign(wxSTC_KEY_RETURN, wxSTC_KEYMOD_SHIFT, wxSTC_CMD_NEWLINE);
|
||||
#else
|
||||
translated_text->CmdKeyAssign(wxSTC_KEY_RETURN, wxSTC_SCMOD_SHIFT, wxSTC_CMD_NEWLINE);
|
||||
#endif
|
||||
|
||||
wxSizer *translated_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Translation"));
|
||||
translated_box->Add(translated_text, 1, wxEXPAND, 0);
|
||||
|
@ -244,7 +250,11 @@ void DialogTranslation::UpdateDisplay() {
|
|||
int initial_pos = original_text->GetLength();
|
||||
original_text->AppendTextRaw(block->GetText().c_str());
|
||||
if (i == cur_block) {
|
||||
#if wxCHECK_VERSION (3, 1, 0)
|
||||
original_text->StartStyling(initial_pos);
|
||||
#else
|
||||
original_text->StartStyling(initial_pos, 31);
|
||||
#endif
|
||||
original_text->SetStyling(block->GetText().size(), 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,7 +131,6 @@ bool update_video_properties(AssFile *file, const AsyncVideoProvider *new_provid
|
|||
return true;
|
||||
|
||||
case MISMATCH_RESAMPLE:
|
||||
// Fallthrough to prompt if the AR changed
|
||||
if (!ar_changed) {
|
||||
ResampleResolution(file, {
|
||||
{0, 0, 0, 0},
|
||||
|
@ -141,6 +140,8 @@ bool update_video_properties(AssFile *file, const AsyncVideoProvider *new_provid
|
|||
});
|
||||
return true;
|
||||
}
|
||||
// Fallthrough
|
||||
// to prompt if the AR changed
|
||||
|
||||
case MISMATCH_PROMPT:
|
||||
int res = prompt(parent, ar_changed, sx, sy, vx, vy);
|
||||
|
|
|
@ -74,3 +74,4 @@ void ShowSpellcheckerDialog(agi::Context *c);
|
|||
void ShowStyleManagerDialog(agi::Context *c);
|
||||
void ShowTimingProcessorDialog(agi::Context *c);
|
||||
void ShowVideoDetailsDialog(agi::Context *c);
|
||||
void ShowAlignToVideoDialog(agi::Context* c);
|
||||
|
|
9
src/dpi_aware.manifest
Normal file
9
src/dpi_aware.manifest
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
|
@ -78,8 +78,8 @@ wxWindow *AssTransformFramerateFilter::GetConfigDialogWindow(wxWindow *parent, a
|
|||
initialInput = "23.976";
|
||||
FromVideo->Enable(false);
|
||||
}
|
||||
InputFramerate = new wxTextCtrl(base,-1,initialInput,wxDefaultPosition,wxSize(60,20));
|
||||
InputSizer->Add(InputFramerate,0,wxEXPAND | wxLEFT,5);
|
||||
InputFramerate = new wxTextCtrl(base,-1,initialInput);
|
||||
InputSizer->Add(InputFramerate, 0, wxEXPAND);
|
||||
InputSizer->Add(FromVideo, 0, wxEXPAND | wxLEFT, 5);
|
||||
InputSizer->AddStretchSpacer(1);
|
||||
|
||||
|
@ -90,7 +90,7 @@ wxWindow *AssTransformFramerateFilter::GetConfigDialogWindow(wxWindow *parent, a
|
|||
|
||||
// Output top line
|
||||
RadioOutputVFR = new wxRadioButton(base,-1,_("V&ariable"),wxDefaultPosition,wxDefaultSize,wxRB_GROUP);
|
||||
OutputSizerTop->Add(RadioOutputVFR,0,wxEXPAND,0);
|
||||
OutputSizerTop->Add(RadioOutputVFR, wxEXPAND);
|
||||
|
||||
// Output bottom line
|
||||
RadioOutputCFR = new wxRadioButton(base,-1,_("&Constant: "));
|
||||
|
@ -99,8 +99,8 @@ wxWindow *AssTransformFramerateFilter::GetConfigDialogWindow(wxWindow *parent, a
|
|||
RadioOutputVFR->Enable(false);
|
||||
RadioOutputCFR->SetValue(true);
|
||||
}
|
||||
OutputFramerate = new wxTextCtrl(base,-1,initialOutput,wxDefaultPosition,wxSize(60,20));
|
||||
OutputSizerBottom->Add(RadioOutputCFR,0,wxEXPAND,0);
|
||||
OutputFramerate = new wxTextCtrl(base,-1,initialOutput);
|
||||
OutputSizerBottom->Add(RadioOutputCFR, wxEXPAND);
|
||||
OutputSizerBottom->Add(OutputFramerate, 0, wxEXPAND | wxLEFT, 5);
|
||||
OutputSizerBottom->AddStretchSpacer(1);
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ enum {
|
|||
FFmpegSourceProvider::FFmpegSourceProvider(agi::BackgroundRunner *br)
|
||||
: br(br)
|
||||
{
|
||||
FFMS_Init(0, 1);
|
||||
FFMS_Init(0, 0);
|
||||
}
|
||||
|
||||
/// @brief Does indexing of a source file
|
||||
|
|
|
@ -66,9 +66,10 @@ std::vector<agi::fs::path> get_installed_fonts() {
|
|||
|
||||
std::vector<agi::fs::path> files;
|
||||
|
||||
for (HKEY hKey : { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }) {
|
||||
HKEY key;
|
||||
auto ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fonts_key_name, 0, KEY_QUERY_VALUE, &key);
|
||||
if (ret != ERROR_SUCCESS) return files;
|
||||
auto ret = RegOpenKeyExW(hKey, fonts_key_name, 0, KEY_QUERY_VALUE, &key);
|
||||
if (ret != ERROR_SUCCESS) continue;
|
||||
BOOST_SCOPE_EXIT_ALL(= ) { RegCloseKey(key); };
|
||||
|
||||
wchar_t fdir[MAX_PATH];
|
||||
|
@ -85,10 +86,11 @@ std::vector<agi::fs::path> get_installed_fonts() {
|
|||
if (ret != ERROR_SUCCESS) continue;
|
||||
|
||||
agi::fs::path font_path(font_filename);
|
||||
if (!agi::fs::FileExists(font_path))
|
||||
if (!agi::fs::FileExists(font_path) && agi::fs::FileExists(font_dir / font_path))
|
||||
font_path = font_dir / font_path;
|
||||
files.push_back(font_path);
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ enum {
|
|||
};
|
||||
|
||||
#ifdef WITH_STARTUPLOG
|
||||
#define StartupLog(a) MessageBox(0, a, "Aegisub startup log", 0)
|
||||
#define StartupLog(a) wxMessageBox(a, "Aegisub startup log")
|
||||
#else
|
||||
#define StartupLog(a) LOG_I("frame_main/init") << a
|
||||
#endif
|
||||
|
@ -240,8 +240,6 @@ void FrameMain::SetDisplayMode(int video, int audio) {
|
|||
TopSizer->Show(videoBox, showVideo, true);
|
||||
ToolsSizer->Show(audioBox, showAudio, true);
|
||||
|
||||
MainSizer->CalcMin();
|
||||
MainSizer->RecalcSizes();
|
||||
MainSizer->Layout();
|
||||
Layout();
|
||||
|
||||
|
|
10279
src/gl/glext.h
10279
src/gl/glext.h
File diff suppressed because it is too large
Load diff
|
@ -52,10 +52,9 @@
|
|||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
/// @class OpenGLTextGlyph
|
||||
/// @brief Struct storing the information needed to draw a glyph
|
||||
struct OpenGLTextGlyph {
|
||||
struct OpenGLText::OpenGLTextGlyph {
|
||||
wxString str; ///< String containing the glyph(s) this is for
|
||||
int tex = 0; ///< OpenGL texture to draw for this glyph
|
||||
float x1 = 0; ///< Left x coordinate of this glyph in the containing texture
|
||||
|
@ -108,7 +107,7 @@ struct OpenGLTextGlyph {
|
|||
|
||||
/// @class OpenGLTextTexture
|
||||
/// @brief OpenGL texture which stores one or more glyphs as sprites
|
||||
class OpenGLTextTexture final : boost::noncopyable {
|
||||
class OpenGLText::OpenGLTextTexture final : boost::noncopyable {
|
||||
int x = 0; ///< Next x coordinate at which a glyph can be inserted
|
||||
int y = 0; ///< Next y coordinate at which a glyph can be inserted
|
||||
int nextY = 0; ///< Y coordinate of the next line; tracked due to that lines
|
||||
|
@ -217,8 +216,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
OpenGLText::OpenGLText() { }
|
||||
OpenGLText::~OpenGLText() { }
|
||||
|
||||
|
@ -286,12 +283,12 @@ void OpenGLText::GetExtent(std::string const& text, int &w, int &h) {
|
|||
}
|
||||
}
|
||||
|
||||
OpenGLTextGlyph const& OpenGLText::GetGlyph(int i) {
|
||||
OpenGLText::OpenGLTextGlyph const& OpenGLText::GetGlyph(int i) {
|
||||
auto res = glyphs.find(i);
|
||||
return res != glyphs.end() ? res->second : CreateGlyph(i);
|
||||
}
|
||||
|
||||
OpenGLTextGlyph const& OpenGLText::CreateGlyph(int n) {
|
||||
OpenGLText::OpenGLTextGlyph const& OpenGLText::CreateGlyph(int n) {
|
||||
OpenGLTextGlyph &glyph = glyphs.emplace(n, OpenGLTextGlyph(n, font)).first->second;
|
||||
|
||||
// Insert into some texture
|
||||
|
|
|
@ -34,16 +34,13 @@
|
|||
|
||||
#include <wx/font.h>
|
||||
|
||||
namespace {
|
||||
struct OpenGLTextGlyph;
|
||||
class OpenGLTextTexture;
|
||||
}
|
||||
|
||||
namespace agi { struct Color; }
|
||||
|
||||
class OpenGLText {
|
||||
struct OpenGLTextGlyph;
|
||||
class OpenGLTextTexture;
|
||||
typedef boost::container::map<int, OpenGLTextGlyph> glyphMap;
|
||||
|
||||
class OpenGLText {
|
||||
float r = 1.f, g = 1.f, b = 1.f, a = 1.f;
|
||||
|
||||
int fontSize = 0;
|
||||
|
|
|
@ -28,7 +28,11 @@
|
|||
#include <OpenGL/glext.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include "gl/glext.h"
|
||||
#endif
|
||||
|
||||
#ifndef GL_GLEXT_VERSION
|
||||
// The following typedef is copied from glext.h
|
||||
typedef void (*PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint* first, const GLsizei* count, GLsizei drawcount);
|
||||
#endif
|
||||
|
||||
static const float deg2rad = 3.1415926536f / 180.f;
|
||||
|
|
|
@ -29,6 +29,11 @@
|
|||
#include <wx/msgdlg.h>
|
||||
|
||||
namespace {
|
||||
const char* added_hotkeys_cj[][3] = {
|
||||
{"time/align", "Video", "KP_TAB"},
|
||||
{nullptr}
|
||||
};
|
||||
|
||||
const char *added_hotkeys_7035[][3] = {
|
||||
{"audio/play/line", "Audio", "R"},
|
||||
{nullptr}
|
||||
|
@ -47,10 +52,12 @@ namespace {
|
|||
{nullptr}
|
||||
};
|
||||
|
||||
#ifdef __WXMAC__
|
||||
const char *added_hotkeys_minimize[][3] = {
|
||||
{"app/minimize", "Default", "Ctrl-M"},
|
||||
{nullptr}
|
||||
};
|
||||
#endif
|
||||
|
||||
void migrate_hotkeys(const char *added[][3]) {
|
||||
auto hk_map = hotkey::inst->GetHotkeyMap();
|
||||
|
@ -81,6 +88,11 @@ void init() {
|
|||
|
||||
auto migrations = OPT_GET("App/Hotkey Migrations")->GetListString();
|
||||
|
||||
if (boost::find(migrations, "cj") == end(migrations)) {
|
||||
migrate_hotkeys(added_hotkeys_cj);
|
||||
migrations.emplace_back("cj");
|
||||
}
|
||||
|
||||
if (boost::find(migrations, "7035") == end(migrations)) {
|
||||
migrate_hotkeys(added_hotkeys_7035);
|
||||
migrations.emplace_back("7035");
|
||||
|
|
127
src/image_position_picker.cpp
Normal file
127
src/image_position_picker.cpp
Normal file
|
@ -0,0 +1,127 @@
|
|||
#include "image_position_picker.h"
|
||||
BEGIN_EVENT_TABLE(ImagePositionPicker, wxPanel)
|
||||
// some useful events
|
||||
/*
|
||||
EVT_MOTION(ImagePositionPicker::mouseMoved)
|
||||
EVT_LEFT_DOWN(ImagePositionPicker::mouseDown)
|
||||
EVT_LEFT_UP(ImagePositionPicker::mouseReleased)
|
||||
EVT_RIGHT_DOWN(ImagePositionPicker::rightClick)
|
||||
EVT_LEAVE_WINDOW(ImagePositionPicker::mouseLeftWindow)
|
||||
EVT_KEY_DOWN(ImagePositionPicker::keyPressed)
|
||||
EVT_KEY_UP(ImagePositionPicker::keyReleased)
|
||||
EVT_MOUSEWHEEL(ImagePositionPicker::mouseWheelMoved)
|
||||
*/
|
||||
|
||||
// catch paint events
|
||||
EVT_PAINT(ImagePositionPicker::paintEvent)
|
||||
//Size event
|
||||
EVT_SIZE(ImagePositionPicker::OnSize)
|
||||
EVT_MOUSE_EVENTS(ImagePositionPicker::OnMouseEvent)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
// some useful events
|
||||
/*
|
||||
void ImagePositionPicker::mouseMoved(wxMouseEvent& event) {}
|
||||
void ImagePositionPicker::mouseDown(wxMouseEvent& event) {}
|
||||
void ImagePositionPicker::mouseWheelMoved(wxMouseEvent& event) {}
|
||||
void ImagePositionPicker::mouseReleased(wxMouseEvent& event) {}
|
||||
void ImagePositionPicker::rightClick(wxMouseEvent& event) {}
|
||||
void ImagePositionPicker::mouseLeftWindow(wxMouseEvent& event) {}
|
||||
void ImagePositionPicker::keyPressed(wxKeyEvent& event) {}
|
||||
void ImagePositionPicker::keyReleased(wxKeyEvent& event) {}
|
||||
*/
|
||||
|
||||
ImagePositionPicker::ImagePositionPicker(wxWindow* parent, wxImage i, updator upd) : wxPanel(parent)
|
||||
{
|
||||
image = i;
|
||||
prevW = -1;
|
||||
prevH = -1;
|
||||
w = image.GetWidth();
|
||||
h = image.GetHeight();
|
||||
update = upd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by the system of by wxWidgets when the panel needs
|
||||
* to be redrawn. You can also trigger this call by
|
||||
* calling Refresh()/Update().
|
||||
*/
|
||||
|
||||
void ImagePositionPicker::paintEvent(wxPaintEvent& evt)
|
||||
{
|
||||
// depending on your system you may need to look at double-buffered dcs
|
||||
wxPaintDC dc(this);
|
||||
render(dc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Alternatively, you can use a clientDC to paint on the panel
|
||||
* at any time. Using this generally does not free you from
|
||||
* catching paint events, since it is possible that e.g. the window
|
||||
* manager throws away your drawing when the window comes to the
|
||||
* background, and expects you will redraw it when the window comes
|
||||
* back (by sending a paint event).
|
||||
*/
|
||||
void ImagePositionPicker::paintNow()
|
||||
{
|
||||
// depending on your system you may need to look at double-buffered dcs
|
||||
wxClientDC dc(this);
|
||||
render(dc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we do the actual rendering. I put it in a separate
|
||||
* method so that it can work no matter what type of DC
|
||||
* (e.g. wxPaintDC or wxClientDC) is used.
|
||||
*/
|
||||
void ImagePositionPicker::render(wxDC& dc)
|
||||
{
|
||||
int neww, newh;
|
||||
dc.GetSize(&neww, &newh);
|
||||
|
||||
if (neww != prevW || newh != prevH)
|
||||
{
|
||||
// keep the image proportionate
|
||||
int ww, hh;
|
||||
if (double(neww) / w >= double(newh) / h) // too long
|
||||
{
|
||||
ww = newh * w / h;
|
||||
hh = newh;
|
||||
}
|
||||
else
|
||||
{
|
||||
ww = neww;
|
||||
hh = neww * h / w;
|
||||
}
|
||||
resized = wxBitmap(image.Scale(ww, hh /*, wxIMAGE_QUALITY_HIGH*/));
|
||||
prevW = ww;
|
||||
prevH = hh;
|
||||
dc.DrawBitmap(resized, 0, 0, false);
|
||||
}
|
||||
else {
|
||||
dc.DrawBitmap(resized, 0, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we call refresh to tell the panel to draw itself again.
|
||||
* So when the user resizes the image panel the image should be resized too.
|
||||
*/
|
||||
void ImagePositionPicker::OnSize(wxSizeEvent& event) {
|
||||
Refresh();
|
||||
//skip the event.
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void ImagePositionPicker::OnMouseEvent(wxMouseEvent& evt)
|
||||
{
|
||||
wxPoint pos = evt.GetPosition();
|
||||
if (evt.Dragging() || evt.LeftDown() || evt.LeftUp())
|
||||
{
|
||||
int x = pos.x * w / prevW;
|
||||
int y = pos.y * h / prevH;
|
||||
if (x >= 0 && x < w && y >= 0 && y < h)
|
||||
update(x, y, image.GetRed(x, y), image.GetGreen(x, y), image.GetBlue(x, y));
|
||||
}
|
||||
}
|
37
src/image_position_picker.h
Normal file
37
src/image_position_picker.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include <wx/wx.h>
|
||||
#include <wx/sizer.h>
|
||||
#include "gl_wrap.h"
|
||||
|
||||
typedef std::function<void(double, double, unsigned char, unsigned char, unsigned char)> updator;
|
||||
|
||||
class ImagePositionPicker : public wxPanel
|
||||
{
|
||||
wxImage image;
|
||||
wxBitmap resized;
|
||||
int prevW, prevH, w, h;
|
||||
|
||||
updator update;
|
||||
|
||||
public:
|
||||
ImagePositionPicker(wxWindow* parent, wxImage i, updator upd);
|
||||
|
||||
void paintEvent(wxPaintEvent & evt);
|
||||
void paintNow();
|
||||
void OnSize(wxSizeEvent& event);
|
||||
void OnMouseEvent(wxMouseEvent& evt);
|
||||
void render(wxDC& dc);
|
||||
|
||||
// some useful events
|
||||
/*
|
||||
void mouseMoved(wxMouseEvent& event);
|
||||
void mouseDown(wxMouseEvent& event);
|
||||
void mouseWheelMoved(wxMouseEvent& event);
|
||||
void mouseReleased(wxMouseEvent& event);
|
||||
void rightClick(wxMouseEvent& event);
|
||||
void mouseLeftWindow(wxMouseEvent& event);
|
||||
void keyPressed(wxKeyEvent& event);
|
||||
void keyReleased(wxKeyEvent& event);
|
||||
*/
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
|
@ -31,5 +31,5 @@ public:
|
|||
InitialLineState(agi::Context *c);
|
||||
|
||||
std::string const& GetInitialText() const { return initial_text; }
|
||||
DEFINE_SIGNAL_ADDERS(InitialStateChanged, AddChangeListener);
|
||||
DEFINE_SIGNAL_ADDERS(InitialStateChanged, AddChangeListener)
|
||||
};
|
||||
|
|
|
@ -40,24 +40,24 @@
|
|||
"Display" : {
|
||||
"Draw" : {
|
||||
"Cursor Time" : true,
|
||||
"Inactive Comments" : true,
|
||||
"Inactive Comments" : false,
|
||||
"Keyframes in Dialogue Mode" : true,
|
||||
"Keyframes in Karaoke Mode" : true,
|
||||
"Seconds" : false,
|
||||
"Video Position" : false
|
||||
"Seconds" : true,
|
||||
"Video Position" : true
|
||||
},
|
||||
"Waveform Style" : 0
|
||||
},
|
||||
"Downmixer" : "ConvertToMono",
|
||||
"Drag Timing" : true,
|
||||
"Inactive Lines Display Mode" : 1,
|
||||
"Inactive Lines Display Mode" : 3,
|
||||
"Karaoke" : {
|
||||
"Font Face" : "Verdana",
|
||||
"Font Size" : 9
|
||||
},
|
||||
"Lead" : {
|
||||
"IN" : 200,
|
||||
"OUT" : 300
|
||||
"IN" : 100,
|
||||
"OUT" : 350
|
||||
},
|
||||
"Line Boundaries Thickness" : 2,
|
||||
"Link" : true,
|
||||
|
@ -75,11 +75,11 @@
|
|||
}
|
||||
},
|
||||
"Snap" : {
|
||||
"Distance" : 10,
|
||||
"Enable" : false
|
||||
"Distance" : 8,
|
||||
"Enable" : true
|
||||
},
|
||||
"Spectrum" : true,
|
||||
"Start Drag Sensitivity" : 3,
|
||||
"Start Drag Sensitivity" : 8,
|
||||
"Track Cursor" : {
|
||||
"Font Face" : ""
|
||||
},
|
||||
|
@ -266,6 +266,13 @@
|
|||
},
|
||||
"Video Dummy" : {
|
||||
"Last Colour" : "rgb(47, 163, 254)"
|
||||
},
|
||||
"Visual Tools" : {
|
||||
"Highlight Primary" : "rgb(255, 169, 40)",
|
||||
"Highlight Secondary" : "rgb(255, 253, 185)",
|
||||
"Lines Primary" : "rgb(187, 0, 0)",
|
||||
"Lines Secondary" : "rgb(106, 32, 19)",
|
||||
"Shaded Area Alpha" : 0.5
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -421,7 +428,7 @@
|
|||
},
|
||||
|
||||
"Timing" : {
|
||||
"Default Duration" : 2000
|
||||
"Default Duration" : 3000
|
||||
},
|
||||
|
||||
"Tool" : {
|
||||
|
@ -545,6 +552,10 @@
|
|||
}
|
||||
},
|
||||
"Only Selection" : false,
|
||||
"Lead" : {
|
||||
"IN" : 100,
|
||||
"OUT" : 350
|
||||
},
|
||||
"Threshold" : {
|
||||
"Adjacent Gap" : 300,
|
||||
"Adjacent Overlap" : 50,
|
||||
|
@ -559,10 +570,15 @@
|
|||
"X" : -1,
|
||||
"Y" : -1
|
||||
},
|
||||
"Maximized" : false
|
||||
"Maximized" : false,
|
||||
"Skip Whitespace" : true
|
||||
},
|
||||
"Visual" : {
|
||||
"Autohide": false
|
||||
},
|
||||
"Align to Video" : {
|
||||
"Tolerance" : 20,
|
||||
"Maximized" : true
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -584,13 +600,12 @@
|
|||
"Dummy" : {
|
||||
"FPS" : 23.975999999999999091,
|
||||
"Last" : {
|
||||
"Height" : 480,
|
||||
"Height" : 720,
|
||||
"Length" : 40000,
|
||||
"Width" : 640
|
||||
"Width" : 1280
|
||||
},
|
||||
"Pattern" : false
|
||||
},
|
||||
"Force BT.601" : true,
|
||||
"Last Script Resolution Mismatch Choice" : 2,
|
||||
"Open Audio" : true,
|
||||
"Overscan Mask" : false,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue