Compare commits
830 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
187d1473a2 | ||
|
|
db47ff6d83 | ||
|
|
f0f08e6b8c | ||
|
|
bcdd375241 | ||
|
|
ec0de7416d | ||
|
|
b7d12a3b5d | ||
|
|
49f67723e2 | ||
|
|
40d785bf0f | ||
|
|
37bd3f1ed6 | ||
|
|
082635c63f | ||
|
|
3d7c4206d1 | ||
|
|
8959c57708 | ||
|
|
eac3191766 | ||
|
|
473a550a03 | ||
|
|
0b803ae534 |
||
|
|
8f007810dc | ||
|
|
c1df50e370 | ||
|
|
8dd479eab0 | ||
|
|
3f2fcb350a | ||
|
|
43c39e03be | ||
|
|
7cc14a7a04 | ||
|
|
e4c9a87eef | ||
|
|
2c9db300ee | ||
|
|
64dbf811b3 | ||
|
|
78ba4aef4b | ||
|
|
c97770d6f4 | ||
|
|
ae24245ef6 | ||
|
|
1d2497b1b1 | ||
|
|
2e10385436 | ||
|
|
c9563cf5ed | ||
|
|
b4b2d9a36c | ||
|
|
24fb6d6065 | ||
|
|
76935aa7b2 | ||
|
|
948801b5a6 | ||
|
|
24114a9ddf | ||
|
|
81c1432816 | ||
|
|
eda51ead20 | ||
|
|
0201c82dc7 | ||
|
|
5943e8f889 | ||
|
|
fa56c3ba55 | ||
|
|
9a5ba4d7d7 | ||
|
|
43e8984b4c | ||
|
|
6776fac0e4 | ||
|
|
b204fbb617 | ||
|
|
2b0c1bef2e | ||
|
|
4418184107 | ||
|
|
aa16eef676 | ||
|
|
1c1be9e27e | ||
|
|
809b11db4b | ||
|
|
b83b18d720 | ||
|
|
18bd640b80 | ||
|
|
896b62f3c1 | ||
|
|
85d16bc730 | ||
|
|
9bc17f78f0 | ||
|
|
67a0b57bfa | ||
|
|
5f59896293 | ||
|
|
c1ff328019 | ||
|
|
e535431caf | ||
|
|
f65c10ad49 | ||
|
|
45bf76b7e2 | ||
|
|
c3c28365b9 | ||
|
|
3190c43eb4 | ||
|
|
87de6bfa1f | ||
|
|
feccc5649e | ||
|
|
8dd6716a9c | ||
|
|
480d73822c | ||
|
|
876aafca57 | ||
|
|
47143e0f1c | ||
|
|
4ed0c7336f | ||
|
|
a7bd1e19c4 | ||
|
|
eaf180ff48 | ||
|
|
f7a3e44e59 | ||
|
|
8ec76d59a7 | ||
|
|
b8fc7d03bb | ||
|
|
89ab760574 | ||
|
|
1bb8f0f1cf | ||
|
|
624dbdb243 | ||
|
|
fd6243c053 | ||
|
|
be6bca9465 | ||
|
|
29de7d6e01 | ||
|
|
3fed40edda | ||
|
|
117d8bbf75 | ||
|
|
caee75995c | ||
|
|
f2634f4d10 | ||
|
|
ea1ed2aba3 | ||
|
|
09cd3790c1 | ||
|
|
882800c88b | ||
|
|
699c605d19 | ||
|
|
d346429a1f | ||
|
|
88e0d9d47a | ||
|
|
fa716899e1 | ||
|
|
61673c1aa1 | ||
|
|
3e0bcbda9f | ||
|
|
9fbea677f6 | ||
|
|
3e2f2f76d4 | ||
|
|
ed21f6dead | ||
|
|
e5e32a8e58 | ||
|
|
07eea5f9d0 | ||
|
|
c731030d25 | ||
|
|
63057a3fac | ||
|
|
91fb4f59d2 | ||
|
|
190999dd92 | ||
|
|
afc98ed4a5 | ||
|
|
91cab20d38 | ||
|
|
ad1f683101 | ||
|
|
3625bc7a4d | ||
|
|
b2695c0d3d | ||
|
|
f8d7513354 | ||
|
|
e73b33791b | ||
|
|
5b42d8637c | ||
|
|
2ccb72ab65 | ||
|
|
727d583037 | ||
|
|
70f6884531 | ||
|
|
42d61877fc | ||
|
|
e9387a3c70 | ||
|
|
2b5adfb10e | ||
|
|
51b94c0954 | ||
|
|
37b44f0ed8 | ||
|
|
73cb90e63c | ||
|
|
415d587bb0 | ||
|
|
ef0c2b68f2 | ||
|
|
3d546bcb45 | ||
|
|
dcaeb045a6 | ||
|
|
4f11eb7c64 | ||
|
|
e3c3453a42 | ||
|
|
f094c70a4a | ||
|
|
4d241dc120 | ||
|
|
9fabdb6e99 | ||
|
|
37167887c9 | ||
|
|
0ab13eca08 | ||
|
|
952f12f631 | ||
|
|
3e3ecc9432 | ||
|
|
3f46a0408a | ||
|
|
387457bf6e | ||
|
|
a9f808e6bc |
||
|
|
3adf7b07d1 | ||
|
|
15e166ecde | ||
|
|
9436bd15c6 | ||
|
|
9cee7263d1 | ||
|
|
8490889e7b | ||
|
|
808d1ef88d | ||
|
|
0ac62190c3 | ||
|
|
7e7f48d70e | ||
|
|
031cf26473 | ||
|
|
f88f810a2e | ||
|
|
4d57ae4caa | ||
|
|
d801cf8cda | ||
|
|
cc4fffc980 | ||
|
|
aa50acce68 | ||
|
|
3619468fcc | ||
|
|
db7f80e80d | ||
|
|
c22653fb50 | ||
|
|
72d249537c | ||
|
|
8a2b8f5e88 | ||
|
|
bd50861ef6 | ||
|
|
e9c1c8fbd6 | ||
|
|
cd27187ac4 | ||
|
|
035e47a3d7 | ||
|
|
1ce1606fda | ||
|
|
c8be36cef6 | ||
|
|
d9a6bba4cf | ||
|
|
52c0d620cc | ||
|
|
939dc5926d | ||
|
|
470ac231a2 | ||
|
|
8943848d1d | ||
|
|
00d46d50af | ||
|
|
e22bb3df89 | ||
|
|
f746d25109 | ||
|
|
6baafba866 | ||
|
|
4a0bcd0fa1 | ||
|
|
906ce2a6e6 | ||
|
|
677adc3cde | ||
|
|
7ea476cace | ||
|
|
e4b509073c | ||
|
|
5787eea73d | ||
|
|
748d20e1be | ||
|
|
1898608413 | ||
|
|
628dce73bf | ||
|
|
13a1173092 | ||
|
|
ece4fe1dd2 | ||
|
|
3a33650a89 | ||
|
|
2626a317f0 | ||
|
|
9a8e9f827e | ||
|
|
451c7afdf1 | ||
|
|
e31aab2f5e | ||
|
|
14aa2b6a7b | ||
|
|
6e56938dc1 | ||
|
|
3461456384 | ||
|
|
ba4d6b029a | ||
|
|
211973f489 | ||
|
|
ab816613d1 | ||
|
|
3845a75d3b | ||
|
|
90ad99a69f | ||
|
|
011028db4d | ||
|
|
a712e16765 | ||
|
|
f57d2e9cad | ||
|
|
45caf2da51 | ||
|
|
fd15280abd | ||
|
|
4f4a743d04 | ||
|
|
ed59afc8ba | ||
|
|
9c148b2223 | ||
|
|
ee18b23087 | ||
|
|
c7f8c9e5fb | ||
|
|
cbec6de865 | ||
|
|
b9a2874217 | ||
|
|
b1a1c07e95 | ||
|
|
9d29d5d10f | ||
|
|
014ac5a0a6 | ||
|
|
451517832e | ||
|
|
d35debe202 | ||
|
|
72cf1165e7 | ||
|
|
a10c06cec8 | ||
|
|
740d699f61 | ||
|
|
6eb3e31fec | ||
|
|
e6c959cbc5 | ||
|
|
0690552c92 | ||
|
|
56e640281c | ||
|
|
112631e160 | ||
|
|
6c7f86cd4d | ||
|
|
c8153f8d9f | ||
|
|
20c484a2cb | ||
|
|
ec3e2c130c | ||
|
|
7f56a8b1a9 | ||
|
|
d7d098956c | ||
|
|
dc1f91e6b3 | ||
|
|
99b76b3668 | ||
|
|
536fd18063 | ||
|
|
b306e9e36d | ||
|
|
d40d810712 | ||
|
|
4a9d2b841d | ||
|
|
069d583849 | ||
|
|
6755986dbe | ||
|
|
6f82d9ab2c | ||
|
|
067b4b1e2d | ||
|
|
27793f67d0 | ||
|
|
a461879e5b | ||
|
|
cc87ab6421 | ||
|
|
9f36d76df9 | ||
|
|
02383cc688 | ||
|
|
a0c6cbc964 | ||
|
|
b3a7e2b219 | ||
|
|
8cc5e80bd0 | ||
|
|
95ec7c4af1 | ||
|
|
f5702e6dbb | ||
|
|
9e048ac7e0 | ||
|
|
9dd31c2e92 | ||
|
|
0cdb3ca9d1 | ||
|
|
fbfbce839c | ||
|
|
445461bec1 | ||
|
|
3b63b5aa67 | ||
|
|
f02511c0b3 | ||
|
|
150af300ad | ||
|
|
128ff3f087 | ||
|
|
7bc216b8b1 | ||
|
|
0ab5113eca | ||
|
|
3006bed3ee | ||
|
|
71418abb86 | ||
|
|
b153f457af | ||
|
|
2afd36d602 | ||
|
|
d2a8eb26a0 | ||
|
|
9fd1e71a04 | ||
|
|
7ad816ff17 | ||
|
|
c45365d1bc | ||
|
|
d93942deab | ||
|
|
4474269032 | ||
|
|
413e1e8398 | ||
|
|
bba22702ab | ||
|
|
2301bc2081 | ||
|
|
1ee9f00fcc | ||
|
|
69bdf3c02f | ||
|
|
dfe6006ec8 | ||
|
|
7d895fb6aa | ||
|
|
515060f869 | ||
|
|
314edd30ef | ||
|
|
82e0f019a0 | ||
|
|
b6b1b81a5c | ||
|
|
25e13b3983 | ||
|
|
1ef959fa97 | ||
|
|
52fc67529f | ||
|
|
3699a78c45 | ||
|
|
49c9f167ac | ||
|
|
280cdc3888 | ||
|
|
f4189f2139 | ||
|
|
4149c05afc | ||
|
|
6da6ca3988 | ||
|
|
255fc9a8df | ||
|
|
29c68b758a | ||
|
|
58e1181977 | ||
|
|
edc41b641c | ||
|
|
c9ef3e431a | ||
|
|
07820a8afa | ||
|
|
ca4ccfdab5 | ||
|
|
7640357bca | ||
|
|
4c51c72d89 | ||
|
|
20cfa4e47f | ||
|
|
3a6be9bd44 | ||
|
|
7a02fcb1e9 | ||
|
|
5a42260fbd | ||
|
|
d4401c2923 | ||
|
|
e7420de849 | ||
|
|
40248df74c | ||
|
|
1e6d500c1e | ||
|
|
dfb20dc45f | ||
|
|
edf588ff5a | ||
|
|
5828d0beb6 | ||
|
|
627c926a29 | ||
|
|
e467765695 | ||
|
|
4ecba56cd5 | ||
|
|
890bd24569 | ||
|
|
f9842b44ff |
||
|
|
ca77fea987 | ||
|
|
b4bc7c2a03 | ||
|
|
0c882703d3 | ||
|
|
759ccd600b | ||
|
|
dd87909edf | ||
|
|
e3fb00b1e9 | ||
|
|
262e4b383e | ||
|
|
6f76129d06 | ||
|
|
638fa8a748 | ||
|
|
68107f6e08 | ||
|
|
bd6c8c30a3 | ||
|
|
52b5319f71 | ||
|
|
8a0c36d921 | ||
|
|
ecef381065 | ||
|
|
841e0a616f | ||
|
|
28125592ab | ||
|
|
089ab3cdb6 | ||
|
|
462a88c449 | ||
|
|
75f3da0160 | ||
|
|
83a7cb49c5 | ||
|
|
73e91c9bc7 | ||
|
|
5f8ddd0e6c | ||
|
|
fbf2075bf8 | ||
|
|
886d9ae8e0 | ||
|
|
a463109055 | ||
|
|
3df8697e4f | ||
|
|
9481c6e5f5 | ||
|
|
7aff6814fc | ||
|
|
4a6642f164 | ||
|
|
5255e44dc6 | ||
|
|
6f37a3006e | ||
|
|
584ee60dab | ||
|
|
22fb1a9332 | ||
|
|
3e81971ad3 | ||
|
|
192cb25519 | ||
|
|
3e89b9cb95 | ||
|
|
c536bfbd59 | ||
|
|
c7d4b68c39 | ||
|
|
cd1bbb9865 | ||
|
|
a44c245a54 | ||
|
|
2af1f8ee5d | ||
|
|
813564caf0 | ||
|
|
7b12fa4829 | ||
|
|
44259358c6 | ||
|
|
c4e8b2c348 | ||
|
|
b8f358ace5 | ||
|
|
de5434328a | ||
|
|
0190785784 | ||
|
|
94d94be158 | ||
|
|
263cea7c05 | ||
|
|
dea421f002 | ||
|
|
f4bda829bc | ||
|
|
edd44b0e23 | ||
|
|
330d51c101 | ||
|
|
f3ed1d8fc5 | ||
|
|
16df1c7991 | ||
|
|
5a05f2cd99 | ||
|
|
99ded957ee | ||
|
|
2574f7a3c5 | ||
|
|
ca05ac409d | ||
|
|
0546c64d13 | ||
|
|
276b9f8efa | ||
|
|
0272038b9f | ||
|
|
95936be701 | ||
|
|
70213c0093 | ||
|
|
9a08ba81a9 | ||
|
|
66a86a84e5 | ||
|
|
f60bf09df0 | ||
|
|
88342a221c | ||
|
|
0e02e9303c | ||
|
|
96553479d5 | ||
|
|
6e9c699241 | ||
|
|
b2c0cb52fb | ||
|
|
b965125939 | ||
|
|
a7742c4244 | ||
|
|
abc0420937 | ||
|
|
3d62f8d231 | ||
|
|
fdf48e393c | ||
|
|
204b057cc7 | ||
|
|
e14821b38a | ||
|
|
b8913f1255 | ||
|
|
5b4ddcc205 | ||
|
|
aedb718da4 | ||
|
|
79078c40cb | ||
|
|
c8f17e36ad | ||
|
|
bf406ee4cb | ||
|
|
c9992a5121 | ||
|
|
f7cd88e6c1 | ||
|
|
cb8966982d | ||
|
|
f9a283d679 | ||
|
|
1f23c8b262 | ||
|
|
1653e8f21e | ||
|
|
cc107d22e3 | ||
|
|
84d34b7fd2 | ||
|
|
aef3ff3313 | ||
|
|
4645960a6d | ||
|
|
12c6d6c2d6 | ||
|
|
31d80d21bd | ||
|
|
0590197436 | ||
|
|
b253677450 | ||
|
|
5da5e933f7 | ||
|
|
095fb36268 | ||
|
|
9b62526af6 | ||
|
|
9a86b1ce8d | ||
|
|
26d8defe26 | ||
|
|
c5de90352a | ||
|
|
156d29cf21 | ||
|
|
dcebbd4c56 | ||
|
|
bd0f5c6977 | ||
|
|
a98bd40888 | ||
|
|
f1b449635a | ||
|
|
077c302f63 | ||
|
|
f40c015742 | ||
|
|
8981951a4c | ||
|
|
eef27754c1 | ||
|
|
82e221789e | ||
|
|
e533e99c7e | ||
|
|
91242096be | ||
|
|
7ecec58a13 | ||
|
|
03d9f4f164 | ||
|
|
9a21789d6b | ||
|
|
9773366d80 | ||
|
|
fc7f57ff44 | ||
|
|
4842b42062 | ||
|
|
c2ecdd7f94 | ||
|
|
0a0f5f2db4 | ||
|
|
fe8ea81cfb | ||
|
|
6488d977db | ||
|
|
4079e78672 | ||
|
|
42b75f6ba9 | ||
|
|
8c74d9663c | ||
|
|
032f04c608 | ||
|
|
7603933357 | ||
|
|
a1e12af803 | ||
|
|
e283775b4b | ||
|
|
e7946aa7e2 | ||
|
|
2775d4a540 | ||
|
|
1de81d1a84 | ||
|
|
a8cac649ba | ||
|
|
48ac4f71b1 | ||
|
|
7f090a336d | ||
|
|
ec9ed11434 | ||
|
|
e4a6afac75 | ||
|
|
4f156be5f5 | ||
|
|
bf76809072 | ||
|
|
d62a137163 | ||
|
|
7cbd68596f | ||
|
|
601d4a0360 | ||
|
|
32223720b3 | ||
|
|
c61ad5d17c | ||
|
|
c7bc5e6392 | ||
|
|
4e2506d9f2 | ||
|
|
5f6d47f553 | ||
|
|
b31288a41c | ||
|
|
3e6578f18e | ||
|
|
39e5f39db5 | ||
|
|
73e31f077f | ||
|
|
e7e8c8e8b9 | ||
|
|
2ee0f3ed3f | ||
|
|
9da33c5584 | ||
|
|
800c23efc9 | ||
|
|
8f0784e66b | ||
|
|
b17e1e48db | ||
|
|
1e6eea881c | ||
|
|
08ba5ea10f | ||
|
|
5f09025088 | ||
|
|
15e259ba8e | ||
|
|
818c3b265e | ||
|
|
6ce6e68f24 | ||
|
|
aa8a3a3a14 | ||
|
|
b220a50e90 | ||
|
|
09f4c297df | ||
|
|
35ce4cd34b | ||
|
|
bbe1f5bf1a | ||
|
|
6ac1a6a7b4 | ||
|
|
bf042bc801 | ||
|
|
1e6f11e3e7 | ||
|
|
5c1e40c192 | ||
|
|
4b8c0e59bc | ||
|
|
12dd546b6b | ||
|
|
1c8b8fe621 | ||
|
|
5d0fa8a131 | ||
|
|
0a7500ff39 | ||
|
|
51ab93793b | ||
|
|
e8144cb246 | ||
|
|
f0dcb021b7 | ||
|
|
e8c11b02ba | ||
|
|
ad729a82d8 | ||
|
|
0536d0d06a | ||
|
|
7b566eb9ec | ||
|
|
1bfdd8cdd4 | ||
|
|
76de6aaf39 | ||
|
|
48d6a1a523 | ||
|
|
fad1987fe5 | ||
|
|
e3021f1c6b | ||
|
|
66bf11065d | ||
|
|
fd8f5f992a | ||
|
|
632033894f | ||
|
|
d6e525eb9a | ||
|
|
ec364da854 | ||
|
|
a20182fff3 | ||
|
|
bf4bad95e3 | ||
|
|
018d03a567 | ||
|
|
10c57d25a8 | ||
|
|
fe4d1e8d96 | ||
|
|
c881784433 | ||
|
|
55ed9ca3f6 | ||
|
|
747365517f | ||
|
|
845106bd1a | ||
|
|
e432281c1a | ||
|
|
fb8726ac63 | ||
|
|
ba535a8ef1 | ||
|
|
78966ff478 | ||
|
|
90ba808094 | ||
|
|
b8ad32cc99 | ||
|
|
fbee0afef7 | ||
|
|
b68c76cca9 | ||
|
|
36e704d3ab | ||
|
|
f57be5f9b0 | ||
|
|
b9d422290e | ||
|
|
38df7d82ff | ||
|
|
b4471e8faa | ||
|
|
6563415480 | ||
|
|
b2834e9ce4 | ||
|
|
dd0355fa32 | ||
|
|
111d56ae05 | ||
|
|
d9c871bfce | ||
|
|
d877eee7ba | ||
|
|
43b758e0d6 | ||
|
|
9b7a9bd6c1 | ||
|
|
81602d4397 | ||
|
|
73fa8d8222 | ||
|
|
48f2e4345e | ||
|
|
abdb9287df | ||
|
|
c4d664491a | ||
|
|
8093eeb80e | ||
|
|
c9a52a055c | ||
|
|
0a2887a432 | ||
|
|
4ced4d39af | ||
|
|
8c818e011d | ||
|
|
1b49f5f908 | ||
|
|
2a58e889f5 | ||
|
|
10273b2846 | ||
|
|
e51b372dcd | ||
|
|
db067eb4c2 | ||
|
|
082d70068f | ||
|
|
59ded13694 | ||
|
|
6ef8186da4 | ||
|
|
7a836aae8f | ||
|
|
fb6c4a1885 | ||
|
|
c61442c5d2 | ||
|
|
b2ede1eead | ||
|
|
926d30e419 | ||
|
|
6414fcb117 | ||
|
|
a73d367232 | ||
|
|
09e8e8864e | ||
|
|
bc533a396e | ||
|
|
97f52a1811 | ||
|
|
482f1afcf4 | ||
|
|
a5a63ddd23 | ||
|
|
950623ee14 | ||
|
|
6f1089dc44 | ||
|
|
af48eb9d23 | ||
|
|
7bce92da3d | ||
|
|
97e51c6310 | ||
|
|
43cc2f4a7e | ||
|
|
16458d7759 | ||
|
|
23c3a1954d | ||
|
|
d3ec32c29a | ||
|
|
5c3d354b26 | ||
|
|
ce59083c33 | ||
|
|
ae0e59a086 | ||
|
|
cc6d9cba90 | ||
|
|
b308422c3d | ||
|
|
04631774e6 | ||
|
|
9923850740 | ||
|
|
c34c65071e | ||
|
|
a967433325 | ||
|
|
06e3ba0a51 | ||
|
|
8b7f395d12 | ||
|
|
1ff352cddc | ||
|
|
48b5b3be1e | ||
|
|
50daef684a | ||
|
|
a10531d22b | ||
|
|
b7dac1002b | ||
|
|
ab6c5c9316 | ||
|
|
921642f87e | ||
|
|
f50aa634d5 | ||
|
|
e56ad29b25 | ||
|
|
e2ccf2050a | ||
|
|
2af29ac19f | ||
|
|
084bd85028 | ||
|
|
41ea61700e | ||
|
|
738927696a | ||
|
|
8908718f4a | ||
|
|
9404bdadfa | ||
|
|
c2c5bf8f9e | ||
|
|
b6fc98502b | ||
|
|
3fab2dd143 | ||
|
|
a54b75b645 | ||
|
|
9ac0c294d5 | ||
|
|
e883d012ec | ||
|
|
21c272791e | ||
|
|
5788897cf8 | ||
|
|
bcf551cf8c | ||
|
|
3fafe5b1b8 | ||
|
|
30034a9f2f | ||
|
|
75e4adfe4b | ||
|
|
e842f45848 | ||
|
|
cf93e68e7d | ||
|
|
e455cbcd8b | ||
|
|
ae9e34966b | ||
|
|
fd263edcbc | ||
|
|
92925e7a91 | ||
|
|
24d68afdb0 | ||
|
|
abdd776d09 | ||
|
|
375f06d6e5 | ||
|
|
6a34f7a7c1 | ||
|
|
db7b0943b5 | ||
|
|
5cae5f0095 | ||
|
|
8f786a3014 | ||
|
|
3863add31f | ||
|
|
a243cdb9ea | ||
|
|
4b5159b623 | ||
|
|
44cda40bca | ||
|
|
e35531fa70 | ||
|
|
279b61f319 | ||
|
|
4282f79438 | ||
|
|
05dce82be8 | ||
|
|
f0f8b4db52 | ||
|
|
66e6fe0c52 | ||
|
|
27170363eb | ||
|
|
08eac5ed3e | ||
|
|
bc7922e316 | ||
|
|
7ede5ef61a | ||
|
|
9a561b817a | ||
|
|
179e1a772d | ||
|
|
a2500df30c | ||
|
|
260e32a463 | ||
|
|
ff5dfd9c6e | ||
|
|
c698c9e8af | ||
|
|
96fcdc230c | ||
|
|
a2275e6f4e | ||
|
|
82e5c684c3 | ||
|
|
df6468de31 | ||
|
|
67d3976033 | ||
|
|
d3e8389906 | ||
|
|
445c2dcb63 | ||
|
|
943aa711a4 | ||
|
|
3b5ae2cb6e | ||
|
|
cd5f1e6eae | ||
|
|
31106e17b7 | ||
|
|
32d4f4ed89 | ||
|
|
0f42887fb0 | ||
|
|
8a1ecf8977 | ||
|
|
f6d38274f2 | ||
|
|
3f0782ca13 | ||
|
|
12b307ffda | ||
|
|
56ac6a262b | ||
|
|
11b7f9da8c | ||
|
|
4aee194e60 | ||
|
|
f96767c13d | ||
|
|
5436c7c574 | ||
|
|
d6a15d3d97 | ||
|
|
71bcaef302 | ||
|
|
165939d321 | ||
|
|
fd9fcea432 | ||
|
|
65d0771280 | ||
|
|
1b3e7a3a24 | ||
|
|
f5c9990b41 | ||
|
|
1be8fa91ee | ||
|
|
d574b5f645 | ||
|
|
03a57f9d94 | ||
|
|
4d84797068 | ||
|
|
f2093a2f2e | ||
|
|
d7f8c6b591 | ||
|
|
00d9dd1276 | ||
|
|
e9244cb69d | ||
|
|
37d1545caf | ||
|
|
e9b034e6f9 | ||
|
|
b06a88af11 | ||
|
|
58352c086e | ||
|
|
c1be2667ae | ||
|
|
8d856435e2 | ||
|
|
d44cf5fe6f | ||
|
|
290927c678 | ||
|
|
3ecc9093bf | ||
|
|
0032175085 | ||
|
|
c379b11318 | ||
|
|
ed95fded50 | ||
|
|
a60f725102 | ||
|
|
2ecbdcd461 | ||
|
|
4514a60d05 | ||
|
|
4a869bd9c6 | ||
|
|
c9d90d1886 | ||
|
|
b38dc095a7 | ||
|
|
e0ce4968bb | ||
|
|
27e787b5f5 | ||
|
|
7a7b14efcd | ||
|
|
3706ea6270 | ||
|
|
388f138d39 | ||
|
|
21ce5665a3 | ||
|
|
fed9e1c15f | ||
|
|
0a5c9328a0 | ||
|
|
b323b32a2b | ||
|
|
e3664c5749 | ||
|
|
30e00f53f8 | ||
|
|
66130edd29 | ||
|
|
d8570ffdc9 | ||
|
|
68377921cb | ||
|
|
5713aca956 | ||
|
|
9e003612d1 | ||
|
|
5285b736d1 | ||
|
|
99c7620893 | ||
|
|
7cea2fedab | ||
|
|
0750dc3264 | ||
|
|
28507aedda | ||
|
|
455d1ba7ed | ||
|
|
febf51a6d6 | ||
|
|
fafe1f2c68 | ||
|
|
42dfbf5448 | ||
|
|
8245d4acda | ||
|
|
8c74dcac10 | ||
|
|
5f6ca4483f | ||
|
|
dbdb689e61 | ||
|
|
a1855fc64a | ||
|
|
5021ef9c93 | ||
|
|
1adf973bd5 | ||
|
|
91d0e7cb0b | ||
|
|
eecd70c65d | ||
|
|
49a823e14b | ||
|
|
798d8462cd | ||
|
|
5919c7166e | ||
|
|
86798ee994 | ||
|
|
7b71f4987b | ||
|
|
4aeca13849 | ||
|
|
50ba015731 | ||
|
|
7413aaf165 | ||
|
|
ac22480c70 | ||
|
|
b254347e0b | ||
|
|
21712753bc | ||
|
|
c16b13da6b | ||
|
|
726b2d2fc4 | ||
|
|
52fce9fba7 | ||
|
|
3c12d81209 | ||
|
|
66fd3a4cd4 | ||
|
|
6215d2fa93 | ||
|
|
961efff810 | ||
|
|
33d8e86db3 | ||
|
|
1c46399683 | ||
|
|
da09d79d01 | ||
|
|
a89cc3f4ca | ||
|
|
31485c58b9 | ||
|
|
035cbb3de6 | ||
|
|
8eeb289dbf | ||
|
|
ea1d13dd3a | ||
|
|
6729ec2110 | ||
|
|
b31ec41399 | ||
|
|
374ecc52a2 | ||
|
|
3ac33017e4 | ||
|
|
abd7777534 | ||
|
|
e53426d0a4 | ||
|
|
bde8179846 | ||
|
|
4a9b928ba8 | ||
|
|
8fbc6674c3 | ||
|
|
a3987d19f4 | ||
|
|
ae331340e7 | ||
|
|
4aa3cb8ac9 | ||
|
|
62bc2c83d2 | ||
|
|
98a22aa105 | ||
|
|
2cad7cd392 | ||
|
|
fbdf8e6938 | ||
|
|
859c7b066d | ||
|
|
006094bb5c | ||
|
|
04939dd462 | ||
|
|
e94ffc6a4e | ||
|
|
c34b4dfcf2 | ||
|
|
a5264b7359 | ||
|
|
8108426140 | ||
|
|
f8a38d9c97 | ||
|
|
1e13f7eacc | ||
|
|
b17255bc35 | ||
|
|
fb2c5af2d1 | ||
|
|
5dfb093472 | ||
|
|
b1838ee2db | ||
|
|
6e6fad1cc9 | ||
|
|
de3a635623 | ||
|
|
6cae0e6390 | ||
|
|
cd3a69c655 | ||
|
|
d5023b37eb | ||
|
|
246c9081ee | ||
|
|
69bede7aae | ||
|
|
3a3e8b02ed | ||
|
|
b4e4df8810 | ||
|
|
533ecbdfae | ||
|
|
cf87f52512 | ||
|
|
cdebe99bb6 | ||
|
|
5b87675ab1 | ||
|
|
838729b99e | ||
|
|
5725538ee8 | ||
|
|
5983b651b6 | ||
|
|
b3248c39db | ||
|
|
70c96226be | ||
|
|
96b0f50302 | ||
|
|
f9fbdedb82 | ||
|
|
ebd3e94414 | ||
|
|
e78fe3df19 | ||
|
|
14417cce28 | ||
|
|
45d5de80ca | ||
|
|
722a421416 | ||
|
|
f49e7ec13e | ||
|
|
91e1263ece | ||
|
|
08f2c26f86 | ||
|
|
28ed87663c | ||
|
|
d3d4ddf1ec | ||
|
|
8475db364d | ||
|
|
24c42aabea | ||
|
|
c3252c7884 | ||
|
|
3a14e07f6f | ||
|
|
9aff9d9346 |
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
|
||||
17
.github/scripts/create_snapshot.sh
vendored
|
|
@ -19,6 +19,7 @@ export lcl=cocoa
|
|||
defaults write $(pwd)/doublecmd.app/Contents/Info CFBundleVersion $DC_REVISION
|
||||
defaults write $(pwd)/doublecmd.app/Contents/Info CFBundleShortVersionString $DC_VER
|
||||
plutil -convert xml1 $(pwd)/doublecmd.app/Contents/Info.plist
|
||||
chmod 644 $(pwd)/doublecmd.app/Contents/Info.plist
|
||||
|
||||
build_doublecmd()
|
||||
{
|
||||
|
|
@ -31,9 +32,23 @@ build_doublecmd()
|
|||
pushd $BUILD_PACK_DIR
|
||||
mv doublecmd.app 'Double Commander.app'
|
||||
codesign --deep --force --verify --verbose --sign '-' 'Double Commander.app'
|
||||
hdiutil create -anyowners -volname "Double Commander" -imagekey zlib-level=9 -format UDZO -fs HFS+ -srcfolder 'Double Commander.app' $PACK_DIR/doublecmd-$DC_VER-$DC_REVISION.$lcl.$CPU_TARGET.dmg
|
||||
popd
|
||||
|
||||
install/darwin/create-dmg/create-dmg \
|
||||
--volname "Double Commander" \
|
||||
--volicon "$BUILD_PACK_DIR/.VolumeIcon.icns" \
|
||||
--background "$BUILD_PACK_DIR/.background/bg.jpg" \
|
||||
--window-pos 200 200 \
|
||||
--window-size 680 366 \
|
||||
--text-size 16 \
|
||||
--icon-size 128 \
|
||||
--icon "Double Commander.app" 110 120 \
|
||||
--app-drop-link 360 120 \
|
||||
--icon "install.txt" 566 123 \
|
||||
--icon ".background" 100 500 \
|
||||
"$PACK_DIR/doublecmd-$DC_VER-$DC_REVISION.$lcl.$CPU_TARGET.dmg" \
|
||||
"$BUILD_PACK_DIR/"
|
||||
|
||||
# Clean DC build dir
|
||||
./clean.sh
|
||||
rm -rf $BUILD_PACK_DIR
|
||||
|
|
|
|||
58
.github/workflows/release.yml
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
name: build-release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [prereleased, released]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-mac:
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- name: Install Free Pascal
|
||||
uses: doublecmd/lazarus-install@mac
|
||||
with:
|
||||
lazarus-version: "stable"
|
||||
|
||||
- name: Get Lazarus source
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'fpc/Lazarus'
|
||||
ref: 'fixes_4'
|
||||
|
||||
- name: Build and install Lazarus
|
||||
run: |
|
||||
make all
|
||||
sudo make install
|
||||
|
||||
- name: Create Lazarus config
|
||||
run: |
|
||||
sudo mkdir -p /etc/lazarus
|
||||
sudo cp tools/install/macosx/environmentoptions.xml /etc/lazarus/environmentoptions.xml
|
||||
sudo sed -i -e "s|_PPCARCH_|fpc|g; s|/Developer/lazarus|/usr/local/share/lazarus|g" /etc/lazarus/environmentoptions.xml
|
||||
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download unrar source code
|
||||
run: wget https://www.rarlab.com/rar/unrarsrc-7.0.9.tar.gz -O /tmp/unrarsrc.tar.gz
|
||||
|
||||
- name: Extract unrar source code
|
||||
run: cd /tmp && tar xzf unrarsrc.tar.gz
|
||||
|
||||
- name: Build packages
|
||||
run: ./.github/scripts/create_release.sh
|
||||
|
||||
- name: Upload binaries to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
file: doublecmd-release/doublecmd*.dmg
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
||||
file_glob: true
|
||||
12
.github/workflows/snapshots.yml
vendored
|
|
@ -1,14 +1,10 @@
|
|||
name: build-snapshot
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'components/**'
|
||||
- 'plugins/**'
|
||||
- 'sdk/**'
|
||||
- 'src/**'
|
||||
release:
|
||||
types: [unpublished]
|
||||
branches:
|
||||
- master
|
||||
- v1.1.x
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}
|
||||
|
|
@ -58,7 +54,7 @@ jobs:
|
|||
- name: Install Lazarus
|
||||
uses: alexx2000/setup-fpc@win
|
||||
with:
|
||||
lazarus-version: "2.2.6"
|
||||
lazarus-version: "stable"
|
||||
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v2
|
||||
|
|
|
|||
2
.github/workflows/winget.yml
vendored
|
|
@ -9,5 +9,5 @@ jobs:
|
|||
- uses: vedantmgoyal2009/winget-releaser@v2
|
||||
with:
|
||||
identifier: alexx2000.DoubleCommander
|
||||
installers-regex: '.(exe|msi)$'
|
||||
installers-regex: '\.msi$'
|
||||
token: ${{ secrets.WINGET_TOKEN }}
|
||||
|
|
|
|||
|
|
@ -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,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
4259
components/Image32/source/Clipper2/Clipper.Engine.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
1247
components/Image32/source/Clipper2/Clipper.RectClip.pas
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
|
|
@ -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
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
-------------------------------------------------------------------------
|
||||
Custom edit control with the look and feel like TLabel
|
||||
|
||||
Copyright (C) 2017-2018 Alexander Koblov (alexx2000@mail.ru)
|
||||
Copyright (C) 2017-2024 Alexander Koblov (alexx2000@mail.ru)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
|
|
@ -58,6 +58,9 @@ type
|
|||
procedure SelectAll;
|
||||
procedure CopyToClipboard;
|
||||
published
|
||||
property Color default clDefault;
|
||||
property Cursor default crIBeam;
|
||||
property ReadOnly default True;
|
||||
property OnMouseDown;
|
||||
property OnMouseMove;
|
||||
property OnMouseUp;
|
||||
|
|
@ -104,12 +107,7 @@ end;
|
|||
procedure TKASCDDrawer.DrawEditBackground(ADest: TCanvas; ADestPos: TPoint;
|
||||
ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx);
|
||||
begin
|
||||
// The background
|
||||
ADest.Pen.Style := psSolid;
|
||||
ADest.Pen.Color := AStateEx.RGBColor;
|
||||
ADest.Brush.Style := bsSolid;
|
||||
ADest.Brush.Color := AStateEx.RGBColor;
|
||||
ADest.Rectangle(0, 0, ASize.cx, ASize.cy);
|
||||
// None
|
||||
end;
|
||||
|
||||
procedure TKASCDDrawer.DrawEdit(ADest: TCanvas; ASize: TSize;
|
||||
|
|
@ -122,10 +120,8 @@ var
|
|||
lTextLeftSpacing, lTextTopSpacing, lTextBottomSpacing: Integer;
|
||||
lTextColor: TColor;
|
||||
i, lVisibleLinesCount: Integer;
|
||||
AClipRect: TRect;
|
||||
begin
|
||||
// Background
|
||||
DrawEditBackground(ADest, Point(0, 0), ASize, AState, AStateEx);
|
||||
|
||||
// General text configurations which apply to all lines
|
||||
// Configure the text color
|
||||
if csfEnabled in AState then
|
||||
|
|
@ -168,10 +164,10 @@ begin
|
|||
// The text
|
||||
ADest.Pen.Style := psClear;
|
||||
ADest.Brush.Style := bsClear;
|
||||
lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lControlTextLen);
|
||||
// ToDo: Implement multi-line selection
|
||||
if (AStateEx.SelLength = 0) or (AStateEx.SelStart.Y <> AStateEx.VisibleTextStart.Y+i) then
|
||||
begin
|
||||
lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lControlTextLen);
|
||||
ADest.TextOut(lTextLeftSpacing, lLineTop, lVisibleText);
|
||||
end
|
||||
// Text and Selection
|
||||
|
|
@ -186,22 +182,18 @@ begin
|
|||
lSelLength := AStateEx.SelLength;
|
||||
if lSelLength < 0 then lSelLength := lSelLength * -1;
|
||||
|
||||
// Text right of the selection
|
||||
// Draw a normal text
|
||||
ADest.Font.Color := lTextColor;
|
||||
ADest.Brush.Color := AStateEx.RGBColor;
|
||||
lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lControlTextLen);
|
||||
ADest.TextOut(lTextLeftSpacing, lLineTop, lVisibleText);
|
||||
|
||||
// The selection text
|
||||
// Draw a selected text
|
||||
ADest.Brush.Color := clHighlight;
|
||||
ADest.Font.Color := clHighlightText;
|
||||
lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lSelLeftPos + lSelLength);
|
||||
ADest.TextOut(lTextLeftSpacing, lLineTop, lVisibleText);
|
||||
|
||||
// Text left of the selection
|
||||
ADest.Font.Color := lTextColor;
|
||||
ADest.Brush.Color := AStateEx.RGBColor;
|
||||
lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lSelLeftPos-AStateEx.VisibleTextStart.X + 1);
|
||||
// Calculate a clip rect
|
||||
AClipRect := ADest.ClipRect;
|
||||
AClipRect.Left := ADest.TextWidth(UTF8Copy(lVisibleText, 1, lSelLeftPos));
|
||||
AClipRect.Right := ADest.TextWidth(UTF8Copy(lVisibleText, 1, lSelLeftPos + lSelLength));
|
||||
IntersectClipRect(ADest.Handle, AClipRect.Left, AClipRect.Top, AClipRect.Right, AClipRect.Bottom);
|
||||
ADest.TextOut(lTextLeftSpacing, lLineTop, lVisibleText);
|
||||
end;
|
||||
end;
|
||||
|
|
@ -382,6 +374,10 @@ begin
|
|||
end;
|
||||
end;
|
||||
end;
|
||||
if ReadOnly and (Key in [VK_BACK, VK_DELETE]) then
|
||||
begin
|
||||
Key:= 0;
|
||||
end;
|
||||
inherited KeyDown(Key, Shift);
|
||||
end;
|
||||
|
||||
|
|
@ -389,10 +385,11 @@ constructor TKASCDEdit.Create(AOwner: TComponent);
|
|||
begin
|
||||
CreatePopupMenu;
|
||||
inherited Create(AOwner);
|
||||
Color:= clForm;
|
||||
ReadOnly:= True;
|
||||
Cursor:= crIBeam;
|
||||
Color:= clDefault;
|
||||
DrawStyle:= dsExtra1;
|
||||
ControlStyle:= ControlStyle + [csParentBackground] - [csOpaque];
|
||||
end;
|
||||
|
||||
procedure TKASCDEdit.MouseMove(Shift: TShiftState; X, Y: integer);
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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="9" Release="5"/>
|
||||
<Files Count="11">
|
||||
<Item1>
|
||||
<Filename Value="kastoolbar.pas"/>
|
||||
<HasRegisterProc Value="True"/>
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
<HasRegisterProc Value="True"/>
|
||||
<UnitName Value="KASButtonPanel"/>
|
||||
</Item10>
|
||||
<Item11>
|
||||
<Filename Value="kascomctrls.pas"/>
|
||||
<HasRegisterProc Value="True"/>
|
||||
<UnitName Value="KASComCtrls"/>
|
||||
</Item11>
|
||||
</Files>
|
||||
<CompatibilityMode Value="True"/>
|
||||
<RequiredPkgs Count="3">
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ interface
|
|||
uses
|
||||
KASToolBar, KASProgressBar, KASPathEdit, KASToolItems, KASComboBox,
|
||||
KASCDEdit, KASStatusBar, KASToolPanel, KASButton, KASButtonPanel,
|
||||
LazarusPackageIntf;
|
||||
KASComCtrls, LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
|
|
@ -25,6 +25,7 @@ begin
|
|||
RegisterUnit('KASToolPanel', @KASToolPanel.Register);
|
||||
RegisterUnit('KASButton', @KASButton.Register);
|
||||
RegisterUnit('KASButtonPanel', @KASButtonPanel.Register);
|
||||
RegisterUnit('KASComCtrls', @KASComCtrls.Register);
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ begin
|
|||
end;
|
||||
|
||||
procedure TKASPathEdit.AutoComplete(const Path: String);
|
||||
{$IF LCL_FULLVERSION >= 2020000}
|
||||
{$IF LCL_FULLVERSION < 4990000}
|
||||
const
|
||||
AFlags: array[Boolean] of TMaskOptions = (
|
||||
[moDisableSets], [moDisableSets, moCaseSensitive]
|
||||
|
|
@ -236,7 +236,7 @@ begin
|
|||
try
|
||||
// Check mask and make absolute file name
|
||||
AMask:= TMask.Create(ExtractFileName(Path) + '*',
|
||||
{$IF LCL_FULLVERSION >= 2020000}
|
||||
{$IF LCL_FULLVERSION < 4990000}
|
||||
AFlags[FileNameCaseSensitive]
|
||||
{$ELSE}
|
||||
FileNameCaseSensitive
|
||||
|
|
@ -367,8 +367,10 @@ end;
|
|||
procedure TKASPathEdit.TextChanged;
|
||||
begin
|
||||
Inherited;
|
||||
// TextChanged is called by user input, "if Modified" is not need
|
||||
if FAutoComplete then AutoComplete(Text);
|
||||
if not Modified then
|
||||
Exit;
|
||||
if FAutoComplete then
|
||||
AutoComplete(Text);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
-------------------------------------------------------------------------
|
||||
Toolbar panel class
|
||||
|
||||
Copyright (C) 2006-2019 Alexander Koblov (alexx2000@mail.ru)
|
||||
Copyright (C) 2006-2023 Alexander Koblov (alexx2000@mail.ru)
|
||||
|
||||
contributors:
|
||||
2012 Przemyslaw Nagay (cobines@gmail.com)
|
||||
|
|
@ -33,7 +33,7 @@ interface
|
|||
uses
|
||||
Classes, SysUtils, LResources, Forms, Controls, ComCtrls,
|
||||
Graphics, Dialogs, ExtCtrls, Buttons, FileUtil, Menus,
|
||||
DCXmlConfig, KASToolItems, LCLVersion;
|
||||
DCXmlConfig, KASToolItems, LCLVersion, LMessages;
|
||||
|
||||
type
|
||||
TOnToolButtonClick = procedure (Sender: TObject) of object;
|
||||
|
|
@ -64,6 +64,7 @@ type
|
|||
function DrawGlyph(ACanvas: TCanvas; const AClient: TRect; const AOffset: TPoint;
|
||||
AState: TButtonState; ATransparent: Boolean; BiDiFlags: Longint): TRect; override;
|
||||
procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
|
||||
procedure CMHintShow(var Message: TLMessage); message CM_HINTSHOW;
|
||||
public
|
||||
constructor Create(AOwner: TComponent; Item: TKASToolItem); reintroduce;
|
||||
destructor Destroy; override;
|
||||
|
|
@ -1089,6 +1090,17 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TKASToolButton.CMHintShow(var Message: TLMessage);
|
||||
begin
|
||||
if (ActionLink <> nil) and FToolItem.ActionHint then
|
||||
begin
|
||||
inherited CMHintShow(Message);
|
||||
end
|
||||
else begin
|
||||
DoOnShowHint(TCMHintShow(Message).HintInfo);
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TKASToolButton.Create(AOwner: TComponent; Item: TKASToolItem);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ type
|
|||
FAction: TBasicAction;
|
||||
property ToolOwner: IToolOwner read FToolOwner;
|
||||
public
|
||||
function ActionHint: Boolean; virtual;
|
||||
procedure Assign(OtherItem: TKASToolItem); virtual;
|
||||
function CheckExecute(ToolItemID: String): Boolean; virtual;
|
||||
function Clone: TKASToolItem; virtual; abstract;
|
||||
|
|
@ -94,6 +95,8 @@ type
|
|||
{ TKASNormalItem }
|
||||
|
||||
TKASNormalItem = class(TKASToolItem)
|
||||
private
|
||||
FShortcutsHint: Boolean;
|
||||
strict private
|
||||
FID: String; // Unique identificator of the button
|
||||
function GetID: String;
|
||||
|
|
@ -105,6 +108,7 @@ type
|
|||
Icon: String;
|
||||
Text: String;
|
||||
Hint: String;
|
||||
function ActionHint: Boolean; override;
|
||||
procedure Assign(OtherItem: TKASToolItem); override;
|
||||
function CheckExecute(ToolItemID: String): Boolean; override;
|
||||
function Clone: TKASToolItem; override;
|
||||
|
|
@ -183,6 +187,11 @@ uses
|
|||
|
||||
{ TKASToolItem }
|
||||
|
||||
function TKASToolItem.ActionHint: Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure TKASToolItem.Assign(OtherItem: TKASToolItem);
|
||||
begin
|
||||
FUserData := OtherItem.FUserData;
|
||||
|
|
@ -481,8 +490,10 @@ function TKASNormalItem.GetShortcutsHint: String;
|
|||
begin
|
||||
if Assigned(FToolOwner) then
|
||||
Result := FToolOwner.GetToolItemShortcutsHint(Self)
|
||||
else
|
||||
else begin
|
||||
Result := '';
|
||||
end;
|
||||
FShortcutsHint := (Length(Result) > 0);
|
||||
end;
|
||||
|
||||
procedure TKASNormalItem.Load(Config: TXmlConfig; Node: TXmlNode; Loader: TKASToolBarLoader);
|
||||
|
|
@ -525,6 +536,11 @@ begin
|
|||
Config.AddValueDef(Node, 'Text', Text, '');
|
||||
end;
|
||||
|
||||
function TKASNormalItem.ActionHint: Boolean;
|
||||
begin
|
||||
Result := not FShortcutsHint;
|
||||
end;
|
||||
|
||||
{ TKASToolBarItems }
|
||||
|
||||
constructor TKASToolBarItems.Create;
|
||||
|
|
|
|||
|
|
@ -8,11 +8,17 @@ uses
|
|||
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Toolwin;
|
||||
|
||||
type
|
||||
|
||||
{ TKASToolPanel }
|
||||
|
||||
TKASToolPanel = class(TToolWindow)
|
||||
public
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
published
|
||||
property Align default alNone;
|
||||
property Anchors;
|
||||
property AutoSize;
|
||||
property BorderSpacing;
|
||||
property ChildSizing;
|
||||
property EdgeBorders default [ebTop];
|
||||
property EdgeInner;
|
||||
|
|
@ -30,4 +36,12 @@ begin
|
|||
RegisterComponents('KASComponents',[TKASToolPanel]);
|
||||
end;
|
||||
|
||||
{ TKASToolPanel }
|
||||
|
||||
constructor TKASToolPanel.Create(TheOwner: TComponent);
|
||||
begin
|
||||
inherited Create(TheOwner);
|
||||
EdgeBorders:= [ebTop];
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ rem This script is called from ..\build.bat.
|
|||
pushd components
|
||||
lazbuild chsdet\chsdet.lpk %DC_ARCH%
|
||||
lazbuild multithreadprocs\multithreadprocslaz.lpk %DC_ARCH%
|
||||
lazbuild dcpcrypt\dcpcrypt.lpk %DC_ARCH%
|
||||
lazbuild kascrypt\kascrypt.lpk %DC_ARCH%
|
||||
lazbuild doublecmd\doublecmd_common.lpk %DC_ARCH%
|
||||
lazbuild Image32\Image32.lpk %DC_ARCH%
|
||||
lazbuild KASToolBar\kascomp.lpk %DC_ARCH%
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ basedir=$(pwd)
|
|||
cd components
|
||||
$lazbuild chsdet/chsdet.lpk $DC_ARCH
|
||||
$lazbuild multithreadprocs/multithreadprocslaz.lpk $DC_ARCH
|
||||
$lazbuild dcpcrypt/dcpcrypt.lpk $DC_ARCH
|
||||
$lazbuild kascrypt/kascrypt.lpk $DC_ARCH
|
||||
$lazbuild doublecmd/doublecmd_common.lpk $DC_ARCH
|
||||
$lazbuild Image32/Image32.lpk $DC_ARCH
|
||||
$lazbuild KASToolBar/kascomp.lpk $DC_ARCH
|
||||
|
|
|
|||
|
|
@ -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,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.
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
-------------------------------------------------------------------------
|
||||
This module contains classes with UTF8 file names support.
|
||||
|
||||
Copyright (C) 2008-2022 Alexander Koblov (alexx2000@mail.ru)
|
||||
Copyright (C) 2008-2024 Alexander Koblov (alexx2000@mail.ru)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -42,7 +42,7 @@ type
|
|||
protected
|
||||
FFileName: String;
|
||||
procedure Sync(AWritten: Int64);
|
||||
procedure SetSize64(const NewSize: Int64); override;
|
||||
procedure SetCapacity(const NewCapacity: Int64);
|
||||
public
|
||||
constructor Create(const AFileName: String; Mode: LongWord); virtual; overload;
|
||||
destructor Destroy; override;
|
||||
|
|
@ -51,6 +51,7 @@ type
|
|||
function Write(const Buffer; Count: LongInt): LongInt; override;
|
||||
property DirtyLimit: Int64 read FDirtyLimit write FDirtyLimit;
|
||||
property AutoSync: Boolean read FAutoSync write SetAutoSync;
|
||||
property Capacity: Int64 write SetCapacity;
|
||||
property FileName: String read FFileName;
|
||||
end;
|
||||
|
||||
|
|
@ -71,8 +72,8 @@ type
|
|||
private
|
||||
FReadOnly: Boolean;
|
||||
public
|
||||
constructor Create(const AFileName: String; Mode: Word); virtual;
|
||||
constructor Create(const AFileName: String; AEscapeLineFeeds : Boolean = False); override;
|
||||
constructor Create(const AFileName: String; Mode: Word; AOptions: TIniFileOptions = []); virtual;
|
||||
constructor Create(const AFileName: String; AOptions: TIniFileOptions = []); override;
|
||||
procedure UpdateFile; override;
|
||||
public
|
||||
property ReadOnly: Boolean read FReadOnly;
|
||||
|
|
@ -156,9 +157,9 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TFileStreamEx.SetSize64(const NewSize: Int64);
|
||||
procedure TFileStreamEx.SetCapacity(const NewCapacity: Int64);
|
||||
begin
|
||||
FileAllocate(Handle, NewSize);
|
||||
FileAllocate(Handle, NewCapacity);
|
||||
end;
|
||||
|
||||
constructor TFileStreamEx.Create(const AFileName: String; Mode: LongWord);
|
||||
|
|
@ -169,7 +170,7 @@ begin
|
|||
begin
|
||||
AHandle:= mbFileCreate(AFileName, Mode);
|
||||
if AHandle = feInvalidHandle then
|
||||
raise EFCreateError.CreateFmt(SFCreateError, [AFileName])
|
||||
raise EFCreateError.CreateFmt(SFCreateError + LineEnding + mbSysErrorMessage, [AFileName])
|
||||
else
|
||||
inherited Create(AHandle);
|
||||
end
|
||||
|
|
@ -177,7 +178,7 @@ begin
|
|||
begin
|
||||
AHandle:= mbFileOpen(AFileName, Mode);
|
||||
if AHandle = feInvalidHandle then
|
||||
raise EFOpenError.CreateFmt(SFOpenError, [AFilename])
|
||||
raise EFOpenError.CreateFmt(SFOpenError + LineEnding + mbSysErrorMessage , [AFilename])
|
||||
else
|
||||
inherited Create(AHandle);
|
||||
end;
|
||||
|
|
@ -270,13 +271,14 @@ end;
|
|||
|
||||
{ TIniFileEx }
|
||||
|
||||
constructor TIniFileEx.Create(const AFileName: String; Mode: Word);
|
||||
constructor TIniFileEx.Create(const AFileName: String; Mode: Word;
|
||||
AOptions: TIniFileOptions);
|
||||
var
|
||||
slLines : TStringListEx;
|
||||
begin
|
||||
FReadOnly := ((Mode and $03) = fmOpenRead);
|
||||
|
||||
inherited Create(EmptyStr);
|
||||
inherited Create(EmptyStr, AOptions);
|
||||
|
||||
if ((Mode and $03) <> fmOpenWrite) then
|
||||
begin
|
||||
|
|
@ -294,7 +296,7 @@ begin
|
|||
Rename(AFileName, False);
|
||||
end;
|
||||
|
||||
constructor TIniFileEx.Create(const AFileName: String; AEscapeLineFeeds: Boolean);
|
||||
constructor TIniFileEx.Create(const AFileName: String; AOptions: TIniFileOptions);
|
||||
var
|
||||
Mode: Word;
|
||||
begin
|
||||
|
|
@ -305,7 +307,7 @@ begin
|
|||
else begin
|
||||
Mode := fmOpenRead or fmShareDenyNone;
|
||||
end;
|
||||
Create(AFileName, Mode);
|
||||
Create(AFileName, Mode, AOptions);
|
||||
end;
|
||||
|
||||
procedure TIniFileEx.UpdateFile;
|
||||
|
|
|
|||
|
|
@ -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,73 @@
|
|||
unit DCDarwin;
|
||||
|
||||
{$mode delphi}
|
||||
{$packrecords c}
|
||||
{$pointermath on}
|
||||
{$modeswitch objectivec1}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, DCBasicTypes, CocoaAll;
|
||||
Classes, SysUtils, DCBasicTypes, CocoaAll, BaseUnix;
|
||||
|
||||
const
|
||||
CLOSE_RANGE_CLOEXEC = (1 << 2);
|
||||
|
||||
function CloseRange(first: cuint; last: cuint; flags: cint): cint; cdecl;
|
||||
|
||||
// MacOS File Utils
|
||||
function MacosFileSetCreationTime( const path:String; const birthtime:TFileTimeEx ): Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
DCUnix;
|
||||
|
||||
type
|
||||
proc_fdinfo = record
|
||||
proc_fd: Int32;
|
||||
proc_fdtype: UInt32;
|
||||
end;
|
||||
Pproc_fdinfo = ^proc_fdinfo;
|
||||
|
||||
const
|
||||
PROC_PIDLISTFDS = 1;
|
||||
PROC_PIDLISTFD_SIZE = SizeOf(proc_fdinfo);
|
||||
|
||||
function proc_pidinfo(pid: cint; flavor: cint; arg: cuint64; buffer: pointer; buffersize: cint): cint; cdecl; external 'proc';
|
||||
|
||||
function CloseRange(first: cuint; last: cuint; flags: cint): cint; cdecl;
|
||||
var
|
||||
I: cint;
|
||||
Handle: cint;
|
||||
ProcessId: TPid;
|
||||
bufferSize: cint;
|
||||
pidInfo: Pproc_fdinfo;
|
||||
begin
|
||||
Result:= -1;
|
||||
ProcessId:= FpGetpid;
|
||||
bufferSize:= proc_pidinfo(ProcessId, PROC_PIDLISTFDS, 0, nil, 0);
|
||||
pidInfo:= GetMem(bufferSize);
|
||||
if Assigned(pidInfo) then
|
||||
begin
|
||||
bufferSize:= proc_pidinfo(ProcessId, PROC_PIDLISTFDS, 0, pidInfo, bufferSize);
|
||||
for I:= 0 to (bufferSize div PROC_PIDLISTFD_SIZE) - 1 do
|
||||
begin
|
||||
Handle:= pidInfo[I].proc_fd;
|
||||
if (Handle >= first) and (Handle <= last) then
|
||||
begin
|
||||
if (flags and CLOSE_RANGE_CLOEXEC <> 0) then
|
||||
FileCloseOnExec(Handle)
|
||||
else begin
|
||||
FileClose(Handle);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Result:= 0;
|
||||
FreeMem(pidInfo);
|
||||
end;
|
||||
end;
|
||||
|
||||
function StringToNSString(const S: String): NSString;
|
||||
begin
|
||||
Result:= NSString(NSString.stringWithUTF8String(PAnsiChar(S)));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -186,13 +188,14 @@ function WinToUnixFileAttr(Attr: TFileAttrs): TFileAttrs;
|
|||
begin
|
||||
Result := S_IRUSR or S_IRGRP or S_IROTH;
|
||||
|
||||
if (Attr and faReadOnly) = 0 then
|
||||
Result := Result or S_IWUSR;
|
||||
|
||||
if (Attr and faDirectory) <> 0 then
|
||||
Result := Result or S_IFDIR or S_IXUGO
|
||||
else
|
||||
Result := Result or S_IFDIR or S_IXUGO or S_IWUSR
|
||||
else begin
|
||||
Result := Result or S_IFREG;
|
||||
|
||||
if (Attr and faReadOnly) = 0 then
|
||||
Result := Result or S_IWUSR;
|
||||
end;
|
||||
end;
|
||||
|
||||
function UnixToWinFileAttr(Attr: TFileAttrs): TFileAttrs;
|
||||
|
|
|
|||
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,6 +39,8 @@ const
|
|||
FSCTL_SET_REPARSE_POINT = $000900A4;
|
||||
FSCTL_GET_REPARSE_POINT = $000900A8;
|
||||
FSCTL_DELETE_REPARSE_POINT = $000900AC;
|
||||
// WSL and Cygwin symbolic link
|
||||
IO_REPARSE_TAG_LX_SYMLINK = $A000001D;
|
||||
|
||||
const
|
||||
REPARSE_DATA_HEADER_SIZE = 8;
|
||||
|
|
@ -68,6 +69,11 @@ type
|
|||
PathBuffer: array[0..0] of WCHAR;
|
||||
end;
|
||||
|
||||
TLxSymlinkReparseBuffer = record
|
||||
FileType: DWORD;
|
||||
PathBuffer: array[0..0] of AnsiChar;
|
||||
end;
|
||||
|
||||
TGenericReparseBuffer = record
|
||||
DataBuffer: array[0..0] of UCHAR;
|
||||
end;
|
||||
|
|
@ -79,7 +85,8 @@ type
|
|||
case Integer of
|
||||
0: (SymbolicLinkReparseBuffer: TSymbolicLinkReparseBuffer);
|
||||
1: (MountPointReparseBuffer: TMountPointReparseBuffer);
|
||||
2: (GenericReparseBuffer: TGenericReparseBuffer);
|
||||
2: (LxSymlinkReparseBuffer: TLxSymlinkReparseBuffer);
|
||||
3: (GenericReparseBuffer: TGenericReparseBuffer);
|
||||
end;
|
||||
TReparseDataBuffer = REPARSE_DATA_BUFFER;
|
||||
PReparseDataBuffer = ^REPARSE_DATA_BUFFER;
|
||||
|
|
@ -95,7 +102,7 @@ type
|
|||
@param(ALinkName The name of the symbolic link)
|
||||
@returns(The function returns @true if successful, @false otherwise)
|
||||
}
|
||||
function CreateSymLink(const ATargetName, ALinkName: UnicodeString): Boolean;
|
||||
function CreateSymLink(const ATargetName, ALinkName: UnicodeString; Attr: UInt32): Boolean;
|
||||
{en
|
||||
Established a hard link beetwen an existing file and new file. This function
|
||||
is only supported on the NTFS file system, and only for files, not directories.
|
||||
|
|
@ -250,6 +257,7 @@ function _CreateSymLink_Old(aTargetFileName, aSymlinkFileName: UnicodeString): B
|
|||
var
|
||||
hDevice: THandle;
|
||||
lpInBuffer: PReparseDataBuffer;
|
||||
dwLastError,
|
||||
nInBufferSize,
|
||||
dwPathBufferSize: DWORD;
|
||||
wsNativeFileName: UnicodeString;
|
||||
|
|
@ -261,7 +269,11 @@ begin
|
|||
hDevice:= CreateFileW(PWideChar(aSymlinkFileName),
|
||||
GENERIC_WRITE, 0, nil, OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
if hDevice = INVALID_HANDLE_VALUE then Exit(False);
|
||||
if hDevice = INVALID_HANDLE_VALUE then
|
||||
begin
|
||||
dwLastError:= GetLastError;
|
||||
Exit(False);
|
||||
end;
|
||||
if Pos(wsLongFileNamePrefix, aTargetFileName) <> 1 then
|
||||
wsNativeFileName:= wsNativeFileNamePrefix + aTargetFileName
|
||||
else begin
|
||||
|
|
@ -288,15 +300,19 @@ begin
|
|||
0, // nOutBufferSize
|
||||
lpBytesReturned, // lpBytesReturned
|
||||
nil); // OVERLAPPED structure
|
||||
|
||||
if not Result then dwLastError:= GetLastError;
|
||||
FreeMem(lpInBuffer);
|
||||
CloseHandle(hDevice);
|
||||
finally
|
||||
if not Result then RemoveDirectoryW(PWideChar(aSymlinkFileName));
|
||||
if not Result then
|
||||
begin
|
||||
RemoveDirectoryW(PWideChar(aSymlinkFileName));
|
||||
SetLastError(dwLastError);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function CreateSymLink(const ATargetName, ALinkName: UnicodeString): Boolean;
|
||||
function CreateSymLink(const ATargetName, ALinkName: UnicodeString; Attr: UInt32): Boolean;
|
||||
var
|
||||
dwAttributes: DWORD;
|
||||
lpFilePart: LPWSTR = nil;
|
||||
|
|
@ -315,7 +331,11 @@ begin
|
|||
AFullPathName:= ATargetName;
|
||||
end;
|
||||
end;
|
||||
dwAttributes:= Windows.GetFileAttributesW(PWideChar(AFullPathName));
|
||||
if (Attr <> FILE_DOES_NOT_EXIST) then
|
||||
dwAttributes:= Attr
|
||||
else begin
|
||||
dwAttributes:= Windows.GetFileAttributesW(PWideChar(AFullPathName));
|
||||
end;
|
||||
if dwAttributes = FILE_DOES_NOT_EXIST then Exit;
|
||||
if HasNewApi = False then
|
||||
begin
|
||||
|
|
@ -339,9 +359,10 @@ end;
|
|||
|
||||
function ReadSymLink(const aSymlinkFileName: UnicodeString; out aTargetFileName: UnicodeString): Boolean;
|
||||
var
|
||||
L: Integer;
|
||||
hDevice: THandle;
|
||||
dwFileAttributes: DWORD;
|
||||
caOutBuffer: array[0..4095] of Byte;
|
||||
caOutBuffer: array[0..MaxSmallint] of Byte;
|
||||
lpOutBuffer: TReparseDataBuffer absolute caOutBuffer;
|
||||
pwcTargetFileName: PWideChar;
|
||||
lpBytesReturned: DWORD = 0;
|
||||
|
|
@ -389,6 +410,13 @@ begin
|
|||
SetLength(aTargetFileName, SubstituteNameLength div SizeOf(WideChar));
|
||||
CopyMemory(PWideChar(aTargetFileName), pwcTargetFileName, SubstituteNameLength);
|
||||
end;
|
||||
IO_REPARSE_TAG_LX_SYMLINK:
|
||||
with lpOutBuffer.LxSymlinkReparseBuffer do
|
||||
begin
|
||||
L:= lpOutBuffer.ReparseDataLength - SizeOf(FileType);
|
||||
SetLength(aTargetFileName, L + 1);
|
||||
SetLength(aTargetFileName, MultiByteToWideChar(CP_UTF8, 0, @PathBuffer[0], L, PWideChar(aTargetFileName), L + 1));
|
||||
end;
|
||||
end;
|
||||
if Pos(wsNetworkFileNamePrefix, aTargetFileName) = 1 then
|
||||
Delete(aTargetFileName, 2, Length(wsNetworkFileNamePrefix) - 2)
|
||||
|
|
|
|||
265
components/doublecmd/dcosutils.pas
Executable file → Normal file
|
|
@ -3,7 +3,7 @@
|
|||
-------------------------------------------------------------------------
|
||||
This unit contains platform dependent functions dealing with operating system.
|
||||
|
||||
Copyright (C) 2006-2023 Alexander Koblov (alexx2000@mail.ru)
|
||||
Copyright (C) 2006-2025 Alexander Koblov (alexx2000@mail.ru)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -31,6 +31,9 @@ uses
|
|||
{$IFDEF UNIX}
|
||||
, BaseUnix, DCUnix
|
||||
{$ENDIF}
|
||||
{$IFDEF LINUX}
|
||||
, DCLinux
|
||||
{$ENDIF}
|
||||
{$IFDEF HAIKU}
|
||||
, DCHaiku
|
||||
{$ENDIF}
|
||||
|
|
@ -43,6 +46,7 @@ const
|
|||
fmOpenSync = $10000;
|
||||
fmOpenDirect = $20000;
|
||||
fmOpenNoATime = $40000;
|
||||
fmOpenSpecial = $80000;
|
||||
|
||||
{$IF DEFINED(UNIX)}
|
||||
ERROR_NOT_SAME_DEVICE = ESysEXDEV;
|
||||
|
|
@ -96,7 +100,7 @@ type
|
|||
PCopyAttributesResult = ^TCopyAttributesResult;
|
||||
|
||||
const
|
||||
faInvalidAttributes: TFileAttrs = TFileAttrs(-1);
|
||||
faInvalidAttributes = TFileAttrs(-1);
|
||||
CopyAttributesOptionCopyAll = [caoCopyAttributes, caoCopyTime, caoCopyOwnership];
|
||||
|
||||
{en
|
||||
|
|
@ -111,6 +115,12 @@ function FPS_ISDIR(iAttr: TFileAttrs) : Boolean;
|
|||
@returns(@true if file is a symbolic link, @false otherwise)
|
||||
}
|
||||
function FPS_ISLNK(iAttr: TFileAttrs) : Boolean;
|
||||
{en
|
||||
Is file a regular file
|
||||
@param(iAttr File attributes)
|
||||
@returns(@true if file is a regular file, @false otherwise)
|
||||
}
|
||||
function FPS_ISREG(iAttr: TFileAttrs) : Boolean;
|
||||
{en
|
||||
Is file executable
|
||||
@param(sFileName File name)
|
||||
|
|
@ -146,6 +156,10 @@ function FileIsReadOnly(iAttr: TFileAttrs): Boolean; inline;
|
|||
The path '/tmp' must already exist.)
|
||||
}
|
||||
function GetTempName(PathPrefix: String; Extension: String = 'tmp'): String;
|
||||
{en
|
||||
Find file in the system PATH
|
||||
}
|
||||
function FindInSystemPath(var FileName: String): Boolean;
|
||||
{en
|
||||
Extract file root directory
|
||||
@param(FileName File name)
|
||||
|
|
@ -177,6 +191,7 @@ function mbFileCreate(const FileName: String): System.THandle; overload; inline;
|
|||
function mbFileCreate(const FileName: String; Mode: LongWord): System.THandle; overload; inline;
|
||||
function mbFileCreate(const FileName: String; Mode, Rights: LongWord): System.THandle; overload;
|
||||
function mbFileAge(const FileName: String): DCBasicTypes.TFileTime;
|
||||
function mbFileGetTime(const FileName: String): DCBasicTypes.TFileTimeEx;
|
||||
// On success returns True.
|
||||
// nanoseconds supported
|
||||
function mbFileGetTime(const FileName: String;
|
||||
|
|
@ -222,6 +237,7 @@ function mbFileSize(const FileName: String): Int64;
|
|||
function FileGetSize(Handle: System.THandle): Int64;
|
||||
function FileFlush(Handle: System.THandle): Boolean;
|
||||
function FileFlushData(Handle: System.THandle): Boolean;
|
||||
function FileIsReadOnlyEx(Handle: System.THandle): Boolean;
|
||||
function FileAllocate(Handle: System.THandle; Size: Int64): Boolean;
|
||||
{ Directory handling functions}
|
||||
function mbGetCurrentDir: String;
|
||||
|
|
@ -293,7 +309,7 @@ function CreateHardLink(const Path, LinkName: String) : Boolean;
|
|||
@param(LinkName Name of symbolic link)
|
||||
@returns(The function returns @true if successful, @false otherwise)
|
||||
}
|
||||
function CreateSymLink(const Path, LinkName: string) : Boolean;
|
||||
function CreateSymLink(const Path, LinkName: string; Attr: UInt32 = faInvalidAttributes) : Boolean;
|
||||
{en
|
||||
Read destination of symbolic link
|
||||
@param(LinkName Name of symbolic link)
|
||||
|
|
@ -381,8 +397,6 @@ const
|
|||
O_SYNC or O_DIRECT);
|
||||
{$ENDIF}
|
||||
|
||||
(*Is Directory*)
|
||||
|
||||
function FPS_ISDIR(iAttr: TFileAttrs) : Boolean; inline;
|
||||
{$IFDEF MSWINDOWS}
|
||||
begin
|
||||
|
|
@ -394,8 +408,6 @@ begin
|
|||
end;
|
||||
{$ENDIF}
|
||||
|
||||
(*Is Link*)
|
||||
|
||||
function FPS_ISLNK(iAttr: TFileAttrs) : Boolean; inline;
|
||||
{$IFDEF MSWINDOWS}
|
||||
begin
|
||||
|
|
@ -407,6 +419,17 @@ begin
|
|||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function FPS_ISREG(iAttr: TFileAttrs) : Boolean; inline;
|
||||
{$IFDEF MSWINDOWS}
|
||||
begin
|
||||
Result := (iAttr and FILE_ATTRIBUTE_DIRECTORY = 0);
|
||||
end;
|
||||
{$ELSE}
|
||||
begin
|
||||
Result := BaseUnix.FPS_ISREG(TMode(iAttr));
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function FileIsExeLib(const sFileName : String) : Boolean;
|
||||
var
|
||||
fsExeLib : TFileStreamEx;
|
||||
|
|
@ -484,54 +507,59 @@ function mbFileCopyAttr(const sSrc, sDst: String;
|
|||
): TCopyAttributesOptions;
|
||||
{$IFDEF MSWINDOWS}
|
||||
var
|
||||
Attr : TFileAttrs;
|
||||
Attr: TWin32FileAttributeData;
|
||||
Option: TCopyAttributesOption;
|
||||
ModificationTime, CreationTime, LastAccessTime: DCBasicTypes.TFileTime;
|
||||
begin
|
||||
Result := [];
|
||||
|
||||
if not GetFileAttributesExW(PWideChar(UTF16LongName(sSrc)), GetFileExInfoStandard, @Attr) then
|
||||
begin
|
||||
Result := Options;
|
||||
if Assigned(Errors) then
|
||||
begin
|
||||
for Option in Result do
|
||||
Errors^[Option]:= GetLastOSError;
|
||||
end;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if [caoCopyAttributes, caoCopyAttrEx] * Options <> [] then
|
||||
begin
|
||||
Attr := mbFileGetAttr(sSrc);
|
||||
if Attr <> faInvalidAttributes then
|
||||
if (not (caoCopyAttributes in Options)) and (Attr.dwFileAttributes and faDirectory = 0) then
|
||||
Attr.dwFileAttributes := (Attr.dwFileAttributes or faArchive);
|
||||
if (caoRemoveReadOnlyAttr in Options) and ((Attr.dwFileAttributes and faReadOnly) <> 0) then
|
||||
Attr.dwFileAttributes := (Attr.dwFileAttributes and not faReadOnly);
|
||||
if not mbFileSetAttr(sDst, Attr.dwFileAttributes) then
|
||||
begin
|
||||
if (not (caoCopyAttributes in Options)) and (Attr and faDirectory = 0) then
|
||||
Attr := (Attr or faArchive);
|
||||
if (caoRemoveReadOnlyAttr in Options) and ((Attr and faReadOnly) <> 0) then
|
||||
Attr := (Attr and not faReadOnly);
|
||||
if not mbFileSetAttr(sDst, Attr) then
|
||||
begin
|
||||
Include(Result, caoCopyAttributes);
|
||||
if Assigned(Errors) then Errors^[caoCopyAttributes]:= GetLastOSError;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
Include(Result, caoCopyAttributes);
|
||||
if Assigned(Errors) then Errors^[caoCopyAttributes]:= GetLastOSError;
|
||||
end;
|
||||
end;
|
||||
|
||||
if caoCopyXattributes in Options then
|
||||
if not FPS_ISLNK(Attr.dwFileAttributes) then
|
||||
begin
|
||||
if not mbFileCopyXattr(sSrc, sDst) then
|
||||
if (caoCopyXattributes in Options) then
|
||||
begin
|
||||
Include(Result, caoCopyXattributes);
|
||||
if Assigned(Errors) then Errors^[caoCopyXattributes]:= GetLastOSError;
|
||||
if not mbFileCopyXattr(sSrc, sDst) then
|
||||
begin
|
||||
Include(Result, caoCopyXattributes);
|
||||
if Assigned(Errors) then Errors^[caoCopyXattributes]:= GetLastOSError;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if [caoCopyTime, caoCopyTimeEx] * Options <> [] then
|
||||
begin
|
||||
if not mbFileGetTime(sSrc, ModificationTime, CreationTime, LastAccessTime) then
|
||||
if ([caoCopyTime, caoCopyTimeEx] * Options <> []) then
|
||||
begin
|
||||
Include(Result, caoCopyTime);
|
||||
if Assigned(Errors) then Errors^[caoCopyTime]:= GetLastOSError;
|
||||
end
|
||||
else begin
|
||||
if not (caoCopyTime in Options) then
|
||||
begin
|
||||
CreationTime:= 0;
|
||||
LastAccessTime:= 0;
|
||||
end
|
||||
else begin
|
||||
CreationTime:= DCBasicTypes.TFileTime(Attr.ftCreationTime);
|
||||
LastAccessTime:= DCBasicTypes.TFileTime(Attr.ftLastAccessTime);
|
||||
end;
|
||||
ModificationTime:= DCBasicTypes.TFileTime(Attr.ftLastWriteTime);
|
||||
|
||||
if not mbFileSetTime(sDst, ModificationTime, CreationTime, LastAccessTime) then
|
||||
begin
|
||||
|
|
@ -670,6 +698,26 @@ begin
|
|||
until not mbFileSystemEntryExists(Result);
|
||||
end;
|
||||
|
||||
function FindInSystemPath(var FileName: String): Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
Path, FullName: String;
|
||||
Value: TDynamicStringArray;
|
||||
begin
|
||||
Path:= mbGetEnvironmentVariable('PATH');
|
||||
Value:= SplitString(Path, PathSeparator);
|
||||
for I:= Low(Value) to High(Value) do
|
||||
begin
|
||||
FullName:= IncludeTrailingPathDelimiter(Value[I]) + FileName;
|
||||
if mbFileExists(FullName) then
|
||||
begin
|
||||
FileName:= FullName;
|
||||
Exit(True);
|
||||
end;
|
||||
end;
|
||||
Result:= False;
|
||||
end;
|
||||
|
||||
function ExtractRootDir(const FileName: String): String;
|
||||
{$IFDEF UNIX}
|
||||
begin
|
||||
|
|
@ -824,6 +872,8 @@ begin
|
|||
end;
|
||||
end;
|
||||
{$ELSE}
|
||||
var
|
||||
Info: BaseUnix.Stat;
|
||||
begin
|
||||
repeat
|
||||
Result:= fpOpen(UTF8ToSys(FileName), AccessModes[Mode and 3] or
|
||||
|
|
@ -832,7 +882,28 @@ begin
|
|||
if Result <> feInvalidHandle then
|
||||
begin
|
||||
FileCloseOnExec(Result);
|
||||
Result:= FileLock(Result, Mode and $FF);
|
||||
if (Mode and fmOpenSpecial = 0) then
|
||||
begin
|
||||
if fpFStat(Result, Info) = 0 then
|
||||
begin
|
||||
if FPS_ISFIFO(Info.st_mode) then
|
||||
begin
|
||||
FileClose(Result);
|
||||
errno:= ESysEINVAL;
|
||||
Exit(feInvalidHandle);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{$IF DEFINED(DARWIN)}
|
||||
if (Mode and (fmOpenSync or fmOpenDirect) <> 0) then
|
||||
begin
|
||||
if (FpFcntl(Result, F_NOCACHE, 1) = -1) then
|
||||
begin
|
||||
FileClose(Result);
|
||||
Exit(feInvalidHandle);
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
|
@ -863,7 +934,16 @@ begin
|
|||
if Result <> feInvalidHandle then
|
||||
begin
|
||||
FileCloseOnExec(Result);
|
||||
Result:= FileLock(Result, Mode and $FF);
|
||||
{$IF DEFINED(DARWIN)}
|
||||
if (Mode and (fmOpenSync or fmOpenDirect) <> 0) then
|
||||
begin
|
||||
if (FpFcntl(Result, F_NOCACHE, 1) = -1) then
|
||||
begin
|
||||
FileClose(Result);
|
||||
Exit(feInvalidHandle);
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
|
@ -895,6 +975,14 @@ begin
|
|||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function mbFileGetTime(const FileName: String): DCBasicTypes.TFileTimeEx;
|
||||
var
|
||||
CreationTime, LastAccessTime: DCBasicTypes.TFileTimeEx;
|
||||
begin
|
||||
if not mbFileGetTime(FileName, Result, CreationTime, LastAccessTime) then
|
||||
Result:= TFileTimeExNull;
|
||||
end;
|
||||
|
||||
function mbFileGetTime(const FileName: String;
|
||||
var ModificationTime: DCBasicTypes.TFileTimeEx;
|
||||
var CreationTime : DCBasicTypes.TFileTimeEx;
|
||||
|
|
@ -1250,8 +1338,10 @@ begin
|
|||
// (On Linux rename() returns success but doesn't do anything
|
||||
// if renaming a file to its hard link.)
|
||||
// We cannot use st_nlink for directories because it means "number of
|
||||
// subdirectories"; hard links to directories are not supported on Linux
|
||||
// or Windows anyway (on MacOSX they are). Therefore we always treat
|
||||
// subdirectories" ("number of all entries" under macOS) in that directory,
|
||||
// plus its special entries '.' and '..';
|
||||
// hard links to directories are not supported on Linux
|
||||
// or Windows anyway (on macOS they are). Therefore we always treat
|
||||
// directories as if they were a single link and rename them using temporary name.
|
||||
|
||||
if (NewFileStat.st_nlink = 1) or BaseUnix.fpS_ISDIR(NewFileStat.st_mode) then
|
||||
|
|
@ -1265,14 +1355,7 @@ begin
|
|||
// We have renamed the old file but the new file name still exists,
|
||||
// so this wasn't a single file on a case-insensitive filesystem
|
||||
// accessible by two names that differ by case.
|
||||
|
||||
FpRename(UTF8ToSys(tmpFileName), UTF8ToSys(OldName)); // Restore old file.
|
||||
{$IFDEF DARWIN}
|
||||
// If it's a directory with multiple hard links then simply unlink the source.
|
||||
if BaseUnix.fpS_ISDIR(NewFileStat.st_mode) and (NewFileStat.st_nlink > 1) then
|
||||
Result := (fpUnLink(UTF8ToSys(OldName)) = 0)
|
||||
else
|
||||
{$ENDIF}
|
||||
Result := False;
|
||||
end
|
||||
else if FpRename(UTF8ToSys(tmpFileName), UTF8ToSys(NewName)) = 0 then
|
||||
|
|
@ -1367,14 +1450,48 @@ begin
|
|||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function FileIsReadOnlyEx(Handle: System.THandle): Boolean;
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
var
|
||||
Info: BY_HANDLE_FILE_INFORMATION;
|
||||
begin
|
||||
if GetFileInformationByHandle(Handle, Info) then
|
||||
Result:= (Info.dwFileAttributes and (faReadOnly or faHidden or faSysFile) <> 0)
|
||||
else
|
||||
Result:= False;
|
||||
end;
|
||||
{$ELSEIF DEFINED(LINUX)}
|
||||
var
|
||||
Flags: UInt32;
|
||||
begin
|
||||
if FileGetFlags(Handle, Flags) then
|
||||
begin
|
||||
if (Flags and (FS_IMMUTABLE_FL or FS_APPEND_FL) <> 0) then
|
||||
Exit(True);
|
||||
end;
|
||||
Result:= False;
|
||||
end;
|
||||
{$ELSE}
|
||||
begin
|
||||
Result:= False;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function FileAllocate(Handle: System.THandle; Size: Int64): Boolean;
|
||||
{$IF DEFINED(LINUX)}
|
||||
var
|
||||
Ret: cint;
|
||||
Sta: TStat;
|
||||
StaFS: TStatFS;
|
||||
begin
|
||||
if (Size > 0) then
|
||||
begin
|
||||
repeat
|
||||
Ret:= fpfStatFS(Handle, @StaFS);
|
||||
until (Ret <> -1) or (fpgeterrno <> ESysEINTR);
|
||||
// FAT32 does not support a fast allocation
|
||||
if (StaFS.fstype = MSDOS_SUPER_MAGIC) then
|
||||
Exit(False);
|
||||
repeat
|
||||
Ret:= fpFStat(Handle, Sta);
|
||||
until (Ret <> -1) or (fpgeterrno <> ESysEINTR);
|
||||
|
|
@ -1384,7 +1501,7 @@ begin
|
|||
Sta.st_size:= (Size + Sta.st_blksize - 1) and not (Sta.st_blksize - 1);
|
||||
repeat
|
||||
Ret:= fpFAllocate(Handle, 0, 0, Sta.st_size);
|
||||
until (Ret <> -1) or (fpgeterrno <> ESysEINTR) or (fpgeterrno <> ESysEAGAIN);
|
||||
until (Ret <> -1) or (fpgeterrno <> ESysEINTR);
|
||||
end;
|
||||
end;
|
||||
Result:= FileTruncate(Handle, Size);
|
||||
|
|
@ -1647,7 +1764,7 @@ begin
|
|||
if EqualPos = 0 then Continue;
|
||||
EnvName:= Copy(EnvVar, 1, EqualPos - 1);
|
||||
EnvValue:= Copy(EnvVar, EqualPos + 1, MaxInt);
|
||||
Result:= StringReplace(Result, '$' + EnvName, EnvValue, [rfReplaceAll, rfIgnoreCase]);
|
||||
Result:= StringReplace(Result, '$' + EnvName, EnvValue, [rfReplaceAll]);
|
||||
Inc(Index);
|
||||
end;
|
||||
end;
|
||||
|
|
@ -1764,21 +1881,27 @@ end;
|
|||
function mbLoadLibrary(const Name: String): TLibHandle;
|
||||
{$IFDEF MSWINDOWS}
|
||||
var
|
||||
dwMode: DWORD;
|
||||
dwErrCode: DWORD;
|
||||
sRememberPath: String;
|
||||
begin
|
||||
dwMode:= SetErrorMode(SEM_FAILCRITICALERRORS or SEM_NOOPENFILEERRORBOX);
|
||||
try
|
||||
//Some plugins using DLL(s) in their directory are loaded correctly only if "CurrentDir" is poining their location.
|
||||
//Also, TC switch "CurrentDir" to their directory when loading them. So let's do the same.
|
||||
sRememberPath:=GetCurrentDir;
|
||||
SetCurrentDir(ExcludeTrailingPathDelimiter(ExtractFilePath(Name)));
|
||||
Result:= LoadLibraryW(PWideChar(CeUtf8ToUtf16(Name)));
|
||||
// Some plugins using DLL(s) in their directory are loaded correctly only if "CurrentDir" is poining their location.
|
||||
// Also, TC switch "CurrentDir" to their directory when loading them. So let's do the same.
|
||||
sRememberPath:= GetCurrentDir;
|
||||
SetCurrentDir(ExtractFileDir(Name));
|
||||
Result:= SafeLoadLibrary(CeUtf8ToUtf16(Name));
|
||||
dwErrCode:= GetLastError;
|
||||
finally
|
||||
SetErrorMode(dwMode);
|
||||
SetCurrentDir(sRememberPath);
|
||||
SetLastError(dwErrCode);
|
||||
end;
|
||||
end;
|
||||
{$ELSE}
|
||||
begin
|
||||
Result:= TLibHandle(dlopen(PChar(UTF8ToSys(Name)), RTLD_LAZY));
|
||||
Result:= SafeLoadLibrary(CeUtf8ToSys(Name));
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
|
@ -1787,29 +1910,37 @@ function mbLoadLibraryEx(const Name: String): TLibHandle;
|
|||
const
|
||||
PATH_ENV = 'PATH';
|
||||
var
|
||||
dwFlags:DWORD;
|
||||
APath: String;
|
||||
APathType: TPathType;
|
||||
usName: UnicodeString;
|
||||
begin
|
||||
usName:= CeUtf8ToUtf16(Name);
|
||||
APathType:= GetPathType(Name);
|
||||
|
||||
if CheckWin32Version(10)then
|
||||
if CheckWin32Version(10) or (GetProcAddress(GetModuleHandleW(Kernel32), 'AddDllDirectory') <> nil) then
|
||||
begin
|
||||
Result:= LoadLibraryExW(PWideChar(usName), 0, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR or LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||
end
|
||||
else if CheckWin32Version(6) then
|
||||
begin
|
||||
SetDllDirectoryW(PWideChar(ExtractFileDir(usName)));
|
||||
try
|
||||
Result:= LoadLibraryW(PWideChar(usName));
|
||||
finally
|
||||
SetDllDirectoryW(nil);
|
||||
if APathType <> ptAbsolute then
|
||||
dwFlags:= 0
|
||||
else begin
|
||||
dwFlags:= LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
|
||||
end;
|
||||
Result:= LoadLibraryExW(PWideChar(usName), 0, dwFlags or LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||
end
|
||||
else begin
|
||||
APath:= mbGetEnvironmentVariable(PATH_ENV);
|
||||
try
|
||||
mbSetEnvironmentVariable(PATH_ENV, ExtractFileDir(Name));
|
||||
Result:= LoadLibraryW(PWideChar(usName));
|
||||
if APathType <> ptAbsolute then
|
||||
SetDllDirectoryW(PWideChar(''))
|
||||
else begin
|
||||
SetDllDirectoryW(PWideChar(ExtractFileDir(usName)));
|
||||
end;
|
||||
try
|
||||
SetEnvironmentVariableW(PATH_ENV, nil);
|
||||
Result:= LoadLibraryW(PWideChar(usName));
|
||||
finally
|
||||
SetDllDirectoryW(nil);
|
||||
end;
|
||||
finally
|
||||
mbSetEnvironmentVariable(PATH_ENV, APath);
|
||||
end;
|
||||
|
|
@ -1817,7 +1948,7 @@ begin
|
|||
end;
|
||||
{$ELSE}
|
||||
begin
|
||||
Result:= TLibHandle(dlopen(PChar(UTF8ToSys(Name)), RTLD_LAZY));
|
||||
Result:= SafeLoadLibrary(CeUtf8ToSys(Name));
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
|
@ -1928,14 +2059,14 @@ begin
|
|||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function CreateSymLink(const Path, LinkName: string) : Boolean;
|
||||
function CreateSymLink(const Path, LinkName: string; Attr: UInt32): Boolean;
|
||||
{$IFDEF MSWINDOWS}
|
||||
var
|
||||
wsPath, wsLinkName: UnicodeString;
|
||||
begin
|
||||
wsPath:= CeUtf8ToUtf16(Path);
|
||||
wsLinkName:= UTF16LongName(LinkName);
|
||||
Result:= DCNtfsLinks.CreateSymlink(wsPath, wsLinkName);
|
||||
Result:= DCNtfsLinks.CreateSymlink(wsPath, wsLinkName, Attr);
|
||||
end;
|
||||
{$ELSE}
|
||||
begin
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ type
|
|||
function Add(const S: String): Integer;
|
||||
function Add(const S: String; ItemData: Pointer): Integer;
|
||||
procedure Clear;
|
||||
procedure Remove(Index: Integer);
|
||||
function Find(const S: String): Integer;
|
||||
function Find(const S: String; Data: Pointer): Integer;
|
||||
function Remove(const S: String): Integer;
|
||||
|
|
@ -162,6 +163,15 @@ begin
|
|||
fCount:= 0;
|
||||
end;
|
||||
|
||||
procedure TStringHashListUtf8.Remove(Index: Integer);
|
||||
begin
|
||||
if (Index >= 0) and (Index < FCount) then
|
||||
begin
|
||||
Dispose(fList[Index]);
|
||||
Delete(Index);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TStringHashListUtf8.CompareString(const Low, Key: String): Boolean;
|
||||
var
|
||||
P: Pointer;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
-------------------------------------------------------------------------
|
||||
Useful functions dealing with strings.
|
||||
|
||||
Copyright (C) 2006-2023 Alexander Koblov (alexx2000@mail.ru)
|
||||
Copyright (C) 2006-2025 Alexander Koblov (alexx2000@mail.ru)
|
||||
Copyright (C) 2012 Przemyslaw Nagay (cobines@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -45,6 +45,12 @@ function ContainsOneOf(StringToCheck: String; PossibleCharacters: String): Boole
|
|||
Convert known directory separators to the current directory separator.
|
||||
}
|
||||
function NormalizePathDelimiters(const Path: String): String;
|
||||
|
||||
{en
|
||||
Convert known directory separators to user defined directory separator.
|
||||
}
|
||||
function ReplaceDirectorySeparator(const Path: String; const Separator : Char): String;
|
||||
|
||||
{en
|
||||
Get last directory name in path
|
||||
@returns(Last directory name in path)
|
||||
|
|
@ -365,6 +371,21 @@ implementation
|
|||
uses
|
||||
DCOSUtils, DCConvertEncoding, StrUtils;
|
||||
|
||||
function ReplaceDirectorySeparator(const Path: String; const Separator : Char): String;
|
||||
const
|
||||
AllowPathDelimiters : set of char = ['\','/'];
|
||||
var
|
||||
I : LongInt;
|
||||
begin
|
||||
Result := Path;
|
||||
if (Separator in AllowPathDelimiters) then
|
||||
begin
|
||||
for I:= 1 to Length(Path) do
|
||||
if Path[I] in AllowPathDelimiters then
|
||||
Result[I]:= Separator
|
||||
end
|
||||
end;
|
||||
|
||||
function NormalizePathDelimiters(const Path: String): String;
|
||||
{$IFDEF UNIX}
|
||||
begin
|
||||
|
|
@ -375,11 +396,16 @@ const
|
|||
AllowPathDelimiters : set of char = ['\','/'];
|
||||
var
|
||||
I : LongInt;
|
||||
uriPos : Integer;
|
||||
begin
|
||||
Result:= Path;
|
||||
// If path is not URI
|
||||
if Pos('://', Result) = 0 then
|
||||
begin
|
||||
uriPos := Pos('://', Result);
|
||||
if (uriPos = 0)
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
or ( (uriPos = 2) and (Path[1] in ['A'..'z']) )
|
||||
{$ENDIF} then
|
||||
begin
|
||||
for I:= 1 to Length(Path) do
|
||||
if Path[I] in AllowPathDelimiters then
|
||||
Result[I]:= DirectorySeparator;
|
||||
|
|
@ -624,7 +650,7 @@ end;
|
|||
function ReplaceInvalidChars(const FileName: String): String;
|
||||
const
|
||||
{$IFDEF MSWINDOWS}
|
||||
ForbiddenChars : set of char = ['<','>',':','"','/','|','?','*'];
|
||||
ForbiddenChars : set of char = [#00..#31, '<','>',':','"','/','|','?','*'];
|
||||
{$ELSE}
|
||||
ForbiddenChars : set of char = [#0];
|
||||
{$ENDIF}
|
||||
|
|
@ -645,7 +671,7 @@ end;
|
|||
function RemoveInvalidCharsFromFileName(const FileName: String): String;
|
||||
const
|
||||
{$IFDEF MSWINDOWS}
|
||||
ForbiddenChars : set of char = ['<','>',':','"','/','\','|','?','*'];
|
||||
ForbiddenChars : set of char = [#00..#31, '<','>',':','"','/','\','|','?','*'];
|
||||
{$ELSE}
|
||||
ForbiddenChars : set of char = ['/'];
|
||||
{$ENDIF}
|
||||
|
|
@ -659,34 +685,56 @@ begin
|
|||
end;
|
||||
|
||||
function ExpandAbsolutePath(const Path: String): String;
|
||||
const
|
||||
PATH_DELIM_POS = {$IFDEF MSWINDOWS}3{$ELSE}1{$ENDIF};
|
||||
var
|
||||
I, J: Integer;
|
||||
begin
|
||||
Result := Path;
|
||||
|
||||
{First remove all references to '\.\'}
|
||||
I := Pos (DirectorySeparator + '.' + DirectorySeparator, Result);
|
||||
// Remove all references to '\.\'
|
||||
I := Pos(DirectorySeparator + '.' + DirectorySeparator, Result);
|
||||
while I <> 0 do
|
||||
begin
|
||||
Delete (Result, I, 2);
|
||||
I := Pos (DirectorySeparator + '.' + DirectorySeparator, Result);
|
||||
end;
|
||||
if StrEnds(Result, DirectorySeparator + '.') then
|
||||
Delete (Result, Length(Result) - 1, 2);
|
||||
begin
|
||||
Delete(Result, I, 2);
|
||||
I := Pos(DirectorySeparator + '.' + DirectorySeparator, Result, I);
|
||||
end;
|
||||
|
||||
{Then remove all references to '\..\'}
|
||||
I := Pos (DirectorySeparator + '..', Result);
|
||||
while (I <> 0) do
|
||||
begin
|
||||
J := Pred (I);
|
||||
while (J > 0) and (Result [J] <> DirectorySeparator) do
|
||||
Dec (J);
|
||||
if (J = 0) then
|
||||
Delete (Result, I, 3)
|
||||
else
|
||||
Delete (Result, J, I - J + 3);
|
||||
I := Pos (DirectorySeparator + '..', Result);
|
||||
end;
|
||||
// Remove all references to '\..\'
|
||||
I := Pos(DirectorySeparator + '..' + DirectorySeparator, Result);
|
||||
while I <> 0 do
|
||||
begin
|
||||
J := Pred(I);
|
||||
while (J > 0) and (Result[J] <> DirectorySeparator) do Dec (J);
|
||||
Delete(Result, J + 1, I - J + 3);
|
||||
I := Pos(DirectorySeparator + '..' + DirectorySeparator, Result);
|
||||
end;
|
||||
|
||||
// Remove a reference to '\..' at the end of line
|
||||
if StrEnds(Result, DirectorySeparator + '..') then
|
||||
begin
|
||||
J := Length(Result) - 3;
|
||||
while (J > 0) and (Result[J] <> DirectorySeparator) do Dec(J);
|
||||
if (J = 0) then
|
||||
Result := EmptyStr
|
||||
else if (J > PATH_DELIM_POS) then
|
||||
Delete(Result, J, MaxInt)
|
||||
else
|
||||
Delete(Result, J + 1, MaxInt);
|
||||
end;
|
||||
|
||||
// Remove a reference to '\.' at the end of line
|
||||
if Length(Result) = 1 then
|
||||
begin
|
||||
if Result[1] = '.' then Result := EmptyStr;
|
||||
end
|
||||
else if StrEnds(Result, DirectorySeparator + '.') then
|
||||
begin
|
||||
if Length(Result) = (PATH_DELIM_POS + 1) then
|
||||
Delete(Result, Length(Result), 1)
|
||||
else
|
||||
Delete(Result, Length(Result) - 1, 2);
|
||||
end;
|
||||
end;
|
||||
|
||||
function HasPathInvalidCharacters(Path: String): Boolean;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ uses
|
|||
the number of bytes this character spans. If the character was valid
|
||||
InvalidCharLen is zero.)
|
||||
}
|
||||
function SafeUTF8NextCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: Integer): Integer;
|
||||
function SafeUTF8NextCharLen(P: PByte; aMaxBytes: IntPtr; out InvalidCharLen: Integer): Integer;
|
||||
|
||||
{en
|
||||
Retrieves length in bytes of the previous UTF-8 character.
|
||||
|
|
@ -40,7 +40,7 @@ function SafeUTF8NextCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: I
|
|||
the number of bytes this character spans. If the character was valid
|
||||
InvalidCharLen is zero.)
|
||||
}
|
||||
function SafeUTF8PrevCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: Integer): Integer;
|
||||
function SafeUTF8PrevCharLen(P: PByte; aMaxBytes: IntPtr; out InvalidCharLen: Integer): Integer;
|
||||
function SafeUTF8NextCharStart(UTF8Str: PByte; Len: PtrInt): PByte;
|
||||
function SafeUTF8PrevCharEnd(UTF8Str: PByte; Len: PtrInt): PByte;
|
||||
{en
|
||||
|
|
@ -83,7 +83,7 @@ uses
|
|||
const
|
||||
maxUTF8Len = 7; // really is 4, but this includes any invalid characters up to length 7
|
||||
|
||||
function SafeUTF8NextCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: Integer): Integer;
|
||||
function SafeUTF8NextCharLen(P: PByte; aMaxBytes: IntPtr; out InvalidCharLen: Integer): Integer;
|
||||
var
|
||||
BytesLen: Integer;
|
||||
i: Integer;
|
||||
|
|
@ -133,7 +133,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function SafeUTF8PrevCharLen(P: PByte; aMaxBytes: Integer; out InvalidCharLen: Integer): Integer;
|
||||
function SafeUTF8PrevCharLen(P: PByte; aMaxBytes: IntPtr; out InvalidCharLen: Integer): Integer;
|
||||
var
|
||||
BytesLen: Integer;
|
||||
signature: Byte;
|
||||
|
|
@ -480,7 +480,7 @@ begin
|
|||
Index:= 0;
|
||||
SrcPos:= PAnsiChar(UTF8Text);
|
||||
while Len > 0 do begin
|
||||
Result[Index]:= UTF8CharacterToUnicode(SrcPos, CharLen);
|
||||
Result[Index]:= UTF8CodepointToUnicode(SrcPos, CharLen);
|
||||
Inc(SrcPos, CharLen);
|
||||
Dec(Len, CharLen);
|
||||
Inc(Index);
|
||||
|
|
|
|||
180
components/doublecmd/dcunix.pas
Executable file → Normal file
|
|
@ -3,7 +3,7 @@
|
|||
-------------------------------------------------------------------------
|
||||
This unit contains Unix specific functions
|
||||
|
||||
Copyright (C) 2015-2023 Alexander Koblov (alexx2000@mail.ru)
|
||||
Copyright (C) 2015-2024 Alexander Koblov (alexx2000@mail.ru)
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -40,13 +40,21 @@ const
|
|||
{$IF DEFINED(LINUX)}
|
||||
FD_CLOEXEC = 1;
|
||||
O_CLOEXEC = &02000000;
|
||||
O_PATH = &010000000;
|
||||
_SC_NPROCESSORS_ONLN = 84;
|
||||
{$ELSEIF DEFINED(FREEBSD)}
|
||||
O_CLOEXEC = &04000000;
|
||||
_SC_NPROCESSORS_ONLN = 58;
|
||||
CLOSE_RANGE_CLOEXEC = (1 << 2);
|
||||
{$ELSEIF DEFINED(NETBSD)}
|
||||
O_CLOEXEC = $00400000;
|
||||
{$ELSEIF DEFINED(HAIKU)}
|
||||
FD_CLOEXEC = 1;
|
||||
O_CLOEXEC = $00000040;
|
||||
{$ELSEIF DEFINED(DARWIN)}
|
||||
F_NOCACHE = 48;
|
||||
O_CLOEXEC = $1000000;
|
||||
_SC_NPROCESSORS_ONLN = 58;
|
||||
{$ELSE}
|
||||
O_CLOEXEC = 0;
|
||||
{$ENDIF}
|
||||
|
|
@ -155,6 +163,7 @@ type
|
|||
{$ELSE}
|
||||
TDCStat = BaseUnix.Stat;
|
||||
{$ENDIF}
|
||||
PDCStat = ^TDCStat;
|
||||
|
||||
TDCStatHelper = record Helper for TDCStat
|
||||
Public
|
||||
|
|
@ -248,6 +257,10 @@ function getgrgid(gid: gid_t): PGroupRecord; cdecl; external clib;
|
|||
fields of the record in the group database that matches the group name)
|
||||
}
|
||||
function getgrnam(name: PChar): PGroupRecord; cdecl; external clib;
|
||||
{en
|
||||
Get configuration information at run time
|
||||
}
|
||||
function sysconf(name: cint): clong; cdecl; external clib;
|
||||
|
||||
function FileLock(Handle: System.THandle; Mode: cInt): System.THandle;
|
||||
|
||||
|
|
@ -255,12 +268,12 @@ function fpMkTime(tm: PTimeStruct): TTime;
|
|||
function fpLocalTime(timer: PTime; tp: PTimeStruct): PTimeStruct;
|
||||
|
||||
{$IF DEFINED(LINUX)}
|
||||
var
|
||||
KernVersion: UInt16;
|
||||
|
||||
function fpFDataSync(fd: cint): cint;
|
||||
function fpCloneFile(src_fd, dst_fd: cint): Boolean;
|
||||
function fpFAllocate(fd: cint; mode: cint; offset, len: coff_t): cint;
|
||||
|
||||
function mbFileGetXattr(const FileName: String): TStringArray;
|
||||
function mbFileCopyXattr(const Source, Target: String): Boolean;
|
||||
{$ENDIF}
|
||||
|
||||
{$IF DEFINED(UNIX) AND NOT DEFINED(DARWIN)}
|
||||
|
|
@ -271,16 +284,25 @@ implementation
|
|||
|
||||
uses
|
||||
Unix, DCConvertEncoding, LazUTF8
|
||||
{$IFDEF DARWIN}
|
||||
{$IF DEFINED(DARWIN)}
|
||||
, DCDarwin
|
||||
{$ELSEIF DEFINED(LINUX)}
|
||||
, Dos, DCLinux, DCOSUtils
|
||||
{$ELSEIF DEFINED(FREEBSD)}
|
||||
, DCOSUtils
|
||||
{$ENDIF}
|
||||
;
|
||||
|
||||
{$IF not DEFINED(LINUX)}
|
||||
function TDCStatHelper.birthtime: TFileTimeEx;
|
||||
begin
|
||||
{$IF DEFINED(HAIKU)}
|
||||
Result.sec:= st_crtime;
|
||||
Result.nanosec:= st_crtimensec;
|
||||
{$ELSE}
|
||||
Result.sec:= st_birthtime;
|
||||
Result.nanosec:= st_birthtimensec;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function TDCStatHelper.mtime: TFileTimeEx;
|
||||
|
|
@ -373,8 +395,6 @@ begin
|
|||
{$ENDIF}
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{$IF DEFINED(BSD)}
|
||||
type rlim_t = Int64;
|
||||
{$ENDIF}
|
||||
|
|
@ -394,26 +414,44 @@ const
|
|||
{$ENDIF}
|
||||
|
||||
procedure tzset(); cdecl; external clib;
|
||||
function sysconf(name: cint): clong; cdecl; external clib;
|
||||
function mktime(tp: PTimeStruct): TTime; cdecl; external clib;
|
||||
function localtime_r(timer: PTime; tp: PTimeStruct): PTimeStruct; cdecl; external clib;
|
||||
function lchown(path : PChar; owner : TUid; group : TGid): cInt; cdecl; external clib;
|
||||
{$IF DEFINED(LINUX)}
|
||||
function fdatasync(fd: cint): cint; cdecl; external clib;
|
||||
function fallocate(fd: cint; mode: cint; offset, len: coff_t): cint; cdecl; external clib;
|
||||
{$ENDIF}
|
||||
|
||||
function lremovexattr(const path, name: PAnsiChar): cint; cdecl; external clib;
|
||||
function llistxattr(const path: PAnsiChar; list: PAnsiChar; size: csize_t): ssize_t; cdecl; external clib;
|
||||
function lgetxattr(const path, name: PAnsiChar; value: Pointer; size: csize_t): ssize_t; cdecl; external clib;
|
||||
function lsetxattr(const path, name: PAnsiChar; const value: Pointer; size: csize_t; flags: cint): cint; cdecl; external clib;
|
||||
{$IF DEFINED(LINUX) OR DEFINED(FREEBSD)}
|
||||
var
|
||||
hLibC: TLibHandle = NilHandle;
|
||||
|
||||
procedure LoadCLibrary;
|
||||
begin
|
||||
hLibC:= mbLoadLibrary(mbGetModuleName(@tzset));
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{$IF DEFINED(LINUX) OR DEFINED(BSD)}
|
||||
var
|
||||
close_range: function(first: cuint; last: cuint; flags: cint): cint; cdecl = nil;
|
||||
{$ENDIF}
|
||||
|
||||
procedure FileCloseOnExecAll;
|
||||
const
|
||||
MAX_FD = 1024;
|
||||
var
|
||||
fd: cint;
|
||||
p: TRLimit;
|
||||
fd_max: rlim_t = RLIM_INFINITY;
|
||||
begin
|
||||
{$IF DEFINED(LINUX) OR DEFINED(BSD)}
|
||||
if Assigned(close_range) then
|
||||
begin
|
||||
close_range(3, High(Int32), CLOSE_RANGE_CLOEXEC);
|
||||
Exit;
|
||||
end;
|
||||
{$ENDIF}
|
||||
if (FpGetRLimit(RLIMIT_NOFILE, @p) = 0) and (p.rlim_cur <> RLIM_INFINITY) then
|
||||
fd_max:= p.rlim_cur
|
||||
else begin
|
||||
|
|
@ -421,8 +459,8 @@ begin
|
|||
fd_max:= sysconf(_SC_OPEN_MAX);
|
||||
{$ENDIF}
|
||||
end;
|
||||
if fd_max = RLIM_INFINITY then
|
||||
fd_max:= High(Byte);
|
||||
if (fd_max = RLIM_INFINITY) or (fd_max > MAX_FD) then
|
||||
fd_max:= MAX_FD;
|
||||
for fd:= 3 to cint(fd_max) do
|
||||
FileCloseOnExec(fd);
|
||||
end;
|
||||
|
|
@ -505,6 +543,7 @@ begin
|
|||
if (fpFStatFS(Handle, @Sbfs) = 0) then
|
||||
begin
|
||||
case UInt32(Sbfs.fstype) of
|
||||
NFS_SUPER_MAGIC,
|
||||
SMB_SUPER_MAGIC,
|
||||
SMB2_MAGIC_NUMBER,
|
||||
CIFS_MAGIC_NUMBER: Exit;
|
||||
|
|
@ -558,103 +597,28 @@ begin
|
|||
Result := fallocate(fd, mode, offset, len);
|
||||
if Result = -1 then fpseterrno(fpgetCerrno);
|
||||
end;
|
||||
|
||||
function mbFileGetXattr(const FileName: String): TStringArray;
|
||||
var
|
||||
AList: String;
|
||||
ALength: ssize_t;
|
||||
AFileName: String;
|
||||
begin
|
||||
SetLength(AList, MaxSmallint);
|
||||
Result:= Default(TStringArray);
|
||||
AFileName:= CeUtf8ToSys(FileName);
|
||||
ALength:= llistxattr(PAnsiChar(AFileName), Pointer(AList), Length(AList));
|
||||
if (ALength < 0) then
|
||||
begin
|
||||
if (fpgetCerrno <> ESysERANGE) then
|
||||
begin
|
||||
fpseterrno(fpgetCerrno);
|
||||
Exit;
|
||||
end
|
||||
else begin
|
||||
ALength:= llistxattr(PAnsiChar(AFileName), nil, 0);
|
||||
if ALength < 0 then
|
||||
begin
|
||||
fpseterrno(fpgetCerrno);
|
||||
Exit;
|
||||
end;
|
||||
SetLength(AList, ALength);
|
||||
ALength:= llistxattr(PAnsiChar(AFileName), Pointer(AList), ALength);
|
||||
if ALength < 0 then
|
||||
begin
|
||||
fpseterrno(fpgetCerrno);
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if (ALength > 0) then
|
||||
begin
|
||||
SetLength(AList, ALength - 1);
|
||||
Result:= AList.Split(#0);
|
||||
end;
|
||||
end;
|
||||
|
||||
function mbFileCopyXattr(const Source, Target: String): Boolean;
|
||||
var
|
||||
Value: String;
|
||||
Index: Integer;
|
||||
ALength: ssize_t;
|
||||
Names: TStringArray;
|
||||
ASource, ATarget: String;
|
||||
begin
|
||||
Result:= True;
|
||||
ASource:= CeUtf8ToSys(Source);
|
||||
ATarget:= CeUtf8ToSys(Target);
|
||||
// Remove attributes from target
|
||||
Names:= mbFileGetXattr(Target);
|
||||
for Index:= 0 to High(Names) do
|
||||
begin
|
||||
lremovexattr(PAnsiChar(ATarget), PAnsiChar(Names[Index]));
|
||||
end;
|
||||
SetLength(Value, MaxSmallint);
|
||||
Names:= mbFileGetXattr(Source);
|
||||
for Index:= 0 to High(Names) do
|
||||
begin
|
||||
ALength:= lgetxattr(PAnsiChar(ASource), PAnsiChar(Names[Index]), Pointer(Value), Length(Value));
|
||||
if (ALength < 0) then
|
||||
begin
|
||||
if (fpgetCerrno <> ESysERANGE) then
|
||||
begin
|
||||
fpseterrno(fpgetCerrno);
|
||||
Exit(False);
|
||||
end
|
||||
else begin
|
||||
ALength:= lgetxattr(PAnsiChar(ASource), PAnsiChar(Names[Index]), nil, 0);
|
||||
if ALength < 0 then
|
||||
begin
|
||||
fpseterrno(fpgetCerrno);
|
||||
Exit(False);
|
||||
end;
|
||||
SetLength(Value, ALength);
|
||||
ALength:= lgetxattr(PAnsiChar(ASource), PAnsiChar(Names[Index]), Pointer(Value), Length(Value));
|
||||
if ALength < 0 then
|
||||
begin
|
||||
fpseterrno(fpgetCerrno);
|
||||
Exit(False);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if (lsetxattr(PAnsiChar(ATarget), PAnsiChar(Names[Index]), Pointer(Value), ALength, 0) < 0) then
|
||||
begin
|
||||
fpseterrno(fpgetCerrno);
|
||||
Exit(fpgeterrno = ESysEOPNOTSUPP);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
initialization
|
||||
procedure Initialize;
|
||||
begin
|
||||
tzset();
|
||||
{$IF DEFINED(LINUX) OR DEFINED(FREEBSD)}
|
||||
LoadCLibrary;
|
||||
{$IF DEFINED(LINUX)}
|
||||
KernVersion:= BEtoN(DosVersion);
|
||||
// Linux kernel >= 5.11
|
||||
if KernVersion >= $50B then
|
||||
{$ENDIF}
|
||||
begin
|
||||
Pointer(close_range):= GetProcAddress(hLibC, 'close_range');
|
||||
end;
|
||||
{$ELSEIF DEFINED(DARWIN)}
|
||||
close_range:= @CloseRange;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
initialization
|
||||
Initialize;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
|||
40
components/doublecmd/dcxmlconfig.pas
Normal file → Executable file
|
|
@ -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,7 +36,7 @@ end"/>
|
|||
</CompilerOptions>
|
||||
<Description Value="Common units for Double Commander"/>
|
||||
<License Value="GNU GPL 2"/>
|
||||
<Version Minor="4" Release="1"/>
|
||||
<Version Minor="4" Release="2"/>
|
||||
<Files Count="12">
|
||||
<Item1>
|
||||
<Filename Value="dcclassesutf8.pas"/>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
{ This file was automatically created by Lazarus. Do not edit!
|
||||
This source is only used to compile and install the package.
|
||||
}
|
||||
|
||||
unit doublecmd_common;
|
||||
|
||||
{$warn 5023 off : no warning about unused units}
|
||||
interface
|
||||
|
||||
uses
|
||||
DCClassesUtf8, DCOSUtils, DCStrUtils, DCBasicTypes, DCFileAttributes,
|
||||
DCConvertEncoding, DCDateTimeUtils, DCXmlConfig, DCProcessUtf8,
|
||||
DCUnicodeUtils, DCStringHashListUtf8, DCJsonConfig;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
{ This file was automatically created by Lazarus. Do not edit!
|
||||
This source is only used to compile and install the package.
|
||||
}
|
||||
|
||||
unit doublecmd_common;
|
||||
|
||||
{$warn 5023 off : no warning about unused units}
|
||||
interface
|
||||
|
||||
uses
|
||||
DCClassesUtf8, DCOSUtils, DCStrUtils, DCBasicTypes, DCFileAttributes,
|
||||
DCConvertEncoding, DCDateTimeUtils, DCXmlConfig, DCProcessUtf8,
|
||||
DCUnicodeUtils, DCStringHashListUtf8, DCJsonConfig;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
|
|
|||
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
|
|
@ -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;
|
||||
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |