Compare commits

...

830 commits

Author SHA1 Message Date
Alexander Koblov
187d1473a2 FIX: Verify checksum - assign OnCreate event (fixes #1894)
(cherry picked from commit 3e09c8c56b)
2026-01-07 14:22:10 +03:00
Alexander Koblov
db47ff6d83 ADD: Verify checksum - use log font, close by enter key (issue #1894)
(cherry picked from commit ee29c08428)
2026-01-07 14:22:10 +03:00
Alexander Koblov
f0f08e6b8c UPD: Verify checksum - hide right margin
(cherry picked from commit f7911094b3)
2026-01-06 13:26:12 +03:00
Alexander Koblov
bcdd375241 UPD: Version number 2026-01-06 12:50:50 +03:00
Alexander Koblov
ec0de7416d FIX: EDateOutOfRange exception with negative Unix time (fixes #2666)
(cherry picked from commit c32db48c03)
2026-01-06 12:47:45 +03:00
Alexander Koblov
b7d12a3b5d UPD: Optimize verify checksum operation
(cherry picked from commit 24c8539069)
2026-01-06 12:27:14 +03:00
Alexander Koblov
49f67723e2 FIX: Hang when read from a named pipe (fixes #2639)
(cherry picked from commit 8c370fd8ea)
2025-12-21 13:29:30 +03:00
Alexander Koblov
40d785bf0f UPD: Release workflow
(cherry picked from commit 190825e653)
2025-12-21 13:25:14 +03:00
Alexander Koblov
37bd3f1ed6 UPD: Version number 2025-12-02 18:28:43 +03:00
Alexander Koblov
082635c63f FIX: Remove read-only temporary files (fixes #2632)
(cherry picked from commit 228802bb5d)
2025-12-02 18:28:43 +03:00
Alexander Koblov
3d7c4206d1 FIX: Double plugin initialization (issue #2616)
(cherry picked from commit 2688fd8499)
2025-12-02 18:28:42 +03:00
Alexander Koblov
8959c57708 FIX: Copy into symbolic link to directory (fixes #2175)
(cherry picked from commit 934bef9782)
2025-12-02 18:28:42 +03:00
Alexander Koblov
eac3191766 FIX: SingleByteEncoding function
(cherry picked from commit 6ace980bb0)
2025-12-02 18:28:42 +03:00
Alexander Koblov
473a550a03 FIX: DCDateTimeUtils - arithmetic overflow (fixes #2627)
(cherry picked from commit 16e9b1d647)
2025-12-02 18:28:41 +03:00
Jozef Gaal
0b803ae534
UPD: Slovak language (#2629)
Slovak language updated
2025-11-30 12:42:49 +03:00
Alexander Koblov
8f007810dc UPD: Zip - Better suspicious symbolic links handling 2025-11-09 15:38:30 +03:00
Alexander Koblov
c1df50e370 FIX: Wrong "From" path when copying from .b64 (issue #1639)
(cherry picked from commit 9370d9ec7c)
2025-11-04 13:28:13 +03:00
Alexander Koblov
8dd479eab0 FIX: KAScrypt - TDCP_blockcipher128.IncCounter
(cherry picked from commit 1f0fe20177)
2025-11-04 13:26:43 +03:00
Alexander Koblov
3f2fcb350a FIX: Zip - When reading archives replace relative paths by underlines
(cherry picked from commit 344b0b786b)
2025-11-04 13:26:43 +03:00
Alexander Koblov
43c39e03be UPD: Zip - Do not extract symbolic links that point outside the target directory
(cherry picked from commit 520c66620e)
2025-11-04 13:26:43 +03:00
Alexander Koblov
7cc14a7a04 UPD: Version number 2025-11-04 13:26:43 +03:00
rich2014
e4c9a87eef UPD: new Icon for macOS, issue #2552
(cherry picked from commit f96c26d465)

UPD: new Icon for macOS, better than before on macOS 15,  issue #2552
(cherry picked from commit 0c34a9cad0)
2025-11-04 13:26:42 +03:00
rich2014
2c9db300ee UPD: 'Mac OS X' to 'macOS' in About Dialog
(cherry picked from commit 5275b991f4)
2025-11-04 13:26:42 +03:00
rich2014
64dbf811b3 FIX: the AutoRefresh issue on APFS bootable volumes on external drives
(cherry picked from commit b607af5a5a)
2025-11-04 13:26:42 +03:00
rich2014
78ba4aef4b FIX: support app icons on macOS 26.1 #2519
NSBMPFileType to NSPNGFileType

(cherry picked from commit 9200ae0a7c)
2025-11-04 13:26:42 +03:00
Alexander Koblov
c97770d6f4 UPD: Lua - synchronize with master branch 2025-11-04 13:26:41 +03:00
Alexander Koblov
ae24245ef6 UPD: DCDateTimeUtils - synchronize with master branch 2025-11-04 13:26:41 +03:00
Alexander Koblov
1d2497b1b1 FIX: Lazarus 4.99 compatibility
(cherry picked from commit 9b108c114b)
2025-11-04 13:26:41 +03:00
Alexander Koblov
2e10385436 FIX: Zip - synchronize central directory header with local file header (fixes #2542)
(cherry picked from commit 4b4b38eb97)
2025-11-04 13:26:40 +03:00
Alexander Koblov
c9563cf5ed FIX: GioFileSource - Copy files between different locations (fixes #2469) 2025-11-04 13:19:34 +03:00
Alexander Koblov
b4b2d9a36c FIX: Calculate Checksum - incorrect output file name 2025-10-12 13:35:23 +03:00
Alexander Koblov
24fb6d6065 FIX: Calculate Checksum - access violation (fixes #2535) 2025-10-12 12:58:35 +03:00
Alexander Koblov
76935aa7b2 FIX: Dark mode - draw toolbar separators 2025-10-12 12:55:50 +03:00
rich2014
948801b5a6 ADD: support app icons on macOS 26 #2519 2025-10-12 12:55:29 +03:00
Alexander Koblov
24114a9ddf FIX: FTP - execute SIZE command in the binary mode (fixes #2510) 2025-10-03 20:28:12 +03:00
Alexander Koblov
81c1432816 FIX: FTP - remove warnings, refactoring 2025-10-03 20:28:05 +03:00
Alexander Koblov
eda51ead20 UPD: Version number 2025-10-03 20:27:25 +03:00
Alexander Koblov
0201c82dc7 FIX: Use _SC_NPROCESSORS_CONF constant 2025-10-03 20:25:43 +03:00
Alexander Koblov
5943e8f889 FIX: Don't use flock function, it does not work correct with network file systems (issue #2018) 2025-10-03 20:23:23 +03:00
Alexander Koblov
fa56c3ba55 FIX: Saving universal-highlighter colors settings (fixes #2514) 2025-10-03 20:23:15 +03:00
Alexander Koblov
9a5ba4d7d7 FIX: Don't normalize path delimiters for terminal commands 2025-10-03 20:22:55 +03:00
Alexander Koblov
43e8984b4c UPD: Use BLAKE3 under x86_64 2025-10-03 20:22:36 +03:00
Alexander Koblov
6776fac0e4 FIX: Viewer - crash with zero size virtual file (issue #2373)
(cherry picked from commit 66d9f04d01)
2025-09-05 22:04:13 +03:00
Alexander Koblov
b204fbb617 FIX: Copy version information with line-ending at the end
(cherry picked from commit b5d031ea5d)
2025-08-09 18:19:33 +03:00
Alexander Koblov
2b0c1bef2e ADD: Flush doublecmd.xml to the disk
(cherry picked from commit 44b35f2e19)
2025-08-05 21:36:48 +03:00
Alexander Koblov
4418184107 UPD: Version number 2025-08-03 16:34:32 +03:00
Alexander Koblov
aa16eef676 FIX: Crash on start with corrupted doublecmd.xml (issue #2430)
(cherry picked from commit d1623e070d)
2025-08-03 16:33:24 +03:00
Alexander Koblov
1c1be9e27e UPD: Use CeUtf16ToUtf8 function (issue #2374)
(cherry picked from commit 0ff4de4985)
2025-08-03 16:33:16 +03:00
Alexander Koblov
809b11db4b UPD: Refactoring version information
(cherry picked from commit c55234ff76)
2025-08-03 16:33:16 +03:00
Alexander Koblov
b83b18d720 FIX: Clear search template description after deleting all templates (fixes #2437)
(cherry picked from commit e459a57623)
2025-08-03 16:33:15 +03:00
Alexander Koblov
18bd640b80 FIX: Scroll line by line with cursor movement
(cherry picked from commit 5ab603bcfe)
2025-08-03 16:33:15 +03:00
Alexander Koblov
896b62f3c1 FIX: GioGetMimeType function with zero size file
(cherry picked from commit 2cefe63169)
2025-08-03 16:33:15 +03:00
rich2014
85d16bc730 FIX: the issue with horizontal scrolling in File Panel, issue #2409
(cherry picked from commit a9b269838a)
2025-07-17 21:24:41 +03:00
Alexander Koblov
9bc17f78f0 FIX: Set focus on the right mouse button click (fixes #2395)
(cherry picked from commit 654eae2e0c)
2025-07-14 20:34:43 +03:00
Alexander Koblov
67a0b57bfa FIX: Possible crash on form close 2025-07-13 14:06:12 +03:00
Alexander Koblov
5f59896293 ADD: SevenZip - more accurate time support (fixes #2381) 2025-06-29 00:03:32 +03:00
Alexander Koblov
c1ff328019 FIX: Diacritics list
(cherry picked from commit a6f85c0c0b)
2025-06-27 23:35:36 +03:00
Alexander Koblov
e535431caf FIX: File creation time is changed to now when file is moved (fixes #2020)
(cherry picked from commit 2bdc88ee2b)
2025-06-27 23:34:01 +03:00
Alexander Koblov
f65c10ad49 ADD: FTP - CLNT command support
(cherry picked from commit bf062ab594)
2025-06-27 23:33:14 +03:00
Alexander Koblov
45bf76b7e2 FIX: Number pad 0 is recognized as a symbol when used as a hotkey (fixes #2277)
(cherry picked from commit 8769a5a248)
2025-06-14 22:46:58 +03:00
Alexander Koblov
c3c28365b9 UPD: Version number 2025-06-14 18:58:58 +03:00
Alexander Koblov
3190c43eb4 FIX: ListLoad - pass directory name with trailing slash (fixes #2041)
(cherry picked from commit 14698a233e)
2025-06-14 18:57:36 +03:00
Alexander Koblov
87de6bfa1f FIX: NormalizeAccentedChar function
(cherry picked from commit ba08ab16cd)
2025-06-13 01:30:07 +03:00
Alexander Koblov
feccc5649e UPD: Diacritics list
(cherry picked from commit 9b94cfa173)
2025-06-13 01:29:59 +03:00
Alexander Koblov
8dd6716a9c ADD: Differ - collapse a home directory in the message box (issue #2345)
(cherry picked from commit 86fba75d0c)
2025-06-07 16:27:51 +03:00
Alexander Koblov
480d73822c UPD: Release workflow
(cherry picked from commit dd23c55109)
2025-06-07 16:27:50 +03:00
Alexander Koblov
876aafca57 FIX: Range check error (fixes #2338)
(cherry picked from commit 3c9894fca3)
2025-06-04 21:18:33 +03:00
Alexander Koblov
47143e0f1c FIX: Rename - select to filename fails in some circumstances (issue #2332)
(cherry picked from commit f6ff7d1337)
2025-06-02 00:23:11 +03:00
Alexander Koblov
4ed0c7336f FIX: Invalid checkboxes state (fixes #2330)
(cherry picked from commit 4154968832)
2025-06-01 19:33:23 +03:00
Alexander Koblov
a7bd1e19c4 FIX: Invalid menu shortcuts (issue #2321)
(cherry picked from commit 548a665a91)
2025-06-01 16:45:11 +03:00
Alexander Koblov
eaf180ff48 FIX: Differ - wrong toolbar buttons sequence
(cherry picked from commit fe99ab9321)
2025-06-01 13:36:57 +03:00
Alexander Koblov
f7a3e44e59 FIX: File types colors dialog gets cropped when resizing window (fixes #2328)
(cherry picked from commit 8c7dea1c64)
2025-06-01 13:02:46 +03:00
Alexander Koblov
8ec76d59a7 UPD: Version number 2025-06-01 01:16:48 +03:00
Alexander Koblov
b8fc7d03bb FIX: Windows XP compatibility
(cherry picked from commit 1af6bd6f7d)
2025-06-01 01:15:01 +03:00
Alexander Koblov
89ab760574 FIX: Viewer - crash with an invalid regular expression
(cherry picked from commit e96a6460b4)
2025-06-01 01:15:00 +03:00
Alexander Koblov
1bb8f0f1cf FIX: Find files - crash with an invalid regular expression (issue #2249)
(cherry picked from commit f63a5a93c5)
2025-06-01 01:15:00 +03:00
Alexander Koblov
624dbdb243 FIX: Use Xwayland with Qt6 version (issue #2290)
(cherry picked from commit 52fed0fea1)
2025-05-31 14:08:56 +03:00
Alexander Koblov
fd6243c053 UPD: DCTheme icon theme 2025-05-31 13:37:58 +03:00
Alexander Koblov
be6bca9465 ADD: Load theme icons list from cache (issue #2297)
(cherry picked from commit c962b5eda0)
2025-05-31 13:27:19 +03:00
Alexander Koblov
29de7d6e01 FIX: Viewer - random crash with enabled caret under Qt (issue #2265)
(cherry picked from commit dd657ed8a1)
2025-05-31 13:23:50 +03:00
Alexander Koblov
3fed40edda FIX: Viewer - enable save action only in the image view mode (fixes #2323)
(cherry picked from commit e7f9679e06)
2025-05-28 21:47:07 +03:00
Alexander Koblov
117d8bbf75 FIX: Cannot focus a disabled or invisible window
(cherry picked from commit 90222158e1)
2025-05-28 21:46:57 +03:00
Alexander Koblov
caee75995c UPD: Use a new toolbar control
(cherry picked from commit b7b47b21c1)
2025-05-25 13:34:01 +03:00
Alexander Koblov
f2634f4d10 FIX: Viewer - wrong toolbar buttons sequence
(cherry picked from commit 3a4700e991)
(cherry picked from commit b6128fae02)
2025-05-25 13:32:12 +03:00
Alexander Koblov
ea1ed2aba3 FIX: Viewer - find-dialog has ugly buttons look (fixes #2301)
(cherry picked from commit 6127c19b04)
2025-05-25 13:24:07 +03:00
Alexander Koblov
09cd3790c1 FIX: TransferLeft and Right commands do not work with folder symbolic links (fixes #2308)
(cherry picked from commit 5fc4cb2e0c)
2025-05-25 13:23:43 +03:00
Alexander Koblov
882800c88b FIX: _SC_NPROCESSORS_ONLN constant value (Linux)
(cherry picked from commit 53f2fb6bc5)
2025-05-23 23:17:08 +03:00
Alexander Koblov
699c605d19 FIX: ELayoutException: TControl.InvalidatePreferredSize loop detected (fixes #2169)
(cherry picked from commit 569a0d1181)
2025-05-23 23:17:08 +03:00
rich2014
d346429a1f UPD: optimize trackpad wheel scrolling #2191
(cherry picked from commit 87a9ba1190)
2025-05-18 19:15:55 +03:00
Alexander Koblov
88e0d9d47a ADD: Swift syntax highlighter
(cherry picked from commit 9a5583c989)
2025-05-18 15:13:49 +03:00
Alexander Koblov
fa716899e1 ADD: Use an additional library search path (Windows)
(cherry picked from commit c0cba942e6)
2025-05-18 15:01:11 +03:00
Alexander Koblov
61673c1aa1 DEL: Obsolete unit
(cherry picked from commit a3cd2d8864)
2025-05-18 15:01:02 +03:00
Alexander Koblov
3e0bcbda9f FIX: Execute QCoreApplication_setAttribute only once
(cherry picked from commit 47f04c0f9a)
2025-05-18 14:33:01 +03:00
Alexander Koblov
9fbea677f6 UPD: Use mbLoadLibraryEx function
(cherry picked from commit 4b65262579)
2025-05-18 00:42:23 +03:00
Alexander Koblov
3e2f2f76d4 FIX: mbLoadLibraryEx function
(cherry picked from commit c8e99df6c3)
2025-05-18 00:42:21 +03:00
Alexander Koblov
ed21f6dead ADD: Print an icons loading time
(cherry picked from commit 1bea1a28b2)
2025-05-17 13:27:45 +03:00
Alexander Koblov
e5e32a8e58 FIX: Partial write
(cherry picked from commit 3879f1658d)
2025-05-17 13:27:21 +03:00
Alexander Koblov
07eea5f9d0 FIX: Lazarus 4.99 compatibility
(cherry picked from commit 68d1c6e4e1)
2025-05-11 12:30:23 +03:00
Alexander Koblov
c731030d25 FIX: Lazarus 4.99 compatibility
(cherry picked from commit e38813f8d5)
2025-05-11 12:29:54 +03:00
Alexander Koblov
63057a3fac FIX: Compatibility with Lazarus 4.99
(cherry picked from commit 11f8742da2)
2025-05-11 12:29:37 +03:00
Alexander Koblov
91fb4f59d2 FIX: Find files - load encodings from search template
(cherry picked from commit 0b21444c15)
2025-05-11 12:26:47 +03:00
Alexander Koblov
190999dd92 UPD: Version number 2025-05-10 18:17:51 +03:00
Alexander Koblov
afc98ed4a5 ADD: Warn about unsaved changes in the file types colors
(cherry picked from commit 4c77384257)
2025-05-10 18:14:16 +03:00
Alexander Koblov
91cab20d38 UPD: Optimize file types colors editing interface (issue #1078)
(cherry picked from commit a5606c0f88)
2025-05-10 18:14:15 +03:00
Alexander Koblov
ad1f683101 UPD: Allow a hard and symbolic link creation from search results
(cherry picked from commit 5b2c3b9334)
2025-05-10 17:54:37 +03:00
Alexander Koblov
3625bc7a4d FIX: Build under FreeBSD
(cherry picked from commit bfc1931ecd)
2025-05-10 17:11:01 +03:00
Alexander Koblov
b2695c0d3d FIX: Create a symbolic link when extract a ZIP-archive under Windows (issue #2298)
(cherry picked from commit ea52d64c6e)
2025-05-10 17:10:25 +03:00
Alexander Koblov
f8d7513354 FIX: Don't allow a control codes in the file names under Windows (fixes #2285) 2025-05-10 17:10:05 +03:00
xBZZZZ
e73b33791b FIX: IntToStrTS when ThousandSeparator is NUL (#1738)
also simplify IntToStrTS (smaller, less variables)
2025-05-10 17:07:56 +03:00
Alexander Koblov
5b42d8637c FIX: Crash at the start with debug build 2025-04-20 16:26:16 +03:00
Alexander Koblov
2ccb72ab65 FIX: Crash at the start with debug build 2025-04-20 16:26:16 +03:00
Alexander Koblov
727d583037 UPD: Image32 library 2025-04-20 16:26:15 +03:00
Alexander Koblov
70f6884531 FIX: Display special folder icons only in the "All associated + EXE/LNK" mode (Windows) 2025-04-20 15:31:10 +03:00
Alexander Koblov
42d61877fc ADD: Load system icon with an absolute path 2025-04-20 15:27:16 +03:00
Alexander Koblov
e9387a3c70 ADD: Get OneDrive folders from registry
(cherry picked from commit 5932fb6658)
2025-04-20 00:22:05 +03:00
Alexander Koblov
2b5adfb10e UPD: DetectEncoding - return a normalized encoding name
(cherry picked from commit c072da45b5)
2025-04-19 15:29:27 +03:00
Alexander Koblov
51b94c0954 UPD: Release workflow
(cherry picked from commit 15ef437b1e)
2025-04-19 14:07:54 +03:00
Alexander Koblov
37b44f0ed8 UPD: Librsvg library search algorithm
(cherry picked from commit 67da3fbabb)
2025-04-19 14:07:44 +03:00
Alexander Koblov
73cb90e63c UPD: mbLoadLibraryEx function
(cherry picked from commit 2dd9817eb9)
2025-04-19 14:07:44 +03:00
Alexander Koblov
415d587bb0 UPD: GetModuleHandleW function
(cherry picked from commit ab26e0eafb)
2025-04-19 14:07:44 +03:00
Alexander Koblov
ef0c2b68f2 UPD: Bulgarian language file 2025-04-19 00:45:50 +03:00
Alexander Koblov
3d546bcb45 FIX: FTP - show error message when cannot load/save settings (fixes #2264)
(cherry picked from commit 63b392d46c)
2025-04-19 00:41:06 +03:00
Alexander Koblov
dcaeb045a6 ADD: TFileStreamEx.Create - show system error message
(cherry picked from commit 685f55b514)
2025-04-19 00:40:56 +03:00
Alexander Koblov
4f11eb7c64 ADD: Use built-in HEIC decoder in Windows 11 24H2
(cherry picked from commit 3e8adb9b93)
2025-04-19 00:40:44 +03:00
Alexander Koblov
e3c3453a42 FIX: Viewer - remove a border in the full screen view (fixes #2235)
(cherry picked from commit 0f43599f75)
2025-04-19 00:40:34 +03:00
Alexander Koblov
f094c70a4a ADD: FTP - better SSH-handshake error logging
(cherry picked from commit d3f15d726c)
2025-04-19 00:40:25 +03:00
Alexander Koblov
4d241dc120 UPD: Don't use SMB1 under Windows 10+
(cherry picked from commit db4feb4e0a)
2025-04-11 18:20:14 +03:00
Alexander Koblov
9fabdb6e99 FIX: Enable resource sharing between the OpenGL contexts (needs by plugins)
(cherry picked from commit caf1d3f080)
2025-04-05 18:24:23 +03:00
Alexander Koblov
37167887c9 FIX: Viewer - crash with unreadable file
(cherry picked from commit e701968cd1)
2025-04-05 18:24:05 +03:00
Alexander Koblov
0ab13eca08 DEL: Standard files
(cherry picked from commit d39ea6e021)
2025-04-05 18:23:44 +03:00
Alexander Koblov
952f12f631 FIX: OneDrive sync status icon overlays not showing (fixes #474)
(cherry picked from commit 5cedc12d24)
2025-04-05 18:21:43 +03:00
Alexander Koblov
3e3ecc9432 UPD: Version number 2025-04-01 20:15:40 +03:00
Alexander Koblov
3f46a0408a UPD: Microsoft Photos bug workaround
(cherry picked from commit 98cc551cf8)
2025-04-01 20:13:13 +03:00
Alexander Koblov
387457bf6e FIX: Find files with long file names under macOS
(cherry picked from commit 37b0a3ff8b)

FIX: Build under ARM64 (macOS)
(cherry picked from commit e89064de97)
2025-03-23 21:15:02 +03:00
VenusGirl❤
a9f808e6bc
UPD: Korean language file (#2239) 2025-03-23 20:49:47 +03:00
Alexander Koblov
3adf7b07d1 UPD: Korean language file 2025-03-22 18:55:27 +03:00
Alexander Koblov
15e166ecde FIX: Restore focus after exit from quick search (issue #2152)
(cherry picked from commit 788c934f43)
2025-03-22 00:30:15 +03:00
Alexander Koblov
9436bd15c6 FIX: Wrong content type guess (issue #2195)
(cherry picked from commit 1a84836c2e)
2025-03-19 22:27:05 +03:00
Alexander Koblov
9cee7263d1 FIX: Image file associated to Windows Photos opens only when there are no spaces in file name/path (fixes #2188)
(cherry picked from commit f7ba104e48)
2025-03-19 22:25:48 +03:00
Alexander Koblov
8490889e7b FIX: Viewer - disable unavailable menu items
(cherry picked from commit 32532a344c)

FIX: Viewer - disable unavailable menu items
(cherry picked from commit ca531db075)
2025-03-19 22:24:33 +03:00
Alexander Koblov
808d1ef88d FIX: Changing the extensions for a highlighter and clicking Apply doesn't save them (fixes #2182)
(cherry picked from commit a2d8afae68)
2025-03-14 13:17:26 +03:00
Alexander Koblov
0ac62190c3 FIX: Viewer - disable unavailable menu items (issue #2212)
(cherry picked from commit 3180cb924c)
2025-03-12 12:53:28 +03:00
Alexander Koblov
7e7f48d70e FIX: GVFS - Overwrite only older files (fixes #2201)
(cherry picked from commit fd6d5a8085)
2025-03-10 12:52:56 +03:00
Alexander Koblov
031cf26473 FIX: Copy WSL/Cygwin symbolic links (issue #2171) 2025-03-01 12:42:59 +03:00
Alexander Koblov
f88f810a2e UPD: Synchronize with master branch 2025-03-01 00:59:42 +03:00
Alexander Koblov
4d57ae4caa FIX: Read a special characters from doublecmd.xml (fixes #2176)
(cherry picked from commit 85faf82d4b)
2025-02-28 22:04:31 +03:00
Alexander Koblov
d801cf8cda ADD: Read WSL/Cygwin symbolic link target (issue #2171)
(cherry picked from commit 67d210711b)
2025-02-28 22:04:24 +03:00
Alexander Koblov
cc4fffc980 FIX: Viewer - wrong text wrapping (fixes #2183)
(cherry picked from commit 0c47b49589)
2025-02-28 22:03:36 +03:00
Alexander Koblov
aa50acce68 FIX: Copy relative symbolic links under Windows (issue #2171)
(cherry picked from commit 52ee174822)
2025-02-28 22:03:24 +03:00
Alexander Koblov
3619468fcc FIX: Zip - compiling 2025-02-16 13:21:29 +03:00
Alexander Koblov
db7f80e80d FIX: Viewer - don't show empty cells in the thumbnails view
(cherry picked from commit e853cdadd9)
2025-02-16 13:14:21 +03:00
Alexander Koblov
c22653fb50 FIX: Viewer - preview thumbnail vertical space (issue #2070)
(cherry picked from commit 38a5f529d9)
2025-02-16 13:14:08 +03:00
Alexander Koblov
72d249537c ADD: Viewer - calculate a folder size
(cherry picked from commit 9ec8f9d483)
2025-02-16 13:13:56 +03:00
Alexander Koblov
8a2b8f5e88 UPD: Use LC_CTYPE to determine locale under Linux
(cherry picked from commit e650495a5a)
2025-02-16 01:13:21 +03:00
Alexander Koblov
bd50861ef6 FIX: Zip - Invalid pointer operation
(cherry picked from commit 054cebe599)
2025-02-15 15:39:20 +03:00
Alexander Koblov
e9c1c8fbd6 UPD: Zip - speed up .zip extraction
(cherry picked from commit dcde783795)
2025-02-15 15:39:19 +03:00
Alexander Koblov
cd27187ac4 DEL: Obsolete units
(cherry picked from commit 255ecc7bda)
2025-02-15 15:39:19 +03:00
Alexander Koblov
035e47a3d7 FIX: Zip - Use new Deflate64 decoder (fixes #2115)
(cherry picked from commit 4fe27b1287)
2025-02-15 15:38:34 +03:00
Alexander Koblov
1ce1606fda ADD: Zip - New Deflate64 decoder (issue #2115)
(cherry picked from commit 5b60341ad7)
2025-02-15 15:38:33 +03:00
Alexander Koblov
c8be36cef6 FIX: Crash with absolute symbolic links (GVFS)
(cherry picked from commit 7d7a729773)
2025-02-15 14:38:01 +03:00
Alexander Koblov
d9a6bba4cf ADD: Copy directory time (GVFS)
(cherry picked from commit 8134add0e6)
2025-02-15 14:38:01 +03:00
Alexander Koblov
52c0d620cc FIX: Get monospace font under Linux (fixes #2062)
(cherry picked from commit 1b1ca89bc1)
2025-02-11 20:12:05 +03:00
Alexander Koblov
939dc5926d FIX: Wrong statistics when copying to phone (issue #2154)
(cherry picked from commit 7c80c8ab23)
2025-02-11 20:11:57 +03:00
Alexander Koblov
470ac231a2 FIX: Disable preview in the quick view mode
(cherry picked from commit f1d0a2c9d9)
2025-02-11 20:11:11 +03:00
Alexander Koblov
8943848d1d ADD: Load folder system icon under Linux when an absolute icon file name used (fixes #2061)
(cherry picked from commit d3a2c1b0d4)
2025-02-09 00:18:27 +03:00
Alexander Koblov
00d46d50af UPD: Version number 2025-02-02 16:08:18 +03:00
Alexander Koblov
e22bb3df89 FIX: Build under GTK2
(cherry picked from commit 4913c46b61)
2025-02-01 23:20:05 +03:00
Alexander Koblov
f746d25109 FIX: Copy and paste files with a newline character (fixes #2085)
(cherry picked from commit a0eaa37f04)
2025-02-01 23:20:05 +03:00
Alexander Koblov
6baafba866 Revert "UPD: Initialize OnGetApplicationName early"
This reverts commit 3a33650a89.
2025-01-18 23:01:52 +03:00
Alexander Koblov
4a0bcd0fa1 ADD: JSON highlighter
(cherry picked from commit 85d1985b9f)
2025-01-18 12:59:10 +03:00
Alexander
906ce2a6e6 ADD: QML syntax highlighter (#2040)
(cherry picked from commit 3cff308d7b)
2025-01-18 12:59:10 +03:00
Alexander Koblov
677adc3cde UPD: Try to create .dmg package 5 times
(cherry picked from commit 7475060655)
2025-01-18 12:57:33 +03:00
j2969719
7ea476cace UPD: Use -sfx switch for rar (#1996)
(cherry picked from commit 5b04565930)
2025-01-18 12:51:53 +03:00
Alexander Koblov
e4b509073c FIX: Viewer - zoom image by mouse wheel
(cherry picked from commit 884720a573)
2025-01-16 22:03:24 +03:00
Alexander Koblov
5787eea73d FIX: Limit max file descriptor number (fixes #2004)
(cherry picked from commit d2b624be18)
2025-01-16 22:03:24 +03:00
Alexander Koblov
748d20e1be FIX: Wrong icon size
(cherry picked from commit 5fbaae7732)
2025-01-13 23:57:11 +03:00
Alexander Koblov
1898608413 FIX: Invalid SVG scaling (fixes #2068)
(cherry picked from commit a15f560ea3)
2025-01-13 23:57:11 +03:00
Alexander Koblov
628dce73bf FIX: Hitting Tab key when Quick Preview open applies focus both file panes (fixes #2079)
(cherry picked from commit e1fbd5c089)
2025-01-12 22:16:55 +03:00
Alexander Koblov
13a1173092 ADD: Allow to use archive icon from built-in theme
(cherry picked from commit 8914e6cd13)
2025-01-12 22:16:47 +03:00
Alexander Koblov
ece4fe1dd2 ADD: Prepare to disable a GTK2 workaround
(cherry picked from commit 671df91744)
2025-01-12 22:16:46 +03:00
Alexander Koblov
3a33650a89 UPD: Initialize OnGetApplicationName early
(cherry picked from commit 7a4ac40739)
2025-01-12 22:13:57 +03:00
Alexander Koblov
2626a317f0 FIX: Unable to make a privileged operation if app's executable has non-default file name in linux (fixes #2071)
(cherry picked from commit 4fc93d275c)
2025-01-12 22:13:44 +03:00
Alexander Koblov
9a8e9f827e FIX: Crash under GTK2 (fixes #2069)
(cherry picked from commit 2a2862c0f1)
2025-01-12 22:13:28 +03:00
Alexander Koblov
451c7afdf1 UPD: GetSystemFolderIcon function under Linux
(cherry picked from commit 026e9755d8)
2025-01-12 22:13:28 +03:00
Alexander Koblov
e31aab2f5e FIX: Load folder system icon under Linux (fixes #2061)
(cherry picked from commit 0135b6d4e8)
2025-01-12 22:13:27 +03:00
Alexander Koblov
14aa2b6a7b ADD: Create directory - option to disable auto-complete (fixes #1494)
(cherry picked from commit f9c2c136ae)
2025-01-07 19:54:04 +03:00
Alexander Koblov
6e56938dc1 FIX: Read fonts settings from xml-config (fixes #2052)
(cherry picked from commit cad083f6e8)
2025-01-07 16:37:16 +03:00
Alexander Koblov
3461456384 FIX: Hotkey list background is not cleared (fixes #2044)
(cherry picked from commit a79429eedc)
2025-01-07 16:36:42 +03:00
Alexander Koblov
ba4d6b029a FIX: The height of color ComboBox is too small (fixes #2043)
(cherry picked from commit 17fb9dcb9d)
2025-01-07 16:36:33 +03:00
Alexander
211973f489 ADD: Kotlin syntax highlighter (#2034)
(cherry picked from commit a769421642)
2024-12-29 19:32:19 +03:00
Alexander Koblov
ab816613d1 FIX: WinToUnixFileAttr function
(cherry picked from commit bbf030a6aa)
2024-12-29 19:32:10 +03:00
Alexander Koblov
3845a75d3b FIX: WCX - restore directory attributes after CloseArchive
(cherry picked from commit c7cf06829c)
2024-12-29 19:31:59 +03:00
Alexander Koblov
90ad99a69f ADD: Display GTK3 version
(cherry picked from commit 0b3b2deb89)
2024-12-29 19:31:38 +03:00
Alexander Koblov
011028db4d DEL: Invalid version information
(cherry picked from commit 63cd93783a)
2024-12-29 19:31:29 +03:00
Alexander Koblov
a712e16765 FIX: Viewer - problem with RegEx search, it cannot find 'qt' case-insensitive (fixes #2012)
(cherry picked from commit d5b2c51a67)
2024-12-29 19:31:14 +03:00
Alexander Koblov
f57d2e9cad UPD: Version number 2024-12-16 23:14:53 +03:00
Alexander Koblov
45caf2da51 FIX: Extra semicolon after "then"
(cherry picked from commit 530aafdc2d)
2024-12-16 23:12:53 +03:00
Alexander Koblov
fd15280abd FIX: Quick view panel crash (fixes #2011)
(cherry picked from commit f0f2b02c53)
2024-12-16 22:58:24 +03:00
Alexander Koblov
4f4a743d04 FIX: Use UTF8StringReplace
(cherry picked from commit ebed22101e)
2024-12-16 22:58:14 +03:00
Alexander Koblov
ed59afc8ba FIX: Multi-line pattern search option state
(cherry picked from commit eb2bf85573)
2024-12-16 22:58:06 +03:00
Alexander Koblov
9c148b2223 ADD: Try to create .dmg package multiple times
(cherry picked from commit 1c09afa958)
2024-11-30 15:03:05 +03:00
Alexander Koblov
ee18b23087 UPD: Release workflow 2024-11-30 15:02:08 +03:00
Alexander Koblov
c7f8c9e5fb DEL: Unused unit
(cherry picked from commit 3eeb0aeaa0)
2024-11-30 14:11:43 +03:00
Alexander Koblov
cbec6de865 UPD: Sound notifications - disable by default
(cherry picked from commit dbfd5abb79)
2024-11-30 14:11:00 +03:00
Alexander Koblov
b9a2874217 FIX: SevenZip - memory leak 2024-11-30 13:31:25 +03:00
Alexander Koblov
b1a1c07e95 FIX: SevenZip - extract empty files (issue #1672)
(cherry picked from commit f827859854)
2024-11-30 13:26:37 +03:00
Alexander Koblov
9d29d5d10f ADD: SevenZip - long file name support (issue #1672) 2024-11-30 13:23:44 +03:00
Alexander Koblov
014ac5a0a6 Revert "UPD: Disable modification of temporary archives"
This reverts commit 740d699f61.
2024-11-29 23:51:01 +03:00
Alexander Koblov
451517832e UPD: PackInfoDlg - file size formatting
(cherry picked from commit 45402ba3d1)
2024-11-28 23:25:19 +03:00
j2969719
d35debe202 UPD: Hide invalid props (#1832)
(cherry picked from commit 9e26803e53)
2024-11-28 23:25:02 +03:00
Alexander Koblov
72cf1165e7 FIX: Don't check a disk free space for file systems which don't have a disk size (issue #753)
(cherry picked from commit db7dfa19fb)
2024-11-28 23:22:11 +03:00
Alexander Koblov
a10c06cec8 ADD: RPM - dependencies information
(cherry picked from commit 6ec5f573b9)
2024-11-28 23:21:51 +03:00
Alexander Koblov
740d699f61 UPD: Disable modification of temporary archives
(cherry picked from commit 23252a36f9)
2024-11-28 23:21:38 +03:00
Alexander Koblov
6eb3e31fec ADD: Play sounds using GStreamer under Linux/FreeBSD
(cherry picked from commit dabd5fbdc2)
2024-11-14 21:15:06 +03:00
Alexander Koblov
e6c959cbc5 ADD: Play sounds using SDL2 under Linux/FreeBSD
(cherry picked from commit ef94d8327b)
2024-11-14 21:15:05 +03:00
Skif-off
0690552c92 ADD: Sound notifications: enable/disable feature; environment variables in paths. (#1866)
(cherry picked from commit 731cf1cfb0)
2024-11-14 21:15:05 +03:00
Alexander Koblov
56e640281c ADD: Feature [0002306] Notification about the end of a long running operation (step 2)
(cherry picked from commit fefa77a1b0)
2024-11-14 21:13:44 +03:00
Alexander Koblov
112631e160 ADD: Feature [0002306] Notification about the end of a long running operation (step 1)
(cherry picked from commit 27849c0dcd)
2024-11-14 21:13:43 +03:00
Alexander Koblov
6c7f86cd4d ADD: Play sound unit
(cherry picked from commit a07d47b1c5)
2024-11-14 21:13:43 +03:00
Alexander Koblov
c8153f8d9f UPD: SyncDirs - file size formatting
(cherry picked from commit b9e5f1a772)
2024-11-14 21:09:25 +03:00
Alexander Koblov
20c484a2cb UPD: Version number 2024-11-11 19:57:43 +03:00
Alexander Koblov
ec3e2c130c UPD: CheckPhotosVersion - optimization
(cherry picked from commit 503584708b)
2024-11-11 19:56:06 +03:00
Alexander Koblov
7f56a8b1a9 ADD: Open images in the Microsoft Photos application starting with version 2024.11050.3002.0 and above
(cherry picked from commit 4c8aa72a3c)
2024-11-11 19:56:06 +03:00
Alexander Koblov
d7d098956c UPD: German language files 2024-11-10 13:39:28 +03:00
Alexander Koblov
dc1f91e6b3 FIX: FTP - Build under Haiku
(cherry picked from commit 5951ace48d)
2024-11-10 13:36:04 +03:00
Alexander Koblov
99b76b3668 ADD: FTP - Print address resolving status
(cherry picked from commit df4164b626)
2024-11-10 13:36:03 +03:00
Alexander Koblov
536fd18063 FIX: FTP - ResolveName under macOS (issue #1604)
(cherry picked from commit 2aa9fe2f5a)
2024-11-10 13:36:03 +03:00
Alexander Koblov
b306e9e36d ADD: Better hotkey conflict detection (issue #1841)
(cherry picked from commit 792e73b463)
2024-11-10 12:47:53 +03:00
Alexander Koblov
d40d810712 UPD: Disable Samba plugin
(cherry picked from commit 8996c1bc15)
2024-11-09 13:47:46 +03:00
Alexander Koblov
4a9d2b841d ADD: Simple network file source (via GIO) 2024-11-09 13:23:28 +03:00
Alexander Koblov
069d583849 UPD: Release workflow
(cherry picked from commit e86a46ae17)
2024-11-06 23:39:09 +03:00
Alexander Koblov
6755986dbe FIX: Memory leak
(cherry picked from commit f43748ee0e)
2024-11-04 00:14:00 +03:00
Alexander Koblov
6f82d9ab2c FIX: Create symbolic link - forward error code (Windows)
(cherry picked from commit 600edcc021)
2024-11-04 00:01:38 +03:00
Alexander Koblov
067b4b1e2d ADD: Create symbolic link error - skip all button
(cherry picked from commit dd7128a35f)
2024-11-04 00:01:38 +03:00
rich2014
27793f67d0 FIX: leaks in MacPreview
(cherry picked from commit d498e63c20)
2024-11-04 00:00:03 +03:00
Alexander Koblov
a461879e5b ADD: SevenZip - self-extract module
(cherry picked from commit 8ae7b5ca3a)
2024-10-31 23:39:26 +03:00
Alexander Koblov
cc87ab6421 FIX: Viewer - code mode and a byte order mark
(cherry picked from commit 7e347cffcd)
2024-10-31 23:39:19 +03:00
Alexander Koblov
9f36d76df9 FIX: DC does not close "Options" on pressing ESC after you selected "Tooltips" section (fixes #1929)
(cherry picked from commit 0b35d32a7a)
2024-10-28 00:06:22 +03:00
Alexander Koblov
02383cc688 FIX: Crash on viewing directory symlink on Linux (fixes #1942)
(cherry picked from commit 8e7dcd1477)
2024-10-28 00:06:03 +03:00
Alexander Koblov
a0c6cbc964 FIX: Background context menu font (fixes #1917)
(cherry picked from commit 14abe92c63)
2024-10-28 00:05:35 +03:00
Alexander Koblov
b3a7e2b219 FIX: Labels and panels background color
(cherry picked from commit 1bf48d63dd)
2024-10-19 14:34:39 +03:00
Alexander Koblov
8cc5e80bd0 FIX: Labels background color (issue #1885)
(cherry picked from commit 3fc2fa3428)
2024-10-19 14:34:39 +03:00
Alexander Koblov
95ec7c4af1 UPD: Version number 2024-10-19 14:32:57 +03:00
Alexander Koblov
f5702e6dbb FIX: Get current icon theme name
(cherry picked from commit c0b4c5521f)
2024-10-19 14:31:33 +03:00
Alexander Koblov
9e048ac7e0 UPD: Greek language file 2024-10-19 13:58:46 +03:00
Alexander Koblov
9dd31c2e92 UPD: Inno Setup script 2024-10-06 14:45:57 +03:00
Alexander Koblov
0cdb3ca9d1 FIX: TKASCDEdit - ReadOnly flag
(cherry picked from commit 87ae081b9b)
2024-10-06 13:53:06 +03:00
Alexander Koblov
fbfbce839c UPD: Don't show '*' in the tabs list menu (issues #1890, #1784)
(cherry picked from commit c13e3a07e6)
2024-10-06 13:52:55 +03:00
Alexander Koblov
445461bec1 FIX: Panels background color (issue #1889)
(cherry picked from commit 66dedd742c)
2024-10-06 13:52:40 +03:00
Alexander Koblov
3b63b5aa67 FIX: Panels background color (issue #1889)
(cherry picked from commit f5a67b9883)
2024-10-06 13:52:39 +03:00
Alexander Koblov
f02511c0b3 ADD: Drag and drop - option to move instead copy (fixes #271)
(cherry picked from commit c42011485b)
2024-10-04 22:52:14 +03:00
j2969719
150af300ad FIX: Unix attr color (#1871)
(cherry picked from commit df4c16a213)
2024-10-04 22:29:17 +03:00
Alexander Koblov
128ff3f087 FIX: SFTP - execute command in the current directory
(cherry picked from commit 3293676910)
2024-10-04 22:28:59 +03:00
Alexander Koblov
7bc216b8b1 FIX: Reset busy flag on abort
(cherry picked from commit d298af4453)
2024-10-04 22:28:59 +03:00
Alexander Koblov
0ab5113eca FIX: History - save a last active file when open archive
(cherry picked from commit a0eac93139)
2024-09-26 23:07:02 +03:00
Alexander Koblov
3006bed3ee UPD: Load Double Commander icon from resources
(cherry picked from commit e906196a37)
2024-09-26 23:06:45 +03:00
Alexander Koblov
71418abb86 FIX: SyncDirs - template with exclude directories
(cherry picked from commit 466cca2851)
2024-09-26 23:06:35 +03:00
Alexander Koblov
b153f457af FIX: Reset mouse state (after using extra buttons)
(cherry picked from commit 5adb793286)
2024-09-26 23:06:35 +03:00
Alexander Koblov
2afd36d602 FIX: Synchronize directories - the vertical scroll bar will not update the content of the list view when dragged with the mouse (fixes #1855)
(cherry picked from commit 62dd19e08b)
2024-09-26 23:06:18 +03:00
Alexander Koblov
d2a8eb26a0 UPD: Version number 2024-09-22 15:46:26 +03:00
Alexander Koblov
9fd1e71a04 FIX: Don't show virtual folders
(cherry picked from commit 483bbef8db)
2024-09-22 15:39:59 +03:00
Alexander Koblov
7ad816ff17 FIX: Access Violation when open TAR archive (fixes #1849)
(cherry picked from commit 81af12959d)
2024-09-22 15:39:50 +03:00
Alexander Koblov
c45365d1bc FIX: The function "Show Occupied Space" does not distinguish between 0-size directories and non-accessible directories (issue #1846)
(cherry picked from commit e32c0398f3)
2024-09-21 14:39:08 +03:00
Alexander Koblov
d93942deab FIX: Viewer - Ctrl+End (go to file end) goes incorrect (fixes #817)
(cherry picked from commit 1da73f2809)
2024-09-21 14:38:57 +03:00
Alexander Koblov
4474269032 UPD: Release workflow 2024-09-21 14:36:45 +03:00
Alexander Koblov
413e1e8398 FIX: FileIsUnixExecutable function result with zero size file
(cherry picked from commit c0c13d5e17)
2024-09-18 21:59:34 +03:00
Alexander Koblov
bba22702ab FIX: Disable workaround with Lazarus >= 3.2
(cherry picked from commit 9bb9d0f9bc)
2024-09-18 21:59:33 +03:00
Alexander Koblov
2301bc2081 UPD: Allocate space using an independent property
(cherry picked from commit fa9bf4e35b)
2024-09-17 00:02:34 +03:00
Alexander Koblov
1ee9f00fcc FIX: Free Pascal >= 3.0 compatibility
(cherry picked from commit f462a30d51)
2024-09-17 00:02:33 +03:00
Alexander Koblov
69bdf3c02f FIX: FileAllocate function
(cherry picked from commit 6f44e95e14)
2024-09-17 00:00:01 +03:00
Alexander Koblov
dfe6006ec8 FIX: Don't use pre-allocation of disk space on the FAT32 under Linux (fixes #1739)
(cherry picked from commit c4ae646f00)
2024-09-17 00:00:00 +03:00
Alexander Koblov
7d895fb6aa FIX: Set focus by right mouse button (Qt)
(cherry picked from commit b99af5fc32)
2024-09-15 22:59:58 +03:00
Alexander Koblov
515060f869 FIX: Extend cell width if text is not fitting into column under Qt (issue #1811)
(cherry picked from commit a489af1a7c)
2024-09-15 22:58:06 +03:00
Alexander Koblov
314edd30ef FIX: Wrong text decoding in internal differ tool (fixes #1816)
(cherry picked from commit 65b46ae819)
2024-09-15 22:58:06 +03:00
Alexander Koblov
82e0f019a0 UPD: Version number 2024-09-07 01:48:11 +03:00
Alexander Koblov
b6b1b81a5c UPD: Speed up checksum calculation
(cherry picked from commit 718d279ea7)
2024-09-07 01:46:05 +03:00
Alexander Koblov
25e13b3983 UPD: KAScrypt - clean up
(cherry picked from commit 7d644055cd)
2024-09-07 01:46:05 +03:00
Alexander Koblov
1ef959fa97 UPD: BLAKE3 - synchronize asm-code with upstream
(cherry picked from commit 855fbfe8f8)
2024-09-07 01:46:04 +03:00
Alexander Koblov
52fc67529f FIX: Drive list - non-letter hotkeys (Windows)
(cherry picked from commit c159f39a8a)
2024-09-07 01:46:04 +03:00
Alexander Koblov
3699a78c45 FIX: Overwrite older (fixes #1786)
(cherry picked from commit 3df381014e)
2024-09-07 01:46:04 +03:00
Alexander Koblov
49c9f167ac FIX: Swapping panels causes the drive name in the inactive panel to be inconsistent (fixes #1723)
(cherry picked from commit 9f5efd0547)
2024-09-07 01:46:04 +03:00
Alexander Koblov
280cdc3888 ADD: mbFileGetTime function
(cherry picked from commit a1402335f2)
2024-09-07 01:46:03 +03:00
Alexander Koblov
f4189f2139 ADD: SyncDirs - stop compare by content
(cherry picked from commit 2a57395f58)
2024-08-15 22:19:57 +03:00
Skif-off
4149c05afc ADD: SyncDirs: 'Unknown' filter (#1728)
(cherry picked from commit f822e0751b)
2024-08-15 22:19:56 +03:00
Alexander Koblov
6da6ca3988 FIX: Build macOS releases
(cherry picked from commit e60cfd00a3)
2024-08-15 22:19:01 +03:00
Alexander Koblov
255fc9a8df UPD: Differ - use new mbFileIsText function
(cherry picked from commit 82e33bb641)
2024-08-15 21:39:00 +03:00
Alexander Koblov
29c68b758a ADD: Viewer - don't use code mode with binary files (issue #1778)
(cherry picked from commit 12528b977c)
2024-08-15 21:38:59 +03:00
Alexander Koblov
58e1181977 ADD: mbFileIsText function
(cherry picked from commit 72481da2ea)
2024-08-15 21:38:59 +03:00
Alexander Koblov
edc41b641c FIX: Viewer - Incorrect selection offset after search in Text mode (issue #1755)
(cherry picked from commit 1ee7a6b2b8)
2024-08-15 21:38:40 +03:00
Alexander Koblov
c9ef3e431a ADD: Show system (root) drive under macOS (fixes #1640)
(cherry picked from commit fcca7ac789)
2024-08-11 22:33:21 +03:00
Alexander Koblov
07820a8afa UPD: Relocate some Linux specific code
(cherry picked from commit 1a6b8338af)
2024-08-09 23:20:45 +03:00
Alexander Koblov
ca4ccfdab5 FIX: Range check error
(cherry picked from commit 06af97c346)
2024-08-03 22:42:29 +03:00
Alexander Koblov
7640357bca Revert "FIX: SevenZip - password dialog priority"
This reverts commit 0aef56bc46.

(cherry picked from commit fcbdf75482)
2024-08-03 22:42:29 +03:00
Alexander Koblov
4c51c72d89 UPD: Use DirHistoryCount with context menu only
(cherry picked from commit 048a8511a5)
2024-08-03 22:42:28 +03:00
rich2014
20cfa4e47f UPD: Uniform Type Identifiers framework supported on x86_64
use -weak_framework instead of linkframework

(cherry picked from commit 8d886d686d)
2024-08-03 22:42:28 +03:00
Alexander Koblov
3a6be9bd44 ADD: Navigation through directory global history menu
(cherry picked from commit f3d000321f)
2024-08-03 22:42:28 +03:00
Alexander Koblov
7a02fcb1e9 ADD: Make DirHistoryCount configurable (fixes #1736)
(cherry picked from commit 0092c7afa7)
2024-08-03 22:42:28 +03:00
Alexander Koblov
5a42260fbd UPD: Version number 2024-07-23 13:51:37 +03:00
Alexander Koblov
d4401c2923 FIX: Don't reload file list on brightness level of inactive panel change (fixes #1760)
(cherry picked from commit f21aa9cc86)
2024-07-23 13:47:12 +03:00
Alexander Koblov
e7420de849 FIX: Don't show dark mode settings under old Windows versions (fixes #1760)
(cherry picked from commit 74e742c26b)
2024-07-23 13:47:11 +03:00
rich2014
40248df74c FIX: set MACOSX_DEPLOYMENT_TARGET=10.11 in create_packages.mac to keep it consistent with other scripts
extractdwrflnfo didn't support 10.5

(cherry picked from commit 30336f33c0)
2024-07-23 13:47:04 +03:00
Alexander Koblov
1e6d500c1e FIX: Zip - crash on file replace with some .tar archives (fixes #1744)
(cherry picked from commit 752d3c9f23)
2024-07-23 13:46:53 +03:00
Alexander Koblov
dfb20dc45f UPD: Don't hide folders with system attribute under Windows (fixes #1741)
(cherry picked from commit 06a5cc8fa2)
2024-07-23 13:46:36 +03:00
Alexander Koblov
edf588ff5a FIX: Cmd key named as Winkey on DC for macOS (fixes #1733)
(cherry picked from commit 7e2421de3e)
2024-07-23 13:46:28 +03:00
rich2014
5828d0beb6 UPD: detect Encoding by the first 4KB in Viewer, keep consistent with the Editor
(cherry picked from commit 900b369d5c)
2024-07-23 13:45:47 +03:00
rich2014
627c926a29 UPD: encoding name mapping for Chinese, Japanese, and Korean in MyDetectCodePageType()
(cherry picked from commit 4f4c53dcb1)
2024-07-23 13:45:34 +03:00
rich2014
e467765695 Fix: subtle synchronization issue related to Grids in DisplayFileListChanged()
(cherry picked from commit dc2d77a5bf)
2024-07-23 13:45:22 +03:00
Alexander Koblov
4ecba56cd5 FIX: Mouse cursor action indicators graphical issues (fixes #1729)
(cherry picked from commit 55da32615a)
2024-07-23 13:43:17 +03:00
Alexander Koblov
890bd24569 ADD: Open images in the Microsoft Photos application under Windows 11 (build >= 22631)
(cherry picked from commit 6270e0920a)
2024-07-23 13:43:01 +03:00
Arkanoid1973
f9842b44ff
UPD: French translation (#1731) 2024-06-27 20:33:09 +03:00
Alexander Koblov
ca77fea987 ADD: UnRAR - more accurate time support
(cherry picked from commit caae56af3e)
2024-06-22 13:08:04 +03:00
Alexander Koblov
b4bc7c2a03 ADD: Zip - more accurate time support (fixes #1700)
(cherry picked from commit d0f9193461)
2024-06-22 13:08:04 +03:00
Alexander Koblov
0c882703d3 ADD: Wcx-plugins - more accurate time support
(cherry picked from commit 1b9671eda7)
2024-06-22 13:08:03 +03:00
Alexander Koblov
759ccd600b UPD: Use TFileTimeEx type
(cherry picked from commit 24edd85df6)
2024-06-22 13:07:54 +03:00
Alexander Koblov
dd87909edf FIX: Allow negative Unix-time (issue #1700)
(cherry picked from commit 035cee8d76)
2024-06-22 13:07:54 +03:00
Alexander Koblov
e3fb00b1e9 UPD: Use TFileTimeEx type
(cherry picked from commit dde35d68dd)
2024-06-22 13:07:54 +03:00
Alexander Koblov
262e4b383e FIX: Mount drive
(cherry picked from commit 573515e601)
2024-06-21 23:26:49 +03:00
Alexander Koblov
6f76129d06 ADD: Don't show extensions for special items
(cherry picked from commit cd3746da5e)
2024-06-21 23:25:52 +03:00
Alexander Koblov
638fa8a748 FIX: Access denied checking (fixes #1725)
(cherry picked from commit a0a9221472)
2024-06-21 23:24:30 +03:00
Alexander Koblov
68107f6e08 UPD: About - link colors
(cherry picked from commit ce960e0774)
2024-06-21 23:24:21 +03:00
Alexander Koblov
bd6c8c30a3 FIX: System language detection (issue #1724)
(cherry picked from commit e410909169)
2024-06-21 23:24:21 +03:00
Alexander Koblov
52b5319f71 FIX: Project file
(cherry picked from commit 8c857bd6d2)
2024-06-21 23:24:08 +03:00
Alexander Koblov
8a0c36d921 UPD: UnRAR - RARHeaderDataEx type
(cherry picked from commit 80d4477cc0)
2024-06-21 23:22:59 +03:00
Alexander Koblov
ecef381065 UPD: Version number 2024-06-16 16:34:30 +03:00
Alexander Koblov
841e0a616f FIX: Renaming through the context menu in place stopped working (fixes #1711)
(cherry picked from commit f996c38bed)
2024-06-16 16:32:49 +03:00
Alexander Koblov
28125592ab UPD: Release workflow
(cherry picked from commit fca1db719a)
2024-06-12 13:40:41 +03:00
Alexander Koblov
089ab3cdb6 ADD: Go highlighter
(cherry picked from commit eb05d249ce)
2024-06-12 12:40:29 +03:00
rich2014
462a88c449 FIX: mouse Scroll Lines limit in Options (min=1 and max=0 before, not follow LCL specifications)
(cherry picked from commit 0f2e388a29)
2024-06-12 12:40:05 +03:00
Alexander Koblov
75f3da0160 FIX: Delete-window auto-size (fixes #1667)
(cherry picked from commit 193dc62a3a)
2024-06-09 23:14:14 +03:00
Alexander Koblov
83a7cb49c5 FIX: Open/Save dialogs all files filter
(cherry picked from commit ce4eb5ebb0)
2024-06-09 23:14:14 +03:00
Alexander Koblov
73e91c9bc7 FIX: Build under Windows (fixes #1702)
(cherry picked from commit 22110c33c7)
2024-06-09 23:14:13 +03:00
rich2014
5f8ddd0e6c FIX #1680: Internal Viewer crashes on macOS
in FPC 3.2.2, there are some bugs in Iconvert().
use the fixed Iconvert() instead of the FPC version on macOS.

(cherry picked from commit 01c8c0c81b)
2024-06-09 23:14:13 +03:00
Alexander Koblov
fbf2075bf8 FIX: Wrong default path for rar extension in WCX plugin for macOS (fixes #1697)
(cherry picked from commit 044706b658)
2024-06-09 23:14:12 +03:00
Alexander Koblov
886d9ae8e0 FIX: Deleting is extremely slow under KDE (issue #812)
(cherry picked from commit a56d313b34)
2024-06-09 23:14:12 +03:00
Alexander Koblov
a463109055 FIX: Dark mode - don't cache theme data (issue #1238)
(cherry picked from commit 520e337f7f)
2024-06-09 23:13:37 +03:00
Alexander Koblov
3df8697e4f FIX: Dark mode - multiple rows of tabs
(cherry picked from commit 519d4c4c41)
2024-06-09 23:13:36 +03:00
Alexander Koblov
9481c6e5f5 FIX: Right-click on the smartphone icon (fixes #1647)
(cherry picked from commit a404e2ffe7)
2024-05-25 17:51:41 +03:00
Alexander Koblov
7aff6814fc FIX: Mark unsupported variable-width encodings
(cherry picked from commit 1286c4fc42)
2024-05-25 17:51:41 +03:00
Alexander Koblov
4a6642f164 FIX: Copy extended attributes when move files (fixes #1670)
(cherry picked from commit c0ff9250bf)
2024-05-25 17:50:16 +03:00
Alexander Koblov
5255e44dc6 UPD: FTP - disable unavailable option
(cherry picked from commit 4ae5fc08b2)
2024-05-25 17:50:02 +03:00
Alexander Koblov
6f37a3006e UPD: Belarusian language file
(cherry picked from commit 3fb10a1a5b)
2024-05-25 17:50:02 +03:00
Alexander Koblov
584ee60dab UPD: FTP - clean up
(cherry picked from commit afc3a9fc9b)
2024-05-25 17:50:01 +03:00
Alexander Koblov
22fb1a9332 ADD: FTP - protocol drop-down list (issue #1604)
(cherry picked from commit 28b2254601)
2024-05-25 17:50:01 +03:00
Alexander Koblov
3e81971ad3 FIX: FTP - Access violation if you try to "Quick connect" when you are already connected (fixes #1664)
(cherry picked from commit 84f1a960b1)
2024-05-25 17:46:56 +03:00
Alexander Koblov
192cb25519 FIX: Wfx-plugins - don't allow forbidden symbols in the plugin name (issue #1655)
(cherry picked from commit 6f9218adcb)
2024-05-25 17:45:53 +03:00
Alexander Koblov
3e89b9cb95 FIX: FTP - opens incorrect path when quick connection used (issue #1654)
(cherry picked from commit 28152ec7f9)
2024-05-25 17:45:53 +03:00
Alexander Koblov
c536bfbd59 FIX: FTP - don't print an error when not necessary (fixes #1656)
(cherry picked from commit 01cc57a338)
2024-05-25 17:45:52 +03:00
Alexander Koblov
c7d4b68c39 ADD: Debian source package build script
(cherry picked from commit e83d6a320d)
2024-05-25 17:45:52 +03:00
Alexander Koblov
cd1bbb9865 FIX: FTP - detect encoding before getting current directory
(cherry picked from commit d2416cc2a4)
2024-05-25 17:45:52 +03:00
Alexander Koblov
a44c245a54 ADD: SSH+SCP - open current directory when remote directory is not specified
(cherry picked from commit 4763aaa86e)
2024-05-25 17:45:51 +03:00
Alexander Koblov
2af1f8ee5d ADD: SFTP - open current directory when remote directory is not specified
(cherry picked from commit fb40c7c4a9)
2024-05-25 17:45:29 +03:00
Alexander Koblov
813564caf0 ADD: Wcx-plugins - don't show file time for files with zero time (fixes #1634)
(cherry picked from commit 832462f36a)
2024-05-25 17:38:10 +03:00
Alexander Koblov
7b12fa4829 FIX: FTP - possible buffer overflow
(cherry picked from commit 508d8c9ada)
2024-05-25 17:38:10 +03:00
Alexander Koblov
44259358c6 FIX: Packing shows "Copying" instead of "Packing" (fixes #1626)
(cherry picked from commit 65e72c0d31)
2024-05-25 17:38:09 +03:00
Alexander Koblov
c4e8b2c348 ADD: Base64 - don't show original file size, it is unknown (issue #1630)
(cherry picked from commit 94d501e320)
2024-05-25 17:38:09 +03:00
Alexander Koblov
b8f358ace5 ADD: WCX-plugins - Don't show zero file size when size is unknown
(cherry picked from commit 024b0d632f)
2024-05-25 17:38:09 +03:00
Alexander Koblov
de5434328a ADD: Base64 - display a packed size
(cherry picked from commit 159a91ab61)
2024-05-25 17:38:08 +03:00
Alexander Koblov
0190785784 UPD: Version number 2024-05-09 17:02:24 +03:00
Alexander Koblov
94d94be158 FIX: DialogBoxParam function
(cherry picked from commit 8ea19a565c)
2024-05-09 17:00:15 +03:00
Alexander Koblov
263cea7c05 UPD: Don't execute MS Photos with elevation
(cherry picked from commit ddd1dd1377)
2024-05-05 23:27:53 +03:00
Alexander Koblov
dea421f002 DEL: Unused units
(cherry picked from commit 344b8eb21f)
2024-05-05 23:27:45 +03:00
Alexander Koblov
f4bda829bc ADD: Open images in the Microsoft Photos application using WinRT APIs
(cherry picked from commit d0c00d792e)
2024-05-05 23:27:38 +03:00
Alexander Koblov
edd44b0e23 FIX: Multiarc copy Copying dialog shows incorrect speed and time remaining on the first copy start (fixes #1609)
(cherry picked from commit a19d3c3ad5)
2024-05-04 15:44:39 +03:00
Alexander Koblov
330d51c101 FIX: Multiarc does not update the "Copying" dialog with "From" / "To" information on the start of the archive extraction (fixes #1606)
(cherry picked from commit 6fc5d04149)
2024-05-04 15:44:39 +03:00
Alexander Koblov
f3ed1d8fc5 FIX: Run in terminal option default value (fixes #504)
(cherry picked from commit 4cdf3f0e6c)
2024-05-04 13:51:18 +03:00
Alexander Koblov
16df1c7991 UPD: Unrar library (fixes #1592) 2024-05-04 13:03:18 +03:00
Alexander Koblov
5a05f2cd99 FIX: Thousands separator in file size does not respect the system setting (fixes #1602)
(cherry picked from commit c96e552037)
2024-05-04 13:00:41 +03:00
Alexander Koblov
99ded957ee ADD: Homebrew libraries path to run-time libraries search path (issue #227)
(cherry picked from commit b6621eeb75)
2024-05-04 13:00:41 +03:00
Alexander Koblov
2574f7a3c5 FIX: Default button height under non macOS
(cherry picked from commit dae59469ce)
2024-05-04 13:00:41 +03:00
Alexander Koblov
ca05ac409d FIX: Case sensitive "cd" command (fixes #1577)
(cherry picked from commit 61a1b24712)
2024-05-04 13:00:40 +03:00
rich2014
0546c64d13 FIX #1593: height of some Buttons on macOS (refer to the implementation in TfrmButtonForm)
(cherry picked from commit 4f0eb9bc9e)
2024-05-04 13:00:40 +03:00
Alexander Koblov
276b9f8efa FIX: FitFileName function under Qt and Lazarus 3.x
(cherry picked from commit 693f0883cb)
2024-05-04 13:00:40 +03:00
rich2014
0272038b9f FIX: background color of some Buttons (issue #1593)
(cherry picked from commit 69ab554ba5)
2024-05-04 13:00:40 +03:00
Alexander Koblov
95936be701 UPD: Version number 2024-04-28 00:47:56 +03:00
Alexander Koblov
70213c0093 FIX: Multiple b64 registration in plugins (fixes #1598)
(cherry picked from commit 6099cdc228)
2024-04-28 00:46:38 +03:00
Alexander Koblov
9a08ba81a9 FIX: Terminal settings has wrong default path to Terminal.app (fixes #1595)
(cherry picked from commit 68a12f8e7a)
2024-04-28 00:46:38 +03:00
Alexander Koblov
66a86a84e5 UPD: Debian control file
(cherry picked from commit 0afd35e6fd)
2024-04-28 00:46:38 +03:00
Alexander Koblov
f60bf09df0 FIX: Label font color
(cherry picked from commit 39d7cecdbc)
2024-04-20 12:54:02 +03:00
Alexander Koblov
88342a221c FIX: MacPreview - open only supported file types (issue #1481)
(cherry picked from commit d2bef610d8)
2024-04-19 18:17:32 +03:00
Alexander Koblov
0e02e9303c FIX: Viewer - zoom image
(cherry picked from commit c4c8e69189)
2024-04-19 18:17:32 +03:00
Alexander Koblov
96553479d5 FIX: Cannot delete a file from .tar.bz2 archive (fixes #1582)
(cherry picked from commit 8725b8ceac)
2024-04-19 18:17:32 +03:00
Alexander Koblov
6e9c699241 ADD: Ability to handle long paths for zip archiver (issue #1581)
(cherry picked from commit 5a48d0b603)
2024-04-19 18:17:32 +03:00
Lars The
b2c0cb52fb UPD: Reorder special folders names (#1573)
Cosmetic rearrangement of the different special folder names for better understanding of the source code.

(cherry picked from commit 629473c426)
2024-04-19 18:17:20 +03:00
Alexander Koblov
b965125939 FIX: Lazarus 3.99 compatibility
(cherry picked from commit 44abcdeb4a)
2024-04-12 00:09:20 +03:00
Alexander Koblov
a7742c4244 FIX: Access violation on Tab - Close All Tabs (fixes #1570)
(cherry picked from commit f7333011bb)
2024-04-12 00:09:07 +03:00
Alexander Koblov
abc0420937 FIX: Rebuild multiarc.ini (fixes #1568)
(cherry picked from commit e751c2ded2)
2024-04-12 00:09:07 +03:00
Alexander Koblov
3d62f8d231 FIX: Rename folder using same name but different capitalization (fixes #1569)
(cherry picked from commit ef9ae898a0)
2024-04-12 00:09:06 +03:00
Alexander Koblov
fdf48e393c UPD: Italian language file
(cherry picked from commit 73059633f0)
2024-04-12 00:09:06 +03:00
Alexander Koblov
204b057cc7 UPD: Don't show unavailable context menu items (issue #1564)
(cherry picked from commit 2128ec073e)
2024-04-12 00:09:06 +03:00
Alexander Koblov
e14821b38a UPD: Zip - speed up .zip creation
(cherry picked from commit 0bed1bda2d)
2024-04-12 00:09:05 +03:00
Alexander Koblov
b8913f1255 UPD: Version number 2024-04-08 23:14:21 +03:00
Alexander Koblov
5b4ddcc205 FIX: Create new column set identifier when save as
(cherry picked from commit 1ee04fc7c1)
2024-04-08 23:13:11 +03:00
Alexander Koblov
aedb718da4 FIX: Default column set identifier
(cherry picked from commit f4da7688ba)
2024-04-08 23:13:11 +03:00
Alexander Koblov
79078c40cb FIX: System language detection under macOS (fixes #1560)
(cherry picked from commit cde5faedf4)
2024-04-08 23:13:10 +03:00
Alexander Koblov
c8f17e36ad UPD: Version info 2024-04-07 14:03:31 +03:00
Alexander Koblov
bf406ee4cb FIX: Warnings
(cherry picked from commit 6e413a96dc)
2024-04-07 14:01:14 +03:00
Alexander Koblov
c9992a5121 ADD: Haiku install script
(cherry picked from commit e4a5db79db)
2024-04-07 14:01:14 +03:00
Alexander Koblov
f7cd88e6c1 ADD: Capability to set custom decimal separator
(cherry picked from commit fea28f382b)
2024-04-06 12:46:47 +03:00
xBZZZZ
cb8966982d FIX: Use cmem unit before cthreads unit (#1553) (#1553)
(cherry picked from commit 0f1f582578)
2024-04-06 12:46:47 +03:00
Alexander Koblov
f9a283d679 FIX: Disable auto-refresh when Double Commander window is in the background (issue #606)
(cherry picked from commit 17c4b7f460)
2024-04-06 12:46:46 +03:00
Alexander Koblov
1f23c8b262 UPD: Version number 2024-03-31 15:14:12 +03:00
Alexander Koblov
1653e8f21e UPD: Optimization, refactoring
(cherry picked from commit 69a8ec935f)
2024-03-31 15:11:18 +03:00
Alexander Koblov
cc107d22e3 UPD: Enable libheif image reader (issue #1538)
(cherry picked from commit b3f06168fa)
2024-03-31 15:11:17 +03:00
Alexander Koblov
84d34b7fd2 FIX: Read AVIF using libheif image reader (issue #1538)
(cherry picked from commit 4c78fe6214)
2024-03-31 15:11:17 +03:00
Alexander Koblov
aef3ff3313 UPD: Disable libheif image reader, it works wrong with some images from https://github.com/link-u/avif-sample-images (issue #1538)
(cherry picked from commit a685367b0c)
2024-03-31 15:11:17 +03:00
Alexander Koblov
4645960a6d FIX: Double Commander crashes when trying to view AVIF image (issue #1538)
(cherry picked from commit 37e268c3f8)
2024-03-31 15:11:16 +03:00
Alexander Koblov
12c6d6c2d6 UPD: Store cache in the program directory in portable mode
(cherry picked from commit 070a667cc9)
2024-03-31 15:11:16 +03:00
Alexander Koblov
31d80d21bd DEL: Obsolete addons (fixes #1545)
(cherry picked from commit c6e5f13764)
2024-03-31 15:11:16 +03:00
Alexander Koblov
0590197436 UPD: Use Command+Drag&Drop to move under macOS (fixes #1536)
(cherry picked from commit b80b584700)
2024-03-31 15:11:16 +03:00
Alexander Koblov
b253677450 FIX: Set focus on mouse click (Lazarus 3.x)
(cherry picked from commit e2cf8a099d)
2024-03-31 15:10:52 +03:00
Alexander Koblov
5da5e933f7 UPD: Clean up
(cherry picked from commit 26023ec1ed)
2024-03-31 15:10:52 +03:00
Alexander Koblov
095fb36268 FIX: List index (0) out of bounds
(cherry picked from commit 205dd3cada)
2024-03-31 15:10:52 +03:00
Alexander Koblov
9b62526af6 FIX: Set focus on mouse click (Lazarus 3.x)
(cherry picked from commit f9313ed71c)
2024-03-31 15:10:52 +03:00
Alexander Koblov
9a86b1ce8d FIX: Disable unavailable options
(cherry picked from commit 09238c8615)
2024-03-31 15:10:51 +03:00
Alexander Koblov
26d8defe26 ADD: Viewer - Max code size limit (fixes #1461)
(cherry picked from commit 72ac5aed61)
2024-03-31 15:10:51 +03:00
Alexander Koblov
c5de90352a ADD: cm_Edit - capability to open file under cursor ('cursor' parameter)
(cherry picked from commit 7bfe465048)
2024-03-31 15:10:50 +03:00
Alexander Koblov
156d29cf21 FIX: Lazarus 3.99 compatibility
(cherry picked from commit 1b39937de7)
2024-03-31 15:10:15 +03:00
Alexander Koblov
dcebbd4c56 UPD: Clean up
(cherry picked from commit 9db5a98161)
2024-03-31 15:10:14 +03:00
Alexander Koblov
bd0f5c6977 FIX: Comparing files by content locks up DC (issue #1527)
(cherry picked from commit c42cd75da9)
2024-03-31 15:09:48 +03:00
Alexander Koblov
a98bd40888 UPD: Enable create separate archives when multiply files selected only (issue #1523)
(cherry picked from commit 2f4a17518e)
2024-03-31 15:09:48 +03:00
j2969719
f1b449635a FIX: FTP - SSH checkbox (#1488)
(cherry picked from commit ed485edd9d)
2024-03-10 14:09:13 +03:00
Alexander Koblov
077c302f63 ADD: Edit path by double click (option)
(cherry picked from commit a8a855d7f3)
2024-03-10 13:55:50 +03:00
Alexander Koblov
f40c015742 FIX: Different color status bars in Options when using QT version in GTK DE (fixes #1456)
(cherry picked from commit 1da29f4779)
2024-03-08 17:42:59 +03:00
Graham Inggs
8981951a4c Update clean.sh (#1504)
Clean temporary files plugins/wcx/unrar/lib/rarlng.rsj and plugins/wfx/ftp/lib/ftppropdlg.lfm

(cherry picked from commit 849760f020)
2024-03-08 17:42:48 +03:00
Alexander Koblov
eef27754c1 UPD: Project files
(cherry picked from commit 184c870c79)
2024-03-08 17:42:47 +03:00
Alexander Koblov
82e221789e ADD: Viewer - open file under cursor by Shift+F3 (fixes #1276)
(cherry picked from commit cdbb2852f6)
2024-03-08 17:42:47 +03:00
Alexander Koblov
e533e99c7e FIX: Build with RabbitVCS define
(cherry picked from commit 3b8e210e6a)
2024-03-08 17:42:25 +03:00
Alexander Koblov
91242096be UPD: Project files
(cherry picked from commit cf2bf7f7f0)
2024-03-08 17:42:24 +03:00
Alexander Koblov
7ecec58a13 FIX: Unreachable code
(cherry picked from commit d5c2c59798)
2024-03-08 17:42:24 +03:00
Alexander Koblov
03d9f4f164 FIX: Skip button
(cherry picked from commit e01d5186f7)
2024-03-08 17:42:24 +03:00
Alexander Koblov
9a21789d6b ADD: Skip all when copy/move a file to itself
(cherry picked from commit c3b3644a57)
2024-03-08 17:42:24 +03:00
Alexander Koblov
9773366d80 FIX: Directory check condition
(cherry picked from commit b1e6a248eb)
2024-03-08 17:42:23 +03:00
Alexander Koblov
fc7f57ff44 UPD: Exif-wdx - use non-localized field names for storage
(cherry picked from commit 46c39f0024)
2024-03-08 17:42:23 +03:00
Alexander Koblov
4842b42062 ADD: Allow rename confirm by mouse click outside edit field
(cherry picked from commit 74b3763c56)
2024-03-08 17:42:23 +03:00
Alexander Koblov
c2ecdd7f94 UPD: Version number 2024-03-08 17:26:02 +03:00
Alexander Koblov
0a0f5f2db4 FIX: Free Pascal 3.2.3 compatibility
(cherry picked from commit 4dbffb2748)
2024-03-08 17:24:51 +03:00
Alexander Koblov
fe8ea81cfb FIX: Differ - binary mode
(cherry picked from commit b9079e7827)
2024-03-08 17:24:51 +03:00
Alexander Koblov
6488d977db FIX: Differ - binary mode (wrong memory read)
(cherry picked from commit f83d70f253)
2024-03-08 17:24:51 +03:00
Alexander Koblov
4079e78672 FIX: Differ - text mode modal dialog
(cherry picked from commit 71725d1bd0)
2024-03-08 17:24:50 +03:00
Alexander Koblov
42b75f6ba9 ADD: FTP - IPv6 support (issue #1483)
(cherry picked from commit 2a971d683c)
2024-03-08 17:24:50 +03:00
rich2014
8c74d9663c Fix #1484: file permissions of Info.plist
(cherry picked from commit 1734d761b7)
2024-03-08 17:24:50 +03:00
Alexander Koblov
032f04c608 ADD: WMP-plugin - save/restore volume level
(cherry picked from commit 384cac5495)
2024-03-08 17:24:49 +03:00
Alexander Koblov
7603933357 ADD: Rust highlighter
(cherry picked from commit b7c4cb1584)
2024-03-08 17:24:49 +03:00
Alexander Koblov
a1e12af803 UPD: Greek language file
(cherry picked from commit cfd166f052)
2024-02-16 23:04:25 +03:00
Alexander Koblov
e283775b4b UPD: Java script highlighter
(cherry picked from commit 5229bfc66e)
2024-02-16 21:54:20 +03:00
Alexander Koblov
e7946aa7e2 UPD: C# highlighter
(cherry picked from commit d8462d0ec5)
2024-02-16 21:54:20 +03:00
Alexander Koblov
2775d4a540 UPD: Version number 2024-02-14 22:58:12 +03:00
Alexander Koblov
1de81d1a84 UPD: Polish language file
(cherry picked from commit d308ae7e30)
2024-02-14 22:57:00 +03:00
Alexander Koblov
a8cac649ba FIX: Apply color settings
(cherry picked from commit a5009f63af)
2024-02-14 22:56:43 +03:00
Alexander Koblov
48ac4f71b1 FIX: Quick view - initial viewer size
(cherry picked from commit c2804dc2cd)
2024-02-14 22:56:43 +03:00
Alexander Koblov
7f090a336d FIX: Viewer - wrong initial image size and position
(cherry picked from commit 741e55c0ea)
2024-02-14 22:56:43 +03:00
Alexander Koblov
ec9ed11434 UPD: COMMANDER_INI_PATH environment variable value
(cherry picked from commit 4b4c1c13dc)
2024-02-14 22:56:42 +03:00
Alexander Koblov
e4a6afac75 FIX: Viewer - reset regular expression search state
(cherry picked from commit 2215be969b)
2024-02-14 22:56:42 +03:00
Alexander Koblov
4f156be5f5 FIX: Multi-Rename Tool - []] template (issue #1469)
(cherry picked from commit bf4138f198)
2024-02-06 22:33:46 +03:00
rich2014
bf76809072 FIX: DefaultFormatSettings needs to be initialized again on macOS (issue #1465)
(cherry picked from commit 2a04efd4db)
2024-02-06 22:33:46 +03:00
Alexander Koblov
d62a137163 FIX: Wrong decimal separator (issue #1465)
(cherry picked from commit 912420fb32)
2024-02-06 22:33:46 +03:00
Alexander Koblov
7cbd68596f FIX: Don't load icon theme twice
(cherry picked from commit 7adcd8647e)
2024-02-06 22:33:45 +03:00
Skif-off
601d4a0360 ADD: Lua - LazUtf8.DetectEncoding and SysUtils.GetTempName functions (#1464)
(cherry picked from commit a1b3b967b7)
2024-02-06 22:33:45 +03:00
Alexander Koblov
32223720b3 FIX: Editor - find/replace switch
(cherry picked from commit 3d32638970)
2024-02-06 22:33:45 +03:00
Alexander Koblov
c61ad5d17c FIX: Interface freeze when call directory hotlist with inaccessible network drive (issue #1441)
(cherry picked from commit c439aac266)
2024-01-28 14:04:23 +03:00
Alexander Koblov
c7bc5e6392 FIX: Don't expand a virtual path under Windows
(cherry picked from commit 70262a35d4)
2024-01-28 14:04:12 +03:00
Demetrius flavious
4e2506d9f2 Fix: directory change to non-normalized paths - issue #130 (#1061)
(cherry picked from commit 273759d119)
2024-01-28 14:04:12 +03:00
Alexander Koblov
5f6d47f553 FIX: ExpandAbsolutePath function (fixes #412)
(cherry picked from commit 8b4d9a068e)
2024-01-28 14:01:50 +03:00
Alexander Koblov
b31288a41c FIX: ExpandAbsolutePath function (fixes #412)
(cherry picked from commit 0522508448)
2024-01-28 14:01:50 +03:00
Alexander Koblov
3e6578f18e FIX: Source bitmap is too small
(cherry picked from commit 573441fc15)
2024-01-28 14:01:50 +03:00
Alexander Koblov
39e5f39db5 ADD: Templates menu sorting
(cherry picked from commit 56b24e5765)
2024-01-28 14:01:49 +03:00
Alexander Koblov
73e31f077f FIX: Invalid typecast
(cherry picked from commit e4cdb921d0)
2024-01-28 14:01:49 +03:00
rich2014
e7e8c8e8b9 FIX #1451: autoplay in MacPreview
(cherry picked from commit b5e943d659)
2024-01-28 14:01:49 +03:00
Alexander Koblov
2ee0f3ed3f FIX: Differ - initial line differences colors
(cherry picked from commit b137622398)
2024-01-28 14:01:49 +03:00
Alexander Koblov
9da33c5584 UPD: Use system thousand separator (issue #1449)
(cherry picked from commit 77a83234a7)
2024-01-28 14:01:49 +03:00
Alexander Koblov
800c23efc9 FIX: TUnixFileTime under Windows
(cherry picked from commit 8ec446d80e)
2024-01-28 14:01:48 +03:00
Alexander Koblov
8f0784e66b ADD: Extract Zstandard archives with a large dictionary
(cherry picked from commit 192ccfd999)
2024-01-28 14:01:48 +03:00
Alexander Koblov
b17e1e48db ADD: COMMANDER_EXE and COMMANDER_INI_PATH environment variables
(cherry picked from commit 785ccd8bf2)
2024-01-28 14:01:48 +03:00
Alexander Koblov
1e6eea881c DEL: Debug message
(cherry picked from commit e350e9b7ff)
2024-01-18 23:18:25 +03:00
Alexander Koblov
08ba5ea10f FIX: ELayoutException: Position range overflow (issue #769, #1358)
(cherry picked from commit 3685bb0a86)
2024-01-18 23:18:25 +03:00
Alexander Koblov
5f09025088 FIX: ELayoutException: Position range overflow (issue #736)
(cherry picked from commit 3793a548f7)
2024-01-18 23:18:24 +03:00
Alexander Koblov
15e259ba8e FIX: SevenZip - password dialog priority
(cherry picked from commit 0aef56bc46)
2024-01-18 23:18:24 +03:00
Alexander Koblov
818c3b265e UPD: Enable overlay icons by default under Unix
(cherry picked from commit 8b8e78a00c)
2024-01-18 23:18:24 +03:00
Alexander Koblov
6ce6e68f24 FIX: Quick View - Access violation
(cherry picked from commit 57059c125b)
2024-01-18 23:18:24 +03:00
Alexander Koblov
aa8a3a3a14 FIX: Lua - use lua_isnumber function
(cherry picked from commit 6bbfb62293)
2024-01-18 23:18:23 +03:00
Alexander Koblov
b220a50e90 FIX: Build under Unix 2024-01-14 15:56:10 +03:00
Alexander Koblov
09f4c297df UPD: Version info 2024-01-14 15:19:49 +03:00
Alexander Koblov
35ce4cd34b UPD: Use DebugLn instead WriteLn (issue #361)
(cherry picked from commit 889e685389)
2024-01-14 15:18:41 +03:00
Alexander Koblov
bbe1f5bf1a FIX: Renaming file breaks the visible length of the other file names (fixes #321)
(cherry picked from commit 39de6b76f5)
2024-01-14 15:18:41 +03:00
VenusGirl❤
6ac1a6a7b4 UPD: Korean language file doublecmd.ko.po (#1434)
(cherry picked from commit 7617271824)
2024-01-13 15:04:04 +03:00
Alexander Koblov
bf042bc801 UPD: German language file
(cherry picked from commit ec477e54af)
2024-01-13 15:04:04 +03:00
Alexander Koblov
1e6f11e3e7 UPD: Language files
(cherry picked from commit b6ebe3a061)
2024-01-13 15:04:03 +03:00
Alexander Koblov
5c1e40c192 ADD: Show list of all open tabs as a menu
(cherry picked from commit fc76f3016c)
2024-01-13 15:04:03 +03:00
Alexander Koblov
4b8c0e59bc FIX: Window title with non-english characters (fixes #1442)
(cherry picked from commit 33078fd3dc)
2024-01-13 13:13:08 +03:00
Alexander Koblov
12dd546b6b FIX: Bug [0001417] Changed sorting settings aren't applied immediately
(cherry picked from commit 285bb31d19)
2024-01-13 13:13:07 +03:00
Alexander Koblov
1c8b8fe621 FIX: Skip archive icon when clear system icon cache
(cherry picked from commit 434ac259d4)
2024-01-13 13:13:07 +03:00
Skif-off
5d0fa8a131 ADD: Lua - Dialogs.InputListBox will also return the index of selected item. (#1440)
(cherry picked from commit cc11730617)
2024-01-13 13:13:07 +03:00
rich2014
0a7500ff39 FIX #1433: Accelerator key (&) supportted in Menu with new version of Lazarus
(cherry picked from commit 9c7051bb86)
2024-01-13 13:13:07 +03:00
rich2014
51ab93793b FIX: memory leaks in Share on MacOS
(cherry picked from commit ecac177983)
2024-01-07 15:14:34 +03:00
rich2014
e8144cb246 UPD: "Open with" menu items sorting refactored on macOS
(cherry picked from commit e3c9945296)
2024-01-07 15:14:34 +03:00
rich2014
f0dcb021b7 UDP: getOtherAppFromDialog() refactored in uShellContextMenu on macOS
(cherry picked from commit 64d65252c1)
2024-01-07 15:14:33 +03:00
rich2014
e8c11b02ba ADD #1430: "Open with" multiple files supported
(cherry picked from commit b73086ff95)
2024-01-07 15:14:33 +03:00
rich2014
ad729a82d8 UPD: replace ExecCmdFork() with LSOpenFromURLSpec() which supports opening multiple files
(cherry picked from commit 1b3f41012b)
2024-01-07 15:14:33 +03:00
Alexander Koblov
0536d0d06a UPD: Header painting
(cherry picked from commit 227c802540)
2024-01-05 15:44:02 +03:00
Alexander Koblov
7b566eb9ec ADD: Grid line color option
(cherry picked from commit b3e2248d8e)
2024-01-05 15:44:01 +03:00
Skif-off
1bfdd8cdd4 UPD: Russian translation (#1428)
(cherry picked from commit 09863ff767)
2024-01-05 15:44:01 +03:00
Alexander Koblov
76de6aaf39 UPD: About dialog
(cherry picked from commit 69b20f461f)
2024-01-05 15:44:01 +03:00
rich2014
48d6a1a523 UPD: install.txt in dmg for macOS updated
(cherry picked from commit a1dd16a8cf)
2024-01-04 20:03:59 +03:00
rich2014
fad1987fe5 UPD: Chinese language file doublecmd.zh_TW.po
(cherry picked from commit 32d712532f)
2024-01-04 18:50:16 +03:00
rich2014
e3021f1c6b UPD: dmg related scripts updated
(cherry picked from commit 6adb88ea72)
2024-01-04 18:50:15 +03:00
rich2014
66bf11065d UPD: create beautiful dmg for macOS
(cherry picked from commit 92456b7880)
2024-01-04 18:50:15 +03:00
rich2014
fd8f5f992a ADD: dmg stuff for macOS
(cherry picked from commit e5dd28249d)
2024-01-04 18:50:15 +03:00
rich2014
632033894f ADD: create-dmg script for macOS
(cherry picked from commit 986983e9c9)
2024-01-04 18:50:15 +03:00
Alexander Koblov
d6e525eb9a UPD: Language files
(cherry picked from commit 745ae87f4a)
2024-01-04 18:50:14 +03:00
Alexander Koblov
ec364da854 FIX: Mount point link state (issue #406)
(cherry picked from commit 5f16ea304c)
2024-01-04 18:50:14 +03:00
Alexander Koblov
a20182fff3 FIX: Mount point bug (fixes #406)
(cherry picked from commit ba24fc8d9a)
2024-01-04 18:50:14 +03:00
Alexander Koblov
bf4bad95e3 UPD: Clean up
(cherry picked from commit 3ef7774bdf)
2024-01-03 14:01:43 +03:00
Alexander Koblov
018d03a567 UPD: Copyright year 2024-01-03 13:52:24 +03:00
Alexander Koblov
10c57d25a8 UPD: Prepare GTK3 support
(cherry picked from commit a509abc40d)
2024-01-03 13:50:01 +03:00
VenusGirl❤
fe4d1e8d96 UPD: Korean language file doublecmd.ko.po (#1426)
(cherry picked from commit c853cc8eeb)
2024-01-03 13:45:07 +03:00
Skif-off
c881784433 UPD: Russian translation (#1427)
(cherry picked from commit 10830c02ef)
2024-01-03 13:45:07 +03:00
Alexander Koblov
55ed9ca3f6 FIX: Alt+Z ambiguous in Polish (fixes #1421)
(cherry picked from commit d2bbc98e36)
2024-01-03 13:44:56 +03:00
rich2014
747365517f UPD: file format i18n
(cherry picked from commit 7242b41828)
2024-01-03 13:44:56 +03:00
rich2014
845106bd1a UPD: file format supported in "Other..." dialog
(cherry picked from commit 5c842621bd)
2024-01-03 13:44:55 +03:00
Alexander Koblov
e432281c1a FIX: Incomplete thumbnail after auto refresh (issue #1409)
(cherry picked from commit 0d3d2e7990)
2024-01-03 13:43:15 +03:00
Alexander Koblov
fb8726ac63 UPD: Version info 2024-01-03 13:42:32 +03:00
Alexander Koblov
ba535a8ef1 ADD: Clear system icon cache on file association change
(cherry picked from commit a3ee638979)
2024-01-02 19:26:58 +03:00
Alexander Koblov
78966ff478 ADD: TStringHashListUtf8.Remove method
(cherry picked from commit 20a161d513)
2024-01-02 19:26:58 +03:00
Alexander Koblov
90ba808094 FIX: Don't cache icons of encrypted files
(cherry picked from commit ce720efcfd)
2023-12-29 23:18:16 +03:00
Alexander Koblov
b8ad32cc99 ADD: Scalable folder icon
(cherry picked from commit 70fcb79d64)
2023-12-29 23:18:16 +03:00
Alexander Koblov
fbee0afef7 FIX: Default shortcut icons
(cherry picked from commit 695ec01ba4)
2023-12-29 23:18:16 +03:00
VenusGirl❤
b68c76cca9 UPD: Korean language file lclstrconsts.ko.po (#1419)
Correct some spelling and typos

(cherry picked from commit 0cae3b4aef)
2023-12-29 23:18:15 +03:00
VenusGirl❤
36e704d3ab UPD: Korean language file doublecmd.ko.po (#1418)
Correct some spelling and typos

(cherry picked from commit ea6e1b113e)
2023-12-29 23:18:15 +03:00
Alexander Koblov
f57be5f9b0 FIX: AddSpecial function (GTK2)
(cherry picked from commit 34b882e036)
2023-12-29 23:18:15 +03:00
rich2014
b9d422290e UPD: debug code removed in TShellContextMenu.FillOpenWithSubMenu()
(cherry picked from commit c127237193)
2023-12-29 23:18:15 +03:00
rich2014
38df7d82ff UPD: Refactor and Simplify menu Delimiter related code
(cherry picked from commit c84e7af695)
2023-12-29 23:18:14 +03:00
rich2014
b4471e8faa UPD: Refactor and Simplify code using CocoaApi instead of Low Level CF Functions in TShellContextMenu.FillOpenWithSubMenu()
(cherry picked from commit cebe949469)
2023-12-29 23:18:14 +03:00
rich2014
6563415480 FIX: "Other..." is not added if “Open with" is empty
(cherry picked from commit 990501fedd)
2023-12-29 23:18:14 +03:00
Alexander Koblov
b2834e9ce4 FIX: Build under Unix
(cherry picked from commit 6b26bf3ddc)
2023-12-29 23:18:14 +03:00
Alexander Koblov
dd0355fa32 ADD: Menu translation
(cherry picked from commit 549e8c2550)
2023-12-29 23:18:14 +03:00
Alexander Koblov
111d56ae05 DEL: Obsolete icons
(cherry picked from commit 9cdef48085)
2023-12-29 23:18:13 +03:00
Alexander Koblov
d9c871bfce UPD: Show overlay icons (option behavior)
(cherry picked from commit edd65a1abe)
2023-12-29 23:18:13 +03:00
Alexander Koblov
d877eee7ba ADD: BitmapMerge procedure
(cherry picked from commit 98fa9d96a2)
2023-12-29 23:18:13 +03:00
VenusGirl❤
43b758e0d6 ADD: Korean language audioinfo.lng (#1416)
(cherry picked from commit f16b70c480)
2023-12-29 23:18:13 +03:00
VenusGirl❤
9b7a9bd6c1 ADD: Korean language file ftp.ko.po (#1415)
(cherry picked from commit a155953d97)
2023-12-29 23:18:12 +03:00
VenusGirl❤
81602d4397 ADD: Korean language file zip.ko.po (#1414)
(cherry picked from commit f693b23df2)
2023-12-29 23:18:12 +03:00
VenusGirl❤
73fa8d8222 ADD: Korean language file unrar.ko.po (#1413)
(cherry picked from commit 71ac3ad873)
2023-12-29 23:18:12 +03:00
VenusGirl❤
48f2e4345e UPD: Korean language file doublecmd.ko.po (#1412)
Correct all mistranslated errors and complete translation of added untranslated strings

(cherry picked from commit b305ddcc31)
2023-12-29 23:18:12 +03:00
VenusGirl❤
abdb9287df UPD: Korean language file lclstrconsts.ko.po (#1411)
(cherry picked from commit dd3c5e3054)
2023-12-29 23:18:12 +03:00
rich2014
c4d664491a ADD: "Other..." added to "Open with" on macOS
(cherry picked from commit 2471e90557)
2023-12-29 23:18:11 +03:00
rich2014
8093eeb80e UPD #1301: "Open with" menu item ordered, keep consistent with Finder
(cherry picked from commit 4573198ba4)
2023-12-29 23:18:11 +03:00
rich2014
c9a52a055c UPD: enable DisplayName on macOS, eg. LSCopyDisplayNameForURL() in "OpenWith" ContextMenu
(cherry picked from commit 1e9a0bb736)
2023-12-29 23:18:11 +03:00
Alexander Koblov
0a2887a432 UPD: Highlight active tab (issue #1351)
(cherry picked from commit 872078e178)
2023-12-24 16:39:12 +03:00
Alexander Koblov
4ced4d39af UPD: Highlight active tab (issue #1351)
(cherry picked from commit 0fefd265c3)
2023-12-24 16:39:12 +03:00
Alexander Koblov
8c818e011d ADD: Install instruction (macOS)
(cherry picked from commit 7635906a13)
2023-12-24 16:39:12 +03:00
Alexander Koblov
1b49f5f908 UPD: Version info 2023-12-24 00:07:16 +03:00
Alexander Koblov
2a58e889f5 UPD: DialogAPI - DialogBoxParam function
(cherry picked from commit 3ba096d853)
2023-12-24 00:05:53 +03:00
Alexander Koblov
10273b2846 UPD: Project file (required packages versions)
(cherry picked from commit 5c863fcd2e)
2023-12-24 00:05:53 +03:00
Alexander Koblov
e51b372dcd DEL: Obsolete icon
(cherry picked from commit ff93132469)
2023-12-24 00:05:52 +03:00
Alexander Koblov
db067eb4c2 FIX: List index out of bounds
(cherry picked from commit 43bf9df753)
2023-12-24 00:05:52 +03:00
Alexander Koblov
082d70068f FIX: Access violation
(cherry picked from commit 4f7eb489a3)
2023-12-23 15:49:20 +03:00
Alexander Koblov
59ded13694 ADD: Quick View - status bar popup menu
(cherry picked from commit cae3081623)
2023-12-23 15:49:20 +03:00
Alexander Koblov
6ef8186da4 FIX: Division by zero
(cherry picked from commit 0ed4d7436a)
2023-12-23 15:49:19 +03:00
Alexander Koblov
7a836aae8f UPD: Language files
(cherry picked from commit 29ebd0850b)
2023-12-23 15:49:18 +03:00
Alexander Koblov
fb6c4a1885 ADD: Viewer - Plugins menu
(cherry picked from commit ed6e5e94b9)
2023-12-23 15:49:18 +03:00
Alexander Koblov
c61442c5d2 FIX: Windows XP compatibility
(cherry picked from commit a896af9641)
2023-12-23 15:49:18 +03:00
Alexander Koblov
b2ede1eead UPD: Lazarus version
(cherry picked from commit dfbfb2d351)
2023-12-23 15:49:18 +03:00
rich2014
926d30e419 UPD: UPD: jump to Home directory instead of Exe directory after decteting the driver unmounted, Keep it consistent with unmouting in DC
(cherry picked from commit f11073847b)
2023-12-23 15:49:17 +03:00
Alexander Koblov
6414fcb117 FIX: Update tree view options (hidden objects)
(cherry picked from commit 021fe137a1)
2023-12-23 15:49:17 +03:00
Alexander Koblov
a73d367232 UPD: Application bundle icon
(cherry picked from commit c01d0c0336)
2023-12-23 15:49:17 +03:00
rich2014
09e8e8864e FIX: the issue that Drive Name changes cannot be automatically updated.
replace kqueue with FSEvent, keep consistent with file monitoring technology.
completely remove dependence on kqueue now.

(cherry picked from commit a50a39b4b7)
2023-12-23 15:49:16 +03:00
rich2014
bc533a396e ADD: class TSimpleDarwinFSWatcher added
(cherry picked from commit 9d7a07b50a)
2023-12-23 15:49:16 +03:00
rich2014
97f52a1811 Fix: crash on startup, introduced by 919f3a4, cthreads/cmem should be the first unit
(cherry picked from commit 2e5b4845de)
2023-12-23 15:49:16 +03:00
rich2014
482f1afcf4 UPD #1289: change to be case insensitive in Drive List on MacOS
(cherry picked from commit 1e38a54f66)
2023-12-23 15:49:16 +03:00
VenusGirl❤
a5a63ddd23 Update doublecmd.iss (#1398)
(cherry picked from commit ebbc60642a)
2023-12-23 15:49:16 +03:00
Alexander Koblov
950623ee14 FIX: Shift+Drag icon from main toolbar to middle toolbar error (fixes #1403)
(cherry picked from commit 50e61222c3)
2023-12-23 15:49:15 +03:00
Alexander Koblov
6f1089dc44 UPD: Use SafeLoadLibrary function
(cherry picked from commit fb22e6ef95)
2023-12-23 15:49:15 +03:00
Alexander Koblov
af48eb9d23 UPD: Initialize error mode early (issue #473)
(cherry picked from commit 919f3a4e18)
2023-12-23 15:49:15 +03:00
Alexander Koblov
7bce92da3d UPD: Application bundle icon
(cherry picked from commit fe02b0adc8)
2023-12-23 15:49:14 +03:00
rich2014
97e51c6310 FIX: DragDrop issue when switching APP by Command+Tab on MacOS
(cherry picked from commit bb2a2a7575)
2023-12-23 15:49:14 +03:00
Alexander Koblov
43cc2f4a7e FIX: Show macfuse drives (issue #1046)
(cherry picked from commit 211a9b894e)
2023-12-23 15:49:14 +03:00
VenusGirl❤
16458d7759 Update lclstrconsts.ko.po (#1397)
Korean update

(cherry picked from commit 52c0b84d65)
2023-12-23 15:49:14 +03:00
Alexander Koblov
23c3a1954d UPD: Speed up file copying and moving with verify (fixes #1000)
(cherry picked from commit 71d735b2df)
2023-12-23 15:49:13 +03:00
Alexander Koblov
d3ec32c29a ADD: Highlight active tab (issue #1351)
(cherry picked from commit 6429138092)
2023-12-23 15:49:13 +03:00
Skif-off
5c3d354b26 ADD: SyncDirs: 'DateTimeFormat' parameter (#1396)
(cherry picked from commit bd9285a1db)
2023-12-23 15:49:13 +03:00
Alexander Koblov
ce59083c33 UPD: Version number 2023-12-17 20:08:39 +03:00
Alexander Koblov
ae0e59a086 FIX: Zip - Don't set attributes when extract symbolic links (fixes #1393)
(cherry picked from commit be9ccaa59e)
2023-12-17 20:07:49 +03:00
Alexander Koblov
cc6d9cba90 FIX: Release package name format
(cherry picked from commit a3783c6e42)
2023-12-17 20:07:49 +03:00
Alexander Koblov
b308422c3d UPD: German language file
(cherry picked from commit 217222c196)
2023-12-16 00:28:19 +03:00
rich2014
04631774e6 UPD: Simplified Chinese translation
(cherry picked from commit 5fc72aa950)
2023-12-16 00:28:19 +03:00
rich2014
9923850740 UPD: Share to 'Share...' on MacOS
(cherry picked from commit 3fc926159e)
2023-12-16 00:28:18 +03:00
rich2014
c34c65071e UPD: ListToNSArray() refactored to be consistent with ListToNSUrlArray()
(cherry picked from commit b0f249691c)
2023-12-16 00:28:18 +03:00
rich2014
a967433325 UPD: showMacOSSharingServiceMenu() refactored
(cherry picked from commit 0cea3e61bd)
2023-12-16 00:28:18 +03:00
rich2014
06e3ba0a51 FIX: memory leaks in Share on MacOS
(cherry picked from commit 7b0923c1f7)
2023-12-16 00:28:17 +03:00
Alexander Koblov
8b7f395d12 FIX: Bug [0002348] Cannot open empty zip files
(cherry picked from commit a6cdf056fc)
2023-12-13 20:45:50 +03:00
Alexander Koblov
1ff352cddc UPD: Language files
(cherry picked from commit fcaa6a5ee8)
2023-12-13 20:45:50 +03:00
rich2014
48b5b3be1e ADD: ContextMenu "Share" i18n
(cherry picked from commit a2872814e3)
2023-12-13 20:45:49 +03:00
rich2014
50daef684a ADD: Share ContextMenu supported on MacOS
(cherry picked from commit 0c3f996e0e)
2023-12-13 20:45:49 +03:00
Alexander Koblov
a10531d22b UPD: FTP - Component name
(cherry picked from commit 8d11b30b5c)
2023-12-12 23:20:54 +03:00
Alexander Koblov
b7dac1002b UPD: Unrar - MsgChoiceBox function
(cherry picked from commit 5669554329)
2023-12-12 23:20:54 +03:00
Alexander Koblov
ab6c5c9316 UPD: DialogAPI - MsgChoiceBox function
(cherry picked from commit 1fdccb4e36)
2023-12-12 23:20:54 +03:00
Alexander Koblov
921642f87e ADD: DialogAPI - TSynEdit control messages
(cherry picked from commit 9bc15f97b2)
2023-12-12 23:20:54 +03:00
Alexander Koblov
f50aa634d5 FIX: FTP - Show file properties dialog
(cherry picked from commit e9d43cf414)
2023-12-12 23:20:53 +03:00
Alexander Koblov
e56ad29b25 ADD: FTP - Show file properties dialog
(cherry picked from commit f0320f65ce)
2023-12-12 23:20:53 +03:00
Alexander Koblov
e2ccf2050a ADD: FTP - Show file overwrite dialog (remote copy)
(cherry picked from commit 1d3f9bdd83)
2023-12-12 23:20:53 +03:00
Alexander Koblov
2af29ac19f ADD: FTP - copy files between remote directories (SSH)
(cherry picked from commit 8883b6936a)
2023-12-12 23:20:52 +03:00
Alexander Koblov
084bd85028 FIX: Build deb_wdx
(cherry picked from commit 873d4fcd5c)
2023-12-10 14:04:19 +03:00
Alexander Koblov
41ea61700e FIX: Plugins under Haiku x86_64 (workaround)
(cherry picked from commit 0d97682dc6)
2023-12-10 14:02:42 +03:00
Alexander Koblov
738927696a UPD: TXzDecompressionStream.Seek function
(cherry picked from commit d8bc7ce213)
2023-12-10 14:00:28 +03:00
Alexander Koblov
8908718f4a UPD: Zip - readme.txt
(cherry picked from commit bf1a1e61df)
2023-12-10 14:00:28 +03:00
Alexander Koblov
9404bdadfa UPD: Zip - increase buffer size
(cherry picked from commit 5c0192a445)
2023-12-10 14:00:27 +03:00
Alexander Koblov
c2c5bf8f9e FIX: Zip - show correct compression progress
ADD: Zip - create .tar.* archives at one step

(cherry picked from commit d0a4cbd864)
2023-12-10 14:00:27 +03:00
Alexander Koblov
b6fc98502b FIX: Quick View - view file with same name and different path in flat view mode
(cherry picked from commit 66bc5720c5)
2023-12-10 13:11:08 +03:00
Alexander Koblov
3fab2dd143 UPD: German language file
(cherry picked from commit 8834eb44e7)
2023-12-09 16:08:42 +03:00
Alexander Koblov
a54b75b645 ADD: Unrar - Show error message when Rar executable not found (fixes #1388)
(cherry picked from commit 0f6cf04319)
2023-12-09 16:08:42 +03:00
Skif-off
9ac0c294d5 UPD: Russian translation (#1382)
(cherry picked from commit 4cbf094658)
2023-12-09 16:08:12 +03:00
Alexander Koblov
e883d012ec UPD: Language files
(cherry picked from commit 02edc2c392)
2023-12-09 16:08:12 +03:00
Alexander Koblov
21c272791e UPD: Language files
(cherry picked from commit fef6ce8dc2)
2023-12-09 16:08:11 +03:00
Alexander Koblov
5788897cf8 FIX: Default hash file format (issue #1183)
(cherry picked from commit 5cb86ee55b)
2023-12-09 16:07:55 +03:00
Alexander Koblov
bcf551cf8c ADD: Capability to choose hash file format (fixes #1183)
(cherry picked from commit cc19b745ae)
2023-12-09 16:07:55 +03:00
Alexander Koblov
3fafe5b1b8 ADD: FTP - SSH-agent authentication (issue #1133)
(cherry picked from commit 9e97bc10d5)
2023-12-09 16:07:38 +03:00
Alexander Koblov
30034a9f2f UPD: German language file
(cherry picked from commit d34dfa7339)
2023-12-09 16:07:23 +03:00
Alexander Koblov
75e4adfe4b UPD: Language files
(cherry picked from commit c299330174)
2023-12-09 16:06:44 +03:00
Skif-off
e842f45848 ADD: Editor - 'Group Undo' option (#1331)
(cherry picked from commit 38e7edf2cd)
2023-12-09 16:06:21 +03:00
Alexander Koblov
cf93e68e7d UPD: Version number 2023-12-09 00:31:48 +03:00
Alexander Koblov
e455cbcd8b FIX: Custom columns - Load inactive mark color (fixes #1389)
(cherry picked from commit ca1bf8c4b0)
2023-12-09 00:30:36 +03:00
Alexander Koblov
ae9e34966b FIX: File not found exception
(cherry picked from commit 47fd6c736b)
2023-12-05 20:38:51 +03:00
Alexander Koblov
fd263edcbc FIX: Drag&Drop into PowerPro
(cherry picked from commit 0f062a7138)
2023-12-05 20:38:50 +03:00
Alexander Koblov
92925e7a91 UPD: Wfx-plugin header
(cherry picked from commit 766792120e)
2023-12-05 20:38:50 +03:00
Alexander Koblov
24d68afdb0 UPD: KAScrypt description
(cherry picked from commit 7c398cfca6)
2023-12-05 20:38:50 +03:00
Alexander Koblov
abdd776d09 UPD: Rename DCPcrypt to KAScrypt
(cherry picked from commit 950c479527)
2023-12-05 20:38:50 +03:00
Alexander Koblov
375f06d6e5 ADD: INI file highlighter - enable hash sign comments
(cherry picked from commit 74fcee4467)
2023-12-05 20:38:49 +03:00
Alexander Koblov
6a34f7a7c1 FIX: Build under 32 bit
(cherry picked from commit 91b57011ee)
2023-12-03 17:05:21 +03:00
Alexander Koblov
db7b0943b5 FIX: Drag-and-dropping a picture (JPG, PNG, ...) from Firefox to Double Commander changes the type to BMP (fixes #1383)
(cherry picked from commit acf3d13b64)
2023-12-03 16:54:29 +03:00
Alexander Koblov
5cae5f0095 FIX: HTTP Browser plugin compatibility
(cherry picked from commit 93f57286d3)
2023-12-03 16:54:29 +03:00
Alexander Koblov
8f786a3014 ADD: Editor - disable save action with read-only file (fixes #1379)
(cherry picked from commit 822bb09f8f)
2023-12-03 16:54:28 +03:00
Alexander Koblov
3863add31f ADD: FileIsReadOnly function
(cherry picked from commit 7720dd970e)
2023-12-03 16:54:28 +03:00
Alexander Koblov
a243cdb9ea FIX: Hangs when cannot open/create file with elevation (issue #1379)
(cherry picked from commit a0c19151b5)
2023-12-03 16:54:28 +03:00
Alexander Koblov
4b5159b623 FIX: Range check error
(cherry picked from commit 3998581673)
2023-12-03 16:53:54 +03:00
Alexander Koblov
44cda40bca UPD: Refactoring
(cherry picked from commit 99b821e879)
2023-12-03 16:53:54 +03:00
rich2014
e35531fa70 FIX: Lazarus/Lcl/Cocoa compatibility
(cherry picked from commit b43710b786)
2023-12-02 00:07:12 +03:00
rich2014
279b61f319 FIX: Lazarus/Lcl/Cocoa compatibility
(cherry picked from commit 79900ca898)
2023-12-02 00:07:01 +03:00
rich2014
4282f79438 Fix #1350: Access violation in hot keys options dialog
(cherry picked from commit 84c5074511)
2023-12-01 21:48:44 +03:00
Alexander Koblov
05dce82be8 FIX: Quick View - load next file with plugins
(cherry picked from commit fc91f7c954)
2023-11-28 20:06:10 +03:00
Alexander Koblov
f0f8b4db52 FIX: Save last error
(cherry picked from commit 4b6bfe3345)
2023-11-28 20:06:09 +03:00
Alexander Koblov
66e6fe0c52 FIX: Differ - Invalid type cast (fixes #1374)
(cherry picked from commit 0d6d4d4e94)
2023-11-28 20:06:09 +03:00
Demetrius flavious
27170363eb FIX: Shell execute for parent directory (fixes #1354) (#1364)
(cherry picked from commit 4d8b7b8b16)
2023-11-26 16:45:29 +03:00
Alexander Koblov
08eac5ed3e FIX: Bug [0001778] WLX plugin Imagine lock current directory
(cherry picked from commit d067079e0a)
2023-11-26 16:45:15 +03:00
Demetrius flavious
bc7922e316 ADD: custom directory separator when copying file names to clipboard (#1352)
(cherry picked from commit 2c58fbdc14)
2023-11-25 00:24:53 +03:00
Alexander Koblov
7ede5ef61a UPD: Disable debug messages (fixes #1370)
(cherry picked from commit cad91f4210)
2023-11-25 00:24:42 +03:00
Alexander Koblov
9a561b817a FIX: Close button autosize (fixes #1368)
(cherry picked from commit 539c6215d7)
2023-11-25 00:24:27 +03:00
Alexander Koblov
179e1a772d FIX: Drawing icons without alpha channel
(cherry picked from commit 6443c5b638)
2023-11-25 00:24:17 +03:00
Alexander Koblov
a2500df30c FIX: Lazarus 3.0 compatibility (workaround)
(cherry picked from commit f7b4475541)
2023-11-19 21:37:36 +03:00
Alexander Koblov
260e32a463 UPD: Version number 2023-11-19 21:36:02 +03:00
Alexander Koblov
ff5dfd9c6e UPD: Read version number from project file 2023-11-19 21:35:09 +03:00
Alexander Koblov
c698c9e8af FIX: FTP - Warning about TLS support
(cherry picked from commit 30c36c5de0)
2023-11-19 21:15:42 +03:00
Alexander Koblov
96fcdc230c FIX: Number of different files not updated during the directory comparison (fixes #328)
(cherry picked from commit 7168ebf8c8)
2023-11-18 11:32:06 +03:00
Alexander Koblov
a2275e6f4e ADD: FTP - OpenSSL 3 support
(cherry picked from commit ceeffbaef6)
2023-11-18 11:30:35 +03:00
Alexander Koblov
82e5c684c3 UPD: Synapse library
(cherry picked from commit e3d7ac1a0f)
2023-11-18 11:30:35 +03:00
Alexander Koblov
df6468de31 ADD: FTP - Print TLS details
(cherry picked from commit 6fe082419e)
2023-11-17 21:18:10 +03:00
Alexander Koblov
67d3976033 ADD: FTP - reuse ssl session for data connection (GnuTLS)
(cherry picked from commit e39d537380)
2023-11-17 21:18:10 +03:00
Alexander Koblov
d3e8389906 FIX: FTP - Don't load GnuTLS library when other already used
(cherry picked from commit 0c25b15d41)
2023-11-17 21:18:10 +03:00
Alexander Koblov
445c2dcb63 UPD: FTP - Rewrote GnuTLS units
(cherry picked from commit 5493a63874)
2023-11-17 21:18:10 +03:00
Alexander Koblov
943aa711a4 UPD: FTP - Synapse blcksock unit
(cherry picked from commit 3a2045b399)
2023-11-17 21:18:10 +03:00
Alexander Koblov
3b5ae2cb6e FIX: Viewer - Prevent view directory in the non-local file system
(cherry picked from commit 072063b8a8)
2023-11-17 21:18:09 +03:00
Alexander Koblov
cd5f1e6eae UPD: Set run-time library search path (fixes #276, #1316)
(cherry picked from commit e56beb368f)
2023-11-17 21:18:09 +03:00
Alexander Koblov
31106e17b7 ADD: Hotkey for queue button in the confirmation dialogs (fixes #1232)
(cherry picked from commit 7d70bc3539)
2023-11-17 21:18:09 +03:00
Alexander Koblov
32d4f4ed89 UPD: FTP - Disable Schannel TLS/SSL (fixes #437)
(cherry picked from commit 6e544ccfc7)
2023-11-14 21:04:56 +03:00
Alexander Koblov
0f42887fb0 ADD: Export DC_CONFIG_PATH environment variable
(cherry picked from commit 522e3d507f)
2023-11-14 21:04:56 +03:00
Alexander Koblov
8a1ecf8977 UPD: Set run-time library search path (fixes #276, #1316)
(cherry picked from commit 6bb8c1c67f)
2023-11-14 21:04:56 +03:00
Alexander Koblov
f6d38274f2 FIX: Native dark mode flags (Windows >= 10)
(cherry picked from commit db18ea0f38)
2023-11-13 21:07:33 +03:00
Alexander Koblov
3f0782ca13 FIX: Don't load same wlx-plugin multiple times
(cherry picked from commit 7ed543a1c5)
2023-11-13 21:07:33 +03:00
Alexander Koblov
12b307ffda FIX: Differ shows "identical" on different files (fixes #1338)
(cherry picked from commit 8e155150a9)
2023-11-12 15:21:10 +03:00
Alexander Koblov
56ac6a262b FIX: Differ shows "identical" on different files (fixes #1338)
(cherry picked from commit ece8367329)
2023-11-11 14:34:40 +03:00
Alexander Koblov
11b7f9da8c UPD: Version number 2023-11-11 12:38:29 +03:00
Alexander Koblov
4aee194e60 FIX: Crash with libfontconfig under Linux i386
(cherry picked from commit 1705059397)
2023-11-06 23:36:10 +03:00
Alexander Koblov
f96767c13d ADD: TFileSystemWatcher.Features function
(cherry picked from commit 24838d18f3)
2023-11-04 14:38:54 +03:00
Alexander Koblov
5436c7c574 FIX: Cannot extract symbolic links from ZIP archives (fixes #1332)
(cherry picked from commit f5539c640a)
2023-11-04 13:57:31 +03:00
Alexander Koblov
d6a15d3d97 FIX: Cannot extract symbolic links from ZIP archives (fixes #1332)
(cherry picked from commit d5f3755e61)
2023-11-04 13:57:30 +03:00
Alexander Koblov
71bcaef302 UPD: Unrar - Language files
(cherry picked from commit bb213486a3)
2023-11-04 13:57:30 +03:00
Alexander Koblov
165939d321 ADD: Unrar 7 support
(cherry picked from commit 3b7ddb2524)
2023-11-04 13:57:30 +03:00
Alexander Koblov
fd9fcea432 UPD: mbReadFileToString function
(cherry picked from commit 8dee95cc1b)
2023-11-04 13:57:30 +03:00
Alexander Koblov
65d0771280 ADD: DialogAPI - MsgChoiceBox and DialogBoxParam functions
(cherry picked from commit 566b1b75e4)
2023-11-04 13:57:29 +03:00
Alexander Koblov
1b3e7a3a24 ADD: Allow to view directories by cm_View (fixes #1323)
(cherry picked from commit 236c6a143f)
2023-10-29 18:26:51 +03:00
Alexander Koblov
f5c9990b41 FIX: Refresh a file list after file rename in the flat view mode (issue #1322)
(cherry picked from commit 4265a6089b)
2023-10-29 18:26:40 +03:00
Alexander Koblov
1be8fa91ee FIX: Access violation on attempt to edit directory in file search results (fixes #949)
(cherry picked from commit 76a5f8025b)
2023-10-27 21:17:48 +03:00
Alexander Koblov
d574b5f645 FIX: Non-integer input using audioinfo Search plugin causes error/crash (fixes #922)
(cherry picked from commit 5777435901)
2023-10-27 21:17:48 +03:00
Alexander Koblov
03a57f9d94 FIX: About dialog - close button position
(cherry picked from commit d4742bcb40)
2023-10-27 21:17:48 +03:00
Alexander Koblov
4d84797068 FIX: About dialog - close button position
(cherry picked from commit d80d94ef3e)
2023-10-27 21:17:48 +03:00
Alexander Koblov
f2093a2f2e UPD: Create hardlink and symlink dialogs
(cherry picked from commit 585e804c10)
2023-10-27 21:17:47 +03:00
Alexander Koblov
d7f8c6b591 FIX: Environment variables are case sensitive under Unix
(cherry picked from commit 28d13ee123)
2023-10-27 21:17:47 +03:00
Alexander Koblov
00d9dd1276 ADD: Network connect button (fixes #265)
(cherry picked from commit fe32a00340)
2023-10-27 21:17:47 +03:00
Alexander Koblov
e9244cb69d UPD: Combine files - show dialog at the main form center
(cherry picked from commit 0991a28b23)
2023-10-27 21:17:46 +03:00
Alexander Koblov
37d1545caf FIX: Combine files dialog autosize
(cherry picked from commit 0946eb1a47)
2023-10-27 21:17:46 +03:00
Alexander Koblov
e9b034e6f9 UPD: About dialog
(cherry picked from commit bea36afb82)
2023-10-27 21:17:46 +03:00
Alexander Koblov
b06a88af11 FIX: Buttons autosize
(cherry picked from commit 6c21e2adb8)
2023-10-27 21:17:46 +03:00
Alexander Koblov
58352c086e FIX: Buttons autosize
(cherry picked from commit 25ec4cc253)
2023-10-27 21:17:45 +03:00
Alexander Koblov
c1be2667ae FIX: Symlink form autosize
(cherry picked from commit 997407ba22)
2023-10-27 21:17:45 +03:00
Alexander Koblov
8d856435e2 UPD: GetCurrentIconTheme function
(cherry picked from commit 3c3f408f70)
2023-10-27 21:17:45 +03:00
Alexander Koblov
d44cf5fe6f ADD: Fly desktop environment
(cherry picked from commit 9f1a98a1b8)
2023-10-27 21:17:45 +03:00
Alexander Koblov
290927c678 FIX: Save XML-config into symbolic link
(cherry picked from commit d6248457c5)
2023-10-22 00:10:42 +03:00
Alexander Koblov
3ecc9093bf UPD: GVFS - don't unescape drive path
(cherry picked from commit 13f9a14f4f)
2023-10-22 00:09:10 +03:00
Alexander Koblov
0032175085 FIX: Save XML-config into symbolic link
(cherry picked from commit 7f38508f46)
2023-10-21 21:44:04 +03:00
Alexander Koblov
c379b11318 ADD: Set process current directory when execute <?..?> command
(cherry picked from commit 63dd485b34)
2023-10-21 14:23:02 +03:00
Alexander Koblov
ed95fded50 UPD: Use TempFileSystemFileSource
(cherry picked from commit fbb03850c5)
2023-10-21 14:23:02 +03:00
Alexander Koblov
a60f725102 FIX: File full path corruption
(cherry picked from commit 27f7173c53)
2023-10-21 14:23:02 +03:00
Alexander Koblov
2ecbdcd461 ADD: Viewer - allow quick view using internal associations with '{!DC-VIEWER}' command
(cherry picked from commit dec24438eb)
2023-10-21 14:23:02 +03:00
Alexander Koblov
4514a60d05 UPD: Viewer - load previous/next file hotkeys
(cherry picked from commit 9d9157e6e1)
2023-10-20 21:38:12 +03:00
Alexander Koblov
4a869bd9c6 ADD: Viewer - SynEdit use editor settings
(cherry picked from commit 10823479aa)
2023-10-20 21:38:11 +03:00
Alexander Koblov
c9d90d1886 ADD: Viewer - SynEdit use editor settings
(cherry picked from commit e3a3e63dba)
2023-10-20 21:38:11 +03:00
Alexander Koblov
b38dc095a7 ADD: Feature [0001289] Store tabs in a separate config file
(cherry picked from commit 2d581148ee)
2023-10-20 21:38:11 +03:00
Alexander Koblov
e0ce4968bb UPD: Version number 2023-10-18 22:00:16 +03:00
rich2014
27e787b5f5 Fix #1312: Key Event eaten by QLPreviewView
(cherry picked from commit f6a7835bd7)
2023-10-18 21:57:56 +03:00
rich2014
7a7b14efcd Fix: Cocoa/TKASPathEdit: call AutoComplete() only when changed by user now
(cherry picked from commit f4a5ad5ef0)
2023-10-18 21:57:56 +03:00
rich2014
3706ea6270 UPD: SplashForm: simplify Panel using default color, compatible with new version of Lazarus
1. adapt to new version on cocoa
2. the appearance on all platforms remains the same
3. see also: f49aedaf1f

(cherry picked from commit 41d9b7e830)
2023-10-18 21:57:56 +03:00
Alexander Koblov
388f138d39 ADD: Viewer - scroll by up/down/pageup/pagedown/left/right keys when caret disabled
(cherry picked from commit 27d7666e45)
2023-10-18 21:57:56 +03:00
Alexander Koblov
21ce5665a3 FIX: Test archive operation progress
(cherry picked from commit dc49a59a9c)
2023-10-14 00:19:19 +03:00
Alexander Koblov
fed9e1c15f UPD: Better archive file operations progress indication
(cherry picked from commit 34841ed2c8)
2023-10-14 00:19:18 +03:00
Alexander Koblov
0a5c9328a0 ADD: Zip - show total progress when compress
(cherry picked from commit c7c51230d1)
2023-10-14 00:19:18 +03:00
Alexander Koblov
b323b32a2b ADD: Zip - show total progress when extract
(cherry picked from commit f89ab9056e)
2023-10-14 00:19:18 +03:00
Alexander Koblov
e3664c5749 ADD: Operation progress - show only percent when size unknown
(cherry picked from commit dca8d10726)
2023-10-14 00:19:17 +03:00
Alexander Koblov
30e00f53f8 UPD: Unrar version 2023-10-14 00:07:38 +03:00
Alexander Koblov
66130edd29 FIX: FileSystemWatcher - 'rename' event under Linux
(cherry picked from commit 4cf86dd929)
2023-10-13 20:15:16 +03:00
Mihaly Nyilas
d8570ffdc9 UPD: Hungarian language file (#1314)
(cherry picked from commit 2ff00ae905)
2023-10-13 20:15:16 +03:00
Alexander Koblov
68377921cb FIX: Range check error (fixes #1292)
(cherry picked from commit a7f80e5fd1)
2023-10-13 20:15:15 +03:00
Alexander Koblov
5713aca956 UPD: Version number 2023-10-09 21:51:28 +03:00
Alexander Koblov
9e003612d1 UPD: Don't show menu separator when it's not required
(cherry picked from commit 493987e2e4)
2023-10-09 21:49:42 +03:00
Alexander Koblov
5285b736d1 FIX: Crash - configure custom columns (issue #1310)
(cherry picked from commit f4c82e3c7a)
2023-10-09 21:49:42 +03:00
Alexander Koblov
99c7620893 FIX: Wrong rows height
(cherry picked from commit f586b0c1cc)
2023-10-09 21:49:42 +03:00
Alexander Koblov
7cea2fedab FIX: ELayoutException: Position range overflow (issue #736)
(cherry picked from commit c968b0de67)
2023-10-09 21:49:41 +03:00
Alexander Koblov
0750dc3264 ADD: Open with other from flatpak sandbox (issue #309)
FIX: Memory leak

(cherry picked from commit 6ee8e81d6d)
2023-10-09 21:49:41 +03:00
Alexander Koblov
28507aedda FIX: Read image using libturbojpeg library under macOS (fixes #1300)
(cherry picked from commit 0ec75f36bc)
2023-10-09 21:49:14 +03:00
Alexander Koblov
455d1ba7ed FIX: Loading the same Thumbnails multiple times in TThumbFileView (fixes #1295)
(cherry picked from commit 9c22daae6a)
2023-10-09 21:49:14 +03:00
rich2014
febf51a6d6 UDP: treat wsFullScreen as Maximized when saving Main Form WindowState
(cherry picked from commit 9bb0aea519)
2023-10-09 21:49:14 +03:00
rich2014
fafe1f2c68 UPD: Cocoa: workaround code about WindowState removed by new Lcl/Cocoa version
(cherry picked from commit bb0f0026b5)
2023-10-09 21:49:13 +03:00
Alexander Koblov
42dfbf5448 UPD: Don't open X-display under Wayland
(cherry picked from commit ad3298dd23)
2023-09-30 22:55:54 +03:00
Alexander Koblov
8245d4acda ADD: Move file to trash from flatpak sandbox (issue #309)
(cherry picked from commit dd9704a8a3)
2023-09-30 22:55:54 +03:00
Alexander Koblov
8c74dcac10 ADD: O_PATH constant
(cherry picked from commit 6a8b3fe1d5)
2023-09-30 22:55:54 +03:00
Alexander Koblov
5f6ca4483f FIX: Build under non macOS
(cherry picked from commit 782d208d9b)
2023-09-29 23:49:37 +03:00
Alexander Koblov
dbdb689e61 FIX: Wrong byte order when read JPEG image using libturbojpeg under macOS (issue #1290)
(cherry picked from commit 337c6ef4dc)
2023-09-29 23:49:37 +03:00
rich2014
a1855fc64a FIX & UPD #1290: generate thumbnails by system native QuickLook on MacOS
(cherry picked from commit 7f5efba427)
2023-09-29 23:49:37 +03:00
Alexander Koblov
5021ef9c93 ADD: Viewer - scroll by up/down keys when caret disabled (fixes #1267)
(cherry picked from commit e81933aff0)
2023-09-29 23:49:37 +03:00
Alexander Koblov
1adf973bd5 UPD: Use xdg-open to open files from flatpak sandbox (issue #309)
(cherry picked from commit 5712b87023)
2023-09-29 23:49:37 +03:00
Alexander Koblov
91d0e7cb0b FIX: Don't show garbage mounts from flatpak sandbox (issue #309)
(cherry picked from commit 1efe181fd2)
2023-09-29 23:49:36 +03:00
Alexander Koblov
eecd70c65d UPD: Don't show directory change error on start
(cherry picked from commit ed026035ed)
2023-09-27 22:09:49 +03:00
Alexander Koblov
49a823e14b FIX: Drag&Drop - move file when drop it on the tab by left + right mouse button (fixes #1287)
(cherry picked from commit aee27d7f2e)
2023-09-25 22:46:47 +03:00
rich2014
798d8462cd UPD: AutoRefresh: further optimize the processing of sub-directory events
fswatch does not callback with sub-directory events, when no directory has FlatView enabled (most of the time)

(cherry picked from commit cf0fd59892)
2023-09-25 22:46:46 +03:00
rich2014
5919c7166e UPD #1278: About and Preferences added to AppMenu
(cherry picked from commit b40d8f44de)
2023-09-25 22:46:46 +03:00
rich2014
86798ee994 FIX: SplashForm: OnCLose missed before
(cherry picked from commit 1f71a393a3)
2023-09-25 22:46:46 +03:00
Alexander Koblov
7b71f4987b FIX: ShowModal function
(cherry picked from commit 7abd581bc3)
2023-09-25 00:08:52 +03:00
Alexander Koblov
4aeca13849 UPD: Viewer - don't show print menu when unavailable (fixes #1291)
(cherry picked from commit ee83513936)
2023-09-25 00:08:52 +03:00
rich2014
50ba015731 Fix #1274: the windows are not correctly enabled after multiple ShowModal()
(cherry picked from commit c2d947bf17)
2023-09-25 00:08:52 +03:00
Alexander Koblov
7413aaf165 UPD: Unrar version 2023-09-24 14:43:05 +03:00
Alexander Koblov
ac22480c70 UPD: Version number 2023-09-24 13:45:55 +03:00
Alexander Koblov
b254347e0b FIX: Find files - search hex sequence
(cherry picked from commit ce81d4bbde)
2023-09-23 22:07:06 +03:00
rich2014
21712753bc Fix: AutoRefresh: compilation issue on Windows and Linux
(cherry picked from commit 8a52783969)
2023-09-23 18:26:15 +03:00
rich2014
c16b13da6b UPD #1266: AutoRefresh: subdirectory events are only handled in FlatView mode
(cherry picked from commit 8494d60e8a)
2023-09-23 18:26:15 +03:00
Alexander Koblov
726b2d2fc4 FIX: Portable any map graphic format reader
(cherry picked from commit 443fc6d370)
2023-09-23 18:26:15 +03:00
Alexander Koblov
52fce9fba7 FIX: Sorting files/folders ignores Case sensitivity on Cyrillic names (fixes #1277)
(cherry picked from commit bba5731565)
2023-09-23 18:26:14 +03:00
Matej
3c12d81209 Update lclstrconsts.sl.po (#1261)
Updated Slovenian translation.

(cherry picked from commit f78d4171bb)
2023-09-20 21:57:12 +03:00
Alexander Koblov
66fd3a4cd4 FIX: Empty dir size in status bar calculates to -1 (fixes #1268)
(cherry picked from commit 4ee3818bb8)
2023-09-20 21:57:12 +03:00
Alexander Koblov
6215d2fa93 FIX: ImageMagick 7 compatibility
FIX: Crash on close when ImageMagick not found

(cherry picked from commit 5605cc3d8a)
2023-09-20 21:57:12 +03:00
Alexander Koblov
961efff810 FIX: Drag&Drop - restore selection of active file when start drag with control key pressed
(cherry picked from commit d98d27d833)
2023-09-20 21:57:11 +03:00
Alexander Koblov
33d8e86db3 ADD: Haiku support
(cherry picked from commit e9835c734d)
2023-09-20 21:57:11 +03:00
Alexander Koblov
1c46399683 ADD: Zip - save password to cache (issue #1254)
(cherry picked from commit 0115f01430)
2023-09-09 15:26:28 +03:00
Alexander Koblov
da09d79d01 FIX: Files associations made in KDE doesn't affect Double Commander (fixes #637)
(cherry picked from commit f3f6a20fbb)
2023-09-09 15:26:28 +03:00
Alexander Koblov
a89cc3f4ca FIX: Change zip plugin configuration force quits (fixes #1233)
(cherry picked from commit e2e3ac9031)
2023-09-09 15:26:28 +03:00
Alexander Koblov
31485c58b9 FIX: Revision number 2023-09-09 12:21:30 +03:00
Alexander Koblov
035cbb3de6 UPD: Version number 2023-09-09 12:20:08 +03:00
Alexander Koblov
8eeb289dbf UPD: Language files
(cherry picked from commit 4b16ac8d95)
2023-09-09 12:18:04 +03:00
Alexander Koblov
ea1d13dd3a FIX: Quick View - focus wrong control when load file from archive (issue #1254)
(cherry picked from commit 7b3df5558d)
2023-09-09 12:18:03 +03:00
Alexander Koblov
6729ec2110 FIX: Wrong background with gtk2 theme Gnome OSX-IV-1.3 (fixes #32)
(cherry picked from commit 8d04bf014d)
2023-09-09 12:18:03 +03:00
rich2014
b31ec41399 UPD: remove unnecessary code, and improve MainForm display
(cherry picked from commit b2129d7790)
2023-09-09 12:18:03 +03:00
rich2014
374ecc52a2 UPD & FIX: handle Splash Form consistently across all platforms, especially on MacOS
1. more Lazarus’ idioms for SplashForm (like Lazarus IDE)
2. SplashForm can be shown correctly on MacOS
3. improved display of SplashForm in Gt2k
4. tested on Win32, Gtk2, Qt5, Cocoa

(cherry picked from commit 623185b685)
2023-09-09 12:18:03 +03:00
Matej
3ac33017e4 Update doublecmd.sl.po (#1248)
This is an update to Slovenian translation. I get an error, when Previewing the changes, but have no idea how to resolve it.

(cherry picked from commit 6b55aa43f0)
2023-09-09 12:18:02 +03:00
Alexander Koblov
abd7777534 FIX: Viewer find skips first matching occurrence (fixes #1250)
(cherry picked from commit 15c1cc8fdf)
2023-09-08 22:58:18 +03:00
Alexander Koblov
e53426d0a4 FIX: Load libheif.dll and it dependencies from the same path
(cherry picked from commit a815a476e6)
2023-09-08 22:58:18 +03:00
Alexander Koblov
bde8179846 ADD: Load library from system PATH
(cherry picked from commit 9f2e26306e)
2023-09-08 22:58:18 +03:00
Paul Gessos
4a9b928ba8 Update doublecmd.el.po until line 4200 (#1247)
(cherry picked from commit 0fc983fe24)
2023-09-08 22:58:17 +03:00
Alexander Koblov
8fbc6674c3 FIX: Revision number 2023-08-19 15:18:22 +03:00
Alexander Koblov
a3987d19f4 FIX: Revision number 2023-08-19 14:57:51 +03:00
Alexander Koblov
ae331340e7 UPD: Version number 2023-08-19 13:36:46 +03:00
Alexander Koblov
4aa3cb8ac9 UPD: Sort icons color
(cherry picked from commit 65cc9a9597)
2023-08-19 13:35:29 +03:00
Alexander Koblov
62bc2c83d2 FIX: Crash with invalid file view type (fixes #1231)
(cherry picked from commit e9172af6ee)
2023-08-18 22:48:05 +03:00
Alexander Koblov
98a22aa105 FIX: SyncDirs - create target subdirectory (fixes #1227)
(cherry picked from commit e663df72d5)
2023-08-18 22:48:05 +03:00
Alexander Koblov
2cad7cd392 FIX: Date & Time formatting in Options default preset cannot get it back if change it (fixes #1225)
(cherry picked from commit 33014e2afd)
2023-08-18 22:48:05 +03:00
Alexander Koblov
fbdf8e6938 FIX: SevenZip - heap corruption
(cherry picked from commit 7c1296856c)
2023-08-15 21:22:35 +03:00
Alexander Koblov
859c7b066d FIX: SevenZip - double-free (VT_BSTR)
(cherry picked from commit 315b3f0e0d)
2023-08-15 21:22:35 +03:00
Alexander Koblov
006094bb5c FIX: cm_AddPlugin - case insensitive pluginst.inf check
(cherry picked from commit de65350e17)
2023-08-15 21:22:34 +03:00
Alexander Koblov
04939dd462 UPD: File properties dialog - enable user/group autocomplete
(cherry picked from commit 27a9940505)
2023-08-15 21:22:34 +03:00
Alexander Koblov
e94ffc6a4e FIX: Folder size within disk images not shown (fixes #1219)
(cherry picked from commit 16e028c05f)
2023-08-15 21:22:34 +03:00
Alexander Koblov
c34b4dfcf2 FIX: Changing the "Open as" encoding of a newly created file clears text editor (fixes #1001)
(cherry picked from commit 3627522862)
2023-08-15 21:22:34 +03:00
Alexander Koblov
a5264b7359 UPD: File properties dialog - allow manual user/group change
(cherry picked from commit 6de0f92dcb)
2023-08-15 21:22:34 +03:00
Graham Inggs
8108426140 Update clean.sh (#1214)
Clean temporary file plugins/wcx/zip/lib/ZipLng.rsj

(cherry picked from commit 10c259525e)
2023-08-15 21:22:15 +03:00
Alexander Koblov
f8a38d9c97 ADD: Show portable devices in the drive list (issue #1211)
(cherry picked from commit c8c2d0faf8)
2023-08-15 21:22:04 +03:00
Alexander Koblov
1e13f7eacc UPD: Version number 2023-08-08 20:41:30 +03:00
Alexander Koblov
b17255bc35 FIX: Zip - crash in the options dialog
(cherry picked from commit c9186d1e81)
2023-08-08 20:39:33 +03:00
rich2014
fb2c5af2d1 UPD: asterisk added to the hint to mark the Tab Locked
(cherry picked from commit bcef15a228)
2023-08-08 20:39:33 +03:00
Alexander Koblov
5dfb093472 FIX: Combining to file with one of the part's full name fails with deleting this part (fixes #1198)
(cherry picked from commit 70bdd45fa4)
2023-08-08 20:39:33 +03:00
rich2014
b1838ee2db FIX #1195: wrong hint is shown when Mouse Move in the blank of the TabControl
(cherry picked from commit bc8f7ac3c2)
2023-08-08 20:39:32 +03:00
rich2014
6e6fad1cc9 UPD: hint in TFileViewHeader improved
(cherry picked from commit 421417a09b)
2023-08-08 20:39:32 +03:00
rich2014
de3a635623 Fix #1187: wrong height of Header in empty TColumnsFileView
(cherry picked from commit 623358eb14)
2023-08-06 18:26:56 +03:00
Alexander Koblov
6cae0e6390 FIX: Revision number 2023-08-05 13:14:48 +03:00
Alexander Koblov
cd3a69c655 UPD: Install scripts (Windows)
(cherry picked from commit 85720b46e3)
2023-08-05 11:02:05 +03:00
Alexander Koblov
d5023b37eb FIX: Read zero minor version
(cherry picked from commit 74c15bb648)
2023-08-05 10:42:15 +03:00
Alexander Koblov
246c9081ee FIX: Broken link icon with cm_FlatViewSel
(cherry picked from commit 354eae9bcb)
2023-08-05 00:28:10 +03:00
rich2014
69bede7aae Fix: wrong hints of PathLabel
(cherry picked from commit c1d4cebee4)
2023-08-05 00:28:10 +03:00
Alexander Koblov
3a3e8b02ed ADD: Create *.msi package
(cherry picked from commit fac7aade70)
2023-08-04 21:38:27 +03:00
Alexander Koblov
b4e4df8810 FIX: [0001897] MSI Installer Does Not Ask for Installation Destination (issue #611)
(cherry picked from commit 182981fb0c)
2023-08-04 21:38:27 +03:00
Alexander Koblov
533ecbdfae FIX: Exif - don't show invalid date
(cherry picked from commit 9ed66b26ce)
2023-08-02 23:08:30 +03:00
Alexander Koblov
cf87f52512 FIX: Unix mode
(cherry picked from commit 06391ac736)
2023-08-02 23:08:29 +03:00
Alexander Koblov
cdebe99bb6 FIX: Publish to WinGet
(cherry picked from commit 7beaff2b48)
2023-08-02 23:08:29 +03:00
Alexander Koblov
5b87675ab1 ADD: Release workflow (macOS)
(cherry picked from commit c6f455c676)
2023-08-02 23:08:29 +03:00
rich2014
838729b99e FIX #1184: Cancel Button in fQuickSearch
(cherry picked from commit 889d3c705a)
2023-08-02 23:08:28 +03:00
Alexander Koblov
5725538ee8 UPD: Polish translation
(cherry picked from commit d7cbbfac0e)
2023-08-01 23:36:14 +03:00
Alexander Koblov
5983b651b6 UPD: Beta version number format
(cherry picked from commit d5255624c6)
2023-08-01 23:36:14 +03:00
Alexander Koblov
b3248c39db FIX: Exif plugin - detect string
(cherry picked from commit 9ae1cbc152)
2023-07-31 20:18:31 +03:00
Alexander Koblov
70c96226be UPD: Disable 'last search' button at start (fixes #176)
(cherry picked from commit 0be7fae2bd)
2023-07-31 20:18:31 +03:00
Alexander Koblov
96b0f50302 UPD: Beta version number format 2023-07-31 20:17:10 +03:00
Alexander Koblov
f9fbdedb82 FIX: Hotkey labels from Keys show up in toolbar hover info tags (fixes #1044)
(cherry picked from commit 03483a1044)
2023-07-30 16:06:14 +03:00
Alexander Koblov
ebd3e94414 FIX: Text viewer cannot show text with filesize>=2G (fixes #958)
(cherry picked from commit f036b26454)
2023-07-30 16:06:14 +03:00
Alexander Koblov
e78fe3df19 FIX: The symbolic link to the directory appears twice during synchronization (fixes #1053)
(cherry picked from commit dd927285d0)
2023-07-30 16:06:13 +03:00
Alexander Koblov
14417cce28 UPD: Lazarus version
(cherry picked from commit b07956b2cf)
2023-07-30 16:06:13 +03:00
Alexander Koblov
45d5de80ca FIX: About dialog - crash
(cherry picked from commit de1ca78cc3)
2023-07-29 15:47:12 +03:00
Alexander Koblov
722a421416 UPD: German language file
(cherry picked from commit 274c712458)
2023-07-29 15:47:12 +03:00
rich2014
f49e7ec13e Fix: ESC handle in Ask Dialog
(cherry picked from commit ab64636e64)
2023-07-29 15:47:12 +03:00
rich2014
91e1263ece UPD: simplify the reference to NSAPP
(cherry picked from commit ba2c077600)
2023-07-29 15:47:12 +03:00
rich2014
08f2c26f86 UPD: Cocoa: workaround code about edtCommand removed by new Lcl/Cocoa version
(cherry picked from commit 39b5ed90bc)
2023-07-29 15:47:11 +03:00
rich2014
28ed87663c Fix: ESC handle in About Dialog
(cherry picked from commit 8359ee6da1)
2023-07-29 15:47:11 +03:00
Alexander Koblov
d3d4ddf1ec FIX: AudioInfo - don't show invalid 'Track (zero-filled)' field
(cherry picked from commit 2efbd8515c)
2023-07-29 15:47:11 +03:00
Alexander Koblov
8475db364d FIX: AudioInfo - read track number
(cherry picked from commit 27e23900bf)
2023-07-29 15:47:10 +03:00
Alexander Koblov
24c42aabea FIX: ColorBox vertical spacing
(cherry picked from commit b9b1e6fc03)
2023-07-29 15:47:10 +03:00
Alexander Koblov
c3252c7884 FIX: Build under Haiku
(cherry picked from commit 266dd8593a)
2023-07-29 15:47:10 +03:00
Alexander Koblov
3a14e07f6f UPD: Free Pascal and Lazarus versions
(cherry picked from commit e09a5ad052)
2023-07-29 15:47:10 +03:00
Alexander Koblov
9aff9d9346 UPD: Version info 2023-07-20 13:45:32 +03:00
731 changed files with 54910 additions and 53080 deletions

112
.github/scripts/create_release.sh vendored Executable file
View file

@ -0,0 +1,112 @@
#!/bin/bash
# The new package will be saved here
PACK_DIR=$PWD/doublecmd-release
# Temp dir for creating *.dmg package
BUILD_PACK_DIR=/var/tmp/doublecmd-$(date +%y.%m.%d)
# Save revision number
DC_REVISION=$(install/linux/update-revision.sh ./ ./)
# Read version number
DC_MAJOR=$(grep 'MajorVersionNr' src/doublecmd.lpi | grep -o '[0-9.]\+')
DC_MINOR=$(grep 'MinorVersionNr' src/doublecmd.lpi | grep -o '[0-9.]\+' || echo 0)
DC_MICRO=$(grep 'RevisionNr' src/doublecmd.lpi | grep -o '[0-9.]\+' || echo 0)
DC_VER=$DC_MAJOR.$DC_MINOR.$DC_MICRO
# Set widgetset
export lcl=cocoa
mkdir -p $PACK_DIR
# Update application bundle version
defaults write $(pwd)/doublecmd.app/Contents/Info CFBundleVersion $DC_REVISION
defaults write $(pwd)/doublecmd.app/Contents/Info CFBundleShortVersionString $DC_VER
plutil -convert xml1 $(pwd)/doublecmd.app/Contents/Info.plist
chmod 644 $(pwd)/doublecmd.app/Contents/Info.plist
build_unrar()
{
DEST_DIR=$(pwd)/install/darwin/lib/$CPU_TARGET
pushd /tmp/unrar
make clean lib CXXFLAGS+="-std=c++14 -DSILENT --target=$TARGET" LDFLAGS+="-dylib --target=$TARGET"
mkdir -p $DEST_DIR && mv libunrar.so $DEST_DIR/libunrar.dylib
popd
}
build_doublecmd()
{
# Build all components of Double Commander
./build.sh release
# Copy libraries
cp -a install/darwin/lib/$CPU_TARGET/*.dylib ./
# Prepare *.dmg package
mkdir -p $BUILD_PACK_DIR
install/darwin/install.sh $BUILD_PACK_DIR
pushd $BUILD_PACK_DIR
mv doublecmd.app 'Double Commander.app'
codesign --deep --force --verify --verbose --sign '-' 'Double Commander.app'
popd
# Create *.dmg package
HDI_TRY=1
while [ $HDI_TRY -le 5 ]; do
echo "Try to create a package $HDI_TRY ..."
# Bug: https://github.com/actions/runner-images/issues/7522
echo Killing XProtect...; sudo pkill -9 XProtect >/dev/null || true;
echo Waiting for XProtect process...; while pgrep XProtect; do sleep 3; done;
install/darwin/create-dmg/create-dmg \
--volname "Double Commander" \
--volicon "$BUILD_PACK_DIR/.VolumeIcon.icns" \
--background "$BUILD_PACK_DIR/.background/bg.jpg" \
--window-pos 200 200 \
--window-size 680 366 \
--text-size 16 \
--icon-size 128 \
--icon "Double Commander.app" 110 120 \
--app-drop-link 360 120 \
--icon "install.txt" 566 123 \
--icon ".background" 100 500 \
"$PACK_DIR/doublecmd-$DC_VER.$lcl.$CPU_TARGET.dmg" \
"$BUILD_PACK_DIR/"
if [ $? -eq 0 ]; then
break
fi
HDI_TRY=$((HDI_TRY+1))
sleep 10
done
# Clean DC build dir
./clean.sh
rm -f *.dylib
rm -rf $BUILD_PACK_DIR
}
# Set processor architecture
export CPU_TARGET=aarch64
export TARGET=arm64-apple-darwin
# Set minimal Mac OS X target version
export MACOSX_DEPLOYMENT_TARGET=11.0
build_unrar
build_doublecmd
# Set processor architecture
export CPU_TARGET=x86_64
export TARGET=x86_64-apple-darwin
# Set minimal Mac OS X target version
export MACOSX_DEPLOYMENT_TARGET=11.0
build_unrar
build_doublecmd

View file

@ -19,6 +19,7 @@ export lcl=cocoa
defaults write $(pwd)/doublecmd.app/Contents/Info CFBundleVersion $DC_REVISION
defaults write $(pwd)/doublecmd.app/Contents/Info CFBundleShortVersionString $DC_VER
plutil -convert xml1 $(pwd)/doublecmd.app/Contents/Info.plist
chmod 644 $(pwd)/doublecmd.app/Contents/Info.plist
build_doublecmd()
{
@ -31,9 +32,23 @@ build_doublecmd()
pushd $BUILD_PACK_DIR
mv doublecmd.app 'Double Commander.app'
codesign --deep --force --verify --verbose --sign '-' 'Double Commander.app'
hdiutil create -anyowners -volname "Double Commander" -imagekey zlib-level=9 -format UDZO -fs HFS+ -srcfolder 'Double Commander.app' $PACK_DIR/doublecmd-$DC_VER-$DC_REVISION.$lcl.$CPU_TARGET.dmg
popd
install/darwin/create-dmg/create-dmg \
--volname "Double Commander" \
--volicon "$BUILD_PACK_DIR/.VolumeIcon.icns" \
--background "$BUILD_PACK_DIR/.background/bg.jpg" \
--window-pos 200 200 \
--window-size 680 366 \
--text-size 16 \
--icon-size 128 \
--icon "Double Commander.app" 110 120 \
--app-drop-link 360 120 \
--icon "install.txt" 566 123 \
--icon ".background" 100 500 \
"$PACK_DIR/doublecmd-$DC_VER-$DC_REVISION.$lcl.$CPU_TARGET.dmg" \
"$BUILD_PACK_DIR/"
# Clean DC build dir
./clean.sh
rm -rf $BUILD_PACK_DIR

58
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,58 @@
name: build-release
on:
workflow_dispatch:
release:
types: [prereleased, released]
concurrency:
group: ${{ github.ref }}
cancel-in-progress: true
jobs:
build-mac:
runs-on: macos-14
steps:
- name: Install Free Pascal
uses: doublecmd/lazarus-install@mac
with:
lazarus-version: "stable"
- name: Get Lazarus source
uses: actions/checkout@v4
with:
repository: 'fpc/Lazarus'
ref: 'fixes_4'
- name: Build and install Lazarus
run: |
make all
sudo make install
- name: Create Lazarus config
run: |
sudo mkdir -p /etc/lazarus
sudo cp tools/install/macosx/environmentoptions.xml /etc/lazarus/environmentoptions.xml
sudo sed -i -e "s|_PPCARCH_|fpc|g; s|/Developer/lazarus|/usr/local/share/lazarus|g" /etc/lazarus/environmentoptions.xml
- name: Checkout source
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download unrar source code
run: wget https://www.rarlab.com/rar/unrarsrc-7.0.9.tar.gz -O /tmp/unrarsrc.tar.gz
- name: Extract unrar source code
run: cd /tmp && tar xzf unrarsrc.tar.gz
- name: Build packages
run: ./.github/scripts/create_release.sh
- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
with:
file: doublecmd-release/doublecmd*.dmg
tag: ${{ github.ref }}
overwrite: true
file_glob: true

View file

@ -1,14 +1,10 @@
name: build-snapshot
on:
push:
paths:
- 'components/**'
- 'plugins/**'
- 'sdk/**'
- 'src/**'
release:
types: [unpublished]
branches:
- master
- v1.1.x
concurrency:
group: ${{ github.ref }}
@ -58,7 +54,7 @@ jobs:
- name: Install Lazarus
uses: alexx2000/setup-fpc@win
with:
lazarus-version: "2.2.6"
lazarus-version: "stable"
- name: Checkout source
uses: actions/checkout@v2

View file

@ -9,5 +9,5 @@ jobs:
- uses: vedantmgoyal2009/winget-releaser@v2
with:
identifier: alexx2000.DoubleCommander
installers-regex: '.(exe|msi)$'
installers-regex: '\.msi$'
token: ${{ secrets.WINGET_TOKEN }}

View file

@ -49,7 +49,7 @@
@echo Clean up components output directories
@del /Q /S components\chsdet\lib\*.*
@del /Q /S components\dcpcrypt\lib\*.*
@del /Q /S components\kascrypt\lib\*.*
@del /Q /S components\doublecmd\lib\*.*
@del /Q /S components\gifanim\lib\*.*
@del /Q /S components\KASToolBar\lib\*.*

View file

@ -5,7 +5,7 @@ rm -f units/*/*
# Clean up components output directories
rm -rf components/chsdet/lib/*
rm -rf components/dcpcrypt/lib/*
rm -rf components/kascrypt/lib/*
rm -rf components/doublecmd/lib/*
rm -rf components/gifanim/lib/*
rm -rf components/Image32/lib/*
@ -27,9 +27,12 @@ find plugins -iname '*.a' -delete
rm -f src/doublecmd.res doublecmd
rm -f tools/extractdwrflnfo
rm -f plugins/wcx/unrar/lib/rarconfdlg.lfm
rm -f plugins/wcx/unrar/lib/rarlng.rsj
rm -f plugins/wcx/zip/lib/ZipConfDlg.lfm
rm -f plugins/wcx/zip/lib/ZipLng.rsj
rm -f plugins/wcx/zip/lib/abresstring.rs?
rm -f plugins/wfx/ftp/lib/FtpConfDlg.lfm
rm -f plugins/wfx/ftp/lib/ftppropdlg.lfm
rm -f plugins/wfx/samba/lib/smbauthdlg.lfm
# Remove debug files

View file

@ -7,8 +7,8 @@
<CompilerOptions>
<Version Value="11"/>
<SearchPaths>
<IncludeFiles Value="source"/>
<OtherUnitFiles Value="source"/>
<IncludeFiles Value="source;source/Clipper2"/>
<OtherUnitFiles Value="source;source/Clipper2"/>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Conditionals Value="if (TargetCPU &lt;> &apos;arm&apos;) then
@ -19,7 +19,7 @@ end"/>
</CompilerOptions>
<Description Value="Image32 is a comprehensive 2D graphics library written entirely in Delphi Pascal, and without dependencies on other libraries. It provides an extensive range of image manipulation and drawing functions that includes text rendering through native parsing of truetype font files."/>
<License Value="Boost Software License - Version 1.0"/>
<Version Major="4" Minor="3"/>
<Version Major="4" Minor="8" Release="1"/>
<Files>
<Item>
<Filename Value="source/Img32.Draw.pas"/>
@ -85,6 +85,34 @@ end"/>
<Filename Value="source/Img32.Vector.pas"/>
<UnitName Value="Img32.Vector"/>
</Item>
<Item>
<Filename Value="source/Clipper2/Clipper.Core.pas"/>
<UnitName Value="Clipper.Core"/>
</Item>
<Item>
<Filename Value="source/Clipper2/Clipper.Engine.pas"/>
<UnitName Value="Clipper.Engine"/>
</Item>
<Item>
<Filename Value="source/Clipper2/Clipper.inc"/>
<Type Value="Include"/>
</Item>
<Item>
<Filename Value="source/Clipper2/Clipper.Minkowski.pas"/>
<UnitName Value="Clipper.Minkowski"/>
</Item>
<Item>
<Filename Value="source/Clipper2/Clipper.Offset.pas"/>
<UnitName Value="Clipper.Offset"/>
</Item>
<Item>
<Filename Value="source/Clipper2/Clipper.pas"/>
<UnitName Value="Clipper"/>
</Item>
<Item>
<Filename Value="source/Clipper2/Clipper.RectClip.pas"/>
<UnitName Value="Clipper.RectClip"/>
</Item>
</Files>
<RequiredPkgs>
<Item>
@ -96,7 +124,7 @@ end"/>
</RequiredPkgs>
<UsageOptions>
<IncludePath Value="source"/>
<UnitPath Value="$(PkgOutDir);source"/>
<UnitPath Value="$(PkgOutDir);source;source/Clipper2"/>
</UsageOptions>
<PublishOptions>
<Version Value="2"/>

View file

@ -10,7 +10,8 @@ interface
uses
Img32.Draw, Img32.Extra, Img32.Fmt.SVG, Img32, Img32.Resamplers,
Img32.SVG.Core, Img32.SVG.Path, Img32.SVG.Reader, Img32.Text,
Img32.Transform, Img32.Vector;
Img32.Transform, Img32.Vector, Clipper.Core, Clipper.Engine,
Clipper.Minkowski, Clipper.Offset, Clipper, Clipper.RectClip;
implementation

View file

@ -4,6 +4,6 @@ A 2D graphics library written in Delphi Pascal
https://github.com/AngusJohnson/Image32
Version: 4.3+ (2022/10/16)
Version: 4.8.1 (2025/01/18)
Author: Angus Johnson

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,133 @@
unit Clipper.Minkowski;
(*******************************************************************************
* Author : Angus Johnson *
* Date : 21 December 2023 *
* Copyright : Angus Johnson 2010-2022 *
* Purpose : Minkowski Addition and Difference *
* License : http://www.boost.org/LICENSE_1_0.txt *
*******************************************************************************)
{$I Clipper.inc}
interface
uses
Classes, Math, Clipper.Core;
function MinkowskiSum(const Pattern, Path: TPath64;
PathIsClosed: Boolean): TPaths64; overload;
function MinkowskiSum(const Pattern, Path: TPathD;
PathIsClosed: Boolean; decimalPlaces: integer = 2): TPathsD; overload;
function MinkowskiDiff(const path1, path2: TPath64): TPaths64; overload;
function MinkowskiDiff(const Pattern, Path: TPathD;
PathIsClosed: Boolean; decimalPlaces: integer): TPathsD; overload;
implementation
uses
Clipper;
function AddPoints(val1, val2: TPoint64): TPoint64;
{$IFDEF INLINING} inline; {$ENDIF}
begin
Result.X := val1.X + val2.X;
Result.Y := val1.Y + val2.Y;
end;
//------------------------------------------------------------------------------
function SubtractPoints(val1, val2: TPoint64): TPoint64;
{$IFDEF INLINING} inline; {$ENDIF}
begin
Result.X := val1.X - val2.X;
Result.Y := val1.Y - val2.Y;
end;
//------------------------------------------------------------------------------
function Minkowski(const Base, Path: TPath64;
IsSum: Boolean; IsClosed: Boolean): TPaths64;
var
i,j,k,g,h, delta, baseLen, pathLen: integer;
tmp: TPaths64;
quad: TPath64;
begin
delta := Iif(IsClosed, 0 , 1);
baseLen := Length(Base);
pathLen := Length(Path);
setLength(tmp, pathLen);
for i := 0 to pathLen -1 do
begin
setLength(tmp[i], baseLen);
if IsSum then
for j := 0 to baseLen -1 do
tmp[i][j] := AddPoints(Path[i], Base[j])
else
for j := 0 to baseLen -1 do
tmp[i][j] := SubtractPoints(Path[i], Base[j]);
end;
SetLength(quad, 4);
SetLength(Result, (pathLen - delta) * baseLen);
g := Iif(IsClosed, pathLen - 1, 0);
for i := delta to pathLen - 1 do
begin
h := baseLen - 1;
k := (i - delta) * baseLen;
for j := 0 to baseLen - 1 do
begin
quad[0] := tmp[g][h];
quad[1] := tmp[i][h];
quad[2] := tmp[i][(j)];
quad[3] := tmp[g][(j)];
if not IsPositive(quad) then
Result[k + j] := ReversePath(quad) else
Result[k + j] := copy(quad, 0, 4);
h := j;
end;
g := i;
end;
end;
//------------------------------------------------------------------------------
function MinkowskiSum(const Pattern, Path: TPath64; PathIsClosed: Boolean): TPaths64;
begin
Result := Union( Minkowski(Pattern, Path, true, PathIsClosed), frNonZero);
end;
//------------------------------------------------------------------------------
function MinkowskiSum(const Pattern, Path: TPathD;
PathIsClosed: Boolean; decimalPlaces: integer): TPathsD;
var
tmp: TPaths64;
scale: double;
begin
scale := Power(10, decimalPlaces);
tmp := Union( Minkowski(ScalePath(Pattern, scale),
ScalePath(Path, scale), true, PathIsClosed), frNonZero);
Result := ScalePathsD(tmp, 1/scale);
end;
//------------------------------------------------------------------------------
function MinkowskiDiff(const path1, path2: TPath64): TPaths64;
begin
Result := Union( Minkowski(path1, path2, false, true), frNonZero);
end;
//------------------------------------------------------------------------------
function MinkowskiDiff(const Pattern, Path: TPathD;
PathIsClosed: Boolean; decimalPlaces: integer): TPathsD;
var
tmp: TPaths64;
scale: double;
begin
scale := Power(10, decimalPlaces);
tmp := Union( Minkowski(ScalePath(Pattern, scale),
ScalePath(Path, scale), false, PathIsClosed), frNonZero);
Result := ScalePathsD(tmp, 1/scale);
end;
//------------------------------------------------------------------------------
end.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,39 @@
///////////////////////////////////////////////////////////////////////////////
//USER DEFINED PREPROCESSOR DIRECTIVES
///////////////////////////////////////////////////////////////////////////////
//For user defined Z-coordinates, defined in Clipper's 'SetZ' callback event
{.$DEFINE USINGZ}
///////////////////////////////////////////////////////////////////////////////
//COMPILER DIFINED PREPROCESSOR DIRECTIVES (ie. do not touch ;))
///////////////////////////////////////////////////////////////////////////////
{$IFDEF FPC}
{$DEFINE INLINING}
{$MODE DELPHI}
{$ELSE}
{$IF COMPILERVERSION < 14}
Requires Delphi version 6 or above.
{$IFEND}
{$IF COMPILERVERSION >= 18} //Delphi 2007
{$DEFINE RECORD_METHODS}
{$DEFINE STRICT}
{$IF COMPILERVERSION >= 19} //Delphi 2009
//While "inlining" is supported from D2005, it's buggy (see QC41166) until D2009
{$DEFINE INLINING}
{$IF COMPILERVERSION >= 23} //Delphi XE2+
{$DEFINE XPLAT_GENERICS}
{$DEFINE ROUNDINGMODE}
{$IF COMPILERVERSION >= 24} //Delphi XE3+
{$LEGACYIFEND ON}
{$IFEND}
{$IFEND}
{$IFEND}
{$IFEND}
{$ENDIF}
{$IFDEF DEBUG}
{$UNDEF INLINING}
{$ENDIF}

View file

@ -0,0 +1,972 @@
unit Clipper;
(*******************************************************************************
* Author : Angus Johnson *
* Date : 7 May 2024 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2024 *
* Purpose : This module provides a simple interface to the Clipper Library *
* License : http://www.boost.org/LICENSE_1_0.txt *
*******************************************************************************)
interface
{$I Clipper.inc}
uses
Math, SysUtils, Classes,
Clipper.Core, Clipper.Engine, Clipper.Offset, Clipper.RectClip;
// A number of structures defined in other units are redeclared here
// so those units won't also need to be declared in your own units clauses.
type
TClipper = Clipper.Engine.TClipper64;
TClipper64 = Clipper.Engine.TClipper64;
TPoint64 = Clipper.Core.TPoint64;
TRect64 = Clipper.Core.TRect64;
TPath64 = Clipper.Core.TPath64;
TPaths64 = Clipper.Core.TPaths64;
TPointD = Clipper.Core.TPointD;
TRectD = Clipper.Core.TRectD;
TPathD = Clipper.Core.TPathD;
TPathsD = Clipper.Core.TPathsD;
TFillRule = Clipper.Core.TFillRule;
TPolyTree64 = Clipper.Engine.TPolyTree64;
TPolyTreeD = Clipper.Engine.TPolyTreeD;
TJoinType = Clipper.Offset.TJoinType;
TEndType = Clipper.Offset.TEndType;
TArrayOfInt64 = array of Int64;
const
frEvenOdd = Clipper.Core.frEvenOdd;
frNonZero = Clipper.Core.frNonZero;
frPositive = Clipper.Core.frPositive;
frNegative = Clipper.Core.frNegative;
jtBevel = Clipper.Offset.jtBevel;
jtSquare = Clipper.Offset.jtSquare;
jtRound = Clipper.Offset.jtRound;
jtMiter = Clipper.Offset.jtMiter;
etPolygon = Clipper.Offset.etPolygon;
etJoined = Clipper.Offset.etJoined;
etButt = Clipper.Offset.etButt;
etSquare = Clipper.Offset.etSquare;
etRound = Clipper.Offset.etRound;
ctNone = Clipper.Core.ctNoClip;
ctIntersection = Clipper.Core.ctIntersection;
ctUnion = Clipper.Core.ctUnion;
ctDifference = Clipper.Core.ctDifference;
ctXor = Clipper.Core.ctXor;
function BooleanOp(clipType: TClipType;
const subjects, clips: TPaths64; fillRule: TFillRule): TPaths64; overload;
function BooleanOp(clipType: TClipType; const subjects, clips:
TPathsD; fillRule: TFillRule; decimalPrec: integer = 2): TPathsD; overload;
procedure BooleanOp(clipType: TClipType; const subjects, clips: TPaths64;
fillRule: TFillRule; polytree: TPolyTree64); overload;
function Intersect(const subjects, clips: TPaths64;
fillRule: TFillRule): TPaths64; overload;
function Union(const subjects, clips: TPaths64;
fillRule: TFillRule): TPaths64; overload;
function Union(const subjects: TPaths64;
fillRule: TFillRule): TPaths64; overload;
function Difference(const subjects, clips: TPaths64;
fillRule: TFillRule): TPaths64; overload;
function XOR_(const subjects, clips: TPaths64;
fillRule: TFillRule): TPaths64; overload;
function Intersect(const subjects, clips: TPathsD;
fillRule: TFillRule; decimalPrec: integer = 2): TPathsD; overload;
function Union(const subjects: TPathsD;
fillRule: TFillRule; decimalPrec: integer = 2): TPathsD; overload;
function Union(const subjects, clips: TPathsD;
fillRule: TFillRule; decimalPrec: integer = 2): TPathsD; overload;
function Difference(const subjects, clips: TPathsD;
fillRule: TFillRule; decimalPrec: integer = 2): TPathsD; overload;
function XOR_(const subjects, clips: TPathsD;
fillRule: TFillRule; decimalPrec: integer = 2): TPathsD; overload;
function InflatePaths(const paths: TPaths64; delta: Double;
jt: TJoinType = jtRound; et: TEndType = etPolygon;
MiterLimit: double = 2.0; ArcTolerance: double = 0.0): TPaths64; overload;
function InflatePaths(const paths: TPathsD; delta: Double;
jt: TJoinType = jtRound; et: TEndType = etPolygon;
miterLimit: double = 2.0; precision: integer = 2;
ArcTolerance: double = 0.0): TPathsD; overload;
// RectClip: for closed paths only (otherwise use RectClipLines)
function RectClip(const rect: TRect64; const path: TPath64): TPath64; overload;
function RectClip(const rect: TRect64; const paths: TPaths64): TPaths64; overload;
function RectClip(const rect: TRectD; const path: TPathD; precision: integer = 2): TPathD; overload;
function RectClip(const rect: TRectD; const paths: TPathsD; precision: integer = 2): TPathsD; overload;
function RectClipLines(const rect: TRect64;
const path: TPath64): TPaths64; overload;
function RectClipLines(const rect: TRect64;
const paths: TPaths64): TPaths64; overload;
function RectClipLines(const rect: TRectD; const path: TPathD;
precision: integer = 2): TPathsD; overload;
function RectClipLines(const rect: TRectD; const paths: TPathsD;
precision: integer = 2): TPathsD; overload;
function TranslatePath(const path: TPath64; dx, dy: Int64): TPath64; overload;
function TranslatePath(const path: TPathD; dx, dy: double): TPathD; overload;
function TranslatePaths(const paths: TPaths64; dx, dy: Int64): TPaths64; overload;
function TranslatePaths(const paths: TPathsD; dx, dy: double): TPathsD; overload;
function MinkowskiSum(const pattern, path: TPath64;
pathIsClosed: Boolean): TPaths64; overload;
function MinkowskiSum(const pattern, path: TPathD;
pathIsClosed: Boolean): TPathsD; overload;
function PolyTreeToPaths64(PolyTree: TPolyTree64): TPaths64;
function PolyTreeToPathsD(PolyTree: TPolyTreeD): TPathsD;
function PathToString(const p: TPath64;
indentSpaces: integer = 0; pointsPerRow: integer = 0): string; overload;
function PathToString(const p: TPathD; decimals: integer;
indentSpaces: integer = 0; pointsPerRow: integer = 0): string; overload;
function PathsToString(const p: TPaths64;
indentSpaces: integer = 0; pointsPerRow: integer = 0): string; overload;
function PathsToString(const p: TPathsD; decimals: integer;
indentSpaces: integer = 0; pointsPerRow: integer = 0): string; overload;
//ShowPolyTreeStructure: only useful when debugging
procedure ShowPolyTreeStructure(polytree: TPolyTree64; strings: TStrings); overload;
procedure ShowPolyTreeStructure(polytree: TPolyTreeD; strings: TStrings); overload;
function MakePath(const ints: array of Int64): TPath64; overload;
function MakePathD(const dbls: array of double): TPathD; overload;
function TrimCollinear(const p: TPath64;
isOpenPath: Boolean = false): TPath64; overload;
function TrimCollinear(const path: TPathD;
precision: integer; isOpenPath: Boolean = false): TPathD; overload;
function PointInPolygon(const pt: TPoint64; const polygon: TPath64):
TPointInPolygonResult;
function SimplifyPath(const path: TPath64;
shapeTolerance: double; isClosedPath: Boolean = true): TPath64; overload;
function SimplifyPaths(const paths: TPaths64;
shapeTolerance: double; isClosedPath: Boolean = true): TPaths64; overload;
function SimplifyPath(const path: TPathD; shapeTolerance: double;
isClosedPath: Boolean = true; decimalPrecision: integer = 2): TPathD; overload;
function SimplifyPaths(const paths: TPathsD; shapeTolerance: double;
isClosedPath: Boolean = true; decimalPrecision: integer = 2): TPathsD; overload;
implementation
uses
Clipper.Minkowski;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
{$IFDEF USINGZ}
function MakePath(const ints: array of Int64): TPath64;
var
i, len: integer;
begin
len := length(ints) div 3;
SetLength(Result, len);
for i := 0 to len -1 do
begin
Result[i].X := ints[i*3];
Result[i].Y := ints[i*3 +1];
Result[i].z := ints[i*3 +2];
end;
end;
//------------------------------------------------------------------------------
function MakePathD(const dbls: array of double): TPathD; overload;
var
i, len: integer;
begin
len := length(dbls) div 3;
SetLength(Result, len);
for i := 0 to len -1 do
begin
Result[i].X := dbls[i*3];
Result[i].Y := dbls[i*3 +1];
Result[i].Z := Round(dbls[i*3 +2]);
end;
end;
//------------------------------------------------------------------------------
{$ELSE}
function MakePath(const ints: array of Int64): TPath64;
var
i, len: integer;
begin
len := length(ints) div 2;
SetLength(Result, len);
for i := 0 to len -1 do
begin
Result[i].X := ints[i*2];
Result[i].Y := ints[i*2 +1];
end;
end;
//------------------------------------------------------------------------------
function MakePathD(const dbls: array of double): TPathD; overload;
var
i, len: integer;
begin
len := length(dbls) div 2;
SetLength(Result, len);
for i := 0 to len -1 do
begin
Result[i].X := dbls[i*2];
Result[i].Y := dbls[i*2 +1];
end;
end;
//------------------------------------------------------------------------------
{$ENDIF}
procedure AddPolyNodeToPaths(Poly: TPolyPath64; var Paths: TPaths64);
var
i: Integer;
begin
if (Length(Poly.Polygon) > 0) then
begin
i := Length(Paths);
SetLength(Paths, i +1);
Paths[i] := Poly.Polygon;
end;
for i := 0 to Poly.Count - 1 do
AddPolyNodeToPaths(Poly[i], Paths);
end;
//------------------------------------------------------------------------------
function PolyTreeToPaths64(PolyTree: TPolyTree64): TPaths64;
begin
Result := nil;
AddPolyNodeToPaths(PolyTree, Result);
end;
//------------------------------------------------------------------------------
procedure AddPolyNodeToPathsD(Poly: TPolyPathD; var Paths: TPathsD);
var
i: Integer;
begin
if (Length(Poly.Polygon) > 0) then
begin
i := Length(Paths);
SetLength(Paths, i +1);
Paths[i] := Poly.Polygon;
end;
for i := 0 to Poly.Count - 1 do
AddPolyNodeToPathsD(Poly[i], Paths);
end;
//------------------------------------------------------------------------------
function PolyTreeToPathsD(PolyTree: TPolyTreeD): TPathsD;
begin
Result := nil;
AddPolyNodeToPathsD(PolyTree, Result);
end;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
function BooleanOp(clipType: TClipType;
const subjects, clips: TPaths64; fillRule: TFillRule): TPaths64;
begin
with TClipper64.Create do
try
AddSubject(subjects);
AddClip(clips);
Execute(clipType, fillRule, Result);
finally
Free;
end;
end;
//------------------------------------------------------------------------------
function BooleanOp(clipType: TClipType; const subjects, clips: TPathsD;
fillRule: TFillRule; decimalPrec: integer = 2): TPathsD;
begin
with TClipperD.Create(decimalPrec) do
try
AddSubject(subjects);
AddClip(clips);
Execute(clipType, fillRule, Result);
finally
Free;
end;
end;
//------------------------------------------------------------------------------
procedure BooleanOp(clipType: TClipType; const subjects, clips: TPaths64;
fillRule: TFillRule; polytree: TPolyTree64);
var
dummy: TPaths64;
begin
with TClipper64.Create do
try
AddSubject(subjects);
AddClip(clips);
Execute(clipType, fillRule, polytree, dummy);
finally
Free;
end;
end;
//------------------------------------------------------------------------------
function Intersect(const subjects, clips: TPaths64; fillRule: TFillRule): TPaths64;
begin
Result := BooleanOp(ctIntersection, subjects, clips, fillRule);
end;
//------------------------------------------------------------------------------
function Union(const subjects, clips: TPaths64; fillRule: TFillRule): TPaths64;
begin
Result := BooleanOp(ctUnion, subjects, clips, fillRule);
end;
//------------------------------------------------------------------------------
function Union(const subjects: TPaths64; fillRule: TFillRule): TPaths64;
begin
Result := BooleanOp(ctUnion, subjects, nil, fillRule);
end;
//------------------------------------------------------------------------------
function Difference(const subjects, clips: TPaths64; fillRule: TFillRule): TPaths64;
begin
Result := BooleanOp(ctDifference, subjects, clips, fillRule);
end;
//------------------------------------------------------------------------------
function XOR_(const subjects, clips: TPaths64; fillRule: TFillRule): TPaths64;
begin
Result := BooleanOp(ctXor, subjects, clips, fillRule);
end;
//------------------------------------------------------------------------------
function Intersect(const subjects, clips: TPathsD;
fillRule: TFillRule; decimalPrec: integer = 2): TPathsD;
begin
Result := BooleanOp(ctIntersection, subjects, clips, fillRule, decimalPrec);
end;
//------------------------------------------------------------------------------
function Union(const subjects, clips: TPathsD;
fillRule: TFillRule; decimalPrec: integer = 2): TPathsD;
begin
Result := BooleanOp(ctUnion, subjects, clips, fillRule, decimalPrec);
end;
//------------------------------------------------------------------------------
function Union(const subjects: TPathsD;
fillRule: TFillRule; decimalPrec: integer = 2): TPathsD;
begin
Result := BooleanOp(ctUnion, subjects, nil, fillRule, decimalPrec);
end;
//------------------------------------------------------------------------------
function Difference(const subjects, clips: TPathsD;
fillRule: TFillRule; decimalPrec: integer = 2): TPathsD;
begin
Result := BooleanOp(ctDifference, subjects, clips, fillRule, decimalPrec);
end;
//------------------------------------------------------------------------------
function XOR_(const subjects, clips: TPathsD;
fillRule: TFillRule; decimalPrec: integer = 2): TPathsD;
begin
Result := BooleanOp(ctXor, subjects, clips, fillRule, decimalPrec);
end;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
function InflatePaths(const paths: TPaths64; delta: Double;
jt: TJoinType; et: TEndType; MiterLimit: double;
ArcTolerance: double): TPaths64;
var
co: TClipperOffset;
begin
co := TClipperOffset.Create(MiterLimit, ArcTolerance);
try
co.AddPaths(paths, jt, et);
co.Execute(delta, Result);
finally
co.free;
end;
end;
//------------------------------------------------------------------------------
function InflatePaths(const paths: TPathsD; delta: Double;
jt: TJoinType; et: TEndType; miterLimit: double;
precision: integer; ArcTolerance: double): TPathsD;
var
pp: TPaths64;
scale, invScale: double;
begin
CheckPrecisionRange(precision);
scale := Power(10, precision);
invScale := 1/scale;
pp := ScalePaths(paths, scale, scale);
with TClipperOffset.Create(miterLimit, ArcTolerance) do
try
AddPaths(pp, jt, et);
Execute(delta * scale, pp); // reuse pp to receive the solution.
finally
free;
end;
Result := ScalePathsD(pp, invScale, invScale);
end;
//------------------------------------------------------------------------------
function RectClip(const rect: TRect64;
const path: TPath64): TPath64;
var
paths: TPaths64;
begin
SetLength(paths, 1);
paths[0] := path;
paths := RectClip(rect, paths);
if Assigned(paths) then
Result := paths[0] else
Result := nil;
end;
//------------------------------------------------------------------------------
function RectClip(const rect: TRect64; const paths: TPaths64): TPaths64;
begin
Result := nil;
if rect.IsEmpty then Exit;
with TRectClip64.Create(rect) do
try
Result := Execute(paths);
finally
Free;
end;
end;
//------------------------------------------------------------------------------
function RectClip(const rect: TRectD; const path: TPathD; precision: integer): TPathD;
var
scale: double;
tmpPath: TPath64;
rec: TRect64;
begin
Result := nil;
if not rect.Intersects(GetBounds(path)) then Exit;
CheckPrecisionRange(precision);
scale := Math.Power(10, precision);
rec := Rect64(ScaleRect(rect, scale));
tmpPath := ScalePath(path, scale);
tmpPath := RectClip(rec, tmpPath);
Result := ScalePathD(tmpPath, 1/scale);
end;
//------------------------------------------------------------------------------
function RectClip(const rect: TRectD; const paths: TPathsD; precision: integer): TPathsD;
var
scale: double;
tmpPaths: TPaths64;
rec: TRect64;
begin
CheckPrecisionRange(precision);
scale := Math.Power(10, precision);
rec := Rect64(ScaleRect(rect, scale));
tmpPaths := ScalePaths(paths, scale);
with TRectClip64.Create(rec) do
try
tmpPaths := Execute(tmpPaths);
finally
Free;
end;
Result := ScalePathsD(tmpPaths, 1/scale);
end;
//------------------------------------------------------------------------------
function RectClipLines(const rect: TRect64; const path: TPath64): TPaths64;
var
tmp: TPaths64;
begin
Result := nil;
SetLength(tmp, 1);
tmp[0] := path;
with TRectClipLines64.Create(rect) do
try
Result := Execute(tmp);
finally
Free;
end;
end;
//------------------------------------------------------------------------------
function RectClipLines(const rect: TRect64; const paths: TPaths64): TPaths64;
begin
Result := nil;
if rect.IsEmpty then Exit;
with TRectClipLines64.Create(rect) do
try
Result := Execute(paths);
finally
Free;
end;
end;
//------------------------------------------------------------------------------
function RectClipLines(const rect: TRectD;
const path: TPathD; precision: integer): TPathsD;
var
scale: double;
tmpPath: TPath64;
tmpPaths: TPaths64;
rec: TRect64;
begin
Result := nil;
if not rect.Intersects(GetBounds(path)) then Exit;
CheckPrecisionRange(precision);
scale := Math.Power(10, precision);
rec := Rect64(ScaleRect(rect, scale));
tmpPath := ScalePath(path, scale);
tmpPaths := RectClipLines(rec, tmpPath);
Result := ScalePathsD(tmpPaths, 1/scale);
end;
//------------------------------------------------------------------------------
function RectClipLines(const rect: TRectD; const paths: TPathsD;
precision: integer = 2): TPathsD;
var
scale: double;
tmpPaths: TPaths64;
rec: TRect64;
begin
Result := nil;
if rect.IsEmpty then Exit;
CheckPrecisionRange(precision);
scale := Math.Power(10, precision);
rec := Rect64(ScaleRect(rect, scale));
tmpPaths := ScalePaths(paths, scale);
with TRectClipLines64.Create(rec) do
try
tmpPaths := Execute(tmpPaths);
finally
Free;
end;
Result := ScalePathsD(tmpPaths, 1/scale);
end;
//------------------------------------------------------------------------------
function TranslatePath(const path: TPath64; dx, dy: Int64): TPath64;
var
i, len: integer;
begin
len := length(path);
setLength(result, len);
for i := 0 to len -1 do
begin
result[i].x := path[i].x + dx;
result[i].y := path[i].y + dy;
end;
end;
//------------------------------------------------------------------------------
function TranslatePath(const path: TPathD; dx, dy: double): TPathD;
var
i, len: integer;
begin
len := length(path);
setLength(result, len);
for i := 0 to len -1 do
begin
result[i].x := path[i].x + dx;
result[i].y := path[i].y + dy;
end;
end;
//------------------------------------------------------------------------------
function TranslatePaths(const paths: TPaths64; dx, dy: Int64): TPaths64;
var
i, len: integer;
begin
len := length(paths);
setLength(result, len);
for i := 0 to len -1 do
begin
result[i] := TranslatePath(paths[i], dx, dy);
end;
end;
//------------------------------------------------------------------------------
function TranslatePaths(const paths: TPathsD; dx, dy: double): TPathsD;
var
i, len: integer;
begin
len := length(paths);
setLength(result, len);
for i := 0 to len -1 do
begin
result[i] := TranslatePath(paths[i], dx, dy);
end;
end;
//------------------------------------------------------------------------------
function MinkowskiSum(const pattern, path: TPath64;
pathIsClosed: Boolean): TPaths64;
begin
Result := Clipper.Minkowski.MinkowskiSum(pattern, path, pathIsClosed);
end;
//------------------------------------------------------------------------------
function MinkowskiSum(const pattern, path: TPathD;
pathIsClosed: Boolean): TPathsD;
begin
Result := Clipper.Minkowski.MinkowskiSum(pattern, path, pathIsClosed);
end;
//------------------------------------------------------------------------------
function PathToString(const p: TPath64;
indentSpaces: integer; pointsPerRow: integer): string;
var
i, highI: Integer;
spaces: string;
begin
spaces := StringOfChar(' ', indentSpaces);
Result := spaces;
highI := high(p);
if highI < 0 then Exit;
for i := 0 to highI -1 do
begin
Result := Result + format('%d,%d, ',[p[i].X,p[i].Y]);
if (pointsPerRow > 0) and ((i + 1) mod pointsPerRow = 0) then
Result := Result + #10 + spaces;
end;
Result := Result + format('%d,%d',[p[highI].X,p[highI].Y]);
end;
//------------------------------------------------------------------------------
function PathToString(const p: TPathD; decimals: integer;
indentSpaces: integer; pointsPerRow: integer): string;
var
i, highI: Integer;
spaces: string;
begin
spaces := StringOfChar(' ', indentSpaces);
Result := '';
highI := high(p);
if highI < 0 then Exit;
for i := 0 to highI -1 do
Result := Result + format('%1.*n,%1.*n, ',
[decimals, p[i].X, decimals, p[i].Y]);
Result := Result + format('%1.*n,%1.*n',[
decimals, p[highI].X, decimals, p[highI].Y]);
end;
//------------------------------------------------------------------------------
function PathsToString(const p: TPaths64;
indentSpaces: integer = 0; pointsPerRow: integer = 0): string;
var
i: integer;
begin
Result := '';
for i := 0 to High(p) do
Result := Result + PathToString(p[i], indentSpaces, pointsPerRow) + #10#10;
end;
//------------------------------------------------------------------------------
function PathsToString(const p: TPathsD; decimals: integer;
indentSpaces: integer = 0; pointsPerRow: integer = 0): string;
var
i: integer;
begin
Result := '';
for i := 0 to High(p) do
Result := Result + PathToString(p[i], indentSpaces, pointsPerRow) + #10#10;
end;
//------------------------------------------------------------------------------
procedure ShowPolyPathStructure64(pp: TPolyPath64; level: integer;
strings: TStrings);
var
i: integer;
spaces, plural: string;
begin
spaces := StringOfChar(' ', level * 2);
if pp.Count = 1 then plural := '' else plural := 's';
if pp.IsHole then
strings.Add(Format('%sA hole containing %d polygon%s', [spaces, pp.Count, plural]))
else
strings.Add(Format('%sA polygon containing %d hole%s', [spaces, pp.Count, plural]));
for i := 0 to pp.Count -1 do
if pp.child[i].Count> 0 then
ShowPolyPathStructure64(pp.child[i], level + 1, strings);
end;
//------------------------------------------------------------------------------
procedure ShowPolyTreeStructure(polytree: TPolyTree64; strings: TStrings);
var
i: integer;
begin
if polytree.Count = 1 then
strings.Add('Polytree with just 1 polygon.') else
strings.Add(Format('Polytree with just %d polygons.', [polytree.Count]));
for i := 0 to polytree.Count -1 do
if polytree[i].Count > 0 then
ShowPolyPathStructure64(polytree[i], 1, strings);
end;
//------------------------------------------------------------------------------
procedure ShowPolyPathStructureD(pp: TPolyPathD; level: integer; strings: TStrings);
var
i: integer;
spaces, plural: string;
begin
spaces := StringOfChar(' ', level * 2);
if pp.Count = 1 then plural := '' else plural := 's';
if pp.IsHole then
strings.Add(Format('%sA hole containing %d polygon%s', [spaces, pp.Count, plural]))
else
strings.Add(Format('%sA polygon containing %d hole%s', [spaces, pp.Count, plural]));
for i := 0 to pp.Count -1 do
if pp.child[i].Count> 0 then
ShowPolyPathStructureD(pp.child[i], level + 1, strings);
end;
//------------------------------------------------------------------------------
procedure ShowPolyTreeStructure(polytree: TPolyTreeD; strings: TStrings);
var
i: integer;
begin
if polytree.Count = 1 then
strings.Add('Polytree with just 1 polygon.') else
strings.Add(Format('Polytree with just %d polygons.', [polytree.Count]));
for i := 0 to polytree.Count -1 do
if polytree[i].Count > 0 then
ShowPolyPathStructureD(polytree[i], 1, strings);
end;
//------------------------------------------------------------------------------
function TrimCollinear(const p: TPath64; isOpenPath: Boolean = false): TPath64;
var
i,j, len: integer;
begin
len := Length(p);
i := 0;
if not isOpenPath then
begin
while (i < len -1) and
IsCollinear(p[len -1], p[i], p[i+1]) do inc(i);
while (i < len -1) and
IsCollinear(p[len -2], p[len -1], p[i]) do dec(len);
end;
if (len - i < 3) then
begin
if not isOpenPath or (len < 2) or PointsEqual(p[0], p[1]) then
Result := nil else
Result := p;
Exit;
end;
SetLength(Result, len -i);
Result[0] := p[i];
j := 0;
for i := i+1 to len -2 do
if not IsCollinear(result[j], p[i], p[i+1]) then
begin
inc(j);
result[j] := p[i];
end;
if isOpenPath then
begin
inc(j);
result[j] := p[len-1];
end
else if not IsCollinear(result[j], p[len-1], result[0]) then
begin
inc(j);
result[j] := p[len-1];
end else
begin
while (j > 1) and
IsCollinear(result[j-1], result[j], result[0]) do dec(j);
if j < 2 then j := -1;
end;
SetLength(Result, j +1);
end;
//------------------------------------------------------------------------------
function TrimCollinear(const path: TPathD;
precision: integer; isOpenPath: Boolean = false): TPathD;
var
p: TPath64;
scale: double;
begin
scale := power(10, precision);
p := ScalePath(path, scale);
p := TrimCollinear(p, isOpenPath);
Result := ScalePathD(p, 1/scale);
end;
//------------------------------------------------------------------------------
function PointInPolygon(const pt: TPoint64;
const polygon: TPath64): TPointInPolygonResult;
begin
Result := Clipper.Core.PointInPolygon(pt, polygon);
end;
//------------------------------------------------------------------------------
function DistanceSqrd(const pt1, pt2: TPoint64): double;
{$IFDEF INLINE} inline; {$ENDIF}
var
x1,y1,x2,y2: double;
begin
// nb: older versions of Delphi don't allow explicit typcasting
x1 := pt1.X; y1 := pt1.Y;
x2 := pt2.X; y2 := pt2.Y;
result := Sqr(x1 - x2) + Sqr(y1 - y2);
end;
//------------------------------------------------------------------------------
function PerpendicDistSqrd(const pt, line1, line2: TPoint64): double;
{$IFDEF INLINE} inline; {$ENDIF}
var
a,b,c,d: double;
begin
a := pt.X - line1.X;
b := pt.Y - line1.Y;
c := line2.X - line1.X;
d := line2.Y - line1.Y;
result := Iif((c = 0) and (d = 0),
0, Sqr(a * d - c * b) / (c * c + d * d));
end;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
type
PSimplifyRec = ^TSimplifyRec;
TSimplifyRec = record
pt : TPoint64;
pdSqrd : double;
prev : PSimplifyRec;
next : PSimplifyRec;
//isEnd : Boolean;
end;
function SimplifyPath(const path: TPath64;
shapeTolerance: double; isClosedPath: Boolean): TPath64;
var
i, highI, minHigh: integer;
tolSqrd: double;
srArray: array of TSimplifyRec;
first, last: PSimplifyRec;
begin
Result := nil;
highI := High(path);
minHigh := Iif(isClosedPath, 2, 1);
if highI < minHigh then Exit;
SetLength(srArray, highI +1);
with srArray[0] do
begin
pt := path[0];
prev := @srArray[highI];
next := @srArray[1];
pdSqrd := Iif(isClosedPath,
PerpendicDistSqrd(path[0], path[highI], path[1]), invalidD);
end;
with srArray[highI] do
begin
pt := path[highI];
prev := @srArray[highI-1];
next := @srArray[0];
pdSqrd := Iif(isClosedPath,
PerpendicDistSqrd(path[highI], path[highI-1], path[0]), invalidD);
end;
for i := 1 to highI -1 do
with srArray[i] do
begin
pt := path[i];
prev := @srArray[i-1];
next := @srArray[i+1];
pdSqrd := PerpendicDistSqrd(path[i], path[i-1], path[i+1]);
end;
first := @srArray[0];
last := first.prev;
tolSqrd := Sqr(shapeTolerance);
while first <> last do
begin
if (first.pdSqrd > tolSqrd) or
(first.next.pdSqrd < first.pdSqrd) then
begin
first := first.next;
Continue;
end;
dec(highI);
first.prev.next := first.next;
first.next.prev := first.prev;
last := first.prev;
first := last.next;
if first.next = first.prev then break;
last.pdSqrd := PerpendicDistSqrd(last.pt, last.prev.pt, first.pt);
first.pdSqrd := PerpendicDistSqrd(first.pt, last.pt, first.next.pt);
end;
if highI < minHigh then Exit;
if not isClosedPath then first := @srArray[0];
SetLength(Result, highI +1);
for i := 0 to HighI do
begin
Result[i] := first.pt;
first := first.next;
end;
end;
//------------------------------------------------------------------------------
function SimplifyPaths(const paths: TPaths64;
shapeTolerance: double; isClosedPath: Boolean): TPaths64;
var
i, len: integer;
begin
len := Length(paths);
SetLength(Result, len);
for i := 0 to len -1 do
result[i] := SimplifyPath(paths[i], shapeTolerance, isClosedPath);
end;
//------------------------------------------------------------------------------
function SimplifyPath(const path: TPathD; shapeTolerance: double;
isClosedPath: Boolean; decimalPrecision: integer): TPathD;
var
p: TPath64;
scale: double;
begin
scale := power(10, decimalPrecision);
p := ScalePath(path, scale);
p := SimplifyPath(p, shapeTolerance, isClosedPath);
Result := ScalePathD(p, 1/scale);
end;
//------------------------------------------------------------------------------
function SimplifyPaths(const paths: TPathsD; shapeTolerance: double;
isClosedPath: Boolean; decimalPrecision: integer): TPathsD;
var
pp: TPaths64;
scale: double;
begin
scale := power(10, decimalPrecision);
pp := ScalePaths(paths, scale);
pp := SimplifyPaths(pp, shapeTolerance, isClosedPath);
Result := ScalePathsD(pp, 1/scale);
end;
//------------------------------------------------------------------------------
end.

View file

@ -0,0 +1,197 @@
unit Img32.Clipper2;
(*******************************************************************************
* Author : Angus Johnson *
* Version : 4.7 *
* Date : 6 January 2025 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2019-2025 *
* Purpose : Wrapper module for the Clipper library *
* License : http://www.boost.org/LICENSE_1_0.txt *
*******************************************************************************)
interface
uses
Img32, Img32.Draw, Img32.Vector, Clipper.Offset;
//nb: InflatePath assumes that there's consistent winding where
//outer paths wind in one direction and inner paths in the other
type
TClipperEndType = Clipper.Offset.TEndType;
function ClipperEndType(endStyle: TEndStyle): TClipperEndType;
function InflatePath(const path: TPathD; delta: Double;
joinStyle: TJoinStyle = jsAuto; endType: TClipperEndType = etPolygon;
miterLimit: double = 2.0; arcTolerance: double = 0.0;
minEdgeLength: double = 0.25): TPathsD;
function InflatePaths(const paths: TPathsD; delta: Double;
joinStyle: TJoinStyle = jsAuto; endType: TClipperEndType = etPolygon;
miterLimit: double = 2.0; arcTolerance: double = 0.0;
minEdgeLength: double = 0): TPathsD;
//UnionPolygon: removes self-intersections
function UnionPolygon(const polygon: TPathD;
fillRule: TFillRule): TPathsD;
function UnionPolygons(const polygons: TPathsD;
fillRule: TFillRule): TPathsD; overload;
function UnionPolygons(const polygon1, polygon2: TPathD;
fillRule: TFillRule): TPathsD; overload;
function UnionPolygons(const polygons1, polygons2: TPathsD;
fillRule: TFillRule): TPathsD; overload;
function IntersectPolygons(const polygons1, polygons2: TPathsD;
fillRule: TFillRule): TPathsD;
function DifferencePolygons(const polygons1, polygons2: TPathsD;
fillRule: TFillRule): TPathsD;
const
etPolygon = Clipper.Offset.etPolygon;
etJoined = Clipper.Offset.etJoined;
etButt = Clipper.Offset.etButt;
etSquare = Clipper.Offset.etSquare;
etRound = Clipper.Offset.etRound;
implementation
uses Clipper, Clipper.Core, Clipper.Engine;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
function ClipperEndType(endStyle: TEndStyle): TClipperEndType;
begin
case endStyle of
esPolygon: Result := etJoined;
esButt: Result := etButt;
esSquare: Result := etSquare;
else Result := etRound;
end;
end;
//------------------------------------------------------------------------------
function InflatePath(const path: Img32.TPathD;
delta: Double; joinStyle: TJoinStyle; endType: TClipperEndType;
miterLimit: double; arcTolerance: double; minEdgeLength: double): Img32.TPathsD;
var
paths: Img32.TPathsD;
begin
setLength(paths, 1);
paths[0] := path;
Result := InflatePaths(paths, delta, joinStyle, endType,
miterLimit, arcTolerance, minEdgeLength);
end;
//------------------------------------------------------------------------------
function InflatePaths(const paths: Img32.TPathsD;
delta: Double; joinStyle: TJoinStyle; endType: TClipperEndType;
miterLimit: double; arcTolerance: double; minEdgeLength: double): Img32.TPathsD;
var
jt: Clipper.Offset.TJoinType;
begin
case joinStyle of
jsSquare : jt := jtSquare;
jsButt : jt := jtBevel;
jsMiter : jt := jtMiter;
jsRound : jt := jtRound;
else if endType = etRound then jt := jtRound
else jt := jtSquare;
end;
Result := Img32.TPathsD(Clipper.InflatePaths(
Clipper.Core.TPathsD(paths), delta, jt, endType));
end;
//------------------------------------------------------------------------------
function UnionPolygon(const polygon: Img32.TPathD;
fillRule: Img32.Vector.TFillRule): Img32.TPathsD;
begin
with TClipperD.Create do
try
AddSubject(Clipper.Core.TPathD(polygon));
Execute(ctUnion,
Clipper.Core.TFillRule(fillRule), Clipper.Core.TPathsD(result));
finally
Free;
end;
end;
//------------------------------------------------------------------------------
function UnionPolygons(const polygons: Img32.TPathsD;
fillRule: Img32.Vector.TFillRule): Img32.TPathsD;
begin
with TClipperD.Create do
try
AddSubject(Clipper.Core.TPathsD(polygons));
Execute(ctUnion,
Clipper.Core.TFillRule(fillRule), Clipper.Core.TPathsD(result));
finally
Free;
end;
end;
//------------------------------------------------------------------------------
function UnionPolygons(const polygon1, polygon2: Img32.TPathD;
fillRule: Img32.Vector.TFillRule): Img32.TPathsD;
begin
with TClipperD.Create do
try
AddSubject(Clipper.Core.TPathD(polygon1));
AddClip(Clipper.Core.TPathD(polygon2));
Execute(ctUnion,
Clipper.Core.TFillRule(fillRule), Clipper.Core.TPathsD(result));
finally
Free;
end;
end;
//------------------------------------------------------------------------------
function UnionPolygons(const polygons1, polygons2: Img32.TPathsD;
fillRule: Img32.Vector.TFillRule): Img32.TPathsD;
begin
with TClipperD.Create do
try
AddSubject(Clipper.Core.TPathsD(polygons1));
AddClip(Clipper.Core.TPathsD(polygons2));
Execute(ctUnion,
Clipper.Core.TFillRule(fillRule), Clipper.Core.TPathsD(result));
finally
Free;
end;
end;
//------------------------------------------------------------------------------
function IntersectPolygons(const polygons1, polygons2: Img32.TPathsD;
fillRule: Img32.Vector.TFillRule): Img32.TPathsD;
begin
with TClipperD.Create do
try
AddSubject(Clipper.Core.TPathsD(polygons1));
AddClip(Clipper.Core.TPathsD(polygons2));
Execute(ctIntersection,
Clipper.Core.TFillRule(fillRule), Clipper.Core.TPathsD(result));
finally
Free;
end;
end;
//------------------------------------------------------------------------------
function DifferencePolygons(const polygons1, polygons2: Img32.TPathsD;
fillRule: Img32.Vector.TFillRule): Img32.TPathsD;
begin
with TClipperD.Create do
try
AddSubject(Clipper.Core.TPathsD(polygons1));
AddClip(Clipper.Core.TPathsD(polygons2));
Execute(ctDifference,
Clipper.Core.TFillRule(fillRule), Clipper.Core.TPathsD(result));
finally
Free;
end;
end;
//------------------------------------------------------------------------------
end.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -2,10 +2,10 @@ unit Img32.Fmt.SVG;
(*******************************************************************************
* Author : Angus Johnson *
* Version : 4.3.1 *
* Date : 5 October 2022 *
* Version : 4.7 *
* Date : 6 January 2025 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2019-2022 *
* Copyright : Angus Johnson 2019-2025 *
* Purpose : SVG file format extension for TImage32 *
* License : http://www.boost.org/LICENSE_1_0.txt *
*******************************************************************************)
@ -15,16 +15,24 @@ interface
{$I Img32.inc}
uses
{$IFDEF MSWINDOWS} Windows, {$ENDIF} SysUtils, Classes, Math,
{$IFDEF MSWINDOWS} Windows, {$ENDIF}
{$IF NOT DEFINED(NEWPOSFUNC) OR DEFINED(FPC)} StrUtils, {$IFEND}
{$IFDEF UNICODE} AnsiStrings, {$ENDIF}
SysUtils, Classes, Math,
{$IFDEF XPLAT_GENERICS} Generics.Collections, Generics.Defaults, {$ENDIF}
Img32, Img32.Vector, Img32.SVG.Reader;
Img32, Img32.Vector, Img32.SVG.Core, Img32.SVG.Reader
{$IF DEFINED(USING_LCL)}, Types{$IFEND}
;
type
TImageFormat_SVG = class(TImageFormat)
public
class function IsValidImageStream(stream: TStream): Boolean; override;
function LoadFromStream(stream: TStream; img32: TImage32): Boolean; override;
procedure SaveToStream(stream: TStream; img32: TImage32); override;
function LoadFromStream(stream: TStream;
img32: TImage32; imgIndex: integer = 0): Boolean; override;
// SaveToStream: not implemented for SVG streams
procedure SaveToStream(stream: TStream;
img32: TImage32; quality: integer = 0); override;
class function CanCopyToClipboard: Boolean; override;
class function CopyToClipboard(img32: TImage32): Boolean; override;
class function CanPasteFromClipboard: Boolean; override;
@ -83,10 +91,6 @@ type
{$ENDIF}
end;
var
defaultSvgWidth: integer = 800;
defaultSvgHeight: integer = 600;
implementation
//------------------------------------------------------------------------------
@ -362,38 +366,38 @@ end;
// Loading (reading) SVG images from file ...
//------------------------------------------------------------------------------
function TImageFormat_SVG.LoadFromStream(stream: TStream; img32: TImage32): Boolean;
function TImageFormat_SVG.LoadFromStream(stream: TStream;
img32: TImage32; imgIndex: integer = 0): Boolean;
var
r: TRectWH;
w,h, sx,sy: double;
sx: double;
begin
with TSvgReader.Create do
try
Result := LoadFromStream(stream);
if not Result then Exit;
r := GetViewbox(img32.Width, img32.Height);
r := RootElement.viewboxWH;
img32.BeginUpdate;
try
if img32.IsEmpty and not r.IsEmpty then
img32.SetSize(Round(r.Width), Round(r.Height))
if img32.IsEmpty then
begin
with RootElement do
if Width.IsValid and Height.IsValid then
img32.SetSize(
Round(Width.GetValue(defaultSvgWidth, 0)),
Round(Height.GetValue(defaultSvgHeight, 0)))
else if not r.IsEmpty then
img32.SetSize(Round(r.Width), Round(r.Height))
else
img32.SetSize(defaultSvgWidth, defaultSvgHeight);
end
else if not r.IsEmpty then
begin
//then scale the SVG to fit image
w := r.Width;
h := r.Height;
sx := img32.Width / w;
sy := img32.Height / h;
if sy < sx then sx := sy;
if not(SameValue(sx, 1, 0.00001)) then
begin
w := w * sx;
h := h * sx;
end;
img32.SetSize(Round(w), Round(h));
end
else
img32.SetSize(defaultSvgWidth, defaultSvgHeight);
// scale the SVG to best fit the image dimensions
sx := GetScaleForBestFit(r.Width, r.Height, img32.Width, img32.Height);
img32.SetSize(Round(r.Width * sx), Round(r.Height * sx));
end;
//draw the SVG image to fit inside the canvas
DrawImage(img32, True);
@ -434,7 +438,8 @@ begin
end;
//------------------------------------------------------------------------------
procedure TImageFormat_SVG.SaveToStream(stream: TStream; img32: TImage32);
procedure TImageFormat_SVG.SaveToStream(stream: TStream;
img32: TImage32; quality: integer);
begin
//not enabled
end;

View file

@ -2,10 +2,10 @@ unit Img32.Resamplers;
(*******************************************************************************
* Author : Angus Johnson *
* Version : 4.3 *
* Date : 27 September 2022 *
* Version : 4.8 *
* Date : 10 January 2025 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2019-2021 *
* Copyright : Angus Johnson 2019-2025 *
* Purpose : For image transformations (scaling, rotating etc.) *
* License : http://www.boost.org/LICENSE_1_0.txt *
*******************************************************************************)
@ -15,111 +15,265 @@ interface
{$I Img32.inc}
uses
SysUtils, Classes, Img32;
SysUtils, Classes, Math, Img32;
//BoxDownSampling: As the name implies, this routine is only intended for
//image down-sampling (ie when shrinking images) where it generally performs
//better than other resamplers which tend to lose too much detail. However,
//because this routine is inferior to other resamplers when performing other
//transformations (ie when enlarging, rotating, and skewing images), it's not
//intended as a general purpose resampler.
procedure BoxDownSampling(Image: TImage32; newWidth, newHeight: Integer);
// Premultiplies the alpha channel into the color channels from pSrc and stores
// it into pDst. pSrc and pDst can be the same pointer.
procedure PremultiplyAlpha(pSrc, pDst: PARGB; count: nativeint); overload;
(* The following functions are registered in the initialization section below
function NearestResampler(img: TImage32; x256, y256: Integer): TColor32;
function BilinearResample(img: TImage32; x256, y256: Integer): TColor32;
function BicubicResample(img: TImage32; x256, y256: Integer): TColor32;
*)
// BoxDownSampling: As the name implies, is only intended for image
// down-sampling (ie shrinking images) where it performs a little better
// than other resamplers which tend toward pixelation. Nevertheless, this
// routine is inferior to other resamplers when performing other
// types of transformations (ie when enlarging, rotating, and skewing images),
// so BoxDownSampling should not be used as a general purpose resampler.
procedure BoxDownSampling(Image: TImage32; scale: double); overload;
procedure BoxDownSampling(Image: TImage32; scaleX, scaleY: double); overload;
procedure BoxDownSampling(Image: TImage32; newWidth, newHeight: Integer); overload;
procedure BoxDownSampling(Image, TargetImage: TImage32; scale: double); overload;
procedure BoxDownSampling(Image, TargetImage: TImage32; scaleX, scaleY: double); overload;
procedure BoxDownSampling(Image, TargetImage: TImage32; newWidth, newHeight: Integer); overload;
procedure NearestNeighborResize(Image: TImage32; newWidth, newHeight: Integer); overload;
procedure NearestNeighborResize(Image, TargetImage: TImage32; newWidth, newHeight: Integer); overload;
procedure ResamplerResize(Image: TImage32; newWidth, newHeight: Integer); overload;
procedure ResamplerResize(Image, TargetImage: TImage32; newWidth, newHeight: Integer); overload;
// The following general purpose resamplers are registered below:
// function NearestResampler(img: TImage32; x, y: double): TColor32;
// function BilinearResample(img: TImage32; x, y: double): TColor32;
// function BicubicResample (img: TImage32; x, y: double): TColor32;
// function WeightedBilinear(img: TImage32; x, y: double): TColor32;
implementation
uses
Img32.Transform;
var
sinWeighted: array [0..255] of Cardinal;
//------------------------------------------------------------------------------
// NearestNeighbor resampler
//------------------------------------------------------------------------------
function NearestResampler(img: TImage32; x256, y256: Integer): TColor32;
function NearestResampler(img: TImage32; x, y: double): TColor32;
var
xi, yi: integer;
begin
if (x256 < -$7f) then
begin
Result := clNone32;
Exit;
end;
if (y256 < -$7f) then
begin
Result := clNone32;
Exit;
end;
if (x256 and $FF > $7F) then inc(x256, $100);
x256 := x256 shr 8;
if y256 and $FF > $7F then inc(y256, $100);
y256 := y256 shr 8;
if (x256 < 0) or (x256 >= img.Width) or
(y256 < 0) or (y256 >= img.Height) then
Result := clNone32 else
Result := img.Pixels[y256 * img.Width + x256];
xi := Round(x); yi := Round(y);
if (xi < 0) or (yi < 0) or (xi >= img.Width) or (yi >= img.Height) then
Result := clNone32 else
Result := img.Pixels[xi + yi * img.Width];
end;
//------------------------------------------------------------------------------
// BiLinear resampler
//------------------------------------------------------------------------------
function BilinearResample(img: TImage32; x256, y256: Integer): TColor32;
function BilinearResample(img: TImage32; x, y: double): TColor32;
var
xi,yi, weight: Integer;
iw, ih: integer;
xx, yy, xR, yB: integer;
weight: integer;
pixels: TArrayOfColor32;
color: TWeightedColor;
xf, yf: cardinal;
weightedColor: TWeightedColor;
xf, yf: double;
begin
iw := img.Width;
ih := img.Height;
pixels := img.Pixels;
if (x256 <= -$100) or (x256 >= iw *$100) or
(y256 <= -$100) or (y256 >= ih *$100) then
if (x < 0) then
begin
result := clNone32;
Exit;
if (x < -0.5) then
begin
xf := -x;
end else
begin
x := 0;
xf := 0;
end;
xx := 0;
xR := 0;
end else
begin
xf := 1-frac(x);
if x >= iw -1 then
begin
xx := iw -1;
xR := xx;
end else
begin
xx := Trunc(x);
xR := xx +1;
end;
end;
if x256 < 0 then xi := -1
else xi := x256 shr 8;
if (y < 0) then
begin
if (y < -0.5) then
begin
yf := -y;
end else
begin
y := 0;
yf := 0;
end;
yy := 0;
yB := 0;
end else
begin
yf := 1-frac(y);
if y >= ih -1 then
begin
yy := ih -1;
yB := yy;
end else
begin
yy := Trunc(y);
yB := yy +1;
end;
end;
if y256 < 0 then yi := -1
else yi := y256 shr 8;
weightedColor.Reset;
xf := x256 and $FF;
yf := y256 and $FF;
weight := Round(xf * yf * 255); //top-left
if weight > 0 then
begin
if (x < 0) or (y < 0) then
weightedColor.AddWeight(weight) else
weightedColor.Add(pixels[xx + yy * iw], weight);
end;
color.Reset;
weight := Round((1-xf) * yf * 255); //top-right
if weight > 0 then
begin
if (x > iw - 0.5) or (y < 0) then
weightedColor.AddWeight(weight) else
weightedColor.Add(pixels[xR + yy * iw], weight);
end;
weight := (($100 - xf) * ($100 - yf)) shr 8; //top-left
if (xi < 0) or (yi < 0) then
color.AddWeight(weight) else
color.Add(pixels[xi + yi * iw], weight);
weight := Round(xf * (1-yf) * 255); //bottom-left
if weight > 0 then
begin
if (x < 0) or (y > ih - 0.5) then
weightedColor.AddWeight(weight) else
weightedColor.Add(pixels[xx + yB * iw], weight);
end;
weight := (xf * ($100 - yf)) shr 8; //top-right
if ((xi+1) >= iw) or (yi < 0) then
color.AddWeight(weight) else
color.Add(pixels[(xi+1) + yi * iw], weight);
weight := Round((1-xf) * (1-yf) * 255); //bottom-right
if weight > 0 then
begin
if (x > iw - 0.5) or (y > ih - 0.5) then
weightedColor.AddWeight(weight) else
weightedColor.Add(pixels[xR + yB * iw], weight);
end;
Result := weightedColor.Color;
end;
//------------------------------------------------------------------------------
weight := (($100 - xf) * yf) shr 8; //bottom-left
if (xi < 0) or ((yi+1) >= ih) then
color.AddWeight(weight) else
color.Add(pixels[(xi) + (yi+1) * iw], weight);
// WeightedBilinearResample: A modified bilinear resampler that's
// less blurry but also a little more pixelated.
function WeightedBilinearResample(img: TImage32; x, y: double): TColor32;
var
iw, ih: integer;
xx, yy, xR, yB: integer;
weight: integer;
pixels: TArrayOfColor32;
weightedColor: TWeightedColor;
xf, yf: double;
begin
iw := img.Width;
ih := img.Height;
pixels := img.Pixels;
weight := (xf * yf) shr 8; //bottom-right
if (xi + 1 >= iw) or (yi + 1 >= ih) then
color.AddWeight(weight) else
color.Add(pixels[(xi+1) + (yi+1) * iw], weight);
if (x < 0) then
begin
if (x < -0.5) then
begin
xf := -x;
end else
begin
x := 0;
xf := 0;
end;
xx := 0;
xR := 0;
end else
begin
xf := 1-frac(x);
if x >= iw -1 then
begin
xx := iw -1;
xR := xx;
end else
begin
xx := Trunc(x);
xR := xx +1;
end;
end;
Result := color.Color;
if (y < 0) then
begin
if (y < -0.5) then
begin
yf := -y;
end else
begin
y := 0;
yf := 0;
end;
yy := 0;
yB := 0;
end else
begin
yf := 1-frac(y);
if y >= ih -1 then
begin
yy := ih -1;
yB := yy;
end else
begin
yy := Trunc(y);
yB := yy +1;
end;
end;
weightedColor.Reset;
weight := sinWeighted[Round(xf * yf * 255)]; //top-left
if weight > 0 then
begin
if (x < 0) or (y < 0) then
weightedColor.AddWeight(weight) else
weightedColor.Add(pixels[xx + yy * iw], weight);
end;
weight := sinWeighted[Round((1-xf) * yf * 255)]; //top-right
if weight > 0 then
begin
if (x > iw - 0.5) or (y < 0) then
weightedColor.AddWeight(weight) else
weightedColor.Add(pixels[xR + yy * iw], weight);
end;
weight := sinWeighted[Round(xf * (1-yf) * 255)]; //bottom-left
if weight > 0 then
begin
if (x < 0) or (y > ih - 0.5) then
weightedColor.AddWeight(weight) else
weightedColor.Add(pixels[xx + yB * iw], weight);
end;
weight := sinWeighted[Round((1-xf) * (1-yf) * 255)]; //bottom-right
if weight > 0 then
begin
if (x > iw - 0.5) or (y > ih - 0.5) then
weightedColor.AddWeight(weight) else
weightedColor.Add(pixels[xR + yB * iw], weight);
end;
Result := weightedColor.Color;
end;
//------------------------------------------------------------------------------
@ -127,7 +281,8 @@ end;
//------------------------------------------------------------------------------
type
TBiCubicEdgeAdjust = (eaNone, eaOne, eaTwo, eaThree, eaFour);
TBiCubicEdgeAdjust = (eaCenterFill,
eaPreStart, eaStart, eaPostStart, eaEnd, eaPostEnd);
var
byteFrac: array [0..255] of double;
@ -136,48 +291,49 @@ var
//------------------------------------------------------------------------------
function CubicHermite(aclr: PColor32; t: Byte; bce: TBiCubicEdgeAdjust): TColor32;
function CubicInterpolate(aclr: PColor32;
t: Byte; bce: TBiCubicEdgeAdjust): TColor32;
var
a,b,c,d: PARGB;
q: TARGB;
aa, bb, cc: integer;
aa, bb, m0, m1: double;
t1, t2, t3: double;
res: TARGB absolute Result;
const
clTrans: TColor32 = clNone32;
begin
case bce of
eaOne:
eaPreStart:
begin
a := @clTrans;
b := @clTrans;
c := PARGB(aclr);
Inc(aclr);
d := PARGB(aclr);
d := c;
end;
eaTwo:
eaStart:
begin
Result := aclr^;
Exit;
end;
eaPostStart:
begin
a := PARGB(aclr);
b := a;
Inc(aclr);
c := PARGB(aclr);
Inc(aclr);
d := PARGB(aclr);
end;
eaThree:
begin
a := PARGB(aclr);
Inc(aclr);
b := PARGB(aclr);
Inc(aclr);
c := PARGB(aclr);
d := c;
end;
eaFour:
eaEnd:
begin
a := PARGB(aclr);
Inc(aclr);
b := PARGB(aclr);
Result := aclr^;
Exit;
end;
eaPostEnd:
begin
Inc(aclr);
a := PARGB(aclr);
b := a;
c := @clTrans;
d := @clTrans;
end;
@ -198,14 +354,21 @@ begin
result := clNone32;
Exit;
end
else if (b = c) then
begin
result := b.Color;
Exit;
end
else if b.A = 0 then
begin
// ignore differences between b & c's color channels
q := c^;
q.A := 0;
b := @q;
end;
if c.A = 0 then
begin
// ignore differences between b & c's color channels
q := b^;
q.A := 0;
c := @q;
@ -215,78 +378,252 @@ begin
t2 := byteFracSq[t];
t3 := byteFracCubed[t];
aa := Integer(-a.A + 3*b.A - 3*c.A + d.A) div 2;
bb := Integer(2*a.A - 5*b.A + 4*c.A - d.A) div 2;
cc := Integer(-a.A + c.A) div 2;
Res.A := ClampByte(aa*t3 + bb*t2 + cc*t1 + b.A);
// find piecewise bicubic interpolation between pixel_b and pixel_c
// at point 't' (as byte div 255) ...
// given parametric equation aa(t^3) + bb(t^2) + cc(t)+ dd = 0
// where t(0) = pixel_b and t(1) = pixel_c
// let m1 = slope at pixel_b (using slope of pixel_c - pixel_a)
// let m2 = slope at pixel_c (using slope of pixel_d - pixel_b)
// then t(0) = aa(0^3) + bb(0^2) + cc(0) + dd = dd
// then t(1) = aa(1^3) + bb(1^2) + cc(1) + dd = aa + bb + cc + dd
// differentiating parametic equation at t'(0) and t'(1) ...
// t'(0) = m0 = 3*aa(0^2) + 2*bb(0) + cc = cc
// t'(1) = m1 = 3*aa(1^2) + 2*bb(1) + cc = 3*aa + 2*bb + cc
// t(0) = dd ::EQ1
// t(1) = aa+bb+cc+dd ::EQ2
// t'(0) = cc ::EQ3
// t'(1) = 3*aa + 2*bb + cc ::EQ4
// solving simultaneous equations
// aa = 2*t(0) -2*t(1) +t'(0) +t'(1)
// bb = 3*t(1) -3*t(0) -2*t'(0) -t'(1)
// cc = m0
// dd = t(0)
aa := Integer(-a.R + 3*b.R - 3*c.R + d.R) div 2;
bb := Integer(2*a.R - 5*b.R + 4*c.R - d.R) div 2;
cc := Integer(-a.R + c.R) div 2;
Res.R := ClampByte(aa*t3 + bb*t2 + cc*t1 + b.R);
m0 {aka t'(0)} := (c.A - a.A) /2;
m1 {aka t'(1)} := (d.A - b.A) /2;
aa := 2*b.A - 2*c.A + m0 + m1;
bb := 3*c.A -3*b.A -2*m0 - m1;
Res.A := ClampByte(aa*t3 + bb*t2 + m0*t1 + b.A);
aa := Integer(-a.G + 3*b.G - 3*c.G + d.G) div 2;
bb := Integer(2*a.G - 5*b.G + 4*c.G - d.G) div 2;
cc := Integer(-a.G + c.G) div 2;
Res.G := ClampByte(aa*t3 + bb*t2 + cc*t1 + b.G);
m0 := (c.R - a.R) /2;
m1 := (d.R - b.R) /2;
aa := 2*b.R - 2*c.R + m0 + m1;
bb := 3*c.R -3*b.R -2*m0 - m1;
Res.R := ClampByte(aa*t3 + bb*t2 + m0*t1 + b.R);
aa := Integer(-a.B + 3*b.B - 3*c.B + d.B) div 2;
bb := Integer(2*a.B - 5*b.B + 4*c.B - d.B) div 2;
cc := Integer(-a.B + c.B) div 2;
Res.B := ClampByte(aa*t3 + bb*t2 + cc*t1 + b.B);
m0 := (c.G - a.G) /2;
m1 := (d.G - b.G) /2;
aa := 2*b.G - 2*c.G + m0 + m1;
bb := 3*c.G -3*b.G -2*m0 - m1;
Res.G := ClampByte(aa*t3 + bb*t2 + m0*t1 + b.G);
m0 := (c.B - a.B) /2;
m1 := (d.B - b.B) /2;
aa := 2*b.B - 2*c.B + m0 + m1;
bb := 3*c.B -3*b.B -2*m0 - m1;
Res.B := ClampByte(aa*t3 + bb*t2 + m0*t1 + b.B);
end;
//------------------------------------------------------------------------------
function BicubicResample(img: TImage32; x256, y256: Integer): TColor32;
function BicubicResample(img: TImage32; x, y: double): TColor32;
var
i, dx,dy, pi, iw, w,h: Integer;
i, pi, iw, ih, last: Integer;
c: array[0..3] of TColor32;
x, y: Integer;
xFrac, yFrac: byte;
bceX, bceY: TBiCubicEdgeAdjust;
begin
Result := clNone32;
iw := img.Width;
w := iw -1;
h := img.Height -1;
ih := img.Height;
last := iw * ih -1;
x := Abs(x256) shr 8;
y := Abs(y256) shr 8;
if (x256 < -$FF) or (x > w) or (y256 < -$FF) or (y > h) then Exit;
if (x256 < 0) then bceX := eaOne
else if (x = 0) then bceX := eaTwo
else if (x256 > w shl 8) then bceX := eaFour
else if (x256 > (w -1) shl 8) then bceX := eaThree
else bceX := eaNone;
if (bceX = eaOne) or (bceX = eaTwo) then dx := 1
else dx := 0;
if (y256 < 0) then bceY := eaOne
else if y = 0 then bceY := eaTwo
else if y = h -1 then bceY := eaThree
else if y = h then bceY := eaFour
else bceY := eaNone;
if (bceY = eaOne) or (bceY = eaTwo) then dy := 1
else dy := 0;
pi := (y -1 +dy) * iw + (x -1 + dx);
if bceY = eaFour then dx := 2
else if bceY = eaThree then dx := 1
else dx := 0;
for i := dy to 3 -dx do
if x < 1 then
begin
c[i] := CubicHermite(@img.Pixels[pi], x256 and $FF, bceX);
inc(pi, iw);
if x < -0.5 then
begin
xFrac := Round((1+x) *255);
bceX := eaPreStart;
end
else if (x < 0) or
((iw = 1) and (x < 0.5)) then
begin
x := 0;
xFrac := 0;
bceX := eaStart;
end
else if (iw = 1) and (x > 0.5) then
begin
// the following is a workaround to avoid the increment in eaPostEnd
bceX := eaPreStart; // ie anti-aliase but without increment
xFrac := Round((1-x) *127); // reversed because 'end' not 'start'
end else
begin
xFrac := Round(frac(x) *255);
bceX := eaPostStart;
end;
end else
begin
xFrac := Round(frac(x) *255);
if x > iw - 1 then
begin
if x > iw - 0.5 then bceX := eaPostEnd
else bceX := eaEnd
end
else
bceX := eaCenterFill;
end;
Result := CubicHermite(@c[dy], y256 and $FF, bceY);
if y < 1 then
begin
if y < -0.5 then
begin
yFrac := Round((1+y) *255);
bceY := eaPreStart;
end
else if (y < 0) or
((ih = 1) and (y < 0.5)) then
begin
y := 0;
yFrac := 0;
bceY := eaStart;
end
else if (ih = 1) and (y > 0.5) then
begin
// the following is a workaround to avoid the increment in eaPostEnd
bceY := eaPreStart; // ie anti-aliase but without increment
yFrac := Round((1-y) *127); // reversed because 'end' not 'start'
end else
begin
yFrac := Round(frac(y) *255);
bceY := eaPostStart;
end;
end else
begin
yFrac := Round(frac(y) *255);
if y > ih - 1 then
begin
if y > ih - 0.5 then bceY := eaPostEnd
else bceY := eaEnd
end
else
bceY := eaCenterFill;
end;
x := Max(0, Min(iw -1, x -1));
y := Max(0, Min(ih -1, y -1));
pi := Trunc(y) * iw + Trunc(x);
for i := 0 to 3 do
begin
c[i] := CubicInterpolate(@img.Pixels[pi], xFrac, bceX);
inc(pi, iw);
if pi > last then break;
end;
Result := CubicInterpolate(@c[0], yFrac, bceY);
end;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
{$RANGECHECKS OFF} // negative index usage for Delphi 7-2007
procedure PremultiplyAlpha(pSrc, pDst: PARGB; count: nativeint);
var
a: byte;
tab: PByteArray;
c: TColor32;
s, d: PColor32Array;
begin
if count = 0 then exit;
// Use negative index trick
inc(pSrc, count);
inc(pDst, count);
count := -count;
// This function is optmized with the assumption that if a pixel has a certain
// alpha channel, then the propability that the following pixels have the same
// alpha channel, is very high.
c := PColor32Array(pSrc)[count];
a := c shr 24;
while True do
begin
case a of
0: // Special handling for 0 => color becomes black
begin
// Win32: Load stack variable into CPU register
s := PColor32Array(pSrc);
d := PColor32Array(pDst);
while True do
begin
d[count] := 0;
inc(count);
if count = 0 then exit;
c := s[count];
a := c shr 24;
if a <> 0 then break;
end;
end;
255: // Special handling for 255 => no color change
begin
// Win32: Load stack variable into CPU register
s := PColor32Array(pSrc);
d := PColor32Array(pDst);
if s = d then // if source=dest, we can skip writing to d
begin
while True do
begin
//d[count] := c; // skip the write
inc(count);
if count = 0 then exit;
c := s[count];
a := c shr 24;
if a <> 255 then break;
end;
end
else
begin
while True do
begin
d[count] := c;
inc(count);
if count = 0 then exit;
c := s[count];
a := c shr 24;
if a <> 255 then break;
end;
end;
end;
else
// Premultiply the alpha channel
// Win32: Load stack variable into CPU register
s := PColor32Array(pSrc);
// Win32: This line "breaks" Delphi's register allocator
//d := PColor32Array(pDst);
while True do
begin
tab := @MulTable[a];
c := (c and $FF000000) or
(tab[Byte(c shr 16)] shl 16) or
(tab[Byte(c shr 8)] shl 8) or
(tab[Byte(c )] );
//d[count] := c;
PColor32Array(pDst)[count] := c;
inc(count);
if count = 0 then exit;
c := s[count];
a := c shr 24;
if (a = 0) or (a = 255) then break;
end;
end;
end;
end;
{$IFDEF RANGECHECKS_ENABLED}
{$RANGECHECKS ON}
{$ENDIF RANGECHECKS_ENABLED}
//------------------------------------------------------------------------------
// BoxDownSampling and related functions
//------------------------------------------------------------------------------
@ -355,19 +692,53 @@ begin
end;
//------------------------------------------------------------------------------
procedure BoxDownSampling(Image: TImage32; scaleX, scaleY: double);
begin
BoxDownSampling(Image, Image, scaleX, scaleY);
end;
//------------------------------------------------------------------------------
procedure BoxDownSampling(Image: TImage32; scale: double);
begin
BoxDownSampling(Image, Image, scale);
end;
//------------------------------------------------------------------------------
procedure BoxDownSampling(Image: TImage32; newWidth, newHeight: Integer);
begin
BoxDownSampling(Image, Image, newWidth, newHeight);
end;
//------------------------------------------------------------------------------
procedure BoxDownSampling(Image, TargetImage: TImage32; scaleX, scaleY: double);
begin
BoxDownSampling(Image, TargetImage,
Max(1, Integer(Round(Image.Width * scaleX))),
Max(1, Integer(Round(Image.Height * scaleY))));
end;
//------------------------------------------------------------------------------
procedure BoxDownSampling(Image, TargetImage: TImage32; scale: double);
begin
BoxDownSampling(Image, TargetImage,
Max(1, Integer(Round(Image.Width * scale))),
Max(1, Integer(Round(Image.Height * scale))));
end;
//------------------------------------------------------------------------------
procedure BoxDownSampling(Image, TargetImage: TImage32; newWidth, newHeight: Integer);
var
x,y, x256,y256,xx256,yy256: Integer;
sx,sy: double;
tmp: TArrayOfColor32;
pc: PColor32;
scaledX: array of Integer;
scaledX: TArrayOfInteger;
begin
sx := Image.Width/newWidth * 256;
sy := Image.Height/newHeight * 256;
SetLength(tmp, newWidth * newHeight);
NewColor32Array(tmp, newWidth * newHeight, True);
SetLength(scaledX, newWidth +1); //+1 for fractional overrun
NewIntegerArray(scaledX, newWidth, True);
for x := 0 to newWidth -1 do
scaledX[x] := Round((x+1) * sx);
@ -388,11 +759,75 @@ begin
y256 := yy256;
end;
Image.BeginUpdate;
Image.SetSize(newWidth, newHeight);
Move(tmp[0], Image.Pixels[0], newWidth * newHeight * SizeOf(TColor32));
Image.EndUpdate;
TargetImage.AssignPixelArray(tmp, newWidth, newHeight);
end;
//------------------------------------------------------------------------------
procedure NearestNeighborResize(Image: TImage32; newWidth, newHeight: Integer);
begin
NearestNeighborResize(Image, Image, newWidth, newHeight);
end;
//------------------------------------------------------------------------------
procedure NearestNeighborResize(Image, TargetImage: TImage32; newWidth, newHeight: Integer);
var
x, y, offset: Integer;
scaledXi, scaledYiOffset: TArrayOfInteger;
tmp: TArrayOfColor32;
pc: PColor32;
pixels: TArrayOfColor32;
begin
//this NearestNeighbor code is slightly more efficient than
//the more general purpose one in Img32.Resamplers
if (newWidth = Image.Width) and (newHeight = Image.Height) then
begin
if TargetImage <> Image then TargetImage.Assign(Image);
Exit;
end;
NewColor32Array(tmp, newWidth * newHeight, True);
//get scaled X & Y values once only (storing them in lookup arrays) ...
NewIntegerArray(scaledXi, newWidth, True);
for x := 0 to newWidth -1 do
scaledXi[x] := (x * Image.Width) div newWidth;
NewIntegerArray(scaledYiOffset, newHeight, True);
SetLength(scaledYiOffset, newHeight);
for y := 0 to newHeight -1 do
//scaledYiOffset[y] := Round(y * Image.Height / newHeight) * Image.Width;
scaledYiOffset[y] := ((y * Image.Height) div newHeight) * Image.Width;
pc := @tmp[0];
pixels := Image.Pixels;
for y := 0 to newHeight - 1 do
begin
offset := scaledYiOffset[y];
for x := 0 to newWidth - 1 do
begin
pc^ := pixels[scaledXi[x] + offset];
inc(pc);
end;
end;
TargetImage.AssignPixelArray(tmp, newWidth, newHeight);
end;
//------------------------------------------------------------------------------
procedure ResamplerResize(Image: TImage32; newWidth, newHeight: Integer);
begin
ResamplerResize(Image, Image, newWidth, newHeight);
end;
//------------------------------------------------------------------------------
procedure ResamplerResize(Image, TargetImage: TImage32; newWidth, newHeight: Integer);
var
mat: TMatrixD;
begin
mat := IdentityMatrix;
MatrixScale(mat, newWidth/Image.Width, newHeight/Image.Height);
AffineTransformImage(Image, TargetImage, mat);
end;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
@ -403,12 +838,15 @@ const
inv255 : double = 1/255;
inv255sqrd : double = 1/(255*255);
inv255cubed: double = 1/(255*255*255);
piDiv256 : double = Pi / 256;
begin
for i := 0 to 255 do
begin
byteFrac[i] := i *inv255;
byteFracSq[i] := i*i *inv255sqrd;
byteFracCubed[i] := i*i*i *inv255cubed;
sinWeighted[i] := Round((Sin(i * piDiv256 - Pi/2) +1) /2 * 255);
end;
end;
//------------------------------------------------------------------------------
@ -419,6 +857,7 @@ initialization
rNearestResampler := RegisterResampler(NearestResampler, 'NearestNeighbor');
rBilinearResampler := RegisterResampler(BilinearResample, 'Bilinear');
rBicubicResampler := RegisterResampler(BicubicResample, 'HermiteBicubic');
rWeightedBilinear := RegisterResampler(WeightedBilinearResample, 'WeightedBilinear');
DefaultResampler := rBilinearResampler;
end.

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,7 @@ const
hClass = $E45C07DD; // Class
hClip_045_path = $B6C7D97A; // Clip-path
hClippath = $241B0E0D; // Clippath
hcollapse = $22A7B0EC; // collapse
hColor = $E953FD29; // Color
hCurrentColor = $5B8F31B0; // CurrentColor
hCx = $B5177A89; // Cx
@ -45,6 +46,7 @@ const
hfeFuncG = $E45FE81A; // feFuncG
hfeFuncR = $F8BB10C8; // feFuncR
hfeGaussianBlur = $B2225552; // feGaussianBlur
hfeImage = $905096A0; // feImage
hfeMerge = $A2C358C0; // feMerge
hfeMergeNode = $F5F1E90F; // feMergeNode
hfeOffset = $04493A72; // feOffset
@ -70,12 +72,15 @@ const
hGradientUnits = $07DD34B6; // GradientUnits
hGramma = $302368DC; // Gramma
hHeight = $52FDF336; // Height
hhidden = $4C4D777D; // hidden
hHref = $8E926F4B; // Href
hId = $1B60404D; // Id
hImage = $D58C8637; // Image
hIn = $4D5FA44B; // In
hIn2 = $FBFE02B1; // In2
hIntercept = $7CBB607F; // Intercept
hItalic = $F07E7786; // Italic
hJustify = $13E85AB8; // Justify
hK1 = $33176D43; // K1
hK2 = $DD11C139; // K2
hK3 = $CF4B25AC; // K3
@ -111,6 +116,7 @@ const
hOrient = $EFF6C65A; // Orient
hOut = $12067E90; // Out
hOver = $C9B82D21; // Over
hOverflow_045_Wrap = $C0B6980D; // Overflow-Wrap
hOverlay = $383BEA5E; // Overlay
hPad = $4A0CAD48; // Pad
hPath = $AD8A7AB5; // Path
@ -129,6 +135,7 @@ const
hRefY = $480CECDB; // RefY
hRepeat = $FF80069D; // Repeat
hResult = $47CD519F; // Result
hRotate = $E8A48E19; // Rotate
hRound = $323B0E24; // Round
hRx = $3ABF70F3; // Rx
hRy = $0C7D9470; // Ry
@ -139,10 +146,12 @@ const
hSlope = $4774735C; // Slope
hSourceAlpha = $F891B958; // SourceAlpha
hSourceGraphic = $A4DB1DC2; // SourceGraphic
hspace = $488AD9F6; // space
hspecularExponent = $93D520E8; // specularExponent
hSpreadMethod = $A08CEB57; // SpreadMethod
hSquare = $20E48144; // Square
hStart = $84DC271F; // Start
hStartOffset = $688E51A0; // StartOffset
hstdDeviation = $00D13F6A; // stdDeviation
hStop = $930CA7F2; // Stop
hStop_045_Color = $9FD6E0BE; // Stop-Color
@ -167,6 +176,7 @@ const
hText = $7F3B51AB; // Text
hText_045_Anchor = $D0D82FE8; // Text-Anchor
hText_045_Decoration = $3BC20862; // Text-Decoration
hTextArea = $0A75EDBF; // TextArea
hTextLength = $DA75EDC0; // TextLength
hTextPath = $18F2748E; // TextPath
hTimes = $FF0E1FBE; // Times
@ -179,7 +189,11 @@ const
hUserSpaceOnUse = $3D19F8A4; // UserSpaceOnUse
hValues = $33429E55; // Values
hViewbox = $AEF665C8; // Viewbox
hVisibility = $9F832B01; // Visibility
hvisible = $96C79D31; // visible
hWhite_045_Space = $0A1C0679; // White-Space
hWidth = $96BEECA0; // Width
hWord_045_Break = $A99E7C27; // Word-Break
hX = $9303A5E5; // X
hX1 = $74A7DE27; // X1
hX2 = $168E21F1; // X2

View file

@ -2,10 +2,10 @@ unit Img32.SVG.Path;
(*******************************************************************************
* Author : Angus Johnson *
* Version : 4.0 *
* Date : 28 December 2021 *
* Version : 4.7 *
* Date : 6 January 2025 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2019-2021 *
* Copyright : Angus Johnson 2019-2025 *
* *
* Purpose : Essential structures and functions to read SVG Path elements *
* *
@ -56,7 +56,10 @@ type
fCtrlPts : TPathD;
fExtend : integer;
protected
function GetFlattened: TPathD; virtual;
procedure Changed; {$IFDEF INLINE} inline; {$ENDIF}
procedure RequireFlattened; virtual;
function GetFlattened: TPathD; overload;
procedure GetFlattened2(var Result: TPathD); overload;
procedure GetFlattenedInternal; virtual; abstract;
procedure Scale(value: double); virtual;
function DescaleAndOffset(const pt: TPointD): TPointD; overload;
@ -88,7 +91,7 @@ type
TSvgCurvedSeg = class(TSvgPathSeg)
protected
pendingScale: double;
function GetFlattened: TPathD; override;
procedure RequireFlattened; override;
function GetPreviousCtrlPt: TPointD;
public
function GetLastCtrlPt: TPointD; virtual;
@ -198,10 +201,15 @@ type
fSegs : array of TSvgPathSeg;
fPendingScale : double;
fPathOffset : TPointD;
fSegsCount : integer;
function GetCount: integer;
function GetSeg(index: integer): TSvgPathSeg;
function AddSeg(segType: TSvgPathSegType;
const startPt: TPointD; const pts: TPathD): TSvgPathSeg;
protected
procedure GrowSegs;
procedure SegsLoaded;
procedure InitSegs(Capacity: Integer);
public
isClosed : Boolean;
constructor Create(parent: TSvgPath);
@ -256,7 +264,7 @@ type
procedure ScaleAndOffset(scale: double; dx, dy: integer);
function GetStringDef(relative: Boolean; decimalPrec: integer): string;
function AddPath: TSvgSubPath;
function AddPath(SegsCapacity: Integer = 0): TSvgSubPath;
procedure DeleteSubPath(subPath: TSvgSubPath);
property Bounds: TRectD read GetBounds;
property CtrlBounds: TRectD read GetControlBounds;
@ -268,15 +276,14 @@ type
UTF8Strings = array of UTF8String;
function GetSvgArcInfoRect(const p1, p2: TPointD; radii: TPointD; phi_rads: double;
fA, fS: boolean): TRectD;
function GetSvgArcInfoRect(const p1, p2: TPointD;
radii: TPointD; phi_rads: double; fA, fS: boolean): TRectD;
implementation
resourcestring
rsSvgPathRangeError = 'TSvgPath.GetPath range error';
rsSvgSubPathRangeError = 'TSvgSubPath.GetSeg range error';
//rsSvgSegmentRangeError = 'TSvgSegment.GetVal range error';
//------------------------------------------------------------------------------
// Miscellaneous functions ...
@ -338,36 +345,68 @@ end;
function GetSingleDigit(var c, endC: PUTF8Char;
out digit: integer): Boolean;
var
cc: PUTF8Char;
ch: UTF8Char;
begin
Result := SkipBlanksAndComma(c, endC) and (c^ >= '0') and (c^ <= '9');
cc := SkipBlanksAndComma(c, endC);
Result := cc < endC;
if not Result then
begin
c := cc;
Exit;
end;
ch := cc^;
Result := (ch >= '0') and (ch <= '9');
if not Result then Exit;
digit := Ord(c^) - Ord('0');
inc(c);
digit := Ord(ch) - Ord('0');
c := cc + 1;
end;
//------------------------------------------------------------------------------
const
SegTypeMap: array['A'..'Z'] of TSvgPathSegType = (
stArc, // A
stUnknown, // B
stCBezier, // C
stUnknown, // D
stUnknown, // E
stUnknown, // F
stUnknown, // G
stHorz, // H
stUnknown, // I
stUnknown, // J
stUnknown, // K
stLine, // L
stMove, // M
stUnknown, // N
stUnknown, // O
stUnknown, // P
stQBezier, // Q
stUnknown, // R
stCSpline, // S
stQSpline, // T
stUnknown, // U
stVert, // V
stUnknown, // W
stUnknown, // X
stUnknown, // Y
stClose // Z
);
function GetSegType(var c, endC: PUTF8Char; out isRelative: Boolean): TSvgPathSegType;
var
ch: UTF8Char;
begin
Result := stUnknown;
if not SkipBlanks(c, endC) then Exit;
ch := upcase(c^);
if not CharInSet(ch,
['A','C','H','M','L','Q','S','T','V','Z']) then Exit;
ch := c^;
case ch of
'M': Result := stMove;
'L': Result := stLine;
'H': Result := stHorz;
'V': Result := stVert;
'A': Result := stArc;
'Q': Result := stQBezier;
'C': Result := stCBezier;
'T': Result := stQSpline;
'S': Result := stCSpline;
'Z': Result := stClose;
'a'..'z': Result := SegTypeMap[UTF8Char(Byte(ch) and not $20)];
'A'..'Z': Result := SegTypeMap[ch];
end;
isRelative := c^ >= 'a';
if Result = stUnknown then Exit;
isRelative := ch >= 'a';
inc(c);
end;
//------------------------------------------------------------------------------
@ -411,35 +450,37 @@ begin
begin
fCtrlPts := ScalePath(fCtrlPts, value);
fFirstPt := ScalePoint(fFirstPt, value);
Changed;
end;
end;
//------------------------------------------------------------------------------
function TSvgPathSeg.DescaleAndOffset(const pt: TPointD): TPointD;
begin
Result := pt;
OffsetPoint(Result, -parent.PathOffset.X, -parent.PathOffset.Y);
Result := TranslatePoint(pt, -parent.PathOffset.X, -parent.PathOffset.Y);
Result := ScalePoint(Result, 1/Owner.Scale);
end;
//------------------------------------------------------------------------------
function TSvgPathSeg.DescaleAndOffset(const p: TPathD): TPathD;
begin
Result := OffsetPath(p, -parent.PathOffset.X, -parent.PathOffset.Y);
Result := TranslatePath(p, -parent.PathOffset.X, -parent.PathOffset.Y);
Result := ScalePath(Result, 1/Owner.Scale);
end;
//------------------------------------------------------------------------------
procedure TSvgPathSeg.Offset(dx, dy: double);
begin
fFirstPt := OffsetPoint(fFirstPt, dx, dy);
fCtrlPts := OffsetPath(fCtrlPts, dx, dy);
fFirstPt := TranslatePoint(fFirstPt, dx, dy);
fCtrlPts := TranslatePath(fCtrlPts, dx, dy);
Changed;
end;
//------------------------------------------------------------------------------
procedure TSvgPathSeg.SetCtrlPts(const pts: TPathD);
begin
fCtrlPts := pts;
Changed;
end;
//------------------------------------------------------------------------------
@ -449,7 +490,7 @@ var
begin
len := Length(pts);
Result := (len <> 0) and (fExtend <> 0) and (len mod fExtend = 0);
if Result then Img32.Vector.AppendPath(fCtrlPts, pts);
if Result then ConcatPaths(fCtrlPts, pts);
end;
//------------------------------------------------------------------------------
@ -459,9 +500,29 @@ begin
end;
//------------------------------------------------------------------------------
procedure TSvgPathSeg.Changed;
begin
if fFlatPath <> nil then
fFlatPath := nil; // DynArrayClear
end;
//------------------------------------------------------------------------------
procedure TSvgPathSeg.RequireFlattened;
begin
if fFlatPath = nil then
GetFlattenedInternal;
end;
//------------------------------------------------------------------------------
function TSvgPathSeg.GetFlattened: TPathD;
begin
GetFlattenedInternal;
RequireFlattened;
Result := fFlatPath;
end;
//------------------------------------------------------------------------------
procedure TSvgPathSeg.GetFlattened2(var Result: TPathD);
begin // uses less DynArrayAsg and DynArrayClear calls
RequireFlattened;
Result := fFlatPath;
end;
//------------------------------------------------------------------------------
@ -483,7 +544,7 @@ end;
procedure TSvgStraightSeg.GetFlattenedInternal;
begin
fFlatPath := PrePendPoint(fFirstPt, fCtrlPts);
PrePendPoint(fFirstPt, fCtrlPts, fFlatPath);
end;
//------------------------------------------------------------------------------
@ -498,15 +559,16 @@ begin
end;
//------------------------------------------------------------------------------
function TSvgCurvedSeg.GetFlattened: TPathD;
procedure TSvgCurvedSeg.RequireFlattened;
begin
//if the image has been rendered previously at a lower resolution, then
//redo the flattening otherwise curves my look very rough.
if (pendingScale < Parent.fPendingScale) then
begin
pendingScale := Parent.fPendingScale;
GetFlattenedInternal;
Result := fFlatPath;
Changed;
end;
inherited RequireFlattened;
end;
//------------------------------------------------------------------------------
@ -517,18 +579,27 @@ end;
//------------------------------------------------------------------------------
function TSvgCurvedSeg.GetPreviousCtrlPt: TPointD;
var
UseParentLastCtrlPt: Boolean;
begin
if (fIdx > 0) and (fSegType in [stQSpline, stCSpline]) then
UseParentLastCtrlPt := False;
if fIdx > 0 then
begin
if (fSegType = stQSpline) and
(fParent[fIdx -1].fSegType in [stQBezier, stQSpline]) then
Result := TSvgCurvedSeg(fParent[fIdx -1]).GetLastCtrlPt
else if (fSegType = stCSpline) and
(fParent[fIdx -1].fSegType in [stCBezier, stCSpline]) then
Result := TSvgCurvedSeg(fParent[fIdx -1]).GetLastCtrlPt
else
Result := fFirstPt;
end else
case fSegType of
stQSpline:
case fParent[fIdx -1].fSegType of
stQBezier, stQSpline: UseParentLastCtrlPt := True;
end;
stCSpline:
case fParent[fIdx -1].fSegType of
stCBezier, stCSpline: UseParentLastCtrlPt := True;
end;
end;
end;
if UseParentLastCtrlPt then
Result := TSvgCurvedSeg(fParent[fIdx -1]).GetLastCtrlPt
else
Result := fFirstPt;
end;
@ -562,12 +633,13 @@ begin
begin
dx := ai.startPos.X - startPos.X;
dy := ai.startPos.Y - startPos.Y;
OffsetRect(rec, dx, dy);
TranslateRect(rec, dx, dy);
startPos := ai.startPos;
endPos := OffsetPoint(endPos, dx, dy);
endPos := TranslatePoint(endPos, dx, dy);
end;
end;
SetCtrlPtsFromArcInfo;
Changed;
end;
//------------------------------------------------------------------------------
@ -611,13 +683,14 @@ end;
procedure TSvgASegment.SetCtrlPtsFromArcInfo;
begin
SetLength(fCtrlPts, 5);
NewPointDArray(fCtrlPts, 5, True);
with fArcInfo do
begin
fCtrlPts[0] := startPos;
GetRectBtnPoints(fCtrlPts[1], fCtrlPts[2], fCtrlPts[3]);
fCtrlPts[4] := endPos;
end;
Changed;
end;
//------------------------------------------------------------------------------
@ -639,7 +712,7 @@ begin
p := Arc(rec, a1, a2, pendingScale);
if rectAngle <> 0 then
p := RotatePath(p, rec.MidPoint, rectAngle);
AppendPath(fFlatPath, p);
ConcatPaths(fFlatPath, p);
end;
end;
//------------------------------------------------------------------------------
@ -661,17 +734,18 @@ end;
procedure TSvgASegment.ReverseArc;
begin
fArcInfo.sweepClockW := not fArcInfo.sweepClockW;
Changed;
end;
//------------------------------------------------------------------------------
procedure TSvgASegment.Offset(dx, dy: double);
begin
inherited;
inherited; // calls Changed
with fArcInfo do
begin
OffsetRect(rec, dx, dy);
startPos := OffsetPoint(startPos, dx, dy);
endPos := OffsetPoint(endPos, dx, dy);
TranslateRect(rec, dx, dy);
startPos := TranslatePoint(startPos, dx, dy);
endPos := TranslatePoint(endPos, dx, dy);
end;
end;
//------------------------------------------------------------------------------
@ -679,7 +753,7 @@ end;
procedure TSvgASegment.Scale(value: Double);
begin
if (value = 0) or (value = 1) then Exit;
inherited;
inherited; // calls Changed
with fArcInfo do
begin
rec := ScaleRect(rec, value);
@ -691,7 +765,7 @@ end;
procedure TSvgASegment.SetCtrlPts(const ctrlPts: TPathD);
begin
//SetCtrlPtsFromArcInfo;
//SetCtrlPtsFromArcInfo; // calls Changed
end;
//------------------------------------------------------------------------------
@ -754,7 +828,7 @@ var
i, len: integer;
begin
len := Length(fCtrlPts) div 3;
SetLength(Result, len);
NewPointDArray(Result, len, True);
for i := 0 to High(Result) do
Result[i] := fCtrlPts[i*3 +2];
end;
@ -873,7 +947,7 @@ var
i, len: integer;
begin
len := Length(fCtrlPts) div 2;
SetLength(Result, len);
NewPointDArray(Result, len, True);
for i := 0 to High(Result) do
Result[i] := fCtrlPts[i*2+1];
end;
@ -938,7 +1012,7 @@ var
i, len: integer;
begin
len := Length(fCtrlPts) div 2;
SetLength(Result, len);
NewPointDArray(Result, len, True);
for i := 0 to High(Result) do
Result[i] := fCtrlPts[i*2+1];
end;
@ -1074,13 +1148,17 @@ end;
function TSvgSubPath.GetFlattenedPath(pendingScale: double): TPathD;
var
i: integer;
flattenedPaths: TPathsD;
begin
if pendingScale <= 0 then pendingScale := 1.0;
if (pendingScale > fPendingScale) then
fPendingScale := pendingScale;
Result := nil;
for i := 0 to High(fSegs) do
AppendPath(Result, fSegs[i].GetFlattened);
SetLength(flattenedPaths, fSegsCount);
for i := 0 to fSegsCount - 1 do
fSegs[i].GetFlattened2(flattenedPaths[i]);
ConcatPaths(Result, flattenedPaths);
end;
//------------------------------------------------------------------------------
@ -1089,8 +1167,11 @@ function TSvgSubPath.AddSeg(segType: TSvgPathSegType;
var
i: integer;
begin
i := Length(fSegs);
SetLength(fSegs, i+1);
i := fSegsCount;
if i = Length(fSegs) then
GrowSegs;
inc(fSegsCount);
case segType of
stCBezier : Result := TSvgCSegment.Create(self, i, startPt);
stHorz : Result := TSvgHSegment.Create(self, i, startPt);
@ -1103,6 +1184,7 @@ begin
end;
fSegs[i] := Result;
Result.fCtrlPts := pts;
Result.fFlatPath := nil;
if Result is TSvgCurvedSeg then
TSvgCurvedSeg(Result).pendingScale := fPendingScale;
end;
@ -1113,8 +1195,11 @@ function TSvgSubPath.AddASeg(const startPt, endPt: TPointD; const rect: TRectD;
var
i: integer;
begin
i := Length(fSegs);
SetLength(fSegs, i+1);
i := fSegsCount;
if i = Length(fSegs) then
GrowSegs;
inc(fSegsCount);
Result := TSvgASegment.Create(self, i, startPt);
fSegs[i] := Result;
Result.pendingScale := self.fPendingScale;
@ -1126,7 +1211,7 @@ begin
rectAngle := angle;
sweepClockW := isClockwise;
end;
Result.SetCtrlPtsFromArcInfo;
Result.SetCtrlPtsFromArcInfo; // calls Changed
end;
//------------------------------------------------------------------------------
@ -1176,11 +1261,14 @@ function TSvgSubPath.AddZSeg(const endPt, firstPt: TPointD): TSvgZSegment;
var
i: integer;
begin
i := Length(fSegs);
SetLength(fSegs, i+1);
i := fSegsCount;
if i = Length(fSegs) then
GrowSegs;
inc(fSegsCount);
Result := TSvgZSegment.Create(self, i, endPt);
fSegs[i] := Result;
SetLength(Result.fCtrlPts, 1);
NewPointDArray(Result.fCtrlPts, 1, True);
Result.fCtrlPts[0] := firstPt;
isClosed := true;
end;
@ -1206,6 +1294,7 @@ begin
if not Result then Exit;
seg[cnt -1].Free;
SetLength(fSegs, cnt -1);
fSegsCount := cnt - 1;
if isClosed then isClosed := false;
end;
//------------------------------------------------------------------------------
@ -1213,10 +1302,22 @@ end;
function TSvgSubPath.GetSimplePath: TPathD;
var
i: integer;
paths: TPathsD;
begin
Result := Img32.Vector.MakePath([GetFirstPt.X, GetFirstPt.Y]);
for i := 0 to High(fSegs) do
AppendPath(Result, fSegs[i].GetOnPathCtrlPts);
if fSegsCount <= 1 then
begin
Result := Img32.Vector.MakePath(GetFirstPt);
for i := 0 to fSegsCount - 1 do
ConcatPaths(Result, fSegs[i].GetOnPathCtrlPts);
end
else
begin
SetLength(paths, 1 + fSegsCount);
paths[0] := Img32.Vector.MakePath(GetFirstPt);
for i := 0 to fSegsCount - 1 do
paths[1 + i] := fSegs[i].GetOnPathCtrlPts;
ConcatPaths(Result, paths);
end;
end;
//------------------------------------------------------------------------------
@ -1225,7 +1326,7 @@ var
pt: TPointD;
begin
Result := '';
if Length(fSegs) = 0 then Exit;
if fSegsCount = 0 then Exit;
if decimalPrec < -3 then decimalPrec := -3
else if decimalPrec > 4 then decimalPrec := 4;
@ -1273,13 +1374,35 @@ begin
for i := 0 to Count -1 do
fSegs[i].Free;
fSegs := nil;
fSegsCount := 0;
fPathOffset := NullPointD;
end;
//------------------------------------------------------------------------------
procedure TSvgSubPath.GrowSegs;
begin
SetLength(fSegs, (fSegsCount * 2) + 1);
end;
//------------------------------------------------------------------------------
procedure TSvgSubPath.SegsLoaded;
begin
// Trim the array to the actual used size
if Length(fSegs) <> fSegsCount then
SetLength(fSegs, fSegsCount);
end;
//------------------------------------------------------------------------------
procedure TSvgSubPath.InitSegs(Capacity: Integer);
begin
if Capacity > fSegsCount then
SetLength(fSegs, Capacity);
end;
//------------------------------------------------------------------------------
function TSvgSubPath.GetCount: integer;
begin
Result := Length(fSegs);
Result := fSegsCount;
end;
//------------------------------------------------------------------------------
@ -1287,8 +1410,7 @@ procedure TSvgSubPath.Offset(dx, dy: double);
var
i: integer;
begin
//fPathOffset := OffsetPoint(pathOffset, dx,dy); //DON'T DO THIS!
for i := 0 to High(fSegs) do fSegs[i].Offset(dx, dy);
for i := 0 to fSegsCount - 1 do fSegs[i].Offset(dx, dy);
end;
//------------------------------------------------------------------------------
@ -1323,7 +1445,7 @@ var
begin
p := nil;
for i := 0 to Count -1 do
AppendPath(p, fSegs[i].fFlatPath);
ConcatPaths(p, fSegs[i].fFlatPath);
Result := Img32.Vector.GetBoundsD(p);
end;
@ -1351,7 +1473,7 @@ begin
with fSubPaths[i] do
begin
if scale <> 1 then
for j := 0 to High(fSegs) do
for j := 0 to fSegsCount - 1 do
fSegs[j].Scale(scale);
Offset(dx,dy);
end;
@ -1392,15 +1514,78 @@ var
if ptCnt = ptCap then
begin
inc(ptCap, 8);
setLength(pts, ptCap);
SetLengthUninit(pts, ptCap);
end;
pts[ptCnt] := pt;
inc(ptCnt);
end;
procedure AllocEstimatedPtsCount(c, endC: PUTF8Char);
begin
// Count the numbers before the next segment type char
ptCap := 0;
while c < endC do
begin
// skip whitespaces
while (c < endC) and (c^ <= space) do
inc(c);
if c >= endC then
break;
case c^ of
'0'..'9', '-', '.', 'E', 'e':
begin
while (c < endC) and (c^ > space) do
inc(c);
Inc(ptCap);
end;
else
Break;
end;
end;
ptCap := ptCap div 2; // two numbers are one point
SetLength(pts, ptCap);
end;
function EstimateSegs(c, endC: PUTF8Char): Integer;
var
ch: UTF8Char;
begin
Result := 0;
while True do
begin
if c >= endC then
Break;
ch := c^;
inc(c);
case ch of
'A'..'Z', 'a'..'z':
begin
case ch of
'M', 'm': // move / close
Break;
'Z', 'z':
begin
Inc(Result);
Break;
end;
'E', 'e': ; // Exponent of a number
else
Inc(Result);
end;
end;
end;
end;
end;
var
ExpectedSegCount: Integer;
begin
Clear;
currSubPath := nil;
ExpectedSegCount := 1;
c := PUTF8Char(value);
endC := c + Length(value);
@ -1414,8 +1599,12 @@ begin
if currSegType = stMove then
begin
if currSubPath <> nil then
currSubPath.SegsLoaded; // Trim the segs array to the actual count
currSubPath := nil;
ExpectedSegCount := EstimateSegs(c, endc);
if isRelative then
lastPt := currPt else
lastPt := InvalidPointD;
@ -1426,21 +1615,31 @@ begin
if IsNumPending(c, endC, true) then
currSegType := stLine else
Continue;
Inc(ExpectedSegCount);
end
else if (currSegType = stClose) then
begin
if currPt.X = InvalidD then Continue;
if Assigned(currSubPath) and (currSubPath.Count > 0) then
begin
lastPt := currPt;
currPt := currSubPath.GetFirstPt;
currSubPath.AddZSeg(lastPt, currPt);
end else
begin
if not Assigned(currSubPath) then
currSubPath := AddPath(1);
currSubPath.AddZSeg(currPt, currPt);
end;
currSubPath.SegsLoaded; // Trim the segs array to the actual count
currSubPath := nil;
ExpectedSegCount := 1;
Continue;
end;
if not Assigned(currSubPath) then
currSubPath := AddPath;
currSubPath := AddPath(ExpectedSegCount);
pts := nil;
ptCnt := 0; ptCap := 0;
@ -1475,6 +1674,7 @@ begin
end;
stCBezier:
begin
AllocEstimatedPtsCount(c, endC);
while IsNumPending(c, endC, true) and
Parse2Num(c, endC, pt2, lastPt) and
Parse2Num(c, endC, pt3, lastPt) and
@ -1485,22 +1685,26 @@ begin
AddPt(currPt);
if isRelative then lastPt := currPt;
end;
SetLength(pts, ptCnt);
if Length(pts) <> ptCnt then
SetLength(pts, ptCnt);
currSubPath.AddSeg(stCBezier, firstPt, pts);
end;
stHorz:
begin
AllocEstimatedPtsCount(c, endC);
while IsNumPending(c, endC, true) and
Parse1Num(c, endC, currPt.X, lastPt.X) do
begin
AddPt(currPt);
if isRelative then lastPt.X := currPt.X;
end;
SetLength(pts, ptCnt);
if Length(pts) <> ptCnt then
SetLength(pts, ptCnt);
currSubPath.AddHSeg(firstPt, pts);
end;
stQBezier, stCSpline:
begin
AllocEstimatedPtsCount(c, endC);
while IsNumPending(c, endC, true) and
Parse2Num(c, endC, pt2, lastPt) and
Parse2Num(c, endC, currPt, lastPt) do
@ -1509,33 +1713,40 @@ begin
AddPt(currPt);
if isRelative then lastPt := currPt;
end;
SetLength(pts, ptCnt);
if Length(pts) <> ptCnt then
SetLength(pts, ptCnt);
currSubPath.AddSeg(currSegType, firstPt, pts);
end;
stLine, stQSpline:
begin
AllocEstimatedPtsCount(c, endC);
while IsNumPending(c, endC, true) and
Parse2Num(c, endC, currPt, lastPt) do
begin
AddPt(currPt);
if isRelative then lastPt := currPt;
end;
SetLength(pts, ptCnt);
if Length(pts) <> ptCnt then
SetLength(pts, ptCnt);
currSubPath.AddSeg(currSegType, firstPt, pts);
end;
stVert:
begin
AllocEstimatedPtsCount(c, endC);
while IsNumPending(c, endC, true) and
Parse1Num(c, endC, currPt.Y, lastPt.Y) do
begin
AddPt(currPt);
if isRelative then lastPt.Y := currPt.Y;
end;
SetLength(pts, ptCnt);
if Length(pts) <> ptCnt then
SetLength(pts, ptCnt);
currSubPath.AddVSeg(firstPt, pts);
end;
end;
end;
if currSubPath <> nil then
currSubPath.SegsLoaded; // Trim the segs array to the actual count
end;
//------------------------------------------------------------------------------
@ -1571,7 +1782,7 @@ var
begin
p := nil;
for i := 0 to Count -1 do
AppendPath(p, fSubPaths[i].GetFlattenedPath);
ConcatPaths(p, fSubPaths[i].GetFlattenedPath);
Result := Img32.Vector.GetBoundsD(p);
end;
//------------------------------------------------------------------------------
@ -1585,25 +1796,36 @@ begin
for i := 0 to Count -1 do
with fSubPaths[i] do
begin
AppendPath(p, GetFirstPt);
for j := 0 to High(fSegs) do
AppendPath(p, fSegs[j].fCtrlPts);
AppendPoint(p, GetFirstPt);
for j := 0 to fSegsCount - 1 do
ConcatPaths(p, fSegs[j].fCtrlPts);
end;
Result := GetBoundsD(p);
//watch out for straight horizontal or vertical lines
if not IsEmptyRect(Result) then Exit;
p := Grow(p, nil, 1, jsSquare, 0);
Result := GetBoundsD(p);
if IsEmptyRect(Result) then
begin
if Result.Width = 0 then
begin
Result.Left := Result.Left - 0.5;
Result.Right := Result.Left + 1.0;
end
else if Result.Height = 0 then
begin
Result.Top := Result.Top - 0.5;
Result.Bottom := Result.Top + 1.0;
end;
end;
end;
//------------------------------------------------------------------------------
function TSvgPath.AddPath: TSvgSubPath;
function TSvgPath.AddPath(SegsCapacity: Integer): TSvgSubPath;
var
i: integer;
begin
i := Count;
Result := TSvgSubPath.Create(self);
Result.InitSegs(SegsCapacity);
SetLength(fSubPaths, i + 1);
fSubPaths[i] := Result;
end;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,22 +1,55 @@
//NO_STORAGE is experimental
//Allows file system storage of layered objects etc
//Must be disabled to compile the experimental 'CtrlDemo' in Examples
// While "storage" is still technically experimental,
// it does allow file system storage of layered objects etc
// Comment out the following preprocessor define if you do wish to
// use storage (eg to compile the experimental 'CtrlDemo' in Examples).
{$DEFINE NO_STORAGE}
//USING_VCL_LCL - using either Delphi or Lazarus Component Libraries
//Adds a few extra library features (eg copying to and from TBitmap objects)
//Enabled is recommended unless you're compiling console applications.
{$DEFINE USING_VCL_LCL}
// default rotation direction is clockwise with positive angles
{.$DEFINE CLOCKWISE_ROTATION_WITH_NEGATIVE_ANGLES}
// Image downsampling occurs when images are reduced in size, and the default downsampling
// function is 'BoxDownSampling'. When downsampling, this function generally produces much
// clearer images than general purpose resamplers (which are much better at upsampling,
// and doing other affine transformations). However, if for some reason you do wish to use
// a general purpose resampler while downsampling, then comment out (ie disable) this define.
{$DEFINE USE_DOWNSAMPLER_AUTOMATICALLY}
// The SimplifyPath and SimplifyPaths functions have changed. Specifically the last
// parameter has changed from IsOpenPath to IsClosedPath, though the default has also
// changed from false to true which should minimise any inconvenience. This change was
// made to remove an inconsistency with other functions that all contain an IsClosedPath
// parameter. However, if this change is going to create havoc for some reason, then
// the following (somewhat temporary) define can be enabled.
{.$DEFINE USE_OLD_SIMPLIFYPATHS}
//USING_VCL_LCL - using either Delphi Visual Component Library or Lazarus Component Library
//is required if using the TImage32Panel component
//and adds a few extra library features (eg copying to and from TBitmap objects)
{$IF DEFINED(FPC)}
{$MACRO ON}
{$DEFINE USING_LCL}
{.$DEFINE USING_VCL_LCL}
{$DEFINE COMPILERVERSION:= 17}
{$ELSEIF declared(FireMonkeyVersion) OR DEFINED(FRAMEWORK_FMX)}
{$DEFINE USING_FMX}
{$ELSE}
{$DEFINE USING_VCL}
{$DEFINE USING_VCL_LCL}
{$IFEND}
{$IFDEF FPC}
{$MODE DELPHI}
{$DEFINE ABSTRACT_CLASSES}
{$DEFINE RECORD_METHODS}
{$DEFINE PBYTE}
{$DEFINE UITYPES}
{$DEFINE NEWPOSFUNC}
{$DEFINE SUPPORTS_POINTERMATH}
{$DEFINE CLASS_STATIC}
{.$DEFINE UITYPES}
{$DEFINE NESTED_TYPES}
{$IFNDEF DEBUG}
{$DEFINE INLINE}
{$DEFINE INLINE_COMPATIBLE}
{$ENDIF}
{$DEFINE DELPHI_PNG}
{$IFDEF WINDOWS}
@ -25,10 +58,10 @@
{$ELSE}
{$IF COMPILERVERSION < 15}
Your version of Delphi is not supported (Image32 requires Delphi version 7 or above)
{$IFEND}
{$IFDEF CPUX86}
{$DEFINE ASM_X86} //caution: do not define in FPC
{$ENDIF}
{$IFEND}
{$IF COMPILERVERSION < 23}
{$DEFINE CPUX86} // CPUX86 was added in Delphi XE2 (added Win64 compiler)
{$IFEND}
{$IF COMPILERVERSION >= 17} //Delphi 2005
{$IFNDEF DEBUG}
{$DEFINE INLINE} //added inlining
@ -49,20 +82,23 @@
{$DEFINE CHARINSET} //added CharInSet function
{$DEFINE EXIT_PARAM} //added Exit(value)
{$DEFINE ALPHAFORMAT} //added TBitmap.AlphaFormat property
{$DEFINE SUPPORTS_POINTERMATH} //added {$POINTERMATH ON/OFF}
{$DEFINE CLASS_STATIC} //added class static methods
{$IF COMPILERVERSION >= 21} //Delphi 2010
{$IFNDEF DEBUG}
{$DEFINE INLINE_COMPATIBLE} //avoid compiler bug with INLINE in Delphi 2005-2009 ("incompatible type")
{$ENDIF}
{$DEFINE GESTURES} //added screen gesture support
{$IF COMPILERVERSION >= 23} //DelphiXE2
{$IF declared(FireMonkeyVersion)} //defined in FMX.Types
{$DEFINE FMX}
{$IFEND}
{$DEFINE USES_NAMESPACES}
{$DEFINE FORMATSETTINGS}
{$DEFINE TROUNDINGMODE}
{$DEFINE UITYPES} //added UITypes unit
{$DEFINE XPLAT_GENERICS} //reasonable cross-platform & generics support
{$DEFINE XPLAT_GENERICS} //cross-platform generics support
{$DEFINE STYLESERVICES} //added StyleServices unit
{$IF COMPILERVERSION >= 24} //DelphiXE3
{$LEGACYIFEND ON}
{$DEFINE NEWPOSFUNC}
{$DEFINE ZEROBASEDSTR}
{$IF COMPILERVERSION >= 25} //DelphiXE4
{$LEGACYIFEND ON} //avoids compiler warning
@ -75,3 +111,11 @@
{$IFEND}
{$IFEND}
{$ENDIF}
{$IFOPT Q+}
{$DEFINE OVERFLOWCHECKS_ENABLED}
{$ENDIF}
{$IFOPT R+}
{$DEFINE RANGECHECKS_ENABLED}
{$ENDIF}

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,7 @@
-------------------------------------------------------------------------
Custom edit control with the look and feel like TLabel
Copyright (C) 2017-2018 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2017-2024 Alexander Koblov (alexx2000@mail.ru)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -58,6 +58,9 @@ type
procedure SelectAll;
procedure CopyToClipboard;
published
property Color default clDefault;
property Cursor default crIBeam;
property ReadOnly default True;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
@ -104,12 +107,7 @@ end;
procedure TKASCDDrawer.DrawEditBackground(ADest: TCanvas; ADestPos: TPoint;
ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx);
begin
// The background
ADest.Pen.Style := psSolid;
ADest.Pen.Color := AStateEx.RGBColor;
ADest.Brush.Style := bsSolid;
ADest.Brush.Color := AStateEx.RGBColor;
ADest.Rectangle(0, 0, ASize.cx, ASize.cy);
// None
end;
procedure TKASCDDrawer.DrawEdit(ADest: TCanvas; ASize: TSize;
@ -122,10 +120,8 @@ var
lTextLeftSpacing, lTextTopSpacing, lTextBottomSpacing: Integer;
lTextColor: TColor;
i, lVisibleLinesCount: Integer;
AClipRect: TRect;
begin
// Background
DrawEditBackground(ADest, Point(0, 0), ASize, AState, AStateEx);
// General text configurations which apply to all lines
// Configure the text color
if csfEnabled in AState then
@ -168,10 +164,10 @@ begin
// The text
ADest.Pen.Style := psClear;
ADest.Brush.Style := bsClear;
lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lControlTextLen);
// ToDo: Implement multi-line selection
if (AStateEx.SelLength = 0) or (AStateEx.SelStart.Y <> AStateEx.VisibleTextStart.Y+i) then
begin
lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lControlTextLen);
ADest.TextOut(lTextLeftSpacing, lLineTop, lVisibleText);
end
// Text and Selection
@ -186,22 +182,18 @@ begin
lSelLength := AStateEx.SelLength;
if lSelLength < 0 then lSelLength := lSelLength * -1;
// Text right of the selection
// Draw a normal text
ADest.Font.Color := lTextColor;
ADest.Brush.Color := AStateEx.RGBColor;
lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lControlTextLen);
ADest.TextOut(lTextLeftSpacing, lLineTop, lVisibleText);
// The selection text
// Draw a selected text
ADest.Brush.Color := clHighlight;
ADest.Font.Color := clHighlightText;
lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lSelLeftPos + lSelLength);
ADest.TextOut(lTextLeftSpacing, lLineTop, lVisibleText);
// Text left of the selection
ADest.Font.Color := lTextColor;
ADest.Brush.Color := AStateEx.RGBColor;
lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lSelLeftPos-AStateEx.VisibleTextStart.X + 1);
// Calculate a clip rect
AClipRect := ADest.ClipRect;
AClipRect.Left := ADest.TextWidth(UTF8Copy(lVisibleText, 1, lSelLeftPos));
AClipRect.Right := ADest.TextWidth(UTF8Copy(lVisibleText, 1, lSelLeftPos + lSelLength));
IntersectClipRect(ADest.Handle, AClipRect.Left, AClipRect.Top, AClipRect.Right, AClipRect.Bottom);
ADest.TextOut(lTextLeftSpacing, lLineTop, lVisibleText);
end;
end;
@ -382,6 +374,10 @@ begin
end;
end;
end;
if ReadOnly and (Key in [VK_BACK, VK_DELETE]) then
begin
Key:= 0;
end;
inherited KeyDown(Key, Shift);
end;
@ -389,10 +385,11 @@ constructor TKASCDEdit.Create(AOwner: TComponent);
begin
CreatePopupMenu;
inherited Create(AOwner);
Color:= clForm;
ReadOnly:= True;
Cursor:= crIBeam;
Color:= clDefault;
DrawStyle:= dsExtra1;
ControlStyle:= ControlStyle + [csParentBackground] - [csOpaque];
end;
procedure TKASCDEdit.MouseMove(Shift: TShiftState; X, Y: integer);

View file

@ -180,6 +180,35 @@ begin
end;
end;
function CalculateHeight(ComboBox: TCustomComboBox): Integer;
var
DC: HDC;
R: TRect;
Flags: Cardinal;
OldFont: HGDIOBJ;
LabelText: String;
MaxHeight: Integer;
begin
with ComboBox do
begin
MaxHeight:= Constraints.MinMaxHeight(10000);
DC := GetDC(Parent.Handle);
try
LabelText:= Items.Text;
R := Rect(0, 0, 10000, MaxHeight);
OldFont := SelectObject(DC, HGDIOBJ(Font.Reference.Handle));
Flags := DT_CALCRECT or DT_EXPANDTABS or DT_SINGLELINE;
DrawText(DC, PChar(LabelText), Length(LabelText), R, Flags);
SelectObject(DC, OldFont);
Result := (R.Bottom - R.Top);
finally
ReleaseDC(Parent.Handle, DC);
end;
end;
end;
{ TComboBoxWithDelItems }
procedure TComboBoxWithDelItems.KeyDown(var Key: Word; Shift: TShiftState);
@ -257,6 +286,7 @@ begin
if (csSubComponent in ComponentStyle) then
begin
ItemHeight:= CalculateHeight(Self);
if (Parent.Anchors * [akLeft, akRight] = [akLeft, akRight]) then
Exit;
end;
@ -270,7 +300,8 @@ procedure TKASColorBox.DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy;
begin
if AMode in [lapAutoAdjustWithoutHorizontalScrolling, lapAutoAdjustForDPI] then
begin
ColorRectWidth:= Round(ColorRectWidth * AXProportion);
if ColorRectWidthStored then
ColorRectWidth:= Round(ColorRectWidth * AXProportion);
end;
// Don't auto adjust horizontal layout
inherited DoAutoAdjustLayout(AMode, 1.0, AYProportion);

View file

@ -0,0 +1,312 @@
unit KASComCtrls;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Controls, ComCtrls, Graphics, Dialogs;
type
{ TToolButtonClr }
TToolButtonClr = class(TToolButton)
private
FButtonColor: TColor;
FColorDialog: TColorDialog;
procedure SetButtonColor(AValue: TColor);
protected
procedure Paint; override;
procedure ShowColorDialog;
public
constructor Create(TheOwner: TComponent); override;
procedure Click; override;
property ButtonColor: TColor read FButtonColor write SetButtonColor;
end;
{ TToolBarAdv }
TToolBarAdv = class(TToolBar)
private
FToolBarFlags: TToolBarFlags;
protected
procedure CalculatePreferredSize(var PreferredWidth,
PreferredHeight: Integer;
{%H-}WithThemeSpace: Boolean); override;
procedure AlignControls({%H-}AControl: TControl;
var RemainingClientRect: TRect); override;
function WrapButtons(UseSize: Integer; out NewWidth,
NewHeight: Integer; Simulate: Boolean): Boolean;
end;
procedure Register;
implementation
uses
Math;
{ TToolButtonClr }
procedure TToolButtonClr.SetButtonColor(AValue: TColor);
begin
if FButtonColor <> AValue then
begin
FButtonColor:= AValue;
Invalidate;
end;
end;
procedure TToolButtonClr.Paint;
var
ARect, IconRect: TRect;
begin
inherited Paint;
if (FToolBar <> nil) and (ClientWidth > 0) and (ClientHeight > 0) then
begin
ARect:= ClientRect;
IconRect.Left:= (ARect.Width - FToolBar.ImagesWidth) div 2;
IconRect.Top:= (ARect.Height - FToolBar.ImagesWidth) div 2;
IconRect.Right:= IconRect.Left + FToolBar.ImagesWidth;
IconRect.Bottom:= IconRect.Top + FToolBar.ImagesWidth;
if Enabled then
begin
Canvas.Brush.Style:= bsSolid;
Canvas.Brush.Color:= FButtonColor
end
else begin
Canvas.Brush.Color:= clGrayText;
Canvas.Brush.Style:= bsDiagCross;
end;
Canvas.Pen.Color:= clBtnText;
Canvas.Rectangle(IconRect);
end;
end;
procedure TToolButtonClr.ShowColorDialog;
begin
if not Enabled then Exit;
if (FColorDialog = nil) then
begin
FColorDialog := TColorDialog.Create(Self);
end;
FColorDialog.Color := ButtonColor;
if FColorDialog.Execute then
begin
ButtonColor := FColorDialog.Color;
end;
end;
constructor TToolButtonClr.Create(TheOwner: TComponent);
begin
FButtonColor:= clRed;
inherited Create(TheOwner);
end;
procedure TToolButtonClr.Click;
begin
inherited Click;
ShowColorDialog;
end;
{ TToolBarAdv }
procedure TToolBarAdv.CalculatePreferredSize(var PreferredWidth,
PreferredHeight: Integer; WithThemeSpace: Boolean);
begin
if IsVertical then
WrapButtons(Height, PreferredWidth, PreferredHeight, True)
else
WrapButtons(Width, PreferredWidth, PreferredHeight, True);
end;
procedure TToolBarAdv.AlignControls(AControl: TControl;
var RemainingClientRect: TRect);
var
NewWidth, NewHeight: integer;
begin
if tbfPlacingControls in FToolBarFlags then exit;
Include(FToolBarFlags, tbfPlacingControls);
DisableAlign;
try
AdjustClientRect(RemainingClientRect);
if IsVertical then
WrapButtons(Height, NewWidth, NewHeight, False)
else
WrapButtons(Width, NewWidth, NewHeight, False);
finally
Exclude(FToolBarFlags, tbfPlacingControls);
EnableAlign;
end;
end;
function TToolBarAdv.WrapButtons(UseSize: Integer; out NewWidth,
NewHeight: Integer; Simulate: Boolean): Boolean;
var
ARect: TRect;
X, Y: Integer;
Vertical: Boolean;
LeftToRight: Boolean;
CurControl: TControl;
StartX, StartY: Integer;
FRowWidth, FRowHeight: Integer;
procedure CalculatePosition;
var
NewBounds: TRect;
StartedAtRowStart: Boolean;
begin
if IsVertical then
begin
NewBounds := Bounds(X, Y, FRowWidth, CurControl.Height);
repeat
if (not Wrapable) or
(NewBounds.Top = StartY) or
(NewBounds.Bottom <= ARect.Bottom) then
begin
// control fits into the column
X := NewBounds.Left;
Y := NewBounds.Top;
Break;
end;
// try next column
NewBounds.Top := StartY;
NewBounds.Bottom := NewBounds.Top + CurControl.Height;
Inc(NewBounds.Left, FRowWidth);
Inc(NewBounds.Right, FRowWidth);
until False;
end
else begin
StartedAtRowStart := (X = StartX);
if LeftToRight then
NewBounds := Bounds(X, Y, CurControl.Width, FRowHeight)
else begin
NewBounds := Bounds(X - CurControl.Width, Y, CurControl.Width, FRowHeight);
end;
repeat
if (not Wrapable) or
(StartedAtRowStart) or
(LeftToRight and ((NewBounds.Left = StartX) or (NewBounds.Right <= ARect.Right))) or
((not LeftToRight) and ((NewBounds.Right = StartX) or (NewBounds.Left >= ARect.Left))) then
begin
// control fits into the row
X := NewBounds.Left;
Y := NewBounds.Top;
Break;
end;
StartedAtRowStart := True;
// try next row
if LeftToRight then
begin
NewBounds.Left := StartX;
NewBounds.Right := NewBounds.Left + CurControl.Width;
end else begin
NewBounds.Right := StartX;
NewBounds.Left := NewBounds.Right - CurControl.Width;
end;
Inc(NewBounds.Top, FRowHeight);
Inc(NewBounds.Bottom, FRowHeight);
until False;
end;
end;
var
I: Integer;
W, H: Integer;
CurClientRect: TRect;
AdjustClientFrame: TRect;
begin
NewWidth := 0;
NewHeight := 0;
Result := True;
Vertical := IsVertical;
FRowWidth:= ButtonWidth;
FRowHeight:= ButtonHeight;
if Vertical then
begin
LeftToRight := True;
end
else begin
LeftToRight := not UseRightToLeftAlignment;
end;
DisableAlign;
BeginUpdate;
try
CurClientRect := ClientRect;
if Vertical then
Inc(CurClientRect.Bottom, UseSize - Height)
else begin
Inc(CurClientRect.Right, UseSize - Width);
end;
ARect := CurClientRect;
AdjustClientRect(ARect);
AdjustClientFrame.Left := ARect.Left - CurClientRect.Left;
AdjustClientFrame.Top := ARect.Top - CurClientRect.Top;
AdjustClientFrame.Right := CurClientRect.Right - ARect.Right;
AdjustClientFrame.Bottom := CurClientRect.Bottom - ARect.Bottom;
//DebugLn(['TToolBar.WrapButtons ',DbgSName(Self),' ARect=',dbgs(ARect)]);
// important: top, left button must start in the AdjustClientRect top, left
// otherwise Toolbar.AutoSize=true will create an endless loop
if Vertical or LeftToRight then
StartX := ARect.Left
else begin
StartX := ARect.Right;
end;
StartY := ARect.Top;
X := StartX;
Y := StartY;
for I := 0 to ButtonList.Count - 1 do
begin
CurControl := TControl(ButtonList[I]);
if not CurControl.IsControlVisible then
Continue;
CalculatePosition;
W := CurControl.Width;
H := CurControl.Height;
if (not Simulate) and ((CurControl.Left <> X) or (CurControl.Top <> Y)) then
begin
CurControl.SetBounds(X, Y, W, H); // Note: do not use SetBoundsKeepBase
end;
// adjust NewWidth, NewHeight
if LeftToRight then
NewWidth := Max(NewWidth, X + W + AdjustClientFrame.Right)
else begin
NewWidth := Max(NewWidth, ARect.Right - X + ARect.Left + AdjustClientFrame.Right);
end;
NewHeight := Max(NewHeight, Y + H + AdjustClientFrame.Bottom);
// step to next position
if IsVertical then
Inc(Y, H)
else if LeftToRight then
Inc(X, W);
end;
finally
EndUpdate;
EnableAlign;
end;
end;
procedure Register;
begin
RegisterComponents('KASComponents', [TToolBarAdv]);
RegisterNoIcon([TToolButtonClr]);
end;
end.

View file

@ -26,8 +26,8 @@
"/>
<License Value="GNU GPL 2
"/>
<Version Major="1" Minor="9" Release="4"/>
<Files Count="10">
<Version Major="1" Minor="9" Release="5"/>
<Files Count="11">
<Item1>
<Filename Value="kastoolbar.pas"/>
<HasRegisterProc Value="True"/>
@ -77,6 +77,11 @@
<HasRegisterProc Value="True"/>
<UnitName Value="KASButtonPanel"/>
</Item10>
<Item11>
<Filename Value="kascomctrls.pas"/>
<HasRegisterProc Value="True"/>
<UnitName Value="KASComCtrls"/>
</Item11>
</Files>
<CompatibilityMode Value="True"/>
<RequiredPkgs Count="3">

View file

@ -10,7 +10,7 @@ interface
uses
KASToolBar, KASProgressBar, KASPathEdit, KASToolItems, KASComboBox,
KASCDEdit, KASStatusBar, KASToolPanel, KASButton, KASButtonPanel,
LazarusPackageIntf;
KASComCtrls, LazarusPackageIntf;
implementation
@ -25,6 +25,7 @@ begin
RegisterUnit('KASToolPanel', @KASToolPanel.Register);
RegisterUnit('KASButton', @KASButton.Register);
RegisterUnit('KASButtonPanel', @KASButtonPanel.Register);
RegisterUnit('KASComCtrls', @KASComCtrls.Register);
end;
initialization

View file

@ -208,7 +208,7 @@ begin
end;
procedure TKASPathEdit.AutoComplete(const Path: String);
{$IF LCL_FULLVERSION >= 2020000}
{$IF LCL_FULLVERSION < 4990000}
const
AFlags: array[Boolean] of TMaskOptions = (
[moDisableSets], [moDisableSets, moCaseSensitive]
@ -236,7 +236,7 @@ begin
try
// Check mask and make absolute file name
AMask:= TMask.Create(ExtractFileName(Path) + '*',
{$IF LCL_FULLVERSION >= 2020000}
{$IF LCL_FULLVERSION < 4990000}
AFlags[FileNameCaseSensitive]
{$ELSE}
FileNameCaseSensitive
@ -367,8 +367,10 @@ end;
procedure TKASPathEdit.TextChanged;
begin
Inherited;
// TextChanged is called by user input, "if Modified" is not need
if FAutoComplete then AutoComplete(Text);
if not Modified then
Exit;
if FAutoComplete then
AutoComplete(Text);
end;
{$ENDIF}

View file

@ -3,7 +3,7 @@
-------------------------------------------------------------------------
Toolbar panel class
Copyright (C) 2006-2019 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2006-2023 Alexander Koblov (alexx2000@mail.ru)
contributors:
2012 Przemyslaw Nagay (cobines@gmail.com)
@ -33,7 +33,7 @@ interface
uses
Classes, SysUtils, LResources, Forms, Controls, ComCtrls,
Graphics, Dialogs, ExtCtrls, Buttons, FileUtil, Menus,
DCXmlConfig, KASToolItems, LCLVersion;
DCXmlConfig, KASToolItems, LCLVersion, LMessages;
type
TOnToolButtonClick = procedure (Sender: TObject) of object;
@ -64,6 +64,7 @@ type
function DrawGlyph(ACanvas: TCanvas; const AClient: TRect; const AOffset: TPoint;
AState: TButtonState; ATransparent: Boolean; BiDiFlags: Longint): TRect; override;
procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
procedure CMHintShow(var Message: TLMessage); message CM_HINTSHOW;
public
constructor Create(AOwner: TComponent; Item: TKASToolItem); reintroduce;
destructor Destroy; override;
@ -1089,6 +1090,17 @@ begin
end;
end;
procedure TKASToolButton.CMHintShow(var Message: TLMessage);
begin
if (ActionLink <> nil) and FToolItem.ActionHint then
begin
inherited CMHintShow(Message);
end
else begin
DoOnShowHint(TCMHintShow(Message).HintInfo);
end;
end;
constructor TKASToolButton.Create(AOwner: TComponent; Item: TKASToolItem);
begin
inherited Create(AOwner);

View file

@ -62,6 +62,7 @@ type
FAction: TBasicAction;
property ToolOwner: IToolOwner read FToolOwner;
public
function ActionHint: Boolean; virtual;
procedure Assign(OtherItem: TKASToolItem); virtual;
function CheckExecute(ToolItemID: String): Boolean; virtual;
function Clone: TKASToolItem; virtual; abstract;
@ -94,6 +95,8 @@ type
{ TKASNormalItem }
TKASNormalItem = class(TKASToolItem)
private
FShortcutsHint: Boolean;
strict private
FID: String; // Unique identificator of the button
function GetID: String;
@ -105,6 +108,7 @@ type
Icon: String;
Text: String;
Hint: String;
function ActionHint: Boolean; override;
procedure Assign(OtherItem: TKASToolItem); override;
function CheckExecute(ToolItemID: String): Boolean; override;
function Clone: TKASToolItem; override;
@ -183,6 +187,11 @@ uses
{ TKASToolItem }
function TKASToolItem.ActionHint: Boolean;
begin
Result := True;
end;
procedure TKASToolItem.Assign(OtherItem: TKASToolItem);
begin
FUserData := OtherItem.FUserData;
@ -481,8 +490,10 @@ function TKASNormalItem.GetShortcutsHint: String;
begin
if Assigned(FToolOwner) then
Result := FToolOwner.GetToolItemShortcutsHint(Self)
else
else begin
Result := '';
end;
FShortcutsHint := (Length(Result) > 0);
end;
procedure TKASNormalItem.Load(Config: TXmlConfig; Node: TXmlNode; Loader: TKASToolBarLoader);
@ -525,6 +536,11 @@ begin
Config.AddValueDef(Node, 'Text', Text, '');
end;
function TKASNormalItem.ActionHint: Boolean;
begin
Result := not FShortcutsHint;
end;
{ TKASToolBarItems }
constructor TKASToolBarItems.Create;

View file

@ -8,11 +8,17 @@ uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Toolwin;
type
{ TKASToolPanel }
TKASToolPanel = class(TToolWindow)
public
constructor Create(TheOwner: TComponent); override;
published
property Align default alNone;
property Anchors;
property AutoSize;
property BorderSpacing;
property ChildSizing;
property EdgeBorders default [ebTop];
property EdgeInner;
@ -30,4 +36,12 @@ begin
RegisterComponents('KASComponents',[TKASToolPanel]);
end;
{ TKASToolPanel }
constructor TKASToolPanel.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
EdgeBorders:= [ebTop];
end;
end.

View file

@ -8,7 +8,7 @@ rem This script is called from ..\build.bat.
pushd components
lazbuild chsdet\chsdet.lpk %DC_ARCH%
lazbuild multithreadprocs\multithreadprocslaz.lpk %DC_ARCH%
lazbuild dcpcrypt\dcpcrypt.lpk %DC_ARCH%
lazbuild kascrypt\kascrypt.lpk %DC_ARCH%
lazbuild doublecmd\doublecmd_common.lpk %DC_ARCH%
lazbuild Image32\Image32.lpk %DC_ARCH%
lazbuild KASToolBar\kascomp.lpk %DC_ARCH%

View file

@ -26,7 +26,7 @@ basedir=$(pwd)
cd components
$lazbuild chsdet/chsdet.lpk $DC_ARCH
$lazbuild multithreadprocs/multithreadprocslaz.lpk $DC_ARCH
$lazbuild dcpcrypt/dcpcrypt.lpk $DC_ARCH
$lazbuild kascrypt/kascrypt.lpk $DC_ARCH
$lazbuild doublecmd/doublecmd_common.lpk $DC_ARCH
$lazbuild Image32/Image32.lpk $DC_ARCH
$lazbuild KASToolBar/kascomp.lpk $DC_ARCH

View file

@ -1,32 +0,0 @@
Change in v2.0.4.1 by Graeme Geldenhuys (2010)
* Version number bumped to v2.0.4.1
* More fixes for 64-bit support
* Removed a lot of compiler warnings - tested with FPC 2.4.1
Change in v2.0.4 by Graeme Geldenhuys (2009)
* Version number bumped to v2.0.4
* Split the Lazarus package into two separate packages
- one is runtime only package and GUI toolkit independent.
- one is Lazarus design-time only package which installs
components in component palette.
* Updated code to be compilable with FPC 2.4.0-rc1
* Updated code to be compilable with 64-bit FPC 2.4.0-rc1.
- Tested under 32-bit & 64-bit Linux on x86 systems.
Changes since DCPCrypt v2 Beta 3:
* Ported DCPCrypt to Lazarus by Barko in 2006
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

View file

@ -1,203 +0,0 @@
temp:= (t2 and (t4 xor t3) xor t6 and t0 xor t5 and t1 xor t4);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 0];
temp:= (t1 and (t3 xor t2) xor t5 and t7 xor t4 and t0 xor t3);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 1];
temp:= (t0 and (t2 xor t1) xor t4 and t6 xor t3 and t7 xor t2);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 2];
temp:= (t7 and (t1 xor t0) xor t3 and t5 xor t2 and t6 xor t1);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 3];
temp:= (t6 and (t0 xor t7) xor t2 and t4 xor t1 and t5 xor t0);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 4];
temp:= (t5 and (t7 xor t6) xor t1 and t3 xor t0 and t4 xor t7);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 5];
temp:= (t4 and (t6 xor t5) xor t0 and t2 xor t7 and t3 xor t6);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 6];
temp:= (t3 and (t5 xor t4) xor t7 and t1 xor t6 and t2 xor t5);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 7];
temp:= (t2 and (t4 xor t3) xor t6 and t0 xor t5 and t1 xor t4);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 8];
temp:= (t1 and (t3 xor t2) xor t5 and t7 xor t4 and t0 xor t3);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9];
temp:= (t0 and (t2 xor t1) xor t4 and t6 xor t3 and t7 xor t2);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[10];
temp:= (t7 and (t1 xor t0) xor t3 and t5 xor t2 and t6 xor t1);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[11];
temp:= (t6 and (t0 xor t7) xor t2 and t4 xor t1 and t5 xor t0);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[12];
temp:= (t5 and (t7 xor t6) xor t1 and t3 xor t0 and t4 xor t7);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[13];
temp:= (t4 and (t6 xor t5) xor t0 and t2 xor t7 and t3 xor t6);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[14];
temp:= (t3 and (t5 xor t4) xor t7 and t1 xor t6 and t2 xor t5);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[15];
temp:= (t2 and (t4 xor t3) xor t6 and t0 xor t5 and t1 xor t4);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[16];
temp:= (t1 and (t3 xor t2) xor t5 and t7 xor t4 and t0 xor t3);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[17];
temp:= (t0 and (t2 xor t1) xor t4 and t6 xor t3 and t7 xor t2);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[18];
temp:= (t7 and (t1 xor t0) xor t3 and t5 xor t2 and t6 xor t1);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[19];
temp:= (t6 and (t0 xor t7) xor t2 and t4 xor t1 and t5 xor t0);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[20];
temp:= (t5 and (t7 xor t6) xor t1 and t3 xor t0 and t4 xor t7);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[21];
temp:= (t4 and (t6 xor t5) xor t0 and t2 xor t7 and t3 xor t6);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[22];
temp:= (t3 and (t5 xor t4) xor t7 and t1 xor t6 and t2 xor t5);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[23];
temp:= (t2 and (t4 xor t3) xor t6 and t0 xor t5 and t1 xor t4);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[24];
temp:= (t1 and (t3 xor t2) xor t5 and t7 xor t4 and t0 xor t3);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[25];
temp:= (t0 and (t2 xor t1) xor t4 and t6 xor t3 and t7 xor t2);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[26];
temp:= (t7 and (t1 xor t0) xor t3 and t5 xor t2 and t6 xor t1);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[27];
temp:= (t6 and (t0 xor t7) xor t2 and t4 xor t1 and t5 xor t0);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[28];
temp:= (t5 and (t7 xor t6) xor t1 and t3 xor t0 and t4 xor t7);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[29];
temp:= (t4 and (t6 xor t5) xor t0 and t2 xor t7 and t3 xor t6);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[30];
temp:= (t3 and (t5 xor t4) xor t7 and t1 xor t6 and t2 xor t5);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[31];
temp:= (t5 and (t3 and not t0 xor t1 and t2 xor t4 xor t6) xor t1 and (t3 xor t2) xor t0 and t2 xor t6);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 5] + $452821E6;
temp:= (t4 and (t2 and not t7 xor t0 and t1 xor t3 xor t5) xor t0 and (t2 xor t1) xor t7 and t1 xor t5);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[14] + $38D01377;
temp:= (t3 and (t1 and not t6 xor t7 and t0 xor t2 xor t4) xor t7 and (t1 xor t0) xor t6 and t0 xor t4);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[26] + $BE5466CF;
temp:= (t2 and (t0 and not t5 xor t6 and t7 xor t1 xor t3) xor t6 and (t0 xor t7) xor t5 and t7 xor t3);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[18] + $34E90C6C;
temp:= (t1 and (t7 and not t4 xor t5 and t6 xor t0 xor t2) xor t5 and (t7 xor t6) xor t4 and t6 xor t2);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[11] + $C0AC29B7;
temp:= (t0 and (t6 and not t3 xor t4 and t5 xor t7 xor t1) xor t4 and (t6 xor t5) xor t3 and t5 xor t1);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[28] + $C97C50DD;
temp:= (t7 and (t5 and not t2 xor t3 and t4 xor t6 xor t0) xor t3 and (t5 xor t4) xor t2 and t4 xor t0);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 7] + $3F84D5B5;
temp:= (t6 and (t4 and not t1 xor t2 and t3 xor t5 xor t7) xor t2 and (t4 xor t3) xor t1 and t3 xor t7);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[16] + $B5470917;
temp:= (t5 and (t3 and not t0 xor t1 and t2 xor t4 xor t6) xor t1 and (t3 xor t2) xor t0 and t2 xor t6);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 0] + $9216D5D9;
temp:= (t4 and (t2 and not t7 xor t0 and t1 xor t3 xor t5) xor t0 and (t2 xor t1) xor t7 and t1 xor t5);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[23] + $8979FB1B;
temp:= (t3 and (t1 and not t6 xor t7 and t0 xor t2 xor t4) xor t7 and (t1 xor t0) xor t6 and t0 xor t4);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[20] + $D1310BA6;
temp:= (t2 and (t0 and not t5 xor t6 and t7 xor t1 xor t3) xor t6 and (t0 xor t7) xor t5 and t7 xor t3);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[22] + $98DFB5AC;
temp:= (t1 and (t7 and not t4 xor t5 and t6 xor t0 xor t2) xor t5 and (t7 xor t6) xor t4 and t6 xor t2);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 1] + $2FFD72DB;
temp:= (t0 and (t6 and not t3 xor t4 and t5 xor t7 xor t1) xor t4 and (t6 xor t5) xor t3 and t5 xor t1);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[10] + $D01ADFB7;
temp:= (t7 and (t5 and not t2 xor t3 and t4 xor t6 xor t0) xor t3 and (t5 xor t4) xor t2 and t4 xor t0);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 4] + $B8E1AFED;
temp:= (t6 and (t4 and not t1 xor t2 and t3 xor t5 xor t7) xor t2 and (t4 xor t3) xor t1 and t3 xor t7);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 8] + $6A267E96;
temp:= (t5 and (t3 and not t0 xor t1 and t2 xor t4 xor t6) xor t1 and (t3 xor t2) xor t0 and t2 xor t6);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[30] + $BA7C9045;
temp:= (t4 and (t2 and not t7 xor t0 and t1 xor t3 xor t5) xor t0 and (t2 xor t1) xor t7 and t1 xor t5);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 3] + $F12C7F99;
temp:= (t3 and (t1 and not t6 xor t7 and t0 xor t2 xor t4) xor t7 and (t1 xor t0) xor t6 and t0 xor t4);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $24A19947;
temp:= (t2 and (t0 and not t5 xor t6 and t7 xor t1 xor t3) xor t6 and (t0 xor t7) xor t5 and t7 xor t3);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 9] + $B3916CF7;
temp:= (t1 and (t7 and not t4 xor t5 and t6 xor t0 xor t2) xor t5 and (t7 xor t6) xor t4 and t6 xor t2);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[17] + $0801F2E2;
temp:= (t0 and (t6 and not t3 xor t4 and t5 xor t7 xor t1) xor t4 and (t6 xor t5) xor t3 and t5 xor t1);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[24] + $858EFC16;
temp:= (t7 and (t5 and not t2 xor t3 and t4 xor t6 xor t0) xor t3 and (t5 xor t4) xor t2 and t4 xor t0);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[29] + $636920D8;
temp:= (t6 and (t4 and not t1 xor t2 and t3 xor t5 xor t7) xor t2 and (t4 xor t3) xor t1 and t3 xor t7);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 6] + $71574E69;
temp:= (t5 and (t3 and not t0 xor t1 and t2 xor t4 xor t6) xor t1 and (t3 xor t2) xor t0 and t2 xor t6);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $A458FEA3;
temp:= (t4 and (t2 and not t7 xor t0 and t1 xor t3 xor t5) xor t0 and (t2 xor t1) xor t7 and t1 xor t5);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[12] + $F4933D7E;
temp:= (t3 and (t1 and not t6 xor t7 and t0 xor t2 xor t4) xor t7 and (t1 xor t0) xor t6 and t0 xor t4);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[15] + $0D95748F;
temp:= (t2 and (t0 and not t5 xor t6 and t7 xor t1 xor t3) xor t6 and (t0 xor t7) xor t5 and t7 xor t3);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[13] + $728EB658;
temp:= (t1 and (t7 and not t4 xor t5 and t6 xor t0 xor t2) xor t5 and (t7 xor t6) xor t4 and t6 xor t2);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 2] + $718BCD58;
temp:= (t0 and (t6 and not t3 xor t4 and t5 xor t7 xor t1) xor t4 and (t6 xor t5) xor t3 and t5 xor t1);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[25] + $82154AEE;
temp:= (t7 and (t5 and not t2 xor t3 and t4 xor t6 xor t0) xor t3 and (t5 xor t4) xor t2 and t4 xor t0);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[31] + $7B54A41D;
temp:= (t6 and (t4 and not t1 xor t2 and t3 xor t5 xor t7) xor t2 and (t4 xor t3) xor t1 and t3 xor t7);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[27] + $C25A59B5;
temp:= (t3 and (t5 and t4 xor t6 xor t0) xor t5 and t2 xor t4 and t1 xor t0);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $9C30D539;
temp:= (t2 and (t4 and t3 xor t5 xor t7) xor t4 and t1 xor t3 and t0 xor t7);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9] + $2AF26013;
temp:= (t1 and (t3 and t2 xor t4 xor t6) xor t3 and t0 xor t2 and t7 xor t6);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 4] + $C5D1B023;
temp:= (t0 and (t2 and t1 xor t3 xor t5) xor t2 and t7 xor t1 and t6 xor t5);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[20] + $286085F0;
temp:= (t7 and (t1 and t0 xor t2 xor t4) xor t1 and t6 xor t0 and t5 xor t4);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[28] + $CA417918;
temp:= (t6 and (t0 and t7 xor t1 xor t3) xor t0 and t5 xor t7 and t4 xor t3);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[17] + $B8DB38EF;
temp:= (t5 and (t7 and t6 xor t0 xor t2) xor t7 and t4 xor t6 and t3 xor t2);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 8] + $8E79DCB0;
temp:= (t4 and (t6 and t5 xor t7 xor t1) xor t6 and t3 xor t5 and t2 xor t1);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[22] + $603A180E;
temp:= (t3 and (t5 and t4 xor t6 xor t0) xor t5 and t2 xor t4 and t1 xor t0);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[29] + $6C9E0E8B;
temp:= (t2 and (t4 and t3 xor t5 xor t7) xor t4 and t1 xor t3 and t0 xor t7);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[14] + $B01E8A3E;
temp:= (t1 and (t3 and t2 xor t4 xor t6) xor t3 and t0 xor t2 and t7 xor t6);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[25] + $D71577C1;
temp:= (t0 and (t2 and t1 xor t3 xor t5) xor t2 and t7 xor t1 and t6 xor t5);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[12] + $BD314B27;
temp:= (t7 and (t1 and t0 xor t2 xor t4) xor t1 and t6 xor t0 and t5 xor t4);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[24] + $78AF2FDA;
temp:= (t6 and (t0 and t7 xor t1 xor t3) xor t0 and t5 xor t7 and t4 xor t3);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[30] + $55605C60;
temp:= (t5 and (t7 and t6 xor t0 xor t2) xor t7 and t4 xor t6 and t3 xor t2);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[16] + $E65525F3;
temp:= (t4 and (t6 and t5 xor t7 xor t1) xor t6 and t3 xor t5 and t2 xor t1);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[26] + $AA55AB94;
temp:= (t3 and (t5 and t4 xor t6 xor t0) xor t5 and t2 xor t4 and t1 xor t0);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[31] + $57489862;
temp:= (t2 and (t4 and t3 xor t5 xor t7) xor t4 and t1 xor t3 and t0 xor t7);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[15] + $63E81440;
temp:= (t1 and (t3 and t2 xor t4 xor t6) xor t3 and t0 xor t2 and t7 xor t6);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 7] + $55CA396A;
temp:= (t0 and (t2 and t1 xor t3 xor t5) xor t2 and t7 xor t1 and t6 xor t5);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 3] + $2AAB10B6;
temp:= (t7 and (t1 and t0 xor t2 xor t4) xor t1 and t6 xor t0 and t5 xor t4);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 1] + $B4CC5C34;
temp:= (t6 and (t0 and t7 xor t1 xor t3) xor t0 and t5 xor t7 and t4 xor t3);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 0] + $1141E8CE;
temp:= (t5 and (t7 and t6 xor t0 xor t2) xor t7 and t4 xor t6 and t3 xor t2);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[18] + $A15486AF;
temp:= (t4 and (t6 and t5 xor t7 xor t1) xor t6 and t3 xor t5 and t2 xor t1);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[27] + $7C72E993;
temp:= (t3 and (t5 and t4 xor t6 xor t0) xor t5 and t2 xor t4 and t1 xor t0);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[13] + $B3EE1411;
temp:= (t2 and (t4 and t3 xor t5 xor t7) xor t4 and t1 xor t3 and t0 xor t7);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 6] + $636FBC2A;
temp:= (t1 and (t3 and t2 xor t4 xor t6) xor t3 and t0 xor t2 and t7 xor t6);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $2BA9C55D;
temp:= (t0 and (t2 and t1 xor t3 xor t5) xor t2 and t7 xor t1 and t6 xor t5);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[10] + $741831F6;
temp:= (t7 and (t1 and t0 xor t2 xor t4) xor t1 and t6 xor t0 and t5 xor t4);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[23] + $CE5C3E16;
temp:= (t6 and (t0 and t7 xor t1 xor t3) xor t0 and t5 xor t7 and t4 xor t3);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[11] + $9B87931E;
temp:= (t5 and (t7 and t6 xor t0 xor t2) xor t7 and t4 xor t6 and t3 xor t2);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 5] + $AFD6BA33;
temp:= (t4 and (t6 and t5 xor t7 xor t1) xor t6 and t3 xor t5 and t2 xor t1);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 2] + $6C24CF5C;

View file

@ -1,272 +0,0 @@
temp:= (t3 and (t0 xor t1) xor t5 and t6 xor t4 and t2 xor t0);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 0];
temp:= (t2 and (t7 xor t0) xor t4 and t5 xor t3 and t1 xor t7);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 1];
temp:= (t1 and (t6 xor t7) xor t3 and t4 xor t2 and t0 xor t6);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 2];
temp:= (t0 and (t5 xor t6) xor t2 and t3 xor t1 and t7 xor t5);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 3];
temp:= (t7 and (t4 xor t5) xor t1 and t2 xor t0 and t6 xor t4);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 4];
temp:= (t6 and (t3 xor t4) xor t0 and t1 xor t7 and t5 xor t3);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 5];
temp:= (t5 and (t2 xor t3) xor t7 and t0 xor t6 and t4 xor t2);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 6];
temp:= (t4 and (t1 xor t2) xor t6 and t7 xor t5 and t3 xor t1);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 7];
temp:= (t3 and (t0 xor t1) xor t5 and t6 xor t4 and t2 xor t0);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 8];
temp:= (t2 and (t7 xor t0) xor t4 and t5 xor t3 and t1 xor t7);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9];
temp:= (t1 and (t6 xor t7) xor t3 and t4 xor t2 and t0 xor t6);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[10];
temp:= (t0 and (t5 xor t6) xor t2 and t3 xor t1 and t7 xor t5);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[11];
temp:= (t7 and (t4 xor t5) xor t1 and t2 xor t0 and t6 xor t4);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[12];
temp:= (t6 and (t3 xor t4) xor t0 and t1 xor t7 and t5 xor t3);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[13];
temp:= (t5 and (t2 xor t3) xor t7 and t0 xor t6 and t4 xor t2);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[14];
temp:= (t4 and (t1 xor t2) xor t6 and t7 xor t5 and t3 xor t1);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[15];
temp:= (t3 and (t0 xor t1) xor t5 and t6 xor t4 and t2 xor t0);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[16];
temp:= (t2 and (t7 xor t0) xor t4 and t5 xor t3 and t1 xor t7);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[17];
temp:= (t1 and (t6 xor t7) xor t3 and t4 xor t2 and t0 xor t6);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[18];
temp:= (t0 and (t5 xor t6) xor t2 and t3 xor t1 and t7 xor t5);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[19];
temp:= (t7 and (t4 xor t5) xor t1 and t2 xor t0 and t6 xor t4);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[20];
temp:= (t6 and (t3 xor t4) xor t0 and t1 xor t7 and t5 xor t3);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[21];
temp:= (t5 and (t2 xor t3) xor t7 and t0 xor t6 and t4 xor t2);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[22];
temp:= (t4 and (t1 xor t2) xor t6 and t7 xor t5 and t3 xor t1);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[23];
temp:= (t3 and (t0 xor t1) xor t5 and t6 xor t4 and t2 xor t0);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[24];
temp:= (t2 and (t7 xor t0) xor t4 and t5 xor t3 and t1 xor t7);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[25];
temp:= (t1 and (t6 xor t7) xor t3 and t4 xor t2 and t0 xor t6);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[26];
temp:= (t0 and (t5 xor t6) xor t2 and t3 xor t1 and t7 xor t5);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[27];
temp:= (t7 and (t4 xor t5) xor t1 and t2 xor t0 and t6 xor t4);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[28];
temp:= (t6 and (t3 xor t4) xor t0 and t1 xor t7 and t5 xor t3);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[29];
temp:= (t5 and (t2 xor t3) xor t7 and t0 xor t6 and t4 xor t2);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[30];
temp:= (t4 and (t1 xor t2) xor t6 and t7 xor t5 and t3 xor t1);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[31];
temp:= (t1 and (t6 and not t0 xor t2 and t5 xor t3 xor t4) xor t2 and (t6 xor t5) xor t0 and t5 xor t4);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 5] + $452821E6;
temp:= (t0 and (t5 and not t7 xor t1 and t4 xor t2 xor t3) xor t1 and (t5 xor t4) xor t7 and t4 xor t3);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[14] + $38D01377;
temp:= (t7 and (t4 and not t6 xor t0 and t3 xor t1 xor t2) xor t0 and (t4 xor t3) xor t6 and t3 xor t2);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[26] + $BE5466CF;
temp:= (t6 and (t3 and not t5 xor t7 and t2 xor t0 xor t1) xor t7 and (t3 xor t2) xor t5 and t2 xor t1);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[18] + $34E90C6C;
temp:= (t5 and (t2 and not t4 xor t6 and t1 xor t7 xor t0) xor t6 and (t2 xor t1) xor t4 and t1 xor t0);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[11] + $C0AC29B7;
temp:= (t4 and (t1 and not t3 xor t5 and t0 xor t6 xor t7) xor t5 and (t1 xor t0) xor t3 and t0 xor t7);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[28] + $C97C50DD;
temp:= (t3 and (t0 and not t2 xor t4 and t7 xor t5 xor t6) xor t4 and (t0 xor t7) xor t2 and t7 xor t6);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 7] + $3F84D5B5;
temp:= (t2 and (t7 and not t1 xor t3 and t6 xor t4 xor t5) xor t3 and (t7 xor t6) xor t1 and t6 xor t5);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[16] + $B5470917;
temp:= (t1 and (t6 and not t0 xor t2 and t5 xor t3 xor t4) xor t2 and (t6 xor t5) xor t0 and t5 xor t4);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 0] + $9216D5D9;
temp:= (t0 and (t5 and not t7 xor t1 and t4 xor t2 xor t3) xor t1 and (t5 xor t4) xor t7 and t4 xor t3);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[23] + $8979FB1B;
temp:= (t7 and (t4 and not t6 xor t0 and t3 xor t1 xor t2) xor t0 and (t4 xor t3) xor t6 and t3 xor t2);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[20] + $D1310BA6;
temp:= (t6 and (t3 and not t5 xor t7 and t2 xor t0 xor t1) xor t7 and (t3 xor t2) xor t5 and t2 xor t1);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[22] + $98DFB5AC;
temp:= (t5 and (t2 and not t4 xor t6 and t1 xor t7 xor t0) xor t6 and (t2 xor t1) xor t4 and t1 xor t0);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 1] + $2FFD72DB;
temp:= (t4 and (t1 and not t3 xor t5 and t0 xor t6 xor t7) xor t5 and (t1 xor t0) xor t3 and t0 xor t7);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[10] + $D01ADFB7;
temp:= (t3 and (t0 and not t2 xor t4 and t7 xor t5 xor t6) xor t4 and (t0 xor t7) xor t2 and t7 xor t6);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 4] + $B8E1AFED;
temp:= (t2 and (t7 and not t1 xor t3 and t6 xor t4 xor t5) xor t3 and (t7 xor t6) xor t1 and t6 xor t5);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 8] + $6A267E96;
temp:= (t1 and (t6 and not t0 xor t2 and t5 xor t3 xor t4) xor t2 and (t6 xor t5) xor t0 and t5 xor t4);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[30] + $BA7C9045;
temp:= (t0 and (t5 and not t7 xor t1 and t4 xor t2 xor t3) xor t1 and (t5 xor t4) xor t7 and t4 xor t3);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 3] + $F12C7F99;
temp:= (t7 and (t4 and not t6 xor t0 and t3 xor t1 xor t2) xor t0 and (t4 xor t3) xor t6 and t3 xor t2);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $24A19947;
temp:= (t6 and (t3 and not t5 xor t7 and t2 xor t0 xor t1) xor t7 and (t3 xor t2) xor t5 and t2 xor t1);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 9] + $B3916CF7;
temp:= (t5 and (t2 and not t4 xor t6 and t1 xor t7 xor t0) xor t6 and (t2 xor t1) xor t4 and t1 xor t0);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[17] + $0801F2E2;
temp:= (t4 and (t1 and not t3 xor t5 and t0 xor t6 xor t7) xor t5 and (t1 xor t0) xor t3 and t0 xor t7);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[24] + $858EFC16;
temp:= (t3 and (t0 and not t2 xor t4 and t7 xor t5 xor t6) xor t4 and (t0 xor t7) xor t2 and t7 xor t6);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[29] + $636920D8;
temp:= (t2 and (t7 and not t1 xor t3 and t6 xor t4 xor t5) xor t3 and (t7 xor t6) xor t1 and t6 xor t5);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 6] + $71574E69;
temp:= (t1 and (t6 and not t0 xor t2 and t5 xor t3 xor t4) xor t2 and (t6 xor t5) xor t0 and t5 xor t4);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $A458FEA3;
temp:= (t0 and (t5 and not t7 xor t1 and t4 xor t2 xor t3) xor t1 and (t5 xor t4) xor t7 and t4 xor t3);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[12] + $F4933D7E;
temp:= (t7 and (t4 and not t6 xor t0 and t3 xor t1 xor t2) xor t0 and (t4 xor t3) xor t6 and t3 xor t2);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[15] + $0D95748F;
temp:= (t6 and (t3 and not t5 xor t7 and t2 xor t0 xor t1) xor t7 and (t3 xor t2) xor t5 and t2 xor t1);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[13] + $728EB658;
temp:= (t5 and (t2 and not t4 xor t6 and t1 xor t7 xor t0) xor t6 and (t2 xor t1) xor t4 and t1 xor t0);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 2] + $718BCD58;
temp:= (t4 and (t1 and not t3 xor t5 and t0 xor t6 xor t7) xor t5 and (t1 xor t0) xor t3 and t0 xor t7);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[25] + $82154AEE;
temp:= (t3 and (t0 and not t2 xor t4 and t7 xor t5 xor t6) xor t4 and (t0 xor t7) xor t2 and t7 xor t6);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[31] + $7B54A41D;
temp:= (t2 and (t7 and not t1 xor t3 and t6 xor t4 xor t5) xor t3 and (t7 xor t6) xor t1 and t6 xor t5);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[27] + $C25A59B5;
temp:= (t6 and (t2 and t0 xor t1 xor t5) xor t2 and t3 xor t0 and t4 xor t5);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $9C30D539;
temp:= (t5 and (t1 and t7 xor t0 xor t4) xor t1 and t2 xor t7 and t3 xor t4);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9] + $2AF26013;
temp:= (t4 and (t0 and t6 xor t7 xor t3) xor t0 and t1 xor t6 and t2 xor t3);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 4] + $C5D1B023;
temp:= (t3 and (t7 and t5 xor t6 xor t2) xor t7 and t0 xor t5 and t1 xor t2);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[20] + $286085F0;
temp:= (t2 and (t6 and t4 xor t5 xor t1) xor t6 and t7 xor t4 and t0 xor t1);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[28] + $CA417918;
temp:= (t1 and (t5 and t3 xor t4 xor t0) xor t5 and t6 xor t3 and t7 xor t0);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[17] + $B8DB38EF;
temp:= (t0 and (t4 and t2 xor t3 xor t7) xor t4 and t5 xor t2 and t6 xor t7);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 8] + $8E79DCB0;
temp:= (t7 and (t3 and t1 xor t2 xor t6) xor t3 and t4 xor t1 and t5 xor t6);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[22] + $603A180E;
temp:= (t6 and (t2 and t0 xor t1 xor t5) xor t2 and t3 xor t0 and t4 xor t5);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[29] + $6C9E0E8B;
temp:= (t5 and (t1 and t7 xor t0 xor t4) xor t1 and t2 xor t7 and t3 xor t4);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[14] + $B01E8A3E;
temp:= (t4 and (t0 and t6 xor t7 xor t3) xor t0 and t1 xor t6 and t2 xor t3);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[25] + $D71577C1;
temp:= (t3 and (t7 and t5 xor t6 xor t2) xor t7 and t0 xor t5 and t1 xor t2);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[12] + $BD314B27;
temp:= (t2 and (t6 and t4 xor t5 xor t1) xor t6 and t7 xor t4 and t0 xor t1);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[24] + $78AF2FDA;
temp:= (t1 and (t5 and t3 xor t4 xor t0) xor t5 and t6 xor t3 and t7 xor t0);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[30] + $55605C60;
temp:= (t0 and (t4 and t2 xor t3 xor t7) xor t4 and t5 xor t2 and t6 xor t7);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[16] + $E65525F3;
temp:= (t7 and (t3 and t1 xor t2 xor t6) xor t3 and t4 xor t1 and t5 xor t6);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[26] + $AA55AB94;
temp:= (t6 and (t2 and t0 xor t1 xor t5) xor t2 and t3 xor t0 and t4 xor t5);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[31] + $57489862;
temp:= (t5 and (t1 and t7 xor t0 xor t4) xor t1 and t2 xor t7 and t3 xor t4);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[15] + $63E81440;
temp:= (t4 and (t0 and t6 xor t7 xor t3) xor t0 and t1 xor t6 and t2 xor t3);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 7] + $55CA396A;
temp:= (t3 and (t7 and t5 xor t6 xor t2) xor t7 and t0 xor t5 and t1 xor t2);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 3] + $2AAB10B6;
temp:= (t2 and (t6 and t4 xor t5 xor t1) xor t6 and t7 xor t4 and t0 xor t1);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 1] + $B4CC5C34;
temp:= (t1 and (t5 and t3 xor t4 xor t0) xor t5 and t6 xor t3 and t7 xor t0);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 0] + $1141E8CE;
temp:= (t0 and (t4 and t2 xor t3 xor t7) xor t4 and t5 xor t2 and t6 xor t7);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[18] + $A15486AF;
temp:= (t7 and (t3 and t1 xor t2 xor t6) xor t3 and t4 xor t1 and t5 xor t6);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[27] + $7C72E993;
temp:= (t6 and (t2 and t0 xor t1 xor t5) xor t2 and t3 xor t0 and t4 xor t5);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[13] + $B3EE1411;
temp:= (t5 and (t1 and t7 xor t0 xor t4) xor t1 and t2 xor t7 and t3 xor t4);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 6] + $636FBC2A;
temp:= (t4 and (t0 and t6 xor t7 xor t3) xor t0 and t1 xor t6 and t2 xor t3);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $2BA9C55D;
temp:= (t3 and (t7 and t5 xor t6 xor t2) xor t7 and t0 xor t5 and t1 xor t2);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[10] + $741831F6;
temp:= (t2 and (t6 and t4 xor t5 xor t1) xor t6 and t7 xor t4 and t0 xor t1);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[23] + $CE5C3E16;
temp:= (t1 and (t5 and t3 xor t4 xor t0) xor t5 and t6 xor t3 and t7 xor t0);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[11] + $9B87931E;
temp:= (t0 and (t4 and t2 xor t3 xor t7) xor t4 and t5 xor t2 and t6 xor t7);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 5] + $AFD6BA33;
temp:= (t7 and (t3 and t1 xor t2 xor t6) xor t3 and t4 xor t1 and t5 xor t6);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 2] + $6C24CF5C;
temp:= (t0 and (t4 and not t2 xor t5 and not t6 xor t1 xor t6 xor t3) xor t5 and (t1 and t2 xor t4 xor t6) xor t2 and t6 xor t3);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[24] + $7A325381;
temp:= (t7 and (t3 and not t1 xor t4 and not t5 xor t0 xor t5 xor t2) xor t4 and (t0 and t1 xor t3 xor t5) xor t1 and t5 xor t2);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 4] + $28958677;
temp:= (t6 and (t2 and not t0 xor t3 and not t4 xor t7 xor t4 xor t1) xor t3 and (t7 and t0 xor t2 xor t4) xor t0 and t4 xor t1);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 0] + $3B8F4898;
temp:= (t5 and (t1 and not t7 xor t2 and not t3 xor t6 xor t3 xor t0) xor t2 and (t6 and t7 xor t1 xor t3) xor t7 and t3 xor t0);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[14] + $6B4BB9AF;
temp:= (t4 and (t0 and not t6 xor t1 and not t2 xor t5 xor t2 xor t7) xor t1 and (t5 and t6 xor t0 xor t2) xor t6 and t2 xor t7);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 2] + $C4BFE81B;
temp:= (t3 and (t7 and not t5 xor t0 and not t1 xor t4 xor t1 xor t6) xor t0 and (t4 and t5 xor t7 xor t1) xor t5 and t1 xor t6);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 7] + $66282193;
temp:= (t2 and (t6 and not t4 xor t7 and not t0 xor t3 xor t0 xor t5) xor t7 and (t3 and t4 xor t6 xor t0) xor t4 and t0 xor t5);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[28] + $61D809CC;
temp:= (t1 and (t5 and not t3 xor t6 and not t7 xor t2 xor t7 xor t4) xor t6 and (t2 and t3 xor t5 xor t7) xor t3 and t7 xor t4);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[23] + $FB21A991;
temp:= (t0 and (t4 and not t2 xor t5 and not t6 xor t1 xor t6 xor t3) xor t5 and (t1 and t2 xor t4 xor t6) xor t2 and t6 xor t3);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[26] + $487CAC60;
temp:= (t7 and (t3 and not t1 xor t4 and not t5 xor t0 xor t5 xor t2) xor t4 and (t0 and t1 xor t3 xor t5) xor t1 and t5 xor t2);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 6] + $5DEC8032;
temp:= (t6 and (t2 and not t0 xor t3 and not t4 xor t7 xor t4 xor t1) xor t3 and (t7 and t0 xor t2 xor t4) xor t0 and t4 xor t1);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[30] + $EF845D5D;
temp:= (t5 and (t1 and not t7 xor t2 and not t3 xor t6 xor t3 xor t0) xor t2 and (t6 and t7 xor t1 xor t3) xor t7 and t3 xor t0);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[20] + $E98575B1;
temp:= (t4 and (t0 and not t6 xor t1 and not t2 xor t5 xor t2 xor t7) xor t1 and (t5 and t6 xor t0 xor t2) xor t6 and t2 xor t7);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[18] + $DC262302;
temp:= (t3 and (t7 and not t5 xor t0 and not t1 xor t4 xor t1 xor t6) xor t0 and (t4 and t5 xor t7 xor t1) xor t5 and t1 xor t6);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[25] + $EB651B88;
temp:= (t2 and (t6 and not t4 xor t7 and not t0 xor t3 xor t0 xor t5) xor t7 and (t3 and t4 xor t6 xor t0) xor t4 and t0 xor t5);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[19] + $23893E81;
temp:= (t1 and (t5 and not t3 xor t6 and not t7 xor t2 xor t7 xor t4) xor t6 and (t2 and t3 xor t5 xor t7) xor t3 and t7 xor t4);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 3] + $D396ACC5;
temp:= (t0 and (t4 and not t2 xor t5 and not t6 xor t1 xor t6 xor t3) xor t5 and (t1 and t2 xor t4 xor t6) xor t2 and t6 xor t3);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[22] + $0F6D6FF3;
temp:= (t7 and (t3 and not t1 xor t4 and not t5 xor t0 xor t5 xor t2) xor t4 and (t0 and t1 xor t3 xor t5) xor t1 and t5 xor t2);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[11] + $83F44239;
temp:= (t6 and (t2 and not t0 xor t3 and not t4 xor t7 xor t4 xor t1) xor t3 and (t7 and t0 xor t2 xor t4) xor t0 and t4 xor t1);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[31] + $2E0B4482;
temp:= (t5 and (t1 and not t7 xor t2 and not t3 xor t6 xor t3 xor t0) xor t2 and (t6 and t7 xor t1 xor t3) xor t7 and t3 xor t0);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[21] + $A4842004;
temp:= (t4 and (t0 and not t6 xor t1 and not t2 xor t5 xor t2 xor t7) xor t1 and (t5 and t6 xor t0 xor t2) xor t6 and t2 xor t7);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 8] + $69C8F04A;
temp:= (t3 and (t7 and not t5 xor t0 and not t1 xor t4 xor t1 xor t6) xor t0 and (t4 and t5 xor t7 xor t1) xor t5 and t1 xor t6);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[27] + $9E1F9B5E;
temp:= (t2 and (t6 and not t4 xor t7 and not t0 xor t3 xor t0 xor t5) xor t7 and (t3 and t4 xor t6 xor t0) xor t4 and t0 xor t5);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[12] + $21C66842;
temp:= (t1 and (t5 and not t3 xor t6 and not t7 xor t2 xor t7 xor t4) xor t6 and (t2 and t3 xor t5 xor t7) xor t3 and t7 xor t4);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 9] + $F6E96C9A;
temp:= (t0 and (t4 and not t2 xor t5 and not t6 xor t1 xor t6 xor t3) xor t5 and (t1 and t2 xor t4 xor t6) xor t2 and t6 xor t3);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 1] + $670C9C61;
temp:= (t7 and (t3 and not t1 xor t4 and not t5 xor t0 xor t5 xor t2) xor t4 and (t0 and t1 xor t3 xor t5) xor t1 and t5 xor t2);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[29] + $ABD388F0;
temp:= (t6 and (t2 and not t0 xor t3 and not t4 xor t7 xor t4 xor t1) xor t3 and (t7 and t0 xor t2 xor t4) xor t0 and t4 xor t1);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 5] + $6A51A0D2;
temp:= (t5 and (t1 and not t7 xor t2 and not t3 xor t6 xor t3 xor t0) xor t2 and (t6 and t7 xor t1 xor t3) xor t7 and t3 xor t0);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[15] + $D8542F68;
temp:= (t4 and (t0 and not t6 xor t1 and not t2 xor t5 xor t2 xor t7) xor t1 and (t5 and t6 xor t0 xor t2) xor t6 and t2 xor t7);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[17] + $960FA728;
temp:= (t3 and (t7 and not t5 xor t0 and not t1 xor t4 xor t1 xor t6) xor t0 and (t4 and t5 xor t7 xor t1) xor t5 and t1 xor t6);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[10] + $AB5133A3;
temp:= (t2 and (t6 and not t4 xor t7 and not t0 xor t3 xor t0 xor t5) xor t7 and (t3 and t4 xor t6 xor t0) xor t4 and t0 xor t5);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[16] + $6EEF0B6C;
temp:= (t1 and (t5 and not t3 xor t6 and not t7 xor t2 xor t7 xor t4) xor t6 and (t2 and t3 xor t5 xor t7) xor t3 and t7 xor t4);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[13] + $137A3BE4;

View file

@ -1,339 +0,0 @@
temp:= (t2 and (t6 xor t1) xor t5 and t4 xor t0 and t3 xor t6);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 0];
temp:= (t1 and (t5 xor t0) xor t4 and t3 xor t7 and t2 xor t5);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 1];
temp:= (t0 and (t4 xor t7) xor t3 and t2 xor t6 and t1 xor t4);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 2];
temp:= (t7 and (t3 xor t6) xor t2 and t1 xor t5 and t0 xor t3);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 3];
temp:= (t6 and (t2 xor t5) xor t1 and t0 xor t4 and t7 xor t2);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 4];
temp:= (t5 and (t1 xor t4) xor t0 and t7 xor t3 and t6 xor t1);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 5];
temp:= (t4 and (t0 xor t3) xor t7 and t6 xor t2 and t5 xor t0);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 6];
temp:= (t3 and (t7 xor t2) xor t6 and t5 xor t1 and t4 xor t7);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 7];
temp:= (t2 and (t6 xor t1) xor t5 and t4 xor t0 and t3 xor t6);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 8];
temp:= (t1 and (t5 xor t0) xor t4 and t3 xor t7 and t2 xor t5);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9];
temp:= (t0 and (t4 xor t7) xor t3 and t2 xor t6 and t1 xor t4);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[10];
temp:= (t7 and (t3 xor t6) xor t2 and t1 xor t5 and t0 xor t3);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[11];
temp:= (t6 and (t2 xor t5) xor t1 and t0 xor t4 and t7 xor t2);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[12];
temp:= (t5 and (t1 xor t4) xor t0 and t7 xor t3 and t6 xor t1);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[13];
temp:= (t4 and (t0 xor t3) xor t7 and t6 xor t2 and t5 xor t0);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[14];
temp:= (t3 and (t7 xor t2) xor t6 and t5 xor t1 and t4 xor t7);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[15];
temp:= (t2 and (t6 xor t1) xor t5 and t4 xor t0 and t3 xor t6);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[16];
temp:= (t1 and (t5 xor t0) xor t4 and t3 xor t7 and t2 xor t5);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[17];
temp:= (t0 and (t4 xor t7) xor t3 and t2 xor t6 and t1 xor t4);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[18];
temp:= (t7 and (t3 xor t6) xor t2 and t1 xor t5 and t0 xor t3);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[19];
temp:= (t6 and (t2 xor t5) xor t1 and t0 xor t4 and t7 xor t2);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[20];
temp:= (t5 and (t1 xor t4) xor t0 and t7 xor t3 and t6 xor t1);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[21];
temp:= (t4 and (t0 xor t3) xor t7 and t6 xor t2 and t5 xor t0);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[22];
temp:= (t3 and (t7 xor t2) xor t6 and t5 xor t1 and t4 xor t7);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[23];
temp:= (t2 and (t6 xor t1) xor t5 and t4 xor t0 and t3 xor t6);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[24];
temp:= (t1 and (t5 xor t0) xor t4 and t3 xor t7 and t2 xor t5);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[25];
temp:= (t0 and (t4 xor t7) xor t3 and t2 xor t6 and t1 xor t4);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[26];
temp:= (t7 and (t3 xor t6) xor t2 and t1 xor t5 and t0 xor t3);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[27];
temp:= (t6 and (t2 xor t5) xor t1 and t0 xor t4 and t7 xor t2);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[28];
temp:= (t5 and (t1 xor t4) xor t0 and t7 xor t3 and t6 xor t1);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[29];
temp:= (t4 and (t0 xor t3) xor t7 and t6 xor t2 and t5 xor t0);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[30];
temp:= (t3 and (t7 xor t2) xor t6 and t5 xor t1 and t4 xor t7);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[31];
temp:= (t3 and (t4 and not t0 xor t1 and t2 xor t6 xor t5) xor t1 and (t4 xor t2) xor t0 and t2 xor t5);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 5] + $452821E6;
temp:= (t2 and (t3 and not t7 xor t0 and t1 xor t5 xor t4) xor t0 and (t3 xor t1) xor t7 and t1 xor t4);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[14] + $38D01377;
temp:= (t1 and (t2 and not t6 xor t7 and t0 xor t4 xor t3) xor t7 and (t2 xor t0) xor t6 and t0 xor t3);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[26] + $BE5466CF;
temp:= (t0 and (t1 and not t5 xor t6 and t7 xor t3 xor t2) xor t6 and (t1 xor t7) xor t5 and t7 xor t2);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[18] + $34E90C6C;
temp:= (t7 and (t0 and not t4 xor t5 and t6 xor t2 xor t1) xor t5 and (t0 xor t6) xor t4 and t6 xor t1);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[11] + $C0AC29B7;
temp:= (t6 and (t7 and not t3 xor t4 and t5 xor t1 xor t0) xor t4 and (t7 xor t5) xor t3 and t5 xor t0);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[28] + $C97C50DD;
temp:= (t5 and (t6 and not t2 xor t3 and t4 xor t0 xor t7) xor t3 and (t6 xor t4) xor t2 and t4 xor t7);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 7] + $3F84D5B5;
temp:= (t4 and (t5 and not t1 xor t2 and t3 xor t7 xor t6) xor t2 and (t5 xor t3) xor t1 and t3 xor t6);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[16] + $B5470917;
temp:= (t3 and (t4 and not t0 xor t1 and t2 xor t6 xor t5) xor t1 and (t4 xor t2) xor t0 and t2 xor t5);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 0] + $9216D5D9;
temp:= (t2 and (t3 and not t7 xor t0 and t1 xor t5 xor t4) xor t0 and (t3 xor t1) xor t7 and t1 xor t4);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[23] + $8979FB1B;
temp:= (t1 and (t2 and not t6 xor t7 and t0 xor t4 xor t3) xor t7 and (t2 xor t0) xor t6 and t0 xor t3);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[20] + $D1310BA6;
temp:= (t0 and (t1 and not t5 xor t6 and t7 xor t3 xor t2) xor t6 and (t1 xor t7) xor t5 and t7 xor t2);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[22] + $98DFB5AC;
temp:= (t7 and (t0 and not t4 xor t5 and t6 xor t2 xor t1) xor t5 and (t0 xor t6) xor t4 and t6 xor t1);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 1] + $2FFD72DB;
temp:= (t6 and (t7 and not t3 xor t4 and t5 xor t1 xor t0) xor t4 and (t7 xor t5) xor t3 and t5 xor t0);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[10] + $D01ADFB7;
temp:= (t5 and (t6 and not t2 xor t3 and t4 xor t0 xor t7) xor t3 and (t6 xor t4) xor t2 and t4 xor t7);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 4] + $B8E1AFED;
temp:= (t4 and (t5 and not t1 xor t2 and t3 xor t7 xor t6) xor t2 and (t5 xor t3) xor t1 and t3 xor t6);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 8] + $6A267E96;
temp:= (t3 and (t4 and not t0 xor t1 and t2 xor t6 xor t5) xor t1 and (t4 xor t2) xor t0 and t2 xor t5);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[30] + $BA7C9045;
temp:= (t2 and (t3 and not t7 xor t0 and t1 xor t5 xor t4) xor t0 and (t3 xor t1) xor t7 and t1 xor t4);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 3] + $F12C7F99;
temp:= (t1 and (t2 and not t6 xor t7 and t0 xor t4 xor t3) xor t7 and (t2 xor t0) xor t6 and t0 xor t3);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $24A19947;
temp:= (t0 and (t1 and not t5 xor t6 and t7 xor t3 xor t2) xor t6 and (t1 xor t7) xor t5 and t7 xor t2);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 9] + $B3916CF7;
temp:= (t7 and (t0 and not t4 xor t5 and t6 xor t2 xor t1) xor t5 and (t0 xor t6) xor t4 and t6 xor t1);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[17] + $0801F2E2;
temp:= (t6 and (t7 and not t3 xor t4 and t5 xor t1 xor t0) xor t4 and (t7 xor t5) xor t3 and t5 xor t0);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[24] + $858EFC16;
temp:= (t5 and (t6 and not t2 xor t3 and t4 xor t0 xor t7) xor t3 and (t6 xor t4) xor t2 and t4 xor t7);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[29] + $636920D8;
temp:= (t4 and (t5 and not t1 xor t2 and t3 xor t7 xor t6) xor t2 and (t5 xor t3) xor t1 and t3 xor t6);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 6] + $71574E69;
temp:= (t3 and (t4 and not t0 xor t1 and t2 xor t6 xor t5) xor t1 and (t4 xor t2) xor t0 and t2 xor t5);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $A458FEA3;
temp:= (t2 and (t3 and not t7 xor t0 and t1 xor t5 xor t4) xor t0 and (t3 xor t1) xor t7 and t1 xor t4);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[12] + $F4933D7E;
temp:= (t1 and (t2 and not t6 xor t7 and t0 xor t4 xor t3) xor t7 and (t2 xor t0) xor t6 and t0 xor t3);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[15] + $0D95748F;
temp:= (t0 and (t1 and not t5 xor t6 and t7 xor t3 xor t2) xor t6 and (t1 xor t7) xor t5 and t7 xor t2);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[13] + $728EB658;
temp:= (t7 and (t0 and not t4 xor t5 and t6 xor t2 xor t1) xor t5 and (t0 xor t6) xor t4 and t6 xor t1);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 2] + $718BCD58;
temp:= (t6 and (t7 and not t3 xor t4 and t5 xor t1 xor t0) xor t4 and (t7 xor t5) xor t3 and t5 xor t0);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[25] + $82154AEE;
temp:= (t5 and (t6 and not t2 xor t3 and t4 xor t0 xor t7) xor t3 and (t6 xor t4) xor t2 and t4 xor t7);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[31] + $7B54A41D;
temp:= (t4 and (t5 and not t1 xor t2 and t3 xor t7 xor t6) xor t2 and (t5 xor t3) xor t1 and t3 xor t6);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[27] + $C25A59B5;
temp:= (t4 and (t1 and t3 xor t2 xor t5) xor t1 and t0 xor t3 and t6 xor t5);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $9C30D539;
temp:= (t3 and (t0 and t2 xor t1 xor t4) xor t0 and t7 xor t2 and t5 xor t4);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9] + $2AF26013;
temp:= (t2 and (t7 and t1 xor t0 xor t3) xor t7 and t6 xor t1 and t4 xor t3);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 4] + $C5D1B023;
temp:= (t1 and (t6 and t0 xor t7 xor t2) xor t6 and t5 xor t0 and t3 xor t2);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[20] + $286085F0;
temp:= (t0 and (t5 and t7 xor t6 xor t1) xor t5 and t4 xor t7 and t2 xor t1);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[28] + $CA417918;
temp:= (t7 and (t4 and t6 xor t5 xor t0) xor t4 and t3 xor t6 and t1 xor t0);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[17] + $B8DB38EF;
temp:= (t6 and (t3 and t5 xor t4 xor t7) xor t3 and t2 xor t5 and t0 xor t7);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 8] + $8E79DCB0;
temp:= (t5 and (t2 and t4 xor t3 xor t6) xor t2 and t1 xor t4 and t7 xor t6);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[22] + $603A180E;
temp:= (t4 and (t1 and t3 xor t2 xor t5) xor t1 and t0 xor t3 and t6 xor t5);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[29] + $6C9E0E8B;
temp:= (t3 and (t0 and t2 xor t1 xor t4) xor t0 and t7 xor t2 and t5 xor t4);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[14] + $B01E8A3E;
temp:= (t2 and (t7 and t1 xor t0 xor t3) xor t7 and t6 xor t1 and t4 xor t3);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[25] + $D71577C1;
temp:= (t1 and (t6 and t0 xor t7 xor t2) xor t6 and t5 xor t0 and t3 xor t2);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[12] + $BD314B27;
temp:= (t0 and (t5 and t7 xor t6 xor t1) xor t5 and t4 xor t7 and t2 xor t1);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[24] + $78AF2FDA;
temp:= (t7 and (t4 and t6 xor t5 xor t0) xor t4 and t3 xor t6 and t1 xor t0);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[30] + $55605C60;
temp:= (t6 and (t3 and t5 xor t4 xor t7) xor t3 and t2 xor t5 and t0 xor t7);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[16] + $E65525F3;
temp:= (t5 and (t2 and t4 xor t3 xor t6) xor t2 and t1 xor t4 and t7 xor t6);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[26] + $AA55AB94;
temp:= (t4 and (t1 and t3 xor t2 xor t5) xor t1 and t0 xor t3 and t6 xor t5);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[31] + $57489862;
temp:= (t3 and (t0 and t2 xor t1 xor t4) xor t0 and t7 xor t2 and t5 xor t4);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[15] + $63E81440;
temp:= (t2 and (t7 and t1 xor t0 xor t3) xor t7 and t6 xor t1 and t4 xor t3);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 7] + $55CA396A;
temp:= (t1 and (t6 and t0 xor t7 xor t2) xor t6 and t5 xor t0 and t3 xor t2);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 3] + $2AAB10B6;
temp:= (t0 and (t5 and t7 xor t6 xor t1) xor t5 and t4 xor t7 and t2 xor t1);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 1] + $B4CC5C34;
temp:= (t7 and (t4 and t6 xor t5 xor t0) xor t4 and t3 xor t6 and t1 xor t0);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 0] + $1141E8CE;
temp:= (t6 and (t3 and t5 xor t4 xor t7) xor t3 and t2 xor t5 and t0 xor t7);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[18] + $A15486AF;
temp:= (t5 and (t2 and t4 xor t3 xor t6) xor t2 and t1 xor t4 and t7 xor t6);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[27] + $7C72E993;
temp:= (t4 and (t1 and t3 xor t2 xor t5) xor t1 and t0 xor t3 and t6 xor t5);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[13] + $B3EE1411;
temp:= (t3 and (t0 and t2 xor t1 xor t4) xor t0 and t7 xor t2 and t5 xor t4);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 6] + $636FBC2A;
temp:= (t2 and (t7 and t1 xor t0 xor t3) xor t7 and t6 xor t1 and t4 xor t3);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $2BA9C55D;
temp:= (t1 and (t6 and t0 xor t7 xor t2) xor t6 and t5 xor t0 and t3 xor t2);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[10] + $741831F6;
temp:= (t0 and (t5 and t7 xor t6 xor t1) xor t5 and t4 xor t7 and t2 xor t1);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[23] + $CE5C3E16;
temp:= (t7 and (t4 and t6 xor t5 xor t0) xor t4 and t3 xor t6 and t1 xor t0);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[11] + $9B87931E;
temp:= (t6 and (t3 and t5 xor t4 xor t7) xor t3 and t2 xor t5 and t0 xor t7);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[ 5] + $AFD6BA33;
temp:= (t5 and (t2 and t4 xor t3 xor t6) xor t2 and t1 xor t4 and t7 xor t6);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 2] + $6C24CF5C;
temp:= (t3 and (t5 and not t0 xor t2 and not t1 xor t4 xor t1 xor t6) xor t2 and (t4 and t0 xor t5 xor t1) xor t0 and t1 xor t6);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[24] + $7A325381;
temp:= (t2 and (t4 and not t7 xor t1 and not t0 xor t3 xor t0 xor t5) xor t1 and (t3 and t7 xor t4 xor t0) xor t7 and t0 xor t5);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 4] + $28958677;
temp:= (t1 and (t3 and not t6 xor t0 and not t7 xor t2 xor t7 xor t4) xor t0 and (t2 and t6 xor t3 xor t7) xor t6 and t7 xor t4);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 0] + $3B8F4898;
temp:= (t0 and (t2 and not t5 xor t7 and not t6 xor t1 xor t6 xor t3) xor t7 and (t1 and t5 xor t2 xor t6) xor t5 and t6 xor t3);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[14] + $6B4BB9AF;
temp:= (t7 and (t1 and not t4 xor t6 and not t5 xor t0 xor t5 xor t2) xor t6 and (t0 and t4 xor t1 xor t5) xor t4 and t5 xor t2);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 2] + $C4BFE81B;
temp:= (t6 and (t0 and not t3 xor t5 and not t4 xor t7 xor t4 xor t1) xor t5 and (t7 and t3 xor t0 xor t4) xor t3 and t4 xor t1);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 7] + $66282193;
temp:= (t5 and (t7 and not t2 xor t4 and not t3 xor t6 xor t3 xor t0) xor t4 and (t6 and t2 xor t7 xor t3) xor t2 and t3 xor t0);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[28] + $61D809CC;
temp:= (t4 and (t6 and not t1 xor t3 and not t2 xor t5 xor t2 xor t7) xor t3 and (t5 and t1 xor t6 xor t2) xor t1 and t2 xor t7);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[23] + $FB21A991;
temp:= (t3 and (t5 and not t0 xor t2 and not t1 xor t4 xor t1 xor t6) xor t2 and (t4 and t0 xor t5 xor t1) xor t0 and t1 xor t6);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[26] + $487CAC60;
temp:= (t2 and (t4 and not t7 xor t1 and not t0 xor t3 xor t0 xor t5) xor t1 and (t3 and t7 xor t4 xor t0) xor t7 and t0 xor t5);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 6] + $5DEC8032;
temp:= (t1 and (t3 and not t6 xor t0 and not t7 xor t2 xor t7 xor t4) xor t0 and (t2 and t6 xor t3 xor t7) xor t6 and t7 xor t4);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[30] + $EF845D5D;
temp:= (t0 and (t2 and not t5 xor t7 and not t6 xor t1 xor t6 xor t3) xor t7 and (t1 and t5 xor t2 xor t6) xor t5 and t6 xor t3);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[20] + $E98575B1;
temp:= (t7 and (t1 and not t4 xor t6 and not t5 xor t0 xor t5 xor t2) xor t6 and (t0 and t4 xor t1 xor t5) xor t4 and t5 xor t2);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[18] + $DC262302;
temp:= (t6 and (t0 and not t3 xor t5 and not t4 xor t7 xor t4 xor t1) xor t5 and (t7 and t3 xor t0 xor t4) xor t3 and t4 xor t1);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[25] + $EB651B88;
temp:= (t5 and (t7 and not t2 xor t4 and not t3 xor t6 xor t3 xor t0) xor t4 and (t6 and t2 xor t7 xor t3) xor t2 and t3 xor t0);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[19] + $23893E81;
temp:= (t4 and (t6 and not t1 xor t3 and not t2 xor t5 xor t2 xor t7) xor t3 and (t5 and t1 xor t6 xor t2) xor t1 and t2 xor t7);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 3] + $D396ACC5;
temp:= (t3 and (t5 and not t0 xor t2 and not t1 xor t4 xor t1 xor t6) xor t2 and (t4 and t0 xor t5 xor t1) xor t0 and t1 xor t6);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[22] + $0F6D6FF3;
temp:= (t2 and (t4 and not t7 xor t1 and not t0 xor t3 xor t0 xor t5) xor t1 and (t3 and t7 xor t4 xor t0) xor t7 and t0 xor t5);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[11] + $83F44239;
temp:= (t1 and (t3 and not t6 xor t0 and not t7 xor t2 xor t7 xor t4) xor t0 and (t2 and t6 xor t3 xor t7) xor t6 and t7 xor t4);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[31] + $2E0B4482;
temp:= (t0 and (t2 and not t5 xor t7 and not t6 xor t1 xor t6 xor t3) xor t7 and (t1 and t5 xor t2 xor t6) xor t5 and t6 xor t3);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[21] + $A4842004;
temp:= (t7 and (t1 and not t4 xor t6 and not t5 xor t0 xor t5 xor t2) xor t6 and (t0 and t4 xor t1 xor t5) xor t4 and t5 xor t2);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 8] + $69C8F04A;
temp:= (t6 and (t0 and not t3 xor t5 and not t4 xor t7 xor t4 xor t1) xor t5 and (t7 and t3 xor t0 xor t4) xor t3 and t4 xor t1);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[27] + $9E1F9B5E;
temp:= (t5 and (t7 and not t2 xor t4 and not t3 xor t6 xor t3 xor t0) xor t4 and (t6 and t2 xor t7 xor t3) xor t2 and t3 xor t0);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[12] + $21C66842;
temp:= (t4 and (t6 and not t1 xor t3 and not t2 xor t5 xor t2 xor t7) xor t3 and (t5 and t1 xor t6 xor t2) xor t1 and t2 xor t7);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[ 9] + $F6E96C9A;
temp:= (t3 and (t5 and not t0 xor t2 and not t1 xor t4 xor t1 xor t6) xor t2 and (t4 and t0 xor t5 xor t1) xor t0 and t1 xor t6);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 1] + $670C9C61;
temp:= (t2 and (t4 and not t7 xor t1 and not t0 xor t3 xor t0 xor t5) xor t1 and (t3 and t7 xor t4 xor t0) xor t7 and t0 xor t5);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[29] + $ABD388F0;
temp:= (t1 and (t3 and not t6 xor t0 and not t7 xor t2 xor t7 xor t4) xor t0 and (t2 and t6 xor t3 xor t7) xor t6 and t7 xor t4);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[ 5] + $6A51A0D2;
temp:= (t0 and (t2 and not t5 xor t7 and not t6 xor t1 xor t6 xor t3) xor t7 and (t1 and t5 xor t2 xor t6) xor t5 and t6 xor t3);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[15] + $D8542F68;
temp:= (t7 and (t1 and not t4 xor t6 and not t5 xor t0 xor t5 xor t2) xor t6 and (t0 and t4 xor t1 xor t5) xor t4 and t5 xor t2);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[17] + $960FA728;
temp:= (t6 and (t0 and not t3 xor t5 and not t4 xor t7 xor t4 xor t1) xor t5 and (t7 and t3 xor t0 xor t4) xor t3 and t4 xor t1);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[10] + $AB5133A3;
temp:= (t5 and (t7 and not t2 xor t4 and not t3 xor t6 xor t3 xor t0) xor t4 and (t6 and t2 xor t7 xor t3) xor t2 and t3 xor t0);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[16] + $6EEF0B6C;
temp:= (t4 and (t6 and not t1 xor t3 and not t2 xor t5 xor t2 xor t7) xor t3 and (t5 and t1 xor t6 xor t2) xor t1 and t2 xor t7);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[13] + $137A3BE4;
temp:= (t1 and (t3 and t4 and t6 xor not t5) xor t3 and t0 xor t4 and t5 xor t6 and t2);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[27] + $BA3BF050;
temp:= (t0 and (t2 and t3 and t5 xor not t4) xor t2 and t7 xor t3 and t4 xor t5 and t1);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 3] + $7EFB2A98;
temp:= (t7 and (t1 and t2 and t4 xor not t3) xor t1 and t6 xor t2 and t3 xor t4 and t0);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[21] + $A1F1651D;
temp:= (t6 and (t0 and t1 and t3 xor not t2) xor t0 and t5 xor t1 and t2 xor t3 and t7);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[26] + $39AF0176;
temp:= (t5 and (t7 and t0 and t2 xor not t1) xor t7 and t4 xor t0 and t1 xor t2 and t6);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[17] + $66CA593E;
temp:= (t4 and (t6 and t7 and t1 xor not t0) xor t6 and t3 xor t7 and t0 xor t1 and t5);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[11] + $82430E88;
temp:= (t3 and (t5 and t6 and t0 xor not t7) xor t5 and t2 xor t6 and t7 xor t0 and t4);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[20] + $8CEE8619;
temp:= (t2 and (t4 and t5 and t7 xor not t6) xor t4 and t1 xor t5 and t6 xor t7 and t3);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[29] + $456F9FB4;
temp:= (t1 and (t3 and t4 and t6 xor not t5) xor t3 and t0 xor t4 and t5 xor t6 and t2);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[19] + $7D84A5C3;
temp:= (t0 and (t2 and t3 and t5 xor not t4) xor t2 and t7 xor t3 and t4 xor t5 and t1);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 0] + $3B8B5EBE;
temp:= (t7 and (t1 and t2 and t4 xor not t3) xor t1 and t6 xor t2 and t3 xor t4 and t0);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[12] + $E06F75D8;
temp:= (t6 and (t0 and t1 and t3 xor not t2) xor t0 and t5 xor t1 and t2 xor t3 and t7);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[ 7] + $85C12073;
temp:= (t5 and (t7 and t0 and t2 xor not t1) xor t7 and t4 xor t0 and t1 xor t2 and t6);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[13] + $401A449F;
temp:= (t4 and (t6 and t7 and t1 xor not t0) xor t6 and t3 xor t7 and t0 xor t1 and t5);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 8] + $56C16AA6;
temp:= (t3 and (t5 and t6 and t0 xor not t7) xor t5 and t2 xor t6 and t7 xor t0 and t4);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[31] + $4ED3AA62;
temp:= (t2 and (t4 and t5 and t7 xor not t6) xor t4 and t1 xor t5 and t6 xor t7 and t3);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[10] + $363F7706;
temp:= (t1 and (t3 and t4 and t6 xor not t5) xor t3 and t0 xor t4 and t5 xor t6 and t2);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 5] + $1BFEDF72;
temp:= (t0 and (t2 and t3 and t5 xor not t4) xor t2 and t7 xor t3 and t4 xor t5 and t1);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[ 9] + $429B023D;
temp:= (t7 and (t1 and t2 and t4 xor not t3) xor t1 and t6 xor t2 and t3 xor t4 and t0);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[14] + $37D0D724;
temp:= (t6 and (t0 and t1 and t3 xor not t2) xor t0 and t5 xor t1 and t2 xor t3 and t7);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[30] + $D00A1248;
temp:= (t5 and (t7 and t0 and t2 xor not t1) xor t7 and t4 xor t0 and t1 xor t2 and t6);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[18] + $DB0FEAD3;
temp:= (t4 and (t6 and t7 and t1 xor not t0) xor t6 and t3 xor t7 and t0 xor t1 and t5);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 6] + $49F1C09B;
temp:= (t3 and (t5 and t6 and t0 xor not t7) xor t5 and t2 xor t6 and t7 xor t0 and t4);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[28] + $075372C9;
temp:= (t2 and (t4 and t5 and t7 xor not t6) xor t4 and t1 xor t5 and t6 xor t7 and t3);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[24] + $80991B7B;
temp:= (t1 and (t3 and t4 and t6 xor not t5) xor t3 and t0 xor t4 and t5 xor t6 and t2);
t7:= ((temp shr 7) or (temp shl 25)) + ((t7 shr 11) or (t7 shl 21)) + w[ 2] + $25D479D8;
temp:= (t0 and (t2 and t3 and t5 xor not t4) xor t2 and t7 xor t3 and t4 xor t5 and t1);
t6:= ((temp shr 7) or (temp shl 25)) + ((t6 shr 11) or (t6 shl 21)) + w[23] + $F6E8DEF7;
temp:= (t7 and (t1 and t2 and t4 xor not t3) xor t1 and t6 xor t2 and t3 xor t4 and t0);
t5:= ((temp shr 7) or (temp shl 25)) + ((t5 shr 11) or (t5 shl 21)) + w[16] + $E3FE501A;
temp:= (t6 and (t0 and t1 and t3 xor not t2) xor t0 and t5 xor t1 and t2 xor t3 and t7);
t4:= ((temp shr 7) or (temp shl 25)) + ((t4 shr 11) or (t4 shl 21)) + w[22] + $B6794C3B;
temp:= (t5 and (t7 and t0 and t2 xor not t1) xor t7 and t4 xor t0 and t1 xor t2 and t6);
t3:= ((temp shr 7) or (temp shl 25)) + ((t3 shr 11) or (t3 shl 21)) + w[ 4] + $976CE0BD;
temp:= (t4 and (t6 and t7 and t1 xor not t0) xor t6 and t3 xor t7 and t0 xor t1 and t5);
t2:= ((temp shr 7) or (temp shl 25)) + ((t2 shr 11) or (t2 shl 21)) + w[ 1] + $04C006BA;
temp:= (t3 and (t5 and t6 and t0 xor not t7) xor t5 and t2 xor t6 and t7 xor t0 and t4);
t1:= ((temp shr 7) or (temp shl 25)) + ((t1 shr 11) or (t1 shl 21)) + w[25] + $C1A94FB6;
temp:= (t2 and (t4 and t5 and t7 xor not t6) xor t4 and t1 xor t5 and t6 xor t7 and t3);
t0:= ((temp shr 7) or (temp shl 25)) + ((t0 shr 11) or (t0 shl 21)) + w[15] + $409F60C4;

View file

@ -1,503 +0,0 @@
{******************************************************************************}
{* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
{******************************************************************************}
{* A binary compatible implementation of Haval ********************************}
{******************************************************************************}
{* Copyright (c) 1999-2002 David Barton *}
{* Permission is hereby granted, free of charge, to any person obtaining a *}
{* copy of this software and associated documentation files (the "Software"), *}
{* to deal in the Software without restriction, including without limitation *}
{* the rights to use, copy, modify, merge, publish, distribute, sublicense, *}
{* and/or sell copies of the Software, and to permit persons to whom the *}
{* Software is furnished to do so, subject to the following conditions: *}
{* *}
{* The above copyright notice and this permission notice shall be included in *}
{* all copies or substantial portions of the Software. *}
{* *}
{* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *}
{* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *}
{* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *}
{* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *}
{* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *}
{* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *}
{* DEALINGS IN THE SOFTWARE. *}
{******************************************************************************}
unit DCPhaval;
{$MODE Delphi}
interface
uses
Classes, Sysutils, DCPcrypt2, DCPconst;
type
TDCP_haval= class(TDCP_hash)
protected
LenHi, LenLo: longword;
Index: DWord;
CurrentHash: array[0..7] of DWord;
HashBuffer: array[0..127] of byte;
procedure Compress;
public
class function GetId: integer; override;
class function GetAlgorithm: string; override;
class function GetHashSize: integer; override;
class function SelfTest: boolean; override;
procedure Init; override;
procedure Burn; override;
procedure Update(const Buffer; Size: longword); override;
procedure Final(var Digest); override;
end;
{ Choose how many passes (previous versions of DCPcrypt uses 5 passes) }
{ ONLY UNCOMMENT ONE! }
//{$DEFINE PASS3}
//{$DEFINE PASS4}
{$DEFINE PASS5}
{ Choose digest length (previous versions of DCPcrypt uses 256bits) }
{ ONLY UNCOMMENT ONE! }
//{$DEFINE DIGEST128}
//{$DEFINE DIGEST160}
//{$DEFINE DIGEST192}
//{$DEFINE DIGEST224}
{$DEFINE DIGEST256}
{******************************************************************************}
{******************************************************************************}
implementation
{$R-}{$Q-}
procedure TDCP_haval.Compress;
var
t7, t6, t5, t4, t3, t2, t1, t0: DWord;
W: array[0..31] of DWord;
Temp: dword;
begin
dcpFillChar(W, SizeOf(W), 0);
t0:= CurrentHash[0];
t1:= CurrentHash[1];
t2:= CurrentHash[2];
t3:= CurrentHash[3];
t4:= CurrentHash[4];
t5:= CurrentHash[5];
t6:= CurrentHash[6];
t7:= CurrentHash[7];
Move(HashBuffer,W,Sizeof(W));
{$IFDEF PASS3}
{$INCLUDE DCPhaval3.inc}
{$ELSE}
{$IFDEF PASS4}
{$INCLUDE DCPhaval4.inc}
{$ELSE}
{$INCLUDE DCPhaval5.inc}
{$ENDIF}
{$ENDIF}
Inc(CurrentHash[0],t0);
Inc(CurrentHash[1],t1);
Inc(CurrentHash[2],t2);
Inc(CurrentHash[3],t3);
Inc(CurrentHash[4],t4);
Inc(CurrentHash[5],t5);
Inc(CurrentHash[6],t6);
Inc(CurrentHash[7],t7);
FillChar(W,Sizeof(W),0);
Index:= 0;
FillChar(HashBuffer,Sizeof(HashBuffer),0);
end;
class function TDCP_haval.GetHashSize: integer;
begin
{$IFDEF DIGEST128}
Result:= 128;
{$ELSE}
{$IFDEF DIGEST160}
Result:= 160;
{$ELSE}
{$IFDEF DIGEST192}
Result:= 192;
{$ELSE}
{$IFDEF DIGEST224}
Result:= 224;
{$ELSE}
Result:= 256;
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
end;
class function TDCP_haval.GetId: integer;
begin
Result:= DCP_haval;
end;
class function TDCP_haval.GetAlgorithm: string;
begin
Result:= 'Haval (';
{$IFDEF DIGEST128}
Result:= Result+'128bit, ';
{$ELSE}
{$IFDEF DIGEST160}
Result:= Result+'160bit, ';
{$ELSE}
{$IFDEF DIGEST192}
Result:= Result+'192bit, ';
{$ELSE}
{$IFDEF DIGEST224}
Result:= Result+'224bit, ';
{$ELSE}
Result:= Result+'256bit, ';
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$IFDEF PASS3}
Result:= Result+'3 passes)';
{$ELSE}
{$IFDEF PASS4}
Result:= Result+'4 passes)';
{$ELSE}
Result:= Result+'5 passes)';
{$ENDIF}
{$ENDIF}
end;
class function TDCP_haval.SelfTest: boolean;
{$IFDEF PASS3}
{$IFDEF DIGEST128}
const
Test1Out: array[0..15] of byte=
($1B,$DC,$55,$6B,$29,$AD,$02,$EC,$09,$AF,$8C,$66,$47,$7F,$2A,$87);
var
TestHash: TDCP_haval;
TestOut: array[0..15] of byte;
begin
TestHash:= TDCP_haval.Create(nil);
TestHash.Init;
TestHash.UpdateStr('');
TestHash.Final(TestOut);
Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out));
TestHash.Free;
{$ELSE}
{$IFDEF DIGEST160}
const
Test1Out: array[0..19] of byte=
($5E,$16,$10,$FC,$ED,$1D,$3A,$DB,$0B,$B1,
$8E,$92,$AC,$2B,$11,$F0,$BD,$99,$D8,$ED);
var
TestHash: TDCP_haval;
TestOut: array[0..19] of byte;
begin
TestHash:= TDCP_haval.Create(nil);
TestHash.Init;
TestHash.UpdateStr('a');
TestHash.Final(TestOut);
Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out));
TestHash.Free;
{$ELSE}
begin
Result:= true;
{$ENDIF}
{$ENDIF}
{$ELSE}
{$IFDEF PASS4}
{$IFDEF DIGEST192}
const
Test1Out: array[0..23] of byte=
($74,$AA,$31,$18,$2F,$F0,$9B,$CC,$E4,$53,$A7,$F7,
$1B,$5A,$7C,$5E,$80,$87,$2F,$A9,$0C,$D9,$3A,$E4);
var
TestHash: TDCP_haval;
TestOut: array[0..23] of byte;
begin
TestHash:= TDCP_haval.Create(nil);
TestHash.Init;
TestHash.UpdateStr('HAVAL');
TestHash.Final(TestOut);
Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out));
TestHash.Free;
{$ELSE}
{$IFDEF DIGEST224}
const
Test1Out: array[0..27] of byte=
($14,$4C,$B2,$DE,$11,$F0,$5D,$F7,$C3,$56,$28,$2A,$3B,$48,
$57,$96,$DA,$65,$3F,$6B,$70,$28,$68,$C7,$DC,$F4,$AE,$76);
var
TestHash: TDCP_haval;
TestOut: array[0..27] of byte;
begin
TestHash:= TDCP_haval.Create(nil);
TestHash.Init;
TestHash.UpdateStr('0123456789');
TestHash.Final(TestOut);
Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out));
TestHash.Free;
{$ELSE}
begin
Result:= true;
{$ENDIF}
{$ENDIF}
{$ELSE}
{$IFDEF DIGEST256}
const
Test1Out: array[0..31] of byte=
($1A,$1D,$C8,$09,$9B,$DA,$A7,$F3,$5B,$4D,$A4,$E8,$05,$F1,$A2,$8F,
$EE,$90,$9D,$8D,$EE,$92,$01,$98,$18,$5C,$BC,$AE,$D8,$A1,$0A,$8D);
Test2Out: array[0..31] of byte=
($C5,$64,$7F,$C6,$C1,$87,$7F,$FF,$96,$74,$2F,$27,$E9,$26,$6B,$68,
$74,$89,$4F,$41,$A0,$8F,$59,$13,$03,$3D,$9D,$53,$2A,$ED,$DB,$39);
var
TestHash: TDCP_haval;
TestOut: array[0..31] of byte;
begin
dcpFillChar(TestOut, SizeOf(TestOut), 0);
TestHash:= TDCP_haval.Create(nil);
TestHash.Init;
TestHash.UpdateStr('abcdefghijklmnopqrstuvwxyz');
TestHash.Final(TestOut);
Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out));
TestHash.Init;
TestHash.UpdateStr('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');
TestHash.Final(TestOut);
Result:= CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out)) and Result;
TestHash.Free;
{$ELSE}
begin
Result:= true;
{$ENDIF}
{$ENDIF}
{$ENDIF}
end;
procedure TDCP_haval.Init;
begin
Burn;
CurrentHash[0]:= $243F6A88;
CurrentHash[1]:= $85A308D3;
CurrentHash[2]:= $13198A2E;
CurrentHash[3]:= $03707344;
CurrentHash[4]:= $A4093822;
CurrentHash[5]:= $299F31D0;
CurrentHash[6]:= $082EFA98;
CurrentHash[7]:= $EC4E6C89;
fInitialized:= true;
end;
procedure TDCP_haval.Burn;
begin
LenHi:= 0; LenLo:= 0;
Index:= 0;
FillChar(HashBuffer,Sizeof(HashBuffer),0);
FillChar(CurrentHash,Sizeof(CurrentHash),0);
fInitialized:= false;
end;
procedure TDCP_haval.Update(const Buffer; Size: longword);
var
PBuf: ^byte;
begin
if not fInitialized then
raise EDCP_hash.Create('Hash not initialized');
Inc(LenHi,Size shr 29);
Inc(LenLo,Size*8);
if LenLo< (Size*8) then
Inc(LenHi);
PBuf:= @Buffer;
while Size> 0 do
begin
if (Sizeof(HashBuffer)-Index)<= DWord(Size) then
begin
Move(PBuf^,HashBuffer[Index],Sizeof(HashBuffer)-Index);
Dec(Size,Sizeof(HashBuffer)-Index);
Inc(PBuf,Sizeof(HashBuffer)-Index);
Compress;
end
else
begin
Move(PBuf^,HashBuffer[Index],Size);
Inc(Index,Size);
Size:= 0;
end;
end;
end;
procedure TDCP_haval.Final(var Digest);
{$IFNDEF DIGEST256}
{$IFNDEF DIGEST224}
var
temp: dword;
{$ENDIF}
{$ENDIF}
begin
if not fInitialized then
raise EDCP_hash.Create('Hash not initialized');
HashBuffer[Index]:= $80;
if Index>= 118 then
Compress;
{$IFDEF PASS3}
{$IFDEF DIGEST128}
HashBuffer[118]:= ((128 and 3) shl 6) or (3 shl 3) or 1;
HashBuffer[119]:= (128 shr 2) and $FF;
{$ELSE}
{$IFDEF DIGEST160}
HashBuffer[118]:= ((160 and 3) shl 6) or (3 shl 3) or 1;
HashBuffer[119]:= (160 shr 2) and $FF;
{$ELSE}
{$IFDEF DIGEST192}
HashBuffer[118]:= ((192 and 3) shl 6) or (3 shl 3) or 1;
HashBuffer[119]:= (192 shr 2) and $FF;
{$ELSE}
{$IFDEF DIGEST224}
HashBuffer[118]:= ((224 and 3) shl 6) or (3 shl 3) or 1;
HashBuffer[119]:= (224 shr 2) and $FF;
{$ELSE}
HashBuffer[118]:= ((256 and 3) shl 6) or (3 shl 3) or 1;
HashBuffer[119]:= (256 shr 2) and $FF;
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ELSE}
{$IFDEF PASS4}
{$IFDEF DIGEST128}
HashBuffer[118]:= ((128 and 3) shl 6) or (4 shl 3) or 1;
HashBuffer[119]:= (128 shr 2) and $FF;
{$ELSE}
{$IFDEF DIGEST160}
HashBuffer[118]:= ((160 and 3) shl 6) or (4 shl 3) or 1;
HashBuffer[119]:= (160 shr 2) and $FF;
{$ELSE}
{$IFDEF DIGEST192}
HashBuffer[118]:= ((192 and 3) shl 6) or (4 shl 3) or 1;
HashBuffer[119]:= (192 shr 2) and $FF;
{$ELSE}
{$IFDEF DIGEST224}
HashBuffer[118]:= ((224 and 3) shl 6) or (4 shl 3) or 1;
HashBuffer[119]:= (224 shr 2) and $FF;
{$ELSE}
HashBuffer[118]:= ((256 and 3) shl 6) or (4 shl 3) or 1;
HashBuffer[119]:= (256 shr 2) and $FF;
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ELSE}
{$IFDEF DIGEST128}
HashBuffer[118]:= ((128 and 3) shl 6) or (5 shl 3) or 1;
HashBuffer[119]:= (2128 shr 2) and $FF;
{$ELSE}
{$IFDEF DIGEST160}
HashBuffer[118]:= ((160 and 3) shl 6) or (5 shl 3) or 1;
HashBuffer[119]:= (160 shr 2) and $FF;
{$ELSE}
{$IFDEF DIGEST192}
HashBuffer[118]:= ((192 and 3) shl 6) or (5 shl 3) or 1;
HashBuffer[119]:= (192 shr 2) and $FF;
{$ELSE}
{$IFDEF DIGEST224}
HashBuffer[118]:= ((224 and 3) shl 6) or (5 shl 3) or 1;
HashBuffer[119]:= (224 shr 2) and $FF;
{$ELSE}
HashBuffer[118]:= ((256 and 3) shl 6) or (5 shl 3) or 1;
HashBuffer[119]:= (256 shr 2) and $FF;
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
PDWord(@HashBuffer[120])^:= LenLo;
PDWord(@HashBuffer[124])^:= LenHi;
Compress;
{$IFDEF DIGEST128}
temp:= (CurrentHash[7] and $000000FF) or
(CurrentHash[6] and $FF000000) or
(CurrentHash[5] and $00FF0000) or
(CurrentHash[4] and $0000FF00);
Inc(CurrentHash[0],(temp shr 8) or (temp shl 24));
temp:= (CurrentHash[7] and $0000FF00) or
(CurrentHash[6] and $000000FF) or
(CurrentHash[5] and $FF000000) or
(CurrentHash[4] and $00FF0000);
Inc(CurrentHash[1],(temp shr 16) or (temp shl 16));
temp:= (CurrentHash[7] and $00FF0000) or
(CurrentHash[6] and $0000FF00) or
(CurrentHash[5] and $000000FF) or
(CurrentHash[4] and $FF000000);
Inc(CurrentHash[2],(temp shr 24) or (temp shl 8));
temp:= (CurrentHash[7] and $FF000000) or
(CurrentHash[6] and $00FF0000) or
(CurrentHash[5] and $0000FF00) or
(CurrentHash[4] and $000000FF);
Inc(CurrentHash[3],temp);
Move(CurrentHash,Digest,128 div 8);
{$ELSE}
{$IFDEF DIGEST160}
temp:= (CurrentHash[7] and $3F) or
(CurrentHash[6] and ($7F shl 25)) or
(CurrentHash[5] and ($3F shl 19));
Inc(CurrentHash[0],(temp shr 19) or (temp shl 13));
temp:= (CurrentHash[7] and ($3F shl 6)) or
(CurrentHash[6] and $3F) or
(CurrentHash[5] and ($7F shl 25));
Inc(CurrentHash[1],(temp shr 25) or (temp shl 7));
temp:= (CurrentHash[7] and ($7F shl 12)) or
(CurrentHash[6] and ($3F shl 6)) or
(CurrentHash[5] and $3F);
Inc(CurrentHash[2],temp);
temp:= (CurrentHash[7] and ($3F shl 19)) or
(CurrentHash[6] and ($7F shl 12)) or
(CurrentHash[5] and ($3F shl 6));
Inc(CurrentHash[3],temp shr 6);
temp:= (CurrentHash[7] and ($7F shl 25)) or
(CurrentHash[6] and ($3F shl 19)) or
(CurrentHash[5] and ($7F shl 12));
Inc(CurrentHash[4],temp shr 12);
Move(CurrentHash,Digest,160 div 8);
{$ELSE}
{$IFDEF DIGEST192}
temp:= (CurrentHash[7] and $1F) or
(CurrentHash[6] and ($3F shl 26));
Inc(CurrentHash[0],(temp shr 26) or (temp shl 6));
temp:= (CurrentHash[7] and ($1F shl 5)) or
(CurrentHash[6] and $1F);
Inc(CurrentHash[1],temp);
temp:= (CurrentHash[7] and ($3F shl 10)) or
(CurrentHash[6] and ($1F shl 5));
Inc(CurrentHash[2],temp shr 5);
temp:= (CurrentHash[7] and ($1F shl 16)) or
(CurrentHash[6] and ($3F shl 10));
Inc(CurrentHash[3],temp shr 10);
temp:= (CurrentHash[7] and ($1F shl 21)) or
(CurrentHash[6] and ($1F shl 16));
Inc(CurrentHash[4],temp shr 16);
temp:= (CurrentHash[7] and ($3F shl 26)) or
(CurrentHash[6] and ($1F shl 21));
Inc(CurrentHash[5],temp shr 21);
Move(CurrentHash,Digest,192 div 8);
{$ELSE}
{$IFDEF DIGEST224}
Inc(CurrentHash[0],(CurrentHash[7] shr 27) and $1F);
Inc(CurrentHash[1],(CurrentHash[7] shr 22) and $1F);
Inc(CurrentHash[2],(CurrentHash[7] shr 18) and $F);
Inc(CurrentHash[3],(CurrentHash[7] shr 13) and $1F);
Inc(CurrentHash[4],(CurrentHash[7] shr 9) and $F);
Inc(CurrentHash[5],(CurrentHash[7] shr 4) and $1F);
Inc(CurrentHash[6],CurrentHash[7] and $F);
Move(CurrentHash,Digest,224 div 8);
{$ELSE}
Move(CurrentHash,Digest,256 div 8);
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
Burn;
end;
end.

View file

@ -1,130 +0,0 @@
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
= DCPcrypt Cryptographic Component Library v2 Beta 3 =
= Copyright (c) 1999-2003 David Barton =
= http://www.cityinthesky.co.uk/ =
= crypto@cityinthesky.co.uk =
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Introduction:
DCPcrypt is a collection of cryptographic components for the Borland
Delphi(tm), C++ Builder(tm) and Kylix(tm) programming languages. The
supported versions are Delphi 4, 5, 6, 7, 2005, C++ Builder (3?), 4,
5, (6?) and Kylix 1 (untested), 2 and 3 (untested).
Thanks to Manuel C. for the modifications to make DCPcrypt work under
Delphi 2005!
The idea behind DCPcrypt is that it should be possible to "drop in"
any algorithm implementation to replace another with minimum or no
code changes. To aid in this goal all cryptographic components are
descended from one of several base classes, TDCP_cipher for encryption
algorithms and TDCP_hash for message digest algorithms.
DCPcrypt is open source software (released under the MIT license) and
as such there is no charge for inclusion in other software. However, I
am currently a student and if you are making money from my software I
would really appreciate a donation of some sort, whether financial or
a license for the software you develop (or if anyone wants to sponsor
a Mathematical Modelling (Masters) student for their final year...).
Please note THIS IS NOT COMPULSORY IN ANY WAY. See
http://www.cityinthesky.co.uk/cryptography.html for details on
financial donations.
This software is OSI Certified Open Source Software.
OSI Certified is a certification mark of the Open Source Initiative.
If you maintain a website then a link to my page at
http://www.cityinthesky.co.uk/ would be great!
What's New:
Changes since DCPcrypt v2 Beta 2 include
* Corrected C++ Builder compilation problem.
Changes since DCPcrypt v2 Beta 1 include
* Renamed source code files for hashes and ciphers to DCPxxx.pas
* Change the format of Cipher.InitStr so that the hash algorithm
used to generate the key is explicitly specified. In order to
get the same functionality as before, use TDCP_sha1.
e.g. Cipher.InitStr('Hello World',TDCP_sha1);
* Block ciphers are now inherited from an intermediate component
that implements the block size specific chaining mode encryption
routines.
* Remove the internal component registration, it was more hassle
than it was worth. If there is a demand for this to be put back
then I might...
* Added the full range of operation modes for Haval. By changing
the defines at the top of DCPhaval.pas you can specify the
number of passes and the output hash size.
* Added the Tiger hash algorithm (192bit digest).
* Changed the name of the file containing TDCP_ripemd160 for
consistency to DCPripemd160 from DCPrmd160.
* GOST no longer appears on the component palette pending verifying
what the actual standard is (the code is still included however).
* Added the RipeMD-128 hash algorithm (128bit digest).
* Added the Serpent block cipher (AES finalist).
* Added the SHA-256,384,512 hash algorithms (256, 384, 512bit digest
respectively).
* Added CTR chaining mode to all block ciphers.
Installation:
Delphi: Open the appropriate package, DCPdelphiX.dpk where X is
your version of Delphi (either 4, 5 or 6). Then press the
install button.
C++ Builder: Create a new design time package and add all the .pas
files from the DCPcrypt2.zip archive including all those
in the Ciphers and Hashes subdirectories. Then press the
install button.
Kylix: Open the DCPkylix.dpk package and then press the install
button (note: Kylix 1 users may need to create a new
package as with C++ Builder as this is a Kylix 2 package).
You may need to add the directory containing DCPcrypt (and the Ciphers
and Hashes subdirectories) to your library search path (found under
Environment Options).
Once installed you will find two extra pages of components on your
component palette, namely DCPciphers and DCPhashes. You can now place
these components onto the form of your application to start using the
algorithms.
Usage:
See the main html documentation in the Docs subdirectory.
Contact:
I appreciate knowing what DCPcrypt is being used for and also if you
have any queries or bug reports please email me at crypto@cityinthesky.co.uk.
DCPcrypt is copyrighted (c) 1999-2003 David Barton.
All trademarks are property of their respective owners.

View file

@ -35,12 +35,13 @@ type
TWinFileTime = QWord; // NTFS time (UTC) (2 x DWORD)
TDosFileTime = LongInt; // MS-DOS time (local)
TUnixFileTime = Int64; // UNIX time (UTC)
{$IFDEF MSWINDOWS}
TFileTime = TWinFileTime;
TFileTimeEx = TFileTime;
{$ELSE}
TFileTime = Int64;
TFileTime = TUnixFileTime;
TFileTimeEx = record
public
@ -52,8 +53,6 @@ type
end;
{$ENDIF}
TUnixFileTime = TFileTime;
PFileTime = ^TFileTime;
PWinFileTime = ^TWinFileTime;
@ -63,10 +62,17 @@ const
implementation
{$IF not DEFINED(MSWINDOWS)}
constructor TFileTimeEx.create( aSec:int64; aNanosec:int64 );
constructor TFileTimeEx.Create(aSec: Int64; aNanosec: Int64);
begin
self.sec:= aSec;
self.nanosec:= aNanosec;
Self.sec:= aSec;
Self.nanosec:= aNanosec;
if Self.nanosec < 0 then
Self.nanosec := 0
else if Self.nanosec > 999999999 then
begin
Self.nanosec := 999999999;
end;
end;
class operator TFileTimeEx.=(l,r : TFileTimeEx): Boolean;

View file

@ -3,7 +3,7 @@
-------------------------------------------------------------------------
This module contains classes with UTF8 file names support.
Copyright (C) 2008-2022 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2008-2024 Alexander Koblov (alexx2000@mail.ru)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -42,7 +42,7 @@ type
protected
FFileName: String;
procedure Sync(AWritten: Int64);
procedure SetSize64(const NewSize: Int64); override;
procedure SetCapacity(const NewCapacity: Int64);
public
constructor Create(const AFileName: String; Mode: LongWord); virtual; overload;
destructor Destroy; override;
@ -51,6 +51,7 @@ type
function Write(const Buffer; Count: LongInt): LongInt; override;
property DirtyLimit: Int64 read FDirtyLimit write FDirtyLimit;
property AutoSync: Boolean read FAutoSync write SetAutoSync;
property Capacity: Int64 write SetCapacity;
property FileName: String read FFileName;
end;
@ -71,8 +72,8 @@ type
private
FReadOnly: Boolean;
public
constructor Create(const AFileName: String; Mode: Word); virtual;
constructor Create(const AFileName: String; AEscapeLineFeeds : Boolean = False); override;
constructor Create(const AFileName: String; Mode: Word; AOptions: TIniFileOptions = []); virtual;
constructor Create(const AFileName: String; AOptions: TIniFileOptions = []); override;
procedure UpdateFile; override;
public
property ReadOnly: Boolean read FReadOnly;
@ -156,9 +157,9 @@ begin
end;
end;
procedure TFileStreamEx.SetSize64(const NewSize: Int64);
procedure TFileStreamEx.SetCapacity(const NewCapacity: Int64);
begin
FileAllocate(Handle, NewSize);
FileAllocate(Handle, NewCapacity);
end;
constructor TFileStreamEx.Create(const AFileName: String; Mode: LongWord);
@ -169,7 +170,7 @@ begin
begin
AHandle:= mbFileCreate(AFileName, Mode);
if AHandle = feInvalidHandle then
raise EFCreateError.CreateFmt(SFCreateError, [AFileName])
raise EFCreateError.CreateFmt(SFCreateError + LineEnding + mbSysErrorMessage, [AFileName])
else
inherited Create(AHandle);
end
@ -177,7 +178,7 @@ begin
begin
AHandle:= mbFileOpen(AFileName, Mode);
if AHandle = feInvalidHandle then
raise EFOpenError.CreateFmt(SFOpenError, [AFilename])
raise EFOpenError.CreateFmt(SFOpenError + LineEnding + mbSysErrorMessage , [AFilename])
else
inherited Create(AHandle);
end;
@ -270,13 +271,14 @@ end;
{ TIniFileEx }
constructor TIniFileEx.Create(const AFileName: String; Mode: Word);
constructor TIniFileEx.Create(const AFileName: String; Mode: Word;
AOptions: TIniFileOptions);
var
slLines : TStringListEx;
begin
FReadOnly := ((Mode and $03) = fmOpenRead);
inherited Create(EmptyStr);
inherited Create(EmptyStr, AOptions);
if ((Mode and $03) <> fmOpenWrite) then
begin
@ -294,7 +296,7 @@ begin
Rename(AFileName, False);
end;
constructor TIniFileEx.Create(const AFileName: String; AEscapeLineFeeds: Boolean);
constructor TIniFileEx.Create(const AFileName: String; AOptions: TIniFileOptions);
var
Mode: Word;
begin
@ -305,7 +307,7 @@ begin
else begin
Mode := fmOpenRead or fmShareDenyNone;
end;
Create(AFileName, Mode);
Create(AFileName, Mode, AOptions);
end;
procedure TIniFileEx.UpdateFile;

View file

@ -61,18 +61,21 @@ function CeTryDecode(const aValue: AnsiString; aCodePage: Cardinal;
{$ELSEIF DEFINED(UNIX)}
var
SystemEncodingUtf8: Boolean = False;
SystemLanguage, SystemEncoding, SystemLocale: String;
SystemEncoding, SystemLocale: String;
{$ENDIF}
var
SystemLanguage: String;
implementation
uses
{$IF DEFINED(UNIX)}
iconvenc_dyn, LazUTF8
LazUTF8
{$IF DEFINED(DARWIN)}
, MacOSAll, CocoaAll
, dc_iconvenc_dyn, MacOSAll, CocoaAll, StrUtils
{$ELSE}
, UnixCP
, iconvenc_dyn, UnixCP
{$ENDIF}
{$ELSEIF DEFINED(MSWINDOWS)}
Windows
@ -324,6 +327,8 @@ begin
end;
procedure Initialize;
var
Buffer: array[1..4] of AnsiChar;
begin
CeOemToSys:= @OEM2Ansi;
CeSysToOem:= @Ansi2OEM;
@ -335,6 +340,9 @@ begin
CeUtf8ToAnsi:= @UTF82Sys;
CeSysToUtf8:= @Sys2UTF8;
CeUtf8ToSys:= @UTF82Sys;
if GetLocaleInfo(GetUserDefaultLCID, LOCALE_SABBREVLANGNAME, @Buffer[1], 4) > 0 then
SystemLanguage := LowerCase(Copy(Buffer, 1, 2));
end;
{$ELSEIF DEFINED(UNIX)}
@ -379,6 +387,7 @@ begin
begin
// Crop to terminating zero
SystemLanguage:= PAnsiChar(SystemLanguage);
SystemLanguage:= Copy2Symb(SystemLanguage, '-');
// Get system country
CurrentLocale:= NSLocale.currentLocale();
Country:= NSString(CurrentLocale.objectForKey(NSLocaleCountryCode)).UTF8String;
@ -398,7 +407,7 @@ begin
Lang:= SysUtils.GetEnvironmentVariable('LC_ALL');
if Length(Lang) = 0 then
begin
Lang:= SysUtils.GetEnvironmentVariable('LC_MESSAGES');
Lang:= SysUtils.GetEnvironmentVariable('LC_CTYPE');
if Length(Lang) = 0 then
begin
Lang:= SysUtils.GetEnvironmentVariable('LANG');

View file

@ -1,18 +1,73 @@
unit DCDarwin;
{$mode delphi}
{$packrecords c}
{$pointermath on}
{$modeswitch objectivec1}
interface
uses
Classes, SysUtils, DCBasicTypes, CocoaAll;
Classes, SysUtils, DCBasicTypes, CocoaAll, BaseUnix;
const
CLOSE_RANGE_CLOEXEC = (1 << 2);
function CloseRange(first: cuint; last: cuint; flags: cint): cint; cdecl;
// MacOS File Utils
function MacosFileSetCreationTime( const path:String; const birthtime:TFileTimeEx ): Boolean;
implementation
uses
DCUnix;
type
proc_fdinfo = record
proc_fd: Int32;
proc_fdtype: UInt32;
end;
Pproc_fdinfo = ^proc_fdinfo;
const
PROC_PIDLISTFDS = 1;
PROC_PIDLISTFD_SIZE = SizeOf(proc_fdinfo);
function proc_pidinfo(pid: cint; flavor: cint; arg: cuint64; buffer: pointer; buffersize: cint): cint; cdecl; external 'proc';
function CloseRange(first: cuint; last: cuint; flags: cint): cint; cdecl;
var
I: cint;
Handle: cint;
ProcessId: TPid;
bufferSize: cint;
pidInfo: Pproc_fdinfo;
begin
Result:= -1;
ProcessId:= FpGetpid;
bufferSize:= proc_pidinfo(ProcessId, PROC_PIDLISTFDS, 0, nil, 0);
pidInfo:= GetMem(bufferSize);
if Assigned(pidInfo) then
begin
bufferSize:= proc_pidinfo(ProcessId, PROC_PIDLISTFDS, 0, pidInfo, bufferSize);
for I:= 0 to (bufferSize div PROC_PIDLISTFD_SIZE) - 1 do
begin
Handle:= pidInfo[I].proc_fd;
if (Handle >= first) and (Handle <= last) then
begin
if (flags and CLOSE_RANGE_CLOEXEC <> 0) then
FileCloseOnExec(Handle)
else begin
FileClose(Handle);
end;
end;
end;
Result:= 0;
FreeMem(pidInfo);
end;
end;
function StringToNSString(const S: String): NSString;
begin
Result:= NSString(NSString.stringWithUTF8String(PAnsiChar(S)));

View file

@ -4,7 +4,7 @@
Date and time functions.
Copyright (C) 2009-2012 Przemysław Nagay (cobines@gmail.com)
Copyright (C) 2017-2022 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2017-2025 Alexander Koblov (alexx2000@mail.ru)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -22,7 +22,8 @@
unit DCDateTimeUtils;
{$mode objfpc}{$H+}
{$mode objfpc}
{$H+}{$R-}{$Q-}
interface
@ -35,11 +36,18 @@ uses
{$ENDIF}
;
const
DATE_TIME_NULL = TDateTime(2958466.0);
function FileTimeToDateTime(FileTime : DCBasicTypes.TFileTime) : TDateTime;
function FileTimeToDateTimeEx(FileTime : DCBasicTypes.TFileTimeEx) : TDateTime;
function DateTimeToFileTime(DateTime : TDateTime) : DCBasicTypes.TFileTime;
function DateTimeToFileTimeEx(DateTime : TDateTime) : DCBasicTypes.TFileTimeEx;
function FileTimeToWinFileTime(FileTime : DCBasicTypes.TFileTime) : TWinFileTime;
function FileTimeExToWinFileTime(FileTime : DCBasicTypes.TFileTimeEx) : TWinFileTime;
function WinFileTimeToFileTimeEx(FileTime: TWinFileTime) : DCBasicTypes.TFileTimeEx;
{en
Converts system specific UTC time to local time.
}
@ -97,10 +105,17 @@ function UnixFileTimeToDateTimeEx(UnixTime: DCBasicTypes.TFileTimeEx) : TDateTim
{$ENDIF}
function DateTimeToUnixFileTime(DateTime: TDateTime) : TUnixFileTime;
function DateTimeToUnixFileTimeEx(DateTime: TDateTime) : DCBasicTypes.TFileTimeEx;
function UnixFileTimeToFileTime(UnixTime: TUnixFileTime): DCBasicTypes.TFileTime;
function UnixFileTimeToDosTime(UnixTime: TUnixFileTime): TDosFileTime;
function DosTimeToUnixFileTime(DosTime: TDosFileTime): TUnixFileTime;
function UnixFileTimeToWinTime(UnixTime: TUnixFileTime): TWinFileTime;
function WinFileTimeToUnixTime(WinTime: TWinFileTime) : TUnixFileTime;
function WinFileTimeToDosTime(FileTime: TWinFileTime): TDosFileTime;
function DosTimeToWinFileTime(FileTime: TDosFileTime): TWinFileTime;
function WcxFileTimeToFileTime(WcxTime: LongInt): DCBasicTypes.TFileTime; inline;
function FileTimeToWcxFileTime(FileTime: DCBasicTypes.TFileTime): LongInt; inline;
function WcxFileTimeToDateTime(WcxTime: LongInt): TDateTime;
@ -140,6 +155,8 @@ uses
const
UnixWinEpoch = TWinFileTime($019DB1DED53E8000); // Unix epoch start
MinWinUnixSec = (0 - TUnixFileTime(UnixWinEpoch div 10000000 - 1));
MaxWinUnixSec = TUnixFileTime(High(TWinFileTime) div 10000000 - 1);
const { Short names of months. }
ShortMonthNames: TMonthNameArray = ('Jan','Feb','Mar','Apr','May','Jun',
@ -276,6 +293,58 @@ begin
end;
{$ENDIF}
function FileTimeToWinFileTime(FileTime: DCBasicTypes.TFileTime): TWinFileTime; inline;
{$IF DEFINED(MSWINDOWS)}
begin
Result:= TWinFileTime(FileTime)
end;
{$ELSEIF DEFINED(UNIX)}
begin
Result:= UnixFileTimeToWinTime(TUnixFileTime(FileTime));
end;
{$ENDIF}
function FileTimeExToWinFileTime(FileTime: DCBasicTypes.TFileTimeEx): TWinFileTime;
{$IF DEFINED(MSWINDOWS)}
begin
Result:= TWinFileTime(FileTime)
end;
{$ELSEIF DEFINED(UNIX)}
begin
if (FileTime.Sec > MaxWinUnixSec) then
Result:= High(TWinFileTime)
else if (FileTime.Sec < MinWinUnixSec) then
Result:= Low(TWinFileTime)
else begin
Result:= UnixWinEpoch + FileTime.sec * 10000000 + FileTime.nanosec div 100;
end;
end;
{$ENDIF}
function WinFileTimeToFileTimeEx(FileTime: TWinFileTime): DCBasicTypes.TFileTimeEx;
{$IF DEFINED(MSWINDOWS)}
begin
Result := TFileTimeEx(FileTime);
end;
{$ELSEIF DEFINED(UNIX)}
begin
if (FileTime >= UnixWinEpoch) then
begin
Result.Sec:= Int64((FileTime - UnixWinEpoch) div 10000000);
Result.NanoSec:= Int64((FileTime - UnixWinEpoch) mod 10000000) * 100;
end
else begin
Result.Sec:= (Int64(FileTime) - Int64(UnixWinEpoch)) div 10000000;
if (Result.Sec = 0) then
Result.NanoSec:= 0
else begin
Result.NanoSec:= (Int64(UnixWinEpoch - FileTime) mod 10000000) * 100;
if (Result.NanoSec > 0) then Result.NanoSec:= 1000000000 - Result.NanoSec;
end;
end;
end;
{$ENDIF}
function FileTimeToLocalFileTime(const FileTime: DCBasicTypes.TFileTime;
out LocalFileTime: DCBasicTypes.TFileTime): LongBool;
{$IFDEF MSWINDOWS}
@ -328,9 +397,7 @@ function WinFileTimeToDateTime(ft : TWinFileTime) : TDateTime;
{$IF DEFINED(MSWINDOWS)}
var
lpUniversalTime, lpLocalTime: TSystemTime;
{$ENDIF}
begin
{$IF DEFINED(MSWINDOWS)}
if (Win32MajorVersion > 5) then
begin
FileTimeToSystemTime(@ft, @lpUniversalTime);
@ -338,20 +405,22 @@ begin
Result := SystemTimeToDateTime(lpLocalTime);
end
else
{$ENDIF}
begin
WinFileTimeToLocalFileTime(ft,ft);
Result := (ft / 864000000000.0) - 109205.0;
end;
end;
{$ELSE}
begin
Result := FileTimeToDateTimeEx(WinFileTimeToFileTimeEx(ft));
end;
{$ENDIF}
function DateTimeToWinFileTime(dt : TDateTime) : TWinFileTime;
{$IF DEFINED(MSWINDOWS)}
var
lpUniversalTime, lpLocalTime: TSystemTime;
{$ENDIF}
begin
{$IF DEFINED(MSWINDOWS)}
if (Win32MajorVersion > 5) then
begin
DateTimeToSystemTime(dt, lpLocalTime);
@ -359,12 +428,16 @@ begin
SystemTimeToFileTime(@lpUniversalTime, @Result);
end
else
{$ENDIF}
begin
Result := Round((Extended(dt) + 109205.0) * 864000000000.0);
WinLocalFileTimeToFileTime(Result, Result);
end;
end;
{$ELSE}
begin
Result := FileTimeExToWinFileTime(DateTimeToFileTimeEx(dt));
end;
{$ENDIF}
function DosFileTimeToDateTime(const DosTime: TDosFileTime): TDateTime;
var
@ -405,10 +478,16 @@ var
Hr, Mn, S, MS: Word;
begin
DecodeDate(DateTime, Yr, Mo, Dy);
if (Yr < 1980) or (Yr > 2107) then // outside DOS file date year range
Yr := 1980;
DecodeTime(DateTime, Hr, Mn, S, MS);
// Outside DOS file date year range
if (Yr < 1980) then
Yr := 1980
else if (Yr > 2107) then
begin
Yr := 2107;
end;
LongRec(Result).Lo := (S shr 1) or (Mn shl 5) or (Hr shl 11);
LongRec(Result).Hi := Dy or (Mo shl 5) or (Word(Yr - 1980) shl 9);
end;
@ -480,7 +559,7 @@ end;
function UnixFileTimeToDateTimeEx(UnixTime: DCBasicTypes.TFileTimeEx) : TDateTime;
var
ATime: TTimeStruct;
milliseconds: Word;
Milliseconds: Word;
begin
if (fpLocalTime(@UnixTime.sec, @ATime) = nil) then
Exit(UnixEpoch);
@ -495,9 +574,11 @@ begin
if ATime.tm_sec > 59 then
ATime.tm_sec := 59;
milliseconds:= round( Extended(UnixTime.nanosec) / (1000.0*1000.0) );
if (milliseconds > 999) then
milliseconds:= 999;
if (UnixTime.nanosec > 999000000) then
Milliseconds := 999
else begin
Milliseconds := Round( Extended(UnixTime.nanosec) / (1000.0 * 1000.0) );
end;
Result := ComposeDateTime(EncodeDate(ATime.tm_year, ATime.tm_mon, ATime.tm_mday),
EncodeTime(ATime.tm_hour, ATime.tm_min, ATime.tm_sec, milliseconds));
@ -515,34 +596,10 @@ end;
function DateTimeToUnixFileTime(DateTime : TDateTime): TUnixFileTime;
{$IF DEFINED(UNIX)}
var
AUnixTime: TTime;
ATime: TTimeStruct;
Year, Month, Day: Word;
Hour, Minute, Second, MilliSecond: Word;
AUnixTime: TFileTimeEx;
begin
if DateTime < UnixEpoch then
raise EDateOutOfRange.Create(DateTime);
DecodeDate(DateTime, Year, Month, Day);
DecodeTime(DateTime, Hour, Minute, Second, MilliSecond);
ATime.tm_isdst:= -1;
ATime.tm_year:= Year - 1900;
ATime.tm_mon:= Month - 1;
ATime.tm_mday:= Day;
ATime.tm_hour:= Hour;
ATime.tm_min:= Minute;
ATime.tm_sec:= Second;
AUnixTime:= fpMkTime(@ATime);
if (AUnixTime < 0) then
Result:= 0
else begin
Result:= TUnixFileTime(AUnixTime);
end;
AUnixTime:= DateTimeToUnixFileTimeEx(DateTime);
Result:= TUnixFileTime(AUnixTime.Sec);
end;
{$ELSE}
var
@ -561,9 +618,6 @@ var
Year, Month, Day: Word;
Hour, Minute, Second, MilliSecond: Word;
begin
if DateTime < UnixEpoch then
raise EDateOutOfRange.Create(DateTime);
DecodeDate(DateTime, Year, Month, Day);
DecodeTime(DateTime, Hour, Minute, Second, MilliSecond);
@ -579,10 +633,11 @@ begin
AUnixTime:= fpMkTime(@ATime);
if (AUnixTime < 0) then
if (AUnixTime = -1) then
Result:= TFileTimeExNull
else begin
Result:= TFileTimeEx.create(AUnixTime, MilliSecond*1000*1000);
if (AUnixTime < 0) then MilliSecond:= 0;
Result:= TFileTimeEx.Create(AUnixTime, MilliSecond * 1000 * 1000);
end;
end;
{$ELSE}
@ -594,11 +649,25 @@ begin
end;
{$ENDIF}
function UnixFileTimeToFileTime(UnixTime: TUnixFileTime): DCBasicTypes.TFileTime; inline;
begin
{$IF DEFINED(MSWINDOWS)}
Result:= UnixFileTimeToWinTime(UnixTime);
{$ELSE}
Result:= UnixTime;
{$ENDIF}
end;
function UnixFileTimeToDosTime(UnixTime: TUnixFileTime): TDosFileTime;
begin
Result := DateTimeToDosFileTime(UnixFileTimeToDateTime(UnixTime));
end;
function DosTimeToUnixFileTime(DosTime: TDosFileTime): TUnixFileTime;
begin
Result:= DateTimeToUnixFileTime(DosFileTimeToDateTime(DosTime));
end;
function UnixFileTimeToWinTime(UnixTime: TUnixFileTime): TWinFileTime;
var
WinFileTime: TWinFileTime;
@ -616,6 +685,16 @@ begin
Result:= TUnixFileTime((WinTime - UnixWinEpoch) div 10000000);
end;
function WinFileTimeToDosTime(FileTime: TWinFileTime): TDosFileTime;
begin
Result := DateTimeToDosFileTime(WinFileTimeToDateTime(FileTime));
end;
function DosTimeToWinFileTime(FileTime: TDosFileTime): TWinFileTime;
begin
Result := DateTimeToWinFileTime(DosFileTimeToDateTime(FileTime));
end;
function WcxFileTimeToFileTime(WcxTime: LongInt): DCBasicTypes.TFileTime;
begin
{$IF DEFINED(MSWINDOWS)}

View file

@ -34,8 +34,10 @@ const
FILE_ATTRIBUTE_READONLY = $0001;
FILE_ATTRIBUTE_HIDDEN = $0002;
FILE_ATTRIBUTE_SYSTEM = $0004;
FILE_ATTRIBUTE_VOLUME = $0008;
FILE_ATTRIBUTE_DIRECTORY = $0010;
FILE_ATTRIBUTE_ARCHIVE = $0020;
FILE_ATTRIBUTE_DEVICE = $0040;
FILE_ATTRIBUTE_NORMAL = $0080;
FILE_ATTRIBUTE_TEMPORARY = $0100;
FILE_ATTRIBUTE_SPARSE_FILE = $0200;
@ -186,13 +188,14 @@ function WinToUnixFileAttr(Attr: TFileAttrs): TFileAttrs;
begin
Result := S_IRUSR or S_IRGRP or S_IROTH;
if (Attr and faReadOnly) = 0 then
Result := Result or S_IWUSR;
if (Attr and faDirectory) <> 0 then
Result := Result or S_IFDIR or S_IXUGO
else
Result := Result or S_IFDIR or S_IXUGO or S_IWUSR
else begin
Result := Result or S_IFREG;
if (Attr and faReadOnly) = 0 then
Result := Result or S_IWUSR;
end;
end;
function UnixToWinFileAttr(Attr: TFileAttrs): TFileAttrs;

View file

@ -0,0 +1,213 @@
{
Double Commander
-------------------------------------------------------------------------
This unit contains Linux specific functions
Copyright (C) 2023 Alexander Koblov (alexx2000@mail.ru)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program. If not, see <https://www.gnu.org/licenses/>
}
unit DCLinux;
{$mode objfpc}{$H+}
{$packrecords c}
interface
uses
Classes, SysUtils, BaseUnix, Unix;
const
CLOSE_RANGE_CLOEXEC = (1 << 2);
const
FS_IOC_GETFLAGS = $80086601;
FS_IOC_SETFLAGS = $40086602;
(*
* Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
*)
FS_SECRM_FL = $00000001; //* Secure deletion */
FS_UNRM_FL = $00000002; //* Undelete */
FS_COMPR_FL = $00000004; //* Compress file */
FS_SYNC_FL = $00000008; //* Synchronous updates */
FS_IMMUTABLE_FL = $00000010; //* Immutable file */
FS_APPEND_FL = $00000020; //* Writes to file may only append */
FS_NODUMP_FL = $00000040; //* Do not dump file */
FS_NOATIME_FL = $00000080; //* Do not update atime */
FS_FL_USER_VISIBLE = $0003DFFF; //* User visible flags */
FS_FL_USER_MODIFIABLE = $000380FF; //* User modifiable flags */
type
TFlagName = record
Flag: UInt32;
Name: AnsiChar;
end;
const
FlagsName: array[1..8] of TFlagName = (
(Flag: FS_SECRM_FL; Name: 's'),
(Flag: FS_UNRM_FL; Name: 'u'),
(Flag: FS_SYNC_FL; Name: 'S'),
(Flag: FS_IMMUTABLE_FL; Name: 'i'),
(Flag: FS_APPEND_FL; Name: 'a'),
(Flag: FS_NODUMP_FL; Name: 'd'),
(Flag: FS_NOATIME_FL; Name: 'A'),
(Flag: FS_COMPR_FL; Name: 'c')
);
function FormatFileFlags(Flags: UInt32): String;
function FileGetFlags(Handle: THandle; out Flags: UInt32): Boolean;
function mbFileGetFlags(const FileName: String; out Flags: UInt32): Boolean;
function mbFileGetXattr(const FileName: String): TStringArray;
function mbFileCopyXattr(const Source, Target: String): Boolean;
implementation
uses
InitC, DCConvertEncoding, DCOSUtils;
function lremovexattr(const path, name: PAnsiChar): cint; cdecl; external clib;
function llistxattr(const path: PAnsiChar; list: PAnsiChar; size: csize_t): ssize_t; cdecl; external clib;
function lgetxattr(const path, name: PAnsiChar; value: Pointer; size: csize_t): ssize_t; cdecl; external clib;
function lsetxattr(const path, name: PAnsiChar; const value: Pointer; size: csize_t; flags: cint): cint; cdecl; external clib;
function FormatFileFlags(Flags: UInt32): String;
var
Index: Integer;
begin
Result:=StringOfChar('-', Length(FlagsName));
for Index:= 1 to High(FlagsName) do
begin
if Flags and FlagsName[Index].Flag <> 0 then
begin
Result[Index]:= FlagsName[Index].Name;
end;
end;
end;
function FileGetFlags(Handle: THandle; out Flags: UInt32): Boolean;
begin
Result:= (FpIOCtl(Handle, FS_IOC_GETFLAGS, @Flags) >= 0);
end;
function mbFileGetFlags(const FileName: String; out Flags: UInt32): Boolean;
var
Handle: THandle;
begin
Handle:= mbFileOpen(FileName, fmOpenRead or fmShareDenyNone);
Result:= Handle <> feInvalidHandle;
if Result then
begin
Result:= (FpIOCtl(Handle, FS_IOC_GETFLAGS, @Flags) >= 0);
FileClose(Handle);
end;
end;
function mbFileGetXattr(const FileName: String): TStringArray;
var
AList: String;
ALength: ssize_t;
AFileName: String;
begin
SetLength(AList, MaxSmallint);
Result:= Default(TStringArray);
AFileName:= CeUtf8ToSys(FileName);
ALength:= llistxattr(PAnsiChar(AFileName), Pointer(AList), Length(AList));
if (ALength < 0) then
begin
if (fpgetCerrno <> ESysERANGE) then
begin
fpseterrno(fpgetCerrno);
Exit;
end
else begin
ALength:= llistxattr(PAnsiChar(AFileName), nil, 0);
if ALength < 0 then
begin
fpseterrno(fpgetCerrno);
Exit;
end;
SetLength(AList, ALength);
ALength:= llistxattr(PAnsiChar(AFileName), Pointer(AList), ALength);
if ALength < 0 then
begin
fpseterrno(fpgetCerrno);
Exit;
end;
end;
end;
if (ALength > 0) then
begin
SetLength(AList, ALength - 1);
Result:= AList.Split(#0);
end;
end;
function mbFileCopyXattr(const Source, Target: String): Boolean;
var
Value: String;
Index: Integer;
ALength: ssize_t;
Names: TStringArray;
ASource, ATarget: String;
begin
Result:= True;
ASource:= CeUtf8ToSys(Source);
ATarget:= CeUtf8ToSys(Target);
// Remove attributes from target
Names:= mbFileGetXattr(Target);
for Index:= 0 to High(Names) do
begin
lremovexattr(PAnsiChar(ATarget), PAnsiChar(Names[Index]));
end;
SetLength(Value, MaxSmallint);
Names:= mbFileGetXattr(Source);
for Index:= 0 to High(Names) do
begin
ALength:= lgetxattr(PAnsiChar(ASource), PAnsiChar(Names[Index]), Pointer(Value), Length(Value));
if (ALength < 0) then
begin
if (fpgetCerrno <> ESysERANGE) then
begin
fpseterrno(fpgetCerrno);
Exit(False);
end
else begin
ALength:= lgetxattr(PAnsiChar(ASource), PAnsiChar(Names[Index]), nil, 0);
if ALength < 0 then
begin
fpseterrno(fpgetCerrno);
Exit(False);
end;
SetLength(Value, ALength);
ALength:= lgetxattr(PAnsiChar(ASource), PAnsiChar(Names[Index]), Pointer(Value), Length(Value));
if ALength < 0 then
begin
fpseterrno(fpgetCerrno);
Exit(False);
end;
end;
end;
if (lsetxattr(PAnsiChar(ATarget), PAnsiChar(Names[Index]), Pointer(Value), ALength, 0) < 0) then
begin
fpseterrno(fpgetCerrno);
Exit(fpgeterrno = ESysEOPNOTSUPP);
end;
end;
end;
end.

View file

@ -4,7 +4,7 @@
This unit contains functions to work with hard and symbolic links
on the NTFS file system.
Copyright (C) 2012-2017 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2012-2025 Alexander Koblov (alexx2000@mail.ru)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -17,8 +17,7 @@
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
License along with this library. If not, see <https://www.gnu.org/licenses/>.
}
unit DCNtfsLinks;
@ -40,6 +39,8 @@ const
FSCTL_SET_REPARSE_POINT = $000900A4;
FSCTL_GET_REPARSE_POINT = $000900A8;
FSCTL_DELETE_REPARSE_POINT = $000900AC;
// WSL and Cygwin symbolic link
IO_REPARSE_TAG_LX_SYMLINK = $A000001D;
const
REPARSE_DATA_HEADER_SIZE = 8;
@ -68,6 +69,11 @@ type
PathBuffer: array[0..0] of WCHAR;
end;
TLxSymlinkReparseBuffer = record
FileType: DWORD;
PathBuffer: array[0..0] of AnsiChar;
end;
TGenericReparseBuffer = record
DataBuffer: array[0..0] of UCHAR;
end;
@ -79,7 +85,8 @@ type
case Integer of
0: (SymbolicLinkReparseBuffer: TSymbolicLinkReparseBuffer);
1: (MountPointReparseBuffer: TMountPointReparseBuffer);
2: (GenericReparseBuffer: TGenericReparseBuffer);
2: (LxSymlinkReparseBuffer: TLxSymlinkReparseBuffer);
3: (GenericReparseBuffer: TGenericReparseBuffer);
end;
TReparseDataBuffer = REPARSE_DATA_BUFFER;
PReparseDataBuffer = ^REPARSE_DATA_BUFFER;
@ -95,7 +102,7 @@ type
@param(ALinkName The name of the symbolic link)
@returns(The function returns @true if successful, @false otherwise)
}
function CreateSymLink(const ATargetName, ALinkName: UnicodeString): Boolean;
function CreateSymLink(const ATargetName, ALinkName: UnicodeString; Attr: UInt32): Boolean;
{en
Established a hard link beetwen an existing file and new file. This function
is only supported on the NTFS file system, and only for files, not directories.
@ -250,6 +257,7 @@ function _CreateSymLink_Old(aTargetFileName, aSymlinkFileName: UnicodeString): B
var
hDevice: THandle;
lpInBuffer: PReparseDataBuffer;
dwLastError,
nInBufferSize,
dwPathBufferSize: DWORD;
wsNativeFileName: UnicodeString;
@ -261,7 +269,11 @@ begin
hDevice:= CreateFileW(PWideChar(aSymlinkFileName),
GENERIC_WRITE, 0, nil, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OPEN_REPARSE_POINT, 0);
if hDevice = INVALID_HANDLE_VALUE then Exit(False);
if hDevice = INVALID_HANDLE_VALUE then
begin
dwLastError:= GetLastError;
Exit(False);
end;
if Pos(wsLongFileNamePrefix, aTargetFileName) <> 1 then
wsNativeFileName:= wsNativeFileNamePrefix + aTargetFileName
else begin
@ -288,15 +300,19 @@ begin
0, // nOutBufferSize
lpBytesReturned, // lpBytesReturned
nil); // OVERLAPPED structure
if not Result then dwLastError:= GetLastError;
FreeMem(lpInBuffer);
CloseHandle(hDevice);
finally
if not Result then RemoveDirectoryW(PWideChar(aSymlinkFileName));
if not Result then
begin
RemoveDirectoryW(PWideChar(aSymlinkFileName));
SetLastError(dwLastError);
end;
end;
end;
function CreateSymLink(const ATargetName, ALinkName: UnicodeString): Boolean;
function CreateSymLink(const ATargetName, ALinkName: UnicodeString; Attr: UInt32): Boolean;
var
dwAttributes: DWORD;
lpFilePart: LPWSTR = nil;
@ -315,7 +331,11 @@ begin
AFullPathName:= ATargetName;
end;
end;
dwAttributes:= Windows.GetFileAttributesW(PWideChar(AFullPathName));
if (Attr <> FILE_DOES_NOT_EXIST) then
dwAttributes:= Attr
else begin
dwAttributes:= Windows.GetFileAttributesW(PWideChar(AFullPathName));
end;
if dwAttributes = FILE_DOES_NOT_EXIST then Exit;
if HasNewApi = False then
begin
@ -339,9 +359,10 @@ end;
function ReadSymLink(const aSymlinkFileName: UnicodeString; out aTargetFileName: UnicodeString): Boolean;
var
L: Integer;
hDevice: THandle;
dwFileAttributes: DWORD;
caOutBuffer: array[0..4095] of Byte;
caOutBuffer: array[0..MaxSmallint] of Byte;
lpOutBuffer: TReparseDataBuffer absolute caOutBuffer;
pwcTargetFileName: PWideChar;
lpBytesReturned: DWORD = 0;
@ -389,6 +410,13 @@ begin
SetLength(aTargetFileName, SubstituteNameLength div SizeOf(WideChar));
CopyMemory(PWideChar(aTargetFileName), pwcTargetFileName, SubstituteNameLength);
end;
IO_REPARSE_TAG_LX_SYMLINK:
with lpOutBuffer.LxSymlinkReparseBuffer do
begin
L:= lpOutBuffer.ReparseDataLength - SizeOf(FileType);
SetLength(aTargetFileName, L + 1);
SetLength(aTargetFileName, MultiByteToWideChar(CP_UTF8, 0, @PathBuffer[0], L, PWideChar(aTargetFileName), L + 1));
end;
end;
if Pos(wsNetworkFileNamePrefix, aTargetFileName) = 1 then
Delete(aTargetFileName, 2, Length(wsNetworkFileNamePrefix) - 2)

265
components/doublecmd/dcosutils.pas Executable file → Normal file
View file

@ -3,7 +3,7 @@
-------------------------------------------------------------------------
This unit contains platform dependent functions dealing with operating system.
Copyright (C) 2006-2023 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2006-2025 Alexander Koblov (alexx2000@mail.ru)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -31,6 +31,9 @@ uses
{$IFDEF UNIX}
, BaseUnix, DCUnix
{$ENDIF}
{$IFDEF LINUX}
, DCLinux
{$ENDIF}
{$IFDEF HAIKU}
, DCHaiku
{$ENDIF}
@ -43,6 +46,7 @@ const
fmOpenSync = $10000;
fmOpenDirect = $20000;
fmOpenNoATime = $40000;
fmOpenSpecial = $80000;
{$IF DEFINED(UNIX)}
ERROR_NOT_SAME_DEVICE = ESysEXDEV;
@ -96,7 +100,7 @@ type
PCopyAttributesResult = ^TCopyAttributesResult;
const
faInvalidAttributes: TFileAttrs = TFileAttrs(-1);
faInvalidAttributes = TFileAttrs(-1);
CopyAttributesOptionCopyAll = [caoCopyAttributes, caoCopyTime, caoCopyOwnership];
{en
@ -111,6 +115,12 @@ function FPS_ISDIR(iAttr: TFileAttrs) : Boolean;
@returns(@true if file is a symbolic link, @false otherwise)
}
function FPS_ISLNK(iAttr: TFileAttrs) : Boolean;
{en
Is file a regular file
@param(iAttr File attributes)
@returns(@true if file is a regular file, @false otherwise)
}
function FPS_ISREG(iAttr: TFileAttrs) : Boolean;
{en
Is file executable
@param(sFileName File name)
@ -146,6 +156,10 @@ function FileIsReadOnly(iAttr: TFileAttrs): Boolean; inline;
The path '/tmp' must already exist.)
}
function GetTempName(PathPrefix: String; Extension: String = 'tmp'): String;
{en
Find file in the system PATH
}
function FindInSystemPath(var FileName: String): Boolean;
{en
Extract file root directory
@param(FileName File name)
@ -177,6 +191,7 @@ function mbFileCreate(const FileName: String): System.THandle; overload; inline;
function mbFileCreate(const FileName: String; Mode: LongWord): System.THandle; overload; inline;
function mbFileCreate(const FileName: String; Mode, Rights: LongWord): System.THandle; overload;
function mbFileAge(const FileName: String): DCBasicTypes.TFileTime;
function mbFileGetTime(const FileName: String): DCBasicTypes.TFileTimeEx;
// On success returns True.
// nanoseconds supported
function mbFileGetTime(const FileName: String;
@ -222,6 +237,7 @@ function mbFileSize(const FileName: String): Int64;
function FileGetSize(Handle: System.THandle): Int64;
function FileFlush(Handle: System.THandle): Boolean;
function FileFlushData(Handle: System.THandle): Boolean;
function FileIsReadOnlyEx(Handle: System.THandle): Boolean;
function FileAllocate(Handle: System.THandle; Size: Int64): Boolean;
{ Directory handling functions}
function mbGetCurrentDir: String;
@ -293,7 +309,7 @@ function CreateHardLink(const Path, LinkName: String) : Boolean;
@param(LinkName Name of symbolic link)
@returns(The function returns @true if successful, @false otherwise)
}
function CreateSymLink(const Path, LinkName: string) : Boolean;
function CreateSymLink(const Path, LinkName: string; Attr: UInt32 = faInvalidAttributes) : Boolean;
{en
Read destination of symbolic link
@param(LinkName Name of symbolic link)
@ -381,8 +397,6 @@ const
O_SYNC or O_DIRECT);
{$ENDIF}
(*Is Directory*)
function FPS_ISDIR(iAttr: TFileAttrs) : Boolean; inline;
{$IFDEF MSWINDOWS}
begin
@ -394,8 +408,6 @@ begin
end;
{$ENDIF}
(*Is Link*)
function FPS_ISLNK(iAttr: TFileAttrs) : Boolean; inline;
{$IFDEF MSWINDOWS}
begin
@ -407,6 +419,17 @@ begin
end;
{$ENDIF}
function FPS_ISREG(iAttr: TFileAttrs) : Boolean; inline;
{$IFDEF MSWINDOWS}
begin
Result := (iAttr and FILE_ATTRIBUTE_DIRECTORY = 0);
end;
{$ELSE}
begin
Result := BaseUnix.FPS_ISREG(TMode(iAttr));
end;
{$ENDIF}
function FileIsExeLib(const sFileName : String) : Boolean;
var
fsExeLib : TFileStreamEx;
@ -484,54 +507,59 @@ function mbFileCopyAttr(const sSrc, sDst: String;
): TCopyAttributesOptions;
{$IFDEF MSWINDOWS}
var
Attr : TFileAttrs;
Attr: TWin32FileAttributeData;
Option: TCopyAttributesOption;
ModificationTime, CreationTime, LastAccessTime: DCBasicTypes.TFileTime;
begin
Result := [];
if not GetFileAttributesExW(PWideChar(UTF16LongName(sSrc)), GetFileExInfoStandard, @Attr) then
begin
Result := Options;
if Assigned(Errors) then
begin
for Option in Result do
Errors^[Option]:= GetLastOSError;
end;
Exit;
end;
if [caoCopyAttributes, caoCopyAttrEx] * Options <> [] then
begin
Attr := mbFileGetAttr(sSrc);
if Attr <> faInvalidAttributes then
if (not (caoCopyAttributes in Options)) and (Attr.dwFileAttributes and faDirectory = 0) then
Attr.dwFileAttributes := (Attr.dwFileAttributes or faArchive);
if (caoRemoveReadOnlyAttr in Options) and ((Attr.dwFileAttributes and faReadOnly) <> 0) then
Attr.dwFileAttributes := (Attr.dwFileAttributes and not faReadOnly);
if not mbFileSetAttr(sDst, Attr.dwFileAttributes) then
begin
if (not (caoCopyAttributes in Options)) and (Attr and faDirectory = 0) then
Attr := (Attr or faArchive);
if (caoRemoveReadOnlyAttr in Options) and ((Attr and faReadOnly) <> 0) then
Attr := (Attr and not faReadOnly);
if not mbFileSetAttr(sDst, Attr) then
begin
Include(Result, caoCopyAttributes);
if Assigned(Errors) then Errors^[caoCopyAttributes]:= GetLastOSError;
end;
end
else begin
Include(Result, caoCopyAttributes);
if Assigned(Errors) then Errors^[caoCopyAttributes]:= GetLastOSError;
end;
end;
if caoCopyXattributes in Options then
if not FPS_ISLNK(Attr.dwFileAttributes) then
begin
if not mbFileCopyXattr(sSrc, sDst) then
if (caoCopyXattributes in Options) then
begin
Include(Result, caoCopyXattributes);
if Assigned(Errors) then Errors^[caoCopyXattributes]:= GetLastOSError;
if not mbFileCopyXattr(sSrc, sDst) then
begin
Include(Result, caoCopyXattributes);
if Assigned(Errors) then Errors^[caoCopyXattributes]:= GetLastOSError;
end;
end;
end;
if [caoCopyTime, caoCopyTimeEx] * Options <> [] then
begin
if not mbFileGetTime(sSrc, ModificationTime, CreationTime, LastAccessTime) then
if ([caoCopyTime, caoCopyTimeEx] * Options <> []) then
begin
Include(Result, caoCopyTime);
if Assigned(Errors) then Errors^[caoCopyTime]:= GetLastOSError;
end
else begin
if not (caoCopyTime in Options) then
begin
CreationTime:= 0;
LastAccessTime:= 0;
end
else begin
CreationTime:= DCBasicTypes.TFileTime(Attr.ftCreationTime);
LastAccessTime:= DCBasicTypes.TFileTime(Attr.ftLastAccessTime);
end;
ModificationTime:= DCBasicTypes.TFileTime(Attr.ftLastWriteTime);
if not mbFileSetTime(sDst, ModificationTime, CreationTime, LastAccessTime) then
begin
@ -670,6 +698,26 @@ begin
until not mbFileSystemEntryExists(Result);
end;
function FindInSystemPath(var FileName: String): Boolean;
var
I: Integer;
Path, FullName: String;
Value: TDynamicStringArray;
begin
Path:= mbGetEnvironmentVariable('PATH');
Value:= SplitString(Path, PathSeparator);
for I:= Low(Value) to High(Value) do
begin
FullName:= IncludeTrailingPathDelimiter(Value[I]) + FileName;
if mbFileExists(FullName) then
begin
FileName:= FullName;
Exit(True);
end;
end;
Result:= False;
end;
function ExtractRootDir(const FileName: String): String;
{$IFDEF UNIX}
begin
@ -824,6 +872,8 @@ begin
end;
end;
{$ELSE}
var
Info: BaseUnix.Stat;
begin
repeat
Result:= fpOpen(UTF8ToSys(FileName), AccessModes[Mode and 3] or
@ -832,7 +882,28 @@ begin
if Result <> feInvalidHandle then
begin
FileCloseOnExec(Result);
Result:= FileLock(Result, Mode and $FF);
if (Mode and fmOpenSpecial = 0) then
begin
if fpFStat(Result, Info) = 0 then
begin
if FPS_ISFIFO(Info.st_mode) then
begin
FileClose(Result);
errno:= ESysEINVAL;
Exit(feInvalidHandle);
end;
end;
end;
{$IF DEFINED(DARWIN)}
if (Mode and (fmOpenSync or fmOpenDirect) <> 0) then
begin
if (FpFcntl(Result, F_NOCACHE, 1) = -1) then
begin
FileClose(Result);
Exit(feInvalidHandle);
end;
end;
{$ENDIF}
end;
end;
{$ENDIF}
@ -863,7 +934,16 @@ begin
if Result <> feInvalidHandle then
begin
FileCloseOnExec(Result);
Result:= FileLock(Result, Mode and $FF);
{$IF DEFINED(DARWIN)}
if (Mode and (fmOpenSync or fmOpenDirect) <> 0) then
begin
if (FpFcntl(Result, F_NOCACHE, 1) = -1) then
begin
FileClose(Result);
Exit(feInvalidHandle);
end;
end;
{$ENDIF}
end;
end;
{$ENDIF}
@ -895,6 +975,14 @@ begin
end;
{$ENDIF}
function mbFileGetTime(const FileName: String): DCBasicTypes.TFileTimeEx;
var
CreationTime, LastAccessTime: DCBasicTypes.TFileTimeEx;
begin
if not mbFileGetTime(FileName, Result, CreationTime, LastAccessTime) then
Result:= TFileTimeExNull;
end;
function mbFileGetTime(const FileName: String;
var ModificationTime: DCBasicTypes.TFileTimeEx;
var CreationTime : DCBasicTypes.TFileTimeEx;
@ -1250,8 +1338,10 @@ begin
// (On Linux rename() returns success but doesn't do anything
// if renaming a file to its hard link.)
// We cannot use st_nlink for directories because it means "number of
// subdirectories"; hard links to directories are not supported on Linux
// or Windows anyway (on MacOSX they are). Therefore we always treat
// subdirectories" ("number of all entries" under macOS) in that directory,
// plus its special entries '.' and '..';
// hard links to directories are not supported on Linux
// or Windows anyway (on macOS they are). Therefore we always treat
// directories as if they were a single link and rename them using temporary name.
if (NewFileStat.st_nlink = 1) or BaseUnix.fpS_ISDIR(NewFileStat.st_mode) then
@ -1265,14 +1355,7 @@ begin
// We have renamed the old file but the new file name still exists,
// so this wasn't a single file on a case-insensitive filesystem
// accessible by two names that differ by case.
FpRename(UTF8ToSys(tmpFileName), UTF8ToSys(OldName)); // Restore old file.
{$IFDEF DARWIN}
// If it's a directory with multiple hard links then simply unlink the source.
if BaseUnix.fpS_ISDIR(NewFileStat.st_mode) and (NewFileStat.st_nlink > 1) then
Result := (fpUnLink(UTF8ToSys(OldName)) = 0)
else
{$ENDIF}
Result := False;
end
else if FpRename(UTF8ToSys(tmpFileName), UTF8ToSys(NewName)) = 0 then
@ -1367,14 +1450,48 @@ begin
end;
{$ENDIF}
function FileIsReadOnlyEx(Handle: System.THandle): Boolean;
{$IF DEFINED(MSWINDOWS)}
var
Info: BY_HANDLE_FILE_INFORMATION;
begin
if GetFileInformationByHandle(Handle, Info) then
Result:= (Info.dwFileAttributes and (faReadOnly or faHidden or faSysFile) <> 0)
else
Result:= False;
end;
{$ELSEIF DEFINED(LINUX)}
var
Flags: UInt32;
begin
if FileGetFlags(Handle, Flags) then
begin
if (Flags and (FS_IMMUTABLE_FL or FS_APPEND_FL) <> 0) then
Exit(True);
end;
Result:= False;
end;
{$ELSE}
begin
Result:= False;
end;
{$ENDIF}
function FileAllocate(Handle: System.THandle; Size: Int64): Boolean;
{$IF DEFINED(LINUX)}
var
Ret: cint;
Sta: TStat;
StaFS: TStatFS;
begin
if (Size > 0) then
begin
repeat
Ret:= fpfStatFS(Handle, @StaFS);
until (Ret <> -1) or (fpgeterrno <> ESysEINTR);
// FAT32 does not support a fast allocation
if (StaFS.fstype = MSDOS_SUPER_MAGIC) then
Exit(False);
repeat
Ret:= fpFStat(Handle, Sta);
until (Ret <> -1) or (fpgeterrno <> ESysEINTR);
@ -1384,7 +1501,7 @@ begin
Sta.st_size:= (Size + Sta.st_blksize - 1) and not (Sta.st_blksize - 1);
repeat
Ret:= fpFAllocate(Handle, 0, 0, Sta.st_size);
until (Ret <> -1) or (fpgeterrno <> ESysEINTR) or (fpgeterrno <> ESysEAGAIN);
until (Ret <> -1) or (fpgeterrno <> ESysEINTR);
end;
end;
Result:= FileTruncate(Handle, Size);
@ -1647,7 +1764,7 @@ begin
if EqualPos = 0 then Continue;
EnvName:= Copy(EnvVar, 1, EqualPos - 1);
EnvValue:= Copy(EnvVar, EqualPos + 1, MaxInt);
Result:= StringReplace(Result, '$' + EnvName, EnvValue, [rfReplaceAll, rfIgnoreCase]);
Result:= StringReplace(Result, '$' + EnvName, EnvValue, [rfReplaceAll]);
Inc(Index);
end;
end;
@ -1764,21 +1881,27 @@ end;
function mbLoadLibrary(const Name: String): TLibHandle;
{$IFDEF MSWINDOWS}
var
dwMode: DWORD;
dwErrCode: DWORD;
sRememberPath: String;
begin
dwMode:= SetErrorMode(SEM_FAILCRITICALERRORS or SEM_NOOPENFILEERRORBOX);
try
//Some plugins using DLL(s) in their directory are loaded correctly only if "CurrentDir" is poining their location.
//Also, TC switch "CurrentDir" to their directory when loading them. So let's do the same.
sRememberPath:=GetCurrentDir;
SetCurrentDir(ExcludeTrailingPathDelimiter(ExtractFilePath(Name)));
Result:= LoadLibraryW(PWideChar(CeUtf8ToUtf16(Name)));
// Some plugins using DLL(s) in their directory are loaded correctly only if "CurrentDir" is poining their location.
// Also, TC switch "CurrentDir" to their directory when loading them. So let's do the same.
sRememberPath:= GetCurrentDir;
SetCurrentDir(ExtractFileDir(Name));
Result:= SafeLoadLibrary(CeUtf8ToUtf16(Name));
dwErrCode:= GetLastError;
finally
SetErrorMode(dwMode);
SetCurrentDir(sRememberPath);
SetLastError(dwErrCode);
end;
end;
{$ELSE}
begin
Result:= TLibHandle(dlopen(PChar(UTF8ToSys(Name)), RTLD_LAZY));
Result:= SafeLoadLibrary(CeUtf8ToSys(Name));
end;
{$ENDIF}
@ -1787,29 +1910,37 @@ function mbLoadLibraryEx(const Name: String): TLibHandle;
const
PATH_ENV = 'PATH';
var
dwFlags:DWORD;
APath: String;
APathType: TPathType;
usName: UnicodeString;
begin
usName:= CeUtf8ToUtf16(Name);
APathType:= GetPathType(Name);
if CheckWin32Version(10)then
if CheckWin32Version(10) or (GetProcAddress(GetModuleHandleW(Kernel32), 'AddDllDirectory') <> nil) then
begin
Result:= LoadLibraryExW(PWideChar(usName), 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR or LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
end
else if CheckWin32Version(6) then
begin
SetDllDirectoryW(PWideChar(ExtractFileDir(usName)));
try
Result:= LoadLibraryW(PWideChar(usName));
finally
SetDllDirectoryW(nil);
if APathType <> ptAbsolute then
dwFlags:= 0
else begin
dwFlags:= LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
end;
Result:= LoadLibraryExW(PWideChar(usName), 0, dwFlags or LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
end
else begin
APath:= mbGetEnvironmentVariable(PATH_ENV);
try
mbSetEnvironmentVariable(PATH_ENV, ExtractFileDir(Name));
Result:= LoadLibraryW(PWideChar(usName));
if APathType <> ptAbsolute then
SetDllDirectoryW(PWideChar(''))
else begin
SetDllDirectoryW(PWideChar(ExtractFileDir(usName)));
end;
try
SetEnvironmentVariableW(PATH_ENV, nil);
Result:= LoadLibraryW(PWideChar(usName));
finally
SetDllDirectoryW(nil);
end;
finally
mbSetEnvironmentVariable(PATH_ENV, APath);
end;
@ -1817,7 +1948,7 @@ begin
end;
{$ELSE}
begin
Result:= TLibHandle(dlopen(PChar(UTF8ToSys(Name)), RTLD_LAZY));
Result:= SafeLoadLibrary(CeUtf8ToSys(Name));
end;
{$ENDIF}
@ -1928,14 +2059,14 @@ begin
end;
{$ENDIF}
function CreateSymLink(const Path, LinkName: string) : Boolean;
function CreateSymLink(const Path, LinkName: string; Attr: UInt32): Boolean;
{$IFDEF MSWINDOWS}
var
wsPath, wsLinkName: UnicodeString;
begin
wsPath:= CeUtf8ToUtf16(Path);
wsLinkName:= UTF16LongName(LinkName);
Result:= DCNtfsLinks.CreateSymlink(wsPath, wsLinkName);
Result:= DCNtfsLinks.CreateSymlink(wsPath, wsLinkName, Attr);
end;
{$ELSE}
begin

View file

@ -27,7 +27,7 @@ uses
type
{ TProcessUtf8 }
{$IF DEFINED(UNIX)}
{$IF DEFINED(UNIX)}
TProcessUtf8 = class(UTF8Process.TProcessUTF8)
private
procedure DoForkEvent(Sender : TObject);
@ -38,12 +38,14 @@ type
function Suspend : Integer; override;
function Terminate (AExitCode : Integer): Boolean; override;
end;
{$ELSEIF DEFINED(MSWINDOWS)}
{$ELSEIF DEFINED(MSWINDOWS) AND (FPC_FULLVERSION < 30301)}
TProcessUtf8 = class(TProcess)
public
procedure Execute; override;
end;
{$ENDIF}
{$ELSE}
TProcessUtf8 = class(TProcess);
{$ENDIF}
implementation
@ -102,7 +104,7 @@ begin
if Result then WaitOnExit;
end;
{$ELSEIF DEFINED(MSWINDOWS)}
{$ELSEIF DEFINED(MSWINDOWS) AND (FPC_FULLVERSION < 30301)}
{$WARN SYMBOL_DEPRECATED OFF}

View file

@ -60,6 +60,7 @@ type
function Add(const S: String): Integer;
function Add(const S: String; ItemData: Pointer): Integer;
procedure Clear;
procedure Remove(Index: Integer);
function Find(const S: String): Integer;
function Find(const S: String; Data: Pointer): Integer;
function Remove(const S: String): Integer;
@ -162,6 +163,15 @@ begin
fCount:= 0;
end;
procedure TStringHashListUtf8.Remove(Index: Integer);
begin
if (Index >= 0) and (Index < FCount) then
begin
Dispose(fList[Index]);
Delete(Index);
end;
end;
function TStringHashListUtf8.CompareString(const Low, Key: String): Boolean;
var
P: Pointer;

View file

@ -3,7 +3,7 @@
-------------------------------------------------------------------------
Useful functions dealing with strings.
Copyright (C) 2006-2023 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2006-2025 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2012 Przemyslaw Nagay (cobines@gmail.com)
This program is free software; you can redistribute it and/or modify
@ -45,6 +45,12 @@ function ContainsOneOf(StringToCheck: String; PossibleCharacters: String): Boole
Convert known directory separators to the current directory separator.
}
function NormalizePathDelimiters(const Path: String): String;
{en
Convert known directory separators to user defined directory separator.
}
function ReplaceDirectorySeparator(const Path: String; const Separator : Char): String;
{en
Get last directory name in path
@returns(Last directory name in path)
@ -365,6 +371,21 @@ implementation
uses
DCOSUtils, DCConvertEncoding, StrUtils;
function ReplaceDirectorySeparator(const Path: String; const Separator : Char): String;
const
AllowPathDelimiters : set of char = ['\','/'];
var
I : LongInt;
begin
Result := Path;
if (Separator in AllowPathDelimiters) then
begin
for I:= 1 to Length(Path) do
if Path[I] in AllowPathDelimiters then
Result[I]:= Separator
end
end;
function NormalizePathDelimiters(const Path: String): String;
{$IFDEF UNIX}
begin
@ -375,11 +396,16 @@ const
AllowPathDelimiters : set of char = ['\','/'];
var
I : LongInt;
uriPos : Integer;
begin
Result:= Path;
// If path is not URI
if Pos('://', Result) = 0 then
begin
uriPos := Pos('://', Result);
if (uriPos = 0)
{$IF DEFINED(MSWINDOWS)}
or ( (uriPos = 2) and (Path[1] in ['A'..'z']) )
{$ENDIF} then
begin
for I:= 1 to Length(Path) do
if Path[I] in AllowPathDelimiters then
Result[I]:= DirectorySeparator;
@ -624,7 +650,7 @@ end;
function ReplaceInvalidChars(const FileName: String): String;
const
{$IFDEF MSWINDOWS}
ForbiddenChars : set of char = ['<','>',':','"','/','|','?','*'];
ForbiddenChars : set of char = [#00..#31, '<','>',':','"','/','|','?','*'];
{$ELSE}
ForbiddenChars : set of char = [#0];
{$ENDIF}
@ -645,7 +671,7 @@ end;
function RemoveInvalidCharsFromFileName(const FileName: String): String;
const
{$IFDEF MSWINDOWS}
ForbiddenChars : set of char = ['<','>',':','"','/','\','|','?','*'];
ForbiddenChars : set of char = [#00..#31, '<','>',':','"','/','\','|','?','*'];
{$ELSE}
ForbiddenChars : set of char = ['/'];
{$ENDIF}
@ -659,34 +685,56 @@ begin
end;
function ExpandAbsolutePath(const Path: String): String;
const
PATH_DELIM_POS = {$IFDEF MSWINDOWS}3{$ELSE}1{$ENDIF};
var
I, J: Integer;
begin
Result := Path;
{First remove all references to '\.\'}
I := Pos (DirectorySeparator + '.' + DirectorySeparator, Result);
// Remove all references to '\.\'
I := Pos(DirectorySeparator + '.' + DirectorySeparator, Result);
while I <> 0 do
begin
Delete (Result, I, 2);
I := Pos (DirectorySeparator + '.' + DirectorySeparator, Result);
end;
if StrEnds(Result, DirectorySeparator + '.') then
Delete (Result, Length(Result) - 1, 2);
begin
Delete(Result, I, 2);
I := Pos(DirectorySeparator + '.' + DirectorySeparator, Result, I);
end;
{Then remove all references to '\..\'}
I := Pos (DirectorySeparator + '..', Result);
while (I <> 0) do
begin
J := Pred (I);
while (J > 0) and (Result [J] <> DirectorySeparator) do
Dec (J);
if (J = 0) then
Delete (Result, I, 3)
else
Delete (Result, J, I - J + 3);
I := Pos (DirectorySeparator + '..', Result);
end;
// Remove all references to '\..\'
I := Pos(DirectorySeparator + '..' + DirectorySeparator, Result);
while I <> 0 do
begin
J := Pred(I);
while (J > 0) and (Result[J] <> DirectorySeparator) do Dec (J);
Delete(Result, J + 1, I - J + 3);
I := Pos(DirectorySeparator + '..' + DirectorySeparator, Result);
end;
// Remove a reference to '\..' at the end of line
if StrEnds(Result, DirectorySeparator + '..') then
begin
J := Length(Result) - 3;
while (J > 0) and (Result[J] <> DirectorySeparator) do Dec(J);
if (J = 0) then
Result := EmptyStr
else if (J > PATH_DELIM_POS) then
Delete(Result, J, MaxInt)
else
Delete(Result, J + 1, MaxInt);
end;
// Remove a reference to '\.' at the end of line
if Length(Result) = 1 then
begin
if Result[1] = '.' then Result := EmptyStr;
end
else if StrEnds(Result, DirectorySeparator + '.') then
begin
if Length(Result) = (PATH_DELIM_POS + 1) then
Delete(Result, Length(Result), 1)
else
Delete(Result, Length(Result) - 1, 2);
end;
end;
function HasPathInvalidCharacters(Path: String): Boolean;

View file

@ -23,7 +23,7 @@ uses
the number of bytes this character spans. If the character was valid
InvalidCharLen is zero.)
}
function SafeUTF8NextCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: Integer): Integer;
function SafeUTF8NextCharLen(P: PByte; aMaxBytes: IntPtr; out InvalidCharLen: Integer): Integer;
{en
Retrieves length in bytes of the previous UTF-8 character.
@ -40,7 +40,7 @@ function SafeUTF8NextCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: I
the number of bytes this character spans. If the character was valid
InvalidCharLen is zero.)
}
function SafeUTF8PrevCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: Integer): Integer;
function SafeUTF8PrevCharLen(P: PByte; aMaxBytes: IntPtr; out InvalidCharLen: Integer): Integer;
function SafeUTF8NextCharStart(UTF8Str: PByte; Len: PtrInt): PByte;
function SafeUTF8PrevCharEnd(UTF8Str: PByte; Len: PtrInt): PByte;
{en
@ -83,7 +83,7 @@ uses
const
maxUTF8Len = 7; // really is 4, but this includes any invalid characters up to length 7
function SafeUTF8NextCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: Integer): Integer;
function SafeUTF8NextCharLen(P: PByte; aMaxBytes: IntPtr; out InvalidCharLen: Integer): Integer;
var
BytesLen: Integer;
i: Integer;
@ -133,7 +133,7 @@ begin
end;
end;
function SafeUTF8PrevCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: Integer): Integer;
function SafeUTF8PrevCharLen(P: PByte; aMaxBytes: IntPtr; out InvalidCharLen: Integer): Integer;
var
BytesLen: Integer;
signature: Byte;
@ -480,7 +480,7 @@ begin
Index:= 0;
SrcPos:= PAnsiChar(UTF8Text);
while Len > 0 do begin
Result[Index]:= UTF8CharacterToUnicode(SrcPos, CharLen);
Result[Index]:= UTF8CodepointToUnicode(SrcPos, CharLen);
Inc(SrcPos, CharLen);
Dec(Len, CharLen);
Inc(Index);

180
components/doublecmd/dcunix.pas Executable file → Normal file
View file

@ -3,7 +3,7 @@
-------------------------------------------------------------------------
This unit contains Unix specific functions
Copyright (C) 2015-2023 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2015-2024 Alexander Koblov (alexx2000@mail.ru)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -40,13 +40,21 @@ const
{$IF DEFINED(LINUX)}
FD_CLOEXEC = 1;
O_CLOEXEC = &02000000;
O_PATH = &010000000;
_SC_NPROCESSORS_ONLN = 84;
{$ELSEIF DEFINED(FREEBSD)}
O_CLOEXEC = &04000000;
_SC_NPROCESSORS_ONLN = 58;
CLOSE_RANGE_CLOEXEC = (1 << 2);
{$ELSEIF DEFINED(NETBSD)}
O_CLOEXEC = $00400000;
{$ELSEIF DEFINED(HAIKU)}
FD_CLOEXEC = 1;
O_CLOEXEC = $00000040;
{$ELSEIF DEFINED(DARWIN)}
F_NOCACHE = 48;
O_CLOEXEC = $1000000;
_SC_NPROCESSORS_ONLN = 58;
{$ELSE}
O_CLOEXEC = 0;
{$ENDIF}
@ -155,6 +163,7 @@ type
{$ELSE}
TDCStat = BaseUnix.Stat;
{$ENDIF}
PDCStat = ^TDCStat;
TDCStatHelper = record Helper for TDCStat
Public
@ -248,6 +257,10 @@ function getgrgid(gid: gid_t): PGroupRecord; cdecl; external clib;
fields of the record in the group database that matches the group name)
}
function getgrnam(name: PChar): PGroupRecord; cdecl; external clib;
{en
Get configuration information at run time
}
function sysconf(name: cint): clong; cdecl; external clib;
function FileLock(Handle: System.THandle; Mode: cInt): System.THandle;
@ -255,12 +268,12 @@ function fpMkTime(tm: PTimeStruct): TTime;
function fpLocalTime(timer: PTime; tp: PTimeStruct): PTimeStruct;
{$IF DEFINED(LINUX)}
var
KernVersion: UInt16;
function fpFDataSync(fd: cint): cint;
function fpCloneFile(src_fd, dst_fd: cint): Boolean;
function fpFAllocate(fd: cint; mode: cint; offset, len: coff_t): cint;
function mbFileGetXattr(const FileName: String): TStringArray;
function mbFileCopyXattr(const Source, Target: String): Boolean;
{$ENDIF}
{$IF DEFINED(UNIX) AND NOT DEFINED(DARWIN)}
@ -271,16 +284,25 @@ implementation
uses
Unix, DCConvertEncoding, LazUTF8
{$IFDEF DARWIN}
{$IF DEFINED(DARWIN)}
, DCDarwin
{$ELSEIF DEFINED(LINUX)}
, Dos, DCLinux, DCOSUtils
{$ELSEIF DEFINED(FREEBSD)}
, DCOSUtils
{$ENDIF}
;
{$IF not DEFINED(LINUX)}
function TDCStatHelper.birthtime: TFileTimeEx;
begin
{$IF DEFINED(HAIKU)}
Result.sec:= st_crtime;
Result.nanosec:= st_crtimensec;
{$ELSE}
Result.sec:= st_birthtime;
Result.nanosec:= st_birthtimensec;
{$ENDIF}
end;
function TDCStatHelper.mtime: TFileTimeEx;
@ -373,8 +395,6 @@ begin
{$ENDIF}
end;
{$IF DEFINED(BSD)}
type rlim_t = Int64;
{$ENDIF}
@ -394,26 +414,44 @@ const
{$ENDIF}
procedure tzset(); cdecl; external clib;
function sysconf(name: cint): clong; cdecl; external clib;
function mktime(tp: PTimeStruct): TTime; cdecl; external clib;
function localtime_r(timer: PTime; tp: PTimeStruct): PTimeStruct; cdecl; external clib;
function lchown(path : PChar; owner : TUid; group : TGid): cInt; cdecl; external clib;
{$IF DEFINED(LINUX)}
function fdatasync(fd: cint): cint; cdecl; external clib;
function fallocate(fd: cint; mode: cint; offset, len: coff_t): cint; cdecl; external clib;
{$ENDIF}
function lremovexattr(const path, name: PAnsiChar): cint; cdecl; external clib;
function llistxattr(const path: PAnsiChar; list: PAnsiChar; size: csize_t): ssize_t; cdecl; external clib;
function lgetxattr(const path, name: PAnsiChar; value: Pointer; size: csize_t): ssize_t; cdecl; external clib;
function lsetxattr(const path, name: PAnsiChar; const value: Pointer; size: csize_t; flags: cint): cint; cdecl; external clib;
{$IF DEFINED(LINUX) OR DEFINED(FREEBSD)}
var
hLibC: TLibHandle = NilHandle;
procedure LoadCLibrary;
begin
hLibC:= mbLoadLibrary(mbGetModuleName(@tzset));
end;
{$ENDIF}
{$IF DEFINED(LINUX) OR DEFINED(BSD)}
var
close_range: function(first: cuint; last: cuint; flags: cint): cint; cdecl = nil;
{$ENDIF}
procedure FileCloseOnExecAll;
const
MAX_FD = 1024;
var
fd: cint;
p: TRLimit;
fd_max: rlim_t = RLIM_INFINITY;
begin
{$IF DEFINED(LINUX) OR DEFINED(BSD)}
if Assigned(close_range) then
begin
close_range(3, High(Int32), CLOSE_RANGE_CLOEXEC);
Exit;
end;
{$ENDIF}
if (FpGetRLimit(RLIMIT_NOFILE, @p) = 0) and (p.rlim_cur <> RLIM_INFINITY) then
fd_max:= p.rlim_cur
else begin
@ -421,8 +459,8 @@ begin
fd_max:= sysconf(_SC_OPEN_MAX);
{$ENDIF}
end;
if fd_max = RLIM_INFINITY then
fd_max:= High(Byte);
if (fd_max = RLIM_INFINITY) or (fd_max > MAX_FD) then
fd_max:= MAX_FD;
for fd:= 3 to cint(fd_max) do
FileCloseOnExec(fd);
end;
@ -505,6 +543,7 @@ begin
if (fpFStatFS(Handle, @Sbfs) = 0) then
begin
case UInt32(Sbfs.fstype) of
NFS_SUPER_MAGIC,
SMB_SUPER_MAGIC,
SMB2_MAGIC_NUMBER,
CIFS_MAGIC_NUMBER: Exit;
@ -558,103 +597,28 @@ begin
Result := fallocate(fd, mode, offset, len);
if Result = -1 then fpseterrno(fpgetCerrno);
end;
function mbFileGetXattr(const FileName: String): TStringArray;
var
AList: String;
ALength: ssize_t;
AFileName: String;
begin
SetLength(AList, MaxSmallint);
Result:= Default(TStringArray);
AFileName:= CeUtf8ToSys(FileName);
ALength:= llistxattr(PAnsiChar(AFileName), Pointer(AList), Length(AList));
if (ALength < 0) then
begin
if (fpgetCerrno <> ESysERANGE) then
begin
fpseterrno(fpgetCerrno);
Exit;
end
else begin
ALength:= llistxattr(PAnsiChar(AFileName), nil, 0);
if ALength < 0 then
begin
fpseterrno(fpgetCerrno);
Exit;
end;
SetLength(AList, ALength);
ALength:= llistxattr(PAnsiChar(AFileName), Pointer(AList), ALength);
if ALength < 0 then
begin
fpseterrno(fpgetCerrno);
Exit;
end;
end;
end;
if (ALength > 0) then
begin
SetLength(AList, ALength - 1);
Result:= AList.Split(#0);
end;
end;
function mbFileCopyXattr(const Source, Target: String): Boolean;
var
Value: String;
Index: Integer;
ALength: ssize_t;
Names: TStringArray;
ASource, ATarget: String;
begin
Result:= True;
ASource:= CeUtf8ToSys(Source);
ATarget:= CeUtf8ToSys(Target);
// Remove attributes from target
Names:= mbFileGetXattr(Target);
for Index:= 0 to High(Names) do
begin
lremovexattr(PAnsiChar(ATarget), PAnsiChar(Names[Index]));
end;
SetLength(Value, MaxSmallint);
Names:= mbFileGetXattr(Source);
for Index:= 0 to High(Names) do
begin
ALength:= lgetxattr(PAnsiChar(ASource), PAnsiChar(Names[Index]), Pointer(Value), Length(Value));
if (ALength < 0) then
begin
if (fpgetCerrno <> ESysERANGE) then
begin
fpseterrno(fpgetCerrno);
Exit(False);
end
else begin
ALength:= lgetxattr(PAnsiChar(ASource), PAnsiChar(Names[Index]), nil, 0);
if ALength < 0 then
begin
fpseterrno(fpgetCerrno);
Exit(False);
end;
SetLength(Value, ALength);
ALength:= lgetxattr(PAnsiChar(ASource), PAnsiChar(Names[Index]), Pointer(Value), Length(Value));
if ALength < 0 then
begin
fpseterrno(fpgetCerrno);
Exit(False);
end;
end;
end;
if (lsetxattr(PAnsiChar(ATarget), PAnsiChar(Names[Index]), Pointer(Value), ALength, 0) < 0) then
begin
fpseterrno(fpgetCerrno);
Exit(fpgeterrno = ESysEOPNOTSUPP);
end;
end;
end;
{$ENDIF}
initialization
procedure Initialize;
begin
tzset();
{$IF DEFINED(LINUX) OR DEFINED(FREEBSD)}
LoadCLibrary;
{$IF DEFINED(LINUX)}
KernVersion:= BEtoN(DosVersion);
// Linux kernel >= 5.11
if KernVersion >= $50B then
{$ENDIF}
begin
Pointer(close_range):= GetProcAddress(hLibC, 'close_range');
end;
{$ELSEIF DEFINED(DARWIN)}
close_range:= @CloseRange;
{$ENDIF}
end;
initialization
Initialize;
end.

40
components/doublecmd/dcxmlconfig.pas Normal file → Executable file
View file

@ -6,6 +6,7 @@
Based on XmlConf from fcl-xml package.
Copyright (C) 2010 Przemyslaw Nagay (cobines@gmail.com)
Copyright (C) 2013-2023 Alexander Koblov (alexx2000@mail.ru)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -21,6 +22,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
}
unit DCXmlConfig;
{$mode objfpc}{$H+}
@ -117,7 +119,7 @@ type
// ------------------------------------------------------------------------
procedure GetFont(const aNode: TXmlNode; Path: TXmlPath;
out Name: String; out Size: Integer; out Style, Quality: Integer;
var Name: String; var Size: Integer; var Style, Quality: Integer;
const DefName: String; const DefSize: Integer; const DefStyle, DefQuality: Integer);
procedure SetFont(const aNode: TXmlNode; Path: TXmlPath;
@ -149,7 +151,10 @@ type
implementation
uses
LazLogger, DCOSUtils, DCClassesUtf8, URIParser;
LazLogger, DCBasicTypes, DCOSUtils, DCClassesUtf8, URIParser;
const
XML_READER_FLAGS = [xrfAllowSpecialCharsInAttributeValue];
const
BoolStrings: array[Boolean] of DOMString = ('False', 'True');
@ -525,7 +530,7 @@ begin
try
if FileStream.Size = 0 then
raise EXmlConfigEmpty.Create('');
ReadXMLFile(TmpDoc, FileStream, FilenameToURI(AFilename), []);
ReadXMLFile(TmpDoc, FileStream, FilenameToURI(AFilename), XML_READER_FLAGS);
if TmpDoc.DocumentElement.NodeName <> ApplicationName then
raise EXMLReadError.Create('Root element is not <' + ApplicationName + '>.');
FDoc.Free;
@ -541,18 +546,19 @@ var
begin
if AStream.Size = 0 then
raise EXmlConfigEmpty.Create('');
ReadXMLFile(TmpDoc, AStream, []);
ReadXMLFile(TmpDoc, AStream, XML_READER_FLAGS);
FDoc.Free;
FDoc := TmpDoc;
end;
procedure TXmlConfig.WriteToFile(const AFilename: String);
var
FileStream: TStream;
FileStream: TFileStreamEx;
begin
FileStream := TFileStreamEx.Create(AFilename, fmCreate or fmShareDenyWrite);
try
WriteToStream(FileStream);
FileStream.Flush;
finally
FileStream.Free;
end;
@ -611,6 +617,8 @@ end;
function TXmlConfig.Save: Boolean;
var
AFileName: String;
dwAttr: TFileAttrs;
bFileExists: Boolean;
sTmpConfigFileName: String;
begin
@ -619,17 +627,25 @@ begin
if FFileName = '' then
Exit;
bFileExists := mbFileExists(FileName);
dwAttr := mbFileGetAttr(FileName);
bFileExists := (dwAttr <> faInvalidAttributes) and (not FPS_ISDIR(dwAttr));
if bFileExists and FPS_ISLNK(dwAttr) then
AFileName := mbReadAllLinks(FileName)
else begin
AFileName := FileName;
end;
// Write to temporary file and if successfully written rename to proper name.
if (not bFileExists) or mbFileAccess(FileName, fmOpenWrite or fmShareDenyWrite) then
if (not bFileExists) or mbFileAccess(AFileName, fmOpenWrite or fmShareDenyWrite) then
begin
sTmpConfigFileName := GetTempName(FileName);
sTmpConfigFileName := GetTempName(AFileName);
try
WriteToFile(sTmpConfigFileName);
if bFileExists then begin
mbFileCopyAttr(FileName, sTmpConfigFileName, [caoCopyOwnership, caoCopyPermissions]);
mbFileCopyAttr(AFileName, sTmpConfigFileName, [caoCopyOwnership, caoCopyPermissions]);
end;
if not mbRenameFile(sTmpConfigFileName, FileName) then
if not mbRenameFile(sTmpConfigFileName, AFileName) then
begin
mbDeleteFile(sTmpConfigFileName);
DebugLogger.Debugln('Cannot save configuration file ', FileName);
@ -776,8 +792,8 @@ begin
end;
end;
procedure TXmlConfig.GetFont(const aNode: TXmlNode; Path: TXmlPath; out
Name: String; out Size: Integer; out Style, Quality: Integer;
procedure TXmlConfig.GetFont(const aNode: TXmlNode; Path: TXmlPath; var
Name: String; var Size: Integer; var Style, Quality: Integer;
const DefName: String; const DefSize: Integer; const DefStyle,
DefQuality: Integer);
begin

View file

@ -8,6 +8,8 @@
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="iconvenc"/>
<OtherUnitFiles Value="iconvenc"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Conditionals Value="if (TargetCPU &lt;> &apos;arm&apos;) then
@ -34,7 +36,7 @@ end"/>
</CompilerOptions>
<Description Value="Common units for Double Commander"/>
<License Value="GNU GPL 2"/>
<Version Minor="4" Release="1"/>
<Version Minor="4" Release="2"/>
<Files Count="12">
<Item1>
<Filename Value="dcclassesutf8.pas"/>

View file

@ -1,17 +1,17 @@
{ This file was automatically created by Lazarus. Do not edit!
This source is only used to compile and install the package.
}
unit doublecmd_common;
{$warn 5023 off : no warning about unused units}
interface
uses
DCClassesUtf8, DCOSUtils, DCStrUtils, DCBasicTypes, DCFileAttributes,
DCConvertEncoding, DCDateTimeUtils, DCXmlConfig, DCProcessUtf8,
DCUnicodeUtils, DCStringHashListUtf8, DCJsonConfig;
implementation
end.
{ This file was automatically created by Lazarus. Do not edit!
This source is only used to compile and install the package.
}
unit doublecmd_common;
{$warn 5023 off : no warning about unused units}
interface
uses
DCClassesUtf8, DCOSUtils, DCStrUtils, DCBasicTypes, DCFileAttributes,
DCConvertEncoding, DCDateTimeUtils, DCXmlConfig, DCProcessUtf8,
DCUnicodeUtils, DCStringHashListUtf8, DCJsonConfig;
implementation
end.

View file

@ -0,0 +1,106 @@
{
This file is part of the Free Pascal run time library.
Copyright (c) 2000 by Marco van de Voort(marco@freepascal.org)
member of the Free Pascal development team
libiconv header translation + a helper routine
http://wiki.freepascal.org/iconvenc Dynamic version
See the file COPYING.FPC, included in this distribution,
for details about the copyright. (LGPL)
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
}
unit dc_iconvenc_dyn;
interface
{$mode objfpc}{$H+}
uses
ctypes,unixtype,baseunix,
dl,
initc;
const
n = 1;
{$ifdef beos}
ESysEILSEQ = EILSEQ;
{$endif}
type
piconv_t = ^iconv_t;
iconv_t = pointer;
Ticonv_open = function(__tocode: pchar; __fromcode: pchar): iconv_t; cdecl;
Ticonv = function(__cd: iconv_t; __inbuf: ppchar; __inbytesleft: psize_t; __outbuf: ppchar; __outbytesleft: psize_t): size_t; cdecl;
Ticonv_close = function(__cd: iconv_t): cint; cdecl;
var
iconv_lib: pointer;
iconv_open: Ticonv_open;
iconv: Ticonv;
iconv_close: Ticonv_close;
IconvLibFound: boolean = False;
function TryLoadLib(LibName: string; var error: string): boolean; // can be used to load non standard libname
function Iconvert(s: string; var res: string; const FromEncoding, ToEncoding: string): cint;
function InitIconv(var error: string): boolean;
implementation
function TryLoadLib(LibName: string; var error: string): boolean;
function resolvesymbol (var funcptr; symbol: string): Boolean;
begin
pointer(funcptr) := pointer(dlsym(iconv_lib, pchar(symbol)));
result := assigned(pointer(funcptr));
if not result then
error := error+#13#10+dlerror();
end;
var
res: boolean;
begin
result := false;
Error := Error+#13#10'Trying '+LibName;
iconv_lib := dlopen(pchar(libname), RTLD_NOW);
if Assigned(iconv_lib) then
begin
result := true;
result := result and resolvesymbol(pointer(iconv),'iconv');
result := result and resolvesymbol(pointer(iconv_open),'iconv_open');
result := result and resolvesymbol(pointer(iconv_close),'iconv_close');
if not result then
begin
result:=true;
result := result and resolvesymbol(pointer(iconv),'libiconv');
result := result and resolvesymbol(pointer(iconv_open),'libiconv_open');
result := result and resolvesymbol(pointer(iconv_close),'libiconv_close');
end;
// if not res then
// dlclose(iconv_lib);
end else
error:=error+#13#10+dlerror();
end;
function InitIconv(var error: string): boolean;
begin
result := true;
error := '';
if not TryLoadLib('libc.so.6', error) then
if not TryLoadLib('libiconv.so', error) then
{$if defined(haiku)}
if not TryLoadLib('libtextencoding.so', error) then
{$ifend}
result := false;
iconvlibfound := iconvlibfound or result;
end;
{$i dc_iconvert.inc}
end.

View file

@ -0,0 +1,53 @@
function Iconvert(S: string; var Res: string; const FromEncoding, ToEncoding: string): cint;
var
InLen, OutLen, Offset: size_t;
Src, Dst: pchar;
H: iconv_t;
lerr: cint;
iconvres: size_t;
begin
H := iconv_open(PChar(ToEncoding), PChar(FromEncoding));
if h=Iconv_t(-1) then
begin
Res := S;
exit(-1);
end;
try
InLen:=Length(s);
outlen:=InLen;
setlength(res,outlen);
Src := PChar(S);
Dst := PChar(Res);
while InLen > 0 do
begin
iconvres := iconv(H, @Src, @InLen, @Dst, @OutLen);
if iconvres = size_t(-1) then
begin
lerr := cerrno;
if lerr = ESysEILSEQ then // unknown char, skip
begin
Inc(Src);
Dec(InLen);
end
else
if lerr = ESysE2BIG then
begin
Offset := Dst - PChar(Res);
SetLength(Res, Length(Res)+InLen*2+5); // 5 is minimally one utf-8 char
Dst := PChar(Res) + Offset;
OutLen := Length(Res) - Offset;
end
else
exit(-1)
end;
end;
finally
setlength(Res,Length(Res) - Outlen);
iconv_close(H);
end;
Result := 0;
end;

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

Before After
Before After

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