mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
Compare commits
2,294 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1f7784288 | ||
|
|
b2d943430e | ||
|
|
c393e90939 | ||
|
|
59e3bdce3c | ||
|
|
ed6d2a875d | ||
|
|
35c02857da | ||
|
|
b8cd177ba3 | ||
|
|
f857fb19fd | ||
|
|
e26d1c1cdb | ||
|
|
10428e142b | ||
|
|
64a37d0c69 | ||
|
|
54d6654ad1 | ||
|
|
0e7285f3e0 | ||
|
|
487a3602cc | ||
|
|
780a53bffc | ||
|
|
44b1ebfb9a | ||
|
|
a26474651f | ||
|
|
2f70adb75b | ||
|
|
af2894c6ef | ||
|
|
887f34e670 | ||
|
|
b2cb9435c5 | ||
|
|
9b4c0854da | ||
|
|
6d0fcfee45 | ||
|
|
9597fcd28d | ||
|
|
55006f111a | ||
|
|
e853d5237e | ||
|
|
81f889e677 | ||
|
|
dae67778de | ||
|
|
630c19c2f2 | ||
|
|
35304eb238 | ||
|
|
9b49371938 | ||
|
|
9add69adef | ||
|
|
dd3f3f70db | ||
|
|
77a97865cf | ||
|
|
4cc05afbf0 | ||
|
|
d586796cc0 | ||
|
|
fda9362805 | ||
|
|
be807fdb54 | ||
|
|
4594d225d5 | ||
|
|
7db7e41489 | ||
|
|
53f9c3c42f | ||
|
|
9cabced1e8 |
||
|
|
ef570c9af4 | ||
|
|
1d49ade80b | ||
|
|
3276638149 | ||
|
|
969fc8d240 | ||
|
|
33bf56ea9b | ||
|
|
34013fda7d | ||
|
|
e9c05e6aaf | ||
|
|
a260581a01 | ||
|
|
3e869b4d9a | ||
|
|
818a171374 | ||
|
|
9781239310 | ||
|
|
39ef1ea0f3 | ||
|
|
56a26c8568 | ||
|
|
7a22f56648 | ||
|
|
888b9ee558 | ||
|
|
5dec42098a | ||
|
|
55299c7771 | ||
|
|
18bc5f7a6e | ||
|
|
0439ed958b | ||
|
|
de67618dd8 | ||
|
|
ed2cc821b2 | ||
|
|
bebe20e6f9 | ||
|
|
e9f3c49ed8 | ||
|
|
0702ce507b | ||
|
|
d47f5f91af | ||
|
|
cf6e1725e1 | ||
|
|
145a333a44 | ||
|
|
08cc9d88c4 | ||
|
|
ec5afcc3b0 | ||
|
|
f2ffcd3e56 | ||
|
|
f08d3af019 | ||
|
|
89ce532f2c | ||
|
|
b5ceffa7c4 | ||
|
|
de9e30608c | ||
|
|
33ec2efc9f | ||
|
|
733fb94cd7 | ||
|
|
5ccb678297 | ||
|
|
a7e860aa16 | ||
|
|
a3b021ee76 | ||
|
|
32a3016ee0 | ||
|
|
f5b670bc2d | ||
|
|
4e7a2ccba3 | ||
|
|
160cf95492 | ||
|
|
76e7585c30 | ||
|
|
714d00fcec | ||
|
|
d843b84a80 | ||
|
|
19bfc7bc06 | ||
|
|
5af28c634e | ||
|
|
c007bfa8e8 | ||
|
|
7e82c17bcf | ||
|
|
9f4bca8c66 | ||
|
|
b32aac982c | ||
|
|
744a272ba7 | ||
|
|
09c3f0de70 | ||
|
|
6a1bb39235 | ||
|
|
4e5db6ccf0 | ||
|
|
8ba4152f6d | ||
|
|
edccfff2c2 | ||
|
|
ee966f872f | ||
|
|
a6cdd5849a | ||
|
|
0a146e0119 | ||
|
|
89154db05d | ||
|
|
2347cc3f30 | ||
|
|
3764ee267c | ||
|
|
7749d73320 | ||
|
|
a5a8437211 | ||
|
|
6ace022260 | ||
|
|
7084211fc6 | ||
|
|
bdfb57b282 | ||
|
|
844cfd64a8 | ||
|
|
7f6e77ae73 | ||
|
|
e864d3458a | ||
|
|
da0d4e5c56 | ||
|
|
05b135967a | ||
|
|
a62f046a94 | ||
|
|
05c1e0e6bb | ||
|
|
98533a9d15 | ||
|
|
b1426fd06d | ||
|
|
df9eb65110 | ||
|
|
fe307c98e4 | ||
|
|
214e61eb13 | ||
|
|
4bde5beaee | ||
|
|
ef92d2660b | ||
|
|
9213dd929e | ||
|
|
d61293302e | ||
|
|
523c15e297 | ||
|
|
d2971bd587 | ||
|
|
1682fc7690 | ||
|
|
ef724fa7d2 | ||
|
|
5267c3387f | ||
|
|
8db33ee722 | ||
|
|
879ef8c6da | ||
|
|
7bcf801792 | ||
|
|
f5ed3acdfa | ||
|
|
c0e020f675 | ||
|
|
a588ff1c95 | ||
|
|
701927f0de | ||
|
|
5b7cddf5c5 | ||
|
|
ed931d1894 | ||
|
|
c25aeeafb6 |
||
|
|
5d2ec82799 | ||
|
|
0b6f62b153 | ||
|
|
7af7de1d8a | ||
|
|
b5f9bae122 | ||
|
|
7c0b46c0e7 | ||
|
|
7d1f047d86 | ||
|
|
2e4316dd39 | ||
|
|
4178f6e58f | ||
|
|
b51733f25e | ||
|
|
45895ad0ed | ||
|
|
0fa82eceb8 | ||
|
|
d90959dbf0 | ||
|
|
56098e1312 | ||
|
|
b05b79bc9a | ||
|
|
3fabe6aef5 | ||
|
|
6b1a346caa | ||
|
|
3e601a1940 |
||
|
|
0ec7b7e32b | ||
|
|
307a682f27 |
||
|
|
adb32099c9 |
||
|
|
59607049b2 |
||
|
|
246f410673 | ||
|
|
92fdf16192 | ||
|
|
a4c174d5ba | ||
|
|
6123a21ed0 |
||
|
|
10a51f880a | ||
|
|
617493ec78 | ||
|
|
4843768305 | ||
|
|
d0140b8834 |
||
|
|
27ca1b3be0 | ||
|
|
5e7a25c691 | ||
|
|
0291126ba2 | ||
|
|
7cf22b45ea | ||
|
|
8918485f72 | ||
|
|
f695bd75ae | ||
|
|
c6ff324ae8 | ||
|
|
ebbe447b1d | ||
|
|
8c3e18eee8 | ||
|
|
961eeb5e24 | ||
|
|
acf007f698 | ||
|
|
ab77a7183f | ||
|
|
e49ddec96c | ||
|
|
e7d8c81a34 | ||
|
|
9088062dec | ||
|
|
77a97a25ed | ||
|
|
e0f075beea | ||
|
|
34c7eb23c0 | ||
|
|
44a15d3e09 | ||
|
|
79ccbfddb3 | ||
|
|
72d5efc80e | ||
|
|
6e5a8a4d21 | ||
|
|
f0a56568d1 | ||
|
|
ec59b39ddb | ||
|
|
91d2178bc7 | ||
|
|
d8426b25b6 | ||
|
|
837cc08394 | ||
|
|
d03fa06aee | ||
|
|
198b296abc | ||
|
|
65d7f5180c | ||
|
|
d002cdc373 | ||
|
|
7c34dfe389 | ||
|
|
043cb97b90 | ||
|
|
97ca989239 | ||
|
|
7851fb014f | ||
|
|
be400728aa | ||
|
|
b44064eb2c | ||
|
|
d9920c2839 | ||
|
|
a5bf4ea880 | ||
|
|
9d285f8e4b | ||
|
|
12d6002a70 | ||
|
|
e5926d7329 | ||
|
|
b3f9dd2b3f | ||
|
|
b7ea4cdf03 | ||
|
|
015e8f3ff5 | ||
|
|
4d6c1e86ad | ||
|
|
c550a0443d | ||
|
|
2b8a209a21 | ||
|
|
ecf3b8196a | ||
|
|
ae48e071ca | ||
|
|
e4931b1235 | ||
|
|
bbb0653d14 | ||
|
|
2c401b9945 | ||
|
|
75954f00f6 | ||
|
|
c753d6f3cc | ||
|
|
35ac84e565 | ||
|
|
765825f714 | ||
|
|
cb25db5dac | ||
|
|
765391e798 | ||
|
|
d2a14e9c26 | ||
|
|
93b08bfeca | ||
|
|
1cf4aa5876 | ||
|
|
eb40609250 | ||
|
|
151b8faf18 | ||
|
|
84fbc76bb3 | ||
|
|
092b9c716b |
||
|
|
31ea6a2032 | ||
|
|
e748d401cc | ||
|
|
a48a556ee6 | ||
|
|
22020d2e85 | ||
|
|
b812db501c | ||
|
|
b90bfebe33 | ||
|
|
f9108d3e0c | ||
|
|
6ab558fbef | ||
|
|
86cb17aa1b | ||
|
|
218e68fc40 | ||
|
|
dced7dd931 | ||
|
|
ad51ed749e | ||
|
|
5f8743c335 | ||
|
|
1d9a690049 | ||
|
|
5383506866 | ||
|
|
685a15bcdf | ||
|
|
c7784ec536 | ||
|
|
c202082fa9 | ||
|
|
5b2f484fd7 | ||
|
|
3838d61125 | ||
|
|
d561e7f146 | ||
|
|
3b1c244ed9 | ||
|
|
26733e1ad9 | ||
|
|
b95e3a0aa4 | ||
|
|
92a94be1a8 | ||
|
|
028529f5d4 | ||
|
|
6f9517675e | ||
|
|
f8cec8aa5b | ||
|
|
cd0df9ff03 | ||
|
|
ef5b6ce6f5 | ||
|
|
60e0f669fd | ||
|
|
72e8732ed6 | ||
|
|
84f71abbc0 | ||
|
|
bc6c15ca9a | ||
|
|
09e7229cc8 | ||
|
|
7283d74399 | ||
|
|
5c4f6d0299 | ||
|
|
3ddb204fdc | ||
|
|
5e067cbc0b | ||
|
|
a20e0931b3 | ||
|
|
0368a6e40d | ||
|
|
a9d0801efb | ||
|
|
3916b3abcb | ||
|
|
1deb745de2 | ||
|
|
408e76e69a | ||
|
|
8a253a806f | ||
|
|
9e4df1c980 | ||
|
|
fa2b57c453 | ||
|
|
c9325738aa | ||
|
|
b171ec1f3a | ||
|
|
96c53ce2d9 | ||
|
|
0673a19546 |
||
|
|
b33bb79302 | ||
|
|
13c1a12a8e | ||
|
|
147cbde8d0 | ||
|
|
f8dd7d0751 | ||
|
|
bc7d7207fe | ||
|
|
f9f2487868 | ||
|
|
1d4f994af8 | ||
|
|
ea416ee321 | ||
|
|
4c4d9ee02d | ||
|
|
a41beeaf38 | ||
|
|
7eb4b23263 | ||
|
|
d98f8e642d | ||
|
|
6be67cfb80 | ||
|
|
b4ee7f9206 | ||
|
|
4fd4024661 | ||
|
|
b9ae1a170f | ||
|
|
0a66df886b | ||
|
|
4faeb6a6fc | ||
|
|
870bdf8b91 | ||
|
|
70f946eb7a | ||
|
|
4a0514711e | ||
|
|
5c8e18b7f9 | ||
|
|
814f6dfc6c | ||
|
|
067161fc93 | ||
|
|
c6c6c0c15a | ||
|
|
af11aa348b | ||
|
|
d572592446 | ||
|
|
e451308c6c | ||
|
|
a13ab41a13 | ||
|
|
0d43aa44d8 | ||
|
|
f98b9a8ece | ||
|
|
41576ba31b | ||
|
|
6d96a149f3 | ||
|
|
79e7e7014a | ||
|
|
ae575fa1c9 | ||
|
|
56dea7477d | ||
|
|
b6579cd71b | ||
|
|
55e92df88e | ||
|
|
0bdad89796 | ||
|
|
2b0d593338 | ||
|
|
62ebd48f22 | ||
|
|
3c19843873 | ||
|
|
214957c269 | ||
|
|
698d682e04 | ||
|
|
a8ebb41c81 | ||
|
|
de6219e1e6 | ||
|
|
3666aba90b | ||
|
|
6c28e7e324 | ||
|
|
40ddf63248 | ||
|
|
f5b45359e0 | ||
|
|
9805aa9184 | ||
|
|
fd4a7ba777 | ||
|
|
06669eeed7 | ||
|
|
2551f0b972 | ||
|
|
1b573d4694 | ||
|
|
0e1f6fffd8 | ||
|
|
cd2367212b | ||
|
|
61a976d182 | ||
|
|
731071daec | ||
|
|
beb65d5fa6 | ||
|
|
cf8a766615 | ||
|
|
24ffc65d16 | ||
|
|
db2d2e7da6 | ||
|
|
ce6f5b42e0 | ||
|
|
f54be93165 | ||
|
|
448e3d2d75 | ||
|
|
4947949834 | ||
|
|
7367b66385 | ||
|
|
f8342e72a1 | ||
|
|
5f6bfb8b5a |
||
|
|
e608cef4bf | ||
|
|
6199cb56f8 | ||
|
|
1cd11e5813 | ||
|
|
b0912aa7e3 | ||
|
|
1bb5c37eb8 | ||
|
|
4816772ac3 | ||
|
|
927ed4ad8d | ||
|
|
7155a8a61f | ||
|
|
1fdad400b9 | ||
|
|
cb9b8f797a | ||
|
|
10bf49637e | ||
|
|
904eb2d016 | ||
|
|
79f551a74d | ||
|
|
3b6d4d1180 | ||
|
|
63b7fd155f | ||
|
|
dd391e22b7 | ||
|
|
76d4ba16ec | ||
|
|
c5b48c6db0 | ||
|
|
3f9e3d35a4 |
||
|
|
1419f3aaac | ||
|
|
ea8928907e |
||
|
|
410c0a1c99 |
||
|
|
a2e63d01b6 | ||
|
|
25c4e77e39 | ||
|
|
e5d1c0b305 | ||
|
|
2aea141aff | ||
|
|
f2eb7513c8 | ||
|
|
506b6b0d74 | ||
|
|
d4b78d952e | ||
|
|
0952d72006 | ||
|
|
707dbe43b5 |
||
|
|
6b4b0c84e4 | ||
|
|
67b86b6195 | ||
|
|
65119380d7 | ||
|
|
32c34dc006 | ||
|
|
285e7ba1f8 | ||
|
|
284a5aab24 | ||
|
|
86b2d918bb | ||
|
|
c39d3974be | ||
|
|
6c9a21c2c7 | ||
|
|
186e70881f | ||
|
|
c1f3a21978 | ||
|
|
09b6398aaa | ||
|
|
e0c6adf681 | ||
|
|
758c204864 | ||
|
|
46ad6779c1 | ||
|
|
fd02b5c048 | ||
|
|
3952582346 | ||
|
|
61d51b21fa | ||
|
|
2596a2582d | ||
|
|
68304a6949 | ||
|
|
43315118f2 | ||
|
|
61d2ecbc1f | ||
|
|
e4c8873b33 | ||
|
|
f103ead98b | ||
|
|
02ecead8d5 | ||
|
|
65936a489e | ||
|
|
1697f71867 | ||
|
|
80c74dd049 | ||
|
|
d925b50f38 | ||
|
|
c6bd4d10f2 | ||
|
|
285b91bb7a | ||
|
|
3793d5a118 | ||
|
|
37e7749fe8 | ||
|
|
8d784194e6 | ||
|
|
3102018072 | ||
|
|
d4ed1c0042 | ||
|
|
e462115f6a | ||
|
|
e3d501af4b | ||
|
|
748d20a584 | ||
|
|
0e8632c63e | ||
|
|
97b8f1e4e6 | ||
|
|
6371bf2df8 | ||
|
|
93a164ecca | ||
|
|
293a827834 | ||
|
|
44c05b6a65 | ||
|
|
8a36e69eba | ||
|
|
c3d6a09ac6 | ||
|
|
ddb9a6c2b0 | ||
|
|
fcf07a7ebb | ||
|
|
039946e768 | ||
|
|
828829ff70 | ||
|
|
18a2b676cc | ||
|
|
87eae46ea8 | ||
|
|
f24e4fdaa8 | ||
|
|
80a332c42f | ||
|
|
f7ca812c3c | ||
|
|
58a09913c9 | ||
|
|
95a8e46db2 | ||
|
|
b680e8aa77 | ||
|
|
ce8d4cfc15 | ||
|
|
60aedea303 | ||
|
|
ea58f2c931 | ||
|
|
fd0d3f161d | ||
|
|
797c6f6553 | ||
|
|
d56a7ed764 | ||
|
|
e48c97b9e8 | ||
|
|
985fab5f00 | ||
|
|
e22b633ffa |
||
|
|
17c092540d | ||
|
|
907d25467f | ||
|
|
ab390e93ce | ||
|
|
b9573559b9 | ||
|
|
a8c875ec27 | ||
|
|
ce6f58dbda | ||
|
|
ec27554fad | ||
|
|
8166903a49 | ||
|
|
1e406c4e06 | ||
|
|
98ef204fab | ||
|
|
f75fbdaecf | ||
|
|
529c9a1fc7 | ||
|
|
c63d8cd385 | ||
|
|
a4b91314c4 | ||
|
|
d7d1828978 | ||
|
|
67218a975d | ||
|
|
ccfeba379b | ||
|
|
2c6b559f8b | ||
|
|
e464e57171 | ||
|
|
2aa0cc9212 | ||
|
|
a980dc77a4 | ||
|
|
71c2d63aa8 | ||
|
|
9f8c2c9dd7 | ||
|
|
8d5395ab65 | ||
|
|
395cebd3bb | ||
|
|
b1a181df1d | ||
|
|
da809f4be8 | ||
|
|
ce0ef49b18 | ||
|
|
78a45e234c | ||
|
|
3da73c7785 | ||
|
|
b753e8b668 | ||
|
|
550867896d | ||
|
|
e206e475c2 | ||
|
|
36dcb932d0 | ||
|
|
5835c60a79 | ||
|
|
443c057ec9 | ||
|
|
41099979ed | ||
|
|
88ca967887 | ||
|
|
54b1f61c60 | ||
|
|
d2451b17e0 | ||
|
|
ca9e169610 | ||
|
|
a445ba431c | ||
|
|
7991af0a06 | ||
|
|
0524bcd4e8 | ||
|
|
53a3a51976 | ||
|
|
e8ed94f129 | ||
|
|
b90e846b7c | ||
|
|
7e233b001a | ||
|
|
694b14cf43 | ||
|
|
624384091f | ||
|
|
9c80e25bb4 | ||
|
|
8fbde876e5 | ||
|
|
121e7ad777 | ||
|
|
3ba2a35462 | ||
|
|
a502dc40de | ||
|
|
931f24fcdb | ||
|
|
fcba5ce8ee | ||
|
|
1072d4d8b2 | ||
|
|
c98327bd5e | ||
|
|
6a832f75f3 | ||
|
|
4730243941 | ||
|
|
2648c2bed2 | ||
|
|
91322b9506 | ||
|
|
4ec86ca2f1 | ||
|
|
8e147eeefc | ||
|
|
c1cfc84933 | ||
|
|
f56d2b3219 | ||
|
|
8c47d3cfc6 | ||
|
|
937321ccd5 | ||
|
|
3229e8a7b1 | ||
|
|
15e1e82887 | ||
|
|
56b1f70baa | ||
|
|
dd22c4ff7c | ||
|
|
da0410a472 | ||
|
|
4acde0cbe7 | ||
|
|
0575cff75e | ||
|
|
20c86c58bf | ||
|
|
3d4dc7d6fc | ||
|
|
a2518d930f | ||
|
|
3e09c8c56b | ||
|
|
ee29c08428 | ||
|
|
6d25dc8bcc | ||
|
|
c2b20fe970 | ||
|
|
f7911094b3 | ||
|
|
e7c9b0579a | ||
|
|
3ebc9c7d7e | ||
|
|
3a6893dc51 | ||
|
|
0bb904d006 | ||
|
|
d0d51b6474 | ||
|
|
c6e5bf89db | ||
|
|
87e20b5615 | ||
|
|
1a99e510c8 | ||
|
|
8f5977e63b | ||
|
|
dd3d54ca31 | ||
|
|
6208c4a832 | ||
|
|
9dad38408a | ||
|
|
a46139cea0 | ||
|
|
a8c21bc879 | ||
|
|
6f46526451 | ||
|
|
54d6fd516b | ||
|
|
cff28911e5 | ||
|
|
f6dcf0fd46 | ||
|
|
900342d648 | ||
|
|
a971639d45 | ||
|
|
e8ec4ecb01 | ||
|
|
aff2d61421 | ||
|
|
d6f468ddd4 | ||
|
|
59a8e395ed | ||
|
|
5cac3685fd | ||
|
|
e69d6ee4c2 | ||
|
|
5fd8496570 | ||
|
|
cc00605fa5 | ||
|
|
3fa8359330 | ||
|
|
1f48c04e20 | ||
|
|
5e32ec839b | ||
|
|
8eafe61176 | ||
|
|
66cfdbda08 | ||
|
|
5cfe18488d | ||
|
|
cfb5e4862c | ||
|
|
f7628a0bdc | ||
|
|
d7ef000c3f | ||
|
|
ef11c19b3a | ||
|
|
07993f1073 | ||
|
|
e89f669e14 | ||
|
|
52a699fbd7 | ||
|
|
9fac3ef5e8 | ||
|
|
50f1403445 | ||
|
|
b22a7b989f | ||
|
|
c32db48c03 | ||
|
|
190825e653 | ||
|
|
e21165673b | ||
|
|
e4c57d8571 | ||
|
|
f3254ee10b | ||
|
|
2f33d5a553 | ||
|
|
c97c74fb02 | ||
|
|
a49dff7e67 | ||
|
|
ef6fdd2e70 | ||
|
|
7437b9b09f | ||
|
|
9c54344b94 | ||
|
|
fbd2aa3bc8 | ||
|
|
32c962239f | ||
|
|
4d0a1966cf | ||
|
|
7f80cfcb70 | ||
|
|
693f887652 | ||
|
|
116e7cebe7 | ||
|
|
a9b86231be | ||
|
|
f88cdb4f0c | ||
|
|
b75ac1e82f | ||
|
|
8c5274e6ff | ||
|
|
ec2bf46f7f | ||
|
|
30b6ae5006 | ||
|
|
039bc46b18 |
||
|
|
83d2cfa181 | ||
|
|
241b97596f | ||
|
|
136b57b087 | ||
|
|
7a76524516 | ||
|
|
90b43d186a | ||
|
|
1f383b0c61 | ||
|
|
2c903ca7c6 | ||
|
|
d30198ece1 | ||
|
|
4abf44f32a |
||
|
|
37ac87a2d7 | ||
|
|
babc01608c | ||
|
|
62bff9e3f8 | ||
|
|
5e3f93306b | ||
|
|
ab2648bd75 | ||
|
|
2f2c660fb5 | ||
|
|
bf7876dfb4 | ||
|
|
0ae14457a9 | ||
|
|
c8e9765bb1 | ||
|
|
c791c0e801 | ||
|
|
c0b5cc3370 | ||
|
|
d33483ada3 | ||
|
|
8ddadf237f | ||
|
|
db6a60377d | ||
|
|
61e91c79bc | ||
|
|
b4b0064ae6 | ||
|
|
2102e7b543 | ||
|
|
8c370fd8ea | ||
|
|
b10bd5609f | ||
|
|
c00716896c |
||
|
|
228802bb5d | ||
|
|
2688fd8499 | ||
|
|
ca615d4c84 | ||
|
|
f27b7f8526 | ||
|
|
aa4b99f3a1 | ||
|
|
1d4dbdd445 | ||
|
|
4d8e71ad11 | ||
|
|
6b806a8026 | ||
|
|
16e9b1d647 | ||
|
|
cc02b71009 | ||
|
|
29f146f1e3 | ||
|
|
332700d57f | ||
|
|
efbe003174 | ||
|
|
124c8b7f02 | ||
|
|
b3866c95c8 | ||
|
|
172c054ce7 | ||
|
|
06fe73ec27 |
||
|
|
542cbb925a | ||
|
|
79cc65f739 | ||
|
|
15c0c27e79 | ||
|
|
50af183b70 | ||
|
|
9a0044e532 | ||
|
|
6d3060aaf2 |
||
|
|
57123c9be6 | ||
|
|
8c0b8c1497 | ||
|
|
0b7aecc0de | ||
|
|
2f6fb62ff1 | ||
|
|
934bef9782 | ||
|
|
6ace980bb0 | ||
|
|
9f34950c19 | ||
|
|
011609f694 | ||
|
|
032168b178 | ||
|
|
e3629ca47a | ||
|
|
da7412bc4d | ||
|
|
60a46c8bed | ||
|
|
5e5652faa4 | ||
|
|
6e10b42d44 | ||
|
|
9732afd824 | ||
|
|
2c83cfb5c4 | ||
|
|
67e45056e7 | ||
|
|
9a251c24de | ||
|
|
c89eaf833b | ||
|
|
b9d9ec7cd4 | ||
|
|
ae0ec15558 | ||
|
|
1f1b6f3757 | ||
|
|
e4ba749929 | ||
|
|
961a7e2cf3 | ||
|
|
c42d1d171f | ||
|
|
5e2980926e |
||
|
|
feafbef9d7 | ||
|
|
d534491ef7 |
||
|
|
a37eb3c678 | ||
|
|
bb311c3553 | ||
|
|
3f588131d4 | ||
|
|
49576ac7ee | ||
|
|
6233fbefd4 | ||
|
|
5ce97db777 | ||
|
|
148ea14905 | ||
|
|
a22ef72883 | ||
|
|
5b418b05bc | ||
|
|
876d0d2333 | ||
|
|
1f86b7cd73 | ||
|
|
663df1faa1 | ||
|
|
64eddc20ce | ||
|
|
417989d64b | ||
|
|
a02a84c5de | ||
|
|
36ea15b9be | ||
|
|
a6c06d7866 | ||
|
|
396d7b541a | ||
|
|
9370d9ec7c | ||
|
|
c1e7ea2106 | ||
|
|
e315432918 | ||
|
|
93788497b9 | ||
|
|
84088e1139 | ||
|
|
b36c755362 |
||
|
|
1f0fe20177 | ||
|
|
344b0b786b | ||
|
|
520c66620e | ||
|
|
3316ac227f | ||
|
|
31b58a086c | ||
|
|
ff6aed5311 | ||
|
|
1420d10aca | ||
|
|
8d37f93ab5 | ||
|
|
b9c57a912b | ||
|
|
251444ef38 | ||
|
|
ca3738ae73 | ||
|
|
c78f665cd5 | ||
|
|
8cf46f7b0a | ||
|
|
8bbb10317a | ||
|
|
4a63633d36 | ||
|
|
632c724605 | ||
|
|
a8e1440aea | ||
|
|
863b4e92b9 | ||
|
|
dfdaa9cdbd | ||
|
|
4ff6ff14dd | ||
|
|
5275b991f4 | ||
|
|
a3813e74e6 | ||
|
|
f316514d6c | ||
|
|
b607af5a5a | ||
|
|
0c34a9cad0 | ||
|
|
0ba15fa523 | ||
|
|
76685248d1 | ||
|
|
2c0ec09624 | ||
|
|
9200ae0a7c | ||
|
|
0d6c9f0027 | ||
|
|
46229c3af3 | ||
|
|
5ec21c44c6 | ||
|
|
7bc7f6f687 | ||
|
|
f96c26d465 | ||
|
|
6463dce0cd | ||
|
|
4b4b38eb97 | ||
|
|
13cf4d30f0 | ||
|
|
186be92aa7 | ||
|
|
bc9d0074d2 | ||
|
|
22a8fdb239 | ||
|
|
ae1fbea502 | ||
|
|
df0bf0f830 | ||
|
|
7009356f41 | ||
|
|
1a30861c1a | ||
|
|
13b9fbf425 |
||
|
|
9eb3025704 | ||
|
|
f28d472fcd | ||
|
|
70b656b88d | ||
|
|
99f6e06c78 | ||
|
|
24c8539069 | ||
|
|
44f38d82ac | ||
|
|
0f9f752cc5 | ||
|
|
8c705a5c17 | ||
|
|
80fcc0e63f | ||
|
|
5cb3b065a2 | ||
|
|
df447bf704 | ||
|
|
78467ea00d | ||
|
|
85f15abb5a | ||
|
|
69b61db9ac | ||
|
|
b9d921e555 | ||
|
|
47c57a80a5 | ||
|
|
09d1d9edb9 | ||
|
|
21a7e06543 | ||
|
|
55481eda5b | ||
|
|
3ad188b21f | ||
|
|
87fb9821e4 | ||
|
|
2390474e16 | ||
|
|
47c5b6efd9 | ||
|
|
84c311a648 | ||
|
|
77c3f9f94b | ||
|
|
e192d3b8bd | ||
|
|
62843e9999 | ||
|
|
9bb0036c76 | ||
|
|
fe40648730 | ||
|
|
10fdf45d15 | ||
|
|
a6a23740d8 | ||
|
|
9136d3b0e5 | ||
|
|
f7d43f7196 |
||
|
|
66d9f04d01 | ||
|
|
77e8eb5b0f |
||
|
|
bbc9f423c7 | ||
|
|
dbbe18c493 | ||
|
|
b5d031ea5d | ||
|
|
9b108c114b | ||
|
|
a60dc187b9 | ||
|
|
0ff4de4985 | ||
|
|
c55234ff76 | ||
|
|
e459a57623 | ||
|
|
5ab603bcfe | ||
|
|
2cefe63169 | ||
|
|
25aa9b6549 | ||
|
|
44b35f2e19 | ||
|
|
d1623e070d | ||
|
|
dbc4d890b7 | ||
|
|
a935e89722 | ||
|
|
5a23bd3f6e | ||
|
|
fcab889b63 | ||
|
|
4ea0ad56e6 | ||
|
|
99736408af |
||
|
|
a9b269838a | ||
|
|
1803271df8 | ||
|
|
c92e859470 | ||
|
|
c601d25df2 | ||
|
|
614ca55830 | ||
|
|
f308690452 | ||
|
|
0244357e5b | ||
|
|
6b7b2e6e43 |
||
|
|
b1b0d4e17e | ||
|
|
0ab9538c99 | ||
|
|
560720d95f | ||
|
|
8f4d30daf4 | ||
|
|
f65507b9ae | ||
|
|
654eae2e0c | ||
|
|
e5c6b6112a | ||
|
|
7d2f308d2f | ||
|
|
262ee2c518 | ||
|
|
99e099e3d9 | ||
|
|
0bcdb51956 | ||
|
|
fa8d20dd4b | ||
|
|
0a277a0ec3 | ||
|
|
85c202f0c8 | ||
|
|
6013171566 | ||
|
|
c87f41c8cb | ||
|
|
613627e391 | ||
|
|
13d57aab25 |
||
|
|
671c12a090 | ||
|
|
ceb271de20 | ||
|
|
0286f2e71f | ||
|
|
2d71b3d9ae | ||
|
|
fa6d5b8a95 | ||
|
|
834b5b4f0d | ||
|
|
01778e34b3 | ||
|
|
132b74341e | ||
|
|
e2f09416b2 | ||
|
|
14dc146845 | ||
|
|
c625ff7b31 | ||
|
|
45dc9d6c40 | ||
|
|
ed9e9882fe | ||
|
|
a601c76280 | ||
|
|
d70586be97 | ||
|
|
89f42755c7 | ||
|
|
ab25a1ccd3 | ||
|
|
bf062ab594 | ||
|
|
0f4ca8230c | ||
|
|
9df79dc94a | ||
|
|
b27864fe36 | ||
|
|
91f98d59f0 | ||
|
|
91d1d605c3 | ||
|
|
9010859c6f | ||
|
|
8a316d20d5 | ||
|
|
a5ead39c74 | ||
|
|
1836be8ebf | ||
|
|
79ba3f946e | ||
|
|
42588e4d1a | ||
|
|
242c3808b6 | ||
|
|
eeb249c216 | ||
|
|
9e690e36ee | ||
|
|
a824defefe | ||
|
|
4e993732ef | ||
|
|
75e59c056f | ||
|
|
d184c1af5a | ||
|
|
c28ce65eef | ||
|
|
2bdc88ee2b | ||
|
|
a6f85c0c0b | ||
|
|
14698a233e | ||
|
|
558a802ad6 | ||
|
|
4e330b2f0c |
||
|
|
d65eae6bf0 | ||
|
|
6d34bc2488 | ||
|
|
7ed5986ea4 | ||
|
|
f31c0b329f | ||
|
|
ba08ab16cd | ||
|
|
4aee2b6d28 | ||
|
|
9b94cfa173 | ||
|
|
c7c71055d6 | ||
|
|
b240bbd2fc | ||
|
|
31d84586e4 | ||
|
|
36104f797a | ||
|
|
8769a5a248 | ||
|
|
86fba75d0c | ||
|
|
dd23c55109 | ||
|
|
3c9894fca3 | ||
|
|
2baeda7ec9 | ||
|
|
abc64806bb | ||
|
|
f6ff7d1337 | ||
|
|
0312823fc4 |
||
|
|
4154968832 | ||
|
|
11b5e330f5 | ||
|
|
548a665a91 | ||
|
|
4800956d1f | ||
|
|
fe99ab9321 | ||
|
|
8c7dea1c64 | ||
|
|
1af6bd6f7d | ||
|
|
caa29d7c64 | ||
|
|
e96a6460b4 | ||
|
|
f63a5a93c5 | ||
|
|
983ba7624c | ||
|
|
e1415be85c | ||
|
|
986415c38b | ||
|
|
dd657ed8a1 | ||
|
|
be4128e1df | ||
|
|
ad0672ff54 | ||
|
|
ff6124bb62 | ||
|
|
7a86a84846 | ||
|
|
e7f9679e06 | ||
|
|
90222158e1 | ||
|
|
5fc4cb2e0c | ||
|
|
52fed0fea1 | ||
|
|
53f2fb6bc5 | ||
|
|
569a0d1181 | ||
|
|
7d4a31c5a2 | ||
|
|
0acfc8b593 | ||
|
|
9c49da4e58 | ||
|
|
6c27f206fd | ||
|
|
952f41a93e | ||
|
|
eb628cd8f4 | ||
|
|
5aa91266c3 | ||
|
|
e63af3136e | ||
|
|
866f2dea27 | ||
|
|
07f3afffbd | ||
|
|
fdfab7d552 | ||
|
|
5773d1e154 | ||
|
|
b4e572d064 | ||
|
|
4e617c8837 | ||
|
|
2fd63c6e40 | ||
|
|
193340675c | ||
|
|
6e5cf95b48 | ||
|
|
63e90f669f | ||
|
|
2507356c85 | ||
|
|
57a1857c2e | ||
|
|
cb0681810d | ||
|
|
b4f6bc0c4f | ||
|
|
3a5e716fc1 | ||
|
|
c2ac156832 | ||
|
|
0ead73a7ae | ||
|
|
41468186ae | ||
|
|
09e7273a18 | ||
|
|
c0cba942e6 | ||
|
|
4598b563f0 | ||
|
|
a3cd2d8864 | ||
|
|
47f04c0f9a | ||
|
|
dab6537415 | ||
|
|
ae40018d57 | ||
|
|
ad4ccd76c9 | ||
|
|
aa410f0ce6 | ||
|
|
4b65262579 | ||
|
|
c8e99df6c3 | ||
|
|
9a5583c989 | ||
|
|
888b239508 | ||
|
|
6127c19b04 | ||
|
|
d52b753e4b | ||
|
|
1bea1a28b2 | ||
|
|
c962b5eda0 | ||
|
|
d86594afdf | ||
|
|
3ff7b289fc | ||
|
|
f7cd7a12d2 | ||
|
|
96c6e03cf4 | ||
|
|
f98f7b9f39 | ||
|
|
19b8645d60 | ||
|
|
ea18f522d4 | ||
|
|
3879f1658d | ||
|
|
559982ac5a | ||
|
|
1d9bbe474f | ||
|
|
84a2000f2c | ||
|
|
4e65f7feae | ||
|
|
f36c3e9af4 | ||
|
|
35d1d92111 | ||
|
|
8938ce9547 | ||
|
|
13aec9f5b0 | ||
|
|
800834e213 | ||
|
|
30a311f100 | ||
|
|
2abf7b5dfe | ||
|
|
d9b7c60ec5 | ||
|
|
52c1991160 | ||
|
|
5761433e56 | ||
|
|
85445cfa0a | ||
|
|
0b21444c15 | ||
|
|
7c707e3343 | ||
|
|
6afa92c16e | ||
|
|
da741beba6 | ||
|
|
9dd8223e0a | ||
|
|
c04880a305 | ||
|
|
d44cffdf26 | ||
|
|
57737f8d98 | ||
|
|
393498aad7 | ||
|
|
9eac2290a0 | ||
|
|
c1be767702 | ||
|
|
7a31edc6c8 | ||
|
|
c8f96e5594 | ||
|
|
09ba77774a | ||
|
|
e8c6106ee1 | ||
|
|
cbb3409a14 | ||
|
|
e8154a4e48 | ||
|
|
4b54c96820 | ||
|
|
f72f67ea94 | ||
|
|
5ea14acc4c | ||
|
|
8a82b341ff | ||
|
|
a3ef77dd87 | ||
|
|
53749a439a | ||
|
|
2f7f150698 | ||
|
|
38b3410422 | ||
|
|
838532a46b | ||
|
|
17ae7acf9e | ||
|
|
e9f502857c | ||
|
|
eacda61c40 | ||
|
|
6efa81c146 | ||
|
|
d6ba03b324 | ||
|
|
cfb951952f | ||
|
|
c797022d0e | ||
|
|
30acda2f89 | ||
|
|
0fad673442 | ||
|
|
748805d1bf | ||
|
|
3d81441df2 | ||
|
|
a9ee5843d9 | ||
|
|
ee5d9df872 | ||
|
|
27b84a6af6 | ||
|
|
93eb7dfd83 | ||
|
|
4f3d0b787e | ||
|
|
eb982a259d | ||
|
|
e868e89be3 | ||
|
|
27dc71e24e | ||
|
|
8cc89f6444 | ||
|
|
eced841224 | ||
|
|
96265e6ba3 | ||
|
|
b2435efdd4 | ||
|
|
17f7252190 | ||
|
|
f6063ca243 | ||
|
|
f4b2a489cc | ||
|
|
25363fbaba | ||
|
|
204959be99 | ||
|
|
9f23878344 | ||
|
|
3cdc7fd78a | ||
|
|
7517fe2c0b | ||
|
|
966d98c4dc | ||
|
|
d6e5e3b730 | ||
|
|
f188356232 | ||
|
|
f8862b158d | ||
|
|
53e69da298 | ||
|
|
89ab4208ff | ||
|
|
f23a994413 | ||
|
|
90e2454947 | ||
|
|
c92279a612 | ||
|
|
51dd337a6c | ||
|
|
b34191cef7 | ||
|
|
60d8139b30 | ||
|
|
972b5c2d37 | ||
|
|
27f1f3ec5b | ||
|
|
1bcf3c3519 | ||
|
|
f38b8013f2 | ||
|
|
e2ac4dd768 | ||
|
|
5b2c3b9334 | ||
|
|
c676d62ec3 | ||
|
|
ea52d64c6e | ||
|
|
c81160caf0 | ||
|
|
e2a810c962 | ||
|
|
859c1fd568 | ||
|
|
bfc1931ecd | ||
|
|
29e886a671 | ||
|
|
316e0c37d8 |
||
|
|
a9e9c7d17c | ||
|
|
e573e66ec7 | ||
|
|
c072da45b5 | ||
|
|
15ef437b1e | ||
|
|
e457ffa8ee |
||
|
|
7c3fdc636a | ||
|
|
67da3fbabb | ||
|
|
2dd9817eb9 | ||
|
|
ab26e0eafb | ||
|
|
168ce6ed8e | ||
|
|
d6844eb919 | ||
|
|
8c50148b40 | ||
|
|
ad45e74c24 | ||
|
|
95815cfdeb | ||
|
|
f374448de0 | ||
|
|
b891864ac8 | ||
|
|
118d9e49a3 | ||
|
|
468a4ac676 | ||
|
|
817ffc71a8 | ||
|
|
d5eb924ff8 | ||
|
|
e4f8460467 | ||
|
|
dd8f11320a | ||
|
|
f9fdb82a95 | ||
|
|
303c013b75 | ||
|
|
4a66a7cda7 | ||
|
|
5935a15497 | ||
|
|
7c92023496 | ||
|
|
4224c96ac5 | ||
|
|
c28c1713cf | ||
|
|
04418aad3c | ||
|
|
63b392d46c | ||
|
|
685f55b514 | ||
|
|
ae0ea18747 | ||
|
|
4b4b721b60 | ||
|
|
3e8adb9b93 | ||
|
|
0f43599f75 | ||
|
|
d3f15d726c | ||
|
|
5932fb6658 | ||
|
|
47c73f5db7 | ||
|
|
20c7de422d | ||
|
|
265223acdb | ||
|
|
6218ba73cf | ||
|
|
3393195b20 | ||
|
|
59bc178c81 | ||
|
|
3faad8190a | ||
|
|
860d6e75c2 | ||
|
|
42a5d38e1a | ||
|
|
68d1c6e4e1 | ||
|
|
db4feb4e0a | ||
|
|
4fc4944856 | ||
|
|
790b0ce677 | ||
|
|
81766500af | ||
|
|
ab1cd6e039 | ||
|
|
e04e484f4a | ||
|
|
03f27f9f4f | ||
|
|
b8c8f04c7d | ||
|
|
36682a19b8 | ||
|
|
e38813f8d5 | ||
|
|
086e813e25 | ||
|
|
8d01df8ed7 | ||
|
|
ca3dfa26f2 | ||
|
|
3090277c21 | ||
|
|
6ba66fdb58 | ||
|
|
ed66c0791f | ||
|
|
90604a968f | ||
|
|
302c1e8450 | ||
|
|
6e3f51de3e | ||
|
|
87fb5ab444 | ||
|
|
59edd9c5eb | ||
|
|
e6ef5e1e1f | ||
|
|
0ba234f544 | ||
|
|
33322aade1 | ||
|
|
9e74a0f0f5 | ||
|
|
aae7a16ecb | ||
|
|
c1c4d7620d | ||
|
|
b7b47b21c1 | ||
|
|
b6128fae02 | ||
|
|
a2aa63ef07 | ||
|
|
b20a971928 | ||
|
|
34a54ef00f | ||
|
|
64ac6f77d9 | ||
|
|
a472549ec6 | ||
|
|
69ddc0e41b | ||
|
|
caf1d3f080 | ||
|
|
011a32cdb4 | ||
|
|
27cfb71656 | ||
|
|
f103e65144 | ||
|
|
aa7853a4c5 | ||
|
|
2f80408d4f | ||
|
|
afd10c3c40 | ||
|
|
50bad64956 | ||
|
|
5f8dc675be | ||
|
|
c3af2a6e20 | ||
|
|
6c84829a7e | ||
|
|
fa123d6f2b | ||
|
|
fc2d65af65 | ||
|
|
6c8971858f | ||
|
|
f1b4f2204f | ||
|
|
d266e7a484 | ||
|
|
ce1131af8b | ||
|
|
b42e2503e7 | ||
|
|
f053d334fe | ||
|
|
e5ba69a40e | ||
|
|
7a974dde4c | ||
|
|
e701968cd1 | ||
|
|
4d1130f775 | ||
|
|
3a4700e991 | ||
|
|
a57bc9a2a8 | ||
|
|
4b17c073d1 | ||
|
|
9de6dd5593 | ||
|
|
16a870fcd9 | ||
|
|
92bd7df527 | ||
|
|
1049fd9722 | ||
|
|
3c8ef9d9f2 | ||
|
|
704f2f2b04 | ||
|
|
d39ea6e021 | ||
|
|
5ca7cc68c2 | ||
|
|
f333a88e0e | ||
|
|
de1b4d1042 | ||
|
|
5cedc12d24 | ||
|
|
650187bcc9 |
||
|
|
98cc551cf8 | ||
|
|
656b459b2a | ||
|
|
e89064de97 | ||
|
|
37b0a3ff8b | ||
|
|
5f981d0e4e | ||
|
|
48136147e9 | ||
|
|
3bd0a10816 | ||
|
|
005c84c2d7 |
||
|
|
f7ba104e48 | ||
|
|
97e1b60a00 |
||
|
|
c27ceed26e | ||
|
|
8fd3f87802 | ||
|
|
ca531db075 | ||
|
|
97ed0aff36 | ||
|
|
f513e32f72 | ||
|
|
33c8b5e56a | ||
|
|
a2d8afae68 | ||
|
|
32532a344c | ||
|
|
3180cb924c | ||
|
|
2bc4832f21 | ||
|
|
fd6d5a8085 | ||
|
|
86ccf0da86 |
||
|
|
1a84836c2e | ||
|
|
761075921e | ||
|
|
ae6f64172d | ||
|
|
46ee816f8b | ||
|
|
87a9ba1190 | ||
|
|
3119015cfe | ||
|
|
158b022c2d | ||
|
|
979b935cf8 | ||
|
|
7f66cd4b13 | ||
|
|
8d6f960a67 | ||
|
|
13893bdd1e | ||
|
|
2f7d5f9b43 | ||
|
|
9e3007bc71 | ||
|
|
aa392b45fc | ||
|
|
9fbaf75cb3 | ||
|
|
6feaa94ad5 | ||
|
|
d336d6eb73 | ||
|
|
de5c4b90a7 | ||
|
|
4aeb2801a3 | ||
|
|
9263696889 | ||
|
|
c15e209c8b | ||
|
|
85faf82d4b | ||
|
|
39cbab00eb | ||
|
|
67d210711b | ||
|
|
2d32109c71 | ||
|
|
e139fcb5ee | ||
|
|
562b9f6a21 | ||
|
|
c3f34eee6f | ||
|
|
e692f4ae02 | ||
|
|
c73ca8d67e | ||
|
|
c9d62203f0 | ||
|
|
e3dd9f0212 | ||
|
|
7050048a4f | ||
|
|
1647bed358 | ||
|
|
dc58700a62 | ||
|
|
f71e7005a3 | ||
|
|
492432ecca | ||
|
|
7b29ac1016 | ||
|
|
0c47b49589 | ||
|
|
31c3a76a20 | ||
|
|
d22b9b7205 | ||
|
|
2fcad93c54 | ||
|
|
1459890d03 | ||
|
|
320203a892 | ||
|
|
52ee174822 | ||
|
|
1489df8e00 | ||
|
|
4cca685782 | ||
|
|
b9afd1aed0 | ||
|
|
30fb9859fb | ||
|
|
9e4bb1a0ed | ||
|
|
2cc56c8e9a | ||
|
|
4271e23fa3 | ||
|
|
7d7a729773 | ||
|
|
8134add0e6 | ||
|
|
4c77384257 | ||
|
|
a5606c0f88 | ||
|
|
6ed1cf6f2a | ||
|
|
fe1a5bdc02 | ||
|
|
1c734ca812 | ||
|
|
1b1ca89bc1 | ||
|
|
7c80c8ab23 | ||
|
|
cf00e81423 | ||
|
|
5dcae55b24 | ||
|
|
ddba18df8b | ||
|
|
81e899136b | ||
|
|
5857acf7f7 | ||
|
|
665ab1eae2 | ||
|
|
43a71cc64d | ||
|
|
e04afa0b3e | ||
|
|
176a05ac34 | ||
|
|
2f11c164d3 | ||
|
|
788c934f43 | ||
|
|
f1d0a2c9d9 | ||
|
|
d3a2c1b0d4 | ||
|
|
2c335a3e53 | ||
|
|
17e12cb48b | ||
|
|
766e2fe93c | ||
|
|
039ca6e1c0 | ||
|
|
9084333d35 | ||
|
|
79627b1c8b | ||
|
|
5aaa6bc54a | ||
|
|
2385f18866 | ||
|
|
a2e5b0eb2b | ||
|
|
e8a19a4569 |
||
|
|
62d6fb32c8 | ||
|
|
8c1c69a4af | ||
|
|
30e0176b75 | ||
|
|
5a5b826bd0 | ||
|
|
11f8742da2 | ||
|
|
8f9205e017 | ||
|
|
e11490874b | ||
|
|
cf490dbd34 | ||
|
|
054cebe599 | ||
|
|
dcde783795 | ||
|
|
255ecc7bda | ||
|
|
1182709542 | ||
|
|
8648f21105 | ||
|
|
8c47809d2c | ||
|
|
282fb12b7a | ||
|
|
319c47f67d | ||
|
|
e7fbe1dd56 | ||
|
|
40f5251161 | ||
|
|
bf477c59d6 | ||
|
|
ece67c1b0a | ||
|
|
5f40088c3f | ||
|
|
1db3bb54e4 | ||
|
|
64b655d292 | ||
|
|
64cd59ecef | ||
|
|
4fe27b1287 | ||
|
|
490d850cd1 | ||
|
|
0894245130 | ||
|
|
7b21584aa5 | ||
|
|
c9c61eeba3 | ||
|
|
5c44a8c628 | ||
|
|
19e82d61ce | ||
|
|
345ea783dc | ||
|
|
bd01ba90fd | ||
|
|
3d8c2a7192 | ||
|
|
5e4d553cb4 | ||
|
|
7d5a6bdb56 | ||
|
|
3f9c6229e9 | ||
|
|
ecc7ec746b | ||
|
|
ff8c8e908c | ||
|
|
d0d70e5fa8 | ||
|
|
2958b138f9 | ||
|
|
ca378ab948 | ||
|
|
5b60341ad7 | ||
|
|
4913c46b61 | ||
|
|
4b5988ae34 |
||
|
|
6dd5b5a1d6 | ||
|
|
af46d2f076 | ||
|
|
e682a876de | ||
|
|
a0eaa37f04 | ||
|
|
7475060655 | ||
|
|
afa8faf711 | ||
|
|
37c22c3ef4 | ||
|
|
05f3ab8446 | ||
|
|
e853cdadd9 | ||
|
|
884720a573 | ||
|
|
d2b624be18 | ||
|
|
5fbaae7732 | ||
|
|
a15f560ea3 | ||
|
|
38a5f529d9 | ||
|
|
e1fbd5c089 | ||
|
|
8914e6cd13 | ||
|
|
b267d10937 | ||
|
|
7a4ac40739 | ||
|
|
4fc93d275c | ||
|
|
671df91744 | ||
|
|
2a2862c0f1 | ||
|
|
026e9755d8 | ||
|
|
85d1985b9f | ||
|
|
3cff308d7b |
||
|
|
0c65eea9dd |
||
|
|
0135b6d4e8 | ||
|
|
cad083f6e8 | ||
|
|
fdcc704ced |
||
|
|
a79429eedc | ||
|
|
17fb9dcb9d | ||
|
|
18d4448ed2 | ||
|
|
d597ee49b6 | ||
|
|
76f1bc9d07 | ||
|
|
dc3a68d907 | ||
|
|
69e928ea09 | ||
|
|
4f3ec507f6 | ||
|
|
b2a3fa2686 | ||
|
|
112ffaa593 | ||
|
|
3340404a90 | ||
|
|
f2ed08ba7a | ||
|
|
ace08aa36d | ||
|
|
a769421642 |
||
|
|
bbf030a6aa | ||
|
|
87f8ba928f | ||
|
|
6ad950c95e | ||
|
|
30d8b77eda | ||
|
|
c7cf06829c | ||
|
|
a233c69f15 |
||
|
|
8b70e6bb1b | ||
|
|
3ecba99193 | ||
|
|
b57192405f | ||
|
|
c586f5f5ba | ||
|
|
47fa44ef6b | ||
|
|
67c9fc946b | ||
|
|
68112b7fdd | ||
|
|
e900156fb1 | ||
|
|
86caadb164 | ||
|
|
b0ad1a0c51 | ||
|
|
27d3a8eee1 | ||
|
|
eca52c6459 | ||
|
|
7c9c1dc94b | ||
|
|
de6fa6ce31 | ||
|
|
3540c79f99 | ||
|
|
19b046aefe | ||
|
|
7491784318 |
||
|
|
4879122cdc |
||
|
|
c0629daf08 | ||
|
|
cbedb26d4f | ||
|
|
ae3d2abeaf | ||
|
|
b8a101a71c | ||
|
|
d578945573 | ||
|
|
0b3b2deb89 | ||
|
|
63cd93783a | ||
|
|
b031cf6133 | ||
|
|
d5b2c51a67 | ||
|
|
530aafdc2d | ||
|
|
f0f2b02c53 | ||
|
|
01a66177ec | ||
|
|
5b04565930 |
||
|
|
561e10ab32 | ||
|
|
537ffde16d | ||
|
|
ebed22101e | ||
|
|
eb2bf85573 | ||
|
|
beb512835e |
||
|
|
d6d54dfb93 | ||
|
|
3df9f5260c | ||
|
|
0c10a9c033 | ||
|
|
7d664ad53c | ||
|
|
7fcceac697 | ||
|
|
52a3869fcb | ||
|
|
1c09afa958 | ||
|
|
a899cf77a9 | ||
|
|
dbfd5abb79 | ||
|
|
01420e301e | ||
|
|
3eeb0aeaa0 | ||
|
|
8f0d4a4907 | ||
|
|
db7dfa19fb | ||
|
|
1dfd10e789 | ||
|
|
d1d437c9cc | ||
|
|
8b8dff2137 | ||
|
|
118ea526d4 | ||
|
|
45402ba3d1 | ||
|
|
9ee1109693 | ||
|
|
863cebc19a | ||
|
|
e69ffe017d | ||
|
|
fabb04cd75 | ||
|
|
df3652d707 | ||
|
|
e6e0e083fa | ||
|
|
6ec5f573b9 | ||
|
|
2cacca2c3a |
||
|
|
23252a36f9 | ||
|
|
5405d59451 | ||
|
|
eac96f8c71 | ||
|
|
f046c9f085 | ||
|
|
17eeef8253 | ||
|
|
dd1e211985 | ||
|
|
5736695059 | ||
|
|
27e6888b2c | ||
|
|
16756b6362 | ||
|
|
38abc6ffc4 | ||
|
|
566d2397bf | ||
|
|
f827859854 | ||
|
|
1521d9dfda | ||
|
|
e5f21889fe | ||
|
|
ef6d192b0f | ||
|
|
59517f8caa | ||
|
|
2c7934f31e | ||
|
|
b75946dc55 | ||
|
|
eb00ca2cf5 | ||
|
|
b9e5f1a772 | ||
|
|
85034e987f |
||
|
|
e2b68b6e53 |
||
|
|
1845694471 | ||
|
|
5c6b46f892 | ||
|
|
86b19c2b10 | ||
|
|
f2b3345653 | ||
|
|
9066702bc4 | ||
|
|
057eb0ac96 | ||
|
|
503584708b | ||
|
|
defc205605 | ||
|
|
4c8aa72a3c | ||
|
|
f11392854a |
||
|
|
8996c1bc15 | ||
|
|
e1733465be | ||
|
|
4e1ead1789 | ||
|
|
9ec8f9d483 | ||
|
|
fd70dbe29a |
||
|
|
edb8bab9f4 | ||
|
|
36378feaa6 | ||
|
|
51161fb569 | ||
|
|
e86a46ae17 | ||
|
|
9d35e96060 | ||
|
|
77e3fc8445 | ||
|
|
275d06df1b | ||
|
|
a60bd9b79d | ||
|
|
d498e63c20 | ||
|
|
c357c055ea | ||
|
|
2073688c09 | ||
|
|
3f86f6d14e | ||
|
|
51de0fb1c2 | ||
|
|
8ae7b5ca3a | ||
|
|
d28cd151f6 | ||
|
|
7e347cffcd | ||
|
|
5951ace48d | ||
|
|
600edcc021 | ||
|
|
dd7128a35f | ||
|
|
ab42674559 |
||
|
|
df4164b626 | ||
|
|
2aa9fe2f5a | ||
|
|
47cffccc5e | ||
|
|
85510ee9b6 | ||
|
|
e960d880e3 | ||
|
|
3b22b4b5c6 | ||
|
|
6b46a2f4cd | ||
|
|
9d0bdc0224 |
||
|
|
0b35d32a7a | ||
|
|
1b72f53617 | ||
|
|
d9887075e2 | ||
|
|
dc3fd9c5ab | ||
|
|
a7093dbd96 |
||
|
|
69663f87a0 | ||
|
|
e43bfc3c57 | ||
|
|
8e7dcd1477 | ||
|
|
1e1a01ef2a | ||
|
|
f43748ee0e | ||
|
|
ebeafd8089 | ||
|
|
b8ec3221fd | ||
|
|
6396d2e625 | ||
|
|
9ed0246608 | ||
|
|
51d5596f24 | ||
|
|
50c505da51 | ||
|
|
cee9297f07 | ||
|
|
f56c649302 | ||
|
|
12adaeca8a | ||
|
|
c199a7d36e | ||
|
|
fbb7f756e0 | ||
|
|
b86380aaa5 |
||
|
|
ddcfc127f0 |
||
|
|
4adfa52f83 |
||
|
|
d616b527db |
||
|
|
0544f3b046 | ||
|
|
5e40d547ea | ||
|
|
60e6ddd2c6 | ||
|
|
b3625ffa47 | ||
|
|
904e910e8b | ||
|
|
093d191417 | ||
|
|
8ed19f0763 |
||
|
|
14abe92c63 | ||
|
|
aa41a1d75c | ||
|
|
10393c3bfe | ||
|
|
5952e6e4a5 | ||
|
|
feee22e21c |
||
|
|
114f1cae6c |
||
|
|
395278e637 |
||
|
|
44f5493321 | ||
|
|
45f448f99c | ||
|
|
82eb373ee7 | ||
|
|
1478a5eea4 | ||
|
|
4509e71249 | ||
|
|
45f7a74bd5 | ||
|
|
1b39c9b210 | ||
|
|
3469361f2a | ||
|
|
9cf517b4e7 | ||
|
|
d174021001 | ||
|
|
13abc11239 | ||
|
|
ad44f75025 | ||
|
|
6ff4d166b5 | ||
|
|
ea812adf0d | ||
|
|
5d886afbca | ||
|
|
a69813350f | ||
|
|
36aed0e126 | ||
|
|
697f88ddcb | ||
|
|
cbb4b2fa5b | ||
|
|
95be3520aa | ||
|
|
00163720f1 | ||
|
|
97149bfbf5 | ||
|
|
c0b4c5521f | ||
|
|
2ef5b6c33d | ||
|
|
99829590d9 |
||
|
|
ec5c977d2d |
||
|
|
f9a5214df4 |
||
|
|
d62505b057 |
||
|
|
2cce7e3845 | ||
|
|
638f4a7997 | ||
|
|
0110f2b639 |
||
|
|
7d85724eeb | ||
|
|
1bf48d63dd | ||
|
|
3fc2fa3428 | ||
|
|
87ae081b9b | ||
|
|
f018766903 | ||
|
|
c13e3a07e6 | ||
|
|
5eb2756f09 |
||
|
|
56611a51ca | ||
|
|
d51ac676f4 |
||
|
|
66dedd742c | ||
|
|
f5a67b9883 | ||
|
|
04babd85e2 | ||
|
|
1271cd1a68 |
||
|
|
61b3f9cae3 | ||
|
|
6394f21656 | ||
|
|
6c24641cd5 | ||
|
|
d067998bed | ||
|
|
53086dbf8c | ||
|
|
5f3ea44844 | ||
|
|
b5af91a15b | ||
|
|
6a99fd2ebb | ||
|
|
27e4b32d30 | ||
|
|
7acc44c2c6 | ||
|
|
0b102f7897 | ||
|
|
ea75da6f0b | ||
|
|
c42011485b | ||
|
|
432f7edd29 | ||
|
|
dabd5fbdc2 | ||
|
|
df4c16a213 |
||
|
|
ef94d8327b | ||
|
|
9c26a1cd5e | ||
|
|
5291ed3c35 | ||
|
|
bc6e961a0d | ||
|
|
67c5d3a2b1 | ||
|
|
7f1fb46919 | ||
|
|
480f7f6181 | ||
|
|
3293676910 | ||
|
|
d298af4453 | ||
|
|
fc6c26f151 | ||
|
|
f32ab111d6 | ||
|
|
c4b07ba6dd | ||
|
|
ab74407105 | ||
|
|
76eecf639c | ||
|
|
731cf1cfb0 |
||
|
|
a0eac93139 | ||
|
|
6f8f46b058 | ||
|
|
c75b3b2716 | ||
|
|
9a290fd289 |
||
|
|
0261d283f4 |
||
|
|
9a7768549d |
||
|
|
1bfec1424c | ||
|
|
2b8ec129ed | ||
|
|
e1336aa137 | ||
|
|
967dcff2c3 | ||
|
|
e906196a37 | ||
|
|
0d38c4e9f0 | ||
|
|
466cca2851 | ||
|
|
5adb793286 | ||
|
|
69196478bc | ||
|
|
62dd19e08b | ||
|
|
483bbef8db | ||
|
|
81af12959d | ||
|
|
c470b315a6 | ||
|
|
4807910fd7 | ||
|
|
11d29e883e |
||
|
|
1b7a57f97c | ||
|
|
931341c272 |
||
|
|
e32c0398f3 | ||
|
|
fe369a3749 | ||
|
|
0604dcb6c7 | ||
|
|
1a9bbd1626 | ||
|
|
5a76864932 | ||
|
|
b0297748ab | ||
|
|
1da73f2809 | ||
|
|
792e73b463 | ||
|
|
8f922a5408 | ||
|
|
cbadb275d4 | ||
|
|
960cbad7fb |
||
|
|
f9c2c136ae | ||
|
|
0a5de71113 | ||
|
|
c0c13d5e17 | ||
|
|
9bb9d0f9bc | ||
|
|
210959a833 | ||
|
|
1c6a71258c |
||
|
|
fa9bf4e35b | ||
|
|
f462a30d51 | ||
|
|
a5bc7dfcca | ||
|
|
83d6e44848 | ||
|
|
8e5ddb0d7d | ||
|
|
b96e143afe | ||
|
|
27aec457a7 | ||
|
|
73fe99b49c | ||
|
|
013c11bf3c | ||
|
|
ea8c59fed2 | ||
|
|
1a136c7754 | ||
|
|
9e26803e53 |
||
|
|
bb504347c8 | ||
|
|
2448a1002d | ||
|
|
3c8fa58a14 | ||
|
|
4c93d2f80b | ||
|
|
276c76a512 | ||
|
|
38c7971ea1 | ||
|
|
436669e5d5 | ||
|
|
12f387d9c1 | ||
|
|
378d3e829d | ||
|
|
d4268a4c84 | ||
|
|
35ff5616f3 | ||
|
|
29cc734aaa | ||
|
|
352c0168db | ||
|
|
2a15152286 | ||
|
|
ef764c8ae9 | ||
|
|
cc0bb25644 | ||
|
|
0033be0732 | ||
|
|
d2882db5ee | ||
|
|
9310362d06 | ||
|
|
22783fa3d2 | ||
|
|
a2f339fb24 | ||
|
|
e8b4058d84 | ||
|
|
d7bbc55b20 | ||
|
|
d575e6a708 |
||
|
|
8114032450 | ||
|
|
8dfa4a52f9 | ||
|
|
c05b9e6a66 | ||
|
|
d011b40705 | ||
|
|
b99af5fc32 | ||
|
|
a489af1a7c | ||
|
|
65b46ae819 | ||
|
|
718d279ea7 | ||
|
|
7d644055cd | ||
|
|
855fbfe8f8 | ||
|
|
c159f39a8a | ||
|
|
3df381014e | ||
|
|
de5e1d44e0 | ||
|
|
9f5efd0547 | ||
|
|
a1402335f2 | ||
|
|
81616d392e | ||
|
|
e60cfd00a3 | ||
|
|
82e33bb641 | ||
|
|
12528b977c | ||
|
|
72481da2ea | ||
|
|
1812ed6e47 |
||
|
|
1ee7a6b2b8 | ||
|
|
fcca7ac789 | ||
|
|
fa88664159 | ||
|
|
1a6b8338af | ||
|
|
06af97c346 | ||
|
|
fefa77a1b0 | ||
|
|
27849c0dcd | ||
|
|
a07d47b1c5 | ||
|
|
fcbdf75482 | ||
|
|
048a8511a5 | ||
|
|
8d886d686d | ||
|
|
f3d000321f | ||
|
|
0092c7afa7 | ||
|
|
f21aa9cc86 | ||
|
|
74e742c26b | ||
|
|
30336f33c0 | ||
|
|
752d3c9f23 | ||
|
|
661859913c |
||
|
|
06a5cc8fa2 | ||
|
|
e650495a5a | ||
|
|
7e2421de3e | ||
|
|
900b369d5c | ||
|
|
6f44e95e14 | ||
|
|
4f4c53dcb1 | ||
|
|
dc2d77a5bf | ||
|
|
c4ae646f00 | ||
|
|
005b798a92 | ||
|
|
55da32615a | ||
|
|
aad26e8f14 | ||
|
|
2782b26b07 | ||
|
|
6270e0920a | ||
|
|
8422b1b077 | ||
|
|
a0a9221472 | ||
|
|
2a57395f58 | ||
|
|
f822e0751b |
||
|
|
ce960e0774 | ||
|
|
e410909169 | ||
|
|
ecb6bd85e9 | ||
|
|
6e187ef760 | ||
|
|
cd3746da5e | ||
|
|
8c857bd6d2 | ||
|
|
caae56af3e | ||
|
|
d0f9193461 | ||
|
|
1b9671eda7 | ||
|
|
573515e601 | ||
|
|
24edd85df6 | ||
|
|
035cee8d76 | ||
|
|
dde35d68dd | ||
|
|
80d4477cc0 | ||
|
|
1780ca370d |
||
|
|
f996c38bed | ||
|
|
fca1db719a | ||
|
|
4094688e42 |
||
|
|
4b978d231e |
||
|
|
eb05d249ce | ||
|
|
4c4a425a52 | ||
|
|
0f2e388a29 | ||
|
|
193dc62a3a | ||
|
|
ce4eb5ebb0 | ||
|
|
22110c33c7 | ||
|
|
01c8c0c81b | ||
|
|
044706b658 | ||
|
|
a56d313b34 | ||
|
|
64c0ae2933 | ||
|
|
a2da252b19 | ||
|
|
3a72a90799 | ||
|
|
cdf070569b | ||
|
|
93e4fafb3a | ||
|
|
520e337f7f | ||
|
|
519d4c4c41 | ||
|
|
5fadb85903 | ||
|
|
2a8513c243 | ||
|
|
5c38b38460 | ||
|
|
a404e2ffe7 | ||
|
|
92b83bfb0d | ||
|
|
1286c4fc42 | ||
|
|
c0ff9250bf | ||
|
|
4ae5fc08b2 | ||
|
|
84f1a960b1 | ||
|
|
3fb10a1a5b | ||
|
|
afc3a9fc9b | ||
|
|
28b2254601 | ||
|
|
f633ea144c |
||
|
|
a6a0398111 |
||
|
|
6f9218adcb | ||
|
|
28152ec7f9 | ||
|
|
01cc57a338 | ||
|
|
e83d6a320d | ||
|
|
d2416cc2a4 | ||
|
|
4763aaa86e | ||
|
|
832462f36a | ||
|
|
508d8c9ada | ||
|
|
65e72c0d31 | ||
|
|
94d501e320 | ||
|
|
024b0d632f | ||
|
|
159a91ab61 | ||
|
|
8ea19a565c | ||
|
|
fb40c7c4a9 | ||
|
|
4cdf3f0e6c | ||
|
|
a19d3c3ad5 | ||
|
|
6fc5d04149 | ||
|
|
f92077f4e2 | ||
|
|
c96e552037 | ||
|
|
b6621eeb75 | ||
|
|
ddd1dd1377 | ||
|
|
dae59469ce | ||
|
|
344b8eb21f | ||
|
|
61a1b24712 | ||
|
|
d0c00d792e | ||
|
|
4f0eb9bc9e | ||
|
|
693f0883cb | ||
|
|
69ab554ba5 | ||
|
|
6099cdc228 | ||
|
|
68a12f8e7a | ||
|
|
0afd35e6fd | ||
|
|
39d7cecdbc | ||
|
|
d2bef610d8 | ||
|
|
c4c8e69189 | ||
|
|
8725b8ceac | ||
|
|
5a48d0b603 | ||
|
|
44abcdeb4a | ||
|
|
629473c426 |
||
|
|
f7333011bb | ||
|
|
e751c2ded2 | ||
|
|
ef9ae898a0 | ||
|
|
73059633f0 | ||
|
|
2128ec073e | ||
|
|
0bed1bda2d | ||
|
|
1ee04fc7c1 | ||
|
|
f4da7688ba | ||
|
|
cde5faedf4 | ||
|
|
6e413a96dc | ||
|
|
e4a5db79db | ||
|
|
fea28f382b | ||
|
|
0f1f582578 |
||
|
|
17c4b7f460 | ||
|
|
69a8ec935f | ||
|
|
b3f06168fa | ||
|
|
4c78fe6214 | ||
|
|
a685367b0c | ||
|
|
37e268c3f8 | ||
|
|
070a667cc9 | ||
|
|
c6e5f13764 | ||
|
|
b80b584700 | ||
|
|
e2cf8a099d | ||
|
|
26023ec1ed | ||
|
|
205dd3cada | ||
|
|
f9313ed71c | ||
|
|
09238c8615 | ||
|
|
72ac5aed61 | ||
|
|
7bfe465048 | ||
|
|
1b39937de7 | ||
|
|
9db5a98161 | ||
|
|
c42cd75da9 | ||
|
|
2f4a17518e | ||
|
|
ed485edd9d |
||
|
|
6c84cb59d6 | ||
|
|
a8a855d7f3 | ||
|
|
bcf728ee89 | ||
|
|
05b14ee6c4 | ||
|
|
2927a95b64 | ||
|
|
1da29f4779 | ||
|
|
8374f75385 | ||
|
|
4fe92d8254 | ||
|
|
4e4887033e | ||
|
|
849760f020 |
||
|
|
184c870c79 | ||
|
|
2e0343433d | ||
|
|
cdbb2852f6 | ||
|
|
2c94aa22b8 | ||
|
|
3b8e210e6a | ||
|
|
cf2bf7f7f0 | ||
|
|
d5c2c59798 | ||
|
|
e01d5186f7 | ||
|
|
c3b3644a57 | ||
|
|
b1e6a248eb | ||
|
|
46c39f0024 | ||
|
|
74b3763c56 | ||
|
|
4dbffb2748 | ||
|
|
b9079e7827 | ||
|
|
f83d70f253 | ||
|
|
71725d1bd0 | ||
|
|
2a971d683c | ||
|
|
1734d761b7 | ||
|
|
384cac5495 | ||
|
|
b7c4cb1584 | ||
|
|
cfd166f052 | ||
|
|
5229bfc66e | ||
|
|
d8462d0ec5 | ||
|
|
a5009f63af | ||
|
|
c2804dc2cd | ||
|
|
741e55c0ea | ||
|
|
d308ae7e30 | ||
|
|
4b4c1c13dc | ||
|
|
2215be969b | ||
|
|
bf4138f198 | ||
|
|
2a04efd4db | ||
|
|
912420fb32 | ||
|
|
7adcd8647e | ||
|
|
a1b3b967b7 |
||
|
|
3d32638970 | ||
|
|
c439aac266 | ||
|
|
8b4d9a068e | ||
|
|
0522508448 | ||
|
|
573441fc15 | ||
|
|
56b24e5765 | ||
|
|
e4cdb921d0 | ||
|
|
b5e943d659 | ||
|
|
b137622398 | ||
|
|
77a83234a7 | ||
|
|
8ec446d80e | ||
|
|
192ccfd999 | ||
|
|
785ccd8bf2 | ||
|
|
e350e9b7ff | ||
|
|
3685bb0a86 | ||
|
|
3793a548f7 | ||
|
|
0aef56bc46 | ||
|
|
8b8e78a00c | ||
|
|
57059c125b | ||
|
|
6bbfb62293 | ||
|
|
889e685389 | ||
|
|
39de6b76f5 | ||
|
|
33078fd3dc | ||
|
|
285bb31d19 | ||
|
|
434ac259d4 | ||
|
|
cc11730617 |
||
|
|
9c7051bb86 | ||
|
|
7617271824 |
||
|
|
ecac177983 | ||
|
|
e3c9945296 | ||
|
|
64d65252c1 | ||
|
|
b73086ff95 | ||
|
|
1b3f41012b | ||
|
|
ec477e54af | ||
|
|
227c802540 | ||
|
|
b3e2248d8e | ||
|
|
09863ff767 |
||
|
|
69b20f461f | ||
|
|
a1dd16a8cf | ||
|
|
b6ebe3a061 | ||
|
|
fc76f3016c | ||
|
|
0942269b58 | ||
|
|
32d712532f | ||
|
|
6adb88ea72 | ||
|
|
92456b7880 | ||
|
|
e5dd28249d | ||
|
|
986983e9c9 | ||
|
|
745ae87f4a | ||
|
|
5f16ea304c | ||
|
|
ba24fc8d9a | ||
|
|
c853cc8eeb |
||
|
|
10830c02ef |
||
|
|
794b8e694f | ||
|
|
d2bbc98e36 | ||
|
|
7242b41828 | ||
|
|
5c842621bd | ||
|
|
80bd221119 | ||
|
|
a3ee638979 | ||
|
|
20a161d513 | ||
|
|
0d3d2e7990 | ||
|
|
ce720efcfd | ||
|
|
70fcb79d64 | ||
|
|
695ec01ba4 | ||
|
|
0cae3b4aef |
||
|
|
ea6e1b113e |
||
|
|
34b882e036 | ||
|
|
c127237193 | ||
|
|
c84e7af695 | ||
|
|
cebe949469 | ||
|
|
990501fedd | ||
|
|
6b26bf3ddc | ||
|
|
549e8c2550 | ||
|
|
9cdef48085 | ||
|
|
edd65a1abe | ||
|
|
98fa9d96a2 | ||
|
|
f16b70c480 |
||
|
|
a155953d97 |
||
|
|
f693b23df2 |
||
|
|
71ac3ad873 |
||
|
|
b305ddcc31 |
||
|
|
dd3c5e3054 |
||
|
|
2471e90557 | ||
|
|
4573198ba4 | ||
|
|
1e9a0bb736 | ||
|
|
872078e178 | ||
|
|
0fefd265c3 | ||
|
|
7635906a13 | ||
|
|
3ba096d853 | ||
|
|
5c863fcd2e | ||
|
|
ff93132469 | ||
|
|
43bf9df753 | ||
|
|
4f7eb489a3 | ||
|
|
cae3081623 | ||
|
|
0ed4d7436a | ||
|
|
29ebd0850b | ||
|
|
ed6e5e94b9 | ||
|
|
a896af9641 | ||
|
|
dfbfb2d351 | ||
|
|
f11073847b | ||
|
|
021fe137a1 | ||
|
|
c01d0c0336 | ||
|
|
a50a39b4b7 | ||
|
|
9d7a07b50a | ||
|
|
2e5b4845de | ||
|
|
1e38a54f66 | ||
|
|
ebbc60642a |
||
|
|
50e61222c3 | ||
|
|
fb22e6ef95 | ||
|
|
919f3a4e18 | ||
|
|
fe02b0adc8 | ||
|
|
bb2a2a7575 | ||
|
|
211a9b894e | ||
|
|
52c0b84d65 |
||
|
|
71d735b2df | ||
|
|
6429138092 | ||
|
|
bd9285a1db |
||
|
|
be9ccaa59e | ||
|
|
a3783c6e42 | ||
|
|
217222c196 | ||
|
|
5fc72aa950 | ||
|
|
3fc926159e | ||
|
|
b0f249691c | ||
|
|
0cea3e61bd | ||
|
|
7b0923c1f7 | ||
|
|
a6cdf056fc | ||
|
|
fcaa6a5ee8 | ||
|
|
a2872814e3 | ||
|
|
0c3f996e0e | ||
|
|
8d11b30b5c | ||
|
|
5669554329 | ||
|
|
1fdccb4e36 | ||
|
|
9bc15f97b2 | ||
|
|
e9d43cf414 | ||
|
|
f0320f65ce | ||
|
|
1d3f9bdd83 | ||
|
|
8883b6936a | ||
|
|
66bc5720c5 | ||
|
|
8834eb44e7 | ||
|
|
0f6cf04319 | ||
|
|
dfa30dbf62 | ||
|
|
ca1bf8c4b0 | ||
|
|
47fd6c736b | ||
|
|
0f062a7138 | ||
|
|
766792120e | ||
|
|
7c398cfca6 | ||
|
|
950c479527 | ||
|
|
74fcee4467 | ||
|
|
91b57011ee | ||
|
|
acf3d13b64 | ||
|
|
93f57286d3 | ||
|
|
822bb09f8f | ||
|
|
7720dd970e | ||
|
|
a0c19151b5 | ||
|
|
4cbf094658 |
||
|
|
02edc2c392 | ||
|
|
fef6ce8dc2 | ||
|
|
a509abc40d | ||
|
|
3998581673 | ||
|
|
99b821e879 | ||
|
|
5cb86ee55b | ||
|
|
cc19b745ae | ||
|
|
84c5074511 | ||
|
|
fc91f7c954 | ||
|
|
4b6bfe3345 | ||
|
|
0d6d4d4e94 | ||
|
|
d067079e0a | ||
|
|
9e97bc10d5 | ||
|
|
4d8b7b8b16 |
||
|
|
d34dfa7339 | ||
|
|
cad91f4210 | ||
|
|
b43710b786 | ||
|
|
539c6215d7 | ||
|
|
3ef7774bdf | ||
|
|
6443c5b638 | ||
|
|
1a1f2e58f0 | ||
|
|
f7b4475541 | ||
|
|
79900ca898 | ||
|
|
7281a8d6ec | ||
|
|
0d97682dc6 | ||
|
|
2c58fbdc14 |
||
|
|
30c36c5de0 | ||
|
|
6a57688876 | ||
|
|
ceeffbaef6 | ||
|
|
e3d7ac1a0f | ||
|
|
6fe082419e | ||
|
|
e39d537380 | ||
|
|
0c25b15d41 | ||
|
|
5493a63874 | ||
|
|
3a2045b399 | ||
|
|
072063b8a8 | ||
|
|
e56beb368f | ||
|
|
7d70bc3539 | ||
|
|
6e544ccfc7 | ||
|
|
7168ebf8c8 | ||
|
|
522e3d507f | ||
|
|
6bb8c1c67f | ||
|
|
db18ea0f38 | ||
|
|
7ed543a1c5 | ||
|
|
8e155150a9 | ||
|
|
c299330174 | ||
|
|
ece8367329 | ||
|
|
1705059397 | ||
|
|
24838d18f3 | ||
|
|
38e7edf2cd |
||
|
|
f5539c640a | ||
|
|
d5f3755e61 | ||
|
|
bb213486a3 | ||
|
|
3b7ddb2524 | ||
|
|
8dee95cc1b | ||
|
|
566b1b75e4 | ||
|
|
236c6a143f | ||
|
|
4265a6089b | ||
|
|
76a5f8025b | ||
|
|
5777435901 | ||
|
|
d4742bcb40 | ||
|
|
d80d94ef3e | ||
|
|
585e804c10 | ||
|
|
28d13ee123 | ||
|
|
fe32a00340 | ||
|
|
0991a28b23 | ||
|
|
0946eb1a47 | ||
|
|
bea36afb82 | ||
|
|
6c21e2adb8 | ||
|
|
25ec4cc253 | ||
|
|
997407ba22 | ||
|
|
3c3f408f70 | ||
|
|
9f1a98a1b8 | ||
|
|
d6248457c5 | ||
|
|
7f38508f46 | ||
|
|
63dd485b34 | ||
|
|
fbb03850c5 | ||
|
|
27f7173c53 | ||
|
|
dec24438eb | ||
|
|
9d9157e6e1 | ||
|
|
10823479aa | ||
|
|
e3a3e63dba | ||
|
|
2d581148ee | ||
|
|
f6a7835bd7 | ||
|
|
f4a5ad5ef0 | ||
|
|
41d9b7e830 | ||
|
|
27d7666e45 | ||
|
|
4cf86dd929 | ||
|
|
2ff00ae905 |
||
|
|
d8bc7ce213 | ||
|
|
a7f80e5fd1 | ||
|
|
493987e2e4 | ||
|
|
f4c82e3c7a | ||
|
|
f586b0c1cc | ||
|
|
c968b0de67 | ||
|
|
873d4fcd5c | ||
|
|
6ee8e81d6d | ||
|
|
dc49a59a9c | ||
|
|
bf1a1e61df | ||
|
|
5c0192a445 | ||
|
|
34841ed2c8 | ||
|
|
d0a4cbd864 | ||
|
|
c7c51230d1 | ||
|
|
f89ab9056e | ||
|
|
dca8d10726 | ||
|
|
0ec75f36bc | ||
|
|
9c22daae6a | ||
|
|
9bb0aea519 | ||
|
|
bb0f0026b5 | ||
|
|
ad3298dd23 | ||
|
|
dd9704a8a3 | ||
|
|
6a8b3fe1d5 | ||
|
|
782d208d9b | ||
|
|
337c6ef4dc | ||
|
|
7f5efba427 | ||
|
|
e81933aff0 | ||
|
|
70262a35d4 | ||
|
|
5712b87023 | ||
|
|
1efe181fd2 | ||
|
|
ed026035ed | ||
|
|
aee27d7f2e | ||
|
|
cf0fd59892 | ||
|
|
b40d8f44de | ||
|
|
1f71a393a3 | ||
|
|
7abd581bc3 | ||
|
|
ee83513936 | ||
|
|
c2d947bf17 | ||
|
|
ce81d4bbde | ||
|
|
8a52783969 | ||
|
|
8494d60e8a | ||
|
|
443fc6d370 | ||
|
|
bba5731565 | ||
|
|
f78d4171bb |
||
|
|
4ee3818bb8 | ||
|
|
5605cc3d8a | ||
|
|
d98d27d833 | ||
|
|
b26aba0b28 |
||
|
|
e9835c734d | ||
|
|
273759d119 |
||
|
|
0115f01430 | ||
|
|
f3f6a20fbb | ||
|
|
e2e3ac9031 | ||
|
|
4b16ac8d95 | ||
|
|
7b3df5558d | ||
|
|
8d04bf014d | ||
|
|
b2129d7790 | ||
|
|
623185b685 | ||
|
|
6b55aa43f0 |
||
|
|
15c1cc8fdf | ||
|
|
a815a476e6 | ||
|
|
9f2e26306e | ||
|
|
0fc983fe24 |
||
|
|
65cc9a9597 | ||
|
|
4e98bfd650 | ||
|
|
d1d603bcdf | ||
|
|
e9172af6ee | ||
|
|
4c4ea18ca7 |
||
|
|
e663df72d5 | ||
|
|
33014e2afd | ||
|
|
7c1296856c | ||
|
|
315b3f0e0d | ||
|
|
de65350e17 | ||
|
|
27a9940505 | ||
|
|
16e028c05f | ||
|
|
3627522862 | ||
|
|
6de0f92dcb | ||
|
|
10c259525e |
||
|
|
050945901d | ||
|
|
c8c2d0faf8 | ||
|
|
c9186d1e81 | ||
|
|
bcef15a228 | ||
|
|
70bdd45fa4 | ||
|
|
bc8f7ac3c2 | ||
|
|
421417a09b | ||
|
|
623358eb14 | ||
|
|
85720b46e3 | ||
|
|
74c15bb648 | ||
|
|
354eae9bcb | ||
|
|
c1d4cebee4 | ||
|
|
fac7aade70 | ||
|
|
182981fb0c | ||
|
|
13f9a14f4f | ||
|
|
9ed66b26ce | ||
|
|
06391ac736 | ||
|
|
7beaff2b48 | ||
|
|
c6f455c676 | ||
|
|
889d3c705a | ||
|
|
d7cbbfac0e | ||
|
|
d5255624c6 | ||
|
|
185c437877 | ||
|
|
9ae1cbc152 | ||
|
|
0be7fae2bd | ||
|
|
03483a1044 | ||
|
|
f036b26454 | ||
|
|
dd927285d0 | ||
|
|
ef08388b48 | ||
|
|
b07956b2cf | ||
|
|
de1ca78cc3 | ||
|
|
274c712458 | ||
|
|
ab64636e64 | ||
|
|
ba2c077600 | ||
|
|
39b5ed90bc | ||
|
|
8359ee6da1 | ||
|
|
2efbd8515c | ||
|
|
27e23900bf | ||
|
|
b9b1e6fc03 | ||
|
|
266dd8593a | ||
|
|
e09a5ad052 | ||
|
|
b322c5c0b3 |
1173 changed files with 186419 additions and 120467 deletions
7
.github/ISSUE_TEMPLATE/config.yml
vendored
7
.github/ISSUE_TEMPLATE/config.yml
vendored
|
|
@ -1,6 +1,9 @@
|
|||
blank_issues_enabled: true
|
||||
blank_issues_enabled: false
|
||||
|
||||
contact_links:
|
||||
- name: Feature request
|
||||
url: https://github.com/doublecmd/doublecmd/discussions/categories/suggestions
|
||||
about: Please use GitHub Discussions to suggest a new feature or improvement
|
||||
- name: I have a question about Double Commander
|
||||
url: https://github.com/doublecmd/doublecmd/discussions
|
||||
url: https://github.com/doublecmd/doublecmd/discussions/categories/general
|
||||
about: Please use GitHub Discussions to ask questions
|
||||
|
|
|
|||
22
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
22
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
|
|
@ -1,22 +0,0 @@
|
|||
name: "Feature request"
|
||||
labels: [enhancement]
|
||||
description: Suggest a new feature or improvement
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before filling a new feature request, please use the [search form](https://doublecmd.sourceforge.io/mantisbt/view_all_bug_page.php) to try to locate similar features at the old bug tracker.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
placeholder:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Proposed technical implementation details (optional)
|
||||
placeholder:
|
||||
validations:
|
||||
required: false
|
||||
7
.github/dependabot.yml
vendored
Normal file
7
.github/dependabot.yml
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
112
.github/scripts/create_release.sh
vendored
Executable file
112
.github/scripts/create_release.sh
vendored
Executable 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
|
||||
13
.github/scripts/create_snapshot.bat
vendored
13
.github/scripts/create_snapshot.bat
vendored
|
|
@ -1,7 +1,4 @@
|
|||
|
||||
rem Set Double Commander version
|
||||
set DC_VER=1.1.0
|
||||
|
||||
rem The new package will be created from here
|
||||
set BUILD_PACK_DIR=%TEMP%\doublecmd-release
|
||||
|
||||
|
|
@ -15,12 +12,20 @@ rem Get revision number
|
|||
call src\platform\git2revisioninc.exe.cmd %CD%
|
||||
echo %REVISION%> %PACK_DIR%\revision.txt
|
||||
|
||||
rem Read version number
|
||||
for /f tokens^=2delims^=^" %%a in ('findstr "MajorVersionNr" src\doublecmd.lpi') do (set DC_MAJOR=%%a)
|
||||
for /f tokens^=2delims^=^" %%a in ('findstr "MinorVersionNr" src\doublecmd.lpi') do (set DC_MINOR=%%a)
|
||||
for /f tokens^=2delims^=^" %%a in ('findstr "RevisionNr" src\doublecmd.lpi') do (set DC_MICRO=%%a)
|
||||
if [%DC_MINOR%] == [] set DC_MINOR=0
|
||||
if [%DC_MICRO%] == [] set DC_MICRO=0
|
||||
set DC_VER=%DC_MAJOR%.%DC_MINOR%.%DC_MICRO%
|
||||
|
||||
rem Change log
|
||||
git log -n 10 --format="%%h %%al %%ai%%n%%s%%n" > %PACK_DIR%\changelog.txt
|
||||
|
||||
rem Get libraries
|
||||
pushd install
|
||||
curl -o windows.7z -L https://github.com/doublecmd/snapshots/raw/main/windows.7z
|
||||
curl -o windows.7z -L https://github.com/doublecmd/external/raw/main/windows.7z
|
||||
"%ProgramFiles%\7-Zip\7z.exe" x windows.7z
|
||||
del /Q windows.7z
|
||||
popd
|
||||
|
|
|
|||
55
.github/scripts/create_snapshot.lnx
vendored
Executable file
55
.github/scripts/create_snapshot.lnx
vendored
Executable file
|
|
@ -0,0 +1,55 @@
|
|||
#!/bin/bash
|
||||
|
||||
# The new package will be saved here
|
||||
PACK_DIR=$PWD/doublecmd-release
|
||||
|
||||
# Temp dir for creating *.tar.xz 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
|
||||
|
||||
# Get libraries
|
||||
pushd install
|
||||
wget https://github.com/doublecmd/external/raw/main/linux.tar.gz
|
||||
tar xzf linux.tar.gz
|
||||
rm -f linux.tar.gz
|
||||
popd
|
||||
|
||||
# Set widgetset
|
||||
export lcl=gtk3
|
||||
|
||||
# Set processor architecture
|
||||
export CPU_TARGET=$(fpc -iTP)
|
||||
|
||||
build_doublecmd()
|
||||
{
|
||||
# Build all components of Double Commander
|
||||
./build.sh release
|
||||
|
||||
# Copy libraries
|
||||
cp -a install/linux/lib/$CPU_TARGET/*.so ./
|
||||
|
||||
# Create *.tar.xz package
|
||||
mkdir -p $BUILD_PACK_DIR
|
||||
install/linux/install.sh --portable-prefix=$BUILD_PACK_DIR
|
||||
pushd $BUILD_PACK_DIR
|
||||
# Set run-time library search path
|
||||
patchelf --set-rpath '$ORIGIN' doublecmd/doublecmd
|
||||
tar -cJf $PACK_DIR/doublecmd-$DC_VER-$DC_REVISION.$lcl.$CPU_TARGET.tar.xz doublecmd
|
||||
popd
|
||||
|
||||
# Clean DC build dir
|
||||
./clean.sh
|
||||
rm -rf $BUILD_PACK_DIR
|
||||
}
|
||||
|
||||
mkdir -p $PACK_DIR
|
||||
|
||||
build_doublecmd
|
||||
66
.github/scripts/create_snapshot.sh
vendored
66
.github/scripts/create_snapshot.sh
vendored
|
|
@ -1,8 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Set Double Commander version
|
||||
DC_VER=1.1.0
|
||||
|
||||
# The new package will be saved here
|
||||
PACK_DIR=$PWD/doublecmd-release
|
||||
|
||||
|
|
@ -12,6 +9,19 @@ 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
|
||||
|
||||
# Get libraries
|
||||
pushd install
|
||||
wget https://github.com/doublecmd/external/raw/main/darwin.tar.gz
|
||||
tar xzf darwin.tar.gz
|
||||
rm -f darwin.tar.gz
|
||||
popd
|
||||
|
||||
# Set widgetset
|
||||
export lcl=cocoa
|
||||
|
||||
|
|
@ -19,21 +29,65 @@ 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()
|
||||
{
|
||||
# Build all components of Double Commander
|
||||
./build.sh release
|
||||
|
||||
# Create *.dmg package
|
||||
# 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'
|
||||
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
|
||||
|
||||
# Create *.dmg package
|
||||
HDI_TRY=0
|
||||
HDI_MAX=5
|
||||
|
||||
while true; do
|
||||
|
||||
HDI_TRY=$((HDI_TRY+1))
|
||||
|
||||
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;
|
||||
|
||||
sudo 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/"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
if [ $HDI_TRY -eq $HDI_MAX ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
sleep 10
|
||||
|
||||
done
|
||||
|
||||
# Clean DC build dir
|
||||
./clean.sh
|
||||
rm -rf $BUILD_PACK_DIR
|
||||
|
|
@ -53,6 +107,6 @@ build_doublecmd
|
|||
# Set processor architecture
|
||||
export CPU_TARGET=x86_64
|
||||
# Set minimal Mac OS X target version
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.11
|
||||
export MACOSX_DEPLOYMENT_TARGET=11.0
|
||||
|
||||
build_doublecmd
|
||||
|
|
|
|||
4
.github/scripts/upload_snapshot.sh
vendored
4
.github/scripts/upload_snapshot.sh
vendored
|
|
@ -11,7 +11,7 @@ if [[ "$OSTYPE" == "msys" ]]; then
|
|||
|
||||
icacls.exe ssh_key //inheritance:r
|
||||
|
||||
echo "rm *.7z" >> upload_snapshot.txt
|
||||
echo "-rm *.7z" >> upload_snapshot.txt
|
||||
echo "put *.7z" >> upload_snapshot.txt
|
||||
echo "put *.txt" >> upload_snapshot.txt
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ else
|
|||
|
||||
chmod 0600 ssh_key
|
||||
|
||||
echo "rm *.dmg" >> upload_snapshot.txt
|
||||
echo "-rm *.dmg" >> upload_snapshot.txt
|
||||
echo "put *.dmg" >> upload_snapshot.txt
|
||||
echo "put *.php" >> upload_snapshot.txt
|
||||
|
||||
|
|
|
|||
58
.github/workflows/release.yml
vendored
Normal file
58
.github/workflows/release.yml
vendored
Normal 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@v6
|
||||
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@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download unrar source code
|
||||
run: wget https://www.rarlab.com/rar/unrarsrc-7.2.3.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
|
||||
124
.github/workflows/snapshots.yml
vendored
124
.github/workflows/snapshots.yml
vendored
|
|
@ -1,6 +1,7 @@
|
|||
name: build-snapshot
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- 'components/**'
|
||||
|
|
@ -16,62 +17,139 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build-mac:
|
||||
runs-on: macos-11
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- name: Install Free Pascal
|
||||
uses: alexx2000/setup-fpc@master
|
||||
uses: doublecmd/lazarus-install@mac
|
||||
with:
|
||||
lazarus-version: "stable"
|
||||
|
||||
- name: Get Lazarus source
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: 'fpc/Lazarus'
|
||||
|
||||
- name: Build and install Lazarus
|
||||
run: make all install
|
||||
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
|
||||
mkdir -p $HOME/.lazarus
|
||||
cp tools/install/macosx/environmentoptions.xml $HOME/.lazarus/environmentoptions.xml
|
||||
sed -i -e "s|_PPCARCH_|fpc|g; s|/Developer/lazarus|/usr/local/share/lazarus|g" $HOME/.lazarus/environmentoptions.xml
|
||||
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Prepare source
|
||||
run: sed -i -e "s|BOX_CLIENT_SECRET = '\*'|BOX_CLIENT_SECRET = '$BOX_CLIENT_SECRET'|g" plugins/wfx/MacCloud/src/drivers/oauth2/box/uboxclient.pas
|
||||
env:
|
||||
BOX_CLIENT_SECRET: ${{ secrets.BOX_CLIENT_SECRET }}
|
||||
|
||||
- name: Build packages
|
||||
run: ./.github/scripts/create_snapshot.sh
|
||||
|
||||
- name: Deploy to snapshot server
|
||||
run: ./.github/scripts/upload_snapshot.sh
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
|
||||
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
|
||||
REMOTE_USER: ${{ secrets.REMOTE_USER }}
|
||||
- name: Share data between jobs
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: snapshot-mac
|
||||
retention-days: 1
|
||||
compression-level: 0
|
||||
path: doublecmd-release/doublecmd*.dmg
|
||||
|
||||
build-win:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Install Lazarus
|
||||
uses: alexx2000/setup-fpc@win
|
||||
uses: doublecmd/lazarus-install@win
|
||||
with:
|
||||
lazarus-version: "2.2.6"
|
||||
lazarus-version: "stable"
|
||||
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Restore timestamps
|
||||
uses: chetan/git-restore-mtime-action@v2
|
||||
|
||||
- name: Build packages
|
||||
run: ./.github/scripts/create_snapshot.bat
|
||||
|
||||
- name: Deploy to snapshot server
|
||||
run: ./.github/scripts/upload_snapshot.sh
|
||||
- name: Share data between jobs
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: snapshot-win
|
||||
retention-days: 1
|
||||
compression-level: 0
|
||||
path: doublecmd-release/*
|
||||
|
||||
build-lin:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install fpc patchelf libgtk-3-dev libdbus-1-dev
|
||||
|
||||
- name: Get Lazarus source
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: 'fpc/Lazarus'
|
||||
|
||||
- name: Build and install Lazarus
|
||||
run: |
|
||||
make all
|
||||
sudo make install
|
||||
|
||||
- name: Create Lazarus config
|
||||
run: |
|
||||
mkdir -p $HOME/.lazarus
|
||||
cp tools/install/linux/environmentoptions.xml $HOME/.lazarus/environmentoptions.xml
|
||||
sed -i -e "s|__LAZARUSDIR__|/usr/local/share/lazarus|g" $HOME/.lazarus/environmentoptions.xml
|
||||
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Build packages
|
||||
run: ./.github/scripts/create_snapshot.lnx
|
||||
|
||||
- name: Share data between jobs
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: snapshot-lin
|
||||
retention-days: 1
|
||||
compression-level: 0
|
||||
path: doublecmd-release/doublecmd*.tar.xz
|
||||
|
||||
upload:
|
||||
needs: [build-win, build-mac, build-lin]
|
||||
runs-on: ubuntu-latest
|
||||
environment: snapshots
|
||||
steps:
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
merge-multiple: true
|
||||
|
||||
- name: Save revision number
|
||||
run: echo "REVISION=$(cat revision.txt)" >> "$GITHUB_ENV"
|
||||
shell: bash
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
|
||||
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
|
||||
REMOTE_USER: ${{ secrets.REMOTE_USER }}
|
||||
|
||||
- name: Upload binaries to snapshots
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_name: doublecmd/snapshots
|
||||
repo_token: ${{ secrets.SNAPSHOTS }}
|
||||
file: ./*
|
||||
release_name: Revision ${{ env.REVISION }}
|
||||
tag: ${{ env.REVISION }}
|
||||
body: ${{ vars.BODY }}
|
||||
overwrite: true
|
||||
file_glob: true
|
||||
|
|
|
|||
4
.github/workflows/winget.yml
vendored
4
.github/workflows/winget.yml
vendored
|
|
@ -4,10 +4,10 @@ on:
|
|||
types: [released]
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: windows-latest # action can only be run on windows
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: vedantmgoyal2009/winget-releaser@v2
|
||||
with:
|
||||
identifier: alexx2000.DoubleCommander
|
||||
installers-regex: '.(exe|msi)$'
|
||||
installers-regex: '\.msi$'
|
||||
token: ${{ secrets.WINGET_TOKEN }}
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -16,6 +16,7 @@
|
|||
*.w?x
|
||||
units/
|
||||
/doublecmd
|
||||
tools/extractdwrflnfo
|
||||
|
||||
# Lazarus autogenerated files (duplicated info)
|
||||
*.rst
|
||||
|
|
|
|||
|
|
@ -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\*.*
|
||||
|
|
|
|||
5
clean.sh
5
clean.sh
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 <> 'arm') 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"/>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
2421
components/Image32/source/Clipper2/Clipper.Core.pas
Normal file
2421
components/Image32/source/Clipper2/Clipper.Core.pas
Normal file
File diff suppressed because it is too large
Load diff
4259
components/Image32/source/Clipper2/Clipper.Engine.pas
Normal file
4259
components/Image32/source/Clipper2/Clipper.Engine.pas
Normal file
File diff suppressed because it is too large
Load diff
133
components/Image32/source/Clipper2/Clipper.Minkowski.pas
Normal file
133
components/Image32/source/Clipper2/Clipper.Minkowski.pas
Normal 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.
|
||||
|
||||
1031
components/Image32/source/Clipper2/Clipper.Offset.pas
Normal file
1031
components/Image32/source/Clipper2/Clipper.Offset.pas
Normal file
File diff suppressed because it is too large
Load diff
1247
components/Image32/source/Clipper2/Clipper.RectClip.pas
Normal file
1247
components/Image32/source/Clipper2/Clipper.RectClip.pas
Normal file
File diff suppressed because it is too large
Load diff
39
components/Image32/source/Clipper2/Clipper.inc
Normal file
39
components/Image32/source/Clipper2/Clipper.inc
Normal 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}
|
||||
972
components/Image32/source/Clipper2/Clipper.pas
Normal file
972
components/Image32/source/Clipper2/Clipper.pas
Normal 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.
|
||||
|
||||
|
||||
197
components/Image32/source/Img32.Clipper2.pas
Normal file
197
components/Image32/source/Img32.Clipper2.pas
Normal 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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
|
@ -3,7 +3,7 @@
|
|||
-------------------------------------------------------------------------
|
||||
Control like TButton which does not steal focus on click
|
||||
|
||||
Copyright (C) 2021-2023 Alexander Koblov (alexx2000@mail.ru)
|
||||
Copyright (C) 2021-2026 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
|
||||
|
|
@ -27,7 +27,7 @@ interface
|
|||
|
||||
uses
|
||||
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls,
|
||||
Buttons, Themes, Types;
|
||||
Buttons, Themes, Types, ImgList, LMessages;
|
||||
|
||||
type
|
||||
|
||||
|
|
@ -37,11 +37,20 @@ type
|
|||
private
|
||||
FState: TButtonState;
|
||||
FShowCaption: Boolean;
|
||||
FMouseInControl: Boolean;
|
||||
FButtonGlyph: TButtonGlyph;
|
||||
FImageChangeLink: TChangeLink;
|
||||
private
|
||||
function GetGlyph: TBitmap;
|
||||
function GetImageWidth: Integer;
|
||||
function IsGlyphStored: Boolean;
|
||||
procedure SetGlyph(AValue: TBitmap);
|
||||
function GetImageIndex: TImageIndex;
|
||||
function GetImages: TCustomImageList;
|
||||
procedure SetImageWidth(AValue: Integer);
|
||||
procedure SetShowCaption(AValue: Boolean);
|
||||
procedure SetImageIndex(AValue: TImageIndex);
|
||||
procedure SetImages(AValue: TCustomImageList);
|
||||
function GetDrawDetails: TThemedElementDetails;
|
||||
protected
|
||||
procedure Paint; override;
|
||||
|
|
@ -54,15 +63,21 @@ type
|
|||
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
||||
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
||||
protected
|
||||
function GetGlyphSize: TSize;
|
||||
procedure GlyphChanged(Sender: TObject);
|
||||
procedure ImageListChange(Sender: TObject);
|
||||
class function GetControlClassDefaultSize: TSize; override;
|
||||
procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
|
||||
procedure CMEnabledChanged(var Message: TLMessage); message CM_ENABLEDCHANGED;
|
||||
procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: Integer; WithThemeSpace: Boolean); override;
|
||||
public
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
published
|
||||
property Action;
|
||||
property Images: TCustomImageList read GetImages write SetImages;
|
||||
property ImageIndex: TImageIndex read GetImageIndex write SetImageIndex default -1;
|
||||
property ImageWidth: Integer read GetImageWidth write SetImageWidth default 0;
|
||||
property Glyph: TBitmap read GetGlyph write SetGlyph stored IsGlyphStored;
|
||||
property ShowCaption: Boolean read FShowCaption write SetShowCaption default True;
|
||||
end;
|
||||
|
|
@ -72,13 +87,16 @@ procedure Register;
|
|||
implementation
|
||||
|
||||
uses
|
||||
LCLType, LCLProc, LCLIntf, ActnList;
|
||||
LCLType, LCLProc, LCLIntf, ActnList, GraphType;
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterComponents('KASComponents',[TKASButton]);
|
||||
end;
|
||||
|
||||
const
|
||||
UpState: array[Boolean] of TButtonState = (bsUp, bsHot);
|
||||
|
||||
{ TKASButton }
|
||||
|
||||
procedure TKASButton.DoEnter;
|
||||
|
|
@ -125,6 +143,21 @@ begin
|
|||
Result:= FButtonGlyph.Glyph;
|
||||
end;
|
||||
|
||||
function TKASButton.GetImageIndex: TImageIndex;
|
||||
begin
|
||||
Result:= FButtonGlyph.ExternalImageIndex;
|
||||
end;
|
||||
|
||||
function TKASButton.GetImages: TCustomImageList;
|
||||
begin
|
||||
Result:= FButtonGlyph.ExternalImages;
|
||||
end;
|
||||
|
||||
function TKASButton.GetImageWidth: Integer;
|
||||
begin
|
||||
Result:= FButtonGlyph.ExternalImageWidth;
|
||||
end;
|
||||
|
||||
function TKASButton.IsGlyphStored: Boolean;
|
||||
var
|
||||
Act: TCustomAction;
|
||||
|
|
@ -148,11 +181,41 @@ begin
|
|||
AdjustSize;
|
||||
end;
|
||||
|
||||
procedure TKASButton.SetImageIndex(AValue: TImageIndex);
|
||||
begin
|
||||
FButtonGlyph.ExternalImageIndex:= AValue;
|
||||
end;
|
||||
|
||||
procedure TKASButton.SetImages(AValue: TCustomImageList);
|
||||
begin
|
||||
if FButtonGlyph.ExternalImages <> nil then
|
||||
begin
|
||||
FButtonGlyph.ExternalImages.UnRegisterChanges(FImageChangeLink);
|
||||
FButtonGlyph.ExternalImages.RemoveFreeNotification(Self);
|
||||
end;
|
||||
FButtonGlyph.ExternalImages := AValue;
|
||||
if FButtonGlyph.ExternalImages <> nil then
|
||||
begin
|
||||
FButtonGlyph.ExternalImages.FreeNotification(Self);
|
||||
FButtonGlyph.ExternalImages.RegisterChanges(FImageChangeLink);
|
||||
end;
|
||||
InvalidatePreferredSize;
|
||||
AdjustSize;
|
||||
end;
|
||||
|
||||
procedure TKASButton.SetImageWidth(AValue: Integer);
|
||||
begin
|
||||
FButtonGlyph.ExternalImageWidth:= AValue;
|
||||
InvalidatePreferredSize;
|
||||
AdjustSize;
|
||||
end;
|
||||
|
||||
procedure TKASButton.Paint;
|
||||
var
|
||||
APoint: TPoint;
|
||||
SysFont: TFont;
|
||||
PaintRect: TRect;
|
||||
AGlyphSize: TSize;
|
||||
TextFlags: Integer;
|
||||
Details: TThemedElementDetails;
|
||||
begin
|
||||
|
|
@ -181,17 +244,22 @@ begin
|
|||
DrawText(Canvas.Handle, PChar(Caption), Length(Caption), PaintRect, TextFlags);
|
||||
end;
|
||||
end
|
||||
else if not FButtonGlyph.Glyph.Empty then
|
||||
begin
|
||||
APoint.X:= (PaintRect.Width - FButtonGlyph.Width) div 2;
|
||||
APoint.Y:= (PaintRect.Height - FButtonGlyph.Height) div 2;
|
||||
FButtonGlyph.Draw(Canvas, PaintRect, APoint, FState, True, 0);
|
||||
else begin
|
||||
AGlyphSize:= GetGlyphSize;
|
||||
|
||||
if (AGlyphSize.CX > 0) and (AGlyphSize.CY > 0) then
|
||||
begin
|
||||
APoint.X:= (PaintRect.Width - AGlyphSize.CX) div 2;
|
||||
APoint.Y:= (PaintRect.Height - AGlyphSize.CY) div 2;
|
||||
FButtonGlyph.Draw(Canvas, PaintRect, APoint, FState, True, 0, Font.PixelsPerInch, GetCanvasScaleFactor);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TKASButton.MouseEnter;
|
||||
begin
|
||||
inherited MouseEnter;
|
||||
FMouseInControl:= True;
|
||||
FState:= bsHot;
|
||||
Invalidate;
|
||||
end;
|
||||
|
|
@ -199,6 +267,7 @@ end;
|
|||
procedure TKASButton.MouseLeave;
|
||||
begin
|
||||
inherited MouseLeave;
|
||||
FMouseInControl:= False;
|
||||
FState:= bsUp;
|
||||
Invalidate;
|
||||
end;
|
||||
|
|
@ -240,12 +309,37 @@ begin
|
|||
Invalidate;
|
||||
end;
|
||||
|
||||
function TKASButton.GetGlyphSize: TSize;
|
||||
var
|
||||
AIndex: Integer;
|
||||
AEffect: TGraphicsDrawEffect;
|
||||
AImageRes: TScaledImageListResolution;
|
||||
begin
|
||||
if (FButtonGlyph.Glyph.Empty) and ((Images = nil) or (ImageIndex = -1)) then
|
||||
begin
|
||||
Result.CX:= 0;
|
||||
Result.CY:= 0;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
FButtonGlyph.GetImageIndexAndEffect(Low(TButtonState), Font.PixelsPerInch,
|
||||
GetCanvasScaleFactor, AImageRes, AIndex, AEffect);
|
||||
|
||||
Result.CX:= AImageRes.Width;
|
||||
Result.CY:= AImageRes.Height;
|
||||
end;
|
||||
|
||||
procedure TKASButton.GlyphChanged(Sender: TObject);
|
||||
begin
|
||||
InvalidatePreferredSize;
|
||||
AdjustSize;
|
||||
end;
|
||||
|
||||
procedure TKASButton.ImageListChange(Sender: TObject);
|
||||
begin
|
||||
if Sender = Images then Invalidate;
|
||||
end;
|
||||
|
||||
class function TKASButton.GetControlClassDefaultSize: TSize;
|
||||
begin
|
||||
Result.CX := 23;
|
||||
|
|
@ -267,23 +361,36 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TKASButton.CMEnabledChanged(var Message: TLMessage);
|
||||
begin
|
||||
if Enabled then
|
||||
FState:= UpState[FMouseInControl]
|
||||
else begin
|
||||
FState:= bsDisabled;
|
||||
end;
|
||||
inherited CMEnabledChanged(Message);
|
||||
end;
|
||||
|
||||
procedure TKASButton.CalculatePreferredSize(var PreferredWidth,
|
||||
PreferredHeight: Integer; WithThemeSpace: Boolean);
|
||||
var
|
||||
PaintRect: TRect;
|
||||
ClientRect: TRect;
|
||||
AGlyphSize: TSize;
|
||||
Details: TThemedElementDetails;
|
||||
begin
|
||||
inherited CalculatePreferredSize(PreferredWidth, PreferredHeight, WithThemeSpace);
|
||||
|
||||
if (not FButtonGlyph.Glyph.Empty) then
|
||||
AGlyphSize:= GetGlyphSize;
|
||||
|
||||
if (AGlyphSize.CX > 0) and (AGlyphSize.CY > 0) then
|
||||
begin
|
||||
Details:= GetDrawDetails;
|
||||
PaintRect:= TRect.Create(0, 0, 32, 32);
|
||||
ClientRect:= ThemeServices.ContentRect(Canvas.Handle, Details, PaintRect);
|
||||
|
||||
PreferredWidth:= Abs(PaintRect.Width - ClientRect.Width) + FButtonGlyph.Width;
|
||||
PreferredHeight:= Abs(PaintRect.Height - ClientRect.Height) + FButtonGlyph.Height;
|
||||
PreferredWidth:= Abs(PaintRect.Width - ClientRect.Width) + AGlyphSize.CX;
|
||||
PreferredHeight:= Abs(PaintRect.Height - ClientRect.Height) + AGlyphSize.CY;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
@ -296,6 +403,9 @@ begin
|
|||
FButtonGlyph.OnChange := GlyphChanged;
|
||||
FButtonGlyph.IsDesigning := csDesigning in ComponentState;
|
||||
|
||||
FImageChangeLink := TChangeLink.Create;
|
||||
FImageChangeLink.OnChange := ImageListChange;
|
||||
|
||||
FShowCaption:= True;
|
||||
TabStop:= True;
|
||||
end;
|
||||
|
|
@ -303,6 +413,7 @@ end;
|
|||
destructor TKASButton.Destroy;
|
||||
begin
|
||||
FreeAndNil(FButtonGlyph);
|
||||
FreeAndNil(FImageChangeLink);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -26,7 +26,7 @@ unit KASCDEdit;
|
|||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, LResources, Controls, Graphics, Dialogs, Types,
|
||||
Classes, SysUtils, LazVersion, LResources, Controls, Graphics, Dialogs, Types,
|
||||
Menus, CustomDrawnControls, CustomDrawnDrawers, CustomDrawn_Common;
|
||||
|
||||
type
|
||||
|
|
@ -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);
|
||||
|
|
@ -415,6 +412,12 @@ begin
|
|||
begin
|
||||
inherited MouseDown(Button, Shift, X, Y);
|
||||
|
||||
{$IF Laz_FullVersion >= 4990000}
|
||||
// see also LCL 4b41b7a:
|
||||
// customdrawn: remove redundant SetFocus from TCDControl.MouseDown
|
||||
SetFocus();
|
||||
{$ENDIF}
|
||||
|
||||
FDragDropStarted := True;
|
||||
|
||||
// Caret positioning
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
312
components/KASToolBar/kascomctrls.pas
Normal file
312
components/KASToolBar/kascomctrls.pas
Normal 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.
|
||||
|
||||
|
|
@ -26,8 +26,8 @@
|
|||
"/>
|
||||
<License Value="GNU GPL 2
|
||||
"/>
|
||||
<Version Major="1" Minor="9" Release="4"/>
|
||||
<Files Count="10">
|
||||
<Version Major="1" Minor="10"/>
|
||||
<Files Count="12">
|
||||
<Item1>
|
||||
<Filename Value="kastoolbar.pas"/>
|
||||
<HasRegisterProc Value="True"/>
|
||||
|
|
@ -77,6 +77,16 @@
|
|||
<HasRegisterProc Value="True"/>
|
||||
<UnitName Value="KASButtonPanel"/>
|
||||
</Item10>
|
||||
<Item11>
|
||||
<Filename Value="kascomctrls.pas"/>
|
||||
<HasRegisterProc Value="True"/>
|
||||
<UnitName Value="KASComCtrls"/>
|
||||
</Item11>
|
||||
<Item12>
|
||||
<Filename Value="kascontrols.pas"/>
|
||||
<HasRegisterProc Value="True"/>
|
||||
<UnitName Value="kascontrols"/>
|
||||
</Item12>
|
||||
</Files>
|
||||
<CompatibilityMode Value="True"/>
|
||||
<RequiredPkgs Count="3">
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ interface
|
|||
uses
|
||||
KASToolBar, KASProgressBar, KASPathEdit, KASToolItems, KASComboBox,
|
||||
KASCDEdit, KASStatusBar, KASToolPanel, KASButton, KASButtonPanel,
|
||||
LazarusPackageIntf;
|
||||
KASComCtrls, KASControls, LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
|
|
@ -25,6 +25,8 @@ begin
|
|||
RegisterUnit('KASToolPanel', @KASToolPanel.Register);
|
||||
RegisterUnit('KASButton', @KASButton.Register);
|
||||
RegisterUnit('KASButtonPanel', @KASButtonPanel.Register);
|
||||
RegisterUnit('KASComCtrls', @KASComCtrls.Register);
|
||||
RegisterUnit('KASControls', @KASControls.Register);
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
|
|
|||
89
components/KASToolBar/kascontrols.pas
Normal file
89
components/KASToolBar/kascontrols.pas
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
unit KASControls;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Controls, StdCtrls, ExtCtrls;
|
||||
|
||||
type
|
||||
|
||||
{ TKASPanel }
|
||||
|
||||
TKASPanel = class(TPanel)
|
||||
private
|
||||
FOnAutoSize: TNotifyEvent;
|
||||
protected
|
||||
procedure DoAutoSize; override;
|
||||
published
|
||||
property OnAutoSize: TNotifyEvent read FOnAutoSize write FOnAutoSize;
|
||||
end;
|
||||
|
||||
{ TKASGroupBox }
|
||||
|
||||
TKASGroupBox = class(TGroupBox)
|
||||
private
|
||||
FOnAutoSize: TNotifyEvent;
|
||||
protected
|
||||
procedure DoAutoSize; override;
|
||||
published
|
||||
property OnAutoSize: TNotifyEvent read FOnAutoSize write FOnAutoSize;
|
||||
end;
|
||||
|
||||
procedure Register;
|
||||
|
||||
implementation
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterComponents('KASComponents', [TKASPanel, TKASGroupBox]);
|
||||
end;
|
||||
|
||||
procedure LabelsAutoSize(Self: TWinControl);
|
||||
var
|
||||
Index: Integer;
|
||||
AControl: TControl;
|
||||
begin
|
||||
with Self do
|
||||
begin
|
||||
DisableAutoSizing;
|
||||
for Index:= 0 to ControlCount - 1 do
|
||||
begin
|
||||
AControl:= Controls[Index];
|
||||
if (not (AControl is TLabel)) and Assigned(AControl.AnchorSide[akTop].Control) then
|
||||
begin
|
||||
if AControl.AnchorSide[akTop].Control is TLabel then
|
||||
AControl.AnchorSide[akTop].Control.Constraints.MinHeight:= AControl.Height;
|
||||
end;
|
||||
end;
|
||||
EnableAutoSizing;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TKASPanel }
|
||||
|
||||
procedure TKASPanel.DoAutoSize;
|
||||
begin
|
||||
inherited DoAutoSize;
|
||||
if not (csDesigning in ComponentState) then
|
||||
begin
|
||||
LabelsAutoSize(Self);
|
||||
if Assigned(FOnAutoSize) then FOnAutoSize(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TKASGroupBox }
|
||||
|
||||
procedure TKASGroupBox.DoAutoSize;
|
||||
begin
|
||||
inherited DoAutoSize;
|
||||
if not (csDesigning in ComponentState) then
|
||||
begin
|
||||
LabelsAutoSize(Self);
|
||||
if Assigned(FOnAutoSize) then FOnAutoSize(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
unit KASPathEdit;
|
||||
|
||||
{$mode delphi}
|
||||
{$interfaces corba}
|
||||
{$IF DEFINED(LCLCOCOA)}
|
||||
{$modeswitch objectivec1}
|
||||
{$ENDIF}
|
||||
|
|
@ -38,15 +39,34 @@ uses
|
|||
|
||||
type
|
||||
|
||||
{ TKASPathEditGetFilesFunc }
|
||||
|
||||
TKASPathEditGetFilesFunc = Procedure (
|
||||
const path: String;
|
||||
const types: TObjectTypes;
|
||||
const sort: TFileSortType;
|
||||
files: TStringList );
|
||||
|
||||
{ IKASPathEditMate }
|
||||
|
||||
IKASPathEditMate = interface
|
||||
function getFilesAtPath(
|
||||
const path: String;
|
||||
const types: TObjectTypes;
|
||||
const sort: TFileSortType ): TStringList;
|
||||
end;
|
||||
|
||||
{ TKASPathEdit }
|
||||
|
||||
TKASPathEdit = class(TEdit)
|
||||
private
|
||||
FMate: IKASPathEditMate;
|
||||
FKeyDown: Word;
|
||||
FBasePath: String;
|
||||
FListBox: TListBox;
|
||||
FPanel: THintWindow;
|
||||
FAutoComplete: Boolean;
|
||||
FGetFilesFunc: TKASPathEditGetFilesFunc;
|
||||
FStringList: TStringList;
|
||||
FObjectTypes: TObjectTypes;
|
||||
FFileSortType: TFileSortType;
|
||||
|
|
@ -80,6 +100,8 @@ type
|
|||
onKeyRETURN: TNotifyEvent;
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
property GetFilesFunc: TKASPathEditGetFilesFunc read FGetFilesFunc write FGetFilesFunc;
|
||||
property Mate: IKASPathEditMate read FMate write FMate;
|
||||
published
|
||||
property ObjectTypes: TObjectTypes read FObjectTypes write SetObjectTypes;
|
||||
property FileSortType: TFileSortType read FFileSortType write FFileSortType;
|
||||
|
|
@ -129,77 +151,6 @@ begin
|
|||
RegisterComponents('KASComponents', [TKASPathEdit]);
|
||||
end;
|
||||
|
||||
function FilesSortAlphabet(List: TStringList; Index1, Index2: Integer): Integer;
|
||||
begin
|
||||
Result:= CompareFilenames(List[Index1], List[Index2]);
|
||||
end;
|
||||
|
||||
function FilesSortFoldersFirst(List: TStringList; Index1, Index2: Integer): Integer;
|
||||
var
|
||||
Attr1, Attr2: IntPtr;
|
||||
begin
|
||||
Attr1:= IntPtr(List.Objects[Index1]);
|
||||
Attr2:= IntPtr(List.Objects[Index2]);
|
||||
if (Attr1 and faDirectory <> 0) and (Attr2 and faDirectory <> 0) then
|
||||
Result:= CompareFilenames(List[Index1], List[Index2])
|
||||
else begin
|
||||
if (Attr1 and faDirectory <> 0) then
|
||||
Result:= -1
|
||||
else begin
|
||||
Result:= 1;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure GetFilesInDir(const ABaseDir: String; AMask: String; AObjectTypes: TObjectTypes;
|
||||
AResult: TStringList; AFileSortType: TFileSortType);
|
||||
var
|
||||
ExcludeAttr: Integer;
|
||||
SearchRec: TSearchRec;
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
ErrMode : LongWord;
|
||||
{$ENDIF}
|
||||
begin
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
ErrMode:= SetErrorMode(SEM_FAILCRITICALERRORS or SEM_NOALIGNMENTFAULTEXCEPT or SEM_NOGPFAULTERRORBOX or SEM_NOOPENFILEERRORBOX);
|
||||
try
|
||||
{$ENDIF}
|
||||
if FindFirst(ABaseDir + AMask, faAnyFile, SearchRec) = 0 then
|
||||
begin
|
||||
ExcludeAttr:= 0;
|
||||
|
||||
if not (otHidden in AObjectTypes) then
|
||||
ExcludeAttr:= ExcludeAttr or faHidden;
|
||||
if not (otFolders in AObjectTypes) then
|
||||
ExcludeAttr:= ExcludeAttr or faDirectory;
|
||||
|
||||
repeat
|
||||
if (SearchRec.Attr and ExcludeAttr <> 0) then
|
||||
Continue;
|
||||
if (SearchRec.Name = '.') or (SearchRec.Name = '..')then
|
||||
Continue;
|
||||
if (SearchRec.Attr and faDirectory = 0) and not (otNonFolders in AObjectTypes) then
|
||||
Continue;
|
||||
|
||||
AResult.AddObject(SearchRec.Name, TObject(IntPtr(SearchRec.Attr)));
|
||||
until FindNext(SearchRec) <> 0;
|
||||
|
||||
if AResult.Count > 0 then
|
||||
begin
|
||||
case AFileSortType of
|
||||
fstAlphabet: AResult.CustomSort(@FilesSortAlphabet);
|
||||
fstFoldersFirst: AResult.CustomSort(@FilesSortFoldersFirst);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
SysUtils.FindClose(SearchRec);
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
finally
|
||||
SetErrorMode(ErrMode);
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
{ TKASPathEdit }
|
||||
|
||||
function TKASPathEdit.isShowingListBox(): Boolean;
|
||||
|
|
@ -208,7 +159,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]
|
||||
|
|
@ -226,49 +177,49 @@ begin
|
|||
BasePath:= ExtractFilePath(Path);
|
||||
if CompareFilenames(FBasePath, BasePath) <> 0 then
|
||||
begin
|
||||
FStringList.Clear;
|
||||
FreeAndNil(FStringList);
|
||||
FBasePath:= BasePath;
|
||||
GetFilesInDir(BasePath, AllFilesMask, FObjectTypes, FStringList, FFileSortType);
|
||||
if Assigned(FMate) then
|
||||
FStringList:= FMate.getFilesAtPath(BasePath, FObjectTypes, FFileSortType);
|
||||
end;
|
||||
if (FStringList.Count > 0) then
|
||||
begin
|
||||
FListBox.Items.BeginUpdate;
|
||||
try
|
||||
// Check mask and make absolute file name
|
||||
AMask:= TMask.Create(ExtractFileName(Path) + '*',
|
||||
{$IF LCL_FULLVERSION >= 2020000}
|
||||
AFlags[FileNameCaseSensitive]
|
||||
if (FStringList=nil) or (FStringList.Count<=0) then
|
||||
Exit;
|
||||
FListBox.Items.BeginUpdate;
|
||||
try
|
||||
// Check mask and make absolute file name
|
||||
AMask:= TMask.Create(ExtractFileName(Path) + '*',
|
||||
{$IF LCL_FULLVERSION < 4990000}
|
||||
AFlags[FileNameCaseSensitive]
|
||||
{$ELSE}
|
||||
FileNameCaseSensitive
|
||||
FileNameCaseSensitive
|
||||
{$ENDIF}
|
||||
);
|
||||
for I:= 0 to FStringList.Count - 1 do
|
||||
begin
|
||||
if AMask.Matches(FStringList[I]) then
|
||||
FListBox.Items.Add(BasePath + FStringList[I]);
|
||||
end;
|
||||
AMask.Free;
|
||||
finally
|
||||
FListBox.Items.EndUpdate;
|
||||
end;
|
||||
if FListBox.Items.Count = 0 then HideListBox;
|
||||
if FListBox.Items.Count > 0 then
|
||||
);
|
||||
for I:= 0 to FStringList.Count - 1 do
|
||||
begin
|
||||
if AMask.Matches(FStringList[I]) then
|
||||
FListBox.Items.Add(BasePath + FStringList[I]);
|
||||
end;
|
||||
AMask.Free;
|
||||
finally
|
||||
FListBox.Items.EndUpdate;
|
||||
end;
|
||||
if FListBox.Items.Count = 0 then HideListBox;
|
||||
if FListBox.Items.Count > 0 then
|
||||
begin
|
||||
ShowListBox;
|
||||
// Calculate ListBox height
|
||||
with FListBox.ItemRect(0) do
|
||||
I:= Bottom - Top; // TListBox.ItemHeight sometimes don't work under GTK2
|
||||
with FListBox do
|
||||
begin
|
||||
ShowListBox;
|
||||
// Calculate ListBox height
|
||||
with FListBox.ItemRect(0) do
|
||||
I:= Bottom - Top; // TListBox.ItemHeight sometimes don't work under GTK2
|
||||
with FListBox do
|
||||
begin
|
||||
{$IF NOT DEFINED(LCLCOCOA)}
|
||||
if Items.Count = 1 then
|
||||
FPanel.ClientHeight:= Self.Height
|
||||
else
|
||||
FPanel.ClientHeight:= I * IfThen(Items.Count > 10, 11, Items.Count + 1);
|
||||
if Items.Count = 1 then
|
||||
FPanel.ClientHeight:= Self.Height
|
||||
else
|
||||
FPanel.ClientHeight:= I * IfThen(Items.Count > 10, 11, Items.Count + 1);
|
||||
{$ELSE}
|
||||
FPanel.ClientHeight:= I * IfThen(Items.Count > 10, 11, Items.Count + 1) + trunc(i/2);
|
||||
FPanel.ClientHeight:= I * IfThen(Items.Count > 10, 11, Items.Count + 1) + trunc(i/2);
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
|
@ -367,8 +318,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}
|
||||
|
||||
|
|
@ -501,8 +454,6 @@ constructor TKASPathEdit.Create(AOwner: TComponent);
|
|||
begin
|
||||
inherited Create(AOwner);
|
||||
|
||||
FStringList:= TStringList.Create;
|
||||
|
||||
FListBox:= TListBox.Create(Self);
|
||||
FListBox.TabStop:= False;
|
||||
FListBox.Align:= alClient;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -58,19 +58,23 @@ type
|
|||
FOverlay: TBitmap;
|
||||
FToolItem: TKASToolItem;
|
||||
function GetToolBar: TKASToolBar;
|
||||
function GetGlyphBitmap: TBitmap;
|
||||
procedure SetGlyphBitmap(bitmap: TBitmap);
|
||||
protected
|
||||
procedure CalculatePreferredSize(var PreferredWidth,
|
||||
PreferredHeight: integer; WithThemeSpace: Boolean); override;
|
||||
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;
|
||||
constructor Create(AOwner: TComponent; Item: TKASToolItem); reintroduce; virtual;
|
||||
destructor Destroy; override;
|
||||
procedure Click; override;
|
||||
public
|
||||
property ToolBar: TKASToolBar read GetToolBar;
|
||||
property ToolItem: TKASToolItem read FToolItem;
|
||||
property Glyph: TBitmap read GetGlyphBitmap write SetGlyphBitmap;
|
||||
end;
|
||||
|
||||
{ TKASToolDivider }
|
||||
|
|
@ -80,6 +84,17 @@ type
|
|||
procedure CalculatePreferredSize(var PreferredWidth,
|
||||
PreferredHeight: integer; WithThemeSpace: Boolean); override;
|
||||
procedure Paint; override;
|
||||
public
|
||||
constructor Create(AOwner: TComponent; Item: TKASToolItem); override;
|
||||
end;
|
||||
|
||||
{ TKASToolLabel }
|
||||
|
||||
TKASToolLabel = class(TKASToolButton)
|
||||
protected
|
||||
procedure Paint; override;
|
||||
public
|
||||
constructor Create(AOwner: TComponent; Item: TKASToolItem); override;
|
||||
end;
|
||||
|
||||
{ TKASToolBar }
|
||||
|
|
@ -164,7 +179,9 @@ type
|
|||
procedure RemoveButton(Button: TKASToolButton);
|
||||
procedure RemoveToolItemExecutor(ExecuteFunction: TOnToolItemExecute);
|
||||
procedure UncheckAllButtons;
|
||||
function GlyphBitmapSize: Integer;
|
||||
procedure UpdateIcon(ToolButton: TKASToolButton);
|
||||
procedure UpdateIconWithBitmap(ToolButton: TKASToolButton; bitmap: TBitmap);
|
||||
procedure UseItems(AItems: TKASToolBarItems);
|
||||
|
||||
procedure LoadConfiguration(Config: TXmlConfig; RootNode: TXmlNode;
|
||||
|
|
@ -203,7 +220,7 @@ procedure Register;
|
|||
implementation
|
||||
|
||||
uses
|
||||
Themes, Types, Math, ActnList, DCOSUtils;
|
||||
Themes, Types, Math, ActnList, LCLType, LCLIntf, DCOSUtils;
|
||||
|
||||
type
|
||||
PToolItemExecutor = ^TToolItemExecutor;
|
||||
|
|
@ -217,6 +234,29 @@ begin
|
|||
RegisterComponents('KASComponents',[TKASToolBar]);
|
||||
end;
|
||||
|
||||
function findScaleFactorByFirstForm: Double;
|
||||
begin
|
||||
Result:= 1;
|
||||
if Screen.FormCount > 0 then
|
||||
Result:= Screen.Forms[0].GetCanvasScaleFactor();
|
||||
end;
|
||||
|
||||
function findScaleFactorByControl( control: TControl ): Double;
|
||||
var
|
||||
topParent: TControl;
|
||||
begin
|
||||
if Assigned(control) then begin
|
||||
topParent:= control.GetTopParent;
|
||||
if Assigned(topParent) then
|
||||
control:= topParent;
|
||||
if (control is TWinControl) and TWinControl(control).HandleAllocated then begin
|
||||
Result:= control.GetCanvasScaleFactor;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
Result:= findScaleFactorByFirstForm();
|
||||
end;
|
||||
|
||||
{ TKASToolBar }
|
||||
|
||||
procedure TKASToolBar.InsertButton(InsertAt: Integer; ToolButton: TKASToolButton);
|
||||
|
|
@ -286,14 +326,19 @@ var
|
|||
procedure CalculatePosition;
|
||||
var
|
||||
NewBounds: TRect;
|
||||
ALineBreak: Boolean;
|
||||
begin
|
||||
ALineBreak:= (CurControl is TKASToolDivider) and (not FShowDividerAsButton) and
|
||||
(TKASToolDivider(CurControl).FToolItem is TKASSeparatorItem) and
|
||||
(TKASSeparatorItem(TKASToolDivider(CurControl).FToolItem).Style = kssLineBreak);
|
||||
|
||||
if IsVertical then
|
||||
begin
|
||||
NewBounds := Bounds(x, y, FRowWidth, CurControl.Height);
|
||||
repeat
|
||||
if (not Wrapable) or
|
||||
(NewBounds.Bottom <= ARect.Bottom) or
|
||||
(NewBounds.Top = StartY) then
|
||||
(NewBounds.Top = StartY) or
|
||||
((NewBounds.Bottom <= ARect.Bottom) and not ALineBreak) then
|
||||
begin
|
||||
// control fits into the column
|
||||
x := NewBounds.Left;
|
||||
|
|
@ -312,8 +357,8 @@ var
|
|||
NewBounds := Bounds(x, y, CurControl.Width, FRowHeight);
|
||||
repeat
|
||||
if (not Wrapable) or
|
||||
(NewBounds.Right <= ARect.Right) or
|
||||
(NewBounds.Left = StartX) then
|
||||
(NewBounds.Left = StartX) or
|
||||
((NewBounds.Right <= ARect.Right) and not ALineBreak) then
|
||||
begin
|
||||
// control fits into the row
|
||||
x := NewBounds.Left;
|
||||
|
|
@ -546,10 +591,18 @@ begin
|
|||
if FGlyphSize = AValue then Exit;
|
||||
FGlyphSize:= AValue;
|
||||
|
||||
self.Images.Clear;
|
||||
self.images.Width:= GlyphBitmapSize;
|
||||
self.images.Height:= GlyphBitmapSize;
|
||||
self.ImagesWidth:= FGlyphSize;
|
||||
Self.Images.Scaled := (findScaleFactorByControl(Self) > 1.0);
|
||||
|
||||
BeginUpdate;
|
||||
try
|
||||
for I := 0 to ButtonList.Count - 1 do
|
||||
for I := 0 to ButtonList.Count - 1 do begin
|
||||
TKASToolButton(ButtonList[i]).ImageIndex:= -1;
|
||||
UpdateIcon(TKASToolButton(ButtonList[i]));
|
||||
end;
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
|
|
@ -728,7 +781,8 @@ begin
|
|||
ToolButton.FOverlay := FOnLoadButtonOverlay(ToolButton.ToolItem, FGlyphSize div 2, clBtnFace);
|
||||
end;
|
||||
|
||||
ToolButton.Glyph.Assign(Bitmap);
|
||||
if Assigned(Bitmap) then
|
||||
self.UpdateIconWithBitmap(ToolButton, Bitmap);
|
||||
finally
|
||||
Bitmap.Free;
|
||||
end;
|
||||
|
|
@ -737,6 +791,18 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TKASToolBar.UpdateIconWithBitmap(ToolButton: TKASToolButton;
|
||||
bitmap: TBitmap);
|
||||
begin
|
||||
if ToolButton.ImageIndex < 0 then begin
|
||||
ToolButton.Images:= self.Images;
|
||||
ToolButton.ImageIndex:= self.Images.Add( bitmap, nil );
|
||||
ToolButton.ImageWidth:= self.ImagesWidth;
|
||||
end else begin
|
||||
self.Images.Replace( ToolButton.ImageIndex, bitmap, nil );
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TKASToolBar.UseItems(AItems: TKASToolBarItems);
|
||||
var
|
||||
i: Integer;
|
||||
|
|
@ -827,7 +893,8 @@ end;
|
|||
constructor TKASToolBar.Create(TheOwner: TComponent);
|
||||
begin
|
||||
inherited Create(TheOwner);
|
||||
FGlyphSize:= 16; // by default
|
||||
self.images:= TImageList.Create(self);
|
||||
self.GlyphSize:= 16; // by default
|
||||
FUpdateCount:= 0;
|
||||
FButtonWidth := 23;
|
||||
FButtonHeight := 22;
|
||||
|
|
@ -848,6 +915,10 @@ begin
|
|||
begin
|
||||
Result := TKASToolDivider.Create(Self, Item);
|
||||
end
|
||||
else if Item is TKASLabelItem then
|
||||
begin
|
||||
Result := TKASToolLabel.Create(Self, Item);
|
||||
end
|
||||
else
|
||||
begin
|
||||
Result := TKASToolButton.Create(Self, Item);
|
||||
|
|
@ -1025,12 +1096,18 @@ begin
|
|||
Buttons[I].Down:= False;
|
||||
end;
|
||||
|
||||
function TKASToolBar.GlyphBitmapSize: Integer;
|
||||
begin
|
||||
Result:= Round(FGlyphSize * findScaleFactorByControl(self));
|
||||
end;
|
||||
|
||||
{ TKASToolButton }
|
||||
|
||||
procedure TKASToolButton.CalculatePreferredSize(var PreferredWidth,
|
||||
PreferredHeight: integer; WithThemeSpace: Boolean);
|
||||
var
|
||||
TextSize: TSize;
|
||||
iconWidth: Integer;
|
||||
begin
|
||||
if (Parent = nil) then
|
||||
inherited
|
||||
|
|
@ -1048,7 +1125,10 @@ begin
|
|||
begin
|
||||
// Size to extent of the icon + caption.
|
||||
TextSize := Canvas.TextExtent(Caption);
|
||||
PreferredWidth := Max(TextSize.cx + Glyph.Width + 16, PreferredWidth);
|
||||
iconWidth := self.ImageWidth;
|
||||
if iconWidth = 0 then
|
||||
iconWidth := Glyph.Width;
|
||||
PreferredWidth := Max(TextSize.cx + iconWidth + 16, PreferredWidth);
|
||||
PreferredHeight := Max(TextSize.cy + 4, PreferredHeight);
|
||||
end;
|
||||
end;
|
||||
|
|
@ -1089,6 +1169,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);
|
||||
|
|
@ -1111,22 +1202,44 @@ begin
|
|||
Result := Parent as TKASToolBar;
|
||||
end;
|
||||
|
||||
function TKASToolButton.GetGlyphBitmap: TBitmap;
|
||||
begin
|
||||
Result:= Inherited Glyph;
|
||||
end;
|
||||
|
||||
procedure TKASToolButton.SetGlyphBitmap(bitmap: TBitmap);
|
||||
begin
|
||||
self.ToolBar.UpdateIconWithBitmap(self, bitmap);
|
||||
end;
|
||||
|
||||
{ TKASToolDivider }
|
||||
|
||||
procedure TKASToolDivider.CalculatePreferredSize(var PreferredWidth,
|
||||
PreferredHeight: integer; WithThemeSpace: Boolean);
|
||||
var
|
||||
ASize: Integer;
|
||||
begin
|
||||
if Assigned(Parent) and (Parent is TKASToolBar) and
|
||||
(not TKASSeparatorItem(FToolItem).Style) and
|
||||
(not TKASToolBar(Parent).FShowDividerAsButton) then
|
||||
begin
|
||||
if ToolBar.IsVertical then
|
||||
if (TKASSeparatorItem(FToolItem).Style = kssSeparator) then
|
||||
ASize:= 5
|
||||
else if (TKASSeparatorItem(FToolItem).Style = kssLineBreak) then
|
||||
ASize:= 0
|
||||
else begin
|
||||
ASize:= -1;
|
||||
end;
|
||||
if ASize < 0 then
|
||||
begin
|
||||
PreferredHeight := 5;
|
||||
inherited;
|
||||
end
|
||||
else if ToolBar.IsVertical then
|
||||
begin
|
||||
PreferredHeight := ASize;
|
||||
PreferredWidth := ToolBar.FRowWidth;
|
||||
end
|
||||
else begin
|
||||
PreferredWidth := 5;
|
||||
PreferredWidth := ASize;
|
||||
PreferredHeight := ToolBar.FRowHeight;
|
||||
end;
|
||||
end
|
||||
|
|
@ -1142,7 +1255,7 @@ begin
|
|||
if Assigned(Parent) and (Parent is TKASToolBar) and
|
||||
not TKASToolBar(Parent).FShowDividerAsButton then
|
||||
begin
|
||||
if TKASSeparatorItem(FToolItem).Style then Exit;
|
||||
if TKASSeparatorItem(FToolItem).Style > kssSeparator then Exit;
|
||||
|
||||
DividerRect:= ClientRect;
|
||||
|
||||
|
|
@ -1185,5 +1298,46 @@ begin
|
|||
inherited Paint;
|
||||
end;
|
||||
|
||||
constructor TKASToolDivider.Create(AOwner: TComponent; Item: TKASToolItem);
|
||||
begin
|
||||
inherited Create(AOwner, Item);
|
||||
ControlStyle:= ControlStyle + [csAutoSize0x0];
|
||||
end;
|
||||
|
||||
{ TKASToolLabel }
|
||||
|
||||
procedure TKASToolLabel.Paint;
|
||||
const
|
||||
cAlignment: array[TAlignment] of Longint = (DT_LEFT, DT_RIGHT, DT_CENTER);
|
||||
var
|
||||
R: TRect;
|
||||
Flags: Longint;
|
||||
LabelText: String;
|
||||
begin
|
||||
R:= ClientRect;
|
||||
Canvas.Font:= Font;
|
||||
LabelText:= Caption;
|
||||
InflateRect(R, -8, 0);
|
||||
Canvas.Brush.Color:= Color;
|
||||
Canvas.Brush.Style:= bsClear;
|
||||
|
||||
Flags:= DT_EXPANDTABS or DT_VCENTER;
|
||||
Flags:= Flags or DT_SINGLELINE or DT_NOPREFIX;
|
||||
|
||||
if UseRightToLeftReading then
|
||||
begin
|
||||
Flags:= Flags or DT_RTLREADING;
|
||||
end;
|
||||
Flags:= Flags or cAlignment[BidiFlipAlignment(Self.Alignment, UseRightToLeftAlignment)];
|
||||
|
||||
DrawText(Canvas.Handle, PAnsiChar(LabelText), Length(LabelText), R, Flags or DT_NOCLIP);
|
||||
end;
|
||||
|
||||
constructor TKASToolLabel.Create(AOwner: TComponent; Item: TKASToolItem);
|
||||
begin
|
||||
inherited Create(AOwner, Item);
|
||||
AutoSize:= True;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ type
|
|||
|
||||
TOnLoadToolItem = procedure (Item: TKASToolItem) of object;
|
||||
|
||||
TKASSeparatorStyle = (kssSeparator, kssDivider, kssLineBreak);
|
||||
|
||||
{$interfaces corba}
|
||||
IToolOwner = interface
|
||||
['{A7908D38-1E13-4E8D-8FA7-8830A2FF9290}']
|
||||
|
|
@ -62,6 +64,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;
|
||||
|
|
@ -81,7 +84,7 @@ type
|
|||
|
||||
TKASSeparatorItem = class(TKASToolItem)
|
||||
public
|
||||
Style: Boolean;
|
||||
Style: TKASSeparatorStyle;
|
||||
procedure Assign(OtherItem: TKASToolItem); override;
|
||||
function Clone: TKASToolItem; override;
|
||||
function ConfigNodeName: String; override;
|
||||
|
|
@ -94,6 +97,8 @@ type
|
|||
{ TKASNormalItem }
|
||||
|
||||
TKASNormalItem = class(TKASToolItem)
|
||||
private
|
||||
FShortcutsHint: Boolean;
|
||||
strict private
|
||||
FID: String; // Unique identificator of the button
|
||||
function GetID: String;
|
||||
|
|
@ -105,6 +110,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;
|
||||
|
|
@ -136,6 +142,10 @@ type
|
|||
property SubItems: TKASToolBarItems read FItems;
|
||||
end;
|
||||
|
||||
{ TKASLabelItem }
|
||||
|
||||
TKASLabelItem = class(TKASNormalItem);
|
||||
|
||||
{ TKASToolBarItems }
|
||||
|
||||
TKASToolBarItems = class
|
||||
|
|
@ -183,6 +193,11 @@ uses
|
|||
|
||||
{ TKASToolItem }
|
||||
|
||||
function TKASToolItem.ActionHint: Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure TKASToolItem.Assign(OtherItem: TKASToolItem);
|
||||
begin
|
||||
FUserData := OtherItem.FUserData;
|
||||
|
|
@ -404,13 +419,20 @@ begin
|
|||
end;
|
||||
|
||||
procedure TKASSeparatorItem.Load(Config: TXmlConfig; Node: TXmlNode; Loader: TKASToolBarLoader);
|
||||
var
|
||||
OldStyle: Boolean;
|
||||
AStyle: array[Boolean] of TKASSeparatorStyle = (kssSeparator, kssDivider);
|
||||
begin
|
||||
Style := Config.GetValue(Node, 'Style', False);
|
||||
if Config.TryGetValue(Node, 'Style', OldStyle) then
|
||||
Style := AStyle[OldStyle]
|
||||
else begin
|
||||
Style := TKASSeparatorStyle(Config.GetValue(Node, 'Style', Integer(kssSeparator)));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TKASSeparatorItem.SaveContents(Config: TXmlConfig; Node: TXmlNode);
|
||||
begin
|
||||
Config.AddValue(Node, 'Style', Style);
|
||||
Config.AddValue(Node, 'Style', Integer(Style));
|
||||
end;
|
||||
|
||||
{ TKASNormalItem }
|
||||
|
|
@ -481,8 +503,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 +549,11 @@ begin
|
|||
Config.AddValueDef(Node, 'Text', Text, '');
|
||||
end;
|
||||
|
||||
function TKASNormalItem.ActionHint: Boolean;
|
||||
begin
|
||||
Result := not FShortcutsHint;
|
||||
end;
|
||||
|
||||
{ TKASToolBarItems }
|
||||
|
||||
constructor TKASToolBarItems.Create;
|
||||
|
|
|
|||
|
|
@ -8,15 +8,22 @@ 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;
|
||||
property EdgeOuter;
|
||||
property OnResize;
|
||||
property TabOrder;
|
||||
property Visible;
|
||||
end;
|
||||
|
|
@ -30,4 +37,12 @@ begin
|
|||
RegisterComponents('KASComponents',[TKASToolPanel]);
|
||||
end;
|
||||
|
||||
{ TKASToolPanel }
|
||||
|
||||
constructor TKASToolPanel.Create(TheOwner: TComponent);
|
||||
begin
|
||||
inherited Create(TheOwner);
|
||||
EdgeBorders:= [ebTop];
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ 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%
|
||||
lazbuild viewer\viewerpackage.lpk %DC_ARCH%
|
||||
lazbuild gifanim\pkg_gifanim.lpk %DC_ARCH%
|
||||
lazbuild gifview\gifview.lpk %DC_ARCH%
|
||||
lazbuild synunihighlighter\synuni.lpk %DC_ARCH%
|
||||
lazbuild virtualterminal\virtualterminal.lpk %DC_ARCH%
|
||||
popd
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ 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
|
||||
$lazbuild viewer/viewerpackage.lpk $DC_ARCH
|
||||
$lazbuild gifanim/pkg_gifanim.lpk $DC_ARCH
|
||||
$lazbuild gifview/gifview.lpk $DC_ARCH
|
||||
$lazbuild synunihighlighter/synuni.lpk $DC_ARCH
|
||||
$lazbuild virtualterminal/virtualterminal.lpk $DC_ARCH
|
||||
cd $basedir
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
CRC / HASH / HMAC
|
||||
http://www.wolfgang-ehrhardt.de/crchash_en.html
|
||||
crc_hash_2016-05-01.zip
|
||||
|
||||
Some modifications done for Double Commander (see doublecmd.diff).
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
Index: kperm_64.inc
|
||||
===================================================================
|
||||
--- kperm_64.inc (revision 6895)
|
||||
+++ kperm_64.inc (working copy)
|
||||
@@ -33,10 +33,14 @@
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
+{$IFDEF FPC}
|
||||
+ {$MACRO ON} {$DEFINE RotL:= RolQWord}
|
||||
+{$ELSE}
|
||||
function RotL(x: u64bit; c: integer): u64bit; {$ifdef HAS_INLINE} inline; {$endif}
|
||||
begin
|
||||
RotL := (x shl c) or (x shr (64-c));
|
||||
end;
|
||||
+{$ENDIF}
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
Index: sha1.pas
|
||||
===================================================================
|
||||
--- sha1.pas
|
||||
+++ sha1.pas
|
||||
@@ -106,7 +106,7 @@
|
||||
|
||||
{$i STD.INC}
|
||||
|
||||
-{$ifdef BIT64}
|
||||
+{$ifndef CPUI386}
|
||||
{$ifndef PurePascal}
|
||||
{$define PurePascal}
|
||||
{$endif}
|
||||
Index: sha3.pas
|
||||
===================================================================
|
||||
--- sha3.pas (revision 6895)
|
||||
+++ sha3.pas (working copy)
|
||||
@@ -6,6 +6,15 @@
|
||||
|
||||
{$i STD.INC}
|
||||
|
||||
+{$ifdef FPC}
|
||||
+ {$ifdef CPUI386}
|
||||
+ {$define USE_MMXCODE}
|
||||
+ {$endif}
|
||||
+ {$ifdef CPU64}
|
||||
+ {$define USE_64BITCODE}
|
||||
+ {$endif}
|
||||
+{$endif}
|
||||
+
|
||||
{.$define USE_64BITCODE} {Use 64-bit for Keccak permutation}
|
||||
{.$define USE_MMXCODE } {Use MMX for Keccak permutation, contributed by Eric Grange}
|
||||
{.$define USE_MMX_AKP } {Use MMX for Keccak permutation, contributed by Anna Kaliszewicz / payl}
|
||||
Index: scrypt.pas
|
||||
===================================================================
|
||||
--- scrypt.pas (revision 7740)
|
||||
+++ scrypt.pas (working copy)
|
||||
@@ -90,7 +90,7 @@
|
||||
implementation
|
||||
|
||||
uses
|
||||
- sha256; {Register SHA256 for HMAC-SHA256}
|
||||
+ SHA3_512; {Register SHA3_512 for HMAC_SHA3_512}
|
||||
|
||||
type
|
||||
TLA16 = array[0..15] of longint;
|
||||
@@ -361,14 +361,14 @@
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
-function pbkfd2_hmac_sha256(pPW: pointer; pLen: word; salt: pointer; sLen,C: longint; var DK; dkLen: longint): integer;
|
||||
- {-Derive key DK from password pPW using salt and iteration count C using (hmac-)sha256}
|
||||
+function pbkdf2_hmac_sha3_512(pPW: pointer; pLen: word; salt: pointer; sLen,C: longint; var DK; dkLen: longint): integer;
|
||||
+ {-Derive key DK from password pPW using salt and iteration count C using hmac_sha3_512}
|
||||
var
|
||||
phash: PHashDesc;
|
||||
begin
|
||||
- {Note: pbkdf2 will return error indicator phash=nil if _SHA256 is not found!}
|
||||
- phash := FindHash_by_ID(_SHA256);
|
||||
- pbkfd2_hmac_sha256 := pbkdf2(phash,pPW,pLen,salt,sLen,C,DK,dkLen);
|
||||
+ {Note: pbkdf2 will return error indicator phash=nil if _SHA3_512 is not found!}
|
||||
+ phash := FindHash_by_ID(_SHA3_512);
|
||||
+ pbkdf2_hmac_sha3_512 := pbkdf2(phash,pPW,pLen,salt,sLen,C,DK,dkLen);
|
||||
end;
|
||||
|
||||
|
||||
@@ -418,7 +418,7 @@
|
||||
pV := malloc(sV);
|
||||
pXY := malloc(sXY);
|
||||
if (pB<>nil) and (pV<>nil) and (pXY<>nil) then begin
|
||||
- err := pbkfd2_hmac_sha256(pPW, pLen, salt, sLen, 1, pB^, sB);
|
||||
+ err := pbkdf2_hmac_sha3_512(pPW, pLen, salt, sLen, 1, pB^, sB);
|
||||
if err=0 then begin
|
||||
pw := pB;
|
||||
for i:=0 to p-1 do begin
|
||||
@@ -425,7 +425,7 @@
|
||||
smix(pw, r, N, pV, pXY);
|
||||
inc(Ptr2Inc(pw), r*128);
|
||||
end;
|
||||
- err := pbkfd2_hmac_sha256(pPW, pLen, pB, sB, 1, DK, dKlen);
|
||||
+ err := pbkdf2_hmac_sha3_512(pPW, pLen, pB, sB, 1, DK, dKlen);
|
||||
end;
|
||||
scrypt_kdf := err;
|
||||
end
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
{ This file was automatically created by Lazarus. do not edit!
|
||||
This source is only used to compile and install the package.
|
||||
}
|
||||
|
||||
unit dcp;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
DCPbase64, DCPblockciphers, DCPconst, DCPcrypt2, DCPblowfish, DCPcast128,
|
||||
DCPcast256, DCPdes, DCPgost, DCPice, DCPidea, DCPmars, DCPmisty1, DCPrc2,
|
||||
DCPrc4, DCPrc5, DCPrc6, DCPrijndael, DCPserpent, DCPtea, DCPtwofish,
|
||||
DCPhaval, DCPmd4, DCPmd5, DCPripemd128, DCPripemd160, DCPsha1, DCPsha256,
|
||||
DCPsha512, DCPtiger;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
30
components/doublecmd/dcclasses.pas
Normal file
30
components/doublecmd/dcclasses.pas
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
unit DCClasses;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, NullStream;
|
||||
|
||||
type
|
||||
|
||||
{ TNullStreamEx }
|
||||
|
||||
TNullStreamEx = class(TNullStream)
|
||||
public
|
||||
function Write(const Buffer; Count: LongInt): LongInt; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TNullStreamEx }
|
||||
|
||||
function TNullStreamEx.Write(const Buffer; Count: LongInt): LongInt;
|
||||
begin
|
||||
Result:= Count;
|
||||
inherited Write(Buffer, Count);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -28,7 +28,7 @@ unit DCClassesUtf8;
|
|||
interface
|
||||
|
||||
uses
|
||||
Classes, RtlConsts, SysUtils, IniFiles;
|
||||
Classes, RtlConsts, SysUtils, IniFiles, Math;
|
||||
|
||||
type
|
||||
{ TFileStreamEx class }
|
||||
|
|
@ -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,8 +51,9 @@ 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;
|
||||
end;
|
||||
|
||||
{ TStringListEx }
|
||||
|
||||
|
|
@ -63,7 +64,7 @@ type
|
|||
function IndexOfValue(const Value: String): Integer;
|
||||
procedure LoadFromFile(const FileName: String); override;
|
||||
procedure SaveToFile(const FileName: String); override;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TIniFileEx }
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
@ -81,7 +82,7 @@ type
|
|||
implementation
|
||||
|
||||
uses
|
||||
DCOSUtils, LazUTF8;
|
||||
DCOSUtils, DCConvertEncoding;
|
||||
|
||||
{ TFileStreamEx }
|
||||
|
||||
|
|
@ -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,15 +170,15 @@ 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
|
||||
else
|
||||
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;
|
||||
|
|
@ -212,11 +213,26 @@ end;
|
|||
{ TStringListEx }
|
||||
|
||||
function TStringListEx.DoCompareText(const S1, S2: String): PtrInt;
|
||||
var
|
||||
U1, U2: UnicodeString;
|
||||
begin
|
||||
U1:= CeUtf8ToUtf16(S1);
|
||||
U2:= CeUtf8ToUtf16(S2);
|
||||
|
||||
if CaseSensitive then
|
||||
Result:= UTF8CompareStr(S1, S2)
|
||||
begin
|
||||
Result:= UnicodeCompareStr(U1, U2);
|
||||
if Result = 0 then
|
||||
begin
|
||||
Result := CompareMemRange(Pointer(U1), Pointer(U2), Min(Length(U1), Length(U2)) * SizeOf(WideChar));
|
||||
if Result = 0 then
|
||||
Result := Length(U1) - Length(U2);
|
||||
end
|
||||
end
|
||||
else
|
||||
Result:= UTF8CompareText(S1, S2);
|
||||
begin
|
||||
Result:= UnicodeCompareText(U1, U2);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TStringListEx.IndexOfValue(const Value: String): Integer;
|
||||
|
|
@ -270,13 +286,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 +311,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 +322,7 @@ begin
|
|||
else begin
|
||||
Mode := fmOpenRead or fmShareDenyNone;
|
||||
end;
|
||||
Create(AFileName, Mode);
|
||||
Create(AFileName, Mode, AOptions);
|
||||
end;
|
||||
|
||||
procedure TIniFileEx.UpdateFile;
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
|
|
|||
|
|
@ -1,18 +1,118 @@
|
|||
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;
|
||||
function mbFileCopyXattr(const Source, Target: String): Boolean;
|
||||
|
||||
// MacOS File Utils
|
||||
function MacosFileSetCreationTime( const path:String; const birthtime:TFileTimeEx ): Boolean;
|
||||
|
||||
type
|
||||
|
||||
{ TDarwinFileUtil }
|
||||
|
||||
TDarwinFileUtil = class
|
||||
class function cloneFile( const fromPath: String; const toPath: String; const size: Int64 ): Boolean;
|
||||
end;
|
||||
|
||||
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);
|
||||
|
||||
const
|
||||
NSAppKitVersionNumber10_13 = 1561;
|
||||
|
||||
const
|
||||
COPYFILE_ACL = 1 shl 0;
|
||||
COPYFILE_STAT = 1 shl 1;
|
||||
COPYFILE_XATTR = 1 shl 2;
|
||||
COPYFILE_DATA = 1 shl 3;
|
||||
|
||||
COPYFILE_SECURITY = COPYFILE_STAT or COPYFILE_ACL;
|
||||
COPYFILE_METADATA = COPYFILE_SECURITY or COPYFILE_XATTR;
|
||||
COPYFILE_ALL = COPYFILE_METADATA or COPYFILE_DATA;
|
||||
|
||||
COPYFILE_UNLINK = 1 shl 21;
|
||||
COPYFILE_CLONE = 1 shl 24;
|
||||
COPYFILE_CLONE_FORCE = 1 shl 25;
|
||||
|
||||
type
|
||||
copyfile_state_t_o = record
|
||||
end;
|
||||
copyfile_state_t = ^copyfile_state_t_o;
|
||||
copyfile_flags_t = UInt32;
|
||||
|
||||
function copyfile( const fromPath: pchar; const toPath: pchar; state: copyfile_state_t; flags: copyfile_flags_t ): Integer;
|
||||
cdecl; external name 'copyfile';
|
||||
|
||||
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 mbFileCopyXattr(const Source, Target: String): Boolean;
|
||||
var
|
||||
ret: Integer;
|
||||
begin
|
||||
Writeln( '>>3> mbFileCopyXattr' );
|
||||
ret:= copyfile( pchar(Source), pchar(Target), nil, COPYFILE_XATTR );
|
||||
fpseterrno( ret );
|
||||
Result:= (ret=0);
|
||||
end;
|
||||
|
||||
function StringToNSString(const S: String): NSString;
|
||||
begin
|
||||
Result:= NSString(NSString.stringWithUTF8String(PAnsiChar(S)));
|
||||
|
|
@ -33,5 +133,39 @@ begin
|
|||
Result:= NSFileManager.defaultManager.setAttributes_ofItemAtPath_error( attrs, nsPath, nil );
|
||||
end;
|
||||
|
||||
{ TDarwinFileUtil }
|
||||
|
||||
// the copyfile() api has two advantages:
|
||||
// 1. dramatically improve file copy speed on APFS
|
||||
// 2. supports copying macOS specific attributes
|
||||
// therefore, we should try copyfile() as much as possible on macOS
|
||||
class function TDarwinFileUtil.cloneFile( const fromPath: String; const toPath: String; const size: Int64 ): Boolean;
|
||||
const
|
||||
NO_CALLBACK_MAXSIZE = 20*1024*1024; // 20MB
|
||||
var
|
||||
flags: copyfile_flags_t;
|
||||
ret: Integer;
|
||||
begin
|
||||
Result:= False;
|
||||
flags:= COPYFILE_ALL;
|
||||
|
||||
// call copyfile() when:
|
||||
// 1. macOS < 10.13 and filesize <= MAX_SIZE (copy only)
|
||||
// 2. macOS >= 10.13 and filesize > MAX_SIZE (clone only, fail fast)
|
||||
// 3. macOS >= 10.13 and filesize <= MAX_SIZE (try clone, then copy)
|
||||
if NSAppKitVersionNumber < NSAppKitVersionNumber10_13 then begin
|
||||
if size > NO_CALLBACK_MAXSIZE then
|
||||
Exit;
|
||||
end else begin
|
||||
if size > NO_CALLBACK_MAXSIZE then
|
||||
flags:= flags or COPYFILE_CLONE_FORCE or COPYFILE_UNLINK
|
||||
else
|
||||
flags:= flags or COPYFILE_CLONE;
|
||||
end;
|
||||
|
||||
ret:= copyfile( pchar(fromPath), pchar(toPath), nil, flags );
|
||||
Result:= (ret=0);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -80,6 +82,8 @@ const
|
|||
S_IRWXU = S_IRUSR or S_IWUSR or S_IXUSR;
|
||||
S_IRWXG = S_IRGRP or S_IWGRP or S_IXGRP;
|
||||
S_IRWXO = S_IROTH or S_IWOTH or S_IXOTH;
|
||||
S_IRUGO = S_IRUSR or S_IRGRP or S_IROTH;
|
||||
S_IWUGO = S_IWUSR or S_IWGRP or S_IWOTH;
|
||||
S_IXUGO = S_IXUSR or S_IXGRP or S_IXOTH;
|
||||
|
||||
{ POSIX setuid(), setgid(), and sticky bit }
|
||||
|
|
@ -99,6 +103,7 @@ const
|
|||
function WinToUnixFileAttr(Attr: TFileAttrs): TFileAttrs;
|
||||
function UnixToWinFileAttr(Attr: TFileAttrs): TFileAttrs;
|
||||
function UnixToWcxFileAttr(Attr: TFileAttrs): TFileAttrs;
|
||||
function WinToWcxFileAttr(Attr: TFileAttrs): TFileAttrs;
|
||||
function UnixToWinFileAttr(const FileName: String; Attr: TFileAttrs): TFileAttrs;
|
||||
|
||||
function SingleStrToFileAttr(sAttr: String): TFileAttrs;
|
||||
|
|
@ -186,13 +191,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;
|
||||
|
|
@ -227,6 +233,17 @@ begin
|
|||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function WinToWcxFileAttr(Attr: TFileAttrs): TFileAttrs;
|
||||
begin
|
||||
{$IF DEFINED(UNIX)}
|
||||
Result := WinToUnixFileAttr(Attr);
|
||||
{$ELSEIF DEFINED(MSWINDOWS)}
|
||||
Result := Attr;
|
||||
{$ELSE}
|
||||
Result := 0;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function UnixToWinFileAttr(const FileName: String; Attr: TFileAttrs): TFileAttrs;
|
||||
begin
|
||||
Result := UnixToWinFileAttr(Attr);
|
||||
|
|
|
|||
213
components/doublecmd/dclinux.pas
Normal file
213
components/doublecmd/dclinux.pas
Normal 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.
|
||||
|
|
@ -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,8 +39,11 @@ 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
|
||||
LX_SYMLINK_HEADER_SIZE = 4;
|
||||
REPARSE_DATA_HEADER_SIZE = 8;
|
||||
MOUNT_POINT_HEADER_SIZE = 8;
|
||||
FILE_DOES_NOT_EXIST = DWORD(-1);
|
||||
|
|
@ -68,6 +70,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 +86,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 +103,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.
|
||||
|
|
@ -112,6 +120,13 @@ function CreateHardLink(const AFileName, ALinkName: UnicodeString): Boolean;
|
|||
@returns(The function returns @true if successful, @false otherwise)
|
||||
}
|
||||
function ReadSymLink(const aSymlinkFileName: UnicodeString; out aTargetFileName: UnicodeString): Boolean;
|
||||
{en
|
||||
Creates a WSL/Cygwin symbolic link.
|
||||
@param(aTargetFileName The name of the existing file)
|
||||
@param(aSymlinkFileName The name of the symbolic link)
|
||||
@returns(The function returns @true if successful, @false otherwise)
|
||||
}
|
||||
function CreateSymLinkUnix(const aTargetFileName: String; const aSymlinkFileName: UnicodeString): Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
|
|
@ -250,6 +265,7 @@ function _CreateSymLink_Old(aTargetFileName, aSymlinkFileName: UnicodeString): B
|
|||
var
|
||||
hDevice: THandle;
|
||||
lpInBuffer: PReparseDataBuffer;
|
||||
dwLastError,
|
||||
nInBufferSize,
|
||||
dwPathBufferSize: DWORD;
|
||||
wsNativeFileName: UnicodeString;
|
||||
|
|
@ -261,7 +277,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 +308,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 +339,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
|
||||
|
|
@ -337,11 +365,61 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function ReadSymLink(const aSymlinkFileName: UnicodeString; out aTargetFileName: UnicodeString): Boolean;
|
||||
function CreateSymLinkUnix(const aTargetFileName: String; const aSymlinkFileName: UnicodeString): Boolean;
|
||||
var
|
||||
hDevice: THandle;
|
||||
dwLastError: DWORD;
|
||||
nInBufferSize: DWORD;
|
||||
dwPathBufferSize: DWORD;
|
||||
lpBytesReturned: DWORD = 0;
|
||||
lpInBuffer: PReparseDataBuffer;
|
||||
begin
|
||||
hDevice:= CreateFileW(PWideChar(aSymlinkFileName),
|
||||
GENERIC_WRITE, 0, nil, CREATE_NEW,
|
||||
FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
if hDevice = INVALID_HANDLE_VALUE then Exit(False);
|
||||
dwPathBufferSize:= Length(aTargetFileName);
|
||||
nInBufferSize:= REPARSE_DATA_HEADER_SIZE + LX_SYMLINK_HEADER_SIZE + dwPathBufferSize;
|
||||
lpInBuffer:= GetMem(nInBufferSize);
|
||||
ZeroMemory(lpInBuffer, nInBufferSize);
|
||||
with lpInBuffer^, lpInBuffer^.LxSymlinkReparseBuffer do
|
||||
begin
|
||||
FileType:= 2; // symbolic link
|
||||
ReparseTag:= IO_REPARSE_TAG_LX_SYMLINK;
|
||||
ReparseDataLength:= LX_SYMLINK_HEADER_SIZE + dwPathBufferSize;
|
||||
CopyMemory(@PathBuffer[0], @aTargetFileName[1], Length(aTargetFileName));
|
||||
end;
|
||||
Result:= DeviceIoControl(hDevice, // handle to file or directory
|
||||
FSCTL_SET_REPARSE_POINT, // dwIoControlCode
|
||||
lpInBuffer, // input buffer
|
||||
nInBufferSize, // size of input buffer
|
||||
nil, // lpOutBuffer
|
||||
0, // nOutBufferSize
|
||||
lpBytesReturned, // lpBytesReturned
|
||||
nil); // OVERLAPPED structure
|
||||
// File system does not support reparse points
|
||||
// Create a normal file with the link target inside
|
||||
if (not Result) and (GetLastError = ERROR_INVALID_FUNCTION) then
|
||||
begin
|
||||
Result:= (FileWrite(hDevice, aTargetFileName[1], dwPathBufferSize) = dwPathBufferSize);
|
||||
if Result then SetFileAttributesW(PWideChar(aSymlinkFileName), FILE_ATTRIBUTE_SYSTEM);
|
||||
end;
|
||||
if not Result then dwLastError:= GetLastError;
|
||||
FreeMem(lpInBuffer);
|
||||
CloseHandle(hDevice);
|
||||
if not Result then
|
||||
begin
|
||||
DeleteFileW(PWideChar(aSymlinkFileName));
|
||||
SetLastError(dwLastError);
|
||||
end;
|
||||
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 +467,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)
|
||||
|
|
|
|||
329
components/doublecmd/dcosutils.pas
Executable file → Normal file
329
components/doublecmd/dcosutils.pas
Executable file → Normal 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,12 @@ uses
|
|||
{$IFDEF UNIX}
|
||||
, BaseUnix, DCUnix
|
||||
{$ENDIF}
|
||||
{$IFDEF LINUX}
|
||||
, DCLinux
|
||||
{$ENDIF}
|
||||
{$IFDEF DARWIN}
|
||||
, DCDarwin
|
||||
{$ENDIF}
|
||||
{$IFDEF HAIKU}
|
||||
, DCHaiku
|
||||
{$ENDIF}
|
||||
|
|
@ -43,6 +49,7 @@ const
|
|||
fmOpenSync = $10000;
|
||||
fmOpenDirect = $20000;
|
||||
fmOpenNoATime = $40000;
|
||||
fmOpenSpecial = $80000;
|
||||
|
||||
{$IF DEFINED(UNIX)}
|
||||
ERROR_NOT_SAME_DEVICE = ESysEXDEV;
|
||||
|
|
@ -50,6 +57,8 @@ const
|
|||
ERROR_NOT_SAME_DEVICE = Windows.ERROR_NOT_SAME_DEVICE;
|
||||
{$ENDIF}
|
||||
|
||||
FileNameNormalized = {$IFDEF DARWIN}True{$ELSE}False{$ENDIF};
|
||||
|
||||
type
|
||||
TFileMapRec = record
|
||||
FileHandle : System.THandle;
|
||||
|
|
@ -96,7 +105,7 @@ type
|
|||
PCopyAttributesResult = ^TCopyAttributesResult;
|
||||
|
||||
const
|
||||
faInvalidAttributes: TFileAttrs = TFileAttrs(-1);
|
||||
faInvalidAttributes = TFileAttrs(-1);
|
||||
CopyAttributesOptionCopyAll = [caoCopyAttributes, caoCopyTime, caoCopyOwnership];
|
||||
|
||||
{en
|
||||
|
|
@ -111,6 +120,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 +161,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)
|
||||
|
|
@ -166,6 +185,8 @@ function MapFile(const sFileName : String; out FileMapRec : TFileMapRec) : Boole
|
|||
}
|
||||
procedure UnMapFile(var FileMapRec : TFileMapRec);
|
||||
|
||||
function NormalizeFileName(const Source: String): String;
|
||||
|
||||
{en
|
||||
Convert from console to UTF8 encoding.
|
||||
}
|
||||
|
|
@ -177,6 +198,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 +244,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 +316,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)
|
||||
|
|
@ -317,6 +340,9 @@ uses
|
|||
{$ENDIF}
|
||||
{$IF DEFINED(UNIX)}
|
||||
Unix, dl,
|
||||
{$ENDIF}
|
||||
{$IF DEFINED(DARWIN)}
|
||||
LazFileUtils,
|
||||
{$ENDIF}
|
||||
DCStrUtils, LazUTF8;
|
||||
|
||||
|
|
@ -381,8 +407,6 @@ const
|
|||
O_SYNC or O_DIRECT);
|
||||
{$ENDIF}
|
||||
|
||||
(*Is Directory*)
|
||||
|
||||
function FPS_ISDIR(iAttr: TFileAttrs) : Boolean; inline;
|
||||
{$IFDEF MSWINDOWS}
|
||||
begin
|
||||
|
|
@ -394,8 +418,6 @@ begin
|
|||
end;
|
||||
{$ENDIF}
|
||||
|
||||
(*Is Link*)
|
||||
|
||||
function FPS_ISLNK(iAttr: TFileAttrs) : Boolean; inline;
|
||||
{$IFDEF MSWINDOWS}
|
||||
begin
|
||||
|
|
@ -407,6 +429,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 +517,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
|
||||
|
|
@ -581,6 +619,14 @@ begin
|
|||
if Assigned(Errors) then Errors^[caoCopyOwnership]:= GetLastOSError;
|
||||
end;
|
||||
end;
|
||||
if caoCopyTime in Options then
|
||||
begin
|
||||
if DC_SymLinkSetTime(sDst, StatInfo.mtime, StatInfo.atime) = false then
|
||||
begin
|
||||
Include(Result, caoCopyTime);
|
||||
if Assigned(Errors) then Errors^[caoCopyTime]:= GetLastOSError;
|
||||
end;
|
||||
end;
|
||||
{$IF DEFINED(HAIKU)}
|
||||
if caoCopyXattributes in Options then
|
||||
begin
|
||||
|
|
@ -627,7 +673,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
{$IF DEFINED(LINUX) or DEFINED(HAIKU)}
|
||||
{$IF DEFINED(LINUX) or DEFINED(DARWIN) or DEFINED(HAIKU)}
|
||||
if caoCopyXattributes in Options then
|
||||
begin
|
||||
if not mbFileCopyXattr(sSrc, sDst) then
|
||||
|
|
@ -670,6 +716,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
|
||||
|
|
@ -795,6 +861,17 @@ begin
|
|||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function NormalizeFileName(const Source: String): String; inline;
|
||||
{$IF DEFINED(DARWIN)}
|
||||
begin
|
||||
Result:= GetDarwinNormalizedFileName(Source);
|
||||
end;
|
||||
{$ELSE}
|
||||
begin
|
||||
Result:= Source;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function ConsoleToUTF8(const Source: String): RawByteString;
|
||||
{$IFDEF MSWINDOWS}
|
||||
begin
|
||||
|
|
@ -818,12 +895,14 @@ begin
|
|||
if (Mode and fmOpenNoATime <> 0) then
|
||||
begin
|
||||
if (Result <> feInvalidHandle) then
|
||||
SetFileTime(Result, nil, @ft, @ft)
|
||||
SetFileTime(Result, nil, @ft, nil)
|
||||
else if GetLastError = ERROR_ACCESS_DENIED then
|
||||
Result := mbFileOpen(FileName, Mode and not fmOpenNoATime);
|
||||
end;
|
||||
end;
|
||||
{$ELSE}
|
||||
var
|
||||
Info: BaseUnix.Stat;
|
||||
begin
|
||||
repeat
|
||||
Result:= fpOpen(UTF8ToSys(FileName), AccessModes[Mode and 3] or
|
||||
|
|
@ -832,7 +911,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 +963,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}
|
||||
|
|
@ -874,27 +983,34 @@ var
|
|||
Handle: System.THandle;
|
||||
FindData: TWin32FindDataW;
|
||||
begin
|
||||
Handle := FindFirstFileW(PWideChar(UTF16LongName(FileName)), FindData);
|
||||
Handle:= FindFirstFileW(PWideChar(UTF16LongName(FileName)), FindData);
|
||||
if Handle <> INVALID_HANDLE_VALUE then
|
||||
begin
|
||||
Windows.FindClose(Handle);
|
||||
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
|
||||
Exit(DCBasicTypes.TWinFileTime(FindData.ftLastWriteTime));
|
||||
end;
|
||||
begin
|
||||
Windows.FindClose(Handle);
|
||||
Exit(DCBasicTypes.TFileTime(FindData.ftLastWriteTime));
|
||||
end;
|
||||
Result:= DCBasicTypes.TFileTime(-1);
|
||||
end;
|
||||
{$ELSE}
|
||||
var
|
||||
Info: BaseUnix.Stat;
|
||||
begin
|
||||
Result:= DCBasicTypes.TFileTime(-1);
|
||||
if fpStat(UTF8ToSys(FileName), Info) >= 0 then
|
||||
{$PUSH}{$R-}
|
||||
Result := Info.st_mtime;
|
||||
{$POP}
|
||||
Result:= DCBasicTypes.TFileTime(Info.st_mtime)
|
||||
else begin
|
||||
Result:= DCBasicTypes.TFileTime(-1);
|
||||
end;
|
||||
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 +1366,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 +1383,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 +1478,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 +1529,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);
|
||||
|
|
@ -1501,8 +1646,16 @@ begin
|
|||
Result := mbFileGetAttr(Path) <> faInvalidAttributes;
|
||||
end;
|
||||
|
||||
function mbCompareFileNames(const FileName1, FileName2: String): Boolean; inline;
|
||||
{$IF DEFINED(WINDOWS) OR DEFINED(DARWIN)}
|
||||
function mbCompareFileNames(const FileName1, FileName2: String): Boolean;
|
||||
{$IF DEFINED(DARWIN)}
|
||||
begin
|
||||
if (Length(FileName1) = 0) or (Length(FileName2) = 0) then
|
||||
Result:= (FileName1 = FileName2)
|
||||
else begin
|
||||
Result:= CompareFilenamesIgnoreCase(FileName1, FileName2) = 0;
|
||||
end;
|
||||
end;
|
||||
{$ELSEIF DEFINED(MSWINDOWS)}
|
||||
begin
|
||||
Result:= (UnicodeCompareText(CeUtf8ToUtf16(FileName1), CeUtf8ToUtf16(FileName2)) = 0);
|
||||
end;
|
||||
|
|
@ -1647,7 +1800,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 +1917,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 +1946,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 +1984,7 @@ begin
|
|||
end;
|
||||
{$ELSE}
|
||||
begin
|
||||
Result:= TLibHandle(dlopen(PChar(UTF8ToSys(Name)), RTLD_LAZY));
|
||||
Result:= SafeLoadLibrary(CeUtf8ToSys(Name));
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
|
@ -1928,14 +2095,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
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,12 +42,14 @@ type
|
|||
private
|
||||
FList: PStringHashItemList;
|
||||
FCount: Integer;
|
||||
fNormalize: Boolean;
|
||||
fCaseSensitive: Boolean;
|
||||
function BinarySearch(HashValue: Cardinal): Integer;
|
||||
function CompareString(const Low, Key: String): Boolean;
|
||||
function CompareValue(const Value1, Value2: Cardinal): Integer;
|
||||
procedure FindHashBoundaries(HashValue: Cardinal; StartFrom: Integer; out First, Last: Integer);
|
||||
function GetData(const S: String): Pointer;
|
||||
procedure SetNormalize(AValue: Boolean);
|
||||
procedure SetCaseSensitive(const Value: Boolean);
|
||||
procedure Delete(Index: Integer);
|
||||
procedure SetData(const S: String; const AValue: Pointer);
|
||||
|
|
@ -60,11 +62,13 @@ 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;
|
||||
function Remove(const S: String; Data: Pointer): Integer;
|
||||
procedure FindBoundaries(StartFrom: Integer; out First, Last: Integer);
|
||||
property Normalize: Boolean read fNormalize write SetNormalize;
|
||||
property CaseSensitive: Boolean read fCaseSensitive write SetCaseSensitive;
|
||||
property Count: Integer read FCount;
|
||||
property Data[const S: String]: Pointer read GetData write SetData; default;
|
||||
|
|
@ -74,7 +78,7 @@ type
|
|||
implementation
|
||||
|
||||
uses
|
||||
LazUTF8;
|
||||
LazUTF8, DCOSUtils;
|
||||
|
||||
{ TStringHashListUtf8 }
|
||||
|
||||
|
|
@ -96,6 +100,10 @@ begin
|
|||
else begin
|
||||
Text:= UTF8LowerCase(S);
|
||||
end;
|
||||
if fNormalize then
|
||||
begin
|
||||
Text:= NormalizeFileName(Text);
|
||||
end;
|
||||
New(Item);
|
||||
Val:= HashOf(Text);
|
||||
Item^.HashValue := Val;
|
||||
|
|
@ -162,6 +170,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;
|
||||
|
|
@ -170,13 +187,20 @@ var
|
|||
begin
|
||||
P:= Pointer(Low);
|
||||
Len:= Length(Low);
|
||||
if fCaseSensitive then
|
||||
if not fNormalize then
|
||||
begin
|
||||
Result:= (Len = Length(Key));
|
||||
if Result then Result:= (CompareByte(P^, Pointer(Key)^, Len) = 0);
|
||||
LKey:= Key;
|
||||
end
|
||||
else begin
|
||||
LKey:= UTF8LowerCase(Key);
|
||||
LKey:= NormalizeFileName(Key);
|
||||
end;
|
||||
if fCaseSensitive then
|
||||
begin
|
||||
Result:= (Len = Length(LKey));
|
||||
if Result then Result:= (CompareByte(P^, Pointer(LKey)^, Len) = 0);
|
||||
end
|
||||
else begin
|
||||
LKey:= UTF8LowerCase(LKey);
|
||||
Result:= (Len = Length(LKey));
|
||||
if Result then Result:= (CompareByte(P^, Pointer(LKey)^, Len) = 0);
|
||||
end;
|
||||
|
|
@ -222,6 +246,18 @@ begin
|
|||
Add(S,AValue);
|
||||
end;
|
||||
|
||||
procedure TStringHashListUtf8.SetNormalize(AValue: Boolean);
|
||||
begin
|
||||
if fNormalize <> AValue then
|
||||
begin
|
||||
if Count > 0 then
|
||||
begin
|
||||
raise EListError.Create(lrsListMustBeEmpty);
|
||||
end;
|
||||
fNormalize := AValue;
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TStringHashListUtf8.Destroy;
|
||||
begin
|
||||
Clear;
|
||||
|
|
@ -239,6 +275,10 @@ begin
|
|||
else begin
|
||||
Text:= UTF8LowerCase(S);
|
||||
end;
|
||||
if fNormalize then
|
||||
begin
|
||||
Text:= NormalizeFileName(Text);
|
||||
end;
|
||||
Value:= HashOf(Text);
|
||||
Result:= BinarySearch(Value);
|
||||
if (Result <> -1) and not CompareString(Text, FList[Result]^.Key) then
|
||||
|
|
@ -265,6 +305,10 @@ begin
|
|||
else begin
|
||||
Text:= UTF8LowerCase(S);
|
||||
end;
|
||||
if fNormalize then
|
||||
begin
|
||||
Text:= NormalizeFileName(Text);
|
||||
end;
|
||||
Value:= HashOf(Text);
|
||||
Result:= BinarySearch(Value);
|
||||
if (Result <> -1) and
|
||||
|
|
@ -325,7 +369,8 @@ end;
|
|||
|
||||
constructor TStringHashListUtf8.Create(CaseSensitivity: boolean);
|
||||
begin
|
||||
fCaseSensitive:=CaseSensitivity;
|
||||
fNormalize:= FileNameNormalized;
|
||||
fCaseSensitive:= CaseSensitivity;
|
||||
inherited Create;
|
||||
end;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -241,6 +247,7 @@ function TrimPath(const Path: String): String;
|
|||
}
|
||||
function TrimRightLineEnding(const sText: String; TextLineBreakStyle: TTextLineBreakStyle): String;
|
||||
function mbCompareText(const s1, s2: String): PtrInt;
|
||||
function mbCompareStr(const s1, s2: String): PtrInt;
|
||||
|
||||
function StrNewW(const mbString: String): PWideChar;
|
||||
procedure StrDisposeW(var pStr : PWideChar);
|
||||
|
|
@ -365,6 +372,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 +397,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 +651,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 +672,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 +686,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;
|
||||
|
|
@ -704,12 +753,12 @@ begin
|
|||
|
||||
sBasePath := IncludeTrailingPathDelimiter(sBasePath);
|
||||
|
||||
BasePathLength := Length(sBasePath);
|
||||
PathToCheckLength := Length(sPathToCheck);
|
||||
BasePathLength := UTF8Length(sBasePath);
|
||||
PathToCheckLength := UTF8Length(sPathToCheck);
|
||||
|
||||
if PathToCheckLength > BasePathLength then
|
||||
begin
|
||||
if mbCompareFileNames(Copy(sPathToCheck, 1, BasePathLength), sBasePath) then
|
||||
if mbCompareFileNames(UTF8Copy(sPathToCheck, 1, BasePathLength), sBasePath) then
|
||||
begin
|
||||
if AllowSubDirs then
|
||||
Result := True
|
||||
|
|
@ -718,10 +767,10 @@ begin
|
|||
// Additionally check if the remaining path is a relative path.
|
||||
|
||||
// Look for a path delimiter in the middle of the filepath.
|
||||
sPathToCheck := Copy(sPathToCheck, 1 + BasePathLength,
|
||||
sPathToCheck := UTF8Copy(sPathToCheck, 1 + BasePathLength,
|
||||
PathToCheckLength - BasePathLength);
|
||||
|
||||
DelimiterPos := Pos(DirectorySeparator, sPathToCheck);
|
||||
DelimiterPos := UTF8Pos(DirectorySeparator, sPathToCheck);
|
||||
|
||||
// If no delimiter was found or it was found at then end (directories
|
||||
// may end with it), then the 'sPathToCheck' is in 'sBasePath'.
|
||||
|
|
@ -736,7 +785,7 @@ begin
|
|||
(((PathToCheckLength = BasePathLength) and
|
||||
(mbCompareFileNames(sPathToCheck, sBasePath))) or
|
||||
((PathToCheckLength = BasePathLength - 1) and
|
||||
(mbCompareFileNames(Copy(sBasePath, 1, PathToCheckLength), sPathToCheck))));
|
||||
(mbCompareFileNames(UTF8Copy(sBasePath, 1, PathToCheckLength), sPathToCheck))));
|
||||
end;
|
||||
|
||||
function ExtractDirLevel(const sPrefix, sPath: String): String;
|
||||
|
|
@ -976,9 +1025,12 @@ end;
|
|||
|
||||
function mbCompareText(const s1, s2: String): PtrInt; inline;
|
||||
begin
|
||||
// From 0.9.31 LazUtils can be used but this package does not exist in 0.9.30.
|
||||
// Result := LazUTF8.UTF8CompareText(s1, s2);
|
||||
Result := WideCompareText(CeUtf8ToUtf16(s1), CeUtf8ToUtf16(s2));
|
||||
Result := UnicodeCompareText(CeUtf8ToUtf16(s1), CeUtf8ToUtf16(s2));
|
||||
end;
|
||||
|
||||
function mbCompareStr(const s1, s2: String): PtrInt; inline;
|
||||
begin
|
||||
Result := UnicodeCompareStr(CeUtf8ToUtf16(s1), CeUtf8ToUtf16(s2));
|
||||
end;
|
||||
|
||||
function StrNewW(const mbString: String): PWideChar;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
211
components/doublecmd/dcunix.pas
Executable file → Normal file
211
components/doublecmd/dcunix.pas
Executable file → Normal 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,24 @@ const
|
|||
{$IF DEFINED(LINUX)}
|
||||
FD_CLOEXEC = 1;
|
||||
O_CLOEXEC = &02000000;
|
||||
O_PATH = &010000000;
|
||||
_SC_NPROCESSORS_CONF = 83;
|
||||
_SC_NPROCESSORS_ONLN = 84;
|
||||
{$ELSEIF DEFINED(FREEBSD)}
|
||||
O_CLOEXEC = &04000000;
|
||||
_SC_NPROCESSORS_CONF = 57;
|
||||
_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_CONF = 57;
|
||||
_SC_NPROCESSORS_ONLN = 58;
|
||||
{$ELSE}
|
||||
O_CLOEXEC = 0;
|
||||
{$ENDIF}
|
||||
|
|
@ -155,6 +166,7 @@ type
|
|||
{$ELSE}
|
||||
TDCStat = BaseUnix.Stat;
|
||||
{$ENDIF}
|
||||
PDCStat = ^TDCStat;
|
||||
|
||||
TDCStatHelper = record Helper for TDCStat
|
||||
Public
|
||||
|
|
@ -172,6 +184,11 @@ function DC_FileSetTime(const FileName: String;
|
|||
const birthtime: TFileTimeEx;
|
||||
const atime : TFileTimeEx ): Boolean;
|
||||
|
||||
// nanoseconds supported, does not follow symbolic links
|
||||
function DC_SymLinkSetTime(const FileName: String;
|
||||
const mtime : TFileTimeEx;
|
||||
const atime : TFileTimeEx ): Boolean;
|
||||
|
||||
|
||||
{en
|
||||
Set the close-on-exec flag to all
|
||||
|
|
@ -248,6 +265,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 +276,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)}
|
||||
|
|
@ -270,17 +291,24 @@ function fnmatch(const pattern: PAnsiChar; const str: PAnsiChar; flags: cint): c
|
|||
implementation
|
||||
|
||||
uses
|
||||
Unix, DCConvertEncoding, LazUTF8
|
||||
{$IFDEF DARWIN}
|
||||
Unix, DCConvertEncoding, DCOSUtils, LazUTF8
|
||||
{$IF DEFINED(DARWIN)}
|
||||
, DCDarwin
|
||||
{$ELSEIF DEFINED(LINUX)}
|
||||
, Dos, DCLinux
|
||||
{$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;
|
||||
|
|
@ -348,6 +376,7 @@ end;
|
|||
{$ENDIF}
|
||||
|
||||
function fputimes( path:pchar; times:Array of UnixType.timeval ): cint; cdecl; external clib name 'utimes';
|
||||
function flutimes( path:pchar; times:Array of UnixType.timeval ): cint; cdecl; external clib name 'lutimes';
|
||||
|
||||
function DC_FileSetTime(const FileName: String;
|
||||
const mtime : TFileTimeEx;
|
||||
|
|
@ -373,7 +402,22 @@ begin
|
|||
{$ENDIF}
|
||||
end;
|
||||
|
||||
|
||||
// Like DC_FileSetTime but uses lutimes() instead of utimes(), so the
|
||||
// timestamp is set on the symlink itself rather than its target.
|
||||
function DC_SymLinkSetTime(const FileName: String;
|
||||
const mtime : TFileTimeEx;
|
||||
const atime : TFileTimeEx ): Boolean;
|
||||
var
|
||||
timevals: Array[0..1] of UnixType.timeval;
|
||||
begin
|
||||
// last access time
|
||||
timevals[0].tv_sec:= atime.sec;
|
||||
timevals[0].tv_usec:= round( Extended(atime.nanosec) / 1000.0 );
|
||||
// last modification time
|
||||
timevals[1].tv_sec:= mtime.sec;
|
||||
timevals[1].tv_usec:= round( Extended(mtime.nanosec) / 1000.0 );
|
||||
Result:= flutimes(pchar(UTF8ToSys(FileName)), timevals) = 0;
|
||||
end;
|
||||
|
||||
{$IF DEFINED(BSD)}
|
||||
type rlim_t = Int64;
|
||||
|
|
@ -394,26 +438,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 +483,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;
|
||||
|
|
@ -454,21 +516,22 @@ begin
|
|||
begin
|
||||
if (I = 1) then
|
||||
sTemp:= PathDelim
|
||||
else
|
||||
else begin
|
||||
sTemp:= Copy(FileName, 1, I - 1);
|
||||
end;
|
||||
// Stat for current directory
|
||||
if (fpLStat(sTemp, recStat) < 0) then Continue;
|
||||
// If it is a link then checking link destination
|
||||
if fpS_ISLNK(recStat.st_mode) then
|
||||
begin
|
||||
sTemp:= fpReadlink(sTemp);
|
||||
sTemp:= mbReadAllLinks(sTemp);
|
||||
Result:= FindMountPointPath(sTemp);
|
||||
Exit;
|
||||
end;
|
||||
// Check device ID
|
||||
if (recStat.st_dev <> st_dev) then
|
||||
begin
|
||||
Result:= Copy(FileName, 1, J);
|
||||
Result:= IncludeTrailingPathDelimiter(Copy(FileName, 1, J));
|
||||
Exit;
|
||||
end;
|
||||
J:= I;
|
||||
|
|
@ -505,6 +568,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 +622,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
40
components/doublecmd/dcxmlconfig.pas
Normal file → Executable 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
|
||||
|
|
|
|||
|
|
@ -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 <> 'arm') then
|
||||
|
|
@ -34,8 +36,8 @@ end"/>
|
|||
</CompilerOptions>
|
||||
<Description Value="Common units for Double Commander"/>
|
||||
<License Value="GNU GPL 2"/>
|
||||
<Version Minor="4" Release="1"/>
|
||||
<Files Count="12">
|
||||
<Version Minor="4" Release="3"/>
|
||||
<Files Count="13">
|
||||
<Item1>
|
||||
<Filename Value="dcclassesutf8.pas"/>
|
||||
<UnitName Value="DCClassesUtf8"/>
|
||||
|
|
@ -84,6 +86,10 @@ end"/>
|
|||
<Filename Value="dcjsonconfig.pas"/>
|
||||
<UnitName Value="DCJsonConfig"/>
|
||||
</Item12>
|
||||
<Item13>
|
||||
<Filename Value="dcclasses.pas"/>
|
||||
<UnitName Value="DCClasses"/>
|
||||
</Item13>
|
||||
</Files>
|
||||
<CompatibilityMode Value="True"/>
|
||||
<RequiredPkgs Count="2">
|
||||
|
|
|
|||
|
|
@ -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, DCClasses;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
|
|
|||
106
components/doublecmd/iconvenc/dc_iconvenc_dyn.pas
Normal file
106
components/doublecmd/iconvenc/dc_iconvenc_dyn.pas
Normal 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.
|
||||
53
components/doublecmd/iconvenc/dc_iconvert.inc
Normal file
53
components/doublecmd/iconvenc/dc_iconvert.inc
Normal 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;
|
||||
|
|
@ -1,370 +0,0 @@
|
|||
Index: gifanim.pas
|
||||
===================================================================
|
||||
--- gifanim.pas (revision none)
|
||||
+++ gifanim.pas (working copy)
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
uses
|
||||
Classes, LCLProc, Lresources, SysUtils, Controls, Graphics, ExtCtrls,
|
||||
- IntfGraphics, FPimage, Contnrs, GraphType, dialogs;
|
||||
+ IntfGraphics, FPimage, Contnrs, GraphType, dialogs, types;
|
||||
|
||||
const
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
procedure DoAutoSize; override;
|
||||
procedure DoStartAnim;
|
||||
procedure DoStopAnim;
|
||||
- class function GetControlClassDefaultSize: TPoint; override;
|
||||
+ class function GetControlClassDefaultSize: TSize; override;
|
||||
procedure GifChanged;
|
||||
procedure LoadFromFile(const Filename: string); virtual;
|
||||
procedure Paint; override;
|
||||
@@ -203,6 +203,8 @@
|
||||
{ Public declarations }
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
+ procedure NextFrame;
|
||||
+ procedure PriorFrame;
|
||||
property Empty: boolean Read FEmpty;
|
||||
property GifBitmaps: TGifList Read FGifBitmaps;
|
||||
property GifIndex: integer Read FCurrentImage;
|
||||
@@ -237,28 +239,9 @@
|
||||
|
||||
implementation
|
||||
|
||||
-uses LazIDEIntf, propedits;
|
||||
-Type
|
||||
- TGifFileNamePropertyEditor=class(TFileNamePropertyEditor)
|
||||
- protected
|
||||
- function GetFilter: String; override;
|
||||
- function GetInitialDirectory: string; override;
|
||||
- end;
|
||||
-function TGifFileNamePropertyEditor.GetFilter: String;
|
||||
-begin
|
||||
- Result := 'GIF|*.gif';
|
||||
-end;
|
||||
-
|
||||
-function TGifFileNamePropertyEditor.GetInitialDirectory: string;
|
||||
-begin
|
||||
- Result:= ExtractFilePath(LazarusIDE.ActiveProject.ProjectInfoFile);
|
||||
-end;
|
||||
-
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterComponents('Wile64', [TGifAnim]);
|
||||
- RegisterPropertyEditor(TypeInfo(String),
|
||||
- TGifAnim, 'FileName', TGifFileNamePropertyEditor);
|
||||
end;
|
||||
|
||||
{ TGifAnim }
|
||||
@@ -268,7 +251,7 @@
|
||||
inherited Create(AOwner);
|
||||
ControlStyle := [csCaptureMouse, csClickEvents, csDoubleClicks];
|
||||
AutoSize := True;
|
||||
- SetInitialBounds(0, 0, GetControlClassDefaultSize.X, GetControlClassDefaultSize.Y);
|
||||
+ SetInitialBounds(0, 0, GetControlClassDefaultSize.CX, GetControlClassDefaultSize.CY);
|
||||
FEmpty := True;
|
||||
FCurrentImage := 0;
|
||||
CurrentView := TBitmap.Create;
|
||||
@@ -295,6 +278,59 @@
|
||||
CurrentView.Free;
|
||||
end;
|
||||
|
||||
+procedure TGifAnim.NextFrame;
|
||||
+begin
|
||||
+ if (not FEmpty) and Visible and (not FAnimate) then
|
||||
+ begin
|
||||
+ if FCurrentImage >= GifBitmaps.Count - 1 then
|
||||
+ FCurrentImage := 0
|
||||
+ else
|
||||
+ Inc(FCurrentImage);
|
||||
+ if Assigned(FOnFrameChanged) then
|
||||
+ FOnFrameChanged(Self);
|
||||
+ Repaint;
|
||||
+ end;
|
||||
+end;
|
||||
+
|
||||
+procedure TGifAnim.PriorFrame;
|
||||
+var
|
||||
+ DesiredImage: Integer;
|
||||
+begin
|
||||
+ if (not FEmpty) and Visible and (not FAnimate) then
|
||||
+ begin
|
||||
+ if FCurrentImage = 0 then
|
||||
+ DesiredImage:= GifBitmaps.Count - 1
|
||||
+ else
|
||||
+ DesiredImage:= FCurrentImage - 1;
|
||||
+ // For proper display repaint image from first frame to desired frame
|
||||
+ FCurrentImage:= 0;
|
||||
+ while FCurrentImage < DesiredImage do
|
||||
+ begin
|
||||
+ with GifBitmaps.Items[FCurrentImage] do
|
||||
+ begin
|
||||
+ BufferImg.Canvas.Brush.Color := (Self.Color);
|
||||
+ if FCurrentImage = 0 then
|
||||
+ BufferImg.Canvas.FillRect(Rect(0, 0, Width, Height));
|
||||
+ if Delay <> 0 then
|
||||
+ FWait.Interval := Delay * 10;
|
||||
+ BufferImg.Canvas.Draw(PosX, PosY, Bitmap);
|
||||
+ case Method of
|
||||
+ //0 : Not specified...
|
||||
+ //1 : No change Background
|
||||
+ 2: BufferImg.Canvas.FillRect(
|
||||
+ Rect(PosX, PosY, Bitmap.Width + PosX, Bitmap.Height + PosY));
|
||||
+
|
||||
+ 3: BufferImg.Canvas.FillRect(Rect(0, 0, Width, Height));
|
||||
+ end;
|
||||
+ end;
|
||||
+ Inc(FCurrentImage);
|
||||
+ end;
|
||||
+ if Assigned(FOnFrameChanged) then
|
||||
+ FOnFrameChanged(Self);
|
||||
+ Repaint;
|
||||
+ end;
|
||||
+end;
|
||||
+
|
||||
function TGifAnim.LoadFromLazarusResource(const ResName: String): boolean;
|
||||
var
|
||||
GifLoader: TGifLoader;
|
||||
@@ -340,12 +376,13 @@
|
||||
begin
|
||||
if (not Empty) and Visible then
|
||||
begin
|
||||
- if FCurrentImage > GifBitmaps.Count - 1 then
|
||||
- FCurrentImage := 0;
|
||||
- if assigned(FOnFrameChanged) then
|
||||
- FOnFrameChanged(self);
|
||||
- Paint;
|
||||
- Inc(FCurrentImage);
|
||||
+ if FCurrentImage >= GifBitmaps.Count - 1 then
|
||||
+ FCurrentImage := 0
|
||||
+ else
|
||||
+ Inc(FCurrentImage);
|
||||
+ if Assigned(FOnFrameChanged) then
|
||||
+ FOnFrameChanged(Self);
|
||||
+ Repaint;
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -365,27 +402,12 @@
|
||||
end;
|
||||
|
||||
procedure TGifAnim.SetFileName(const AValue: string);
|
||||
-var
|
||||
- fn: string;
|
||||
begin
|
||||
-
|
||||
- if (FFileName = AValue) then
|
||||
- exit;
|
||||
+ if (FFileName = AValue) then Exit;
|
||||
FFileName := AValue;
|
||||
ResetImage;
|
||||
- if (FFileName = '') then exit;
|
||||
- if (csDesigning in ComponentState) then
|
||||
- begin
|
||||
- fn:= ExtractFileName(AValue);
|
||||
- FFileName:= ExtractFilePath(AValue);
|
||||
- FFileName:= ExtractRelativepath(ExtractFilePath(LazarusIDE.ActiveProject.ProjectInfoFile) ,FFileName);
|
||||
- FFileName:=FFileName+fn;
|
||||
- LoadFromFile(FFileName+fn);
|
||||
- end
|
||||
- else begin
|
||||
- FFileName := AValue;
|
||||
- LoadFromFile(FFileName);
|
||||
- end;
|
||||
+ if (FFileName = '') then Exit;
|
||||
+ LoadFromFile(FFileName);
|
||||
if not Empty then
|
||||
GifChanged;
|
||||
end;
|
||||
@@ -441,10 +463,10 @@
|
||||
end;
|
||||
end;
|
||||
|
||||
-class function TGifAnim.GetControlClassDefaultSize: TPoint;
|
||||
+class function TGifAnim.GetControlClassDefaultSize: TSize;
|
||||
begin
|
||||
- Result.X := 90;
|
||||
- Result.Y := 90;
|
||||
+ Result.CX := 90;
|
||||
+ Result.CY := 90;
|
||||
end;
|
||||
|
||||
procedure TGifAnim.GifChanged;
|
||||
Index: gifanimdsgn.pas
|
||||
===================================================================
|
||||
--- gifanimdsgn.pas (revision 0)
|
||||
+++ gifanimdsgn.pas (revision 0)
|
||||
@@ -0,0 +1,41 @@
|
||||
+unit GifAnimDsgn;
|
||||
+
|
||||
+{$mode objfpc}{$H+}
|
||||
+
|
||||
+interface
|
||||
+
|
||||
+uses
|
||||
+ LazIDEIntf, PropEdits;
|
||||
+
|
||||
+Type
|
||||
+ TGifFileNamePropertyEditor = class(TFileNamePropertyEditor)
|
||||
+ protected
|
||||
+ function GetFilter: String; override;
|
||||
+ function GetInitialDirectory: string; override;
|
||||
+ end;
|
||||
+
|
||||
+procedure Register;
|
||||
+
|
||||
+implementation
|
||||
+
|
||||
+uses
|
||||
+ SysUtils, GifAnim;
|
||||
+
|
||||
+function TGifFileNamePropertyEditor.GetFilter: String;
|
||||
+begin
|
||||
+ Result := 'GIF|*.gif';
|
||||
+end;
|
||||
+
|
||||
+function TGifFileNamePropertyEditor.GetInitialDirectory: string;
|
||||
+begin
|
||||
+ Result:= ExtractFilePath(LazarusIDE.ActiveProject.ProjectInfoFile);
|
||||
+end;
|
||||
+
|
||||
+procedure Register;
|
||||
+begin
|
||||
+ RegisterPropertyEditor(TypeInfo(String), TGifAnim,
|
||||
+ 'FileName', TGifFileNamePropertyEditor);
|
||||
+end;
|
||||
+
|
||||
+end.
|
||||
+
|
||||
Index: pkg_gifanim.lpk
|
||||
===================================================================
|
||||
--- pkg_gifanim.lpk (revision none)
|
||||
+++ pkg_gifanim.lpk (working copy)
|
||||
@@ -1,15 +1,21 @@
|
||||
-<?xml version="1.0"?>
|
||||
+<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
- <Package Version="3">
|
||||
+ <Package Version="4">
|
||||
<PathDelim Value="\"/>
|
||||
<Name Value="pkg_gifanim"/>
|
||||
+ <AddToProjectUsesSection Value="True"/>
|
||||
<Author Value="Laurent Jacques"/>
|
||||
<CompilerOptions>
|
||||
- <Version Value="8"/>
|
||||
+ <Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<SearchPaths>
|
||||
- <OtherUnitFiles Value="$(LazarusDir)\ide\"/>
|
||||
+ <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
+ <Linking>
|
||||
+ <Debugging>
|
||||
+ <DebugInfoType Value="dsDwarf2Set"/>
|
||||
+ </Debugging>
|
||||
+ </Linking>
|
||||
<Other>
|
||||
<CompilerPath Value="$(CompPath)"/>
|
||||
</Other>
|
||||
@@ -33,15 +39,16 @@
|
||||
<Type Value="RunAndDesignTime"/>
|
||||
<RequiredPkgs Count="2">
|
||||
<Item1>
|
||||
- <PackageName Value="FCL"/>
|
||||
+ <PackageName Value="LCL"/>
|
||||
<MinVersion Major="1" Valid="True"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
- <PackageName Value="IDEIntf"/>
|
||||
+ <PackageName Value="FCL"/>
|
||||
+ <MinVersion Major="1" Valid="True"/>
|
||||
</Item2>
|
||||
</RequiredPkgs>
|
||||
<UsageOptions>
|
||||
- <UnitPath Value="$(PkgOutDir)\"/>
|
||||
+ <UnitPath Value="$(PkgOutDir)"/>
|
||||
</UsageOptions>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
Index: pkg_gifanim_dsgn.lpk
|
||||
===================================================================
|
||||
--- pkg_gifanim_dsgn.lpk (revision 0)
|
||||
+++ pkg_gifanim_dsgn.lpk (revision 0)
|
||||
@@ -0,0 +1,49 @@
|
||||
+<?xml version="1.0" encoding="UTF-8"?>
|
||||
+<CONFIG>
|
||||
+ <Package Version="4">
|
||||
+ <PathDelim Value="\"/>
|
||||
+ <Name Value="pkg_gifanim_dsgn"/>
|
||||
+ <CompilerOptions>
|
||||
+ <Version Value="11"/>
|
||||
+ <PathDelim Value="\"/>
|
||||
+ <SearchPaths>
|
||||
+ <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
+ </SearchPaths>
|
||||
+ <Linking>
|
||||
+ <Debugging>
|
||||
+ <DebugInfoType Value="dsDwarf2Set"/>
|
||||
+ </Debugging>
|
||||
+ </Linking>
|
||||
+ <Other>
|
||||
+ <CompilerMessages>
|
||||
+ <MsgFileName Value=""/>
|
||||
+ </CompilerMessages>
|
||||
+ <CompilerPath Value="$(CompPath)"/>
|
||||
+ </Other>
|
||||
+ </CompilerOptions>
|
||||
+ <License Value="GPL"/>
|
||||
+ <Version Major="1" Minor="4"/>
|
||||
+ <Files Count="1">
|
||||
+ <Item1>
|
||||
+ <Filename Value="gifanimdsgn.pas"/>
|
||||
+ <HasRegisterProc Value="True"/>
|
||||
+ <UnitName Value="GifAnimDsgn"/>
|
||||
+ </Item1>
|
||||
+ </Files>
|
||||
+ <Type Value="DesignTime"/>
|
||||
+ <RequiredPkgs Count="2">
|
||||
+ <Item1>
|
||||
+ <PackageName Value="IDEIntf"/>
|
||||
+ </Item1>
|
||||
+ <Item2>
|
||||
+ <PackageName Value="pkg_gifanim"/>
|
||||
+ </Item2>
|
||||
+ </RequiredPkgs>
|
||||
+ <UsageOptions>
|
||||
+ <UnitPath Value="$(PkgOutDir)"/>
|
||||
+ </UsageOptions>
|
||||
+ <PublishOptions>
|
||||
+ <Version Value="2"/>
|
||||
+ </PublishOptions>
|
||||
+ </Package>
|
||||
+</CONFIG>
|
||||
Index: pkg_gifanim_dsgn.pas
|
||||
===================================================================
|
||||
--- pkg_gifanim_dsgn.pas (revision 0)
|
||||
+++ pkg_gifanim_dsgn.pas (revision 0)
|
||||
@@ -0,0 +1,21 @@
|
||||
+{ This file was automatically created by Lazarus. Do not edit!
|
||||
+ This source is only used to compile and install the package.
|
||||
+ }
|
||||
+
|
||||
+unit pkg_gifanim_dsgn;
|
||||
+
|
||||
+interface
|
||||
+
|
||||
+uses
|
||||
+ GifAnimDsgn, LazarusPackageIntf;
|
||||
+
|
||||
+implementation
|
||||
+
|
||||
+procedure Register;
|
||||
+begin
|
||||
+ RegisterUnit('GifAnimDsgn', @GifAnimDsgn.Register);
|
||||
+end;
|
||||
+
|
||||
+initialization
|
||||
+ RegisterPackage('pkg_gifanim_dsgn', @Register);
|
||||
+end.
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
LazarusResources.Add('tgifanim','XPM',[
|
||||
'/* XPM */'#13#10'static char * gifanim_xpm[] = {'#13#10'"24 24 31 1",'#13#10
|
||||
+'" '#9'c None",'#13#10'".'#9'c #959595",'#13#10'"+'#9'c #E1E1E1",'#13#10'"@'
|
||||
+#9'c #919191",'#13#10'"#'#9'c #848484",'#13#10'"$'#9'c #888888",'#13#10'"%'#9
|
||||
+'c #EEEEEE",'#13#10'"&'#9'c #E6E9EC",'#13#10'"*'#9'c #D6DFE8",'#13#10'"='#9
|
||||
+'c #FFFFFF",'#13#10'"-'#9'c #E7F0F9",'#13#10'";'#9'c #3783CE",'#13#10'">'#9
|
||||
+'c #FFF7F7",'#13#10'",'#9'c #FFEFEF",'#13#10'"'''#9'c #F7F2F5",'#13#10'")'#9
|
||||
+'c #F7FAFD",'#13#10'"!'#9'c #FF5757",'#13#10'"~'#9'c #FFDFDF",'#13#10'"{'#9
|
||||
+'c #FF4F4F",'#13#10'"]'#9'c #FFD7D7",'#13#10'"^'#9'c #FF4747",'#13#10'"/'#9
|
||||
+'c #FF3F3F",'#13#10'"('#9'c #8D8D8D",'#13#10'"_'#9'c #EEE6E6",'#13#10'":'#9
|
||||
+'c #EED6D6",'#13#10'"<'#9'c #EECECE",'#13#10'"['#9'c #FAFAFA",'#13#10'"}'#9
|
||||
+'c #F2F2F2",'#13#10'"|'#9'c #F6F6F6",'#13#10'"1'#9'c #A2A2A2",'#13#10'"2'#9
|
||||
+'c #FAF2F2",'#13#10'" .++@ @++. ",'#13#10'" @@@##$$$$$$$$$$$$##'
|
||||
+'@@@ ",'#13#10'" .++$#$$$$$$$$$$$$#$++. ",'#13#10'" .++@+%%&**&&**&%%+@++. "'
|
||||
+','#13#10'" @@@@%==-;;--;;-==%@@@@ ",'#13#10'" .++.%==-;;--;;-==%.++. ",'#13
|
||||
+#10'" .++.%>,''--))--'',>%.++. ",'#13#10'" @@@@%,!~>====>~!,%@@@@ ",'#13#10
|
||||
+'" .++.%>~{]~~~~]{~>%.++. ",'#13#10'" .++.%=>~^////^~>=%.++. ",'#13#10'" @@@'
|
||||
+'(+%%_:<<<<:_%%+(@@@ ",'#13#10'" .++$#$$$$$$$$$$$$#$++. ",'#13#10'" .++$#$$$'
|
||||
+'$$$$$$$$$#$++. ",'#13#10'" @@@(+%%&**&%%%%%%+(@@@ ",'#13#10'" .++.%==-;;-[}'
|
||||
+'}[==%.++. ",'#13#10'" .++.%==-;;-|11|==%.++. ",'#13#10'" @@@@%>,''--)[}}2,>'
|
||||
+'%@@@@ ",'#13#10'" .++.%,!~>====>~!,%.++. ",'#13#10'" .++.%>~{]~~~~]{~>%.++.'
|
||||
+' ",'#13#10'" @@@@%=>~^////^~>=%@@@@ ",'#13#10'" .++@+%%_:<<<<:_%%+@++. ",'
|
||||
+#13#10'" .++$#$$$$$$$$$$$$#$++. ",'#13#10'" @@@##$$$$$$$$$$$$##@@@ ",'#13#10
|
||||
+'" .++@ @++. "};'#13#10
|
||||
]);
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,41 +0,0 @@
|
|||
unit GifAnimDsgn;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
LazIDEIntf, PropEdits;
|
||||
|
||||
Type
|
||||
TGifFileNamePropertyEditor = class(TFileNamePropertyEditor)
|
||||
protected
|
||||
function GetFilter: String; override;
|
||||
function GetInitialDirectory: string; override;
|
||||
end;
|
||||
|
||||
procedure Register;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
SysUtils, GifAnim;
|
||||
|
||||
function TGifFileNamePropertyEditor.GetFilter: String;
|
||||
begin
|
||||
Result := 'GIF|*.gif';
|
||||
end;
|
||||
|
||||
function TGifFileNamePropertyEditor.GetInitialDirectory: string;
|
||||
begin
|
||||
Result:= ExtractFilePath(LazarusIDE.ActiveProject.ProjectInfoFile);
|
||||
end;
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterPropertyEditor(TypeInfo(String), TGifAnim,
|
||||
'FileName', TGifFileNamePropertyEditor);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<Package Version="4">
|
||||
<PathDelim Value="\"/>
|
||||
<Name Value="pkg_gifanim"/>
|
||||
<AddToProjectUsesSection Value="True"/>
|
||||
<Author Value="Laurent Jacques"/>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<SearchPaths>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<DebugInfoType Value="dsDwarf2Set"/>
|
||||
</Debugging>
|
||||
</Linking>
|
||||
<Other>
|
||||
<CompilerPath Value="$(CompPath)"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
<Description Value="Show Gif Animation
|
||||
"/>
|
||||
<License Value="GPL
|
||||
"/>
|
||||
<Version Major="1" Minor="5"/>
|
||||
<Files Count="2">
|
||||
<Item1>
|
||||
<Filename Value="gifanim.pas"/>
|
||||
<HasRegisterProc Value="True"/>
|
||||
<UnitName Value="GifAnim"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<Filename Value="gifanim.lrs"/>
|
||||
<Type Value="LRS"/>
|
||||
</Item2>
|
||||
</Files>
|
||||
<Type Value="RunAndDesignTime"/>
|
||||
<RequiredPkgs Count="2">
|
||||
<Item1>
|
||||
<PackageName Value="LCL"/>
|
||||
<MinVersion Major="1" Valid="True"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<PackageName Value="FCL"/>
|
||||
<MinVersion Major="1" Valid="True"/>
|
||||
</Item2>
|
||||
</RequiredPkgs>
|
||||
<UsageOptions>
|
||||
<UnitPath Value="$(PkgOutDir)"/>
|
||||
</UsageOptions>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
<IgnoreBinaries Value="False"/>
|
||||
</PublishOptions>
|
||||
</Package>
|
||||
</CONFIG>
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
{ This file was automatically created by Lazarus. Do not edit!
|
||||
This source is only used to compile and install the package.
|
||||
}
|
||||
|
||||
unit pkg_gifanim;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
GifAnim, LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterUnit('GifAnim', @GifAnim.Register);
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterPackage('pkg_gifanim', @Register);
|
||||
end.
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<Package Version="4">
|
||||
<PathDelim Value="\"/>
|
||||
<Name Value="pkg_gifanim_dsgn"/>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<SearchPaths>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<DebugInfoType Value="dsDwarf2Set"/>
|
||||
</Debugging>
|
||||
</Linking>
|
||||
<Other>
|
||||
<CompilerMessages>
|
||||
<MsgFileName Value=""/>
|
||||
</CompilerMessages>
|
||||
<CompilerPath Value="$(CompPath)"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
<License Value="GPL"/>
|
||||
<Version Major="1" Minor="4"/>
|
||||
<Files Count="1">
|
||||
<Item1>
|
||||
<Filename Value="gifanimdsgn.pas"/>
|
||||
<HasRegisterProc Value="True"/>
|
||||
<UnitName Value="GifAnimDsgn"/>
|
||||
</Item1>
|
||||
</Files>
|
||||
<Type Value="DesignTime"/>
|
||||
<RequiredPkgs Count="2">
|
||||
<Item1>
|
||||
<PackageName Value="IDEIntf"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<PackageName Value="pkg_gifanim"/>
|
||||
</Item2>
|
||||
</RequiredPkgs>
|
||||
<UsageOptions>
|
||||
<UnitPath Value="$(PkgOutDir)"/>
|
||||
</UsageOptions>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
</PublishOptions>
|
||||
</Package>
|
||||
</CONFIG>
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
{ This file was automatically created by Lazarus. Do not edit!
|
||||
This source is only used to compile and install the package.
|
||||
}
|
||||
|
||||
unit pkg_gifanim_dsgn;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
GifAnimDsgn, LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterUnit('GifAnimDsgn', @GifAnimDsgn.Register);
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterPackage('pkg_gifanim_dsgn', @Register);
|
||||
end.
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
GifAnim
|
||||
http://wile64.perso.neuf.fr/download/download.php?cat=4&id=8
|
||||
Version 1.4 (14/09/2009)
|
||||
|
||||
Some modifications done for Double Commander (see doublecmd.diff).
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
|
||||
1) Gif in ressource file
|
||||
-------------------------
|
||||
|
||||
- Create ressource file with lazres ex : lazres mygif.lrs gif1.gif gif2.gif
|
||||
- Put TGifAnim on your form
|
||||
- In the FormCreate add (see down)
|
||||
|
||||
[code]
|
||||
|
||||
procedure TForm1.FormCreate(Sender: TObject);
|
||||
begin
|
||||
GifAnim1.LoadFromLazarusResource('gif1');
|
||||
GifAnim2.LoadFromLazarusResource('gif2');
|
||||
end;
|
||||
|
||||
[/code]
|
||||
|
||||
- And insert ressouce file in initialization section (see down)
|
||||
|
||||
[code]
|
||||
|
||||
initialization
|
||||
{$I unit1.lrs}
|
||||
{$I mesgif.lrs}
|
||||
|
||||
[/code]
|
||||
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
/* XPM */
|
||||
static char * gifanim_xpm[] = {
|
||||
"24 24 31 1",
|
||||
" c None",
|
||||
". c #959595",
|
||||
"+ c #E1E1E1",
|
||||
"@ c #919191",
|
||||
"# c #848484",
|
||||
"$ c #888888",
|
||||
"% c #EEEEEE",
|
||||
"& c #E6E9EC",
|
||||
"* c #D6DFE8",
|
||||
"= c #FFFFFF",
|
||||
"- c #E7F0F9",
|
||||
"; c #3783CE",
|
||||
"> c #FFF7F7",
|
||||
", c #FFEFEF",
|
||||
"' c #F7F2F5",
|
||||
") c #F7FAFD",
|
||||
"! c #FF5757",
|
||||
"~ c #FFDFDF",
|
||||
"{ c #FF4F4F",
|
||||
"] c #FFD7D7",
|
||||
"^ c #FF4747",
|
||||
"/ c #FF3F3F",
|
||||
"( c #8D8D8D",
|
||||
"_ c #EEE6E6",
|
||||
": c #EED6D6",
|
||||
"< c #EECECE",
|
||||
"[ c #FAFAFA",
|
||||
"} c #F2F2F2",
|
||||
"| c #F6F6F6",
|
||||
"1 c #A2A2A2",
|
||||
"2 c #FAF2F2",
|
||||
" .++@ @++. ",
|
||||
" @@@##$$$$$$$$$$$$##@@@ ",
|
||||
" .++$#$$$$$$$$$$$$#$++. ",
|
||||
" .++@+%%&**&&**&%%+@++. ",
|
||||
" @@@@%==-;;--;;-==%@@@@ ",
|
||||
" .++.%==-;;--;;-==%.++. ",
|
||||
" .++.%>,'--))--',>%.++. ",
|
||||
" @@@@%,!~>====>~!,%@@@@ ",
|
||||
" .++.%>~{]~~~~]{~>%.++. ",
|
||||
" .++.%=>~^////^~>=%.++. ",
|
||||
" @@@(+%%_:<<<<:_%%+(@@@ ",
|
||||
" .++$#$$$$$$$$$$$$#$++. ",
|
||||
" .++$#$$$$$$$$$$$$#$++. ",
|
||||
" @@@(+%%&**&%%%%%%+(@@@ ",
|
||||
" .++.%==-;;-[}}[==%.++. ",
|
||||
" .++.%==-;;-|11|==%.++. ",
|
||||
" @@@@%>,'--)[}}2,>%@@@@ ",
|
||||
" .++.%,!~>====>~!,%.++. ",
|
||||
" .++.%>~{]~~~~]{~>%.++. ",
|
||||
" @@@@%=>~^////^~>=%@@@@ ",
|
||||
" .++@+%%_:<<<<:_%%+@++. ",
|
||||
" .++$#$$$$$$$$$$$$#$++. ",
|
||||
" @@@##$$$$$$$$$$$$##@@@ ",
|
||||
" .++@ @++. "};
|
||||
373
components/gifview/LICENSE.txt
Normal file
373
components/gifview/LICENSE.txt
Normal file
|
|
@ -0,0 +1,373 @@
|
|||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
||||
15
components/gifview/README.txt
Normal file
15
components/gifview/README.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
GifView
|
||||
|
||||
Animated GIF Viewer Component
|
||||
|
||||
Copyright (C) 2025 Alexander Koblov
|
||||
|
||||
License:
|
||||
MPL 2.0
|
||||
|
||||
Based on:
|
||||
TGIFViewer
|
||||
https://github.com/jdelauney/TGIFViewer
|
||||
|
||||
Original author:
|
||||
Copyright (C) 2018 J.Delauney (BeanzMaster)
|
||||
56
components/gifview/gifview.lpk
Normal file
56
components/gifview/gifview.lpk
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<Package Version="5">
|
||||
<PathDelim Value="\"/>
|
||||
<Name Value="GifView"/>
|
||||
<Type Value="RunAndDesignTime"/>
|
||||
<Author Value="Jérôme Delauney (BeanzMaster), Alexander Koblov"/>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<SearchPaths>
|
||||
<OtherUnitFiles Value="source"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<DebugInfoType Value="dsDwarf2Set"/>
|
||||
</Debugging>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
<Description Value="GIF Viewer"/>
|
||||
<License Value="MPL-2.0"/>
|
||||
<Version Major="1"/>
|
||||
<Files>
|
||||
<Item>
|
||||
<Filename Value="source\GifViewerStrConsts.pas"/>
|
||||
<UnitName Value="GifViewerStrConsts"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Filename Value="source\uFastBitmap.pas"/>
|
||||
<UnitName Value="uFastBitmap"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Filename Value="source\uGifViewer.pas"/>
|
||||
<HasRegisterProc Value="True"/>
|
||||
<UnitName Value="uGifViewer"/>
|
||||
</Item>
|
||||
</Files>
|
||||
<RequiredPkgs>
|
||||
<Item>
|
||||
<PackageName Value="LCL"/>
|
||||
<MinVersion Major="2" Minor="2" Valid="True"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<PackageName Value="FCL"/>
|
||||
</Item>
|
||||
</RequiredPkgs>
|
||||
<UsageOptions>
|
||||
<UnitPath Value="$(PkgOutDir)"/>
|
||||
</UsageOptions>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
<UseFileFilters Value="True"/>
|
||||
</PublishOptions>
|
||||
</Package>
|
||||
</CONFIG>
|
||||
22
components/gifview/gifview.pas
Normal file
22
components/gifview/gifview.pas
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{ This file was automatically created by Lazarus. Do not edit!
|
||||
This source is only used to compile and install the package.
|
||||
}
|
||||
|
||||
unit GifView;
|
||||
|
||||
{$warn 5023 off : no warning about unused units}
|
||||
interface
|
||||
|
||||
uses
|
||||
GifViewerStrConsts, uFastBitmap, uGifViewer, LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterUnit('uGifViewer', @uGifViewer.Register);
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterPackage('GifView', @Register);
|
||||
end.
|
||||
BIN
components/gifview/gifview.res
Normal file
BIN
components/gifview/gifview.res
Normal file
Binary file not shown.
36
components/gifview/source/GifViewerStrConsts.pas
Normal file
36
components/gifview/source/GifViewerStrConsts.pas
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
Unit GifViewerStrConsts;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
Interface
|
||||
|
||||
ResourceString
|
||||
// Messages d'erreurs ou de notifications
|
||||
// Error or notification messages
|
||||
//uGifViewer
|
||||
rsScreenBadColorSize = 'Invalid number of colors in the global palette.';
|
||||
rsImageBadColorSize = 'Number of colors is invalid in local palette.';
|
||||
rsBadSignature = 'GIF invalid signature: %s';
|
||||
rsBadScreenSize = 'Invalid image size: %dx%d';
|
||||
rsEmptyColorMap = 'Error no palette of color available for this image!';
|
||||
rsEmptyImage = 'The picture is empty';
|
||||
rsUnknownVersion = 'Unknown GIF version';
|
||||
rsFileNotFound = 'The file %s not found !';
|
||||
rsResourceNotFound = 'Resource %s not found!';
|
||||
rsBufferOverFlow = 'Image #%d: The decoder has been stopped to prevent a buffer overflow';
|
||||
rsInvalidOutputBufferSize = 'Image #%d: The size of the output buffer is invalid (size < = 0)';
|
||||
rsInvalidInputBufferSize = 'Image #%d: The size of the input buffer is invalid (size < = 0)';
|
||||
rsInvalidBufferSize = 'Image #%d: The size of the input and output buffer are invalid (size < = 0)';
|
||||
rsLZWInternalErrorOutputBufferOverflow = 'Output buffer overflow in the GIF LZW decoder buffer. Report this bug. This is a serious bug!';
|
||||
rsLZWInternalErrorInputBufferOverflow = 'Input buffer overflow in the GIF LZW decoder. Report this bug. This is a serious bug!';
|
||||
rsLZWInvalidInput = 'Image #%d: The decoder encountered an invalid entry (corrupted data)';
|
||||
rsLZWOutputBufferTooSmall = 'Image #%d: The decoder could not decode all the data because the output buffer is too small';
|
||||
rsAllFrameCorrupted = 'All images in the GIF are corrupted. Unable to display GIF file.';
|
||||
//uFastBitmap
|
||||
rsBitmapCreateError = 'An Error occured while creating TBitmap';
|
||||
rsBitmapScanlineOutOfRange = 'Scanline : Index Out of range';
|
||||
|
||||
Implementation
|
||||
|
||||
End.
|
||||
|
||||
1048
components/gifview/source/uFastBitmap.pas
Normal file
1048
components/gifview/source/uFastBitmap.pas
Normal file
File diff suppressed because it is too large
Load diff
2785
components/gifview/source/uGifViewer.pas
Normal file
2785
components/gifview/source/uGifViewer.pas
Normal file
File diff suppressed because it is too large
Load diff
BIN
components/gifview/tgifview.png
Normal file
BIN
components/gifview/tgifview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 975 B |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue