1
0
Fork 0

Compare commits

...

213 Commits
mia ... dev

Author SHA1 Message Date
wangqr 3bde4dd751 Move coveralls to after_success in Travis CI
So it won't affect the build result
2020-07-28 17:29:51 -04:00
wangqr 533716c6c0 Add default path on Windows in FindAviSynth.cmake 2020-07-28 16:32:33 -04:00
Oneric 98abe53b15 po/de: Update German translation
Translate missing strings, defuzz (mostly) and some corrections
(hopefully without introducing new errors), like:
 - non-matching printf format strings
 - discrepancy of '...' usage or not-usage in English and German
 - Ntsc → NTSC, etc
2020-07-26 18:47:35 +02:00
wangqr 7e3a0fb926 FFMS actually can be used without cache 2020-07-20 21:38:08 -04:00
wangqr 79c2141082 Delete temporary file on close 2020-07-20 18:57:09 -04:00
wangqr a58902c938 Gracefully handle 32-bit memory limit 2020-07-20 18:31:00 -04:00
wangqr e5f543c1ab Add support for XAudio2 redistributable
Bundle XAudio2 to better support Win7

Fix wangqr/Aegisub#59
2020-07-20 16:16:20 -04:00
wangqr 940181c7bc Update po files 2020-07-17 13:18:46 -04:00
wangqr 79a71c3176 Fix syntax error in e2ea84541f 2020-07-17 12:47:06 -04:00
Oneric 4aee271d03 po/make_pot: Fix sorting and make POSIX compliant
Replaces non POSIX `echo -e` with an equivalent printf call and
fixes sorting of lua files.

This still leaves a problem with the order of old commented strings
being being reversed and there #, c-format comments being stripped.
See: https://savannah.gnu.org/bugs/?58778
2020-07-17 18:29:16 +02:00
Oneric e2ea84541f AlignToVideo: Handle tolerance = 0 correctly
Checking if the diff is '>' instead of '>=' will always fail if
tolerance=0, even if the colours are identical. This will cause the line
to get a startime greter than its end time, which is not desireable.

Rounding errors and limits of floating type precision might still affect
the comparison. An additional sanity check before calculation is added
to ensure the selected position and colour match within tolerance.
This allows us to refactor the search code to never check the starting
frame and guanrantees valid timings with start<end even with
rounding errors.
2020-07-17 18:07:18 +02:00
Oneric 7f4cdaea42 AlignToVideo: Improve rgb->lab precision 2020-07-17 17:09:05 +02:00
Oneric 26f0713aae dialog_align: Remove point at the end of the tooltips
No other tooltips end with points, even if they're a sentence.These
ones aren't even sentences.
Also updates all *.po files accordingly, with an hacked in
POT-Creation-Date due to issues with make_pot.sh.
2020-07-17 16:12:41 +02:00
Oneric b64bc3916b Readme: Fix Typo 2020-07-17 00:10:55 +02:00
wangqr e98b7292f1 Update po files 2020-07-05 15:13:38 -04:00
wangqr 971f955f1a Update README.md 2020-07-05 02:27:50 -04:00
wangqr 8dececc3cb Use millisecond in Make Adjacent step in Timing Post-Processor
Fix wangqr/Aegisub#57
2020-07-04 05:22:14 -04:00
wangqr 1e3e478f5f Disable alt drag check when setting timing values by absolute values
In AudioTimingControllerDialogue

Fix Aegisub/Aegisub#186
2020-07-02 01:58:26 -04:00
wangqr 2b827decd0 Explicitly set buffer to 24-bit color + 8-bit alpha
As wxGLCanvas does not set this for us now, even when WX_GL_RGBA is specified

Fix wangqr/Aegisub#55
2020-06-29 23:37:37 -04:00
wangqr 5f326cc873 Correctly write float header when saving WAV audio clip
Fix wangqr/Aegisub#56
2020-06-29 04:57:55 -04:00
wangqr 65ba6af0f0 Remove .. from include paths
Fix wangqr/Aegisub#52
2020-06-08 04:45:05 -04:00
wangqr b9b1443578 Remove gcc 4.7 workaround 2020-06-07 12:24:26 -04:00
wangqr af8cb9b601 Test hunspell and uchardet on Travis macOS 2020-06-07 12:09:04 -04:00
wangqr e481d033cb Prevent event queue flooded by wxEVT_PAINT by moving some repaint request to OnIdle 2020-06-05 22:34:06 -04:00
wangqr 7b69476b5b Move wxSTC::GotoPos to idle event in fonts collector dialog
wxSTC::GotoPos is CPU consuming. Calling it every time when fonts collector worker thread adds log to wxSTC causes performance issues. So we only set a flag to request go to end, and actually do it when idle.

Fix TypesettingTools/Aegisub#28
2020-06-04 10:35:14 -04:00
wangqr 51648c638b Reallocate static ranges for wxMenuItem
Previously different menus may use conflict ids in range 10000~.

Fix TypesettingTools/Aegisub#53
See also Aegisub/Aegisub#131
2020-06-03 23:49:04 -04:00
wangqr 71c940f933 Fix initial state of AudioTimingControllerDialogue
It should not be in alt-dragging mode by default.

Fix TypesettingTools/Aegisub#32
2020-06-03 20:00:54 -04:00
wangqr 809b789b61 Remove unreachable assert 2020-06-01 22:33:01 -04:00
wangqr 6028c7f6cb Set default build type to Release 2020-06-01 22:16:28 -04:00
wangqr d9e67d3b27 Use CMake pch support 2020-05-31 02:04:22 -04:00
wangqr bf241635e1 avisynthplus no longer in AUR for Archlinux 2020-05-31 00:43:20 -04:00
wangqr 95fe52aeaa Remove mysterious brackets 2020-05-31 00:41:29 -04:00
wangqr 8d03571613 Add Apply button to select lines dialog
Allow modifying selection without closing dialog.

Fix wangqr/Aegisub#49
2020-05-31 00:21:19 -04:00
wangqr 1fda1d2b05 Fix XAudio2 handle leak 2020-05-31 00:18:33 -04:00
wangqr e2430b6fca Remove vendor submodules 2020-05-29 00:55:02 -04:00
wangqr e53bdd32d7 Save state of "show original" for osx
Fix wangqr/Aegisub#47
2020-05-27 03:15:59 -04:00
wangqr 60eae86e21 Stable version of avs+ now available on arch 2020-05-21 16:23:52 -04:00
wangqr 333f928019 Save state of "show original"
Fix wangqr/Aegisub#41
2020-05-17 23:36:52 -04:00
wangqr 5e71125825 Fix Windows build with boost 1.73.0 2020-05-17 22:41:57 -04:00
wangqr 47c95e5fe5 Remove unnecessary compiler flags
Also Fix CI
2020-05-09 13:44:13 -04:00
wangqr 9d812a8aac Use standard static_assert instead of homemade macro 2020-05-09 12:21:09 -04:00
wangqr 38a0e20edc Happy new year 2020-05-07 13:43:09 -04:00
wangqr 3ec57295fd Use id instead of pos to robustly locate VisualToolDrag button 2020-05-06 21:22:53 -04:00
wangqr 47b2bfd544 Move AddSeparator to VisualTool::SetToolbar 2020-05-06 21:20:53 -04:00
wangqr 7ac2983c61 Remove redundant UpdateToggleButtons() in VisualToolDrag::OnSubTool 2020-05-06 20:24:15 -04:00
wangqr 76802c3441 Remove unnecessary Realize() when constructing Visual Tools toolbar
The Realize() will change the toolbar size on macOS, which may trigger VideoDisplay::Render and VisualToolDrag::UpdateToggleButtons. Therefore, if we want to call Realize, it must be after setting VideoDisplay::tool and calling VisualTool::SetToolbar. Otherwise, the first will cause an infinite recursion from if(!tool) condition in VideoDisplay::Render, the latter will cause NULL dereference (because VisualToolDrag::toolbar is not set yet).

On the other hand, we do not need to call Realize here at all. If the toolbar does not show, we don't need to call Realize. If the toolbar will show, then Realize will be called by VisualTool after adding their buttons, in VisualTool::SetToolbar.

So we remove the Realize() call from VideoDisplay::SetTool.

Fix wangqr/Aegisub#21
Fix wangqr/Aegisub#44
2020-05-06 20:13:04 -04:00
wangqr ac88eadd78 Use wxGenericStaticBitmap on wxOSX>=3.1.0 to get mouse event
See https://trac.wxwidgets.org/ticket/18545
Fix wangqr/Aegisub#45
2020-05-06 15:32:54 -04:00
wangqr 839dcc5aed Handle @loader_path in libboost on macOS
See wangqr/Aegisub#39
2020-05-06 13:14:06 -04:00
wangqr f501567e2d Use native color depth for audio rendering
See wangqr/Aegisub#39
2020-05-06 12:48:56 -04:00
wangqr 5dd58aca8b Add write permission before install_name_tool when doing osx-bundle
Fix wangqr/Aegisub#39
2020-04-14 10:28:15 -04:00
wangqr b92a2593cb Expand all widgets in SubsEditBox to get a consistent height 2020-04-10 09:51:08 -04:00
wangqr c1dca9cb1f Remove icon size option from Windows
Windows now always use the default size, with correct HiDPI handling
2020-04-10 00:04:06 -04:00
wangqr 55f379e229 Add required windows macro for Boost::asio 2020-04-09 22:00:19 -04:00
wangqr 76f4b3aaa2 CMake: Remove /MP to support Ninja build 2020-04-09 21:59:27 -04:00
wangqr cdebf5f3d4 Handle long path in GDI font lister 2020-04-09 11:03:23 -04:00
Ryan Lucia a281285615 Set visual tool default feature color correctly
Fixes TypesettingTools/Aegisub#50
2020-04-08 18:10:52 -04:00
wangqr 0e01f053e2 Fix touch date issue in setup.ps1 2020-04-03 22:21:38 -04:00
wangqr 638f1eb99e Detect byte order
Since uchardet does not do that for us

Fix wangqr/Aegisub#38
2020-04-03 22:21:00 -04:00
wangqr 799d96602d Fix uchardet enable macro
It should be applied to libaegisub
2020-04-03 22:19:25 -04:00
wangqr 01f6e86901 Modernize CMake (part 2) 2020-03-31 02:26:31 -04:00
wangqr c0c2a9100d Modernize CMake (part 1) 2020-03-30 20:32:16 -04:00
wangqr 5318838b93 Migrate tests/setup.bat to PowerShell
Removed set / ping hacks
2020-03-29 22:25:15 -04:00
wangqr 62708e8e5c Ensure stdcall on XAudio2 callback
Fix for x86 build
2020-03-29 22:18:49 -04:00
wangqr 4b096e6c6e Merge branch 'dev-small-changes' into dev 2020-03-20 20:15:18 -04:00
wangqr ef99ce14fd Detect iconv type at compile time instead of project generation 2020-03-20 08:03:44 -04:00
wangqr 88c486aca4 Change default audio output to XAudio2 on Windows
Downmix defaults to disabled on non-Windows OSes, because we don't support non-mono output at the moment
2020-03-20 04:13:41 -04:00
wangqr 3351235434 Move macOS specific build issue to Wiki 2020-03-14 01:00:44 -04:00
wangqr 64d0f86d8d Add git_version.h generation to CMake 2020-03-11 17:07:33 -04:00
wangqr 3394f22a93 Expand layer SpinCtrl a little
to compensate wxMac bug with GetSizeFromText
2020-03-10 01:16:28 -04:00
wangqr f71919f2ae Fix missing config option for Align on macOS 2020-03-09 21:02:33 -04:00
wangqr b6b21930fa Use homebrew addon instead of manually executing 2020-03-09 20:23:48 -04:00
wangqr 7cad0e06f9 Remove redundant email notification 2020-03-09 20:01:24 -04:00
wangqr 3096376ee6 Revert special naming for LuaJIT shared object
This was a hack on macOS when LuaJIT is dynamic only, and no longer needed as we are also using static LuaJIT on macOS now
2020-03-09 19:56:24 -04:00
wangqr 460cf9a9fd Drop support for macOS < 10.10
They are less than 2.4% in all macOS and 0.2% in all OS
2020-03-09 19:50:56 -04:00
wangqr db855e8cf5 Fix Travis warning 2020-03-09 19:47:07 -04:00
wangqr ed83c39807 Add back unit test to macOS
This reverts commit 272c2f48f1.
2020-03-09 17:36:52 -04:00
wangqr 52032dc14b Upgrade LuaJIT to 2.1.0-beta3 2020-03-09 13:01:09 -04:00
wangqr 3a50ba0386 Fix osx-fix-libs.py
Create symbolic links, to make libicu happy
Rewrite the script in python3, as python2 is deprecated
2020-03-08 19:17:53 -04:00
C.W. Betts e7b64aa741 Poke the OS X icons.
More recent versions of OS X caused the old icons to display incorrectly/as garbage.
2020-03-08 17:48:52 -04:00
wangqr 8034fbbd22 Fix missing config option 2020-03-08 03:36:46 -04:00
wangqr 272c2f48f1 Ignore unit tests on macOS for now 2020-03-08 03:24:04 -04:00
wangqr b557dfcb6e Update build instructions in README
CMake is not tested on macOS now, so don't include it in README. Be more specific on where to find dependencies.
2020-03-08 03:06:04 -04:00
wangqr 3556c9629e Remove IME handling code for Scintilla
The code was for wxCocoa, which is a dead implementation of wxWidgets. wxOSX/Cocoa does not need this hack anymore. And the code is causing linking errors due to using private structures in wxCocoa.

Revert fffb138b81
2020-03-08 01:48:58 -05:00
wangqr f8bd53c479 Add macOS to travis 2020-03-08 01:37:27 -05:00
wangqr 50f63a54d0 Rewrite build instructions 2020-03-07 20:10:45 -05:00
wangqr 6cad7c3d6c Fix build issue with AviSynth on linux 2020-03-06 16:18:52 -05:00
wangqr 6bd3f4c26b Use target name without directory in $*_OBJ macro
Fix Aegisub/Aegisub#171
2020-02-17 15:08:29 +08:00
wangqr cd7ee8d505 Use the first matched font in GDI font lister
Previously, when reading font data, we only set FaceName to the matched font. When we are using some font with special font weight (e.g. @Source Han Sans J Heavy), if we do not correct the font weight in the LOGFONTW struct, then subsequent call to get_font_data will fall back to default font. This causes wrongly matching Arial.ttf to any font that does not provide standard font weights.

Instead of only correcting FaceName using the matched font, we simply use the first matched font, thus the FaceName, Weight, CharSet, etc. will all be correct. This also eliminates the memcpy.
2020-01-05 17:12:02 -05:00
wangqr cb77c0b395 Add option to downmix FFMS audio
When enabled, restore FFMS to old behavior, downmixing auduo to S16 mono. This can reduce cache usage.

Fix wangqr/Aegisub#31
2019-12-26 17:31:59 -05:00
wangqr 80ef2fbf35 Submit "align to video" on double click
Fix wangqr/Aegisub#34
2019-12-25 18:38:42 -05:00
wangqr 20fc9043e8 Don't shrink the size of layer SpinCtrl on GTK3 2019-11-21 23:04:51 -05:00
wangqr a520f8a4a3 Rerender video display after EVT_PAINT
Otherwise the video display will be blank after restore from minimized.
2019-11-10 23:17:43 -05:00
wangqr 1bda6052b6 Use GetSizeFromText instead of GetSizeFromTextSize(GetTextExtent) 2019-11-07 16:06:53 -05:00
wangqr 557e81be1d VideoDisplay: Move render code to render callback
Previously, Render is called every time when the content is updated from event callbacks. So simply moving the mouse around will spam the event queue and cause video stuck. Now we do render in render callback, and only set a flag to indicate the need of re-render.
2019-11-04 07:03:45 -05:00
wangqr f2676ddc3a Avisynth audio provider: add option to allow no downmix 2019-11-02 22:26:02 -04:00
Charlie Jiang a2fc4bf479 🐛 Fix: lagi: Don't close iconv_t if it is iconv_invalid
When certain iconv_t is invalid, iconv_invalid(0xfffffffffffffffffffffff) will be returned. Passing it to iconv_close will cause a SIGSEGV.
2019-11-02 21:23:27 -04:00
wangqr 71894fd769 Fix bugs in ram audio provider
There was some magic bit operations to calculate the cache block offsets. This only works when both bytes_per_sample and channels are power of 2. Originally the format is assumed to be int16 mono, which satisfies this requirement. However in case we use original audio data, the channels can be something not a power of 2 (e.g. for 5.1 channel audio the number of channels is 6). This will break the calculation. We rewrite the calculation, without using those bit operations.
2019-11-02 02:26:36 -04:00
wangqr 56434c5f58 Fix bugs in separating Int16Mono and original audio
* A memory leak in FillBufferInt16Mono
* A now unnecessary assert
2019-11-02 00:41:14 -04:00
Luke Gorrie 45cd713ef9 lj_str.c: Remove special-case string interning fastpath
lj_str_new() had a separate fast-path and slow-path. This was bad
because (a) the fast-path was complex and (b) the fast-path was
actually slower than the slow-path in practice and (c) in practice it
could cause confusing performance problems depending on the memory
alignment of any often-reused string buffers in a program.

This change specifically makes the 'life' benchmark faster and more
robust to memory layout.
2019-11-02 00:23:50 -04:00
wangqr 29fd12258f Fix lint warnings about unexpected */
Introduced in b86238456f
2019-11-02 00:23:50 -04:00
wangqr b947116937 Separate XAudio2 from DirectSound in preference and CMake 2019-11-02 00:23:50 -04:00
wangqr 309996aeb2 Remove the usage of __FILE__
Prepare for reproducible build
2019-11-02 00:23:44 -04:00
wangqr 2929b9db37 XAudio2: Try orignal sound format first, and fallback to 16bit mono on failure 2019-11-01 21:58:11 -04:00
wangqr 2ca9cf0de0 Fix unit tests
As we have removed the int16 convert and downmix related stuff.
2019-11-01 04:12:35 -04:00
wangqr 0336779735 Added experimental XAudio2 audio player
Removed downsampling in FFMS2 and CreateConvertAudioProvider, to ensure we can get the original audio channels and data.

Fix Aegisub/Aegisub#160
2019-11-01 03:32:42 -04:00
wangqr b86238456f Change channels number and bytes per second to hardcoded value
Because these audio players can only handle 16bit mono anyway.
2019-10-30 01:16:28 -04:00
wangqr 620033915a Handle channel > 1 in hd & ram cache audio provider 2019-10-30 00:47:45 -04:00
wangqr c1a4e0674b Move the ConvertAudioProvider into GetInt16MonoAudio function
And use a dummy ConvertAudioProvider to keep backward compatibility.
2019-10-30 00:19:10 -04:00
wangqr 24d52bb1ee Clearly state int16 Mono of the audio provider in function name
Most code assumes the audio provider is providing int16 single channel audio data, without actually checking them. In this commit, we add a new function to provide the needed int16 mono data with checking.
2019-10-29 21:45:40 -04:00
wangqr 7c5cac0316 Remove hardcoded height of the slider
Before this the slider is only partially displayed
2019-10-28 20:45:29 -04:00
wangqr 5fc01de1e5 Fix rotation degree calculation 2019-10-28 20:21:02 -04:00
wangqr bd7a7ac551 Remove duplicated version check 2019-10-28 11:22:24 -04:00
wangqr 41c0e49813 Only expand thumb at Paint
This will give a more natural indication of where the position is. When dragging with mouse, now the thumb block will always center under the mouse position.

Fix wangqr/Aegisub#26
2019-10-26 02:44:40 -04:00
wangqr f74b3acd0e Revert "Remove unused adv dependency"
This reverts commit ea4010dcbe.
adv is required for Sash and DataViewCtrl
2019-10-17 16:40:27 -04:00
wangqr 41bb13cff2 Fix FromUTF8 usage with wxWidgets 3.0 2019-10-17 16:14:21 -04:00
wangqr f92abc863e Remove exception in destructor of agi::io::Save
Provide Close() for error handling
Correctly parse boost error code
Handle failure in TextFileWriter

Fix wangqr/Aegisub#25
2019-10-17 03:29:59 -04:00
Thomas Goyne b2be79366e Adjust the index of the drag subtool button for the addition of the separator 2019-10-16 11:10:13 -04:00
wangqr ea4010dcbe Remove unused adv dependency 2019-10-05 09:53:07 -04:00
scx 8db6c60bc3 Update desktop file
- Add Keywords
 - Add StartupWMClass
 - Update Categories
2019-09-25 17:25:38 -04:00
wangqr 0e29c8d0e4 Modify make_pot to use xgettext instead of grep
To match the change in af5060d6a3
2019-09-25 17:23:10 -04:00
wangqr 0fbcaea871 Fix make_pot.sh 2019-09-25 16:59:34 -04:00
wangqr 7c76136726 fix: infinite recursion when loading video
In 888be0607f some changes have been made to video_display.cpp which causes infinite recursion: the video display enables video/tool/cross tool when running VideoDisplay::Render() for the first time.
But when setting up the tool, the video box size is changed, which calls VideoDisplay::Render() again. So we need to set the tool BEFORE it modifies the box by "AddSeparator".

Fix wangqr/Aegisub#21

Co-authored-by: Charlie Jiang <cqjjjzr@126.com>
2019-09-23 11:58:51 -04:00
darealshinji d708f3ecd8 don't be too pedantic on the OpenAL checks 2019-09-22 20:12:00 -04:00
Yakauleu Uladzislau 22063d7e6b Added Belarusian Localization 2019-09-22 20:09:12 -04:00
wangqr 3c2414c0df Handle video flip and rotate metadata in ffms2
Fix Aegisub/Aegisub#149
2019-09-22 15:12:18 -04:00
wangqr 9c95e81784 Add gcc-9 to travis 2019-09-21 04:16:15 -04:00
wangqr 716549f2c9 Fix lagi_thes unit tests on Windows
The thes file was using \r\n line ends, and \r was not stripped, causing the encoding string has a \r at its end.
Use binary mode and always use \n as line ends.
2019-09-18 18:11:18 -04:00
wangqr d5eba08cbe Add workaround for wrong initial wxTextCtrl size in about dialog
See https://trac.wxwidgets.org/ticket/18507

Fix wangqr/Aegisub#19
2019-09-17 20:25:50 -04:00
wangqr af5060d6a3 Fix msgfmt missing LINGUAS 2019-09-15 21:06:39 -04:00
wangqr e51b93683d In Properties dialog, create the button first
So the foucus goes to the OK button on init. This will let wxWidgets correctly handle the initial position of text in wxTextCtrl

Fix wangqr/Aegisub#6
2019-09-15 19:46:53 -04:00
wangqr f1ef3d2d2c Fix PCM provider bugs 2019-09-15 19:46:43 -04:00
wangqr a4d49c66d0 Fix failing unit tests on Windows 2019-09-15 00:45:25 -04:00
wangqr 7a8e2ec816 Fix gtest setup.bat on Windows 2019-09-14 21:11:03 -04:00
wangqr 186c98308e Use gettext for desktop file instead of intltool 2019-09-13 17:59:38 -04:00
wangqr 7c500a096a Search user fonts in GDI font lister
Windows now allow user install fonts without admin. List HKCU for those fonts.
https://blogs.windows.com/windowsexperience/2018/06/27/announcing-windows-10-insider-preview-build-17704/
2019-09-13 15:49:15 -04:00
wangqr bd4c7789cf Add openal and CMake test to travis 2019-09-12 02:42:11 -04:00
wangqr 3eff75d56e In tagless_find_helper only tag before start should be ignored
The search result is irrelevant to which tag we should ignore

Fix wangqr/Aegisub#17
2019-09-11 11:29:20 -04:00
wangqr da699f124e Fix wrong memset usage 2019-09-10 02:15:48 -04:00
wangqr 1204a3be85 Cleanup CMake 2019-09-10 01:37:48 -04:00
wangqr 9e6b7e94c0 Fix crash in cache invalidation
The original version uses a reverse iterator, whose .base() is invalid after KillMacroBlock() erases it.

Fix TypesettingTools/Aegisub#33
Fix Aegisub/Aegisub#142
2019-09-08 13:01:55 -04:00
davste0816 ad02d39f44 Fix Move Down button in Export dialog 2019-09-08 11:37:52 -04:00
davste0816 d914ad72b5 Add .webm to extension list, add .eac3 as an audio format
Co-Authored-By: FichteFoll <fichtefoll2@googlemail.com>
2019-09-08 11:37:52 -04:00
davste0816 055aa379e5 Recognize .opus as an audio format, .h264 .hevc as video formats 2019-09-08 11:37:45 -04:00
wangqr 97792e15a8 Add WITH_* switchs to CMake to optional features 2019-09-08 07:12:19 -04:00
wangqr 4a874de442 Fix missing autopoint 2019-09-08 05:53:48 -04:00
scx 5d14137710 make_pot.sh: Check presence of xmlstarlet and jq 2019-09-08 04:35:05 -04:00
scx d252dcf32d Integrate AppData file with build system 2019-09-08 04:35:05 -04:00
scx 4f351b8b4a Add AppData file template 2019-09-08 04:35:05 -04:00
scx c4e0f40370 Fix compiler flags
http://devel.aegisub.org/ticket/1899
http://devel.aegisub.org/ticket/1900
https://github.com/Aegisub/Aegisub/pull/29
2019-09-08 02:25:56 -04:00
scx 05c0ba0e46 Add missing AM_GNU_GETTEXT_VERSION macro
Bug: http://devel.aegisub.org/ticket/1914
2019-09-08 02:22:51 -04:00
wangqr e4e04c9e87 Stop using deprecated hunspell API 2019-09-08 00:29:41 -04:00
wangqr 81160b2ec0 Remove conflicting glext.h 2019-09-07 22:29:23 -04:00
wangqr bf28e7efc3 Add PulseAudio to cmake 2019-09-07 12:35:27 -04:00
wangqr c2c44f1ad2 Fix build warnings
For pimpl with anonymous namespace, see https://stackoverflow.com/questions/39684438
2019-09-07 01:31:16 -04:00
wangqr 5dd201bc2d Update README.md and prepare for release 2019-09-05 22:16:58 -04:00
wangqr 3663d118b6 Separate desktop template for CMake
So it does not affect the translation
2019-09-04 22:46:29 -04:00
wangqr 60a722db31 Don't internally reset the selection after collected fonts
This creates an inconsistency between UI and internal mode.

Fix wangqr/Aegisub#10
2019-09-03 11:58:20 -04:00
wangqr d65643ddee Remove extra semicolon 2019-09-02 22:23:19 -04:00
wangqr fbca222295 Add back original travis tests 2019-09-02 22:06:41 -04:00
wangqr 3225ae39f4 Fix Makefile build
A missing header (acconf.h) issue was introduced in 34575a9786
In 419386aadd, some new source files have been added but not added to the file list in Makefile
2019-09-02 13:46:50 -04:00
wangqr 888be0607f visualSubToolBar now use same style as other toolbars
Previously visualSubToolBar has boarder while visualToolBar does not. So the width of the toolbar will change when toggling visualSubToolBar.

Now we remove the boarder so they have the same width. A separator is added at the top of visualToolBar instead to provide visual cue.

Fix wangqr/Aegisub#11
2019-09-01 22:55:13 -04:00
scx 4200b85fb4 Fix crashing when picking language
Aegisub crashes immediately after selecting any language
from the end of the list (above the 100th position).
This is because it can support no more than 100 languages.
This patch extends this limit up to 1000 languages (locales).

Fixes Aegisub/Aegisub#131
2019-09-01 19:17:35 -04:00
wangqr 0b8b286767 Fix crash on right click due to no spell checker 2019-09-01 19:15:28 -04:00
wangqr 139132a964 Use AviSynth from system 2019-09-01 19:15:21 -04:00
wangqr 4a3689d6e7 Remove the trailing period in help text of time/align
Fix wangqr/Aegisub#7
2019-08-24 02:10:08 -04:00
wangqr 248e69a9b6 Use absolute distance when scrolling audio box with mouse wheel
Instead of 1/3 screen per tick. So the distance of scroll no longer depends on the width of the audio box. Besides, 1/3 is feels to far for me when the audio box is wide.

See wangqr/Aegisub#5
2019-08-24 01:16:18 -04:00
wangqr 46474e0319 Set the height of sub box to the same as secondary_editor
The secondary_editor is a wxTextCtrl, whose height is calculated from 2 rows of text. Using this height gives better consistency on screens with different DPIs, instead of using hard coded value like 50px
2019-08-24 01:12:16 -04:00
wangqr 50544cf749 Set the height of sub box back to 50px
Revert the change made in ad15c53fb1.
As a temporary solution for wangqr/Aegisub#4.
2019-08-18 22:25:50 -04:00
wangqr e9a68f22b9 Remove the usage of dummy wxTimerEvent 2019-07-24 09:11:17 -04:00
wangqr d6ddea0f65 Detect EBML magic number to skip encoding detection for MKV
MKV loads slow after f733297499
2019-06-16 19:16:31 -04:00
wangqr 2bbed6c5a0 Load audio when video is successfully loaded
Fix bug introduced in 8f40ca44ce
2019-06-06 16:32:26 -04:00
wangqr 592250eeaa Remove call to wxSizer::CalcMin and wxSizer::RecalcSizes
As they are used internally by Layout and should not be called
directly.
2019-06-06 15:24:40 -04:00
wangqr 8f40ca44ce Try auto loading audio from video only when actually loading a video
If the user drop some files into Aegisub, we try to load sub, video,
audio, etc from them. When "Automatically open audio when opening
video" is checked in config, we try to load audio from the path of
the video. This should only be done if the video is newly loaded. So
we should never try to load audio from video if the user is just
opening a subtitle.

See https://github.com/Aegisub/Aegisub/issues/121#issuecomment-498489847
2019-06-06 14:31:07 -04:00
wangqr f776db2d2b Change the default fontsize and the list of resolutions
The default fontsize is changed to 48. While it still looks small
on the default 720p video, it is actually bigger than
    20 / 480 * 720 = 30

Here 720p is the default video resolution after 837d5a41d7. Some
common resolutions are also added to the preset list.

Fix wangqr/Aegisub#3
2019-06-03 22:08:11 -04:00
wangqr f9ffc46bf6 Add linux desktop icon 2019-05-22 20:45:51 -04:00
wangqr 019e68147e Fix FFT first sample location
Fix wangqr/Aegisub#1
2019-05-22 20:10:09 -04:00
wangqr f733297499 Rewrite encoding detection
Now feeds all data to uchardet, when uchardet is available. The file
size limit is removed.

When uchardet is not available, we look for UTF-8 BOM.
This should make loading UTF-8-BOM files faster.
Because Aegisub always save file in UTF-8-BOM, this should also
guarentee Aegisub will load large (>100MB) file saved by itself.

See Aegisub/Aegisub#110
2019-05-18 22:13:26 -04:00
wangqr 4c6d370d51 Add install target 2019-05-18 20:10:18 -04:00
wangqr b7c640d061 Fix High DPI issue on GTK
* Use icon size in the config
2019-05-17 13:58:14 -04:00
wangqr 2c06f03f5b Add AviSynth support 2019-05-16 11:07:57 -04:00
wangqr 1819fc8d8b Fix iconv ConversionFailure on long path 2019-05-16 11:04:53 -04:00
wangqr ba54e8d12f Fix build warnings 2019-05-11 21:36:34 -04:00
Ryan Lucia c76e410d30 Divorce stored TPP lead-in/out values from config
There's no real reason to link these as far as I can tell, and plenty of
valid reasons not to
2019-05-11 20:04:29 -04:00
Ryan Lucia bb2cfb1fcd Properly ignore ASS whitespace characters in character counter 2019-05-11 20:00:49 -04:00
Ryan Lucia 9abcc03202 Add configuration options for colors in visual typesetting tools 2019-05-11 19:43:54 -04:00
Ryan Lucia 837d5a41d7 Update default config to modern standards 2019-05-11 19:38:10 -04:00
Ryan Lucia 875456c803 Use FFMS2 constant in place of magic number 2019-05-10 15:22:26 -04:00
Ryan Lucia 9ddecfdd46 Ignore VS build files
Most files were moved to .vs directory with VS15
2019-05-10 15:17:19 -04:00
Ryan Lucia 70f27eae4b Pass 0 to FFMS_Init
The argument is no longer used, and the docs specify to pass a value of 0 to avoid confusion
2019-05-10 15:12:55 -04:00
Ryan Lucia 8d2ef3fca7 Point users at a functional bug tracker 2019-05-10 15:09:25 -04:00
Ryan Lucia 48869ae0ad Fix line order when splitting after current frame 2019-05-10 15:09:05 -04:00
Ryan Lucia b00285cf71 Use proper event for DoubleUpdater
Previously changes weren't recognized because the event bound was for integers
2019-05-10 15:06:01 -04:00
Ryan Lucia c6c9e05406 Remove dead forums link 2019-05-10 15:05:18 -04:00
Ryan Lucia fc1a78aeca Make translation assistant skipping whitespace an explicit setting 2019-05-10 15:04:48 -04:00
Ryan Lucia 38bb1790ab Remove Force BT.601 option and update color matrix guessing 2019-05-10 15:03:20 -04:00
Ryan Lucia fff08c4650 Add support for setting status bar text from Lua 2019-05-10 14:54:05 -04:00
wangqr 163d57d6a2 Fix LuaJIT segfault 2019-05-09 21:36:11 -04:00
wangqr 6266867586 Fix errors in AlignToVideo
* Call TimeAtFrame with correct parameter
* Fix syntax error
2019-05-09 16:54:20 -04:00
wangqr 4431f678ce Update about dialog 2019-05-09 16:30:38 -04:00
Charlie Jiang 419386aadd Merge remote-tracking branch 'origind-dev/master'
Add align to video function
2019-05-09 16:26:08 -04:00
wangqr c4cce28766 Update README to use CMake 2019-05-08 22:49:53 -04:00
wangqr 1ae2f60b9a Fix CMake build errors 2019-05-08 17:09:29 -04:00
wangqr b6eebcd7ef Fix build warnings 2019-05-08 17:09:07 -04:00
wangqr bf55264e6d Fix VS2019 compile issues 2019-05-08 16:34:53 -04:00
wangqr 34575a9786 Migrate to CMake to update packages easier 2019-05-08 16:34:39 -04:00
wangqr 69310d40ae Correctly handle memory free using Lua GC
Instead of manually free. Otherwise return value of `search' may refer to invalid memory.
Fix Aegisub/Aegisub#99
2019-03-15 00:01:29 -04:00
wangqr 657d9d5149 Bump boost version to 1.69.0
Fix Aegisub/Aegisub#93
2019-03-14 23:58:28 -04:00
wangqr 043a45cf91 Add DPI aware to Aegisub manifest 2018-12-08 01:20:08 -05:00
wangqr ad15c53fb1 Add DPI awareness
* Removed most hard coded wxSize
* Sub edit box now have DPI aware icons
2018-12-08 01:20:08 -05:00
wangqr 841a35a6fd Fix overflow bound 2018-12-08 01:20:08 -05:00
wangqr ee7dc6af4e Fix millisecond to centisecond convertion
Fix Aegisub/Aegisub#94
2018-12-08 01:20:08 -05:00
wangqr 77da2436c5 Change some text box size to make it looks better on HiDPI 2018-12-08 01:20:08 -05:00
wangqr 7be2325629 Fix travis-ci build script 2018-12-08 00:48:00 -05:00
776 changed files with 251450 additions and 346125 deletions

6
.gitignore vendored
View File

@ -5,6 +5,7 @@
*.bz2
*.cache
*.dep
*.db
*.dll
*.dmg
*.exe
@ -14,13 +15,13 @@
*.ilk
*.log
*.manifest
!src/dpi_aware.manifest
*.mkv
*.mo
*.ncb
*.obj
*.opensdf
*.orig
*.patch
*.pch
*.pdb
*.profdata
@ -63,6 +64,8 @@ git_version.h
git_version.xml
packages/desktop/aegisub.desktop
packages/desktop/aegisub.desktop.template
packages/desktop/aegisub.appdata.xml
packages/desktop/aegisub.appdata.xml.template
src/aegisub
src/libresrc/bitmap.cpp
src/libresrc/bitmap.h
@ -86,3 +89,4 @@ vendor/luajit/src/lj_vm.s
vendor/luajit/src/luajit
.nuget
.vs

38
.gitmodules vendored
View File

@ -1,42 +1,4 @@
[submodule "freetype2"]
path = vendor/freetype2
url = git://git.sv.nongnu.org/freetype/freetype2.git
ignore = dirty
[submodule "wxWidgets"]
path = vendor/wxWidgets
url = git://github.com/Aegisub/wxWidgets.git
ignore = dirty
[submodule "googletest"]
path = vendor/googletest
url = git://github.com/svn2github/googletest.git
ignore = dirty
[submodule "ffmpeg"]
path = vendor/ffmpeg
url = git://source.ffmpeg.org/ffmpeg.git
ignore = dirty
[submodule "ffms2"]
path = vendor/ffms2
url = git://github.com/FFMS/ffms2.git
branch = master
ignore = dirty
[submodule "libass"]
path = vendor/libass
url = git://github.com/libass/libass.git
branch = master
[submodule "icu"]
path = vendor/icu
url = git://github.com/svn2github/icu4c.git
branch = master
ignore = dirty
[submodule "boost"]
path = vendor/boost
url = https://github.com/boostorg/boost.git
ignore = dirty
[submodule "fftw"]
path = vendor/fftw
url = https://github.com/Aegisub/fftw3.git
ignore = dirty
[submodule "uchardet"]
path = vendor/uchardet
url = https://github.com/BYVoid/uchardet
ignore = dirty

View File

@ -1,5 +1,5 @@
sudo: required
dist: trusty
os: linux
dist: bionic
language: cpp
git:
@ -8,61 +8,97 @@ git:
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa: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
- gcc-10
- g++-10
- python3-pip
- python3-setuptools
homebrew:
packages:
- autoconf
- boost
- ffmpeg
- ffms2
- fftw
- freetype
- fribidi
- gettext
- icu4c
- libass
- lua
- luarocks
- m4
- wxmac
- hunspell
- uchardet
update: true
matrix:
env:
- ''
- BUILD_SUIT=autotools WITH_COVERALLS=y
- CC=gcc-10 CXX=g++-10
- BUILD_SUIT=autotools CC=gcc-10 CXX=g++-10
jobs:
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
- os: osx
osx_image: xcode11.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 ../..
- ./.travis/install.sh
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
notifications:
email:
- on_success: change
- on_failure: change
- if [ "$TRAVIS_OS_NAME" = 'osx' ]; then
export PATH="/usr/local/opt/gettext/bin:/usr/local/opt/icu4c/sbin:/usr/local/opt/icu4c/bin:$PATH";
export CPPFLAGS="-I/usr/local/opt/gettext/include -I/usr/local/opt/icu4c/include";
export LDFLAGS="-L/usr/local/opt/gettext/lib -L/usr/local/opt/icu4c/lib";
export ACLOCAL_PATH="/usr/local/opt/gettext/share/aclocal";
export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig";
./autogen.sh;
./configure --enable-debug || cat config.log;
make -j2 || travis_terminate 1;
make test || travis_terminate 1;
elif [ "$BUILD_SUIT" = 'autotools' ]; then
if [ ! -z "$WITH_COVERALLS" ]; then
export CPPFLAGS="--coverage";
export LIBS="-lgcov";
fi;
./autogen.sh;
./configure --enable-debug || cat config.log;
make -j2 || travis_terminate 1;
make test || travis_terminate 1;
else
mkdir build-dir;
cd build-dir;
cmake -DCMAKE_CXX_FLAGS='-Wall -Wextra -Wno-unused-parameter -pedantic' -DCMAKE_C_FLAGS='-Wall -Wextra -Wno-unused-parameter' -DWITH_STARTUPLOG=ON -DWITH_TEST=ON ..;
make -j2 || travis_terminate 1;
make test || travis_terminate 1;
fi
after_success:
- if [ ! -z "$WITH_COVERALLS" ]; then
coveralls --exclude vendor --exclude src --exclude build --exclude tools --exclude libaegisub/windows > /dev/null;
fi

23
.travis/install.sh Executable file
View File

@ -0,0 +1,23 @@
#! /bin/bash
set -e
if [ "$TRAVIS_OS_NAME" = 'linux' ]; then
# Remove the CMake provided by travis
sudo rm -rf /usr/local/cmake*
if [ "$BUILD_SUIT" = 'autotools' ]; then
if [ ! -z "$WITH_COVERALLS" ]; then
sudo pip3 install -U cpp-coveralls
fi
git submodule --quiet init
git submodule --quiet update vendor/googletest
else
pushd /usr/src/googletest
sudo cmake .
sudo make install -j2
popd
fi
fi
sudo luarocks install busted > /dev/null
sudo luarocks install moonscript > /dev/null
sudo luarocks install uuid > /dev/null

76
CMakeLists.test.txt Normal file
View File

@ -0,0 +1,76 @@
if(UNIX)
add_executable(aegisub-lua EXCLUDE_FROM_ALL
automation/tests/aegisub.cpp
)
target_link_libraries(aegisub-lua PRIVATE libaegisub luabins luajit "Boost::locale")
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 "${PROJECT_SOURCE_DIR}/tests/support")
target_link_libraries(gtest-run PRIVATE libaegisub "Boost::filesystem" "GTest::GTest" "Iconv::Iconv")
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)

786
CMakeLists.txt Normal file
View File

@ -0,0 +1,786 @@
cmake_minimum_required(VERSION 3.16)
cmake_policy(SET CMP0074 NEW)
project(Aegisub)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
# Explicitly set the build type to Release if no other type is specified
# on the command line. Without this, cmake defaults to an unoptimized,
# non-debug build, which almost nobody wants.
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
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 "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/buildvm_arch.h"
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen"
COMMAND luajit-minilua ../dynasm/dynasm.lua -LN -D WIN -D JIT -D FFI -D P64 -o "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/buildvm_arch.h" vm_x86.dasc
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
)
else()
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/buildvm_arch.h"
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen"
COMMAND luajit-minilua ../dynasm/dynasm.lua -LN -D WIN -D JIT -D FFI -o "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/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 "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/buildvm_arch.h"
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen"
COMMAND luajit-minilua ../dynasm/dynasm.lua -D P64 -D JIT -D FFI -D FPU -D HFABI -D VER= -o "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/buildvm_arch.h" vm_x86.dasc
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
)
else()
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/buildvm_arch.h"
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen"
COMMAND luajit-minilua ../dynasm/dynasm.lua -D JIT -D FFI -D FPU -D HFABI -D VER= -o "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/buildvm_arch.h" vm_x86.dasc
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
)
endif()
endif()
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
"${CMAKE_CURRENT_BINARY_DIR}/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 "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen")
if(UNIX)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/lj_vm.s"
COMMAND luajit-buildvm -m elfasm -o "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/lj_vm.s"
)
elseif(MSVC)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/lj_vm.obj"
COMMAND luajit-buildvm -m peobj -o "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/lj_vm.obj"
)
endif()
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/lj_ffdef.h"
COMMAND luajit-buildvm -m ffdef -o "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/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 "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/lj_bcdef.h"
COMMAND luajit-buildvm -m bcdef -o "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/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 "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/lj_folddef.h"
COMMAND luajit-buildvm -m folddef -o "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/lj_folddef.h" lj_opt_fold.c
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/lj_recdef.h"
COMMAND luajit-buildvm -m recdef -o "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/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 "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/lj_libdef.h"
COMMAND luajit-buildvm -m libdef -o "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/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 "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/jit/vmdef.lua"
COMMAND luajit-buildvm -m vmdef -o "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/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
"${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/lj_ffdef.h"
"${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/lj_bcdef.h"
"${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/lj_folddef.h"
"${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/lj_recdef.h"
"${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen/lj_libdef.h"
# "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/jit/vmdef.lua"
)
target_compile_definitions(luajit PRIVATE LUAJIT_ENABLE_LUA52COMPAT)
target_include_directories(luajit PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/gen" PUBLIC "vendor/luajit/src")
if(WIN32)
target_sources(luajit PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/lj_vm.obj")
else()
target_sources(luajit PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/lj_vm.s")
set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/vendor/luajit/src/lj_vm.s" PROPERTY LANGUAGE C)
target_link_libraries(luajit ${CMAKE_DL_LIBS})
endif()
add_subdirectory(vendor/luabins)
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)
target_include_directories(libaegisub PUBLIC "libaegisub/include")
target_precompile_headers(libaegisub PRIVATE "libaegisub/lagi_pre.h")
target_link_libraries(libaegisub PRIVATE luajit luabins)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/default_config.cpp" "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/default_config.h"
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/default_config_platform.json"
COMMAND luajit-minilua "${PROJECT_SOURCE_DIR}/tools/respack.lua" manifest.respack default_config.cpp default_config.h
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc"
)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/bitmap.cpp" "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/bitmap.h"
COMMAND luajit-minilua ../../tools/respack.lua manifest.respack "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/bitmap.cpp" "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/bitmap.h"
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bitmaps
)
add_subdirectory("vendor/csri")
add_executable(Aegisub WIN32
"${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/bitmap.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/default_config.h"
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
"${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/bitmap.cpp"
"${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/default_config.cpp"
src/libresrc/libresrc.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 PRIVATE ${CMAKE_DL_LIBS} libaegisub luajit)
target_compile_definitions(Aegisub PRIVATE CMAKE_BUILD)
target_include_directories(Aegisub PRIVATE "src/libresrc" "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc")
target_precompile_headers(Aegisub PRIVATE "src/agi_pre.h")
if(WIN32)
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/build/git_version.h")
message(SEND_ERROR
"build/git_version.h not found.\n"
"Automatic generation of build/git_version.h is not supported on Windows. Please run\n"
" build/version.sh .\n"
"at the source directory from an environment with bash and git. You may use WSL, msys (git bash), or Cygwin."
)
else()
target_include_directories(Aegisub PRIVATE "build")
endif()
else()
add_custom_target(git_version build/version.sh .
BYPRODUCTS "${PROJECT_SOURCE_DIR}/build/git_version.h" "${PROJECT_SOURCE_DIR}/build/git_version.xml"
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
)
add_dependencies(Aegisub git_version)
target_include_directories(Aegisub PRIVATE "build")
endif()
option(WITH_BUILD_CREDIT "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)
add_definitions("/DNOMINMAX /DINITGUID")
target_link_libraries(Aegisub LINK_PRIVATE 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)
endif()
if(WIN32)
target_sources(Aegisub PRIVATE src/font_file_lister_gdi.cpp)
else()
find_package(Fontconfig REQUIRED)
target_link_libraries(Aegisub PRIVATE "Fontconfig::Fontconfig")
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 LINK_PRIVATE ${ass_LIBRARIES})
find_package(Boost REQUIRED container filesystem locale regex thread)
target_link_libraries(libaegisub PRIVATE "Boost::locale" "Boost::regex" "Boost::thread")
target_link_libraries(libaegisub PUBLIC "Boost::headers" "Boost::container" "Boost::filesystem")
target_link_libraries(Aegisub PRIVATE "Boost::headers" "Boost::container" "Boost::filesystem" "Boost::locale" "Boost::regex")
find_package(OpenGL REQUIRED)
target_link_libraries(Aegisub PRIVATE "OpenGL::GL")
find_package(Iconv REQUIRED)
target_link_libraries(libaegisub PRIVATE "Iconv::Iconv")
find_package(ICU REQUIRED uc)
target_link_libraries(libaegisub PRIVATE "ICU::uc")
target_link_libraries(Aegisub PRIVATE "ICU::uc")
find_package(wxWidgets REQUIRED adv base core gl stc xml)
include(${wxWidgets_USE_FILE})
target_link_libraries(Aegisub LINK_PRIVATE ${wxWidgets_LIBRARIES})
find_package(ZLIB REQUIRED)
target_link_libraries(Aegisub PRIVATE "ZLIB::ZLIB")
find_package(ALSA)
option(WITH_ALSA "Enable ALSA support" ${ALSA_FOUND})
if(WITH_ALSA)
find_package(ALSA REQUIRED)
target_compile_definitions(Aegisub PRIVATE "WITH_ALSA")
target_link_libraries(Aegisub PRIVATE "ALSA::ALSA")
target_sources(Aegisub PRIVATE src/audio_player_alsa.cpp)
endif()
find_package(AviSynth)
option(WITH_AVISYNTH "Enable AviSynth support" ${AviSynth_FOUND})
if(WITH_AVISYNTH)
find_package(AviSynth REQUIRED)
target_compile_definitions(Aegisub PRIVATE "WITH_AVISYNTH")
target_include_directories(Aegisub PRIVATE ${AviSynth_INCLUDE_DIRS})
if(WIN32)
target_link_libraries(Aegisub LINK_PRIVATE Vfw32)
endif()
get_filename_component(Avisynth_LIBRARY_NAME "${AviSynth_SHARED_LIBRARY}" NAME CACHE)
target_compile_definitions(Aegisub PRIVATE "AVISYNTH_SO=\"${Avisynth_LIBRARY_NAME}\"")
target_sources(Aegisub PRIVATE src/audio_provider_avs.cpp src/avisynth_wrap.cpp src/video_provider_avs.cpp)
endif()
option(WITH_CSRI "Enable CSRI support" ON)
if(WITH_CSRI)
target_compile_definitions(Aegisub PRIVATE "WITH_CSRI")
target_link_libraries(Aegisub PRIVATE csri)
target_sources(Aegisub PRIVATE src/subtitles_provider_csri.cpp)
endif()
if(WIN32)
option(WITH_DIRECTSOUND "Enable DirectSound support" ON)
if(WITH_DIRECTSOUND)
target_compile_definitions(Aegisub PRIVATE "WITH_DIRECTSOUND")
target_link_libraries(Aegisub LINK_PRIVATE dsound)
target_sources(Aegisub PRIVATE src/audio_player_dsound.cpp src/audio_player_dsound2.cpp)
endif()
option(WITH_XAUDIO2 "Enable XAudio2 support" ON)
if(WITH_XAUDIO2)
target_compile_definitions(Aegisub PRIVATE "WITH_XAUDIO2")
target_sources(Aegisub PRIVATE src/audio_player_xaudio2.cpp)
option(XAUDIO2_REDIST "Use XAudio redistributable")
if(XAUDIO2_REDIST)
find_package(XAudio2redist REQUIRED)
target_compile_definitions(Aegisub PRIVATE "XAUDIO2_REDIST")
target_include_directories(Aegisub PRIVATE ${XAudio2redist_INCLUDE_DIRS})
target_link_libraries(Aegisub PRIVATE ${XAudio2redist_LIBRARIES})
endif()
endif()
else()
set(WITH_DIRECTSOUND OFF)
set(WITH_XAUDIO2 OFF)
endif()
find_package(FFMS2)
option(WITH_FFMS2 "Enable FFMS2 support" ${FFMS2_FOUND})
if(WITH_FFMS2)
find_package(FFMS2 REQUIRED)
target_compile_definitions(Aegisub PRIVATE "WITH_FFMS2")
target_include_directories(Aegisub PRIVATE ${FFMS2_INCLUDE_DIRS})
target_link_libraries(Aegisub LINK_PRIVATE ${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()
find_package(FFTW)
option(WITH_FFTW3 "Enable fftw support" ${FFTW_FOUND})
if(WITH_FFTW3)
find_package(FFTW REQUIRED)
target_compile_definitions(Aegisub PRIVATE "WITH_FFTW3")
target_include_directories(Aegisub PRIVATE ${FFTW_INCLUDES})
target_link_libraries(Aegisub LINK_PRIVATE ${FFTW_LIBRARIES})
endif()
find_package(Hunspell)
option(WITH_HUNSPELL "Enable Hunspell support" ${HUNSPELL_FOUND})
if(WITH_HUNSPELL)
find_package(Hunspell REQUIRED)
target_compile_definitions(Aegisub PRIVATE "WITH_HUNSPELL")
target_link_libraries(Aegisub PRIVATE "hunspell")
target_sources(Aegisub PRIVATE src/spellchecker_hunspell.cpp)
endif()
find_package(PulseAudio)
option(WITH_LIBPULSE "Enable PulseAudio support" ${PULSEAUDIO_FOUND})
if(WITH_LIBPULSE)
find_package(PulseAudio REQUIRED)
target_compile_definitions(Aegisub PRIVATE "WITH_LIBPULSE")
target_include_directories(Aegisub PRIVATE ${PULSEAUDIO_INCLUDE_DIR})
target_link_libraries(Aegisub LINK_PRIVATE ${PULSEAUDIO_LIBRARY})
target_sources(Aegisub PRIVATE src/audio_player_pulse.cpp)
endif()
find_package(OpenAL)
option(WITH_OPENAL "Enable OpenAL support" ${OPENAL_FOUND})
if(WITH_OPENAL)
find_package(OpenAL REQUIRED)
target_compile_definitions(Aegisub PRIVATE "WITH_OPENAL")
target_include_directories(Aegisub PRIVATE ${OPENAL_INCLUDE_DIR})
target_link_libraries(Aegisub LINK_PRIVATE ${OPENAL_LIBRARY})
target_sources(Aegisub PRIVATE src/audio_player_openal.cpp)
endif()
find_package(OSS)
option(WITH_OSS "Enable OSS support" ${OSS_FOUND})
if(WITH_OSS)
find_package(OSS REQUIRED)
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()
find_package(PortAudio)
option(WITH_PORTAUDIO "Enable PortAudio support" ${PortAudio_FOUND})
if(WITH_PORTAUDIO)
find_package(PortAudio REQUIRED)
target_compile_definitions(Aegisub PRIVATE "WITH_PORTAUDIO")
target_include_directories(Aegisub PRIVATE ${PortAudio_INCLUDE_DIRS})
target_link_libraries(Aegisub LINK_PRIVATE ${PortAudio_LIBRARIES})
target_sources(Aegisub PRIVATE src/audio_player_portaudio.cpp)
endif()
option(WITH_STARTUPLOG "Enable startup log")
if(WITH_STARTUPLOG)
target_compile_definitions(Aegisub PRIVATE "WITH_STARTUPLOG")
endif()
find_package(uchardet)
option(WITH_UCHARDET "Enable uchardet support" ${uchardet_FOUND})
if(WITH_UCHARDET)
find_package(uchardet REQUIRED)
target_compile_definitions(libaegisub PRIVATE "WITH_UCHARDET")
target_include_directories(libaegisub PRIVATE ${uchardet_INCLUDE_DIRS})
target_link_libraries(libaegisub PRIVATE ${uchardet_LIBRARIES})
endif()
option(WITH_UPDATE_CHECKER "Enable update checker")
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_sources(Aegisub PRIVATE src/dialog_version_check.cpp)
endif()
if(WIN32)
if(WITH_XAUDIO2)
set(DEFAULT_PLAYER_AUDIO "XAudio2" CACHE STRING "Default audio player")
elseif(WITH_DIRECTSOUND)
set(DEFAULT_PLAYER_AUDIO "DirectSound" 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 enable one of these audio players:\n"
" - XAudio2\n"
" - DirectSound\n"
"\n"
)
set(DEFAULT_PLAYER_AUDIO "NONE" CACHE STRING "Default audio player")
endif()
configure_file("src/libresrc/default_config_win.json.in" "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/default_config_platform.json" @ONLY)
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()
configure_file("src/libresrc/default_config_platform.json.in" "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/default_config_platform.json" @ONLY)
endif()
configure_file("src/libresrc/default_config.json" "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/default_config.json" COPYONLY)
configure_file("src/libresrc/default_hotkey.json" "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/default_hotkey.json" COPYONLY)
configure_file("src/libresrc/default_menu.json" "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/default_menu.json" COPYONLY)
configure_file("src/libresrc/default_mru.json" "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/default_mru.json" COPYONLY)
configure_file("src/libresrc/default_toolbar.json" "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/default_toolbar.json" COPYONLY)
configure_file("src/libresrc/manifest.respack" "${CMAKE_CURRENT_BINARY_DIR}/src/libresrc/manifest.respack" COPYONLY)
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"
" XAudio2: ${WITH_XAUDIO2}\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"
)

View File

@ -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/
@ -103,10 +104,6 @@ LIBS_PORTAUDIO = @PORTAUDIO_LIBS@
LIBS_PTHREAD = @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
LIBS_UCHARDET = @UCHARDET_LIBS@
ifeq (yes, $(BUILD_DARWIN))
LIBS_LUA = $(TOP)vendor/luajit/src/libluajit-aegisub.so
endif
FONTCONFIG_CONF_DIR = @FONTCONFIG_CONF_DIR@
#####################

View File

@ -5,9 +5,9 @@ COMMANDS := all install clean distclean test depclean osx-bundle osx-dmg test-au
# Would be nice to move this somewhere else (Makefile.inc?)
ifeq (yes, $(BUILD_DARWIN))
CFLAGS += -mmacosx-version-min=10.8 -gfull
CXXFLAGS += -mmacosx-version-min=10.8 -gfull
LDFLAGS += -mmacosx-version-min=10.8 -Wl,-dead_strip -pagezero_size 10000 -image_base 100000000
CFLAGS += -mmacosx-version-min=10.10 -gfull -DLUAJIT_ENABLE_GC64
CXXFLAGS += -mmacosx-version-min=10.10 -gfull -DLUAJIT_ENABLE_GC64
LDFLAGS += -mmacosx-version-min=10.10 -Wl,-dead_strip
LIB_SHARED_LINK = $(LIB_SHARED_LINK_OSX)
endif
@ -112,7 +112,7 @@ POST_FLAGS = $($@_FLAGS) -c -o $@ $<
# Libraries contain all object files they depend on (but they may depend on other files)
# Not using libtool on OS X because it has an unsilenceable warning about a
# compatibility issue with BSD 4.3 (wtf)
lib%.a: $$($$*_OBJ)
lib%.a: $$($$(*F)_OBJ)
@$(BIN_MKDIR_P) $(dir $@)
$(BIN_AR) cru $@ $(filter %.o,$^)
$(BIN_RANLIB) $@

117
README.md
View File

@ -1,85 +1,76 @@
[![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).
For binaries and general information see [the homepage](http://www.aegisub.org) and [release page](https://github.com/wangqr/Aegisub/releases).
The bug tracker can be found at http://devel.aegisub.org.
The bug tracker can be found at https://github.com/wangqr/Aegisub/issues .
Support is available on [the forums](http://forum.aegisub.org) or [on IRC](irc://irc.rizon.net/aegisub).
If you want to test the upstream version, r8942 [can be downloaded here](http://www.plorkyeran.com/aegisub/). If both r8942 and this fork have some common issue, report at [upstream](https://github.com/Aegisub/Aegisub/issues) may let more people see your issue, and I am also watching the upstream for issues. If it is a wangqr fork specific issue, report it here.
Support is available on IRC ( irc://irc.rizon.net/aegisub , for upstream version) or via issues.
## Building Aegisub
### Windows
### autoconf / make (for linux and macOS)
Prerequisites:
This is the recommended way of building Aegisub on linux and macOS. Currently AviSynth+ support is not included in autoconf project. If you need AviSynth+ support, see CMake instructions below.
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.
Aegisub has some required dependencies:
* `libass`
* `Boost`(with ICU support)
* `OpenGL`
* `libicu`
* `wxWidgets`
* `zlib`
* `fontconfig` (not needed on Windows)
* `luajit` (or `lua`)
There are a few optional dependencies:
and optional dependencies:
* `ALSA`
* `FFMS2`
* `FFTW`
* `Hunspell`
* `OpenAL`
* `uchardet`
* `AviSynth+`
1. msgfmt, to build the translations
2. WinRAR, to build the portable installer
3. InnoSetup, to build the regular installer
You can use the package manager provided by your distro to install these dependencies. Package name varies by distro. Some useful references are:
All other dependencies are either stored in the repository or are included as submodules.
* For ArchLinux, refer to [AUR](https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=aegisub-git).
* For Ubuntu, refer to [Travis](.travis.yml#L14-L32).
* For macOS, see [Special notice for macOS](https://github.com/wangqr/Aegisub/wiki/Special-notice-for-macOS) on project Wiki.
Building:
After installing the dependencies, you can clone and build Aegisub with:
```sh
git clone https://github.com/wangqr/Aegisub.git
cd Aegisub
./autogen.sh
./configure
make
```
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.
### CMake (for Windows and linux)
You should now have a `bin` directory in your Aegisub directory which contains `aegisub32d.exe`, along with a pile of other files.
This fork also provides CMake build. The CMake project will only build Aegisub itself, without the translation.
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.
You still need to install the dependencies above. To enable AviSynth+ support, it is also needed. Installing dependencies on Windows can be tricky, as Windows doesn't have a good package manager. Refer to [the Wiki page](https://github.com/wangqr/Aegisub/wiki/Compile-guide-for-Windows-(CMake,-MSVC)) on how to get all dependencies on Windows.
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.
After installing the dependencies, you can clone and build Aegisub with:
### OS X
```sh
git clone https://github.com/wangqr/Aegisub.git
cd Aegisub
./build/version.sh . # This will generate build/git_version.h
mkdir build-dir
cd build-dir
cmake .. # Or use cmake-gui / ccmake
make
```
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.
Features can be turned on/off in CMake by toggling the `WITH_*` switches.
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`.
For Archlinux users, you can also try the [PKGBUILD in project wiki](https://github.com/wangqr/Aegisub/wiki/PKGBUILD-for-Arch).
## Updating Moonscript
@ -95,4 +86,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.

View File

@ -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) ->

View File

@ -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;

View File

@ -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
---

View File

@ -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 -->

31
cmake/FindAviSynth.cmake Normal file
View File

@ -0,0 +1,31 @@
find_package(PkgConfig QUIET)
pkg_check_modules(PC_AviSynth QUIET avisynth)
find_path(AviSynth_INCLUDE_DIRS
NAMES avisynth.h
PATHS "C:/Program Files/AviSynth+/FilterSDK/include" "C:/Program Files (x86)/AviSynth+/FilterSDK/include"
PATH_SUFFIXES avisynth
HINTS ${PC_AviSynth_INCLUDE_DIRS}
)
if(WIN32)
find_file(AviSynth_SHARED_LIBRARY
NAMES AviSynth.dll
PATHS "C:/Windows/System32/"
PATH_SUFFIXES c_api
HINTS ${PC_AviSynth_LIBRARY_DIRS}
)
else()
find_library(AviSynth_SHARED_LIBRARY
NAMES avisynth
PATH_SUFFIXES c_api
HINTS ${PC_AviSynth_LIBRARY_DIRS}
)
endif()
set(AviSynth_VERSION ${PC_AviSynth_VERSION})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(AviSynth
FOUND_VAR AviSynth_FOUND
REQUIRED_VARS
AviSynth_SHARED_LIBRARY
AviSynth_INCLUDE_DIRS
VERSION_VAR AviSynth_VERSION
)

19
cmake/FindFFMS2.cmake Normal file
View 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
View 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)

66
cmake/FindHunspell.cmake Normal file
View File

@ -0,0 +1,66 @@
# - 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 )
if(NOT TARGET hunspell)
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 ()
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)
if (HUNSPELL_HAS_STRING_API)
message(STATUS "Hunspell has string API")
set_target_properties(hunspell PROPERTIES INTERFACE_COMPILE_DEFINITIONS 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
View 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
View 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
)

View 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)

View File

@ -0,0 +1,13 @@
find_path(XAudio2redist_INCLUDE_DIRS
NAMES xaudio2redist.h
)
find_library(XAudio2redist_LIBRARIES
NAMES xaudio2_9redist
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(XAudio2redist
FOUND_VAR XAudio2redist_FOUND
REQUIRED_VARS
XAudio2redist_LIBRARIES
XAudio2redist_INCLUDE_DIRS
)

20
cmake/Findass.cmake Normal file
View 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
View 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
)

View 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;
}

View File

@ -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,16 @@ 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"
# For mac compiler which still stuck on c++98
AC_CXX_FLAG([-std=c++11])
AC_CXX_FLAG([-Wno-c++11-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"
])
])
@ -267,20 +270,6 @@ AC_SUBST(ICONV_CFLAGS)
AS_IF([test x$agi_cv_with_iconv = xno], [AC_MSG_FAILURE([Please install a working iconv library.])])
AC_AGI_COMPILE([iconv (const)], [iconv_const], [$ICONV_CFLAGS], [$ICONV_LIBS],[
#include <iconv.h>
int main(void) {
iconv_t cd = iconv_open("UTF-16", "UTF-8");
const char *in = "in";
char *out = new char();
size_t res, inbytesleft, outbytesleft;
res = iconv(cd, &in, &inbytesleft, &out, &outbytesleft);
return 0;
} ])
AS_IF([test x$agi_cv_with_iconv_const = xyes],
[AC_DEFINE(AGI_ICONV_CONST, 1, [Enable if iconv expects the in argument to be const])])
###############
# Audio Players
###############
@ -334,9 +323,9 @@ AS_IF([test x$with_openal != xno], [
#endif
int main(void) {
ALCdevice *device = alcOpenDevice(0);
if (!device) return 1;
ALCcontext *context = alcCreateContext(device, 0);
if (!context) return 1;
alcDestroyContext(context);
alcCloseDevice(device);
return 0;
} ])
])
@ -426,7 +415,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 +494,7 @@ AC_PCH_FLAG([-fpch-preprocess])
# Internationalisation support
##############################
AM_GNU_GETTEXT([external])
AM_GNU_GETTEXT_VERSION([0.19.7])
################
# Update checker
@ -564,6 +554,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

View File

@ -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))

View File

@ -21,13 +21,107 @@
#include "libaegisub/log.h"
#include "libaegisub/util.h"
namespace agi {
void AudioProvider::GetAudioWithVolume(void *buf, int64_t start, int64_t count, double volume) const {
GetAudio(buf, start, count);
namespace {
template<typename Source>
class ConvertFloatToInt16 {
Source* src;
public:
ConvertFloatToInt16(Source* src) :src(src) {}
int16_t operator[](size_t idx) const {
Source expanded = src[idx] * 32768;
return expanded < -32768 ? -32768 :
expanded > 32767 ? 32767 :
static_cast<int16_t>(expanded);
}
};
// 8 bits per sample is assumed to be unsigned with a bias of 128,
// while everything else is assumed to be signed with zero bias
class ConvertIntToInt16 {
void* src;
int bytes_per_sample;
public:
ConvertIntToInt16(void* src, int bytes_per_sample) :src(src), bytes_per_sample(bytes_per_sample) {}
const int16_t& operator[](size_t idx) const {
return *reinterpret_cast<int16_t*>(reinterpret_cast<char*>(src) + (idx + 1) * bytes_per_sample - sizeof(int16_t));
}
};
class ConvertUInt8ToInt16 {
uint8_t* src;
public:
ConvertUInt8ToInt16(uint8_t* src) :src(src) {}
int16_t operator[](size_t idx) const {
return int16_t(src[idx]-128) << 8;
}
};
template<typename Source>
class DownmixToMono {
Source src;
int channels;
public:
DownmixToMono(Source src, int channels) :src(src), channels(channels) {}
int16_t operator[](size_t idx) const {
int ret = 0;
// Just average the channels together
for (int i = 0; i < channels; ++i)
ret += src[idx * channels + i];
return ret / channels;
}
};
}
namespace agi {
void AudioProvider::FillBufferInt16Mono(int16_t* buf, int64_t start, int64_t count) const {
if (!float_samples && bytes_per_sample == 2 && channels == 1) {
FillBuffer(buf, start, count);
return;
}
void* buff = malloc(bytes_per_sample * count * channels);
FillBuffer(buff, start, count);
if (channels == 1) {
if (float_samples) {
if (bytes_per_sample == sizeof(float))
for (int64_t i = 0; i < count; ++i)
buf[i] = ConvertFloatToInt16<float>(reinterpret_cast<float*>(buff))[i];
else if (bytes_per_sample == sizeof(double))
for (int64_t i = 0; i < count; ++i)
buf[i] = ConvertFloatToInt16<double>(reinterpret_cast<double*>(buff))[i];
}
else {
if (bytes_per_sample == sizeof(uint8_t))
for (int64_t i = 0; i < count; ++i)
buf[i] = ConvertUInt8ToInt16(reinterpret_cast<uint8_t*>(buff))[i];
else
for (int64_t i = 0; i < count; ++i)
buf[i] = ConvertIntToInt16(buff, bytes_per_sample)[i];
}
}
else {
if (float_samples) {
if (bytes_per_sample == sizeof(float))
for (int64_t i = 0; i < count; ++i)
buf[i] = DownmixToMono<ConvertFloatToInt16<float> >(ConvertFloatToInt16<float>(reinterpret_cast<float*>(buff)), channels)[i];
else if (bytes_per_sample == sizeof(double))
for (int64_t i = 0; i < count; ++i)
buf[i] = DownmixToMono<ConvertFloatToInt16<double> >(ConvertFloatToInt16<double>(reinterpret_cast<double*>(buff)), channels)[i];
}
else {
if (bytes_per_sample == sizeof(uint8_t))
for (int64_t i = 0; i < count; ++i)
buf[i] = DownmixToMono<ConvertUInt8ToInt16>(ConvertUInt8ToInt16(reinterpret_cast<uint8_t*>(buff)), channels)[i];
else
for (int64_t i = 0; i < count; ++i)
buf[i] = DownmixToMono<ConvertIntToInt16>(ConvertIntToInt16(buff, bytes_per_sample), channels)[i];
}
}
free(buff);
}
void AudioProvider::GetInt16MonoAudioWithVolume(int16_t *buf, int64_t start, int64_t count, double volume) const {
GetInt16MonoAudio(buf, start, count);
if (volume == 1.0) return;
if (bytes_per_sample != 2)
throw agi::InternalError("GetAudioWithVolume called on unconverted audio stream");
auto buffer = static_cast<int16_t *>(buf);
for (size_t i = 0; i < (size_t)count; ++i)
@ -75,6 +169,39 @@ void AudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const {
}
}
void AudioProvider::GetInt16MonoAudio(int16_t* buf, int64_t start, int64_t count) const {
if (start < 0) {
memset(buf, 0, sizeof(int16_t) * std::min(-start, count));
buf -= start;
count += start;
start = 0;
}
if (start + count > num_samples) {
int64_t zero_count = std::min(count, start + count - num_samples);
count -= zero_count;
memset(buf + count, 0, sizeof(int16_t) * zero_count);
}
if (count <= 0) return;
try {
FillBufferInt16Mono(buf, start, count);
}
catch (AudioDecodeError const& e) {
// We don't have any good way to report errors here, so just log the
// failure and return silence
LOG_E("audio_provider") << e.GetMessage();
memset(buf, 0, sizeof(int16_t) * count);
return;
}
catch (...) {
LOG_E("audio_provider") << "Unknown audio decoding error";
memset(buf, 0, sizeof(int16_t) * count);
return;
}
}
namespace {
class writer {
io::Save outfile;
@ -114,7 +241,7 @@ void SaveAudioClip(AudioProvider const& provider, fs::path const& path, int star
out.write("WAVEfmt ");
out.write<int32_t>(16); // Size of chunk
out.write<int16_t>(1); // compression format (PCM)
out.write<int16_t>(provider.AreSamplesFloat() ? 3 : 1); // compression format (1: WAVE_FORMAT_PCM, 3: WAVE_FORMAT_IEEE_FLOAT)
out.write<int16_t>(provider.GetChannels());
out.write<int32_t>(provider.GetSampleRate());
out.write<int32_t>(provider.GetSampleRate() * provider.GetChannels() * provider.GetBytesPerSample());

View File

@ -23,115 +23,18 @@
using namespace agi;
/// Anything integral -> 16 bit signed machine-endian audio converter
/// Anything -> mono 16 bit signed machine-endian audio converter
namespace {
template<class Target>
class BitdepthConvertAudioProvider final : public AudioProviderWrapper {
int src_bytes_per_sample;
mutable std::vector<uint8_t> src_buf;
class ConvertAudioProvider final : public AudioProviderWrapper {
public:
BitdepthConvertAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) {
if (bytes_per_sample > 8)
throw AudioProviderError("Audio format converter: audio with bitdepths greater than 64 bits/sample is currently unsupported");
src_bytes_per_sample = bytes_per_sample;
bytes_per_sample = sizeof(Target);
}
void FillBuffer(void *buf, int64_t start, int64_t count64) const override {
auto count = static_cast<size_t>(count64);
assert(count == 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) {
int64_t sample = 0;
// 8 bits per sample is assumed to be unsigned with a bias of 127,
// while everything else is assumed to be signed with zero bias
if (src_bytes_per_sample == 1)
sample = src_buf[i] - 128;
else {
for (int j = src_bytes_per_sample; j > 0; --j) {
sample <<= 8;
sample += src_buf[i * src_bytes_per_sample + j - 1];
}
}
if (static_cast<size_t>(src_bytes_per_sample) > sizeof(Target))
sample /= 1LL << (src_bytes_per_sample - sizeof(Target)) * 8;
else if (static_cast<size_t>(src_bytes_per_sample) < sizeof(Target))
sample *= 1LL << (sizeof(Target) - src_bytes_per_sample ) * 8;
dest[i] = static_cast<Target>(sample);
}
}
};
/// Floating point -> 16 bit signed machine-endian audio converter
template<class Source, class Target>
class FloatConvertAudioProvider final : public AudioProviderWrapper {
mutable std::vector<Source> src_buf;
public:
FloatConvertAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) {
bytes_per_sample = sizeof(Target);
ConvertAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) {
float_samples = false;
}
void FillBuffer(void *buf, int64_t start, int64_t count64) const override {
auto count = static_cast<size_t>(count64);
assert(count == count64);
src_buf.resize(count * channels);
source->GetAudio(&src_buf[0], start, count);
auto dest = static_cast<Target*>(buf);
for (size_t i = 0; i < static_cast<size_t>(count * channels); ++i) {
Source expanded;
if (src_buf[i] < 0)
expanded = static_cast<Target>(-src_buf[i] * std::numeric_limits<Target>::min());
else
expanded = static_cast<Target>(src_buf[i] * std::numeric_limits<Target>::max());
dest[i] = expanded < std::numeric_limits<Target>::min() ? std::numeric_limits<Target>::min() :
expanded > std::numeric_limits<Target>::max() ? std::numeric_limits<Target>::max() :
static_cast<Target>(expanded);
}
}
};
/// Non-mono 16-bit signed machine-endian -> mono 16-bit signed machine endian converter
class DownmixAudioProvider final : public AudioProviderWrapper {
int src_channels;
mutable std::vector<int16_t> src_buf;
public:
DownmixAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) {
src_channels = channels;
channels = 1;
bytes_per_sample = sizeof(int16_t);
}
void FillBuffer(void *buf, int64_t start, int64_t count64) const override {
auto count = static_cast<size_t>(count64);
assert(count == count64);
src_buf.resize(count * src_channels);
source->GetAudio(&src_buf[0], start, count);
auto dst = static_cast<int16_t*>(buf);
// Just average the channels together
while (count-- > 0) {
int sum = 0;
for (int c = 0; c < src_channels; ++c)
sum += src_buf[count * src_channels + c];
dst[count] = static_cast<int16_t>(sum / src_channels);
}
void FillBuffer(void *buf, int64_t start, int64_t count) const override {
source->GetInt16MonoAudio(reinterpret_cast<int16_t*>(buf), start, count);
}
};
@ -175,28 +78,22 @@ public:
namespace agi {
std::unique_ptr<AudioProvider> CreateConvertAudioProvider(std::unique_ptr<AudioProvider> provider) {
// Ensure 16-bit audio with proper endianness
if (provider->AreSamplesFloat()) {
if (provider->AreSamplesFloat())
LOG_D("audio_provider") << "Converting float to S16";
if (provider->GetBytesPerSample() == sizeof(float))
provider = agi::make_unique<FloatConvertAudioProvider<float, int16_t>>(std::move(provider));
else
provider = agi::make_unique<FloatConvertAudioProvider<double, int16_t>>(std::move(provider));
}
if (provider->GetBytesPerSample() != 2) {
LOG_D("audio_provider") << "Converting " << provider->GetBytesPerSample() << " bytes per sample or wrong endian to S16";
provider = agi::make_unique<BitdepthConvertAudioProvider<int16_t>>(std::move(provider));
}
else if (provider->GetBytesPerSample() != 2)
LOG_D("audio_provider") << "Converting " << provider->GetBytesPerSample() << " bytes per sample to S16";
// We currently only support mono audio
if (provider->GetChannels() != 1) {
if (provider->GetChannels() != 1)
LOG_D("audio_provider") << "Downmixing to mono from " << provider->GetChannels() << " channels";
provider = agi::make_unique<DownmixAudioProvider>(std::move(provider));
}
// Some players don't like low sample rate audio
while (provider->GetSampleRate() < 32000) {
LOG_D("audio_provider") << "Doubling sample rate";
provider = agi::make_unique<SampleDoublingAudioProvider>(std::move(provider));
if (provider->GetSampleRate() < 32000) {
provider = agi::make_unique<ConvertAudioProvider>(std::move(provider));
while (provider->GetSampleRate() < 32000) {
LOG_D("audio_provider") << "Doubling sample rate";
provider = agi::make_unique<SampleDoublingAudioProvider>(std::move(provider));
}
}
return provider;

View File

@ -38,20 +38,20 @@ class HDAudioProvider final : public AudioProviderWrapper {
void FillBuffer(void *buf, int64_t start, int64_t count) const override {
auto missing = std::min(count, start + count - decoded_samples);
if (missing > 0) {
memset(static_cast<int16_t*>(buf) + count - missing, 0, missing * bytes_per_sample);
memset(static_cast<int16_t*>(buf) + count - missing, 0, missing * bytes_per_sample * channels);
count -= missing;
}
if (count > 0) {
start *= bytes_per_sample;
count *= bytes_per_sample;
start *= bytes_per_sample * channels;
count *= bytes_per_sample * channels;
memcpy(buf, file.read(start, count), count);
}
}
fs::path CacheFilename(fs::path const& dir) {
// Check free space
if ((uint64_t)num_samples * bytes_per_sample > fs::FreeSpace(dir))
if ((uint64_t)num_samples * bytes_per_sample * channels > fs::FreeSpace(dir))
throw AudioProviderError("Not enough free disk space in " + dir.string() + " to cache the audio");
return format("audio-%lld-%lld", time(nullptr),
@ -61,7 +61,7 @@ class HDAudioProvider final : public AudioProviderWrapper {
public:
HDAudioProvider(std::unique_ptr<AudioProvider> src, agi::fs::path const& dir)
: AudioProviderWrapper(std::move(src))
, file(dir / CacheFilename(dir), num_samples * bytes_per_sample)
, file(dir / CacheFilename(dir), num_samples * bytes_per_sample* channels)
{
decoded_samples = 0;
decoder = std::thread([&] {
@ -69,7 +69,7 @@ public:
for (int64_t i = 0; i < num_samples; i += block) {
if (cancelled) break;
block = std::min(block, num_samples - i);
source->GetAudio(file.write(i * bytes_per_sample, block * bytes_per_sample), i, block);
source->GetAudio(file.write(i * bytes_per_sample * channels, block * bytes_per_sample * channels), i, block);
decoded_samples += block;
}
});

View File

@ -29,6 +29,11 @@ class LockAudioProvider final : public agi::AudioProviderWrapper {
source->GetAudio(buf, start, count);
}
void FillBufferInt16Mono(int16_t *buf, int64_t start, int64_t count) const override {
std::unique_lock<std::mutex> lock(mutex);
source->GetInt16MonoAudio(buf, start, count);
}
public:
LockAudioProvider(std::unique_ptr<AudioProvider> src)
: AudioProviderWrapper(std::move(src))

View File

@ -56,6 +56,7 @@ class PCMAudioProvider : public AudioProvider {
start += read_count;
pos += ip.num_samples;
}
ZeroFill(write_buf, count);
}
protected:
@ -67,7 +68,7 @@ protected:
template<typename T, typename UInt>
T Read(UInt *data_left) {
if (*data_left < sizeof(T)) throw file_ended();
if (file.size() - file_pos < sizeof(T)) throw file_ended();
if (file_pos > file.size() || file.size() - file_pos < sizeof(T)) throw file_ended();
auto data = file.read(file_pos, sizeof(T));
file_pos += sizeof(T);
@ -89,7 +90,7 @@ struct FourCC {
bool operator==(const char *cmp) const { return !(*this != cmp); }
};
// Overview of RIFF WAV: <http://www.sonicspot.com/guide/wavefiles.html>
// Overview of RIFF WAV: https://docs.microsoft.com/en-us/previous-versions/windows/hardware/design/dn653308(v=vs.85)
struct RiffWav {
using DataSize = uint32_t;
using ChunkId = FourCC;
@ -97,7 +98,7 @@ struct RiffWav {
static const char *riff_id() { return "RIFF"; }
static const char *wave_id() { return "WAVE"; }
static const char *fmt_id() { return "fmt "; }
static const char *data_id() { return "data "; }
static const char *data_id() { return "data"; }
static const int alignment = 1;
@ -127,7 +128,7 @@ static const GUID w64Guiddata = {{
0x64, 0x61, 0x74, 0x61, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
}};
// http://www.vcs.de/fileadmin/user_upload/MBS/PDF/Whitepaper/Informations_about_Sony_Wave64.pdf
// http://www.ambisonia.com/Members/mleese/sony_wave64.pdf/sony_wave64.pdf
struct Wave64 {
using DataSize = uint64_t;
using ChunkId = GUID;
@ -140,7 +141,7 @@ struct Wave64 {
static const uint64_t alignment = 7ULL;
// Wave 64 includes the size of the header in the chunk sizes
static uint64_t data_size(uint64_t size) { return size - 16; }
static uint64_t data_size(uint64_t size) { return size - 24; }
static uint64_t chunk_size(uint64_t size) { return size - 24; }
};
@ -164,9 +165,11 @@ public:
throw AudioDataNotFound("File is not a RIFF WAV file");
while (data_left) {
auto chunk_fcc = Read<ChunkId>(&data_left);
auto chunk_size = Impl::chunk_size(Read<DataSize>(&data_left));
uint64_t chunk_end = file_pos + chunk_size;
data_left -= std::min(chunk_size, data_left);
if (chunk_fcc == Impl::fmt_id()) {
@ -186,14 +189,16 @@ public:
else if (chunk_fcc == Impl::data_id()) {
if (!channels || !sample_rate || !bytes_per_sample)
throw AudioProviderError("Found 'data' chunk without format being set.");
index_points.emplace_back(IndexPoint{file_pos, chunk_size / bytes_per_sample / channels});
num_samples += chunk_size / bytes_per_sample / channels;
uint64_t chunk_decoded_samples = std::min<uint64_t>(chunk_size, file.size() - file_pos) / bytes_per_sample / channels;
decoded_samples += chunk_decoded_samples;
index_points.emplace_back(IndexPoint{file_pos, chunk_decoded_samples });
}
// There's a bunch of other chunk types. They're all dumb.
// blocks are aligned and the padding bytes are not included in
// the size of the chunk
file_pos += (chunk_size + Impl::alignment) & ~Impl::alignment;
file_pos = (chunk_end + Impl::alignment) & ~Impl::alignment;
}
}
@ -202,7 +207,8 @@ public:
throw AudioDataNotFound("File ended before reaching format chunk");
// Truncated files are fine otherwise
}
decoded_samples = num_samples;
if (decoded_samples == 0)
throw AudioDataNotFound("No audio sample can be decoded");
}
};
}

View File

@ -46,14 +46,14 @@ public:
decoded_samples = 0;
try {
blockcache.resize((source->GetNumSamples() * source->GetBytesPerSample() + CacheBlockSize - 1) >> CacheBits);
blockcache.resize((num_samples * bytes_per_sample * channels + CacheBlockSize - 1) >> CacheBits);
}
catch (std::bad_alloc const&) {
throw AudioProviderError("Not enough memory available to cache in RAM");
}
decoder = std::thread([&] {
int64_t readsize = CacheBlockSize / source->GetBytesPerSample();
int64_t readsize = CacheBlockSize / bytes_per_sample / channels;
for (size_t i = 0; i < blockcache.size(); i++) {
if (cancelled) break;
auto actual_read = std::min<int64_t>(readsize, num_samples - i * readsize);
@ -71,20 +71,22 @@ public:
void RAMAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
auto charbuf = static_cast<char *>(buf);
for (int64_t bytes_remaining = count * bytes_per_sample; bytes_remaining; ) {
for (int64_t bytes_remaining = count * bytes_per_sample * channels; bytes_remaining; ) {
if (start >= decoded_samples) {
memset(charbuf, 0, bytes_remaining);
break;
}
const int 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);
const int64_t samples_per_block = CacheBlockSize / bytes_per_sample / channels;
const size_t i = start / samples_per_block;
const int start_offset = (start % samples_per_block) * bytes_per_sample * channels;
const int read_size = std::min<int>(bytes_remaining, samples_per_block * bytes_per_sample * channels - start_offset);
memcpy(charbuf, &blockcache[i][start_offset], read_size);
charbuf += read_size;
bytes_remaining -= read_size;
start += read_size / bytes_per_sample;
start += read_size / bytes_per_sample / channels;
}
}
}

View File

@ -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)
++count;
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;
}

View File

@ -23,43 +23,86 @@
#ifdef WITH_UCHARDET
#include <uchardet/uchardet.h>
#include <boost/algorithm/string/case_conv.hpp>
#endif
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";
// First check for known magic bytes which identify the file type
if (fp.size() >= 4) {
const char* header = fp.read(0, 4);
if (!strncmp(header, "\xef\xbb\xbf", 3))
return "utf-8";
if (!strncmp(header, "\x00\x00\xfe\xff", 4))
return "utf-32be";
if (!strncmp(header, "\xff\xfe\x00\x00", 4))
return "utf-32le";
if (!strncmp(header, "\xfe\xff", 2))
return "utf-16be";
if (!strncmp(header, "\xff\xfe", 2))
return "utf-16le";
if (!strncmp(header, "\x1a\x45\xdf\xa3", 4))
return "binary"; // Actually EBML/Matroska
}
#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);
// uchardet does not tell us the byte order of UTF-16 / UTF-32, so do it ourself
std::string encoding_lower{ encoding };
boost::to_lower(encoding_lower);
if (encoding_lower == "utf-16") {
uint64_t le_score = 0, be_score = 0;
for (uint64_t offset = 0; offset < fp.size(); ) {
auto read = std::min<uint64_t>(65536, fp.size() - offset);
auto buf = fp.read(offset, read);
for (uint64_t i = 0; i + 1 < read; i += 2) {
if (!buf[i])
++be_score;
if (!buf[i + 1])
++le_score;
}
offset += read;
}
return le_score < be_score ? "utf-16be" : "utf-16le";
}
else if (encoding_lower == "utf-32") {
uint64_t le_score = 0, be_score = 0;
for (uint64_t offset = 0; offset < fp.size(); ) {
auto read = std::min<uint64_t>(65536, fp.size() - offset);
auto buf = fp.read(offset, read);
for (uint64_t i = 0; i + 3 < read; i += 2) {
if (!buf[i])
++be_score;
if (!buf[i + 3])
++le_score;
}
offset += read;
}
return le_score < be_score ? "utf-32be" : "utf-32le";
}
return encoding.empty() ? "binary" : encoding;
#else
// 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'))

View File

@ -33,12 +33,6 @@
#define ICONV_POSIX
#endif
#ifdef AGI_ICONV_CONST
#define ICONV_CONST_CAST(a) a
#else
#define ICONV_CONST_CAST(a) const_cast<char **>(a)
#endif
static const iconv_t iconv_invalid = (iconv_t)-1;
static const size_t iconv_failed = (size_t)-1;
@ -286,7 +280,13 @@ Iconv::~Iconv() {
}
size_t Iconv::operator()(const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) {
return iconv(cd, ICONV_CONST_CAST(inbuf), inbytesleft, outbuf, outbytesleft);
struct InbufConstCast{
const char** p;
InbufConstCast(const char** p) : p(p) {}
operator const char** () const { return p; }
operator char** () const { return const_cast<char**>(p); }
} inbuf_const_cast(inbuf);
return iconv(cd, inbuf_const_cast, inbytesleft, outbuf, outbytesleft);
}
IconvWrapper::IconvWrapper(const char* sourceEncoding, const char* destEncoding, bool enableSubst)
@ -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;
@ -420,7 +420,7 @@ size_t IconvWrapper::DstStrLen(const char* str) {
bool IsConversionSupported(const char *src, const char *dst) {
iconv_t cd = iconv_open(dst, src);
bool supported = cd != iconv_invalid;
iconv_close(cd);
if (supported) iconv_close(cd);
return supported;
}

View File

@ -14,6 +14,11 @@
//
// Aegisub Project http://www.aegisub.org/
#ifdef _WIN32
// For Boost::asio
#include <sdkddkver.h>
#endif
#include "libaegisub/dispatch.h"
#include "libaegisub/util.h"

View File

@ -78,10 +78,10 @@ file_mapping::file_mapping(fs::path const& filename, bool temporary)
#ifdef _WIN32
: handle(CreateFileW(filename.wstring().c_str(),
temporary ? read_write : read_only,
temporary ? FILE_SHARE_READ | FILE_SHARE_WRITE : FILE_SHARE_READ,
temporary ? FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE : FILE_SHARE_READ,
nullptr,
temporary ? OPEN_ALWAYS : OPEN_EXISTING,
0, 0))
temporary ? FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE : 0, 0))
{
if (handle == ipcdetail::invalid_file()) {
switch (GetLastError()) {

View File

@ -30,6 +30,27 @@ namespace ec = boost::system::errc;
// boost::filesystem functions throw a single exception type for all
// errors, which isn't really what we want, so do some crazy wrapper
// shit to map error codes to more useful exceptions.
#ifdef BOOST_WINDOWS_API
#include <winerror.h>
#define CHECKED_CALL(exp, src_path, dst_path) \
boost::system::error_code ec; \
exp; \
switch (ec.value()) {\
case ERROR_SUCCESS: break; \
case ERROR_FILE_NOT_FOUND: throw FileNotFound(src_path); \
case ERROR_DIRECTORY: throw NotADirectory(src_path); \
case ERROR_DISK_FULL: throw DriveFull(dst_path); \
case ERROR_ACCESS_DENIED: \
if (!src_path.empty()) \
acs::CheckFileRead(src_path); \
if (!dst_path.empty()) \
acs::CheckFileWrite(dst_path); \
throw AccessDenied(src_path); \
default: \
LOG_D("filesystem") << "Unknown error when calling '" << #exp << "': " << ec << ": " << ec.message(); \
throw FileSystemUnknownError(ec.message()); \
}
#else
#define CHECKED_CALL(exp, src_path, dst_path) \
boost::system::error_code ec; \
exp; \
@ -49,6 +70,7 @@ namespace ec = boost::system::errc;
LOG_D("filesystem") << "Unknown error when calling '" << #exp << "': " << ec << ": " << ec.message(); \
throw FileSystemUnknownError(ec.message()); \
}
#endif
#define CHECKED_CALL_RETURN(exp, src_path) \
CHECKED_CALL(auto ret = exp, src_path, agi::fs::path()); \

View File

@ -56,7 +56,8 @@ Save::Save(fs::path const& file, bool binary)
}
}
Save::~Save() noexcept(false) {
void Save::Close() {
if (!fp) return;
fp.reset(); // Need to close before rename on Windows to unlock the file
for (int i = 0; i < 10; ++i) {
try {
@ -72,5 +73,12 @@ Save::~Save() noexcept(false) {
}
}
Save::~Save() {
try {
Close();
}
catch (agi::fs::FileSystemError const&) {}
}
} // namespace io
} // namespace agi

View File

@ -22,8 +22,9 @@ namespace agi {
line_iterator_base::line_iterator_base(std::istream &stream, std::string encoding)
: stream(&stream)
{
boost::to_lower(encoding);
if (encoding != "utf-8") {
std::string encoding_lower{ encoding };
boost::to_lower(encoding_lower);
if (encoding_lower != "utf-8") {
agi::charset::IconvWrapper c("utf-8", encoding.c_str());
c.Convert("\r", 1, reinterpret_cast<char *>(&cr), sizeof(int));
c.Convert("\n", 1, reinterpret_cast<char *>(&lf), sizeof(int));

View File

@ -81,13 +81,19 @@ decltype(LogSink::messages) LogSink::GetMessages() const {
return ret;
}
#ifdef LOG_WITH_FILE
Message::Message(const char *section, Severity severity, const char *file, const char *func, int line)
#else
Message::Message(const char* section, Severity severity, const char* func, int line)
#endif
: msg(buffer, sizeof buffer)
{
using namespace std::chrono;
sm.section = section;
sm.severity = severity;
#ifdef LOG_WITH_FILE
sm.file = file;
#endif
sm.func = func;
sm.line = line;
sm.time = duration_cast<nanoseconds>(steady_clock::now().time_since_epoch()).count();
@ -109,7 +115,9 @@ void JsonEmitter::log(SinkMessage const& sm) {
entry["usec"] = sm.time % 1000000000;
entry["severity"] = sm.severity;
entry["section"] = sm.section;
#ifdef LOG_WITH_FILE
entry["file"] = sm.file;
#endif
entry["func"] = sm.func;
entry["line"] = sm.line;
entry["message"] = sm.message;

View File

@ -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
@ -184,7 +184,6 @@ void tagless_find_helper::map_range(size_t &s, size_t &e) {
continue;
}
assert(block.first > s);
// Blocks after the match are irrelevant
if (block.first >= e) break;

View File

@ -28,16 +28,17 @@ public:
Time(std::string const& text);
/// Get millisecond, rounded to centisecond precision
operator int() const { return time / 10 * 10; }
// Always round up for 5ms because the range is [start, stop)
operator int() const { return (time + 5) - (time + 5) % 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
/// Get millisecond, without centisecond round
int GetMillisecond() const noexcept { return time; }
/// 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;
};
}

View File

@ -36,6 +36,7 @@ protected:
bool float_samples = false;
virtual void FillBuffer(void *buf, int64_t start, int64_t count) const = 0;
virtual void FillBufferInt16Mono(int16_t* buf, int64_t start, int64_t count) const;
void ZeroFill(void *buf, int64_t count) const;
@ -43,7 +44,8 @@ public:
virtual ~AudioProvider() = default;
void GetAudio(void *buf, int64_t start, int64_t count) const;
void GetAudioWithVolume(void *buf, int64_t start, int64_t count, double volume) const;
void GetInt16MonoAudio(int16_t* buf, int64_t start, int64_t count) const;
void GetInt16MonoAudioWithVolume(int16_t *buf, int64_t start, int64_t count, double volume) const;
int64_t GetNumSamples() const { return num_samples; }
int64_t GetDecodedSamples() const { return decoded_samples; }

View File

@ -98,12 +98,6 @@ namespace agi {
std::string const& GetMessage() const { return message; }
};
/// @brief Convenience macro to include the current location in code
///
/// Intended for use in error messages where it can sometimes be convenient to
/// indicate the exact position the error occurred at.
#define AG_WHERE " (at " __FILE__ ":" #__LINE__ ")"
/// @brief Convenience macro for declaring exceptions
/// @param classname Name of the exception class to declare
/// @param baseclass Class to derive from

View File

@ -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): ");

View File

@ -38,8 +38,9 @@ class Save {
public:
Save(fs::path const& file, bool binary = false);
~Save() noexcept(false);
~Save();
std::ostream& Get() { return *fp; }
void Close();
};
} // namespace io

View File

@ -21,7 +21,11 @@
// These macros below aren't a perm solution, it will depend on how annoying they are through
// actual usage, and also depends on msvc support.
#ifdef LOG_WITH_FILE
#define LOG_SINK(section, severity) agi::log::Message(section, severity, __FILE__, __FUNCTION__, __LINE__).stream()
#else
#define LOG_SINK(section, severity) agi::log::Message(section, severity, __FUNCTION__, __LINE__).stream()
#endif
#define LOG_E(section) LOG_SINK(section, agi::log::Exception)
#define LOG_A(section) LOG_SINK(section, agi::log::Assert)
#define LOG_W(section) LOG_SINK(section, agi::log::Warning)
@ -59,7 +63,9 @@ struct SinkMessage {
std::string message; ///< Formatted message
int64_t time; ///< Time at execution in nanoseconds since epoch
const char *section; ///< Section info eg "video/open" "video/seek" etc
#ifdef LOG_WITH_FILE
const char *file; ///< Source file
#endif
const char *func; ///< Function name
Severity severity; ///< Severity
int line; ///< Source line
@ -125,7 +131,11 @@ class Message {
char buffer[2048];
public:
Message(const char *section, Severity severity, const char *file, const char *func, int line);
#ifdef LOG_WITH_FILE
Message(const char* section, Severity severity, const char* file, const char* func, int line);
#else
Message(const char* section, Severity severity, const char* func, int line);
#endif
~Message();
std::ostream& stream() { return msg; }
};

View File

@ -1,5 +1,5 @@
#ifdef __cplusplus
#ifndef _WIN32
#if !defined(_WIN32) && !defined(CMAKE_BUILD)
#include "../acconf.h"
#endif
@ -14,11 +14,6 @@
#include <ctime>
// Common C++
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4996)
#endif
#include <algorithm>
#include <functional>
#include <iterator>
@ -28,16 +23,10 @@
#include <string>
#include <vector>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
// Boost
#include <boost/range/algorithm.hpp>
#include <boost/range/irange.hpp>
#include <boost/regex.hpp>
#define BOOST_NO_SCOPED_ENUMS
#include <boost/filesystem.hpp>
#undef BOOST_NO_SCOPED_ENUMS
#include <boost/interprocess/streams/bufferstream.hpp>
#endif

View File

@ -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},

View File

@ -24,14 +24,20 @@ void EmitSTDOUT::log(SinkMessage const& sm) {
tm tmtime;
localtime_r(&time, &tmtime);
#ifdef LOG_WITH_FILE
printf("%c %02d:%02d:%02d %-9ld <%-25s> [%s:%s:%d] %.*s\n",
#else
printf("%c %02d:%02d:%02d %-9ld <%-25s> [%s:%d] %.*s\n",
#endif
Severity_ID[sm.severity],
tmtime.tm_hour,
tmtime.tm_min,
tmtime.tm_sec,
(long)(sm.time % 1000000000),
sm.section,
#ifdef LOG_WITH_FILE
sm.file,
#endif
sm.func,
sm.line,
(int)sm.message.size(),

View File

@ -27,8 +27,12 @@ void EmitSTDOUT::log(SinkMessage const& sm) {
localtime_s(&tmtime, &time);
char buff[65536];
#ifdef LOG_WITH_FILE
_snprintf_s(buff, _TRUNCATE, "%s (%d): %c %02d:%02d:%02d.%-3ld <%-25s> [%s] %.*s\n",
sm.file,
#else
_snprintf_s(buff, _TRUNCATE, "Line %d: %c %02d:%02d:%02d.%-3ld <%-25s> [%s] %.*s\n",
#endif
sm.line,
Severity_ID[sm.severity],
tmtime.tm_hour,

View File

@ -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 $< -d $(TOP)po -o $@
%.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

View 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>

View File

@ -1,13 +1,15 @@
[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
Categories=AudioVideo;AudioVideoEditing;
Keywords=subtitles;subtitle;captions;captioning;video;audio;
MimeType=application/x-srt;text/plain;text/x-ass;text/x-microdvd;text/x-ssa;
StartupNotify=true
StartupWMClass=aegisub

View File

@ -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

1
po/LINGUAS Normal file
View File

@ -0,0 +1 @@
ar be bg ca cs da de el es eu fa fi fr_FR gl hu id it ja ko nl pl pt_BR pt_PT ru sr_RS@latin sr_RS uk_UA vi zh_CN zh_TW

File diff suppressed because it is too large Load Diff

11247
po/ar.po

File diff suppressed because it is too large Load Diff

6729
po/be.po Normal file

File diff suppressed because it is too large Load Diff

11168
po/bg.po

File diff suppressed because it is too large Load Diff

14216
po/ca.po

File diff suppressed because it is too large Load Diff

12824
po/cs.po

File diff suppressed because it is too large Load Diff

11198
po/da.po

File diff suppressed because it is too large Load Diff

10662
po/de.po

File diff suppressed because it is too large Load Diff

15159
po/el.po

File diff suppressed because it is too large Load Diff

10868
po/es.po

File diff suppressed because it is too large Load Diff

12460
po/eu.po

File diff suppressed because it is too large Load Diff

11168
po/fa.po

File diff suppressed because it is too large Load Diff

10718
po/fi.po

File diff suppressed because it is too large Load Diff

13112
po/fr_FR.po

File diff suppressed because it is too large Load Diff

11200
po/gl.po

File diff suppressed because it is too large Load Diff

12747
po/hu.po

File diff suppressed because it is too large Load Diff

12314
po/id.po

File diff suppressed because it is too large Load Diff

13156
po/it.po

File diff suppressed because it is too large Load Diff

11275
po/ja.po

File diff suppressed because it is too large Load Diff

12844
po/ko.po

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,8 @@
#!/bin/sh
#Abort on error
set -e
maybe_append() {
while read -r msg; do
msgfile=$(echo $msg | cut -d'|' -f1)
@ -7,18 +10,21 @@ maybe_append() {
msgid=$(echo $msg | cut -d'|' -f3-)
if ! grep -Fq "msgid $msgid" aegisub.pot; then
echo "\n#: $msgfile:$msgline\nmsgid $msgid\nmsgstr \"\"\n" >> aegisub.pot
printf "\n#: %s:%s\nmsgid %s\nmsgstr \"\"\n\n" \
"$msgfile" "$msgline" "$msgid" >> aegisub.pot
fi
done
}
find ../src ../src/command -name \*.cpp -o -name \*.h \
| xgettext --files-from=- -o - --c++ -k_ -kSTR_MENU -kSTR_DISP -kSTR_HELP -kfmt_tl -kfmt_plural:2,3 -kwxT -kwxPLURAL:1,2 \
| sed 's/SOME DESCRIPTIVE TITLE./Aegisub 3.2/' \
| sed 's/YEAR/2005-2014/' \
find ../src -name \*.cpp -o -name \*.h \
| LC_ALL=C sort \
| xgettext --files-from=- -o - --c++ \
-k_ -kSTR_MENU -kSTR_DISP -kSTR_HELP -kfmt_tl -kfmt_plural:2,3 -kwxT -kwxPLURAL:1,2 \
| sed 's/SOME DESCRIPTIVE TITLE./Aegisub 3.3+/' \
| sed 's/YEAR/2005-2020/' \
| sed "s/THE PACKAGE'S COPYRIGHT HOLDER/Rodrigo Braz Monteiro, Niels Martin Hansen, Thomas Goyne et. al./" \
| sed 's/PACKAGE/Aegisub/' \
| sed 's/VERSION/3.2.0/' \
| sed 's/VERSION/3.3+/' \
| sed 's/FIRST AUTHOR <EMAIL@ADDRESS>/Niels Martin Hansen <nielsm@aegisub.org>/' \
| sed 's/CHARSET/UTF-8/' \
> aegisub.pot
@ -33,18 +39,18 @@ grep '"[A-Za-z ]\+" : {' -n ../src/libresrc/default_hotkey.json \
| sed 's/^\([0-9]\+:\).*\("[^"]\+"\).*$/default_hotkey.json|\1|\2/' \
| maybe_append
find ../automation -name *.lua \
| xargs grep tr\"[^\"]\*\" -o -n \
find ../automation -name '*.lua' \
| LC_ALL=C sort \
| xargs grep 'tr"[^"]*"' -o -n \
| sed 's/\(.*\):\([0-9]\+\):tr\(".*"\)/\1|\2|\3/' \
| sed 's/\\/\\\\\\\\/g' \
| sed 's/\\/\\\\/g' \
| maybe_append
for i in 'Name' 'GenericName' 'Comment'
do
grep ^_$i -n ../packages/desktop/aegisub.desktop.template.in \
| sed 's/\([0-9]\+\):[^=]\+=\(.*\)$/aegisub.desktop|\1|"\2"/' \
| maybe_append
done
xgettext ../packages/desktop/aegisub.desktop.template.in --language=Desktop --join-existing --omit-header -o aegisub.pot
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
grep '^_[A-Za-z0-9]*=.*' ../packages/win_installer/fragment_strings.iss.in | while read line
do
@ -52,3 +58,10 @@ do
| sed 's/[^=]*=\(.*\)/packages\/win_installer\/fragment_strings.iss|1|"\1"/' \
| maybe_append
done
for i in $(cat LINGUAS)
do
# Run msgmerge twice to workaround https://savannah.gnu.org/bugs/?58778
msgmerge --update --backup=none --no-fuzzy-matching --sort-by-file $i.po aegisub.pot
msgmerge --update --backup=none --no-fuzzy-matching --sort-by-file $i.po aegisub.pot
done

11255
po/nl.po

File diff suppressed because it is too large Load Diff

11609
po/pl.po

File diff suppressed because it is too large Load Diff

11706
po/pt_BR.po

File diff suppressed because it is too large Load Diff

15558
po/pt_PT.po

File diff suppressed because it is too large Load Diff

11228
po/ru.po

File diff suppressed because it is too large Load Diff

12701
po/sr_RS.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

11065
po/uk_UA.po

File diff suppressed because it is too large Load Diff

13864
po/vi.po

File diff suppressed because it is too large Load Diff

10260
po/zh_CN.po

File diff suppressed because it is too large Load Diff

10268
po/zh_TW.po

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../header.mk
PROGRAM += $(d)src
src_CPPFLAGS := -I$(d) -I.. -I$(d)include -I$(TOP)libaegisub/include -I$(TOP)build \
src_CPPFLAGS := -I$(d) -I$(d)include -I$(TOP)libaegisub/include -I$(TOP)build \
$(CFLAGS_PTHREAD) $(CFLAGS_FFTW3) $(CFLAGS_ICU) $(CPPFLAGS_BOOST)
src_CXXFLAGS := $(CXXFLAGS_WX)
src_LIBS := $(LIBS_GL) $(LIBS_PTHREAD) $(LIBS_WX) $(LIBS_FREETYPE) \
@ -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)

View File

@ -48,7 +48,7 @@
#define _CRT_SECURE_NO_WARNINGS
#endif
#ifndef _WIN32
#if !defined(_WIN32) && !defined(CMAKE_BUILD)
#include "../acconf.h"
#endif
@ -63,11 +63,6 @@
#include <cstdint>
#include <ctime>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4996)
#endif
// Common C++
#include <algorithm>
#include <array>
@ -86,10 +81,6 @@
#include <utility>
#include <vector>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#ifdef _WIN32
#include <objbase.h>
#include <mmsystem.h>
@ -106,9 +97,7 @@
#include <boost/range/algorithm.hpp>
#include <boost/range/irange.hpp>
#include <boost/regex.hpp>
#define BOOST_NO_SCOPED_ENUMS
#include <boost/filesystem/path.hpp>
#undef BOOST_NO_SCOPED_ENUMS
#include <boost/interprocess/streams/bufferstream.hpp>
#include <boost/interprocess/streams/vectorstream.hpp>

View File

@ -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

View File

@ -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;

View File

@ -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))

View File

@ -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;
@ -153,7 +154,7 @@ class AudioDisplayScrollbar final : public AudioDisplayInteractionObject {
// Recalculate thumb bounds from position and length data
void RecalculateThumb()
{
thumb.width = std::max<int>(min_width, (int64_t)bounds.width * page_length / data_length);
thumb.width = int((int64_t)bounds.width * page_length / data_length);
thumb.height = height;
thumb.x = int((int64_t)bounds.width * position / data_length);
thumb.y = bounds.y;
@ -263,13 +264,18 @@ public:
dc.SetPen(wxPen(colours.Light()));
dc.SetBrush(wxBrush(colours.Light()));
dc.DrawRectangle(thumb);
// Paint the thumb at least min_width, expand to both left and right
if (thumb.width < min_width)
dc.DrawRectangle(wxRect(thumb.x - (min_width - thumb.width) / 2, thumb.y, min_width, thumb.height));
else
dc.DrawRectangle(thumb);
}
};
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 +484,7 @@ public:
}
};
namespace {
class AudioStyleRangeMerger final : public AudioRenderingStyleRanges {
typedef std::map<int, AudioRenderingStyle> style_map;
public:

Some files were not shown because too many files have changed in this diff Show More